drd: Add a consistency check
[valgrind.git] / coregrind / m_debuginfo / readelf.c
blob09cd03339643698027a9556d0014f7ab31ef9c70
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-2013 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, write to the Free Software
26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27 02111-1307, USA.
29 The GNU General Public License is contained in the file COPYING.
32 #if defined(VGO_linux)
34 #include "pub_core_basics.h"
35 #include "pub_core_vki.h"
36 #include "pub_core_debuginfo.h"
37 #include "pub_core_libcbase.h"
38 #include "pub_core_libcprint.h"
39 #include "pub_core_libcassert.h"
40 #include "pub_core_machine.h" /* VG_ELF_CLASS */
41 #include "pub_core_options.h"
42 #include "pub_core_oset.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"
55 /* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
56 #include <elf.h>
57 /* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
59 /*------------------------------------------------------------*/
60 /*--- 32/64-bit parameterisation ---*/
61 /*------------------------------------------------------------*/
63 /* For all the ELF macros and types which specify '32' or '64',
64 select the correct variant for this platform and give it
65 an 'XX' name. Then use the 'XX' variant consistently in
66 the rest of this file.
68 #if VG_WORDSIZE == 4
69 # define ElfXX_Ehdr Elf32_Ehdr
70 # define ElfXX_Shdr Elf32_Shdr
71 # define ElfXX_Phdr Elf32_Phdr
72 # define ElfXX_Nhdr Elf32_Nhdr
73 # define ElfXX_Sym Elf32_Sym
74 # define ElfXX_Off Elf32_Off
75 # define ElfXX_Word Elf32_Word
76 # define ElfXX_Addr Elf32_Addr
77 # define ElfXX_Dyn Elf32_Dyn
78 # define ELFXX_ST_BIND ELF32_ST_BIND
79 # define ELFXX_ST_TYPE ELF32_ST_TYPE
81 #elif VG_WORDSIZE == 8
82 # define ElfXX_Ehdr Elf64_Ehdr
83 # define ElfXX_Shdr Elf64_Shdr
84 # define ElfXX_Phdr Elf64_Phdr
85 # define ElfXX_Nhdr Elf64_Nhdr
86 # define ElfXX_Sym Elf64_Sym
87 # define ElfXX_Off Elf64_Off
88 # define ElfXX_Word Elf64_Word
89 # define ElfXX_Addr Elf64_Addr
90 # define ElfXX_Dyn Elf64_Dyn
91 # define ELFXX_ST_BIND ELF64_ST_BIND
92 # define ELFXX_ST_TYPE ELF64_ST_TYPE
94 #else
95 # error "VG_WORDSIZE should be 4 or 8"
96 #endif
99 /*------------------------------------------------------------*/
100 /*--- ---*/
101 /*--- Read symbol table and line info from ELF files. ---*/
102 /*--- ---*/
103 /*------------------------------------------------------------*/
105 /* readelf.c parses ELF files and acquires symbol table info from
106 them. It calls onwards to readdwarf.c to read DWARF2/3 line number
107 and call frame info found. */
109 /* Identify an ELF object file by peering at the first few bytes of
110 it. */
112 Bool ML_(is_elf_object_file)( const void* image, SizeT n_image, Bool rel_ok )
114 const ElfXX_Ehdr* ehdr = image;
115 Int ok = 1;
117 if (n_image < sizeof(ElfXX_Ehdr))
118 return False;
120 ok &= (ehdr->e_ident[EI_MAG0] == 0x7F
121 && ehdr->e_ident[EI_MAG1] == 'E'
122 && ehdr->e_ident[EI_MAG2] == 'L'
123 && ehdr->e_ident[EI_MAG3] == 'F');
124 ok &= (ehdr->e_ident[EI_CLASS] == VG_ELF_CLASS
125 && ehdr->e_ident[EI_DATA] == VG_ELF_DATA2XXX
126 && ehdr->e_ident[EI_VERSION] == EV_CURRENT);
127 ok &= (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN
128 || (rel_ok && ehdr->e_type == ET_REL));
129 ok &= (ehdr->e_machine == VG_ELF_MACHINE);
130 ok &= (ehdr->e_version == EV_CURRENT);
131 ok &= (ehdr->e_shstrndx != SHN_UNDEF);
132 ok &= (ehdr->e_shoff != 0 && ehdr->e_shnum != 0);
133 ok &= ((ehdr->e_phoff != 0 && ehdr->e_phnum != 0)
134 || ehdr->e_type == ET_REL);
136 return ok ? True : False;
140 /* The same thing, but operating on a DiImage instead. */
142 static Bool is_elf_object_file_by_DiImage( DiImage* img, Bool rel_ok )
144 /* Be sure this doesn't make the frame too big. */
145 vg_assert(sizeof(ElfXX_Ehdr) <= 512);
147 ElfXX_Ehdr ehdr;
148 if (!ML_(img_valid)(img, 0, sizeof(ehdr)))
149 return False;
151 ML_(img_get)(&ehdr, img, 0, sizeof(ehdr));
152 return ML_(is_elf_object_file)( &ehdr, sizeof(ehdr), rel_ok );
156 /* Show a raw ELF symbol, given its in-image address and name. */
158 static
159 void show_raw_elf_symbol ( DiImage* strtab_img,
160 Int i,
161 const ElfXX_Sym* sym,
162 DiOffT sym_name_ioff, Addr sym_svma,
163 Bool ppc64_linux_format )
165 const HChar* space = ppc64_linux_format ? " " : "";
166 VG_(printf)("raw symbol [%4d]: ", i);
167 switch (ELFXX_ST_BIND(sym->st_info)) {
168 case STB_LOCAL: VG_(printf)("LOC "); break;
169 case STB_GLOBAL: VG_(printf)("GLO "); break;
170 case STB_WEAK: VG_(printf)("WEA "); break;
171 case STB_LOPROC: VG_(printf)("lop "); break;
172 case STB_HIPROC: VG_(printf)("hip "); break;
173 default: VG_(printf)("??? "); break;
175 switch (ELFXX_ST_TYPE(sym->st_info)) {
176 case STT_NOTYPE: VG_(printf)("NOT "); break;
177 case STT_OBJECT: VG_(printf)("OBJ "); break;
178 case STT_FUNC: VG_(printf)("FUN "); break;
179 case STT_SECTION: VG_(printf)("SEC "); break;
180 case STT_FILE: VG_(printf)("FIL "); break;
181 case STT_LOPROC: VG_(printf)("lop "); break;
182 case STT_HIPROC: VG_(printf)("hip "); break;
183 default: VG_(printf)("??? "); break;
185 HChar* sym_name = NULL;
186 if (sym->st_name)
187 sym_name = ML_(img_strdup)(strtab_img, "di.sres.1", sym_name_ioff);
188 VG_(printf)(": svma %#010lx, %ssz %4llu %s\n",
189 sym_svma, space, (ULong)(sym->st_size + 0UL),
190 (sym_name ? sym_name : "NONAME") );
191 if (sym_name)
192 ML_(dinfo_free)(sym_name);
196 /* Decide whether SYM is something we should collect, and if so, copy
197 relevant info to the _OUT arguments. For {x86,amd64,ppc32}-linux
198 this is straightforward - the name, address, size are copied out
199 unchanged.
201 There is a bit of a kludge re data symbols (see KLUDGED BSS CHECK
202 below): we assume that the .bss is mapped immediately after .data,
203 and so accept any data symbol which exists in the range [start of
204 .data, size of .data + size of .bss). I don't know if this is
205 really correct/justifiable, or not.
207 For ppc64be-linux it's more complex. If the symbol is seen to be in
208 the .opd section, it is taken to be a function descriptor, and so
209 a dereference is attempted, in order to get hold of the real entry
210 point address. Also as part of the dereference, there is an attempt
211 to calculate the TOC pointer (R2 value) associated with the symbol.
213 To support the ppc64be-linux pre-"dotless" ABI (prior to gcc 4.0.0),
214 if the symbol is seen to be outside the .opd section and its name
215 starts with a dot, an .opd deference is not attempted, and no TOC
216 pointer is calculated, but the leading dot is removed from the
217 name.
219 As a result, on ppc64be-linux, the caller of this function may have
220 to piece together the real size, address, name of the symbol from
221 multiple calls to this function. Ugly and confusing.
223 static
224 Bool get_elf_symbol_info (
225 /* INPUTS */
226 struct _DebugInfo* di, /* containing DebugInfo */
227 const ElfXX_Sym* sym, /* ELF symbol */
228 DiOffT sym_name_ioff, /* name, may be absent (DiOffT_INVALID) */
229 const DiSlice* escn_strtab, /* holds the name */
230 Addr sym_svma, /* address as stated in the object file */
231 Bool symtab_in_debug, /* symbol table is in the debug file */
232 const DiSlice* escn_opd, /* the .opd (ppc64be-linux only) */
233 PtrdiffT opd_bias, /* for biasing AVMAs found in .opd */
234 /* OUTPUTS */
235 DiOffT* sym_name_out_ioff, /* name (in strtab) we should record */
236 SymAVMAs* sym_avmas_out, /* sym avmas we should record */
237 Int* sym_size_out, /* symbol size */
238 Bool* from_opd_out, /* ppc64be-linux only: did we deref an
239 .opd entry? */
240 Bool* is_text_out, /* is this a text symbol? */
241 Bool* is_ifunc /* is this a STT_GNU_IFUNC function ?*/
244 Bool plausible;
245 # if defined(VGP_ppc64be_linux)
246 Bool is_in_opd;
247 # endif
248 Bool in_text, in_data, in_sdata, in_rodata, in_bss, in_sbss;
249 Addr text_svma, data_svma, sdata_svma, rodata_svma, bss_svma, sbss_svma;
250 PtrdiffT text_bias, data_bias, sdata_bias, rodata_bias, bss_bias, sbss_bias;
252 /* Set defaults */
253 *sym_name_out_ioff = sym_name_ioff;
254 (*sym_avmas_out).main = sym_svma; /* we will bias this shortly */
255 *is_text_out = True;
256 SET_TOCPTR_AVMA(*sym_avmas_out, 0); /* default to unknown/inapplicable */
257 SET_LOCAL_EP_AVMA(*sym_avmas_out, 0); /* default to unknown/inapplicable */
258 *from_opd_out = False;
259 *is_ifunc = False;
261 /* Get the symbol size, but restrict it to fit in a signed 32 bit
262 int. Also, deal with the stupid case of negative size by making
263 the size be 1. Note that sym->st_size has type UWord,
264 effectively. */
265 { Word size_tmp = (Word)sym->st_size;
266 Word max_Int = (1LL << 31) - 1;
267 if (size_tmp < 0) size_tmp = 1;
268 if (size_tmp > max_Int) size_tmp = max_Int;
269 *sym_size_out = (Int)size_tmp;
271 /* After this point refer only to *sym_size_out and not to
272 sym->st_size. */
274 /* Figure out if we're interested in the symbol. Firstly, is it of
275 the right flavour? */
276 plausible
277 = (ELFXX_ST_BIND(sym->st_info) == STB_GLOBAL
278 || ELFXX_ST_BIND(sym->st_info) == STB_LOCAL
279 || ELFXX_ST_BIND(sym->st_info) == STB_WEAK
282 (ELFXX_ST_TYPE(sym->st_info) == STT_FUNC
283 || ELFXX_ST_TYPE(sym->st_info) == STT_OBJECT
284 # ifdef STT_GNU_IFUNC
285 || ELFXX_ST_TYPE(sym->st_info) == STT_GNU_IFUNC
286 # endif
289 /* Work out the svma and bias for each section as it will appear in
290 addresses in the symbol table. */
291 if (symtab_in_debug) {
292 text_svma = di->text_debug_svma;
293 text_bias = di->text_debug_bias;
294 data_svma = di->data_debug_svma;
295 data_bias = di->data_debug_bias;
296 sdata_svma = di->sdata_debug_svma;
297 sdata_bias = di->sdata_debug_bias;
298 rodata_svma = di->rodata_debug_svma;
299 rodata_bias = di->rodata_debug_bias;
300 bss_svma = di->bss_debug_svma;
301 bss_bias = di->bss_debug_bias;
302 sbss_svma = di->sbss_debug_svma;
303 sbss_bias = di->sbss_debug_bias;
304 } else {
305 text_svma = di->text_svma;
306 text_bias = di->text_bias;
307 data_svma = di->data_svma;
308 data_bias = di->data_bias;
309 sdata_svma = di->sdata_svma;
310 sdata_bias = di->sdata_bias;
311 rodata_svma = di->rodata_svma;
312 rodata_bias = di->rodata_bias;
313 bss_svma = di->bss_svma;
314 bss_bias = di->bss_bias;
315 sbss_svma = di->sbss_svma;
316 sbss_bias = di->sbss_bias;
319 /* Now bias (*sym_avmas_out).main accordingly by figuring out exactly which
320 section the symbol is from and bias accordingly. Screws up if
321 the previously deduced section svma address ranges are wrong. */
322 if (di->text_present
323 && di->text_size > 0
324 && sym_svma >= text_svma
325 && sym_svma < text_svma + di->text_size) {
326 *is_text_out = True;
327 (*sym_avmas_out).main += text_bias;
328 } else
329 if (di->data_present
330 && di->data_size > 0
331 && sym_svma >= data_svma
332 && sym_svma < data_svma + di->data_size) {
333 *is_text_out = False;
334 (*sym_avmas_out).main += data_bias;
335 } else
336 if (di->sdata_present
337 && di->sdata_size > 0
338 && sym_svma >= sdata_svma
339 && sym_svma < sdata_svma + di->sdata_size) {
340 *is_text_out = False;
341 (*sym_avmas_out).main += sdata_bias;
342 } else
343 if (di->rodata_present
344 && di->rodata_size > 0
345 && sym_svma >= rodata_svma
346 && sym_svma < rodata_svma + di->rodata_size) {
347 *is_text_out = False;
348 (*sym_avmas_out).main += rodata_bias;
349 } else
350 if (di->bss_present
351 && di->bss_size > 0
352 && sym_svma >= bss_svma
353 && sym_svma < bss_svma + di->bss_size) {
354 *is_text_out = False;
355 (*sym_avmas_out).main += bss_bias;
356 } else
357 if (di->sbss_present
358 && di->sbss_size > 0
359 && sym_svma >= sbss_svma
360 && sym_svma < sbss_svma + di->sbss_size) {
361 *is_text_out = False;
362 (*sym_avmas_out).main += sbss_bias;
363 } else {
364 /* Assume it's in .text. Is this a good idea? */
365 *is_text_out = True;
366 (*sym_avmas_out).main += text_bias;
369 # ifdef STT_GNU_IFUNC
370 /* Check for indirect functions. */
371 if (*is_text_out
372 && ELFXX_ST_TYPE(sym->st_info) == STT_GNU_IFUNC) {
373 *is_ifunc = True;
375 # endif
377 # if defined(VGP_ppc64be_linux)
378 /* Allow STT_NOTYPE in the very special case where we're running on
379 ppc64be-linux and the symbol is one which the .opd-chasing hack
380 below will chase. */
381 if (!plausible
382 && *is_text_out
383 && ELFXX_ST_TYPE(sym->st_info) == STT_NOTYPE
384 && *sym_size_out > 0
385 && di->opd_present
386 && di->opd_size > 0
387 && (*sym_avmas_out).main >= di->opd_avma
388 && (*sym_avmas_out).main < di->opd_avma + di->opd_size)
389 plausible = True;
390 # endif
392 if (!plausible)
393 return False;
395 /* Ignore if nameless. */
396 if (sym_name_ioff == DiOffT_INVALID
397 || /* VG_(strlen)(sym_name) == 0 */
398 /* equivalent but cheaper ... */
399 ML_(img_get_UChar)(escn_strtab->img, sym_name_ioff) == '\0') {
400 if (TRACE_SYMTAB_ENABLED) {
401 HChar* sym_name = ML_(img_strdup)(escn_strtab->img,
402 "di.gesi.1", sym_name_ioff);
403 TRACE_SYMTAB(" ignore -- nameless: %s\n", sym_name);
404 if (sym_name) ML_(dinfo_free)(sym_name);
406 return False;
409 /* Ignore if zero-sized. Except on Android:
411 On Android 2.3.5, some of the symbols that Memcheck needs to
412 intercept (for noise reduction purposes) have zero size, due to
413 lack of .size directives in handwritten assembly sources. So we
414 can't reject them out of hand -- instead give them a bogusly
415 large size and let canonicaliseSymtab trim them so they don't
416 overlap any following symbols. At least the following symbols
417 are known to be affected:
419 in /system/lib/libc.so: strlen strcmp strcpy memcmp memcpy
420 in /system/bin/linker: __dl_strcmp __dl_strlen
422 if (*sym_size_out == 0) {
423 # if defined(VGPV_arm_linux_android) \
424 || defined(VGPV_x86_linux_android) \
425 || defined(VGPV_mips32_linux_android) \
426 || defined(VGPV_arm64_linux_android)
427 *sym_size_out = 2048;
428 # else
429 if (TRACE_SYMTAB_ENABLED) {
430 HChar* sym_name = ML_(img_strdup)(escn_strtab->img,
431 "di.gesi.2", sym_name_ioff);
432 TRACE_SYMTAB(" ignore -- size=0: %s\n", sym_name);
433 if (sym_name) ML_(dinfo_free)(sym_name);
435 return False;
436 # endif
439 /* This seems to significantly reduce the number of junk
440 symbols, and particularly reduces the number of
441 overlapping address ranges. Don't ask me why ... */
442 if ((Int)sym->st_value == 0) {
443 if (TRACE_SYMTAB_ENABLED) {
444 HChar* sym_name = ML_(img_strdup)(escn_strtab->img,
445 "di.gesi.3", sym_name_ioff);
446 TRACE_SYMTAB( " ignore -- valu=0: %s\n", sym_name);
447 if (sym_name) ML_(dinfo_free)(sym_name);
449 return False;
452 /* If it's apparently in a GOT or PLT, it's really a reference to a
453 symbol defined elsewhere, so ignore it. */
454 if (di->got_present
455 && di->got_size > 0
456 && (*sym_avmas_out).main >= di->got_avma
457 && (*sym_avmas_out).main < di->got_avma + di->got_size) {
458 if (TRACE_SYMTAB_ENABLED) {
459 HChar* sym_name = ML_(img_strdup)(escn_strtab->img,
460 "di.gesi.4", sym_name_ioff);
461 TRACE_SYMTAB(" ignore -- in GOT: %s\n", sym_name);
462 if (sym_name) ML_(dinfo_free)(sym_name);
464 return False;
466 if (di->plt_present
467 && di->plt_size > 0
468 && (*sym_avmas_out).main >= di->plt_avma
469 && (*sym_avmas_out).main < di->plt_avma + di->plt_size) {
470 if (TRACE_SYMTAB_ENABLED) {
471 HChar* sym_name = ML_(img_strdup)(escn_strtab->img,
472 "di.gesi.5", sym_name_ioff);
473 TRACE_SYMTAB(" ignore -- in PLT: %s\n", sym_name);
474 if (sym_name) ML_(dinfo_free)(sym_name);
476 return False;
479 /* ppc64be-linux nasty hack: if the symbol is in an .opd section,
480 then really what we have is the address of a function
481 descriptor. So use the first word of that as the function's
482 text.
484 See thread starting at
485 http://gcc.gnu.org/ml/gcc-patches/2004-08/msg00557.html
487 # if defined(VGP_ppc64be_linux)
488 /* Host and guest may have different Endianess, used by BE only */
489 is_in_opd = False;
490 # endif
492 if (di->opd_present
493 && di->opd_size > 0
494 && (*sym_avmas_out).main >= di->opd_avma
495 && (*sym_avmas_out).main < di->opd_avma + di->opd_size) {
496 # if !defined(VGP_ppc64be_linux)
497 if (TRACE_SYMTAB_ENABLED) {
498 HChar* sym_name = ML_(img_strdup)(escn_strtab->img,
499 "di.gesi.6", sym_name_ioff);
500 TRACE_SYMTAB(" ignore -- in OPD: %s\n", sym_name);
501 if (sym_name) ML_(dinfo_free)(sym_name);
503 return False;
504 # else
505 Int offset_in_opd;
506 Bool details = 1||False;
508 if (details)
509 TRACE_SYMTAB("opdXXX: opd_bias %p, sym_svma_out %p\n",
510 (void*)(opd_bias), (void*)(*sym_avmas_out).main);
512 if (!VG_IS_8_ALIGNED((*sym_avmas_out).main)) {
513 if (TRACE_SYMTAB_ENABLED) {
514 HChar* sym_name = ML_(img_strdup)(escn_strtab->img,
515 "di.gesi.6a", sym_name_ioff);
516 TRACE_SYMTAB(" ignore -- not 8-aligned: %s\n", sym_name);
517 if (sym_name) ML_(dinfo_free)(sym_name);
519 return False;
522 /* (*sym_avmas_out).main is a avma pointing into the .opd section. We
523 know the vma of the opd section start, so we can figure out
524 how far into the opd section this is. */
526 offset_in_opd = (Addr)(*sym_avmas_out).main - (Addr)(di->opd_avma);
527 if (offset_in_opd < 0 || offset_in_opd >= di->opd_size) {
528 if (TRACE_SYMTAB_ENABLED) {
529 HChar* sym_name = ML_(img_strdup)(escn_strtab->img,
530 "di.gesi.6a", sym_name_ioff);
531 TRACE_SYMTAB(" ignore -- invalid OPD offset: %s\n", sym_name);
532 if (sym_name) ML_(dinfo_free)(sym_name);
534 return False;
537 /* Now we want to know what's at that offset in the .opd
538 section. We can't look in the running image since it won't
539 necessarily have been mapped. But we can consult the oimage.
540 opd_img is the start address of the .opd in the oimage.
541 Hence: */
543 ULong fn_descr[2]; /* is actually 3 words, but we need only 2 */
544 if (!ML_(img_valid)(escn_opd->img, escn_opd->ioff + offset_in_opd,
545 sizeof(fn_descr))) {
546 if (TRACE_SYMTAB_ENABLED) {
547 HChar* sym_name = ML_(img_strdup)(escn_strtab->img,
548 "di.gesi.6b", sym_name_ioff);
549 TRACE_SYMTAB(" ignore -- invalid OPD fn_descr offset: %s\n",
550 sym_name);
551 if (sym_name) ML_(dinfo_free)(sym_name);
554 return False;
557 /* This can't fail now, because we just checked the offset
558 above. */
559 ML_(img_get)(&fn_descr[0], escn_opd->img,
560 escn_opd->ioff + offset_in_opd, sizeof(fn_descr));
562 if (details)
563 TRACE_SYMTAB("opdXXY: offset %d, fn_descr %p\n",
564 offset_in_opd, fn_descr);
565 if (details)
566 TRACE_SYMTAB("opdXXZ: *fn_descr %p\n", (void*)(fn_descr[0]));
568 /* opd_bias is the what we have to add to SVMAs found in .opd to
569 get plausible .text AVMAs for the entry point, and .data
570 AVMAs (presumably) for the TOC locations. We use the caller
571 supplied value (which is di->text_bias) for both of these.
572 Not sure why that is correct - it seems to work, and sounds
573 OK for fn_descr[0], but surely we need to use the data bias
574 and not the text bias for fn_descr[1] ? Oh Well.
576 (*sym_avmas_out).main = fn_descr[0] + opd_bias;
577 SET_TOCPTR_AVMA(*sym_avmas_out, fn_descr[1] + opd_bias);
578 *from_opd_out = True;
579 is_in_opd = True;
581 /* Do a final sanity check: if the symbol falls outside the
582 DebugInfo's mapped range, ignore it. Since (*sym_avmas_out).main has
583 been updated, that can be achieved simply by falling through
584 to the test below. */
586 # endif /* ppc64-linux nasty hack */
589 /* Here's yet another ppc64-linux hack. Get rid of leading dot if
590 the symbol is outside .opd. */
591 # if defined(VGP_ppc64be_linux)
592 if (di->opd_size > 0
593 && !is_in_opd
594 && *sym_name_out_ioff != DiOffT_INVALID
595 && ML_(img_get_UChar)(escn_strtab->img, *sym_name_out_ioff) == '.') {
596 vg_assert(!(*from_opd_out));
597 (*sym_name_out_ioff)++;
599 # endif
601 /* If no part of the symbol falls within the mapped range,
602 ignore it. */
604 in_text
605 = di->text_present
606 && di->text_size > 0
607 && !((*sym_avmas_out).main + *sym_size_out <= di->text_avma
608 || (*sym_avmas_out).main >= di->text_avma + di->text_size);
610 in_data
611 = di->data_present
612 && di->data_size > 0
613 && !((*sym_avmas_out).main + *sym_size_out <= di->data_avma
614 || (*sym_avmas_out).main >= di->data_avma + di->data_size);
616 in_sdata
617 = di->sdata_present
618 && di->sdata_size > 0
619 && !((*sym_avmas_out).main + *sym_size_out <= di->sdata_avma
620 || (*sym_avmas_out).main >= di->sdata_avma + di->sdata_size);
622 in_rodata
623 = di->rodata_present
624 && di->rodata_size > 0
625 && !((*sym_avmas_out).main + *sym_size_out <= di->rodata_avma
626 || (*sym_avmas_out).main >= di->rodata_avma + di->rodata_size);
628 in_bss
629 = di->bss_present
630 && di->bss_size > 0
631 && !((*sym_avmas_out).main + *sym_size_out <= di->bss_avma
632 || (*sym_avmas_out).main >= di->bss_avma + di->bss_size);
634 in_sbss
635 = di->sbss_present
636 && di->sbss_size > 0
637 && !((*sym_avmas_out).main + *sym_size_out <= di->sbss_avma
638 || (*sym_avmas_out).main >= di->sbss_avma + di->sbss_size);
641 if (*is_text_out) {
642 /* This used to reject any symbol falling outside the text
643 segment ("if (!in_text) ..."). Now it is relaxed slightly,
644 to reject only symbols which fall outside the area mapped
645 r-x. This is in accordance with r7427. See
646 "Comment_Regarding_Text_Range_Checks" in storage.c for
647 background. */
648 Bool in_rx;
649 vg_assert(di->fsm.have_rx_map);
650 /* This could actually wrap around and cause
651 ML_(find_rx_mapping) to assert. But that seems so unlikely,
652 let's wait for it to happen before fixing it. */
653 in_rx = (ML_(find_rx_mapping)(
655 (*sym_avmas_out).main,
656 (*sym_avmas_out).main + *sym_size_out) != NULL);
657 if (in_text)
658 vg_assert(in_rx);
659 if (!in_rx) {
660 TRACE_SYMTAB(
661 "ignore -- %#lx .. %#lx outside .text svma range %#lx .. %#lx\n",
662 (*sym_avmas_out).main, (*sym_avmas_out).main + *sym_size_out,
663 di->text_avma,
664 di->text_avma + di->text_size);
665 return False;
667 } else {
668 if (!(in_data || in_sdata || in_rodata || in_bss || in_sbss)) {
669 TRACE_SYMTAB(
670 "ignore -- %#lx .. %#lx outside .data / .sdata / .rodata "
671 "/ .bss / .sbss svma ranges\n",
672 (*sym_avmas_out).main, (*sym_avmas_out).main + *sym_size_out);
673 return False;
677 # if defined(VGP_ppc64be_linux)
678 if (di->opd_present && di->opd_size > 0) {
679 vg_assert((*sym_avmas_out).main + *sym_size_out <= di->opd_avma
680 || (*sym_avmas_out).main >= di->opd_avma + di->opd_size);
682 #endif
684 # if defined(VGP_ppc64le_linux)
685 /* PPC64 LE ABI uses three bits in the st_other field to indicate the number
686 * of instructions between the function's global and local entry points. An
687 * offset of 0 indicates that there is one entry point. The value must be:
689 * 0 - one entry point, local and global are the same
690 * 1 - reserved
691 * 2 - local entry point is one instruction after the global entry point
692 * 3 - local entry point is two instructions after the global entry point
693 * 4 - local entry point is four instructions after the global entry point
694 * 5 - local entry point is eight instructions after the global entry point
695 * 6 - local entry point is sixteen instructions after the global entry point
696 * 7 - reserved
698 * Extract the three bit field from the other field is done by:
699 * (other_field & STO_PPC64_LOCAL_MASK) >> STO_PPC_LOCAL_BIT
701 * where the #define values are given in include/elf/powerpc.h file for
702 * the PPC binutils.
704 * conversion of the three bit field to bytes is given by
706 * ((1 << bit_field) >> 2) << 2
709 #define STO_PPC64_LOCAL_BIT 5
710 #define STO_PPC64_LOCAL_MASK (7 << STO_PPC64_LOCAL_BIT)
712 unsigned int bit_field, dist_to_local_entry;
713 /* extract the other filed */
714 bit_field = (sym->st_other & STO_PPC64_LOCAL_MASK) >> STO_PPC64_LOCAL_BIT;
716 if ((bit_field > 0) && (bit_field < 7)) {
717 /* store the local entry point address */
718 dist_to_local_entry = ((1 << bit_field) >> 2) << 2;
719 SET_LOCAL_EP_AVMA(*sym_avmas_out,
720 (*sym_avmas_out).main + dist_to_local_entry);
722 if (TRACE_SYMTAB_ENABLED) {
723 HChar* sym_name = ML_(img_strdup)(escn_strtab->img,
724 "di.gesi.5", sym_name_ioff);
725 VG_(printf)("Local entry point: %s at %#010x\n",
726 sym_name,
727 (unsigned int)GET_LOCAL_EP_AVMA(*sym_avmas_out));
731 # endif
733 /* Acquire! */
734 return True;
738 /* Read an ELF symbol table (normal or dynamic). This one is for the
739 "normal" case ({x86,amd64,ppc32,arm,mips32,mips64, ppc64le}-linux). */
740 static
741 __attribute__((unused)) /* not referred to on all targets */
742 void read_elf_symtab__normal(
743 struct _DebugInfo* di, const HChar* tab_name,
744 DiSlice* escn_symtab,
745 DiSlice* escn_strtab,
746 DiSlice* escn_opd, /* ppc64be-linux only */
747 Bool symtab_in_debug
750 if (escn_strtab->img == NULL || escn_symtab->img == NULL) {
751 HChar buf[80]; // FIXME: allocate dynamically
752 vg_assert(VG_(strlen)(tab_name) < 40);
753 VG_(sprintf)(buf, " object doesn't have a %s", tab_name);
754 ML_(symerr)(di, False, buf);
755 return;
758 TRACE_SYMTAB("\n--- Reading (ELF, standard) %s (%lld entries) ---\n",
759 tab_name, escn_symtab->szB/sizeof(ElfXX_Sym) );
761 /* Perhaps should start at i = 1; ELF docs suggest that entry
762 0 always denotes 'unknown symbol'. */
763 Word i;
764 for (i = 1; i < (Word)(escn_symtab->szB/sizeof(ElfXX_Sym)); i++) {
765 ElfXX_Sym sym;
766 ML_(img_get)(&sym, escn_symtab->img,
767 escn_symtab->ioff + i * sizeof(ElfXX_Sym), sizeof(sym));
768 DiOffT sym_name = escn_strtab->ioff + sym.st_name;
769 Addr sym_svma = sym.st_value;
771 if (di->trace_symtab)
772 show_raw_elf_symbol(escn_strtab->img, i,
773 &sym, sym_name, sym_svma, False);
775 SymAVMAs sym_avmas_really;
776 Int sym_size = 0;
777 Bool from_opd = False, is_text = False, is_ifunc = False;
778 DiOffT sym_name_really = DiOffT_INVALID;
779 sym_avmas_really.main = 0;
780 SET_TOCPTR_AVMA(sym_avmas_really, 0);
781 SET_LOCAL_EP_AVMA(sym_avmas_really, 0);
782 if (get_elf_symbol_info(di, &sym, sym_name, escn_strtab,
783 sym_svma, symtab_in_debug,
784 escn_opd, di->text_bias,
785 &sym_name_really,
786 &sym_avmas_really,
787 &sym_size,
788 &from_opd, &is_text, &is_ifunc)) {
790 DiSym disym;
791 VG_(memset)(&disym, 0, sizeof(disym));
792 HChar* cstr = ML_(img_strdup)(escn_strtab->img,
793 "di.res__n.1", sym_name_really);
794 disym.avmas = sym_avmas_really;
795 disym.pri_name = ML_(addStr) ( di, cstr, -1 );
796 disym.sec_names = NULL;
797 disym.size = sym_size;
798 disym.isText = is_text;
799 disym.isIFunc = is_ifunc;
800 if (cstr) { ML_(dinfo_free)(cstr); cstr = NULL; }
801 vg_assert(disym.pri_name);
802 vg_assert(GET_TOCPTR_AVMA(disym.avmas) == 0);
803 /* has no role except on ppc64be-linux */
804 ML_(addSym) ( di, &disym );
806 if (TRACE_SYMTAB_ENABLED) {
807 TRACE_SYMTAB(" rec(%c) [%4ld]: "
808 " val %#010lx, sz %4d %s\n",
809 is_text ? 't' : 'd',
811 disym.avmas.main,
812 (Int)disym.size,
813 disym.pri_name
815 if (GET_LOCAL_EP_AVMA(disym.avmas) != 0) {
816 TRACE_SYMTAB(" local entry point %#010lx\n",
817 GET_LOCAL_EP_AVMA(disym.avmas));
826 /* Read an ELF symbol table (normal or dynamic). This one is for
827 ppc64be-linux, which requires special treatment. */
829 typedef
830 struct {
831 Addr addr;
832 DiOffT name;
833 /* We have to store also the DiImage* so as to give context for
834 |name|. This is not part of the key (in terms of lookup) but
835 there's no easy other way to do this. Ugly. */
836 DiImage* img;
838 TempSymKey;
840 typedef
841 struct {
842 TempSymKey key;
843 Addr tocptr;
844 Int size;
845 Bool from_opd;
846 Bool is_text;
847 Bool is_ifunc;
849 TempSym;
851 static Word cmp_TempSymKey ( const TempSymKey* key1, const TempSym* elem2 )
853 /* Stay sane ... */
854 vg_assert(key1->img == elem2->key.img);
855 vg_assert(key1->img != NULL);
856 if (key1->addr < elem2->key.addr) return -1;
857 if (key1->addr > elem2->key.addr) return 1;
858 vg_assert(key1->name != DiOffT_INVALID);
859 vg_assert(elem2->key.name != DiOffT_INVALID);
860 return (Word)ML_(img_strcmp)(key1->img, key1->name, elem2->key.name);
863 static
864 __attribute__((unused)) /* not referred to on all targets */
865 void read_elf_symtab__ppc64be_linux(
866 struct _DebugInfo* di, const HChar* tab_name,
867 DiSlice* escn_symtab,
868 DiSlice* escn_strtab,
869 DiSlice* escn_opd, /* ppc64be-linux only */
870 Bool symtab_in_debug
873 Word i;
874 Int old_size;
875 Bool modify_size, modify_tocptr;
876 OSet *oset;
877 TempSymKey key;
878 TempSym *elem;
879 TempSym *prev;
881 if (escn_strtab->img == NULL || escn_symtab->img == NULL) {
882 HChar buf[80]; // FIXME: allocate dynamically
883 vg_assert(VG_(strlen)(tab_name) < 40);
884 VG_(sprintf)(buf, " object doesn't have a %s", tab_name);
885 ML_(symerr)(di, False, buf);
886 return;
889 TRACE_SYMTAB("\n--- Reading (ELF, ppc64be-linux) %s (%lld entries) ---\n",
890 tab_name, escn_symtab->szB/sizeof(ElfXX_Sym) );
892 oset = VG_(OSetGen_Create)( offsetof(TempSym,key),
893 (OSetCmp_t)cmp_TempSymKey,
894 ML_(dinfo_zalloc), "di.respl.1",
895 ML_(dinfo_free) );
897 /* Perhaps should start at i = 1; ELF docs suggest that entry
898 0 always denotes 'unknown symbol'. */
899 for (i = 1; i < (Word)(escn_symtab->szB/sizeof(ElfXX_Sym)); i++) {
900 ElfXX_Sym sym;
901 ML_(img_get)(&sym, escn_symtab->img,
902 escn_symtab->ioff + i * sizeof(ElfXX_Sym), sizeof(sym));
903 DiOffT sym_name = escn_strtab->ioff + sym.st_name;
904 Addr sym_svma = sym.st_value;
906 if (di->trace_symtab)
907 show_raw_elf_symbol(escn_strtab->img, i,
908 &sym, sym_name, sym_svma, True);
910 SymAVMAs sym_avmas_really;
911 Int sym_size = 0;
912 Bool from_opd = False, is_text = False, is_ifunc = False;
913 DiOffT sym_name_really = DiOffT_INVALID;
914 DiSym disym;
915 VG_(memset)(&disym, 0, sizeof(disym));
916 sym_avmas_really.main = 0;
917 SET_TOCPTR_AVMA(sym_avmas_really, 0);
918 SET_LOCAL_EP_AVMA(sym_avmas_really, 0);
919 if (get_elf_symbol_info(di, &sym, sym_name, escn_strtab,
920 sym_svma, symtab_in_debug,
921 escn_opd, di->text_bias,
922 &sym_name_really,
923 &sym_avmas_really,
924 &sym_size,
925 &from_opd, &is_text, &is_ifunc)) {
927 /* Check if we've seen this (name,addr) key before. */
928 key.addr = sym_avmas_really.main;
929 key.name = sym_name_really;
930 key.img = escn_strtab->img;
931 prev = VG_(OSetGen_Lookup)( oset, &key );
933 if (prev) {
935 /* Seen it before. Fold in whatever new info we can. */
936 modify_size = False;
937 modify_tocptr = False;
938 old_size = 0;
940 if (prev->from_opd && !from_opd
941 && (prev->size == 24 || prev->size == 16)
942 && sym_size != prev->size) {
943 /* Existing one is an opd-redirect, with a bogus size,
944 so the only useful new fact we have is the real size
945 of the symbol. */
946 modify_size = True;
947 old_size = prev->size;
948 prev->size = sym_size;
950 else
951 if (!prev->from_opd && from_opd
952 && (sym_size == 24 || sym_size == 16)) {
953 /* Existing one is non-opd, new one is opd. What we
954 can acquire from the new one is the TOC ptr to be
955 used. Since the existing sym is non-toc, it
956 shouldn't currently have an known TOC ptr. */
957 vg_assert(prev->tocptr == 0);
958 modify_tocptr = True;
959 prev->tocptr = GET_TOCPTR_AVMA(sym_avmas_really);
961 else {
962 /* ignore. can we do better here? */
965 /* Only one or the other is possible (I think) */
966 vg_assert(!(modify_size && modify_tocptr));
968 if (modify_size && di->trace_symtab) {
969 VG_(printf)(" modify (old sz %4d) "
970 " val %#010lx, toc %#010lx, sz %4d %lld\n",
971 old_size,
972 prev->key.addr,
973 prev->tocptr,
974 (Int) prev->size,
975 (ULong)prev->key.name
978 if (modify_tocptr && di->trace_symtab) {
979 VG_(printf)(" modify (upd tocptr) "
980 " val %#010lx, toc %#010lx, sz %4d %lld\n",
981 prev->key.addr,
982 prev->tocptr,
983 (Int) prev->size,
984 (ULong)prev->key.name
988 } else {
990 /* A new (name,addr) key. Add and continue. */
991 elem = VG_(OSetGen_AllocNode)(oset, sizeof(TempSym));
992 elem->key = key;
993 elem->tocptr = GET_TOCPTR_AVMA(sym_avmas_really);
994 elem->size = sym_size;
995 elem->from_opd = from_opd;
996 elem->is_text = is_text;
997 elem->is_ifunc = is_ifunc;
998 VG_(OSetGen_Insert)(oset, elem);
999 if (di->trace_symtab) {
1000 HChar* str = ML_(img_strdup)(escn_strtab->img, "di.respl.2",
1001 elem->key.name);
1002 VG_(printf)(" to-oset [%4ld]: "
1003 " val %#010lx, toc %#010lx, sz %4d %s\n",
1005 elem->key.addr,
1006 elem->tocptr,
1007 (Int) elem->size,
1010 if (str) ML_(dinfo_free)(str);
1017 /* All the syms that matter are in the oset. Now pull them out,
1018 build a "standard" symbol table, and nuke the oset. */
1020 i = 0;
1021 VG_(OSetGen_ResetIter)( oset );
1023 while ( (elem = VG_(OSetGen_Next)(oset)) ) {
1024 DiSym disym;
1025 VG_(memset)(&disym, 0, sizeof(disym));
1026 HChar* cstr = ML_(img_strdup)(escn_strtab->img,
1027 "di.res__ppc64.1", elem->key.name);
1028 disym.avmas.main = elem->key.addr;
1029 SET_TOCPTR_AVMA(disym.avmas, elem->tocptr);
1030 SET_LOCAL_EP_AVMA(disym.avmas, 0); // ppc64be does not use local_ep.
1031 disym.pri_name = ML_(addStr) ( di, cstr, -1 );
1032 disym.sec_names = NULL;
1033 disym.size = elem->size;
1034 disym.isText = elem->is_text;
1035 disym.isIFunc = elem->is_ifunc;
1036 if (cstr) { ML_(dinfo_free)(cstr); cstr = NULL; }
1037 vg_assert(disym.pri_name != NULL);
1039 ML_(addSym) ( di, &disym );
1040 if (di->trace_symtab) {
1041 VG_(printf)(" rec(%c) [%4ld]: "
1042 " val %#010lx, toc %#010lx, sz %4d %s\n",
1043 disym.isText ? 't' : 'd',
1045 disym.avmas.main,
1046 GET_TOCPTR_AVMA(disym.avmas),
1047 (Int) disym.size,
1048 disym.pri_name
1051 i++;
1054 VG_(OSetGen_Destroy)( oset );
1059 * Look for a build-id in an ELF image. The build-id specification
1060 * can be found here:
1062 * http://fedoraproject.org/wiki/RolandMcGrath/BuildID
1064 * Returned string must be freed by the caller.
1066 static
1067 HChar* find_buildid(DiImage* img, Bool rel_ok, Bool search_shdrs)
1069 HChar* buildid = NULL;
1071 # ifdef NT_GNU_BUILD_ID
1072 if (is_elf_object_file_by_DiImage(img, rel_ok)) {
1073 Word i;
1075 ElfXX_Ehdr ehdr;
1076 ML_(img_get)(&ehdr, img, 0, sizeof(ehdr));
1077 for (i = 0; i < ehdr.e_phnum; i++) {
1078 ElfXX_Phdr phdr;
1079 ML_(img_get)(&phdr, img,
1080 ehdr.e_phoff + i * ehdr.e_phentsize, sizeof(phdr));
1082 if (phdr.p_type == PT_NOTE) {
1083 ElfXX_Off note_ioff = phdr.p_offset;
1085 while (note_ioff < phdr.p_offset + phdr.p_filesz) {
1086 ElfXX_Nhdr note;
1087 ML_(img_get)(&note, img, (DiOffT)note_ioff, sizeof(note));
1088 DiOffT name_ioff = note_ioff + sizeof(ElfXX_Nhdr);
1089 DiOffT desc_ioff = name_ioff + ((note.n_namesz + 3) & ~3);
1090 if (ML_(img_strcmp_c)(img, name_ioff, ELF_NOTE_GNU) == 0
1091 && note.n_type == NT_GNU_BUILD_ID) {
1092 buildid = ML_(dinfo_zalloc)("di.fbi.1",
1093 note.n_descsz * 2 + 1);
1094 Word j;
1095 for (j = 0; j < note.n_descsz; j++) {
1096 UChar desc_j = ML_(img_get_UChar)(img, desc_ioff + j);
1097 VG_(sprintf)(buildid + VG_(strlen)(buildid),
1098 "%02x", (UInt)desc_j);
1102 note_ioff = note_ioff + sizeof(ElfXX_Nhdr)
1103 + ((note.n_namesz + 3) & ~3)
1104 + ((note.n_descsz + 3) & ~3);
1109 /* Normally we would only search shdrs for ET_REL files, but when
1110 we search for a separate .debug file phdrs might not be there
1111 (they are never loaded) or have been corrupted, so try again
1112 against shdrs. */
1113 if (buildid || (!rel_ok && !search_shdrs))
1114 return buildid;
1116 for (i = 0; i < ehdr.e_shnum; i++) {
1117 ElfXX_Shdr shdr;
1118 ML_(img_get)(&shdr, img,
1119 ehdr.e_shoff + i * ehdr.e_shentsize, sizeof(shdr));
1121 if (shdr.sh_type == SHT_NOTE) {
1122 ElfXX_Off note_ioff = shdr.sh_offset;
1124 while (note_ioff < shdr.sh_offset + shdr.sh_size) {
1125 ElfXX_Nhdr note;
1126 ML_(img_get)(&note, img, (DiOffT)note_ioff, sizeof(note));
1127 DiOffT name_ioff = note_ioff + sizeof(ElfXX_Nhdr);
1128 DiOffT desc_ioff = name_ioff + ((note.n_namesz + 3) & ~3);
1130 if (ML_(img_strcmp_c)(img, name_ioff, ELF_NOTE_GNU) == 0
1131 && note.n_type == NT_GNU_BUILD_ID) {
1132 buildid = ML_(dinfo_zalloc)("di.fbi.2",
1133 note.n_descsz * 2 + 1);
1134 Word j;
1135 for (j = 0; j < note.n_descsz; j++) {
1136 UChar desc_j = ML_(img_get_UChar)(img, desc_ioff + j);
1137 VG_(sprintf)(buildid + VG_(strlen)(buildid),
1138 "%02x", (UInt)desc_j);
1142 note_ioff = note_ioff + sizeof(ElfXX_Nhdr)
1143 + ((note.n_namesz + 3) & ~3)
1144 + ((note.n_descsz + 3) & ~3);
1149 # endif /* def NT_GNU_BUILD_ID */
1151 return buildid;
1155 /* Try and open a separate debug file, ignoring any where the CRC does
1156 not match the value from the main object file. Returned DiImage
1157 must be discarded by the caller.
1159 If |serverAddr| is NULL, |name| is expected to be a fully qualified
1160 (absolute) path to the file in the local filesystem. If
1161 |serverAddr| is non-NULL, it is expected to be an IPv4 and port
1162 spec of the form "d.d.d.d:d" or "d.d.d.d", and |name| is expected
1163 to be a plain filename (no path components at all).
1165 static
1166 DiImage* open_debug_file( const HChar* name, const HChar* buildid, UInt crc,
1167 Bool rel_ok, const HChar* serverAddr )
1169 DiImage* dimg
1170 = serverAddr ? ML_(img_from_di_server)(name, serverAddr)
1171 : ML_(img_from_local_file)(name);
1172 if (dimg == NULL)
1173 return NULL;
1175 if (VG_(clo_verbosity) > 1) {
1176 if (serverAddr)
1177 VG_(message)(Vg_DebugMsg, " Considering %s on server %s ..\n",
1178 name, serverAddr);
1179 else
1180 VG_(message)(Vg_DebugMsg, " Considering %s ..\n", name);
1183 /* We will always check the crc if we have one (altfiles don't have one)
1184 for now because we might be opening the main file again by any other
1185 name, and that obviously also has the same buildid. More efficient
1186 would be an fstat bases check or a check that the file actually
1187 contains .debug* sections. */
1188 if (buildid && crc == 0) {
1189 HChar* debug_buildid = find_buildid(dimg, rel_ok, True);
1190 if (debug_buildid == NULL || VG_(strcmp)(buildid, debug_buildid) != 0) {
1191 ML_(img_done)(dimg);
1192 if (VG_(clo_verbosity) > 1)
1193 VG_(message)(Vg_DebugMsg,
1194 " .. build-id mismatch (found %s wanted %s)\n",
1195 debug_buildid, buildid);
1196 ML_(dinfo_free)(debug_buildid);
1197 return NULL;
1199 ML_(dinfo_free)(debug_buildid);
1200 if (VG_(clo_verbosity) > 1)
1201 VG_(message)(Vg_DebugMsg, " .. build-id is valid\n");
1202 } else {
1203 UInt calccrc = ML_(img_calc_gnu_debuglink_crc32)(dimg);
1204 if (calccrc != crc) {
1205 ML_(img_done)(dimg);
1206 if (VG_(clo_verbosity) > 1)
1207 VG_(message)(Vg_DebugMsg,
1208 " .. CRC mismatch (computed %08x wanted %08x)\n", calccrc, crc);
1209 return NULL;
1212 if (VG_(clo_verbosity) > 1)
1213 VG_(message)(Vg_DebugMsg, " .. CRC is valid\n");
1216 return dimg;
1220 /* Try to find a separate debug file for a given object file. If
1221 found, return its DiImage, which should be freed by the caller. If
1222 |buildid| is non-NULL, then a debug object matching it is
1223 acceptable. If |buildid| is NULL or doesn't specify a findable
1224 debug object, then we look in various places to find a file with
1225 the specified CRC. And if that doesn't work out then we give
1226 up. */
1227 static
1228 DiImage* find_debug_file( struct _DebugInfo* di,
1229 const HChar* objpath, const HChar* buildid,
1230 const HChar* debugname, UInt crc, Bool rel_ok )
1232 const HChar* extrapath = VG_(clo_extra_debuginfo_path);
1233 const HChar* serverpath = VG_(clo_debuginfo_server);
1235 DiImage* dimg = NULL; /* the img that we found */
1236 HChar* debugpath = NULL; /* where we found it */
1238 if (buildid != NULL) {
1239 debugpath = ML_(dinfo_zalloc)("di.fdf.1",
1240 VG_(strlen)(buildid) + 33);
1242 VG_(sprintf)(debugpath, "/usr/lib/debug/.build-id/%c%c/%s.debug",
1243 buildid[0], buildid[1], buildid + 2);
1245 dimg = open_debug_file(debugpath, buildid, 0, rel_ok, NULL);
1246 if (!dimg) {
1247 ML_(dinfo_free)(debugpath);
1248 debugpath = NULL;
1252 if (dimg == NULL && debugname != NULL) {
1253 HChar *objdir = ML_(dinfo_strdup)("di.fdf.2", objpath);
1254 HChar *objdirptr;
1256 if ((objdirptr = VG_(strrchr)(objdir, '/')) != NULL)
1257 *objdirptr = '\0';
1259 debugpath = ML_(dinfo_zalloc)(
1260 "di.fdf.3",
1261 VG_(strlen)(objdir) + VG_(strlen)(debugname) + 64
1262 + (extrapath ? VG_(strlen)(extrapath) : 0)
1263 + (serverpath ? VG_(strlen)(serverpath) : 0));
1265 VG_(sprintf)(debugpath, "%s/%s", objdir, debugname);
1266 dimg = open_debug_file(debugpath, buildid, crc, rel_ok, NULL);
1267 if (dimg != NULL) goto dimg_ok;
1269 VG_(sprintf)(debugpath, "%s/.debug/%s", objdir, debugname);
1270 dimg = open_debug_file(debugpath, buildid, crc, rel_ok, NULL);
1271 if (dimg != NULL) goto dimg_ok;
1273 VG_(sprintf)(debugpath, "/usr/lib/debug%s/%s", objdir, debugname);
1274 dimg = open_debug_file(debugpath, buildid, crc, rel_ok, NULL);
1275 if (dimg != NULL) goto dimg_ok;
1277 if (extrapath) {
1278 VG_(sprintf)(debugpath, "%s%s/%s", extrapath,
1279 objdir, debugname);
1280 dimg = open_debug_file(debugpath, buildid, crc, rel_ok, NULL);
1281 if (dimg != NULL) goto dimg_ok;
1284 if (serverpath) {
1285 /* When looking on the debuginfo server, always just pass the
1286 basename. */
1287 const HChar* basename = debugname;
1288 if (VG_(strstr)(basename, "/") != NULL) {
1289 basename = VG_(strrchr)(basename, '/') + 1;
1291 VG_(sprintf)(debugpath, "%s on %s", basename, serverpath);
1292 dimg = open_debug_file(basename, buildid, crc, rel_ok, serverpath);
1293 if (dimg) goto dimg_ok;
1296 dimg_ok:
1298 ML_(dinfo_free)(objdir);
1301 if (dimg != NULL) {
1302 vg_assert(debugpath);
1303 TRACE_SYMTAB("\n");
1304 TRACE_SYMTAB("------ Found a debuginfo file: %s\n", debugpath);
1306 /* Only set once, we might be called again for opening the altfile. */
1307 if (di->fsm.dbgname == NULL)
1308 di->fsm.dbgname = ML_(dinfo_strdup)("di.fdf.4", debugpath);
1311 if (debugpath)
1312 ML_(dinfo_free)(debugpath);
1314 return dimg;
1318 /* Try to find a separate debug file for a given object file, in a
1319 hacky and dangerous way: check only the --extra-debuginfo-path and
1320 the --debuginfo-server. And don't do a consistency check. */
1321 static
1322 DiImage* find_debug_file_ad_hoc( const DebugInfo* di,
1323 const HChar* objpath )
1325 const HChar* extrapath = VG_(clo_extra_debuginfo_path);
1326 const HChar* serverpath = VG_(clo_debuginfo_server);
1328 DiImage* dimg = NULL; /* the img that we found */
1329 HChar* debugpath = NULL; /* where we found it */
1331 HChar *objdir = ML_(dinfo_strdup)("di.fdfah.1", objpath);
1332 HChar *objdirptr;
1334 if ((objdirptr = VG_(strrchr)(objdir, '/')) != NULL)
1335 *objdirptr = '\0';
1337 debugpath = ML_(dinfo_zalloc)(
1338 "di.fdfah.3",
1339 VG_(strlen)(objdir) + 64
1340 + (extrapath ? VG_(strlen)(extrapath) : 0)
1341 + (serverpath ? VG_(strlen)(serverpath) : 0));
1343 if (extrapath) {
1344 VG_(sprintf)(debugpath, "%s/%s", extrapath, objpath);
1345 dimg = ML_(img_from_local_file)(debugpath);
1346 if (dimg != NULL) {
1347 if (VG_(clo_verbosity) > 1) {
1348 VG_(message)(Vg_DebugMsg, " Using (POSSIBLY MISMATCHED) %s\n",
1349 debugpath);
1351 goto dimg_ok;
1354 if (serverpath) {
1355 /* When looking on the debuginfo server, always just pass the
1356 basename. */
1357 const HChar* basename = objpath;
1358 if (VG_(strstr)(basename, "/") != NULL) {
1359 basename = VG_(strrchr)(basename, '/') + 1;
1361 VG_(sprintf)(debugpath, "%s on %s", basename, serverpath);
1362 dimg = ML_(img_from_di_server)(basename, serverpath);
1363 if (dimg != NULL) {
1364 if (VG_(clo_verbosity) > 1) {
1365 VG_(message)(Vg_DebugMsg, " Using (POSSIBLY MISMATCHED) %s\n",
1366 debugpath);
1368 goto dimg_ok;
1372 dimg_ok:
1374 ML_(dinfo_free)(objdir);
1376 if (dimg != NULL) {
1377 vg_assert(debugpath);
1378 TRACE_SYMTAB("\n");
1379 TRACE_SYMTAB("------ Found an ad_hoc debuginfo file: %s\n", debugpath);
1382 if (debugpath)
1383 ML_(dinfo_free)(debugpath);
1385 return dimg;
1389 static DiOffT INDEX_BIS ( DiOffT base, UWord idx, UWord scale ) {
1390 // This is a bit stupid. Really, idx and scale ought to be
1391 // 64-bit quantities, always.
1392 return base + (DiOffT)idx * (DiOffT)scale;
1396 /* Find the file offset corresponding to SVMA by using the program
1397 headers. This is taken from binutils-2.17/binutils/readelf.c
1398 offset_from_vma(). */
1399 static
1400 Word file_offset_from_svma ( /*OUT*/Bool* ok,
1401 Addr svma,
1402 DiImage* img,
1403 DiOffT phdr_ioff,
1404 Word phdr_nent,
1405 Word phdr_ent_szB )
1407 Word i;
1408 for (i = 0; i < phdr_nent; i++) {
1409 ElfXX_Phdr seg;
1410 ML_(img_get)(&seg, img,
1411 INDEX_BIS(phdr_ioff, i, phdr_ent_szB), sizeof(seg));
1412 if (seg.p_type != PT_LOAD)
1413 continue;
1414 if (svma >= (seg.p_vaddr & -seg.p_align)
1415 && svma + 1 <= seg.p_vaddr + seg.p_filesz) {
1416 *ok = True;
1417 return svma - seg.p_vaddr + seg.p_offset;
1420 *ok = False;
1421 return 0;
1425 /* The central function for reading ELF debug info. For the
1426 object/exe specified by the DebugInfo, find ELF sections, then read
1427 the symbols, line number info, file name info, CFA (stack-unwind
1428 info) and anything else we want, into the tables within the
1429 supplied DebugInfo.
1432 Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
1434 /* This function is long and complex. That, and the presence of
1435 nested scopes, means it's not always easy to see which parts are
1436 in loops/conditionals and which aren't. To make it easier to
1437 follow, points executed exactly once -- that is, those which are
1438 the top level of the function -- are marked TOPLEVEL.
1440 /* Consistent terminology for local variable names, without which
1441 it's almost unfollowably complex:
1443 In which file?
1444 in the main ELF file *_m*
1445 in the debuginfo file *_d*
1446 in the alt debuginfo file *_a*
1448 What kind of thing?
1449 _{m,d,a}img a DiImage*
1450 _{m,d,a}ioff an offset in the image (DiOffT)
1451 _{m,d,a}nent "number of entries"
1452 _{m,d,a}ent_szB "size in bytes of an entry"
1453 ehdr_{m,d,a} ELF header
1454 phdr Program header
1455 shdr Section header
1456 a_X a temporary X
1457 _escn an DiSlice (elf section info) variable
1458 szB size in bytes
1462 /* TOPLEVEL */
1463 Bool res, ok;
1464 Word i, j;
1465 Bool dynbss_present = False;
1466 Bool sdynbss_present = False;
1468 /* Image for the main ELF file we're working with. */
1469 DiImage* mimg = NULL;
1471 /* Ditto for any ELF debuginfo file that we might happen to load. */
1472 DiImage* dimg = NULL;
1474 /* Ditto for alternate ELF debuginfo file that we might happen to load. */
1475 DiImage* aimg = NULL;
1477 /* ELF header offset for the main file. Should be zero since the
1478 ELF header is at start of file. */
1479 DiOffT ehdr_mioff = 0;
1481 /* Program header table image addr, # entries, entry size */
1482 DiOffT phdr_mioff = 0;
1483 UWord phdr_mnent = 0;
1484 UWord phdr_ment_szB = 0;
1486 /* Section header image addr, # entries, entry size. Also the
1487 associated string table. */
1488 DiOffT shdr_mioff = 0;
1489 UWord shdr_mnent = 0;
1490 UWord shdr_ment_szB = 0;
1491 DiOffT shdr_strtab_mioff = 0;
1493 /* SVMAs covered by rx and rw segments and corresponding biases.
1494 Normally each object would provide just one rx and one rw area,
1495 but various ELF mangling tools create objects with multiple
1496 such entries, hence the generality. */
1497 typedef
1498 struct {
1499 Addr svma_base;
1500 Addr svma_limit;
1501 PtrdiffT bias;
1502 Bool exec;
1504 RangeAndBias;
1506 XArray* /* of RangeAndBias */ svma_ranges = NULL;
1508 vg_assert(di);
1509 vg_assert(di->fsm.have_rx_map == True);
1510 vg_assert(di->fsm.have_rw_map == True);
1511 vg_assert(di->have_dinfo == False);
1512 vg_assert(di->fsm.filename);
1513 vg_assert(!di->symtab);
1514 vg_assert(!di->loctab);
1515 vg_assert(!di->inltab);
1516 vg_assert(!di->cfsi_base);
1517 vg_assert(!di->cfsi_m_ix);
1518 vg_assert(!di->cfsi_rd);
1519 vg_assert(!di->cfsi_exprs);
1520 vg_assert(!di->strpool);
1521 vg_assert(!di->fndnpool);
1522 vg_assert(!di->soname);
1525 Bool has_nonempty_rx = False;
1526 Bool has_nonempty_rw = False;
1527 for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1528 DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
1529 if (!map->rx && !map->rw)
1530 continue;
1531 if (map->rx && map->size > 0)
1532 has_nonempty_rx = True;
1533 if (map->rw && map->size > 0)
1534 has_nonempty_rw = True;
1535 /* If this doesn't hold true, it means that m_syswrap/m_aspacemgr
1536 managed to do a mapping where the start isn't page aligned.
1537 Which sounds pretty bogus to me. */
1538 vg_assert(VG_IS_PAGE_ALIGNED(map->avma));
1540 vg_assert(has_nonempty_rx);
1541 vg_assert(has_nonempty_rw);
1544 /* ----------------------------------------------------------
1545 At this point, there is very little information in the
1546 DebugInfo. We only know that something that looks like an ELF
1547 file has been mapped rx-ishly and rw-ishly as recorded in the
1548 di->fsm.maps array items. First we examine the file's ELF
1549 Program Header, and, by comparing that against the di->fsm.maps
1550 info, try to figure out the AVMAs for the sections we care
1551 about, that should have been mapped: text, data, sdata, bss,
1552 got, plt, and toc.
1553 ---------------------------------------------------------- */
1555 res = False;
1557 if (VG_(clo_verbosity) > 1 || VG_(clo_trace_redir))
1558 VG_(message)(Vg_DebugMsg, "Reading syms from %s\n",
1559 di->fsm.filename );
1561 /* Connect to the primary object image, so that we can read symbols
1562 and line number info out of it. It will be disconnected
1563 immediately thereafter; it is only connected transiently. */
1564 mimg = ML_(img_from_local_file)(di->fsm.filename);
1565 if (mimg == NULL) {
1566 VG_(message)(Vg_UserMsg, "warning: connection to image %s failed\n",
1567 di->fsm.filename );
1568 VG_(message)(Vg_UserMsg, " no symbols or debug info loaded\n" );
1569 return False;
1572 /* Ok, the object image is available. Now verify that it is a
1573 valid ELF .so or executable image. */
1574 ok = is_elf_object_file_by_DiImage(mimg, False);
1575 if (!ok) {
1576 ML_(symerr)(di, True, "Invalid ELF Header");
1577 goto out;
1580 /* Find where the program and section header tables are, and give
1581 up if either is missing or outside the image (bogus). */
1582 ElfXX_Ehdr ehdr_m;
1583 vg_assert(ehdr_mioff == 0); // ensured by its initialisation
1584 ok = ML_(img_valid)(mimg, ehdr_mioff, sizeof(ehdr_m));
1585 vg_assert(ok); // ML_(is_elf_object_file) should ensure this
1586 ML_(img_get)(&ehdr_m, mimg, ehdr_mioff, sizeof(ehdr_m));
1588 phdr_mioff = ehdr_mioff + ehdr_m.e_phoff;
1589 phdr_mnent = ehdr_m.e_phnum;
1590 phdr_ment_szB = ehdr_m.e_phentsize;
1592 shdr_mioff = ehdr_mioff + ehdr_m.e_shoff;
1593 shdr_mnent = ehdr_m.e_shnum;
1594 shdr_ment_szB = ehdr_m.e_shentsize;
1596 TRACE_SYMTAB("------ Basic facts about the object ------\n");
1597 TRACE_SYMTAB("object: n_oimage %llu\n",
1598 (ULong)ML_(img_size)(mimg));
1599 TRACE_SYMTAB("phdr: ioff %llu nent %ld ent_szB %ld\n",
1600 phdr_mioff, phdr_mnent, phdr_ment_szB);
1601 TRACE_SYMTAB("shdr: ioff %llu nent %ld ent_szB %ld\n",
1602 shdr_mioff, shdr_mnent, shdr_ment_szB);
1603 for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1604 const DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
1605 if (map->rx)
1606 TRACE_SYMTAB("rx_map: avma %#lx size %lu foff %lu\n",
1607 map->avma, map->size, map->foff);
1609 for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1610 const DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
1611 if (map->rw)
1612 TRACE_SYMTAB("rw_map: avma %#lx size %lu foff %lu\n",
1613 map->avma, map->size, map->foff);
1616 if (phdr_mnent == 0
1617 || !ML_(img_valid)(mimg, phdr_mioff, phdr_mnent * phdr_ment_szB)) {
1618 ML_(symerr)(di, True, "Missing or invalid ELF Program Header Table");
1619 goto out;
1622 if (shdr_mnent == 0
1623 || !ML_(img_valid)(mimg, shdr_mioff, shdr_mnent * shdr_ment_szB)) {
1624 ML_(symerr)(di, True, "Missing or invalid ELF Section Header Table");
1625 goto out;
1628 /* Also find the section header's string table, and validate. */
1629 /* checked previously by is_elf_object_file: */
1630 vg_assert(ehdr_m.e_shstrndx != SHN_UNDEF);
1632 // shdr_mioff is the offset of the section header table
1633 // and we need the ehdr_m.e_shstrndx'th entry
1634 { ElfXX_Shdr a_shdr;
1635 ML_(img_get)(&a_shdr, mimg,
1636 INDEX_BIS(shdr_mioff, ehdr_m.e_shstrndx, shdr_ment_szB),
1637 sizeof(a_shdr));
1638 shdr_strtab_mioff
1639 = ehdr_mioff /* isn't this always zero? */ + a_shdr.sh_offset;
1641 if (!ML_(img_valid)(mimg, shdr_strtab_mioff,
1642 1/*bogus, but we don't know the real size*/ )) {
1643 ML_(symerr)(di, True, "Invalid ELF Section Header String Table");
1644 goto out;
1648 TRACE_SYMTAB("shdr: string table at %llu\n", shdr_strtab_mioff);
1650 svma_ranges = VG_(newXA)(ML_(dinfo_zalloc), "di.relfdi.1",
1651 ML_(dinfo_free), sizeof(RangeAndBias));
1653 /* TOPLEVEL */
1654 /* Look through the program header table, and:
1655 - copy information from suitable PT_LOAD entries into svma_ranges
1656 - find (or fake up) the .soname for this object.
1658 TRACE_SYMTAB("\n");
1659 TRACE_SYMTAB("------ Examining the program headers ------\n");
1660 vg_assert(di->soname == NULL);
1662 /* TOPLEVEL */
1663 ElfXX_Addr prev_svma = 0;
1665 for (i = 0; i < phdr_mnent; i++) {
1666 ElfXX_Phdr a_phdr;
1667 ML_(img_get)(&a_phdr, mimg,
1668 INDEX_BIS(phdr_mioff, i, phdr_ment_szB),
1669 sizeof(a_phdr));
1671 /* Make sure the PT_LOADable entries are in order and
1672 non-overlapping. This in turn means the address ranges
1673 slurped into svma_ranges are in order and
1674 non-overlapping. */
1676 if (a_phdr.p_type == PT_LOAD) {
1677 TRACE_SYMTAB("PT_LOAD[%ld]: p_vaddr %#lx (prev %#lx)\n",
1678 i, (UWord)a_phdr.p_vaddr, (UWord)prev_svma);
1679 TRACE_SYMTAB("PT_LOAD[%ld]: p_offset %lu, p_filesz %lu,"
1680 " perms %c%c%c\n",
1681 i, (UWord)a_phdr.p_offset, (UWord)a_phdr.p_filesz,
1682 a_phdr.p_flags & PF_R ? 'r' : '-',
1683 a_phdr.p_flags & PF_W ? 'w' : '-',
1684 a_phdr.p_flags & PF_X ? 'x' : '-');
1685 if (a_phdr.p_vaddr < prev_svma) {
1686 ML_(symerr)(di, True,
1687 "ELF Program Headers are not in ascending order");
1688 goto out;
1690 prev_svma = a_phdr.p_vaddr;
1691 if (a_phdr.p_memsz > 0) {
1692 Bool loaded = False;
1693 for (j = 0; j < VG_(sizeXA)(di->fsm.maps); j++) {
1694 const DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, j);
1695 if ( (map->rx || map->rw)
1696 && map->size > 0 /* stay sane */
1697 && a_phdr.p_offset >= map->foff
1698 && a_phdr.p_offset < map->foff + map->size
1699 && a_phdr.p_offset + a_phdr.p_filesz
1700 <= map->foff + map->size) {
1701 RangeAndBias item;
1702 item.svma_base = a_phdr.p_vaddr;
1703 item.svma_limit = a_phdr.p_vaddr + a_phdr.p_memsz;
1704 item.bias = map->avma - map->foff
1705 + a_phdr.p_offset - a_phdr.p_vaddr;
1706 if (map->rw
1707 && (a_phdr.p_flags & (PF_R | PF_W))
1708 == (PF_R | PF_W)) {
1709 item.exec = False;
1710 VG_(addToXA)(svma_ranges, &item);
1711 TRACE_SYMTAB(
1712 "PT_LOAD[%ld]: acquired as rw, bias 0x%lx\n",
1713 i, item.bias);
1714 loaded = True;
1716 if (map->rx
1717 && (a_phdr.p_flags & (PF_R | PF_X))
1718 == (PF_R | PF_X)) {
1719 item.exec = True;
1720 VG_(addToXA)(svma_ranges, &item);
1721 TRACE_SYMTAB(
1722 "PT_LOAD[%ld]: acquired as rx, bias 0x%lx\n",
1723 i, item.bias);
1724 loaded = True;
1728 if (!loaded) {
1729 ML_(symerr)(di, False,
1730 "ELF section outside all mapped regions");
1731 /* This problem might be solved by further memory mappings.
1732 Avoid the vg_assert(!di->soname) at the beginning of this
1733 function if DYNAMIC section has been already processed. */
1734 if (di->soname) {
1735 ML_(dinfo_free)(di->soname);
1736 di->soname = NULL;
1738 goto out;
1743 /* Try to get the soname. If there isn't one, use "NONE".
1744 The seginfo needs to have some kind of soname in order to
1745 facilitate writing redirect functions, since all redirect
1746 specifications require a soname (pattern). */
1747 if (a_phdr.p_type == PT_DYNAMIC && di->soname == NULL) {
1748 Word stroff = -1;
1749 DiOffT strtab_mioff = DiOffT_INVALID;
1750 for (j = 0; True/*exit check is in the loop*/; j++) {
1751 ElfXX_Dyn t_dyn_m; /* dyn_img[j] */
1752 ML_(img_get)(&t_dyn_m, mimg,
1753 INDEX_BIS(ehdr_mioff + a_phdr.p_offset,
1754 j, sizeof(ElfXX_Dyn)),
1755 sizeof(t_dyn_m));
1756 if (t_dyn_m.d_tag == DT_NULL)
1757 break;
1759 switch (t_dyn_m.d_tag) {
1760 case DT_SONAME: {
1761 stroff = t_dyn_m.d_un.d_val;
1762 break;
1764 case DT_STRTAB: {
1765 Bool ok2 = False;
1766 Word offset = file_offset_from_svma(
1767 &ok2, t_dyn_m.d_un.d_ptr, mimg,
1768 phdr_mioff, phdr_mnent, phdr_ment_szB
1770 if (ok2 && strtab_mioff == DiOffT_INVALID) {
1771 // Check for obviously bogus offsets.
1772 if (!ML_(img_valid)(mimg, offset, 1)) {
1773 ML_(symerr)(di, True, "Invalid DT_STRTAB offset");
1774 goto out;
1776 strtab_mioff = ehdr_mioff + offset;
1777 vg_assert(ehdr_mioff == 0); // should always be
1779 break;
1781 default:
1782 break;
1785 if (stroff != -1 && strtab_mioff != DiOffT_INVALID) {
1786 di->soname = ML_(img_strdup)(mimg, "di.redi.1",
1787 strtab_mioff + stroff);
1788 TRACE_SYMTAB("Found soname = %s\n", di->soname);
1791 } /* for (i = 0; i < phdr_Mnent; i++) ... */
1792 /* TOPLEVEL */
1794 } /* examine the program headers (local scope) */
1796 /* TOPLEVEL */
1798 /* If, after looking at all the program headers, we still didn't
1799 find a soname, add a fake one. */
1800 if (di->soname == NULL) {
1801 TRACE_SYMTAB("No soname found; using (fake) \"NONE\"\n");
1802 di->soname = ML_(dinfo_strdup)("di.redi.2", "NONE");
1805 vg_assert(VG_(sizeXA)(svma_ranges) != 0);
1807 /* Now read the section table. */
1808 TRACE_SYMTAB("\n");
1809 TRACE_SYMTAB("------ Examining the section headers ------\n");
1810 for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1811 const DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
1812 if (map->rx)
1813 TRACE_SYMTAB("rx: at %#lx are mapped foffsets %ld .. %ld\n",
1814 map->avma, map->foff, map->foff + map->size - 1 );
1816 TRACE_SYMTAB("rx: contains these svma regions:\n");
1817 for (i = 0; i < VG_(sizeXA)(svma_ranges); i++) {
1818 const RangeAndBias* reg = VG_(indexXA)(svma_ranges, i);
1819 if (reg->exec)
1820 TRACE_SYMTAB(" svmas %#lx .. %#lx with bias %#lx\n",
1821 reg->svma_base, reg->svma_limit - 1, reg->bias );
1823 for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1824 const DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
1825 if (map->rw)
1826 TRACE_SYMTAB("rw: at %#lx are mapped foffsets %ld .. %ld\n",
1827 map->avma, map->foff, map->foff + map->size - 1 );
1829 TRACE_SYMTAB("rw: contains these svma regions:\n");
1830 for (i = 0; i < VG_(sizeXA)(svma_ranges); i++) {
1831 const RangeAndBias* reg = VG_(indexXA)(svma_ranges, i);
1832 if (!reg->exec)
1833 TRACE_SYMTAB(" svmas %#lx .. %#lx with bias %#lx\n",
1834 reg->svma_base, reg->svma_limit - 1, reg->bias );
1837 /* TOPLEVEL */
1838 /* Iterate over section headers */
1839 for (i = 0; i < shdr_mnent; i++) {
1840 ElfXX_Shdr a_shdr;
1841 ML_(img_get)(&a_shdr, mimg,
1842 INDEX_BIS(shdr_mioff, i, shdr_ment_szB), sizeof(a_shdr));
1843 DiOffT name_mioff = shdr_strtab_mioff + a_shdr.sh_name;
1844 HChar* name = ML_(img_strdup)(mimg, "di.redi_name.1", name_mioff);
1845 Addr svma = a_shdr.sh_addr;
1846 OffT foff = a_shdr.sh_offset;
1847 UWord size = a_shdr.sh_size; /* Do not change this to be signed. */
1848 UInt alyn = a_shdr.sh_addralign;
1849 Bool bits = !(a_shdr.sh_type == SHT_NOBITS);
1850 /* Look through our collection of info obtained from the PT_LOAD
1851 headers, and make 'inrx' and 'inrw' point to the first entry
1852 in each that intersects 'avma'. If in each case none is found,
1853 leave the relevant pointer at NULL. */
1854 RangeAndBias* inrx = NULL;
1855 RangeAndBias* inrw = NULL;
1856 for (j = 0; j < VG_(sizeXA)(svma_ranges); j++) {
1857 RangeAndBias* rng = VG_(indexXA)(svma_ranges, j);
1858 if (svma >= rng->svma_base && svma < rng->svma_limit) {
1859 if (!inrx && rng->exec) {
1860 inrx = rng;
1861 } else if (!inrw && !rng->exec) {
1862 inrw = rng;
1864 if (inrx && inrw)
1865 break;
1869 TRACE_SYMTAB(" [sec %2ld] %s %s al%2u foff %6ld .. %6ld "
1870 " svma %p name \"%s\"\n",
1871 i, inrx ? "rx" : " ", inrw ? "rw" : " ", alyn,
1872 foff, foff+size-1, (void*)svma, name);
1874 /* Check for sane-sized segments. SHT_NOBITS sections have zero
1875 size in the file. */
1876 if ((foff >= ML_(img_size)(mimg))
1877 || (foff + (bits ? size : 0) > ML_(img_size)(mimg))) {
1878 ML_(symerr)(di, True, "ELF Section extends beyond image end");
1879 goto out;
1882 /* Check for a sane alignment value. */
1883 if (alyn > 0 && -1 == VG_(log2)(alyn)) {
1884 ML_(symerr)(di, True, "ELF Section contains invalid "
1885 ".sh_addralign value");
1886 goto out;
1889 /* Ignore zero sized sections. */
1890 if (size == 0) {
1891 TRACE_SYMTAB("zero sized section \"%s\", ignoring\n", name);
1892 ML_(dinfo_free)(name);
1893 continue;
1896 # define BAD(_secname) \
1897 do { ML_(symerr)(di, True, \
1898 "Can't make sense of " _secname \
1899 " section mapping"); \
1900 /* make sure we don't assert if we find */ \
1901 /* ourselves back in this routine later, */ \
1902 /* with the same di */ \
1903 di->soname = NULL; \
1904 goto out; \
1905 } while (0)
1907 /* Find avma-s for: .text .data .sdata .rodata .bss .sbss .plt .got .opd
1908 and .eh_frame */
1910 /* Accept .text where mapped as rx (code), even if zero-sized */
1911 if (0 == VG_(strcmp)(name, ".text")) {
1912 if (inrx && !di->text_present) {
1913 di->text_present = True;
1914 di->text_svma = svma;
1915 di->text_avma = svma + inrx->bias;
1916 di->text_size = size;
1917 di->text_bias = inrx->bias;
1918 di->text_debug_svma = svma;
1919 di->text_debug_bias = inrx->bias;
1920 TRACE_SYMTAB("acquiring .text svma = %#lx .. %#lx\n",
1921 di->text_svma,
1922 di->text_svma + di->text_size - 1);
1923 TRACE_SYMTAB("acquiring .text avma = %#lx .. %#lx\n",
1924 di->text_avma,
1925 di->text_avma + di->text_size - 1);
1926 TRACE_SYMTAB("acquiring .text bias = %#lx\n", di->text_bias);
1927 } else {
1928 BAD(".text");
1932 /* Accept .data where mapped as rw (data), even if zero-sized */
1933 if (0 == VG_(strcmp)(name, ".data")) {
1934 if (inrw && !di->data_present) {
1935 di->data_present = True;
1936 di->data_svma = svma;
1937 di->data_avma = svma + inrw->bias;
1938 di->data_size = size;
1939 di->data_bias = inrw->bias;
1940 di->data_debug_svma = svma;
1941 di->data_debug_bias = inrw->bias;
1942 TRACE_SYMTAB("acquiring .data svma = %#lx .. %#lx\n",
1943 di->data_svma,
1944 di->data_svma + di->data_size - 1);
1945 TRACE_SYMTAB("acquiring .data avma = %#lx .. %#lx\n",
1946 di->data_avma,
1947 di->data_avma + di->data_size - 1);
1948 TRACE_SYMTAB("acquiring .data bias = %#lx\n", di->data_bias);
1949 } else {
1950 BAD(".data");
1954 /* Accept .sdata where mapped as rw (data) */
1955 if (0 == VG_(strcmp)(name, ".sdata")) {
1956 if (inrw && !di->sdata_present) {
1957 di->sdata_present = True;
1958 di->sdata_svma = svma;
1959 di->sdata_avma = svma + inrw->bias;
1960 di->sdata_size = size;
1961 di->sdata_bias = inrw->bias;
1962 di->sdata_debug_svma = svma;
1963 di->sdata_debug_bias = inrw->bias;
1964 TRACE_SYMTAB("acquiring .sdata svma = %#lx .. %#lx\n",
1965 di->sdata_svma,
1966 di->sdata_svma + di->sdata_size - 1);
1967 TRACE_SYMTAB("acquiring .sdata avma = %#lx .. %#lx\n",
1968 di->sdata_avma,
1969 di->sdata_avma + di->sdata_size - 1);
1970 TRACE_SYMTAB("acquiring .sdata bias = %#lx\n", di->sdata_bias);
1971 } else {
1972 BAD(".sdata");
1976 /* Accept .rodata where mapped as rx (data), even if zero-sized */
1977 if (0 == VG_(strcmp)(name, ".rodata")) {
1978 if (inrx && !di->rodata_present) {
1979 di->rodata_present = True;
1980 di->rodata_svma = svma;
1981 di->rodata_avma = svma + inrx->bias;
1982 di->rodata_size = size;
1983 di->rodata_bias = inrx->bias;
1984 di->rodata_debug_svma = svma;
1985 di->rodata_debug_bias = inrx->bias;
1986 /* NB was 'inrw' prior to r11794 */
1987 TRACE_SYMTAB("acquiring .rodata svma = %#lx .. %#lx\n",
1988 di->rodata_svma,
1989 di->rodata_svma + di->rodata_size - 1);
1990 TRACE_SYMTAB("acquiring .rodata avma = %#lx .. %#lx\n",
1991 di->rodata_avma,
1992 di->rodata_avma + di->rodata_size - 1);
1993 TRACE_SYMTAB("acquiring .rodata bias = %#lx\n", di->rodata_bias);
1994 } else {
1995 BAD(".rodata");
1999 if (0 == VG_(strcmp)(name, ".dynbss")) {
2000 if (inrw && !di->bss_present) {
2001 dynbss_present = True;
2002 di->bss_present = True;
2003 di->bss_svma = svma;
2004 di->bss_avma = svma + inrw->bias;
2005 di->bss_size = size;
2006 di->bss_bias = inrw->bias;
2007 di->bss_debug_svma = svma;
2008 di->bss_debug_bias = inrw->bias;
2009 TRACE_SYMTAB("acquiring .dynbss svma = %#lx .. %#lx\n",
2010 di->bss_svma,
2011 di->bss_svma + di->bss_size - 1);
2012 TRACE_SYMTAB("acquiring .dynbss avma = %#lx .. %#lx\n",
2013 di->bss_avma,
2014 di->bss_avma + di->bss_size - 1);
2015 TRACE_SYMTAB("acquiring .dynbss bias = %#lx\n", di->bss_bias);
2019 /* Accept .bss where mapped as rw (data), even if zero-sized */
2020 if (0 == VG_(strcmp)(name, ".bss")) {
2021 if (inrw && dynbss_present) {
2022 vg_assert(di->bss_present);
2023 dynbss_present = False;
2024 vg_assert(di->bss_svma + di->bss_size == svma);
2025 di->bss_size += size;
2026 TRACE_SYMTAB("acquiring .bss svma = %#lx .. %#lx\n",
2027 svma, svma + size - 1);
2028 TRACE_SYMTAB("acquiring .bss avma = %#lx .. %#lx\n",
2029 svma + inrw->bias, svma + inrw->bias + size - 1);
2030 TRACE_SYMTAB("acquiring .bss bias = %#lx\n", di->bss_bias);
2031 } else
2033 if (inrw && !di->bss_present) {
2034 di->bss_present = True;
2035 di->bss_svma = svma;
2036 di->bss_avma = svma + inrw->bias;
2037 di->bss_size = size;
2038 di->bss_bias = inrw->bias;
2039 di->bss_debug_svma = svma;
2040 di->bss_debug_bias = inrw->bias;
2041 TRACE_SYMTAB("acquiring .bss svma = %#lx .. %#lx\n",
2042 di->bss_svma,
2043 di->bss_svma + di->bss_size - 1);
2044 TRACE_SYMTAB("acquiring .bss avma = %#lx .. %#lx\n",
2045 di->bss_avma,
2046 di->bss_avma + di->bss_size - 1);
2047 TRACE_SYMTAB("acquiring .bss bias = %#lx\n", di->bss_bias);
2048 } else
2050 /* Now one from the wtf?! department ... */
2051 if (inrx && (!inrw) && !di->bss_present) {
2052 /* File contains a .bss, but it got mapped as rx only.
2053 This is very strange. For now, just pretend we didn't
2054 see it :-) */
2055 di->bss_present = False;
2056 di->bss_svma = 0;
2057 di->bss_avma = 0;
2058 di->bss_size = 0;
2059 di->bss_bias = 0;
2060 di->bss_debug_svma = 0;
2061 di->bss_debug_bias = 0;
2062 if (!VG_(clo_xml)) {
2063 VG_(message)(Vg_UserMsg,
2064 "Warning: the following file's .bss is "
2065 "mapped r-x only - ignoring .bss syms\n");
2066 VG_(message)(Vg_UserMsg, " %s\n", di->fsm.filename
2067 ? di->fsm.filename
2068 : "(null?!)" );
2070 } else
2072 if ((!inrw) && (!inrx) && !di->bss_present) {
2073 /* File contains a .bss, but it didn't get mapped. Ignore. */
2074 di->bss_present = False;
2075 di->bss_svma = 0;
2076 di->bss_avma = 0;
2077 di->bss_size = 0;
2078 di->bss_bias = 0;
2079 } else {
2080 BAD(".bss");
2084 if (0 == VG_(strcmp)(name, ".sdynbss")) {
2085 if (inrw && !di->sbss_present) {
2086 sdynbss_present = True;
2087 di->sbss_present = True;
2088 di->sbss_svma = svma;
2089 di->sbss_avma = svma + inrw->bias;
2090 di->sbss_size = size;
2091 di->sbss_bias = inrw->bias;
2092 di->sbss_debug_svma = svma;
2093 di->sbss_debug_bias = inrw->bias;
2094 TRACE_SYMTAB("acquiring .sdynbss svma = %#lx .. %#lx\n",
2095 di->sbss_svma,
2096 di->sbss_svma + di->sbss_size - 1);
2097 TRACE_SYMTAB("acquiring .sdynbss avma = %#lx .. %#lx\n",
2098 di->sbss_avma,
2099 di->sbss_avma + di->sbss_size - 1);
2100 TRACE_SYMTAB("acquiring .sdynbss bias = %#lx\n", di->sbss_bias);
2104 /* Accept .sbss where mapped as rw (data) */
2105 if (0 == VG_(strcmp)(name, ".sbss")) {
2106 if (inrw && sdynbss_present) {
2107 vg_assert(di->sbss_present);
2108 sdynbss_present = False;
2109 vg_assert(di->sbss_svma + di->sbss_size == svma);
2110 di->sbss_size += size;
2111 TRACE_SYMTAB("acquiring .sbss svma = %#lx .. %#lx\n",
2112 svma, svma + size - 1);
2113 TRACE_SYMTAB("acquiring .sbss avma = %#lx .. %#lx\n",
2114 svma + inrw->bias, svma + inrw->bias + size - 1);
2115 TRACE_SYMTAB("acquiring .sbss bias = %#lx\n", di->sbss_bias);
2116 } else
2118 if (inrw && !di->sbss_present) {
2119 di->sbss_present = True;
2120 di->sbss_svma = svma;
2121 di->sbss_avma = svma + inrw->bias;
2122 di->sbss_size = size;
2123 di->sbss_bias = inrw->bias;
2124 di->sbss_debug_svma = svma;
2125 di->sbss_debug_bias = inrw->bias;
2126 TRACE_SYMTAB("acquiring .sbss svma = %#lx .. %#lx\n",
2127 di->sbss_svma,
2128 di->sbss_svma + di->sbss_size - 1);
2129 TRACE_SYMTAB("acquiring .sbss avma = %#lx .. %#lx\n",
2130 di->sbss_avma,
2131 di->sbss_avma + di->sbss_size - 1);
2132 TRACE_SYMTAB("acquiring .sbss bias = %#lx\n", di->sbss_bias);
2133 } else {
2134 BAD(".sbss");
2138 /* Accept .got where mapped as rw (data) */
2139 if (0 == VG_(strcmp)(name, ".got")) {
2140 if (inrw && !di->got_present) {
2141 di->got_present = True;
2142 di->got_avma = svma + inrw->bias;
2143 di->got_size = size;
2144 TRACE_SYMTAB("acquiring .got avma = %#lx\n", di->got_avma);
2145 } else {
2146 BAD(".got");
2150 /* Accept .got.plt where mapped as rw (data) */
2151 if (0 == VG_(strcmp)(name, ".got.plt")) {
2152 if (inrw && !di->gotplt_present) {
2153 di->gotplt_present = True;
2154 di->gotplt_avma = svma + inrw->bias;
2155 di->gotplt_size = size;
2156 TRACE_SYMTAB("acquiring .got.plt avma = %#lx\n", di->gotplt_avma);
2157 } else if (size != 0) {
2158 BAD(".got.plt");
2162 /* PLT is different on different platforms, it seems. */
2163 # if defined(VGP_x86_linux) || defined(VGP_amd64_linux) \
2164 || defined(VGP_arm_linux) || defined (VGP_s390x_linux) \
2165 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
2166 || defined(VGP_arm64_linux)
2167 /* Accept .plt where mapped as rx (code) */
2168 if (0 == VG_(strcmp)(name, ".plt")) {
2169 if (inrx && !di->plt_present) {
2170 di->plt_present = True;
2171 di->plt_avma = svma + inrx->bias;
2172 di->plt_size = size;
2173 TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
2174 } else {
2175 BAD(".plt");
2178 # elif defined(VGP_ppc32_linux)
2179 /* Accept .plt where mapped as rw (data) */
2180 if (0 == VG_(strcmp)(name, ".plt")) {
2181 if (inrw && !di->plt_present) {
2182 di->plt_present = True;
2183 di->plt_avma = svma + inrw->bias;
2184 di->plt_size = size;
2185 TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
2186 } else {
2187 BAD(".plt");
2190 # elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
2191 /* Accept .plt where mapped as rw (data), or unmapped */
2192 if (0 == VG_(strcmp)(name, ".plt")) {
2193 if (inrw && !di->plt_present) {
2194 di->plt_present = True;
2195 di->plt_avma = svma + inrw->bias;
2196 di->plt_size = size;
2197 TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
2198 } else
2199 if ((!inrw) && (!inrx) && size > 0 && !di->plt_present) {
2200 /* File contains a .plt, but it didn't get mapped.
2201 Presumably it is not required on this platform. At
2202 least don't reject the situation as invalid. */
2203 di->plt_present = True;
2204 di->plt_avma = 0;
2205 di->plt_size = 0;
2206 } else {
2207 BAD(".plt");
2210 # else
2211 # error "Unsupported platform"
2212 # endif
2214 /* Accept .opd where mapped as rw (data) */
2215 if (0 == VG_(strcmp)(name, ".opd")) {
2216 if (inrw && !di->opd_present) {
2217 di->opd_present = True;
2218 di->opd_avma = svma + inrw->bias;
2219 di->opd_size = size;
2220 TRACE_SYMTAB("acquiring .opd avma = %#lx\n", di->opd_avma);
2221 } else {
2222 BAD(".opd");
2226 /* Accept .eh_frame where mapped as rx (code). This seems to be
2227 the common case. However, if that doesn't pan out, try for
2228 rw (data) instead. We can handle up to N_EHFRAME_SECTS per
2229 ELF object. */
2230 if (0 == VG_(strcmp)(name, ".eh_frame")) {
2231 if (inrx && di->n_ehframe < N_EHFRAME_SECTS) {
2232 di->ehframe_avma[di->n_ehframe] = svma + inrx->bias;
2233 di->ehframe_size[di->n_ehframe] = size;
2234 TRACE_SYMTAB("acquiring .eh_frame avma = %#lx\n",
2235 di->ehframe_avma[di->n_ehframe]);
2236 di->n_ehframe++;
2237 } else
2238 if (inrw && di->n_ehframe < N_EHFRAME_SECTS) {
2239 di->ehframe_avma[di->n_ehframe] = svma + inrw->bias;
2240 di->ehframe_size[di->n_ehframe] = size;
2241 TRACE_SYMTAB("acquiring .eh_frame avma = %#lx\n",
2242 di->ehframe_avma[di->n_ehframe]);
2243 di->n_ehframe++;
2244 } else {
2245 BAD(".eh_frame");
2249 /* Accept .ARM.exidx where mapped as rx (code). */
2250 /* FIXME: make sure the entire section is mapped in, not just
2251 the first address. */
2252 if (0 == VG_(strcmp)(name, ".ARM.exidx")) {
2253 if (inrx && !di->exidx_present) {
2254 di->exidx_present = True;
2255 di->exidx_svma = svma;
2256 di->exidx_avma = svma + inrx->bias;
2257 di->exidx_size = size;
2258 di->exidx_bias = inrx->bias;
2259 TRACE_SYMTAB("acquiring .exidx svma = %#lx .. %#lx\n",
2260 di->exidx_svma,
2261 di->exidx_svma + di->exidx_size - 1);
2262 TRACE_SYMTAB("acquiring .exidx avma = %#lx .. %#lx\n",
2263 di->exidx_avma,
2264 di->exidx_avma + di->exidx_size - 1);
2265 TRACE_SYMTAB("acquiring .exidx bias = %#lx\n", di->exidx_bias);
2266 } else {
2267 BAD(".ARM.exidx");
2271 /* Accept .ARM.extab where mapped as rx (code). */
2272 /* FIXME: make sure the entire section is mapped in, not just
2273 the first address. */
2274 if (0 == VG_(strcmp)(name, ".ARM.extab")) {
2275 if (inrx && !di->extab_present) {
2276 di->extab_present = True;
2277 di->extab_svma = svma;
2278 di->extab_avma = svma + inrx->bias;
2279 di->extab_size = size;
2280 di->extab_bias = inrx->bias;
2281 TRACE_SYMTAB("acquiring .extab svma = %#lx .. %#lx\n",
2282 di->extab_svma,
2283 di->extab_svma + di->extab_size - 1);
2284 TRACE_SYMTAB("acquiring .extab avma = %#lx .. %#lx\n",
2285 di->extab_avma,
2286 di->extab_avma + di->extab_size - 1);
2287 TRACE_SYMTAB("acquiring .extab bias = %#lx\n", di->extab_bias);
2288 } else {
2289 BAD(".ARM.extab");
2293 ML_(dinfo_free)(name);
2295 # undef BAD
2297 } /* iterate over the section headers */
2299 /* TOPLEVEL */
2300 if (0) VG_(printf)("YYYY text_: avma %#lx size %ld bias %#lx\n",
2301 di->text_avma, di->text_size, di->text_bias);
2303 if (VG_(clo_verbosity) > 2 || VG_(clo_trace_redir))
2304 VG_(message)(Vg_DebugMsg, " svma %#010lx, avma %#010lx\n",
2305 di->text_avma - di->text_bias,
2306 di->text_avma );
2308 TRACE_SYMTAB("\n");
2309 TRACE_SYMTAB("------ Finding image addresses "
2310 "for debug-info sections ------\n");
2312 /* TOPLEVEL */
2313 /* Find interesting sections, read the symbol table(s), read any
2314 debug information. Each section is located either in the main,
2315 debug or alt-debug files, but only in one. For each section,
2316 |section_escn| records which of |mimg|, |dimg| or |aimg| we
2317 found it in, along with the section's image offset and its size.
2318 The triples (section_img, section_ioff, section_szB) are
2319 consistent, in that they are always either (NULL,
2320 DiOffT_INVALID, 0), or refer to the same image, and are all
2321 assigned together. */
2323 /* TOPLEVEL */
2324 DiSlice strtab_escn = DiSlice_INVALID; // .strtab
2325 DiSlice symtab_escn = DiSlice_INVALID; // .symtab
2326 DiSlice dynstr_escn = DiSlice_INVALID; // .dynstr
2327 DiSlice dynsym_escn = DiSlice_INVALID; // .dynsym
2328 DiSlice debuglink_escn = DiSlice_INVALID; // .gnu_debuglink
2329 DiSlice debugaltlink_escn = DiSlice_INVALID; // .gnu_debugaltlink
2330 DiSlice debug_line_escn = DiSlice_INVALID; // .debug_line (dwarf2)
2331 DiSlice debug_info_escn = DiSlice_INVALID; // .debug_info (dwarf2)
2332 DiSlice debug_types_escn = DiSlice_INVALID; // .debug_types (dwarf4)
2333 DiSlice debug_abbv_escn = DiSlice_INVALID; // .debug_abbrev (dwarf2)
2334 DiSlice debug_str_escn = DiSlice_INVALID; // .debug_str (dwarf2)
2335 DiSlice debug_ranges_escn = DiSlice_INVALID; // .debug_ranges (dwarf2)
2336 DiSlice debug_loc_escn = DiSlice_INVALID; // .debug_loc (dwarf2)
2337 DiSlice debug_frame_escn = DiSlice_INVALID; // .debug_frame (dwarf2)
2338 DiSlice debug_line_alt_escn = DiSlice_INVALID; // .debug_line (alt)
2339 DiSlice debug_info_alt_escn = DiSlice_INVALID; // .debug_info (alt)
2340 DiSlice debug_abbv_alt_escn = DiSlice_INVALID; // .debug_abbrev (alt)
2341 DiSlice debug_str_alt_escn = DiSlice_INVALID; // .debug_str (alt)
2342 DiSlice dwarf1d_escn = DiSlice_INVALID; // .debug (dwarf1)
2343 DiSlice dwarf1l_escn = DiSlice_INVALID; // .line (dwarf1)
2344 DiSlice opd_escn = DiSlice_INVALID; // .opd (dwarf2,
2345 // ppc64be-linux)
2346 DiSlice ehframe_escn[N_EHFRAME_SECTS]; // .eh_frame (dwarf2)
2348 for (i = 0; i < N_EHFRAME_SECTS; i++)
2349 ehframe_escn[i] = DiSlice_INVALID;
2351 /* Find all interesting sections */
2353 UInt ehframe_mix = 0;
2355 /* What FIND does: it finds the section called _SEC_NAME. The
2356 size of it is assigned to _SEC_SIZE. The address of the
2357 section in the transiently loaded oimage is assigned to
2358 _SEC_IMG. If the section is found, _POST_FX is executed
2359 after _SEC_NAME and _SEC_SIZE have been assigned to.
2361 Even for sections which are marked loadable, the client's
2362 ld.so may not have loaded them yet, so there is no guarantee
2363 that we can safely prod around in any such area). Because
2364 the entire object file is transiently mapped aboard for
2365 inspection, it's always safe to inspect that area. */
2367 /* TOPLEVEL */
2368 /* Iterate over section headers (again) */
2369 for (i = 0; i < ehdr_m.e_shnum; i++) {
2371 # define FINDX(_sec_name, _sec_escn, _post_fx) \
2372 do { \
2373 ElfXX_Shdr a_shdr; \
2374 ML_(img_get)(&a_shdr, mimg, \
2375 INDEX_BIS(shdr_mioff, i, shdr_ment_szB), \
2376 sizeof(a_shdr)); \
2377 if (0 == ML_(img_strcmp_c)(mimg, shdr_strtab_mioff \
2378 + a_shdr.sh_name, _sec_name)) { \
2379 Bool nobits; \
2380 _sec_escn.img = mimg; \
2381 _sec_escn.ioff = (DiOffT)a_shdr.sh_offset; \
2382 _sec_escn.szB = a_shdr.sh_size; \
2383 nobits = a_shdr.sh_type == SHT_NOBITS; \
2384 vg_assert(_sec_escn.img != NULL); \
2385 vg_assert(_sec_escn.ioff != DiOffT_INVALID); \
2386 TRACE_SYMTAB( "%18s: ioff %llu .. %llu\n", \
2387 _sec_name, (ULong)_sec_escn.ioff, \
2388 ((ULong)_sec_escn.ioff) + _sec_escn.szB - 1); \
2389 /* SHT_NOBITS sections have zero size in the file. */ \
2390 if ( a_shdr.sh_offset \
2391 + (nobits ? 0 : _sec_escn.szB) > ML_(img_size)(mimg) ) { \
2392 ML_(symerr)(di, True, \
2393 " section beyond image end?!"); \
2394 goto out; \
2396 _post_fx; \
2398 } while (0);
2400 /* Version with no post-effects */
2401 # define FIND(_sec_name, _sec_escn) \
2402 FINDX(_sec_name, _sec_escn, /**/)
2404 /* NAME ElfSec */
2405 FIND(".dynsym", dynsym_escn)
2406 FIND(".dynstr", dynstr_escn)
2407 FIND(".symtab", symtab_escn)
2408 FIND(".strtab", strtab_escn)
2410 FIND(".gnu_debuglink", debuglink_escn)
2411 FIND(".gnu_debugaltlink", debugaltlink_escn)
2413 FIND(".debug_line", debug_line_escn)
2414 FIND(".debug_info", debug_info_escn)
2415 FIND(".debug_types", debug_types_escn)
2416 FIND(".debug_abbrev", debug_abbv_escn)
2417 FIND(".debug_str", debug_str_escn)
2418 FIND(".debug_ranges", debug_ranges_escn)
2419 FIND(".debug_loc", debug_loc_escn)
2420 FIND(".debug_frame", debug_frame_escn)
2422 FIND(".debug", dwarf1d_escn)
2423 FIND(".line", dwarf1l_escn)
2425 FIND(".opd", opd_escn)
2427 FINDX(".eh_frame", ehframe_escn[ehframe_mix],
2428 do { ehframe_mix++; vg_assert(ehframe_mix <= N_EHFRAME_SECTS);
2429 } while (0)
2431 /* Comment_on_EH_FRAME_MULTIPLE_INSTANCES: w.r.t. .eh_frame
2432 multi-instance kludgery, how are we assured that the order
2433 in which we fill in ehframe_escn[] is consistent with the
2434 order in which we previously filled in di->ehframe_avma[]
2435 and di->ehframe_size[] ? By the fact that in both cases,
2436 these arrays were filled in by iterating over the section
2437 headers top-to-bottom. So both loops (this one and the
2438 previous one) encounter the .eh_frame entries in the same
2439 order and so fill in these arrays in a consistent order.
2442 # undef FINDX
2443 # undef FIND
2444 } /* Iterate over section headers (again) */
2446 /* TOPLEVEL */
2447 /* Now, see if we can find a debuginfo object, and if so connect
2448 |dimg| to it. */
2449 vg_assert(dimg == NULL && aimg == NULL);
2451 /* Look for a build-id */
2452 HChar* buildid = find_buildid(mimg, False, False);
2454 /* Look for a debug image that matches either the build-id or
2455 the debuglink-CRC32 in the main image. If the main image
2456 doesn't contain either of those then this won't even bother
2457 to try looking. This looks in all known places, including
2458 the --extra-debuginfo-path if specified and on the
2459 --debuginfo-server if specified. */
2460 if (buildid != NULL || debuglink_escn.img != NULL) {
2461 /* Do have a debuglink section? */
2462 if (debuglink_escn.img != NULL) {
2463 UInt crc_offset
2464 = VG_ROUNDUP(ML_(img_strlen)(debuglink_escn.img,
2465 debuglink_escn.ioff)+1, 4);
2466 vg_assert(crc_offset + sizeof(UInt) <= debuglink_escn.szB);
2468 /* Extract the CRC from the debuglink section */
2469 UInt crc = ML_(img_get_UInt)(debuglink_escn.img,
2470 debuglink_escn.ioff + crc_offset);
2472 /* See if we can find a matching debug file */
2473 HChar* debuglink_str_m
2474 = ML_(img_strdup)(debuglink_escn.img,
2475 "di.redi_dlk.1", debuglink_escn.ioff);
2476 dimg = find_debug_file( di, di->fsm.filename, buildid,
2477 debuglink_str_m, crc, False );
2478 if (debuglink_str_m)
2479 ML_(dinfo_free)(debuglink_str_m);
2480 } else {
2481 /* See if we can find a matching debug file */
2482 dimg = find_debug_file( di, di->fsm.filename, buildid,
2483 NULL, 0, False );
2487 if (buildid) {
2488 ML_(dinfo_free)(buildid);
2489 buildid = NULL; /* paranoia */
2492 /* As a last-ditch measure, try looking for in the
2493 --extra-debuginfo-path and/or on the --debuginfo-server, but
2494 only in the case where --allow-mismatched-debuginfo=yes.
2495 This is dangerous in that (1) it gives no assurance that the
2496 debuginfo object matches the main one, and hence (2) we will
2497 very likely get an assertion in the code below, if indeed
2498 there is a mismatch. Hence it is disabled by default
2499 (--allow-mismatched-debuginfo=no). Nevertheless it's
2500 sometimes a useful way of getting out of a tight spot.
2502 Note that we're ignoring the name in the .gnu_debuglink
2503 section here, and just looking for a file of the same name
2504 either the extra-path or on the server. */
2505 if (dimg == NULL && VG_(clo_allow_mismatched_debuginfo)) {
2506 dimg = find_debug_file_ad_hoc( di, di->fsm.filename );
2509 /* TOPLEVEL */
2510 /* If we were successful in finding a debug image, pull various
2511 SVMA/bias/size and image addresses out of it. */
2512 if (dimg != NULL && is_elf_object_file_by_DiImage(dimg, False)) {
2514 /* Pull out and validate program header and section header info */
2515 DiOffT ehdr_dioff = 0;
2516 ElfXX_Ehdr ehdr_dimg;
2517 ML_(img_get)(&ehdr_dimg, dimg, ehdr_dioff, sizeof(ehdr_dimg));
2519 DiOffT phdr_dioff = ehdr_dimg.e_phoff;
2520 UWord phdr_dnent = ehdr_dimg.e_phnum;
2521 UWord phdr_dent_szB = ehdr_dimg.e_phentsize;
2523 DiOffT shdr_dioff = ehdr_dimg.e_shoff;
2524 UWord shdr_dnent = ehdr_dimg.e_shnum;
2525 UWord shdr_dent_szB = ehdr_dimg.e_shentsize;
2527 DiOffT shdr_strtab_dioff = DiOffT_INVALID;
2529 /* SVMAs covered by rx and rw segments and corresponding bias. */
2530 Addr rx_dsvma_limit = 0;
2531 PtrdiffT rx_dbias = 0;
2532 Addr rw_dsvma_limit = 0;
2533 PtrdiffT rw_dbias = 0;
2535 Bool need_symtab, need_dwarf2, need_dwarf1;
2537 if (phdr_dnent == 0
2538 || !ML_(img_valid)(dimg, phdr_dioff,
2539 phdr_dnent * phdr_dent_szB)) {
2540 ML_(symerr)(di, True,
2541 "Missing or invalid ELF Program Header Table"
2542 " (debuginfo file)");
2543 goto out;
2546 if (shdr_dnent == 0
2547 || !ML_(img_valid)(dimg, shdr_dioff,
2548 shdr_dnent * shdr_dent_szB)) {
2549 ML_(symerr)(di, True,
2550 "Missing or invalid ELF Section Header Table"
2551 " (debuginfo file)");
2552 goto out;
2555 /* Also find the section header's string table, and validate. */
2556 /* checked previously by is_elf_object_file: */
2557 vg_assert(ehdr_dimg.e_shstrndx != SHN_UNDEF);
2559 // shdr_dioff is the offset of the section header table
2560 // and we need the ehdr_dimg.e_shstrndx'th entry
2561 { ElfXX_Shdr a_shdr;
2562 ML_(img_get)(&a_shdr, dimg,
2563 INDEX_BIS(shdr_dioff, ehdr_dimg.e_shstrndx,
2564 shdr_dent_szB),
2565 sizeof(a_shdr));
2566 shdr_strtab_dioff = a_shdr.sh_offset;
2567 if (!ML_(img_valid)(dimg, shdr_strtab_dioff,
2568 1/*bogus, but we don't know the real size*/)) {
2569 ML_(symerr)(di, True,
2570 "Invalid ELF Section Header String Table"
2571 " (debuginfo file)");
2572 goto out;
2576 for (i = 0; i < ehdr_dimg.e_phnum; i++) {
2577 ElfXX_Phdr a_phdr;
2578 ML_(img_get)(&a_phdr, dimg, INDEX_BIS(ehdr_dimg.e_phoff,
2579 i, phdr_dent_szB),
2580 sizeof(a_phdr));
2581 if (a_phdr.p_type == PT_LOAD) {
2582 for (j = 0; j < VG_(sizeXA)(di->fsm.maps); j++) {
2583 const DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, j);
2584 if ( a_phdr.p_offset >= map->foff
2585 && a_phdr.p_offset < map->foff + map->size
2586 && a_phdr.p_offset + a_phdr.p_filesz
2587 < map->foff + map->size) {
2588 if (map->rx && rx_dsvma_limit == 0) {
2589 rx_dsvma_limit = a_phdr.p_vaddr + a_phdr.p_memsz;
2590 rx_dbias = map->avma - map->foff + a_phdr.p_offset
2591 - a_phdr.p_vaddr;
2593 if (map->rw && rw_dsvma_limit == 0) {
2594 rw_dsvma_limit = a_phdr.p_vaddr + a_phdr.p_memsz;
2595 rw_dbias = map->avma - map->foff + a_phdr.p_offset
2596 - a_phdr.p_vaddr;
2598 break;
2604 need_symtab = (symtab_escn.img == NULL);
2605 need_dwarf2 = (debug_info_escn.img == NULL);
2606 need_dwarf1 = (dwarf1d_escn.img == NULL);
2608 /* Find all interesting sections in the debug image */
2609 for (i = 0; i < ehdr_dimg.e_shnum; i++) {
2611 /* Find debug svma and bias information for sections
2612 we found in the main file. */
2614 # define FIND(_sec, _seg) \
2615 do { \
2616 ElfXX_Shdr a_shdr; \
2617 ML_(img_get)(&a_shdr, dimg, \
2618 INDEX_BIS(shdr_dioff, i, shdr_dent_szB), \
2619 sizeof(a_shdr)); \
2620 if (di->_sec##_present \
2621 && 0 == ML_(img_strcmp_c)(dimg, shdr_strtab_dioff \
2622 + a_shdr.sh_name, "." #_sec)) { \
2623 vg_assert(di->_sec##_size == a_shdr.sh_size); \
2624 /* JRS 2013-Jun-01: the following assert doesn't contain */ \
2625 /* any ==s, which seems to me to be suspicious. */ \
2626 vg_assert(di->_sec##_avma + a_shdr.sh_addr + _seg##_dbias); \
2627 /* Assume we have a correct value for the main */ \
2628 /* object's bias. Use that to derive the debuginfo */ \
2629 /* object's bias, by adding the difference in SVMAs */ \
2630 /* for the corresponding sections in the two files. */ \
2631 /* That should take care of all prelinking effects. */ \
2632 di->_sec##_debug_svma = a_shdr.sh_addr; \
2633 di->_sec##_debug_bias \
2634 = di->_sec##_bias + \
2635 di->_sec##_svma - di->_sec##_debug_svma; \
2636 TRACE_SYMTAB("acquiring ." #_sec \
2637 " debug svma = %#lx .. %#lx\n", \
2638 di->_sec##_debug_svma, \
2639 di->_sec##_debug_svma + di->_sec##_size - 1); \
2640 TRACE_SYMTAB("acquiring ." #_sec " debug bias = %#lx\n", \
2641 di->_sec##_debug_bias); \
2643 } while (0);
2645 /* SECTION SEGMENT */
2646 FIND(text, rx)
2647 FIND(data, rw)
2648 FIND(sdata, rw)
2649 FIND(rodata, rw)
2650 FIND(bss, rw)
2651 FIND(sbss, rw)
2653 # undef FIND
2655 /* Same deal as previous FIND, except only do it for those
2656 sections which we didn't find in the main file. */
2658 # define FIND(_condition, _sec_name, _sec_escn) \
2659 do { \
2660 ElfXX_Shdr a_shdr; \
2661 ML_(img_get)(&a_shdr, dimg, \
2662 INDEX_BIS(shdr_dioff, i, shdr_dent_szB), \
2663 sizeof(a_shdr)); \
2664 if (_condition \
2665 && 0 == ML_(img_strcmp_c)(dimg, shdr_strtab_dioff \
2666 + a_shdr.sh_name, _sec_name)) { \
2667 Bool nobits; \
2668 if (_sec_escn.img != NULL) { \
2669 ML_(symerr)(di, True, \
2670 " debuginfo section duplicates a" \
2671 " section in the main ELF file"); \
2672 goto out; \
2674 _sec_escn.img = dimg; \
2675 _sec_escn.ioff = (DiOffT)a_shdr.sh_offset; \
2676 _sec_escn.szB = a_shdr.sh_size; \
2677 nobits = a_shdr.sh_type == SHT_NOBITS; \
2678 vg_assert(_sec_escn.img != NULL); \
2679 vg_assert(_sec_escn.ioff != DiOffT_INVALID); \
2680 TRACE_SYMTAB( "%18s: dioff %llu .. %llu\n", \
2681 _sec_name, \
2682 (ULong)_sec_escn.ioff, \
2683 ((ULong)_sec_escn.ioff) + _sec_escn.szB - 1); \
2684 /* SHT_NOBITS sections have zero size in the file. */ \
2685 if (a_shdr.sh_offset \
2686 + (nobits ? 0 : _sec_escn.szB) > ML_(img_size)(dimg)) { \
2687 ML_(symerr)(di, True, \
2688 " section beyond image end?!"); \
2689 goto out; \
2692 } while (0);
2694 /* NEEDED? NAME ElfSec */
2695 FIND(need_symtab, ".symtab", symtab_escn)
2696 FIND(need_symtab, ".strtab", strtab_escn)
2697 FIND(need_dwarf2, ".debug_line", debug_line_escn)
2698 FIND(need_dwarf2, ".debug_info", debug_info_escn)
2699 FIND(need_dwarf2, ".debug_types", debug_types_escn)
2701 FIND(need_dwarf2, ".debug_abbrev", debug_abbv_escn)
2702 FIND(need_dwarf2, ".debug_str", debug_str_escn)
2703 FIND(need_dwarf2, ".debug_ranges", debug_ranges_escn)
2705 FIND(need_dwarf2, ".debug_loc", debug_loc_escn)
2706 FIND(need_dwarf2, ".debug_frame", debug_frame_escn)
2708 FIND(need_dwarf2, ".gnu_debugaltlink", debugaltlink_escn)
2710 FIND(need_dwarf1, ".debug", dwarf1d_escn)
2711 FIND(need_dwarf1, ".line", dwarf1l_escn)
2713 # undef FIND
2714 } /* Find all interesting sections */
2715 } /* do we have a debug image? */
2717 /* TOPLEVEL */
2718 /* Look for alternate debug image, and if found, connect |aimg|
2719 to it. */
2720 vg_assert(aimg == NULL);
2722 if (debugaltlink_escn.img != NULL) {
2723 HChar* altfile_str_m
2724 = ML_(img_strdup)(debugaltlink_escn.img,
2725 "di.fbi.3", debugaltlink_escn.ioff);
2726 UInt buildid_offset = ML_(img_strlen)(debugaltlink_escn.img,
2727 debugaltlink_escn.ioff)+1;
2729 vg_assert(buildid_offset < debugaltlink_escn.szB);
2731 HChar *altbuildid
2732 = ML_(dinfo_zalloc)("di.fbi.4",
2733 (debugaltlink_escn.szB - buildid_offset)
2734 * 2 + 1);
2736 /* The altfile might be relative to the debug file or main file. */
2737 HChar *dbgname = di->fsm.dbgname ? di->fsm.dbgname : di->fsm.filename;
2739 for (j = 0; j < debugaltlink_escn.szB - buildid_offset; j++)
2740 VG_(sprintf)(
2741 altbuildid + 2 * j, "%02x",
2742 (UInt)ML_(img_get_UChar)(debugaltlink_escn.img,
2743 debugaltlink_escn.ioff
2744 + buildid_offset + j));
2746 /* See if we can find a matching debug file */
2747 aimg = find_debug_file( di, dbgname, altbuildid,
2748 altfile_str_m, 0, True );
2750 if (altfile_str_m)
2751 ML_(dinfo_free)(altfile_str_m);
2752 ML_(dinfo_free)(altbuildid);
2755 /* TOPLEVEL */
2756 /* If we were successful in finding alternate debug image, pull various
2757 size and image addresses out of it. */
2758 if (aimg != NULL && is_elf_object_file_by_DiImage(aimg, True)) {
2760 /* Pull out and validate program header and section header info */
2761 DiOffT ehdr_aioff = 0;
2762 ElfXX_Ehdr ehdr_aimg;
2763 ML_(img_get)(&ehdr_aimg, aimg, ehdr_aioff, sizeof(ehdr_aimg));
2765 DiOffT shdr_aioff = ehdr_aimg.e_shoff;
2766 UWord shdr_anent = ehdr_aimg.e_shnum;
2767 UWord shdr_aent_szB = ehdr_aimg.e_shentsize;
2769 DiOffT shdr_strtab_aioff = DiOffT_INVALID;
2771 if (shdr_anent == 0
2772 || !ML_(img_valid)(aimg, shdr_aioff,
2773 shdr_anent * shdr_aent_szB)) {
2774 ML_(symerr)(di, True,
2775 "Missing or invalid ELF Section Header Table"
2776 " (alternate debuginfo file)");
2777 goto out;
2780 /* Also find the section header's string table, and validate. */
2781 /* checked previously by is_elf_object_file: */
2782 vg_assert(ehdr_aimg.e_shstrndx != SHN_UNDEF);
2784 // shdr_aioff is the offset of the section header table
2785 // and we need the ehdr_aimg.e_shstrndx'th entry
2786 { ElfXX_Shdr a_shdr;
2787 ML_(img_get)(&a_shdr, aimg,
2788 INDEX_BIS(shdr_aioff, ehdr_aimg.e_shstrndx,
2789 shdr_aent_szB),
2790 sizeof(a_shdr));
2791 shdr_strtab_aioff = a_shdr.sh_offset;
2792 if (!ML_(img_valid)(aimg, shdr_strtab_aioff,
2793 1/*bogus, but we don't know the real size*/)) {
2794 ML_(symerr)(di, True,
2795 "Invalid ELF Section Header String Table"
2796 " (alternate debuginfo file)");
2797 goto out;
2801 /* Find all interesting sections */
2802 for (i = 0; i < ehdr_aimg.e_shnum; i++) {
2804 # define FIND(_sec_name, _sec_escn) \
2805 do { \
2806 ElfXX_Shdr a_shdr; \
2807 ML_(img_get)(&a_shdr, aimg, \
2808 INDEX_BIS(shdr_aioff, i, shdr_aent_szB), \
2809 sizeof(a_shdr)); \
2810 if (0 == ML_(img_strcmp_c)(aimg, shdr_strtab_aioff \
2811 + a_shdr.sh_name, _sec_name)) { \
2812 if (_sec_escn.img != NULL) { \
2813 ML_(symerr)(di, True, \
2814 " alternate debuginfo section duplicates a" \
2815 " section in the main ELF file"); \
2816 goto out; \
2818 _sec_escn.img = aimg; \
2819 _sec_escn.ioff = (DiOffT)a_shdr.sh_offset; \
2820 _sec_escn.szB = a_shdr.sh_size; \
2821 vg_assert(_sec_escn.img != NULL); \
2822 vg_assert(_sec_escn.ioff != DiOffT_INVALID); \
2823 TRACE_SYMTAB( "%18s: aioff %llu .. %llu\n", \
2824 _sec_name, \
2825 (ULong)_sec_escn.ioff, \
2826 ((ULong)_sec_escn.ioff) + _sec_escn.szB - 1); \
2828 } while (0);
2830 /* NAME ElfSec */
2831 FIND(".debug_line", debug_line_alt_escn)
2832 FIND(".debug_info", debug_info_alt_escn)
2833 FIND(".debug_abbrev", debug_abbv_alt_escn)
2834 FIND(".debug_str", debug_str_alt_escn)
2836 # undef FIND
2837 } /* Find all interesting sections */
2838 } /* do we have a debug image? */
2841 /* TOPLEVEL */
2842 /* Check some sizes */
2843 vg_assert((dynsym_escn.szB % sizeof(ElfXX_Sym)) == 0);
2844 vg_assert((symtab_escn.szB % sizeof(ElfXX_Sym)) == 0);
2846 /* TOPLEVEL */
2847 /* Read symbols */
2849 void (*read_elf_symtab)(struct _DebugInfo*, const HChar*,
2850 DiSlice*, DiSlice*, DiSlice*, Bool);
2851 Bool symtab_in_debug;
2852 # if defined(VGP_ppc64be_linux)
2853 read_elf_symtab = read_elf_symtab__ppc64be_linux;
2854 # else
2855 read_elf_symtab = read_elf_symtab__normal;
2856 # endif
2857 symtab_in_debug = symtab_escn.img == dimg;
2858 read_elf_symtab(di, "symbol table",
2859 &symtab_escn, &strtab_escn, &opd_escn,
2860 symtab_in_debug);
2861 read_elf_symtab(di, "dynamic symbol table",
2862 &dynsym_escn, &dynstr_escn, &opd_escn,
2863 False);
2866 /* TOPLEVEL */
2867 /* Read .eh_frame and .debug_frame (call-frame-info) if any. Do
2868 the .eh_frame section(s) first. */
2869 vg_assert(di->n_ehframe >= 0 && di->n_ehframe <= N_EHFRAME_SECTS);
2870 for (i = 0; i < di->n_ehframe; i++) {
2871 /* see Comment_on_EH_FRAME_MULTIPLE_INSTANCES above for why
2872 this next assertion should hold. */
2873 vg_assert(ML_(sli_is_valid)(ehframe_escn[i]));
2874 vg_assert(ehframe_escn[i].szB == di->ehframe_size[i]);
2875 ML_(read_callframe_info_dwarf3)( di,
2876 ehframe_escn[i],
2877 di->ehframe_avma[i],
2878 True/*is_ehframe*/ );
2880 if (ML_(sli_is_valid)(debug_frame_escn)) {
2881 ML_(read_callframe_info_dwarf3)( di,
2882 debug_frame_escn,
2883 0/*assume zero avma*/,
2884 False/*!is_ehframe*/ );
2887 /* TOPLEVEL */
2888 /* jrs 2006-01-01: icc-8.1 has been observed to generate
2889 binaries without debug_str sections. Don't preclude
2890 debuginfo reading for that reason, but, in
2891 read_unitinfo_dwarf2, do check that debugstr is non-NULL
2892 before using it. */
2893 if (ML_(sli_is_valid)(debug_info_escn)
2894 && ML_(sli_is_valid)(debug_abbv_escn)
2895 && ML_(sli_is_valid)(debug_line_escn)) {
2896 /* The old reader: line numbers and unwind info only */
2897 ML_(read_debuginfo_dwarf3) ( di,
2898 debug_info_escn,
2899 debug_types_escn,
2900 debug_abbv_escn,
2901 debug_line_escn,
2902 debug_str_escn,
2903 debug_str_alt_escn );
2904 /* The new reader: read the DIEs in .debug_info to acquire
2905 information on variable types and locations or inline info.
2906 But only if the tool asks for it, or the user requests it on
2907 the command line. */
2908 if (VG_(clo_read_var_info) /* the user or tool asked for it */
2909 || VG_(clo_read_inline_info)) {
2910 ML_(new_dwarf3_reader)(
2911 di, debug_info_escn, debug_types_escn,
2912 debug_abbv_escn, debug_line_escn,
2913 debug_str_escn, debug_ranges_escn,
2914 debug_loc_escn, debug_info_alt_escn,
2915 debug_abbv_alt_escn, debug_line_alt_escn,
2916 debug_str_alt_escn
2921 /* TOPLEVEL */
2922 // JRS 31 July 2014: dwarf-1 reading is currently broken and
2923 // therefore deactivated.
2924 //if (dwarf1d_img && dwarf1l_img) {
2925 // ML_(read_debuginfo_dwarf1) ( di, dwarf1d_img, dwarf1d_sz,
2926 // dwarf1l_img, dwarf1l_sz );
2929 # if defined(VGA_arm)
2930 /* TOPLEVEL */
2931 /* ARM32 only: read .exidx/.extab if present. Note we are
2932 reading these directly out of the mapped in (running) image.
2933 Also, read these only if no CFI based unwind info was
2934 acquired for this file.
2936 An .exidx section is always required, but the .extab section
2937 can be optionally omitted, provided that .exidx does not
2938 refer to it. If the .exidx is erroneous and does refer to
2939 .extab even though .extab is missing, the range checks done
2940 by GET_EX_U32 in ExtabEntryExtract in readexidx.c should
2941 prevent any invalid memory accesses, and cause the .extab to
2942 be rejected as invalid.
2944 FIXME:
2945 * check with m_aspacemgr that the entire [exidx_avma, +exidx_size)
2946 and [extab_avma, +extab_size) areas are readable, since we're
2947 reading this stuff out of the running image (not from a file/socket)
2948 and we don't want to segfault.
2949 * DebugInfo::exidx_bias and use text_bias instead.
2950 I think it's always the same.
2951 * remove DebugInfo::{extab_bias, exidx_svma, extab_svma} since
2952 they are never used.
2954 if (di->exidx_present
2955 && di->cfsi_used == 0
2956 && di->text_present && di->text_size > 0) {
2957 Addr text_last_svma = di->text_svma + di->text_size - 1;
2958 ML_(read_exidx)( di, (UChar*)di->exidx_avma, di->exidx_size,
2959 (UChar*)di->extab_avma, di->extab_size,
2960 text_last_svma,
2961 di->exidx_bias );
2963 # endif /* defined(VGA_arm) */
2965 } /* "Find interesting sections, read the symbol table(s), read any debug
2966 information" (a local scope) */
2968 /* TOPLEVEL */
2969 res = True;
2971 /* If reading Dwarf3 variable type/location info, print a line
2972 showing the number of variables read for each object.
2973 (Currently disabled -- is a sanity-check mechanism for
2974 exp-sgcheck.) */
2975 if (0 && VG_(clo_read_var_info)) {
2976 UWord nVars = 0;
2977 if (di->varinfo) {
2978 for (j = 0; j < VG_(sizeXA)(di->varinfo); j++) {
2979 OSet* /* of DiAddrRange */ scope
2980 = *(OSet**)VG_(indexXA)(di->varinfo, j);
2981 vg_assert(scope);
2982 VG_(OSetGen_ResetIter)( scope );
2983 while (True) {
2984 DiAddrRange* range = VG_(OSetGen_Next)( scope );
2985 if (!range) break;
2986 vg_assert(range->vars);
2987 Word w = VG_(sizeXA)(range->vars);
2988 vg_assert(w >= 0);
2989 if (0) VG_(printf)("range %#lx %#lx %ld\n",
2990 range->aMin, range->aMax, w);
2991 nVars += (UWord)w;
2995 VG_(umsg)("VARINFO: %7lu vars %7ld text_size %s\n",
2996 nVars, di->text_size, di->fsm.filename);
2998 /* TOPLEVEL */
3000 out:
3002 /* Last, but not least, detach from the image(s). */
3003 if (mimg) ML_(img_done)(mimg);
3004 if (dimg) ML_(img_done)(dimg);
3005 if (aimg) ML_(img_done)(aimg);
3007 if (svma_ranges) VG_(deleteXA)(svma_ranges);
3009 return res;
3010 } /* out: */
3012 /* NOTREACHED */
3015 #endif // defined(VGO_linux)
3017 /*--------------------------------------------------------------------*/
3018 /*--- end ---*/
3019 /*--------------------------------------------------------------------*/