1
2 /*--------------------------------------------------------------------*/
3 /*--- Reading of syms & debug info from ELF .so/executable files. ---*/
4 /*--- readelf.c ---*/
5 /*--------------------------------------------------------------------*/
6
7 /*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
10
11 Copyright (C) 2000-2013 Julian Seward
12 jseward@acm.org
13
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.
18
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.
23
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.
28
29 The GNU General Public License is contained in the file COPYING.
30 */
31
32 #if defined(VGO_linux)
33
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_readstabs.h" /* and stabs, if we're unlucky */
54
55 /* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
56 #include <elf.h>
57 /* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
58
59 /*------------------------------------------------------------*/
60 /*--- 32/64-bit parameterisation ---*/
61 /*------------------------------------------------------------*/
62
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.
67 */
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
80
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
93
94 #else
95 # error "VG_WORDSIZE should be 4 or 8"
96 #endif
97
98
99 /*------------------------------------------------------------*/
100 /*--- ---*/
101 /*--- Read symbol table and line info from ELF files. ---*/
102 /*--- ---*/
103 /*------------------------------------------------------------*/
104
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. */
108
109 /* Identify an ELF object file by peering at the first few bytes of
110 it. */
111
ML_(is_elf_object_file)112 Bool ML_(is_elf_object_file)( void* image, SizeT n_image, Bool rel_ok )
113 {
114 ElfXX_Ehdr* ehdr = (ElfXX_Ehdr*)image;
115 Int ok = 1;
116
117 if (n_image < sizeof(ElfXX_Ehdr))
118 return False;
119
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);
135
136 return ok ? True : False;
137 }
138
139
140 /* The same thing, but operating on a DiImage instead. */
141
is_elf_object_file_by_DiImage(DiImage * img,Bool rel_ok)142 static Bool is_elf_object_file_by_DiImage( DiImage* img, Bool rel_ok )
143 {
144 /* Be sure this doesn't make the frame too big. */
145 vg_assert(sizeof(ElfXX_Ehdr) <= 512);
146
147 ElfXX_Ehdr ehdr;
148 if (!ML_(img_valid)(img, 0, sizeof(ehdr)))
149 return False;
150
151 ML_(img_get)(&ehdr, img, 0, sizeof(ehdr));
152 return ML_(is_elf_object_file)( &ehdr, sizeof(ehdr), rel_ok );
153 }
154
155
156 /* Show a raw ELF symbol, given its in-image address and name. */
157
158 static
show_raw_elf_symbol(DiImage * strtab_img,Int i,ElfXX_Sym * sym,DiOffT sym_name_ioff,Addr sym_svma,Bool ppc64_linux_format)159 void show_raw_elf_symbol ( DiImage* strtab_img,
160 Int i,
161 ElfXX_Sym* sym,
162 DiOffT sym_name_ioff, Addr sym_svma,
163 Bool ppc64_linux_format )
164 {
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;
174 }
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;
184 }
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 %4ld %s\n",
189 sym_svma, space, sym->st_size + 0UL,
190 (sym_name ? sym_name : "NONAME") );
191 if (sym_name)
192 ML_(dinfo_free)(sym_name);
193 }
194
195
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.
200
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.
206
207 For ppc64-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.
212
213 To support the ppc64-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 the leading dot is removed from the
217 name.
218
219 As a result, on ppc64-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.
222 */
223 static
get_elf_symbol_info(struct _DebugInfo * di,ElfXX_Sym * sym,DiOffT sym_name_ioff,DiSlice * escn_strtab,Addr sym_svma,Bool symtab_in_debug,DiSlice * escn_opd,PtrdiffT opd_bias,DiOffT * sym_name_out_ioff,Addr * sym_avma_out,Int * sym_size_out,Addr * sym_tocptr_out,Bool * from_opd_out,Bool * is_text_out,Bool * is_ifunc)224 Bool get_elf_symbol_info (
225 /* INPUTS */
226 struct _DebugInfo* di, /* containing DebugInfo */
227 ElfXX_Sym* sym, /* ELF symbol */
228 DiOffT sym_name_ioff, /* name, may be absent (DiOffT_INVALID) */
229 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 DiSlice* escn_opd, /* the .opd (ppc64-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 Addr* sym_avma_out, /* addr we should record */
237 Int* sym_size_out, /* symbol size */
238 Addr* sym_tocptr_out, /* ppc64-linux only: R2 value to be
239 used on entry */
240 Bool* from_opd_out, /* ppc64-linux only: did we deref an
241 .opd entry? */
242 Bool* is_text_out, /* is this a text symbol? */
243 Bool* is_ifunc /* is this a STT_GNU_IFUNC function ?*/
244 )
245 {
246 Bool plausible;
247 # if defined(VGP_ppc64_linux)
248 Bool is_in_opd;
249 # endif
250 Bool in_text, in_data, in_sdata, in_rodata, in_bss, in_sbss;
251 Addr text_svma, data_svma, sdata_svma, rodata_svma, bss_svma, sbss_svma;
252 PtrdiffT text_bias, data_bias, sdata_bias, rodata_bias, bss_bias, sbss_bias;
253
254 /* Set defaults */
255 *sym_name_out_ioff = sym_name_ioff;
256 *sym_avma_out = sym_svma; /* we will bias this shortly */
257 *is_text_out = True;
258 *sym_tocptr_out = 0; /* unknown/inapplicable */
259 *from_opd_out = False;
260 *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;
270 }
271 /* After this point refer only to *sym_size_out and not to
272 sym->st_size. */
273
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
280 )
281 &&
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
287 );
288
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;
317 }
318
319 /* Now bias sym_avma_out 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_avma_out += 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_avma_out += 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_avma_out += 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_avma_out += 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_avma_out += 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_avma_out += sbss_bias;
363 } else {
364 /* Assume it's in .text. Is this a good idea? */
365 *is_text_out = True;
366 *sym_avma_out += text_bias;
367 }
368
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;
374 }
375 # endif
376
377 # if defined(VGP_ppc64_linux)
378 /* Allow STT_NOTYPE in the very special case where we're running on
379 ppc64-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_avma_out >= di->opd_avma
388 && *sym_avma_out < di->opd_avma + di->opd_size)
389 plausible = True;
390 # endif
391
392 if (!plausible)
393 return False;
394
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);
405 }
406 return False;
407 }
408
409 /* Ignore if zero-sized. Except on Android:
410
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:
418
419 in /system/lib/libc.so: strlen strcmp strcpy memcmp memcpy
420 in /system/bin/linker: __dl_strcmp __dl_strlen
421 */
422 if (*sym_size_out == 0) {
423 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
424 *sym_size_out = 2048;
425 # else
426 if (TRACE_SYMTAB_ENABLED) {
427 HChar* sym_name = ML_(img_strdup)(escn_strtab->img,
428 "di.gesi.2", sym_name_ioff);
429 TRACE_SYMTAB(" ignore -- size=0: %s\n", sym_name);
430 if (sym_name) ML_(dinfo_free)(sym_name);
431 }
432 return False;
433 # endif
434 }
435
436 /* This seems to significantly reduce the number of junk
437 symbols, and particularly reduces the number of
438 overlapping address ranges. Don't ask me why ... */
439 if ((Int)sym->st_value == 0) {
440 if (TRACE_SYMTAB_ENABLED) {
441 HChar* sym_name = ML_(img_strdup)(escn_strtab->img,
442 "di.gesi.3", sym_name_ioff);
443 TRACE_SYMTAB( " ignore -- valu=0: %s\n", sym_name);
444 if (sym_name) ML_(dinfo_free)(sym_name);
445 }
446 return False;
447 }
448
449 /* If it's apparently in a GOT or PLT, it's really a reference to a
450 symbol defined elsewhere, so ignore it. */
451 if (di->got_present
452 && di->got_size > 0
453 && *sym_avma_out >= di->got_avma
454 && *sym_avma_out < di->got_avma + di->got_size) {
455 if (TRACE_SYMTAB_ENABLED) {
456 HChar* sym_name = ML_(img_strdup)(escn_strtab->img,
457 "di.gesi.4", sym_name_ioff);
458 TRACE_SYMTAB(" ignore -- in GOT: %s\n", sym_name);
459 if (sym_name) ML_(dinfo_free)(sym_name);
460 }
461 return False;
462 }
463 if (di->plt_present
464 && di->plt_size > 0
465 && *sym_avma_out >= di->plt_avma
466 && *sym_avma_out < di->plt_avma + di->plt_size) {
467 if (TRACE_SYMTAB_ENABLED) {
468 HChar* sym_name = ML_(img_strdup)(escn_strtab->img,
469 "di.gesi.5", sym_name_ioff);
470 TRACE_SYMTAB(" ignore -- in PLT: %s\n", sym_name);
471 if (sym_name) ML_(dinfo_free)(sym_name);
472 }
473 return False;
474 }
475
476 /* ppc64-linux nasty hack: if the symbol is in an .opd section,
477 then really what we have is the address of a function
478 descriptor. So use the first word of that as the function's
479 text.
480
481 See thread starting at
482 http://gcc.gnu.org/ml/gcc-patches/2004-08/msg00557.html
483 */
484 # if defined(VGP_ppc64_linux)
485 is_in_opd = False;
486 # endif
487
488 if (di->opd_present
489 && di->opd_size > 0
490 && *sym_avma_out >= di->opd_avma
491 && *sym_avma_out < di->opd_avma + di->opd_size) {
492 # if !defined(VGP_ppc64_linux)
493 if (TRACE_SYMTAB_ENABLED) {
494 HChar* sym_name = ML_(img_strdup)(escn_strtab->img,
495 "di.gesi.6", sym_name_ioff);
496 TRACE_SYMTAB(" ignore -- in OPD: %s\n", sym_name);
497 if (sym_name) ML_(dinfo_free)(sym_name);
498 }
499 return False;
500 # else
501 Int offset_in_opd;
502 Bool details = 1||False;
503
504 if (details)
505 TRACE_SYMTAB("opdXXX: opd_bias %p, sym_svma_out %p\n",
506 (void*)(opd_bias), (void*)*sym_avma_out);
507
508 if (!VG_IS_8_ALIGNED(*sym_avma_out)) {
509 if (TRACE_SYMTAB_ENABLED) {
510 HChar* sym_name = ML_(img_strdup)(escn_strtab->img,
511 "di.gesi.6a", sym_name_ioff);
512 TRACE_SYMTAB(" ignore -- not 8-aligned: %s\n", sym_name);
513 if (sym_name) ML_(dinfo_free)(sym_name);
514 }
515 return False;
516 }
517
518 /* *sym_avma_out is a vma pointing into the .opd section. We
519 know the vma of the opd section start, so we can figure out
520 how far into the opd section this is. */
521
522 offset_in_opd = (Addr)(*sym_avma_out) - (Addr)(di->opd_avma);
523 if (offset_in_opd < 0 || offset_in_opd >= di->opd_size) {
524 if (TRACE_SYMTAB_ENABLED) {
525 HChar* sym_name = ML_(img_strdup)(escn_strtab->img,
526 "di.gesi.6a", sym_name_ioff);
527 TRACE_SYMTAB(" ignore -- invalid OPD offset: %s\n", sym_name);
528 if (sym_name) ML_(dinfo_free)(sym_name);
529 }
530 return False;
531 }
532
533 /* Now we want to know what's at that offset in the .opd
534 section. We can't look in the running image since it won't
535 necessarily have been mapped. But we can consult the oimage.
536 opd_img is the start address of the .opd in the oimage.
537 Hence: */
538
539 ULong fn_descr[2]; /* is actually 3 words, but we need only 2 */
540 if (!ML_(img_valid)(escn_opd->img, escn_opd->ioff + offset_in_opd,
541 sizeof(fn_descr))) {
542 if (TRACE_SYMTAB_ENABLED) {
543 HChar* sym_name = ML_(img_strdup)(escn_strtab->img,
544 "di.gesi.6b", sym_name_ioff);
545 TRACE_SYMTAB(" ignore -- invalid OPD fn_descr offset: %s\n",
546 sym_name);
547 if (sym_name) ML_(dinfo_free)(sym_name);
548
549 }
550 return False;
551 }
552
553 /* This can't fail now, because we just checked the offset
554 above. */
555 ML_(img_get)(&fn_descr[0], escn_opd->img,
556 escn_opd->ioff + offset_in_opd, sizeof(fn_descr));
557
558 if (details)
559 TRACE_SYMTAB("opdXXY: offset %d, fn_descr %p\n",
560 offset_in_opd, fn_descr);
561 if (details)
562 TRACE_SYMTAB("opdXXZ: *fn_descr %p\n", (void*)(fn_descr[0]));
563
564 /* opd_bias is the what we have to add to SVMAs found in .opd to
565 get plausible .text AVMAs for the entry point, and .data
566 AVMAs (presumably) for the TOC locations. We use the caller
567 supplied value (which is di->text_bias) for both of these.
568 Not sure why that is correct - it seems to work, and sounds
569 OK for fn_descr[0], but surely we need to use the data bias
570 and not the text bias for fn_descr[1] ? Oh Well.
571 */
572 *sym_avma_out = fn_descr[0] + opd_bias;
573 *sym_tocptr_out = fn_descr[1] + opd_bias;
574 *from_opd_out = True;
575 is_in_opd = True;
576
577 /* Do a final sanity check: if the symbol falls outside the
578 DebugInfo's mapped range, ignore it. Since *sym_avma_out has
579 been updated, that can be achieved simply by falling through
580 to the test below. */
581
582 # endif /* ppc64-linux nasty hack */
583 }
584
585 /* Here's yet another ppc64-linux hack. Get rid of leading dot if
586 the symbol is outside .opd. */
587 # if defined(VGP_ppc64_linux)
588 if (di->opd_size > 0
589 && !is_in_opd
590 && *sym_name_out_ioff != DiOffT_INVALID
591 && ML_(img_get_UChar)(escn_strtab->img, *sym_name_out_ioff) == '.') {
592 vg_assert(!(*from_opd_out));
593 (*sym_name_out_ioff)++;
594 }
595 # endif
596
597 /* If no part of the symbol falls within the mapped range,
598 ignore it. */
599
600 in_text
601 = di->text_present
602 && di->text_size > 0
603 && !(*sym_avma_out + *sym_size_out <= di->text_avma
604 || *sym_avma_out >= di->text_avma + di->text_size);
605
606 in_data
607 = di->data_present
608 && di->data_size > 0
609 && !(*sym_avma_out + *sym_size_out <= di->data_avma
610 || *sym_avma_out >= di->data_avma + di->data_size);
611
612 in_sdata
613 = di->sdata_present
614 && di->sdata_size > 0
615 && !(*sym_avma_out + *sym_size_out <= di->sdata_avma
616 || *sym_avma_out >= di->sdata_avma + di->sdata_size);
617
618 in_rodata
619 = di->rodata_present
620 && di->rodata_size > 0
621 && !(*sym_avma_out + *sym_size_out <= di->rodata_avma
622 || *sym_avma_out >= di->rodata_avma + di->rodata_size);
623
624 in_bss
625 = di->bss_present
626 && di->bss_size > 0
627 && !(*sym_avma_out + *sym_size_out <= di->bss_avma
628 || *sym_avma_out >= di->bss_avma + di->bss_size);
629
630 in_sbss
631 = di->sbss_present
632 && di->sbss_size > 0
633 && !(*sym_avma_out + *sym_size_out <= di->sbss_avma
634 || *sym_avma_out >= di->sbss_avma + di->sbss_size);
635
636
637 if (*is_text_out) {
638 /* This used to reject any symbol falling outside the text
639 segment ("if (!in_text) ..."). Now it is relaxed slightly,
640 to reject only symbols which fall outside the area mapped
641 r-x. This is in accordance with r7427. See
642 "Comment_Regarding_Text_Range_Checks" in storage.c for
643 background. */
644 Bool in_rx;
645 vg_assert(di->fsm.have_rx_map);
646 /* This could actually wrap around and cause
647 ML_(find_rx_mapping) to assert. But that seems so unlikely,
648 let's wait for it to happen before fixing it. */
649 in_rx = (ML_(find_rx_mapping)(di, *sym_avma_out,
650 *sym_avma_out + *sym_size_out) != NULL);
651 if (in_text)
652 vg_assert(in_rx);
653 if (!in_rx) {
654 TRACE_SYMTAB(
655 "ignore -- %#lx .. %#lx outside .text svma range %#lx .. %#lx\n",
656 *sym_avma_out, *sym_avma_out + *sym_size_out,
657 di->text_avma,
658 di->text_avma + di->text_size);
659 return False;
660 }
661 } else {
662 if (!(in_data || in_sdata || in_rodata || in_bss || in_sbss)) {
663 TRACE_SYMTAB(
664 "ignore -- %#lx .. %#lx outside .data / .sdata / .rodata "
665 "/ .bss / .sbss svma ranges\n",
666 *sym_avma_out, *sym_avma_out + *sym_size_out);
667 return False;
668 }
669 }
670
671 # if defined(VGP_ppc64_linux)
672 /* It's crucial that we never add symbol addresses in the .opd
673 section. This would completely mess up function redirection and
674 intercepting. This assert ensures that any symbols that make it
675 into the symbol table on ppc64-linux don't point into .opd. */
676 if (di->opd_present && di->opd_size > 0) {
677 vg_assert(*sym_avma_out + *sym_size_out <= di->opd_avma
678 || *sym_avma_out >= di->opd_avma + di->opd_size);
679 }
680 # endif
681
682 /* Acquire! */
683 return True;
684 }
685
686
687 /* Read an ELF symbol table (normal or dynamic). This one is for the
688 "normal" case ({x86,amd64,ppc32,arm,mips32,mips64}-linux). */
689 static
690 __attribute__((unused)) /* not referred to on all targets */
read_elf_symtab__normal(struct _DebugInfo * di,const HChar * tab_name,DiSlice * escn_symtab,DiSlice * escn_strtab,DiSlice * escn_opd,Bool symtab_in_debug)691 void read_elf_symtab__normal(
692 struct _DebugInfo* di, const HChar* tab_name,
693 DiSlice* escn_symtab,
694 DiSlice* escn_strtab,
695 DiSlice* escn_opd, /* ppc64-linux only */
696 Bool symtab_in_debug
697 )
698 {
699 if (escn_strtab->img == NULL || escn_symtab->img == NULL) {
700 HChar buf[80];
701 vg_assert(VG_(strlen)(tab_name) < 40);
702 VG_(sprintf)(buf, " object doesn't have a %s", tab_name);
703 ML_(symerr)(di, False, buf);
704 return;
705 }
706
707 TRACE_SYMTAB("\n--- Reading (ELF, standard) %s (%lld entries) ---\n",
708 tab_name, escn_symtab->szB/sizeof(ElfXX_Sym) );
709
710 /* Perhaps should start at i = 1; ELF docs suggest that entry
711 0 always denotes 'unknown symbol'. */
712 Word i;
713 for (i = 1; i < (Word)(escn_symtab->szB/sizeof(ElfXX_Sym)); i++) {
714 ElfXX_Sym sym;
715 ML_(img_get)(&sym, escn_symtab->img,
716 escn_symtab->ioff + i * sizeof(ElfXX_Sym), sizeof(sym));
717 DiOffT sym_name = escn_strtab->ioff + sym.st_name;
718 Addr sym_svma = sym.st_value;
719
720 if (di->trace_symtab)
721 show_raw_elf_symbol(escn_strtab->img, i,
722 &sym, sym_name, sym_svma, False);
723
724 Addr sym_avma_really = 0;
725 Int sym_size = 0;
726 Addr sym_tocptr = 0;
727 Bool from_opd = False, is_text = False, is_ifunc = False;
728 DiOffT sym_name_really = DiOffT_INVALID;
729 if (get_elf_symbol_info(di, &sym, sym_name, escn_strtab,
730 sym_svma, symtab_in_debug,
731 escn_opd, di->text_bias,
732 &sym_name_really,
733 &sym_avma_really,
734 &sym_size,
735 &sym_tocptr,
736 &from_opd, &is_text, &is_ifunc)) {
737
738 DiSym disym;
739 VG_(memset)(&disym, 0, sizeof(disym));
740 HChar* cstr = ML_(img_strdup)(escn_strtab->img,
741 "di.res__n.1", sym_name_really);
742 disym.addr = sym_avma_really;
743 disym.tocptr = sym_tocptr;
744 disym.pri_name = ML_(addStr) ( di, cstr, -1 );
745 disym.sec_names = NULL;
746 disym.size = sym_size;
747 disym.isText = is_text;
748 disym.isIFunc = is_ifunc;
749 if (cstr) { ML_(dinfo_free)(cstr); cstr = NULL; }
750 vg_assert(disym.pri_name);
751 vg_assert(disym.tocptr == 0); /* has no role except on ppc64-linux */
752 ML_(addSym) ( di, &disym );
753
754 if (TRACE_SYMTAB_ENABLED) {
755 TRACE_SYMTAB(" rec(%c) [%4ld]: "
756 " val %#010lx, sz %4d %s\n",
757 is_text ? 't' : 'd',
758 i,
759 disym.addr,
760 (Int)disym.size,
761 (HChar*)disym.pri_name
762 );
763 }
764
765 }
766 }
767 }
768
769
770 /* Read an ELF symbol table (normal or dynamic). This one is for
771 ppc64-linux, which requires special treatment. */
772
773 typedef
774 struct {
775 Addr addr;
776 DiOffT name;
777 /* We have to store also the DiImage* so as to give context for
778 |name|. This is not part of the key (in terms of lookup) but
779 there's no easy other way to do this. Ugly. */
780 DiImage* img;
781 }
782 TempSymKey;
783
784 typedef
785 struct {
786 TempSymKey key;
787 Addr tocptr;
788 Int size;
789 Bool from_opd;
790 Bool is_text;
791 Bool is_ifunc;
792 }
793 TempSym;
794
cmp_TempSymKey(TempSymKey * key1,TempSym * elem2)795 static Word cmp_TempSymKey ( TempSymKey* key1, TempSym* elem2 )
796 {
797 /* Stay sane ... */
798 vg_assert(key1->img == elem2->key.img);
799 vg_assert(key1->img != NULL);
800 if (key1->addr < elem2->key.addr) return -1;
801 if (key1->addr > elem2->key.addr) return 1;
802 vg_assert(key1->name != DiOffT_INVALID);
803 vg_assert(elem2->key.name != DiOffT_INVALID);
804 return (Word)ML_(img_strcmp)(key1->img, key1->name, elem2->key.name);
805 }
806
807 static
808 __attribute__((unused)) /* not referred to on all targets */
read_elf_symtab__ppc64_linux(struct _DebugInfo * di,const HChar * tab_name,DiSlice * escn_symtab,DiSlice * escn_strtab,DiSlice * escn_opd,Bool symtab_in_debug)809 void read_elf_symtab__ppc64_linux(
810 struct _DebugInfo* di, const HChar* tab_name,
811 DiSlice* escn_symtab,
812 DiSlice* escn_strtab,
813 DiSlice* escn_opd, /* ppc64-linux only */
814 Bool symtab_in_debug
815 )
816 {
817 Word i;
818 Int old_size;
819 Bool modify_size, modify_tocptr;
820 OSet *oset;
821 TempSymKey key;
822 TempSym *elem;
823 TempSym *prev;
824
825 if (escn_strtab->img == NULL || escn_symtab->img == NULL) {
826 HChar buf[80];
827 vg_assert(VG_(strlen)(tab_name) < 40);
828 VG_(sprintf)(buf, " object doesn't have a %s", tab_name);
829 ML_(symerr)(di, False, buf);
830 return;
831 }
832
833 TRACE_SYMTAB("\n--- Reading (ELF, ppc64-linux) %s (%lld entries) ---\n",
834 tab_name, escn_symtab->szB/sizeof(ElfXX_Sym) );
835
836 oset = VG_(OSetGen_Create)( offsetof(TempSym,key),
837 (OSetCmp_t)cmp_TempSymKey,
838 ML_(dinfo_zalloc), "di.respl.1",
839 ML_(dinfo_free) );
840 vg_assert(oset);
841
842 /* Perhaps should start at i = 1; ELF docs suggest that entry
843 0 always denotes 'unknown symbol'. */
844 for (i = 1; i < (Word)(escn_symtab->szB/sizeof(ElfXX_Sym)); i++) {
845 ElfXX_Sym sym;
846 ML_(img_get)(&sym, escn_symtab->img,
847 escn_symtab->ioff + i * sizeof(ElfXX_Sym), sizeof(sym));
848 DiOffT sym_name = escn_strtab->ioff + sym.st_name;
849 Addr sym_svma = sym.st_value;
850
851 if (di->trace_symtab)
852 show_raw_elf_symbol(escn_strtab->img, i,
853 &sym, sym_name, sym_svma, True);
854
855 Addr sym_avma_really = 0;
856 Int sym_size = 0;
857 Addr sym_tocptr = 0;
858 Bool from_opd = False, is_text = False, is_ifunc = False;
859 DiOffT sym_name_really = DiOffT_INVALID;
860 DiSym disym;
861 VG_(memset)(&disym, 0, sizeof(disym));
862 if (get_elf_symbol_info(di, &sym, sym_name, escn_strtab,
863 sym_svma, symtab_in_debug,
864 escn_opd, di->text_bias,
865 &sym_name_really,
866 &sym_avma_really,
867 &sym_size,
868 &sym_tocptr,
869 &from_opd, &is_text, &is_ifunc)) {
870
871 /* Check if we've seen this (name,addr) key before. */
872 key.addr = sym_avma_really;
873 key.name = sym_name_really;
874 key.img = escn_strtab->img;
875 prev = VG_(OSetGen_Lookup)( oset, &key );
876
877 if (prev) {
878
879 /* Seen it before. Fold in whatever new info we can. */
880 modify_size = False;
881 modify_tocptr = False;
882 old_size = 0;
883
884 if (prev->from_opd && !from_opd
885 && (prev->size == 24 || prev->size == 16)
886 && sym_size != prev->size) {
887 /* Existing one is an opd-redirect, with a bogus size,
888 so the only useful new fact we have is the real size
889 of the symbol. */
890 modify_size = True;
891 old_size = prev->size;
892 prev->size = sym_size;
893 }
894 else
895 if (!prev->from_opd && from_opd
896 && (sym_size == 24 || sym_size == 16)) {
897 /* Existing one is non-opd, new one is opd. What we
898 can acquire from the new one is the TOC ptr to be
899 used. Since the existing sym is non-toc, it
900 shouldn't currently have an known TOC ptr. */
901 vg_assert(prev->tocptr == 0);
902 modify_tocptr = True;
903 prev->tocptr = sym_tocptr;
904 }
905 else {
906 /* ignore. can we do better here? */
907 }
908
909 /* Only one or the other is possible (I think) */
910 vg_assert(!(modify_size && modify_tocptr));
911
912 if (modify_size && di->trace_symtab) {
913 VG_(printf)(" modify (old sz %4d) "
914 " val %#010lx, toc %#010lx, sz %4d %lld\n",
915 old_size,
916 prev->key.addr,
917 prev->tocptr,
918 (Int) prev->size,
919 (ULong)prev->key.name
920 );
921 }
922 if (modify_tocptr && di->trace_symtab) {
923 VG_(printf)(" modify (upd tocptr) "
924 " val %#010lx, toc %#010lx, sz %4d %lld\n",
925 prev->key.addr,
926 prev->tocptr,
927 (Int) prev->size,
928 (ULong)prev->key.name
929 );
930 }
931
932 } else {
933
934 /* A new (name,addr) key. Add and continue. */
935 elem = VG_(OSetGen_AllocNode)(oset, sizeof(TempSym));
936 vg_assert(elem);
937 elem->key = key;
938 elem->tocptr = sym_tocptr;
939 elem->size = sym_size;
940 elem->from_opd = from_opd;
941 elem->is_text = is_text;
942 elem->is_ifunc = is_ifunc;
943 VG_(OSetGen_Insert)(oset, elem);
944 if (di->trace_symtab) {
945 HChar* str = ML_(img_strdup)(escn_strtab->img, "di.respl.2",
946 elem->key.name);
947 VG_(printf)(" to-oset [%4ld]: "
948 " val %#010lx, toc %#010lx, sz %4d %s\n",
949 i,
950 elem->key.addr,
951 elem->tocptr,
952 (Int) elem->size,
953 str
954 );
955 if (str) ML_(dinfo_free)(str);
956 }
957
958 }
959 }
960 }
961
962 /* All the syms that matter are in the oset. Now pull them out,
963 build a "standard" symbol table, and nuke the oset. */
964
965 i = 0;
966 VG_(OSetGen_ResetIter)( oset );
967
968 while ( (elem = VG_(OSetGen_Next)(oset)) ) {
969 DiSym disym;
970 VG_(memset)(&disym, 0, sizeof(disym));
971 HChar* cstr = ML_(img_strdup)(escn_strtab->img,
972 "di.res__ppc64.1", elem->key.name);
973 disym.addr = elem->key.addr;
974 disym.tocptr = elem->tocptr;
975 disym.pri_name = ML_(addStr) ( di, cstr, -1 );
976 disym.sec_names = NULL;
977 disym.size = elem->size;
978 disym.isText = elem->is_text;
979 disym.isIFunc = elem->is_ifunc;
980 if (cstr) { ML_(dinfo_free)(cstr); cstr = NULL; }
981 vg_assert(disym.pri_name != NULL);
982
983 ML_(addSym) ( di, &disym );
984 if (di->trace_symtab) {
985 VG_(printf)(" rec(%c) [%4ld]: "
986 " val %#010lx, toc %#010lx, sz %4d %s\n",
987 disym.isText ? 't' : 'd',
988 i,
989 disym.addr,
990 disym.tocptr,
991 (Int) disym.size,
992 (HChar*)disym.pri_name
993 );
994 }
995 i++;
996 }
997
998 VG_(OSetGen_Destroy)( oset );
999 }
1000
1001
1002 /*
1003 * Look for a build-id in an ELF image. The build-id specification
1004 * can be found here:
1005 *
1006 * http://fedoraproject.org/wiki/RolandMcGrath/BuildID
1007 *
1008 * Returned string must be freed by the caller.
1009 */
1010 static
find_buildid(DiImage * img,Bool rel_ok,Bool search_shdrs)1011 HChar* find_buildid(DiImage* img, Bool rel_ok, Bool search_shdrs)
1012 {
1013 HChar* buildid = NULL;
1014
1015 # ifdef NT_GNU_BUILD_ID
1016 if (is_elf_object_file_by_DiImage(img, rel_ok)) {
1017 Word i;
1018
1019 ElfXX_Ehdr ehdr;
1020 ML_(img_get)(&ehdr, img, 0, sizeof(ehdr));
1021 for (i = 0; i < ehdr.e_phnum; i++) {
1022 ElfXX_Phdr phdr;
1023 ML_(img_get)(&phdr, img,
1024 ehdr.e_phoff + i * ehdr.e_phentsize, sizeof(phdr));
1025
1026 if (phdr.p_type == PT_NOTE) {
1027 ElfXX_Off note_ioff = phdr.p_offset;
1028
1029 while (note_ioff < phdr.p_offset + phdr.p_filesz) {
1030 ElfXX_Nhdr note;
1031 ML_(img_get)(¬e, img, (DiOffT)note_ioff, sizeof(note));
1032 DiOffT name_ioff = note_ioff + sizeof(ElfXX_Nhdr);
1033 DiOffT desc_ioff = name_ioff + ((note.n_namesz + 3) & ~3);
1034 if (ML_(img_strcmp_c)(img, name_ioff, ELF_NOTE_GNU) == 0
1035 && note.n_type == NT_GNU_BUILD_ID) {
1036 buildid = ML_(dinfo_zalloc)("di.fbi.1",
1037 note.n_descsz * 2 + 1);
1038 Word j;
1039 for (j = 0; j < note.n_descsz; j++) {
1040 UChar desc_j = ML_(img_get_UChar)(img, desc_ioff + j);
1041 VG_(sprintf)(buildid + VG_(strlen)(buildid),
1042 "%02x", (UInt)desc_j);
1043 }
1044 }
1045
1046 note_ioff = note_ioff + sizeof(ElfXX_Nhdr)
1047 + ((note.n_namesz + 3) & ~3)
1048 + ((note.n_descsz + 3) & ~3);
1049 }
1050 }
1051 }
1052
1053 /* Normally we would only search shdrs for ET_REL files, but when
1054 we search for a separate .debug file phdrs might not be there
1055 (they are never loaded) or have been corrupted, so try again
1056 against shdrs. */
1057 if (buildid || (!rel_ok && !search_shdrs))
1058 return buildid;
1059
1060 for (i = 0; i < ehdr.e_shnum; i++) {
1061 ElfXX_Shdr shdr;
1062 ML_(img_get)(&shdr, img,
1063 ehdr.e_shoff + i * ehdr.e_shentsize, sizeof(shdr));
1064
1065 if (shdr.sh_type == SHT_NOTE) {
1066 ElfXX_Off note_ioff = shdr.sh_offset;
1067
1068 while (note_ioff < shdr.sh_offset + shdr.sh_size) {
1069 ElfXX_Nhdr note;
1070 ML_(img_get)(¬e, img, (DiOffT)note_ioff, sizeof(note));
1071 DiOffT name_ioff = note_ioff + sizeof(ElfXX_Nhdr);
1072 DiOffT desc_ioff = name_ioff + ((note.n_namesz + 3) & ~3);
1073
1074 if (ML_(img_strcmp_c)(img, name_ioff, ELF_NOTE_GNU) == 0
1075 && note.n_type == NT_GNU_BUILD_ID) {
1076 buildid = ML_(dinfo_zalloc)("di.fbi.2",
1077 note.n_descsz * 2 + 1);
1078 Word j;
1079 for (j = 0; j < note.n_descsz; j++) {
1080 UChar desc_j = ML_(img_get_UChar)(img, desc_ioff + j);
1081 VG_(sprintf)(buildid + VG_(strlen)(buildid),
1082 "%02x", (UInt)desc_j);
1083 }
1084 }
1085
1086 note_ioff = note_ioff + sizeof(ElfXX_Nhdr)
1087 + ((note.n_namesz + 3) & ~3)
1088 + ((note.n_descsz + 3) & ~3);
1089 }
1090 }
1091 }
1092 }
1093 # endif /* def NT_GNU_BUILD_ID */
1094
1095 return buildid;
1096 }
1097
1098
1099 /* Try and open a separate debug file, ignoring any where the CRC does
1100 not match the value from the main object file. Returned DiImage
1101 must be discarded by the caller.
1102
1103 If |serverAddr| is NULL, |name| is expected to be a fully qualified
1104 (absolute) path to the file in the local filesystem. If
1105 |serverAddr| is non-NULL, it is expected to be an IPv4 and port
1106 spec of the form "d.d.d.d:d" or "d.d.d.d", and |name| is expected
1107 to be a plain filename (no path components at all).
1108 */
1109 static
open_debug_file(const HChar * name,const HChar * buildid,UInt crc,Bool rel_ok,const HChar * serverAddr)1110 DiImage* open_debug_file( const HChar* name, const HChar* buildid, UInt crc,
1111 Bool rel_ok, const HChar* serverAddr )
1112 {
1113 DiImage* dimg
1114 = serverAddr ? ML_(img_from_di_server)(name, serverAddr)
1115 : ML_(img_from_local_file)(name);
1116 if (dimg == NULL)
1117 return NULL;
1118
1119 if (VG_(clo_verbosity) > 1) {
1120 if (serverAddr)
1121 VG_(message)(Vg_DebugMsg, " Considering %s on server %s ..\n",
1122 name, serverAddr);
1123 else
1124 VG_(message)(Vg_DebugMsg, " Considering %s ..\n", name);
1125 }
1126
1127 if (buildid) {
1128 HChar* debug_buildid = find_buildid(dimg, rel_ok, True);
1129 if (debug_buildid == NULL || VG_(strcmp)(buildid, debug_buildid) != 0) {
1130 ML_(img_done)(dimg);
1131 if (VG_(clo_verbosity) > 1)
1132 VG_(message)(Vg_DebugMsg,
1133 " .. build-id mismatch (found %s wanted %s)\n",
1134 debug_buildid, buildid);
1135 ML_(dinfo_free)(debug_buildid);
1136 return NULL;
1137 }
1138 ML_(dinfo_free)(debug_buildid);
1139 if (VG_(clo_verbosity) > 1)
1140 VG_(message)(Vg_DebugMsg, " .. build-id is valid\n");
1141 } else {
1142 UInt calccrc = ML_(img_calc_gnu_debuglink_crc32)(dimg);
1143 if (calccrc != crc) {
1144 ML_(img_done)(dimg);
1145 if (VG_(clo_verbosity) > 1)
1146 VG_(message)(Vg_DebugMsg,
1147 " .. CRC mismatch (computed %08x wanted %08x)\n", calccrc, crc);
1148 return NULL;
1149 }
1150
1151 if (VG_(clo_verbosity) > 1)
1152 VG_(message)(Vg_DebugMsg, " .. CRC is valid\n");
1153 }
1154
1155 return dimg;
1156 }
1157
1158
1159 /* Try to find a separate debug file for a given object file. If
1160 found, return its DiImage, which should be freed by the caller. If
1161 |buildid| is non-NULL, then a debug object matching it is
1162 acceptable. If |buildid| is NULL or doesn't specify a findable
1163 debug object, then we look in various places to find a file with
1164 the specified CRC. And if that doesn't work out then we give
1165 up. */
1166 static
find_debug_file(struct _DebugInfo * di,const HChar * objpath,const HChar * buildid,const HChar * debugname,UInt crc,Bool rel_ok)1167 DiImage* find_debug_file( struct _DebugInfo* di,
1168 const HChar* objpath, const HChar* buildid,
1169 const HChar* debugname, UInt crc, Bool rel_ok )
1170 {
1171 const HChar* extrapath = VG_(clo_extra_debuginfo_path);
1172 const HChar* serverpath = VG_(clo_debuginfo_server);
1173
1174 DiImage* dimg = NULL; /* the img that we found */
1175 HChar* debugpath = NULL; /* where we found it */
1176
1177 if (buildid != NULL) {
1178 debugpath = ML_(dinfo_zalloc)("di.fdf.1",
1179 VG_(strlen)(buildid) + 33);
1180
1181 VG_(sprintf)(debugpath, "/usr/lib/debug/.build-id/%c%c/%s.debug",
1182 buildid[0], buildid[1], buildid + 2);
1183
1184 dimg = open_debug_file(debugpath, buildid, 0, rel_ok, NULL);
1185 if (!dimg) {
1186 ML_(dinfo_free)(debugpath);
1187 debugpath = NULL;
1188 }
1189 }
1190
1191 if (dimg == NULL && debugname != NULL && !rel_ok) {
1192 HChar *objdir = ML_(dinfo_strdup)("di.fdf.2", objpath);
1193 HChar *objdirptr;
1194
1195 if ((objdirptr = VG_(strrchr)(objdir, '/')) != NULL)
1196 *objdirptr = '\0';
1197
1198 debugpath = ML_(dinfo_zalloc)(
1199 "di.fdf.3",
1200 VG_(strlen)(objdir) + VG_(strlen)(debugname) + 64
1201 + (extrapath ? VG_(strlen)(extrapath) : 0)
1202 + (serverpath ? VG_(strlen)(serverpath) : 0));
1203
1204 VG_(sprintf)(debugpath, "%s/%s", objdir, debugname);
1205 dimg = open_debug_file(debugpath, NULL, crc, rel_ok, NULL);
1206 if (dimg != NULL) goto dimg_ok;
1207
1208 VG_(sprintf)(debugpath, "%s/.debug/%s", objdir, debugname);
1209 dimg = open_debug_file(debugpath, NULL, crc, rel_ok, NULL);
1210 if (dimg != NULL) goto dimg_ok;
1211
1212 VG_(sprintf)(debugpath, "/usr/lib/debug%s/%s", objdir, debugname);
1213 dimg = open_debug_file(debugpath, NULL, crc, rel_ok, NULL);
1214 if (dimg != NULL) goto dimg_ok;
1215
1216 if (extrapath) {
1217 VG_(sprintf)(debugpath, "%s%s/%s", extrapath,
1218 objdir, debugname);
1219 dimg = open_debug_file(debugpath, NULL, crc, rel_ok, NULL);
1220 if (dimg != NULL) goto dimg_ok;
1221 }
1222
1223 if (serverpath) {
1224 /* When looking on the debuginfo server, always just pass the
1225 basename. */
1226 const HChar* basename = debugname;
1227 if (VG_(strstr)(basename, "/") != NULL) {
1228 basename = VG_(strrchr)(basename, '/') + 1;
1229 }
1230 VG_(sprintf)(debugpath, "%s on %s", basename, serverpath);
1231 dimg = open_debug_file(basename, NULL, crc, rel_ok, serverpath);
1232 if (dimg) goto dimg_ok;
1233 }
1234
1235 #if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
1236 VG_(sprintf)(debugpath, "/data/local/symbols%s/%s", objdir, debugname);
1237 dimg = open_debug_file(debugpath, NULL, crc, rel_ok, NULL);
1238 if (dimg != NULL) goto dimg_ok;
1239 #endif
1240
1241 dimg_ok:
1242
1243 ML_(dinfo_free)(objdir);
1244 }
1245
1246 if (dimg != NULL) {
1247 vg_assert(debugpath);
1248 TRACE_SYMTAB("\n");
1249 TRACE_SYMTAB("------ Found a debuginfo file: %s\n", debugpath);
1250 }
1251
1252 if (debugpath)
1253 ML_(dinfo_free)(debugpath);
1254
1255 return dimg;
1256 }
1257
1258
1259 /* Try to find a separate debug file for a given object file, in a
1260 hacky and dangerous way: check only the --extra-debuginfo-path and
1261 the --debuginfo-server. And don't do a consistency check. */
1262 static
find_debug_file_ad_hoc(struct _DebugInfo * di,const HChar * objpath)1263 DiImage* find_debug_file_ad_hoc( struct _DebugInfo* di,
1264 const HChar* objpath )
1265 {
1266 const HChar* extrapath = VG_(clo_extra_debuginfo_path);
1267 const HChar* serverpath = VG_(clo_debuginfo_server);
1268
1269 DiImage* dimg = NULL; /* the img that we found */
1270 HChar* debugpath = NULL; /* where we found it */
1271
1272 HChar *objdir = ML_(dinfo_strdup)("di.fdfah.1", objpath);
1273 HChar *objdirptr;
1274
1275 if ((objdirptr = VG_(strrchr)(objdir, '/')) != NULL)
1276 *objdirptr = '\0';
1277
1278 debugpath = ML_(dinfo_zalloc)(
1279 "di.fdfah.3",
1280 VG_(strlen)(objdir) + 64
1281 + (extrapath ? VG_(strlen)(extrapath) : 0)
1282 + (serverpath ? VG_(strlen)(serverpath) : 0));
1283
1284 if (extrapath) {
1285 VG_(sprintf)(debugpath, "%s/%s", extrapath, objpath);
1286 dimg = ML_(img_from_local_file)(debugpath);
1287 if (dimg != NULL) {
1288 if (VG_(clo_verbosity) > 1) {
1289 VG_(message)(Vg_DebugMsg, " Using (POSSIBLY MISMATCHED) %s\n",
1290 debugpath);
1291 }
1292 goto dimg_ok;
1293 }
1294 }
1295 if (serverpath) {
1296 /* When looking on the debuginfo server, always just pass the
1297 basename. */
1298 const HChar* basename = objpath;
1299 if (VG_(strstr)(basename, "/") != NULL) {
1300 basename = VG_(strrchr)(basename, '/') + 1;
1301 }
1302 VG_(sprintf)(debugpath, "%s on %s", basename, serverpath);
1303 dimg = ML_(img_from_di_server)(basename, serverpath);
1304 if (dimg != NULL) {
1305 if (VG_(clo_verbosity) > 1) {
1306 VG_(message)(Vg_DebugMsg, " Using (POSSIBLY MISMATCHED) %s\n",
1307 debugpath);
1308 }
1309 goto dimg_ok;
1310 }
1311 }
1312
1313 dimg_ok:
1314
1315 ML_(dinfo_free)(objdir);
1316
1317 if (dimg != NULL) {
1318 vg_assert(debugpath);
1319 TRACE_SYMTAB("\n");
1320 TRACE_SYMTAB("------ Found an ad_hoc debuginfo file: %s\n", debugpath);
1321 }
1322
1323 if (debugpath)
1324 ML_(dinfo_free)(debugpath);
1325
1326 return dimg;
1327 }
1328
1329
INDEX_BIS(DiOffT base,UWord idx,UWord scale)1330 static DiOffT INDEX_BIS ( DiOffT base, UWord idx, UWord scale ) {
1331 // This is a bit stupid. Really, idx and scale ought to be
1332 // 64-bit quantities, always.
1333 return base + (DiOffT)idx * (DiOffT)scale;
1334 }
1335
1336
1337 /* Find the file offset corresponding to SVMA by using the program
1338 headers. This is taken from binutils-2.17/binutils/readelf.c
1339 offset_from_vma(). */
1340 static
file_offset_from_svma(Bool * ok,Addr svma,DiImage * img,DiOffT phdr_ioff,Word phdr_nent,Word phdr_ent_szB)1341 Word file_offset_from_svma ( /*OUT*/Bool* ok,
1342 Addr svma,
1343 DiImage* img,
1344 DiOffT phdr_ioff,
1345 Word phdr_nent,
1346 Word phdr_ent_szB )
1347 {
1348 Word i;
1349 for (i = 0; i < phdr_nent; i++) {
1350 ElfXX_Phdr seg;
1351 ML_(img_get)(&seg, img,
1352 INDEX_BIS(phdr_ioff, i, phdr_ent_szB), sizeof(seg));
1353 if (seg.p_type != PT_LOAD)
1354 continue;
1355 if (svma >= (seg.p_vaddr & -seg.p_align)
1356 && svma + 1 <= seg.p_vaddr + seg.p_filesz) {
1357 *ok = True;
1358 return svma - seg.p_vaddr + seg.p_offset;
1359 }
1360 }
1361 *ok = False;
1362 return 0;
1363 }
1364
1365
1366 /* The central function for reading ELF debug info. For the
1367 object/exe specified by the DebugInfo, find ELF sections, then read
1368 the symbols, line number info, file name info, CFA (stack-unwind
1369 info) and anything else we want, into the tables within the
1370 supplied DebugInfo.
1371 */
1372
ML_(read_elf_debug_info)1373 Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
1374 {
1375 /* This function is long and complex. That, and the presence of
1376 nested scopes, means it's not always easy to see which parts are
1377 in loops/conditionals and which aren't. To make it easier to
1378 follow, points executed exactly once -- that is, those which are
1379 the top level of the function -- are marked TOPLEVEL.
1380 */
1381 /* Consistent terminology for local variable names, without which
1382 it's almost unfollowably complex:
1383
1384 In which file?
1385 in the main ELF file *_m*
1386 in the debuginfo file *_d*
1387 in the alt debuginfo file *_a*
1388
1389 What kind of thing?
1390 _{m,d,a}img a DiImage*
1391 _{m,d,a}ioff an offset in the image (DiOffT)
1392 _{m,d,a}nent "number of entries"
1393 _{m,d,a}ent_szB "size in bytes of an entry"
1394 ehdr_{m,d,a} ELF header
1395 phdr Program header
1396 shdr Section header
1397 a_X a temporary X
1398 _escn an DiSlice (elf section info) variable
1399 szB size in bytes
1400 */
1401
1402
1403 /* TOPLEVEL */
1404 Bool res, ok;
1405 Word i, j;
1406 Bool dynbss_present = False;
1407 Bool sdynbss_present = False;
1408
1409 /* Image for the main ELF file we're working with. */
1410 DiImage* mimg = NULL;
1411
1412 /* Ditto for any ELF debuginfo file that we might happen to load. */
1413 DiImage* dimg = NULL;
1414
1415 /* Ditto for alternate ELF debuginfo file that we might happen to load. */
1416 DiImage* aimg = NULL;
1417
1418 /* ELF header offset for the main file. Should be zero since the
1419 ELF header is at start of file. */
1420 DiOffT ehdr_mioff = 0;
1421
1422 /* Program header table image addr, # entries, entry size */
1423 DiOffT phdr_mioff = 0;
1424 UWord phdr_mnent = 0;
1425 UWord phdr_ment_szB = 0;
1426
1427 /* Section header image addr, # entries, entry size. Also the
1428 associated string table. */
1429 DiOffT shdr_mioff = 0;
1430 UWord shdr_mnent = 0;
1431 UWord shdr_ment_szB = 0;
1432 DiOffT shdr_strtab_mioff = 0;
1433
1434 /* SVMAs covered by rx and rw segments and corresponding biases.
1435 Normally each object would provide just one rx and one rw area,
1436 but various ELF mangling tools create objects with multiple
1437 such entries, hence the generality. */
1438 typedef
1439 struct {
1440 Addr svma_base;
1441 Addr svma_limit;
1442 PtrdiffT bias;
1443 Bool exec;
1444 }
1445 RangeAndBias;
1446
1447 XArray* /* of RangeAndBias */ svma_ranges = NULL;
1448
1449 vg_assert(di);
1450 vg_assert(di->fsm.have_rx_map == True);
1451 vg_assert(di->fsm.have_rw_map == True);
1452 vg_assert(di->have_dinfo == False);
1453 vg_assert(di->fsm.filename);
1454 vg_assert(!di->symtab);
1455 vg_assert(!di->loctab);
1456 vg_assert(!di->cfsi);
1457 vg_assert(!di->cfsi_exprs);
1458 vg_assert(!di->strchunks);
1459 vg_assert(!di->soname);
1460
1461 {
1462 Bool has_nonempty_rx = False;
1463 Bool has_nonempty_rw = False;
1464 for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1465 struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
1466 if (!map->rx && !map->rw)
1467 continue;
1468 if (map->rx && map->size > 0)
1469 has_nonempty_rx = True;
1470 if (map->rw && map->size > 0)
1471 has_nonempty_rw = True;
1472 /* If this doesn't hold true, it means that m_syswrap/m_aspacemgr
1473 managed to do a mapping where the start isn't page aligned.
1474 Which sounds pretty bogus to me. */
1475 vg_assert(VG_IS_PAGE_ALIGNED(map->avma));
1476 }
1477 vg_assert(has_nonempty_rx);
1478 vg_assert(has_nonempty_rw);
1479 }
1480
1481 /* ----------------------------------------------------------
1482 At this point, there is very little information in the
1483 DebugInfo. We only know that something that looks like an ELF
1484 file has been mapped rx-ishly and rw-ishly as recorded in the
1485 di->fsm.maps array items. First we examine the file's ELF
1486 Program Header, and, by comparing that against the di->fsm.maps
1487 info, try to figure out the AVMAs for the sections we care
1488 about, that should have been mapped: text, data, sdata, bss,
1489 got, plt, and toc.
1490 ---------------------------------------------------------- */
1491
1492 res = False;
1493
1494 if (VG_(clo_verbosity) > 1 || VG_(clo_trace_redir))
1495 VG_(message)(Vg_DebugMsg, "Reading syms from %s\n",
1496 di->fsm.filename );
1497
1498 /* Connect to the primary object image, so that we can read symbols
1499 and line number info out of it. It will be disconnected
1500 immediately thereafter; it is only connected transiently. */
1501 mimg = ML_(img_from_local_file)(di->fsm.filename);
1502 if (mimg == NULL) {
1503 VG_(message)(Vg_UserMsg, "warning: connection to image %s failed\n",
1504 di->fsm.filename );
1505 VG_(message)(Vg_UserMsg, " no symbols or debug info loaded\n" );
1506 return False;
1507 }
1508
1509 /* Ok, the object image is available. Now verify that it is a
1510 valid ELF .so or executable image. */
1511 ok = is_elf_object_file_by_DiImage(mimg, False);
1512 if (!ok) {
1513 ML_(symerr)(di, True, "Invalid ELF Header");
1514 goto out;
1515 }
1516
1517 /* Find where the program and section header tables are, and give
1518 up if either is missing or outside the image (bogus). */
1519 ElfXX_Ehdr ehdr_m;
1520 vg_assert(ehdr_mioff == 0); // ensured by its initialisation
1521 ok = ML_(img_valid)(mimg, ehdr_mioff, sizeof(ehdr_m));
1522 vg_assert(ok); // ML_(is_elf_object_file) should ensure this
1523 ML_(img_get)(&ehdr_m, mimg, ehdr_mioff, sizeof(ehdr_m));
1524
1525 phdr_mioff = ehdr_mioff + ehdr_m.e_phoff;
1526 phdr_mnent = ehdr_m.e_phnum;
1527 phdr_ment_szB = ehdr_m.e_phentsize;
1528
1529 shdr_mioff = ehdr_mioff + ehdr_m.e_shoff;
1530 shdr_mnent = ehdr_m.e_shnum;
1531 shdr_ment_szB = ehdr_m.e_shentsize;
1532
1533 TRACE_SYMTAB("------ Basic facts about the object ------\n");
1534 TRACE_SYMTAB("object: n_oimage %llu\n",
1535 (ULong)ML_(img_size)(mimg));
1536 TRACE_SYMTAB("phdr: ioff %llu nent %ld ent_szB %ld\n",
1537 phdr_mioff, phdr_mnent, phdr_ment_szB);
1538 TRACE_SYMTAB("shdr: ioff %llu nent %ld ent_szB %ld\n",
1539 shdr_mioff, shdr_mnent, shdr_ment_szB);
1540 for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1541 struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
1542 if (map->rx)
1543 TRACE_SYMTAB("rx_map: avma %#lx size %lu foff %lu\n",
1544 map->avma, map->size, map->foff);
1545 }
1546 for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1547 struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
1548 if (map->rw)
1549 TRACE_SYMTAB("rw_map: avma %#lx size %lu foff %lu\n",
1550 map->avma, map->size, map->foff);
1551 }
1552
1553 if (phdr_mnent == 0
1554 || !ML_(img_valid)(mimg, phdr_mioff, phdr_mnent * phdr_ment_szB)) {
1555 ML_(symerr)(di, True, "Missing or invalid ELF Program Header Table");
1556 goto out;
1557 }
1558
1559 if (shdr_mnent == 0
1560 || !ML_(img_valid)(mimg, shdr_mioff, shdr_mnent * shdr_ment_szB)) {
1561 ML_(symerr)(di, True, "Missing or invalid ELF Section Header Table");
1562 goto out;
1563 }
1564
1565 /* Also find the section header's string table, and validate. */
1566 /* checked previously by is_elf_object_file: */
1567 vg_assert(ehdr_m.e_shstrndx != SHN_UNDEF);
1568
1569 // shdr_mioff is the offset of the section header table
1570 // and we need the ehdr_m.e_shstrndx'th entry
1571 { ElfXX_Shdr a_shdr;
1572 ML_(img_get)(&a_shdr, mimg,
1573 INDEX_BIS(shdr_mioff, ehdr_m.e_shstrndx, shdr_ment_szB),
1574 sizeof(a_shdr));
1575 shdr_strtab_mioff
1576 = ehdr_mioff /* isn't this always zero? */ + a_shdr.sh_offset;
1577
1578 if (!ML_(img_valid)(mimg, shdr_strtab_mioff,
1579 1/*bogus, but we don't know the real size*/ )) {
1580 ML_(symerr)(di, True, "Invalid ELF Section Header String Table");
1581 goto out;
1582 }
1583 }
1584
1585 TRACE_SYMTAB("shdr: string table at %llu\n", shdr_strtab_mioff);
1586
1587 svma_ranges = VG_(newXA)(ML_(dinfo_zalloc), "di.relfdi.1",
1588 ML_(dinfo_free), sizeof(RangeAndBias));
1589
1590 /* TOPLEVEL */
1591 /* Look through the program header table, and:
1592 - copy information from suitable PT_LOAD entries into svma_ranges
1593 - find (or fake up) the .soname for this object.
1594 */
1595 TRACE_SYMTAB("\n");
1596 TRACE_SYMTAB("------ Examining the program headers ------\n");
1597 vg_assert(di->soname == NULL);
1598 {
1599 /* TOPLEVEL */
1600 ElfXX_Addr prev_svma = 0;
1601
1602 for (i = 0; i < phdr_mnent; i++) {
1603 ElfXX_Phdr a_phdr;
1604 ML_(img_get)(&a_phdr, mimg,
1605 INDEX_BIS(phdr_mioff, i, phdr_ment_szB),
1606 sizeof(a_phdr));
1607
1608 /* Make sure the PT_LOADable entries are in order and
1609 non-overlapping. This in turn means the address ranges
1610 slurped into svma_ranges are in order and
1611 non-overlapping. */
1612
1613 if (a_phdr.p_type == PT_LOAD) {
1614 TRACE_SYMTAB("PT_LOAD[%ld]: p_vaddr %#lx (prev %#lx)\n",
1615 i, (UWord)a_phdr.p_vaddr, (UWord)prev_svma);
1616 TRACE_SYMTAB("PT_LOAD[%ld]: p_offset %lu, p_filesz %lu,"
1617 " perms %c%c%c\n",
1618 i, (UWord)a_phdr.p_offset, (UWord)a_phdr.p_filesz,
1619 a_phdr.p_flags & PF_R ? 'r' : '-',
1620 a_phdr.p_flags & PF_W ? 'w' : '-',
1621 a_phdr.p_flags & PF_X ? 'x' : '-');
1622 if (a_phdr.p_vaddr < prev_svma) {
1623 ML_(symerr)(di, True,
1624 "ELF Program Headers are not in ascending order");
1625 goto out;
1626 }
1627 prev_svma = a_phdr.p_vaddr;
1628 if (a_phdr.p_memsz > 0) {
1629 Bool loaded = False;
1630 for (j = 0; j < VG_(sizeXA)(di->fsm.maps); j++) {
1631 struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, j);
1632 if ( (map->rx || map->rw)
1633 && a_phdr.p_offset >= map->foff
1634 && a_phdr.p_offset < map->foff + map->size
1635 && a_phdr.p_offset + a_phdr.p_filesz
1636 <= map->foff + map->size) {
1637 RangeAndBias item;
1638 item.svma_base = a_phdr.p_vaddr;
1639 item.svma_limit = a_phdr.p_vaddr + a_phdr.p_memsz;
1640 item.bias = map->avma - map->foff
1641 + a_phdr.p_offset - a_phdr.p_vaddr;
1642 if (map->rw
1643 && (a_phdr.p_flags & (PF_R | PF_W))
1644 == (PF_R | PF_W)) {
1645 item.exec = False;
1646 VG_(addToXA)(svma_ranges, &item);
1647 TRACE_SYMTAB("PT_LOAD[%ld]: acquired as rw\n", i);
1648 loaded = True;
1649 }
1650 if (map->rx
1651 && (a_phdr.p_flags & (PF_R | PF_X))
1652 == (PF_R | PF_X)) {
1653 item.exec = True;
1654 VG_(addToXA)(svma_ranges, &item);
1655 TRACE_SYMTAB("PT_LOAD[%ld]: acquired as rx\n", i);
1656 loaded = True;
1657 }
1658 }
1659 }
1660 if (!loaded) {
1661 ML_(symerr)(di, False,
1662 "ELF section outside all mapped regions");
1663 /* This problem might be solved by further memory mappings.
1664 Avoid the vg_assert(!di->soname) at the beginning of this
1665 function if DYNAMIC section has been already processed. */
1666 if (di->soname) {
1667 ML_(dinfo_free)(di->soname);
1668 di->soname = NULL;
1669 }
1670 goto out;
1671 }
1672 }
1673 }
1674
1675 /* Try to get the soname. If there isn't one, use "NONE".
1676 The seginfo needs to have some kind of soname in order to
1677 facilitate writing redirect functions, since all redirect
1678 specifications require a soname (pattern). */
1679 if (a_phdr.p_type == PT_DYNAMIC && di->soname == NULL) {
1680 Word stroff = -1;
1681 DiOffT strtab_mioff = DiOffT_INVALID;
1682 for (j = 0; True/*exit check is in the loop*/; j++) {
1683 ElfXX_Dyn t_dyn_m; /* dyn_img[j] */
1684 ML_(img_get)(&t_dyn_m, mimg,
1685 INDEX_BIS(ehdr_mioff + a_phdr.p_offset,
1686 j, sizeof(ElfXX_Dyn)),
1687 sizeof(t_dyn_m));
1688 if (t_dyn_m.d_tag == DT_NULL)
1689 break;
1690
1691 switch (t_dyn_m.d_tag) {
1692 case DT_SONAME: {
1693 stroff = t_dyn_m.d_un.d_val;
1694 break;
1695 }
1696 case DT_STRTAB: {
1697 Bool ok2 = False;
1698 Word offset = file_offset_from_svma(
1699 &ok2, t_dyn_m.d_un.d_ptr, mimg,
1700 phdr_mioff, phdr_mnent, phdr_ment_szB
1701 );
1702 if (ok2 && strtab_mioff == DiOffT_INVALID) {
1703 // Check for obviously bogus offsets.
1704 if (!ML_(img_valid)(mimg, offset, 1)) {
1705 ML_(symerr)(di, True, "Invalid DT_STRTAB offset");
1706 goto out;
1707 }
1708 strtab_mioff = ehdr_mioff + offset;
1709 vg_assert(ehdr_mioff == 0); // should always be
1710 }
1711 break;
1712 }
1713 default:
1714 break;
1715 }
1716 }
1717 if (stroff != -1 && strtab_mioff != DiOffT_INVALID) {
1718 di->soname = ML_(img_strdup)(mimg, "di.redi.1",
1719 strtab_mioff + stroff);
1720 TRACE_SYMTAB("Found soname = %s\n", di->soname);
1721 }
1722 }
1723 } /* for (i = 0; i < phdr_Mnent; i++) ... */
1724 /* TOPLEVEL */
1725
1726 } /* examine the program headers (local scope) */
1727
1728 /* TOPLEVEL */
1729
1730 /* If, after looking at all the program headers, we still didn't
1731 find a soname, add a fake one. */
1732 if (di->soname == NULL) {
1733 TRACE_SYMTAB("No soname found; using (fake) \"NONE\"\n");
1734 di->soname = ML_(dinfo_strdup)("di.redi.2", "NONE");
1735 }
1736
1737 vg_assert(VG_(sizeXA)(svma_ranges) != 0);
1738
1739 /* Now read the section table. */
1740 TRACE_SYMTAB("\n");
1741 TRACE_SYMTAB("------ Examining the section headers ------\n");
1742 for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1743 struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
1744 if (map->rx)
1745 TRACE_SYMTAB("rx: at %#lx are mapped foffsets %ld .. %ld\n",
1746 map->avma, map->foff, map->foff + map->size - 1 );
1747 }
1748 TRACE_SYMTAB("rx: contains these svma regions:\n");
1749 for (i = 0; i < VG_(sizeXA)(svma_ranges); i++) {
1750 RangeAndBias* reg = VG_(indexXA)(svma_ranges, i);
1751 if (reg->exec)
1752 TRACE_SYMTAB(" svmas %#lx .. %#lx with bias %#lx\n",
1753 reg->svma_base, reg->svma_limit - 1, reg->bias );
1754 }
1755 for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1756 struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
1757 if (map->rw)
1758 TRACE_SYMTAB("rw: at %#lx are mapped foffsets %ld .. %ld\n",
1759 map->avma, map->foff, map->foff + map->size - 1 );
1760 }
1761 TRACE_SYMTAB("rw: contains these svma regions:\n");
1762 for (i = 0; i < VG_(sizeXA)(svma_ranges); i++) {
1763 RangeAndBias* reg = VG_(indexXA)(svma_ranges, i);
1764 if (!reg->exec)
1765 TRACE_SYMTAB(" svmas %#lx .. %#lx with bias %#lx\n",
1766 reg->svma_base, reg->svma_limit - 1, reg->bias );
1767 }
1768
1769 /* TOPLEVEL */
1770 /* Iterate over section headers */
1771 for (i = 0; i < shdr_mnent; i++) {
1772 ElfXX_Shdr a_shdr;
1773 ML_(img_get)(&a_shdr, mimg,
1774 INDEX_BIS(shdr_mioff, i, shdr_ment_szB), sizeof(a_shdr));
1775 DiOffT name_mioff = shdr_strtab_mioff + a_shdr.sh_name;
1776 HChar* name = ML_(img_strdup)(mimg, "di.redi_name.1", name_mioff);
1777 Addr svma = a_shdr.sh_addr;
1778 OffT foff = a_shdr.sh_offset;
1779 UWord size = a_shdr.sh_size; /* Do not change this to be signed. */
1780 UInt alyn = a_shdr.sh_addralign;
1781 Bool bits = !(a_shdr.sh_type == SHT_NOBITS);
1782 /* Look through our collection of info obtained from the PT_LOAD
1783 headers, and make 'inrx' and 'inrw' point to the first entry
1784 in each that intersects 'avma'. If in each case none is found,
1785 leave the relevant pointer at NULL. */
1786 RangeAndBias* inrx = NULL;
1787 RangeAndBias* inrw = NULL;
1788 for (j = 0; j < VG_(sizeXA)(svma_ranges); j++) {
1789 RangeAndBias* rng = VG_(indexXA)(svma_ranges, j);
1790 if (svma >= rng->svma_base && svma < rng->svma_limit) {
1791 if (!inrx && rng->exec) {
1792 inrx = rng;
1793 } else if (!inrw && !rng->exec) {
1794 inrw = rng;
1795 }
1796 if (inrx && inrw)
1797 break;
1798 }
1799 }
1800
1801 TRACE_SYMTAB(" [sec %2ld] %s %s al%2u foff %6ld .. %6ld "
1802 " svma %p name \"%s\"\n",
1803 i, inrx ? "rx" : " ", inrw ? "rw" : " ", alyn,
1804 foff, foff+size-1, (void*)svma, name);
1805
1806 /* Check for sane-sized segments. SHT_NOBITS sections have zero
1807 size in the file. */
1808 if ((foff >= ML_(img_size)(mimg))
1809 || (foff + (bits ? size : 0) > ML_(img_size)(mimg))) {
1810 ML_(symerr)(di, True, "ELF Section extends beyond image end");
1811 goto out;
1812 }
1813
1814 /* Check for a sane alignment value. */
1815 if (alyn > 0 && -1 == VG_(log2)(alyn)) {
1816 ML_(symerr)(di, True, "ELF Section contains invalid "
1817 ".sh_addralign value");
1818 goto out;
1819 }
1820
1821 /* Ignore zero sized sections. */
1822 if (size == 0) {
1823 TRACE_SYMTAB("zero sized section \"%s\", ignoring\n", name);
1824 ML_(dinfo_free)(name);
1825 continue;
1826 }
1827
1828 # define BAD(_secname) \
1829 do { ML_(symerr)(di, True, \
1830 "Can't make sense of " _secname \
1831 " section mapping"); \
1832 /* make sure we don't assert if we find */ \
1833 /* ourselves back in this routine later, */ \
1834 /* with the same di */ \
1835 di->soname = NULL; \
1836 goto out; \
1837 } while (0)
1838
1839 /* Find avma-s for: .text .data .sdata .rodata .bss .sbss .plt .got .opd
1840 and .eh_frame */
1841
1842 /* Accept .text where mapped as rx (code), even if zero-sized */
1843 if (0 == VG_(strcmp)(name, ".text")) {
1844 if (inrx && !di->text_present) {
1845 di->text_present = True;
1846 di->text_svma = svma;
1847 di->text_avma = svma + inrx->bias;
1848 di->text_size = size;
1849 di->text_bias = inrx->bias;
1850 di->text_debug_svma = svma;
1851 di->text_debug_bias = inrx->bias;
1852 TRACE_SYMTAB("acquiring .text svma = %#lx .. %#lx\n",
1853 di->text_svma,
1854 di->text_svma + di->text_size - 1);
1855 TRACE_SYMTAB("acquiring .text avma = %#lx .. %#lx\n",
1856 di->text_avma,
1857 di->text_avma + di->text_size - 1);
1858 TRACE_SYMTAB("acquiring .text bias = %#lx\n", di->text_bias);
1859 } else {
1860 BAD(".text");
1861 }
1862 }
1863
1864 /* Accept .data where mapped as rw (data), even if zero-sized */
1865 if (0 == VG_(strcmp)(name, ".data")) {
1866 if (inrw && !di->data_present) {
1867 di->data_present = True;
1868 di->data_svma = svma;
1869 di->data_avma = svma + inrw->bias;
1870 di->data_size = size;
1871 di->data_bias = inrw->bias;
1872 di->data_debug_svma = svma;
1873 di->data_debug_bias = inrw->bias;
1874 TRACE_SYMTAB("acquiring .data svma = %#lx .. %#lx\n",
1875 di->data_svma,
1876 di->data_svma + di->data_size - 1);
1877 TRACE_SYMTAB("acquiring .data avma = %#lx .. %#lx\n",
1878 di->data_avma,
1879 di->data_avma + di->data_size - 1);
1880 TRACE_SYMTAB("acquiring .data bias = %#lx\n", di->data_bias);
1881 } else {
1882 BAD(".data");
1883 }
1884 }
1885
1886 /* Accept .sdata where mapped as rw (data) */
1887 if (0 == VG_(strcmp)(name, ".sdata")) {
1888 if (inrw && !di->sdata_present) {
1889 di->sdata_present = True;
1890 di->sdata_svma = svma;
1891 di->sdata_avma = svma + inrw->bias;
1892 di->sdata_size = size;
1893 di->sdata_bias = inrw->bias;
1894 di->sdata_debug_svma = svma;
1895 di->sdata_debug_bias = inrw->bias;
1896 TRACE_SYMTAB("acquiring .sdata svma = %#lx .. %#lx\n",
1897 di->sdata_svma,
1898 di->sdata_svma + di->sdata_size - 1);
1899 TRACE_SYMTAB("acquiring .sdata avma = %#lx .. %#lx\n",
1900 di->sdata_avma,
1901 di->sdata_avma + di->sdata_size - 1);
1902 TRACE_SYMTAB("acquiring .sdata bias = %#lx\n", di->sdata_bias);
1903 } else {
1904 BAD(".sdata");
1905 }
1906 }
1907
1908 /* Accept .rodata where mapped as rx (data), even if zero-sized */
1909 if (0 == VG_(strcmp)(name, ".rodata")) {
1910 if (inrx && !di->rodata_present) {
1911 di->rodata_present = True;
1912 di->rodata_svma = svma;
1913 di->rodata_avma = svma + inrx->bias;
1914 di->rodata_size = size;
1915 di->rodata_bias = inrx->bias;
1916 di->rodata_debug_svma = svma;
1917 di->rodata_debug_bias = inrx->bias;
1918 /* NB was 'inrw' prior to r11794 */
1919 TRACE_SYMTAB("acquiring .rodata svma = %#lx .. %#lx\n",
1920 di->rodata_svma,
1921 di->rodata_svma + di->rodata_size - 1);
1922 TRACE_SYMTAB("acquiring .rodata avma = %#lx .. %#lx\n",
1923 di->rodata_avma,
1924 di->rodata_avma + di->rodata_size - 1);
1925 TRACE_SYMTAB("acquiring .rodata bias = %#lx\n", di->rodata_bias);
1926 } else {
1927 BAD(".rodata");
1928 }
1929 }
1930
1931 if (0 == VG_(strcmp)(name, ".dynbss")) {
1932 if (inrw && !di->bss_present) {
1933 dynbss_present = True;
1934 di->bss_present = True;
1935 di->bss_svma = svma;
1936 di->bss_avma = svma + inrw->bias;
1937 di->bss_size = size;
1938 di->bss_bias = inrw->bias;
1939 di->bss_debug_svma = svma;
1940 di->bss_debug_bias = inrw->bias;
1941 TRACE_SYMTAB("acquiring .dynbss svma = %#lx .. %#lx\n",
1942 di->bss_svma,
1943 di->bss_svma + di->bss_size - 1);
1944 TRACE_SYMTAB("acquiring .dynbss avma = %#lx .. %#lx\n",
1945 di->bss_avma,
1946 di->bss_avma + di->bss_size - 1);
1947 TRACE_SYMTAB("acquiring .dynbss bias = %#lx\n", di->bss_bias);
1948 }
1949 }
1950
1951 /* Accept .bss where mapped as rw (data), even if zero-sized */
1952 if (0 == VG_(strcmp)(name, ".bss")) {
1953 if (inrw && dynbss_present) {
1954 vg_assert(di->bss_present);
1955 dynbss_present = False;
1956 vg_assert(di->bss_svma + di->bss_size == svma);
1957 di->bss_size += size;
1958 TRACE_SYMTAB("acquiring .bss svma = %#lx .. %#lx\n",
1959 svma, svma + size - 1);
1960 TRACE_SYMTAB("acquiring .bss avma = %#lx .. %#lx\n",
1961 svma + inrw->bias, svma + inrw->bias + size - 1);
1962 TRACE_SYMTAB("acquiring .bss bias = %#lx\n", di->bss_bias);
1963 } else
1964
1965 if (inrw && !di->bss_present) {
1966 di->bss_present = True;
1967 di->bss_svma = svma;
1968 di->bss_avma = svma + inrw->bias;
1969 di->bss_size = size;
1970 di->bss_bias = inrw->bias;
1971 di->bss_debug_svma = svma;
1972 di->bss_debug_bias = inrw->bias;
1973 TRACE_SYMTAB("acquiring .bss svma = %#lx .. %#lx\n",
1974 di->bss_svma,
1975 di->bss_svma + di->bss_size - 1);
1976 TRACE_SYMTAB("acquiring .bss avma = %#lx .. %#lx\n",
1977 di->bss_avma,
1978 di->bss_avma + di->bss_size - 1);
1979 TRACE_SYMTAB("acquiring .bss bias = %#lx\n", di->bss_bias);
1980 } else
1981
1982 /* Now one from the wtf?! department ... */
1983 if (inrx && (!inrw) && !di->bss_present) {
1984 /* File contains a .bss, but it got mapped as rx only.
1985 This is very strange. For now, just pretend we didn't
1986 see it :-) */
1987 di->bss_present = False;
1988 di->bss_svma = 0;
1989 di->bss_avma = 0;
1990 di->bss_size = 0;
1991 di->bss_bias = 0;
1992 di->bss_debug_svma = 0;
1993 di->bss_debug_bias = 0;
1994 if (!VG_(clo_xml)) {
1995 VG_(message)(Vg_UserMsg,
1996 "Warning: the following file's .bss is "
1997 "mapped r-x only - ignoring .bss syms\n");
1998 VG_(message)(Vg_UserMsg, " %s\n", di->fsm.filename
1999 ? di->fsm.filename
2000 : "(null?!)" );
2001 }
2002 } else
2003
2004 if ((!inrw) && (!inrx) && !di->bss_present) {
2005 /* File contains a .bss, but it didn't get mapped. Ignore. */
2006 di->bss_present = False;
2007 di->bss_svma = 0;
2008 di->bss_avma = 0;
2009 di->bss_size = 0;
2010 di->bss_bias = 0;
2011 } else {
2012 BAD(".bss");
2013 }
2014 }
2015
2016 if (0 == VG_(strcmp)(name, ".sdynbss")) {
2017 if (inrw && !di->sbss_present) {
2018 sdynbss_present = True;
2019 di->sbss_present = True;
2020 di->sbss_svma = svma;
2021 di->sbss_avma = svma + inrw->bias;
2022 di->sbss_size = size;
2023 di->sbss_bias = inrw->bias;
2024 di->sbss_debug_svma = svma;
2025 di->sbss_debug_bias = inrw->bias;
2026 TRACE_SYMTAB("acquiring .sdynbss svma = %#lx .. %#lx\n",
2027 di->sbss_svma,
2028 di->sbss_svma + di->sbss_size - 1);
2029 TRACE_SYMTAB("acquiring .sdynbss avma = %#lx .. %#lx\n",
2030 di->sbss_avma,
2031 di->sbss_avma + di->sbss_size - 1);
2032 TRACE_SYMTAB("acquiring .sdynbss bias = %#lx\n", di->sbss_bias);
2033 }
2034 }
2035
2036 /* Accept .sbss where mapped as rw (data) */
2037 if (0 == VG_(strcmp)(name, ".sbss")) {
2038 if (inrw && sdynbss_present) {
2039 vg_assert(di->sbss_present);
2040 sdynbss_present = False;
2041 vg_assert(di->sbss_svma + di->sbss_size == svma);
2042 di->sbss_size += size;
2043 TRACE_SYMTAB("acquiring .sbss svma = %#lx .. %#lx\n",
2044 svma, svma + size - 1);
2045 TRACE_SYMTAB("acquiring .sbss avma = %#lx .. %#lx\n",
2046 svma + inrw->bias, svma + inrw->bias + size - 1);
2047 TRACE_SYMTAB("acquiring .sbss bias = %#lx\n", di->sbss_bias);
2048 } else
2049
2050 if (inrw && !di->sbss_present) {
2051 di->sbss_present = True;
2052 di->sbss_svma = svma;
2053 di->sbss_avma = svma + inrw->bias;
2054 di->sbss_size = size;
2055 di->sbss_bias = inrw->bias;
2056 di->sbss_debug_svma = svma;
2057 di->sbss_debug_bias = inrw->bias;
2058 TRACE_SYMTAB("acquiring .sbss svma = %#lx .. %#lx\n",
2059 di->sbss_svma,
2060 di->sbss_svma + di->sbss_size - 1);
2061 TRACE_SYMTAB("acquiring .sbss avma = %#lx .. %#lx\n",
2062 di->sbss_avma,
2063 di->sbss_avma + di->sbss_size - 1);
2064 TRACE_SYMTAB("acquiring .sbss bias = %#lx\n", di->sbss_bias);
2065 } else {
2066 BAD(".sbss");
2067 }
2068 }
2069
2070 /* Accept .got where mapped as rw (data) */
2071 if (0 == VG_(strcmp)(name, ".got")) {
2072 if (inrw && !di->got_present) {
2073 di->got_present = True;
2074 di->got_avma = svma + inrw->bias;
2075 di->got_size = size;
2076 TRACE_SYMTAB("acquiring .got avma = %#lx\n", di->got_avma);
2077 } else {
2078 BAD(".got");
2079 }
2080 }
2081
2082 /* Accept .got.plt where mapped as rw (data) */
2083 if (0 == VG_(strcmp)(name, ".got.plt")) {
2084 if (inrw && !di->gotplt_present) {
2085 di->gotplt_present = True;
2086 di->gotplt_avma = svma + inrw->bias;
2087 di->gotplt_size = size;
2088 TRACE_SYMTAB("acquiring .got.plt avma = %#lx\n", di->gotplt_avma);
2089 } else if (size != 0) {
2090 BAD(".got.plt");
2091 }
2092 }
2093
2094 /* PLT is different on different platforms, it seems. */
2095 # if defined(VGP_x86_linux) || defined(VGP_amd64_linux) \
2096 || defined(VGP_arm_linux) || defined (VGP_s390x_linux) \
2097 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
2098 || defined(VGP_arm64_linux)
2099 /* Accept .plt where mapped as rx (code) */
2100 if (0 == VG_(strcmp)(name, ".plt")) {
2101 if (inrx && !di->plt_present) {
2102 di->plt_present = True;
2103 di->plt_avma = svma + inrx->bias;
2104 di->plt_size = size;
2105 TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
2106 } else {
2107 BAD(".plt");
2108 }
2109 }
2110 # elif defined(VGP_ppc32_linux)
2111 /* Accept .plt where mapped as rw (data) */
2112 if (0 == VG_(strcmp)(name, ".plt")) {
2113 if (inrw && !di->plt_present) {
2114 di->plt_present = True;
2115 di->plt_avma = svma + inrw->bias;
2116 di->plt_size = size;
2117 TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
2118 } else {
2119 BAD(".plt");
2120 }
2121 }
2122 # elif defined(VGP_ppc64_linux)
2123 /* Accept .plt where mapped as rw (data), or unmapped */
2124 if (0 == VG_(strcmp)(name, ".plt")) {
2125 if (inrw && !di->plt_present) {
2126 di->plt_present = True;
2127 di->plt_avma = svma + inrw->bias;
2128 di->plt_size = size;
2129 TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
2130 } else
2131 if ((!inrw) && (!inrx) && size > 0 && !di->plt_present) {
2132 /* File contains a .plt, but it didn't get mapped.
2133 Presumably it is not required on this platform. At
2134 least don't reject the situation as invalid. */
2135 di->plt_present = True;
2136 di->plt_avma = 0;
2137 di->plt_size = 0;
2138 } else {
2139 BAD(".plt");
2140 }
2141 }
2142 # else
2143 # error "Unsupported platform"
2144 # endif
2145
2146 /* Accept .opd where mapped as rw (data) */
2147 if (0 == VG_(strcmp)(name, ".opd")) {
2148 if (inrw && !di->opd_present) {
2149 di->opd_present = True;
2150 di->opd_avma = svma + inrw->bias;
2151 di->opd_size = size;
2152 TRACE_SYMTAB("acquiring .opd avma = %#lx\n", di->opd_avma);
2153 } else {
2154 BAD(".opd");
2155 }
2156 }
2157
2158 /* Accept .eh_frame where mapped as rx (code). This seems to be
2159 the common case. However, if that doesn't pan out, try for
2160 rw (data) instead. We can handle up to N_EHFRAME_SECTS per
2161 ELF object. */
2162 if (0 == VG_(strcmp)(name, ".eh_frame")) {
2163 if (inrx && di->n_ehframe < N_EHFRAME_SECTS) {
2164 di->ehframe_avma[di->n_ehframe] = svma + inrx->bias;
2165 di->ehframe_size[di->n_ehframe] = size;
2166 TRACE_SYMTAB("acquiring .eh_frame avma = %#lx\n",
2167 di->ehframe_avma[di->n_ehframe]);
2168 di->n_ehframe++;
2169 } else
2170 if (inrw && di->n_ehframe < N_EHFRAME_SECTS) {
2171 di->ehframe_avma[di->n_ehframe] = svma + inrw->bias;
2172 di->ehframe_size[di->n_ehframe] = size;
2173 TRACE_SYMTAB("acquiring .eh_frame avma = %#lx\n",
2174 di->ehframe_avma[di->n_ehframe]);
2175 di->n_ehframe++;
2176 } else {
2177 BAD(".eh_frame");
2178 }
2179 }
2180
2181 ML_(dinfo_free)(name);
2182
2183 # undef BAD
2184
2185 } /* iterate over the section headers */
2186
2187 /* TOPLEVEL */
2188 if (0) VG_(printf)("YYYY text_: avma %#lx size %ld bias %#lx\n",
2189 di->text_avma, di->text_size, di->text_bias);
2190
2191 if (VG_(clo_verbosity) > 2 || VG_(clo_trace_redir))
2192 VG_(message)(Vg_DebugMsg, " svma %#010lx, avma %#010lx\n",
2193 di->text_avma - di->text_bias,
2194 di->text_avma );
2195
2196 TRACE_SYMTAB("\n");
2197 TRACE_SYMTAB("------ Finding image addresses "
2198 "for debug-info sections ------\n");
2199
2200 /* TOPLEVEL */
2201 /* Find interesting sections, read the symbol table(s), read any
2202 debug information. Each section is located either in the main,
2203 debug or alt-debug files, but only in one. For each section,
2204 |section_escn| records which of |mimg|, |dimg| or |aimg| we
2205 found it in, along with the section's image offset and its size.
2206 The triples (section_img, section_ioff, section_szB) are
2207 consistent, in that they are always either (NULL,
2208 DiOffT_INVALID, 0), or refer to the same image, and are all
2209 assigned together. */
2210 {
2211 /* TOPLEVEL */
2212 DiSlice strtab_escn = DiSlice_INVALID; // .strtab
2213 DiSlice symtab_escn = DiSlice_INVALID; // .symtab
2214 DiSlice dynstr_escn = DiSlice_INVALID; // .dynstr
2215 DiSlice dynsym_escn = DiSlice_INVALID; // .dynsym
2216 DiSlice debuglink_escn = DiSlice_INVALID; // .gnu_debuglink
2217 DiSlice debugaltlink_escn = DiSlice_INVALID; // .gnu_debugaltlink
2218 DiSlice stab_escn = DiSlice_INVALID; // .stab (stabs)
2219 DiSlice stabstr_escn = DiSlice_INVALID; // .stabstr (stabs)
2220 DiSlice debug_line_escn = DiSlice_INVALID; // .debug_line (dwarf2)
2221 DiSlice debug_info_escn = DiSlice_INVALID; // .debug_info (dwarf2)
2222 DiSlice debug_types_escn = DiSlice_INVALID; // .debug_types (dwarf4)
2223 DiSlice debug_abbv_escn = DiSlice_INVALID; // .debug_abbrev (dwarf2)
2224 DiSlice debug_str_escn = DiSlice_INVALID; // .debug_str (dwarf2)
2225 DiSlice debug_ranges_escn = DiSlice_INVALID; // .debug_ranges (dwarf2)
2226 DiSlice debug_loc_escn = DiSlice_INVALID; // .debug_loc (dwarf2)
2227 DiSlice debug_frame_escn = DiSlice_INVALID; // .debug_frame (dwarf2)
2228 DiSlice debug_line_alt_escn = DiSlice_INVALID; // .debug_line (alt)
2229 DiSlice debug_info_alt_escn = DiSlice_INVALID; // .debug_info (alt)
2230 DiSlice debug_abbv_alt_escn = DiSlice_INVALID; // .debug_abbrev (alt)
2231 DiSlice debug_str_alt_escn = DiSlice_INVALID; // .debug_str (alt)
2232 DiSlice dwarf1d_escn = DiSlice_INVALID; // .debug (dwarf1)
2233 DiSlice dwarf1l_escn = DiSlice_INVALID; // .line (dwarf1)
2234 DiSlice opd_escn = DiSlice_INVALID; // .opd (dwarf2,
2235 // ppc64-linux)
2236 DiSlice ehframe_escn[N_EHFRAME_SECTS]; // .eh_frame (dwarf2)
2237
2238 for (i = 0; i < N_EHFRAME_SECTS; i++)
2239 ehframe_escn[i] = DiSlice_INVALID;
2240
2241 /* Find all interesting sections */
2242
2243 UInt ehframe_mix = 0;
2244
2245 /* What FIND does: it finds the section called _SEC_NAME. The
2246 size of it is assigned to _SEC_SIZE. The address of the
2247 section in the transiently loaded oimage is assigned to
2248 _SEC_IMG. If the section is found, _POST_FX is executed
2249 after _SEC_NAME and _SEC_SIZE have been assigned to.
2250
2251 Even for sections which are marked loadable, the client's
2252 ld.so may not have loaded them yet, so there is no guarantee
2253 that we can safely prod around in any such area). Because
2254 the entire object file is transiently mapped aboard for
2255 inspection, it's always safe to inspect that area. */
2256
2257 /* TOPLEVEL */
2258 /* Iterate over section headers (again) */
2259 for (i = 0; i < ehdr_m.e_shnum; i++) {
2260
2261 # define FINDX(_sec_name, _sec_escn, _post_fx) \
2262 do { \
2263 ElfXX_Shdr a_shdr; \
2264 ML_(img_get)(&a_shdr, mimg, \
2265 INDEX_BIS(shdr_mioff, i, shdr_ment_szB), \
2266 sizeof(a_shdr)); \
2267 if (0 == ML_(img_strcmp_c)(mimg, shdr_strtab_mioff \
2268 + a_shdr.sh_name, _sec_name)) { \
2269 Bool nobits; \
2270 _sec_escn.img = mimg; \
2271 _sec_escn.ioff = (DiOffT)a_shdr.sh_offset; \
2272 _sec_escn.szB = a_shdr.sh_size; \
2273 nobits = a_shdr.sh_type == SHT_NOBITS; \
2274 vg_assert(_sec_escn.img != NULL); \
2275 vg_assert(_sec_escn.ioff != DiOffT_INVALID); \
2276 TRACE_SYMTAB( "%18s: ioff %llu .. %llu\n", \
2277 _sec_name, (ULong)_sec_escn.ioff, \
2278 ((ULong)_sec_escn.ioff) + _sec_escn.szB - 1); \
2279 /* SHT_NOBITS sections have zero size in the file. */ \
2280 if ( a_shdr.sh_offset \
2281 + (nobits ? 0 : _sec_escn.szB) > ML_(img_size)(mimg) ) { \
2282 ML_(symerr)(di, True, \
2283 " section beyond image end?!"); \
2284 goto out; \
2285 } \
2286 _post_fx; \
2287 } \
2288 } while (0);
2289
2290 /* Version with no post-effects */
2291 # define FIND(_sec_name, _sec_escn) \
2292 FINDX(_sec_name, _sec_escn, /**/)
2293
2294 /* NAME ElfSec */
2295 FIND(".dynsym", dynsym_escn)
2296 FIND(".dynstr", dynstr_escn)
2297 FIND(".symtab", symtab_escn)
2298 FIND(".strtab", strtab_escn)
2299
2300 FIND(".gnu_debuglink", debuglink_escn)
2301 FIND(".gnu_debugaltlink", debugaltlink_escn)
2302
2303 FIND(".stab", stab_escn)
2304 FIND(".stabstr", stabstr_escn)
2305
2306 FIND(".debug_line", debug_line_escn)
2307 FIND(".debug_info", debug_info_escn)
2308 FIND(".debug_types", debug_types_escn)
2309 FIND(".debug_abbrev", debug_abbv_escn)
2310 FIND(".debug_str", debug_str_escn)
2311 FIND(".debug_ranges", debug_ranges_escn)
2312 FIND(".debug_loc", debug_loc_escn)
2313 FIND(".debug_frame", debug_frame_escn)
2314
2315 FIND(".debug", dwarf1d_escn)
2316 FIND(".line", dwarf1l_escn)
2317
2318 FIND(".opd", opd_escn)
2319
2320 FINDX(".eh_frame", ehframe_escn[ehframe_mix],
2321 do { ehframe_mix++; vg_assert(ehframe_mix <= N_EHFRAME_SECTS);
2322 } while (0)
2323 )
2324 /* Comment_on_EH_FRAME_MULTIPLE_INSTANCES: w.r.t. .eh_frame
2325 multi-instance kludgery, how are we assured that the order
2326 in which we fill in ehframe_escn[] is consistent with the
2327 order in which we previously filled in di->ehframe_avma[]
2328 and di->ehframe_size[] ? By the fact that in both cases,
2329 these arrays were filled in by iterating over the section
2330 headers top-to-bottom. So both loops (this one and the
2331 previous one) encounter the .eh_frame entries in the same
2332 order and so fill in these arrays in a consistent order.
2333 */
2334
2335 # undef FINDX
2336 # undef FIND
2337 } /* Iterate over section headers (again) */
2338
2339 /* TOPLEVEL */
2340 /* Now, see if we can find a debuginfo object, and if so connect
2341 |dimg| to it. */
2342 vg_assert(dimg == NULL && aimg == NULL);
2343
2344 /* Look for a build-id */
2345 HChar* buildid = find_buildid(mimg, False, False);
2346
2347 /* Look for a debug image that matches either the build-id or
2348 the debuglink-CRC32 in the main image. If the main image
2349 doesn't contain either of those then this won't even bother
2350 to try looking. This looks in all known places, including
2351 the --extra-debuginfo-path if specified and on the
2352 --debuginfo-server if specified. */
2353 if (buildid != NULL || debuglink_escn.img != NULL) {
2354 /* Do have a debuglink section? */
2355 if (debuglink_escn.img != NULL) {
2356 UInt crc_offset
2357 = VG_ROUNDUP(ML_(img_strlen)(debuglink_escn.img,
2358 debuglink_escn.ioff)+1, 4);
2359 vg_assert(crc_offset + sizeof(UInt) <= debuglink_escn.szB);
2360
2361 /* Extract the CRC from the debuglink section */
2362 UInt crc = ML_(img_get_UInt)(debuglink_escn.img,
2363 debuglink_escn.ioff + crc_offset);
2364
2365 /* See if we can find a matching debug file */
2366 HChar* debuglink_str_m
2367 = ML_(img_strdup)(debuglink_escn.img,
2368 "di.redi_dlk.1", debuglink_escn.ioff);
2369 dimg = find_debug_file( di, di->fsm.filename, buildid,
2370 debuglink_str_m, crc, False );
2371 if (debuglink_str_m)
2372 ML_(dinfo_free)(debuglink_str_m);
2373 } else {
2374 /* See if we can find a matching debug file */
2375 dimg = find_debug_file( di, di->fsm.filename, buildid,
2376 NULL, 0, False );
2377 }
2378 }
2379
2380 if (buildid) {
2381 ML_(dinfo_free)(buildid);
2382 buildid = NULL; /* paranoia */
2383 }
2384
2385 /* As a last-ditch measure, try looking for in the
2386 --extra-debuginfo-path and/or on the --debuginfo-server, but
2387 only in the case where --allow-mismatched-debuginfo=yes.
2388 This is dangerous in that (1) it gives no assurance that the
2389 debuginfo object matches the main one, and hence (2) we will
2390 very likely get an assertion in the code below, if indeed
2391 there is a mismatch. Hence it is disabled by default
2392 (--allow-mismatched-debuginfo=no). Nevertheless it's
2393 sometimes a useful way of getting out of a tight spot.
2394
2395 Note that we're ignoring the name in the .gnu_debuglink
2396 section here, and just looking for a file of the same name
2397 either the extra-path or on the server. */
2398 if (dimg == NULL && VG_(clo_allow_mismatched_debuginfo)) {
2399 dimg = find_debug_file_ad_hoc( di, di->fsm.filename );
2400 }
2401
2402 /* TOPLEVEL */
2403 /* If we were successful in finding a debug image, pull various
2404 SVMA/bias/size and image addresses out of it. */
2405 if (dimg != NULL && is_elf_object_file_by_DiImage(dimg, False)) {
2406
2407 /* Pull out and validate program header and section header info */
2408 DiOffT ehdr_dioff = 0;
2409 ElfXX_Ehdr ehdr_dimg;
2410 ML_(img_get)(&ehdr_dimg, dimg, ehdr_dioff, sizeof(ehdr_dimg));
2411
2412 DiOffT phdr_dioff = ehdr_dimg.e_phoff;
2413 UWord phdr_dnent = ehdr_dimg.e_phnum;
2414 UWord phdr_dent_szB = ehdr_dimg.e_phentsize;
2415
2416 DiOffT shdr_dioff = ehdr_dimg.e_shoff;
2417 UWord shdr_dnent = ehdr_dimg.e_shnum;
2418 UWord shdr_dent_szB = ehdr_dimg.e_shentsize;
2419
2420 DiOffT shdr_strtab_dioff = DiOffT_INVALID;
2421
2422 /* SVMAs covered by rx and rw segments and corresponding bias. */
2423 Addr rx_dsvma_limit = 0;
2424 PtrdiffT rx_dbias = 0;
2425 Addr rw_dsvma_limit = 0;
2426 PtrdiffT rw_dbias = 0;
2427
2428 Bool need_symtab, need_stabs, need_dwarf2, need_dwarf1;
2429
2430 if (phdr_dnent == 0
2431 || !ML_(img_valid)(dimg, phdr_dioff,
2432 phdr_dnent * phdr_dent_szB)) {
2433 ML_(symerr)(di, True,
2434 "Missing or invalid ELF Program Header Table"
2435 " (debuginfo file)");
2436 goto out;
2437 }
2438
2439 if (shdr_dnent == 0
2440 || !ML_(img_valid)(dimg, shdr_dioff,
2441 shdr_dnent * shdr_dent_szB)) {
2442 ML_(symerr)(di, True,
2443 "Missing or invalid ELF Section Header Table"
2444 " (debuginfo file)");
2445 goto out;
2446 }
2447
2448 /* Also find the section header's string table, and validate. */
2449 /* checked previously by is_elf_object_file: */
2450 vg_assert(ehdr_dimg.e_shstrndx != SHN_UNDEF);
2451
2452 // shdr_dioff is the offset of the section header table
2453 // and we need the ehdr_dimg.e_shstrndx'th entry
2454 { ElfXX_Shdr a_shdr;
2455 ML_(img_get)(&a_shdr, dimg,
2456 INDEX_BIS(shdr_dioff, ehdr_dimg.e_shstrndx,
2457 shdr_dent_szB),
2458 sizeof(a_shdr));
2459 shdr_strtab_dioff = a_shdr.sh_offset;
2460 if (!ML_(img_valid)(dimg, shdr_strtab_dioff,
2461 1/*bogus, but we don't know the real size*/)) {
2462 ML_(symerr)(di, True,
2463 "Invalid ELF Section Header String Table"
2464 " (debuginfo file)");
2465 goto out;
2466 }
2467 }
2468
2469 for (i = 0; i < ehdr_dimg.e_phnum; i++) {
2470 ElfXX_Phdr a_phdr;
2471 ML_(img_get)(&a_phdr, dimg, INDEX_BIS(ehdr_dimg.e_phoff,
2472 i, phdr_dent_szB),
2473 sizeof(a_phdr));
2474 if (a_phdr.p_type == PT_LOAD) {
2475 for (j = 0; j < VG_(sizeXA)(di->fsm.maps); j++) {
2476 struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, j);
2477 if ( a_phdr.p_offset >= map->foff
2478 && a_phdr.p_offset < map->foff + map->size
2479 && a_phdr.p_offset + a_phdr.p_filesz
2480 < map->foff + map->size) {
2481 if (map->rx && rx_dsvma_limit == 0) {
2482 rx_dsvma_limit = a_phdr.p_vaddr + a_phdr.p_memsz;
2483 rx_dbias = map->avma - map->foff + a_phdr.p_offset
2484 - a_phdr.p_vaddr;
2485 }
2486 if (map->rw && rw_dsvma_limit == 0) {
2487 rw_dsvma_limit = a_phdr.p_vaddr + a_phdr.p_memsz;
2488 rw_dbias = map->avma - map->foff + a_phdr.p_offset
2489 - a_phdr.p_vaddr;
2490 }
2491 break;
2492 }
2493 }
2494 }
2495 }
2496
2497 need_symtab = (symtab_escn.img == NULL);
2498 need_stabs = (stab_escn.img == NULL);
2499 need_dwarf2 = (debug_info_escn.img == NULL);
2500 need_dwarf1 = (dwarf1d_escn.img == NULL);
2501
2502 /* Find all interesting sections in the debug image */
2503 for (i = 0; i < ehdr_dimg.e_shnum; i++) {
2504
2505 /* Find debug svma and bias information for sections
2506 we found in the main file. */
2507
2508 # define FIND(_sec, _seg) \
2509 do { \
2510 ElfXX_Shdr a_shdr; \
2511 ML_(img_get)(&a_shdr, dimg, \
2512 INDEX_BIS(shdr_dioff, i, shdr_dent_szB), \
2513 sizeof(a_shdr)); \
2514 if (di->_sec##_present \
2515 && 0 == ML_(img_strcmp_c)(dimg, shdr_strtab_dioff \
2516 + a_shdr.sh_name, "." #_sec)) { \
2517 vg_assert(di->_sec##_size == a_shdr.sh_size); \
2518 /* JRS 2013-Jun-01: the following assert doesn't contain */ \
2519 /* any ==s, which seems to me to be suspicious. */ \
2520 vg_assert(di->_sec##_avma + a_shdr.sh_addr + _seg##_dbias); \
2521 /* Assume we have a correct value for the main */ \
2522 /* object's bias. Use that to derive the debuginfo */ \
2523 /* object's bias, by adding the difference in SVMAs */ \
2524 /* for the corresponding sections in the two files. */ \
2525 /* That should take care of all prelinking effects. */ \
2526 di->_sec##_debug_svma = a_shdr.sh_addr; \
2527 di->_sec##_debug_bias \
2528 = di->_sec##_bias + \
2529 di->_sec##_svma - di->_sec##_debug_svma; \
2530 TRACE_SYMTAB("acquiring ." #_sec \
2531 " debug svma = %#lx .. %#lx\n", \
2532 di->_sec##_debug_svma, \
2533 di->_sec##_debug_svma + di->_sec##_size - 1); \
2534 TRACE_SYMTAB("acquiring ." #_sec " debug bias = %#lx\n", \
2535 di->_sec##_debug_bias); \
2536 } \
2537 } while (0);
2538
2539 /* SECTION SEGMENT */
2540 FIND(text, rx)
2541 FIND(data, rw)
2542 FIND(sdata, rw)
2543 FIND(rodata, rw)
2544 FIND(bss, rw)
2545 FIND(sbss, rw)
2546
2547 # undef FIND
2548
2549 /* Same deal as previous FIND, except only do it for those
2550 sections which we didn't find in the main file. */
2551
2552 # define FIND(_condition, _sec_name, _sec_escn) \
2553 do { \
2554 ElfXX_Shdr a_shdr; \
2555 ML_(img_get)(&a_shdr, dimg, \
2556 INDEX_BIS(shdr_dioff, i, shdr_dent_szB), \
2557 sizeof(a_shdr)); \
2558 if (_condition \
2559 && 0 == ML_(img_strcmp_c)(dimg, shdr_strtab_dioff \
2560 + a_shdr.sh_name, _sec_name)) { \
2561 Bool nobits; \
2562 if (_sec_escn.img != NULL) { \
2563 ML_(symerr)(di, True, \
2564 " debuginfo section duplicates a" \
2565 " section in the main ELF file"); \
2566 goto out; \
2567 } \
2568 _sec_escn.img = dimg; \
2569 _sec_escn.ioff = (DiOffT)a_shdr.sh_offset; \
2570 _sec_escn.szB = a_shdr.sh_size; \
2571 nobits = a_shdr.sh_type == SHT_NOBITS; \
2572 vg_assert(_sec_escn.img != NULL); \
2573 vg_assert(_sec_escn.ioff != DiOffT_INVALID); \
2574 TRACE_SYMTAB( "%18s: dioff %llu .. %llu\n", \
2575 _sec_name, \
2576 (ULong)_sec_escn.ioff, \
2577 ((ULong)_sec_escn.ioff) + _sec_escn.szB - 1); \
2578 /* SHT_NOBITS sections have zero size in the file. */ \
2579 if (a_shdr.sh_offset \
2580 + (nobits ? 0 : _sec_escn.szB) > ML_(img_size)(dimg)) { \
2581 ML_(symerr)(di, True, \
2582 " section beyond image end?!"); \
2583 goto out; \
2584 } \
2585 } \
2586 } while (0);
2587
2588 /* NEEDED? NAME ElfSec */
2589 FIND(need_symtab, ".symtab", symtab_escn)
2590 FIND(need_symtab, ".strtab", strtab_escn)
2591 FIND(need_stabs, ".stab", stab_escn)
2592 FIND(need_stabs, ".stabstr", stabstr_escn)
2593 FIND(need_dwarf2, ".debug_line", debug_line_escn)
2594 FIND(need_dwarf2, ".debug_info", debug_info_escn)
2595 FIND(need_dwarf2, ".debug_types", debug_types_escn)
2596
2597 FIND(need_dwarf2, ".debug_abbrev", debug_abbv_escn)
2598 FIND(need_dwarf2, ".debug_str", debug_str_escn)
2599 FIND(need_dwarf2, ".debug_ranges", debug_ranges_escn)
2600
2601 FIND(need_dwarf2, ".debug_loc", debug_loc_escn)
2602 FIND(need_dwarf2, ".debug_frame", debug_frame_escn)
2603
2604 FIND(need_dwarf2, ".gnu_debugaltlink", debugaltlink_escn)
2605
2606 FIND(need_dwarf1, ".debug", dwarf1d_escn)
2607 FIND(need_dwarf1, ".line", dwarf1l_escn)
2608
2609 # undef FIND
2610 } /* Find all interesting sections */
2611 } /* do we have a debug image? */
2612
2613 /* TOPLEVEL */
2614 /* Look for alternate debug image, and if found, connect |aimg|
2615 to it. */
2616 vg_assert(aimg == NULL);
2617
2618 if (debugaltlink_escn.img != NULL) {
2619 UInt buildid_offset = ML_(img_strlen)(debugaltlink_escn.img,
2620 debugaltlink_escn.ioff)+1;
2621
2622 vg_assert(buildid_offset < debugaltlink_escn.szB);
2623
2624 HChar *altbuildid
2625 = ML_(dinfo_zalloc)("di.fbi.4",
2626 (debugaltlink_escn.szB - buildid_offset)
2627 * 2 + 1);
2628
2629 for (j = 0; j < debugaltlink_escn.szB - buildid_offset; j++)
2630 VG_(sprintf)(
2631 altbuildid + 2 * j, "%02x",
2632 (UInt)ML_(img_get_UChar)(debugaltlink_escn.img,
2633 debugaltlink_escn.ioff
2634 + buildid_offset + j));
2635
2636 /* See if we can find a matching debug file */
2637 aimg = find_debug_file( di, di->fsm.filename, altbuildid,
2638 NULL, 0, True );
2639
2640 ML_(dinfo_free)(altbuildid);
2641 }
2642
2643 /* TOPLEVEL */
2644 /* If we were successful in finding alternate debug image, pull various
2645 size and image addresses out of it. */
2646 if (aimg != NULL && is_elf_object_file_by_DiImage(aimg, True)) {
2647
2648 /* Pull out and validate program header and section header info */
2649 DiOffT ehdr_aioff = 0;
2650 ElfXX_Ehdr ehdr_aimg;
2651 ML_(img_get)(&ehdr_aimg, aimg, ehdr_aioff, sizeof(ehdr_aimg));
2652
2653 DiOffT shdr_aioff = ehdr_aimg.e_shoff;
2654 UWord shdr_anent = ehdr_aimg.e_shnum;
2655 UWord shdr_aent_szB = ehdr_aimg.e_shentsize;
2656
2657 DiOffT shdr_strtab_aioff = DiOffT_INVALID;
2658
2659 if (shdr_anent == 0
2660 || !ML_(img_valid)(aimg, shdr_aioff,
2661 shdr_anent * shdr_aent_szB)) {
2662 ML_(symerr)(di, True,
2663 "Missing or invalid ELF Section Header Table"
2664 " (alternate debuginfo file)");
2665 goto out;
2666 }
2667
2668 /* Also find the section header's string table, and validate. */
2669 /* checked previously by is_elf_object_file: */
2670 vg_assert(ehdr_aimg.e_shstrndx != SHN_UNDEF);
2671
2672 // shdr_aioff is the offset of the section header table
2673 // and we need the ehdr_aimg.e_shstrndx'th entry
2674 { ElfXX_Shdr a_shdr;
2675 ML_(img_get)(&a_shdr, aimg,
2676 INDEX_BIS(shdr_aioff, ehdr_aimg.e_shstrndx,
2677 shdr_aent_szB),
2678 sizeof(a_shdr));
2679 shdr_strtab_aioff = a_shdr.sh_offset;
2680 if (!ML_(img_valid)(aimg, shdr_strtab_aioff,
2681 1/*bogus, but we don't know the real size*/)) {
2682 ML_(symerr)(di, True,
2683 "Invalid ELF Section Header String Table"
2684 " (alternate debuginfo file)");
2685 goto out;
2686 }
2687 }
2688
2689 /* Find all interesting sections */
2690 for (i = 0; i < ehdr_aimg.e_shnum; i++) {
2691
2692 # define FIND(_sec_name, _sec_escn) \
2693 do { \
2694 ElfXX_Shdr a_shdr; \
2695 ML_(img_get)(&a_shdr, aimg, \
2696 INDEX_BIS(shdr_aioff, i, shdr_aent_szB), \
2697 sizeof(a_shdr)); \
2698 if (0 == ML_(img_strcmp_c)(aimg, shdr_strtab_aioff \
2699 + a_shdr.sh_name, _sec_name)) { \
2700 if (_sec_escn.img != NULL) { \
2701 ML_(symerr)(di, True, \
2702 " alternate debuginfo section duplicates a" \
2703 " section in the main ELF file"); \
2704 goto out; \
2705 } \
2706 _sec_escn.img = aimg; \
2707 _sec_escn.ioff = (DiOffT)a_shdr.sh_offset; \
2708 _sec_escn.szB = a_shdr.sh_size; \
2709 vg_assert(_sec_escn.img != NULL); \
2710 vg_assert(_sec_escn.ioff != DiOffT_INVALID); \
2711 TRACE_SYMTAB( "%18s: aioff %llu .. %llu\n", \
2712 _sec_name, \
2713 (ULong)_sec_escn.ioff, \
2714 ((ULong)_sec_escn.ioff) + _sec_escn.szB - 1); \
2715 } \
2716 } while (0);
2717
2718 /* NAME ElfSec */
2719 FIND(".debug_line", debug_line_alt_escn)
2720 FIND(".debug_info", debug_info_alt_escn)
2721 FIND(".debug_abbrev", debug_abbv_alt_escn)
2722 FIND(".debug_str", debug_str_alt_escn)
2723
2724 # undef FIND
2725 } /* Find all interesting sections */
2726 } /* do we have a debug image? */
2727
2728
2729 /* TOPLEVEL */
2730 /* Check some sizes */
2731 vg_assert((dynsym_escn.szB % sizeof(ElfXX_Sym)) == 0);
2732 vg_assert((symtab_escn.szB % sizeof(ElfXX_Sym)) == 0);
2733
2734 /* Read symbols */
2735 {
2736 void (*read_elf_symtab)(struct _DebugInfo*, const HChar*,
2737 DiSlice*, DiSlice*, DiSlice*, Bool);
2738 Bool symtab_in_debug;
2739 # if defined(VGP_ppc64_linux)
2740 read_elf_symtab = read_elf_symtab__ppc64_linux;
2741 # else
2742 read_elf_symtab = read_elf_symtab__normal;
2743 # endif
2744 symtab_in_debug = symtab_escn.img == dimg;
2745 read_elf_symtab(di, "symbol table",
2746 &symtab_escn, &strtab_escn, &opd_escn,
2747 symtab_in_debug);
2748 read_elf_symtab(di, "dynamic symbol table",
2749 &dynsym_escn, &dynstr_escn, &opd_escn,
2750 False);
2751 } /* Read symbols */
2752
2753 /* TOPLEVEL */
2754 /* Read .eh_frame and .debug_frame (call-frame-info) if any. Do
2755 the .eh_frame section(s) first. */
2756 vg_assert(di->n_ehframe >= 0 && di->n_ehframe <= N_EHFRAME_SECTS);
2757 for (i = 0; i < di->n_ehframe; i++) {
2758 /* see Comment_on_EH_FRAME_MULTIPLE_INSTANCES above for why
2759 this next assertion should hold. */
2760 vg_assert(ML_(sli_is_valid)(ehframe_escn[i]));
2761 vg_assert(ehframe_escn[i].szB == di->ehframe_size[i]);
2762 ML_(read_callframe_info_dwarf3)( di,
2763 ehframe_escn[i],
2764 di->ehframe_avma[i],
2765 True/*is_ehframe*/ );
2766 }
2767 if (ML_(sli_is_valid)(debug_frame_escn)) {
2768 ML_(read_callframe_info_dwarf3)( di,
2769 debug_frame_escn,
2770 0/*assume zero avma*/,
2771 False/*!is_ehframe*/ );
2772 }
2773
2774 /* Read the stabs and/or dwarf2 debug information, if any. It
2775 appears reading stabs stuff on amd64-linux doesn't work, so
2776 we ignore it. On s390x stabs also doesnt work and we always
2777 have the dwarf info in the eh_frame. We also segfault on
2778 ppc64-linux when reading stabs, so skip that. ppc32-linux
2779 seems OK though. Also skip on Android. */
2780 # if !defined(VGP_amd64_linux) \
2781 && !defined(VGP_s390x_linux) \
2782 && !defined(VGP_ppc64_linux) \
2783 && !defined(VGPV_arm_linux_android) \
2784 && !defined(VGPV_x86_linux_android) \
2785 && !defined(VGP_mips64_linux)
2786 #if 0
2787 if (stab_img && stabstr_img) {
2788 ML_(read_debuginfo_stabs) ( di, stab_img, stab_sz,
2789 stabstr_img, stabstr_sz );
2790 }
2791 #endif
2792 # endif
2793 /* jrs 2006-01-01: icc-8.1 has been observed to generate
2794 binaries without debug_str sections. Don't preclude
2795 debuginfo reading for that reason, but, in
2796 read_unitinfo_dwarf2, do check that debugstr is non-NULL
2797 before using it. */
2798 if (ML_(sli_is_valid)(debug_info_escn)
2799 && ML_(sli_is_valid)(debug_abbv_escn)
2800 && ML_(sli_is_valid)(debug_line_escn)) {
2801 /* The old reader: line numbers and unwind info only */
2802 ML_(read_debuginfo_dwarf3) ( di,
2803 debug_info_escn,
2804 debug_types_escn,
2805 debug_abbv_escn,
2806 debug_line_escn,
2807 debug_str_escn,
2808 debug_str_alt_escn );
2809 /* The new reader: read the DIEs in .debug_info to acquire
2810 information on variable types and locations. But only if
2811 the tool asks for it, or the user requests it on the
2812 command line. */
2813 if (VG_(needs).var_info /* the tool requires it */
2814 || VG_(clo_read_var_info) /* the user asked for it */) {
2815 ML_(new_dwarf3_reader)(
2816 di, debug_info_escn, debug_types_escn,
2817 debug_abbv_escn, debug_line_escn,
2818 debug_str_escn, debug_ranges_escn,
2819 debug_loc_escn, debug_info_alt_escn,
2820 debug_abbv_alt_escn, debug_line_alt_escn,
2821 debug_str_alt_escn
2822 );
2823 }
2824 }
2825 #if 0
2826 if (dwarf1d_img && dwarf1l_img) {
2827 ML_(read_debuginfo_dwarf1) ( di, dwarf1d_img, dwarf1d_sz,
2828 dwarf1l_img, dwarf1l_sz );
2829 }
2830 #endif
2831 /* TOPLEVEL */
2832
2833 } /* "Find interesting sections, read the symbol table(s), read any debug
2834 information" (a local scope) */
2835
2836 /* TOPLEVEL */
2837 res = True;
2838
2839 /* If reading Dwarf3 variable type/location info, print a line
2840 showing the number of variables read for each object.
2841 (Currently disabled -- is a sanity-check mechanism for
2842 exp-sgcheck.) */
2843 if (0 && (VG_(needs).var_info || VG_(clo_read_var_info))) {
2844 UWord nVars = 0;
2845 if (di->varinfo) {
2846 for (j = 0; j < VG_(sizeXA)(di->varinfo); j++) {
2847 OSet* /* of DiAddrRange */ scope
2848 = *(OSet**)VG_(indexXA)(di->varinfo, j);
2849 vg_assert(scope);
2850 VG_(OSetGen_ResetIter)( scope );
2851 while (True) {
2852 DiAddrRange* range = VG_(OSetGen_Next)( scope );
2853 if (!range) break;
2854 vg_assert(range->vars);
2855 Word w = VG_(sizeXA)(range->vars);
2856 vg_assert(w >= 0);
2857 if (0) VG_(printf)("range %#lx %#lx %ld\n",
2858 range->aMin, range->aMax, w);
2859 nVars += (UWord)w;
2860 }
2861 }
2862 }
2863 VG_(umsg)("VARINFO: %7lu vars %7ld text_size %s\n",
2864 nVars, di->text_size, di->fsm.filename);
2865 }
2866 /* TOPLEVEL */
2867
2868 out:
2869 {
2870 /* Last, but not least, detach from the image(s). */
2871 if (mimg) ML_(img_done)(mimg);
2872 if (dimg) ML_(img_done)(dimg);
2873 if (aimg) ML_(img_done)(aimg);
2874
2875 if (svma_ranges) VG_(deleteXA)(svma_ranges);
2876
2877 return res;
2878 } /* out: */
2879
2880 /* NOTREACHED */
2881 }
2882
2883 #endif // defined(VGO_linux)
2884
2885 /*--------------------------------------------------------------------*/
2886 /*--- end ---*/
2887 /*--------------------------------------------------------------------*/
2888