drd/tests/Makefile.am: Fix indentation
[valgrind.git] / coregrind / m_debuginfo / readelf.c
blob40e546a8475fcc9a79a3b1ef5f0abd2968cae561
2 /*--------------------------------------------------------------------*/
3 /*--- Reading of syms & debug info from ELF .so/executable files. ---*/
4 /*--- readelf.c ---*/
5 /*--------------------------------------------------------------------*/
7 /*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
11 Copyright (C) 2000-2017 Julian Seward
12 jseward@acm.org
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, see <http://www.gnu.org/licenses/>.
27 The GNU General Public License is contained in the file COPYING.
30 #if defined(VGO_linux) || defined(VGO_solaris)
32 #include "pub_core_basics.h"
33 #include "pub_core_vki.h"
34 #include "pub_core_vkiscnums.h"
35 #include "pub_core_debuginfo.h"
36 #include "pub_core_libcbase.h"
37 #include "pub_core_libcprint.h"
38 #include "pub_core_libcassert.h"
39 #include "pub_core_machine.h" /* VG_ELF_CLASS */
40 #include "pub_core_options.h"
41 #include "pub_core_oset.h"
42 #include "pub_core_syscall.h"
43 #include "pub_core_tooliface.h" /* VG_(needs) */
44 #include "pub_core_xarray.h"
45 #include "priv_misc.h" /* dinfo_zalloc/free/strdup */
46 #include "priv_image.h"
47 #include "priv_d3basics.h"
48 #include "priv_tytypes.h"
49 #include "priv_storage.h"
50 #include "priv_readelf.h" /* self */
51 #include "priv_readdwarf.h" /* 'cos ELF contains DWARF */
52 #include "priv_readdwarf3.h"
53 #include "priv_readexidx.h"
54 #include "config.h"
56 /* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
57 #include <elf.h>
58 #if defined(VGO_solaris)
59 #include <sys/link.h> /* ElfXX_Dyn, DT_* */
60 #endif
61 /* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
63 #if !defined(HAVE_ELF32_CHDR)
64 typedef struct {
65 Elf32_Word ch_type;
66 Elf32_Word ch_size;
67 Elf32_Word ch_addralign;
68 } Elf32_Chdr;
69 #endif
71 #if !defined(HAVE_ELF64_CHDR)
72 typedef struct {
73 Elf64_Word ch_type;
74 Elf64_Word ch_reserved;
75 Elf64_Xword ch_size;
76 Elf64_Xword ch_addralign;
77 } Elf64_Chdr;
78 #endif
80 #if !defined(SHF_COMPRESSED)
81 #define SHF_COMPRESSED (1 << 11)
82 #endif
84 #if !defined(ELFCOMPRESS_ZLIB)
85 #define ELFCOMPRESS_ZLIB 1
86 #endif
88 #define SIZE_OF_ZLIB_HEADER 12
90 /*------------------------------------------------------------*/
91 /*--- 32/64-bit parameterisation ---*/
92 /*------------------------------------------------------------*/
94 /* For all the ELF macros and types which specify '32' or '64',
95 select the correct variant for this platform and give it
96 an 'XX' name. Then use the 'XX' variant consistently in
97 the rest of this file.
99 #if VG_WORDSIZE == 4
100 # define ElfXX_Ehdr Elf32_Ehdr
101 # define ElfXX_Shdr Elf32_Shdr
102 # define ElfXX_Phdr Elf32_Phdr
103 # define ElfXX_Nhdr Elf32_Nhdr
104 # define ElfXX_Sym Elf32_Sym
105 # define ElfXX_Off Elf32_Off
106 # define ElfXX_Word Elf32_Word
107 # define ElfXX_Addr Elf32_Addr
108 # define ElfXX_Dyn Elf32_Dyn
109 # define ELFXX_ST_BIND ELF32_ST_BIND
110 # define ELFXX_ST_TYPE ELF32_ST_TYPE
111 # define ElfXX_Chdr Elf32_Chdr
113 #elif VG_WORDSIZE == 8
114 # define ElfXX_Ehdr Elf64_Ehdr
115 # define ElfXX_Shdr Elf64_Shdr
116 # define ElfXX_Phdr Elf64_Phdr
117 # define ElfXX_Nhdr Elf64_Nhdr
118 # define ElfXX_Sym Elf64_Sym
119 # define ElfXX_Off Elf64_Off
120 # define ElfXX_Word Elf64_Word
121 # define ElfXX_Addr Elf64_Addr
122 # define ElfXX_Dyn Elf64_Dyn
123 # define ELFXX_ST_BIND ELF64_ST_BIND
124 # define ELFXX_ST_TYPE ELF64_ST_TYPE
125 # define ElfXX_Chdr Elf64_Chdr
127 #else
128 # error "VG_WORDSIZE should be 4 or 8"
129 #endif
132 /*------------------------------------------------------------*/
133 /*--- ---*/
134 /*--- Read symbol table and line info from ELF files. ---*/
135 /*--- ---*/
136 /*------------------------------------------------------------*/
138 /* readelf.c parses ELF files and acquires symbol table info from
139 them. It calls onwards to readdwarf.c to read DWARF2/3 line number
140 and call frame info found. */
142 /* Identify an ELF object file by peering at the first few bytes of
143 it. */
145 Bool ML_(is_elf_object_file)( const void* image, SizeT n_image, Bool rel_ok )
147 const ElfXX_Ehdr* ehdr = image;
148 Int ok = 1;
150 if (n_image < sizeof(ElfXX_Ehdr))
151 return False;
153 ok &= (ehdr->e_ident[EI_MAG0] == 0x7F
154 && ehdr->e_ident[EI_MAG1] == 'E'
155 && ehdr->e_ident[EI_MAG2] == 'L'
156 && ehdr->e_ident[EI_MAG3] == 'F');
157 ok &= (ehdr->e_ident[EI_CLASS] == VG_ELF_CLASS
158 && ehdr->e_ident[EI_DATA] == VG_ELF_DATA2XXX
159 && ehdr->e_ident[EI_VERSION] == EV_CURRENT);
160 ok &= (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN
161 || (rel_ok && ehdr->e_type == ET_REL));
162 ok &= (ehdr->e_machine == VG_ELF_MACHINE);
163 ok &= (ehdr->e_version == EV_CURRENT);
164 ok &= (ehdr->e_shstrndx != SHN_UNDEF);
165 ok &= (ehdr->e_shoff != 0 && ehdr->e_shnum != 0);
166 ok &= ((ehdr->e_phoff != 0 && ehdr->e_phnum != 0)
167 || ehdr->e_type == ET_REL);
169 return ok ? True : False;
173 /* The same thing, but operating on a DiImage instead. */
175 static Bool is_elf_object_file_by_DiImage( DiImage* img, Bool rel_ok )
177 /* Be sure this doesn't make the frame too big. */
178 vg_assert(sizeof(ElfXX_Ehdr) <= 512);
180 ElfXX_Ehdr ehdr;
181 if (!ML_(img_valid)(img, 0, sizeof(ehdr)))
182 return False;
184 ML_(img_get)(&ehdr, img, 0, sizeof(ehdr));
185 return ML_(is_elf_object_file)( &ehdr, sizeof(ehdr), rel_ok );
189 /* Show a raw ELF symbol, given its in-image address and name. */
191 static
192 void show_raw_elf_symbol ( DiImage* strtab_img,
193 Int i,
194 const ElfXX_Sym* sym,
195 DiOffT sym_name_ioff, Addr sym_svma,
196 Bool ppc64_linux_format )
198 const HChar* space = ppc64_linux_format ? " " : "";
199 VG_(printf)("raw symbol [%4d]: ", i);
200 switch (ELFXX_ST_BIND(sym->st_info)) {
201 case STB_LOCAL: VG_(printf)("LOC "); break;
202 case STB_GLOBAL: VG_(printf)("GLO "); break;
203 case STB_WEAK: VG_(printf)("WEA "); break;
204 case STB_LOPROC: VG_(printf)("lop "); break;
205 case STB_HIPROC: VG_(printf)("hip "); break;
206 default: VG_(printf)("??? "); break;
208 switch (ELFXX_ST_TYPE(sym->st_info)) {
209 case STT_NOTYPE: VG_(printf)("NOT "); break;
210 case STT_OBJECT: VG_(printf)("OBJ "); break;
211 case STT_FUNC: VG_(printf)("FUN "); break;
212 case STT_SECTION: VG_(printf)("SEC "); break;
213 case STT_FILE: VG_(printf)("FIL "); break;
214 case STT_LOPROC: VG_(printf)("lop "); break;
215 case STT_HIPROC: VG_(printf)("hip "); break;
216 default: VG_(printf)("??? "); break;
218 HChar* sym_name = NULL;
219 if (sym->st_name)
220 sym_name = ML_(img_strdup)(strtab_img, "di.sres.1", sym_name_ioff);
221 VG_(printf)(": svma %#010lx, %ssz %4llu %s\n",
222 sym_svma, space, (ULong)(sym->st_size + 0UL),
223 (sym_name ? sym_name : "NONAME") );
224 if (sym_name)
225 ML_(dinfo_free)(sym_name);
229 /* Decide whether SYM is something we should collect, and if so, copy
230 relevant info to the _OUT arguments. For {x86,amd64,ppc32}-linux
231 this is straightforward - the name, address, size are copied out
232 unchanged.
234 There is a bit of a kludge re data symbols (see KLUDGED BSS CHECK
235 below): we assume that the .bss is mapped immediately after .data,
236 and so accept any data symbol which exists in the range [start of
237 .data, size of .data + size of .bss). I don't know if this is
238 really correct/justifiable, or not.
240 For ppc64be-linux it's more complex. If the symbol is seen to be in
241 the .opd section, it is taken to be a function descriptor, and so
242 a dereference is attempted, in order to get hold of the real entry
243 point address. Also as part of the dereference, there is an attempt
244 to calculate the TOC pointer (R2 value) associated with the symbol.
246 To support the ppc64be-linux pre-"dotless" ABI (prior to gcc 4.0.0),
247 if the symbol is seen to be outside the .opd section and its name
248 starts with a dot, an .opd deference is not attempted, and no TOC
249 pointer is calculated, but the leading dot is removed from the
250 name.
252 As a result, on ppc64be-linux, the caller of this function may have
253 to piece together the real size, address, name of the symbol from
254 multiple calls to this function. Ugly and confusing.
256 static
257 Bool get_elf_symbol_info (
258 /* INPUTS */
259 struct _DebugInfo* di, /* containing DebugInfo */
260 const ElfXX_Sym* sym, /* ELF symbol */
261 DiOffT sym_name_ioff, /* name, may be absent (DiOffT_INVALID) */
262 const DiSlice* escn_strtab, /* holds the name */
263 Addr sym_svma, /* address as stated in the object file */
264 Bool symtab_in_debug, /* symbol table is in the debug file */
265 const DiSlice* escn_opd, /* the .opd (ppc64be-linux only) */
266 PtrdiffT opd_bias, /* for biasing AVMAs found in .opd */
267 /* OUTPUTS */
268 DiOffT* sym_name_out_ioff, /* name (in strtab) we should record */
269 SymAVMAs* sym_avmas_out, /* sym avmas we should record */
270 Int* sym_size_out, /* symbol size */
271 Bool* from_opd_out, /* ppc64be-linux only: did we deref an
272 .opd entry? */
273 Bool* is_text_out, /* is this a text symbol? */
274 Bool* is_ifunc_out, /* is this a STT_GNU_IFUNC function ?*/
275 Bool* is_global_out /* is this a global symbol ?*/
278 Bool plausible;
279 # if defined(VGP_ppc64be_linux)
280 Bool is_in_opd;
281 # endif
282 Bool in_text, in_data, in_sdata, in_rodata, in_bss, in_sbss;
283 Addr text_svma, data_svma, sdata_svma, rodata_svma, bss_svma, sbss_svma;
284 PtrdiffT text_bias, data_bias, sdata_bias, rodata_bias, bss_bias, sbss_bias;
285 # if defined(VGPV_arm_linux_android) \
286 || defined(VGPV_x86_linux_android) \
287 || defined(VGPV_mips32_linux_android) \
288 || defined(VGPV_arm64_linux_android)
289 Addr available_size = 0;
290 #define COMPUTE_AVAILABLE_SIZE(segsvma, segsize) \
291 available_size = segsvma + segsize - sym_svma
292 #else
293 #define COMPUTE_AVAILABLE_SIZE(segsvma, segsize)
294 #endif
296 /* Set defaults */
297 *sym_name_out_ioff = sym_name_ioff;
298 (*sym_avmas_out).main = sym_svma; /* we will bias this shortly */
299 *is_text_out = True;
300 SET_TOCPTR_AVMA(*sym_avmas_out, 0); /* default to unknown/inapplicable */
301 SET_LOCAL_EP_AVMA(*sym_avmas_out, 0); /* default to unknown/inapplicable */
302 *from_opd_out = False;
303 *is_ifunc_out = False;
304 *is_global_out = False;
306 /* Get the symbol size, but restrict it to fit in a signed 32 bit
307 int. Also, deal with the stupid case of negative size by making
308 the size be 1. Note that sym->st_size has type UWord,
309 effectively. */
310 { Word size_tmp = (Word)sym->st_size;
311 Word max_Int = (1LL << 31) - 1;
312 if (size_tmp < 0) size_tmp = 1;
313 if (size_tmp > max_Int) size_tmp = max_Int;
314 *sym_size_out = (Int)size_tmp;
316 /* After this point refer only to *sym_size_out and not to
317 sym->st_size. */
319 /* Figure out if we're interested in the symbol. Firstly, is it of
320 the right flavour? */
321 plausible
322 = (ELFXX_ST_BIND(sym->st_info) == STB_GLOBAL
323 || ELFXX_ST_BIND(sym->st_info) == STB_LOCAL
324 || ELFXX_ST_BIND(sym->st_info) == STB_WEAK
327 (ELFXX_ST_TYPE(sym->st_info) == STT_FUNC
328 || ELFXX_ST_TYPE(sym->st_info) == STT_OBJECT
329 # ifdef STT_GNU_IFUNC
330 || ELFXX_ST_TYPE(sym->st_info) == STT_GNU_IFUNC
331 # endif
334 /* Work out the svma and bias for each section as it will appear in
335 addresses in the symbol table. */
336 if (symtab_in_debug) {
337 text_svma = di->text_debug_svma;
338 text_bias = di->text_debug_bias;
339 data_svma = di->data_debug_svma;
340 data_bias = di->data_debug_bias;
341 sdata_svma = di->sdata_debug_svma;
342 sdata_bias = di->sdata_debug_bias;
343 rodata_svma = di->rodata_debug_svma;
344 rodata_bias = di->rodata_debug_bias;
345 bss_svma = di->bss_debug_svma;
346 bss_bias = di->bss_debug_bias;
347 sbss_svma = di->sbss_debug_svma;
348 sbss_bias = di->sbss_debug_bias;
349 } else {
350 text_svma = di->text_svma;
351 text_bias = di->text_bias;
352 data_svma = di->data_svma;
353 data_bias = di->data_bias;
354 sdata_svma = di->sdata_svma;
355 sdata_bias = di->sdata_bias;
356 rodata_svma = di->rodata_svma;
357 rodata_bias = di->rodata_bias;
358 bss_svma = di->bss_svma;
359 bss_bias = di->bss_bias;
360 sbss_svma = di->sbss_svma;
361 sbss_bias = di->sbss_bias;
364 /* Now bias (*sym_avmas_out).main accordingly by figuring out exactly which
365 section the symbol is from and bias accordingly. Screws up if
366 the previously deduced section svma address ranges are wrong. */
367 if (di->text_present
368 && di->text_size > 0
369 && sym_svma >= text_svma
370 && sym_svma < text_svma + di->text_size) {
371 *is_text_out = True;
372 (*sym_avmas_out).main += text_bias;
373 COMPUTE_AVAILABLE_SIZE(text_svma, di->text_size);
374 } else
375 if (di->data_present
376 && di->data_size > 0
377 && sym_svma >= data_svma
378 && sym_svma < data_svma + di->data_size) {
379 *is_text_out = False;
380 (*sym_avmas_out).main += data_bias;
381 COMPUTE_AVAILABLE_SIZE(data_svma, di->data_size);
382 } else
383 if (di->sdata_present
384 && di->sdata_size > 0
385 && sym_svma >= sdata_svma
386 && sym_svma < sdata_svma + di->sdata_size) {
387 *is_text_out = False;
388 (*sym_avmas_out).main += sdata_bias;
389 COMPUTE_AVAILABLE_SIZE(sdata_svma, di->sdata_size);
390 } else
391 if (di->rodata_present
392 && di->rodata_size > 0
393 && sym_svma >= rodata_svma
394 && sym_svma < rodata_svma + di->rodata_size) {
395 *is_text_out = False;
396 (*sym_avmas_out).main += rodata_bias;
397 COMPUTE_AVAILABLE_SIZE(rodata_svma, di->rodata_size);
398 } else
399 if (di->bss_present
400 && di->bss_size > 0
401 && sym_svma >= bss_svma
402 && sym_svma < bss_svma + di->bss_size) {
403 *is_text_out = False;
404 (*sym_avmas_out).main += bss_bias;
405 COMPUTE_AVAILABLE_SIZE(bss_svma, di->bss_size);
406 } else
407 if (di->sbss_present
408 && di->sbss_size > 0
409 && sym_svma >= sbss_svma
410 && sym_svma < sbss_svma + di->sbss_size) {
411 *is_text_out = False;
412 (*sym_avmas_out).main += sbss_bias;
413 COMPUTE_AVAILABLE_SIZE(sbss_svma, di->sbss_size);
414 } else {
415 /* Assume it's in .text. Is this a good idea? */
416 *is_text_out = True;
417 (*sym_avmas_out).main += text_bias;
420 # ifdef STT_GNU_IFUNC
421 /* Check for indirect functions. */
422 if (*is_text_out
423 && ELFXX_ST_TYPE(sym->st_info) == STT_GNU_IFUNC) {
424 *is_ifunc_out = True;
426 # endif
428 if (ELFXX_ST_BIND(sym->st_info) == STB_GLOBAL) {
429 *is_global_out = True;
432 # if defined(VGP_ppc64be_linux)
433 /* Allow STT_NOTYPE in the very special case where we're running on
434 ppc64be-linux and the symbol is one which the .opd-chasing hack
435 below will chase. */
436 if (!plausible
437 && *is_text_out
438 && ELFXX_ST_TYPE(sym->st_info) == STT_NOTYPE
439 && *sym_size_out > 0
440 && di->opd_present
441 && di->opd_size > 0
442 && (*sym_avmas_out).main >= di->opd_avma
443 && (*sym_avmas_out).main < di->opd_avma + di->opd_size)
444 plausible = True;
445 # endif
447 if (!plausible)
448 return False;
450 /* Ignore if nameless. */
451 if (sym_name_ioff == DiOffT_INVALID
452 || /* VG_(strlen)(sym_name) == 0 */
453 /* equivalent but cheaper ... */
454 ML_(img_get_UChar)(escn_strtab->img, sym_name_ioff) == '\0') {
455 if (TRACE_SYMTAB_ENABLED) {
456 HChar* sym_name = ML_(img_strdup)(escn_strtab->img,
457 "di.gesi.1", sym_name_ioff);
458 TRACE_SYMTAB(" ignore -- nameless: %s\n", sym_name);
459 if (sym_name) ML_(dinfo_free)(sym_name);
461 return False;
464 /* Ignore if zero-sized. Except on Android:
466 On Android 2.3.5, some of the symbols that Memcheck needs to
467 intercept (for noise reduction purposes) have zero size, due to
468 lack of .size directives in handwritten assembly sources. So we
469 can't reject them out of hand -- instead give them a bogusly
470 large size and let canonicaliseSymtab trim them so they don't
471 overlap any following symbols. At least the following symbols
472 are known to be affected:
474 in /system/lib/libc.so: strlen strcmp strcpy memcmp memcpy
475 in /system/bin/linker: __dl_strcmp __dl_strlen
477 if (*sym_size_out == 0) {
478 # if defined(VGPV_arm_linux_android) \
479 || defined(VGPV_x86_linux_android) \
480 || defined(VGPV_mips32_linux_android) \
481 || defined(VGPV_arm64_linux_android)
482 *sym_size_out = available_size ? available_size : 2048;
483 # else
484 if (TRACE_SYMTAB_ENABLED) {
485 HChar* sym_name = ML_(img_strdup)(escn_strtab->img,
486 "di.gesi.2", sym_name_ioff);
487 TRACE_SYMTAB(" ignore -- size=0: %s\n", sym_name);
488 if (sym_name) ML_(dinfo_free)(sym_name);
490 return False;
491 # endif
494 /* This seems to significantly reduce the number of junk
495 symbols, and particularly reduces the number of
496 overlapping address ranges. Don't ask me why ... */
497 if ((Int)sym->st_value == 0) {
498 if (TRACE_SYMTAB_ENABLED) {
499 HChar* sym_name = ML_(img_strdup)(escn_strtab->img,
500 "di.gesi.3", sym_name_ioff);
501 TRACE_SYMTAB( " ignore -- valu=0: %s\n", sym_name);
502 if (sym_name) ML_(dinfo_free)(sym_name);
504 return False;
507 /* If it's apparently in a GOT or PLT, it's really a reference to a
508 symbol defined elsewhere, so ignore it. */
509 if (di->got_present
510 && di->got_size > 0
511 && (*sym_avmas_out).main >= di->got_avma
512 && (*sym_avmas_out).main < di->got_avma + di->got_size) {
513 if (TRACE_SYMTAB_ENABLED) {
514 HChar* sym_name = ML_(img_strdup)(escn_strtab->img,
515 "di.gesi.4", sym_name_ioff);
516 TRACE_SYMTAB(" ignore -- in GOT: %s\n", sym_name);
517 if (sym_name) ML_(dinfo_free)(sym_name);
519 return False;
521 if (di->plt_present
522 && di->plt_size > 0
523 && (*sym_avmas_out).main >= di->plt_avma
524 && (*sym_avmas_out).main < di->plt_avma + di->plt_size) {
525 if (TRACE_SYMTAB_ENABLED) {
526 HChar* sym_name = ML_(img_strdup)(escn_strtab->img,
527 "di.gesi.5", sym_name_ioff);
528 TRACE_SYMTAB(" ignore -- in PLT: %s\n", sym_name);
529 if (sym_name) ML_(dinfo_free)(sym_name);
531 return False;
534 /* ppc64be-linux nasty hack: if the symbol is in an .opd section,
535 then really what we have is the address of a function
536 descriptor. So use the first word of that as the function's
537 text.
539 See thread starting at
540 http://gcc.gnu.org/ml/gcc-patches/2004-08/msg00557.html
542 # if defined(VGP_ppc64be_linux)
543 /* Host and guest may have different Endianness, used by BE only */
544 is_in_opd = False;
545 # endif
547 if (di->opd_present
548 && di->opd_size > 0
549 && (*sym_avmas_out).main >= di->opd_avma
550 && (*sym_avmas_out).main < di->opd_avma + di->opd_size) {
551 # if !defined(VGP_ppc64be_linux)
552 if (TRACE_SYMTAB_ENABLED) {
553 HChar* sym_name = ML_(img_strdup)(escn_strtab->img,
554 "di.gesi.6", sym_name_ioff);
555 TRACE_SYMTAB(" ignore -- in OPD: %s\n", sym_name);
556 if (sym_name) ML_(dinfo_free)(sym_name);
558 return False;
559 # else
560 Int offset_in_opd;
561 Bool details = 1||False;
563 if (details)
564 TRACE_SYMTAB("opdXXX: opd_bias %p, sym_svma_out %p\n",
565 (void*)(opd_bias), (void*)(*sym_avmas_out).main);
567 if (!VG_IS_8_ALIGNED((*sym_avmas_out).main)) {
568 if (TRACE_SYMTAB_ENABLED) {
569 HChar* sym_name = ML_(img_strdup)(escn_strtab->img,
570 "di.gesi.6a", sym_name_ioff);
571 TRACE_SYMTAB(" ignore -- not 8-aligned: %s\n", sym_name);
572 if (sym_name) ML_(dinfo_free)(sym_name);
574 return False;
577 /* (*sym_avmas_out).main is a avma pointing into the .opd section. We
578 know the vma of the opd section start, so we can figure out
579 how far into the opd section this is. */
581 offset_in_opd = (Addr)(*sym_avmas_out).main - (Addr)(di->opd_avma);
582 if (offset_in_opd < 0 || offset_in_opd >= di->opd_size) {
583 if (TRACE_SYMTAB_ENABLED) {
584 HChar* sym_name = ML_(img_strdup)(escn_strtab->img,
585 "di.gesi.6a", sym_name_ioff);
586 TRACE_SYMTAB(" ignore -- invalid OPD offset: %s\n", sym_name);
587 if (sym_name) ML_(dinfo_free)(sym_name);
589 return False;
592 /* Now we want to know what's at that offset in the .opd
593 section. We can't look in the running image since it won't
594 necessarily have been mapped. But we can consult the oimage.
595 opd_img is the start address of the .opd in the oimage.
596 Hence: */
598 ULong fn_descr[2]; /* is actually 3 words, but we need only 2 */
599 if (!ML_(img_valid)(escn_opd->img, escn_opd->ioff + offset_in_opd,
600 sizeof(fn_descr))) {
601 if (TRACE_SYMTAB_ENABLED) {
602 HChar* sym_name = ML_(img_strdup)(escn_strtab->img,
603 "di.gesi.6b", sym_name_ioff);
604 TRACE_SYMTAB(" ignore -- invalid OPD fn_descr offset: %s\n",
605 sym_name);
606 if (sym_name) ML_(dinfo_free)(sym_name);
609 return False;
612 /* This can't fail now, because we just checked the offset
613 above. */
614 ML_(img_get)(&fn_descr[0], escn_opd->img,
615 escn_opd->ioff + offset_in_opd, sizeof(fn_descr));
617 if (details)
618 TRACE_SYMTAB("opdXXY: offset %d, fn_descr %p\n",
619 offset_in_opd, fn_descr);
620 if (details)
621 TRACE_SYMTAB("opdXXZ: *fn_descr %p\n", (void*)(fn_descr[0]));
623 /* opd_bias is the what we have to add to SVMAs found in .opd to
624 get plausible .text AVMAs for the entry point, and .data
625 AVMAs (presumably) for the TOC locations. We use the caller
626 supplied value (which is di->text_bias) for both of these.
627 Not sure why that is correct - it seems to work, and sounds
628 OK for fn_descr[0], but surely we need to use the data bias
629 and not the text bias for fn_descr[1] ? Oh Well.
631 (*sym_avmas_out).main = fn_descr[0] + opd_bias;
632 SET_TOCPTR_AVMA(*sym_avmas_out, fn_descr[1] + opd_bias);
633 *from_opd_out = True;
634 is_in_opd = True;
636 /* Do a final sanity check: if the symbol falls outside the
637 DebugInfo's mapped range, ignore it. Since (*sym_avmas_out).main has
638 been updated, that can be achieved simply by falling through
639 to the test below. */
641 # endif /* ppc64-linux nasty hack */
644 /* Here's yet another ppc64-linux hack. Get rid of leading dot if
645 the symbol is outside .opd. */
646 # if defined(VGP_ppc64be_linux)
647 if (di->opd_size > 0
648 && !is_in_opd
649 && *sym_name_out_ioff != DiOffT_INVALID
650 && ML_(img_get_UChar)(escn_strtab->img, *sym_name_out_ioff) == '.') {
651 vg_assert(!(*from_opd_out));
652 (*sym_name_out_ioff)++;
654 # endif
656 /* If no part of the symbol falls within the mapped range,
657 ignore it. */
659 in_text
660 = di->text_present
661 && di->text_size > 0
662 && !((*sym_avmas_out).main + *sym_size_out <= di->text_avma
663 || (*sym_avmas_out).main >= di->text_avma + di->text_size);
665 in_data
666 = di->data_present
667 && di->data_size > 0
668 && !((*sym_avmas_out).main + *sym_size_out <= di->data_avma
669 || (*sym_avmas_out).main >= di->data_avma + di->data_size);
671 in_sdata
672 = di->sdata_present
673 && di->sdata_size > 0
674 && !((*sym_avmas_out).main + *sym_size_out <= di->sdata_avma
675 || (*sym_avmas_out).main >= di->sdata_avma + di->sdata_size);
677 in_rodata
678 = di->rodata_present
679 && di->rodata_size > 0
680 && !((*sym_avmas_out).main + *sym_size_out <= di->rodata_avma
681 || (*sym_avmas_out).main >= di->rodata_avma + di->rodata_size);
683 in_bss
684 = di->bss_present
685 && di->bss_size > 0
686 && !((*sym_avmas_out).main + *sym_size_out <= di->bss_avma
687 || (*sym_avmas_out).main >= di->bss_avma + di->bss_size);
689 in_sbss
690 = di->sbss_present
691 && di->sbss_size > 0
692 && !((*sym_avmas_out).main + *sym_size_out <= di->sbss_avma
693 || (*sym_avmas_out).main >= di->sbss_avma + di->sbss_size);
696 if (*is_text_out) {
697 /* This used to reject any symbol falling outside the text
698 segment ("if (!in_text) ..."). Now it is relaxed slightly,
699 to reject only symbols which fall outside the area mapped
700 r-x. This is in accordance with r7427. See
701 "Comment_Regarding_Text_Range_Checks" in storage.c for
702 background. */
703 Bool in_rx;
704 vg_assert(di->fsm.have_rx_map);
705 /* This could actually wrap around and cause
706 ML_(find_rx_mapping) to assert. But that seems so unlikely,
707 let's wait for it to happen before fixing it. */
708 in_rx = (ML_(find_rx_mapping)(
710 (*sym_avmas_out).main,
711 (*sym_avmas_out).main + *sym_size_out - 1) != NULL);
712 if (in_text)
713 vg_assert(in_rx);
714 if (!in_rx) {
715 TRACE_SYMTAB(
716 "ignore -- %#lx .. %#lx outside .text svma range %#lx .. %#lx\n",
717 (*sym_avmas_out).main, (*sym_avmas_out).main + *sym_size_out - 1,
718 di->text_avma,
719 di->text_avma + di->text_size - 1);
720 return False;
722 } else {
723 if (!(in_data || in_sdata || in_rodata || in_bss || in_sbss)) {
724 TRACE_SYMTAB(
725 "ignore -- %#lx .. %#lx outside .data / .sdata / .rodata "
726 "/ .bss / .sbss svma ranges\n",
727 (*sym_avmas_out).main, (*sym_avmas_out).main + *sym_size_out - 1);
728 return False;
732 # if defined(VGP_ppc64be_linux)
733 if (di->opd_present && di->opd_size > 0) {
734 vg_assert((*sym_avmas_out).main + *sym_size_out <= di->opd_avma
735 || (*sym_avmas_out).main >= di->opd_avma + di->opd_size);
737 #endif
739 # if defined(VGP_ppc64le_linux)
740 /* PPC64 LE ABI uses three bits in the st_other field to indicate the number
741 * of instructions between the function's global and local entry points. An
742 * offset of 0 indicates that there is one entry point. The value must be:
744 * 0 - one entry point, local and global are the same
745 * 1 - reserved
746 * 2 - local entry point is one instruction after the global entry point
747 * 3 - local entry point is two instructions after the global entry point
748 * 4 - local entry point is four instructions after the global entry point
749 * 5 - local entry point is eight instructions after the global entry point
750 * 6 - local entry point is sixteen instructions after the global entry point
751 * 7 - reserved
753 * Extract the three bit field from the other field is done by:
754 * (other_field & STO_PPC64_LOCAL_MASK) >> STO_PPC_LOCAL_BIT
756 * where the #define values are given in include/elf/powerpc.h file for
757 * the PPC binutils.
759 * conversion of the three bit field to bytes is given by
761 * ((1 << bit_field) >> 2) << 2
764 #define STO_PPC64_LOCAL_BIT 5
765 #define STO_PPC64_LOCAL_MASK (7 << STO_PPC64_LOCAL_BIT)
767 unsigned int bit_field, dist_to_local_entry;
768 /* extract the other filed */
769 bit_field = (sym->st_other & STO_PPC64_LOCAL_MASK) >> STO_PPC64_LOCAL_BIT;
771 if ((bit_field > 0) && (bit_field < 7)) {
772 /* store the local entry point address */
773 dist_to_local_entry = ((1 << bit_field) >> 2) << 2;
774 SET_LOCAL_EP_AVMA(*sym_avmas_out,
775 (*sym_avmas_out).main + dist_to_local_entry);
777 if (TRACE_SYMTAB_ENABLED) {
778 HChar* sym_name = ML_(img_strdup)(escn_strtab->img,
779 "di.gesi.5", sym_name_ioff);
780 VG_(printf)("Local entry point: %s at %#010x\n",
781 sym_name,
782 (unsigned int)GET_LOCAL_EP_AVMA(*sym_avmas_out));
786 # endif
788 /* Acquire! */
789 return True;
793 /* Read an ELF symbol table (normal or dynamic). This one is for the
794 "normal" case ({x86,amd64,ppc32,arm,mips32,mips64, ppc64le}-linux). */
795 static
796 __attribute__((unused)) /* not referred to on all targets */
797 void read_elf_symtab__normal(
798 struct _DebugInfo* di, const HChar* tab_name,
799 DiSlice* escn_symtab,
800 DiSlice* escn_strtab,
801 DiSlice* escn_opd, /* ppc64be-linux only */
802 Bool symtab_in_debug
805 if (escn_strtab->img == NULL || escn_symtab->img == NULL) {
806 HChar buf[VG_(strlen)(tab_name) + 40];
807 VG_(sprintf)(buf, " object doesn't have a %s", tab_name);
808 ML_(symerr)(di, False, buf);
809 return;
812 TRACE_SYMTAB("\n--- Reading (ELF, standard) %s (%llu entries) ---\n",
813 tab_name, escn_symtab->szB/sizeof(ElfXX_Sym) );
815 /* Perhaps should start at i = 1; ELF docs suggest that entry
816 0 always denotes 'unknown symbol'. */
817 Word i;
818 for (i = 1; i < (Word)(escn_symtab->szB/sizeof(ElfXX_Sym)); i++) {
819 ElfXX_Sym sym;
820 ML_(img_get)(&sym, escn_symtab->img,
821 escn_symtab->ioff + i * sizeof(ElfXX_Sym), sizeof(sym));
822 DiOffT sym_name = escn_strtab->ioff + sym.st_name;
823 Addr sym_svma = sym.st_value;
825 if (di->trace_symtab)
826 show_raw_elf_symbol(escn_strtab->img, i,
827 &sym, sym_name, sym_svma, False);
829 SymAVMAs sym_avmas_really;
830 Int sym_size = 0;
831 Bool from_opd = False, is_text = False, is_ifunc = False;
832 Bool is_global = False;
833 DiOffT sym_name_really = DiOffT_INVALID;
834 sym_avmas_really.main = 0;
835 SET_TOCPTR_AVMA(sym_avmas_really, 0);
836 SET_LOCAL_EP_AVMA(sym_avmas_really, 0);
837 if (get_elf_symbol_info(di, &sym, sym_name, escn_strtab,
838 sym_svma, symtab_in_debug,
839 escn_opd, di->text_bias,
840 &sym_name_really,
841 &sym_avmas_really,
842 &sym_size,
843 &from_opd, &is_text, &is_ifunc, &is_global)) {
845 DiSym disym;
846 VG_(memset)(&disym, 0, sizeof(disym));
847 HChar* cstr = ML_(img_strdup)(escn_strtab->img,
848 "di.res__n.1", sym_name_really);
849 disym.avmas = sym_avmas_really;
850 disym.pri_name = ML_(addStr) ( di, cstr, -1 );
851 disym.sec_names = NULL;
852 disym.size = sym_size;
853 disym.isText = is_text;
854 disym.isIFunc = is_ifunc;
855 disym.isGlobal = is_global;
856 if (cstr) { ML_(dinfo_free)(cstr); cstr = NULL; }
857 vg_assert(disym.pri_name);
858 vg_assert(GET_TOCPTR_AVMA(disym.avmas) == 0);
859 /* has no role except on ppc64be-linux */
860 ML_(addSym) ( di, &disym );
862 if (TRACE_SYMTAB_ENABLED) {
863 TRACE_SYMTAB(" rec(%c) [%4ld]: "
864 " val %#010lx, sz %4d %s\n",
865 is_text ? 't' : 'd',
867 disym.avmas.main,
868 (Int)disym.size,
869 disym.pri_name
871 if (GET_LOCAL_EP_AVMA(disym.avmas) != 0) {
872 TRACE_SYMTAB(" local entry point %#010lx\n",
873 GET_LOCAL_EP_AVMA(disym.avmas));
882 /* Read an ELF symbol table (normal or dynamic). This one is for
883 ppc64be-linux, which requires special treatment. */
885 typedef
886 struct {
887 Addr addr;
888 DiOffT name;
889 /* We have to store also the DiImage* so as to give context for
890 |name|. This is not part of the key (in terms of lookup) but
891 there's no easy other way to do this. Ugly. */
892 DiImage* img;
894 TempSymKey;
896 typedef
897 struct {
898 TempSymKey key;
899 Addr tocptr;
900 Int size;
901 Bool from_opd;
902 Bool is_text;
903 Bool is_ifunc;
904 Bool is_global;
906 TempSym;
908 static Word cmp_TempSymKey ( const TempSymKey* key1, const TempSym* elem2 )
910 /* Stay sane ... */
911 vg_assert(key1->img == elem2->key.img);
912 vg_assert(key1->img != NULL);
913 if (key1->addr < elem2->key.addr) return -1;
914 if (key1->addr > elem2->key.addr) return 1;
915 vg_assert(key1->name != DiOffT_INVALID);
916 vg_assert(elem2->key.name != DiOffT_INVALID);
917 return (Word)ML_(img_strcmp)(key1->img, key1->name, elem2->key.name);
920 static
921 __attribute__((unused)) /* not referred to on all targets */
922 void read_elf_symtab__ppc64be_linux(
923 struct _DebugInfo* di, const HChar* tab_name,
924 DiSlice* escn_symtab,
925 DiSlice* escn_strtab,
926 DiSlice* escn_opd, /* ppc64be-linux only */
927 Bool symtab_in_debug
930 Word i;
931 Int old_size;
932 Bool modify_size, modify_tocptr;
933 OSet *oset;
934 TempSymKey key;
935 TempSym *elem;
936 TempSym *prev;
938 if (escn_strtab->img == NULL || escn_symtab->img == NULL) {
939 HChar buf[VG_(strlen)(tab_name) + 40];
940 VG_(sprintf)(buf, " object doesn't have a %s", tab_name);
941 ML_(symerr)(di, False, buf);
942 return;
945 TRACE_SYMTAB("\n--- Reading (ELF, ppc64be-linux) %s (%llu entries) ---\n",
946 tab_name, escn_symtab->szB/sizeof(ElfXX_Sym) );
948 oset = VG_(OSetGen_Create)( offsetof(TempSym,key),
949 (OSetCmp_t)cmp_TempSymKey,
950 ML_(dinfo_zalloc), "di.respl.1",
951 ML_(dinfo_free) );
953 /* Perhaps should start at i = 1; ELF docs suggest that entry
954 0 always denotes 'unknown symbol'. */
955 for (i = 1; i < (Word)(escn_symtab->szB/sizeof(ElfXX_Sym)); i++) {
956 ElfXX_Sym sym;
957 ML_(img_get)(&sym, escn_symtab->img,
958 escn_symtab->ioff + i * sizeof(ElfXX_Sym), sizeof(sym));
959 DiOffT sym_name = escn_strtab->ioff + sym.st_name;
960 Addr sym_svma = sym.st_value;
962 if (di->trace_symtab)
963 show_raw_elf_symbol(escn_strtab->img, i,
964 &sym, sym_name, sym_svma, True);
966 SymAVMAs sym_avmas_really;
967 Int sym_size = 0;
968 Bool from_opd = False, is_text = False, is_ifunc = False;
969 Bool is_global = False;
970 DiOffT sym_name_really = DiOffT_INVALID;
971 DiSym disym;
972 VG_(memset)(&disym, 0, sizeof(disym));
973 sym_avmas_really.main = 0;
974 SET_TOCPTR_AVMA(sym_avmas_really, 0);
975 SET_LOCAL_EP_AVMA(sym_avmas_really, 0);
976 if (get_elf_symbol_info(di, &sym, sym_name, escn_strtab,
977 sym_svma, symtab_in_debug,
978 escn_opd, di->text_bias,
979 &sym_name_really,
980 &sym_avmas_really,
981 &sym_size,
982 &from_opd, &is_text, &is_ifunc, &is_global)) {
984 /* Check if we've seen this (name,addr) key before. */
985 key.addr = sym_avmas_really.main;
986 key.name = sym_name_really;
987 key.img = escn_strtab->img;
988 prev = VG_(OSetGen_Lookup)( oset, &key );
990 if (prev) {
992 /* Seen it before. Fold in whatever new info we can. */
993 modify_size = False;
994 modify_tocptr = False;
995 old_size = 0;
997 if (prev->from_opd && !from_opd
998 && (prev->size == 24 || prev->size == 16)
999 && sym_size != prev->size) {
1000 /* Existing one is an opd-redirect, with a bogus size,
1001 so the only useful new fact we have is the real size
1002 of the symbol. */
1003 modify_size = True;
1004 old_size = prev->size;
1005 prev->size = sym_size;
1007 else
1008 if (!prev->from_opd && from_opd
1009 && (sym_size == 24 || sym_size == 16)) {
1010 /* Existing one is non-opd, new one is opd. What we
1011 can acquire from the new one is the TOC ptr to be
1012 used. Since the existing sym is non-toc, it
1013 shouldn't currently have an known TOC ptr. */
1014 vg_assert(prev->tocptr == 0);
1015 modify_tocptr = True;
1016 prev->tocptr = GET_TOCPTR_AVMA(sym_avmas_really);
1018 else {
1019 /* ignore. can we do better here? */
1022 /* Only one or the other is possible (I think) */
1023 vg_assert(!(modify_size && modify_tocptr));
1025 if (modify_size && di->trace_symtab) {
1026 VG_(printf)(" modify (old sz %4d) "
1027 " val %#010lx, toc %#010lx, sz %4d %llu\n",
1028 old_size,
1029 prev->key.addr,
1030 prev->tocptr,
1031 prev->size,
1032 prev->key.name
1035 if (modify_tocptr && di->trace_symtab) {
1036 VG_(printf)(" modify (upd tocptr) "
1037 " val %#010lx, toc %#010lx, sz %4d %llu\n",
1038 prev->key.addr,
1039 prev->tocptr,
1040 prev->size,
1041 prev->key.name
1045 } else {
1047 /* A new (name,addr) key. Add and continue. */
1048 elem = VG_(OSetGen_AllocNode)(oset, sizeof(TempSym));
1049 elem->key = key;
1050 elem->tocptr = GET_TOCPTR_AVMA(sym_avmas_really);
1051 elem->size = sym_size;
1052 elem->from_opd = from_opd;
1053 elem->is_text = is_text;
1054 elem->is_ifunc = is_ifunc;
1055 elem->is_global = is_global;
1056 VG_(OSetGen_Insert)(oset, elem);
1057 if (di->trace_symtab) {
1058 HChar* str = ML_(img_strdup)(escn_strtab->img, "di.respl.2",
1059 elem->key.name);
1060 VG_(printf)(" to-oset [%4ld]: "
1061 " val %#010lx, toc %#010lx, sz %4d %s\n",
1063 elem->key.addr,
1064 elem->tocptr,
1065 (Int) elem->size,
1068 if (str) ML_(dinfo_free)(str);
1075 /* All the syms that matter are in the oset. Now pull them out,
1076 build a "standard" symbol table, and nuke the oset. */
1078 i = 0;
1079 VG_(OSetGen_ResetIter)( oset );
1081 while ( (elem = VG_(OSetGen_Next)(oset)) ) {
1082 DiSym disym;
1083 VG_(memset)(&disym, 0, sizeof(disym));
1084 HChar* cstr = ML_(img_strdup)(escn_strtab->img,
1085 "di.res__ppc64.1", elem->key.name);
1086 disym.avmas.main = elem->key.addr;
1087 SET_TOCPTR_AVMA(disym.avmas, elem->tocptr);
1088 SET_LOCAL_EP_AVMA(disym.avmas, 0); // ppc64be does not use local_ep.
1089 disym.pri_name = ML_(addStr) ( di, cstr, -1 );
1090 disym.sec_names = NULL;
1091 disym.size = elem->size;
1092 disym.isText = elem->is_text;
1093 disym.isIFunc = elem->is_ifunc;
1094 disym.isGlobal = elem->is_global;
1095 if (cstr) { ML_(dinfo_free)(cstr); cstr = NULL; }
1096 vg_assert(disym.pri_name != NULL);
1098 ML_(addSym) ( di, &disym );
1099 if (di->trace_symtab) {
1100 VG_(printf)(" rec(%c%c%c) [%4ld]: "
1101 " val %#010lx, toc %#010lx, sz %4d %s\n",
1102 disym.isText ? 't' : 'd',
1103 disym.isIFunc ? 'i' : '-',
1104 disym.isGlobal ? 'g' : 'l',
1106 disym.avmas.main,
1107 GET_TOCPTR_AVMA(disym.avmas),
1108 (Int) disym.size,
1109 disym.pri_name
1112 i++;
1115 VG_(OSetGen_Destroy)( oset );
1120 * Look for a build-id in an ELF image. The build-id specification
1121 * can be found here:
1123 * http://fedoraproject.org/wiki/RolandMcGrath/BuildID
1125 * Returned string must be freed by the caller.
1127 static
1128 HChar* find_buildid(DiImage* img, Bool rel_ok, Bool search_shdrs)
1130 HChar* buildid = NULL;
1132 # ifdef NT_GNU_BUILD_ID
1133 if (is_elf_object_file_by_DiImage(img, rel_ok)) {
1134 Word i;
1136 ElfXX_Ehdr ehdr;
1137 ML_(img_get)(&ehdr, img, 0, sizeof(ehdr));
1138 /* Skip the phdrs when we have to search the shdrs. In separate
1139 .debug files the phdrs might not be valid (they are a copy of
1140 the main ELF file) and might trigger assertions when getting
1141 image notes based on them. */
1142 for (i = 0; !search_shdrs && i < ehdr.e_phnum; i++) {
1143 ElfXX_Phdr phdr;
1144 ML_(img_get)(&phdr, img,
1145 ehdr.e_phoff + i * ehdr.e_phentsize, sizeof(phdr));
1147 if (phdr.p_type == PT_NOTE) {
1148 ElfXX_Off note_ioff = phdr.p_offset;
1150 while (note_ioff < phdr.p_offset + phdr.p_filesz) {
1151 ElfXX_Nhdr note;
1152 ML_(img_get)(&note, img, (DiOffT)note_ioff, sizeof(note));
1153 DiOffT name_ioff = note_ioff + sizeof(ElfXX_Nhdr);
1154 DiOffT desc_ioff = name_ioff + ((note.n_namesz + 3) & ~3);
1155 if (ML_(img_strcmp_c)(img, name_ioff, ELF_NOTE_GNU) == 0
1156 && note.n_type == NT_GNU_BUILD_ID) {
1157 buildid = ML_(dinfo_zalloc)("di.fbi.1",
1158 note.n_descsz * 2 + 1);
1159 Word j;
1160 for (j = 0; j < note.n_descsz; j++) {
1161 UChar desc_j = ML_(img_get_UChar)(img, desc_ioff + j);
1162 VG_(sprintf)(buildid + VG_(strlen)(buildid),
1163 "%02x", (UInt)desc_j);
1167 note_ioff = note_ioff + sizeof(ElfXX_Nhdr)
1168 + ((note.n_namesz + 3) & ~3)
1169 + ((note.n_descsz + 3) & ~3);
1174 /* Normally we would only search shdrs for ET_REL files, but when
1175 we search for a separate .debug file phdrs might not be there
1176 (they are never loaded) or have been corrupted, so try again
1177 against shdrs. */
1178 if (buildid || (!rel_ok && !search_shdrs))
1179 return buildid;
1181 for (i = 0; i < ehdr.e_shnum; i++) {
1182 ElfXX_Shdr shdr;
1183 ML_(img_get)(&shdr, img,
1184 ehdr.e_shoff + i * ehdr.e_shentsize, sizeof(shdr));
1186 if (shdr.sh_type == SHT_NOTE) {
1187 ElfXX_Off note_ioff = shdr.sh_offset;
1189 while (note_ioff < shdr.sh_offset + shdr.sh_size) {
1190 ElfXX_Nhdr note;
1191 ML_(img_get)(&note, img, (DiOffT)note_ioff, sizeof(note));
1192 DiOffT name_ioff = note_ioff + sizeof(ElfXX_Nhdr);
1193 DiOffT desc_ioff = name_ioff + ((note.n_namesz + 3) & ~3);
1195 if (ML_(img_strcmp_c)(img, name_ioff, ELF_NOTE_GNU) == 0
1196 && note.n_type == NT_GNU_BUILD_ID) {
1197 buildid = ML_(dinfo_zalloc)("di.fbi.2",
1198 note.n_descsz * 2 + 1);
1199 Word j;
1200 for (j = 0; j < note.n_descsz; j++) {
1201 UChar desc_j = ML_(img_get_UChar)(img, desc_ioff + j);
1202 VG_(sprintf)(buildid + VG_(strlen)(buildid),
1203 "%02x", (UInt)desc_j);
1207 note_ioff = note_ioff + sizeof(ElfXX_Nhdr)
1208 + ((note.n_namesz + 3) & ~3)
1209 + ((note.n_descsz + 3) & ~3);
1214 # endif /* def NT_GNU_BUILD_ID */
1216 return buildid;
1220 /* Try and open a separate debug file, ignoring any where the CRC does
1221 not match the value from the main object file. Returned DiImage
1222 must be discarded by the caller.
1224 If |serverAddr| is NULL, |name| is expected to be a fully qualified
1225 (absolute) path to the file in the local filesystem. If
1226 |serverAddr| is non-NULL, it is expected to be an IPv4 and port
1227 spec of the form "d.d.d.d:d" or "d.d.d.d", and |name| is expected
1228 to be a plain filename (no path components at all).
1230 static
1231 DiImage* open_debug_file( const HChar* name, const HChar* buildid, UInt crc,
1232 Bool rel_ok, const HChar* serverAddr )
1234 DiImage* dimg
1235 = serverAddr ? ML_(img_from_di_server)(name, serverAddr)
1236 : ML_(img_from_local_file)(name);
1237 if (dimg == NULL)
1238 return NULL;
1240 if (VG_(clo_verbosity) > 1) {
1241 if (serverAddr)
1242 VG_(message)(Vg_DebugMsg, " Considering %s on server %s ..\n",
1243 name, serverAddr);
1244 else
1245 VG_(message)(Vg_DebugMsg, " Considering %s ..\n", name);
1248 /* We will always check the crc if we have one (altfiles don't have one)
1249 for now because we might be opening the main file again by any other
1250 name, and that obviously also has the same buildid. More efficient
1251 would be an fstat bases check or a check that the file actually
1252 contains .debug* sections. */
1253 if (buildid && crc == 0) {
1254 HChar* debug_buildid = find_buildid(dimg, rel_ok, True);
1255 if (debug_buildid == NULL || VG_(strcmp)(buildid, debug_buildid) != 0) {
1256 ML_(img_done)(dimg);
1257 if (VG_(clo_verbosity) > 1)
1258 VG_(message)(Vg_DebugMsg,
1259 " .. build-id mismatch (found %s wanted %s)\n",
1260 debug_buildid, buildid);
1261 ML_(dinfo_free)(debug_buildid);
1262 return NULL;
1264 ML_(dinfo_free)(debug_buildid);
1265 if (VG_(clo_verbosity) > 1)
1266 VG_(message)(Vg_DebugMsg, " .. build-id is valid\n");
1267 } else {
1268 UInt calccrc = ML_(img_calc_gnu_debuglink_crc32)(dimg);
1269 if (calccrc != crc) {
1270 ML_(img_done)(dimg);
1271 if (VG_(clo_verbosity) > 1)
1272 VG_(message)(Vg_DebugMsg,
1273 " .. CRC mismatch (computed %08x wanted %08x)\n", calccrc, crc);
1274 return NULL;
1277 if (VG_(clo_verbosity) > 1)
1278 VG_(message)(Vg_DebugMsg, " .. CRC is valid\n");
1281 return dimg;
1285 /* Try to find a separate debug file for a given object file. If
1286 found, return its DiImage, which should be freed by the caller. If
1287 |buildid| is non-NULL, then a debug object matching it is
1288 acceptable. If |buildid| is NULL or doesn't specify a findable
1289 debug object, then we look in various places to find a file with
1290 the specified CRC. And if that doesn't work out then we give
1291 up. */
1292 static
1293 DiImage* find_debug_file( struct _DebugInfo* di,
1294 const HChar* objpath, const HChar* buildid,
1295 const HChar* debugname, UInt crc, Bool rel_ok )
1297 const HChar* extrapath = VG_(clo_extra_debuginfo_path);
1298 const HChar* serverpath = VG_(clo_debuginfo_server);
1300 DiImage* dimg = NULL; /* the img that we found */
1301 HChar* debugpath = NULL; /* where we found it */
1303 if (buildid != NULL) {
1304 debugpath = ML_(dinfo_zalloc)("di.fdf.1",
1305 VG_(strlen)(buildid) + 33);
1307 VG_(sprintf)(debugpath, "/usr/lib/debug/.build-id/%c%c/%s.debug",
1308 buildid[0], buildid[1], buildid + 2);
1310 dimg = open_debug_file(debugpath, buildid, 0, rel_ok, NULL);
1311 if (!dimg) {
1312 ML_(dinfo_free)(debugpath);
1313 debugpath = NULL;
1317 if (dimg == NULL && debugname != NULL) {
1318 HChar *objdir = ML_(dinfo_strdup)("di.fdf.2", objpath);
1319 HChar *objdirptr;
1321 if ((objdirptr = VG_(strrchr)(objdir, '/')) != NULL)
1322 *objdirptr = '\0';
1324 debugpath = ML_(dinfo_zalloc)(
1325 "di.fdf.3",
1326 VG_(strlen)(objdir) + VG_(strlen)(debugname) + 64
1327 + (extrapath ? VG_(strlen)(extrapath) : 0)
1328 + (serverpath ? VG_(strlen)(serverpath) : 0));
1330 if (debugname[0] == '/') {
1331 VG_(sprintf)(debugpath, "%s", debugname);
1332 dimg = open_debug_file(debugpath, buildid, crc, rel_ok, NULL);
1333 if (dimg != NULL) goto dimg_ok;
1336 VG_(sprintf)(debugpath, "%s/%s", objdir, debugname);
1337 dimg = open_debug_file(debugpath, buildid, crc, rel_ok, NULL);
1338 if (dimg != NULL) goto dimg_ok;
1340 VG_(sprintf)(debugpath, "%s/.debug/%s", objdir, debugname);
1341 dimg = open_debug_file(debugpath, buildid, crc, rel_ok, NULL);
1342 if (dimg != NULL) goto dimg_ok;
1344 VG_(sprintf)(debugpath, "/usr/lib/debug%s/%s", objdir, debugname);
1345 dimg = open_debug_file(debugpath, buildid, crc, rel_ok, NULL);
1346 if (dimg != NULL) goto dimg_ok;
1348 if (extrapath) {
1349 VG_(sprintf)(debugpath, "%s%s/%s", extrapath,
1350 objdir, debugname);
1351 dimg = open_debug_file(debugpath, buildid, crc, rel_ok, NULL);
1352 if (dimg != NULL) goto dimg_ok;
1355 if (serverpath) {
1356 /* When looking on the debuginfo server, always just pass the
1357 basename. */
1358 const HChar* basename = debugname;
1359 if (VG_(strstr)(basename, "/") != NULL) {
1360 basename = VG_(strrchr)(basename, '/') + 1;
1362 VG_(sprintf)(debugpath, "%s on %s", basename, serverpath);
1363 dimg = open_debug_file(basename, buildid, crc, rel_ok, serverpath);
1364 if (dimg) goto dimg_ok;
1367 dimg_ok:
1369 ML_(dinfo_free)(objdir);
1372 if (dimg != NULL) {
1373 vg_assert(debugpath);
1374 TRACE_SYMTAB("\n");
1375 TRACE_SYMTAB("------ Found a debuginfo file: %s\n", debugpath);
1377 /* Only set once, we might be called again for opening the altfile. */
1378 if (di->fsm.dbgname == NULL)
1379 di->fsm.dbgname = ML_(dinfo_strdup)("di.fdf.4", debugpath);
1382 if (debugpath)
1383 ML_(dinfo_free)(debugpath);
1385 return dimg;
1389 /* Try to find a separate debug file for a given object file, in a
1390 hacky and dangerous way: check only the --extra-debuginfo-path and
1391 the --debuginfo-server. And don't do a consistency check. */
1392 static
1393 DiImage* find_debug_file_ad_hoc( const DebugInfo* di,
1394 const HChar* objpath )
1396 const HChar* extrapath = VG_(clo_extra_debuginfo_path);
1397 const HChar* serverpath = VG_(clo_debuginfo_server);
1399 DiImage* dimg = NULL; /* the img that we found */
1400 HChar* debugpath = NULL; /* where we found it */
1402 HChar *objdir = ML_(dinfo_strdup)("di.fdfah.1", objpath);
1403 HChar *objdirptr;
1405 if ((objdirptr = VG_(strrchr)(objdir, '/')) != NULL)
1406 *objdirptr = '\0';
1408 debugpath = ML_(dinfo_zalloc)(
1409 "di.fdfah.3",
1410 VG_(strlen)(objdir) + 64
1411 + (extrapath ? VG_(strlen)(extrapath) : 0)
1412 + (serverpath ? VG_(strlen)(serverpath) : 0));
1414 if (extrapath) {
1415 VG_(sprintf)(debugpath, "%s/%s", extrapath, objpath);
1416 dimg = ML_(img_from_local_file)(debugpath);
1417 if (dimg != NULL) {
1418 if (VG_(clo_verbosity) > 1) {
1419 VG_(message)(Vg_DebugMsg, " Using (POSSIBLY MISMATCHED) %s\n",
1420 debugpath);
1422 goto dimg_ok;
1425 if (serverpath) {
1426 /* When looking on the debuginfo server, always just pass the
1427 basename. */
1428 const HChar* basename = objpath;
1429 if (VG_(strstr)(basename, "/") != NULL) {
1430 basename = VG_(strrchr)(basename, '/') + 1;
1432 VG_(sprintf)(debugpath, "%s on %s", basename, serverpath);
1433 dimg = ML_(img_from_di_server)(basename, serverpath);
1434 if (dimg != NULL) {
1435 if (VG_(clo_verbosity) > 1) {
1436 VG_(message)(Vg_DebugMsg, " Using (POSSIBLY MISMATCHED) %s\n",
1437 debugpath);
1439 goto dimg_ok;
1443 dimg_ok:
1445 ML_(dinfo_free)(objdir);
1447 if (dimg != NULL) {
1448 vg_assert(debugpath);
1449 TRACE_SYMTAB("\n");
1450 TRACE_SYMTAB("------ Found an ad_hoc debuginfo file: %s\n", debugpath);
1453 if (debugpath)
1454 ML_(dinfo_free)(debugpath);
1456 return dimg;
1460 static DiOffT INDEX_BIS ( DiOffT base, UWord idx, UWord scale ) {
1461 // This is a bit stupid. Really, idx and scale ought to be
1462 // 64-bit quantities, always.
1463 return base + (DiOffT)idx * (DiOffT)scale;
1467 /* Find the file offset corresponding to SVMA by using the program
1468 headers. This is taken from binutils-2.17/binutils/readelf.c
1469 offset_from_vma(). */
1470 static
1471 Word file_offset_from_svma ( /*OUT*/Bool* ok,
1472 Addr svma,
1473 DiImage* img,
1474 DiOffT phdr_ioff,
1475 Word phdr_nent,
1476 Word phdr_ent_szB )
1478 Word i;
1479 for (i = 0; i < phdr_nent; i++) {
1480 ElfXX_Phdr seg;
1481 ML_(img_get)(&seg, img,
1482 INDEX_BIS(phdr_ioff, i, phdr_ent_szB), sizeof(seg));
1483 if (seg.p_type != PT_LOAD)
1484 continue;
1485 if (svma >= (seg.p_vaddr & -seg.p_align)
1486 && svma + 1 <= seg.p_vaddr + seg.p_filesz) {
1487 *ok = True;
1488 return svma - seg.p_vaddr + seg.p_offset;
1491 *ok = False;
1492 return 0;
1495 /* Check if section is compressed and modify DiSlice if it is.
1496 Returns False in case of unsupported compression type.
1498 static Bool check_compression(ElfXX_Shdr* h, DiSlice* s) {
1499 if (h->sh_flags & SHF_COMPRESSED) {
1500 ElfXX_Chdr chdr;
1501 ML_(img_get)(&chdr, s->img, s->ioff, sizeof(ElfXX_Chdr));
1502 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
1503 return False;
1504 s->ioff = ML_(img_mark_compressed_part)(s->img,
1505 s->ioff + sizeof(ElfXX_Chdr),
1506 s->szB - sizeof(ElfXX_Chdr),
1507 (SizeT)chdr.ch_size);
1508 s->szB = chdr.ch_size;
1509 } else if (h->sh_size > SIZE_OF_ZLIB_HEADER) {
1510 /* Read the zlib header. In this case, it should be "ZLIB"
1511 followed by the uncompressed section size, 8 bytes in BE order. */
1512 UChar tmp[SIZE_OF_ZLIB_HEADER];
1513 ML_(img_get)(tmp, s->img, s->ioff, SIZE_OF_ZLIB_HEADER);
1514 if (VG_(memcmp)(tmp, "ZLIB", 4) == 0) {
1515 SizeT size;
1516 # if (VG_WORDSIZE == 8)
1517 size = tmp[4]; size <<= 8;
1518 size += tmp[5]; size <<= 8;
1519 size += tmp[6]; size <<= 8;
1520 size += tmp[7]; size <<= 8;
1521 # else
1522 vg_assert((tmp[4] == 0) && (tmp[5] == 0) && (tmp[6] == 0)
1523 && (tmp[7] == 0));
1524 size = 0;
1525 # endif
1526 size += tmp[8]; size <<= 8;
1527 size += tmp[9]; size <<= 8;
1528 size += tmp[10]; size <<= 8;
1529 size += tmp[11];
1530 s->ioff = ML_(img_mark_compressed_part)(s->img,
1531 s->ioff + SIZE_OF_ZLIB_HEADER,
1532 s->szB - SIZE_OF_ZLIB_HEADER,
1533 size);
1534 s->szB = size;
1537 return True;
1540 /* Helper function to get the readlink path. Returns a copy of path if the
1541 file wasn't a symbolic link. Returns NULL on error. Unless NULL is
1542 returned the result needs to be released with dinfo_free.
1544 static HChar* readlink_path (const HChar *path)
1546 SizeT bufsiz = VG_(strlen)(path);
1547 HChar *buf = ML_(dinfo_strdup)("readlink_path.strdup", path);
1548 UInt tries = 6;
1550 while (tries > 0) {
1551 SysRes res;
1552 #if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
1553 res = VG_(do_syscall4)(__NR_readlinkat, VKI_AT_FDCWD,
1554 (UWord)path, (UWord)buf, bufsiz);
1555 #elif defined(VGO_linux) || defined(VGO_darwin)
1556 res = VG_(do_syscall3)(__NR_readlink, (UWord)path, (UWord)buf, bufsiz);
1557 #elif defined(VGO_solaris)
1558 res = VG_(do_syscall4)(__NR_readlinkat, VKI_AT_FDCWD, (UWord)path,
1559 (UWord)buf, bufsiz);
1560 #else
1561 # error Unknown OS
1562 #endif
1563 if (sr_isError(res)) {
1564 if (sr_Err(res) == VKI_EINVAL)
1565 return buf; // It wasn't a symbolic link, return the strdup result.
1566 ML_(dinfo_free)(buf);
1567 return NULL;
1570 SSizeT r = sr_Res(res);
1571 if (r < 0) break;
1572 if (r == bufsiz) { // buffer too small; increase and retry
1573 bufsiz *= 2 + 16;
1574 buf = ML_(dinfo_realloc)("readlink_path.realloc", buf, bufsiz);
1575 tries--;
1576 continue;
1578 buf[r] = '\0';
1579 break;
1582 if (tries == 0) { // We tried, but weird long path?
1583 ML_(dinfo_free)(buf);
1584 return NULL;
1587 if (buf[0] == '/')
1588 return buf;
1590 /* Relative path, add link dir. */
1591 HChar *linkdirptr;
1592 SizeT linkdir_len = VG_(strlen)(path);
1593 if ((linkdirptr = VG_(strrchr)(path, '/')) != NULL)
1594 linkdir_len -= VG_(strlen)(linkdirptr + 1);
1596 SizeT buflen = VG_(strlen)(buf);
1597 SizeT needed = linkdir_len + buflen + 1;
1598 if (bufsiz < needed)
1599 buf = ML_(dinfo_realloc)("readlink_path.linkdir", buf, needed);
1601 VG_(memmove)(buf + linkdir_len, buf, buflen);
1602 VG_(memcpy)(buf, path, linkdir_len);
1603 buf[needed - 1] = '\0';
1605 return buf;
1608 /* The central function for reading ELF debug info. For the
1609 object/exe specified by the DebugInfo, find ELF sections, then read
1610 the symbols, line number info, file name info, CFA (stack-unwind
1611 info) and anything else we want, into the tables within the
1612 supplied DebugInfo.
1615 Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
1617 /* This function is long and complex. That, and the presence of
1618 nested scopes, means it's not always easy to see which parts are
1619 in loops/conditionals and which aren't. To make it easier to
1620 follow, points executed exactly once -- that is, those which are
1621 the top level of the function -- are marked TOPLEVEL.
1623 /* Consistent terminology for local variable names, without which
1624 it's almost unfollowably complex:
1626 In which file?
1627 in the main ELF file *_m*
1628 in the debuginfo file *_d*
1629 in the alt debuginfo file *_a*
1631 What kind of thing?
1632 _{m,d,a}img a DiImage*
1633 _{m,d,a}ioff an offset in the image (DiOffT)
1634 _{m,d,a}nent "number of entries"
1635 _{m,d,a}ent_szB "size in bytes of an entry"
1636 ehdr_{m,d,a} ELF header
1637 phdr Program header
1638 shdr Section header
1639 a_X a temporary X
1640 _escn an DiSlice (elf section info) variable
1641 szB size in bytes
1645 /* TOPLEVEL */
1646 Bool res, ok;
1647 Word i, j;
1648 Bool dynbss_present = False;
1649 Bool sdynbss_present = False;
1651 /* Image for the main ELF file we're working with. */
1652 DiImage* mimg = NULL;
1654 /* Ditto for any ELF debuginfo file that we might happen to load. */
1655 DiImage* dimg = NULL;
1657 /* Ditto for alternate ELF debuginfo file that we might happen to load. */
1658 DiImage* aimg = NULL;
1660 /* ELF header offset for the main file. Should be zero since the
1661 ELF header is at start of file. */
1662 DiOffT ehdr_mioff = 0;
1664 /* Program header table image addr, # entries, entry size */
1665 DiOffT phdr_mioff = 0;
1666 UWord phdr_mnent = 0;
1667 UWord phdr_ment_szB = 0;
1669 /* Section header image addr, # entries, entry size. Also the
1670 associated string table. */
1671 DiOffT shdr_mioff = 0;
1672 UWord shdr_mnent = 0;
1673 UWord shdr_ment_szB = 0;
1674 DiOffT shdr_strtab_mioff = 0;
1676 /* SVMAs covered by rx and rw segments and corresponding biases.
1677 Normally each object would provide just one rx and one rw area,
1678 but various ELF mangling tools create objects with multiple
1679 such entries, hence the generality. */
1680 typedef
1681 struct {
1682 Addr svma_base;
1683 Addr svma_limit;
1684 PtrdiffT bias;
1685 Bool exec;
1687 RangeAndBias;
1689 XArray* /* of RangeAndBias */ svma_ranges = NULL;
1691 # if defined(SOLARIS_PT_SUNDWTRACE_THRP)
1692 Addr dtrace_data_vaddr = 0;
1693 # endif
1695 vg_assert(di);
1696 vg_assert(di->fsm.have_rx_map == True);
1697 vg_assert(di->fsm.have_rw_map == True);
1698 vg_assert(di->have_dinfo == False);
1699 vg_assert(di->fsm.filename);
1700 vg_assert(!di->symtab);
1701 vg_assert(!di->loctab);
1702 vg_assert(!di->inltab);
1703 vg_assert(!di->cfsi_base);
1704 vg_assert(!di->cfsi_m_ix);
1705 vg_assert(!di->cfsi_rd);
1706 vg_assert(!di->cfsi_exprs);
1707 vg_assert(!di->strpool);
1708 vg_assert(!di->fndnpool);
1709 vg_assert(!di->soname);
1712 Bool has_nonempty_rx = False;
1713 Bool has_nonempty_rw = False;
1714 for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1715 DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
1716 if (!map->rx && !map->rw)
1717 continue;
1718 if (map->rx && map->size > 0)
1719 has_nonempty_rx = True;
1720 if (map->rw && map->size > 0)
1721 has_nonempty_rw = True;
1722 /* If this doesn't hold true, it means that m_syswrap/m_aspacemgr
1723 managed to do a mapping where the start isn't page aligned.
1724 Which sounds pretty bogus to me. */
1725 vg_assert(VG_IS_PAGE_ALIGNED(map->avma));
1727 vg_assert(has_nonempty_rx);
1728 vg_assert(has_nonempty_rw);
1731 /* ----------------------------------------------------------
1732 At this point, there is very little information in the
1733 DebugInfo. We only know that something that looks like an ELF
1734 file has been mapped rx-ishly and rw-ishly as recorded in the
1735 di->fsm.maps array items. First we examine the file's ELF
1736 Program Header, and, by comparing that against the di->fsm.maps
1737 info, try to figure out the AVMAs for the sections we care
1738 about, that should have been mapped: text, data, sdata, bss,
1739 got, plt, and toc.
1740 ---------------------------------------------------------- */
1742 res = False;
1744 if (VG_(clo_verbosity) > 1 || VG_(clo_trace_redir))
1745 VG_(message)(Vg_DebugMsg, "Reading syms from %s\n",
1746 di->fsm.filename );
1748 /* Connect to the primary object image, so that we can read symbols
1749 and line number info out of it. It will be disconnected
1750 immediately thereafter; it is only connected transiently. */
1751 mimg = ML_(img_from_local_file)(di->fsm.filename);
1752 if (mimg == NULL) {
1753 VG_(message)(Vg_UserMsg, "warning: connection to image %s failed\n",
1754 di->fsm.filename );
1755 VG_(message)(Vg_UserMsg, " no symbols or debug info loaded\n" );
1756 return False;
1759 /* Ok, the object image is available. Now verify that it is a
1760 valid ELF .so or executable image. */
1761 ok = is_elf_object_file_by_DiImage(mimg, False);
1762 if (!ok) {
1763 ML_(symerr)(di, True, "Invalid ELF Header");
1764 goto out;
1767 /* Find where the program and section header tables are, and give
1768 up if either is missing or outside the image (bogus). */
1769 ElfXX_Ehdr ehdr_m;
1770 vg_assert(ehdr_mioff == 0); // ensured by its initialisation
1771 ok = ML_(img_valid)(mimg, ehdr_mioff, sizeof(ehdr_m));
1772 vg_assert(ok); // ML_(is_elf_object_file) should ensure this
1773 ML_(img_get)(&ehdr_m, mimg, ehdr_mioff, sizeof(ehdr_m));
1775 phdr_mioff = ehdr_mioff + ehdr_m.e_phoff;
1776 phdr_mnent = ehdr_m.e_phnum;
1777 phdr_ment_szB = ehdr_m.e_phentsize;
1779 shdr_mioff = ehdr_mioff + ehdr_m.e_shoff;
1780 shdr_mnent = ehdr_m.e_shnum;
1781 shdr_ment_szB = ehdr_m.e_shentsize;
1783 TRACE_SYMTAB("------ Basic facts about the object ------\n");
1784 TRACE_SYMTAB("object: n_oimage %llu\n",
1785 (ULong)ML_(img_size)(mimg));
1786 TRACE_SYMTAB("phdr: ioff %llu nent %lu ent_szB %lu\n",
1787 phdr_mioff, phdr_mnent, phdr_ment_szB);
1788 TRACE_SYMTAB("shdr: ioff %llu nent %lu ent_szB %lu\n",
1789 shdr_mioff, shdr_mnent, shdr_ment_szB);
1790 for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1791 const DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
1792 if (map->rx)
1793 TRACE_SYMTAB("rx_map: avma %#lx size %lu foff %ld\n",
1794 map->avma, map->size, map->foff);
1796 for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1797 const DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
1798 if (map->rw)
1799 TRACE_SYMTAB("rw_map: avma %#lx size %lu foff %ld\n",
1800 map->avma, map->size, map->foff);
1803 if (phdr_mnent == 0
1804 || !ML_(img_valid)(mimg, phdr_mioff, phdr_mnent * phdr_ment_szB)) {
1805 ML_(symerr)(di, True, "Missing or invalid ELF Program Header Table");
1806 goto out;
1809 if (shdr_mnent == 0
1810 || !ML_(img_valid)(mimg, shdr_mioff, shdr_mnent * shdr_ment_szB)) {
1811 ML_(symerr)(di, True, "Missing or invalid ELF Section Header Table");
1812 goto out;
1815 /* Also find the section header's string table, and validate. */
1816 /* checked previously by is_elf_object_file: */
1817 vg_assert(ehdr_m.e_shstrndx != SHN_UNDEF);
1819 // shdr_mioff is the offset of the section header table
1820 // and we need the ehdr_m.e_shstrndx'th entry
1821 { ElfXX_Shdr a_shdr;
1822 ML_(img_get)(&a_shdr, mimg,
1823 INDEX_BIS(shdr_mioff, ehdr_m.e_shstrndx, shdr_ment_szB),
1824 sizeof(a_shdr));
1825 shdr_strtab_mioff
1826 = ehdr_mioff /* isn't this always zero? */ + a_shdr.sh_offset;
1828 if (!ML_(img_valid)(mimg, shdr_strtab_mioff,
1829 1/*bogus, but we don't know the real size*/ )) {
1830 ML_(symerr)(di, True, "Invalid ELF Section Header String Table");
1831 goto out;
1835 TRACE_SYMTAB("shdr: string table at %llu\n", shdr_strtab_mioff);
1837 svma_ranges = VG_(newXA)(ML_(dinfo_zalloc), "di.relfdi.1",
1838 ML_(dinfo_free), sizeof(RangeAndBias));
1840 /* TOPLEVEL */
1841 /* Look through the program header table, and:
1842 - copy information from suitable PT_LOAD entries into svma_ranges
1843 - find (or fake up) the .soname for this object.
1845 TRACE_SYMTAB("\n");
1846 TRACE_SYMTAB("------ Examining the program headers ------\n");
1847 vg_assert(di->soname == NULL);
1849 /* TOPLEVEL */
1850 ElfXX_Addr prev_svma = 0;
1852 for (i = 0; i < phdr_mnent; i++) {
1853 ElfXX_Phdr a_phdr;
1854 ML_(img_get)(&a_phdr, mimg,
1855 INDEX_BIS(phdr_mioff, i, phdr_ment_szB),
1856 sizeof(a_phdr));
1858 /* Make sure the PT_LOADable entries are in order and
1859 non-overlapping. This in turn means the address ranges
1860 slurped into svma_ranges are in order and
1861 non-overlapping. */
1863 if (a_phdr.p_type == PT_LOAD) {
1864 TRACE_SYMTAB("PT_LOAD[%ld]: p_vaddr %#lx (prev %#lx)\n",
1865 i, (UWord)a_phdr.p_vaddr, (UWord)prev_svma);
1866 TRACE_SYMTAB("PT_LOAD[%ld]: p_offset %lu, p_filesz %lu,"
1867 " perms %c%c%c\n",
1868 i, (UWord)a_phdr.p_offset, (UWord)a_phdr.p_filesz,
1869 a_phdr.p_flags & PF_R ? 'r' : '-',
1870 a_phdr.p_flags & PF_W ? 'w' : '-',
1871 a_phdr.p_flags & PF_X ? 'x' : '-');
1872 if (a_phdr.p_vaddr < prev_svma) {
1873 ML_(symerr)(di, True,
1874 "ELF Program Headers are not in ascending order");
1875 goto out;
1877 prev_svma = a_phdr.p_vaddr;
1878 if (a_phdr.p_memsz > 0) {
1879 Bool loaded = False;
1880 for (j = 0; j < VG_(sizeXA)(di->fsm.maps); j++) {
1881 const DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, j);
1882 if ( (map->rx || map->rw || map->ro)
1883 && map->size > 0 /* stay sane */
1884 && a_phdr.p_offset >= map->foff
1885 && a_phdr.p_offset < map->foff + map->size
1886 && a_phdr.p_offset + a_phdr.p_filesz
1887 <= map->foff + map->size) {
1888 RangeAndBias item;
1889 item.svma_base = a_phdr.p_vaddr;
1890 item.svma_limit = a_phdr.p_vaddr + a_phdr.p_memsz;
1891 item.bias = map->avma - map->foff
1892 + a_phdr.p_offset - a_phdr.p_vaddr;
1893 if (map->rw
1894 && (a_phdr.p_flags & (PF_R | PF_W))
1895 == (PF_R | PF_W)) {
1896 item.exec = False;
1897 VG_(addToXA)(svma_ranges, &item);
1898 TRACE_SYMTAB(
1899 "PT_LOAD[%ld]: acquired as rw, bias 0x%lx\n",
1900 i, (UWord)item.bias);
1901 loaded = True;
1903 if (map->rx
1904 && (a_phdr.p_flags & (PF_R | PF_X))
1905 == (PF_R | PF_X)) {
1906 item.exec = True;
1907 VG_(addToXA)(svma_ranges, &item);
1908 TRACE_SYMTAB(
1909 "PT_LOAD[%ld]: acquired as rx, bias 0x%lx\n",
1910 i, (UWord)item.bias);
1911 loaded = True;
1913 if (map->ro
1914 && (a_phdr.p_flags & (PF_R | PF_W | PF_X))
1915 == PF_R) {
1916 item.exec = False;
1917 VG_(addToXA)(svma_ranges, &item);
1918 TRACE_SYMTAB(
1919 "PT_LOAD[%ld]: acquired as ro, bias 0x%lx\n",
1920 i, (UWord)item.bias);
1921 loaded = True;
1925 if (!loaded) {
1926 # if defined(SOLARIS_PT_SUNDWTRACE_THRP)
1927 if ((a_phdr.p_memsz == VKI_PT_SUNWDTRACE_SIZE)
1928 && ((a_phdr.p_flags & (PF_R | PF_W | PF_X)) == PF_R)) {
1929 TRACE_SYMTAB("PT_LOAD[%ld]: ignore dtrace_data program "
1930 "header\n", i);
1931 dtrace_data_vaddr = a_phdr.p_vaddr;
1932 continue;
1934 # endif /* SOLARIS_PT_SUNDWTRACE_THRP */
1936 ML_(symerr)(di, False,
1937 "ELF section outside all mapped regions");
1938 /* This problem might be solved by further memory mappings.
1939 Avoid the vg_assert(!di->soname) at the beginning of this
1940 function if DYNAMIC section has been already processed. */
1941 if (di->soname) {
1942 ML_(dinfo_free)(di->soname);
1943 di->soname = NULL;
1945 goto out;
1950 /* Try to get the soname. If there isn't one, use "NONE".
1951 The seginfo needs to have some kind of soname in order to
1952 facilitate writing redirect functions, since all redirect
1953 specifications require a soname (pattern). */
1954 if (a_phdr.p_type == PT_DYNAMIC && di->soname == NULL) {
1955 Word stroff = -1;
1956 DiOffT strtab_mioff = DiOffT_INVALID;
1957 for (j = 0; True/*exit check is in the loop*/; j++) {
1958 ElfXX_Dyn t_dyn_m; /* dyn_img[j] */
1959 ML_(img_get)(&t_dyn_m, mimg,
1960 INDEX_BIS(ehdr_mioff + a_phdr.p_offset,
1961 j, sizeof(ElfXX_Dyn)),
1962 sizeof(t_dyn_m));
1963 if (t_dyn_m.d_tag == DT_NULL)
1964 break;
1966 switch (t_dyn_m.d_tag) {
1967 case DT_SONAME: {
1968 stroff = t_dyn_m.d_un.d_val;
1969 break;
1971 case DT_STRTAB: {
1972 Bool ok2 = False;
1973 Word offset = file_offset_from_svma(
1974 &ok2, t_dyn_m.d_un.d_ptr, mimg,
1975 phdr_mioff, phdr_mnent, phdr_ment_szB
1977 if (ok2 && strtab_mioff == DiOffT_INVALID) {
1978 // Check for obviously bogus offsets.
1979 if (!ML_(img_valid)(mimg, offset, 1)) {
1980 ML_(symerr)(di, True, "Invalid DT_STRTAB offset");
1981 goto out;
1983 strtab_mioff = ehdr_mioff + offset;
1984 vg_assert(ehdr_mioff == 0); // should always be
1986 break;
1988 default:
1989 break;
1992 if (stroff != -1 && strtab_mioff != DiOffT_INVALID) {
1993 di->soname = ML_(img_strdup)(mimg, "di.redi.1",
1994 strtab_mioff + stroff);
1995 TRACE_SYMTAB("Found soname = %s\n", di->soname);
1998 } /* for (i = 0; i < phdr_Mnent; i++) ... */
1999 /* TOPLEVEL */
2001 } /* examine the program headers (local scope) */
2003 /* TOPLEVEL */
2005 /* If, after looking at all the program headers, we still didn't
2006 find a soname, add a fake one. */
2007 if (di->soname == NULL) {
2008 TRACE_SYMTAB("No soname found; using (fake) \"NONE\"\n");
2009 di->soname = ML_(dinfo_strdup)("di.redi.2", "NONE");
2012 vg_assert(VG_(sizeXA)(svma_ranges) != 0);
2014 /* Now read the section table. */
2015 TRACE_SYMTAB("\n");
2016 TRACE_SYMTAB("------ Examining the section headers ------\n");
2017 for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
2018 const DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
2019 if (map->rx)
2020 TRACE_SYMTAB("rx: at %#lx are mapped foffsets %ld .. %lu\n",
2021 map->avma, map->foff, map->foff + map->size - 1 );
2023 TRACE_SYMTAB("rx: contains these svma regions:\n");
2024 for (i = 0; i < VG_(sizeXA)(svma_ranges); i++) {
2025 const RangeAndBias* reg = VG_(indexXA)(svma_ranges, i);
2026 if (reg->exec)
2027 TRACE_SYMTAB(" svmas %#lx .. %#lx with bias %#lx\n",
2028 reg->svma_base, reg->svma_limit - 1, (UWord)reg->bias );
2030 for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
2031 const DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
2032 if (map->rw)
2033 TRACE_SYMTAB("rw: at %#lx are mapped foffsets %ld .. %lu\n",
2034 map->avma, map->foff, map->foff + map->size - 1 );
2036 TRACE_SYMTAB("rw: contains these svma regions:\n");
2037 for (i = 0; i < VG_(sizeXA)(svma_ranges); i++) {
2038 const RangeAndBias* reg = VG_(indexXA)(svma_ranges, i);
2039 if (!reg->exec)
2040 TRACE_SYMTAB(" svmas %#lx .. %#lx with bias %#lx\n",
2041 reg->svma_base, reg->svma_limit - 1, (UWord)reg->bias );
2044 /* TOPLEVEL */
2045 /* Iterate over section headers */
2046 for (i = 0; i < shdr_mnent; i++) {
2047 ElfXX_Shdr a_shdr;
2048 ML_(img_get)(&a_shdr, mimg,
2049 INDEX_BIS(shdr_mioff, i, shdr_ment_szB), sizeof(a_shdr));
2050 DiOffT name_mioff = shdr_strtab_mioff + a_shdr.sh_name;
2051 HChar* name = ML_(img_strdup)(mimg, "di.redi_name.2", name_mioff);
2052 Addr svma = a_shdr.sh_addr;
2053 OffT foff = a_shdr.sh_offset;
2054 UWord size = a_shdr.sh_size; /* Do not change this to be signed. */
2055 UInt alyn = a_shdr.sh_addralign;
2056 Bool nobits = a_shdr.sh_type == SHT_NOBITS;
2057 /* Look through our collection of info obtained from the PT_LOAD
2058 headers, and make 'inrx' and 'inrw' point to the first entry
2059 in each that intersects 'avma'. If in each case none is found,
2060 leave the relevant pointer at NULL. */
2061 RangeAndBias* inrx = NULL;
2062 RangeAndBias* inrw = NULL;
2063 for (j = 0; j < VG_(sizeXA)(svma_ranges); j++) {
2064 RangeAndBias* rng = VG_(indexXA)(svma_ranges, j);
2065 if (svma >= rng->svma_base && svma < rng->svma_limit) {
2066 if (!inrx && rng->exec) {
2067 inrx = rng;
2068 } else if (!inrw && !rng->exec) {
2069 inrw = rng;
2071 if (inrx && inrw)
2072 break;
2076 TRACE_SYMTAB(" [sec %2ld] %s %s al%4u foff %6ld .. %6lu "
2077 " svma %p name \"%s\"\n",
2078 i, inrx ? "rx" : " ", inrw ? "rw" : " ", alyn,
2079 foff, (size == 0) ? foff : foff+size-1, (void *) svma, name);
2081 /* Check for sane-sized segments. SHT_NOBITS sections have zero
2082 size in the file and their offsets are just conceptual. */
2083 if (!nobits &&
2084 (foff >= ML_(img_size)(mimg) || foff + size > ML_(img_size)(mimg))) {
2085 ML_(symerr)(di, True, "ELF Section extends beyond image end");
2086 goto out;
2089 /* Check for a sane alignment value. */
2090 if (alyn > 0 && -1 == VG_(log2)(alyn)) {
2091 ML_(symerr)(di, True, "ELF Section contains invalid "
2092 ".sh_addralign value");
2093 goto out;
2096 /* Ignore zero sized sections. */
2097 if (size == 0) {
2098 TRACE_SYMTAB("zero sized section \"%s\", ignoring\n", name);
2099 ML_(dinfo_free)(name);
2100 continue;
2103 # define BAD(_secname) \
2104 do { ML_(symerr)(di, True, \
2105 "Can't make sense of " _secname \
2106 " section mapping"); \
2107 /* make sure we don't assert if we find */ \
2108 /* ourselves back in this routine later, */ \
2109 /* with the same di */ \
2110 di->soname = NULL; \
2111 goto out; \
2112 } while (0)
2114 /* Find avma-s for: .text .data .sdata .rodata .bss .sbss .plt .got .opd
2115 and .eh_frame */
2117 /* Accept .text where mapped as rx (code), even if zero-sized */
2118 if (0 == VG_(strcmp)(name, ".text")) {
2119 if (inrx && !di->text_present) {
2120 di->text_present = True;
2121 di->text_svma = svma;
2122 di->text_avma = svma + inrx->bias;
2123 di->text_size = size;
2124 di->text_bias = inrx->bias;
2125 di->text_debug_svma = svma;
2126 di->text_debug_bias = inrx->bias;
2127 TRACE_SYMTAB("acquiring .text svma = %#lx .. %#lx\n",
2128 di->text_svma,
2129 di->text_svma + di->text_size - 1);
2130 TRACE_SYMTAB("acquiring .text avma = %#lx .. %#lx\n",
2131 di->text_avma,
2132 di->text_avma + di->text_size - 1);
2133 TRACE_SYMTAB("acquiring .text bias = %#lx\n", (UWord)di->text_bias);
2134 } else {
2135 BAD(".text");
2139 /* Accept .data where mapped as rw (data), even if zero-sized */
2140 if (0 == VG_(strcmp)(name, ".data")) {
2141 # if defined(SOLARIS_PT_SUNDWTRACE_THRP)
2142 if ((size == VKI_PT_SUNWDTRACE_SIZE) && (svma == dtrace_data_vaddr)) {
2143 TRACE_SYMTAB("ignoring .data section for dtrace_data "
2144 "%#lx .. %#lx\n", svma, svma + size - 1);
2145 } else
2146 # endif /* SOLARIS_PT_SUNDWTRACE_THRP */
2147 if (inrw && !di->data_present) {
2148 di->data_present = True;
2149 di->data_svma = svma;
2150 di->data_avma = svma + inrw->bias;
2151 di->data_size = size;
2152 di->data_bias = inrw->bias;
2153 di->data_debug_svma = svma;
2154 di->data_debug_bias = inrw->bias;
2155 TRACE_SYMTAB("acquiring .data svma = %#lx .. %#lx\n",
2156 di->data_svma,
2157 di->data_svma + di->data_size - 1);
2158 TRACE_SYMTAB("acquiring .data avma = %#lx .. %#lx\n",
2159 di->data_avma,
2160 di->data_avma + di->data_size - 1);
2161 TRACE_SYMTAB("acquiring .data bias = %#lx\n", (UWord)di->data_bias);
2162 } else {
2163 BAD(".data");
2167 /* Accept .sdata where mapped as rw (data) */
2168 if (0 == VG_(strcmp)(name, ".sdata")) {
2169 if (inrw && !di->sdata_present) {
2170 di->sdata_present = True;
2171 di->sdata_svma = svma;
2172 di->sdata_avma = svma + inrw->bias;
2173 di->sdata_size = size;
2174 di->sdata_bias = inrw->bias;
2175 di->sdata_debug_svma = svma;
2176 di->sdata_debug_bias = inrw->bias;
2177 TRACE_SYMTAB("acquiring .sdata svma = %#lx .. %#lx\n",
2178 di->sdata_svma,
2179 di->sdata_svma + di->sdata_size - 1);
2180 TRACE_SYMTAB("acquiring .sdata avma = %#lx .. %#lx\n",
2181 di->sdata_avma,
2182 di->sdata_avma + di->sdata_size - 1);
2183 TRACE_SYMTAB("acquiring .sdata bias = %#lx\n",
2184 (UWord)di->sdata_bias);
2185 } else {
2186 BAD(".sdata");
2190 /* Accept .rodata where mapped as rx or rw (data), even if zero-sized */
2191 if (0 == VG_(strcmp)(name, ".rodata")) {
2192 if (!di->rodata_present) {
2193 di->rodata_svma = svma;
2194 di->rodata_avma = svma;
2195 di->rodata_size = size;
2196 di->rodata_debug_svma = svma;
2197 if (inrx) {
2198 di->rodata_avma += inrx->bias;
2199 di->rodata_bias = inrx->bias;
2200 di->rodata_debug_bias = inrx->bias;
2201 } else if (inrw) {
2202 di->rodata_avma += inrw->bias;
2203 di->rodata_bias = inrw->bias;
2204 di->rodata_debug_bias = inrw->bias;
2205 } else {
2206 BAD(".rodata");
2208 di->rodata_present = True;
2209 TRACE_SYMTAB("acquiring .rodata svma = %#lx .. %#lx\n",
2210 di->rodata_svma,
2211 di->rodata_svma + di->rodata_size - 1);
2212 TRACE_SYMTAB("acquiring .rodata avma = %#lx .. %#lx\n",
2213 di->rodata_avma,
2214 di->rodata_avma + di->rodata_size - 1);
2215 TRACE_SYMTAB("acquiring .rodata bias = %#lx\n",
2216 (UWord)di->rodata_bias);
2217 } else {
2218 BAD(".rodata");
2222 if (0 == VG_(strcmp)(name, ".dynbss")) {
2223 if (inrw && !di->bss_present) {
2224 dynbss_present = True;
2225 di->bss_present = True;
2226 di->bss_svma = svma;
2227 di->bss_avma = svma + inrw->bias;
2228 di->bss_size = size;
2229 di->bss_bias = inrw->bias;
2230 di->bss_debug_svma = svma;
2231 di->bss_debug_bias = inrw->bias;
2232 TRACE_SYMTAB("acquiring .dynbss svma = %#lx .. %#lx\n",
2233 di->bss_svma,
2234 di->bss_svma + di->bss_size - 1);
2235 TRACE_SYMTAB("acquiring .dynbss avma = %#lx .. %#lx\n",
2236 di->bss_avma,
2237 di->bss_avma + di->bss_size - 1);
2238 TRACE_SYMTAB("acquiring .dynbss bias = %#lx\n",
2239 (UWord)di->bss_bias);
2243 /* Accept .bss where mapped as rw (data), even if zero-sized */
2244 if (0 == VG_(strcmp)(name, ".bss")) {
2245 if (inrw && dynbss_present) {
2246 vg_assert(di->bss_present);
2247 dynbss_present = False;
2248 vg_assert(di->bss_svma + di->bss_size == svma);
2249 di->bss_size += size;
2250 TRACE_SYMTAB("acquiring .bss svma = %#lx .. %#lx\n",
2251 svma, svma + size - 1);
2252 TRACE_SYMTAB("acquiring .bss avma = %#lx .. %#lx\n",
2253 svma + inrw->bias, svma + inrw->bias + size - 1);
2254 TRACE_SYMTAB("acquiring .bss bias = %#lx\n",
2255 (UWord)di->bss_bias);
2256 } else
2258 if (inrw && !di->bss_present) {
2259 di->bss_present = True;
2260 di->bss_svma = svma;
2261 di->bss_avma = svma + inrw->bias;
2262 di->bss_size = size;
2263 di->bss_bias = inrw->bias;
2264 di->bss_debug_svma = svma;
2265 di->bss_debug_bias = inrw->bias;
2266 TRACE_SYMTAB("acquiring .bss svma = %#lx .. %#lx\n",
2267 di->bss_svma,
2268 di->bss_svma + di->bss_size - 1);
2269 TRACE_SYMTAB("acquiring .bss avma = %#lx .. %#lx\n",
2270 di->bss_avma,
2271 di->bss_avma + di->bss_size - 1);
2272 TRACE_SYMTAB("acquiring .bss bias = %#lx\n",
2273 (UWord)di->bss_bias);
2274 } else
2276 /* Now one from the wtf?! department ... */
2277 if (inrx && (!inrw) && !di->bss_present) {
2278 /* File contains a .bss, but it got mapped as rx only.
2279 This is very strange. For now, just pretend we didn't
2280 see it :-) */
2281 di->bss_present = False;
2282 di->bss_svma = 0;
2283 di->bss_avma = 0;
2284 di->bss_size = 0;
2285 di->bss_bias = 0;
2286 di->bss_debug_svma = 0;
2287 di->bss_debug_bias = 0;
2288 if (!VG_(clo_xml)) {
2289 VG_(message)(Vg_UserMsg,
2290 "Warning: the following file's .bss is "
2291 "mapped r-x only - ignoring .bss syms\n");
2292 VG_(message)(Vg_UserMsg, " %s\n", di->fsm.filename
2293 ? di->fsm.filename
2294 : "(null?!)" );
2296 } else
2298 if ((!inrw) && (!inrx) && !di->bss_present) {
2299 /* File contains a .bss, but it didn't get mapped. Ignore. */
2300 di->bss_present = False;
2301 di->bss_svma = 0;
2302 di->bss_avma = 0;
2303 di->bss_size = 0;
2304 di->bss_bias = 0;
2305 } else {
2306 BAD(".bss");
2310 if (0 == VG_(strcmp)(name, ".sdynbss")) {
2311 if (inrw && !di->sbss_present) {
2312 sdynbss_present = True;
2313 di->sbss_present = True;
2314 di->sbss_svma = svma;
2315 di->sbss_avma = svma + inrw->bias;
2316 di->sbss_size = size;
2317 di->sbss_bias = inrw->bias;
2318 di->sbss_debug_svma = svma;
2319 di->sbss_debug_bias = inrw->bias;
2320 TRACE_SYMTAB("acquiring .sdynbss svma = %#lx .. %#lx\n",
2321 di->sbss_svma,
2322 di->sbss_svma + di->sbss_size - 1);
2323 TRACE_SYMTAB("acquiring .sdynbss avma = %#lx .. %#lx\n",
2324 di->sbss_avma,
2325 di->sbss_avma + di->sbss_size - 1);
2326 TRACE_SYMTAB("acquiring .sdynbss bias = %#lx\n",
2327 (UWord)di->sbss_bias);
2331 /* Accept .sbss where mapped as rw (data) */
2332 if (0 == VG_(strcmp)(name, ".sbss")) {
2333 if (inrw && sdynbss_present) {
2334 vg_assert(di->sbss_present);
2335 sdynbss_present = False;
2336 vg_assert(di->sbss_svma + di->sbss_size == svma);
2337 di->sbss_size += size;
2338 TRACE_SYMTAB("acquiring .sbss svma = %#lx .. %#lx\n",
2339 svma, svma + size - 1);
2340 TRACE_SYMTAB("acquiring .sbss avma = %#lx .. %#lx\n",
2341 svma + inrw->bias, svma + inrw->bias + size - 1);
2342 TRACE_SYMTAB("acquiring .sbss bias = %#lx\n", (UWord)di->sbss_bias);
2343 } else
2345 if (inrw && !di->sbss_present) {
2346 di->sbss_present = True;
2347 di->sbss_svma = svma;
2348 di->sbss_avma = svma + inrw->bias;
2349 di->sbss_size = size;
2350 di->sbss_bias = inrw->bias;
2351 di->sbss_debug_svma = svma;
2352 di->sbss_debug_bias = inrw->bias;
2353 TRACE_SYMTAB("acquiring .sbss svma = %#lx .. %#lx\n",
2354 di->sbss_svma,
2355 di->sbss_svma + di->sbss_size - 1);
2356 TRACE_SYMTAB("acquiring .sbss avma = %#lx .. %#lx\n",
2357 di->sbss_avma,
2358 di->sbss_avma + di->sbss_size - 1);
2359 TRACE_SYMTAB("acquiring .sbss bias = %#lx\n", (UWord)di->sbss_bias);
2360 } else {
2361 BAD(".sbss");
2365 /* Accept .got where mapped as rw (data) */
2366 if (0 == VG_(strcmp)(name, ".got")) {
2367 if (inrw && !di->got_present) {
2368 di->got_present = True;
2369 di->got_avma = svma + inrw->bias;
2370 di->got_size = size;
2371 TRACE_SYMTAB("acquiring .got avma = %#lx\n", di->got_avma);
2372 } else {
2373 BAD(".got");
2377 /* Accept .got.plt where mapped as rw (data) */
2378 if (0 == VG_(strcmp)(name, ".got.plt")) {
2379 if (inrw && !di->gotplt_present) {
2380 di->gotplt_present = True;
2381 di->gotplt_avma = svma + inrw->bias;
2382 di->gotplt_size = size;
2383 TRACE_SYMTAB("acquiring .got.plt avma = %#lx\n", di->gotplt_avma);
2384 } else if (size != 0) {
2385 BAD(".got.plt");
2389 /* PLT is different on different platforms, it seems. */
2390 # if defined(VGP_x86_linux) || defined(VGP_amd64_linux) \
2391 || defined(VGP_arm_linux) || defined (VGP_s390x_linux) \
2392 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
2393 || defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) \
2394 || defined(VGP_x86_solaris) || defined(VGP_amd64_solaris)
2395 /* Accept .plt where mapped as rx (code) */
2396 if (0 == VG_(strcmp)(name, ".plt")) {
2397 if (inrx && !di->plt_present) {
2398 di->plt_present = True;
2399 di->plt_avma = svma + inrx->bias;
2400 di->plt_size = size;
2401 TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
2402 } else {
2403 BAD(".plt");
2406 # elif defined(VGP_ppc32_linux)
2407 /* Accept .plt where mapped as rw (data) */
2408 if (0 == VG_(strcmp)(name, ".plt")) {
2409 if (inrw && !di->plt_present) {
2410 di->plt_present = True;
2411 di->plt_avma = svma + inrw->bias;
2412 di->plt_size = size;
2413 TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
2414 } else {
2415 BAD(".plt");
2418 # elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
2419 /* Accept .plt where mapped as rw (data), or unmapped */
2420 if (0 == VG_(strcmp)(name, ".plt")) {
2421 if (inrw && !di->plt_present) {
2422 di->plt_present = True;
2423 di->plt_avma = svma + inrw->bias;
2424 di->plt_size = size;
2425 TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
2426 } else
2427 if ((!inrw) && (!inrx) && size > 0 && !di->plt_present) {
2428 /* File contains a .plt, but it didn't get mapped.
2429 Presumably it is not required on this platform. At
2430 least don't reject the situation as invalid. */
2431 di->plt_present = True;
2432 di->plt_avma = 0;
2433 di->plt_size = 0;
2434 } else {
2435 BAD(".plt");
2438 # else
2439 # error "Unsupported platform"
2440 # endif
2442 /* Accept .opd where mapped as rw (data) */
2443 if (0 == VG_(strcmp)(name, ".opd")) {
2444 if (inrw && !di->opd_present) {
2445 di->opd_present = True;
2446 di->opd_avma = svma + inrw->bias;
2447 di->opd_size = size;
2448 TRACE_SYMTAB("acquiring .opd avma = %#lx\n", di->opd_avma);
2449 } else {
2450 BAD(".opd");
2454 /* Accept .eh_frame where mapped as rx (code). This seems to be
2455 the common case. However, if that doesn't pan out, try for
2456 rw (data) instead. We can handle up to N_EHFRAME_SECTS per
2457 ELF object. */
2458 if (0 == VG_(strcmp)(name, ".eh_frame")) {
2459 if (inrx && di->n_ehframe < N_EHFRAME_SECTS) {
2460 di->ehframe_avma[di->n_ehframe] = svma + inrx->bias;
2461 di->ehframe_size[di->n_ehframe] = size;
2462 TRACE_SYMTAB("acquiring .eh_frame avma = %#lx\n",
2463 di->ehframe_avma[di->n_ehframe]);
2464 di->n_ehframe++;
2465 } else
2466 if (inrw && di->n_ehframe < N_EHFRAME_SECTS) {
2467 di->ehframe_avma[di->n_ehframe] = svma + inrw->bias;
2468 di->ehframe_size[di->n_ehframe] = size;
2469 TRACE_SYMTAB("acquiring .eh_frame avma = %#lx\n",
2470 di->ehframe_avma[di->n_ehframe]);
2471 di->n_ehframe++;
2472 } else {
2473 BAD(".eh_frame");
2477 /* Accept .ARM.exidx where mapped as rx (code). */
2478 /* FIXME: make sure the entire section is mapped in, not just
2479 the first address. */
2480 if (0 == VG_(strcmp)(name, ".ARM.exidx")) {
2481 if (inrx && !di->exidx_present) {
2482 di->exidx_present = True;
2483 di->exidx_svma = svma;
2484 di->exidx_avma = svma + inrx->bias;
2485 di->exidx_size = size;
2486 di->exidx_bias = inrx->bias;
2487 TRACE_SYMTAB("acquiring .exidx svma = %#lx .. %#lx\n",
2488 di->exidx_svma,
2489 di->exidx_svma + di->exidx_size - 1);
2490 TRACE_SYMTAB("acquiring .exidx avma = %#lx .. %#lx\n",
2491 di->exidx_avma,
2492 di->exidx_avma + di->exidx_size - 1);
2493 TRACE_SYMTAB("acquiring .exidx bias = %#lx\n",
2494 (UWord)di->exidx_bias);
2495 } else {
2496 BAD(".ARM.exidx");
2500 /* Accept .ARM.extab where mapped as rx (code). */
2501 /* FIXME: make sure the entire section is mapped in, not just
2502 the first address. */
2503 if (0 == VG_(strcmp)(name, ".ARM.extab")) {
2504 if (inrx && !di->extab_present) {
2505 di->extab_present = True;
2506 di->extab_svma = svma;
2507 di->extab_avma = svma + inrx->bias;
2508 di->extab_size = size;
2509 di->extab_bias = inrx->bias;
2510 TRACE_SYMTAB("acquiring .extab svma = %#lx .. %#lx\n",
2511 di->extab_svma,
2512 di->extab_svma + di->extab_size - 1);
2513 TRACE_SYMTAB("acquiring .extab avma = %#lx .. %#lx\n",
2514 di->extab_avma,
2515 di->extab_avma + di->extab_size - 1);
2516 TRACE_SYMTAB("acquiring .extab bias = %#lx\n",
2517 (UWord)di->extab_bias);
2518 } else {
2519 BAD(".ARM.extab");
2523 ML_(dinfo_free)(name);
2525 # undef BAD
2527 } /* iterate over the section headers */
2529 /* TOPLEVEL */
2530 if (0) VG_(printf)("YYYY text_: avma %#lx size %lu bias %#lx\n",
2531 di->text_avma, di->text_size, (UWord)di->text_bias);
2533 if (VG_(clo_verbosity) > 2 || VG_(clo_trace_redir))
2534 VG_(message)(Vg_DebugMsg, " svma %#010lx, avma %#010lx\n",
2535 di->text_avma - di->text_bias,
2536 di->text_avma );
2538 TRACE_SYMTAB("\n");
2539 TRACE_SYMTAB("------ Finding image addresses "
2540 "for debug-info sections ------\n");
2542 /* TOPLEVEL */
2543 /* Find interesting sections, read the symbol table(s), read any
2544 debug information. Each section is located either in the main,
2545 debug or alt-debug files, but only in one. For each section,
2546 |section_escn| records which of |mimg|, |dimg| or |aimg| we
2547 found it in, along with the section's image offset and its size.
2548 The triples (section_img, section_ioff, section_szB) are
2549 consistent, in that they are always either (NULL,
2550 DiOffT_INVALID, 0), or refer to the same image, and are all
2551 assigned together. */
2553 /* TOPLEVEL */
2554 DiSlice strtab_escn = DiSlice_INVALID; // .strtab
2555 DiSlice symtab_escn = DiSlice_INVALID; // .symtab
2556 DiSlice dynstr_escn = DiSlice_INVALID; // .dynstr
2557 DiSlice dynsym_escn = DiSlice_INVALID; // .dynsym
2558 # if defined(VGO_solaris)
2559 DiSlice ldynsym_escn = DiSlice_INVALID; // .SUNW_ldynsym
2560 # endif
2561 DiSlice debuglink_escn = DiSlice_INVALID; // .gnu_debuglink
2562 DiSlice debugaltlink_escn = DiSlice_INVALID; // .gnu_debugaltlink
2563 DiSlice debug_line_escn = DiSlice_INVALID; // .debug_line (dwarf2)
2564 DiSlice debug_info_escn = DiSlice_INVALID; // .debug_info (dwarf2)
2565 DiSlice debug_types_escn = DiSlice_INVALID; // .debug_types (dwarf4)
2566 DiSlice debug_abbv_escn = DiSlice_INVALID; // .debug_abbrev (dwarf2)
2567 DiSlice debug_str_escn = DiSlice_INVALID; // .debug_str (dwarf2)
2568 DiSlice debug_ranges_escn = DiSlice_INVALID; // .debug_ranges (dwarf2)
2569 DiSlice debug_loc_escn = DiSlice_INVALID; // .debug_loc (dwarf2)
2570 DiSlice debug_frame_escn = DiSlice_INVALID; // .debug_frame (dwarf2)
2571 DiSlice debug_line_alt_escn = DiSlice_INVALID; // .debug_line (alt)
2572 DiSlice debug_info_alt_escn = DiSlice_INVALID; // .debug_info (alt)
2573 DiSlice debug_abbv_alt_escn = DiSlice_INVALID; // .debug_abbrev (alt)
2574 DiSlice debug_str_alt_escn = DiSlice_INVALID; // .debug_str (alt)
2575 DiSlice dwarf1d_escn = DiSlice_INVALID; // .debug (dwarf1)
2576 DiSlice dwarf1l_escn = DiSlice_INVALID; // .line (dwarf1)
2577 DiSlice opd_escn = DiSlice_INVALID; // .opd (dwarf2,
2578 // ppc64be-linux)
2579 DiSlice ehframe_escn[N_EHFRAME_SECTS]; // .eh_frame (dwarf2)
2581 for (i = 0; i < N_EHFRAME_SECTS; i++)
2582 ehframe_escn[i] = DiSlice_INVALID;
2584 /* Find all interesting sections */
2586 UInt ehframe_mix = 0;
2588 /* What FIND does: it finds the section called _SEC_NAME. The
2589 size of it is assigned to _SEC_SIZE. The address of the
2590 section in the transiently loaded oimage is assigned to
2591 _SEC_IMG. If the section is found, _POST_FX is executed
2592 after _SEC_NAME and _SEC_SIZE have been assigned to.
2594 Even for sections which are marked loadable, the client's
2595 ld.so may not have loaded them yet, so there is no guarantee
2596 that we can safely prod around in any such area). Because
2597 the entire object file is transiently mapped aboard for
2598 inspection, it's always safe to inspect that area. */
2600 /* TOPLEVEL */
2601 /* Iterate over section headers (again) */
2602 for (i = 0; i < ehdr_m.e_shnum; i++) {
2604 # define FINDX(_sec_name, _sec_escn, _post_fx) \
2605 do { \
2606 ElfXX_Shdr a_shdr; \
2607 ML_(img_get)(&a_shdr, mimg, \
2608 INDEX_BIS(shdr_mioff, i, shdr_ment_szB), \
2609 sizeof(a_shdr)); \
2610 if (0 == ML_(img_strcmp_c)(mimg, shdr_strtab_mioff \
2611 + a_shdr.sh_name, _sec_name)) { \
2612 Bool nobits; \
2613 _sec_escn.img = mimg; \
2614 _sec_escn.ioff = (DiOffT)a_shdr.sh_offset; \
2615 _sec_escn.szB = a_shdr.sh_size; \
2616 if (!check_compression(&a_shdr, &_sec_escn)) { \
2617 ML_(symerr)(di, True, " Compression type is unsupported"); \
2618 goto out; \
2620 nobits = a_shdr.sh_type == SHT_NOBITS; \
2621 vg_assert(_sec_escn.img != NULL); \
2622 vg_assert(_sec_escn.ioff != DiOffT_INVALID); \
2623 TRACE_SYMTAB( "%-18s: ioff %llu .. %llu\n", \
2624 _sec_name, (ULong)a_shdr.sh_offset, \
2625 ((ULong)a_shdr.sh_offset) + a_shdr.sh_size - 1); \
2626 /* SHT_NOBITS sections have zero size in the file. */ \
2627 if (!nobits && \
2628 a_shdr.sh_offset + \
2629 a_shdr.sh_size > ML_(img_real_size)(mimg)) { \
2630 ML_(symerr)(di, True, \
2631 " section beyond image end?!"); \
2632 goto out; \
2634 _post_fx; \
2636 } while (0);
2638 /* Version with no post-effects */
2639 # define FIND(_sec_name, _sec_escn) \
2640 FINDX(_sec_name, _sec_escn, /**/)
2642 /* NAME ElfSec */
2643 FIND( ".dynsym", dynsym_escn)
2644 FIND( ".dynstr", dynstr_escn)
2645 FIND( ".symtab", symtab_escn)
2646 FIND( ".strtab", strtab_escn)
2647 # if defined(VGO_solaris)
2648 FIND( ".SUNW_ldynsym", ldynsym_escn)
2649 # endif
2651 FIND( ".gnu_debuglink", debuglink_escn)
2652 FIND( ".gnu_debugaltlink", debugaltlink_escn)
2654 FIND( ".debug_line", debug_line_escn)
2655 if (!ML_(sli_is_valid)(debug_line_escn))
2656 FIND(".zdebug_line", debug_line_escn)
2658 FIND( ".debug_info", debug_info_escn)
2659 if (!ML_(sli_is_valid)(debug_info_escn))
2660 FIND(".zdebug_info", debug_info_escn)
2662 FIND( ".debug_types", debug_types_escn)
2663 if (!ML_(sli_is_valid)(debug_types_escn))
2664 FIND(".zdebug_types", debug_types_escn)
2666 FIND( ".debug_abbrev", debug_abbv_escn)
2667 if (!ML_(sli_is_valid)(debug_abbv_escn))
2668 FIND(".zdebug_abbrev", debug_abbv_escn)
2670 FIND( ".debug_str", debug_str_escn)
2671 if (!ML_(sli_is_valid)(debug_str_escn))
2672 FIND(".zdebug_str", debug_str_escn)
2674 FIND( ".debug_ranges", debug_ranges_escn)
2675 if (!ML_(sli_is_valid)(debug_ranges_escn))
2676 FIND(".zdebug_ranges", debug_ranges_escn)
2678 FIND( ".debug_loc", debug_loc_escn)
2679 if (!ML_(sli_is_valid)(debug_loc_escn))
2680 FIND(".zdebug_loc", debug_loc_escn)
2682 FIND( ".debug_frame", debug_frame_escn)
2683 if (!ML_(sli_is_valid)(debug_frame_escn))
2684 FIND(".zdebug_frame", debug_frame_escn)
2686 FIND( ".debug", dwarf1d_escn)
2687 FIND( ".line", dwarf1l_escn)
2689 FIND( ".opd", opd_escn)
2691 FINDX( ".eh_frame", ehframe_escn[ehframe_mix],
2692 do { ehframe_mix++; vg_assert(ehframe_mix <= N_EHFRAME_SECTS);
2693 } while (0)
2695 /* Comment_on_EH_FRAME_MULTIPLE_INSTANCES: w.r.t. .eh_frame
2696 multi-instance kludgery, how are we assured that the order
2697 in which we fill in ehframe_escn[] is consistent with the
2698 order in which we previously filled in di->ehframe_avma[]
2699 and di->ehframe_size[] ? By the fact that in both cases,
2700 these arrays were filled in by iterating over the section
2701 headers top-to-bottom. So both loops (this one and the
2702 previous one) encounter the .eh_frame entries in the same
2703 order and so fill in these arrays in a consistent order.
2706 # undef FINDX
2707 # undef FIND
2708 } /* Iterate over section headers (again) */
2710 /* TOPLEVEL */
2711 /* Now, see if we can find a debuginfo object, and if so connect
2712 |dimg| to it. */
2713 vg_assert(dimg == NULL && aimg == NULL);
2715 /* Look for a build-id */
2716 HChar* buildid = find_buildid(mimg, False, False);
2718 /* Look for a debug image that matches either the build-id or
2719 the debuglink-CRC32 in the main image. If the main image
2720 doesn't contain either of those then this won't even bother
2721 to try looking. This looks in all known places, including
2722 the --extra-debuginfo-path if specified and on the
2723 --debuginfo-server if specified. */
2724 if (buildid != NULL || debuglink_escn.img != NULL) {
2725 /* Do have a debuglink section? */
2726 if (debuglink_escn.img != NULL) {
2727 UInt crc_offset
2728 = VG_ROUNDUP(ML_(img_strlen)(debuglink_escn.img,
2729 debuglink_escn.ioff)+1, 4);
2730 vg_assert(crc_offset + sizeof(UInt) <= debuglink_escn.szB);
2732 /* Extract the CRC from the debuglink section */
2733 UInt crc = ML_(img_get_UInt)(debuglink_escn.img,
2734 debuglink_escn.ioff + crc_offset);
2736 /* See if we can find a matching debug file */
2737 HChar* debuglink_str_m
2738 = ML_(img_strdup)(debuglink_escn.img,
2739 "di.redi_dlk.1", debuglink_escn.ioff);
2740 dimg = find_debug_file( di, di->fsm.filename, buildid,
2741 debuglink_str_m, crc, False );
2742 if (debuglink_str_m)
2743 ML_(dinfo_free)(debuglink_str_m);
2744 } else {
2745 /* See if we can find a matching debug file */
2746 dimg = find_debug_file( di, di->fsm.filename, buildid,
2747 NULL, 0, False );
2751 if (buildid) {
2752 ML_(dinfo_free)(buildid);
2753 buildid = NULL; /* paranoia */
2756 /* As a last-ditch measure, try looking for in the
2757 --extra-debuginfo-path and/or on the --debuginfo-server, but
2758 only in the case where --allow-mismatched-debuginfo=yes.
2759 This is dangerous in that (1) it gives no assurance that the
2760 debuginfo object matches the main one, and hence (2) we will
2761 very likely get an assertion in the code below, if indeed
2762 there is a mismatch. Hence it is disabled by default
2763 (--allow-mismatched-debuginfo=no). Nevertheless it's
2764 sometimes a useful way of getting out of a tight spot.
2766 Note that we're ignoring the name in the .gnu_debuglink
2767 section here, and just looking for a file of the same name
2768 either the extra-path or on the server. */
2769 if (dimg == NULL && VG_(clo_allow_mismatched_debuginfo)) {
2770 dimg = find_debug_file_ad_hoc( di, di->fsm.filename );
2773 /* TOPLEVEL */
2774 /* If we were successful in finding a debug image, pull various
2775 SVMA/bias/size and image addresses out of it. */
2776 if (dimg != NULL && is_elf_object_file_by_DiImage(dimg, False)) {
2778 /* Pull out and validate program header and section header info */
2779 DiOffT ehdr_dioff = 0;
2780 ElfXX_Ehdr ehdr_dimg;
2781 ML_(img_get)(&ehdr_dimg, dimg, ehdr_dioff, sizeof(ehdr_dimg));
2783 DiOffT phdr_dioff = ehdr_dimg.e_phoff;
2784 UWord phdr_dnent = ehdr_dimg.e_phnum;
2785 UWord phdr_dent_szB = ehdr_dimg.e_phentsize;
2787 DiOffT shdr_dioff = ehdr_dimg.e_shoff;
2788 UWord shdr_dnent = ehdr_dimg.e_shnum;
2789 UWord shdr_dent_szB = ehdr_dimg.e_shentsize;
2791 DiOffT shdr_strtab_dioff = DiOffT_INVALID;
2793 /* SVMAs covered by rx and rw segments and corresponding bias. */
2794 Addr rx_dsvma_limit = 0;
2795 PtrdiffT rx_dbias = 0;
2796 Addr rw_dsvma_limit = 0;
2797 PtrdiffT rw_dbias = 0;
2799 Bool need_symtab, need_dwarf2, need_dwarf1;
2801 if (phdr_dnent == 0
2802 || !ML_(img_valid)(dimg, phdr_dioff,
2803 phdr_dnent * phdr_dent_szB)) {
2804 ML_(symerr)(di, True,
2805 "Missing or invalid ELF Program Header Table"
2806 " (debuginfo file)");
2807 goto out;
2810 if (shdr_dnent == 0
2811 || !ML_(img_valid)(dimg, shdr_dioff,
2812 shdr_dnent * shdr_dent_szB)) {
2813 ML_(symerr)(di, True,
2814 "Missing or invalid ELF Section Header Table"
2815 " (debuginfo file)");
2816 goto out;
2819 /* Also find the section header's string table, and validate. */
2820 /* checked previously by is_elf_object_file: */
2821 vg_assert(ehdr_dimg.e_shstrndx != SHN_UNDEF);
2823 // shdr_dioff is the offset of the section header table
2824 // and we need the ehdr_dimg.e_shstrndx'th entry
2825 { ElfXX_Shdr a_shdr;
2826 ML_(img_get)(&a_shdr, dimg,
2827 INDEX_BIS(shdr_dioff, ehdr_dimg.e_shstrndx,
2828 shdr_dent_szB),
2829 sizeof(a_shdr));
2830 shdr_strtab_dioff = a_shdr.sh_offset;
2831 if (!ML_(img_valid)(dimg, shdr_strtab_dioff,
2832 1/*bogus, but we don't know the real size*/)) {
2833 ML_(symerr)(di, True,
2834 "Invalid ELF Section Header String Table"
2835 " (debuginfo file)");
2836 goto out;
2840 for (i = 0; i < ehdr_dimg.e_phnum; i++) {
2841 ElfXX_Phdr a_phdr;
2842 ML_(img_get)(&a_phdr, dimg, INDEX_BIS(ehdr_dimg.e_phoff,
2843 i, phdr_dent_szB),
2844 sizeof(a_phdr));
2845 if (a_phdr.p_type == PT_LOAD) {
2846 for (j = 0; j < VG_(sizeXA)(di->fsm.maps); j++) {
2847 const DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, j);
2848 if ( a_phdr.p_offset >= map->foff
2849 && a_phdr.p_offset < map->foff + map->size
2850 && a_phdr.p_offset + a_phdr.p_filesz
2851 < map->foff + map->size) {
2852 if (map->rx && rx_dsvma_limit == 0) {
2853 rx_dsvma_limit = a_phdr.p_vaddr + a_phdr.p_memsz;
2854 rx_dbias = map->avma - map->foff + a_phdr.p_offset
2855 - a_phdr.p_vaddr;
2857 if (map->rw && rw_dsvma_limit == 0) {
2858 rw_dsvma_limit = a_phdr.p_vaddr + a_phdr.p_memsz;
2859 rw_dbias = map->avma - map->foff + a_phdr.p_offset
2860 - a_phdr.p_vaddr;
2862 break;
2868 need_symtab = (symtab_escn.img == NULL);
2869 need_dwarf2 = (debug_info_escn.img == NULL);
2870 need_dwarf1 = (dwarf1d_escn.img == NULL);
2872 /* Find all interesting sections in the debug image */
2873 for (i = 0; i < ehdr_dimg.e_shnum; i++) {
2875 /* Find debug svma and bias information for sections
2876 we found in the main file. */
2878 # define FIND(_sec, _seg) \
2879 do { \
2880 ElfXX_Shdr a_shdr; \
2881 ML_(img_get)(&a_shdr, dimg, \
2882 INDEX_BIS(shdr_dioff, i, shdr_dent_szB), \
2883 sizeof(a_shdr)); \
2884 if (di->_sec##_present \
2885 && 0 == ML_(img_strcmp_c)(dimg, shdr_strtab_dioff \
2886 + a_shdr.sh_name, "." #_sec)) { \
2887 vg_assert(di->_sec##_size == a_shdr.sh_size); \
2888 /* JRS 2013-Jun-01: the following assert doesn't contain */ \
2889 /* any ==s, which seems to me to be suspicious. */ \
2890 vg_assert(di->_sec##_avma + a_shdr.sh_addr + _seg##_dbias); \
2891 /* Assume we have a correct value for the main */ \
2892 /* object's bias. Use that to derive the debuginfo */ \
2893 /* object's bias, by adding the difference in SVMAs */ \
2894 /* for the corresponding sections in the two files. */ \
2895 /* That should take care of all prelinking effects. */ \
2896 di->_sec##_debug_svma = a_shdr.sh_addr; \
2897 di->_sec##_debug_bias \
2898 = di->_sec##_bias + \
2899 di->_sec##_svma - di->_sec##_debug_svma; \
2900 TRACE_SYMTAB("acquiring ." #_sec \
2901 " debug svma = %#lx .. %#lx\n", \
2902 di->_sec##_debug_svma, \
2903 di->_sec##_debug_svma + di->_sec##_size - 1); \
2904 TRACE_SYMTAB("acquiring ." #_sec " debug bias = %#lx\n", \
2905 (UWord)di->_sec##_debug_bias); \
2907 } while (0);
2909 /* SECTION SEGMENT */
2910 FIND(text, rx)
2911 FIND(data, rw)
2912 FIND(sdata, rw)
2913 FIND(rodata, rw)
2914 FIND(bss, rw)
2915 FIND(sbss, rw)
2917 # undef FIND
2919 /* Same deal as previous FIND, except only do it for those
2920 sections which we didn't find in the main file. */
2922 # define FIND(_condition, _sec_name, _sec_escn) \
2923 do { \
2924 ElfXX_Shdr a_shdr; \
2925 ML_(img_get)(&a_shdr, dimg, \
2926 INDEX_BIS(shdr_dioff, i, shdr_dent_szB), \
2927 sizeof(a_shdr)); \
2928 if (_condition \
2929 && 0 == ML_(img_strcmp_c)(dimg, shdr_strtab_dioff \
2930 + a_shdr.sh_name, _sec_name)) { \
2931 Bool nobits; \
2932 if (_sec_escn.img != NULL) { \
2933 ML_(symerr)(di, True, \
2934 " debuginfo section duplicates a" \
2935 " section in the main ELF file"); \
2936 goto out; \
2938 _sec_escn.img = dimg; \
2939 _sec_escn.ioff = (DiOffT)a_shdr.sh_offset; \
2940 _sec_escn.szB = a_shdr.sh_size; \
2941 if (!check_compression(&a_shdr, &_sec_escn)) { \
2942 ML_(symerr)(di, True, " Compression type is unsupported"); \
2943 goto out; \
2945 nobits = a_shdr.sh_type == SHT_NOBITS; \
2946 vg_assert(_sec_escn.img != NULL); \
2947 vg_assert(_sec_escn.ioff != DiOffT_INVALID); \
2948 TRACE_SYMTAB( "%-18s: dioff %llu .. %llu\n", \
2949 _sec_name, \
2950 (ULong)a_shdr.sh_offset, \
2951 ((ULong)a_shdr.sh_offset) + a_shdr.sh_size - 1); \
2952 /* SHT_NOBITS sections have zero size in the file. */ \
2953 if (!nobits && a_shdr.sh_offset \
2954 + a_shdr.sh_size > ML_(img_real_size)(_sec_escn.img)) { \
2955 ML_(symerr)(di, True, \
2956 " section beyond image end?!"); \
2957 goto out; \
2960 } while (0);
2962 /* NEEDED? NAME ElfSec */
2963 FIND( need_symtab, ".symtab", symtab_escn)
2964 FIND( need_symtab, ".strtab", strtab_escn)
2965 FIND( need_dwarf2, ".debug_line", debug_line_escn)
2966 if (!ML_(sli_is_valid)(debug_line_escn))
2967 FIND(need_dwarf2, ".zdebug_line", debug_line_escn)
2969 FIND( need_dwarf2, ".debug_info", debug_info_escn)
2970 if (!ML_(sli_is_valid)(debug_info_escn))
2971 FIND(need_dwarf2, ".zdebug_info", debug_info_escn)
2973 FIND( need_dwarf2, ".debug_types", debug_types_escn)
2974 if (!ML_(sli_is_valid)(debug_types_escn))
2975 FIND(need_dwarf2, ".zdebug_types", debug_types_escn)
2977 FIND( need_dwarf2, ".debug_abbrev", debug_abbv_escn)
2978 if (!ML_(sli_is_valid)(debug_abbv_escn))
2979 FIND(need_dwarf2, ".zdebug_abbrev", debug_abbv_escn)
2981 FIND( need_dwarf2, ".debug_str", debug_str_escn)
2982 if (!ML_(sli_is_valid)(debug_str_escn))
2983 FIND(need_dwarf2, ".zdebug_str", debug_str_escn)
2985 FIND( need_dwarf2, ".debug_ranges", debug_ranges_escn)
2986 if (!ML_(sli_is_valid)(debug_ranges_escn))
2987 FIND(need_dwarf2, ".zdebug_ranges", debug_ranges_escn)
2989 FIND( need_dwarf2, ".debug_loc", debug_loc_escn)
2990 if (!ML_(sli_is_valid)(debug_loc_escn))
2991 FIND(need_dwarf2, ".zdebug_loc", debug_loc_escn)
2993 FIND( need_dwarf2, ".debug_frame", debug_frame_escn)
2994 if (!ML_(sli_is_valid)(debug_frame_escn))
2995 FIND(need_dwarf2, ".zdebug_frame", debug_frame_escn)
2997 FIND( need_dwarf2, ".gnu_debugaltlink", debugaltlink_escn)
2999 FIND( need_dwarf1, ".debug", dwarf1d_escn)
3000 FIND( need_dwarf1, ".line", dwarf1l_escn)
3002 # undef FIND
3003 } /* Find all interesting sections */
3004 } /* do we have a debug image? */
3006 /* TOPLEVEL */
3007 /* Look for alternate debug image, and if found, connect |aimg|
3008 to it. */
3009 vg_assert(aimg == NULL);
3011 if (debugaltlink_escn.img != NULL) {
3012 HChar* altfile_str_m
3013 = ML_(img_strdup)(debugaltlink_escn.img,
3014 "di.fbi.3", debugaltlink_escn.ioff);
3015 UInt buildid_offset = ML_(img_strlen)(debugaltlink_escn.img,
3016 debugaltlink_escn.ioff)+1;
3018 vg_assert(buildid_offset < debugaltlink_escn.szB);
3020 HChar *altbuildid
3021 = ML_(dinfo_zalloc)("di.fbi.4",
3022 (debugaltlink_escn.szB - buildid_offset)
3023 * 2 + 1);
3025 /* The altfile might be relative to the debug file or main file.
3026 Make sure that we got the real file, not a symlink. */
3027 HChar *dbgname = di->fsm.dbgname ? di->fsm.dbgname : di->fsm.filename;
3028 HChar* rdbgname = readlink_path (dbgname);
3029 if (rdbgname == NULL)
3030 rdbgname = ML_(dinfo_strdup)("rdbgname", dbgname);
3032 for (j = 0; j < debugaltlink_escn.szB - buildid_offset; j++)
3033 VG_(sprintf)(
3034 altbuildid + 2 * j, "%02x",
3035 (UInt)ML_(img_get_UChar)(debugaltlink_escn.img,
3036 debugaltlink_escn.ioff
3037 + buildid_offset + j));
3039 /* See if we can find a matching debug file */
3040 aimg = find_debug_file( di, rdbgname, altbuildid,
3041 altfile_str_m, 0, True );
3043 ML_(dinfo_free)(rdbgname);
3045 if (altfile_str_m)
3046 ML_(dinfo_free)(altfile_str_m);
3047 ML_(dinfo_free)(altbuildid);
3050 /* TOPLEVEL */
3051 /* If we were successful in finding alternate debug image, pull various
3052 size and image addresses out of it. */
3053 if (aimg != NULL && is_elf_object_file_by_DiImage(aimg, True)) {
3055 /* Pull out and validate program header and section header info */
3056 DiOffT ehdr_aioff = 0;
3057 ElfXX_Ehdr ehdr_aimg;
3058 ML_(img_get)(&ehdr_aimg, aimg, ehdr_aioff, sizeof(ehdr_aimg));
3060 DiOffT shdr_aioff = ehdr_aimg.e_shoff;
3061 UWord shdr_anent = ehdr_aimg.e_shnum;
3062 UWord shdr_aent_szB = ehdr_aimg.e_shentsize;
3064 DiOffT shdr_strtab_aioff = DiOffT_INVALID;
3066 if (shdr_anent == 0
3067 || !ML_(img_valid)(aimg, shdr_aioff,
3068 shdr_anent * shdr_aent_szB)) {
3069 ML_(symerr)(di, True,
3070 "Missing or invalid ELF Section Header Table"
3071 " (alternate debuginfo file)");
3072 goto out;
3075 /* Also find the section header's string table, and validate. */
3076 /* checked previously by is_elf_object_file: */
3077 vg_assert(ehdr_aimg.e_shstrndx != SHN_UNDEF);
3079 // shdr_aioff is the offset of the section header table
3080 // and we need the ehdr_aimg.e_shstrndx'th entry
3081 { ElfXX_Shdr a_shdr;
3082 ML_(img_get)(&a_shdr, aimg,
3083 INDEX_BIS(shdr_aioff, ehdr_aimg.e_shstrndx,
3084 shdr_aent_szB),
3085 sizeof(a_shdr));
3086 shdr_strtab_aioff = a_shdr.sh_offset;
3087 if (!ML_(img_valid)(aimg, shdr_strtab_aioff,
3088 1/*bogus, but we don't know the real size*/)) {
3089 ML_(symerr)(di, True,
3090 "Invalid ELF Section Header String Table"
3091 " (alternate debuginfo file)");
3092 goto out;
3096 /* Find all interesting sections */
3097 for (i = 0; i < ehdr_aimg.e_shnum; i++) {
3099 # define FIND(_sec_name, _sec_escn) \
3100 do { \
3101 ElfXX_Shdr a_shdr; \
3102 ML_(img_get)(&a_shdr, aimg, \
3103 INDEX_BIS(shdr_aioff, i, shdr_aent_szB), \
3104 sizeof(a_shdr)); \
3105 if (0 == ML_(img_strcmp_c)(aimg, shdr_strtab_aioff \
3106 + a_shdr.sh_name, _sec_name)) { \
3107 if (_sec_escn.img != NULL) { \
3108 ML_(symerr)(di, True, \
3109 " alternate debuginfo section duplicates a" \
3110 " section in the main ELF file"); \
3111 goto out; \
3113 _sec_escn.img = aimg; \
3114 _sec_escn.ioff = (DiOffT)a_shdr.sh_offset; \
3115 _sec_escn.szB = a_shdr.sh_size; \
3116 if (!check_compression(&a_shdr, &_sec_escn)) { \
3117 ML_(symerr)(di, True, " Compression type is " \
3118 "unsupported"); \
3119 goto out; \
3121 vg_assert(_sec_escn.img != NULL); \
3122 vg_assert(_sec_escn.ioff != DiOffT_INVALID); \
3123 TRACE_SYMTAB( "%-18s: aioff %llu .. %llu\n", \
3124 _sec_name, \
3125 (ULong)a_shdr.sh_offset, \
3126 ((ULong)a_shdr.sh_offset) + a_shdr.sh_size - 1); \
3128 } while (0);
3130 /* NAME ElfSec */
3131 FIND(".debug_line", debug_line_alt_escn)
3132 if (!ML_(sli_is_valid)(debug_line_alt_escn))
3133 FIND(".zdebug_line", debug_line_alt_escn)
3135 FIND(".debug_info", debug_info_alt_escn)
3136 if (!ML_(sli_is_valid)(debug_info_alt_escn))
3137 FIND(".zdebug_info", debug_info_alt_escn)
3139 FIND(".debug_abbrev", debug_abbv_alt_escn)
3140 if (!ML_(sli_is_valid)(debug_abbv_alt_escn))
3141 FIND(".zdebug_abbrev", debug_abbv_alt_escn)
3143 FIND(".debug_str", debug_str_alt_escn)
3144 if (!ML_(sli_is_valid)(debug_str_alt_escn))
3145 FIND(".zdebug_str", debug_str_alt_escn)
3147 # undef FIND
3148 } /* Find all interesting sections */
3149 } /* do we have a debug image? */
3152 /* TOPLEVEL */
3153 /* Check some sizes */
3154 vg_assert((dynsym_escn.szB % sizeof(ElfXX_Sym)) == 0);
3155 vg_assert((symtab_escn.szB % sizeof(ElfXX_Sym)) == 0);
3156 # if defined(VGO_solaris)
3157 vg_assert((ldynsym_escn.szB % sizeof(ElfXX_Sym)) == 0);
3158 # endif
3160 /* TOPLEVEL */
3161 /* Read symbols */
3163 void (*read_elf_symtab)(struct _DebugInfo*, const HChar*,
3164 DiSlice*, DiSlice*, DiSlice*, Bool);
3165 Bool symtab_in_debug;
3166 # if defined(VGP_ppc64be_linux)
3167 read_elf_symtab = read_elf_symtab__ppc64be_linux;
3168 # else
3169 read_elf_symtab = read_elf_symtab__normal;
3170 # endif
3171 symtab_in_debug = symtab_escn.img == dimg;
3172 read_elf_symtab(di, "symbol table",
3173 &symtab_escn, &strtab_escn, &opd_escn,
3174 symtab_in_debug);
3175 read_elf_symtab(di, "dynamic symbol table",
3176 &dynsym_escn, &dynstr_escn, &opd_escn,
3177 False);
3178 # if defined(VGO_solaris)
3179 read_elf_symtab(di, "local dynamic symbol table",
3180 &ldynsym_escn, &dynstr_escn, &opd_escn,
3181 False);
3182 # endif
3185 /* TOPLEVEL */
3186 /* Read .eh_frame and .debug_frame (call-frame-info) if any. Do
3187 the .eh_frame section(s) first. */
3188 vg_assert(di->n_ehframe >= 0 && di->n_ehframe <= N_EHFRAME_SECTS);
3189 for (i = 0; i < di->n_ehframe; i++) {
3190 /* see Comment_on_EH_FRAME_MULTIPLE_INSTANCES above for why
3191 this next assertion should hold. */
3192 vg_assert(ML_(sli_is_valid)(ehframe_escn[i]));
3193 vg_assert(ehframe_escn[i].szB == di->ehframe_size[i]);
3194 ML_(read_callframe_info_dwarf3)( di,
3195 ehframe_escn[i],
3196 di->ehframe_avma[i],
3197 True/*is_ehframe*/ );
3199 if (ML_(sli_is_valid)(debug_frame_escn)) {
3200 ML_(read_callframe_info_dwarf3)( di,
3201 debug_frame_escn,
3202 0/*assume zero avma*/,
3203 False/*!is_ehframe*/ );
3206 /* TOPLEVEL */
3207 /* jrs 2006-01-01: icc-8.1 has been observed to generate
3208 binaries without debug_str sections. Don't preclude
3209 debuginfo reading for that reason, but, in
3210 read_unitinfo_dwarf2, do check that debugstr is non-NULL
3211 before using it. */
3212 if (ML_(sli_is_valid)(debug_info_escn)
3213 && ML_(sli_is_valid)(debug_abbv_escn)
3214 && ML_(sli_is_valid)(debug_line_escn)) {
3215 /* The old reader: line numbers and unwind info only */
3216 ML_(read_debuginfo_dwarf3) ( di,
3217 debug_info_escn,
3218 debug_types_escn,
3219 debug_abbv_escn,
3220 debug_line_escn,
3221 debug_str_escn,
3222 debug_str_alt_escn );
3223 /* The new reader: read the DIEs in .debug_info to acquire
3224 information on variable types and locations or inline info.
3225 But only if the tool asks for it, or the user requests it on
3226 the command line. */
3227 if (VG_(clo_read_var_info) /* the user or tool asked for it */
3228 || VG_(clo_read_inline_info)) {
3229 ML_(new_dwarf3_reader)(
3230 di, debug_info_escn, debug_types_escn,
3231 debug_abbv_escn, debug_line_escn,
3232 debug_str_escn, debug_ranges_escn,
3233 debug_loc_escn, debug_info_alt_escn,
3234 debug_abbv_alt_escn, debug_line_alt_escn,
3235 debug_str_alt_escn
3240 /* TOPLEVEL */
3241 // JRS 31 July 2014: dwarf-1 reading is currently broken and
3242 // therefore deactivated.
3243 //if (dwarf1d_img && dwarf1l_img) {
3244 // ML_(read_debuginfo_dwarf1) ( di, dwarf1d_img, dwarf1d_sz,
3245 // dwarf1l_img, dwarf1l_sz );
3248 # if defined(VGA_arm)
3249 /* TOPLEVEL */
3250 /* ARM32 only: read .exidx/.extab if present. Note we are
3251 reading these directly out of the mapped in (running) image.
3252 Also, read these only if no CFI based unwind info was
3253 acquired for this file.
3255 An .exidx section is always required, but the .extab section
3256 can be optionally omitted, provided that .exidx does not
3257 refer to it. If the .exidx is erroneous and does refer to
3258 .extab even though .extab is missing, the range checks done
3259 by GET_EX_U32 in ExtabEntryExtract in readexidx.c should
3260 prevent any invalid memory accesses, and cause the .extab to
3261 be rejected as invalid.
3263 FIXME:
3264 * check with m_aspacemgr that the entire [exidx_avma, +exidx_size)
3265 and [extab_avma, +extab_size) areas are readable, since we're
3266 reading this stuff out of the running image (not from a file/socket)
3267 and we don't want to segfault.
3268 * DebugInfo::exidx_bias and use text_bias instead.
3269 I think it's always the same.
3270 * remove DebugInfo::{extab_bias, exidx_svma, extab_svma} since
3271 they are never used.
3273 if (di->exidx_present
3274 && di->cfsi_used == 0
3275 && di->text_present && di->text_size > 0) {
3276 Addr text_last_svma = di->text_svma + di->text_size - 1;
3277 ML_(read_exidx)( di, (UChar*)di->exidx_avma, di->exidx_size,
3278 (UChar*)di->extab_avma, di->extab_size,
3279 text_last_svma,
3280 di->exidx_bias );
3282 # endif /* defined(VGA_arm) */
3284 } /* "Find interesting sections, read the symbol table(s), read any debug
3285 information" (a local scope) */
3287 /* TOPLEVEL */
3288 res = True;
3290 /* If reading Dwarf3 variable type/location info, print a line
3291 showing the number of variables read for each object.
3292 (Currently disabled -- is a sanity-check mechanism for
3293 exp-sgcheck.) */
3294 if (0 && VG_(clo_read_var_info)) {
3295 UWord nVars = 0;
3296 if (di->varinfo) {
3297 for (j = 0; j < VG_(sizeXA)(di->varinfo); j++) {
3298 OSet* /* of DiAddrRange */ scope
3299 = *(OSet**)VG_(indexXA)(di->varinfo, j);
3300 vg_assert(scope);
3301 VG_(OSetGen_ResetIter)( scope );
3302 while (True) {
3303 DiAddrRange* range = VG_(OSetGen_Next)( scope );
3304 if (!range) break;
3305 vg_assert(range->vars);
3306 Word w = VG_(sizeXA)(range->vars);
3307 vg_assert(w >= 0);
3308 if (0) VG_(printf)("range %#lx %#lx %ld\n",
3309 range->aMin, range->aMax, w);
3310 nVars += (UWord)w;
3314 VG_(umsg)("VARINFO: %7lu vars %7lu text_size %s\n",
3315 nVars, di->text_size, di->fsm.filename);
3317 /* TOPLEVEL */
3319 out:
3321 /* Last, but not least, detach from the image(s). */
3322 if (mimg) ML_(img_done)(mimg);
3323 if (dimg) ML_(img_done)(dimg);
3324 if (aimg) ML_(img_done)(aimg);
3326 if (svma_ranges) VG_(deleteXA)(svma_ranges);
3328 return res;
3329 } /* out: */
3331 /* NOTREACHED */
3334 #endif // defined(VGO_linux) || defined(VGO_solaris)
3336 /*--------------------------------------------------------------------*/
3337 /*--- end ---*/
3338 /*--------------------------------------------------------------------*/