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