2 /*--------------------------------------------------------------------*/
3 /*--- Reading of syms & debug info from ELF .so/executable files. ---*/
5 /*--------------------------------------------------------------------*/
8 This file is part of Valgrind, a dynamic binary instrumentation
11 Copyright (C) 2000-2010 Julian Seward
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License as
16 published by the Free Software Foundation; either version 2 of the
17 License, or (at your option) any later version.
19 This program is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
29 The GNU General Public License is contained in the file COPYING.
32 #if defined(VGO_linux) || defined(VGO_l4re)
34 #include "pub_core_basics.h"
35 #include "pub_core_vki.h"
36 #include "pub_core_debuginfo.h"
37 #include "pub_core_libcbase.h"
38 #include "pub_core_libcprint.h"
39 #include "pub_core_libcassert.h"
40 #include "pub_core_libcfile.h"
41 #include "pub_core_aspacemgr.h" /* for mmaping debuginfo files */
42 #include "pub_core_machine.h" /* VG_ELF_CLASS */
43 #include "pub_core_options.h"
44 #include "pub_core_oset.h"
45 #include "pub_core_tooliface.h" /* VG_(needs) */
46 #include "pub_core_xarray.h"
47 #include "priv_misc.h" /* dinfo_zalloc/free/strdup */
48 #include "priv_d3basics.h"
49 #include "priv_tytypes.h"
50 #include "priv_storage.h"
51 #include "priv_readelf.h" /* self */
52 #include "priv_readdwarf.h" /* 'cos ELF contains DWARF */
53 #include "priv_readdwarf3.h"
54 #include "priv_readstabs.h" /* and stabs, if we're unlucky */
56 /* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
58 /* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
60 /*------------------------------------------------------------*/
61 /*--- 32/64-bit parameterisation ---*/
62 /*------------------------------------------------------------*/
64 /* For all the ELF macros and types which specify '32' or '64',
65 select the correct variant for this platform and give it
66 an 'XX' name. Then use the 'XX' variant consistently in
67 the rest of this file.
70 # define ElfXX_Ehdr Elf32_Ehdr
71 # define ElfXX_Shdr Elf32_Shdr
72 # define ElfXX_Phdr Elf32_Phdr
73 # define ElfXX_Nhdr Elf32_Nhdr
74 # define ElfXX_Sym Elf32_Sym
75 # define ElfXX_Off Elf32_Off
76 # define ElfXX_Word Elf32_Word
77 # define ElfXX_Addr Elf32_Addr
78 # define ElfXX_Dyn Elf32_Dyn
79 # define ELFXX_ST_BIND ELF32_ST_BIND
80 # define ELFXX_ST_TYPE ELF32_ST_TYPE
82 #elif VG_WORDSIZE == 8
83 # define ElfXX_Ehdr Elf64_Ehdr
84 # define ElfXX_Shdr Elf64_Shdr
85 # define ElfXX_Phdr Elf64_Phdr
86 # define ElfXX_Nhdr Elf64_Nhdr
87 # define ElfXX_Sym Elf64_Sym
88 # define ElfXX_Off Elf64_Off
89 # define ElfXX_Word Elf64_Word
90 # define ElfXX_Addr Elf64_Addr
91 # define ElfXX_Dyn Elf64_Dyn
92 # define ELFXX_ST_BIND ELF64_ST_BIND
93 # define ELFXX_ST_TYPE ELF64_ST_TYPE
96 # error "VG_WORDSIZE should be 4 or 8"
100 /*------------------------------------------------------------*/
102 /*--- Read symbol table and line info from ELF files. ---*/
104 /*------------------------------------------------------------*/
106 /* readelf.c parses ELF files and acquires symbol table info from
107 them. It calls onwards to readdwarf.c to read DWARF2/3 line number
108 and call frame info found. */
111 /* Identify an ELF object file by peering at the first few bytes of
114 Bool ML_(is_elf_object_file)( void* image, SizeT n_image )
116 ElfXX_Ehdr* ehdr = (ElfXX_Ehdr*)image;
119 if (n_image < sizeof(ElfXX_Ehdr))
122 ok &= (ehdr->e_ident[EI_MAG0] == 0x7F
123 && ehdr->e_ident[EI_MAG1] == 'E'
124 && ehdr->e_ident[EI_MAG2] == 'L'
125 && ehdr->e_ident[EI_MAG3] == 'F');
126 ok &= (ehdr->e_ident[EI_CLASS] == VG_ELF_CLASS
127 && ehdr->e_ident[EI_DATA] == VG_ELF_DATA2XXX
128 && ehdr->e_ident[EI_VERSION] == EV_CURRENT);
129 ok &= (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN);
130 ok &= (ehdr->e_machine == VG_ELF_MACHINE);
131 ok &= (ehdr->e_version == EV_CURRENT);
132 ok &= (ehdr->e_shstrndx != SHN_UNDEF);
133 ok &= (ehdr->e_shoff != 0 && ehdr->e_shnum != 0);
134 ok &= (ehdr->e_phoff != 0 && ehdr->e_phnum != 0);
143 /* Show a raw ELF symbol, given its in-image address and name. */
146 void show_raw_elf_symbol ( Int i,
147 ElfXX_Sym* sym, Char* sym_name, Addr sym_svma,
148 Bool ppc64_linux_format )
150 HChar* space = ppc64_linux_format ? " " : "";
151 VG_(printf)("raw symbol [%4d]: ", i);
152 switch (ELFXX_ST_BIND(sym->st_info)) {
153 case STB_LOCAL: VG_(printf)("LOC "); break;
154 case STB_GLOBAL: VG_(printf)("GLO "); break;
155 case STB_WEAK: VG_(printf)("WEA "); break;
156 case STB_LOPROC: VG_(printf)("lop "); break;
157 case STB_HIPROC: VG_(printf)("hip "); break;
158 default: VG_(printf)("??? "); break;
160 switch (ELFXX_ST_TYPE(sym->st_info)) {
161 case STT_NOTYPE: VG_(printf)("NOT "); break;
162 case STT_OBJECT: VG_(printf)("OBJ "); break;
163 case STT_FUNC: VG_(printf)("FUN "); break;
164 case STT_SECTION: VG_(printf)("SEC "); break;
165 case STT_FILE: VG_(printf)("FIL "); break;
166 case STT_LOPROC: VG_(printf)("lop "); break;
167 case STT_HIPROC: VG_(printf)("hip "); break;
168 default: VG_(printf)("??? "); break;
170 VG_(printf)(": svma %#010lx, %ssz %4ld %s\n",
171 sym_svma, space, sym->st_size + 0UL,
172 ( sym->st_name ? sym_name : (Char*)"NONAME" ) );
176 /* Decide whether SYM is something we should collect, and if so, copy
177 relevant info to the _OUT arguments. For {x86,amd64,ppc32}-linux
178 this is straightforward - the name, address, size are copied out
181 There is a bit of a kludge re data symbols (see KLUDGED BSS CHECK
182 below): we assume that the .bss is mapped immediately after .data,
183 and so accept any data symbol which exists in the range [start of
184 .data, size of .data + size of .bss). I don't know if this is
185 really correct/justifiable, or not.
187 For ppc64-linux it's more complex. If the symbol is seen to be in
188 the .opd section, it is taken to be a function descriptor, and so
189 a dereference is attempted, in order to get hold of the real entry
190 point address. Also as part of the dereference, there is an attempt
191 to calculate the TOC pointer (R2 value) associated with the symbol.
193 To support the ppc64-linux pre-"dotless" ABI (prior to gcc 4.0.0),
194 if the symbol is seen to be outside the .opd section and its name
195 starts with a dot, an .opd deference is not attempted, and no TOC
196 pointer is calculated, but the the leading dot is removed from the
199 As a result, on ppc64-linux, the caller of this function may have
200 to piece together the real size, address, name of the symbol from
201 multiple calls to this function. Ugly and confusing.
204 Bool get_elf_symbol_info (
206 struct _DebugInfo* di, /* containing DebugInfo */
207 ElfXX_Sym* sym, /* ELF symbol */
208 Char* sym_name, /* name */
209 Addr sym_svma, /* address as stated in the object file */
210 Bool symtab_in_debug, /* symbol table is in the debug file */
211 UChar* opd_img, /* oimage of .opd sec (ppc64-linux only) */
212 PtrdiffT opd_bias, /* for biasing AVMAs found in .opd */
214 Char** sym_name_out, /* name we should record */
215 Addr* sym_avma_out, /* addr we should record */
216 Int* sym_size_out, /* symbol size */
217 Addr* sym_tocptr_out, /* ppc64-linux only: R2 value to be
219 Bool* from_opd_out, /* ppc64-linux only: did we deref an
221 Bool* is_text_out, /* is this a text symbol? */
222 Bool* is_ifunc /* is this a STT_GNU_IFUNC function ?*/
226 # if defined(VGP_ppc64_linux)
229 Bool in_text, in_data, in_sdata, in_rodata, in_bss, in_sbss;
230 Addr text_svma, data_svma, sdata_svma, rodata_svma, bss_svma, sbss_svma;
231 PtrdiffT text_bias, data_bias, sdata_bias, rodata_bias, bss_bias, sbss_bias;
234 *sym_name_out = sym_name;
235 *sym_avma_out = sym_svma; /* we will bias this shortly */
237 *sym_size_out = (Int)sym->st_size;
238 *sym_tocptr_out = 0; /* unknown/inapplicable */
239 *from_opd_out = False;
242 /* Figure out if we're interested in the symbol. Firstly, is it of
243 the right flavour? */
245 = (ELFXX_ST_BIND(sym->st_info) == STB_GLOBAL
246 || ELFXX_ST_BIND(sym->st_info) == STB_LOCAL
247 || ELFXX_ST_BIND(sym->st_info) == STB_WEAK
250 (ELFXX_ST_TYPE(sym->st_info) == STT_FUNC
251 || ELFXX_ST_TYPE(sym->st_info) == STT_OBJECT
253 || ELFXX_ST_TYPE(sym->st_info) == STT_GNU_IFUNC
257 /* Work out the svma and bias for each section as it will appear in
258 addresses in the symbol table. */
259 if (symtab_in_debug) {
260 text_svma = di->text_debug_svma;
261 text_bias = di->text_debug_bias;
262 data_svma = di->data_debug_svma;
263 data_bias = di->data_debug_bias;
264 sdata_svma = di->sdata_debug_svma;
265 sdata_bias = di->sdata_debug_bias;
266 rodata_svma = di->rodata_debug_svma;
267 rodata_bias = di->rodata_debug_bias;
268 bss_svma = di->bss_debug_svma;
269 bss_bias = di->bss_debug_bias;
270 sbss_svma = di->sbss_debug_svma;
271 sbss_bias = di->sbss_debug_bias;
273 text_svma = di->text_svma;
274 text_bias = di->text_bias;
275 data_svma = di->data_svma;
276 data_bias = di->data_bias;
277 sdata_svma = di->sdata_svma;
278 sdata_bias = di->sdata_bias;
279 rodata_svma = di->rodata_svma;
280 rodata_bias = di->rodata_bias;
281 bss_svma = di->bss_svma;
282 bss_bias = di->bss_bias;
283 sbss_svma = di->sbss_svma;
284 sbss_bias = di->sbss_bias;
287 /* Now bias sym_avma_out accordingly by figuring out exactly which
288 section the symbol is from and bias accordingly. Screws up if
289 the previously deduced section svma address ranges are wrong. */
292 && sym_svma >= text_svma
293 && sym_svma < text_svma + di->text_size) {
295 *sym_avma_out += text_bias;
299 && sym_svma >= data_svma
300 && sym_svma < data_svma + di->data_size) {
301 *is_text_out = False;
302 *sym_avma_out += data_bias;
304 if (di->sdata_present
305 && di->sdata_size > 0
306 && sym_svma >= sdata_svma
307 && sym_svma < sdata_svma + di->sdata_size) {
308 *is_text_out = False;
309 *sym_avma_out += sdata_bias;
311 if (di->rodata_present
312 && di->rodata_size > 0
313 && sym_svma >= rodata_svma
314 && sym_svma < rodata_svma + di->rodata_size) {
315 *is_text_out = False;
316 *sym_avma_out += rodata_bias;
320 && sym_svma >= bss_svma
321 && sym_svma < bss_svma + di->bss_size) {
322 *is_text_out = False;
323 *sym_avma_out += bss_bias;
327 && sym_svma >= sbss_svma
328 && sym_svma < sbss_svma + di->sbss_size) {
329 *is_text_out = False;
330 *sym_avma_out += sbss_bias;
332 /* Assume it's in .text. Is this a good idea? */
334 *sym_avma_out += text_bias;
337 # ifdef STT_GNU_IFUNC
338 /* Check for indirect functions. */
340 && ELFXX_ST_TYPE(sym->st_info) == STT_GNU_IFUNC) {
345 # if defined(VGP_ppc64_linux)
346 /* Allow STT_NOTYPE in the very special case where we're running on
347 ppc64-linux and the symbol is one which the .opd-chasing hack
351 && ELFXX_ST_TYPE(sym->st_info) == STT_NOTYPE
355 && *sym_avma_out >= di->opd_avma
356 && *sym_avma_out < di->opd_avma + di->opd_size)
363 /* Ignore if nameless, or zero-sized. */
364 if (sym->st_name == (ElfXX_Word)0
365 || /* VG_(strlen)(sym_name) == 0 */
366 /* equivalent but cheaper ... */
368 || sym->st_size == 0) {
369 TRACE_SYMTAB(" ignore -- size=0: %s\n", sym_name);
373 /* This seems to significantly reduce the number of junk
374 symbols, and particularly reduces the number of
375 overlapping address ranges. Don't ask me why ... */
376 if ((Int)sym->st_value == 0) {
377 TRACE_SYMTAB( " ignore -- valu=0: %s\n", sym_name);
381 /* If it's apparently in a GOT or PLT, it's really a reference to a
382 symbol defined elsewhere, so ignore it. */
385 && *sym_avma_out >= di->got_avma
386 && *sym_avma_out < di->got_avma + di->got_size) {
387 TRACE_SYMTAB(" ignore -- in GOT: %s\n", sym_name);
392 && *sym_avma_out >= di->plt_avma
393 && *sym_avma_out < di->plt_avma + di->plt_size) {
394 TRACE_SYMTAB(" ignore -- in PLT: %s\n", sym_name);
398 /* ppc64-linux nasty hack: if the symbol is in an .opd section,
399 then really what we have is the address of a function
400 descriptor. So use the first word of that as the function's
403 See thread starting at
404 http://gcc.gnu.org/ml/gcc-patches/2004-08/msg00557.html
406 # if defined(VGP_ppc64_linux)
412 && *sym_avma_out >= di->opd_avma
413 && *sym_avma_out < di->opd_avma + di->opd_size) {
414 # if !defined(VGP_ppc64_linux)
415 TRACE_SYMTAB(" ignore -- in OPD: %s\n", sym_name);
420 Bool details = 1||False;
423 TRACE_SYMTAB("opdXXX: opd_bias %p, sym_svma_out %p\n",
424 (void*)(opd_bias), (void*)*sym_avma_out);
426 if (!VG_IS_8_ALIGNED(*sym_avma_out)) {
427 TRACE_SYMTAB(" ignore -- not 8-aligned: %s\n", sym_name);
431 /* *sym_avma_out is a vma pointing into the .opd section. We
432 know the vma of the opd section start, so we can figure out
433 how far into the opd section this is. */
435 offset_in_opd = (Addr)(*sym_avma_out) - (Addr)(di->opd_avma);
436 if (offset_in_opd < 0 || offset_in_opd >= di->opd_size) {
437 TRACE_SYMTAB(" ignore -- invalid OPD offset: %s\n", sym_name);
441 /* Now we want to know what's at that offset in the .opd
442 section. We can't look in the running image since it won't
443 necessarily have been mapped. But we can consult the oimage.
444 opd_img is the start address of the .opd in the oimage.
447 fn_descr = (ULong*)(opd_img + offset_in_opd);
450 TRACE_SYMTAB("opdXXY: offset %d, fn_descr %p\n",
451 offset_in_opd, fn_descr);
453 TRACE_SYMTAB("opdXXZ: *fn_descr %p\n", (void*)(fn_descr[0]));
455 /* opd_bias is the what we have to add to SVMAs found in .opd to
456 get plausible .text AVMAs for the entry point, and .data
457 AVMAs (presumably) for the TOC locations. We use the caller
458 supplied value (which is di->text_bias) for both of these.
459 Not sure why that is correct - it seems to work, and sounds
460 OK for fn_descr[0], but surely we need to use the data bias
461 and not the text bias for fn_descr[1] ? Oh Well.
463 *sym_avma_out = fn_descr[0] + opd_bias;
464 *sym_tocptr_out = fn_descr[1] + opd_bias;
465 *from_opd_out = True;
468 /* Do a final sanity check: if the symbol falls outside the
469 DebugInfo's mapped range, ignore it. Since *sym_avma_out has
470 been updated, that can be achieved simply by falling through
471 to the test below. */
473 # endif /* ppc64-linux nasty hack */
476 /* Here's yet another ppc64-linux hack. Get rid of leading dot if
477 the symbol is outside .opd. */
478 # if defined(VGP_ppc64_linux)
481 && sym_name[0] == '.') {
482 vg_assert(!(*from_opd_out));
483 *sym_name_out = &sym_name[1];
487 /* If no part of the symbol falls within the mapped range,
493 && !(*sym_avma_out + *sym_size_out <= di->text_avma
494 || *sym_avma_out >= di->text_avma + di->text_size);
499 && !(*sym_avma_out + *sym_size_out <= di->data_avma
500 || *sym_avma_out >= di->data_avma + di->data_size);
504 && di->sdata_size > 0
505 && !(*sym_avma_out + *sym_size_out <= di->sdata_avma
506 || *sym_avma_out >= di->sdata_avma + di->sdata_size);
510 && di->rodata_size > 0
511 && !(*sym_avma_out + *sym_size_out <= di->rodata_avma
512 || *sym_avma_out >= di->rodata_avma + di->rodata_size);
517 && !(*sym_avma_out + *sym_size_out <= di->bss_avma
518 || *sym_avma_out >= di->bss_avma + di->bss_size);
523 && !(*sym_avma_out + *sym_size_out <= di->sbss_avma
524 || *sym_avma_out >= di->sbss_avma + di->sbss_size);
528 /* This used to reject any symbol falling outside the text
529 segment ("if (!in_text) ..."). Now it is relaxed slightly,
530 to reject only symbols which fall outside the area mapped
531 r-x. This is in accordance with r7427. See
532 "Comment_Regarding_Text_Range_Checks" in storage.c for
535 vg_assert(di->have_rx_map);
536 in_rx = (!(*sym_avma_out + *sym_size_out <= di->rx_map_avma
537 || *sym_avma_out >= di->rx_map_avma + di->rx_map_size));
542 "ignore -- %#lx .. %#lx outside .text svma range %#lx .. %#lx\n",
543 *sym_avma_out, *sym_avma_out + *sym_size_out,
545 di->text_avma + di->text_size);
549 if (!(in_data || in_sdata || in_rodata || in_bss || in_sbss)) {
551 "ignore -- %#lx .. %#lx outside .data / .sdata / .rodata / .bss / .sbss svma ranges\n",
552 *sym_avma_out, *sym_avma_out + *sym_size_out);
557 # if defined(VGP_ppc64_linux)
558 /* It's crucial that we never add symbol addresses in the .opd
559 section. This would completely mess up function redirection and
560 intercepting. This assert ensures that anysymbols that make it
561 into the symbol table on ppc64-linux don't point into .opd. */
562 if (di->opd_present && di->opd_size > 0) {
563 vg_assert(*sym_avma_out + *sym_size_out <= di->opd_avma
564 || *sym_avma_out >= di->opd_avma + di->opd_size);
573 /* Read an ELF symbol table (normal or dynamic). This one is for the
574 "normal" case ({x86,amd64,ppc32}-linux). */
576 __attribute__((unused)) /* not referred to on all targets */
577 void read_elf_symtab__normal(
578 struct _DebugInfo* di, UChar* tab_name,
579 ElfXX_Sym* symtab_img, SizeT symtab_szB,
580 UChar* strtab_img, SizeT strtab_szB,
581 Bool symtab_in_debug,
582 UChar* opd_img /* ppc64-linux only */
586 Addr sym_svma, sym_avma_really;
587 Char *sym_name, *sym_name_really;
590 Bool from_opd, is_text, is_ifunc;
594 if (strtab_img == NULL || symtab_img == NULL) {
596 vg_assert(VG_(strlen)(tab_name) < 40);
597 VG_(sprintf)(buf, " object doesn't have a %s", tab_name);
598 ML_(symerr)(di, False, buf);
602 TRACE_SYMTAB("\n--- Reading (ELF, standard) %s (%ld entries) ---\n",
603 tab_name, symtab_szB/sizeof(ElfXX_Sym) );
605 /* Perhaps should start at i = 1; ELF docs suggest that entry
606 0 always denotes 'unknown symbol'. */
607 for (i = 1; i < (Word)(symtab_szB/sizeof(ElfXX_Sym)); i++) {
608 sym = & symtab_img[i];
609 sym_name = (UChar*)(strtab_img + sym->st_name);
610 sym_svma = sym->st_value;
612 if (di->trace_symtab)
613 show_raw_elf_symbol(i, sym, sym_name, sym_svma, False);
615 if (get_elf_symbol_info(di, sym, sym_name, sym_svma,
617 opd_img, di->text_bias,
622 &from_opd, &is_text, &is_ifunc)) {
624 risym.addr = sym_avma_really;
625 risym.size = sym_size;
626 risym.name = ML_(addStr) ( di, sym_name_really, -1 );
627 risym.tocptr = sym_tocptr;
628 risym.isText = is_text;
629 risym.isIFunc = is_ifunc;
630 vg_assert(risym.name != NULL);
631 vg_assert(risym.tocptr == 0); /* has no role except on ppc64-linux */
632 ML_(addSym) ( di, &risym );
634 if (di->trace_symtab) {
635 VG_(printf)(" rec(%c) [%4ld]: "
636 " val %#010lx, sz %4d %s\n",
650 /* Read an ELF symbol table (normal or dynamic). This one is for
651 ppc64-linux, which requires special treatment. */
671 static Word cmp_TempSymKey ( TempSymKey* key1, TempSym* elem2 ) {
672 if (key1->addr < elem2->key.addr) return -1;
673 if (key1->addr > elem2->key.addr) return 1;
674 return (Word)VG_(strcmp)(key1->name, elem2->key.name);
678 __attribute__((unused)) /* not referred to on all targets */
679 void read_elf_symtab__ppc64_linux(
680 struct _DebugInfo* di, UChar* tab_name,
681 ElfXX_Sym* symtab_img, SizeT symtab_szB,
682 UChar* strtab_img, SizeT strtab_szB,
683 Bool symtab_in_debug,
684 UChar* opd_img /* ppc64-linux only */
689 Addr sym_svma, sym_avma_really;
690 Char *sym_name, *sym_name_really;
693 Bool from_opd, modify_size, modify_tocptr, is_text, is_ifunc;
701 if (strtab_img == NULL || symtab_img == NULL) {
703 vg_assert(VG_(strlen)(tab_name) < 40);
704 VG_(sprintf)(buf, " object doesn't have a %s", tab_name);
705 ML_(symerr)(di, False, buf);
709 TRACE_SYMTAB("\n--- Reading (ELF, ppc64-linux) %s (%ld entries) ---\n",
710 tab_name, symtab_szB/sizeof(ElfXX_Sym) );
712 oset = VG_(OSetGen_Create)( offsetof(TempSym,key),
713 (OSetCmp_t)cmp_TempSymKey,
714 ML_(dinfo_zalloc), "di.respl.1",
718 /* Perhaps should start at i = 1; ELF docs suggest that entry
719 0 always denotes 'unknown symbol'. */
720 for (i = 1; i < (Word)(symtab_szB/sizeof(ElfXX_Sym)); i++) {
721 sym = & symtab_img[i];
722 sym_name = (Char*)(strtab_img + sym->st_name);
723 sym_svma = sym->st_value;
725 if (di->trace_symtab)
726 show_raw_elf_symbol(i, sym, sym_name, sym_svma, True);
728 if (get_elf_symbol_info(di, sym, sym_name, sym_svma,
730 opd_img, di->text_bias,
735 &from_opd, &is_text, &is_ifunc)) {
737 /* Check if we've seen this (name,addr) key before. */
738 key.addr = sym_avma_really;
739 key.name = sym_name_really;
740 prev = VG_(OSetGen_Lookup)( oset, &key );
744 /* Seen it before. Fold in whatever new info we can. */
746 modify_tocptr = False;
749 if (prev->from_opd && !from_opd
750 && (prev->size == 24 || prev->size == 16)
751 && sym_size != prev->size) {
752 /* Existing one is an opd-redirect, with a bogus size,
753 so the only useful new fact we have is the real size
756 old_size = prev->size;
757 prev->size = sym_size;
760 if (!prev->from_opd && from_opd
761 && (sym_size == 24 || sym_size == 16)) {
762 /* Existing one is non-opd, new one is opd. What we
763 can acquire from the new one is the TOC ptr to be
764 used. Since the existing sym is non-toc, it
765 shouldn't currently have an known TOC ptr. */
766 vg_assert(prev->tocptr == 0);
767 modify_tocptr = True;
768 prev->tocptr = sym_tocptr;
771 /* ignore. can we do better here? */
774 /* Only one or the other is possible (I think) */
775 vg_assert(!(modify_size && modify_tocptr));
777 if (modify_size && di->trace_symtab) {
778 VG_(printf)(" modify (old sz %4d) "
779 " val %#010lx, toc %#010lx, sz %4d %s\n",
784 (HChar*)prev->key.name
787 if (modify_tocptr && di->trace_symtab) {
788 VG_(printf)(" modify (upd tocptr) "
789 " val %#010lx, toc %#010lx, sz %4d %s\n",
793 (HChar*)prev->key.name
799 /* A new (name,addr) key. Add and continue. */
800 elem = VG_(OSetGen_AllocNode)(oset, sizeof(TempSym));
803 elem->tocptr = sym_tocptr;
804 elem->size = sym_size;
805 elem->from_opd = from_opd;
806 elem->is_text = is_text;
807 elem->is_ifunc = is_ifunc;
808 VG_(OSetGen_Insert)(oset, elem);
809 if (di->trace_symtab) {
810 VG_(printf)(" to-oset [%4ld]: "
811 " val %#010lx, toc %#010lx, sz %4d %s\n",
816 (HChar*)elem->key.name
824 /* All the syms that matter are in the oset. Now pull them out,
825 build a "standard" symbol table, and nuke the oset. */
828 VG_(OSetGen_ResetIter)( oset );
830 while ( (elem = VG_(OSetGen_Next)(oset)) ) {
831 risym.addr = elem->key.addr;
832 risym.size = elem->size;
833 risym.name = ML_(addStr) ( di, elem->key.name, -1 );
834 risym.tocptr = elem->tocptr;
835 risym.isText = elem->is_text;
836 risym.isIFunc = elem->is_ifunc;
837 vg_assert(risym.name != NULL);
839 ML_(addSym) ( di, &risym );
840 if (di->trace_symtab) {
841 VG_(printf)(" rec(%c) [%4ld]: "
842 " val %#010lx, toc %#010lx, sz %4d %s\n",
843 risym.isText ? 't' : 'd',
854 VG_(OSetGen_Destroy)( oset );
859 * Look for a build-id in an ELF image. The build-id specification
862 * http://fedoraproject.org/wiki/RolandMcGrath/BuildID
865 Char *find_buildid(Addr image, UWord n_image)
867 Char* buildid = NULL;
868 ElfXX_Ehdr* ehdr = (ElfXX_Ehdr*)image;
870 #ifdef NT_GNU_BUILD_ID
871 if (n_image >= sizeof(ElfXX_Ehdr) &&
872 ML_(is_elf_object_file)(ehdr, n_image)) {
875 for (i = 0; i < ehdr->e_phnum; i++) {
876 ElfXX_Phdr* phdr = (ElfXX_Phdr*)(image + ehdr->e_phoff + i * ehdr->e_phentsize);
878 if (phdr->p_type == PT_NOTE) {
879 ElfXX_Off offset = phdr->p_offset;
881 while (offset < phdr->p_offset + phdr->p_filesz) {
882 ElfXX_Nhdr* note = (ElfXX_Nhdr*)(image + offset);
883 Char* name = (Char *)note + sizeof(ElfXX_Nhdr);
884 UChar *desc = (UChar *)name + ((note->n_namesz + 3) & ~3);
887 if (VG_(strcmp)(name, ELF_NOTE_GNU) == 0 &&
888 note->n_type == NT_GNU_BUILD_ID) {
889 buildid = ML_(dinfo_zalloc)("di.fbi.1", note->n_descsz * 2 + 1);
891 for (j = 0; j < note->n_descsz; j++) {
892 VG_(sprintf)(buildid + VG_(strlen)(buildid), "%02x", desc[j]);
896 offset = offset + sizeof(ElfXX_Nhdr)
897 + ((note->n_namesz + 3) & ~3)
898 + ((note->n_descsz + 3) & ~3);
909 * This routine for calculating the CRC for a separate debug file
910 * is GPLed code borrowed from GNU binutils.
913 calc_gnu_debuglink_crc32(UInt crc, const UChar *buf, Int len)
915 static const UInt crc32_table[256] =
917 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
918 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
919 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
920 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
921 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
922 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
923 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
924 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
925 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
926 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
927 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
928 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
929 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
930 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
931 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
932 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
933 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
934 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
935 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
936 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
937 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
938 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
939 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
940 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
941 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
942 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
943 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
944 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
945 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
946 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
947 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
948 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
949 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
950 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
951 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
952 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
953 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
954 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
955 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
956 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
957 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
958 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
959 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
960 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
961 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
962 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
963 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
964 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
965 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
966 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
967 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
972 crc = ~crc & 0xffffffff;
973 for (end = buf + len; buf < end; ++ buf)
974 crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
975 return ~crc & 0xffffffff;;
979 * Try and open a separate debug file, ignoring any where the CRC does
980 * not match the value from the main object file.
983 Addr open_debug_file( Char* name, Char* buildid, UInt crc, /*OUT*/UWord* size )
986 struct vg_stat stat_buf;
989 fd = VG_(open)(name, VKI_O_RDONLY, 0);
993 if (VG_(fstat)(sr_Res(fd), &stat_buf) != 0) {
994 VG_(close)(sr_Res(fd));
998 if (VG_(clo_verbosity) > 1)
999 VG_(message)(Vg_DebugMsg, " Considering %s ..\n", name);
1001 *size = stat_buf.size;
1003 sres = VG_(am_mmap_file_float_valgrind)
1004 ( *size, VKI_PROT_READ, sr_Res(fd), 0 );
1006 VG_(close)(sr_Res(fd));
1008 if (sr_isError(sres))
1012 Char* debug_buildid = find_buildid(sr_Res(sres), *size);
1013 if (debug_buildid == NULL || VG_(strcmp)(buildid, debug_buildid) != 0) {
1014 SysRes res = VG_(am_munmap_valgrind)(sr_Res(sres), *size);
1015 vg_assert(!sr_isError(res));
1016 if (VG_(clo_verbosity) > 1)
1017 VG_(message)(Vg_DebugMsg,
1018 " .. build-id mismatch (found %s wanted %s)\n", debug_buildid, buildid);
1019 ML_(dinfo_free)(debug_buildid);
1022 ML_(dinfo_free)(debug_buildid);
1024 if (VG_(clo_verbosity) > 1)
1025 VG_(message)(Vg_DebugMsg, " .. build-id is valid\n");
1027 calccrc = calc_gnu_debuglink_crc32(0, (UChar*)sr_Res(sres), *size);
1028 if (calccrc != crc) {
1029 SysRes res = VG_(am_munmap_valgrind)(sr_Res(sres), *size);
1030 vg_assert(!sr_isError(res));
1031 if (VG_(clo_verbosity) > 1)
1032 VG_(message)(Vg_DebugMsg,
1033 " .. CRC mismatch (computed %08x wanted %08x)\n", calccrc, crc);
1037 if (VG_(clo_verbosity) > 1)
1038 VG_(message)(Vg_DebugMsg, " .. CRC is valid\n");
1041 return sr_Res(sres);
1045 * Try to find a separate debug file for a given object file.
1048 Addr find_debug_file( struct _DebugInfo* di,
1049 Char* objpath, Char* buildid,
1050 Char* debugname, UInt crc,
1051 /*OUT*/UWord* size )
1053 Char *debugpath = NULL;
1056 if (buildid != NULL) {
1057 debugpath = ML_(dinfo_zalloc)(
1059 VG_(strlen)(buildid) + 33);
1061 VG_(sprintf)(debugpath, "/usr/lib/debug/.build-id/%c%c/%s.debug",
1062 buildid[0], buildid[1], buildid + 2);
1064 if ((addr = open_debug_file(debugpath, buildid, 0, size)) == 0) {
1065 ML_(dinfo_free)(debugpath);
1070 if (addr == 0 && debugname != NULL) {
1071 Char *objdir = ML_(dinfo_strdup)("di.fdf.2", objpath);
1074 if ((objdirptr = VG_(strrchr)(objdir, '/')) != NULL)
1077 debugpath = ML_(dinfo_zalloc)(
1079 VG_(strlen)(objdir) + VG_(strlen)(debugname) + 32);
1081 VG_(sprintf)(debugpath, "%s/%s", objdir, debugname);
1083 if ((addr = open_debug_file(debugpath, NULL, crc, size)) == 0) {
1084 VG_(sprintf)(debugpath, "%s/.debug/%s", objdir, debugname);
1085 if ((addr = open_debug_file(debugpath, NULL, crc, size)) == 0) {
1086 VG_(sprintf)(debugpath, "/usr/lib/debug%s/%s", objdir, debugname);
1087 addr = open_debug_file(debugpath, NULL, crc, size);
1091 ML_(dinfo_free)(objdir);
1096 TRACE_SYMTAB("------ Found a debuginfo file: %s\n", debugpath);
1099 ML_(dinfo_free)(debugpath);
1105 static Bool contained_within ( Addr outer, UWord n_outer,
1106 Addr inner, UWord n_inner )
1108 if (n_outer == 0 || n_inner == 0)
1110 /* Simplistic .. assumes no wraparound (reasonably enough) */
1111 if (inner >= outer && inner+n_inner <= outer+n_outer)
1116 static void* INDEX_BIS ( void* base, Word idx, Word scale ) {
1117 return (void*)( ((UChar*)base) + idx * scale );
1121 /* Find the file offset corresponding to SVMA by using the program
1122 headers. This is taken from binutils-2.17/binutils/readelf.c
1123 offset_from_vma(). */
1125 Word file_offset_from_svma ( /*OUT*/Bool* ok,
1127 ElfXX_Phdr* phdr_img,
1133 for (i = 0; i < phdr_nent; i++) {
1134 seg = INDEX_BIS( phdr_img, i, phdr_ent_szB );
1135 if (seg->p_type != PT_LOAD)
1137 if (svma >= (seg->p_vaddr & -seg->p_align)
1138 && svma + 1 <= seg->p_vaddr + seg->p_filesz) {
1140 return svma - seg->p_vaddr + seg->p_offset;
1147 /* The central function for reading ELF debug info. For the
1148 object/exe specified by the DebugInfo, find ELF sections, then read
1149 the symbols, line number info, file name info, CFA (stack-unwind
1150 info) and anything else we want, into the tables within the
1153 Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
1158 Bool dynbss_present = False;
1159 Bool sdynbss_present = False;
1161 /* Image addresses for the ELF file we're working with. */
1165 /* Ditto for any ELF debuginfo file that we might happen to load. */
1169 /* ELF header for the main file. Should == oimage since is at
1171 ElfXX_Ehdr* ehdr_img = NULL;
1173 /* Program header table image addr, # entries, entry size */
1174 ElfXX_Phdr* phdr_img = NULL;
1175 UWord phdr_nent = 0;
1176 UWord phdr_ent_szB = 0;
1178 /* Section header image addr, # entries, entry size. Also the
1179 associated string table. */
1180 ElfXX_Shdr* shdr_img = NULL;
1181 UWord shdr_nent = 0;
1182 UWord shdr_ent_szB = 0;
1183 UChar* shdr_strtab_img = NULL;
1185 /* SVMAs covered by rx and rw segments and corresponding bias. */
1186 Addr rx_svma_base = 0;
1187 Addr rx_svma_limit = 0;
1188 PtrdiffT rx_bias = 0;
1189 Addr rw_svma_base = 0;
1190 Addr rw_svma_limit = 0;
1191 PtrdiffT rw_bias = 0;
1194 Char* buildid = NULL;
1197 vg_assert(di->have_rx_map == True);
1198 vg_assert(di->have_rw_map == True);
1199 vg_assert(di->rx_map_size > 0);
1200 vg_assert(di->rw_map_size > 0);
1201 vg_assert(di->have_dinfo == False);
1202 vg_assert(di->filename);
1203 vg_assert(!di->memname);
1204 vg_assert(!di->symtab);
1205 vg_assert(!di->loctab);
1206 vg_assert(!di->cfsi);
1207 vg_assert(!di->cfsi_exprs);
1208 vg_assert(!di->strchunks);
1209 vg_assert(!di->soname);
1211 /* If these don't hold true, it means that m_syswrap/m_aspacemgr
1212 managed to do a mapping where the start isn't page aligned.
1213 Which sounds pretty bogus to me. */
1214 vg_assert(VG_IS_PAGE_ALIGNED(di->rx_map_avma));
1215 vg_assert(VG_IS_PAGE_ALIGNED(di->rw_map_avma));
1217 /* ----------------------------------------------------------
1218 At this point, there is very little information in the
1219 DebugInfo. We only know that something that looks like an ELF
1220 file has been mapped rx-ishly as recorded with the di->*rx_map*
1221 fields and has also been mapped rw-ishly as recorded with the
1222 di->*rw_map* fields. First we examine the file's ELF Program
1223 Header, and, by comparing that against the di->*r{w,x}_map*
1224 info, try to figure out the AVMAs for the sections we care
1225 about, that should have been mapped: text, data, sdata, bss got,
1227 ---------------------------------------------------------- */
1231 oimage = (Addr)NULL;
1232 if (VG_(clo_verbosity) > 1 || VG_(clo_trace_redir))
1233 VG_(message)(Vg_DebugMsg, "Reading syms from %s (%#lx)\n",
1234 di->filename, di->rx_map_avma );
1236 /* mmap the object image aboard, so that we can read symbols and
1237 line number info out of it. It will be munmapped immediately
1238 thereafter; it is only aboard transiently. */
1240 fd = VG_(open)(di->filename, VKI_O_RDONLY, 0);
1241 if (sr_isError(fd)) {
1242 ML_(symerr)(di, True, "Can't open .so/.exe to read symbols?!");
1246 { Long n_oimageLL = VG_(fsize)(sr_Res(fd));
1247 if (n_oimageLL <= 0) {
1248 ML_(symerr)(di, True, "Can't stat .so/.exe (to determine its size)?!");
1249 VG_(close)(sr_Res(fd));
1252 n_oimage = (UWord)(ULong)n_oimageLL;
1255 sres = VG_(am_mmap_file_float_valgrind)
1256 ( n_oimage, VKI_PROT_READ, sr_Res(fd), 0 );
1258 VG_(close)(sr_Res(fd));
1260 if (sr_isError(sres)) {
1261 VG_(message)(Vg_UserMsg, "warning: mmap failed on %s\n", di->filename );
1262 VG_(message)(Vg_UserMsg, " no symbols or debug info loaded\n" );
1266 oimage = sr_Res(sres);
1267 /* Check against wraparound. am_mmap_file_float_valgrind should
1268 not produce a wrapped-around mapping. */
1269 vg_assert(n_oimage > 0);
1270 vg_assert(oimage + n_oimage > oimage);
1273 VG_(printf)("read_elf_debug_info: OIMAGE = %p - %p\n",
1274 (void*)oimage, (void*)(oimage + (UWord)n_oimage));
1277 /* Ok, the object image is safely in oimage[0 .. n_oimage-1]. Now
1278 verify that it is a valid ELF .so or executable image. */
1280 ok = (n_oimage >= sizeof(ElfXX_Ehdr));
1281 ehdr_img = (ElfXX_Ehdr*)oimage;
1284 ok &= ML_(is_elf_object_file)(ehdr_img, n_oimage);
1287 ML_(symerr)(di, True, "Invalid ELF Header");
1291 /* Find where the program and section header tables are, and give
1292 up if either is missing or outside the image (bogus). */
1293 phdr_img = (ElfXX_Phdr*)( ((UChar*)ehdr_img) + ehdr_img->e_phoff );
1294 phdr_nent = ehdr_img->e_phnum;
1295 phdr_ent_szB = ehdr_img->e_phentsize;
1297 shdr_img = (ElfXX_Shdr*)( ((UChar*)ehdr_img) + ehdr_img->e_shoff );
1298 shdr_nent = ehdr_img->e_shnum;
1299 shdr_ent_szB = ehdr_img->e_shentsize;
1301 TRACE_SYMTAB("------ Basic facts about the object ------\n");
1302 TRACE_SYMTAB("object: img %p n_oimage %ld\n",
1303 (void*)oimage, n_oimage);
1304 TRACE_SYMTAB("phdr: img %p nent %ld ent_szB %ld\n",
1305 phdr_img, phdr_nent, phdr_ent_szB);
1306 TRACE_SYMTAB("shdr: img %p nent %ld ent_szB %ld\n",
1307 shdr_img, shdr_nent, shdr_ent_szB);
1310 || !contained_within(
1312 (Addr)phdr_img, phdr_nent * phdr_ent_szB)) {
1313 ML_(symerr)(di, True, "Missing or invalid ELF Program Header Table");
1318 || !contained_within(
1320 (Addr)shdr_img, shdr_nent * shdr_ent_szB)) {
1321 ML_(symerr)(di, True, "Missing or invalid ELF Section Header Table");
1325 /* Also find the section header's string table, and validate. */
1326 /* checked previously by is_elf_object_file: */
1327 vg_assert( ehdr_img->e_shstrndx != SHN_UNDEF );
1330 = (UChar*)( ((UChar*)ehdr_img)
1331 + shdr_img[ehdr_img->e_shstrndx].sh_offset);
1332 if (!contained_within( oimage, n_oimage,
1333 (Addr)shdr_strtab_img,
1334 1/*bogus, but we don't know the real size*/ )) {
1335 ML_(symerr)(di, True, "Invalid ELF Section Header String Table");
1339 TRACE_SYMTAB("shdr: string table at %p\n", shdr_strtab_img );
1341 /* Do another amazingly tedious thing: find out the .soname for
1342 this object. Apparently requires looking through the program
1345 TRACE_SYMTAB("------ Looking for the soname ------\n");
1346 vg_assert(di->soname == NULL);
1348 ElfXX_Addr prev_svma = 0;
1350 for (i = 0; i < phdr_nent; i++) {
1351 ElfXX_Phdr* phdr = INDEX_BIS( phdr_img, i, phdr_ent_szB );
1353 /* Make sure the PT_LOADable entries are in order */
1354 if (phdr->p_type == PT_LOAD) {
1355 TRACE_SYMTAB("PT_LOAD in order?: %#lx %#lx\n",
1357 phdr->p_vaddr + 0UL);
1358 if (phdr->p_vaddr < prev_svma) {
1359 ML_(symerr)(di, True,
1360 "ELF Program Headers are not in ascending order");
1363 prev_svma = phdr->p_vaddr;
1364 if (rx_svma_limit == 0
1365 && phdr->p_offset >= di->rx_map_foff
1366 && phdr->p_offset < di->rx_map_foff + di->rx_map_size
1367 && phdr->p_offset + phdr->p_filesz <= di->rx_map_foff + di->rx_map_size) {
1368 rx_svma_base = phdr->p_vaddr;
1369 rx_svma_limit = phdr->p_vaddr + phdr->p_memsz;
1370 rx_bias = di->rx_map_avma - di->rx_map_foff + phdr->p_offset - phdr->p_vaddr;
1372 else if (rw_svma_limit == 0
1373 && phdr->p_offset >= di->rw_map_foff
1374 && phdr->p_offset < di->rw_map_foff + di->rw_map_size
1375 && phdr->p_offset + phdr->p_filesz <= di->rw_map_foff + di->rw_map_size) {
1376 rw_svma_base = phdr->p_vaddr;
1377 rw_svma_limit = phdr->p_vaddr + phdr->p_memsz;
1378 rw_bias = di->rw_map_avma - di->rw_map_foff + phdr->p_offset - phdr->p_vaddr;
1382 /* Try to get the soname. If there isn't one, use "NONE".
1383 The seginfo needs to have some kind of soname in order to
1384 facilitate writing redirect functions, since all redirect
1385 specifications require a soname (pattern). */
1386 if (phdr->p_type == PT_DYNAMIC && di->soname == NULL) {
1387 ElfXX_Dyn* dyn_img = (ElfXX_Dyn*)( ((UChar*)ehdr_img)
1390 UChar* strtab = NULL;
1392 for (j = 0; dyn_img[j].d_tag != DT_NULL; j++) {
1393 switch (dyn_img[j].d_tag) {
1395 stroff = dyn_img[j].d_un.d_val;
1400 Word offset = file_offset_from_svma(
1402 dyn_img[j].d_un.d_ptr,
1404 phdr_nent, phdr_ent_szB
1406 if (ok2 && strtab == NULL) {
1407 vg_assert(offset >= 0 && offset <= n_oimage);
1408 strtab = ((UChar*)ehdr_img) + offset;
1416 if (stroff != -1 && strtab != NULL) {
1417 TRACE_SYMTAB("Found soname = %s\n", strtab+stroff);
1418 di->soname = ML_(dinfo_strdup)("di.redi.1", strtab+stroff);
1421 } /* for (i = 0; i < phdr_nent; i++) ... */
1422 } /* look for the soname */
1424 /* If, after looking at all the program headers, we still didn't
1425 find a soname, add a fake one. */
1426 if (di->soname == NULL) {
1427 TRACE_SYMTAB("No soname found; using (fake) \"NONE\"\n");
1428 di->soname = "NONE";
1431 vg_assert(rx_svma_limit != 0);
1432 vg_assert(rw_svma_limit != 0);
1434 /* Now read the section table. */
1436 TRACE_SYMTAB("------ Examining the section headers "
1437 "and program headers ------\n");
1438 TRACE_SYMTAB("rx: at %#lx are mapped foffsets %ld .. %ld\n",
1440 di->rx_map_foff, di->rx_map_foff + di->rx_map_size - 1 );
1441 TRACE_SYMTAB("rx: contains svmas %#lx .. %#lx with bias %#lx\n",
1442 rx_svma_base, rx_svma_limit - 1, rx_bias );
1443 TRACE_SYMTAB("rw: at %#lx are mapped foffsets %ld .. %ld\n",
1445 di->rw_map_foff, di->rw_map_foff + di->rw_map_size - 1 );
1446 TRACE_SYMTAB("rw: contains svmas %#lx .. %#lx with bias %#lx\n",
1447 rw_svma_base, rw_svma_limit - 1, rw_bias );
1449 for (i = 0; i < shdr_nent; i++) {
1450 ElfXX_Shdr* shdr = INDEX_BIS( shdr_img, i, shdr_ent_szB );
1451 UChar* name = shdr_strtab_img + shdr->sh_name;
1452 Addr svma = shdr->sh_addr;
1453 OffT foff = shdr->sh_offset;
1454 UWord size = shdr->sh_size;
1455 UInt alyn = shdr->sh_addralign;
1456 Bool bits = !(shdr->sh_type == SHT_NOBITS);
1457 Bool inrx = svma >= rx_svma_base && svma < rx_svma_limit;
1458 Bool inrw = svma >= rw_svma_base && svma < rw_svma_limit;
1460 TRACE_SYMTAB(" [sec %2ld] %s %s al%2u foff %6ld .. %6ld "
1461 " svma %p name \"%s\"\n",
1462 i, inrx ? "rx" : " ", inrw ? "rw" : " ", alyn,
1463 foff, foff+size-1, (void*)svma, name );
1465 /* Check for sane-sized segments. SHT_NOBITS sections have zero
1466 size in the file. */
1467 if ((foff >= n_oimage) || (foff + (bits ? size : 0) > n_oimage)) {
1468 ML_(symerr)(di, True, "ELF Section extends beyond image end");
1472 /* Check for a sane alignment value. */
1473 if (alyn > 0 && -1 == VG_(log2)(alyn)) {
1474 ML_(symerr)(di, True, "ELF Section contains invalid "
1475 ".sh_addralign value");
1479 # define BAD(_secname) \
1480 do { ML_(symerr)(di, True, \
1481 "Can't make sense of " _secname \
1482 " section mapping"); \
1486 /* Find avma-s for: .text .data .sdata .rodata .bss .sbss .plt .got .opd
1489 /* Accept .text where mapped as rx (code), even if zero-sized */
1490 if (0 == VG_(strcmp)(name, ".text")) {
1491 if (inrx && size >= 0 && !di->text_present) {
1492 di->text_present = True;
1493 di->text_svma = svma;
1494 di->text_avma = svma + rx_bias;
1495 di->text_size = size;
1496 di->text_bias = rx_bias;
1497 di->text_debug_svma = svma;
1498 di->text_debug_bias = rx_bias;
1499 TRACE_SYMTAB("acquiring .text svma = %#lx .. %#lx\n",
1501 di->text_svma + di->text_size - 1);
1502 TRACE_SYMTAB("acquiring .text avma = %#lx .. %#lx\n",
1504 di->text_avma + di->text_size - 1);
1505 TRACE_SYMTAB("acquiring .text bias = %#lx\n", di->text_bias);
1511 /* Accept .data where mapped as rw (data), even if zero-sized */
1512 if (0 == VG_(strcmp)(name, ".data")) {
1513 if (inrw && size >= 0 && !di->data_present) {
1514 di->data_present = True;
1515 di->data_svma = svma;
1516 di->data_avma = svma + rw_bias;
1517 di->data_size = size;
1518 di->data_bias = rw_bias;
1519 di->data_debug_svma = svma;
1520 di->data_debug_bias = rw_bias;
1521 TRACE_SYMTAB("acquiring .data svma = %#lx .. %#lx\n",
1523 di->data_svma + di->data_size - 1);
1524 TRACE_SYMTAB("acquiring .data avma = %#lx .. %#lx\n",
1526 di->data_avma + di->data_size - 1);
1527 TRACE_SYMTAB("acquiring .data bias = %#lx\n", di->data_bias);
1533 /* Accept .sdata where mapped as rw (data) */
1534 if (0 == VG_(strcmp)(name, ".sdata")) {
1535 if (inrw && size > 0 && !di->sdata_present) {
1536 di->sdata_present = True;
1537 di->sdata_svma = svma;
1538 di->sdata_avma = svma + rw_bias;
1539 di->sdata_size = size;
1540 di->sdata_bias = rw_bias;
1541 di->sdata_debug_svma = svma;
1542 di->sdata_debug_bias = rw_bias;
1543 TRACE_SYMTAB("acquiring .sdata svma = %#lx .. %#lx\n",
1545 di->sdata_svma + di->sdata_size - 1);
1546 TRACE_SYMTAB("acquiring .sdata avma = %#lx .. %#lx\n",
1548 di->sdata_avma + di->sdata_size - 1);
1549 TRACE_SYMTAB("acquiring .sdata bias = %#lx\n", di->sdata_bias);
1555 /* Accept .rodata where mapped as rx (data), even if zero-sized */
1556 if (0 == VG_(strcmp)(name, ".rodata")) {
1557 if (inrx && size >= 0 && !di->rodata_present) {
1558 di->rodata_present = True;
1559 di->rodata_svma = svma;
1560 di->rodata_avma = svma + rx_bias;
1561 di->rodata_size = size;
1562 di->rodata_bias = rx_bias;
1563 di->rodata_debug_svma = svma;
1564 di->rodata_debug_bias = rw_bias;
1565 TRACE_SYMTAB("acquiring .rodata svma = %#lx .. %#lx\n",
1567 di->rodata_svma + di->rodata_size - 1);
1568 TRACE_SYMTAB("acquiring .rodata avma = %#lx .. %#lx\n",
1570 di->rodata_avma + di->rodata_size - 1);
1571 TRACE_SYMTAB("acquiring .rodata bias = %#lx\n", di->rodata_bias);
1577 if (0 == VG_(strcmp)(name, ".dynbss")) {
1578 if (inrw && size > 0 && !di->bss_present) {
1579 dynbss_present = True;
1580 di->bss_present = True;
1581 di->bss_svma = svma;
1582 di->bss_avma = svma + rw_bias;
1583 di->bss_size = size;
1584 di->bss_bias = rw_bias;
1585 di->bss_debug_svma = svma;
1586 di->bss_debug_bias = rw_bias;
1587 TRACE_SYMTAB("acquiring .dynbss svma = %#lx .. %#lx\n",
1589 di->bss_svma + di->bss_size - 1);
1590 TRACE_SYMTAB("acquiring .dynbss avma = %#lx .. %#lx\n",
1592 di->bss_avma + di->bss_size - 1);
1593 TRACE_SYMTAB("acquiring .dynbss bias = %#lx\n", di->bss_bias);
1597 /* Accept .bss where mapped as rw (data), even if zero-sized */
1598 if (0 == VG_(strcmp)(name, ".bss")) {
1599 if (inrw && size > 0 && dynbss_present) {
1600 vg_assert(di->bss_present);
1601 dynbss_present = False;
1602 vg_assert(di->bss_svma + di->bss_size == svma);
1603 di->bss_size += size;
1604 TRACE_SYMTAB("acquiring .bss svma = %#lx .. %#lx\n",
1605 svma, svma + size - 1);
1606 TRACE_SYMTAB("acquiring .bss avma = %#lx .. %#lx\n",
1607 svma + rw_bias, svma + rw_bias + size - 1);
1608 TRACE_SYMTAB("acquiring .bss bias = %#lx\n", di->bss_bias);
1611 if (inrw && size >= 0 && !di->bss_present) {
1612 di->bss_present = True;
1613 di->bss_svma = svma;
1614 di->bss_avma = svma + rw_bias;
1615 di->bss_size = size;
1616 di->bss_bias = rw_bias;
1617 di->bss_debug_svma = svma;
1618 di->bss_debug_bias = rw_bias;
1619 TRACE_SYMTAB("acquiring .bss svma = %#lx .. %#lx\n",
1621 di->bss_svma + di->bss_size - 1);
1622 TRACE_SYMTAB("acquiring .bss avma = %#lx .. %#lx\n",
1624 di->bss_avma + di->bss_size - 1);
1625 TRACE_SYMTAB("acquiring .bss bias = %#lx\n", di->bss_bias);
1628 /* Now one from the wtf?! department ... */
1629 if (inrx && (!inrw) && size >= 0 && !di->bss_present) {
1630 /* File contains a .bss, but it got mapped as rx only.
1631 This is very strange. For now, just pretend we didn't
1633 di->bss_present = False;
1638 di->bss_debug_svma = 0;
1639 di->bss_debug_bias = 0;
1640 if (!VG_(clo_xml)) {
1641 VG_(message)(Vg_UserMsg,
1642 "Warning: the following file's .bss is "
1643 "mapped r-x only - ignoring .bss syms\n");
1644 VG_(message)(Vg_UserMsg, " %s\n", di->filename
1646 : (UChar*)"(null?!)" );
1650 if ((!inrw) && (!inrx) && size >= 0 && !di->bss_present) {
1651 /* File contains a .bss, but it didn't get mapped. Ignore. */
1652 di->bss_present = False;
1662 if (0 == VG_(strcmp)(name, ".sdynbss")) {
1663 if (inrw && size >= 0 && !di->sbss_present) {
1664 sdynbss_present = True;
1665 di->sbss_present = True;
1666 di->sbss_svma = svma;
1667 di->sbss_avma = svma + rw_bias;
1668 di->sbss_size = size;
1669 di->sbss_bias = rw_bias;
1670 di->sbss_debug_svma = svma;
1671 di->sbss_debug_bias = rw_bias;
1672 TRACE_SYMTAB("acquiring .sdynbss svma = %#lx .. %#lx\n",
1674 di->sbss_svma + di->sbss_size - 1);
1675 TRACE_SYMTAB("acquiring .sdynbss avma = %#lx .. %#lx\n",
1677 di->sbss_avma + di->sbss_size - 1);
1678 TRACE_SYMTAB("acquiring .sdynbss bias = %#lx\n", di->sbss_bias);
1682 /* Accept .sbss where mapped as rw (data) */
1683 if (0 == VG_(strcmp)(name, ".sbss")) {
1684 if (inrw && size > 0 && sdynbss_present) {
1685 vg_assert(di->sbss_present);
1686 sdynbss_present = False;
1687 vg_assert(di->sbss_svma + di->sbss_size == svma);
1688 di->sbss_size += size;
1689 TRACE_SYMTAB("acquiring .sbss svma = %#lx .. %#lx\n",
1690 svma, svma + size - 1);
1691 TRACE_SYMTAB("acquiring .sbss avma = %#lx .. %#lx\n",
1692 svma + rw_bias, svma + rw_bias + size - 1);
1693 TRACE_SYMTAB("acquiring .sbss bias = %#lx\n", di->sbss_bias);
1696 if (inrw && size > 0 && !di->sbss_present) {
1697 di->sbss_present = True;
1698 di->sbss_svma = svma;
1699 di->sbss_avma = svma + rw_bias;
1700 di->sbss_size = size;
1701 di->sbss_bias = rw_bias;
1702 di->sbss_debug_svma = svma;
1703 di->sbss_debug_bias = rw_bias;
1704 TRACE_SYMTAB("acquiring .sbss svma = %#lx .. %#lx\n",
1706 di->sbss_svma + di->sbss_size - 1);
1707 TRACE_SYMTAB("acquiring .sbss avma = %#lx .. %#lx\n",
1709 di->sbss_avma + di->sbss_size - 1);
1710 TRACE_SYMTAB("acquiring .sbss bias = %#lx\n", di->sbss_bias);
1716 /* Accept .got where mapped as rw (data) */
1717 if (0 == VG_(strcmp)(name, ".got")) {
1718 if (inrw && size > 0 && !di->got_present) {
1719 di->got_present = True;
1720 di->got_avma = svma + rw_bias;
1721 di->got_size = size;
1722 TRACE_SYMTAB("acquiring .got avma = %#lx\n", di->got_avma);
1728 /* Accept .got.plt where mapped as rw (data) */
1729 if (0 == VG_(strcmp)(name, ".got.plt")) {
1730 if (inrw && size > 0 && !di->gotplt_present) {
1731 di->gotplt_present = True;
1732 di->gotplt_avma = svma + rw_bias;
1733 di->gotplt_size = size;
1734 TRACE_SYMTAB("acquiring .got.plt avma = %#lx\n", di->gotplt_avma);
1735 } else if (size != 0) {
1740 /* PLT is different on different platforms, it seems. */
1741 # if defined(VGP_x86_linux) || defined(VGP_amd64_linux) \
1742 || defined(VGP_arm_linux) || defined(VGP_s390x_linux) \
1743 || defined(VGP_x86_l4re)
1744 /* Accept .plt where mapped as rx (code) */
1745 if (0 == VG_(strcmp)(name, ".plt")) {
1746 if (inrx && size > 0 && !di->plt_present) {
1747 di->plt_present = True;
1748 di->plt_avma = svma + rx_bias;
1749 di->plt_size = size;
1750 TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
1755 # elif defined(VGP_ppc32_linux)
1756 /* Accept .plt where mapped as rw (data) */
1757 if (0 == VG_(strcmp)(name, ".plt")) {
1758 if (inrw && size > 0 && !di->plt_present) {
1759 di->plt_present = True;
1760 di->plt_avma = svma + rw_bias;
1761 di->plt_size = size;
1762 TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
1767 # elif defined(VGP_ppc64_linux)
1768 /* Accept .plt where mapped as rw (data), or unmapped */
1769 if (0 == VG_(strcmp)(name, ".plt")) {
1770 if (inrw && size > 0 && !di->plt_present) {
1771 di->plt_present = True;
1772 di->plt_avma = svma + rw_bias;
1773 di->plt_size = size;
1774 TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
1776 if ((!inrw) && (!inrx) && size > 0 && !di->plt_present) {
1777 /* File contains a .plt, but it didn't get mapped.
1778 Presumably it is not required on this platform. At
1779 least don't reject the situation as invalid. */
1780 di->plt_present = True;
1788 # error "Unsupported platform"
1791 /* Accept .opd where mapped as rw (data) */
1792 if (0 == VG_(strcmp)(name, ".opd")) {
1793 if (inrw && size > 0 && !di->opd_present) {
1794 di->opd_present = True;
1795 di->opd_avma = svma + rw_bias;
1796 di->opd_size = size;
1797 TRACE_SYMTAB("acquiring .opd avma = %#lx\n", di->opd_avma);
1803 /* Accept .eh_frame where mapped as rx (code). This seems to be
1804 the common case. However, if that doesn't pan out, try for
1805 rw (data) instead. */
1806 if (0 == VG_(strcmp)(name, ".eh_frame")) {
1807 if (inrx && size > 0 && !di->ehframe_present) {
1808 di->ehframe_present = True;
1809 di->ehframe_avma = svma + rx_bias;
1810 di->ehframe_size = size;
1811 TRACE_SYMTAB("acquiring .eh_frame avma = %#lx\n", di->ehframe_avma);
1813 if (inrw && size > 0 && !di->ehframe_present) {
1814 di->ehframe_present = True;
1815 di->ehframe_avma = svma + rw_bias;
1816 di->ehframe_size = size;
1817 TRACE_SYMTAB("acquiring .eh_frame avma = %#lx\n", di->ehframe_avma);
1827 if (0) VG_(printf)("YYYY text_: avma %#lx size %ld bias %#lx\n",
1828 di->text_avma, di->text_size, di->text_bias);
1830 if (VG_(clo_verbosity) > 2 || VG_(clo_trace_redir))
1831 VG_(message)(Vg_DebugMsg, " svma %#010lx, avma %#010lx\n",
1832 di->text_avma - di->text_bias,
1836 TRACE_SYMTAB("------ Finding image addresses "
1837 "for debug-info sections ------\n");
1839 /* Find interesting sections, read the symbol table(s), read any debug
1842 /* IMAGE addresses: pointers to start of sections in the
1843 transiently loaded oimage, not in the fragments of the file
1844 mapped in by the guest's dynamic linker. */
1845 UChar* strtab_img = NULL; /* .strtab */
1846 ElfXX_Sym* symtab_img = NULL; /* .symtab */
1847 UChar* dynstr_img = NULL; /* .dynstr */
1848 ElfXX_Sym* dynsym_img = NULL; /* .dynsym */
1849 UChar* debuglink_img = NULL; /* .gnu_debuglink */
1850 UChar* stab_img = NULL; /* .stab (stabs) */
1851 UChar* stabstr_img = NULL; /* .stabstr (stabs) */
1852 UChar* debug_line_img = NULL; /* .debug_line (dwarf2) */
1853 UChar* debug_info_img = NULL; /* .debug_info (dwarf2) */
1854 UChar* debug_abbv_img = NULL; /* .debug_abbrev (dwarf2) */
1855 UChar* debug_str_img = NULL; /* .debug_str (dwarf2) */
1856 UChar* debug_ranges_img = NULL; /* .debug_ranges (dwarf2) */
1857 UChar* debug_loc_img = NULL; /* .debug_loc (dwarf2) */
1858 UChar* debug_frame_img = NULL; /* .debug_frame (dwarf2) */
1859 UChar* dwarf1d_img = NULL; /* .debug (dwarf1) */
1860 UChar* dwarf1l_img = NULL; /* .line (dwarf1) */
1861 UChar* ehframe_img = NULL; /* .eh_frame (dwarf2) */
1862 UChar* opd_img = NULL; /* .opd (dwarf2,
1864 /* Section sizes, in bytes */
1865 SizeT strtab_sz = 0;
1866 SizeT symtab_sz = 0;
1867 SizeT dynstr_sz = 0;
1868 SizeT dynsym_sz = 0;
1869 SizeT debuglink_sz = 0;
1871 SizeT stabstr_sz = 0;
1872 SizeT debug_line_sz = 0;
1873 SizeT debug_info_sz = 0;
1874 SizeT debug_abbv_sz = 0;
1875 SizeT debug_str_sz = 0;
1876 SizeT debug_ranges_sz = 0;
1877 SizeT debug_loc_sz = 0;
1878 SizeT debug_frame_sz = 0;
1879 SizeT dwarf1d_sz = 0;
1880 SizeT dwarf1l_sz = 0;
1881 SizeT ehframe_sz = 0;
1882 SizeT opd_sz_unused = 0;
1884 /* Find all interesting sections */
1886 /* What FIND does: it finds the section called SEC_NAME. The
1887 size of it is assigned to SEC_SIZE. The address of the
1888 section in the transiently loaded oimage is assigned to
1889 SEC_FILEA. Even for sections which are marked loadable, the
1890 client's ld.so may not have loaded them yet, so there is no
1891 guarantee that we can safely prod around in any such area).
1892 Because the entire object file is transiently mapped aboard
1893 for inspection, it's always safe to inspect that area. */
1895 for (i = 0; i < ehdr_img->e_shnum; i++) {
1897 # define FIND(sec_name, sec_size, sec_img) \
1898 do { ElfXX_Shdr* shdr \
1899 = INDEX_BIS( shdr_img, i, shdr_ent_szB ); \
1900 if (0 == VG_(strcmp)(sec_name, shdr_strtab_img \
1901 + shdr->sh_name)) { \
1903 sec_img = (void*)(oimage + shdr->sh_offset); \
1904 sec_size = shdr->sh_size; \
1905 nobits = shdr->sh_type == SHT_NOBITS; \
1906 TRACE_SYMTAB( "%18s: img %p .. %p\n", \
1907 sec_name, (UChar*)sec_img, \
1908 ((UChar*)sec_img) + sec_size - 1); \
1909 /* SHT_NOBITS sections have zero size in the file. */ \
1910 if ( shdr->sh_offset \
1911 + (nobits ? 0 : sec_size) > n_oimage ) { \
1912 ML_(symerr)(di, True, \
1913 " section beyond image end?!"); \
1919 /* NAME SIZE IMAGE addr */
1920 FIND(".dynsym", dynsym_sz, dynsym_img)
1921 FIND(".dynstr", dynstr_sz, dynstr_img)
1922 FIND(".symtab", symtab_sz, symtab_img)
1923 FIND(".strtab", strtab_sz, strtab_img)
1925 FIND(".gnu_debuglink", debuglink_sz, debuglink_img)
1927 FIND(".stab", stab_sz, stab_img)
1928 FIND(".stabstr", stabstr_sz, stabstr_img)
1930 FIND(".debug_line", debug_line_sz, debug_line_img)
1931 FIND(".debug_info", debug_info_sz, debug_info_img)
1932 FIND(".debug_abbrev", debug_abbv_sz, debug_abbv_img)
1933 FIND(".debug_str", debug_str_sz, debug_str_img)
1934 FIND(".debug_ranges", debug_ranges_sz, debug_ranges_img)
1935 FIND(".debug_loc", debug_loc_sz, debug_loc_img)
1936 FIND(".debug_frame", debug_frame_sz, debug_frame_img)
1938 FIND(".debug", dwarf1d_sz, dwarf1d_img)
1939 FIND(".line", dwarf1l_sz, dwarf1l_img)
1940 FIND(".eh_frame", ehframe_sz, ehframe_img)
1942 FIND(".opd", opd_sz_unused, opd_img)
1947 /* Look for a build-id */
1948 buildid = find_buildid(oimage, n_oimage);
1950 /* Look for a debug image */
1951 if (buildid != NULL || debuglink_img != NULL) {
1952 /* Do have a debuglink section? */
1953 if (debuglink_img != NULL) {
1954 UInt crc_offset = VG_ROUNDUP(VG_(strlen)(debuglink_img)+1, 4);
1957 vg_assert(crc_offset + sizeof(UInt) <= debuglink_sz);
1959 /* Extract the CRC from the debuglink section */
1960 crc = *(UInt *)(debuglink_img + crc_offset);
1962 /* See if we can find a matching debug file */
1963 dimage = find_debug_file( di, di->filename, buildid,
1964 debuglink_img, crc, &n_dimage );
1966 /* See if we can find a matching debug file */
1967 dimage = find_debug_file( di, di->filename, buildid, NULL, 0, &n_dimage );
1970 ML_(dinfo_free)(buildid);
1973 && n_dimage >= sizeof(ElfXX_Ehdr)
1974 && ML_(is_elf_object_file)((void*)dimage, n_dimage)) {
1976 /* Pull out and validate program header and section header info */
1977 ElfXX_Ehdr* ehdr_dimg = (ElfXX_Ehdr*)dimage;
1978 ElfXX_Phdr* phdr_dimg = (ElfXX_Phdr*)( ((UChar*)ehdr_dimg)
1979 + ehdr_dimg->e_phoff );
1980 UWord phdr_dnent = ehdr_dimg->e_phnum;
1981 UWord phdr_dent_szB = ehdr_dimg->e_phentsize;
1982 ElfXX_Shdr* shdr_dimg = (ElfXX_Shdr*)( ((UChar*)ehdr_dimg)
1983 + ehdr_dimg->e_shoff );
1984 UWord shdr_dnent = ehdr_dimg->e_shnum;
1985 UWord shdr_dent_szB = ehdr_dimg->e_shentsize;
1986 UChar* shdr_strtab_dimg = NULL;
1988 /* SVMAs covered by rx and rw segments and corresponding bias. */
1989 /* Addr rx_dsvma_base = 0; */ /* UNUSED */
1990 Addr rx_dsvma_limit = 0;
1991 PtrdiffT rx_dbias = 0;
1992 /* Addr rw_dsvma_base = 0; */ /* UNUSED */
1993 Addr rw_dsvma_limit = 0;
1994 PtrdiffT rw_dbias = 0;
1996 Bool need_symtab, need_stabs, need_dwarf2, need_dwarf1;
1999 || !contained_within(
2001 (Addr)phdr_dimg, phdr_dnent * phdr_dent_szB)) {
2002 ML_(symerr)(di, True,
2003 "Missing or invalid ELF Program Header Table"
2004 " (debuginfo file)");
2009 || !contained_within(
2011 (Addr)shdr_dimg, shdr_dnent * shdr_dent_szB)) {
2012 ML_(symerr)(di, True,
2013 "Missing or invalid ELF Section Header Table"
2014 " (debuginfo file)");
2018 /* Also find the section header's string table, and validate. */
2019 /* checked previously by is_elf_object_file: */
2020 vg_assert( ehdr_dimg->e_shstrndx != SHN_UNDEF );
2023 = (UChar*)( ((UChar*)ehdr_dimg)
2024 + shdr_dimg[ehdr_dimg->e_shstrndx].sh_offset);
2025 if (!contained_within(
2027 (Addr)shdr_strtab_dimg,
2028 1/*bogus, but we don't know the real size*/ )) {
2029 ML_(symerr)(di, True,
2030 "Invalid ELF Section Header String Table"
2031 " (debuginfo file)");
2035 need_symtab = (NULL == symtab_img);
2036 need_stabs = (NULL == stab_img);
2037 need_dwarf2 = (NULL == debug_info_img);
2038 need_dwarf1 = (NULL == dwarf1d_img);
2040 for (i = 0; i < ehdr_dimg->e_phnum; i++) {
2042 = INDEX_BIS( (void*)(dimage + ehdr_dimg->e_phoff),
2044 if (phdr->p_type == PT_LOAD) {
2045 if (rx_dsvma_limit == 0
2046 && phdr->p_offset >= di->rx_map_foff
2047 && phdr->p_offset < di->rx_map_foff + di->rx_map_size
2048 && phdr->p_offset + phdr->p_filesz <= di->rx_map_foff + di->rx_map_size) {
2049 /* rx_dsvma_base = phdr->p_vaddr; */ /* UNUSED */
2050 rx_dsvma_limit = phdr->p_vaddr + phdr->p_memsz;
2051 rx_dbias = di->rx_map_avma - di->rx_map_foff + phdr->p_offset - phdr->p_vaddr;
2054 if (rw_dsvma_limit == 0
2055 && phdr->p_offset >= di->rw_map_foff
2056 && phdr->p_offset < di->rw_map_foff + di->rw_map_size
2057 && phdr->p_offset + phdr->p_filesz <= di->rw_map_foff + di->rw_map_size) {
2058 /* rw_dsvma_base = phdr->p_vaddr; */ /* UNUSED */
2059 rw_dsvma_limit = phdr->p_vaddr + phdr->p_memsz;
2060 rw_dbias = di->rw_map_avma - di->rw_map_foff + phdr->p_offset - phdr->p_vaddr;
2065 /* Find all interesting sections */
2066 for (i = 0; i < ehdr_dimg->e_shnum; i++) {
2068 /* Find debug svma and bias information for sections
2069 we found in the main file. */
2071 # define FIND(sec, seg) \
2072 do { ElfXX_Shdr* shdr \
2073 = INDEX_BIS( shdr_dimg, i, shdr_dent_szB ); \
2074 if (di->sec##_present \
2075 && 0 == VG_(strcmp)("." #sec, \
2076 shdr_strtab_dimg + shdr->sh_name)) { \
2077 vg_assert(di->sec##_size == shdr->sh_size); \
2078 vg_assert(di->sec##_avma + shdr->sh_addr + seg##_dbias); \
2079 di->sec##_debug_svma = shdr->sh_addr; \
2080 di->sec##_debug_bias = seg##_dbias; \
2081 TRACE_SYMTAB("acquiring ." #sec " debug svma = %#lx .. %#lx\n", \
2082 di->sec##_debug_svma, \
2083 di->sec##_debug_svma + di->sec##_size - 1); \
2084 TRACE_SYMTAB("acquiring ." #sec " debug bias = %#lx\n", \
2085 di->sec##_debug_bias); \
2089 /* SECTION SEGMENT */
2099 /* Same deal as previous FIND, except only do it for those
2100 sections for which we didn't find anything useful in
2103 # define FIND(condition, sec_name, sec_size, sec_img) \
2104 do { ElfXX_Shdr* shdr \
2105 = INDEX_BIS( shdr_dimg, i, shdr_dent_szB ); \
2107 && 0 == VG_(strcmp)(sec_name, \
2108 shdr_strtab_dimg + shdr->sh_name)) { \
2111 VG_(core_panic)("repeated section!\n"); \
2112 sec_img = (void*)(dimage + shdr->sh_offset); \
2113 sec_size = shdr->sh_size; \
2114 nobits = shdr->sh_type == SHT_NOBITS; \
2115 TRACE_SYMTAB( "%18s: dimg %p .. %p\n", \
2118 ((UChar*)sec_img) + sec_size - 1); \
2119 /* SHT_NOBITS sections have zero size in the file. */ \
2120 if ( shdr->sh_offset \
2121 + (nobits ? 0 : sec_size) > n_dimage ) { \
2122 ML_(symerr)(di, True, \
2123 " section beyond image end?!"); \
2129 /* NEEDED? NAME SIZE IMAGE addr */
2130 FIND(need_symtab, ".symtab", symtab_sz, symtab_img)
2131 FIND(need_symtab, ".strtab", strtab_sz, strtab_img)
2132 FIND(need_stabs, ".stab", stab_sz, stab_img)
2133 FIND(need_stabs, ".stabstr", stabstr_sz, stabstr_img)
2134 FIND(need_dwarf2, ".debug_line", debug_line_sz, debug_line_img)
2135 FIND(need_dwarf2, ".debug_info", debug_info_sz, debug_info_img)
2136 FIND(need_dwarf2, ".debug_abbrev", debug_abbv_sz, debug_abbv_img)
2137 FIND(need_dwarf2, ".debug_str", debug_str_sz, debug_str_img)
2138 FIND(need_dwarf2, ".debug_ranges", debug_ranges_sz,
2140 FIND(need_dwarf2, ".debug_loc", debug_loc_sz, debug_loc_img)
2141 FIND(need_dwarf2, ".debug_frame", debug_frame_sz,
2143 FIND(need_dwarf1, ".debug", dwarf1d_sz, dwarf1d_img)
2144 FIND(need_dwarf1, ".line", dwarf1l_sz, dwarf1l_img)
2151 /* Check some sizes */
2152 vg_assert((dynsym_sz % sizeof(ElfXX_Sym)) == 0);
2153 vg_assert((symtab_sz % sizeof(ElfXX_Sym)) == 0);
2157 void (*read_elf_symtab)(struct _DebugInfo*,UChar*,
2161 Bool symtab_in_debug;
2162 # if defined(VGP_ppc64_linux)
2163 read_elf_symtab = read_elf_symtab__ppc64_linux;
2165 read_elf_symtab = read_elf_symtab__normal;
2167 symtab_in_debug = (Addr)symtab_img >= dimage
2168 && (Addr)symtab_img < dimage + n_dimage;
2169 read_elf_symtab(di, "symbol table",
2170 symtab_img, symtab_sz,
2171 strtab_img, strtab_sz,
2172 symtab_in_debug, opd_img);
2174 read_elf_symtab(di, "dynamic symbol table",
2175 dynsym_img, dynsym_sz,
2176 dynstr_img, dynstr_sz,
2180 /* Read .eh_frame and .debug_frame (call-frame-info) if any */
2182 vg_assert(ehframe_sz == di->ehframe_size);
2183 ML_(read_callframe_info_dwarf3)( di, ehframe_img, ehframe_sz, True );
2185 if (debug_frame_sz) {
2186 ML_(read_callframe_info_dwarf3)( di, debug_frame_img,
2187 debug_frame_sz, False );
2190 /* Read the stabs and/or dwarf2 debug information, if any. It
2191 appears reading stabs stuff on amd64-linux doesn't work, so
2192 we ignore it. On s390x stabs also doesnt work and we always
2193 have the dwarf info in the eh_frame. */
2194 # if !defined(VGP_amd64_linux) && !defined(VGP_s390x_linux)
2195 if (stab_img && stabstr_img) {
2196 ML_(read_debuginfo_stabs) ( di, stab_img, stab_sz,
2197 stabstr_img, stabstr_sz );
2200 /* jrs 2006-01-01: icc-8.1 has been observed to generate
2201 binaries without debug_str sections. Don't preclude
2202 debuginfo reading for that reason, but, in
2203 read_unitinfo_dwarf2, do check that debugstr is non-NULL
2205 if (debug_info_img && debug_abbv_img && debug_line_img
2206 /* && debug_str_img */) {
2208 /* The old reader: line numbers and unwind info only */
2209 ML_(read_debuginfo_dwarf3) ( di,
2210 debug_info_img, debug_info_sz,
2211 debug_abbv_img, debug_abbv_sz,
2212 debug_line_img, debug_line_sz,
2213 debug_str_img, debug_str_sz );
2215 /* The new reader: read the DIEs in .debug_info to acquire
2216 information on variable types and locations. But only if
2217 the tool asks for it, or the user requests it on the
2219 if (VG_(needs).var_info /* the tool requires it */
2220 || VG_(clo_read_var_info) /* the user asked for it */) {
2221 ML_(new_dwarf3_reader)(
2222 di, debug_info_img, debug_info_sz,
2223 debug_abbv_img, debug_abbv_sz,
2224 debug_line_img, debug_line_sz,
2225 debug_str_img, debug_str_sz,
2226 debug_ranges_img, debug_ranges_sz,
2227 debug_loc_img, debug_loc_sz
2231 if (dwarf1d_img && dwarf1l_img) {
2232 ML_(read_debuginfo_dwarf1) ( di, dwarf1d_img, dwarf1d_sz,
2233 dwarf1l_img, dwarf1l_sz );
2238 /* If reading Dwarf3 variable type/location info, print a line
2239 showing the number of variables read for each object.
2240 (Currently disabled -- is a sanity-check mechanism for
2242 if (0 && (VG_(needs).var_info || VG_(clo_read_var_info))) {
2246 for (j = 0; j < VG_(sizeXA)(di->varinfo); j++) {
2247 OSet* /* of DiAddrRange */ scope
2248 = *(OSet**)VG_(indexXA)(di->varinfo, j);
2250 VG_(OSetGen_ResetIter)( scope );
2252 DiAddrRange* range = VG_(OSetGen_Next)( scope );
2254 vg_assert(range->vars);
2255 Word w = VG_(sizeXA)(range->vars);
2257 if (0) VG_(printf)("range %#lx %#lx %ld\n",
2258 range->aMin, range->aMax, w);
2263 VG_(umsg)("VARINFO: %7lu vars %7ld text_size %s\n",
2264 nVars, di->text_size, di->filename);
2270 /* Last, but not least, heave the image(s) back overboard. */
2272 m_res = VG_(am_munmap_valgrind) ( dimage, n_dimage );
2273 vg_assert(!sr_isError(m_res));
2275 m_res = VG_(am_munmap_valgrind) ( oimage, n_oimage );
2276 vg_assert(!sr_isError(m_res));
2281 #endif // defined(VGO_linux)
2283 /*--------------------------------------------------------------------*/
2285 /*--------------------------------------------------------------------*/