2 /*--------------------------------------------------------------------*/
3 /*--- Reading of syms & debug info from ELF .so/executable files. ---*/
5 /*--------------------------------------------------------------------*/
8 This file is part of Valgrind, a dynamic binary instrumentation
11 Copyright (C) 2000-2017 Julian Seward
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License as
16 published by the Free Software Foundation; either version 2 of the
17 License, or (at your option) any later version.
19 This program is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
29 The GNU General Public License is contained in the file COPYING.
32 #if defined(VGO_linux) || defined(VGO_solaris)
34 #include "pub_core_basics.h"
35 #include "pub_core_vki.h"
36 #include "pub_core_vkiscnums.h"
37 #include "pub_core_debuginfo.h"
38 #include "pub_core_libcbase.h"
39 #include "pub_core_libcprint.h"
40 #include "pub_core_libcassert.h"
41 #include "pub_core_machine.h" /* VG_ELF_CLASS */
42 #include "pub_core_options.h"
43 #include "pub_core_oset.h"
44 #include "pub_core_syscall.h"
45 #include "pub_core_tooliface.h" /* VG_(needs) */
46 #include "pub_core_xarray.h"
47 #include "priv_misc.h" /* dinfo_zalloc/free/strdup */
48 #include "priv_image.h"
49 #include "priv_d3basics.h"
50 #include "priv_tytypes.h"
51 #include "priv_storage.h"
52 #include "priv_readelf.h" /* self */
53 #include "priv_readdwarf.h" /* 'cos ELF contains DWARF */
54 #include "priv_readdwarf3.h"
55 #include "priv_readexidx.h"
58 /* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
60 #if defined(VGO_solaris)
61 #include <sys/link.h> /* ElfXX_Dyn, DT_* */
63 /* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
65 #if !defined(HAVE_ELF32_CHDR)
69 Elf32_Word ch_addralign
;
73 #if !defined(HAVE_ELF64_CHDR)
76 Elf64_Word ch_reserved
;
78 Elf64_Xword ch_addralign
;
82 #if !defined(SHF_COMPRESSED)
83 #define SHF_COMPRESSED (1 << 11)
86 #if !defined(ELFCOMPRESS_ZLIB)
87 #define ELFCOMPRESS_ZLIB 1
90 #define SIZE_OF_ZLIB_HEADER 12
92 /*------------------------------------------------------------*/
93 /*--- 32/64-bit parameterisation ---*/
94 /*------------------------------------------------------------*/
96 /* For all the ELF macros and types which specify '32' or '64',
97 select the correct variant for this platform and give it
98 an 'XX' name. Then use the 'XX' variant consistently in
99 the rest of this file.
102 # define ElfXX_Ehdr Elf32_Ehdr
103 # define ElfXX_Shdr Elf32_Shdr
104 # define ElfXX_Phdr Elf32_Phdr
105 # define ElfXX_Nhdr Elf32_Nhdr
106 # define ElfXX_Sym Elf32_Sym
107 # define ElfXX_Off Elf32_Off
108 # define ElfXX_Word Elf32_Word
109 # define ElfXX_Addr Elf32_Addr
110 # define ElfXX_Dyn Elf32_Dyn
111 # define ELFXX_ST_BIND ELF32_ST_BIND
112 # define ELFXX_ST_TYPE ELF32_ST_TYPE
113 # define ElfXX_Chdr Elf32_Chdr
115 #elif VG_WORDSIZE == 8
116 # define ElfXX_Ehdr Elf64_Ehdr
117 # define ElfXX_Shdr Elf64_Shdr
118 # define ElfXX_Phdr Elf64_Phdr
119 # define ElfXX_Nhdr Elf64_Nhdr
120 # define ElfXX_Sym Elf64_Sym
121 # define ElfXX_Off Elf64_Off
122 # define ElfXX_Word Elf64_Word
123 # define ElfXX_Addr Elf64_Addr
124 # define ElfXX_Dyn Elf64_Dyn
125 # define ELFXX_ST_BIND ELF64_ST_BIND
126 # define ELFXX_ST_TYPE ELF64_ST_TYPE
127 # define ElfXX_Chdr Elf64_Chdr
130 # error "VG_WORDSIZE should be 4 or 8"
134 /*------------------------------------------------------------*/
136 /*--- Read symbol table and line info from ELF files. ---*/
138 /*------------------------------------------------------------*/
140 /* readelf.c parses ELF files and acquires symbol table info from
141 them. It calls onwards to readdwarf.c to read DWARF2/3 line number
142 and call frame info found. */
144 /* Identify an ELF object file by peering at the first few bytes of
147 Bool
ML_(is_elf_object_file
)( const void* image
, SizeT n_image
, Bool rel_ok
)
149 const ElfXX_Ehdr
* ehdr
= image
;
152 if (n_image
< sizeof(ElfXX_Ehdr
))
155 ok
&= (ehdr
->e_ident
[EI_MAG0
] == 0x7F
156 && ehdr
->e_ident
[EI_MAG1
] == 'E'
157 && ehdr
->e_ident
[EI_MAG2
] == 'L'
158 && ehdr
->e_ident
[EI_MAG3
] == 'F');
159 ok
&= (ehdr
->e_ident
[EI_CLASS
] == VG_ELF_CLASS
160 && ehdr
->e_ident
[EI_DATA
] == VG_ELF_DATA2XXX
161 && ehdr
->e_ident
[EI_VERSION
] == EV_CURRENT
);
162 ok
&= (ehdr
->e_type
== ET_EXEC
|| ehdr
->e_type
== ET_DYN
163 || (rel_ok
&& ehdr
->e_type
== ET_REL
));
164 ok
&= (ehdr
->e_machine
== VG_ELF_MACHINE
);
165 ok
&= (ehdr
->e_version
== EV_CURRENT
);
166 ok
&= (ehdr
->e_shstrndx
!= SHN_UNDEF
);
167 ok
&= (ehdr
->e_shoff
!= 0 && ehdr
->e_shnum
!= 0);
168 ok
&= ((ehdr
->e_phoff
!= 0 && ehdr
->e_phnum
!= 0)
169 || ehdr
->e_type
== ET_REL
);
171 return ok
? True
: False
;
175 /* The same thing, but operating on a DiImage instead. */
177 static Bool
is_elf_object_file_by_DiImage( DiImage
* img
, Bool rel_ok
)
179 /* Be sure this doesn't make the frame too big. */
180 vg_assert(sizeof(ElfXX_Ehdr
) <= 512);
183 if (!ML_(img_valid
)(img
, 0, sizeof(ehdr
)))
186 ML_(img_get
)(&ehdr
, img
, 0, sizeof(ehdr
));
187 return ML_(is_elf_object_file
)( &ehdr
, sizeof(ehdr
), rel_ok
);
191 /* Show a raw ELF symbol, given its in-image address and name. */
194 void show_raw_elf_symbol ( DiImage
* strtab_img
,
196 const ElfXX_Sym
* sym
,
197 DiOffT sym_name_ioff
, Addr sym_svma
,
198 Bool ppc64_linux_format
)
200 const HChar
* space
= ppc64_linux_format
? " " : "";
201 VG_(printf
)("raw symbol [%4d]: ", i
);
202 switch (ELFXX_ST_BIND(sym
->st_info
)) {
203 case STB_LOCAL
: VG_(printf
)("LOC "); break;
204 case STB_GLOBAL
: VG_(printf
)("GLO "); break;
205 case STB_WEAK
: VG_(printf
)("WEA "); break;
206 case STB_LOPROC
: VG_(printf
)("lop "); break;
207 case STB_HIPROC
: VG_(printf
)("hip "); break;
208 default: VG_(printf
)("??? "); break;
210 switch (ELFXX_ST_TYPE(sym
->st_info
)) {
211 case STT_NOTYPE
: VG_(printf
)("NOT "); break;
212 case STT_OBJECT
: VG_(printf
)("OBJ "); break;
213 case STT_FUNC
: VG_(printf
)("FUN "); break;
214 case STT_SECTION
: VG_(printf
)("SEC "); break;
215 case STT_FILE
: VG_(printf
)("FIL "); break;
216 case STT_LOPROC
: VG_(printf
)("lop "); break;
217 case STT_HIPROC
: VG_(printf
)("hip "); break;
218 default: VG_(printf
)("??? "); break;
220 HChar
* sym_name
= NULL
;
222 sym_name
= ML_(img_strdup
)(strtab_img
, "di.sres.1", sym_name_ioff
);
223 VG_(printf
)(": svma %#010lx, %ssz %4llu %s\n",
224 sym_svma
, space
, (ULong
)(sym
->st_size
+ 0UL),
225 (sym_name
? sym_name
: "NONAME") );
227 ML_(dinfo_free
)(sym_name
);
231 /* Decide whether SYM is something we should collect, and if so, copy
232 relevant info to the _OUT arguments. For {x86,amd64,ppc32}-linux
233 this is straightforward - the name, address, size are copied out
236 There is a bit of a kludge re data symbols (see KLUDGED BSS CHECK
237 below): we assume that the .bss is mapped immediately after .data,
238 and so accept any data symbol which exists in the range [start of
239 .data, size of .data + size of .bss). I don't know if this is
240 really correct/justifiable, or not.
242 For ppc64be-linux it's more complex. If the symbol is seen to be in
243 the .opd section, it is taken to be a function descriptor, and so
244 a dereference is attempted, in order to get hold of the real entry
245 point address. Also as part of the dereference, there is an attempt
246 to calculate the TOC pointer (R2 value) associated with the symbol.
248 To support the ppc64be-linux pre-"dotless" ABI (prior to gcc 4.0.0),
249 if the symbol is seen to be outside the .opd section and its name
250 starts with a dot, an .opd deference is not attempted, and no TOC
251 pointer is calculated, but the leading dot is removed from the
254 As a result, on ppc64be-linux, the caller of this function may have
255 to piece together the real size, address, name of the symbol from
256 multiple calls to this function. Ugly and confusing.
259 Bool
get_elf_symbol_info (
261 struct _DebugInfo
* di
, /* containing DebugInfo */
262 const ElfXX_Sym
* sym
, /* ELF symbol */
263 DiOffT sym_name_ioff
, /* name, may be absent (DiOffT_INVALID) */
264 const DiSlice
* escn_strtab
, /* holds the name */
265 Addr sym_svma
, /* address as stated in the object file */
266 Bool symtab_in_debug
, /* symbol table is in the debug file */
267 const DiSlice
* escn_opd
, /* the .opd (ppc64be-linux only) */
268 PtrdiffT opd_bias
, /* for biasing AVMAs found in .opd */
270 DiOffT
* sym_name_out_ioff
, /* name (in strtab) we should record */
271 SymAVMAs
* sym_avmas_out
, /* sym avmas we should record */
272 Int
* sym_size_out
, /* symbol size */
273 Bool
* from_opd_out
, /* ppc64be-linux only: did we deref an
275 Bool
* is_text_out
, /* is this a text symbol? */
276 Bool
* is_ifunc_out
, /* is this a STT_GNU_IFUNC function ?*/
277 Bool
* is_global_out
/* is this a global symbol ?*/
281 # if defined(VGP_ppc64be_linux)
284 Bool in_text
, in_data
, in_sdata
, in_rodata
, in_bss
, in_sbss
;
285 Addr text_svma
, data_svma
, sdata_svma
, rodata_svma
, bss_svma
, sbss_svma
;
286 PtrdiffT text_bias
, data_bias
, sdata_bias
, rodata_bias
, bss_bias
, sbss_bias
;
287 # if defined(VGPV_arm_linux_android) \
288 || defined(VGPV_x86_linux_android) \
289 || defined(VGPV_mips32_linux_android) \
290 || defined(VGPV_arm64_linux_android)
291 Addr available_size
= 0;
292 #define COMPUTE_AVAILABLE_SIZE(segsvma, segsize) \
293 available_size = segsvma + segsize - sym_svma
295 #define COMPUTE_AVAILABLE_SIZE(segsvma, segsize)
299 *sym_name_out_ioff
= sym_name_ioff
;
300 (*sym_avmas_out
).main
= sym_svma
; /* we will bias this shortly */
302 SET_TOCPTR_AVMA(*sym_avmas_out
, 0); /* default to unknown/inapplicable */
303 SET_LOCAL_EP_AVMA(*sym_avmas_out
, 0); /* default to unknown/inapplicable */
304 *from_opd_out
= False
;
305 *is_ifunc_out
= False
;
306 *is_global_out
= False
;
308 /* Get the symbol size, but restrict it to fit in a signed 32 bit
309 int. Also, deal with the stupid case of negative size by making
310 the size be 1. Note that sym->st_size has type UWord,
312 { Word size_tmp
= (Word
)sym
->st_size
;
313 Word max_Int
= (1LL << 31) - 1;
314 if (size_tmp
< 0) size_tmp
= 1;
315 if (size_tmp
> max_Int
) size_tmp
= max_Int
;
316 *sym_size_out
= (Int
)size_tmp
;
318 /* After this point refer only to *sym_size_out and not to
321 /* Figure out if we're interested in the symbol. Firstly, is it of
322 the right flavour? */
324 = (ELFXX_ST_BIND(sym
->st_info
) == STB_GLOBAL
325 || ELFXX_ST_BIND(sym
->st_info
) == STB_LOCAL
326 || ELFXX_ST_BIND(sym
->st_info
) == STB_WEAK
329 (ELFXX_ST_TYPE(sym
->st_info
) == STT_FUNC
330 || ELFXX_ST_TYPE(sym
->st_info
) == STT_OBJECT
331 # ifdef STT_GNU_IFUNC
332 || ELFXX_ST_TYPE(sym
->st_info
) == STT_GNU_IFUNC
336 /* Work out the svma and bias for each section as it will appear in
337 addresses in the symbol table. */
338 if (symtab_in_debug
) {
339 text_svma
= di
->text_debug_svma
;
340 text_bias
= di
->text_debug_bias
;
341 data_svma
= di
->data_debug_svma
;
342 data_bias
= di
->data_debug_bias
;
343 sdata_svma
= di
->sdata_debug_svma
;
344 sdata_bias
= di
->sdata_debug_bias
;
345 rodata_svma
= di
->rodata_debug_svma
;
346 rodata_bias
= di
->rodata_debug_bias
;
347 bss_svma
= di
->bss_debug_svma
;
348 bss_bias
= di
->bss_debug_bias
;
349 sbss_svma
= di
->sbss_debug_svma
;
350 sbss_bias
= di
->sbss_debug_bias
;
352 text_svma
= di
->text_svma
;
353 text_bias
= di
->text_bias
;
354 data_svma
= di
->data_svma
;
355 data_bias
= di
->data_bias
;
356 sdata_svma
= di
->sdata_svma
;
357 sdata_bias
= di
->sdata_bias
;
358 rodata_svma
= di
->rodata_svma
;
359 rodata_bias
= di
->rodata_bias
;
360 bss_svma
= di
->bss_svma
;
361 bss_bias
= di
->bss_bias
;
362 sbss_svma
= di
->sbss_svma
;
363 sbss_bias
= di
->sbss_bias
;
366 /* Now bias (*sym_avmas_out).main accordingly by figuring out exactly which
367 section the symbol is from and bias accordingly. Screws up if
368 the previously deduced section svma address ranges are wrong. */
371 && sym_svma
>= text_svma
372 && sym_svma
< text_svma
+ di
->text_size
) {
374 (*sym_avmas_out
).main
+= text_bias
;
375 COMPUTE_AVAILABLE_SIZE(text_svma
, di
->text_size
);
379 && sym_svma
>= data_svma
380 && sym_svma
< data_svma
+ di
->data_size
) {
381 *is_text_out
= False
;
382 (*sym_avmas_out
).main
+= data_bias
;
383 COMPUTE_AVAILABLE_SIZE(data_svma
, di
->data_size
);
385 if (di
->sdata_present
386 && di
->sdata_size
> 0
387 && sym_svma
>= sdata_svma
388 && sym_svma
< sdata_svma
+ di
->sdata_size
) {
389 *is_text_out
= False
;
390 (*sym_avmas_out
).main
+= sdata_bias
;
391 COMPUTE_AVAILABLE_SIZE(sdata_svma
, di
->sdata_size
);
393 if (di
->rodata_present
394 && di
->rodata_size
> 0
395 && sym_svma
>= rodata_svma
396 && sym_svma
< rodata_svma
+ di
->rodata_size
) {
397 *is_text_out
= False
;
398 (*sym_avmas_out
).main
+= rodata_bias
;
399 COMPUTE_AVAILABLE_SIZE(rodata_svma
, di
->rodata_size
);
403 && sym_svma
>= bss_svma
404 && sym_svma
< bss_svma
+ di
->bss_size
) {
405 *is_text_out
= False
;
406 (*sym_avmas_out
).main
+= bss_bias
;
407 COMPUTE_AVAILABLE_SIZE(bss_svma
, di
->bss_size
);
411 && sym_svma
>= sbss_svma
412 && sym_svma
< sbss_svma
+ di
->sbss_size
) {
413 *is_text_out
= False
;
414 (*sym_avmas_out
).main
+= sbss_bias
;
415 COMPUTE_AVAILABLE_SIZE(sbss_svma
, di
->sbss_size
);
417 /* Assume it's in .text. Is this a good idea? */
419 (*sym_avmas_out
).main
+= text_bias
;
422 # ifdef STT_GNU_IFUNC
423 /* Check for indirect functions. */
425 && ELFXX_ST_TYPE(sym
->st_info
) == STT_GNU_IFUNC
) {
426 *is_ifunc_out
= True
;
430 if (ELFXX_ST_BIND(sym
->st_info
) == STB_GLOBAL
) {
431 *is_global_out
= True
;
434 # if defined(VGP_ppc64be_linux)
435 /* Allow STT_NOTYPE in the very special case where we're running on
436 ppc64be-linux and the symbol is one which the .opd-chasing hack
440 && ELFXX_ST_TYPE(sym
->st_info
) == STT_NOTYPE
444 && (*sym_avmas_out
).main
>= di
->opd_avma
445 && (*sym_avmas_out
).main
< di
->opd_avma
+ di
->opd_size
)
452 /* Ignore if nameless. */
453 if (sym_name_ioff
== DiOffT_INVALID
454 || /* VG_(strlen)(sym_name) == 0 */
455 /* equivalent but cheaper ... */
456 ML_(img_get_UChar
)(escn_strtab
->img
, sym_name_ioff
) == '\0') {
457 if (TRACE_SYMTAB_ENABLED
) {
458 HChar
* sym_name
= ML_(img_strdup
)(escn_strtab
->img
,
459 "di.gesi.1", sym_name_ioff
);
460 TRACE_SYMTAB(" ignore -- nameless: %s\n", sym_name
);
461 if (sym_name
) ML_(dinfo_free
)(sym_name
);
466 /* Ignore if zero-sized. Except on Android:
468 On Android 2.3.5, some of the symbols that Memcheck needs to
469 intercept (for noise reduction purposes) have zero size, due to
470 lack of .size directives in handwritten assembly sources. So we
471 can't reject them out of hand -- instead give them a bogusly
472 large size and let canonicaliseSymtab trim them so they don't
473 overlap any following symbols. At least the following symbols
474 are known to be affected:
476 in /system/lib/libc.so: strlen strcmp strcpy memcmp memcpy
477 in /system/bin/linker: __dl_strcmp __dl_strlen
479 if (*sym_size_out
== 0) {
480 # if defined(VGPV_arm_linux_android) \
481 || defined(VGPV_x86_linux_android) \
482 || defined(VGPV_mips32_linux_android) \
483 || defined(VGPV_arm64_linux_android)
484 *sym_size_out
= available_size
? available_size
: 2048;
486 if (TRACE_SYMTAB_ENABLED
) {
487 HChar
* sym_name
= ML_(img_strdup
)(escn_strtab
->img
,
488 "di.gesi.2", sym_name_ioff
);
489 TRACE_SYMTAB(" ignore -- size=0: %s\n", sym_name
);
490 if (sym_name
) ML_(dinfo_free
)(sym_name
);
496 /* This seems to significantly reduce the number of junk
497 symbols, and particularly reduces the number of
498 overlapping address ranges. Don't ask me why ... */
499 if ((Int
)sym
->st_value
== 0) {
500 if (TRACE_SYMTAB_ENABLED
) {
501 HChar
* sym_name
= ML_(img_strdup
)(escn_strtab
->img
,
502 "di.gesi.3", sym_name_ioff
);
503 TRACE_SYMTAB( " ignore -- valu=0: %s\n", sym_name
);
504 if (sym_name
) ML_(dinfo_free
)(sym_name
);
509 /* If it's apparently in a GOT or PLT, it's really a reference to a
510 symbol defined elsewhere, so ignore it. */
513 && (*sym_avmas_out
).main
>= di
->got_avma
514 && (*sym_avmas_out
).main
< di
->got_avma
+ di
->got_size
) {
515 if (TRACE_SYMTAB_ENABLED
) {
516 HChar
* sym_name
= ML_(img_strdup
)(escn_strtab
->img
,
517 "di.gesi.4", sym_name_ioff
);
518 TRACE_SYMTAB(" ignore -- in GOT: %s\n", sym_name
);
519 if (sym_name
) ML_(dinfo_free
)(sym_name
);
525 && (*sym_avmas_out
).main
>= di
->plt_avma
526 && (*sym_avmas_out
).main
< di
->plt_avma
+ di
->plt_size
) {
527 if (TRACE_SYMTAB_ENABLED
) {
528 HChar
* sym_name
= ML_(img_strdup
)(escn_strtab
->img
,
529 "di.gesi.5", sym_name_ioff
);
530 TRACE_SYMTAB(" ignore -- in PLT: %s\n", sym_name
);
531 if (sym_name
) ML_(dinfo_free
)(sym_name
);
536 /* ppc64be-linux nasty hack: if the symbol is in an .opd section,
537 then really what we have is the address of a function
538 descriptor. So use the first word of that as the function's
541 See thread starting at
542 http://gcc.gnu.org/ml/gcc-patches/2004-08/msg00557.html
544 # if defined(VGP_ppc64be_linux)
545 /* Host and guest may have different Endianness, used by BE only */
551 && (*sym_avmas_out
).main
>= di
->opd_avma
552 && (*sym_avmas_out
).main
< di
->opd_avma
+ di
->opd_size
) {
553 # if !defined(VGP_ppc64be_linux)
554 if (TRACE_SYMTAB_ENABLED
) {
555 HChar
* sym_name
= ML_(img_strdup
)(escn_strtab
->img
,
556 "di.gesi.6", sym_name_ioff
);
557 TRACE_SYMTAB(" ignore -- in OPD: %s\n", sym_name
);
558 if (sym_name
) ML_(dinfo_free
)(sym_name
);
563 Bool details
= 1||False
;
566 TRACE_SYMTAB("opdXXX: opd_bias %p, sym_svma_out %p\n",
567 (void*)(opd_bias
), (void*)(*sym_avmas_out
).main
);
569 if (!VG_IS_8_ALIGNED((*sym_avmas_out
).main
)) {
570 if (TRACE_SYMTAB_ENABLED
) {
571 HChar
* sym_name
= ML_(img_strdup
)(escn_strtab
->img
,
572 "di.gesi.6a", sym_name_ioff
);
573 TRACE_SYMTAB(" ignore -- not 8-aligned: %s\n", sym_name
);
574 if (sym_name
) ML_(dinfo_free
)(sym_name
);
579 /* (*sym_avmas_out).main is a avma pointing into the .opd section. We
580 know the vma of the opd section start, so we can figure out
581 how far into the opd section this is. */
583 offset_in_opd
= (Addr
)(*sym_avmas_out
).main
- (Addr
)(di
->opd_avma
);
584 if (offset_in_opd
< 0 || offset_in_opd
>= di
->opd_size
) {
585 if (TRACE_SYMTAB_ENABLED
) {
586 HChar
* sym_name
= ML_(img_strdup
)(escn_strtab
->img
,
587 "di.gesi.6a", sym_name_ioff
);
588 TRACE_SYMTAB(" ignore -- invalid OPD offset: %s\n", sym_name
);
589 if (sym_name
) ML_(dinfo_free
)(sym_name
);
594 /* Now we want to know what's at that offset in the .opd
595 section. We can't look in the running image since it won't
596 necessarily have been mapped. But we can consult the oimage.
597 opd_img is the start address of the .opd in the oimage.
600 ULong fn_descr
[2]; /* is actually 3 words, but we need only 2 */
601 if (!ML_(img_valid
)(escn_opd
->img
, escn_opd
->ioff
+ offset_in_opd
,
603 if (TRACE_SYMTAB_ENABLED
) {
604 HChar
* sym_name
= ML_(img_strdup
)(escn_strtab
->img
,
605 "di.gesi.6b", sym_name_ioff
);
606 TRACE_SYMTAB(" ignore -- invalid OPD fn_descr offset: %s\n",
608 if (sym_name
) ML_(dinfo_free
)(sym_name
);
614 /* This can't fail now, because we just checked the offset
616 ML_(img_get
)(&fn_descr
[0], escn_opd
->img
,
617 escn_opd
->ioff
+ offset_in_opd
, sizeof(fn_descr
));
620 TRACE_SYMTAB("opdXXY: offset %d, fn_descr %p\n",
621 offset_in_opd
, fn_descr
);
623 TRACE_SYMTAB("opdXXZ: *fn_descr %p\n", (void*)(fn_descr
[0]));
625 /* opd_bias is the what we have to add to SVMAs found in .opd to
626 get plausible .text AVMAs for the entry point, and .data
627 AVMAs (presumably) for the TOC locations. We use the caller
628 supplied value (which is di->text_bias) for both of these.
629 Not sure why that is correct - it seems to work, and sounds
630 OK for fn_descr[0], but surely we need to use the data bias
631 and not the text bias for fn_descr[1] ? Oh Well.
633 (*sym_avmas_out
).main
= fn_descr
[0] + opd_bias
;
634 SET_TOCPTR_AVMA(*sym_avmas_out
, fn_descr
[1] + opd_bias
);
635 *from_opd_out
= True
;
638 /* Do a final sanity check: if the symbol falls outside the
639 DebugInfo's mapped range, ignore it. Since (*sym_avmas_out).main has
640 been updated, that can be achieved simply by falling through
641 to the test below. */
643 # endif /* ppc64-linux nasty hack */
646 /* Here's yet another ppc64-linux hack. Get rid of leading dot if
647 the symbol is outside .opd. */
648 # if defined(VGP_ppc64be_linux)
651 && *sym_name_out_ioff
!= DiOffT_INVALID
652 && ML_(img_get_UChar
)(escn_strtab
->img
, *sym_name_out_ioff
) == '.') {
653 vg_assert(!(*from_opd_out
));
654 (*sym_name_out_ioff
)++;
658 /* If no part of the symbol falls within the mapped range,
664 && !((*sym_avmas_out
).main
+ *sym_size_out
<= di
->text_avma
665 || (*sym_avmas_out
).main
>= di
->text_avma
+ di
->text_size
);
670 && !((*sym_avmas_out
).main
+ *sym_size_out
<= di
->data_avma
671 || (*sym_avmas_out
).main
>= di
->data_avma
+ di
->data_size
);
675 && di
->sdata_size
> 0
676 && !((*sym_avmas_out
).main
+ *sym_size_out
<= di
->sdata_avma
677 || (*sym_avmas_out
).main
>= di
->sdata_avma
+ di
->sdata_size
);
681 && di
->rodata_size
> 0
682 && !((*sym_avmas_out
).main
+ *sym_size_out
<= di
->rodata_avma
683 || (*sym_avmas_out
).main
>= di
->rodata_avma
+ di
->rodata_size
);
688 && !((*sym_avmas_out
).main
+ *sym_size_out
<= di
->bss_avma
689 || (*sym_avmas_out
).main
>= di
->bss_avma
+ di
->bss_size
);
694 && !((*sym_avmas_out
).main
+ *sym_size_out
<= di
->sbss_avma
695 || (*sym_avmas_out
).main
>= di
->sbss_avma
+ di
->sbss_size
);
699 /* This used to reject any symbol falling outside the text
700 segment ("if (!in_text) ..."). Now it is relaxed slightly,
701 to reject only symbols which fall outside the area mapped
702 r-x. This is in accordance with r7427. See
703 "Comment_Regarding_Text_Range_Checks" in storage.c for
706 vg_assert(di
->fsm
.have_rx_map
);
707 /* This could actually wrap around and cause
708 ML_(find_rx_mapping) to assert. But that seems so unlikely,
709 let's wait for it to happen before fixing it. */
710 in_rx
= (ML_(find_rx_mapping
)(
712 (*sym_avmas_out
).main
,
713 (*sym_avmas_out
).main
+ *sym_size_out
- 1) != NULL
);
718 "ignore -- %#lx .. %#lx outside .text svma range %#lx .. %#lx\n",
719 (*sym_avmas_out
).main
, (*sym_avmas_out
).main
+ *sym_size_out
- 1,
721 di
->text_avma
+ di
->text_size
- 1);
725 if (!(in_data
|| in_sdata
|| in_rodata
|| in_bss
|| in_sbss
)) {
727 "ignore -- %#lx .. %#lx outside .data / .sdata / .rodata "
728 "/ .bss / .sbss svma ranges\n",
729 (*sym_avmas_out
).main
, (*sym_avmas_out
).main
+ *sym_size_out
- 1);
734 # if defined(VGP_ppc64be_linux)
735 if (di
->opd_present
&& di
->opd_size
> 0) {
736 vg_assert((*sym_avmas_out
).main
+ *sym_size_out
<= di
->opd_avma
737 || (*sym_avmas_out
).main
>= di
->opd_avma
+ di
->opd_size
);
741 # if defined(VGP_ppc64le_linux)
742 /* PPC64 LE ABI uses three bits in the st_other field to indicate the number
743 * of instructions between the function's global and local entry points. An
744 * offset of 0 indicates that there is one entry point. The value must be:
746 * 0 - one entry point, local and global are the same
748 * 2 - local entry point is one instruction after the global entry point
749 * 3 - local entry point is two instructions after the global entry point
750 * 4 - local entry point is four instructions after the global entry point
751 * 5 - local entry point is eight instructions after the global entry point
752 * 6 - local entry point is sixteen instructions after the global entry point
755 * Extract the three bit field from the other field is done by:
756 * (other_field & STO_PPC64_LOCAL_MASK) >> STO_PPC_LOCAL_BIT
758 * where the #define values are given in include/elf/powerpc.h file for
761 * conversion of the three bit field to bytes is given by
763 * ((1 << bit_field) >> 2) << 2
766 #define STO_PPC64_LOCAL_BIT 5
767 #define STO_PPC64_LOCAL_MASK (7 << STO_PPC64_LOCAL_BIT)
769 unsigned int bit_field
, dist_to_local_entry
;
770 /* extract the other filed */
771 bit_field
= (sym
->st_other
& STO_PPC64_LOCAL_MASK
) >> STO_PPC64_LOCAL_BIT
;
773 if ((bit_field
> 0) && (bit_field
< 7)) {
774 /* store the local entry point address */
775 dist_to_local_entry
= ((1 << bit_field
) >> 2) << 2;
776 SET_LOCAL_EP_AVMA(*sym_avmas_out
,
777 (*sym_avmas_out
).main
+ dist_to_local_entry
);
779 if (TRACE_SYMTAB_ENABLED
) {
780 HChar
* sym_name
= ML_(img_strdup
)(escn_strtab
->img
,
781 "di.gesi.5", sym_name_ioff
);
782 VG_(printf
)("Local entry point: %s at %#010x\n",
784 (unsigned int)GET_LOCAL_EP_AVMA(*sym_avmas_out
));
795 /* Read an ELF symbol table (normal or dynamic). This one is for the
796 "normal" case ({x86,amd64,ppc32,arm,mips32,mips64, ppc64le}-linux). */
798 __attribute__((unused
)) /* not referred to on all targets */
799 void read_elf_symtab__normal(
800 struct _DebugInfo
* di
, const HChar
* tab_name
,
801 DiSlice
* escn_symtab
,
802 DiSlice
* escn_strtab
,
803 DiSlice
* escn_opd
, /* ppc64be-linux only */
807 if (escn_strtab
->img
== NULL
|| escn_symtab
->img
== NULL
) {
808 HChar buf
[VG_(strlen
)(tab_name
) + 40];
809 VG_(sprintf
)(buf
, " object doesn't have a %s", tab_name
);
810 ML_(symerr
)(di
, False
, buf
);
814 TRACE_SYMTAB("\n--- Reading (ELF, standard) %s (%llu entries) ---\n",
815 tab_name
, escn_symtab
->szB
/sizeof(ElfXX_Sym
) );
817 /* Perhaps should start at i = 1; ELF docs suggest that entry
818 0 always denotes 'unknown symbol'. */
820 for (i
= 1; i
< (Word
)(escn_symtab
->szB
/sizeof(ElfXX_Sym
)); i
++) {
822 ML_(img_get
)(&sym
, escn_symtab
->img
,
823 escn_symtab
->ioff
+ i
* sizeof(ElfXX_Sym
), sizeof(sym
));
824 DiOffT sym_name
= escn_strtab
->ioff
+ sym
.st_name
;
825 Addr sym_svma
= sym
.st_value
;
827 if (di
->trace_symtab
)
828 show_raw_elf_symbol(escn_strtab
->img
, i
,
829 &sym
, sym_name
, sym_svma
, False
);
831 SymAVMAs sym_avmas_really
;
833 Bool from_opd
= False
, is_text
= False
, is_ifunc
= False
;
834 Bool is_global
= False
;
835 DiOffT sym_name_really
= DiOffT_INVALID
;
836 sym_avmas_really
.main
= 0;
837 SET_TOCPTR_AVMA(sym_avmas_really
, 0);
838 SET_LOCAL_EP_AVMA(sym_avmas_really
, 0);
839 if (get_elf_symbol_info(di
, &sym
, sym_name
, escn_strtab
,
840 sym_svma
, symtab_in_debug
,
841 escn_opd
, di
->text_bias
,
845 &from_opd
, &is_text
, &is_ifunc
, &is_global
)) {
848 VG_(memset
)(&disym
, 0, sizeof(disym
));
849 HChar
* cstr
= ML_(img_strdup
)(escn_strtab
->img
,
850 "di.res__n.1", sym_name_really
);
851 disym
.avmas
= sym_avmas_really
;
852 disym
.pri_name
= ML_(addStr
) ( di
, cstr
, -1 );
853 disym
.sec_names
= NULL
;
854 disym
.size
= sym_size
;
855 disym
.isText
= is_text
;
856 disym
.isIFunc
= is_ifunc
;
857 disym
.isGlobal
= is_global
;
858 if (cstr
) { ML_(dinfo_free
)(cstr
); cstr
= NULL
; }
859 vg_assert(disym
.pri_name
);
860 vg_assert(GET_TOCPTR_AVMA(disym
.avmas
) == 0);
861 /* has no role except on ppc64be-linux */
862 ML_(addSym
) ( di
, &disym
);
864 if (TRACE_SYMTAB_ENABLED
) {
865 TRACE_SYMTAB(" rec(%c) [%4ld]: "
866 " val %#010lx, sz %4d %s\n",
873 if (GET_LOCAL_EP_AVMA(disym
.avmas
) != 0) {
874 TRACE_SYMTAB(" local entry point %#010lx\n",
875 GET_LOCAL_EP_AVMA(disym
.avmas
));
884 /* Read an ELF symbol table (normal or dynamic). This one is for
885 ppc64be-linux, which requires special treatment. */
891 /* We have to store also the DiImage* so as to give context for
892 |name|. This is not part of the key (in terms of lookup) but
893 there's no easy other way to do this. Ugly. */
910 static Word
cmp_TempSymKey ( const TempSymKey
* key1
, const TempSym
* elem2
)
913 vg_assert(key1
->img
== elem2
->key
.img
);
914 vg_assert(key1
->img
!= NULL
);
915 if (key1
->addr
< elem2
->key
.addr
) return -1;
916 if (key1
->addr
> elem2
->key
.addr
) return 1;
917 vg_assert(key1
->name
!= DiOffT_INVALID
);
918 vg_assert(elem2
->key
.name
!= DiOffT_INVALID
);
919 return (Word
)ML_(img_strcmp
)(key1
->img
, key1
->name
, elem2
->key
.name
);
923 __attribute__((unused
)) /* not referred to on all targets */
924 void read_elf_symtab__ppc64be_linux(
925 struct _DebugInfo
* di
, const HChar
* tab_name
,
926 DiSlice
* escn_symtab
,
927 DiSlice
* escn_strtab
,
928 DiSlice
* escn_opd
, /* ppc64be-linux only */
934 Bool modify_size
, modify_tocptr
;
940 if (escn_strtab
->img
== NULL
|| escn_symtab
->img
== NULL
) {
941 HChar buf
[VG_(strlen
)(tab_name
) + 40];
942 VG_(sprintf
)(buf
, " object doesn't have a %s", tab_name
);
943 ML_(symerr
)(di
, False
, buf
);
947 TRACE_SYMTAB("\n--- Reading (ELF, ppc64be-linux) %s (%llu entries) ---\n",
948 tab_name
, escn_symtab
->szB
/sizeof(ElfXX_Sym
) );
950 oset
= VG_(OSetGen_Create
)( offsetof(TempSym
,key
),
951 (OSetCmp_t
)cmp_TempSymKey
,
952 ML_(dinfo_zalloc
), "di.respl.1",
955 /* Perhaps should start at i = 1; ELF docs suggest that entry
956 0 always denotes 'unknown symbol'. */
957 for (i
= 1; i
< (Word
)(escn_symtab
->szB
/sizeof(ElfXX_Sym
)); i
++) {
959 ML_(img_get
)(&sym
, escn_symtab
->img
,
960 escn_symtab
->ioff
+ i
* sizeof(ElfXX_Sym
), sizeof(sym
));
961 DiOffT sym_name
= escn_strtab
->ioff
+ sym
.st_name
;
962 Addr sym_svma
= sym
.st_value
;
964 if (di
->trace_symtab
)
965 show_raw_elf_symbol(escn_strtab
->img
, i
,
966 &sym
, sym_name
, sym_svma
, True
);
968 SymAVMAs sym_avmas_really
;
970 Bool from_opd
= False
, is_text
= False
, is_ifunc
= False
;
971 Bool is_global
= False
;
972 DiOffT sym_name_really
= DiOffT_INVALID
;
974 VG_(memset
)(&disym
, 0, sizeof(disym
));
975 sym_avmas_really
.main
= 0;
976 SET_TOCPTR_AVMA(sym_avmas_really
, 0);
977 SET_LOCAL_EP_AVMA(sym_avmas_really
, 0);
978 if (get_elf_symbol_info(di
, &sym
, sym_name
, escn_strtab
,
979 sym_svma
, symtab_in_debug
,
980 escn_opd
, di
->text_bias
,
984 &from_opd
, &is_text
, &is_ifunc
, &is_global
)) {
986 /* Check if we've seen this (name,addr) key before. */
987 key
.addr
= sym_avmas_really
.main
;
988 key
.name
= sym_name_really
;
989 key
.img
= escn_strtab
->img
;
990 prev
= VG_(OSetGen_Lookup
)( oset
, &key
);
994 /* Seen it before. Fold in whatever new info we can. */
996 modify_tocptr
= False
;
999 if (prev
->from_opd
&& !from_opd
1000 && (prev
->size
== 24 || prev
->size
== 16)
1001 && sym_size
!= prev
->size
) {
1002 /* Existing one is an opd-redirect, with a bogus size,
1003 so the only useful new fact we have is the real size
1006 old_size
= prev
->size
;
1007 prev
->size
= sym_size
;
1010 if (!prev
->from_opd
&& from_opd
1011 && (sym_size
== 24 || sym_size
== 16)) {
1012 /* Existing one is non-opd, new one is opd. What we
1013 can acquire from the new one is the TOC ptr to be
1014 used. Since the existing sym is non-toc, it
1015 shouldn't currently have an known TOC ptr. */
1016 vg_assert(prev
->tocptr
== 0);
1017 modify_tocptr
= True
;
1018 prev
->tocptr
= GET_TOCPTR_AVMA(sym_avmas_really
);
1021 /* ignore. can we do better here? */
1024 /* Only one or the other is possible (I think) */
1025 vg_assert(!(modify_size
&& modify_tocptr
));
1027 if (modify_size
&& di
->trace_symtab
) {
1028 VG_(printf
)(" modify (old sz %4d) "
1029 " val %#010lx, toc %#010lx, sz %4d %llu\n",
1037 if (modify_tocptr
&& di
->trace_symtab
) {
1038 VG_(printf
)(" modify (upd tocptr) "
1039 " val %#010lx, toc %#010lx, sz %4d %llu\n",
1049 /* A new (name,addr) key. Add and continue. */
1050 elem
= VG_(OSetGen_AllocNode
)(oset
, sizeof(TempSym
));
1052 elem
->tocptr
= GET_TOCPTR_AVMA(sym_avmas_really
);
1053 elem
->size
= sym_size
;
1054 elem
->from_opd
= from_opd
;
1055 elem
->is_text
= is_text
;
1056 elem
->is_ifunc
= is_ifunc
;
1057 elem
->is_global
= is_global
;
1058 VG_(OSetGen_Insert
)(oset
, elem
);
1059 if (di
->trace_symtab
) {
1060 HChar
* str
= ML_(img_strdup
)(escn_strtab
->img
, "di.respl.2",
1062 VG_(printf
)(" to-oset [%4ld]: "
1063 " val %#010lx, toc %#010lx, sz %4d %s\n",
1070 if (str
) ML_(dinfo_free
)(str
);
1077 /* All the syms that matter are in the oset. Now pull them out,
1078 build a "standard" symbol table, and nuke the oset. */
1081 VG_(OSetGen_ResetIter
)( oset
);
1083 while ( (elem
= VG_(OSetGen_Next
)(oset
)) ) {
1085 VG_(memset
)(&disym
, 0, sizeof(disym
));
1086 HChar
* cstr
= ML_(img_strdup
)(escn_strtab
->img
,
1087 "di.res__ppc64.1", elem
->key
.name
);
1088 disym
.avmas
.main
= elem
->key
.addr
;
1089 SET_TOCPTR_AVMA(disym
.avmas
, elem
->tocptr
);
1090 SET_LOCAL_EP_AVMA(disym
.avmas
, 0); // ppc64be does not use local_ep.
1091 disym
.pri_name
= ML_(addStr
) ( di
, cstr
, -1 );
1092 disym
.sec_names
= NULL
;
1093 disym
.size
= elem
->size
;
1094 disym
.isText
= elem
->is_text
;
1095 disym
.isIFunc
= elem
->is_ifunc
;
1096 disym
.isGlobal
= elem
->is_global
;
1097 if (cstr
) { ML_(dinfo_free
)(cstr
); cstr
= NULL
; }
1098 vg_assert(disym
.pri_name
!= NULL
);
1100 ML_(addSym
) ( di
, &disym
);
1101 if (di
->trace_symtab
) {
1102 VG_(printf
)(" rec(%c%c%c) [%4ld]: "
1103 " val %#010lx, toc %#010lx, sz %4d %s\n",
1104 disym
.isText
? 't' : 'd',
1105 disym
.isIFunc
? 'i' : '-',
1106 disym
.isGlobal
? 'g' : 'l',
1109 GET_TOCPTR_AVMA(disym
.avmas
),
1117 VG_(OSetGen_Destroy
)( oset
);
1122 * Look for a build-id in an ELF image. The build-id specification
1123 * can be found here:
1125 * http://fedoraproject.org/wiki/RolandMcGrath/BuildID
1127 * Returned string must be freed by the caller.
1130 HChar
* find_buildid(DiImage
* img
, Bool rel_ok
, Bool search_shdrs
)
1132 HChar
* buildid
= NULL
;
1134 # ifdef NT_GNU_BUILD_ID
1135 if (is_elf_object_file_by_DiImage(img
, rel_ok
)) {
1139 ML_(img_get
)(&ehdr
, img
, 0, sizeof(ehdr
));
1140 for (i
= 0; i
< ehdr
.e_phnum
; i
++) {
1142 ML_(img_get
)(&phdr
, img
,
1143 ehdr
.e_phoff
+ i
* ehdr
.e_phentsize
, sizeof(phdr
));
1145 if (phdr
.p_type
== PT_NOTE
) {
1146 ElfXX_Off note_ioff
= phdr
.p_offset
;
1148 while (note_ioff
< phdr
.p_offset
+ phdr
.p_filesz
) {
1150 ML_(img_get
)(¬e
, img
, (DiOffT
)note_ioff
, sizeof(note
));
1151 DiOffT name_ioff
= note_ioff
+ sizeof(ElfXX_Nhdr
);
1152 DiOffT desc_ioff
= name_ioff
+ ((note
.n_namesz
+ 3) & ~3);
1153 if (ML_(img_strcmp_c
)(img
, name_ioff
, ELF_NOTE_GNU
) == 0
1154 && note
.n_type
== NT_GNU_BUILD_ID
) {
1155 buildid
= ML_(dinfo_zalloc
)("di.fbi.1",
1156 note
.n_descsz
* 2 + 1);
1158 for (j
= 0; j
< note
.n_descsz
; j
++) {
1159 UChar desc_j
= ML_(img_get_UChar
)(img
, desc_ioff
+ j
);
1160 VG_(sprintf
)(buildid
+ VG_(strlen
)(buildid
),
1161 "%02x", (UInt
)desc_j
);
1165 note_ioff
= note_ioff
+ sizeof(ElfXX_Nhdr
)
1166 + ((note
.n_namesz
+ 3) & ~3)
1167 + ((note
.n_descsz
+ 3) & ~3);
1172 /* Normally we would only search shdrs for ET_REL files, but when
1173 we search for a separate .debug file phdrs might not be there
1174 (they are never loaded) or have been corrupted, so try again
1176 if (buildid
|| (!rel_ok
&& !search_shdrs
))
1179 for (i
= 0; i
< ehdr
.e_shnum
; i
++) {
1181 ML_(img_get
)(&shdr
, img
,
1182 ehdr
.e_shoff
+ i
* ehdr
.e_shentsize
, sizeof(shdr
));
1184 if (shdr
.sh_type
== SHT_NOTE
) {
1185 ElfXX_Off note_ioff
= shdr
.sh_offset
;
1187 while (note_ioff
< shdr
.sh_offset
+ shdr
.sh_size
) {
1189 ML_(img_get
)(¬e
, img
, (DiOffT
)note_ioff
, sizeof(note
));
1190 DiOffT name_ioff
= note_ioff
+ sizeof(ElfXX_Nhdr
);
1191 DiOffT desc_ioff
= name_ioff
+ ((note
.n_namesz
+ 3) & ~3);
1193 if (ML_(img_strcmp_c
)(img
, name_ioff
, ELF_NOTE_GNU
) == 0
1194 && note
.n_type
== NT_GNU_BUILD_ID
) {
1195 buildid
= ML_(dinfo_zalloc
)("di.fbi.2",
1196 note
.n_descsz
* 2 + 1);
1198 for (j
= 0; j
< note
.n_descsz
; j
++) {
1199 UChar desc_j
= ML_(img_get_UChar
)(img
, desc_ioff
+ j
);
1200 VG_(sprintf
)(buildid
+ VG_(strlen
)(buildid
),
1201 "%02x", (UInt
)desc_j
);
1205 note_ioff
= note_ioff
+ sizeof(ElfXX_Nhdr
)
1206 + ((note
.n_namesz
+ 3) & ~3)
1207 + ((note
.n_descsz
+ 3) & ~3);
1212 # endif /* def NT_GNU_BUILD_ID */
1218 /* Try and open a separate debug file, ignoring any where the CRC does
1219 not match the value from the main object file. Returned DiImage
1220 must be discarded by the caller.
1222 If |serverAddr| is NULL, |name| is expected to be a fully qualified
1223 (absolute) path to the file in the local filesystem. If
1224 |serverAddr| is non-NULL, it is expected to be an IPv4 and port
1225 spec of the form "d.d.d.d:d" or "d.d.d.d", and |name| is expected
1226 to be a plain filename (no path components at all).
1229 DiImage
* open_debug_file( const HChar
* name
, const HChar
* buildid
, UInt crc
,
1230 Bool rel_ok
, const HChar
* serverAddr
)
1233 = serverAddr
? ML_(img_from_di_server
)(name
, serverAddr
)
1234 : ML_(img_from_local_file
)(name
);
1238 if (VG_(clo_verbosity
) > 1) {
1240 VG_(message
)(Vg_DebugMsg
, " Considering %s on server %s ..\n",
1243 VG_(message
)(Vg_DebugMsg
, " Considering %s ..\n", name
);
1246 /* We will always check the crc if we have one (altfiles don't have one)
1247 for now because we might be opening the main file again by any other
1248 name, and that obviously also has the same buildid. More efficient
1249 would be an fstat bases check or a check that the file actually
1250 contains .debug* sections. */
1251 if (buildid
&& crc
== 0) {
1252 HChar
* debug_buildid
= find_buildid(dimg
, rel_ok
, True
);
1253 if (debug_buildid
== NULL
|| VG_(strcmp
)(buildid
, debug_buildid
) != 0) {
1254 ML_(img_done
)(dimg
);
1255 if (VG_(clo_verbosity
) > 1)
1256 VG_(message
)(Vg_DebugMsg
,
1257 " .. build-id mismatch (found %s wanted %s)\n",
1258 debug_buildid
, buildid
);
1259 ML_(dinfo_free
)(debug_buildid
);
1262 ML_(dinfo_free
)(debug_buildid
);
1263 if (VG_(clo_verbosity
) > 1)
1264 VG_(message
)(Vg_DebugMsg
, " .. build-id is valid\n");
1266 UInt calccrc
= ML_(img_calc_gnu_debuglink_crc32
)(dimg
);
1267 if (calccrc
!= crc
) {
1268 ML_(img_done
)(dimg
);
1269 if (VG_(clo_verbosity
) > 1)
1270 VG_(message
)(Vg_DebugMsg
,
1271 " .. CRC mismatch (computed %08x wanted %08x)\n", calccrc
, crc
);
1275 if (VG_(clo_verbosity
) > 1)
1276 VG_(message
)(Vg_DebugMsg
, " .. CRC is valid\n");
1283 /* Try to find a separate debug file for a given object file. If
1284 found, return its DiImage, which should be freed by the caller. If
1285 |buildid| is non-NULL, then a debug object matching it is
1286 acceptable. If |buildid| is NULL or doesn't specify a findable
1287 debug object, then we look in various places to find a file with
1288 the specified CRC. And if that doesn't work out then we give
1291 DiImage
* find_debug_file( struct _DebugInfo
* di
,
1292 const HChar
* objpath
, const HChar
* buildid
,
1293 const HChar
* debugname
, UInt crc
, Bool rel_ok
)
1295 const HChar
* extrapath
= VG_(clo_extra_debuginfo_path
);
1296 const HChar
* serverpath
= VG_(clo_debuginfo_server
);
1298 DiImage
* dimg
= NULL
; /* the img that we found */
1299 HChar
* debugpath
= NULL
; /* where we found it */
1301 if (buildid
!= NULL
) {
1302 debugpath
= ML_(dinfo_zalloc
)("di.fdf.1",
1303 VG_(strlen
)(buildid
) + 33);
1305 VG_(sprintf
)(debugpath
, "/usr/lib/debug/.build-id/%c%c/%s.debug",
1306 buildid
[0], buildid
[1], buildid
+ 2);
1308 dimg
= open_debug_file(debugpath
, buildid
, 0, rel_ok
, NULL
);
1310 ML_(dinfo_free
)(debugpath
);
1315 if (dimg
== NULL
&& debugname
!= NULL
) {
1316 HChar
*objdir
= ML_(dinfo_strdup
)("di.fdf.2", objpath
);
1319 if ((objdirptr
= VG_(strrchr
)(objdir
, '/')) != NULL
)
1322 debugpath
= ML_(dinfo_zalloc
)(
1324 VG_(strlen
)(objdir
) + VG_(strlen
)(debugname
) + 64
1325 + (extrapath
? VG_(strlen
)(extrapath
) : 0)
1326 + (serverpath
? VG_(strlen
)(serverpath
) : 0));
1328 if (debugname
[0] == '/') {
1329 VG_(sprintf
)(debugpath
, "%s", debugname
);
1330 dimg
= open_debug_file(debugpath
, buildid
, crc
, rel_ok
, NULL
);
1331 if (dimg
!= NULL
) goto dimg_ok
;
1334 VG_(sprintf
)(debugpath
, "%s/%s", objdir
, debugname
);
1335 dimg
= open_debug_file(debugpath
, buildid
, crc
, rel_ok
, NULL
);
1336 if (dimg
!= NULL
) goto dimg_ok
;
1338 VG_(sprintf
)(debugpath
, "%s/.debug/%s", objdir
, debugname
);
1339 dimg
= open_debug_file(debugpath
, buildid
, crc
, rel_ok
, NULL
);
1340 if (dimg
!= NULL
) goto dimg_ok
;
1342 VG_(sprintf
)(debugpath
, "/usr/lib/debug%s/%s", objdir
, debugname
);
1343 dimg
= open_debug_file(debugpath
, buildid
, crc
, rel_ok
, NULL
);
1344 if (dimg
!= NULL
) goto dimg_ok
;
1347 VG_(sprintf
)(debugpath
, "%s%s/%s", extrapath
,
1349 dimg
= open_debug_file(debugpath
, buildid
, crc
, rel_ok
, NULL
);
1350 if (dimg
!= NULL
) goto dimg_ok
;
1354 /* When looking on the debuginfo server, always just pass the
1356 const HChar
* basename
= debugname
;
1357 if (VG_(strstr
)(basename
, "/") != NULL
) {
1358 basename
= VG_(strrchr
)(basename
, '/') + 1;
1360 VG_(sprintf
)(debugpath
, "%s on %s", basename
, serverpath
);
1361 dimg
= open_debug_file(basename
, buildid
, crc
, rel_ok
, serverpath
);
1362 if (dimg
) goto dimg_ok
;
1367 ML_(dinfo_free
)(objdir
);
1371 vg_assert(debugpath
);
1373 TRACE_SYMTAB("------ Found a debuginfo file: %s\n", debugpath
);
1375 /* Only set once, we might be called again for opening the altfile. */
1376 if (di
->fsm
.dbgname
== NULL
)
1377 di
->fsm
.dbgname
= ML_(dinfo_strdup
)("di.fdf.4", debugpath
);
1381 ML_(dinfo_free
)(debugpath
);
1387 /* Try to find a separate debug file for a given object file, in a
1388 hacky and dangerous way: check only the --extra-debuginfo-path and
1389 the --debuginfo-server. And don't do a consistency check. */
1391 DiImage
* find_debug_file_ad_hoc( const DebugInfo
* di
,
1392 const HChar
* objpath
)
1394 const HChar
* extrapath
= VG_(clo_extra_debuginfo_path
);
1395 const HChar
* serverpath
= VG_(clo_debuginfo_server
);
1397 DiImage
* dimg
= NULL
; /* the img that we found */
1398 HChar
* debugpath
= NULL
; /* where we found it */
1400 HChar
*objdir
= ML_(dinfo_strdup
)("di.fdfah.1", objpath
);
1403 if ((objdirptr
= VG_(strrchr
)(objdir
, '/')) != NULL
)
1406 debugpath
= ML_(dinfo_zalloc
)(
1408 VG_(strlen
)(objdir
) + 64
1409 + (extrapath
? VG_(strlen
)(extrapath
) : 0)
1410 + (serverpath
? VG_(strlen
)(serverpath
) : 0));
1413 VG_(sprintf
)(debugpath
, "%s/%s", extrapath
, objpath
);
1414 dimg
= ML_(img_from_local_file
)(debugpath
);
1416 if (VG_(clo_verbosity
) > 1) {
1417 VG_(message
)(Vg_DebugMsg
, " Using (POSSIBLY MISMATCHED) %s\n",
1424 /* When looking on the debuginfo server, always just pass the
1426 const HChar
* basename
= objpath
;
1427 if (VG_(strstr
)(basename
, "/") != NULL
) {
1428 basename
= VG_(strrchr
)(basename
, '/') + 1;
1430 VG_(sprintf
)(debugpath
, "%s on %s", basename
, serverpath
);
1431 dimg
= ML_(img_from_di_server
)(basename
, serverpath
);
1433 if (VG_(clo_verbosity
) > 1) {
1434 VG_(message
)(Vg_DebugMsg
, " Using (POSSIBLY MISMATCHED) %s\n",
1443 ML_(dinfo_free
)(objdir
);
1446 vg_assert(debugpath
);
1448 TRACE_SYMTAB("------ Found an ad_hoc debuginfo file: %s\n", debugpath
);
1452 ML_(dinfo_free
)(debugpath
);
1458 static DiOffT
INDEX_BIS ( DiOffT base
, UWord idx
, UWord scale
) {
1459 // This is a bit stupid. Really, idx and scale ought to be
1460 // 64-bit quantities, always.
1461 return base
+ (DiOffT
)idx
* (DiOffT
)scale
;
1465 /* Find the file offset corresponding to SVMA by using the program
1466 headers. This is taken from binutils-2.17/binutils/readelf.c
1467 offset_from_vma(). */
1469 Word
file_offset_from_svma ( /*OUT*/Bool
* ok
,
1477 for (i
= 0; i
< phdr_nent
; i
++) {
1479 ML_(img_get
)(&seg
, img
,
1480 INDEX_BIS(phdr_ioff
, i
, phdr_ent_szB
), sizeof(seg
));
1481 if (seg
.p_type
!= PT_LOAD
)
1483 if (svma
>= (seg
.p_vaddr
& -seg
.p_align
)
1484 && svma
+ 1 <= seg
.p_vaddr
+ seg
.p_filesz
) {
1486 return svma
- seg
.p_vaddr
+ seg
.p_offset
;
1493 /* Check if section is compressed and modify DiSlice if it is.
1494 Returns False in case of unsupported compression type.
1496 static Bool
check_compression(ElfXX_Shdr
* h
, DiSlice
* s
) {
1497 if (h
->sh_flags
& SHF_COMPRESSED
) {
1499 ML_(img_get
)(&chdr
, s
->img
, s
->ioff
, sizeof(ElfXX_Chdr
));
1500 if (chdr
.ch_type
!= ELFCOMPRESS_ZLIB
)
1502 s
->ioff
= ML_(img_mark_compressed_part
)(s
->img
,
1503 s
->ioff
+ sizeof(ElfXX_Chdr
),
1504 s
->szB
- sizeof(ElfXX_Chdr
),
1505 (SizeT
)chdr
.ch_size
);
1506 s
->szB
= chdr
.ch_size
;
1507 } else if (h
->sh_size
> SIZE_OF_ZLIB_HEADER
) {
1508 /* Read the zlib header. In this case, it should be "ZLIB"
1509 followed by the uncompressed section size, 8 bytes in BE order. */
1510 UChar tmp
[SIZE_OF_ZLIB_HEADER
];
1511 ML_(img_get
)(tmp
, s
->img
, s
->ioff
, SIZE_OF_ZLIB_HEADER
);
1512 if (VG_(memcmp
)(tmp
, "ZLIB", 4) == 0) {
1514 # if (VG_WORDSIZE == 8)
1515 size
= tmp
[4]; size
<<= 8;
1516 size
+= tmp
[5]; size
<<= 8;
1517 size
+= tmp
[6]; size
<<= 8;
1518 size
+= tmp
[7]; size
<<= 8;
1520 vg_assert((tmp
[4] == 0) && (tmp
[5] == 0) && (tmp
[6] == 0)
1524 size
+= tmp
[8]; size
<<= 8;
1525 size
+= tmp
[9]; size
<<= 8;
1526 size
+= tmp
[10]; size
<<= 8;
1528 s
->ioff
= ML_(img_mark_compressed_part
)(s
->img
,
1529 s
->ioff
+ SIZE_OF_ZLIB_HEADER
,
1530 s
->szB
- SIZE_OF_ZLIB_HEADER
,
1538 /* Helper function to get the readlink path. Returns a copy of path if the
1539 file wasn't a symbolic link. Returns NULL on error. Unless NULL is
1540 returned the result needs to be released with dinfo_free.
1542 static HChar
* readlink_path (const HChar
*path
)
1544 SizeT bufsiz
= VG_(strlen
)(path
);
1545 HChar
*buf
= ML_(dinfo_strdup
)("readlink_path.strdup", path
);
1550 #if defined(VGP_arm64_linux)
1551 res
= VG_(do_syscall4
)(__NR_readlinkat
, VKI_AT_FDCWD
,
1552 (UWord
)path
, (UWord
)buf
, bufsiz
);
1553 #elif defined(VGO_linux) || defined(VGO_darwin)
1554 res
= VG_(do_syscall3
)(__NR_readlink
, (UWord
)path
, (UWord
)buf
, bufsiz
);
1555 #elif defined(VGO_solaris)
1556 res
= VG_(do_syscall4
)(__NR_readlinkat
, VKI_AT_FDCWD
, (UWord
)path
,
1557 (UWord
)buf
, bufsiz
);
1561 if (sr_isError(res
)) {
1562 if (sr_Err(res
) == VKI_EINVAL
)
1563 return buf
; // It wasn't a symbolic link, return the strdup result.
1564 ML_(dinfo_free
)(buf
);
1568 SSizeT r
= sr_Res(res
);
1570 if (r
== bufsiz
) { // buffer too small; increase and retry
1572 buf
= ML_(dinfo_realloc
)("readlink_path.realloc", buf
, bufsiz
);
1580 if (tries
== 0) { // We tried, but weird long path?
1581 ML_(dinfo_free
)(buf
);
1588 /* Relative path, add link dir. */
1590 SizeT linkdir_len
= VG_(strlen
)(path
);
1591 if ((linkdirptr
= VG_(strrchr
)(path
, '/')) != NULL
)
1592 linkdir_len
-= VG_(strlen
)(linkdirptr
+ 1);
1594 SizeT buflen
= VG_(strlen
)(buf
);
1595 SizeT needed
= linkdir_len
+ buflen
+ 1;
1596 if (bufsiz
< needed
)
1597 buf
= ML_(dinfo_realloc
)("readlink_path.linkdir", buf
, needed
);
1599 VG_(memmove
)(buf
+ linkdir_len
, buf
, buflen
);
1600 VG_(memcpy
)(buf
, path
, linkdir_len
);
1601 buf
[needed
- 1] = '\0';
1606 /* The central function for reading ELF debug info. For the
1607 object/exe specified by the DebugInfo, find ELF sections, then read
1608 the symbols, line number info, file name info, CFA (stack-unwind
1609 info) and anything else we want, into the tables within the
1613 Bool
ML_(read_elf_debug_info
) ( struct _DebugInfo
* di
)
1615 /* This function is long and complex. That, and the presence of
1616 nested scopes, means it's not always easy to see which parts are
1617 in loops/conditionals and which aren't. To make it easier to
1618 follow, points executed exactly once -- that is, those which are
1619 the top level of the function -- are marked TOPLEVEL.
1621 /* Consistent terminology for local variable names, without which
1622 it's almost unfollowably complex:
1625 in the main ELF file *_m*
1626 in the debuginfo file *_d*
1627 in the alt debuginfo file *_a*
1630 _{m,d,a}img a DiImage*
1631 _{m,d,a}ioff an offset in the image (DiOffT)
1632 _{m,d,a}nent "number of entries"
1633 _{m,d,a}ent_szB "size in bytes of an entry"
1634 ehdr_{m,d,a} ELF header
1638 _escn an DiSlice (elf section info) variable
1646 Bool dynbss_present
= False
;
1647 Bool sdynbss_present
= False
;
1649 /* Image for the main ELF file we're working with. */
1650 DiImage
* mimg
= NULL
;
1652 /* Ditto for any ELF debuginfo file that we might happen to load. */
1653 DiImage
* dimg
= NULL
;
1655 /* Ditto for alternate ELF debuginfo file that we might happen to load. */
1656 DiImage
* aimg
= NULL
;
1658 /* ELF header offset for the main file. Should be zero since the
1659 ELF header is at start of file. */
1660 DiOffT ehdr_mioff
= 0;
1662 /* Program header table image addr, # entries, entry size */
1663 DiOffT phdr_mioff
= 0;
1664 UWord phdr_mnent
= 0;
1665 UWord phdr_ment_szB
= 0;
1667 /* Section header image addr, # entries, entry size. Also the
1668 associated string table. */
1669 DiOffT shdr_mioff
= 0;
1670 UWord shdr_mnent
= 0;
1671 UWord shdr_ment_szB
= 0;
1672 DiOffT shdr_strtab_mioff
= 0;
1674 /* SVMAs covered by rx and rw segments and corresponding biases.
1675 Normally each object would provide just one rx and one rw area,
1676 but various ELF mangling tools create objects with multiple
1677 such entries, hence the generality. */
1687 XArray
* /* of RangeAndBias */ svma_ranges
= NULL
;
1689 # if defined(SOLARIS_PT_SUNDWTRACE_THRP)
1690 Addr dtrace_data_vaddr
= 0;
1694 vg_assert(di
->fsm
.have_rx_map
== True
);
1695 vg_assert(di
->fsm
.have_rw_map
== True
);
1696 vg_assert(di
->have_dinfo
== False
);
1697 vg_assert(di
->fsm
.filename
);
1698 vg_assert(!di
->symtab
);
1699 vg_assert(!di
->loctab
);
1700 vg_assert(!di
->inltab
);
1701 vg_assert(!di
->cfsi_base
);
1702 vg_assert(!di
->cfsi_m_ix
);
1703 vg_assert(!di
->cfsi_rd
);
1704 vg_assert(!di
->cfsi_exprs
);
1705 vg_assert(!di
->strpool
);
1706 vg_assert(!di
->fndnpool
);
1707 vg_assert(!di
->soname
);
1710 Bool has_nonempty_rx
= False
;
1711 Bool has_nonempty_rw
= False
;
1712 for (i
= 0; i
< VG_(sizeXA
)(di
->fsm
.maps
); i
++) {
1713 DebugInfoMapping
* map
= VG_(indexXA
)(di
->fsm
.maps
, i
);
1714 if (!map
->rx
&& !map
->rw
)
1716 if (map
->rx
&& map
->size
> 0)
1717 has_nonempty_rx
= True
;
1718 if (map
->rw
&& map
->size
> 0)
1719 has_nonempty_rw
= True
;
1720 /* If this doesn't hold true, it means that m_syswrap/m_aspacemgr
1721 managed to do a mapping where the start isn't page aligned.
1722 Which sounds pretty bogus to me. */
1723 vg_assert(VG_IS_PAGE_ALIGNED(map
->avma
));
1725 vg_assert(has_nonempty_rx
);
1726 vg_assert(has_nonempty_rw
);
1729 /* ----------------------------------------------------------
1730 At this point, there is very little information in the
1731 DebugInfo. We only know that something that looks like an ELF
1732 file has been mapped rx-ishly and rw-ishly as recorded in the
1733 di->fsm.maps array items. First we examine the file's ELF
1734 Program Header, and, by comparing that against the di->fsm.maps
1735 info, try to figure out the AVMAs for the sections we care
1736 about, that should have been mapped: text, data, sdata, bss,
1738 ---------------------------------------------------------- */
1742 if (VG_(clo_verbosity
) > 1 || VG_(clo_trace_redir
))
1743 VG_(message
)(Vg_DebugMsg
, "Reading syms from %s\n",
1746 /* Connect to the primary object image, so that we can read symbols
1747 and line number info out of it. It will be disconnected
1748 immediately thereafter; it is only connected transiently. */
1749 mimg
= ML_(img_from_local_file
)(di
->fsm
.filename
);
1751 VG_(message
)(Vg_UserMsg
, "warning: connection to image %s failed\n",
1753 VG_(message
)(Vg_UserMsg
, " no symbols or debug info loaded\n" );
1757 /* Ok, the object image is available. Now verify that it is a
1758 valid ELF .so or executable image. */
1759 ok
= is_elf_object_file_by_DiImage(mimg
, False
);
1761 ML_(symerr
)(di
, True
, "Invalid ELF Header");
1765 /* Find where the program and section header tables are, and give
1766 up if either is missing or outside the image (bogus). */
1768 vg_assert(ehdr_mioff
== 0); // ensured by its initialisation
1769 ok
= ML_(img_valid
)(mimg
, ehdr_mioff
, sizeof(ehdr_m
));
1770 vg_assert(ok
); // ML_(is_elf_object_file) should ensure this
1771 ML_(img_get
)(&ehdr_m
, mimg
, ehdr_mioff
, sizeof(ehdr_m
));
1773 phdr_mioff
= ehdr_mioff
+ ehdr_m
.e_phoff
;
1774 phdr_mnent
= ehdr_m
.e_phnum
;
1775 phdr_ment_szB
= ehdr_m
.e_phentsize
;
1777 shdr_mioff
= ehdr_mioff
+ ehdr_m
.e_shoff
;
1778 shdr_mnent
= ehdr_m
.e_shnum
;
1779 shdr_ment_szB
= ehdr_m
.e_shentsize
;
1781 TRACE_SYMTAB("------ Basic facts about the object ------\n");
1782 TRACE_SYMTAB("object: n_oimage %llu\n",
1783 (ULong
)ML_(img_size
)(mimg
));
1784 TRACE_SYMTAB("phdr: ioff %llu nent %lu ent_szB %lu\n",
1785 phdr_mioff
, phdr_mnent
, phdr_ment_szB
);
1786 TRACE_SYMTAB("shdr: ioff %llu nent %lu ent_szB %lu\n",
1787 shdr_mioff
, shdr_mnent
, shdr_ment_szB
);
1788 for (i
= 0; i
< VG_(sizeXA
)(di
->fsm
.maps
); i
++) {
1789 const DebugInfoMapping
* map
= VG_(indexXA
)(di
->fsm
.maps
, i
);
1791 TRACE_SYMTAB("rx_map: avma %#lx size %lu foff %ld\n",
1792 map
->avma
, map
->size
, map
->foff
);
1794 for (i
= 0; i
< VG_(sizeXA
)(di
->fsm
.maps
); i
++) {
1795 const DebugInfoMapping
* map
= VG_(indexXA
)(di
->fsm
.maps
, i
);
1797 TRACE_SYMTAB("rw_map: avma %#lx size %lu foff %ld\n",
1798 map
->avma
, map
->size
, map
->foff
);
1802 || !ML_(img_valid
)(mimg
, phdr_mioff
, phdr_mnent
* phdr_ment_szB
)) {
1803 ML_(symerr
)(di
, True
, "Missing or invalid ELF Program Header Table");
1808 || !ML_(img_valid
)(mimg
, shdr_mioff
, shdr_mnent
* shdr_ment_szB
)) {
1809 ML_(symerr
)(di
, True
, "Missing or invalid ELF Section Header Table");
1813 /* Also find the section header's string table, and validate. */
1814 /* checked previously by is_elf_object_file: */
1815 vg_assert(ehdr_m
.e_shstrndx
!= SHN_UNDEF
);
1817 // shdr_mioff is the offset of the section header table
1818 // and we need the ehdr_m.e_shstrndx'th entry
1819 { ElfXX_Shdr a_shdr
;
1820 ML_(img_get
)(&a_shdr
, mimg
,
1821 INDEX_BIS(shdr_mioff
, ehdr_m
.e_shstrndx
, shdr_ment_szB
),
1824 = ehdr_mioff
/* isn't this always zero? */ + a_shdr
.sh_offset
;
1826 if (!ML_(img_valid
)(mimg
, shdr_strtab_mioff
,
1827 1/*bogus, but we don't know the real size*/ )) {
1828 ML_(symerr
)(di
, True
, "Invalid ELF Section Header String Table");
1833 TRACE_SYMTAB("shdr: string table at %llu\n", shdr_strtab_mioff
);
1835 svma_ranges
= VG_(newXA
)(ML_(dinfo_zalloc
), "di.relfdi.1",
1836 ML_(dinfo_free
), sizeof(RangeAndBias
));
1839 /* Look through the program header table, and:
1840 - copy information from suitable PT_LOAD entries into svma_ranges
1841 - find (or fake up) the .soname for this object.
1844 TRACE_SYMTAB("------ Examining the program headers ------\n");
1845 vg_assert(di
->soname
== NULL
);
1848 ElfXX_Addr prev_svma
= 0;
1850 for (i
= 0; i
< phdr_mnent
; i
++) {
1852 ML_(img_get
)(&a_phdr
, mimg
,
1853 INDEX_BIS(phdr_mioff
, i
, phdr_ment_szB
),
1856 /* Make sure the PT_LOADable entries are in order and
1857 non-overlapping. This in turn means the address ranges
1858 slurped into svma_ranges are in order and
1861 if (a_phdr
.p_type
== PT_LOAD
) {
1862 TRACE_SYMTAB("PT_LOAD[%ld]: p_vaddr %#lx (prev %#lx)\n",
1863 i
, (UWord
)a_phdr
.p_vaddr
, (UWord
)prev_svma
);
1864 TRACE_SYMTAB("PT_LOAD[%ld]: p_offset %lu, p_filesz %lu,"
1866 i
, (UWord
)a_phdr
.p_offset
, (UWord
)a_phdr
.p_filesz
,
1867 a_phdr
.p_flags
& PF_R
? 'r' : '-',
1868 a_phdr
.p_flags
& PF_W
? 'w' : '-',
1869 a_phdr
.p_flags
& PF_X
? 'x' : '-');
1870 if (a_phdr
.p_vaddr
< prev_svma
) {
1871 ML_(symerr
)(di
, True
,
1872 "ELF Program Headers are not in ascending order");
1875 prev_svma
= a_phdr
.p_vaddr
;
1876 if (a_phdr
.p_memsz
> 0) {
1877 Bool loaded
= False
;
1878 for (j
= 0; j
< VG_(sizeXA
)(di
->fsm
.maps
); j
++) {
1879 const DebugInfoMapping
* map
= VG_(indexXA
)(di
->fsm
.maps
, j
);
1880 if ( (map
->rx
|| map
->rw
)
1881 && map
->size
> 0 /* stay sane */
1882 && a_phdr
.p_offset
>= map
->foff
1883 && a_phdr
.p_offset
< map
->foff
+ map
->size
1884 && a_phdr
.p_offset
+ a_phdr
.p_filesz
1885 <= map
->foff
+ map
->size
) {
1887 item
.svma_base
= a_phdr
.p_vaddr
;
1888 item
.svma_limit
= a_phdr
.p_vaddr
+ a_phdr
.p_memsz
;
1889 item
.bias
= map
->avma
- map
->foff
1890 + a_phdr
.p_offset
- a_phdr
.p_vaddr
;
1892 && (a_phdr
.p_flags
& (PF_R
| PF_W
))
1895 VG_(addToXA
)(svma_ranges
, &item
);
1897 "PT_LOAD[%ld]: acquired as rw, bias 0x%lx\n",
1898 i
, (UWord
)item
.bias
);
1902 && (a_phdr
.p_flags
& (PF_R
| PF_X
))
1905 VG_(addToXA
)(svma_ranges
, &item
);
1907 "PT_LOAD[%ld]: acquired as rx, bias 0x%lx\n",
1908 i
, (UWord
)item
.bias
);
1914 # if defined(SOLARIS_PT_SUNDWTRACE_THRP)
1915 if ((a_phdr
.p_memsz
== VKI_PT_SUNWDTRACE_SIZE
)
1916 && ((a_phdr
.p_flags
& (PF_R
| PF_W
| PF_X
)) == PF_R
)) {
1917 TRACE_SYMTAB("PT_LOAD[%ld]: ignore dtrace_data program "
1919 dtrace_data_vaddr
= a_phdr
.p_vaddr
;
1922 # endif /* SOLARIS_PT_SUNDWTRACE_THRP */
1924 ML_(symerr
)(di
, False
,
1925 "ELF section outside all mapped regions");
1926 /* This problem might be solved by further memory mappings.
1927 Avoid the vg_assert(!di->soname) at the beginning of this
1928 function if DYNAMIC section has been already processed. */
1930 ML_(dinfo_free
)(di
->soname
);
1938 /* Try to get the soname. If there isn't one, use "NONE".
1939 The seginfo needs to have some kind of soname in order to
1940 facilitate writing redirect functions, since all redirect
1941 specifications require a soname (pattern). */
1942 if (a_phdr
.p_type
== PT_DYNAMIC
&& di
->soname
== NULL
) {
1944 DiOffT strtab_mioff
= DiOffT_INVALID
;
1945 for (j
= 0; True
/*exit check is in the loop*/; j
++) {
1946 ElfXX_Dyn t_dyn_m
; /* dyn_img[j] */
1947 ML_(img_get
)(&t_dyn_m
, mimg
,
1948 INDEX_BIS(ehdr_mioff
+ a_phdr
.p_offset
,
1949 j
, sizeof(ElfXX_Dyn
)),
1951 if (t_dyn_m
.d_tag
== DT_NULL
)
1954 switch (t_dyn_m
.d_tag
) {
1956 stroff
= t_dyn_m
.d_un
.d_val
;
1961 Word offset
= file_offset_from_svma(
1962 &ok2
, t_dyn_m
.d_un
.d_ptr
, mimg
,
1963 phdr_mioff
, phdr_mnent
, phdr_ment_szB
1965 if (ok2
&& strtab_mioff
== DiOffT_INVALID
) {
1966 // Check for obviously bogus offsets.
1967 if (!ML_(img_valid
)(mimg
, offset
, 1)) {
1968 ML_(symerr
)(di
, True
, "Invalid DT_STRTAB offset");
1971 strtab_mioff
= ehdr_mioff
+ offset
;
1972 vg_assert(ehdr_mioff
== 0); // should always be
1980 if (stroff
!= -1 && strtab_mioff
!= DiOffT_INVALID
) {
1981 di
->soname
= ML_(img_strdup
)(mimg
, "di.redi.1",
1982 strtab_mioff
+ stroff
);
1983 TRACE_SYMTAB("Found soname = %s\n", di
->soname
);
1986 } /* for (i = 0; i < phdr_Mnent; i++) ... */
1989 } /* examine the program headers (local scope) */
1993 /* If, after looking at all the program headers, we still didn't
1994 find a soname, add a fake one. */
1995 if (di
->soname
== NULL
) {
1996 TRACE_SYMTAB("No soname found; using (fake) \"NONE\"\n");
1997 di
->soname
= ML_(dinfo_strdup
)("di.redi.2", "NONE");
2000 vg_assert(VG_(sizeXA
)(svma_ranges
) != 0);
2002 /* Now read the section table. */
2004 TRACE_SYMTAB("------ Examining the section headers ------\n");
2005 for (i
= 0; i
< VG_(sizeXA
)(di
->fsm
.maps
); i
++) {
2006 const DebugInfoMapping
* map
= VG_(indexXA
)(di
->fsm
.maps
, i
);
2008 TRACE_SYMTAB("rx: at %#lx are mapped foffsets %ld .. %lu\n",
2009 map
->avma
, map
->foff
, map
->foff
+ map
->size
- 1 );
2011 TRACE_SYMTAB("rx: contains these svma regions:\n");
2012 for (i
= 0; i
< VG_(sizeXA
)(svma_ranges
); i
++) {
2013 const RangeAndBias
* reg
= VG_(indexXA
)(svma_ranges
, i
);
2015 TRACE_SYMTAB(" svmas %#lx .. %#lx with bias %#lx\n",
2016 reg
->svma_base
, reg
->svma_limit
- 1, (UWord
)reg
->bias
);
2018 for (i
= 0; i
< VG_(sizeXA
)(di
->fsm
.maps
); i
++) {
2019 const DebugInfoMapping
* map
= VG_(indexXA
)(di
->fsm
.maps
, i
);
2021 TRACE_SYMTAB("rw: at %#lx are mapped foffsets %ld .. %lu\n",
2022 map
->avma
, map
->foff
, map
->foff
+ map
->size
- 1 );
2024 TRACE_SYMTAB("rw: contains these svma regions:\n");
2025 for (i
= 0; i
< VG_(sizeXA
)(svma_ranges
); i
++) {
2026 const RangeAndBias
* reg
= VG_(indexXA
)(svma_ranges
, i
);
2028 TRACE_SYMTAB(" svmas %#lx .. %#lx with bias %#lx\n",
2029 reg
->svma_base
, reg
->svma_limit
- 1, (UWord
)reg
->bias
);
2033 /* Iterate over section headers */
2034 for (i
= 0; i
< shdr_mnent
; i
++) {
2036 ML_(img_get
)(&a_shdr
, mimg
,
2037 INDEX_BIS(shdr_mioff
, i
, shdr_ment_szB
), sizeof(a_shdr
));
2038 DiOffT name_mioff
= shdr_strtab_mioff
+ a_shdr
.sh_name
;
2039 HChar
* name
= ML_(img_strdup
)(mimg
, "di.redi_name.2", name_mioff
);
2040 Addr svma
= a_shdr
.sh_addr
;
2041 OffT foff
= a_shdr
.sh_offset
;
2042 UWord size
= a_shdr
.sh_size
; /* Do not change this to be signed. */
2043 UInt alyn
= a_shdr
.sh_addralign
;
2044 Bool nobits
= a_shdr
.sh_type
== SHT_NOBITS
;
2045 /* Look through our collection of info obtained from the PT_LOAD
2046 headers, and make 'inrx' and 'inrw' point to the first entry
2047 in each that intersects 'avma'. If in each case none is found,
2048 leave the relevant pointer at NULL. */
2049 RangeAndBias
* inrx
= NULL
;
2050 RangeAndBias
* inrw
= NULL
;
2051 for (j
= 0; j
< VG_(sizeXA
)(svma_ranges
); j
++) {
2052 RangeAndBias
* rng
= VG_(indexXA
)(svma_ranges
, j
);
2053 if (svma
>= rng
->svma_base
&& svma
< rng
->svma_limit
) {
2054 if (!inrx
&& rng
->exec
) {
2056 } else if (!inrw
&& !rng
->exec
) {
2064 TRACE_SYMTAB(" [sec %2ld] %s %s al%4u foff %6ld .. %6lu "
2065 " svma %p name \"%s\"\n",
2066 i
, inrx
? "rx" : " ", inrw
? "rw" : " ", alyn
,
2067 foff
, (size
== 0) ? foff
: foff
+size
-1, (void *) svma
, name
);
2069 /* Check for sane-sized segments. SHT_NOBITS sections have zero
2070 size in the file and their offsets are just conceptual. */
2072 (foff
>= ML_(img_size
)(mimg
) || foff
+ size
> ML_(img_size
)(mimg
))) {
2073 ML_(symerr
)(di
, True
, "ELF Section extends beyond image end");
2077 /* Check for a sane alignment value. */
2078 if (alyn
> 0 && -1 == VG_(log2
)(alyn
)) {
2079 ML_(symerr
)(di
, True
, "ELF Section contains invalid "
2080 ".sh_addralign value");
2084 /* Ignore zero sized sections. */
2086 TRACE_SYMTAB("zero sized section \"%s\", ignoring\n", name
);
2087 ML_(dinfo_free
)(name
);
2091 # define BAD(_secname) \
2092 do { ML_(symerr)(di, True, \
2093 "Can't make sense of " _secname \
2094 " section mapping"); \
2095 /* make sure we don't assert if we find */ \
2096 /* ourselves back in this routine later, */ \
2097 /* with the same di */ \
2098 di->soname = NULL; \
2102 /* Find avma-s for: .text .data .sdata .rodata .bss .sbss .plt .got .opd
2105 /* Accept .text where mapped as rx (code), even if zero-sized */
2106 if (0 == VG_(strcmp
)(name
, ".text")) {
2107 if (inrx
&& !di
->text_present
) {
2108 di
->text_present
= True
;
2109 di
->text_svma
= svma
;
2110 di
->text_avma
= svma
+ inrx
->bias
;
2111 di
->text_size
= size
;
2112 di
->text_bias
= inrx
->bias
;
2113 di
->text_debug_svma
= svma
;
2114 di
->text_debug_bias
= inrx
->bias
;
2115 TRACE_SYMTAB("acquiring .text svma = %#lx .. %#lx\n",
2117 di
->text_svma
+ di
->text_size
- 1);
2118 TRACE_SYMTAB("acquiring .text avma = %#lx .. %#lx\n",
2120 di
->text_avma
+ di
->text_size
- 1);
2121 TRACE_SYMTAB("acquiring .text bias = %#lx\n", (UWord
)di
->text_bias
);
2127 /* Accept .data where mapped as rw (data), even if zero-sized */
2128 if (0 == VG_(strcmp
)(name
, ".data")) {
2129 # if defined(SOLARIS_PT_SUNDWTRACE_THRP)
2130 if ((size
== VKI_PT_SUNWDTRACE_SIZE
) && (svma
== dtrace_data_vaddr
)) {
2131 TRACE_SYMTAB("ignoring .data section for dtrace_data "
2132 "%#lx .. %#lx\n", svma
, svma
+ size
- 1);
2134 # endif /* SOLARIS_PT_SUNDWTRACE_THRP */
2135 if (inrw
&& !di
->data_present
) {
2136 di
->data_present
= True
;
2137 di
->data_svma
= svma
;
2138 di
->data_avma
= svma
+ inrw
->bias
;
2139 di
->data_size
= size
;
2140 di
->data_bias
= inrw
->bias
;
2141 di
->data_debug_svma
= svma
;
2142 di
->data_debug_bias
= inrw
->bias
;
2143 TRACE_SYMTAB("acquiring .data svma = %#lx .. %#lx\n",
2145 di
->data_svma
+ di
->data_size
- 1);
2146 TRACE_SYMTAB("acquiring .data avma = %#lx .. %#lx\n",
2148 di
->data_avma
+ di
->data_size
- 1);
2149 TRACE_SYMTAB("acquiring .data bias = %#lx\n", (UWord
)di
->data_bias
);
2155 /* Accept .sdata where mapped as rw (data) */
2156 if (0 == VG_(strcmp
)(name
, ".sdata")) {
2157 if (inrw
&& !di
->sdata_present
) {
2158 di
->sdata_present
= True
;
2159 di
->sdata_svma
= svma
;
2160 di
->sdata_avma
= svma
+ inrw
->bias
;
2161 di
->sdata_size
= size
;
2162 di
->sdata_bias
= inrw
->bias
;
2163 di
->sdata_debug_svma
= svma
;
2164 di
->sdata_debug_bias
= inrw
->bias
;
2165 TRACE_SYMTAB("acquiring .sdata svma = %#lx .. %#lx\n",
2167 di
->sdata_svma
+ di
->sdata_size
- 1);
2168 TRACE_SYMTAB("acquiring .sdata avma = %#lx .. %#lx\n",
2170 di
->sdata_avma
+ di
->sdata_size
- 1);
2171 TRACE_SYMTAB("acquiring .sdata bias = %#lx\n",
2172 (UWord
)di
->sdata_bias
);
2178 /* Accept .rodata where mapped as rx (data), even if zero-sized */
2179 if (0 == VG_(strcmp
)(name
, ".rodata")) {
2180 if (inrx
&& !di
->rodata_present
) {
2181 di
->rodata_present
= True
;
2182 di
->rodata_svma
= svma
;
2183 di
->rodata_avma
= svma
+ inrx
->bias
;
2184 di
->rodata_size
= size
;
2185 di
->rodata_bias
= inrx
->bias
;
2186 di
->rodata_debug_svma
= svma
;
2187 di
->rodata_debug_bias
= inrx
->bias
;
2188 /* NB was 'inrw' prior to r11794 */
2189 TRACE_SYMTAB("acquiring .rodata svma = %#lx .. %#lx\n",
2191 di
->rodata_svma
+ di
->rodata_size
- 1);
2192 TRACE_SYMTAB("acquiring .rodata avma = %#lx .. %#lx\n",
2194 di
->rodata_avma
+ di
->rodata_size
- 1);
2195 TRACE_SYMTAB("acquiring .rodata bias = %#lx\n",
2196 (UWord
)di
->rodata_bias
);
2202 if (0 == VG_(strcmp
)(name
, ".dynbss")) {
2203 if (inrw
&& !di
->bss_present
) {
2204 dynbss_present
= True
;
2205 di
->bss_present
= True
;
2206 di
->bss_svma
= svma
;
2207 di
->bss_avma
= svma
+ inrw
->bias
;
2208 di
->bss_size
= size
;
2209 di
->bss_bias
= inrw
->bias
;
2210 di
->bss_debug_svma
= svma
;
2211 di
->bss_debug_bias
= inrw
->bias
;
2212 TRACE_SYMTAB("acquiring .dynbss svma = %#lx .. %#lx\n",
2214 di
->bss_svma
+ di
->bss_size
- 1);
2215 TRACE_SYMTAB("acquiring .dynbss avma = %#lx .. %#lx\n",
2217 di
->bss_avma
+ di
->bss_size
- 1);
2218 TRACE_SYMTAB("acquiring .dynbss bias = %#lx\n",
2219 (UWord
)di
->bss_bias
);
2223 /* Accept .bss where mapped as rw (data), even if zero-sized */
2224 if (0 == VG_(strcmp
)(name
, ".bss")) {
2225 if (inrw
&& dynbss_present
) {
2226 vg_assert(di
->bss_present
);
2227 dynbss_present
= False
;
2228 vg_assert(di
->bss_svma
+ di
->bss_size
== svma
);
2229 di
->bss_size
+= size
;
2230 TRACE_SYMTAB("acquiring .bss svma = %#lx .. %#lx\n",
2231 svma
, svma
+ size
- 1);
2232 TRACE_SYMTAB("acquiring .bss avma = %#lx .. %#lx\n",
2233 svma
+ inrw
->bias
, svma
+ inrw
->bias
+ size
- 1);
2234 TRACE_SYMTAB("acquiring .bss bias = %#lx\n",
2235 (UWord
)di
->bss_bias
);
2238 if (inrw
&& !di
->bss_present
) {
2239 di
->bss_present
= True
;
2240 di
->bss_svma
= svma
;
2241 di
->bss_avma
= svma
+ inrw
->bias
;
2242 di
->bss_size
= size
;
2243 di
->bss_bias
= inrw
->bias
;
2244 di
->bss_debug_svma
= svma
;
2245 di
->bss_debug_bias
= inrw
->bias
;
2246 TRACE_SYMTAB("acquiring .bss svma = %#lx .. %#lx\n",
2248 di
->bss_svma
+ di
->bss_size
- 1);
2249 TRACE_SYMTAB("acquiring .bss avma = %#lx .. %#lx\n",
2251 di
->bss_avma
+ di
->bss_size
- 1);
2252 TRACE_SYMTAB("acquiring .bss bias = %#lx\n",
2253 (UWord
)di
->bss_bias
);
2256 /* Now one from the wtf?! department ... */
2257 if (inrx
&& (!inrw
) && !di
->bss_present
) {
2258 /* File contains a .bss, but it got mapped as rx only.
2259 This is very strange. For now, just pretend we didn't
2261 di
->bss_present
= False
;
2266 di
->bss_debug_svma
= 0;
2267 di
->bss_debug_bias
= 0;
2268 if (!VG_(clo_xml
)) {
2269 VG_(message
)(Vg_UserMsg
,
2270 "Warning: the following file's .bss is "
2271 "mapped r-x only - ignoring .bss syms\n");
2272 VG_(message
)(Vg_UserMsg
, " %s\n", di
->fsm
.filename
2278 if ((!inrw
) && (!inrx
) && !di
->bss_present
) {
2279 /* File contains a .bss, but it didn't get mapped. Ignore. */
2280 di
->bss_present
= False
;
2290 if (0 == VG_(strcmp
)(name
, ".sdynbss")) {
2291 if (inrw
&& !di
->sbss_present
) {
2292 sdynbss_present
= True
;
2293 di
->sbss_present
= True
;
2294 di
->sbss_svma
= svma
;
2295 di
->sbss_avma
= svma
+ inrw
->bias
;
2296 di
->sbss_size
= size
;
2297 di
->sbss_bias
= inrw
->bias
;
2298 di
->sbss_debug_svma
= svma
;
2299 di
->sbss_debug_bias
= inrw
->bias
;
2300 TRACE_SYMTAB("acquiring .sdynbss svma = %#lx .. %#lx\n",
2302 di
->sbss_svma
+ di
->sbss_size
- 1);
2303 TRACE_SYMTAB("acquiring .sdynbss avma = %#lx .. %#lx\n",
2305 di
->sbss_avma
+ di
->sbss_size
- 1);
2306 TRACE_SYMTAB("acquiring .sdynbss bias = %#lx\n",
2307 (UWord
)di
->sbss_bias
);
2311 /* Accept .sbss where mapped as rw (data) */
2312 if (0 == VG_(strcmp
)(name
, ".sbss")) {
2313 if (inrw
&& sdynbss_present
) {
2314 vg_assert(di
->sbss_present
);
2315 sdynbss_present
= False
;
2316 vg_assert(di
->sbss_svma
+ di
->sbss_size
== svma
);
2317 di
->sbss_size
+= size
;
2318 TRACE_SYMTAB("acquiring .sbss svma = %#lx .. %#lx\n",
2319 svma
, svma
+ size
- 1);
2320 TRACE_SYMTAB("acquiring .sbss avma = %#lx .. %#lx\n",
2321 svma
+ inrw
->bias
, svma
+ inrw
->bias
+ size
- 1);
2322 TRACE_SYMTAB("acquiring .sbss bias = %#lx\n", (UWord
)di
->sbss_bias
);
2325 if (inrw
&& !di
->sbss_present
) {
2326 di
->sbss_present
= True
;
2327 di
->sbss_svma
= svma
;
2328 di
->sbss_avma
= svma
+ inrw
->bias
;
2329 di
->sbss_size
= size
;
2330 di
->sbss_bias
= inrw
->bias
;
2331 di
->sbss_debug_svma
= svma
;
2332 di
->sbss_debug_bias
= inrw
->bias
;
2333 TRACE_SYMTAB("acquiring .sbss svma = %#lx .. %#lx\n",
2335 di
->sbss_svma
+ di
->sbss_size
- 1);
2336 TRACE_SYMTAB("acquiring .sbss avma = %#lx .. %#lx\n",
2338 di
->sbss_avma
+ di
->sbss_size
- 1);
2339 TRACE_SYMTAB("acquiring .sbss bias = %#lx\n", (UWord
)di
->sbss_bias
);
2345 /* Accept .got where mapped as rw (data) */
2346 if (0 == VG_(strcmp
)(name
, ".got")) {
2347 if (inrw
&& !di
->got_present
) {
2348 di
->got_present
= True
;
2349 di
->got_avma
= svma
+ inrw
->bias
;
2350 di
->got_size
= size
;
2351 TRACE_SYMTAB("acquiring .got avma = %#lx\n", di
->got_avma
);
2357 /* Accept .got.plt where mapped as rw (data) */
2358 if (0 == VG_(strcmp
)(name
, ".got.plt")) {
2359 if (inrw
&& !di
->gotplt_present
) {
2360 di
->gotplt_present
= True
;
2361 di
->gotplt_avma
= svma
+ inrw
->bias
;
2362 di
->gotplt_size
= size
;
2363 TRACE_SYMTAB("acquiring .got.plt avma = %#lx\n", di
->gotplt_avma
);
2364 } else if (size
!= 0) {
2369 /* PLT is different on different platforms, it seems. */
2370 # if defined(VGP_x86_linux) || defined(VGP_amd64_linux) \
2371 || defined(VGP_arm_linux) || defined (VGP_s390x_linux) \
2372 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
2373 || defined(VGP_arm64_linux) \
2374 || defined(VGP_x86_solaris) || defined(VGP_amd64_solaris)
2375 /* Accept .plt where mapped as rx (code) */
2376 if (0 == VG_(strcmp
)(name
, ".plt")) {
2377 if (inrx
&& !di
->plt_present
) {
2378 di
->plt_present
= True
;
2379 di
->plt_avma
= svma
+ inrx
->bias
;
2380 di
->plt_size
= size
;
2381 TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di
->plt_avma
);
2386 # elif defined(VGP_ppc32_linux)
2387 /* Accept .plt where mapped as rw (data) */
2388 if (0 == VG_(strcmp
)(name
, ".plt")) {
2389 if (inrw
&& !di
->plt_present
) {
2390 di
->plt_present
= True
;
2391 di
->plt_avma
= svma
+ inrw
->bias
;
2392 di
->plt_size
= size
;
2393 TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di
->plt_avma
);
2398 # elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
2399 /* Accept .plt where mapped as rw (data), or unmapped */
2400 if (0 == VG_(strcmp
)(name
, ".plt")) {
2401 if (inrw
&& !di
->plt_present
) {
2402 di
->plt_present
= True
;
2403 di
->plt_avma
= svma
+ inrw
->bias
;
2404 di
->plt_size
= size
;
2405 TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di
->plt_avma
);
2407 if ((!inrw
) && (!inrx
) && size
> 0 && !di
->plt_present
) {
2408 /* File contains a .plt, but it didn't get mapped.
2409 Presumably it is not required on this platform. At
2410 least don't reject the situation as invalid. */
2411 di
->plt_present
= True
;
2419 # error "Unsupported platform"
2422 /* Accept .opd where mapped as rw (data) */
2423 if (0 == VG_(strcmp
)(name
, ".opd")) {
2424 if (inrw
&& !di
->opd_present
) {
2425 di
->opd_present
= True
;
2426 di
->opd_avma
= svma
+ inrw
->bias
;
2427 di
->opd_size
= size
;
2428 TRACE_SYMTAB("acquiring .opd avma = %#lx\n", di
->opd_avma
);
2434 /* Accept .eh_frame where mapped as rx (code). This seems to be
2435 the common case. However, if that doesn't pan out, try for
2436 rw (data) instead. We can handle up to N_EHFRAME_SECTS per
2438 if (0 == VG_(strcmp
)(name
, ".eh_frame")) {
2439 if (inrx
&& di
->n_ehframe
< N_EHFRAME_SECTS
) {
2440 di
->ehframe_avma
[di
->n_ehframe
] = svma
+ inrx
->bias
;
2441 di
->ehframe_size
[di
->n_ehframe
] = size
;
2442 TRACE_SYMTAB("acquiring .eh_frame avma = %#lx\n",
2443 di
->ehframe_avma
[di
->n_ehframe
]);
2446 if (inrw
&& di
->n_ehframe
< N_EHFRAME_SECTS
) {
2447 di
->ehframe_avma
[di
->n_ehframe
] = svma
+ inrw
->bias
;
2448 di
->ehframe_size
[di
->n_ehframe
] = size
;
2449 TRACE_SYMTAB("acquiring .eh_frame avma = %#lx\n",
2450 di
->ehframe_avma
[di
->n_ehframe
]);
2457 /* Accept .ARM.exidx where mapped as rx (code). */
2458 /* FIXME: make sure the entire section is mapped in, not just
2459 the first address. */
2460 if (0 == VG_(strcmp
)(name
, ".ARM.exidx")) {
2461 if (inrx
&& !di
->exidx_present
) {
2462 di
->exidx_present
= True
;
2463 di
->exidx_svma
= svma
;
2464 di
->exidx_avma
= svma
+ inrx
->bias
;
2465 di
->exidx_size
= size
;
2466 di
->exidx_bias
= inrx
->bias
;
2467 TRACE_SYMTAB("acquiring .exidx svma = %#lx .. %#lx\n",
2469 di
->exidx_svma
+ di
->exidx_size
- 1);
2470 TRACE_SYMTAB("acquiring .exidx avma = %#lx .. %#lx\n",
2472 di
->exidx_avma
+ di
->exidx_size
- 1);
2473 TRACE_SYMTAB("acquiring .exidx bias = %#lx\n",
2474 (UWord
)di
->exidx_bias
);
2480 /* Accept .ARM.extab where mapped as rx (code). */
2481 /* FIXME: make sure the entire section is mapped in, not just
2482 the first address. */
2483 if (0 == VG_(strcmp
)(name
, ".ARM.extab")) {
2484 if (inrx
&& !di
->extab_present
) {
2485 di
->extab_present
= True
;
2486 di
->extab_svma
= svma
;
2487 di
->extab_avma
= svma
+ inrx
->bias
;
2488 di
->extab_size
= size
;
2489 di
->extab_bias
= inrx
->bias
;
2490 TRACE_SYMTAB("acquiring .extab svma = %#lx .. %#lx\n",
2492 di
->extab_svma
+ di
->extab_size
- 1);
2493 TRACE_SYMTAB("acquiring .extab avma = %#lx .. %#lx\n",
2495 di
->extab_avma
+ di
->extab_size
- 1);
2496 TRACE_SYMTAB("acquiring .extab bias = %#lx\n",
2497 (UWord
)di
->extab_bias
);
2503 ML_(dinfo_free
)(name
);
2507 } /* iterate over the section headers */
2510 if (0) VG_(printf
)("YYYY text_: avma %#lx size %lu bias %#lx\n",
2511 di
->text_avma
, di
->text_size
, (UWord
)di
->text_bias
);
2513 if (VG_(clo_verbosity
) > 2 || VG_(clo_trace_redir
))
2514 VG_(message
)(Vg_DebugMsg
, " svma %#010lx, avma %#010lx\n",
2515 di
->text_avma
- di
->text_bias
,
2519 TRACE_SYMTAB("------ Finding image addresses "
2520 "for debug-info sections ------\n");
2523 /* Find interesting sections, read the symbol table(s), read any
2524 debug information. Each section is located either in the main,
2525 debug or alt-debug files, but only in one. For each section,
2526 |section_escn| records which of |mimg|, |dimg| or |aimg| we
2527 found it in, along with the section's image offset and its size.
2528 The triples (section_img, section_ioff, section_szB) are
2529 consistent, in that they are always either (NULL,
2530 DiOffT_INVALID, 0), or refer to the same image, and are all
2531 assigned together. */
2534 DiSlice strtab_escn
= DiSlice_INVALID
; // .strtab
2535 DiSlice symtab_escn
= DiSlice_INVALID
; // .symtab
2536 DiSlice dynstr_escn
= DiSlice_INVALID
; // .dynstr
2537 DiSlice dynsym_escn
= DiSlice_INVALID
; // .dynsym
2538 # if defined(VGO_solaris)
2539 DiSlice ldynsym_escn
= DiSlice_INVALID
; // .SUNW_ldynsym
2541 DiSlice debuglink_escn
= DiSlice_INVALID
; // .gnu_debuglink
2542 DiSlice debugaltlink_escn
= DiSlice_INVALID
; // .gnu_debugaltlink
2543 DiSlice debug_line_escn
= DiSlice_INVALID
; // .debug_line (dwarf2)
2544 DiSlice debug_info_escn
= DiSlice_INVALID
; // .debug_info (dwarf2)
2545 DiSlice debug_types_escn
= DiSlice_INVALID
; // .debug_types (dwarf4)
2546 DiSlice debug_abbv_escn
= DiSlice_INVALID
; // .debug_abbrev (dwarf2)
2547 DiSlice debug_str_escn
= DiSlice_INVALID
; // .debug_str (dwarf2)
2548 DiSlice debug_ranges_escn
= DiSlice_INVALID
; // .debug_ranges (dwarf2)
2549 DiSlice debug_loc_escn
= DiSlice_INVALID
; // .debug_loc (dwarf2)
2550 DiSlice debug_frame_escn
= DiSlice_INVALID
; // .debug_frame (dwarf2)
2551 DiSlice debug_line_alt_escn
= DiSlice_INVALID
; // .debug_line (alt)
2552 DiSlice debug_info_alt_escn
= DiSlice_INVALID
; // .debug_info (alt)
2553 DiSlice debug_abbv_alt_escn
= DiSlice_INVALID
; // .debug_abbrev (alt)
2554 DiSlice debug_str_alt_escn
= DiSlice_INVALID
; // .debug_str (alt)
2555 DiSlice dwarf1d_escn
= DiSlice_INVALID
; // .debug (dwarf1)
2556 DiSlice dwarf1l_escn
= DiSlice_INVALID
; // .line (dwarf1)
2557 DiSlice opd_escn
= DiSlice_INVALID
; // .opd (dwarf2,
2559 DiSlice ehframe_escn
[N_EHFRAME_SECTS
]; // .eh_frame (dwarf2)
2561 for (i
= 0; i
< N_EHFRAME_SECTS
; i
++)
2562 ehframe_escn
[i
] = DiSlice_INVALID
;
2564 /* Find all interesting sections */
2566 UInt ehframe_mix
= 0;
2568 /* What FIND does: it finds the section called _SEC_NAME. The
2569 size of it is assigned to _SEC_SIZE. The address of the
2570 section in the transiently loaded oimage is assigned to
2571 _SEC_IMG. If the section is found, _POST_FX is executed
2572 after _SEC_NAME and _SEC_SIZE have been assigned to.
2574 Even for sections which are marked loadable, the client's
2575 ld.so may not have loaded them yet, so there is no guarantee
2576 that we can safely prod around in any such area). Because
2577 the entire object file is transiently mapped aboard for
2578 inspection, it's always safe to inspect that area. */
2581 /* Iterate over section headers (again) */
2582 for (i
= 0; i
< ehdr_m
.e_shnum
; i
++) {
2584 # define FINDX(_sec_name, _sec_escn, _post_fx) \
2586 ElfXX_Shdr a_shdr; \
2587 ML_(img_get)(&a_shdr, mimg, \
2588 INDEX_BIS(shdr_mioff, i, shdr_ment_szB), \
2590 if (0 == ML_(img_strcmp_c)(mimg, shdr_strtab_mioff \
2591 + a_shdr.sh_name, _sec_name)) { \
2593 _sec_escn.img = mimg; \
2594 _sec_escn.ioff = (DiOffT)a_shdr.sh_offset; \
2595 _sec_escn.szB = a_shdr.sh_size; \
2596 if (!check_compression(&a_shdr, &_sec_escn)) { \
2597 ML_(symerr)(di, True, " Compression type is unsupported"); \
2600 nobits = a_shdr.sh_type == SHT_NOBITS; \
2601 vg_assert(_sec_escn.img != NULL); \
2602 vg_assert(_sec_escn.ioff != DiOffT_INVALID); \
2603 TRACE_SYMTAB( "%-18s: ioff %llu .. %llu\n", \
2604 _sec_name, (ULong)a_shdr.sh_offset, \
2605 ((ULong)a_shdr.sh_offset) + a_shdr.sh_size - 1); \
2606 /* SHT_NOBITS sections have zero size in the file. */ \
2608 a_shdr.sh_offset + \
2609 a_shdr.sh_size > ML_(img_real_size)(mimg)) { \
2610 ML_(symerr)(di, True, \
2611 " section beyond image end?!"); \
2618 /* Version with no post-effects */
2619 # define FIND(_sec_name, _sec_escn) \
2620 FINDX(_sec_name, _sec_escn, /**/)
2623 FIND( ".dynsym", dynsym_escn
)
2624 FIND( ".dynstr", dynstr_escn
)
2625 FIND( ".symtab", symtab_escn
)
2626 FIND( ".strtab", strtab_escn
)
2627 # if defined(VGO_solaris)
2628 FIND( ".SUNW_ldynsym", ldynsym_escn
)
2631 FIND( ".gnu_debuglink", debuglink_escn
)
2632 FIND( ".gnu_debugaltlink", debugaltlink_escn
)
2634 FIND( ".debug_line", debug_line_escn
)
2635 if (!ML_(sli_is_valid
)(debug_line_escn
))
2636 FIND(".zdebug_line", debug_line_escn
)
2638 FIND( ".debug_info", debug_info_escn
)
2639 if (!ML_(sli_is_valid
)(debug_info_escn
))
2640 FIND(".zdebug_info", debug_info_escn
)
2642 FIND( ".debug_types", debug_types_escn
)
2643 if (!ML_(sli_is_valid
)(debug_types_escn
))
2644 FIND(".zdebug_types", debug_types_escn
)
2646 FIND( ".debug_abbrev", debug_abbv_escn
)
2647 if (!ML_(sli_is_valid
)(debug_abbv_escn
))
2648 FIND(".zdebug_abbrev", debug_abbv_escn
)
2650 FIND( ".debug_str", debug_str_escn
)
2651 if (!ML_(sli_is_valid
)(debug_str_escn
))
2652 FIND(".zdebug_str", debug_str_escn
)
2654 FIND( ".debug_ranges", debug_ranges_escn
)
2655 if (!ML_(sli_is_valid
)(debug_ranges_escn
))
2656 FIND(".zdebug_ranges", debug_ranges_escn
)
2658 FIND( ".debug_loc", debug_loc_escn
)
2659 if (!ML_(sli_is_valid
)(debug_loc_escn
))
2660 FIND(".zdebug_loc", debug_loc_escn
)
2662 FIND( ".debug_frame", debug_frame_escn
)
2663 if (!ML_(sli_is_valid
)(debug_frame_escn
))
2664 FIND(".zdebug_frame", debug_frame_escn
)
2666 FIND( ".debug", dwarf1d_escn
)
2667 FIND( ".line", dwarf1l_escn
)
2669 FIND( ".opd", opd_escn
)
2671 FINDX( ".eh_frame", ehframe_escn
[ehframe_mix
],
2672 do { ehframe_mix
++; vg_assert(ehframe_mix
<= N_EHFRAME_SECTS
);
2675 /* Comment_on_EH_FRAME_MULTIPLE_INSTANCES: w.r.t. .eh_frame
2676 multi-instance kludgery, how are we assured that the order
2677 in which we fill in ehframe_escn[] is consistent with the
2678 order in which we previously filled in di->ehframe_avma[]
2679 and di->ehframe_size[] ? By the fact that in both cases,
2680 these arrays were filled in by iterating over the section
2681 headers top-to-bottom. So both loops (this one and the
2682 previous one) encounter the .eh_frame entries in the same
2683 order and so fill in these arrays in a consistent order.
2688 } /* Iterate over section headers (again) */
2691 /* Now, see if we can find a debuginfo object, and if so connect
2693 vg_assert(dimg
== NULL
&& aimg
== NULL
);
2695 /* Look for a build-id */
2696 HChar
* buildid
= find_buildid(mimg
, False
, False
);
2698 /* Look for a debug image that matches either the build-id or
2699 the debuglink-CRC32 in the main image. If the main image
2700 doesn't contain either of those then this won't even bother
2701 to try looking. This looks in all known places, including
2702 the --extra-debuginfo-path if specified and on the
2703 --debuginfo-server if specified. */
2704 if (buildid
!= NULL
|| debuglink_escn
.img
!= NULL
) {
2705 /* Do have a debuglink section? */
2706 if (debuglink_escn
.img
!= NULL
) {
2708 = VG_ROUNDUP(ML_(img_strlen
)(debuglink_escn
.img
,
2709 debuglink_escn
.ioff
)+1, 4);
2710 vg_assert(crc_offset
+ sizeof(UInt
) <= debuglink_escn
.szB
);
2712 /* Extract the CRC from the debuglink section */
2713 UInt crc
= ML_(img_get_UInt
)(debuglink_escn
.img
,
2714 debuglink_escn
.ioff
+ crc_offset
);
2716 /* See if we can find a matching debug file */
2717 HChar
* debuglink_str_m
2718 = ML_(img_strdup
)(debuglink_escn
.img
,
2719 "di.redi_dlk.1", debuglink_escn
.ioff
);
2720 dimg
= find_debug_file( di
, di
->fsm
.filename
, buildid
,
2721 debuglink_str_m
, crc
, False
);
2722 if (debuglink_str_m
)
2723 ML_(dinfo_free
)(debuglink_str_m
);
2725 /* See if we can find a matching debug file */
2726 dimg
= find_debug_file( di
, di
->fsm
.filename
, buildid
,
2732 ML_(dinfo_free
)(buildid
);
2733 buildid
= NULL
; /* paranoia */
2736 /* As a last-ditch measure, try looking for in the
2737 --extra-debuginfo-path and/or on the --debuginfo-server, but
2738 only in the case where --allow-mismatched-debuginfo=yes.
2739 This is dangerous in that (1) it gives no assurance that the
2740 debuginfo object matches the main one, and hence (2) we will
2741 very likely get an assertion in the code below, if indeed
2742 there is a mismatch. Hence it is disabled by default
2743 (--allow-mismatched-debuginfo=no). Nevertheless it's
2744 sometimes a useful way of getting out of a tight spot.
2746 Note that we're ignoring the name in the .gnu_debuglink
2747 section here, and just looking for a file of the same name
2748 either the extra-path or on the server. */
2749 if (dimg
== NULL
&& VG_(clo_allow_mismatched_debuginfo
)) {
2750 dimg
= find_debug_file_ad_hoc( di
, di
->fsm
.filename
);
2754 /* If we were successful in finding a debug image, pull various
2755 SVMA/bias/size and image addresses out of it. */
2756 if (dimg
!= NULL
&& is_elf_object_file_by_DiImage(dimg
, False
)) {
2758 /* Pull out and validate program header and section header info */
2759 DiOffT ehdr_dioff
= 0;
2760 ElfXX_Ehdr ehdr_dimg
;
2761 ML_(img_get
)(&ehdr_dimg
, dimg
, ehdr_dioff
, sizeof(ehdr_dimg
));
2763 DiOffT phdr_dioff
= ehdr_dimg
.e_phoff
;
2764 UWord phdr_dnent
= ehdr_dimg
.e_phnum
;
2765 UWord phdr_dent_szB
= ehdr_dimg
.e_phentsize
;
2767 DiOffT shdr_dioff
= ehdr_dimg
.e_shoff
;
2768 UWord shdr_dnent
= ehdr_dimg
.e_shnum
;
2769 UWord shdr_dent_szB
= ehdr_dimg
.e_shentsize
;
2771 DiOffT shdr_strtab_dioff
= DiOffT_INVALID
;
2773 /* SVMAs covered by rx and rw segments and corresponding bias. */
2774 Addr rx_dsvma_limit
= 0;
2775 PtrdiffT rx_dbias
= 0;
2776 Addr rw_dsvma_limit
= 0;
2777 PtrdiffT rw_dbias
= 0;
2779 Bool need_symtab
, need_dwarf2
, need_dwarf1
;
2782 || !ML_(img_valid
)(dimg
, phdr_dioff
,
2783 phdr_dnent
* phdr_dent_szB
)) {
2784 ML_(symerr
)(di
, True
,
2785 "Missing or invalid ELF Program Header Table"
2786 " (debuginfo file)");
2791 || !ML_(img_valid
)(dimg
, shdr_dioff
,
2792 shdr_dnent
* shdr_dent_szB
)) {
2793 ML_(symerr
)(di
, True
,
2794 "Missing or invalid ELF Section Header Table"
2795 " (debuginfo file)");
2799 /* Also find the section header's string table, and validate. */
2800 /* checked previously by is_elf_object_file: */
2801 vg_assert(ehdr_dimg
.e_shstrndx
!= SHN_UNDEF
);
2803 // shdr_dioff is the offset of the section header table
2804 // and we need the ehdr_dimg.e_shstrndx'th entry
2805 { ElfXX_Shdr a_shdr
;
2806 ML_(img_get
)(&a_shdr
, dimg
,
2807 INDEX_BIS(shdr_dioff
, ehdr_dimg
.e_shstrndx
,
2810 shdr_strtab_dioff
= a_shdr
.sh_offset
;
2811 if (!ML_(img_valid
)(dimg
, shdr_strtab_dioff
,
2812 1/*bogus, but we don't know the real size*/)) {
2813 ML_(symerr
)(di
, True
,
2814 "Invalid ELF Section Header String Table"
2815 " (debuginfo file)");
2820 for (i
= 0; i
< ehdr_dimg
.e_phnum
; i
++) {
2822 ML_(img_get
)(&a_phdr
, dimg
, INDEX_BIS(ehdr_dimg
.e_phoff
,
2825 if (a_phdr
.p_type
== PT_LOAD
) {
2826 for (j
= 0; j
< VG_(sizeXA
)(di
->fsm
.maps
); j
++) {
2827 const DebugInfoMapping
* map
= VG_(indexXA
)(di
->fsm
.maps
, j
);
2828 if ( a_phdr
.p_offset
>= map
->foff
2829 && a_phdr
.p_offset
< map
->foff
+ map
->size
2830 && a_phdr
.p_offset
+ a_phdr
.p_filesz
2831 < map
->foff
+ map
->size
) {
2832 if (map
->rx
&& rx_dsvma_limit
== 0) {
2833 rx_dsvma_limit
= a_phdr
.p_vaddr
+ a_phdr
.p_memsz
;
2834 rx_dbias
= map
->avma
- map
->foff
+ a_phdr
.p_offset
2837 if (map
->rw
&& rw_dsvma_limit
== 0) {
2838 rw_dsvma_limit
= a_phdr
.p_vaddr
+ a_phdr
.p_memsz
;
2839 rw_dbias
= map
->avma
- map
->foff
+ a_phdr
.p_offset
2848 need_symtab
= (symtab_escn
.img
== NULL
);
2849 need_dwarf2
= (debug_info_escn
.img
== NULL
);
2850 need_dwarf1
= (dwarf1d_escn
.img
== NULL
);
2852 /* Find all interesting sections in the debug image */
2853 for (i
= 0; i
< ehdr_dimg
.e_shnum
; i
++) {
2855 /* Find debug svma and bias information for sections
2856 we found in the main file. */
2858 # define FIND(_sec, _seg) \
2860 ElfXX_Shdr a_shdr; \
2861 ML_(img_get)(&a_shdr, dimg, \
2862 INDEX_BIS(shdr_dioff, i, shdr_dent_szB), \
2864 if (di->_sec##_present \
2865 && 0 == ML_(img_strcmp_c)(dimg, shdr_strtab_dioff \
2866 + a_shdr.sh_name, "." #_sec)) { \
2867 vg_assert(di->_sec##_size == a_shdr.sh_size); \
2868 /* JRS 2013-Jun-01: the following assert doesn't contain */ \
2869 /* any ==s, which seems to me to be suspicious. */ \
2870 vg_assert(di->_sec##_avma + a_shdr.sh_addr + _seg##_dbias); \
2871 /* Assume we have a correct value for the main */ \
2872 /* object's bias. Use that to derive the debuginfo */ \
2873 /* object's bias, by adding the difference in SVMAs */ \
2874 /* for the corresponding sections in the two files. */ \
2875 /* That should take care of all prelinking effects. */ \
2876 di->_sec##_debug_svma = a_shdr.sh_addr; \
2877 di->_sec##_debug_bias \
2878 = di->_sec##_bias + \
2879 di->_sec##_svma - di->_sec##_debug_svma; \
2880 TRACE_SYMTAB("acquiring ." #_sec \
2881 " debug svma = %#lx .. %#lx\n", \
2882 di->_sec##_debug_svma, \
2883 di->_sec##_debug_svma + di->_sec##_size - 1); \
2884 TRACE_SYMTAB("acquiring ." #_sec " debug bias = %#lx\n", \
2885 (UWord)di->_sec##_debug_bias); \
2889 /* SECTION SEGMENT */
2899 /* Same deal as previous FIND, except only do it for those
2900 sections which we didn't find in the main file. */
2902 # define FIND(_condition, _sec_name, _sec_escn) \
2904 ElfXX_Shdr a_shdr; \
2905 ML_(img_get)(&a_shdr, dimg, \
2906 INDEX_BIS(shdr_dioff, i, shdr_dent_szB), \
2909 && 0 == ML_(img_strcmp_c)(dimg, shdr_strtab_dioff \
2910 + a_shdr.sh_name, _sec_name)) { \
2912 if (_sec_escn.img != NULL) { \
2913 ML_(symerr)(di, True, \
2914 " debuginfo section duplicates a" \
2915 " section in the main ELF file"); \
2918 _sec_escn.img = dimg; \
2919 _sec_escn.ioff = (DiOffT)a_shdr.sh_offset; \
2920 _sec_escn.szB = a_shdr.sh_size; \
2921 if (!check_compression(&a_shdr, &_sec_escn)) { \
2922 ML_(symerr)(di, True, " Compression type is unsupported"); \
2925 nobits = a_shdr.sh_type == SHT_NOBITS; \
2926 vg_assert(_sec_escn.img != NULL); \
2927 vg_assert(_sec_escn.ioff != DiOffT_INVALID); \
2928 TRACE_SYMTAB( "%-18s: dioff %llu .. %llu\n", \
2930 (ULong)a_shdr.sh_offset, \
2931 ((ULong)a_shdr.sh_offset) + a_shdr.sh_size - 1); \
2932 /* SHT_NOBITS sections have zero size in the file. */ \
2933 if (!nobits && a_shdr.sh_offset \
2934 + a_shdr.sh_size > ML_(img_real_size)(_sec_escn.img)) { \
2935 ML_(symerr)(di, True, \
2936 " section beyond image end?!"); \
2942 /* NEEDED? NAME ElfSec */
2943 FIND( need_symtab
, ".symtab", symtab_escn
)
2944 FIND( need_symtab
, ".strtab", strtab_escn
)
2945 FIND( need_dwarf2
, ".debug_line", debug_line_escn
)
2946 if (!ML_(sli_is_valid
)(debug_line_escn
))
2947 FIND(need_dwarf2
, ".zdebug_line", debug_line_escn
)
2949 FIND( need_dwarf2
, ".debug_info", debug_info_escn
)
2950 if (!ML_(sli_is_valid
)(debug_info_escn
))
2951 FIND(need_dwarf2
, ".zdebug_info", debug_info_escn
)
2953 FIND( need_dwarf2
, ".debug_types", debug_types_escn
)
2954 if (!ML_(sli_is_valid
)(debug_types_escn
))
2955 FIND(need_dwarf2
, ".zdebug_types", debug_types_escn
)
2957 FIND( need_dwarf2
, ".debug_abbrev", debug_abbv_escn
)
2958 if (!ML_(sli_is_valid
)(debug_abbv_escn
))
2959 FIND(need_dwarf2
, ".zdebug_abbrev", debug_abbv_escn
)
2961 FIND( need_dwarf2
, ".debug_str", debug_str_escn
)
2962 if (!ML_(sli_is_valid
)(debug_str_escn
))
2963 FIND(need_dwarf2
, ".zdebug_str", debug_str_escn
)
2965 FIND( need_dwarf2
, ".debug_ranges", debug_ranges_escn
)
2966 if (!ML_(sli_is_valid
)(debug_ranges_escn
))
2967 FIND(need_dwarf2
, ".zdebug_ranges", debug_ranges_escn
)
2969 FIND( need_dwarf2
, ".debug_loc", debug_loc_escn
)
2970 if (!ML_(sli_is_valid
)(debug_loc_escn
))
2971 FIND(need_dwarf2
, ".zdebug_loc", debug_loc_escn
)
2973 FIND( need_dwarf2
, ".debug_frame", debug_frame_escn
)
2974 if (!ML_(sli_is_valid
)(debug_frame_escn
))
2975 FIND(need_dwarf2
, ".zdebug_frame", debug_frame_escn
)
2977 FIND( need_dwarf2
, ".gnu_debugaltlink", debugaltlink_escn
)
2979 FIND( need_dwarf1
, ".debug", dwarf1d_escn
)
2980 FIND( need_dwarf1
, ".line", dwarf1l_escn
)
2983 } /* Find all interesting sections */
2984 } /* do we have a debug image? */
2987 /* Look for alternate debug image, and if found, connect |aimg|
2989 vg_assert(aimg
== NULL
);
2991 if (debugaltlink_escn
.img
!= NULL
) {
2992 HChar
* altfile_str_m
2993 = ML_(img_strdup
)(debugaltlink_escn
.img
,
2994 "di.fbi.3", debugaltlink_escn
.ioff
);
2995 UInt buildid_offset
= ML_(img_strlen
)(debugaltlink_escn
.img
,
2996 debugaltlink_escn
.ioff
)+1;
2998 vg_assert(buildid_offset
< debugaltlink_escn
.szB
);
3001 = ML_(dinfo_zalloc
)("di.fbi.4",
3002 (debugaltlink_escn
.szB
- buildid_offset
)
3005 /* The altfile might be relative to the debug file or main file.
3006 Make sure that we got the real file, not a symlink. */
3007 HChar
*dbgname
= di
->fsm
.dbgname
? di
->fsm
.dbgname
: di
->fsm
.filename
;
3008 HChar
* rdbgname
= readlink_path (dbgname
);
3009 if (rdbgname
== NULL
)
3010 rdbgname
= ML_(dinfo_strdup
)("rdbgname", dbgname
);
3012 for (j
= 0; j
< debugaltlink_escn
.szB
- buildid_offset
; j
++)
3014 altbuildid
+ 2 * j
, "%02x",
3015 (UInt
)ML_(img_get_UChar
)(debugaltlink_escn
.img
,
3016 debugaltlink_escn
.ioff
3017 + buildid_offset
+ j
));
3019 /* See if we can find a matching debug file */
3020 aimg
= find_debug_file( di
, rdbgname
, altbuildid
,
3021 altfile_str_m
, 0, True
);
3023 ML_(dinfo_free
)(rdbgname
);
3026 ML_(dinfo_free
)(altfile_str_m
);
3027 ML_(dinfo_free
)(altbuildid
);
3031 /* If we were successful in finding alternate debug image, pull various
3032 size and image addresses out of it. */
3033 if (aimg
!= NULL
&& is_elf_object_file_by_DiImage(aimg
, True
)) {
3035 /* Pull out and validate program header and section header info */
3036 DiOffT ehdr_aioff
= 0;
3037 ElfXX_Ehdr ehdr_aimg
;
3038 ML_(img_get
)(&ehdr_aimg
, aimg
, ehdr_aioff
, sizeof(ehdr_aimg
));
3040 DiOffT shdr_aioff
= ehdr_aimg
.e_shoff
;
3041 UWord shdr_anent
= ehdr_aimg
.e_shnum
;
3042 UWord shdr_aent_szB
= ehdr_aimg
.e_shentsize
;
3044 DiOffT shdr_strtab_aioff
= DiOffT_INVALID
;
3047 || !ML_(img_valid
)(aimg
, shdr_aioff
,
3048 shdr_anent
* shdr_aent_szB
)) {
3049 ML_(symerr
)(di
, True
,
3050 "Missing or invalid ELF Section Header Table"
3051 " (alternate debuginfo file)");
3055 /* Also find the section header's string table, and validate. */
3056 /* checked previously by is_elf_object_file: */
3057 vg_assert(ehdr_aimg
.e_shstrndx
!= SHN_UNDEF
);
3059 // shdr_aioff is the offset of the section header table
3060 // and we need the ehdr_aimg.e_shstrndx'th entry
3061 { ElfXX_Shdr a_shdr
;
3062 ML_(img_get
)(&a_shdr
, aimg
,
3063 INDEX_BIS(shdr_aioff
, ehdr_aimg
.e_shstrndx
,
3066 shdr_strtab_aioff
= a_shdr
.sh_offset
;
3067 if (!ML_(img_valid
)(aimg
, shdr_strtab_aioff
,
3068 1/*bogus, but we don't know the real size*/)) {
3069 ML_(symerr
)(di
, True
,
3070 "Invalid ELF Section Header String Table"
3071 " (alternate debuginfo file)");
3076 /* Find all interesting sections */
3077 for (i
= 0; i
< ehdr_aimg
.e_shnum
; i
++) {
3079 # define FIND(_sec_name, _sec_escn) \
3081 ElfXX_Shdr a_shdr; \
3082 ML_(img_get)(&a_shdr, aimg, \
3083 INDEX_BIS(shdr_aioff, i, shdr_aent_szB), \
3085 if (0 == ML_(img_strcmp_c)(aimg, shdr_strtab_aioff \
3086 + a_shdr.sh_name, _sec_name)) { \
3087 if (_sec_escn.img != NULL) { \
3088 ML_(symerr)(di, True, \
3089 " alternate debuginfo section duplicates a" \
3090 " section in the main ELF file"); \
3093 _sec_escn.img = aimg; \
3094 _sec_escn.ioff = (DiOffT)a_shdr.sh_offset; \
3095 _sec_escn.szB = a_shdr.sh_size; \
3096 if (!check_compression(&a_shdr, &_sec_escn)) { \
3097 ML_(symerr)(di, True, " Compression type is " \
3101 vg_assert(_sec_escn.img != NULL); \
3102 vg_assert(_sec_escn.ioff != DiOffT_INVALID); \
3103 TRACE_SYMTAB( "%-18s: aioff %llu .. %llu\n", \
3105 (ULong)a_shdr.sh_offset, \
3106 ((ULong)a_shdr.sh_offset) + a_shdr.sh_size - 1); \
3111 FIND(".debug_line", debug_line_alt_escn
)
3112 if (!ML_(sli_is_valid
)(debug_line_alt_escn
))
3113 FIND(".zdebug_line", debug_line_alt_escn
)
3115 FIND(".debug_info", debug_info_alt_escn
)
3116 if (!ML_(sli_is_valid
)(debug_info_alt_escn
))
3117 FIND(".zdebug_info", debug_info_alt_escn
)
3119 FIND(".debug_abbrev", debug_abbv_alt_escn
)
3120 if (!ML_(sli_is_valid
)(debug_abbv_alt_escn
))
3121 FIND(".zdebug_abbrev", debug_abbv_alt_escn
)
3123 FIND(".debug_str", debug_str_alt_escn
)
3124 if (!ML_(sli_is_valid
)(debug_str_alt_escn
))
3125 FIND(".zdebug_str", debug_str_alt_escn
)
3128 } /* Find all interesting sections */
3129 } /* do we have a debug image? */
3133 /* Check some sizes */
3134 vg_assert((dynsym_escn
.szB
% sizeof(ElfXX_Sym
)) == 0);
3135 vg_assert((symtab_escn
.szB
% sizeof(ElfXX_Sym
)) == 0);
3136 # if defined(VGO_solaris)
3137 vg_assert((ldynsym_escn
.szB
% sizeof(ElfXX_Sym
)) == 0);
3143 void (*read_elf_symtab
)(struct _DebugInfo
*, const HChar
*,
3144 DiSlice
*, DiSlice
*, DiSlice
*, Bool
);
3145 Bool symtab_in_debug
;
3146 # if defined(VGP_ppc64be_linux)
3147 read_elf_symtab
= read_elf_symtab__ppc64be_linux
;
3149 read_elf_symtab
= read_elf_symtab__normal
;
3151 symtab_in_debug
= symtab_escn
.img
== dimg
;
3152 read_elf_symtab(di
, "symbol table",
3153 &symtab_escn
, &strtab_escn
, &opd_escn
,
3155 read_elf_symtab(di
, "dynamic symbol table",
3156 &dynsym_escn
, &dynstr_escn
, &opd_escn
,
3158 # if defined(VGO_solaris)
3159 read_elf_symtab(di
, "local dynamic symbol table",
3160 &ldynsym_escn
, &dynstr_escn
, &opd_escn
,
3166 /* Read .eh_frame and .debug_frame (call-frame-info) if any. Do
3167 the .eh_frame section(s) first. */
3168 vg_assert(di
->n_ehframe
>= 0 && di
->n_ehframe
<= N_EHFRAME_SECTS
);
3169 for (i
= 0; i
< di
->n_ehframe
; i
++) {
3170 /* see Comment_on_EH_FRAME_MULTIPLE_INSTANCES above for why
3171 this next assertion should hold. */
3172 vg_assert(ML_(sli_is_valid
)(ehframe_escn
[i
]));
3173 vg_assert(ehframe_escn
[i
].szB
== di
->ehframe_size
[i
]);
3174 ML_(read_callframe_info_dwarf3
)( di
,
3176 di
->ehframe_avma
[i
],
3177 True
/*is_ehframe*/ );
3179 if (ML_(sli_is_valid
)(debug_frame_escn
)) {
3180 ML_(read_callframe_info_dwarf3
)( di
,
3182 0/*assume zero avma*/,
3183 False
/*!is_ehframe*/ );
3187 /* jrs 2006-01-01: icc-8.1 has been observed to generate
3188 binaries without debug_str sections. Don't preclude
3189 debuginfo reading for that reason, but, in
3190 read_unitinfo_dwarf2, do check that debugstr is non-NULL
3192 if (ML_(sli_is_valid
)(debug_info_escn
)
3193 && ML_(sli_is_valid
)(debug_abbv_escn
)
3194 && ML_(sli_is_valid
)(debug_line_escn
)) {
3195 /* The old reader: line numbers and unwind info only */
3196 ML_(read_debuginfo_dwarf3
) ( di
,
3202 debug_str_alt_escn
);
3203 /* The new reader: read the DIEs in .debug_info to acquire
3204 information on variable types and locations or inline info.
3205 But only if the tool asks for it, or the user requests it on
3206 the command line. */
3207 if (VG_(clo_read_var_info
) /* the user or tool asked for it */
3208 || VG_(clo_read_inline_info
)) {
3209 ML_(new_dwarf3_reader
)(
3210 di
, debug_info_escn
, debug_types_escn
,
3211 debug_abbv_escn
, debug_line_escn
,
3212 debug_str_escn
, debug_ranges_escn
,
3213 debug_loc_escn
, debug_info_alt_escn
,
3214 debug_abbv_alt_escn
, debug_line_alt_escn
,
3221 // JRS 31 July 2014: dwarf-1 reading is currently broken and
3222 // therefore deactivated.
3223 //if (dwarf1d_img && dwarf1l_img) {
3224 // ML_(read_debuginfo_dwarf1) ( di, dwarf1d_img, dwarf1d_sz,
3225 // dwarf1l_img, dwarf1l_sz );
3228 # if defined(VGA_arm)
3230 /* ARM32 only: read .exidx/.extab if present. Note we are
3231 reading these directly out of the mapped in (running) image.
3232 Also, read these only if no CFI based unwind info was
3233 acquired for this file.
3235 An .exidx section is always required, but the .extab section
3236 can be optionally omitted, provided that .exidx does not
3237 refer to it. If the .exidx is erroneous and does refer to
3238 .extab even though .extab is missing, the range checks done
3239 by GET_EX_U32 in ExtabEntryExtract in readexidx.c should
3240 prevent any invalid memory accesses, and cause the .extab to
3241 be rejected as invalid.
3244 * check with m_aspacemgr that the entire [exidx_avma, +exidx_size)
3245 and [extab_avma, +extab_size) areas are readable, since we're
3246 reading this stuff out of the running image (not from a file/socket)
3247 and we don't want to segfault.
3248 * DebugInfo::exidx_bias and use text_bias instead.
3249 I think it's always the same.
3250 * remove DebugInfo::{extab_bias, exidx_svma, extab_svma} since
3251 they are never used.
3253 if (di
->exidx_present
3254 && di
->cfsi_used
== 0
3255 && di
->text_present
&& di
->text_size
> 0) {
3256 Addr text_last_svma
= di
->text_svma
+ di
->text_size
- 1;
3257 ML_(read_exidx
)( di
, (UChar
*)di
->exidx_avma
, di
->exidx_size
,
3258 (UChar
*)di
->extab_avma
, di
->extab_size
,
3262 # endif /* defined(VGA_arm) */
3264 } /* "Find interesting sections, read the symbol table(s), read any debug
3265 information" (a local scope) */
3270 /* If reading Dwarf3 variable type/location info, print a line
3271 showing the number of variables read for each object.
3272 (Currently disabled -- is a sanity-check mechanism for
3274 if (0 && VG_(clo_read_var_info
)) {
3277 for (j
= 0; j
< VG_(sizeXA
)(di
->varinfo
); j
++) {
3278 OSet
* /* of DiAddrRange */ scope
3279 = *(OSet
**)VG_(indexXA
)(di
->varinfo
, j
);
3281 VG_(OSetGen_ResetIter
)( scope
);
3283 DiAddrRange
* range
= VG_(OSetGen_Next
)( scope
);
3285 vg_assert(range
->vars
);
3286 Word w
= VG_(sizeXA
)(range
->vars
);
3288 if (0) VG_(printf
)("range %#lx %#lx %ld\n",
3289 range
->aMin
, range
->aMax
, w
);
3294 VG_(umsg
)("VARINFO: %7lu vars %7lu text_size %s\n",
3295 nVars
, di
->text_size
, di
->fsm
.filename
);
3301 /* Last, but not least, detach from the image(s). */
3302 if (mimg
) ML_(img_done
)(mimg
);
3303 if (dimg
) ML_(img_done
)(dimg
);
3304 if (aimg
) ML_(img_done
)(aimg
);
3306 if (svma_ranges
) VG_(deleteXA
)(svma_ranges
);
3314 #endif // defined(VGO_linux) || defined(VGO_solaris)
3316 /*--------------------------------------------------------------------*/
3318 /*--------------------------------------------------------------------*/