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, see <http://www.gnu.org/licenses/>.
27 The GNU General Public License is contained in the file COPYING.
30 #if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd)
32 #include "pub_core_basics.h"
33 #include "pub_core_vki.h"
34 #include "pub_core_vkiscnums.h"
35 #include "pub_core_debuginfo.h"
36 #include "pub_core_libcbase.h"
37 #include "pub_core_libcprint.h"
38 #include "pub_core_libcassert.h"
39 #include "pub_core_libcfile.h"
40 #include "pub_core_libcproc.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_pathscan.h" /* find_executable */
45 #include "pub_core_syscall.h"
46 #include "pub_core_tooliface.h" /* VG_(needs) */
47 #include "pub_core_xarray.h"
48 #include "pub_core_libcproc.h"
49 #include "priv_misc.h" /* dinfo_zalloc/free/strdup */
50 #include "priv_image.h"
51 #include "priv_d3basics.h"
52 #include "priv_tytypes.h"
53 #include "priv_storage.h"
54 #include "priv_readelf.h" /* self */
55 #include "priv_readdwarf.h" /* 'cos ELF contains DWARF */
56 #include "priv_readdwarf3.h"
57 #include "priv_readexidx.h"
60 /* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
62 #if defined(VGO_solaris)
63 #include <sys/link.h> /* ElfXX_Dyn, DT_* */
65 /* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
67 #if !defined(HAVE_ELF32_CHDR)
71 Elf32_Word ch_addralign
;
75 #if !defined(HAVE_ELF64_CHDR)
78 Elf64_Word ch_reserved
;
80 Elf64_Xword ch_addralign
;
84 #if !defined(SHF_COMPRESSED)
85 #define SHF_COMPRESSED (1 << 11)
88 #if !defined(ELFCOMPRESS_ZLIB)
89 #define ELFCOMPRESS_ZLIB 1
92 #define SIZE_OF_ZLIB_HEADER 12
94 /*------------------------------------------------------------*/
95 /*--- 32/64-bit parameterisation ---*/
96 /*------------------------------------------------------------*/
98 /* For all the ELF macros and types which specify '32' or '64',
99 select the correct variant for this platform and give it
100 an 'XX' name. Then use the 'XX' variant consistently in
101 the rest of this file.
104 # define ElfXX_Ehdr Elf32_Ehdr
105 # define ElfXX_Shdr Elf32_Shdr
106 # define ElfXX_Phdr Elf32_Phdr
107 # define ElfXX_Nhdr Elf32_Nhdr
108 # define ElfXX_Sym Elf32_Sym
109 # define ElfXX_Off Elf32_Off
110 # define ElfXX_Word Elf32_Word
111 # define ElfXX_Addr Elf32_Addr
112 # define ElfXX_Dyn Elf32_Dyn
113 # define ELFXX_ST_BIND ELF32_ST_BIND
114 # define ELFXX_ST_TYPE ELF32_ST_TYPE
115 # define ElfXX_Chdr Elf32_Chdr
117 #elif VG_WORDSIZE == 8
118 # define ElfXX_Ehdr Elf64_Ehdr
119 # define ElfXX_Shdr Elf64_Shdr
120 # define ElfXX_Phdr Elf64_Phdr
121 # define ElfXX_Nhdr Elf64_Nhdr
122 # define ElfXX_Sym Elf64_Sym
123 # define ElfXX_Off Elf64_Off
124 # define ElfXX_Word Elf64_Word
125 # define ElfXX_Addr Elf64_Addr
126 # define ElfXX_Dyn Elf64_Dyn
127 # define ELFXX_ST_BIND ELF64_ST_BIND
128 # define ELFXX_ST_TYPE ELF64_ST_TYPE
129 # define ElfXX_Chdr Elf64_Chdr
132 # error "VG_WORDSIZE should be 4 or 8"
136 /*------------------------------------------------------------*/
138 /*--- Read symbol table and line info from ELF files. ---*/
140 /*------------------------------------------------------------*/
142 /* readelf.c parses ELF files and acquires symbol table info from
143 them. It calls onwards to readdwarf.c to read DWARF2/3 line number
144 and call frame info found. */
146 /* Identify an ELF object file by peering at the first few bytes of
149 Bool
ML_(is_elf_object_file
)( const void* image
, SizeT n_image
, Bool rel_ok
)
151 const ElfXX_Ehdr
* ehdr
= image
;
154 if (n_image
< sizeof(ElfXX_Ehdr
))
157 ok
&= (ehdr
->e_ident
[EI_MAG0
] == 0x7F
158 && ehdr
->e_ident
[EI_MAG1
] == 'E'
159 && ehdr
->e_ident
[EI_MAG2
] == 'L'
160 && ehdr
->e_ident
[EI_MAG3
] == 'F');
161 ok
&= (ehdr
->e_ident
[EI_CLASS
] == VG_ELF_CLASS
162 && ehdr
->e_ident
[EI_DATA
] == VG_ELF_DATA2XXX
163 && ehdr
->e_ident
[EI_VERSION
] == EV_CURRENT
);
164 ok
&= (ehdr
->e_type
== ET_EXEC
|| ehdr
->e_type
== ET_DYN
165 || (rel_ok
&& ehdr
->e_type
== ET_REL
));
166 ok
&= (ehdr
->e_machine
== VG_ELF_MACHINE
);
167 ok
&= (ehdr
->e_version
== EV_CURRENT
);
168 ok
&= (ehdr
->e_shstrndx
!= SHN_UNDEF
);
169 ok
&= (ehdr
->e_shoff
!= 0 && ehdr
->e_shnum
!= 0);
170 ok
&= ((ehdr
->e_phoff
!= 0 && ehdr
->e_phnum
!= 0)
171 || ehdr
->e_type
== ET_REL
);
173 return ok
? True
: False
;
177 /* The same thing, but operating on a DiImage instead. */
179 static Bool
is_elf_object_file_by_DiImage( DiImage
* img
, Bool rel_ok
)
181 /* Be sure this doesn't make the frame too big. */
182 vg_assert(sizeof(ElfXX_Ehdr
) <= 512);
185 if (!ML_(img_valid
)(img
, 0, sizeof(ehdr
)))
188 ML_(img_get
)(&ehdr
, img
, 0, sizeof(ehdr
));
189 return ML_(is_elf_object_file
)( &ehdr
, sizeof(ehdr
), rel_ok
);
193 /* Show a raw ELF symbol, given its in-image address and name. */
196 void show_raw_elf_symbol ( DiImage
* strtab_img
,
198 const ElfXX_Sym
* sym
,
199 DiOffT sym_name_ioff
, Addr sym_svma
,
200 Bool ppc64_linux_format
)
202 const HChar
* space
= ppc64_linux_format
? " " : "";
203 VG_(printf
)("raw symbol [%4d]: ", i
);
204 switch (ELFXX_ST_BIND(sym
->st_info
)) {
205 case STB_LOCAL
: VG_(printf
)("LOC "); break;
206 case STB_GLOBAL
: VG_(printf
)("GLO "); break;
207 case STB_WEAK
: VG_(printf
)("WEA "); break;
208 case STB_LOPROC
: VG_(printf
)("lop "); break;
209 case STB_HIPROC
: VG_(printf
)("hip "); break;
210 default: VG_(printf
)("??? "); break;
212 switch (ELFXX_ST_TYPE(sym
->st_info
)) {
213 case STT_NOTYPE
: VG_(printf
)("NOT "); break;
214 case STT_OBJECT
: VG_(printf
)("OBJ "); break;
215 case STT_FUNC
: VG_(printf
)("FUN "); break;
216 case STT_SECTION
: VG_(printf
)("SEC "); break;
217 case STT_FILE
: VG_(printf
)("FIL "); break;
218 case STT_LOPROC
: VG_(printf
)("lop "); break;
219 case STT_HIPROC
: VG_(printf
)("hip "); break;
220 default: VG_(printf
)("??? "); break;
222 HChar
* sym_name
= NULL
;
224 sym_name
= ML_(img_strdup
)(strtab_img
, "di.sres.1", sym_name_ioff
);
225 VG_(printf
)(": svma %#010lx, %ssz %4llu %s\n",
226 sym_svma
, space
, (ULong
)(sym
->st_size
+ 0UL),
227 (sym_name
? sym_name
: "NONAME") );
229 ML_(dinfo_free
)(sym_name
);
233 /* Decide whether SYM is something we should collect, and if so, copy
234 relevant info to the _OUT arguments. For {x86,amd64,ppc32}-linux
235 this is straightforward - the name, address, size are copied out
238 There is a bit of a kludge re data symbols (see KLUDGED BSS CHECK
239 below): we assume that the .bss is mapped immediately after .data,
240 and so accept any data symbol which exists in the range [start of
241 .data, size of .data + size of .bss). I don't know if this is
242 really correct/justifiable, or not.
244 For ppc64be-linux it's more complex. If the symbol is seen to be in
245 the .opd section, it is taken to be a function descriptor, and so
246 a dereference is attempted, in order to get hold of the real entry
247 point address. Also as part of the dereference, there is an attempt
248 to calculate the TOC pointer (R2 value) associated with the symbol.
250 To support the ppc64be-linux pre-"dotless" ABI (prior to gcc 4.0.0),
251 if the symbol is seen to be outside the .opd section and its name
252 starts with a dot, an .opd deference is not attempted, and no TOC
253 pointer is calculated, but the leading dot is removed from the
256 As a result, on ppc64be-linux, the caller of this function may have
257 to piece together the real size, address, name of the symbol from
258 multiple calls to this function. Ugly and confusing.
261 Bool
get_elf_symbol_info (
263 struct _DebugInfo
* di
, /* containing DebugInfo */
264 const ElfXX_Sym
* sym
, /* ELF symbol */
265 DiOffT sym_name_ioff
, /* name, may be absent (DiOffT_INVALID) */
266 const DiSlice
* escn_strtab
, /* holds the name */
267 Addr sym_svma
, /* address as stated in the object file */
268 Bool symtab_in_debug
, /* symbol table is in the debug file */
269 const DiSlice
* escn_opd
, /* the .opd (ppc64be-linux only) */
270 PtrdiffT opd_bias
, /* for biasing AVMAs found in .opd */
272 DiOffT
* sym_name_out_ioff
, /* name (in strtab) we should record */
273 SymAVMAs
* sym_avmas_out
, /* sym avmas we should record */
274 Int
* sym_size_out
, /* symbol size */
275 Bool
* from_opd_out
, /* ppc64be-linux only: did we deref an
277 Bool
* is_text_out
, /* is this a text symbol? */
278 Bool
* is_ifunc_out
, /* is this a STT_GNU_IFUNC function ?*/
279 Bool
* is_global_out
/* is this a global symbol ?*/
283 # if defined(VGP_ppc64be_linux)
286 Bool in_text
, in_data
, in_sdata
, in_rodata
, in_bss
, in_sbss
;
287 Addr text_svma
, data_svma
, sdata_svma
, rodata_svma
, bss_svma
, sbss_svma
;
288 PtrdiffT text_bias
, data_bias
, sdata_bias
, rodata_bias
, bss_bias
, sbss_bias
;
289 # if defined(VGPV_arm_linux_android) \
290 || defined(VGPV_x86_linux_android) \
291 || defined(VGPV_mips32_linux_android) \
292 || defined(VGPV_arm64_linux_android)
293 Addr available_size
= 0;
294 #define COMPUTE_AVAILABLE_SIZE(segsvma, segsize) \
295 available_size = segsvma + segsize - sym_svma
297 #define COMPUTE_AVAILABLE_SIZE(segsvma, segsize)
301 *sym_name_out_ioff
= sym_name_ioff
;
302 (*sym_avmas_out
).main
= sym_svma
; /* we will bias this shortly */
304 SET_TOCPTR_AVMA(*sym_avmas_out
, 0); /* default to unknown/inapplicable */
305 SET_LOCAL_EP_AVMA(*sym_avmas_out
, 0); /* default to unknown/inapplicable */
306 *from_opd_out
= False
;
307 *is_ifunc_out
= False
;
308 *is_global_out
= False
;
310 /* Get the symbol size, but restrict it to fit in a signed 32 bit
311 int. Also, deal with the stupid case of negative size by making
312 the size be 1. Note that sym->st_size has type UWord,
314 { Word size_tmp
= (Word
)sym
->st_size
;
315 Word max_Int
= (1LL << 31) - 1;
316 if (size_tmp
< 0) size_tmp
= 1;
317 if (size_tmp
> max_Int
) size_tmp
= max_Int
;
318 *sym_size_out
= (Int
)size_tmp
;
320 /* After this point refer only to *sym_size_out and not to
323 /* Figure out if we're interested in the symbol. Firstly, is it of
324 the right flavour? */
326 = (ELFXX_ST_BIND(sym
->st_info
) == STB_GLOBAL
327 || ELFXX_ST_BIND(sym
->st_info
) == STB_LOCAL
328 || ELFXX_ST_BIND(sym
->st_info
) == STB_WEAK
331 (ELFXX_ST_TYPE(sym
->st_info
) == STT_FUNC
332 || ELFXX_ST_TYPE(sym
->st_info
) == STT_OBJECT
333 # ifdef STT_GNU_IFUNC
334 || ELFXX_ST_TYPE(sym
->st_info
) == STT_GNU_IFUNC
338 /* Work out the svma and bias for each section as it will appear in
339 addresses in the symbol table. */
340 if (symtab_in_debug
) {
341 text_svma
= di
->text_debug_svma
;
342 text_bias
= di
->text_debug_bias
;
343 data_svma
= di
->data_debug_svma
;
344 data_bias
= di
->data_debug_bias
;
345 sdata_svma
= di
->sdata_debug_svma
;
346 sdata_bias
= di
->sdata_debug_bias
;
347 rodata_svma
= di
->rodata_debug_svma
;
348 rodata_bias
= di
->rodata_debug_bias
;
349 bss_svma
= di
->bss_debug_svma
;
350 bss_bias
= di
->bss_debug_bias
;
351 sbss_svma
= di
->sbss_debug_svma
;
352 sbss_bias
= di
->sbss_debug_bias
;
354 text_svma
= di
->text_svma
;
355 text_bias
= di
->text_bias
;
356 data_svma
= di
->data_svma
;
357 data_bias
= di
->data_bias
;
358 sdata_svma
= di
->sdata_svma
;
359 sdata_bias
= di
->sdata_bias
;
360 rodata_svma
= di
->rodata_svma
;
361 rodata_bias
= di
->rodata_bias
;
362 bss_svma
= di
->bss_svma
;
363 bss_bias
= di
->bss_bias
;
364 sbss_svma
= di
->sbss_svma
;
365 sbss_bias
= di
->sbss_bias
;
368 /* Now bias (*sym_avmas_out).main accordingly by figuring out exactly which
369 section the symbol is from and bias accordingly. Screws up if
370 the previously deduced section svma address ranges are wrong. */
373 && sym_svma
>= text_svma
374 && sym_svma
< text_svma
+ di
->text_size
) {
376 (*sym_avmas_out
).main
+= text_bias
;
377 COMPUTE_AVAILABLE_SIZE(text_svma
, di
->text_size
);
381 && sym_svma
>= data_svma
382 && sym_svma
< data_svma
+ di
->data_size
) {
383 *is_text_out
= False
;
384 (*sym_avmas_out
).main
+= data_bias
;
385 COMPUTE_AVAILABLE_SIZE(data_svma
, di
->data_size
);
387 if (di
->sdata_present
388 && di
->sdata_size
> 0
389 && sym_svma
>= sdata_svma
390 && sym_svma
< sdata_svma
+ di
->sdata_size
) {
391 *is_text_out
= False
;
392 (*sym_avmas_out
).main
+= sdata_bias
;
393 COMPUTE_AVAILABLE_SIZE(sdata_svma
, di
->sdata_size
);
395 if (di
->rodata_present
396 && di
->rodata_size
> 0
397 && sym_svma
>= rodata_svma
398 && sym_svma
< rodata_svma
+ di
->rodata_size
) {
399 *is_text_out
= False
;
400 (*sym_avmas_out
).main
+= rodata_bias
;
401 COMPUTE_AVAILABLE_SIZE(rodata_svma
, di
->rodata_size
);
405 && sym_svma
>= bss_svma
406 && sym_svma
< bss_svma
+ di
->bss_size
) {
407 *is_text_out
= False
;
408 (*sym_avmas_out
).main
+= bss_bias
;
409 COMPUTE_AVAILABLE_SIZE(bss_svma
, di
->bss_size
);
413 && sym_svma
>= sbss_svma
414 && sym_svma
< sbss_svma
+ di
->sbss_size
) {
415 *is_text_out
= False
;
416 (*sym_avmas_out
).main
+= sbss_bias
;
417 COMPUTE_AVAILABLE_SIZE(sbss_svma
, di
->sbss_size
);
419 /* Assume it's in .text. Is this a good idea? */
421 (*sym_avmas_out
).main
+= text_bias
;
424 # ifdef STT_GNU_IFUNC
425 /* Check for indirect functions. */
427 && ELFXX_ST_TYPE(sym
->st_info
) == STT_GNU_IFUNC
) {
428 *is_ifunc_out
= True
;
432 if (ELFXX_ST_BIND(sym
->st_info
) == STB_GLOBAL
433 || ELFXX_ST_BIND(sym
->st_info
) == STB_WEAK
) {
434 *is_global_out
= True
;
437 # if defined(VGP_ppc64be_linux)
438 /* Allow STT_NOTYPE in the very special case where we're running on
439 ppc64be-linux and the symbol is one which the .opd-chasing hack
443 && ELFXX_ST_TYPE(sym
->st_info
) == STT_NOTYPE
447 && (*sym_avmas_out
).main
>= di
->opd_avma
448 && (*sym_avmas_out
).main
< di
->opd_avma
+ di
->opd_size
)
455 /* Ignore if nameless. */
456 if (sym_name_ioff
== DiOffT_INVALID
457 || /* VG_(strlen)(sym_name) == 0 */
458 /* equivalent but cheaper ... */
459 ML_(img_get_UChar
)(escn_strtab
->img
, sym_name_ioff
) == '\0') {
460 if (TRACE_SYMTAB_ENABLED
) {
461 HChar
* sym_name
= ML_(img_strdup
)(escn_strtab
->img
,
462 "di.gesi.1", sym_name_ioff
);
463 TRACE_SYMTAB(" ignore -- nameless: %s\n", sym_name
);
464 if (sym_name
) ML_(dinfo_free
)(sym_name
);
469 /* Ignore if zero-sized. Except on Android:
471 On Android 2.3.5, some of the symbols that Memcheck needs to
472 intercept (for noise reduction purposes) have zero size, due to
473 lack of .size directives in handwritten assembly sources. So we
474 can't reject them out of hand -- instead give them a bogusly
475 large size and let canonicaliseSymtab trim them so they don't
476 overlap any following symbols. At least the following symbols
477 are known to be affected:
479 in /system/lib/libc.so: strlen strcmp strcpy memcmp memcpy
480 in /system/bin/linker: __dl_strcmp __dl_strlen
482 if (*sym_size_out
== 0) {
483 # if defined(VGPV_arm_linux_android) \
484 || defined(VGPV_x86_linux_android) \
485 || defined(VGPV_mips32_linux_android) \
486 || defined(VGPV_arm64_linux_android)
487 *sym_size_out
= available_size
? available_size
: 2048;
489 if (TRACE_SYMTAB_ENABLED
) {
490 HChar
* sym_name
= ML_(img_strdup
)(escn_strtab
->img
,
491 "di.gesi.2", sym_name_ioff
);
492 TRACE_SYMTAB(" ignore -- size=0: %s\n", sym_name
);
493 if (sym_name
) ML_(dinfo_free
)(sym_name
);
499 /* This seems to significantly reduce the number of junk
500 symbols, and particularly reduces the number of
501 overlapping address ranges. Don't ask me why ... */
502 if ((Int
)sym
->st_value
== 0) {
503 if (TRACE_SYMTAB_ENABLED
) {
504 HChar
* sym_name
= ML_(img_strdup
)(escn_strtab
->img
,
505 "di.gesi.3", sym_name_ioff
);
506 TRACE_SYMTAB( " ignore -- valu=0: %s\n", sym_name
);
507 if (sym_name
) ML_(dinfo_free
)(sym_name
);
512 /* If it's apparently in a GOT or PLT, it's really a reference to a
513 symbol defined elsewhere, so ignore it. */
516 && (*sym_avmas_out
).main
>= di
->got_avma
517 && (*sym_avmas_out
).main
< di
->got_avma
+ di
->got_size
) {
518 if (TRACE_SYMTAB_ENABLED
) {
519 HChar
* sym_name
= ML_(img_strdup
)(escn_strtab
->img
,
520 "di.gesi.4", sym_name_ioff
);
521 TRACE_SYMTAB(" ignore -- in GOT: %s\n", sym_name
);
522 if (sym_name
) ML_(dinfo_free
)(sym_name
);
528 && (*sym_avmas_out
).main
>= di
->plt_avma
529 && (*sym_avmas_out
).main
< di
->plt_avma
+ di
->plt_size
) {
530 if (TRACE_SYMTAB_ENABLED
) {
531 HChar
* sym_name
= ML_(img_strdup
)(escn_strtab
->img
,
532 "di.gesi.5", sym_name_ioff
);
533 TRACE_SYMTAB(" ignore -- in PLT: %s\n", sym_name
);
534 if (sym_name
) ML_(dinfo_free
)(sym_name
);
539 /* ppc64be-linux nasty hack: if the symbol is in an .opd section,
540 then really what we have is the address of a function
541 descriptor. So use the first word of that as the function's
544 See thread starting at
545 http://gcc.gnu.org/ml/gcc-patches/2004-08/msg00557.html
547 # if defined(VGP_ppc64be_linux)
548 /* Host and guest may have different Endianness, used by BE only */
554 && (*sym_avmas_out
).main
>= di
->opd_avma
555 && (*sym_avmas_out
).main
< di
->opd_avma
+ di
->opd_size
) {
556 # if !defined(VGP_ppc64be_linux)
557 if (TRACE_SYMTAB_ENABLED
) {
558 HChar
* sym_name
= ML_(img_strdup
)(escn_strtab
->img
,
559 "di.gesi.6", sym_name_ioff
);
560 TRACE_SYMTAB(" ignore -- in OPD: %s\n", sym_name
);
561 if (sym_name
) ML_(dinfo_free
)(sym_name
);
566 Bool details
= 1||False
;
569 TRACE_SYMTAB("opdXXX: opd_bias %p, sym_svma_out %p\n",
570 (void*)(opd_bias
), (void*)(*sym_avmas_out
).main
);
572 if (!VG_IS_8_ALIGNED((*sym_avmas_out
).main
)) {
573 if (TRACE_SYMTAB_ENABLED
) {
574 HChar
* sym_name
= ML_(img_strdup
)(escn_strtab
->img
,
575 "di.gesi.6a", sym_name_ioff
);
576 TRACE_SYMTAB(" ignore -- not 8-aligned: %s\n", sym_name
);
577 if (sym_name
) ML_(dinfo_free
)(sym_name
);
582 /* (*sym_avmas_out).main is a avma pointing into the .opd section. We
583 know the vma of the opd section start, so we can figure out
584 how far into the opd section this is. */
586 offset_in_opd
= (Addr
)(*sym_avmas_out
).main
- (Addr
)(di
->opd_avma
);
587 if (offset_in_opd
< 0 || offset_in_opd
>= di
->opd_size
) {
588 if (TRACE_SYMTAB_ENABLED
) {
589 HChar
* sym_name
= ML_(img_strdup
)(escn_strtab
->img
,
590 "di.gesi.6a", sym_name_ioff
);
591 TRACE_SYMTAB(" ignore -- invalid OPD offset: %s\n", sym_name
);
592 if (sym_name
) ML_(dinfo_free
)(sym_name
);
597 /* Now we want to know what's at that offset in the .opd
598 section. We can't look in the running image since it won't
599 necessarily have been mapped. But we can consult the oimage.
600 opd_img is the start address of the .opd in the oimage.
603 ULong fn_descr
[2]; /* is actually 3 words, but we need only 2 */
604 if (!ML_(img_valid
)(escn_opd
->img
, escn_opd
->ioff
+ offset_in_opd
,
606 if (TRACE_SYMTAB_ENABLED
) {
607 HChar
* sym_name
= ML_(img_strdup
)(escn_strtab
->img
,
608 "di.gesi.6b", sym_name_ioff
);
609 TRACE_SYMTAB(" ignore -- invalid OPD fn_descr offset: %s\n",
611 if (sym_name
) ML_(dinfo_free
)(sym_name
);
617 /* This can't fail now, because we just checked the offset
619 ML_(img_get
)(&fn_descr
[0], escn_opd
->img
,
620 escn_opd
->ioff
+ offset_in_opd
, sizeof(fn_descr
));
623 TRACE_SYMTAB("opdXXY: offset %d, fn_descr %p\n",
624 offset_in_opd
, fn_descr
);
626 TRACE_SYMTAB("opdXXZ: *fn_descr %p\n", (void*)(fn_descr
[0]));
628 /* opd_bias is the what we have to add to SVMAs found in .opd to
629 get plausible .text AVMAs for the entry point, and .data
630 AVMAs (presumably) for the TOC locations. We use the caller
631 supplied value (which is di->text_bias) for both of these.
632 Not sure why that is correct - it seems to work, and sounds
633 OK for fn_descr[0], but surely we need to use the data bias
634 and not the text bias for fn_descr[1] ? Oh Well.
636 (*sym_avmas_out
).main
= fn_descr
[0] + opd_bias
;
637 SET_TOCPTR_AVMA(*sym_avmas_out
, fn_descr
[1] + opd_bias
);
638 *from_opd_out
= True
;
641 /* Do a final sanity check: if the symbol falls outside the
642 DebugInfo's mapped range, ignore it. Since (*sym_avmas_out).main has
643 been updated, that can be achieved simply by falling through
644 to the test below. */
646 # endif /* ppc64-linux nasty hack */
649 /* Here's yet another ppc64-linux hack. Get rid of leading dot if
650 the symbol is outside .opd. */
651 # if defined(VGP_ppc64be_linux)
654 && *sym_name_out_ioff
!= DiOffT_INVALID
655 && ML_(img_get_UChar
)(escn_strtab
->img
, *sym_name_out_ioff
) == '.') {
656 vg_assert(!(*from_opd_out
));
657 (*sym_name_out_ioff
)++;
661 /* If no part of the symbol falls within the mapped range,
667 && !((*sym_avmas_out
).main
+ *sym_size_out
<= di
->text_avma
668 || (*sym_avmas_out
).main
>= di
->text_avma
+ di
->text_size
);
673 && !((*sym_avmas_out
).main
+ *sym_size_out
<= di
->data_avma
674 || (*sym_avmas_out
).main
>= di
->data_avma
+ di
->data_size
);
678 && di
->sdata_size
> 0
679 && !((*sym_avmas_out
).main
+ *sym_size_out
<= di
->sdata_avma
680 || (*sym_avmas_out
).main
>= di
->sdata_avma
+ di
->sdata_size
);
684 && di
->rodata_size
> 0
685 && !((*sym_avmas_out
).main
+ *sym_size_out
<= di
->rodata_avma
686 || (*sym_avmas_out
).main
>= di
->rodata_avma
+ di
->rodata_size
);
691 && !((*sym_avmas_out
).main
+ *sym_size_out
<= di
->bss_avma
692 || (*sym_avmas_out
).main
>= di
->bss_avma
+ di
->bss_size
);
697 && !((*sym_avmas_out
).main
+ *sym_size_out
<= di
->sbss_avma
698 || (*sym_avmas_out
).main
>= di
->sbss_avma
+ di
->sbss_size
);
702 /* This used to reject any symbol falling outside the text
703 segment ("if (!in_text) ..."). Now it is relaxed slightly,
704 to reject only symbols which fall outside the area mapped
705 r-x. This is in accordance with r7427. See
706 "Comment_Regarding_Text_Range_Checks" in storage.c for
709 vg_assert(di
->fsm
.have_rx_map
);
710 /* This could actually wrap around and cause
711 ML_(find_rx_mapping) to assert. But that seems so unlikely,
712 let's wait for it to happen before fixing it. */
713 in_rx
= (ML_(find_rx_mapping
)(
715 (*sym_avmas_out
).main
,
716 (*sym_avmas_out
).main
+ *sym_size_out
- 1) != NULL
);
721 "ignore -- %#lx .. %#lx outside .text svma range %#lx .. %#lx\n",
722 (*sym_avmas_out
).main
, (*sym_avmas_out
).main
+ *sym_size_out
- 1,
724 di
->text_avma
+ di
->text_size
- 1);
728 if (!(in_data
|| in_sdata
|| in_rodata
|| in_bss
|| in_sbss
)) {
730 "ignore -- %#lx .. %#lx outside .data / .sdata / .rodata "
731 "/ .bss / .sbss svma ranges\n",
732 (*sym_avmas_out
).main
, (*sym_avmas_out
).main
+ *sym_size_out
- 1);
737 # if defined(VGP_ppc64be_linux)
738 if (di
->opd_present
&& di
->opd_size
> 0) {
739 vg_assert((*sym_avmas_out
).main
+ *sym_size_out
<= di
->opd_avma
740 || (*sym_avmas_out
).main
>= di
->opd_avma
+ di
->opd_size
);
744 # if defined(VGP_ppc64le_linux)
745 /* PPC64 LE ABI uses three bits in the st_other field to indicate the number
746 * of instructions between the function's global and local entry points. An
747 * offset of 0 indicates that there is one entry point. The value must be:
749 * 0 - one entry point, local and global are the same
751 * 2 - local entry point is one instruction after the global entry point
752 * 3 - local entry point is two instructions after the global entry point
753 * 4 - local entry point is four instructions after the global entry point
754 * 5 - local entry point is eight instructions after the global entry point
755 * 6 - local entry point is sixteen instructions after the global entry point
758 * Extract the three bit field from the other field is done by:
759 * (other_field & STO_PPC64_LOCAL_MASK) >> STO_PPC_LOCAL_BIT
761 * where the #define values are given in include/elf/powerpc.h file for
764 * conversion of the three bit field to bytes is given by
766 * ((1 << bit_field) >> 2) << 2
769 #define STO_PPC64_LOCAL_BIT 5
770 #define STO_PPC64_LOCAL_MASK (7 << STO_PPC64_LOCAL_BIT)
772 unsigned int bit_field
, dist_to_local_entry
;
773 /* extract the other filed */
774 bit_field
= (sym
->st_other
& STO_PPC64_LOCAL_MASK
) >> STO_PPC64_LOCAL_BIT
;
776 if ((bit_field
> 0) && (bit_field
< 7)) {
777 /* store the local entry point address */
778 dist_to_local_entry
= ((1 << bit_field
) >> 2) << 2;
779 SET_LOCAL_EP_AVMA(*sym_avmas_out
,
780 (*sym_avmas_out
).main
+ dist_to_local_entry
);
782 if (TRACE_SYMTAB_ENABLED
) {
783 HChar
* sym_name
= ML_(img_strdup
)(escn_strtab
->img
,
784 "di.gesi.5", sym_name_ioff
);
785 VG_(printf
)("Local entry point: %s at %#010x\n",
787 (unsigned int)GET_LOCAL_EP_AVMA(*sym_avmas_out
));
798 /* Read an ELF symbol table (normal or dynamic). This one is for the
799 "normal" case ({x86,amd64,ppc32,arm,mips32,mips64, ppc64le}-linux). */
801 __attribute__((unused
)) /* not referred to on all targets */
802 void read_elf_symtab__normal(
803 struct _DebugInfo
* di
, const HChar
* tab_name
,
804 DiSlice
* escn_symtab
,
805 DiSlice
* escn_strtab
,
806 DiSlice
* escn_opd
, /* ppc64be-linux only */
810 if (escn_strtab
->img
== NULL
|| escn_symtab
->img
== NULL
) {
811 HChar buf
[VG_(strlen
)(tab_name
) + 40];
812 VG_(sprintf
)(buf
, " object doesn't have a %s", tab_name
);
813 ML_(symerr
)(di
, False
, buf
);
817 TRACE_SYMTAB("\n--- Reading (ELF, standard) %s (%llu entries) ---\n",
818 tab_name
, escn_symtab
->szB
/sizeof(ElfXX_Sym
) );
820 /* Perhaps should start at i = 1; ELF docs suggest that entry
821 0 always denotes 'unknown symbol'. */
823 for (i
= 1; i
< (Word
)(escn_symtab
->szB
/sizeof(ElfXX_Sym
)); i
++) {
825 ML_(img_get
)(&sym
, escn_symtab
->img
,
826 escn_symtab
->ioff
+ i
* sizeof(ElfXX_Sym
), sizeof(sym
));
827 DiOffT sym_name
= escn_strtab
->ioff
+ sym
.st_name
;
828 Addr sym_svma
= sym
.st_value
;
830 if (di
->trace_symtab
)
831 show_raw_elf_symbol(escn_strtab
->img
, i
,
832 &sym
, sym_name
, sym_svma
, False
);
834 SymAVMAs sym_avmas_really
;
836 Bool from_opd
= False
, is_text
= False
, is_ifunc
= False
;
837 Bool is_global
= False
;
838 DiOffT sym_name_really
= DiOffT_INVALID
;
839 sym_avmas_really
.main
= 0;
840 SET_TOCPTR_AVMA(sym_avmas_really
, 0);
841 SET_LOCAL_EP_AVMA(sym_avmas_really
, 0);
842 if (get_elf_symbol_info(di
, &sym
, sym_name
, escn_strtab
,
843 sym_svma
, symtab_in_debug
,
844 escn_opd
, di
->text_bias
,
848 &from_opd
, &is_text
, &is_ifunc
, &is_global
)) {
851 VG_(memset
)(&disym
, 0, sizeof(disym
));
852 HChar
* cstr
= ML_(img_strdup
)(escn_strtab
->img
,
853 "di.res__n.1", sym_name_really
);
854 disym
.avmas
= sym_avmas_really
;
855 disym
.pri_name
= ML_(addStr
) ( di
, cstr
, -1 );
856 disym
.sec_names
= NULL
;
857 disym
.size
= sym_size
;
858 disym
.isText
= is_text
;
859 disym
.isIFunc
= is_ifunc
;
860 disym
.isGlobal
= is_global
;
861 if (cstr
) { ML_(dinfo_free
)(cstr
); cstr
= NULL
; }
862 vg_assert(disym
.pri_name
);
863 vg_assert(GET_TOCPTR_AVMA(disym
.avmas
) == 0);
864 /* has no role except on ppc64be-linux */
865 ML_(addSym
) ( di
, &disym
);
867 if (TRACE_SYMTAB_ENABLED
) {
868 TRACE_SYMTAB(" rec(%c) [%4ld]: "
869 " val %#010lx, sz %4d %s\n",
876 if (GET_LOCAL_EP_AVMA(disym
.avmas
) != 0) {
877 TRACE_SYMTAB(" local entry point %#010lx\n",
878 GET_LOCAL_EP_AVMA(disym
.avmas
));
887 /* Read an ELF symbol table (normal or dynamic). This one is for
888 ppc64be-linux, which requires special treatment. */
894 /* We have to store also the DiImage* so as to give context for
895 |name|. This is not part of the key (in terms of lookup) but
896 there's no easy other way to do this. Ugly. */
913 static Word
cmp_TempSymKey ( const TempSymKey
* key1
, const TempSym
* elem2
)
916 vg_assert(key1
->img
== elem2
->key
.img
);
917 vg_assert(key1
->img
!= NULL
);
918 if (key1
->addr
< elem2
->key
.addr
) return -1;
919 if (key1
->addr
> elem2
->key
.addr
) return 1;
920 vg_assert(key1
->name
!= DiOffT_INVALID
);
921 vg_assert(elem2
->key
.name
!= DiOffT_INVALID
);
922 return (Word
)ML_(img_strcmp
)(key1
->img
, key1
->name
, elem2
->key
.name
);
926 __attribute__((unused
)) /* not referred to on all targets */
927 void read_elf_symtab__ppc64be_linux(
928 struct _DebugInfo
* di
, const HChar
* tab_name
,
929 DiSlice
* escn_symtab
,
930 DiSlice
* escn_strtab
,
931 DiSlice
* escn_opd
, /* ppc64be-linux only */
937 Bool modify_size
, modify_tocptr
;
943 if (escn_strtab
->img
== NULL
|| escn_symtab
->img
== NULL
) {
944 HChar buf
[VG_(strlen
)(tab_name
) + 40];
945 VG_(sprintf
)(buf
, " object doesn't have a %s", tab_name
);
946 ML_(symerr
)(di
, False
, buf
);
950 TRACE_SYMTAB("\n--- Reading (ELF, ppc64be-linux) %s (%llu entries) ---\n",
951 tab_name
, escn_symtab
->szB
/sizeof(ElfXX_Sym
) );
953 oset
= VG_(OSetGen_Create
)( offsetof(TempSym
,key
),
954 (OSetCmp_t
)cmp_TempSymKey
,
955 ML_(dinfo_zalloc
), "di.respl.1",
958 /* Perhaps should start at i = 1; ELF docs suggest that entry
959 0 always denotes 'unknown symbol'. */
960 for (i
= 1; i
< (Word
)(escn_symtab
->szB
/sizeof(ElfXX_Sym
)); i
++) {
962 ML_(img_get
)(&sym
, escn_symtab
->img
,
963 escn_symtab
->ioff
+ i
* sizeof(ElfXX_Sym
), sizeof(sym
));
964 DiOffT sym_name
= escn_strtab
->ioff
+ sym
.st_name
;
965 Addr sym_svma
= sym
.st_value
;
967 if (di
->trace_symtab
)
968 show_raw_elf_symbol(escn_strtab
->img
, i
,
969 &sym
, sym_name
, sym_svma
, True
);
971 SymAVMAs sym_avmas_really
;
973 Bool from_opd
= False
, is_text
= False
, is_ifunc
= False
;
974 Bool is_global
= False
;
975 DiOffT sym_name_really
= DiOffT_INVALID
;
977 VG_(memset
)(&disym
, 0, sizeof(disym
));
978 sym_avmas_really
.main
= 0;
979 SET_TOCPTR_AVMA(sym_avmas_really
, 0);
980 SET_LOCAL_EP_AVMA(sym_avmas_really
, 0);
981 if (get_elf_symbol_info(di
, &sym
, sym_name
, escn_strtab
,
982 sym_svma
, symtab_in_debug
,
983 escn_opd
, di
->text_bias
,
987 &from_opd
, &is_text
, &is_ifunc
, &is_global
)) {
989 /* Check if we've seen this (name,addr) key before. */
990 key
.addr
= sym_avmas_really
.main
;
991 key
.name
= sym_name_really
;
992 key
.img
= escn_strtab
->img
;
993 prev
= VG_(OSetGen_Lookup
)( oset
, &key
);
997 /* Seen it before. Fold in whatever new info we can. */
999 modify_tocptr
= False
;
1002 if (prev
->from_opd
&& !from_opd
1003 && (prev
->size
== 24 || prev
->size
== 16)
1004 && sym_size
!= prev
->size
) {
1005 /* Existing one is an opd-redirect, with a bogus size,
1006 so the only useful new fact we have is the real size
1009 old_size
= prev
->size
;
1010 prev
->size
= sym_size
;
1013 if (!prev
->from_opd
&& from_opd
1014 && (sym_size
== 24 || sym_size
== 16)) {
1015 /* Existing one is non-opd, new one is opd. What we
1016 can acquire from the new one is the TOC ptr to be
1017 used. Since the existing sym is non-toc, it
1018 shouldn't currently have an known TOC ptr. */
1019 vg_assert(prev
->tocptr
== 0);
1020 modify_tocptr
= True
;
1021 prev
->tocptr
= GET_TOCPTR_AVMA(sym_avmas_really
);
1024 /* ignore. can we do better here? */
1027 /* Only one or the other is possible (I think) */
1028 vg_assert(!(modify_size
&& modify_tocptr
));
1030 if (modify_size
&& di
->trace_symtab
) {
1031 VG_(printf
)(" modify (old sz %4d) "
1032 " val %#010lx, toc %#010lx, sz %4d %llu\n",
1040 if (modify_tocptr
&& di
->trace_symtab
) {
1041 VG_(printf
)(" modify (upd tocptr) "
1042 " val %#010lx, toc %#010lx, sz %4d %llu\n",
1052 /* A new (name,addr) key. Add and continue. */
1053 elem
= VG_(OSetGen_AllocNode
)(oset
, sizeof(TempSym
));
1055 elem
->tocptr
= GET_TOCPTR_AVMA(sym_avmas_really
);
1056 elem
->size
= sym_size
;
1057 elem
->from_opd
= from_opd
;
1058 elem
->is_text
= is_text
;
1059 elem
->is_ifunc
= is_ifunc
;
1060 elem
->is_global
= is_global
;
1061 VG_(OSetGen_Insert
)(oset
, elem
);
1062 if (di
->trace_symtab
) {
1063 HChar
* str
= ML_(img_strdup
)(escn_strtab
->img
, "di.respl.2",
1065 VG_(printf
)(" to-oset [%4ld]: "
1066 " val %#010lx, toc %#010lx, sz %4d %s\n",
1073 if (str
) ML_(dinfo_free
)(str
);
1080 /* All the syms that matter are in the oset. Now pull them out,
1081 build a "standard" symbol table, and nuke the oset. */
1084 VG_(OSetGen_ResetIter
)( oset
);
1086 while ( (elem
= VG_(OSetGen_Next
)(oset
)) ) {
1088 VG_(memset
)(&disym
, 0, sizeof(disym
));
1089 HChar
* cstr
= ML_(img_strdup
)(escn_strtab
->img
,
1090 "di.res__ppc64.1", elem
->key
.name
);
1091 disym
.avmas
.main
= elem
->key
.addr
;
1092 SET_TOCPTR_AVMA(disym
.avmas
, elem
->tocptr
);
1093 SET_LOCAL_EP_AVMA(disym
.avmas
, 0); // ppc64be does not use local_ep.
1094 disym
.pri_name
= ML_(addStr
) ( di
, cstr
, -1 );
1095 disym
.sec_names
= NULL
;
1096 disym
.size
= elem
->size
;
1097 disym
.isText
= elem
->is_text
;
1098 disym
.isIFunc
= elem
->is_ifunc
;
1099 disym
.isGlobal
= elem
->is_global
;
1100 if (cstr
) { ML_(dinfo_free
)(cstr
); cstr
= NULL
; }
1101 vg_assert(disym
.pri_name
!= NULL
);
1103 ML_(addSym
) ( di
, &disym
);
1104 if (di
->trace_symtab
) {
1105 VG_(printf
)(" rec(%c%c%c) [%4ld]: "
1106 " val %#010lx, toc %#010lx, sz %4d %s\n",
1107 disym
.isText
? 't' : 'd',
1108 disym
.isIFunc
? 'i' : '-',
1109 disym
.isGlobal
? 'g' : 'l',
1112 GET_TOCPTR_AVMA(disym
.avmas
),
1120 VG_(OSetGen_Destroy
)( oset
);
1123 #if defined(VGO_freebsd)
1126 * read_and_set_osrel
1128 * "osrel" is in an Elf note. It has values such as 1201000 for FreeBSD 12.1
1129 * Some of the behaviour related to SIGSEGV and SIGBUS signals depends on the
1130 * kernel reading this value.
1132 * However in the case of Valgrind, the host is strictly statically linked and
1133 * does not contain the NT_FREEBSD_ABI_TAG note. And even if it did, we want to
1134 * override the value with that of the guest.
1136 * At some later date we might want to look at the value of "fctl0" (note with the
1137 * NT_FREEBSD_FEATURE_CTL type). This seems to be related to Address Space Layout
1138 * Randomization. No hurry at the moment.
1140 * See /usr/src/sys/kern/imgact_elf.c for details on how the kernel reads these
1144 void read_and_set_osrel(DiImage
* img
)
1146 if (is_elf_object_file_by_DiImage(img
, False
)) {
1150 ML_(img_get
)(&ehdr
, img
, 0, sizeof(ehdr
));
1152 /* only set osrel for executable files, not for subsequent shared libraries */
1153 if (ehdr
.e_type
!= ET_EXEC
) {
1157 /* Skip the phdrs when we have to search the shdrs. In separate
1158 .debug files the phdrs might not be valid (they are a copy of
1159 the main ELF file) and might trigger assertions when getting
1160 image notes based on them. */
1161 for (i
= 0; i
< ehdr
.e_phnum
; i
++) {
1163 ML_(img_get
)(&phdr
, img
,
1164 ehdr
.e_phoff
+ i
* ehdr
.e_phentsize
, sizeof(phdr
));
1166 if (phdr
.p_type
== PT_NOTE
) {
1167 ElfXX_Off note_ioff
= phdr
.p_offset
;
1169 while (note_ioff
< phdr
.p_offset
+ phdr
.p_filesz
) {
1171 ML_(img_get
)(note
, img
, (DiOffT
)note_ioff
, sizeof(note
));
1172 DiOffT name_ioff
= note_ioff
+ sizeof(ElfXX_Nhdr
);
1173 //DiOffT desc_ioff = name_ioff + ((note[0].n_namesz + 3) & ~3);
1174 if (ML_(img_strcmp_c
)(img
, name_ioff
, "FreeBSD") == 0
1175 && note
[0].n_type
== VKI_NT_FREEBSD_ABI_TAG
) {
1177 u_int32_t osrel
= note
[1].n_type
;
1180 name
[1] = KERN_PROC
;
1181 name
[2] = KERN_PROC_OSREL
;
1182 name
[3] = VG_(getpid
)();
1183 SizeT newlen
= sizeof(osrel
);
1184 Int error
= VG_(sysctl
)(name
, 4, NULL
, NULL
, &osrel
, newlen
);
1186 VG_(message
)(Vg_DebugMsg
, "Warning: failed to set osrel for current process with value %u\n", osrel
);
1188 if (VG_(clo_verbosity
) > 1) {
1189 VG_(message
)(Vg_DebugMsg
, "Set osrel for current process with value %u\n", osrel
);
1193 note_ioff
= note_ioff
+ sizeof(ElfXX_Nhdr
)
1194 + ((note
[0].n_namesz
+ 3) & ~3)
1195 + ((note
[0].n_descsz
+ 3) & ~3);
1205 * Look for a build-id in an ELF image. The build-id specification
1206 * can be found here:
1208 * http://fedoraproject.org/wiki/RolandMcGrath/BuildID
1210 * Returned string must be freed by the caller.
1213 HChar
* find_buildid(DiImage
* img
, Bool rel_ok
, Bool search_shdrs
)
1215 HChar
* buildid
= NULL
;
1217 # ifdef NT_GNU_BUILD_ID
1218 if (is_elf_object_file_by_DiImage(img
, rel_ok
)) {
1222 ML_(img_get
)(&ehdr
, img
, 0, sizeof(ehdr
));
1223 /* Skip the phdrs when we have to search the shdrs. In separate
1224 .debug files the phdrs might not be valid (they are a copy of
1225 the main ELF file) and might trigger assertions when getting
1226 image notes based on them. */
1227 for (i
= 0; !search_shdrs
&& i
< ehdr
.e_phnum
; i
++) {
1229 ML_(img_get
)(&phdr
, img
,
1230 ehdr
.e_phoff
+ i
* ehdr
.e_phentsize
, sizeof(phdr
));
1232 if (phdr
.p_type
== PT_NOTE
) {
1233 ElfXX_Off note_ioff
= phdr
.p_offset
;
1235 while (note_ioff
< phdr
.p_offset
+ phdr
.p_filesz
) {
1237 ML_(img_get
)(¬e
, img
, (DiOffT
)note_ioff
, sizeof(note
));
1238 DiOffT name_ioff
= note_ioff
+ sizeof(ElfXX_Nhdr
);
1239 DiOffT desc_ioff
= name_ioff
+ ((note
.n_namesz
+ 3) & ~3);
1240 if (ML_(img_strcmp_c
)(img
, name_ioff
, ELF_NOTE_GNU
) == 0
1241 && note
.n_type
== NT_GNU_BUILD_ID
) {
1242 buildid
= ML_(dinfo_zalloc
)("di.fbi.1",
1243 note
.n_descsz
* 2 + 1);
1245 for (j
= 0; j
< note
.n_descsz
; j
++) {
1246 UChar desc_j
= ML_(img_get_UChar
)(img
, desc_ioff
+ j
);
1247 VG_(sprintf
)(buildid
+ VG_(strlen
)(buildid
),
1248 "%02x", (UInt
)desc_j
);
1252 note_ioff
= note_ioff
+ sizeof(ElfXX_Nhdr
)
1253 + ((note
.n_namesz
+ 3) & ~3)
1254 + ((note
.n_descsz
+ 3) & ~3);
1259 /* Normally we would only search shdrs for ET_REL files, but when
1260 we search for a separate .debug file phdrs might not be there
1261 (they are never loaded) or have been corrupted, so try again
1263 if (buildid
|| (!rel_ok
&& !search_shdrs
))
1266 for (i
= 0; i
< ehdr
.e_shnum
; i
++) {
1268 ML_(img_get
)(&shdr
, img
,
1269 ehdr
.e_shoff
+ i
* ehdr
.e_shentsize
, sizeof(shdr
));
1271 if (shdr
.sh_type
== SHT_NOTE
) {
1272 ElfXX_Off note_ioff
= shdr
.sh_offset
;
1274 while (note_ioff
< shdr
.sh_offset
+ shdr
.sh_size
) {
1276 ML_(img_get
)(¬e
, img
, (DiOffT
)note_ioff
, sizeof(note
));
1277 DiOffT name_ioff
= note_ioff
+ sizeof(ElfXX_Nhdr
);
1278 DiOffT desc_ioff
= name_ioff
+ ((note
.n_namesz
+ 3) & ~3);
1280 if (ML_(img_strcmp_c
)(img
, name_ioff
, ELF_NOTE_GNU
) == 0
1281 && note
.n_type
== NT_GNU_BUILD_ID
) {
1282 buildid
= ML_(dinfo_zalloc
)("di.fbi.2",
1283 note
.n_descsz
* 2 + 1);
1285 for (j
= 0; j
< note
.n_descsz
; j
++) {
1286 UChar desc_j
= ML_(img_get_UChar
)(img
, desc_ioff
+ j
);
1287 VG_(sprintf
)(buildid
+ VG_(strlen
)(buildid
),
1288 "%02x", (UInt
)desc_j
);
1292 note_ioff
= note_ioff
+ sizeof(ElfXX_Nhdr
)
1293 + ((note
.n_namesz
+ 3) & ~3)
1294 + ((note
.n_descsz
+ 3) & ~3);
1299 # endif /* def NT_GNU_BUILD_ID */
1305 /* Try and open a separate debug file, ignoring any where the CRC does
1306 not match the value from the main object file. Returned DiImage
1307 must be discarded by the caller.
1309 If |serverAddr| is NULL, |name| is expected to be a fully qualified
1310 (absolute) path to the file in the local filesystem. If
1311 |serverAddr| is non-NULL, it is expected to be an IPv4 and port
1312 spec of the form "d.d.d.d:d" or "d.d.d.d", and |name| is expected
1313 to be a plain filename (no path components at all).
1316 DiImage
* open_debug_file( const HChar
* name
, const HChar
* buildid
, UInt crc
,
1317 Bool rel_ok
, const HChar
* serverAddr
)
1320 = serverAddr
? ML_(img_from_di_server
)(name
, serverAddr
)
1321 : ML_(img_from_local_file
)(name
);
1325 if (VG_(clo_verbosity
) > 1) {
1327 VG_(message
)(Vg_DebugMsg
, " Considering %s on server %s ..\n",
1330 VG_(message
)(Vg_DebugMsg
, " Considering %s ..\n", name
);
1333 /* We will always check the crc if we have one (altfiles don't have one)
1334 for now because we might be opening the main file again by any other
1335 name, and that obviously also has the same buildid. More efficient
1336 would be an fstat bases check or a check that the file actually
1337 contains .debug* sections. */
1338 if (buildid
&& crc
== 0) {
1339 HChar
* debug_buildid
= find_buildid(dimg
, rel_ok
, True
);
1340 if (debug_buildid
== NULL
|| VG_(strcmp
)(buildid
, debug_buildid
) != 0) {
1341 ML_(img_done
)(dimg
);
1342 if (VG_(clo_verbosity
) > 1)
1343 VG_(message
)(Vg_DebugMsg
,
1344 " .. build-id mismatch (found %s wanted %s)\n",
1345 debug_buildid
, buildid
);
1346 ML_(dinfo_free
)(debug_buildid
);
1349 ML_(dinfo_free
)(debug_buildid
);
1350 if (VG_(clo_verbosity
) > 1)
1351 VG_(message
)(Vg_DebugMsg
, " .. build-id is valid\n");
1353 UInt calccrc
= ML_(img_calc_gnu_debuglink_crc32
)(dimg
);
1354 if (calccrc
!= crc
) {
1355 ML_(img_done
)(dimg
);
1356 if (VG_(clo_verbosity
) > 1)
1357 VG_(message
)(Vg_DebugMsg
,
1358 " .. CRC mismatch (computed %08x wanted %08x)\n", calccrc
, crc
);
1362 if (VG_(clo_verbosity
) > 1)
1363 VG_(message
)(Vg_DebugMsg
, " .. CRC is valid\n");
1369 #if defined(VGO_linux)
1370 /* Return the path of the debuginfod-find executable. */
1372 const HChar
* debuginfod_find_path( void )
1374 static const HChar
* path
= (const HChar
*) -1;
1376 if (path
== (const HChar
*) -1) {
1377 if (VG_(getenv
)("DEBUGINFOD_URLS") == NULL
1378 || VG_(strcmp
)("", VG_(getenv("DEBUGINFOD_URLS"))) == 0)
1381 path
= VG_(find_executable
)("debuginfod-find");
1387 /* Try to find a separate debug file with |buildid| via debuginfod. If found,
1388 return its DiImage. Searches for a local debuginfod-find executable and
1389 runs it in a child process in order to download the debug file. */
1391 DiImage
* find_debug_file_debuginfod( const HChar
* objpath
,
1393 const HChar
* buildid
,
1394 const UInt crc
, Bool rel_ok
)
1396 # define BUF_SIZE 4096
1397 Int out_fds
[2], err_fds
[2]; /* pipe fds */
1398 DiImage
* dimg
= NULL
; /* the img we found */
1399 HChar buf
[BUF_SIZE
]; /* executable output buffer */
1400 const HChar
* path
; /* executable path */
1401 SizeT len
; /* number of bytes read int buf */
1402 Int ret
; /* result of read call */
1404 if (buildid
== NULL
)
1407 if ((path
= debuginfod_find_path()) == NULL
)
1410 if (VG_(pipe
)(out_fds
) != 0
1411 || VG_(pipe
)(err_fds
) != 0)
1414 if (VG_(clo_verbosity
) > 1)
1415 VG_(umsg
)("Downloading debug info for %s...\n", objpath
);
1417 /* Run debuginfod-find to query servers for the debuginfo. */
1418 Int pid
= VG_(fork
)();
1420 const HChar
*argv
[4] = { path
, "debuginfo", buildid
, (HChar
*)0 };
1422 /* Redirect stdout and stderr */
1423 SysRes res
= VG_(dup2
)(out_fds
[1], 1);
1424 if (sr_Res(res
) < 0)
1427 res
= VG_(dup2
)(err_fds
[1], 2);
1428 if (sr_Res(res
) < 0)
1431 /* Disable extra stderr output since it does not play well with umesg */
1432 VG_(env_unsetenv
)(VG_(client_envp
), "DEBUGINFOD_VERBOSE", NULL
);
1433 VG_(env_unsetenv
)(VG_(client_envp
), "DEBUGINFOD_PROGRESS", NULL
);
1435 VG_(close
)(out_fds
[0]);
1436 VG_(close
)(err_fds
[0]);
1437 VG_(execv
)(argv
[0], argv
);
1439 /* If we are still alive here, execv failed. */
1443 VG_(close
)(out_fds
[1]);
1444 VG_(close
)(err_fds
[1]);
1447 if (VG_(clo_verbosity
) > 1)
1448 VG_(umsg
)("Server Error\n");
1451 VG_(waitpid
)(pid
, NULL
, 0);
1453 /* Set dimg if download was successful. */
1456 while (len
>= 0 && len
< BUF_SIZE
) {
1457 ret
= VG_(read
)(out_fds
[0], buf
+ len
, BUF_SIZE
- len
);
1462 if (ret
>= 0 && len
> 0
1463 && buf
[0] == '/' && buf
[len
-1] == '\n') {
1465 /* Remove newline from filename before trying to open debug file */
1467 dimg
= open_debug_file(buf
, buildid
, crc
, rel_ok
, NULL
);
1471 ML_(dinfo_free
)(*debugpath
);
1473 *debugpath
= ML_(dinfo_strdup
)("di.fdfd.1", buf
);
1474 if (VG_(clo_verbosity
) > 1)
1475 VG_(umsg
)("Successfully downloaded debug file for %s\n",
1481 /* Download failed so try to print error message. */
1483 if (VG_(read
)(err_fds
[0], buf
, BUF_SIZE
) > 0
1484 && (nl
= VG_(strchr
)(buf
, '\n'))) {
1486 if (VG_(clo_verbosity
) > 1)
1487 VG_(umsg
)("%s\n", buf
);
1489 if (VG_(clo_verbosity
) > 1)
1490 VG_(umsg
)("Server Error\n");
1493 VG_(close
)(out_fds
[0]);
1494 VG_(close
)(err_fds
[0]);
1499 /* Try to find a separate debug file for a given object file. If
1500 found, return its DiImage, which should be freed by the caller. If
1501 |buildid| is non-NULL, then a debug object matching it is
1502 acceptable. If |buildid| is NULL or doesn't specify a findable
1503 debug object, then we look in various places to find a file with
1504 the specified CRC. And if that doesn't work out then we give
1507 DiImage
* find_debug_file( struct _DebugInfo
* di
,
1508 const HChar
* objpath
, const HChar
* buildid
,
1509 const HChar
* debugname
, UInt crc
, Bool rel_ok
)
1511 const HChar
* extrapath
= VG_(clo_extra_debuginfo_path
);
1512 const HChar
* serverpath
= VG_(clo_debuginfo_server
);
1514 DiImage
* dimg
= NULL
; /* the img that we found */
1515 HChar
* debugpath
= NULL
; /* where we found it */
1517 if (buildid
!= NULL
) {
1518 debugpath
= ML_(dinfo_zalloc
)("di.fdf.1",
1519 VG_(strlen
)(buildid
) + 33);
1521 VG_(sprintf
)(debugpath
, "/usr/lib/debug/.build-id/%c%c/%s.debug",
1522 buildid
[0], buildid
[1], buildid
+ 2);
1524 dimg
= open_debug_file(debugpath
, buildid
, 0, rel_ok
, NULL
);
1526 ML_(dinfo_free
)(debugpath
);
1531 if (dimg
== NULL
&& debugname
!= NULL
) {
1532 HChar
*objdir
= ML_(dinfo_strdup
)("di.fdf.2", objpath
);
1533 HChar
*usrmerge_objdir
;
1536 if ((objdirptr
= VG_(strrchr
)(objdir
, '/')) != NULL
)
1539 if ((objdirptr
= VG_(strstr
)(objdir
, "usr")) != NULL
)
1540 usrmerge_objdir
= objdirptr
+ VG_(strlen
)("usr");
1542 usrmerge_objdir
= NULL
;
1544 debugpath
= ML_(dinfo_zalloc
)(
1546 VG_(strlen
)(objdir
) + VG_(strlen
)(debugname
) + 64
1547 + (extrapath
? VG_(strlen
)(extrapath
) : 0)
1548 + (serverpath
? VG_(strlen
)(serverpath
) : 0));
1550 # define TRY_OBJDIR(format, ...) \
1552 VG_(sprintf)(debugpath, format, __VA_ARGS__); \
1553 dimg = open_debug_file(debugpath, buildid, crc, rel_ok, NULL); \
1554 if (dimg != NULL) goto dimg_ok; \
1557 # define TRY_OBJDIR_USRMERGE_OBJDIR(format) \
1559 TRY_OBJDIR(format, objdir, debugname); \
1560 if (usrmerge_objdir != NULL) { \
1561 TRY_OBJDIR(format, usrmerge_objdir, debugname); \
1565 if (debugname
[0] == '/') {
1566 TRY_OBJDIR("%s", debugname
);
1569 TRY_OBJDIR_USRMERGE_OBJDIR("%s/%s");
1570 TRY_OBJDIR_USRMERGE_OBJDIR("%s/.debug/%s");
1571 TRY_OBJDIR_USRMERGE_OBJDIR("/usr/lib/debug%s/%s");
1574 TRY_OBJDIR("%s%s/%s", extrapath
, objdir
, debugname
);
1575 if (usrmerge_objdir
!= NULL
)
1576 TRY_OBJDIR("%s%s/%s", extrapath
, usrmerge_objdir
, debugname
);
1582 /* When looking on the debuginfo server, always just pass the
1584 const HChar
* basename
= debugname
;
1585 if (VG_(strstr
)(basename
, "/") != NULL
) {
1586 basename
= VG_(strrchr
)(basename
, '/') + 1;
1588 VG_(sprintf
)(debugpath
, "%s on %s", basename
, serverpath
);
1589 dimg
= open_debug_file(basename
, buildid
, crc
, rel_ok
, serverpath
);
1590 if (dimg
) goto dimg_ok
;
1595 ML_(dinfo_free
)(objdir
);
1598 # if defined(VGO_linux)
1599 if (VG_(clo_enable_debuginfod
) && dimg
== NULL
)
1600 dimg
= find_debug_file_debuginfod(objpath
, &debugpath
, buildid
, crc
, rel_ok
);
1604 vg_assert(debugpath
);
1606 TRACE_SYMTAB("------ Found a debuginfo file: %s\n", debugpath
);
1608 /* Only set once, we might be called again for opening the altfile. */
1609 if (di
->fsm
.dbgname
== NULL
)
1610 di
->fsm
.dbgname
= ML_(dinfo_strdup
)("di.fdf.4", debugpath
);
1614 ML_(dinfo_free
)(debugpath
);
1620 /* Try to find a separate debug file for a given object file, in a
1621 hacky and dangerous way: check only the --extra-debuginfo-path and
1622 the --debuginfo-server. And don't do a consistency check. */
1624 DiImage
* find_debug_file_ad_hoc( const DebugInfo
* di
,
1625 const HChar
* objpath
)
1627 const HChar
* extrapath
= VG_(clo_extra_debuginfo_path
);
1628 const HChar
* serverpath
= VG_(clo_debuginfo_server
);
1630 DiImage
* dimg
= NULL
; /* the img that we found */
1631 HChar
* debugpath
= NULL
; /* where we found it */
1633 HChar
*objdir
= ML_(dinfo_strdup
)("di.fdfah.1", objpath
);
1636 if ((objdirptr
= VG_(strrchr
)(objdir
, '/')) != NULL
)
1639 debugpath
= ML_(dinfo_zalloc
)(
1641 VG_(strlen
)(objdir
) + 64
1642 + (extrapath
? VG_(strlen
)(extrapath
) : 0)
1643 + (serverpath
? VG_(strlen
)(serverpath
) : 0));
1646 VG_(sprintf
)(debugpath
, "%s/%s", extrapath
, objpath
);
1647 dimg
= ML_(img_from_local_file
)(debugpath
);
1649 if (VG_(clo_verbosity
) > 1) {
1650 VG_(message
)(Vg_DebugMsg
, " Using (POSSIBLY MISMATCHED) %s\n",
1657 /* When looking on the debuginfo server, always just pass the
1659 const HChar
* basename
= objpath
;
1660 if (VG_(strstr
)(basename
, "/") != NULL
) {
1661 basename
= VG_(strrchr
)(basename
, '/') + 1;
1663 VG_(sprintf
)(debugpath
, "%s on %s", basename
, serverpath
);
1664 dimg
= ML_(img_from_di_server
)(basename
, serverpath
);
1666 if (VG_(clo_verbosity
) > 1) {
1667 VG_(message
)(Vg_DebugMsg
, " Using (POSSIBLY MISMATCHED) %s\n",
1676 ML_(dinfo_free
)(objdir
);
1679 vg_assert(debugpath
);
1681 TRACE_SYMTAB("------ Found an ad_hoc debuginfo file: %s\n", debugpath
);
1685 ML_(dinfo_free
)(debugpath
);
1691 static DiOffT
INDEX_BIS ( DiOffT base
, UWord idx
, UWord scale
) {
1692 // This is a bit stupid. Really, idx and scale ought to be
1693 // 64-bit quantities, always.
1694 return base
+ (DiOffT
)idx
* (DiOffT
)scale
;
1698 /* Find the file offset corresponding to SVMA by using the program
1699 headers. This is taken from binutils-2.17/binutils/readelf.c
1700 offset_from_vma(). */
1702 Word
file_offset_from_svma ( /*OUT*/Bool
* ok
,
1710 for (i
= 0; i
< phdr_nent
; i
++) {
1712 ML_(img_get
)(&seg
, img
,
1713 INDEX_BIS(phdr_ioff
, i
, phdr_ent_szB
), sizeof(seg
));
1714 if (seg
.p_type
!= PT_LOAD
)
1716 if (svma
>= (seg
.p_vaddr
& -seg
.p_align
)
1717 && svma
+ 1 <= seg
.p_vaddr
+ seg
.p_filesz
) {
1719 return svma
- seg
.p_vaddr
+ seg
.p_offset
;
1726 /* Check if section is compressed and modify DiSlice if it is.
1727 Returns False in case of unsupported compression type.
1729 static Bool
check_compression(ElfXX_Shdr
* h
, DiSlice
* s
) {
1730 if (h
->sh_flags
& SHF_COMPRESSED
) {
1732 ML_(img_get
)(&chdr
, s
->img
, s
->ioff
, sizeof(ElfXX_Chdr
));
1733 if (chdr
.ch_type
!= ELFCOMPRESS_ZLIB
)
1735 s
->ioff
= ML_(img_mark_compressed_part
)(s
->img
,
1736 s
->ioff
+ sizeof(ElfXX_Chdr
),
1737 s
->szB
- sizeof(ElfXX_Chdr
),
1738 (SizeT
)chdr
.ch_size
);
1739 s
->szB
= chdr
.ch_size
;
1740 } else if (h
->sh_size
> SIZE_OF_ZLIB_HEADER
) {
1741 /* Read the zlib header. In this case, it should be "ZLIB"
1742 followed by the uncompressed section size, 8 bytes in BE order. */
1743 UChar tmp
[SIZE_OF_ZLIB_HEADER
];
1744 ML_(img_get
)(tmp
, s
->img
, s
->ioff
, SIZE_OF_ZLIB_HEADER
);
1745 if (VG_(memcmp
)(tmp
, "ZLIB", 4) == 0) {
1747 # if (VG_WORDSIZE == 8)
1748 size
= tmp
[4]; size
<<= 8;
1749 size
+= tmp
[5]; size
<<= 8;
1750 size
+= tmp
[6]; size
<<= 8;
1751 size
+= tmp
[7]; size
<<= 8;
1753 vg_assert((tmp
[4] == 0) && (tmp
[5] == 0) && (tmp
[6] == 0)
1757 size
+= tmp
[8]; size
<<= 8;
1758 size
+= tmp
[9]; size
<<= 8;
1759 size
+= tmp
[10]; size
<<= 8;
1761 s
->ioff
= ML_(img_mark_compressed_part
)(s
->img
,
1762 s
->ioff
+ SIZE_OF_ZLIB_HEADER
,
1763 s
->szB
- SIZE_OF_ZLIB_HEADER
,
1771 /* Helper function to get the readlink path. Returns a copy of path if the
1772 file wasn't a symbolic link. Returns NULL on error. Unless NULL is
1773 returned the result needs to be released with dinfo_free.
1775 static HChar
* readlink_path (const HChar
*path
)
1777 SizeT bufsiz
= VG_(strlen
)(path
);
1778 HChar
*buf
= ML_(dinfo_strdup
)("readlink_path.strdup", path
);
1783 #if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
1784 res
= VG_(do_syscall4
)(__NR_readlinkat
, VKI_AT_FDCWD
,
1785 (UWord
)path
, (UWord
)buf
, bufsiz
);
1786 #elif defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_freebsd)
1787 res
= VG_(do_syscall3
)(__NR_readlink
, (UWord
)path
, (UWord
)buf
, bufsiz
);
1788 #elif defined(VGO_solaris)
1789 res
= VG_(do_syscall4
)(__NR_readlinkat
, VKI_AT_FDCWD
, (UWord
)path
,
1790 (UWord
)buf
, bufsiz
);
1794 if (sr_isError(res
)) {
1795 if (sr_Err(res
) == VKI_EINVAL
)
1796 return buf
; // It wasn't a symbolic link, return the strdup result.
1797 ML_(dinfo_free
)(buf
);
1801 SSizeT r
= sr_Res(res
);
1803 if (r
== bufsiz
) { // buffer too small; increase and retry
1805 buf
= ML_(dinfo_realloc
)("readlink_path.realloc", buf
, bufsiz
);
1813 if (tries
== 0) { // We tried, but weird long path?
1814 ML_(dinfo_free
)(buf
);
1821 /* Relative path, add link dir. */
1823 SizeT linkdir_len
= VG_(strlen
)(path
);
1824 if ((linkdirptr
= VG_(strrchr
)(path
, '/')) != NULL
)
1825 linkdir_len
-= VG_(strlen
)(linkdirptr
+ 1);
1827 SizeT buflen
= VG_(strlen
)(buf
);
1828 SizeT needed
= linkdir_len
+ buflen
+ 1;
1829 if (bufsiz
< needed
)
1830 buf
= ML_(dinfo_realloc
)("readlink_path.linkdir", buf
, needed
);
1832 VG_(memmove
)(buf
+ linkdir_len
, buf
, buflen
);
1833 VG_(memcpy
)(buf
, path
, linkdir_len
);
1834 buf
[needed
- 1] = '\0';
1839 /* The central function for reading ELF debug info. For the
1840 object/exe specified by the DebugInfo, find ELF sections, then read
1841 the symbols, line number info, file name info, CFA (stack-unwind
1842 info) and anything else we want, into the tables within the
1846 Bool
ML_(read_elf_debug_info
) ( struct _DebugInfo
* di
)
1848 /* This function is long and complex. That, and the presence of
1849 nested scopes, means it's not always easy to see which parts are
1850 in loops/conditionals and which aren't. To make it easier to
1851 follow, points executed exactly once -- that is, those which are
1852 the top level of the function -- are marked TOPLEVEL.
1854 /* Consistent terminology for local variable names, without which
1855 it's almost unfollowably complex:
1858 in the main ELF file *_m*
1859 in the debuginfo file *_d*
1860 in the alt debuginfo file *_a*
1863 _{m,d,a}img a DiImage*
1864 _{m,d,a}ioff an offset in the image (DiOffT)
1865 _{m,d,a}nent "number of entries"
1866 _{m,d,a}ent_szB "size in bytes of an entry"
1867 ehdr_{m,d,a} ELF header
1871 _escn an DiSlice (elf section info) variable
1879 Bool dynbss_present
= False
;
1880 Bool sdynbss_present
= False
;
1882 /* Image for the main ELF file we're working with. */
1883 DiImage
* mimg
= NULL
;
1885 /* Ditto for any ELF debuginfo file that we might happen to load. */
1886 DiImage
* dimg
= NULL
;
1888 /* Ditto for alternate ELF debuginfo file that we might happen to load. */
1889 DiImage
* aimg
= NULL
;
1891 /* ELF header offset for the main file. Should be zero since the
1892 ELF header is at start of file. */
1893 DiOffT ehdr_mioff
= 0;
1895 /* Program header table image addr, # entries, entry size */
1896 DiOffT phdr_mioff
= 0;
1897 UWord phdr_mnent
= 0;
1898 UWord phdr_ment_szB
= 0;
1900 /* Section header image addr, # entries, entry size. Also the
1901 associated string table. */
1902 DiOffT shdr_mioff
= 0;
1903 UWord shdr_mnent
= 0;
1904 UWord shdr_ment_szB
= 0;
1905 DiOffT shdr_strtab_mioff
= 0;
1907 /* SVMAs covered by rx and rw segments and corresponding biases.
1908 Normally each object would provide just one rx and one rw area,
1909 but various ELF mangling tools create objects with multiple
1910 such entries, hence the generality. */
1920 XArray
* /* of RangeAndBias */ svma_ranges
= NULL
;
1922 # if defined(SOLARIS_PT_SUNDWTRACE_THRP)
1923 Addr dtrace_data_vaddr
= 0;
1927 vg_assert(di
->fsm
.have_rx_map
== True
);
1928 vg_assert(di
->fsm
.rw_map_count
>= 1);
1929 vg_assert(di
->have_dinfo
== False
);
1930 vg_assert(di
->fsm
.filename
);
1931 vg_assert(!di
->symtab
);
1932 vg_assert(!di
->loctab
);
1933 vg_assert(!di
->inltab
);
1934 vg_assert(!di
->cfsi_base
);
1935 vg_assert(!di
->cfsi_m_ix
);
1936 vg_assert(!di
->cfsi_rd
);
1937 vg_assert(!di
->cfsi_exprs
);
1938 vg_assert(!di
->strpool
);
1939 vg_assert(!di
->fndnpool
);
1940 vg_assert(!di
->soname
);
1943 Bool has_nonempty_rx
= False
;
1944 Bool has_nonempty_rw
= False
;
1945 for (i
= 0; i
< VG_(sizeXA
)(di
->fsm
.maps
); i
++) {
1946 DebugInfoMapping
* map
= VG_(indexXA
)(di
->fsm
.maps
, i
);
1947 if (!map
->rx
&& !map
->rw
)
1949 if (map
->rx
&& map
->size
> 0)
1950 has_nonempty_rx
= True
;
1951 if (map
->rw
&& map
->size
> 0)
1952 has_nonempty_rw
= True
;
1953 /* If this doesn't hold true, it means that m_syswrap/m_aspacemgr
1954 managed to do a mapping where the start isn't page aligned.
1955 Which sounds pretty bogus to me. */
1956 vg_assert(VG_IS_PAGE_ALIGNED(map
->avma
));
1958 vg_assert(has_nonempty_rx
);
1959 vg_assert(has_nonempty_rw
);
1962 /* ----------------------------------------------------------
1963 At this point, there is very little information in the
1964 DebugInfo. We only know that something that looks like an ELF
1965 file has been mapped rx-ishly and rw-ishly as recorded in the
1966 di->fsm.maps array items. First we examine the file's ELF
1967 Program Header, and, by comparing that against the di->fsm.maps
1968 info, try to figure out the AVMAs for the sections we care
1969 about, that should have been mapped: text, data, sdata, bss,
1971 ---------------------------------------------------------- */
1975 if (VG_(clo_verbosity
) > 1 || VG_(clo_trace_redir
))
1976 VG_(message
)(Vg_DebugMsg
, "Reading syms from %s\n",
1979 /* Connect to the primary object image, so that we can read symbols
1980 and line number info out of it. It will be disconnected
1981 immediately thereafter; it is only connected transiently. */
1982 mimg
= ML_(img_from_local_file
)(di
->fsm
.filename
);
1984 VG_(message
)(Vg_UserMsg
, "warning: connection to image %s failed\n",
1986 VG_(message
)(Vg_UserMsg
, " no symbols or debug info loaded\n" );
1990 /* Ok, the object image is available. Now verify that it is a
1991 valid ELF .so or executable image. */
1992 ok
= is_elf_object_file_by_DiImage(mimg
, False
);
1994 ML_(symerr
)(di
, True
, "Invalid ELF Header");
1998 /* Find where the program and section header tables are, and give
1999 up if either is missing or outside the image (bogus). */
2001 vg_assert(ehdr_mioff
== 0); // ensured by its initialisation
2002 ok
= ML_(img_valid
)(mimg
, ehdr_mioff
, sizeof(ehdr_m
));
2003 vg_assert(ok
); // ML_(is_elf_object_file) should ensure this
2004 ML_(img_get
)(&ehdr_m
, mimg
, ehdr_mioff
, sizeof(ehdr_m
));
2006 phdr_mioff
= ehdr_mioff
+ ehdr_m
.e_phoff
;
2007 phdr_mnent
= ehdr_m
.e_phnum
;
2008 phdr_ment_szB
= ehdr_m
.e_phentsize
;
2010 shdr_mioff
= ehdr_mioff
+ ehdr_m
.e_shoff
;
2011 shdr_mnent
= ehdr_m
.e_shnum
;
2012 shdr_ment_szB
= ehdr_m
.e_shentsize
;
2014 TRACE_SYMTAB("------ Basic facts about the object ------\n");
2015 TRACE_SYMTAB("object: n_oimage %llu\n",
2016 (ULong
)ML_(img_size
)(mimg
));
2017 TRACE_SYMTAB("phdr: ioff %llu nent %lu ent_szB %lu\n",
2018 phdr_mioff
, phdr_mnent
, phdr_ment_szB
);
2019 TRACE_SYMTAB("shdr: ioff %llu nent %lu ent_szB %lu\n",
2020 shdr_mioff
, shdr_mnent
, shdr_ment_szB
);
2021 for (i
= 0; i
< VG_(sizeXA
)(di
->fsm
.maps
); i
++) {
2022 const DebugInfoMapping
* map
= VG_(indexXA
)(di
->fsm
.maps
, i
);
2024 TRACE_SYMTAB("rx_map: avma %#lx size %lu foff %lld\n",
2025 map
->avma
, map
->size
, (Long
)map
->foff
);
2027 for (i
= 0; i
< VG_(sizeXA
)(di
->fsm
.maps
); i
++) {
2028 const DebugInfoMapping
* map
= VG_(indexXA
)(di
->fsm
.maps
, i
);
2030 TRACE_SYMTAB("rw_map: avma %#lx size %lu foff %lld\n",
2031 map
->avma
, map
->size
, (Long
)map
->foff
);
2035 || !ML_(img_valid
)(mimg
, phdr_mioff
, phdr_mnent
* phdr_ment_szB
)) {
2036 ML_(symerr
)(di
, True
, "Missing or invalid ELF Program Header Table");
2041 || !ML_(img_valid
)(mimg
, shdr_mioff
, shdr_mnent
* shdr_ment_szB
)) {
2042 ML_(symerr
)(di
, True
, "Missing or invalid ELF Section Header Table");
2046 /* Also find the section header's string table, and validate. */
2047 /* checked previously by is_elf_object_file: */
2048 vg_assert(ehdr_m
.e_shstrndx
!= SHN_UNDEF
);
2050 // shdr_mioff is the offset of the section header table
2051 // and we need the ehdr_m.e_shstrndx'th entry
2052 { ElfXX_Shdr a_shdr
;
2053 ML_(img_get
)(&a_shdr
, mimg
,
2054 INDEX_BIS(shdr_mioff
, ehdr_m
.e_shstrndx
, shdr_ment_szB
),
2057 = ehdr_mioff
/* isn't this always zero? */ + a_shdr
.sh_offset
;
2059 if (!ML_(img_valid
)(mimg
, shdr_strtab_mioff
,
2060 1/*bogus, but we don't know the real size*/ )) {
2061 ML_(symerr
)(di
, True
, "Invalid ELF Section Header String Table");
2066 TRACE_SYMTAB("shdr: string table at %llu\n", shdr_strtab_mioff
);
2068 svma_ranges
= VG_(newXA
)(ML_(dinfo_zalloc
), "di.relfdi.1",
2069 ML_(dinfo_free
), sizeof(RangeAndBias
));
2072 /* Look through the program header table, and:
2073 - copy information from suitable PT_LOAD entries into svma_ranges
2074 - find (or fake up) the .soname for this object.
2077 TRACE_SYMTAB("------ Examining the program headers ------\n");
2078 vg_assert(di
->soname
== NULL
);
2081 ElfXX_Addr prev_svma
= 0;
2083 for (i
= 0; i
< phdr_mnent
; i
++) {
2085 ML_(img_get
)(&a_phdr
, mimg
,
2086 INDEX_BIS(phdr_mioff
, i
, phdr_ment_szB
),
2089 /* Make sure the PT_LOADable entries are in order and
2090 non-overlapping. This in turn means the address ranges
2091 slurped into svma_ranges are in order and
2094 if (a_phdr
.p_type
== PT_LOAD
) {
2095 TRACE_SYMTAB("PT_LOAD[%ld]: p_vaddr %#lx (prev %#lx)\n",
2096 i
, (UWord
)a_phdr
.p_vaddr
, (UWord
)prev_svma
);
2097 TRACE_SYMTAB("PT_LOAD[%ld]: p_offset %lu, p_filesz %lu,"
2099 i
, (UWord
)a_phdr
.p_offset
, (UWord
)a_phdr
.p_filesz
,
2100 a_phdr
.p_flags
& PF_R
? 'r' : '-',
2101 a_phdr
.p_flags
& PF_W
? 'w' : '-',
2102 a_phdr
.p_flags
& PF_X
? 'x' : '-');
2103 if (a_phdr
.p_vaddr
< prev_svma
) {
2104 ML_(symerr
)(di
, True
,
2105 "ELF Program Headers are not in ascending order");
2108 prev_svma
= a_phdr
.p_vaddr
;
2109 if (a_phdr
.p_memsz
> 0) {
2110 Bool loaded
= False
;
2111 for (j
= 0; j
< VG_(sizeXA
)(di
->fsm
.maps
); j
++) {
2112 const DebugInfoMapping
* map
= VG_(indexXA
)(di
->fsm
.maps
, j
);
2113 if ( (map
->rx
|| map
->rw
|| map
->ro
)
2114 && map
->size
> 0 /* stay sane */
2115 && a_phdr
.p_offset
>= map
->foff
2116 && a_phdr
.p_offset
< map
->foff
+ map
->size
2117 && a_phdr
.p_offset
+ a_phdr
.p_filesz
2118 <= map
->foff
+ map
->size
) {
2120 item
.svma_base
= a_phdr
.p_vaddr
;
2121 item
.svma_limit
= a_phdr
.p_vaddr
+ a_phdr
.p_memsz
;
2122 item
.bias
= map
->avma
- map
->foff
2123 + a_phdr
.p_offset
- a_phdr
.p_vaddr
;
2125 && (a_phdr
.p_flags
& (PF_R
| PF_W
))
2128 VG_(addToXA
)(svma_ranges
, &item
);
2130 "PT_LOAD[%ld]: acquired as rw, bias 0x%lx\n",
2131 i
, (UWord
)item
.bias
);
2135 && (a_phdr
.p_flags
& (PF_R
| PF_X
))
2138 VG_(addToXA
)(svma_ranges
, &item
);
2140 "PT_LOAD[%ld]: acquired as rx, bias 0x%lx\n",
2141 i
, (UWord
)item
.bias
);
2145 && (a_phdr
.p_flags
& (PF_R
| PF_W
| PF_X
))
2148 VG_(addToXA
)(svma_ranges
, &item
);
2150 "PT_LOAD[%ld]: acquired as ro, bias 0x%lx\n",
2151 i
, (UWord
)item
.bias
);
2157 # if defined(SOLARIS_PT_SUNDWTRACE_THRP)
2158 if ((a_phdr
.p_memsz
== VKI_PT_SUNWDTRACE_SIZE
)
2159 && ((a_phdr
.p_flags
& (PF_R
| PF_W
| PF_X
)) == PF_R
)) {
2160 TRACE_SYMTAB("PT_LOAD[%ld]: ignore dtrace_data program "
2162 dtrace_data_vaddr
= a_phdr
.p_vaddr
;
2165 # endif /* SOLARIS_PT_SUNDWTRACE_THRP */
2167 ML_(symerr
)(di
, False
,
2168 "ELF section outside all mapped regions");
2169 /* This problem might be solved by further memory mappings.
2170 Avoid the vg_assert(!di->soname) at the beginning of this
2171 function if DYNAMIC section has been already processed. */
2173 ML_(dinfo_free
)(di
->soname
);
2181 /* Try to get the soname. If there isn't one, use "NONE".
2182 The seginfo needs to have some kind of soname in order to
2183 facilitate writing redirect functions, since all redirect
2184 specifications require a soname (pattern). */
2185 if (a_phdr
.p_type
== PT_DYNAMIC
&& di
->soname
== NULL
) {
2187 DiOffT strtab_mioff
= DiOffT_INVALID
;
2188 for (j
= 0; True
/*exit check is in the loop*/; j
++) {
2189 ElfXX_Dyn t_dyn_m
; /* dyn_img[j] */
2190 ML_(img_get
)(&t_dyn_m
, mimg
,
2191 INDEX_BIS(ehdr_mioff
+ a_phdr
.p_offset
,
2192 j
, sizeof(ElfXX_Dyn
)),
2194 if (t_dyn_m
.d_tag
== DT_NULL
)
2197 switch (t_dyn_m
.d_tag
) {
2199 stroff
= t_dyn_m
.d_un
.d_val
;
2204 Word offset
= file_offset_from_svma(
2205 &ok2
, t_dyn_m
.d_un
.d_ptr
, mimg
,
2206 phdr_mioff
, phdr_mnent
, phdr_ment_szB
2208 if (ok2
&& strtab_mioff
== DiOffT_INVALID
) {
2209 // Check for obviously bogus offsets.
2210 if (!ML_(img_valid
)(mimg
, offset
, 1)) {
2211 ML_(symerr
)(di
, True
, "Invalid DT_STRTAB offset");
2214 strtab_mioff
= ehdr_mioff
+ offset
;
2215 vg_assert(ehdr_mioff
== 0); // should always be
2223 if (stroff
!= -1 && strtab_mioff
!= DiOffT_INVALID
) {
2224 di
->soname
= ML_(img_strdup
)(mimg
, "di.redi.1",
2225 strtab_mioff
+ stroff
);
2226 TRACE_SYMTAB("Found soname = %s\n", di
->soname
);
2229 } /* for (i = 0; i < phdr_Mnent; i++) ... */
2232 } /* examine the program headers (local scope) */
2236 /* If, after looking at all the program headers, we still didn't
2237 find a soname, add a fake one. */
2238 if (di
->soname
== NULL
) {
2239 TRACE_SYMTAB("No soname found; using (fake) \"NONE\"\n");
2240 di
->soname
= ML_(dinfo_strdup
)("di.redi.2", "NONE");
2243 vg_assert(VG_(sizeXA
)(svma_ranges
) != 0);
2245 /* Now read the section table. */
2247 TRACE_SYMTAB("------ Examining the section headers ------\n");
2248 for (i
= 0; i
< VG_(sizeXA
)(di
->fsm
.maps
); i
++) {
2249 const DebugInfoMapping
* map
= VG_(indexXA
)(di
->fsm
.maps
, i
);
2251 TRACE_SYMTAB("rx: at %#lx are mapped foffsets %lld .. %lld\n",
2252 map
->avma
, (Long
)map
->foff
, (Long
)(map
->foff
+ map
->size
- 1) );
2254 TRACE_SYMTAB("rx: contains these svma regions:\n");
2255 for (i
= 0; i
< VG_(sizeXA
)(svma_ranges
); i
++) {
2256 const RangeAndBias
* reg
= VG_(indexXA
)(svma_ranges
, i
);
2258 TRACE_SYMTAB(" svmas %#lx .. %#lx with bias %#lx\n",
2259 reg
->svma_base
, reg
->svma_limit
- 1, (UWord
)reg
->bias
);
2261 for (i
= 0; i
< VG_(sizeXA
)(di
->fsm
.maps
); i
++) {
2262 const DebugInfoMapping
* map
= VG_(indexXA
)(di
->fsm
.maps
, i
);
2264 TRACE_SYMTAB("rw: at %#lx are mapped foffsets %lld .. %lld\n",
2265 map
->avma
, (Long
)map
->foff
, (Long
)(map
->foff
+ map
->size
- 1) );
2268 TRACE_SYMTAB("rw: contains these svma regions:\n");
2269 for (i
= 0; i
< VG_(sizeXA
)(svma_ranges
); i
++) {
2270 const RangeAndBias
* reg
= VG_(indexXA
)(svma_ranges
, i
);
2272 TRACE_SYMTAB(" svmas %#lx .. %#lx with bias %#lx\n",
2273 reg
->svma_base
, reg
->svma_limit
- 1, (UWord
)reg
->bias
);
2277 /* Iterate over section headers */
2278 for (i
= 0; i
< shdr_mnent
; i
++) {
2280 ML_(img_get
)(&a_shdr
, mimg
,
2281 INDEX_BIS(shdr_mioff
, i
, shdr_ment_szB
), sizeof(a_shdr
));
2282 DiOffT name_mioff
= shdr_strtab_mioff
+ a_shdr
.sh_name
;
2283 HChar
* name
= ML_(img_strdup
)(mimg
, "di.redi_name.2", name_mioff
);
2284 Addr svma
= a_shdr
.sh_addr
;
2285 OffT foff
= a_shdr
.sh_offset
;
2286 UWord size
= a_shdr
.sh_size
; /* Do not change this to be signed. */
2287 UInt alyn
= a_shdr
.sh_addralign
;
2288 Bool nobits
= a_shdr
.sh_type
== SHT_NOBITS
;
2289 /* Look through our collection of info obtained from the PT_LOAD
2290 headers, and make 'inrx' and 'inrw1' point to the first entry
2291 in each that intersects 'avma'. If in each case none is found,
2292 leave the relevant pointer at NULL. */
2293 RangeAndBias
* inrx
= NULL
;
2294 RangeAndBias
* inrw1
= NULL
;
2295 /* Depending on the link editro there may be two RW PT_LOAD headers
2296 * If so this will point to the seond one */
2297 RangeAndBias
* inrw2
= NULL
;
2298 /* used to switch between inrw1 and inrw2 */
2301 for (j
= 0; j
< VG_(sizeXA
)(svma_ranges
); j
++) {
2302 RangeAndBias
* rng
= VG_(indexXA
)(svma_ranges
, j
);
2303 if (svma
>= rng
->svma_base
&& svma
< rng
->svma_limit
) {
2304 if (!inrx
&& rng
->exec
) {
2306 } else if (!inrw1
&& !rng
->exec
) {
2308 } else if (!inrw2
&& !rng
->exec
) {
2314 TRACE_SYMTAB(" [sec %2ld] %s %s %s al%4u foff %6lld .. %6lld "
2315 " svma %p name \"%s\"\n",
2316 i
, inrx
? "rx" : " ", inrw1
? "rw" : " ", inrw2
? "rw" : " ",
2317 alyn
, (Long
) foff
, (size
== 0) ? (Long
)foff
: (Long
)(foff
+size
-1),
2318 (void *) svma
, name
);
2320 /* Check for sane-sized segments. SHT_NOBITS sections have zero
2321 size in the file and their offsets are just conceptual. */
2323 (foff
>= ML_(img_size
)(mimg
) || foff
+ size
> ML_(img_size
)(mimg
))) {
2324 ML_(symerr
)(di
, True
, "ELF Section extends beyond image end");
2328 /* Check for a sane alignment value. */
2329 if (alyn
> 0 && -1 == VG_(log2
)(alyn
)) {
2330 ML_(symerr
)(di
, True
, "ELF Section contains invalid "
2331 ".sh_addralign value");
2335 /* Ignore zero sized sections. */
2337 TRACE_SYMTAB("zero sized section \"%s\", ignoring\n", name
);
2338 ML_(dinfo_free
)(name
);
2342 # define BAD(_secname) \
2343 do { ML_(symerr)(di, True, \
2344 "Can't make sense of " _secname \
2345 " section mapping"); \
2346 /* make sure we don't assert if we find */ \
2347 /* ourselves back in this routine later, */ \
2348 /* with the same di */ \
2349 di->soname = NULL; \
2353 /* Find avma-s for: .text .data .sdata .rodata .bss .sbss .plt .got .opd
2356 /* In inrw2 is non-NULL then it will be used for .data .got.plt .bss */
2358 /* Accept .text where mapped as rx (code), even if zero-sized */
2359 if (0 == VG_(strcmp
)(name
, ".text")) {
2360 if (inrx
&& !di
->text_present
) {
2361 di
->text_present
= True
;
2362 di
->text_svma
= svma
;
2363 di
->text_avma
= svma
+ inrx
->bias
;
2364 di
->text_size
= size
;
2365 di
->text_bias
= inrx
->bias
;
2366 di
->text_debug_svma
= svma
;
2367 di
->text_debug_bias
= inrx
->bias
;
2368 TRACE_SYMTAB("acquiring .text svma = %#lx .. %#lx\n",
2370 di
->text_svma
+ di
->text_size
- 1);
2371 TRACE_SYMTAB("acquiring .text avma = %#lx .. %#lx\n",
2373 di
->text_avma
+ di
->text_size
- 1);
2374 TRACE_SYMTAB("acquiring .text bias = %#lx\n", (UWord
)di
->text_bias
);
2380 /* Accept .data where mapped as rw (data), even if zero-sized */
2381 if (0 == VG_(strcmp
)(name
, ".data")) {
2382 # if defined(SOLARIS_PT_SUNDWTRACE_THRP)
2383 if ((size
== VKI_PT_SUNWDTRACE_SIZE
) && (svma
== dtrace_data_vaddr
)) {
2384 TRACE_SYMTAB("ignoring .data section for dtrace_data "
2385 "%#lx .. %#lx\n", svma
, svma
+ size
- 1);
2387 # endif /* SOLARIS_PT_SUNDWTRACE_THRP */
2395 if (inrw
&& !di
->data_present
) {
2396 di
->data_present
= True
;
2397 di
->data_svma
= svma
;
2398 di
->data_avma
= svma
+ inrw
->bias
;
2399 di
->data_size
= size
;
2400 di
->data_bias
= inrw
->bias
;
2401 di
->data_debug_svma
= svma
;
2402 di
->data_debug_bias
= inrw
->bias
;
2403 TRACE_SYMTAB("acquiring .data svma = %#lx .. %#lx\n",
2405 di
->data_svma
+ di
->data_size
- 1);
2406 TRACE_SYMTAB("acquiring .data avma = %#lx .. %#lx\n",
2408 di
->data_avma
+ di
->data_size
- 1);
2409 TRACE_SYMTAB("acquiring .data bias = %#lx\n", (UWord
)di
->data_bias
);
2415 /* Accept .sdata where mapped as rw (data) */
2416 if (0 == VG_(strcmp
)(name
, ".sdata")) {
2417 if (inrw1
&& !di
->sdata_present
) {
2418 di
->sdata_present
= True
;
2419 di
->sdata_svma
= svma
;
2420 di
->sdata_avma
= svma
+ inrw1
->bias
;
2421 di
->sdata_size
= size
;
2422 di
->sdata_bias
= inrw1
->bias
;
2423 di
->sdata_debug_svma
= svma
;
2424 di
->sdata_debug_bias
= inrw1
->bias
;
2425 TRACE_SYMTAB("acquiring .sdata svma = %#lx .. %#lx\n",
2427 di
->sdata_svma
+ di
->sdata_size
- 1);
2428 TRACE_SYMTAB("acquiring .sdata avma = %#lx .. %#lx\n",
2430 di
->sdata_avma
+ di
->sdata_size
- 1);
2431 TRACE_SYMTAB("acquiring .sdata bias = %#lx\n",
2432 (UWord
)di
->sdata_bias
);
2438 /* Accept .rodata where mapped as rx or rw (data), even if zero-sized */
2439 if (0 == VG_(strcmp
)(name
, ".rodata")) {
2440 if (!di
->rodata_present
) {
2441 di
->rodata_svma
= svma
;
2442 di
->rodata_avma
= svma
;
2443 di
->rodata_size
= size
;
2444 di
->rodata_debug_svma
= svma
;
2446 di
->rodata_avma
+= inrx
->bias
;
2447 di
->rodata_bias
= inrx
->bias
;
2448 di
->rodata_debug_bias
= inrx
->bias
;
2450 di
->rodata_avma
+= inrw1
->bias
;
2451 di
->rodata_bias
= inrw1
->bias
;
2452 di
->rodata_debug_bias
= inrw1
->bias
;
2456 di
->rodata_present
= True
;
2457 TRACE_SYMTAB("acquiring .rodata svma = %#lx .. %#lx\n",
2459 di
->rodata_svma
+ di
->rodata_size
- 1);
2460 TRACE_SYMTAB("acquiring .rodata avma = %#lx .. %#lx\n",
2462 di
->rodata_avma
+ di
->rodata_size
- 1);
2463 TRACE_SYMTAB("acquiring .rodata bias = %#lx\n",
2464 (UWord
)di
->rodata_bias
);
2470 if (0 == VG_(strcmp
)(name
, ".dynbss")) {
2471 if (inrw1
&& !di
->bss_present
) {
2472 dynbss_present
= True
;
2473 di
->bss_present
= True
;
2474 di
->bss_svma
= svma
;
2475 di
->bss_avma
= svma
+ inrw1
->bias
;
2476 di
->bss_size
= size
;
2477 di
->bss_bias
= inrw1
->bias
;
2478 di
->bss_debug_svma
= svma
;
2479 di
->bss_debug_bias
= inrw1
->bias
;
2480 TRACE_SYMTAB("acquiring .dynbss svma = %#lx .. %#lx\n",
2482 di
->bss_svma
+ di
->bss_size
- 1);
2483 TRACE_SYMTAB("acquiring .dynbss avma = %#lx .. %#lx\n",
2485 di
->bss_avma
+ di
->bss_size
- 1);
2486 TRACE_SYMTAB("acquiring .dynbss bias = %#lx\n",
2487 (UWord
)di
->bss_bias
);
2491 /* Accept .bss where mapped as rw (data), even if zero-sized */
2492 if (0 == VG_(strcmp
)(name
, ".bss")) {
2500 if (inrw
&& dynbss_present
) {
2501 vg_assert(di
->bss_present
);
2502 dynbss_present
= False
;
2503 vg_assert(di
->bss_svma
+ di
->bss_size
== svma
);
2504 di
->bss_size
+= size
;
2505 TRACE_SYMTAB("acquiring .bss svma = %#lx .. %#lx\n",
2506 svma
, svma
+ size
- 1);
2507 TRACE_SYMTAB("acquiring .bss avma = %#lx .. %#lx\n",
2508 svma
+ inrw
->bias
, svma
+ inrw
->bias
+ size
- 1);
2509 TRACE_SYMTAB("acquiring .bss bias = %#lx\n",
2510 (UWord
)di
->bss_bias
);
2513 if (inrw
&& !di
->bss_present
) {
2514 di
->bss_present
= True
;
2515 di
->bss_svma
= svma
;
2516 di
->bss_avma
= svma
+ inrw
->bias
;
2517 di
->bss_size
= size
;
2518 di
->bss_bias
= inrw
->bias
;
2519 di
->bss_debug_svma
= svma
;
2520 di
->bss_debug_bias
= inrw
->bias
;
2521 TRACE_SYMTAB("acquiring .bss svma = %#lx .. %#lx\n",
2523 di
->bss_svma
+ di
->bss_size
- 1);
2524 TRACE_SYMTAB("acquiring .bss avma = %#lx .. %#lx\n",
2526 di
->bss_avma
+ di
->bss_size
- 1);
2527 TRACE_SYMTAB("acquiring .bss bias = %#lx\n",
2528 (UWord
)di
->bss_bias
);
2531 /* Now one from the wtf?! department ... */
2532 if (inrx
&& (!inrw
) && !di
->bss_present
) {
2533 /* File contains a .bss, but it got mapped as rx only.
2534 This is very strange. For now, just pretend we didn't
2536 di
->bss_present
= False
;
2541 di
->bss_debug_svma
= 0;
2542 di
->bss_debug_bias
= 0;
2543 if (!VG_(clo_xml
)) {
2544 VG_(message
)(Vg_UserMsg
,
2545 "Warning: the following file's .bss is "
2546 "mapped r-x only - ignoring .bss syms\n");
2547 VG_(message
)(Vg_UserMsg
, " %s\n", di
->fsm
.filename
2553 if ((!inrw
) && (!inrx
) && !di
->bss_present
) {
2554 /* File contains a .bss, but it didn't get mapped. Ignore. */
2555 di
->bss_present
= False
;
2565 if (0 == VG_(strcmp
)(name
, ".sdynbss")) {
2566 if (inrw1
&& !di
->sbss_present
) {
2567 sdynbss_present
= True
;
2568 di
->sbss_present
= True
;
2569 di
->sbss_svma
= svma
;
2570 di
->sbss_avma
= svma
+ inrw1
->bias
;
2571 di
->sbss_size
= size
;
2572 di
->sbss_bias
= inrw1
->bias
;
2573 di
->sbss_debug_svma
= svma
;
2574 di
->sbss_debug_bias
= inrw1
->bias
;
2575 TRACE_SYMTAB("acquiring .sdynbss svma = %#lx .. %#lx\n",
2577 di
->sbss_svma
+ di
->sbss_size
- 1);
2578 TRACE_SYMTAB("acquiring .sdynbss avma = %#lx .. %#lx\n",
2580 di
->sbss_avma
+ di
->sbss_size
- 1);
2581 TRACE_SYMTAB("acquiring .sdynbss bias = %#lx\n",
2582 (UWord
)di
->sbss_bias
);
2586 /* Accept .sbss where mapped as rw (data) */
2587 if (0 == VG_(strcmp
)(name
, ".sbss")) {
2588 if (inrw1
&& sdynbss_present
) {
2589 vg_assert(di
->sbss_present
);
2590 sdynbss_present
= False
;
2591 vg_assert(di
->sbss_svma
+ di
->sbss_size
== svma
);
2592 di
->sbss_size
+= size
;
2593 TRACE_SYMTAB("acquiring .sbss svma = %#lx .. %#lx\n",
2594 svma
, svma
+ size
- 1);
2595 TRACE_SYMTAB("acquiring .sbss avma = %#lx .. %#lx\n",
2596 svma
+ inrw1
->bias
, svma
+ inrw1
->bias
+ size
- 1);
2597 TRACE_SYMTAB("acquiring .sbss bias = %#lx\n", (UWord
)di
->sbss_bias
);
2600 if (inrw1
&& !di
->sbss_present
) {
2601 di
->sbss_present
= True
;
2602 di
->sbss_svma
= svma
;
2603 di
->sbss_avma
= svma
+ inrw1
->bias
;
2604 di
->sbss_size
= size
;
2605 di
->sbss_bias
= inrw1
->bias
;
2606 di
->sbss_debug_svma
= svma
;
2607 di
->sbss_debug_bias
= inrw1
->bias
;
2608 TRACE_SYMTAB("acquiring .sbss svma = %#lx .. %#lx\n",
2610 di
->sbss_svma
+ di
->sbss_size
- 1);
2611 TRACE_SYMTAB("acquiring .sbss avma = %#lx .. %#lx\n",
2613 di
->sbss_avma
+ di
->sbss_size
- 1);
2614 TRACE_SYMTAB("acquiring .sbss bias = %#lx\n", (UWord
)di
->sbss_bias
);
2620 /* Accept .got where mapped as rw (data) */
2621 if (0 == VG_(strcmp
)(name
, ".got")) {
2622 if (inrw1
&& !di
->got_present
) {
2623 di
->got_present
= True
;
2624 di
->got_avma
= svma
+ inrw1
->bias
;
2625 di
->got_size
= size
;
2626 TRACE_SYMTAB("acquiring .got avma = %#lx\n", di
->got_avma
);
2632 /* Accept .got.plt where mapped as rw (data) */
2633 if (0 == VG_(strcmp
)(name
, ".got.plt")) {
2641 if (inrw
&& !di
->gotplt_present
) {
2642 di
->gotplt_present
= True
;
2643 di
->gotplt_avma
= svma
+ inrw
->bias
;
2644 di
->gotplt_size
= size
;
2645 TRACE_SYMTAB("acquiring .got.plt avma = %#lx\n", di
->gotplt_avma
);
2646 } else if (size
!= 0) {
2651 /* PLT is different on different platforms, it seems. */
2652 # if defined(VGP_x86_linux) || defined(VGP_amd64_linux) \
2653 || defined(VGP_arm_linux) || defined (VGP_s390x_linux) \
2654 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
2655 || defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) \
2656 || defined(VGP_x86_solaris) || defined(VGP_amd64_solaris) \
2657 || defined(VGP_x86_freebsd) || defined(VGP_amd64_freebsd)
2658 /* Accept .plt where mapped as rx (code) */
2659 if (0 == VG_(strcmp
)(name
, ".plt")) {
2660 if (inrx
&& !di
->plt_present
) {
2661 di
->plt_present
= True
;
2662 di
->plt_avma
= svma
+ inrx
->bias
;
2663 di
->plt_size
= size
;
2664 TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di
->plt_avma
);
2669 # elif defined(VGP_ppc32_linux)
2670 /* Accept .plt where mapped as rw (data) */
2671 if (0 == VG_(strcmp
)(name
, ".plt")) {
2672 if (inrw1
&& !di
->plt_present
) {
2673 di
->plt_present
= True
;
2674 di
->plt_avma
= svma
+ inrw1
->bias
;
2675 di
->plt_size
= size
;
2676 TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di
->plt_avma
);
2681 # elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
2682 /* Accept .plt where mapped as rw (data), or unmapped */
2683 if (0 == VG_(strcmp
)(name
, ".plt")) {
2684 if (inrw1
&& !di
->plt_present
) {
2685 di
->plt_present
= True
;
2686 di
->plt_avma
= svma
+ inrw1
->bias
;
2687 di
->plt_size
= size
;
2688 TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di
->plt_avma
);
2690 if ((!inrw1
) && (!inrx
) && size
> 0 && !di
->plt_present
) {
2691 /* File contains a .plt, but it didn't get mapped.
2692 Presumably it is not required on this platform. At
2693 least don't reject the situation as invalid. */
2694 di
->plt_present
= True
;
2702 # error "Unsupported platform"
2705 /* Accept .opd where mapped as rw (data) */
2706 if (0 == VG_(strcmp
)(name
, ".opd")) {
2707 if (inrw1
&& !di
->opd_present
) {
2708 di
->opd_present
= True
;
2709 di
->opd_avma
= svma
+ inrw1
->bias
;
2710 di
->opd_size
= size
;
2711 TRACE_SYMTAB("acquiring .opd avma = %#lx\n", di
->opd_avma
);
2717 /* Accept .eh_frame where mapped as rx (code). This seems to be
2718 the common case. However, if that doesn't pan out, try for
2719 rw (data) instead. We can handle up to N_EHFRAME_SECTS per
2721 if (0 == VG_(strcmp
)(name
, ".eh_frame")) {
2722 if (inrx
&& di
->n_ehframe
< N_EHFRAME_SECTS
) {
2723 di
->ehframe_avma
[di
->n_ehframe
] = svma
+ inrx
->bias
;
2724 di
->ehframe_size
[di
->n_ehframe
] = size
;
2725 TRACE_SYMTAB("acquiring .eh_frame avma = %#lx\n",
2726 di
->ehframe_avma
[di
->n_ehframe
]);
2729 if (inrw1
&& di
->n_ehframe
< N_EHFRAME_SECTS
) {
2730 di
->ehframe_avma
[di
->n_ehframe
] = svma
+ inrw1
->bias
;
2731 di
->ehframe_size
[di
->n_ehframe
] = size
;
2732 TRACE_SYMTAB("acquiring .eh_frame avma = %#lx\n",
2733 di
->ehframe_avma
[di
->n_ehframe
]);
2740 /* Accept .ARM.exidx where mapped as rx (code). */
2741 /* FIXME: make sure the entire section is mapped in, not just
2742 the first address. */
2743 if (0 == VG_(strcmp
)(name
, ".ARM.exidx")) {
2744 if (inrx
&& !di
->exidx_present
) {
2745 di
->exidx_present
= True
;
2746 di
->exidx_svma
= svma
;
2747 di
->exidx_avma
= svma
+ inrx
->bias
;
2748 di
->exidx_size
= size
;
2749 di
->exidx_bias
= inrx
->bias
;
2750 TRACE_SYMTAB("acquiring .exidx svma = %#lx .. %#lx\n",
2752 di
->exidx_svma
+ di
->exidx_size
- 1);
2753 TRACE_SYMTAB("acquiring .exidx avma = %#lx .. %#lx\n",
2755 di
->exidx_avma
+ di
->exidx_size
- 1);
2756 TRACE_SYMTAB("acquiring .exidx bias = %#lx\n",
2757 (UWord
)di
->exidx_bias
);
2763 /* Accept .ARM.extab where mapped as rx (code). */
2764 /* FIXME: make sure the entire section is mapped in, not just
2765 the first address. */
2766 if (0 == VG_(strcmp
)(name
, ".ARM.extab")) {
2767 if (inrx
&& !di
->extab_present
) {
2768 di
->extab_present
= True
;
2769 di
->extab_svma
= svma
;
2770 di
->extab_avma
= svma
+ inrx
->bias
;
2771 di
->extab_size
= size
;
2772 di
->extab_bias
= inrx
->bias
;
2773 TRACE_SYMTAB("acquiring .extab svma = %#lx .. %#lx\n",
2775 di
->extab_svma
+ di
->extab_size
- 1);
2776 TRACE_SYMTAB("acquiring .extab avma = %#lx .. %#lx\n",
2778 di
->extab_avma
+ di
->extab_size
- 1);
2779 TRACE_SYMTAB("acquiring .extab bias = %#lx\n",
2780 (UWord
)di
->extab_bias
);
2786 ML_(dinfo_free
)(name
);
2790 } /* iterate over the section headers */
2793 if (0) VG_(printf
)("YYYY text_: avma %#lx size %lu bias %#lx\n",
2794 di
->text_avma
, di
->text_size
, (UWord
)di
->text_bias
);
2796 if (VG_(clo_verbosity
) > 2 || VG_(clo_trace_redir
))
2797 VG_(message
)(Vg_DebugMsg
, " svma %#010lx, avma %#010lx\n",
2798 di
->text_avma
- di
->text_bias
,
2802 TRACE_SYMTAB("------ Finding image addresses "
2803 "for debug-info sections ------\n");
2806 /* Find interesting sections, read the symbol table(s), read any
2807 debug information. Each section is located either in the main,
2808 debug or alt-debug files, but only in one. For each section,
2809 |section_escn| records which of |mimg|, |dimg| or |aimg| we
2810 found it in, along with the section's image offset and its size.
2811 The triples (section_img, section_ioff, section_szB) are
2812 consistent, in that they are always either (NULL,
2813 DiOffT_INVALID, 0), or refer to the same image, and are all
2814 assigned together. */
2817 DiSlice strtab_escn
= DiSlice_INVALID
; // .strtab
2818 DiSlice symtab_escn
= DiSlice_INVALID
; // .symtab
2819 DiSlice dynstr_escn
= DiSlice_INVALID
; // .dynstr
2820 DiSlice dynsym_escn
= DiSlice_INVALID
; // .dynsym
2821 # if defined(VGO_solaris)
2822 DiSlice ldynsym_escn
= DiSlice_INVALID
; // .SUNW_ldynsym
2824 DiSlice debuglink_escn
= DiSlice_INVALID
; // .gnu_debuglink
2825 DiSlice debugaltlink_escn
= DiSlice_INVALID
; // .gnu_debugaltlink
2826 DiSlice debug_line_escn
= DiSlice_INVALID
; // .debug_line (dwarf2)
2827 DiSlice debug_info_escn
= DiSlice_INVALID
; // .debug_info (dwarf2)
2828 DiSlice debug_types_escn
= DiSlice_INVALID
; // .debug_types (dwarf4)
2829 DiSlice debug_abbv_escn
= DiSlice_INVALID
; // .debug_abbrev (dwarf2)
2830 DiSlice debug_str_escn
= DiSlice_INVALID
; // .debug_str (dwarf2)
2831 DiSlice debug_line_str_escn
= DiSlice_INVALID
; // .debug_line_str(dwarf5)
2832 DiSlice debug_ranges_escn
= DiSlice_INVALID
; // .debug_ranges (dwarf2)
2833 DiSlice debug_rnglists_escn
= DiSlice_INVALID
; // .debug_rnglists(dwarf5)
2834 DiSlice debug_loclists_escn
= DiSlice_INVALID
; // .debug_loclists(dwarf5)
2835 DiSlice debug_addr_escn
= DiSlice_INVALID
; // .debug_addr (dwarf5)
2836 DiSlice debug_str_offsets_escn
= DiSlice_INVALID
; // .debug_str_offsets (dwarf5)
2837 DiSlice debug_loc_escn
= DiSlice_INVALID
; // .debug_loc (dwarf2)
2838 DiSlice debug_frame_escn
= DiSlice_INVALID
; // .debug_frame (dwarf2)
2839 DiSlice debug_line_alt_escn
= DiSlice_INVALID
; // .debug_line (alt)
2840 DiSlice debug_info_alt_escn
= DiSlice_INVALID
; // .debug_info (alt)
2841 DiSlice debug_abbv_alt_escn
= DiSlice_INVALID
; // .debug_abbrev (alt)
2842 DiSlice debug_str_alt_escn
= DiSlice_INVALID
; // .debug_str (alt)
2843 DiSlice dwarf1d_escn
= DiSlice_INVALID
; // .debug (dwarf1)
2844 DiSlice dwarf1l_escn
= DiSlice_INVALID
; // .line (dwarf1)
2845 DiSlice opd_escn
= DiSlice_INVALID
; // .opd (dwarf2,
2847 DiSlice ehframe_escn
[N_EHFRAME_SECTS
]; // .eh_frame (dwarf2)
2849 for (i
= 0; i
< N_EHFRAME_SECTS
; i
++)
2850 ehframe_escn
[i
] = DiSlice_INVALID
;
2852 /* Find all interesting sections */
2854 UInt ehframe_mix
= 0;
2856 /* What FIND does: it finds the section called _SEC_NAME. The
2857 size of it is assigned to _SEC_SIZE. The address of the
2858 section in the transiently loaded oimage is assigned to
2859 _SEC_IMG. If the section is found, _POST_FX is executed
2860 after _SEC_NAME and _SEC_SIZE have been assigned to.
2862 Even for sections which are marked loadable, the client's
2863 ld.so may not have loaded them yet, so there is no guarantee
2864 that we can safely prod around in any such area). Because
2865 the entire object file is transiently mapped aboard for
2866 inspection, it's always safe to inspect that area. */
2869 /* Iterate over section headers (again) */
2870 for (i
= 0; i
< ehdr_m
.e_shnum
; i
++) {
2872 # define FINDX(_sec_name, _sec_escn, _post_fx) \
2874 ElfXX_Shdr a_shdr; \
2875 ML_(img_get)(&a_shdr, mimg, \
2876 INDEX_BIS(shdr_mioff, i, shdr_ment_szB), \
2878 if (0 == ML_(img_strcmp_c)(mimg, shdr_strtab_mioff \
2879 + a_shdr.sh_name, _sec_name)) { \
2881 _sec_escn.img = mimg; \
2882 _sec_escn.ioff = (DiOffT)a_shdr.sh_offset; \
2883 _sec_escn.szB = a_shdr.sh_size; \
2884 if (!check_compression(&a_shdr, &_sec_escn)) { \
2885 ML_(symerr)(di, True, " Compression type is unsupported"); \
2888 nobits = a_shdr.sh_type == SHT_NOBITS; \
2889 vg_assert(_sec_escn.img != NULL); \
2890 vg_assert(_sec_escn.ioff != DiOffT_INVALID); \
2891 TRACE_SYMTAB( "%-18s: ioff %llu .. %llu\n", \
2892 _sec_name, (ULong)a_shdr.sh_offset, \
2893 ((ULong)a_shdr.sh_offset) + a_shdr.sh_size - 1); \
2894 /* SHT_NOBITS sections have zero size in the file. */ \
2896 a_shdr.sh_offset + \
2897 a_shdr.sh_size > ML_(img_real_size)(mimg)) { \
2898 ML_(symerr)(di, True, \
2899 " section beyond image end?!"); \
2906 /* Version with no post-effects */
2907 # define FIND(_sec_name, _sec_escn) \
2908 FINDX(_sec_name, _sec_escn, /**/)
2911 FIND( ".dynsym", dynsym_escn
)
2912 FIND( ".dynstr", dynstr_escn
)
2913 FIND( ".symtab", symtab_escn
)
2914 FIND( ".strtab", strtab_escn
)
2915 # if defined(VGO_solaris)
2916 FIND( ".SUNW_ldynsym", ldynsym_escn
)
2919 FIND( ".gnu_debuglink", debuglink_escn
)
2920 FIND( ".gnu_debugaltlink", debugaltlink_escn
)
2922 FIND( ".debug_line", debug_line_escn
)
2923 if (!ML_(sli_is_valid
)(debug_line_escn
))
2924 FIND(".zdebug_line", debug_line_escn
)
2926 FIND( ".debug_info", debug_info_escn
)
2927 if (!ML_(sli_is_valid
)(debug_info_escn
))
2928 FIND(".zdebug_info", debug_info_escn
)
2930 FIND( ".debug_types", debug_types_escn
)
2931 if (!ML_(sli_is_valid
)(debug_types_escn
))
2932 FIND(".zdebug_types", debug_types_escn
)
2934 FIND( ".debug_abbrev", debug_abbv_escn
)
2935 if (!ML_(sli_is_valid
)(debug_abbv_escn
))
2936 FIND(".zdebug_abbrev", debug_abbv_escn
)
2938 FIND( ".debug_str", debug_str_escn
)
2939 if (!ML_(sli_is_valid
)(debug_str_escn
))
2940 FIND(".zdebug_str", debug_str_escn
)
2942 FIND( ".debug_line_str", debug_line_str_escn
)
2943 if (!ML_(sli_is_valid
)(debug_line_str_escn
))
2944 FIND(".zdebug_str", debug_line_str_escn
)
2946 FIND( ".debug_ranges", debug_ranges_escn
)
2947 if (!ML_(sli_is_valid
)(debug_ranges_escn
))
2948 FIND(".zdebug_ranges", debug_ranges_escn
)
2950 FIND( ".debug_rnglists", debug_rnglists_escn
)
2951 if (!ML_(sli_is_valid
)(debug_rnglists_escn
))
2952 FIND(".zdebug_rnglists", debug_rnglists_escn
)
2954 FIND( ".debug_loclists", debug_loclists_escn
)
2955 if (!ML_(sli_is_valid
)(debug_loclists_escn
))
2956 FIND(".zdebug_loclists", debug_loclists_escn
)
2958 FIND( ".debug_loc", debug_loc_escn
)
2959 if (!ML_(sli_is_valid
)(debug_loc_escn
))
2960 FIND(".zdebug_loc", debug_loc_escn
)
2962 FIND( ".debug_frame", debug_frame_escn
)
2963 if (!ML_(sli_is_valid
)(debug_frame_escn
))
2964 FIND(".zdebug_frame", debug_frame_escn
)
2966 FIND( ".debug_addr", debug_addr_escn
)
2967 if (!ML_(sli_is_valid
)(debug_addr_escn
))
2968 FIND(".zdebug_addr", debug_addr_escn
)
2970 FIND( ".debug_str_offsets", debug_str_offsets_escn
)
2971 if (!ML_(sli_is_valid
)(debug_str_offsets_escn
))
2972 FIND(".zdebug_str_offsets", debug_str_offsets_escn
)
2974 FIND( ".debug", dwarf1d_escn
)
2975 FIND( ".line", dwarf1l_escn
)
2977 FIND( ".opd", opd_escn
)
2979 FINDX( ".eh_frame", ehframe_escn
[ehframe_mix
],
2980 do { ehframe_mix
++; vg_assert(ehframe_mix
<= N_EHFRAME_SECTS
);
2983 /* Comment_on_EH_FRAME_MULTIPLE_INSTANCES: w.r.t. .eh_frame
2984 multi-instance kludgery, how are we assured that the order
2985 in which we fill in ehframe_escn[] is consistent with the
2986 order in which we previously filled in di->ehframe_avma[]
2987 and di->ehframe_size[] ? By the fact that in both cases,
2988 these arrays were filled in by iterating over the section
2989 headers top-to-bottom. So both loops (this one and the
2990 previous one) encounter the .eh_frame entries in the same
2991 order and so fill in these arrays in a consistent order.
2996 } /* Iterate over section headers (again) */
2999 /* Now, see if we can find a debuginfo object, and if so connect
3001 vg_assert(dimg
== NULL
&& aimg
== NULL
);
3003 #if defined(VGO_freebsd)
3005 read_and_set_osrel(mimg
);
3009 /* Look for a build-id */
3010 HChar
* buildid
= find_buildid(mimg
, False
, False
);
3012 /* If we don't have a .debug_info section in the main image then
3013 look for a debug image that matches either the build-id or
3014 the debuglink-CRC32 in the main image. If the main image
3015 doesn't contain either of those then this won't even bother
3016 to try looking. This looks in all known places, including
3017 the --extra-debuginfo-path if specified and on the
3018 --debuginfo-server if specified. */
3019 if (debug_info_escn
.img
== NULL
&&
3020 (buildid
!= NULL
|| debuglink_escn
.img
!= NULL
)) {
3021 /* Do have a debuglink section? */
3022 if (debuglink_escn
.img
!= NULL
) {
3024 = VG_ROUNDUP(ML_(img_strlen
)(debuglink_escn
.img
,
3025 debuglink_escn
.ioff
)+1, 4);
3026 vg_assert(crc_offset
+ sizeof(UInt
) <= debuglink_escn
.szB
);
3028 /* Extract the CRC from the debuglink section */
3029 UInt crc
= ML_(img_get_UInt
)(debuglink_escn
.img
,
3030 debuglink_escn
.ioff
+ crc_offset
);
3032 /* See if we can find a matching debug file */
3033 HChar
* debuglink_str_m
3034 = ML_(img_strdup
)(debuglink_escn
.img
,
3035 "di.redi_dlk.1", debuglink_escn
.ioff
);
3036 dimg
= find_debug_file( di
, di
->fsm
.filename
, buildid
,
3037 debuglink_str_m
, crc
, False
);
3038 if (debuglink_str_m
)
3039 ML_(dinfo_free
)(debuglink_str_m
);
3041 /* See if we can find a matching debug file */
3042 dimg
= find_debug_file( di
, di
->fsm
.filename
, buildid
,
3048 ML_(dinfo_free
)(buildid
);
3049 buildid
= NULL
; /* paranoia */
3052 /* As a last-ditch measure, try looking for in the
3053 --extra-debuginfo-path and/or on the --debuginfo-server, but
3054 only in the case where --allow-mismatched-debuginfo=yes.
3055 This is dangerous in that (1) it gives no assurance that the
3056 debuginfo object matches the main one, and hence (2) we will
3057 very likely get an assertion in the code below, if indeed
3058 there is a mismatch. Hence it is disabled by default
3059 (--allow-mismatched-debuginfo=no). Nevertheless it's
3060 sometimes a useful way of getting out of a tight spot.
3062 Note that we're ignoring the name in the .gnu_debuglink
3063 section here, and just looking for a file of the same name
3064 either the extra-path or on the server. */
3065 if (dimg
== NULL
&& VG_(clo_allow_mismatched_debuginfo
)) {
3066 dimg
= find_debug_file_ad_hoc( di
, di
->fsm
.filename
);
3070 /* If we were successful in finding a debug image, pull various
3071 SVMA/bias/size and image addresses out of it. */
3072 if (dimg
!= NULL
&& is_elf_object_file_by_DiImage(dimg
, False
)) {
3074 /* Pull out and validate program header and section header info */
3075 DiOffT ehdr_dioff
= 0;
3076 ElfXX_Ehdr ehdr_dimg
;
3077 ML_(img_get
)(&ehdr_dimg
, dimg
, ehdr_dioff
, sizeof(ehdr_dimg
));
3079 DiOffT phdr_dioff
= ehdr_dimg
.e_phoff
;
3080 UWord phdr_dnent
= ehdr_dimg
.e_phnum
;
3081 UWord phdr_dent_szB
= ehdr_dimg
.e_phentsize
;
3083 DiOffT shdr_dioff
= ehdr_dimg
.e_shoff
;
3084 UWord shdr_dnent
= ehdr_dimg
.e_shnum
;
3085 UWord shdr_dent_szB
= ehdr_dimg
.e_shentsize
;
3087 DiOffT shdr_strtab_dioff
= DiOffT_INVALID
;
3089 /* SVMAs covered by rx and rw segments and corresponding bias. */
3090 Addr rx_dsvma_limit
= 0;
3091 PtrdiffT rx_dbias
= 0;
3092 Addr rw_dsvma_limit
= 0;
3093 PtrdiffT rw_dbias
= 0;
3095 Bool need_symtab
, need_dwarf2
, need_dwarf1
;
3098 || !ML_(img_valid
)(dimg
, phdr_dioff
,
3099 phdr_dnent
* phdr_dent_szB
)) {
3100 ML_(symerr
)(di
, True
,
3101 "Missing or invalid ELF Program Header Table"
3102 " (debuginfo file)");
3107 || !ML_(img_valid
)(dimg
, shdr_dioff
,
3108 shdr_dnent
* shdr_dent_szB
)) {
3109 ML_(symerr
)(di
, True
,
3110 "Missing or invalid ELF Section Header Table"
3111 " (debuginfo file)");
3115 /* Also find the section header's string table, and validate. */
3116 /* checked previously by is_elf_object_file: */
3117 vg_assert(ehdr_dimg
.e_shstrndx
!= SHN_UNDEF
);
3119 // shdr_dioff is the offset of the section header table
3120 // and we need the ehdr_dimg.e_shstrndx'th entry
3121 { ElfXX_Shdr a_shdr
;
3122 ML_(img_get
)(&a_shdr
, dimg
,
3123 INDEX_BIS(shdr_dioff
, ehdr_dimg
.e_shstrndx
,
3126 shdr_strtab_dioff
= a_shdr
.sh_offset
;
3127 if (!ML_(img_valid
)(dimg
, shdr_strtab_dioff
,
3128 1/*bogus, but we don't know the real size*/)) {
3129 ML_(symerr
)(di
, True
,
3130 "Invalid ELF Section Header String Table"
3131 " (debuginfo file)");
3136 for (i
= 0; i
< ehdr_dimg
.e_phnum
; i
++) {
3138 ML_(img_get
)(&a_phdr
, dimg
, INDEX_BIS(ehdr_dimg
.e_phoff
,
3141 if (a_phdr
.p_type
== PT_LOAD
) {
3142 for (j
= 0; j
< VG_(sizeXA
)(di
->fsm
.maps
); j
++) {
3143 const DebugInfoMapping
* map
= VG_(indexXA
)(di
->fsm
.maps
, j
);
3144 if ( a_phdr
.p_offset
>= map
->foff
3145 && a_phdr
.p_offset
< map
->foff
+ map
->size
3146 && a_phdr
.p_offset
+ a_phdr
.p_filesz
3147 < map
->foff
+ map
->size
) {
3148 if (map
->rx
&& rx_dsvma_limit
== 0) {
3149 rx_dsvma_limit
= a_phdr
.p_vaddr
+ a_phdr
.p_memsz
;
3150 rx_dbias
= map
->avma
- map
->foff
+ a_phdr
.p_offset
3153 if (map
->rw
&& rw_dsvma_limit
== 0) {
3154 rw_dsvma_limit
= a_phdr
.p_vaddr
+ a_phdr
.p_memsz
;
3155 rw_dbias
= map
->avma
- map
->foff
+ a_phdr
.p_offset
3164 need_symtab
= (symtab_escn
.img
== NULL
);
3165 need_dwarf2
= (debug_info_escn
.img
== NULL
);
3166 need_dwarf1
= (dwarf1d_escn
.img
== NULL
);
3168 /* Find all interesting sections in the debug image */
3169 for (i
= 0; i
< ehdr_dimg
.e_shnum
; i
++) {
3171 /* Find debug svma and bias information for sections
3172 we found in the main file. */
3174 # define FIND(_sec, _seg) \
3176 ElfXX_Shdr a_shdr; \
3177 ML_(img_get)(&a_shdr, dimg, \
3178 INDEX_BIS(shdr_dioff, i, shdr_dent_szB), \
3180 if (di->_sec##_present \
3181 && 0 == ML_(img_strcmp_c)(dimg, shdr_strtab_dioff \
3182 + a_shdr.sh_name, "." #_sec)) { \
3183 vg_assert(di->_sec##_size == a_shdr.sh_size); \
3184 /* JRS 2013-Jun-01: the following assert doesn't contain */ \
3185 /* any ==s, which seems to me to be suspicious. */ \
3186 vg_assert(di->_sec##_avma + a_shdr.sh_addr + _seg##_dbias); \
3187 /* Assume we have a correct value for the main */ \
3188 /* object's bias. Use that to derive the debuginfo */ \
3189 /* object's bias, by adding the difference in SVMAs */ \
3190 /* for the corresponding sections in the two files. */ \
3191 /* That should take care of all prelinking effects. */ \
3192 di->_sec##_debug_svma = a_shdr.sh_addr; \
3193 di->_sec##_debug_bias \
3194 = di->_sec##_bias + \
3195 di->_sec##_svma - di->_sec##_debug_svma; \
3196 TRACE_SYMTAB("acquiring ." #_sec \
3197 " debug svma = %#lx .. %#lx\n", \
3198 di->_sec##_debug_svma, \
3199 di->_sec##_debug_svma + di->_sec##_size - 1); \
3200 TRACE_SYMTAB("acquiring ." #_sec " debug bias = %#lx\n", \
3201 (UWord)di->_sec##_debug_bias); \
3205 /* SECTION SEGMENT */
3215 /* Same deal as previous FIND, except only do it for those
3216 sections which we didn't find in the main file. */
3218 # define FIND(_condition, _sec_name, _sec_escn) \
3220 ElfXX_Shdr a_shdr; \
3221 ML_(img_get)(&a_shdr, dimg, \
3222 INDEX_BIS(shdr_dioff, i, shdr_dent_szB), \
3225 && 0 == ML_(img_strcmp_c)(dimg, shdr_strtab_dioff \
3226 + a_shdr.sh_name, _sec_name)) { \
3228 if (_sec_escn.img != NULL) { \
3229 ML_(symerr)(di, True, \
3230 " debuginfo section duplicates a" \
3231 " section in the main ELF file"); \
3234 _sec_escn.img = dimg; \
3235 _sec_escn.ioff = (DiOffT)a_shdr.sh_offset; \
3236 _sec_escn.szB = a_shdr.sh_size; \
3237 if (!check_compression(&a_shdr, &_sec_escn)) { \
3238 ML_(symerr)(di, True, " Compression type is unsupported"); \
3241 nobits = a_shdr.sh_type == SHT_NOBITS; \
3242 vg_assert(_sec_escn.img != NULL); \
3243 vg_assert(_sec_escn.ioff != DiOffT_INVALID); \
3244 TRACE_SYMTAB( "%-18s: dioff %llu .. %llu\n", \
3246 (ULong)a_shdr.sh_offset, \
3247 ((ULong)a_shdr.sh_offset) + a_shdr.sh_size - 1); \
3248 /* SHT_NOBITS sections have zero size in the file. */ \
3249 if (!nobits && a_shdr.sh_offset \
3250 + a_shdr.sh_size > ML_(img_real_size)(_sec_escn.img)) { \
3251 ML_(symerr)(di, True, \
3252 " section beyond image end?!"); \
3258 /* NEEDED? NAME ElfSec */
3259 FIND( need_symtab
, ".symtab", symtab_escn
)
3260 FIND( need_symtab
, ".strtab", strtab_escn
)
3261 FIND( need_dwarf2
, ".debug_line", debug_line_escn
)
3262 if (!ML_(sli_is_valid
)(debug_line_escn
))
3263 FIND(need_dwarf2
, ".zdebug_line", debug_line_escn
)
3265 FIND( need_dwarf2
, ".debug_info", debug_info_escn
)
3266 if (!ML_(sli_is_valid
)(debug_info_escn
))
3267 FIND(need_dwarf2
, ".zdebug_info", debug_info_escn
)
3269 FIND( need_dwarf2
, ".debug_types", debug_types_escn
)
3270 if (!ML_(sli_is_valid
)(debug_types_escn
))
3271 FIND(need_dwarf2
, ".zdebug_types", debug_types_escn
)
3273 FIND( need_dwarf2
, ".debug_abbrev", debug_abbv_escn
)
3274 if (!ML_(sli_is_valid
)(debug_abbv_escn
))
3275 FIND(need_dwarf2
, ".zdebug_abbrev", debug_abbv_escn
)
3277 FIND( need_dwarf2
, ".debug_str", debug_str_escn
)
3278 if (!ML_(sli_is_valid
)(debug_str_escn
))
3279 FIND(need_dwarf2
, ".zdebug_str", debug_str_escn
)
3281 FIND( need_dwarf2
, ".debug_line_str", debug_line_str_escn
)
3282 if (!ML_(sli_is_valid
)(debug_line_str_escn
))
3283 FIND(need_dwarf2
, ".zdebug_line_str", debug_line_str_escn
)
3285 FIND( need_dwarf2
, ".debug_ranges", debug_ranges_escn
)
3286 if (!ML_(sli_is_valid
)(debug_ranges_escn
))
3287 FIND(need_dwarf2
, ".zdebug_ranges", debug_ranges_escn
)
3289 FIND( need_dwarf2
, ".debug_rnglists", debug_rnglists_escn
)
3290 if (!ML_(sli_is_valid
)(debug_rnglists_escn
))
3291 FIND(need_dwarf2
, ".zdebug_rnglists", debug_rnglists_escn
)
3293 FIND( need_dwarf2
, ".debug_loclists", debug_loclists_escn
)
3294 if (!ML_(sli_is_valid
)(debug_loclists_escn
))
3295 FIND(need_dwarf2
, ".zdebug_loclists", debug_loclists_escn
)
3297 FIND( need_dwarf2
, ".debug_loc", debug_loc_escn
)
3298 if (!ML_(sli_is_valid
)(debug_loc_escn
))
3299 FIND(need_dwarf2
, ".zdebug_loc", debug_loc_escn
)
3301 FIND( need_dwarf2
, ".debug_frame", debug_frame_escn
)
3302 if (!ML_(sli_is_valid
)(debug_frame_escn
))
3303 FIND(need_dwarf2
, ".zdebug_frame", debug_frame_escn
)
3305 FIND( need_dwarf2
, ".debug_addr", debug_addr_escn
)
3306 if (!ML_(sli_is_valid
)(debug_addr_escn
))
3307 FIND(need_dwarf2
, ".zdebug_addr", debug_addr_escn
)
3309 FIND( need_dwarf2
, ".debug_str_offsets", debug_str_offsets_escn
)
3310 if (!ML_(sli_is_valid
)(debug_str_offsets_escn
))
3311 FIND(need_dwarf2
, ".zdebug_str_offsets", debug_str_offsets_escn
)
3313 if (!ML_(sli_is_valid
)(debugaltlink_escn
))
3314 FIND( need_dwarf2
, ".gnu_debugaltlink", debugaltlink_escn
)
3316 FIND( need_dwarf1
, ".debug", dwarf1d_escn
)
3317 FIND( need_dwarf1
, ".line", dwarf1l_escn
)
3320 } /* Find all interesting sections */
3321 } /* do we have a debug image? */
3324 /* Look for alternate debug image, and if found, connect |aimg|
3326 vg_assert(aimg
== NULL
);
3328 if (debugaltlink_escn
.img
!= NULL
) {
3329 HChar
* altfile_str_m
3330 = ML_(img_strdup
)(debugaltlink_escn
.img
,
3331 "di.fbi.3", debugaltlink_escn
.ioff
);
3332 UInt buildid_offset
= ML_(img_strlen
)(debugaltlink_escn
.img
,
3333 debugaltlink_escn
.ioff
)+1;
3335 vg_assert(buildid_offset
< debugaltlink_escn
.szB
);
3338 = ML_(dinfo_zalloc
)("di.fbi.4",
3339 (debugaltlink_escn
.szB
- buildid_offset
)
3342 /* The altfile might be relative to the debug file or main file.
3343 Make sure that we got the real file, not a symlink. */
3344 HChar
*dbgname
= di
->fsm
.dbgname
? di
->fsm
.dbgname
: di
->fsm
.filename
;
3345 HChar
* rdbgname
= readlink_path (dbgname
);
3346 if (rdbgname
== NULL
)
3347 rdbgname
= ML_(dinfo_strdup
)("rdbgname", dbgname
);
3349 for (j
= 0; j
< debugaltlink_escn
.szB
- buildid_offset
; j
++)
3351 altbuildid
+ 2 * j
, "%02x",
3352 (UInt
)ML_(img_get_UChar
)(debugaltlink_escn
.img
,
3353 debugaltlink_escn
.ioff
3354 + buildid_offset
+ j
));
3356 /* See if we can find a matching debug file */
3357 aimg
= find_debug_file( di
, rdbgname
, altbuildid
,
3358 altfile_str_m
, 0, True
);
3360 ML_(dinfo_free
)(rdbgname
);
3363 ML_(dinfo_free
)(altfile_str_m
);
3364 ML_(dinfo_free
)(altbuildid
);
3368 /* If we were successful in finding alternate debug image, pull various
3369 size and image addresses out of it. */
3370 if (aimg
!= NULL
&& is_elf_object_file_by_DiImage(aimg
, True
)) {
3372 /* Pull out and validate program header and section header info */
3373 DiOffT ehdr_aioff
= 0;
3374 ElfXX_Ehdr ehdr_aimg
;
3375 ML_(img_get
)(&ehdr_aimg
, aimg
, ehdr_aioff
, sizeof(ehdr_aimg
));
3377 DiOffT shdr_aioff
= ehdr_aimg
.e_shoff
;
3378 UWord shdr_anent
= ehdr_aimg
.e_shnum
;
3379 UWord shdr_aent_szB
= ehdr_aimg
.e_shentsize
;
3381 DiOffT shdr_strtab_aioff
= DiOffT_INVALID
;
3384 || !ML_(img_valid
)(aimg
, shdr_aioff
,
3385 shdr_anent
* shdr_aent_szB
)) {
3386 ML_(symerr
)(di
, True
,
3387 "Missing or invalid ELF Section Header Table"
3388 " (alternate debuginfo file)");
3392 /* Also find the section header's string table, and validate. */
3393 /* checked previously by is_elf_object_file: */
3394 vg_assert(ehdr_aimg
.e_shstrndx
!= SHN_UNDEF
);
3396 // shdr_aioff is the offset of the section header table
3397 // and we need the ehdr_aimg.e_shstrndx'th entry
3398 { ElfXX_Shdr a_shdr
;
3399 ML_(img_get
)(&a_shdr
, aimg
,
3400 INDEX_BIS(shdr_aioff
, ehdr_aimg
.e_shstrndx
,
3403 shdr_strtab_aioff
= a_shdr
.sh_offset
;
3404 if (!ML_(img_valid
)(aimg
, shdr_strtab_aioff
,
3405 1/*bogus, but we don't know the real size*/)) {
3406 ML_(symerr
)(di
, True
,
3407 "Invalid ELF Section Header String Table"
3408 " (alternate debuginfo file)");
3413 /* Find all interesting sections */
3414 for (i
= 0; i
< ehdr_aimg
.e_shnum
; i
++) {
3416 # define FIND(_sec_name, _sec_escn) \
3418 ElfXX_Shdr a_shdr; \
3419 ML_(img_get)(&a_shdr, aimg, \
3420 INDEX_BIS(shdr_aioff, i, shdr_aent_szB), \
3422 if (0 == ML_(img_strcmp_c)(aimg, shdr_strtab_aioff \
3423 + a_shdr.sh_name, _sec_name)) { \
3424 if (_sec_escn.img != NULL) { \
3425 ML_(symerr)(di, True, \
3426 " alternate debuginfo section duplicates a" \
3427 " section in the main ELF file"); \
3430 _sec_escn.img = aimg; \
3431 _sec_escn.ioff = (DiOffT)a_shdr.sh_offset; \
3432 _sec_escn.szB = a_shdr.sh_size; \
3433 if (!check_compression(&a_shdr, &_sec_escn)) { \
3434 ML_(symerr)(di, True, " Compression type is " \
3438 vg_assert(_sec_escn.img != NULL); \
3439 vg_assert(_sec_escn.ioff != DiOffT_INVALID); \
3440 TRACE_SYMTAB( "%-18s: aioff %llu .. %llu\n", \
3442 (ULong)a_shdr.sh_offset, \
3443 ((ULong)a_shdr.sh_offset) + a_shdr.sh_size - 1); \
3448 FIND(".debug_line", debug_line_alt_escn
)
3449 if (!ML_(sli_is_valid
)(debug_line_alt_escn
))
3450 FIND(".zdebug_line", debug_line_alt_escn
)
3452 FIND(".debug_info", debug_info_alt_escn
)
3453 if (!ML_(sli_is_valid
)(debug_info_alt_escn
))
3454 FIND(".zdebug_info", debug_info_alt_escn
)
3456 FIND(".debug_abbrev", debug_abbv_alt_escn
)
3457 if (!ML_(sli_is_valid
)(debug_abbv_alt_escn
))
3458 FIND(".zdebug_abbrev", debug_abbv_alt_escn
)
3460 FIND(".debug_str", debug_str_alt_escn
)
3461 if (!ML_(sli_is_valid
)(debug_str_alt_escn
))
3462 FIND(".zdebug_str", debug_str_alt_escn
)
3465 } /* Find all interesting sections */
3466 } /* do we have a debug image? */
3470 /* Check some sizes */
3471 vg_assert((dynsym_escn
.szB
% sizeof(ElfXX_Sym
)) == 0);
3472 vg_assert((symtab_escn
.szB
% sizeof(ElfXX_Sym
)) == 0);
3473 # if defined(VGO_solaris)
3474 vg_assert((ldynsym_escn
.szB
% sizeof(ElfXX_Sym
)) == 0);
3480 void (*read_elf_symtab
)(struct _DebugInfo
*, const HChar
*,
3481 DiSlice
*, DiSlice
*, DiSlice
*, Bool
);
3482 Bool symtab_in_debug
;
3483 # if defined(VGP_ppc64be_linux)
3484 read_elf_symtab
= read_elf_symtab__ppc64be_linux
;
3486 read_elf_symtab
= read_elf_symtab__normal
;
3488 symtab_in_debug
= symtab_escn
.img
== dimg
;
3489 read_elf_symtab(di
, "symbol table",
3490 &symtab_escn
, &strtab_escn
, &opd_escn
,
3492 read_elf_symtab(di
, "dynamic symbol table",
3493 &dynsym_escn
, &dynstr_escn
, &opd_escn
,
3495 # if defined(VGO_solaris)
3496 read_elf_symtab(di
, "local dynamic symbol table",
3497 &ldynsym_escn
, &dynstr_escn
, &opd_escn
,
3503 /* Read .eh_frame and .debug_frame (call-frame-info) if any. Do
3504 the .eh_frame section(s) first. */
3505 vg_assert(di
->n_ehframe
>= 0 && di
->n_ehframe
<= N_EHFRAME_SECTS
);
3506 for (i
= 0; i
< di
->n_ehframe
; i
++) {
3507 /* see Comment_on_EH_FRAME_MULTIPLE_INSTANCES above for why
3508 this next assertion should hold. */
3509 vg_assert(ML_(sli_is_valid
)(ehframe_escn
[i
]));
3510 vg_assert(ehframe_escn
[i
].szB
== di
->ehframe_size
[i
]);
3511 ML_(read_callframe_info_dwarf3
)( di
,
3513 di
->ehframe_avma
[i
],
3514 True
/*is_ehframe*/ );
3516 if (ML_(sli_is_valid
)(debug_frame_escn
)) {
3517 ML_(read_callframe_info_dwarf3
)( di
,
3519 0/*assume zero avma*/,
3520 False
/*!is_ehframe*/ );
3524 /* jrs 2006-01-01: icc-8.1 has been observed to generate
3525 binaries without debug_str sections. Don't preclude
3526 debuginfo reading for that reason, but, in
3527 read_unitinfo_dwarf2, do check that debugstr is non-NULL
3529 if (ML_(sli_is_valid
)(debug_info_escn
)
3530 && ML_(sli_is_valid
)(debug_abbv_escn
)
3531 && ML_(sli_is_valid
)(debug_line_escn
)) {
3532 /* The old reader: line numbers and unwind info only */
3533 ML_(read_debuginfo_dwarf3
) ( di
,
3540 debug_line_str_escn
);
3541 /* The new reader: read the DIEs in .debug_info to acquire
3542 information on variable types and locations or inline info.
3543 But only if the tool asks for it, or the user requests it on
3544 the command line. */
3545 if (VG_(clo_read_var_info
) /* the user or tool asked for it */
3546 || VG_(clo_read_inline_info
)) {
3547 ML_(new_dwarf3_reader
)(
3548 di
, debug_info_escn
, debug_types_escn
,
3549 debug_abbv_escn
, debug_line_escn
,
3550 debug_str_escn
, debug_ranges_escn
,
3551 debug_rnglists_escn
, debug_loclists_escn
,
3552 debug_loc_escn
, debug_info_alt_escn
,
3553 debug_abbv_alt_escn
, debug_line_alt_escn
,
3554 debug_str_alt_escn
, debug_line_str_escn
,
3555 debug_addr_escn
, debug_str_offsets_escn
3561 // JRS 31 July 2014: dwarf-1 reading is currently broken and
3562 // therefore deactivated.
3563 //if (dwarf1d_img && dwarf1l_img) {
3564 // ML_(read_debuginfo_dwarf1) ( di, dwarf1d_img, dwarf1d_sz,
3565 // dwarf1l_img, dwarf1l_sz );
3568 # if defined(VGA_arm)
3570 /* ARM32 only: read .exidx/.extab if present. Note we are
3571 reading these directly out of the mapped in (running) image.
3572 Also, read these only if no CFI based unwind info was
3573 acquired for this file.
3575 An .exidx section is always required, but the .extab section
3576 can be optionally omitted, provided that .exidx does not
3577 refer to it. If the .exidx is erroneous and does refer to
3578 .extab even though .extab is missing, the range checks done
3579 by GET_EX_U32 in ExtabEntryExtract in readexidx.c should
3580 prevent any invalid memory accesses, and cause the .extab to
3581 be rejected as invalid.
3584 * check with m_aspacemgr that the entire [exidx_avma, +exidx_size)
3585 and [extab_avma, +extab_size) areas are readable, since we're
3586 reading this stuff out of the running image (not from a file/socket)
3587 and we don't want to segfault.
3588 * DebugInfo::exidx_bias and use text_bias instead.
3589 I think it's always the same.
3590 * remove DebugInfo::{extab_bias, exidx_svma, extab_svma} since
3591 they are never used.
3593 if (di
->exidx_present
3594 && di
->cfsi_used
== 0
3595 && di
->text_present
&& di
->text_size
> 0) {
3596 Addr text_last_svma
= di
->text_svma
+ di
->text_size
- 1;
3597 ML_(read_exidx
)( di
, (UChar
*)di
->exidx_avma
, di
->exidx_size
,
3598 (UChar
*)di
->extab_avma
, di
->extab_size
,
3602 # endif /* defined(VGA_arm) */
3604 } /* "Find interesting sections, read the symbol table(s), read any debug
3605 information" (a local scope) */
3610 /* If reading Dwarf3 variable type/location info, print a line
3611 showing the number of variables read for each object.
3612 (Currently disabled -- is a sanity-check mechanism for
3614 if (0 && VG_(clo_read_var_info
)) {
3617 for (j
= 0; j
< VG_(sizeXA
)(di
->varinfo
); j
++) {
3618 OSet
* /* of DiAddrRange */ scope
3619 = *(OSet
**)VG_(indexXA
)(di
->varinfo
, j
);
3621 VG_(OSetGen_ResetIter
)( scope
);
3623 DiAddrRange
* range
= VG_(OSetGen_Next
)( scope
);
3625 vg_assert(range
->vars
);
3626 Word w
= VG_(sizeXA
)(range
->vars
);
3628 if (0) VG_(printf
)("range %#lx %#lx %ld\n",
3629 range
->aMin
, range
->aMax
, w
);
3634 VG_(umsg
)("VARINFO: %7lu vars %7lu text_size %s\n",
3635 nVars
, di
->text_size
, di
->fsm
.filename
);
3641 /* Last, but not least, detach from the image(s). */
3642 if (mimg
) ML_(img_done
)(mimg
);
3643 if (dimg
) ML_(img_done
)(dimg
);
3644 if (aimg
) ML_(img_done
)(aimg
);
3646 if (svma_ranges
) VG_(deleteXA
)(svma_ranges
);
3654 Bool
ML_(check_elf_and_get_rw_loads
) ( Int fd
, const HChar
* filename
, Int
* rw_load_count
)
3658 DiImage
* mimg
= NULL
;
3659 DiOffT ehdr_mioff
= 0;
3660 DiOffT phdr_mioff
= 0;
3661 UWord phdr_mnent
= 0U;
3662 UWord phdr_ment_szB
= 0U;
3666 mimg
= ML_(img_from_fd
)(fd
, filename
);
3668 VG_(message
)(Vg_UserMsg
, "warning: connection to image %s failed\n",
3670 VG_(message
)(Vg_UserMsg
, " cannot read program headers \n" );
3674 ok
= is_elf_object_file_by_DiImage(mimg
, False
);
3681 #if defined(VGA_amd64) || defined(VGA_ppc64be) || defined(VGA_ppc64le) || defined(VGA_arm) || defined(VGA_arm64)
3687 #if defined(VGO_solaris)
3691 vg_assert(ehdr_mioff
== 0); // ensured by its initialisation
3692 ok
= ML_(img_valid
)(mimg
, ehdr_mioff
, sizeof(ehdr_m
));
3693 vg_assert(ok
); // ML_(is_elf_object_file) should ensure this
3694 ML_(img_get
)(&ehdr_m
, mimg
, ehdr_mioff
, sizeof(ehdr_m
));
3696 phdr_mioff
= ehdr_mioff
+ ehdr_m
.e_phoff
;
3697 phdr_mnent
= ehdr_m
.e_phnum
;
3698 phdr_ment_szB
= ehdr_m
.e_phentsize
;
3700 for (i
= 0U; i
< phdr_mnent
; i
++) {
3702 ML_(img_get
)(&a_phdr
, mimg
,
3703 INDEX_BIS(phdr_mioff
, i
, phdr_ment_szB
),
3706 if (a_phdr
.p_type
== PT_LOAD
) {
3707 if (a_phdr
.p_memsz
> 0) {
3708 if (((a_phdr
.p_flags
& (PF_R
| PF_W
)) == (PF_R
| PF_W
)) &&
3709 ((a_phdr
.p_flags
& flag_x
) == 0)) {
3715 * Just because The ELF file contains 2 RW PT_LOAD segments it
3716 * doesn't mean that Valgrind will also make 2 calls to
3717 * VG_(di_notify_mmap). If the stars are all aligned
3718 * (which usually means that the ELF file is the client
3719 * executable with the segment offset for the
3720 * second PT_LOAD falls exactly on 0x1000) then the NSegements
3721 * will get merged and VG_(di_notify_mmap) only gets called once. */
3722 if (*rw_load_count
== 2 &&
3723 ehdr_m
.e_type
== ET_EXEC
&&
3724 a_phdr
.p_offset
== VG_PGROUNDDN(a_phdr
.p_offset
) )
3730 } /* for (i = 0; i < phdr_Mnent; i++) ... */
3736 /* Last, but not least, detach from the image(s). */
3737 if (mimg
) ML_(img_free
)(mimg
);
3747 #endif // defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd)
3749 /*--------------------------------------------------------------------*/
3751 /*--------------------------------------------------------------------*/