~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/perf/util/debuginfo.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 /*
  3  * DWARF debug information handling code.  Copied from probe-finder.c.
  4  *
  5  * Written by Masami Hiramatsu <mhiramat@redhat.com>
  6  */
  7 
  8 #include <errno.h>
  9 #include <fcntl.h>
 10 #include <stdio.h>
 11 #include <stdlib.h>
 12 #include <string.h>
 13 #include <unistd.h>
 14 #include <linux/zalloc.h>
 15 
 16 #include "build-id.h"
 17 #include "dso.h"
 18 #include "debug.h"
 19 #include "debuginfo.h"
 20 #include "symbol.h"
 21 
 22 #ifdef HAVE_DEBUGINFOD_SUPPORT
 23 #include <elfutils/debuginfod.h>
 24 #endif
 25 
 26 /* Dwarf FL wrappers */
 27 static char *debuginfo_path;    /* Currently dummy */
 28 
 29 static const Dwfl_Callbacks offline_callbacks = {
 30         .find_debuginfo = dwfl_standard_find_debuginfo,
 31         .debuginfo_path = &debuginfo_path,
 32 
 33         .section_address = dwfl_offline_section_address,
 34 
 35         /* We use this table for core files too.  */
 36         .find_elf = dwfl_build_id_find_elf,
 37 };
 38 
 39 /* Get a Dwarf from offline image */
 40 static int debuginfo__init_offline_dwarf(struct debuginfo *dbg,
 41                                          const char *path)
 42 {
 43         GElf_Addr dummy;
 44         int fd;
 45 
 46         fd = open(path, O_RDONLY);
 47         if (fd < 0)
 48                 return fd;
 49 
 50         dbg->dwfl = dwfl_begin(&offline_callbacks);
 51         if (!dbg->dwfl)
 52                 goto error;
 53 
 54         dwfl_report_begin(dbg->dwfl);
 55         dbg->mod = dwfl_report_offline(dbg->dwfl, "", "", fd);
 56         if (!dbg->mod)
 57                 goto error;
 58 
 59         dbg->dbg = dwfl_module_getdwarf(dbg->mod, &dbg->bias);
 60         if (!dbg->dbg)
 61                 goto error;
 62 
 63         dwfl_module_build_id(dbg->mod, &dbg->build_id, &dummy);
 64 
 65         dwfl_report_end(dbg->dwfl, NULL, NULL);
 66 
 67         return 0;
 68 error:
 69         if (dbg->dwfl)
 70                 dwfl_end(dbg->dwfl);
 71         else
 72                 close(fd);
 73         memset(dbg, 0, sizeof(*dbg));
 74 
 75         return -ENOENT;
 76 }
 77 
 78 static struct debuginfo *__debuginfo__new(const char *path)
 79 {
 80         struct debuginfo *dbg = zalloc(sizeof(*dbg));
 81         if (!dbg)
 82                 return NULL;
 83 
 84         if (debuginfo__init_offline_dwarf(dbg, path) < 0)
 85                 zfree(&dbg);
 86         if (dbg)
 87                 pr_debug("Open Debuginfo file: %s\n", path);
 88         return dbg;
 89 }
 90 
 91 enum dso_binary_type distro_dwarf_types[] = {
 92         DSO_BINARY_TYPE__FEDORA_DEBUGINFO,
 93         DSO_BINARY_TYPE__UBUNTU_DEBUGINFO,
 94         DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO,
 95         DSO_BINARY_TYPE__BUILDID_DEBUGINFO,
 96         DSO_BINARY_TYPE__MIXEDUP_UBUNTU_DEBUGINFO,
 97         DSO_BINARY_TYPE__NOT_FOUND,
 98 };
 99 
100 struct debuginfo *debuginfo__new(const char *path)
101 {
102         enum dso_binary_type *type;
103         char buf[PATH_MAX], nil = '\0';
104         struct dso *dso;
105         struct debuginfo *dinfo = NULL;
106         struct build_id bid;
107 
108         /* Try to open distro debuginfo files */
109         dso = dso__new(path);
110         if (!dso)
111                 goto out;
112 
113         /* Set the build id for DSO_BINARY_TYPE__BUILDID_DEBUGINFO */
114         if (is_regular_file(path) && filename__read_build_id(path, &bid) > 0)
115                 dso__set_build_id(dso, &bid);
116 
117         for (type = distro_dwarf_types;
118              !dinfo && *type != DSO_BINARY_TYPE__NOT_FOUND;
119              type++) {
120                 if (dso__read_binary_type_filename(dso, *type, &nil,
121                                                    buf, PATH_MAX) < 0)
122                         continue;
123                 dinfo = __debuginfo__new(buf);
124         }
125         dso__put(dso);
126 
127 out:
128         /* if failed to open all distro debuginfo, open given binary */
129         return dinfo ? : __debuginfo__new(path);
130 }
131 
132 void debuginfo__delete(struct debuginfo *dbg)
133 {
134         if (dbg) {
135                 if (dbg->dwfl)
136                         dwfl_end(dbg->dwfl);
137                 free(dbg);
138         }
139 }
140 
141 /* For the kernel module, we need a special code to get a DIE */
142 int debuginfo__get_text_offset(struct debuginfo *dbg, Dwarf_Addr *offs,
143                                 bool adjust_offset)
144 {
145         int n, i;
146         Elf32_Word shndx;
147         Elf_Scn *scn;
148         Elf *elf;
149         GElf_Shdr mem, *shdr;
150         const char *p;
151 
152         elf = dwfl_module_getelf(dbg->mod, &dbg->bias);
153         if (!elf)
154                 return -EINVAL;
155 
156         /* Get the number of relocations */
157         n = dwfl_module_relocations(dbg->mod);
158         if (n < 0)
159                 return -ENOENT;
160         /* Search the relocation related .text section */
161         for (i = 0; i < n; i++) {
162                 p = dwfl_module_relocation_info(dbg->mod, i, &shndx);
163                 if (strcmp(p, ".text") == 0) {
164                         /* OK, get the section header */
165                         scn = elf_getscn(elf, shndx);
166                         if (!scn)
167                                 return -ENOENT;
168                         shdr = gelf_getshdr(scn, &mem);
169                         if (!shdr)
170                                 return -ENOENT;
171                         *offs = shdr->sh_addr;
172                         if (adjust_offset)
173                                 *offs -= shdr->sh_offset;
174                 }
175         }
176         return 0;
177 }
178 
179 #ifdef HAVE_DEBUGINFOD_SUPPORT
180 int get_source_from_debuginfod(const char *raw_path,
181                                const char *sbuild_id, char **new_path)
182 {
183         debuginfod_client *c = debuginfod_begin();
184         const char *p = raw_path;
185         int fd;
186 
187         if (!c)
188                 return -ENOMEM;
189 
190         fd = debuginfod_find_source(c, (const unsigned char *)sbuild_id,
191                                 0, p, new_path);
192         pr_debug("Search %s from debuginfod -> %d\n", p, fd);
193         if (fd >= 0)
194                 close(fd);
195         debuginfod_end(c);
196         if (fd < 0) {
197                 pr_debug("Failed to find %s in debuginfod (%s)\n",
198                         raw_path, sbuild_id);
199                 return -ENOENT;
200         }
201         pr_debug("Got a source %s\n", *new_path);
202 
203         return 0;
204 }
205 #endif /* HAVE_DEBUGINFOD_SUPPORT */
206 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php