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 *is_global_out
= True
;
436 # if defined(VGP_ppc64be_linux)
437 /* Allow STT_NOTYPE in the very special case where we're running on
438 ppc64be-linux and the symbol is one which the .opd-chasing hack
442 && ELFXX_ST_TYPE(sym
->st_info
) == STT_NOTYPE
446 && (*sym_avmas_out
).main
>= di
->opd_avma
447 && (*sym_avmas_out
).main
< di
->opd_avma
+ di
->opd_size
)
454 /* Ignore if nameless. */
455 if (sym_name_ioff
== DiOffT_INVALID
456 || /* VG_(strlen)(sym_name) == 0 */
457 /* equivalent but cheaper ... */
458 ML_(img_get_UChar
)(escn_strtab
->img
, sym_name_ioff
) == '\0') {
459 if (TRACE_SYMTAB_ENABLED
) {
460 HChar
* sym_name
= ML_(img_strdup
)(escn_strtab
->img
,
461 "di.gesi.1", sym_name_ioff
);
462 TRACE_SYMTAB(" ignore -- nameless: %s\n", sym_name
);
463 if (sym_name
) ML_(dinfo_free
)(sym_name
);
468 /* Ignore if zero-sized. Except on Android:
470 On Android 2.3.5, some of the symbols that Memcheck needs to
471 intercept (for noise reduction purposes) have zero size, due to
472 lack of .size directives in handwritten assembly sources. So we
473 can't reject them out of hand -- instead give them a bogusly
474 large size and let canonicaliseSymtab trim them so they don't
475 overlap any following symbols. At least the following symbols
476 are known to be affected:
478 in /system/lib/libc.so: strlen strcmp strcpy memcmp memcpy
479 in /system/bin/linker: __dl_strcmp __dl_strlen
481 if (*sym_size_out
== 0) {
482 # if defined(VGPV_arm_linux_android) \
483 || defined(VGPV_x86_linux_android) \
484 || defined(VGPV_mips32_linux_android) \
485 || defined(VGPV_arm64_linux_android)
486 *sym_size_out
= available_size
? available_size
: 2048;
488 if (TRACE_SYMTAB_ENABLED
) {
489 HChar
* sym_name
= ML_(img_strdup
)(escn_strtab
->img
,
490 "di.gesi.2", sym_name_ioff
);
491 TRACE_SYMTAB(" ignore -- size=0: %s\n", sym_name
);
492 if (sym_name
) ML_(dinfo_free
)(sym_name
);
498 /* This seems to significantly reduce the number of junk
499 symbols, and particularly reduces the number of
500 overlapping address ranges. Don't ask me why ... */
501 if ((Int
)sym
->st_value
== 0) {
502 if (TRACE_SYMTAB_ENABLED
) {
503 HChar
* sym_name
= ML_(img_strdup
)(escn_strtab
->img
,
504 "di.gesi.3", sym_name_ioff
);
505 TRACE_SYMTAB( " ignore -- valu=0: %s\n", sym_name
);
506 if (sym_name
) ML_(dinfo_free
)(sym_name
);
511 /* If it's apparently in a GOT or PLT, it's really a reference to a
512 symbol defined elsewhere, so ignore it. */
515 && (*sym_avmas_out
).main
>= di
->got_avma
516 && (*sym_avmas_out
).main
< di
->got_avma
+ di
->got_size
) {
517 if (TRACE_SYMTAB_ENABLED
) {
518 HChar
* sym_name
= ML_(img_strdup
)(escn_strtab
->img
,
519 "di.gesi.4", sym_name_ioff
);
520 TRACE_SYMTAB(" ignore -- in GOT: %s\n", sym_name
);
521 if (sym_name
) ML_(dinfo_free
)(sym_name
);
527 && (*sym_avmas_out
).main
>= di
->plt_avma
528 && (*sym_avmas_out
).main
< di
->plt_avma
+ di
->plt_size
) {
529 if (TRACE_SYMTAB_ENABLED
) {
530 HChar
* sym_name
= ML_(img_strdup
)(escn_strtab
->img
,
531 "di.gesi.5", sym_name_ioff
);
532 TRACE_SYMTAB(" ignore -- in PLT: %s\n", sym_name
);
533 if (sym_name
) ML_(dinfo_free
)(sym_name
);
538 /* ppc64be-linux nasty hack: if the symbol is in an .opd section,
539 then really what we have is the address of a function
540 descriptor. So use the first word of that as the function's
543 See thread starting at
544 http://gcc.gnu.org/ml/gcc-patches/2004-08/msg00557.html
546 # if defined(VGP_ppc64be_linux)
547 /* Host and guest may have different Endianness, used by BE only */
553 && (*sym_avmas_out
).main
>= di
->opd_avma
554 && (*sym_avmas_out
).main
< di
->opd_avma
+ di
->opd_size
) {
555 # if !defined(VGP_ppc64be_linux)
556 if (TRACE_SYMTAB_ENABLED
) {
557 HChar
* sym_name
= ML_(img_strdup
)(escn_strtab
->img
,
558 "di.gesi.6", sym_name_ioff
);
559 TRACE_SYMTAB(" ignore -- in OPD: %s\n", sym_name
);
560 if (sym_name
) ML_(dinfo_free
)(sym_name
);
565 Bool details
= 1||False
;
568 TRACE_SYMTAB("opdXXX: opd_bias %p, sym_svma_out %p\n",
569 (void*)(opd_bias
), (void*)(*sym_avmas_out
).main
);
571 if (!VG_IS_8_ALIGNED((*sym_avmas_out
).main
)) {
572 if (TRACE_SYMTAB_ENABLED
) {
573 HChar
* sym_name
= ML_(img_strdup
)(escn_strtab
->img
,
574 "di.gesi.6a", sym_name_ioff
);
575 TRACE_SYMTAB(" ignore -- not 8-aligned: %s\n", sym_name
);
576 if (sym_name
) ML_(dinfo_free
)(sym_name
);
581 /* (*sym_avmas_out).main is a avma pointing into the .opd section. We
582 know the vma of the opd section start, so we can figure out
583 how far into the opd section this is. */
585 offset_in_opd
= (Addr
)(*sym_avmas_out
).main
- (Addr
)(di
->opd_avma
);
586 if (offset_in_opd
< 0 || offset_in_opd
>= di
->opd_size
) {
587 if (TRACE_SYMTAB_ENABLED
) {
588 HChar
* sym_name
= ML_(img_strdup
)(escn_strtab
->img
,
589 "di.gesi.6a", sym_name_ioff
);
590 TRACE_SYMTAB(" ignore -- invalid OPD offset: %s\n", sym_name
);
591 if (sym_name
) ML_(dinfo_free
)(sym_name
);
596 /* Now we want to know what's at that offset in the .opd
597 section. We can't look in the running image since it won't
598 necessarily have been mapped. But we can consult the oimage.
599 opd_img is the start address of the .opd in the oimage.
602 ULong fn_descr
[2]; /* is actually 3 words, but we need only 2 */
603 if (!ML_(img_valid
)(escn_opd
->img
, escn_opd
->ioff
+ offset_in_opd
,
605 if (TRACE_SYMTAB_ENABLED
) {
606 HChar
* sym_name
= ML_(img_strdup
)(escn_strtab
->img
,
607 "di.gesi.6b", sym_name_ioff
);
608 TRACE_SYMTAB(" ignore -- invalid OPD fn_descr offset: %s\n",
610 if (sym_name
) ML_(dinfo_free
)(sym_name
);
616 /* This can't fail now, because we just checked the offset
618 ML_(img_get
)(&fn_descr
[0], escn_opd
->img
,
619 escn_opd
->ioff
+ offset_in_opd
, sizeof(fn_descr
));
622 TRACE_SYMTAB("opdXXY: offset %d, fn_descr %p\n",
623 offset_in_opd
, fn_descr
);
625 TRACE_SYMTAB("opdXXZ: *fn_descr %p\n", (void*)(fn_descr
[0]));
627 /* opd_bias is the what we have to add to SVMAs found in .opd to
628 get plausible .text AVMAs for the entry point, and .data
629 AVMAs (presumably) for the TOC locations. We use the caller
630 supplied value (which is di->text_bias) for both of these.
631 Not sure why that is correct - it seems to work, and sounds
632 OK for fn_descr[0], but surely we need to use the data bias
633 and not the text bias for fn_descr[1] ? Oh Well.
635 (*sym_avmas_out
).main
= fn_descr
[0] + opd_bias
;
636 SET_TOCPTR_AVMA(*sym_avmas_out
, fn_descr
[1] + opd_bias
);
637 *from_opd_out
= True
;
640 /* Do a final sanity check: if the symbol falls outside the
641 DebugInfo's mapped range, ignore it. Since (*sym_avmas_out).main has
642 been updated, that can be achieved simply by falling through
643 to the test below. */
645 # endif /* ppc64-linux nasty hack */
648 /* Here's yet another ppc64-linux hack. Get rid of leading dot if
649 the symbol is outside .opd. */
650 # if defined(VGP_ppc64be_linux)
653 && *sym_name_out_ioff
!= DiOffT_INVALID
654 && ML_(img_get_UChar
)(escn_strtab
->img
, *sym_name_out_ioff
) == '.') {
655 vg_assert(!(*from_opd_out
));
656 (*sym_name_out_ioff
)++;
660 /* If no part of the symbol falls within the mapped range,
666 && !((*sym_avmas_out
).main
+ *sym_size_out
<= di
->text_avma
667 || (*sym_avmas_out
).main
>= di
->text_avma
+ di
->text_size
);
672 && !((*sym_avmas_out
).main
+ *sym_size_out
<= di
->data_avma
673 || (*sym_avmas_out
).main
>= di
->data_avma
+ di
->data_size
);
677 && di
->sdata_size
> 0
678 && !((*sym_avmas_out
).main
+ *sym_size_out
<= di
->sdata_avma
679 || (*sym_avmas_out
).main
>= di
->sdata_avma
+ di
->sdata_size
);
683 && di
->rodata_size
> 0
684 && !((*sym_avmas_out
).main
+ *sym_size_out
<= di
->rodata_avma
685 || (*sym_avmas_out
).main
>= di
->rodata_avma
+ di
->rodata_size
);
690 && !((*sym_avmas_out
).main
+ *sym_size_out
<= di
->bss_avma
691 || (*sym_avmas_out
).main
>= di
->bss_avma
+ di
->bss_size
);
696 && !((*sym_avmas_out
).main
+ *sym_size_out
<= di
->sbss_avma
697 || (*sym_avmas_out
).main
>= di
->sbss_avma
+ di
->sbss_size
);
701 /* This used to reject any symbol falling outside the text
702 segment ("if (!in_text) ..."). Now it is relaxed slightly,
703 to reject only symbols which fall outside the area mapped
704 r-x. This is in accordance with r7427. See
705 "Comment_Regarding_Text_Range_Checks" in storage.c for
708 vg_assert(di
->fsm
.have_rx_map
);
709 /* This could actually wrap around and cause
710 ML_(find_rx_mapping) to assert. But that seems so unlikely,
711 let's wait for it to happen before fixing it. */
712 in_rx
= (ML_(find_rx_mapping
)(
714 (*sym_avmas_out
).main
,
715 (*sym_avmas_out
).main
+ *sym_size_out
- 1) != NULL
);
720 "ignore -- %#lx .. %#lx outside .text svma range %#lx .. %#lx\n",
721 (*sym_avmas_out
).main
, (*sym_avmas_out
).main
+ *sym_size_out
- 1,
723 di
->text_avma
+ di
->text_size
- 1);
727 if (!(in_data
|| in_sdata
|| in_rodata
|| in_bss
|| in_sbss
)) {
729 "ignore -- %#lx .. %#lx outside .data / .sdata / .rodata "
730 "/ .bss / .sbss svma ranges\n",
731 (*sym_avmas_out
).main
, (*sym_avmas_out
).main
+ *sym_size_out
- 1);
736 # if defined(VGP_ppc64be_linux)
737 if (di
->opd_present
&& di
->opd_size
> 0) {
738 vg_assert((*sym_avmas_out
).main
+ *sym_size_out
<= di
->opd_avma
739 || (*sym_avmas_out
).main
>= di
->opd_avma
+ di
->opd_size
);
743 # if defined(VGP_ppc64le_linux)
744 /* PPC64 LE ABI uses three bits in the st_other field to indicate the number
745 * of instructions between the function's global and local entry points. An
746 * offset of 0 indicates that there is one entry point. The value must be:
748 * 0 - one entry point, local and global are the same
750 * 2 - local entry point is one instruction after the global entry point
751 * 3 - local entry point is two instructions after the global entry point
752 * 4 - local entry point is four instructions after the global entry point
753 * 5 - local entry point is eight instructions after the global entry point
754 * 6 - local entry point is sixteen instructions after the global entry point
757 * Extract the three bit field from the other field is done by:
758 * (other_field & STO_PPC64_LOCAL_MASK) >> STO_PPC_LOCAL_BIT
760 * where the #define values are given in include/elf/powerpc.h file for
763 * conversion of the three bit field to bytes is given by
765 * ((1 << bit_field) >> 2) << 2
768 #define STO_PPC64_LOCAL_BIT 5
769 #define STO_PPC64_LOCAL_MASK (7 << STO_PPC64_LOCAL_BIT)
771 unsigned int bit_field
, dist_to_local_entry
;
772 /* extract the other filed */
773 bit_field
= (sym
->st_other
& STO_PPC64_LOCAL_MASK
) >> STO_PPC64_LOCAL_BIT
;
775 if ((bit_field
> 0) && (bit_field
< 7)) {
776 /* store the local entry point address */
777 dist_to_local_entry
= ((1 << bit_field
) >> 2) << 2;
778 SET_LOCAL_EP_AVMA(*sym_avmas_out
,
779 (*sym_avmas_out
).main
+ dist_to_local_entry
);
781 if (TRACE_SYMTAB_ENABLED
) {
782 HChar
* sym_name
= ML_(img_strdup
)(escn_strtab
->img
,
783 "di.gesi.5", sym_name_ioff
);
784 VG_(printf
)("Local entry point: %s at %#010x\n",
786 (unsigned int)GET_LOCAL_EP_AVMA(*sym_avmas_out
));
797 /* Read an ELF symbol table (normal or dynamic). This one is for the
798 "normal" case ({x86,amd64,ppc32,arm,mips32,mips64, ppc64le}-linux). */
800 __attribute__((unused
)) /* not referred to on all targets */
801 void read_elf_symtab__normal(
802 struct _DebugInfo
* di
, const HChar
* tab_name
,
803 DiSlice
* escn_symtab
,
804 DiSlice
* escn_strtab
,
805 DiSlice
* escn_opd
, /* ppc64be-linux only */
809 if (escn_strtab
->img
== NULL
|| escn_symtab
->img
== NULL
) {
810 HChar buf
[VG_(strlen
)(tab_name
) + 40];
811 VG_(sprintf
)(buf
, " object doesn't have a %s", tab_name
);
812 ML_(symerr
)(di
, False
, buf
);
816 TRACE_SYMTAB("\n--- Reading (ELF, standard) %s (%llu entries) ---\n",
817 tab_name
, escn_symtab
->szB
/sizeof(ElfXX_Sym
) );
819 /* Perhaps should start at i = 1; ELF docs suggest that entry
820 0 always denotes 'unknown symbol'. */
822 for (i
= 1; i
< (Word
)(escn_symtab
->szB
/sizeof(ElfXX_Sym
)); i
++) {
824 ML_(img_get
)(&sym
, escn_symtab
->img
,
825 escn_symtab
->ioff
+ i
* sizeof(ElfXX_Sym
), sizeof(sym
));
826 DiOffT sym_name
= escn_strtab
->ioff
+ sym
.st_name
;
827 Addr sym_svma
= sym
.st_value
;
829 if (di
->trace_symtab
)
830 show_raw_elf_symbol(escn_strtab
->img
, i
,
831 &sym
, sym_name
, sym_svma
, False
);
833 SymAVMAs sym_avmas_really
;
835 Bool from_opd
= False
, is_text
= False
, is_ifunc
= False
;
836 Bool is_global
= False
;
837 DiOffT sym_name_really
= DiOffT_INVALID
;
838 sym_avmas_really
.main
= 0;
839 SET_TOCPTR_AVMA(sym_avmas_really
, 0);
840 SET_LOCAL_EP_AVMA(sym_avmas_really
, 0);
841 if (get_elf_symbol_info(di
, &sym
, sym_name
, escn_strtab
,
842 sym_svma
, symtab_in_debug
,
843 escn_opd
, di
->text_bias
,
847 &from_opd
, &is_text
, &is_ifunc
, &is_global
)) {
850 VG_(memset
)(&disym
, 0, sizeof(disym
));
851 HChar
* cstr
= ML_(img_strdup
)(escn_strtab
->img
,
852 "di.res__n.1", sym_name_really
);
853 disym
.avmas
= sym_avmas_really
;
854 disym
.pri_name
= ML_(addStr
) ( di
, cstr
, -1 );
855 disym
.sec_names
= NULL
;
856 disym
.size
= sym_size
;
857 disym
.isText
= is_text
;
858 disym
.isIFunc
= is_ifunc
;
859 disym
.isGlobal
= is_global
;
860 if (cstr
) { ML_(dinfo_free
)(cstr
); cstr
= NULL
; }
861 vg_assert(disym
.pri_name
);
862 vg_assert(GET_TOCPTR_AVMA(disym
.avmas
) == 0);
863 /* has no role except on ppc64be-linux */
864 ML_(addSym
) ( di
, &disym
);
866 if (TRACE_SYMTAB_ENABLED
) {
867 TRACE_SYMTAB(" rec(%c) [%4ld]: "
868 " val %#010lx, sz %4d %s\n",
875 if (GET_LOCAL_EP_AVMA(disym
.avmas
) != 0) {
876 TRACE_SYMTAB(" local entry point %#010lx\n",
877 GET_LOCAL_EP_AVMA(disym
.avmas
));
886 /* Read an ELF symbol table (normal or dynamic). This one is for
887 ppc64be-linux, which requires special treatment. */
893 /* We have to store also the DiImage* so as to give context for
894 |name|. This is not part of the key (in terms of lookup) but
895 there's no easy other way to do this. Ugly. */
912 static Word
cmp_TempSymKey ( const TempSymKey
* key1
, const TempSym
* elem2
)
915 vg_assert(key1
->img
== elem2
->key
.img
);
916 vg_assert(key1
->img
!= NULL
);
917 if (key1
->addr
< elem2
->key
.addr
) return -1;
918 if (key1
->addr
> elem2
->key
.addr
) return 1;
919 vg_assert(key1
->name
!= DiOffT_INVALID
);
920 vg_assert(elem2
->key
.name
!= DiOffT_INVALID
);
921 return (Word
)ML_(img_strcmp
)(key1
->img
, key1
->name
, elem2
->key
.name
);
925 __attribute__((unused
)) /* not referred to on all targets */
926 void read_elf_symtab__ppc64be_linux(
927 struct _DebugInfo
* di
, const HChar
* tab_name
,
928 DiSlice
* escn_symtab
,
929 DiSlice
* escn_strtab
,
930 DiSlice
* escn_opd
, /* ppc64be-linux only */
936 Bool modify_size
, modify_tocptr
;
942 if (escn_strtab
->img
== NULL
|| escn_symtab
->img
== NULL
) {
943 HChar buf
[VG_(strlen
)(tab_name
) + 40];
944 VG_(sprintf
)(buf
, " object doesn't have a %s", tab_name
);
945 ML_(symerr
)(di
, False
, buf
);
949 TRACE_SYMTAB("\n--- Reading (ELF, ppc64be-linux) %s (%llu entries) ---\n",
950 tab_name
, escn_symtab
->szB
/sizeof(ElfXX_Sym
) );
952 oset
= VG_(OSetGen_Create
)( offsetof(TempSym
,key
),
953 (OSetCmp_t
)cmp_TempSymKey
,
954 ML_(dinfo_zalloc
), "di.respl.1",
957 /* Perhaps should start at i = 1; ELF docs suggest that entry
958 0 always denotes 'unknown symbol'. */
959 for (i
= 1; i
< (Word
)(escn_symtab
->szB
/sizeof(ElfXX_Sym
)); i
++) {
961 ML_(img_get
)(&sym
, escn_symtab
->img
,
962 escn_symtab
->ioff
+ i
* sizeof(ElfXX_Sym
), sizeof(sym
));
963 DiOffT sym_name
= escn_strtab
->ioff
+ sym
.st_name
;
964 Addr sym_svma
= sym
.st_value
;
966 if (di
->trace_symtab
)
967 show_raw_elf_symbol(escn_strtab
->img
, i
,
968 &sym
, sym_name
, sym_svma
, True
);
970 SymAVMAs sym_avmas_really
;
972 Bool from_opd
= False
, is_text
= False
, is_ifunc
= False
;
973 Bool is_global
= False
;
974 DiOffT sym_name_really
= DiOffT_INVALID
;
976 VG_(memset
)(&disym
, 0, sizeof(disym
));
977 sym_avmas_really
.main
= 0;
978 SET_TOCPTR_AVMA(sym_avmas_really
, 0);
979 SET_LOCAL_EP_AVMA(sym_avmas_really
, 0);
980 if (get_elf_symbol_info(di
, &sym
, sym_name
, escn_strtab
,
981 sym_svma
, symtab_in_debug
,
982 escn_opd
, di
->text_bias
,
986 &from_opd
, &is_text
, &is_ifunc
, &is_global
)) {
988 /* Check if we've seen this (name,addr) key before. */
989 key
.addr
= sym_avmas_really
.main
;
990 key
.name
= sym_name_really
;
991 key
.img
= escn_strtab
->img
;
992 prev
= VG_(OSetGen_Lookup
)( oset
, &key
);
996 /* Seen it before. Fold in whatever new info we can. */
998 modify_tocptr
= False
;
1001 if (prev
->from_opd
&& !from_opd
1002 && (prev
->size
== 24 || prev
->size
== 16)
1003 && sym_size
!= prev
->size
) {
1004 /* Existing one is an opd-redirect, with a bogus size,
1005 so the only useful new fact we have is the real size
1008 old_size
= prev
->size
;
1009 prev
->size
= sym_size
;
1012 if (!prev
->from_opd
&& from_opd
1013 && (sym_size
== 24 || sym_size
== 16)) {
1014 /* Existing one is non-opd, new one is opd. What we
1015 can acquire from the new one is the TOC ptr to be
1016 used. Since the existing sym is non-toc, it
1017 shouldn't currently have an known TOC ptr. */
1018 vg_assert(prev
->tocptr
== 0);
1019 modify_tocptr
= True
;
1020 prev
->tocptr
= GET_TOCPTR_AVMA(sym_avmas_really
);
1023 /* ignore. can we do better here? */
1026 /* Only one or the other is possible (I think) */
1027 vg_assert(!(modify_size
&& modify_tocptr
));
1029 if (modify_size
&& di
->trace_symtab
) {
1030 VG_(printf
)(" modify (old sz %4d) "
1031 " val %#010lx, toc %#010lx, sz %4d %llu\n",
1039 if (modify_tocptr
&& di
->trace_symtab
) {
1040 VG_(printf
)(" modify (upd tocptr) "
1041 " val %#010lx, toc %#010lx, sz %4d %llu\n",
1051 /* A new (name,addr) key. Add and continue. */
1052 elem
= VG_(OSetGen_AllocNode
)(oset
, sizeof(TempSym
));
1054 elem
->tocptr
= GET_TOCPTR_AVMA(sym_avmas_really
);
1055 elem
->size
= sym_size
;
1056 elem
->from_opd
= from_opd
;
1057 elem
->is_text
= is_text
;
1058 elem
->is_ifunc
= is_ifunc
;
1059 elem
->is_global
= is_global
;
1060 VG_(OSetGen_Insert
)(oset
, elem
);
1061 if (di
->trace_symtab
) {
1062 HChar
* str
= ML_(img_strdup
)(escn_strtab
->img
, "di.respl.2",
1064 VG_(printf
)(" to-oset [%4ld]: "
1065 " val %#010lx, toc %#010lx, sz %4d %s\n",
1072 if (str
) ML_(dinfo_free
)(str
);
1079 /* All the syms that matter are in the oset. Now pull them out,
1080 build a "standard" symbol table, and nuke the oset. */
1083 VG_(OSetGen_ResetIter
)( oset
);
1085 while ( (elem
= VG_(OSetGen_Next
)(oset
)) ) {
1087 VG_(memset
)(&disym
, 0, sizeof(disym
));
1088 HChar
* cstr
= ML_(img_strdup
)(escn_strtab
->img
,
1089 "di.res__ppc64.1", elem
->key
.name
);
1090 disym
.avmas
.main
= elem
->key
.addr
;
1091 SET_TOCPTR_AVMA(disym
.avmas
, elem
->tocptr
);
1092 SET_LOCAL_EP_AVMA(disym
.avmas
, 0); // ppc64be does not use local_ep.
1093 disym
.pri_name
= ML_(addStr
) ( di
, cstr
, -1 );
1094 disym
.sec_names
= NULL
;
1095 disym
.size
= elem
->size
;
1096 disym
.isText
= elem
->is_text
;
1097 disym
.isIFunc
= elem
->is_ifunc
;
1098 disym
.isGlobal
= elem
->is_global
;
1099 if (cstr
) { ML_(dinfo_free
)(cstr
); cstr
= NULL
; }
1100 vg_assert(disym
.pri_name
!= NULL
);
1102 ML_(addSym
) ( di
, &disym
);
1103 if (di
->trace_symtab
) {
1104 VG_(printf
)(" rec(%c%c%c) [%4ld]: "
1105 " val %#010lx, toc %#010lx, sz %4d %s\n",
1106 disym
.isText
? 't' : 'd',
1107 disym
.isIFunc
? 'i' : '-',
1108 disym
.isGlobal
? 'g' : 'l',
1111 GET_TOCPTR_AVMA(disym
.avmas
),
1119 VG_(OSetGen_Destroy
)( oset
);
1122 #if defined(VGO_freebsd)
1125 * read_and_set_osrel
1127 * "osrel" is in an Elf note. It has values such as 1201000 for FreeBSD 12.1
1128 * Some of the behaviour related to SIGSEGV and SIGBUS signals depends on the
1129 * kernel reading this value.
1131 * However in the case of Valgrind, the host is strictly statically linked and
1132 * does not contain the NT_FREEBSD_ABI_TAG note. And even if it did, we want to
1133 * override the value with that of the guest.
1135 * At some later date we might want to look at the value of "fctl0" (note with the
1136 * NT_FREEBSD_FEATURE_CTL type). This seems to be related to Address Space Layout
1137 * Randomization. No hurry at the moment.
1139 * See /usr/src/sys/kern/imgact_elf.c for details on how the kernel reads these
1143 void read_and_set_osrel(DiImage
* img
)
1145 if (is_elf_object_file_by_DiImage(img
, False
)) {
1149 ML_(img_get
)(&ehdr
, img
, 0, sizeof(ehdr
));
1151 /* only set osrel for executable files, not for subsequent shared libraries */
1152 if (ehdr
.e_type
!= ET_EXEC
) {
1156 /* Skip the phdrs when we have to search the shdrs. In separate
1157 .debug files the phdrs might not be valid (they are a copy of
1158 the main ELF file) and might trigger assertions when getting
1159 image notes based on them. */
1160 for (i
= 0; i
< ehdr
.e_phnum
; i
++) {
1162 ML_(img_get
)(&phdr
, img
,
1163 ehdr
.e_phoff
+ i
* ehdr
.e_phentsize
, sizeof(phdr
));
1165 if (phdr
.p_type
== PT_NOTE
) {
1166 ElfXX_Off note_ioff
= phdr
.p_offset
;
1168 while (note_ioff
< phdr
.p_offset
+ phdr
.p_filesz
) {
1170 ML_(img_get
)(note
, img
, (DiOffT
)note_ioff
, sizeof(note
));
1171 DiOffT name_ioff
= note_ioff
+ sizeof(ElfXX_Nhdr
);
1172 //DiOffT desc_ioff = name_ioff + ((note[0].n_namesz + 3) & ~3);
1173 if (ML_(img_strcmp_c
)(img
, name_ioff
, "FreeBSD") == 0
1174 && note
[0].n_type
== VKI_NT_FREEBSD_ABI_TAG
) {
1176 u_int32_t osrel
= note
[1].n_type
;
1179 name
[1] = KERN_PROC
;
1180 name
[2] = KERN_PROC_OSREL
;
1181 name
[3] = VG_(getpid
)();
1182 SizeT newlen
= sizeof(osrel
);
1183 Int error
= VG_(sysctl
)(name
, 4, NULL
, NULL
, &osrel
, newlen
);
1185 VG_(message
)(Vg_DebugMsg
, "Warning: failed to set osrel for current process with value %u\n", osrel
);
1187 if (VG_(clo_verbosity
) > 1) {
1188 VG_(message
)(Vg_DebugMsg
, "Set osrel for current process with value %u\n", osrel
);
1192 note_ioff
= note_ioff
+ sizeof(ElfXX_Nhdr
)
1193 + ((note
[0].n_namesz
+ 3) & ~3)
1194 + ((note
[0].n_descsz
+ 3) & ~3);
1204 * Look for a build-id in an ELF image. The build-id specification
1205 * can be found here:
1207 * http://fedoraproject.org/wiki/RolandMcGrath/BuildID
1209 * Returned string must be freed by the caller.
1212 HChar
* find_buildid(DiImage
* img
, Bool rel_ok
, Bool search_shdrs
)
1214 HChar
* buildid
= NULL
;
1216 # ifdef NT_GNU_BUILD_ID
1217 if (is_elf_object_file_by_DiImage(img
, rel_ok
)) {
1221 ML_(img_get
)(&ehdr
, img
, 0, sizeof(ehdr
));
1222 /* Skip the phdrs when we have to search the shdrs. In separate
1223 .debug files the phdrs might not be valid (they are a copy of
1224 the main ELF file) and might trigger assertions when getting
1225 image notes based on them. */
1226 for (i
= 0; !search_shdrs
&& i
< ehdr
.e_phnum
; i
++) {
1228 ML_(img_get
)(&phdr
, img
,
1229 ehdr
.e_phoff
+ i
* ehdr
.e_phentsize
, sizeof(phdr
));
1231 if (phdr
.p_type
== PT_NOTE
) {
1232 ElfXX_Off note_ioff
= phdr
.p_offset
;
1234 while (note_ioff
< phdr
.p_offset
+ phdr
.p_filesz
) {
1236 ML_(img_get
)(¬e
, img
, (DiOffT
)note_ioff
, sizeof(note
));
1237 DiOffT name_ioff
= note_ioff
+ sizeof(ElfXX_Nhdr
);
1238 DiOffT desc_ioff
= name_ioff
+ ((note
.n_namesz
+ 3) & ~3);
1239 if (ML_(img_strcmp_c
)(img
, name_ioff
, ELF_NOTE_GNU
) == 0
1240 && note
.n_type
== NT_GNU_BUILD_ID
) {
1241 buildid
= ML_(dinfo_zalloc
)("di.fbi.1",
1242 note
.n_descsz
* 2 + 1);
1244 for (j
= 0; j
< note
.n_descsz
; j
++) {
1245 UChar desc_j
= ML_(img_get_UChar
)(img
, desc_ioff
+ j
);
1246 VG_(sprintf
)(buildid
+ VG_(strlen
)(buildid
),
1247 "%02x", (UInt
)desc_j
);
1251 note_ioff
= note_ioff
+ sizeof(ElfXX_Nhdr
)
1252 + ((note
.n_namesz
+ 3) & ~3)
1253 + ((note
.n_descsz
+ 3) & ~3);
1258 /* Normally we would only search shdrs for ET_REL files, but when
1259 we search for a separate .debug file phdrs might not be there
1260 (they are never loaded) or have been corrupted, so try again
1262 if (buildid
|| (!rel_ok
&& !search_shdrs
))
1265 for (i
= 0; i
< ehdr
.e_shnum
; i
++) {
1267 ML_(img_get
)(&shdr
, img
,
1268 ehdr
.e_shoff
+ i
* ehdr
.e_shentsize
, sizeof(shdr
));
1270 if (shdr
.sh_type
== SHT_NOTE
) {
1271 ElfXX_Off note_ioff
= shdr
.sh_offset
;
1273 while (note_ioff
< shdr
.sh_offset
+ shdr
.sh_size
) {
1275 ML_(img_get
)(¬e
, img
, (DiOffT
)note_ioff
, sizeof(note
));
1276 DiOffT name_ioff
= note_ioff
+ sizeof(ElfXX_Nhdr
);
1277 DiOffT desc_ioff
= name_ioff
+ ((note
.n_namesz
+ 3) & ~3);
1279 if (ML_(img_strcmp_c
)(img
, name_ioff
, ELF_NOTE_GNU
) == 0
1280 && note
.n_type
== NT_GNU_BUILD_ID
) {
1281 buildid
= ML_(dinfo_zalloc
)("di.fbi.2",
1282 note
.n_descsz
* 2 + 1);
1284 for (j
= 0; j
< note
.n_descsz
; j
++) {
1285 UChar desc_j
= ML_(img_get_UChar
)(img
, desc_ioff
+ j
);
1286 VG_(sprintf
)(buildid
+ VG_(strlen
)(buildid
),
1287 "%02x", (UInt
)desc_j
);
1291 note_ioff
= note_ioff
+ sizeof(ElfXX_Nhdr
)
1292 + ((note
.n_namesz
+ 3) & ~3)
1293 + ((note
.n_descsz
+ 3) & ~3);
1298 # endif /* def NT_GNU_BUILD_ID */
1304 /* Try and open a separate debug file, ignoring any where the CRC does
1305 not match the value from the main object file. Returned DiImage
1306 must be discarded by the caller.
1308 If |serverAddr| is NULL, |name| is expected to be a fully qualified
1309 (absolute) path to the file in the local filesystem. If
1310 |serverAddr| is non-NULL, it is expected to be an IPv4 and port
1311 spec of the form "d.d.d.d:d" or "d.d.d.d", and |name| is expected
1312 to be a plain filename (no path components at all).
1315 DiImage
* open_debug_file( const HChar
* name
, const HChar
* buildid
, UInt crc
,
1316 Bool rel_ok
, const HChar
* serverAddr
)
1319 = serverAddr
? ML_(img_from_di_server
)(name
, serverAddr
)
1320 : ML_(img_from_local_file
)(name
);
1324 if (VG_(clo_verbosity
) > 1) {
1326 VG_(message
)(Vg_DebugMsg
, " Considering %s on server %s ..\n",
1329 VG_(message
)(Vg_DebugMsg
, " Considering %s ..\n", name
);
1332 /* We will always check the crc if we have one (altfiles don't have one)
1333 for now because we might be opening the main file again by any other
1334 name, and that obviously also has the same buildid. More efficient
1335 would be an fstat bases check or a check that the file actually
1336 contains .debug* sections. */
1337 if (buildid
&& crc
== 0) {
1338 HChar
* debug_buildid
= find_buildid(dimg
, rel_ok
, True
);
1339 if (debug_buildid
== NULL
|| VG_(strcmp
)(buildid
, debug_buildid
) != 0) {
1340 ML_(img_done
)(dimg
);
1341 if (VG_(clo_verbosity
) > 1)
1342 VG_(message
)(Vg_DebugMsg
,
1343 " .. build-id mismatch (found %s wanted %s)\n",
1344 debug_buildid
, buildid
);
1345 ML_(dinfo_free
)(debug_buildid
);
1348 ML_(dinfo_free
)(debug_buildid
);
1349 if (VG_(clo_verbosity
) > 1)
1350 VG_(message
)(Vg_DebugMsg
, " .. build-id is valid\n");
1352 UInt calccrc
= ML_(img_calc_gnu_debuglink_crc32
)(dimg
);
1353 if (calccrc
!= crc
) {
1354 ML_(img_done
)(dimg
);
1355 if (VG_(clo_verbosity
) > 1)
1356 VG_(message
)(Vg_DebugMsg
,
1357 " .. CRC mismatch (computed %08x wanted %08x)\n", calccrc
, crc
);
1361 if (VG_(clo_verbosity
) > 1)
1362 VG_(message
)(Vg_DebugMsg
, " .. CRC is valid\n");
1368 #if defined(VGO_linux)
1369 /* Return the path of the debuginfod-find executable. */
1371 const HChar
* debuginfod_find_path( void )
1373 static const HChar
* path
= (const HChar
*) -1;
1375 if (path
== (const HChar
*) -1) {
1376 if (VG_(getenv
)("DEBUGINFOD_URLS") == NULL
1377 || VG_(strcmp
)("", VG_(getenv("DEBUGINFOD_URLS"))) == 0)
1380 path
= VG_(find_executable
)("debuginfod-find");
1386 /* Try to find a separate debug file with |buildid| via debuginfod. If found,
1387 return its DiImage. Searches for a local debuginfod-find executable and
1388 runs it in a child process in order to download the debug file. */
1390 DiImage
* find_debug_file_debuginfod( const HChar
* objpath
,
1392 const HChar
* buildid
,
1393 const UInt crc
, Bool rel_ok
)
1395 # define BUF_SIZE 4096
1396 Int out_fds
[2], err_fds
[2]; /* pipe fds */
1397 DiImage
* dimg
= NULL
; /* the img we found */
1398 HChar buf
[BUF_SIZE
]; /* executable output buffer */
1399 const HChar
* path
; /* executable path */
1400 SizeT len
; /* number of bytes read int buf */
1401 Int ret
; /* result of read call */
1403 if (buildid
== NULL
)
1406 if ((path
= debuginfod_find_path()) == NULL
)
1409 if (VG_(pipe
)(out_fds
) != 0
1410 || VG_(pipe
)(err_fds
) != 0)
1413 if (VG_(clo_verbosity
) > 1)
1414 VG_(umsg
)("Downloading debug info for %s...\n", objpath
);
1416 /* Run debuginfod-find to query servers for the debuginfo. */
1417 Int pid
= VG_(fork
)();
1419 const HChar
*argv
[4] = { path
, "debuginfo", buildid
, (HChar
*)0 };
1421 /* Redirect stdout and stderr */
1422 SysRes res
= VG_(dup2
)(out_fds
[1], 1);
1423 if (sr_Res(res
) < 0)
1426 res
= VG_(dup2
)(err_fds
[1], 2);
1427 if (sr_Res(res
) < 0)
1430 /* Disable extra stderr output since it does not play well with umesg */
1431 VG_(env_unsetenv
)(VG_(client_envp
), "DEBUGINFOD_VERBOSE", NULL
);
1432 VG_(env_unsetenv
)(VG_(client_envp
), "DEBUGINFOD_PROGRESS", NULL
);
1434 VG_(close
)(out_fds
[0]);
1435 VG_(close
)(err_fds
[0]);
1436 VG_(execv
)(argv
[0], argv
);
1438 /* If we are still alive here, execv failed. */
1442 VG_(close
)(out_fds
[1]);
1443 VG_(close
)(err_fds
[1]);
1446 if (VG_(clo_verbosity
) > 1)
1447 VG_(umsg
)("Server Error\n");
1450 VG_(waitpid
)(pid
, NULL
, 0);
1452 /* Set dimg if download was successful. */
1455 while (len
>= 0 && len
< BUF_SIZE
) {
1456 ret
= VG_(read
)(out_fds
[0], buf
+ len
, BUF_SIZE
- len
);
1461 if (ret
>= 0 && len
> 0
1462 && buf
[0] == '/' && buf
[len
-1] == '\n') {
1464 /* Remove newline from filename before trying to open debug file */
1466 dimg
= open_debug_file(buf
, buildid
, crc
, rel_ok
, NULL
);
1470 ML_(dinfo_free
)(*debugpath
);
1472 *debugpath
= ML_(dinfo_strdup
)("di.fdfd.1", buf
);
1473 if (VG_(clo_verbosity
) > 1)
1474 VG_(umsg
)("Successfully downloaded debug file for %s\n",
1480 /* Download failed so try to print error message. */
1482 if (VG_(read
)(err_fds
[0], buf
, BUF_SIZE
) > 0
1483 && (nl
= VG_(strchr
)(buf
, '\n'))) {
1485 if (VG_(clo_verbosity
) > 1)
1486 VG_(umsg
)("%s\n", buf
);
1488 if (VG_(clo_verbosity
) > 1)
1489 VG_(umsg
)("Server Error\n");
1492 VG_(close
)(out_fds
[0]);
1493 VG_(close
)(err_fds
[0]);
1498 /* Try to find a separate debug file for a given object file. If
1499 found, return its DiImage, which should be freed by the caller. If
1500 |buildid| is non-NULL, then a debug object matching it is
1501 acceptable. If |buildid| is NULL or doesn't specify a findable
1502 debug object, then we look in various places to find a file with
1503 the specified CRC. And if that doesn't work out then we give
1506 DiImage
* find_debug_file( struct _DebugInfo
* di
,
1507 const HChar
* objpath
, const HChar
* buildid
,
1508 const HChar
* debugname
, UInt crc
, Bool rel_ok
)
1510 const HChar
* extrapath
= VG_(clo_extra_debuginfo_path
);
1511 const HChar
* serverpath
= VG_(clo_debuginfo_server
);
1513 DiImage
* dimg
= NULL
; /* the img that we found */
1514 HChar
* debugpath
= NULL
; /* where we found it */
1516 if (buildid
!= NULL
) {
1517 debugpath
= ML_(dinfo_zalloc
)("di.fdf.1",
1518 VG_(strlen
)(buildid
) + 33);
1520 VG_(sprintf
)(debugpath
, "/usr/lib/debug/.build-id/%c%c/%s.debug",
1521 buildid
[0], buildid
[1], buildid
+ 2);
1523 dimg
= open_debug_file(debugpath
, buildid
, 0, rel_ok
, NULL
);
1525 ML_(dinfo_free
)(debugpath
);
1530 if (dimg
== NULL
&& debugname
!= NULL
) {
1531 HChar
*objdir
= ML_(dinfo_strdup
)("di.fdf.2", objpath
);
1532 HChar
*usrmerge_objdir
;
1535 if ((objdirptr
= VG_(strrchr
)(objdir
, '/')) != NULL
)
1538 if ((objdirptr
= VG_(strstr
)(objdir
, "usr")) != NULL
)
1539 usrmerge_objdir
= objdirptr
+ VG_(strlen
)("usr");
1541 usrmerge_objdir
= NULL
;
1543 debugpath
= ML_(dinfo_zalloc
)(
1545 VG_(strlen
)(objdir
) + VG_(strlen
)(debugname
) + 64
1546 + (extrapath
? VG_(strlen
)(extrapath
) : 0)
1547 + (serverpath
? VG_(strlen
)(serverpath
) : 0));
1549 # define TRY_OBJDIR(format, ...) \
1551 VG_(sprintf)(debugpath, format, __VA_ARGS__); \
1552 dimg = open_debug_file(debugpath, buildid, crc, rel_ok, NULL); \
1553 if (dimg != NULL) goto dimg_ok; \
1556 # define TRY_OBJDIR_USRMERGE_OBJDIR(format) \
1558 TRY_OBJDIR(format, objdir, debugname); \
1559 if (usrmerge_objdir != NULL) { \
1560 TRY_OBJDIR(format, usrmerge_objdir, debugname); \
1564 if (debugname
[0] == '/') {
1565 TRY_OBJDIR("%s", debugname
);
1568 TRY_OBJDIR_USRMERGE_OBJDIR("%s/%s");
1569 TRY_OBJDIR_USRMERGE_OBJDIR("%s/.debug/%s");
1570 TRY_OBJDIR_USRMERGE_OBJDIR("/usr/lib/debug%s/%s");
1573 TRY_OBJDIR("%s%s/%s", extrapath
, objdir
, debugname
);
1574 if (usrmerge_objdir
!= NULL
)
1575 TRY_OBJDIR("%s%s/%s", extrapath
, usrmerge_objdir
, debugname
);
1581 /* When looking on the debuginfo server, always just pass the
1583 const HChar
* basename
= debugname
;
1584 if (VG_(strstr
)(basename
, "/") != NULL
) {
1585 basename
= VG_(strrchr
)(basename
, '/') + 1;
1587 VG_(sprintf
)(debugpath
, "%s on %s", basename
, serverpath
);
1588 dimg
= open_debug_file(basename
, buildid
, crc
, rel_ok
, serverpath
);
1589 if (dimg
) goto dimg_ok
;
1594 ML_(dinfo_free
)(objdir
);
1597 # if defined(VGO_linux)
1598 if (VG_(clo_enable_debuginfod
) && dimg
== NULL
)
1599 dimg
= find_debug_file_debuginfod(objpath
, &debugpath
, buildid
, crc
, rel_ok
);
1603 vg_assert(debugpath
);
1605 TRACE_SYMTAB("------ Found a debuginfo file: %s\n", debugpath
);
1607 /* Only set once, we might be called again for opening the altfile. */
1608 if (di
->fsm
.dbgname
== NULL
)
1609 di
->fsm
.dbgname
= ML_(dinfo_strdup
)("di.fdf.4", debugpath
);
1613 ML_(dinfo_free
)(debugpath
);
1619 /* Try to find a separate debug file for a given object file, in a
1620 hacky and dangerous way: check only the --extra-debuginfo-path and
1621 the --debuginfo-server. And don't do a consistency check. */
1623 DiImage
* find_debug_file_ad_hoc( const DebugInfo
* di
,
1624 const HChar
* objpath
)
1626 const HChar
* extrapath
= VG_(clo_extra_debuginfo_path
);
1627 const HChar
* serverpath
= VG_(clo_debuginfo_server
);
1629 DiImage
* dimg
= NULL
; /* the img that we found */
1630 HChar
* debugpath
= NULL
; /* where we found it */
1632 HChar
*objdir
= ML_(dinfo_strdup
)("di.fdfah.1", objpath
);
1635 if ((objdirptr
= VG_(strrchr
)(objdir
, '/')) != NULL
)
1638 debugpath
= ML_(dinfo_zalloc
)(
1640 VG_(strlen
)(objdir
) + 64
1641 + (extrapath
? VG_(strlen
)(extrapath
) : 0)
1642 + (serverpath
? VG_(strlen
)(serverpath
) : 0));
1645 VG_(sprintf
)(debugpath
, "%s/%s", extrapath
, objpath
);
1646 dimg
= ML_(img_from_local_file
)(debugpath
);
1648 if (VG_(clo_verbosity
) > 1) {
1649 VG_(message
)(Vg_DebugMsg
, " Using (POSSIBLY MISMATCHED) %s\n",
1656 /* When looking on the debuginfo server, always just pass the
1658 const HChar
* basename
= objpath
;
1659 if (VG_(strstr
)(basename
, "/") != NULL
) {
1660 basename
= VG_(strrchr
)(basename
, '/') + 1;
1662 VG_(sprintf
)(debugpath
, "%s on %s", basename
, serverpath
);
1663 dimg
= ML_(img_from_di_server
)(basename
, serverpath
);
1665 if (VG_(clo_verbosity
) > 1) {
1666 VG_(message
)(Vg_DebugMsg
, " Using (POSSIBLY MISMATCHED) %s\n",
1675 ML_(dinfo_free
)(objdir
);
1678 vg_assert(debugpath
);
1680 TRACE_SYMTAB("------ Found an ad_hoc debuginfo file: %s\n", debugpath
);
1684 ML_(dinfo_free
)(debugpath
);
1690 static DiOffT
INDEX_BIS ( DiOffT base
, UWord idx
, UWord scale
) {
1691 // This is a bit stupid. Really, idx and scale ought to be
1692 // 64-bit quantities, always.
1693 return base
+ (DiOffT
)idx
* (DiOffT
)scale
;
1697 /* Find the file offset corresponding to SVMA by using the program
1698 headers. This is taken from binutils-2.17/binutils/readelf.c
1699 offset_from_vma(). */
1701 Word
file_offset_from_svma ( /*OUT*/Bool
* ok
,
1709 for (i
= 0; i
< phdr_nent
; i
++) {
1711 ML_(img_get
)(&seg
, img
,
1712 INDEX_BIS(phdr_ioff
, i
, phdr_ent_szB
), sizeof(seg
));
1713 if (seg
.p_type
!= PT_LOAD
)
1715 if (svma
>= (seg
.p_vaddr
& -seg
.p_align
)
1716 && svma
+ 1 <= seg
.p_vaddr
+ seg
.p_filesz
) {
1718 return svma
- seg
.p_vaddr
+ seg
.p_offset
;
1725 /* Check if section is compressed and modify DiSlice if it is.
1726 Returns False in case of unsupported compression type.
1728 static Bool
check_compression(ElfXX_Shdr
* h
, DiSlice
* s
) {
1729 if (h
->sh_flags
& SHF_COMPRESSED
) {
1731 ML_(img_get
)(&chdr
, s
->img
, s
->ioff
, sizeof(ElfXX_Chdr
));
1732 if (chdr
.ch_type
!= ELFCOMPRESS_ZLIB
)
1734 s
->ioff
= ML_(img_mark_compressed_part
)(s
->img
,
1735 s
->ioff
+ sizeof(ElfXX_Chdr
),
1736 s
->szB
- sizeof(ElfXX_Chdr
),
1737 (SizeT
)chdr
.ch_size
);
1738 s
->szB
= chdr
.ch_size
;
1739 } else if (h
->sh_size
> SIZE_OF_ZLIB_HEADER
) {
1740 /* Read the zlib header. In this case, it should be "ZLIB"
1741 followed by the uncompressed section size, 8 bytes in BE order. */
1742 UChar tmp
[SIZE_OF_ZLIB_HEADER
];
1743 ML_(img_get
)(tmp
, s
->img
, s
->ioff
, SIZE_OF_ZLIB_HEADER
);
1744 if (VG_(memcmp
)(tmp
, "ZLIB", 4) == 0) {
1746 # if (VG_WORDSIZE == 8)
1747 size
= tmp
[4]; size
<<= 8;
1748 size
+= tmp
[5]; size
<<= 8;
1749 size
+= tmp
[6]; size
<<= 8;
1750 size
+= tmp
[7]; size
<<= 8;
1752 vg_assert((tmp
[4] == 0) && (tmp
[5] == 0) && (tmp
[6] == 0)
1756 size
+= tmp
[8]; size
<<= 8;
1757 size
+= tmp
[9]; size
<<= 8;
1758 size
+= tmp
[10]; size
<<= 8;
1760 s
->ioff
= ML_(img_mark_compressed_part
)(s
->img
,
1761 s
->ioff
+ SIZE_OF_ZLIB_HEADER
,
1762 s
->szB
- SIZE_OF_ZLIB_HEADER
,
1770 /* Helper function to get the readlink path. Returns a copy of path if the
1771 file wasn't a symbolic link. Returns NULL on error. Unless NULL is
1772 returned the result needs to be released with dinfo_free.
1774 static HChar
* readlink_path (const HChar
*path
)
1776 SizeT bufsiz
= VG_(strlen
)(path
);
1777 HChar
*buf
= ML_(dinfo_strdup
)("readlink_path.strdup", path
);
1782 #if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
1783 res
= VG_(do_syscall4
)(__NR_readlinkat
, VKI_AT_FDCWD
,
1784 (UWord
)path
, (UWord
)buf
, bufsiz
);
1785 #elif defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_freebsd)
1786 res
= VG_(do_syscall3
)(__NR_readlink
, (UWord
)path
, (UWord
)buf
, bufsiz
);
1787 #elif defined(VGO_solaris)
1788 res
= VG_(do_syscall4
)(__NR_readlinkat
, VKI_AT_FDCWD
, (UWord
)path
,
1789 (UWord
)buf
, bufsiz
);
1793 if (sr_isError(res
)) {
1794 if (sr_Err(res
) == VKI_EINVAL
)
1795 return buf
; // It wasn't a symbolic link, return the strdup result.
1796 ML_(dinfo_free
)(buf
);
1800 SSizeT r
= sr_Res(res
);
1802 if (r
== bufsiz
) { // buffer too small; increase and retry
1804 buf
= ML_(dinfo_realloc
)("readlink_path.realloc", buf
, bufsiz
);
1812 if (tries
== 0) { // We tried, but weird long path?
1813 ML_(dinfo_free
)(buf
);
1820 /* Relative path, add link dir. */
1822 SizeT linkdir_len
= VG_(strlen
)(path
);
1823 if ((linkdirptr
= VG_(strrchr
)(path
, '/')) != NULL
)
1824 linkdir_len
-= VG_(strlen
)(linkdirptr
+ 1);
1826 SizeT buflen
= VG_(strlen
)(buf
);
1827 SizeT needed
= linkdir_len
+ buflen
+ 1;
1828 if (bufsiz
< needed
)
1829 buf
= ML_(dinfo_realloc
)("readlink_path.linkdir", buf
, needed
);
1831 VG_(memmove
)(buf
+ linkdir_len
, buf
, buflen
);
1832 VG_(memcpy
)(buf
, path
, linkdir_len
);
1833 buf
[needed
- 1] = '\0';
1838 /* The central function for reading ELF debug info. For the
1839 object/exe specified by the DebugInfo, find ELF sections, then read
1840 the symbols, line number info, file name info, CFA (stack-unwind
1841 info) and anything else we want, into the tables within the
1845 Bool
ML_(read_elf_debug_info
) ( struct _DebugInfo
* di
)
1847 /* This function is long and complex. That, and the presence of
1848 nested scopes, means it's not always easy to see which parts are
1849 in loops/conditionals and which aren't. To make it easier to
1850 follow, points executed exactly once -- that is, those which are
1851 the top level of the function -- are marked TOPLEVEL.
1853 /* Consistent terminology for local variable names, without which
1854 it's almost unfollowably complex:
1857 in the main ELF file *_m*
1858 in the debuginfo file *_d*
1859 in the alt debuginfo file *_a*
1862 _{m,d,a}img a DiImage*
1863 _{m,d,a}ioff an offset in the image (DiOffT)
1864 _{m,d,a}nent "number of entries"
1865 _{m,d,a}ent_szB "size in bytes of an entry"
1866 ehdr_{m,d,a} ELF header
1870 _escn an DiSlice (elf section info) variable
1878 Bool dynbss_present
= False
;
1879 Bool sdynbss_present
= False
;
1881 /* Image for the main ELF file we're working with. */
1882 DiImage
* mimg
= NULL
;
1884 /* Ditto for any ELF debuginfo file that we might happen to load. */
1885 DiImage
* dimg
= NULL
;
1887 /* Ditto for alternate ELF debuginfo file that we might happen to load. */
1888 DiImage
* aimg
= NULL
;
1890 /* ELF header offset for the main file. Should be zero since the
1891 ELF header is at start of file. */
1892 DiOffT ehdr_mioff
= 0;
1894 /* Program header table image addr, # entries, entry size */
1895 DiOffT phdr_mioff
= 0;
1896 UWord phdr_mnent
= 0;
1897 UWord phdr_ment_szB
= 0;
1899 /* Section header image addr, # entries, entry size. Also the
1900 associated string table. */
1901 DiOffT shdr_mioff
= 0;
1902 UWord shdr_mnent
= 0;
1903 UWord shdr_ment_szB
= 0;
1904 DiOffT shdr_strtab_mioff
= 0;
1906 /* SVMAs covered by rx and rw segments and corresponding biases.
1907 Normally each object would provide just one rx and one rw area,
1908 but various ELF mangling tools create objects with multiple
1909 such entries, hence the generality. */
1919 XArray
* /* of RangeAndBias */ svma_ranges
= NULL
;
1921 # if defined(SOLARIS_PT_SUNDWTRACE_THRP)
1922 Addr dtrace_data_vaddr
= 0;
1926 vg_assert(di
->fsm
.have_rx_map
== True
);
1927 vg_assert(di
->fsm
.rw_map_count
>= 1);
1928 vg_assert(di
->have_dinfo
== False
);
1929 vg_assert(di
->fsm
.filename
);
1930 vg_assert(!di
->symtab
);
1931 vg_assert(!di
->loctab
);
1932 vg_assert(!di
->inltab
);
1933 vg_assert(!di
->cfsi_base
);
1934 vg_assert(!di
->cfsi_m_ix
);
1935 vg_assert(!di
->cfsi_rd
);
1936 vg_assert(!di
->cfsi_exprs
);
1937 vg_assert(!di
->strpool
);
1938 vg_assert(!di
->fndnpool
);
1939 vg_assert(!di
->soname
);
1942 Bool has_nonempty_rx
= False
;
1943 Bool has_nonempty_rw
= False
;
1944 for (i
= 0; i
< VG_(sizeXA
)(di
->fsm
.maps
); i
++) {
1945 DebugInfoMapping
* map
= VG_(indexXA
)(di
->fsm
.maps
, i
);
1946 if (!map
->rx
&& !map
->rw
)
1948 if (map
->rx
&& map
->size
> 0)
1949 has_nonempty_rx
= True
;
1950 if (map
->rw
&& map
->size
> 0)
1951 has_nonempty_rw
= True
;
1952 /* If this doesn't hold true, it means that m_syswrap/m_aspacemgr
1953 managed to do a mapping where the start isn't page aligned.
1954 Which sounds pretty bogus to me. */
1955 vg_assert(VG_IS_PAGE_ALIGNED(map
->avma
));
1957 vg_assert(has_nonempty_rx
);
1958 vg_assert(has_nonempty_rw
);
1961 /* ----------------------------------------------------------
1962 At this point, there is very little information in the
1963 DebugInfo. We only know that something that looks like an ELF
1964 file has been mapped rx-ishly and rw-ishly as recorded in the
1965 di->fsm.maps array items. First we examine the file's ELF
1966 Program Header, and, by comparing that against the di->fsm.maps
1967 info, try to figure out the AVMAs for the sections we care
1968 about, that should have been mapped: text, data, sdata, bss,
1970 ---------------------------------------------------------- */
1974 if (VG_(clo_verbosity
) > 1 || VG_(clo_trace_redir
))
1975 VG_(message
)(Vg_DebugMsg
, "Reading syms from %s\n",
1978 /* Connect to the primary object image, so that we can read symbols
1979 and line number info out of it. It will be disconnected
1980 immediately thereafter; it is only connected transiently. */
1981 mimg
= ML_(img_from_local_file
)(di
->fsm
.filename
);
1983 VG_(message
)(Vg_UserMsg
, "warning: connection to image %s failed\n",
1985 VG_(message
)(Vg_UserMsg
, " no symbols or debug info loaded\n" );
1989 /* Ok, the object image is available. Now verify that it is a
1990 valid ELF .so or executable image. */
1991 ok
= is_elf_object_file_by_DiImage(mimg
, False
);
1993 ML_(symerr
)(di
, True
, "Invalid ELF Header");
1997 /* Find where the program and section header tables are, and give
1998 up if either is missing or outside the image (bogus). */
2000 vg_assert(ehdr_mioff
== 0); // ensured by its initialisation
2001 ok
= ML_(img_valid
)(mimg
, ehdr_mioff
, sizeof(ehdr_m
));
2002 vg_assert(ok
); // ML_(is_elf_object_file) should ensure this
2003 ML_(img_get
)(&ehdr_m
, mimg
, ehdr_mioff
, sizeof(ehdr_m
));
2005 phdr_mioff
= ehdr_mioff
+ ehdr_m
.e_phoff
;
2006 phdr_mnent
= ehdr_m
.e_phnum
;
2007 phdr_ment_szB
= ehdr_m
.e_phentsize
;
2009 shdr_mioff
= ehdr_mioff
+ ehdr_m
.e_shoff
;
2010 shdr_mnent
= ehdr_m
.e_shnum
;
2011 shdr_ment_szB
= ehdr_m
.e_shentsize
;
2013 TRACE_SYMTAB("------ Basic facts about the object ------\n");
2014 TRACE_SYMTAB("object: n_oimage %llu\n",
2015 (ULong
)ML_(img_size
)(mimg
));
2016 TRACE_SYMTAB("phdr: ioff %llu nent %lu ent_szB %lu\n",
2017 phdr_mioff
, phdr_mnent
, phdr_ment_szB
);
2018 TRACE_SYMTAB("shdr: ioff %llu nent %lu ent_szB %lu\n",
2019 shdr_mioff
, shdr_mnent
, shdr_ment_szB
);
2020 for (i
= 0; i
< VG_(sizeXA
)(di
->fsm
.maps
); i
++) {
2021 const DebugInfoMapping
* map
= VG_(indexXA
)(di
->fsm
.maps
, i
);
2023 TRACE_SYMTAB("rx_map: avma %#lx size %lu foff %lld\n",
2024 map
->avma
, map
->size
, (Long
)map
->foff
);
2026 for (i
= 0; i
< VG_(sizeXA
)(di
->fsm
.maps
); i
++) {
2027 const DebugInfoMapping
* map
= VG_(indexXA
)(di
->fsm
.maps
, i
);
2029 TRACE_SYMTAB("rw_map: avma %#lx size %lu foff %lld\n",
2030 map
->avma
, map
->size
, (Long
)map
->foff
);
2034 || !ML_(img_valid
)(mimg
, phdr_mioff
, phdr_mnent
* phdr_ment_szB
)) {
2035 ML_(symerr
)(di
, True
, "Missing or invalid ELF Program Header Table");
2040 || !ML_(img_valid
)(mimg
, shdr_mioff
, shdr_mnent
* shdr_ment_szB
)) {
2041 ML_(symerr
)(di
, True
, "Missing or invalid ELF Section Header Table");
2045 /* Also find the section header's string table, and validate. */
2046 /* checked previously by is_elf_object_file: */
2047 vg_assert(ehdr_m
.e_shstrndx
!= SHN_UNDEF
);
2049 // shdr_mioff is the offset of the section header table
2050 // and we need the ehdr_m.e_shstrndx'th entry
2051 { ElfXX_Shdr a_shdr
;
2052 ML_(img_get
)(&a_shdr
, mimg
,
2053 INDEX_BIS(shdr_mioff
, ehdr_m
.e_shstrndx
, shdr_ment_szB
),
2056 = ehdr_mioff
/* isn't this always zero? */ + a_shdr
.sh_offset
;
2058 if (!ML_(img_valid
)(mimg
, shdr_strtab_mioff
,
2059 1/*bogus, but we don't know the real size*/ )) {
2060 ML_(symerr
)(di
, True
, "Invalid ELF Section Header String Table");
2065 TRACE_SYMTAB("shdr: string table at %llu\n", shdr_strtab_mioff
);
2067 svma_ranges
= VG_(newXA
)(ML_(dinfo_zalloc
), "di.relfdi.1",
2068 ML_(dinfo_free
), sizeof(RangeAndBias
));
2071 /* Look through the program header table, and:
2072 - copy information from suitable PT_LOAD entries into svma_ranges
2073 - find (or fake up) the .soname for this object.
2076 TRACE_SYMTAB("------ Examining the program headers ------\n");
2077 vg_assert(di
->soname
== NULL
);
2080 ElfXX_Addr prev_svma
= 0;
2082 for (i
= 0; i
< phdr_mnent
; i
++) {
2084 ML_(img_get
)(&a_phdr
, mimg
,
2085 INDEX_BIS(phdr_mioff
, i
, phdr_ment_szB
),
2088 /* Make sure the PT_LOADable entries are in order and
2089 non-overlapping. This in turn means the address ranges
2090 slurped into svma_ranges are in order and
2093 if (a_phdr
.p_type
== PT_LOAD
) {
2094 TRACE_SYMTAB("PT_LOAD[%ld]: p_vaddr %#lx (prev %#lx)\n",
2095 i
, (UWord
)a_phdr
.p_vaddr
, (UWord
)prev_svma
);
2096 TRACE_SYMTAB("PT_LOAD[%ld]: p_offset %lu, p_filesz %lu,"
2098 i
, (UWord
)a_phdr
.p_offset
, (UWord
)a_phdr
.p_filesz
,
2099 a_phdr
.p_flags
& PF_R
? 'r' : '-',
2100 a_phdr
.p_flags
& PF_W
? 'w' : '-',
2101 a_phdr
.p_flags
& PF_X
? 'x' : '-');
2102 if (a_phdr
.p_vaddr
< prev_svma
) {
2103 ML_(symerr
)(di
, True
,
2104 "ELF Program Headers are not in ascending order");
2107 prev_svma
= a_phdr
.p_vaddr
;
2108 if (a_phdr
.p_memsz
> 0) {
2109 Bool loaded
= False
;
2110 for (j
= 0; j
< VG_(sizeXA
)(di
->fsm
.maps
); j
++) {
2111 const DebugInfoMapping
* map
= VG_(indexXA
)(di
->fsm
.maps
, j
);
2112 if ( (map
->rx
|| map
->rw
|| map
->ro
)
2113 && map
->size
> 0 /* stay sane */
2114 && a_phdr
.p_offset
>= map
->foff
2115 && a_phdr
.p_offset
< map
->foff
+ map
->size
2116 && a_phdr
.p_offset
+ a_phdr
.p_filesz
2117 <= map
->foff
+ map
->size
) {
2119 item
.svma_base
= a_phdr
.p_vaddr
;
2120 item
.svma_limit
= a_phdr
.p_vaddr
+ a_phdr
.p_memsz
;
2121 item
.bias
= map
->avma
- map
->foff
2122 + a_phdr
.p_offset
- a_phdr
.p_vaddr
;
2124 && (a_phdr
.p_flags
& (PF_R
| PF_W
))
2127 VG_(addToXA
)(svma_ranges
, &item
);
2129 "PT_LOAD[%ld]: acquired as rw, bias 0x%lx\n",
2130 i
, (UWord
)item
.bias
);
2134 && (a_phdr
.p_flags
& (PF_R
| PF_X
))
2137 VG_(addToXA
)(svma_ranges
, &item
);
2139 "PT_LOAD[%ld]: acquired as rx, bias 0x%lx\n",
2140 i
, (UWord
)item
.bias
);
2144 && (a_phdr
.p_flags
& (PF_R
| PF_W
| PF_X
))
2147 VG_(addToXA
)(svma_ranges
, &item
);
2149 "PT_LOAD[%ld]: acquired as ro, bias 0x%lx\n",
2150 i
, (UWord
)item
.bias
);
2156 # if defined(SOLARIS_PT_SUNDWTRACE_THRP)
2157 if ((a_phdr
.p_memsz
== VKI_PT_SUNWDTRACE_SIZE
)
2158 && ((a_phdr
.p_flags
& (PF_R
| PF_W
| PF_X
)) == PF_R
)) {
2159 TRACE_SYMTAB("PT_LOAD[%ld]: ignore dtrace_data program "
2161 dtrace_data_vaddr
= a_phdr
.p_vaddr
;
2164 # endif /* SOLARIS_PT_SUNDWTRACE_THRP */
2166 ML_(symerr
)(di
, False
,
2167 "ELF section outside all mapped regions");
2168 /* This problem might be solved by further memory mappings.
2169 Avoid the vg_assert(!di->soname) at the beginning of this
2170 function if DYNAMIC section has been already processed. */
2172 ML_(dinfo_free
)(di
->soname
);
2180 /* Try to get the soname. If there isn't one, use "NONE".
2181 The seginfo needs to have some kind of soname in order to
2182 facilitate writing redirect functions, since all redirect
2183 specifications require a soname (pattern). */
2184 if (a_phdr
.p_type
== PT_DYNAMIC
&& di
->soname
== NULL
) {
2186 DiOffT strtab_mioff
= DiOffT_INVALID
;
2187 for (j
= 0; True
/*exit check is in the loop*/; j
++) {
2188 ElfXX_Dyn t_dyn_m
; /* dyn_img[j] */
2189 ML_(img_get
)(&t_dyn_m
, mimg
,
2190 INDEX_BIS(ehdr_mioff
+ a_phdr
.p_offset
,
2191 j
, sizeof(ElfXX_Dyn
)),
2193 if (t_dyn_m
.d_tag
== DT_NULL
)
2196 switch (t_dyn_m
.d_tag
) {
2198 stroff
= t_dyn_m
.d_un
.d_val
;
2203 Word offset
= file_offset_from_svma(
2204 &ok2
, t_dyn_m
.d_un
.d_ptr
, mimg
,
2205 phdr_mioff
, phdr_mnent
, phdr_ment_szB
2207 if (ok2
&& strtab_mioff
== DiOffT_INVALID
) {
2208 // Check for obviously bogus offsets.
2209 if (!ML_(img_valid
)(mimg
, offset
, 1)) {
2210 ML_(symerr
)(di
, True
, "Invalid DT_STRTAB offset");
2213 strtab_mioff
= ehdr_mioff
+ offset
;
2214 vg_assert(ehdr_mioff
== 0); // should always be
2222 if (stroff
!= -1 && strtab_mioff
!= DiOffT_INVALID
) {
2223 di
->soname
= ML_(img_strdup
)(mimg
, "di.redi.1",
2224 strtab_mioff
+ stroff
);
2225 TRACE_SYMTAB("Found soname = %s\n", di
->soname
);
2228 } /* for (i = 0; i < phdr_Mnent; i++) ... */
2231 } /* examine the program headers (local scope) */
2235 /* If, after looking at all the program headers, we still didn't
2236 find a soname, add a fake one. */
2237 if (di
->soname
== NULL
) {
2238 TRACE_SYMTAB("No soname found; using (fake) \"NONE\"\n");
2239 di
->soname
= ML_(dinfo_strdup
)("di.redi.2", "NONE");
2242 vg_assert(VG_(sizeXA
)(svma_ranges
) != 0);
2244 /* Now read the section table. */
2246 TRACE_SYMTAB("------ Examining the section headers ------\n");
2247 for (i
= 0; i
< VG_(sizeXA
)(di
->fsm
.maps
); i
++) {
2248 const DebugInfoMapping
* map
= VG_(indexXA
)(di
->fsm
.maps
, i
);
2250 TRACE_SYMTAB("rx: at %#lx are mapped foffsets %lld .. %lld\n",
2251 map
->avma
, (Long
)map
->foff
, (Long
)(map
->foff
+ map
->size
- 1) );
2253 TRACE_SYMTAB("rx: contains these svma regions:\n");
2254 for (i
= 0; i
< VG_(sizeXA
)(svma_ranges
); i
++) {
2255 const RangeAndBias
* reg
= VG_(indexXA
)(svma_ranges
, i
);
2257 TRACE_SYMTAB(" svmas %#lx .. %#lx with bias %#lx\n",
2258 reg
->svma_base
, reg
->svma_limit
- 1, (UWord
)reg
->bias
);
2260 for (i
= 0; i
< VG_(sizeXA
)(di
->fsm
.maps
); i
++) {
2261 const DebugInfoMapping
* map
= VG_(indexXA
)(di
->fsm
.maps
, i
);
2263 TRACE_SYMTAB("rw: at %#lx are mapped foffsets %lld .. %lld\n",
2264 map
->avma
, (Long
)map
->foff
, (Long
)(map
->foff
+ map
->size
- 1) );
2267 TRACE_SYMTAB("rw: contains these svma regions:\n");
2268 for (i
= 0; i
< VG_(sizeXA
)(svma_ranges
); i
++) {
2269 const RangeAndBias
* reg
= VG_(indexXA
)(svma_ranges
, i
);
2271 TRACE_SYMTAB(" svmas %#lx .. %#lx with bias %#lx\n",
2272 reg
->svma_base
, reg
->svma_limit
- 1, (UWord
)reg
->bias
);
2276 /* Iterate over section headers */
2277 for (i
= 0; i
< shdr_mnent
; i
++) {
2279 ML_(img_get
)(&a_shdr
, mimg
,
2280 INDEX_BIS(shdr_mioff
, i
, shdr_ment_szB
), sizeof(a_shdr
));
2281 DiOffT name_mioff
= shdr_strtab_mioff
+ a_shdr
.sh_name
;
2282 HChar
* name
= ML_(img_strdup
)(mimg
, "di.redi_name.2", name_mioff
);
2283 Addr svma
= a_shdr
.sh_addr
;
2284 OffT foff
= a_shdr
.sh_offset
;
2285 UWord size
= a_shdr
.sh_size
; /* Do not change this to be signed. */
2286 UInt alyn
= a_shdr
.sh_addralign
;
2287 Bool nobits
= a_shdr
.sh_type
== SHT_NOBITS
;
2288 /* Look through our collection of info obtained from the PT_LOAD
2289 headers, and make 'inrx' and 'inrw1' point to the first entry
2290 in each that intersects 'avma'. If in each case none is found,
2291 leave the relevant pointer at NULL. */
2292 RangeAndBias
* inrx
= NULL
;
2293 RangeAndBias
* inrw1
= NULL
;
2294 /* Depending on the link editro there may be two RW PT_LOAD headers
2295 * If so this will point to the seond one */
2296 RangeAndBias
* inrw2
= NULL
;
2297 /* used to switch between inrw1 and inrw2 */
2300 for (j
= 0; j
< VG_(sizeXA
)(svma_ranges
); j
++) {
2301 RangeAndBias
* rng
= VG_(indexXA
)(svma_ranges
, j
);
2302 if (svma
>= rng
->svma_base
&& svma
< rng
->svma_limit
) {
2303 if (!inrx
&& rng
->exec
) {
2305 } else if (!inrw1
&& !rng
->exec
) {
2307 } else if (!inrw2
&& !rng
->exec
) {
2313 TRACE_SYMTAB(" [sec %2ld] %s %s %s al%4u foff %6lld .. %6lld "
2314 " svma %p name \"%s\"\n",
2315 i
, inrx
? "rx" : " ", inrw1
? "rw" : " ", inrw2
? "rw" : " ",
2316 alyn
, (Long
) foff
, (size
== 0) ? (Long
)foff
: (Long
)(foff
+size
-1),
2317 (void *) svma
, name
);
2319 /* Check for sane-sized segments. SHT_NOBITS sections have zero
2320 size in the file and their offsets are just conceptual. */
2322 (foff
>= ML_(img_size
)(mimg
) || foff
+ size
> ML_(img_size
)(mimg
))) {
2323 ML_(symerr
)(di
, True
, "ELF Section extends beyond image end");
2327 /* Check for a sane alignment value. */
2328 if (alyn
> 0 && -1 == VG_(log2
)(alyn
)) {
2329 ML_(symerr
)(di
, True
, "ELF Section contains invalid "
2330 ".sh_addralign value");
2334 /* Ignore zero sized sections. */
2336 TRACE_SYMTAB("zero sized section \"%s\", ignoring\n", name
);
2337 ML_(dinfo_free
)(name
);
2341 # define BAD(_secname) \
2342 do { ML_(symerr)(di, True, \
2343 "Can't make sense of " _secname \
2344 " section mapping"); \
2345 /* make sure we don't assert if we find */ \
2346 /* ourselves back in this routine later, */ \
2347 /* with the same di */ \
2348 di->soname = NULL; \
2352 /* Find avma-s for: .text .data .sdata .rodata .bss .sbss .plt .got .opd
2355 /* In inrw2 is non-NULL then it will be used for .data .got.plt .bss */
2357 /* Accept .text where mapped as rx (code), even if zero-sized */
2358 if (0 == VG_(strcmp
)(name
, ".text")) {
2359 if (inrx
&& !di
->text_present
) {
2360 di
->text_present
= True
;
2361 di
->text_svma
= svma
;
2362 di
->text_avma
= svma
+ inrx
->bias
;
2363 di
->text_size
= size
;
2364 di
->text_bias
= inrx
->bias
;
2365 di
->text_debug_svma
= svma
;
2366 di
->text_debug_bias
= inrx
->bias
;
2367 TRACE_SYMTAB("acquiring .text svma = %#lx .. %#lx\n",
2369 di
->text_svma
+ di
->text_size
- 1);
2370 TRACE_SYMTAB("acquiring .text avma = %#lx .. %#lx\n",
2372 di
->text_avma
+ di
->text_size
- 1);
2373 TRACE_SYMTAB("acquiring .text bias = %#lx\n", (UWord
)di
->text_bias
);
2379 /* Accept .data where mapped as rw (data), even if zero-sized */
2380 if (0 == VG_(strcmp
)(name
, ".data")) {
2381 # if defined(SOLARIS_PT_SUNDWTRACE_THRP)
2382 if ((size
== VKI_PT_SUNWDTRACE_SIZE
) && (svma
== dtrace_data_vaddr
)) {
2383 TRACE_SYMTAB("ignoring .data section for dtrace_data "
2384 "%#lx .. %#lx\n", svma
, svma
+ size
- 1);
2386 # endif /* SOLARIS_PT_SUNDWTRACE_THRP */
2394 if (inrw
&& !di
->data_present
) {
2395 di
->data_present
= True
;
2396 di
->data_svma
= svma
;
2397 di
->data_avma
= svma
+ inrw
->bias
;
2398 di
->data_size
= size
;
2399 di
->data_bias
= inrw
->bias
;
2400 di
->data_debug_svma
= svma
;
2401 di
->data_debug_bias
= inrw
->bias
;
2402 TRACE_SYMTAB("acquiring .data svma = %#lx .. %#lx\n",
2404 di
->data_svma
+ di
->data_size
- 1);
2405 TRACE_SYMTAB("acquiring .data avma = %#lx .. %#lx\n",
2407 di
->data_avma
+ di
->data_size
- 1);
2408 TRACE_SYMTAB("acquiring .data bias = %#lx\n", (UWord
)di
->data_bias
);
2414 /* Accept .sdata where mapped as rw (data) */
2415 if (0 == VG_(strcmp
)(name
, ".sdata")) {
2416 if (inrw1
&& !di
->sdata_present
) {
2417 di
->sdata_present
= True
;
2418 di
->sdata_svma
= svma
;
2419 di
->sdata_avma
= svma
+ inrw1
->bias
;
2420 di
->sdata_size
= size
;
2421 di
->sdata_bias
= inrw1
->bias
;
2422 di
->sdata_debug_svma
= svma
;
2423 di
->sdata_debug_bias
= inrw1
->bias
;
2424 TRACE_SYMTAB("acquiring .sdata svma = %#lx .. %#lx\n",
2426 di
->sdata_svma
+ di
->sdata_size
- 1);
2427 TRACE_SYMTAB("acquiring .sdata avma = %#lx .. %#lx\n",
2429 di
->sdata_avma
+ di
->sdata_size
- 1);
2430 TRACE_SYMTAB("acquiring .sdata bias = %#lx\n",
2431 (UWord
)di
->sdata_bias
);
2437 /* Accept .rodata where mapped as rx or rw (data), even if zero-sized */
2438 if (0 == VG_(strcmp
)(name
, ".rodata")) {
2439 if (!di
->rodata_present
) {
2440 di
->rodata_svma
= svma
;
2441 di
->rodata_avma
= svma
;
2442 di
->rodata_size
= size
;
2443 di
->rodata_debug_svma
= svma
;
2445 di
->rodata_avma
+= inrx
->bias
;
2446 di
->rodata_bias
= inrx
->bias
;
2447 di
->rodata_debug_bias
= inrx
->bias
;
2449 di
->rodata_avma
+= inrw1
->bias
;
2450 di
->rodata_bias
= inrw1
->bias
;
2451 di
->rodata_debug_bias
= inrw1
->bias
;
2455 di
->rodata_present
= True
;
2456 TRACE_SYMTAB("acquiring .rodata svma = %#lx .. %#lx\n",
2458 di
->rodata_svma
+ di
->rodata_size
- 1);
2459 TRACE_SYMTAB("acquiring .rodata avma = %#lx .. %#lx\n",
2461 di
->rodata_avma
+ di
->rodata_size
- 1);
2462 TRACE_SYMTAB("acquiring .rodata bias = %#lx\n",
2463 (UWord
)di
->rodata_bias
);
2469 if (0 == VG_(strcmp
)(name
, ".dynbss")) {
2470 if (inrw1
&& !di
->bss_present
) {
2471 dynbss_present
= True
;
2472 di
->bss_present
= True
;
2473 di
->bss_svma
= svma
;
2474 di
->bss_avma
= svma
+ inrw1
->bias
;
2475 di
->bss_size
= size
;
2476 di
->bss_bias
= inrw1
->bias
;
2477 di
->bss_debug_svma
= svma
;
2478 di
->bss_debug_bias
= inrw1
->bias
;
2479 TRACE_SYMTAB("acquiring .dynbss svma = %#lx .. %#lx\n",
2481 di
->bss_svma
+ di
->bss_size
- 1);
2482 TRACE_SYMTAB("acquiring .dynbss avma = %#lx .. %#lx\n",
2484 di
->bss_avma
+ di
->bss_size
- 1);
2485 TRACE_SYMTAB("acquiring .dynbss bias = %#lx\n",
2486 (UWord
)di
->bss_bias
);
2490 /* Accept .bss where mapped as rw (data), even if zero-sized */
2491 if (0 == VG_(strcmp
)(name
, ".bss")) {
2499 if (inrw
&& dynbss_present
) {
2500 vg_assert(di
->bss_present
);
2501 dynbss_present
= False
;
2502 vg_assert(di
->bss_svma
+ di
->bss_size
== svma
);
2503 di
->bss_size
+= size
;
2504 TRACE_SYMTAB("acquiring .bss svma = %#lx .. %#lx\n",
2505 svma
, svma
+ size
- 1);
2506 TRACE_SYMTAB("acquiring .bss avma = %#lx .. %#lx\n",
2507 svma
+ inrw
->bias
, svma
+ inrw
->bias
+ size
- 1);
2508 TRACE_SYMTAB("acquiring .bss bias = %#lx\n",
2509 (UWord
)di
->bss_bias
);
2512 if (inrw
&& !di
->bss_present
) {
2513 di
->bss_present
= True
;
2514 di
->bss_svma
= svma
;
2515 di
->bss_avma
= svma
+ inrw
->bias
;
2516 di
->bss_size
= size
;
2517 di
->bss_bias
= inrw
->bias
;
2518 di
->bss_debug_svma
= svma
;
2519 di
->bss_debug_bias
= inrw
->bias
;
2520 TRACE_SYMTAB("acquiring .bss svma = %#lx .. %#lx\n",
2522 di
->bss_svma
+ di
->bss_size
- 1);
2523 TRACE_SYMTAB("acquiring .bss avma = %#lx .. %#lx\n",
2525 di
->bss_avma
+ di
->bss_size
- 1);
2526 TRACE_SYMTAB("acquiring .bss bias = %#lx\n",
2527 (UWord
)di
->bss_bias
);
2530 /* Now one from the wtf?! department ... */
2531 if (inrx
&& (!inrw
) && !di
->bss_present
) {
2532 /* File contains a .bss, but it got mapped as rx only.
2533 This is very strange. For now, just pretend we didn't
2535 di
->bss_present
= False
;
2540 di
->bss_debug_svma
= 0;
2541 di
->bss_debug_bias
= 0;
2542 if (!VG_(clo_xml
)) {
2543 VG_(message
)(Vg_UserMsg
,
2544 "Warning: the following file's .bss is "
2545 "mapped r-x only - ignoring .bss syms\n");
2546 VG_(message
)(Vg_UserMsg
, " %s\n", di
->fsm
.filename
2552 if ((!inrw
) && (!inrx
) && !di
->bss_present
) {
2553 /* File contains a .bss, but it didn't get mapped. Ignore. */
2554 di
->bss_present
= False
;
2564 if (0 == VG_(strcmp
)(name
, ".sdynbss")) {
2565 if (inrw1
&& !di
->sbss_present
) {
2566 sdynbss_present
= True
;
2567 di
->sbss_present
= True
;
2568 di
->sbss_svma
= svma
;
2569 di
->sbss_avma
= svma
+ inrw1
->bias
;
2570 di
->sbss_size
= size
;
2571 di
->sbss_bias
= inrw1
->bias
;
2572 di
->sbss_debug_svma
= svma
;
2573 di
->sbss_debug_bias
= inrw1
->bias
;
2574 TRACE_SYMTAB("acquiring .sdynbss svma = %#lx .. %#lx\n",
2576 di
->sbss_svma
+ di
->sbss_size
- 1);
2577 TRACE_SYMTAB("acquiring .sdynbss avma = %#lx .. %#lx\n",
2579 di
->sbss_avma
+ di
->sbss_size
- 1);
2580 TRACE_SYMTAB("acquiring .sdynbss bias = %#lx\n",
2581 (UWord
)di
->sbss_bias
);
2585 /* Accept .sbss where mapped as rw (data) */
2586 if (0 == VG_(strcmp
)(name
, ".sbss")) {
2587 if (inrw1
&& sdynbss_present
) {
2588 vg_assert(di
->sbss_present
);
2589 sdynbss_present
= False
;
2590 vg_assert(di
->sbss_svma
+ di
->sbss_size
== svma
);
2591 di
->sbss_size
+= size
;
2592 TRACE_SYMTAB("acquiring .sbss svma = %#lx .. %#lx\n",
2593 svma
, svma
+ size
- 1);
2594 TRACE_SYMTAB("acquiring .sbss avma = %#lx .. %#lx\n",
2595 svma
+ inrw1
->bias
, svma
+ inrw1
->bias
+ size
- 1);
2596 TRACE_SYMTAB("acquiring .sbss bias = %#lx\n", (UWord
)di
->sbss_bias
);
2599 if (inrw1
&& !di
->sbss_present
) {
2600 di
->sbss_present
= True
;
2601 di
->sbss_svma
= svma
;
2602 di
->sbss_avma
= svma
+ inrw1
->bias
;
2603 di
->sbss_size
= size
;
2604 di
->sbss_bias
= inrw1
->bias
;
2605 di
->sbss_debug_svma
= svma
;
2606 di
->sbss_debug_bias
= inrw1
->bias
;
2607 TRACE_SYMTAB("acquiring .sbss svma = %#lx .. %#lx\n",
2609 di
->sbss_svma
+ di
->sbss_size
- 1);
2610 TRACE_SYMTAB("acquiring .sbss avma = %#lx .. %#lx\n",
2612 di
->sbss_avma
+ di
->sbss_size
- 1);
2613 TRACE_SYMTAB("acquiring .sbss bias = %#lx\n", (UWord
)di
->sbss_bias
);
2619 /* Accept .got where mapped as rw (data) */
2620 if (0 == VG_(strcmp
)(name
, ".got")) {
2621 if (inrw1
&& !di
->got_present
) {
2622 di
->got_present
= True
;
2623 di
->got_avma
= svma
+ inrw1
->bias
;
2624 di
->got_size
= size
;
2625 TRACE_SYMTAB("acquiring .got avma = %#lx\n", di
->got_avma
);
2631 /* Accept .got.plt where mapped as rw (data) */
2632 if (0 == VG_(strcmp
)(name
, ".got.plt")) {
2640 if (inrw
&& !di
->gotplt_present
) {
2641 di
->gotplt_present
= True
;
2642 di
->gotplt_avma
= svma
+ inrw
->bias
;
2643 di
->gotplt_size
= size
;
2644 TRACE_SYMTAB("acquiring .got.plt avma = %#lx\n", di
->gotplt_avma
);
2645 } else if (size
!= 0) {
2650 /* PLT is different on different platforms, it seems. */
2651 # if defined(VGP_x86_linux) || defined(VGP_amd64_linux) \
2652 || defined(VGP_arm_linux) || defined (VGP_s390x_linux) \
2653 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
2654 || defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) \
2655 || defined(VGP_x86_solaris) || defined(VGP_amd64_solaris) \
2656 || defined(VGP_x86_freebsd) || defined(VGP_amd64_freebsd)
2657 /* Accept .plt where mapped as rx (code) */
2658 if (0 == VG_(strcmp
)(name
, ".plt")) {
2659 if (inrx
&& !di
->plt_present
) {
2660 di
->plt_present
= True
;
2661 di
->plt_avma
= svma
+ inrx
->bias
;
2662 di
->plt_size
= size
;
2663 TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di
->plt_avma
);
2668 # elif defined(VGP_ppc32_linux)
2669 /* Accept .plt where mapped as rw (data) */
2670 if (0 == VG_(strcmp
)(name
, ".plt")) {
2671 if (inrw1
&& !di
->plt_present
) {
2672 di
->plt_present
= True
;
2673 di
->plt_avma
= svma
+ inrw1
->bias
;
2674 di
->plt_size
= size
;
2675 TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di
->plt_avma
);
2680 # elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
2681 /* Accept .plt where mapped as rw (data), or unmapped */
2682 if (0 == VG_(strcmp
)(name
, ".plt")) {
2683 if (inrw1
&& !di
->plt_present
) {
2684 di
->plt_present
= True
;
2685 di
->plt_avma
= svma
+ inrw1
->bias
;
2686 di
->plt_size
= size
;
2687 TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di
->plt_avma
);
2689 if ((!inrw1
) && (!inrx
) && size
> 0 && !di
->plt_present
) {
2690 /* File contains a .plt, but it didn't get mapped.
2691 Presumably it is not required on this platform. At
2692 least don't reject the situation as invalid. */
2693 di
->plt_present
= True
;
2701 # error "Unsupported platform"
2704 /* Accept .opd where mapped as rw (data) */
2705 if (0 == VG_(strcmp
)(name
, ".opd")) {
2706 if (inrw1
&& !di
->opd_present
) {
2707 di
->opd_present
= True
;
2708 di
->opd_avma
= svma
+ inrw1
->bias
;
2709 di
->opd_size
= size
;
2710 TRACE_SYMTAB("acquiring .opd avma = %#lx\n", di
->opd_avma
);
2716 /* Accept .eh_frame where mapped as rx (code). This seems to be
2717 the common case. However, if that doesn't pan out, try for
2718 rw (data) instead. We can handle up to N_EHFRAME_SECTS per
2720 if (0 == VG_(strcmp
)(name
, ".eh_frame")) {
2721 if (inrx
&& di
->n_ehframe
< N_EHFRAME_SECTS
) {
2722 di
->ehframe_avma
[di
->n_ehframe
] = svma
+ inrx
->bias
;
2723 di
->ehframe_size
[di
->n_ehframe
] = size
;
2724 TRACE_SYMTAB("acquiring .eh_frame avma = %#lx\n",
2725 di
->ehframe_avma
[di
->n_ehframe
]);
2728 if (inrw1
&& di
->n_ehframe
< N_EHFRAME_SECTS
) {
2729 di
->ehframe_avma
[di
->n_ehframe
] = svma
+ inrw1
->bias
;
2730 di
->ehframe_size
[di
->n_ehframe
] = size
;
2731 TRACE_SYMTAB("acquiring .eh_frame avma = %#lx\n",
2732 di
->ehframe_avma
[di
->n_ehframe
]);
2739 /* Accept .ARM.exidx where mapped as rx (code). */
2740 /* FIXME: make sure the entire section is mapped in, not just
2741 the first address. */
2742 if (0 == VG_(strcmp
)(name
, ".ARM.exidx")) {
2743 if (inrx
&& !di
->exidx_present
) {
2744 di
->exidx_present
= True
;
2745 di
->exidx_svma
= svma
;
2746 di
->exidx_avma
= svma
+ inrx
->bias
;
2747 di
->exidx_size
= size
;
2748 di
->exidx_bias
= inrx
->bias
;
2749 TRACE_SYMTAB("acquiring .exidx svma = %#lx .. %#lx\n",
2751 di
->exidx_svma
+ di
->exidx_size
- 1);
2752 TRACE_SYMTAB("acquiring .exidx avma = %#lx .. %#lx\n",
2754 di
->exidx_avma
+ di
->exidx_size
- 1);
2755 TRACE_SYMTAB("acquiring .exidx bias = %#lx\n",
2756 (UWord
)di
->exidx_bias
);
2762 /* Accept .ARM.extab where mapped as rx (code). */
2763 /* FIXME: make sure the entire section is mapped in, not just
2764 the first address. */
2765 if (0 == VG_(strcmp
)(name
, ".ARM.extab")) {
2766 if (inrx
&& !di
->extab_present
) {
2767 di
->extab_present
= True
;
2768 di
->extab_svma
= svma
;
2769 di
->extab_avma
= svma
+ inrx
->bias
;
2770 di
->extab_size
= size
;
2771 di
->extab_bias
= inrx
->bias
;
2772 TRACE_SYMTAB("acquiring .extab svma = %#lx .. %#lx\n",
2774 di
->extab_svma
+ di
->extab_size
- 1);
2775 TRACE_SYMTAB("acquiring .extab avma = %#lx .. %#lx\n",
2777 di
->extab_avma
+ di
->extab_size
- 1);
2778 TRACE_SYMTAB("acquiring .extab bias = %#lx\n",
2779 (UWord
)di
->extab_bias
);
2785 ML_(dinfo_free
)(name
);
2789 } /* iterate over the section headers */
2792 if (0) VG_(printf
)("YYYY text_: avma %#lx size %lu bias %#lx\n",
2793 di
->text_avma
, di
->text_size
, (UWord
)di
->text_bias
);
2795 if (VG_(clo_verbosity
) > 2 || VG_(clo_trace_redir
))
2796 VG_(message
)(Vg_DebugMsg
, " svma %#010lx, avma %#010lx\n",
2797 di
->text_avma
- di
->text_bias
,
2801 TRACE_SYMTAB("------ Finding image addresses "
2802 "for debug-info sections ------\n");
2805 /* Find interesting sections, read the symbol table(s), read any
2806 debug information. Each section is located either in the main,
2807 debug or alt-debug files, but only in one. For each section,
2808 |section_escn| records which of |mimg|, |dimg| or |aimg| we
2809 found it in, along with the section's image offset and its size.
2810 The triples (section_img, section_ioff, section_szB) are
2811 consistent, in that they are always either (NULL,
2812 DiOffT_INVALID, 0), or refer to the same image, and are all
2813 assigned together. */
2816 DiSlice strtab_escn
= DiSlice_INVALID
; // .strtab
2817 DiSlice symtab_escn
= DiSlice_INVALID
; // .symtab
2818 DiSlice dynstr_escn
= DiSlice_INVALID
; // .dynstr
2819 DiSlice dynsym_escn
= DiSlice_INVALID
; // .dynsym
2820 # if defined(VGO_solaris)
2821 DiSlice ldynsym_escn
= DiSlice_INVALID
; // .SUNW_ldynsym
2823 DiSlice debuglink_escn
= DiSlice_INVALID
; // .gnu_debuglink
2824 DiSlice debugaltlink_escn
= DiSlice_INVALID
; // .gnu_debugaltlink
2825 DiSlice debug_line_escn
= DiSlice_INVALID
; // .debug_line (dwarf2)
2826 DiSlice debug_info_escn
= DiSlice_INVALID
; // .debug_info (dwarf2)
2827 DiSlice debug_types_escn
= DiSlice_INVALID
; // .debug_types (dwarf4)
2828 DiSlice debug_abbv_escn
= DiSlice_INVALID
; // .debug_abbrev (dwarf2)
2829 DiSlice debug_str_escn
= DiSlice_INVALID
; // .debug_str (dwarf2)
2830 DiSlice debug_line_str_escn
= DiSlice_INVALID
; // .debug_line_str(dwarf5)
2831 DiSlice debug_ranges_escn
= DiSlice_INVALID
; // .debug_ranges (dwarf2)
2832 DiSlice debug_rnglists_escn
= DiSlice_INVALID
; // .debug_rnglists(dwarf5)
2833 DiSlice debug_loclists_escn
= DiSlice_INVALID
; // .debug_loclists(dwarf5)
2834 DiSlice debug_addr_escn
= DiSlice_INVALID
; // .debug_addr (dwarf5)
2835 DiSlice debug_str_offsets_escn
= DiSlice_INVALID
; // .debug_str_offsets (dwarf5)
2836 DiSlice debug_loc_escn
= DiSlice_INVALID
; // .debug_loc (dwarf2)
2837 DiSlice debug_frame_escn
= DiSlice_INVALID
; // .debug_frame (dwarf2)
2838 DiSlice debug_line_alt_escn
= DiSlice_INVALID
; // .debug_line (alt)
2839 DiSlice debug_info_alt_escn
= DiSlice_INVALID
; // .debug_info (alt)
2840 DiSlice debug_abbv_alt_escn
= DiSlice_INVALID
; // .debug_abbrev (alt)
2841 DiSlice debug_str_alt_escn
= DiSlice_INVALID
; // .debug_str (alt)
2842 DiSlice dwarf1d_escn
= DiSlice_INVALID
; // .debug (dwarf1)
2843 DiSlice dwarf1l_escn
= DiSlice_INVALID
; // .line (dwarf1)
2844 DiSlice opd_escn
= DiSlice_INVALID
; // .opd (dwarf2,
2846 DiSlice ehframe_escn
[N_EHFRAME_SECTS
]; // .eh_frame (dwarf2)
2848 for (i
= 0; i
< N_EHFRAME_SECTS
; i
++)
2849 ehframe_escn
[i
] = DiSlice_INVALID
;
2851 /* Find all interesting sections */
2853 UInt ehframe_mix
= 0;
2855 /* What FIND does: it finds the section called _SEC_NAME. The
2856 size of it is assigned to _SEC_SIZE. The address of the
2857 section in the transiently loaded oimage is assigned to
2858 _SEC_IMG. If the section is found, _POST_FX is executed
2859 after _SEC_NAME and _SEC_SIZE have been assigned to.
2861 Even for sections which are marked loadable, the client's
2862 ld.so may not have loaded them yet, so there is no guarantee
2863 that we can safely prod around in any such area). Because
2864 the entire object file is transiently mapped aboard for
2865 inspection, it's always safe to inspect that area. */
2868 /* Iterate over section headers (again) */
2869 for (i
= 0; i
< ehdr_m
.e_shnum
; i
++) {
2871 # define FINDX(_sec_name, _sec_escn, _post_fx) \
2873 ElfXX_Shdr a_shdr; \
2874 ML_(img_get)(&a_shdr, mimg, \
2875 INDEX_BIS(shdr_mioff, i, shdr_ment_szB), \
2877 if (0 == ML_(img_strcmp_c)(mimg, shdr_strtab_mioff \
2878 + a_shdr.sh_name, _sec_name)) { \
2880 _sec_escn.img = mimg; \
2881 _sec_escn.ioff = (DiOffT)a_shdr.sh_offset; \
2882 _sec_escn.szB = a_shdr.sh_size; \
2883 if (!check_compression(&a_shdr, &_sec_escn)) { \
2884 ML_(symerr)(di, True, " Compression type is unsupported"); \
2887 nobits = a_shdr.sh_type == SHT_NOBITS; \
2888 vg_assert(_sec_escn.img != NULL); \
2889 vg_assert(_sec_escn.ioff != DiOffT_INVALID); \
2890 TRACE_SYMTAB( "%-18s: ioff %llu .. %llu\n", \
2891 _sec_name, (ULong)a_shdr.sh_offset, \
2892 ((ULong)a_shdr.sh_offset) + a_shdr.sh_size - 1); \
2893 /* SHT_NOBITS sections have zero size in the file. */ \
2895 a_shdr.sh_offset + \
2896 a_shdr.sh_size > ML_(img_real_size)(mimg)) { \
2897 ML_(symerr)(di, True, \
2898 " section beyond image end?!"); \
2905 /* Version with no post-effects */
2906 # define FIND(_sec_name, _sec_escn) \
2907 FINDX(_sec_name, _sec_escn, /**/)
2910 FIND( ".dynsym", dynsym_escn
)
2911 FIND( ".dynstr", dynstr_escn
)
2912 FIND( ".symtab", symtab_escn
)
2913 FIND( ".strtab", strtab_escn
)
2914 # if defined(VGO_solaris)
2915 FIND( ".SUNW_ldynsym", ldynsym_escn
)
2918 FIND( ".gnu_debuglink", debuglink_escn
)
2919 FIND( ".gnu_debugaltlink", debugaltlink_escn
)
2921 FIND( ".debug_line", debug_line_escn
)
2922 if (!ML_(sli_is_valid
)(debug_line_escn
))
2923 FIND(".zdebug_line", debug_line_escn
)
2925 FIND( ".debug_info", debug_info_escn
)
2926 if (!ML_(sli_is_valid
)(debug_info_escn
))
2927 FIND(".zdebug_info", debug_info_escn
)
2929 FIND( ".debug_types", debug_types_escn
)
2930 if (!ML_(sli_is_valid
)(debug_types_escn
))
2931 FIND(".zdebug_types", debug_types_escn
)
2933 FIND( ".debug_abbrev", debug_abbv_escn
)
2934 if (!ML_(sli_is_valid
)(debug_abbv_escn
))
2935 FIND(".zdebug_abbrev", debug_abbv_escn
)
2937 FIND( ".debug_str", debug_str_escn
)
2938 if (!ML_(sli_is_valid
)(debug_str_escn
))
2939 FIND(".zdebug_str", debug_str_escn
)
2941 FIND( ".debug_line_str", debug_line_str_escn
)
2942 if (!ML_(sli_is_valid
)(debug_line_str_escn
))
2943 FIND(".zdebug_str", debug_line_str_escn
)
2945 FIND( ".debug_ranges", debug_ranges_escn
)
2946 if (!ML_(sli_is_valid
)(debug_ranges_escn
))
2947 FIND(".zdebug_ranges", debug_ranges_escn
)
2949 FIND( ".debug_rnglists", debug_rnglists_escn
)
2950 if (!ML_(sli_is_valid
)(debug_rnglists_escn
))
2951 FIND(".zdebug_rnglists", debug_rnglists_escn
)
2953 FIND( ".debug_loclists", debug_loclists_escn
)
2954 if (!ML_(sli_is_valid
)(debug_loclists_escn
))
2955 FIND(".zdebug_loclists", debug_loclists_escn
)
2957 FIND( ".debug_loc", debug_loc_escn
)
2958 if (!ML_(sli_is_valid
)(debug_loc_escn
))
2959 FIND(".zdebug_loc", debug_loc_escn
)
2961 FIND( ".debug_frame", debug_frame_escn
)
2962 if (!ML_(sli_is_valid
)(debug_frame_escn
))
2963 FIND(".zdebug_frame", debug_frame_escn
)
2965 FIND( ".debug_addr", debug_addr_escn
)
2966 if (!ML_(sli_is_valid
)(debug_addr_escn
))
2967 FIND(".zdebug_addr", debug_addr_escn
)
2969 FIND( ".debug_str_offsets", debug_str_offsets_escn
)
2970 if (!ML_(sli_is_valid
)(debug_str_offsets_escn
))
2971 FIND(".zdebug_str_offsets", debug_str_offsets_escn
)
2973 FIND( ".debug", dwarf1d_escn
)
2974 FIND( ".line", dwarf1l_escn
)
2976 FIND( ".opd", opd_escn
)
2978 FINDX( ".eh_frame", ehframe_escn
[ehframe_mix
],
2979 do { ehframe_mix
++; vg_assert(ehframe_mix
<= N_EHFRAME_SECTS
);
2982 /* Comment_on_EH_FRAME_MULTIPLE_INSTANCES: w.r.t. .eh_frame
2983 multi-instance kludgery, how are we assured that the order
2984 in which we fill in ehframe_escn[] is consistent with the
2985 order in which we previously filled in di->ehframe_avma[]
2986 and di->ehframe_size[] ? By the fact that in both cases,
2987 these arrays were filled in by iterating over the section
2988 headers top-to-bottom. So both loops (this one and the
2989 previous one) encounter the .eh_frame entries in the same
2990 order and so fill in these arrays in a consistent order.
2995 } /* Iterate over section headers (again) */
2998 /* Now, see if we can find a debuginfo object, and if so connect
3000 vg_assert(dimg
== NULL
&& aimg
== NULL
);
3002 #if defined(VGO_freebsd)
3004 read_and_set_osrel(mimg
);
3008 /* Look for a build-id */
3009 HChar
* buildid
= find_buildid(mimg
, False
, False
);
3011 /* If we don't have a .debug_info section in the main image then
3012 look for a debug image that matches either the build-id or
3013 the debuglink-CRC32 in the main image. If the main image
3014 doesn't contain either of those then this won't even bother
3015 to try looking. This looks in all known places, including
3016 the --extra-debuginfo-path if specified and on the
3017 --debuginfo-server if specified. */
3018 if (debug_info_escn
.img
== NULL
&&
3019 (buildid
!= NULL
|| debuglink_escn
.img
!= NULL
)) {
3020 /* Do have a debuglink section? */
3021 if (debuglink_escn
.img
!= NULL
) {
3023 = VG_ROUNDUP(ML_(img_strlen
)(debuglink_escn
.img
,
3024 debuglink_escn
.ioff
)+1, 4);
3025 vg_assert(crc_offset
+ sizeof(UInt
) <= debuglink_escn
.szB
);
3027 /* Extract the CRC from the debuglink section */
3028 UInt crc
= ML_(img_get_UInt
)(debuglink_escn
.img
,
3029 debuglink_escn
.ioff
+ crc_offset
);
3031 /* See if we can find a matching debug file */
3032 HChar
* debuglink_str_m
3033 = ML_(img_strdup
)(debuglink_escn
.img
,
3034 "di.redi_dlk.1", debuglink_escn
.ioff
);
3035 dimg
= find_debug_file( di
, di
->fsm
.filename
, buildid
,
3036 debuglink_str_m
, crc
, False
);
3037 if (debuglink_str_m
)
3038 ML_(dinfo_free
)(debuglink_str_m
);
3040 /* See if we can find a matching debug file */
3041 dimg
= find_debug_file( di
, di
->fsm
.filename
, buildid
,
3047 ML_(dinfo_free
)(buildid
);
3048 buildid
= NULL
; /* paranoia */
3051 /* As a last-ditch measure, try looking for in the
3052 --extra-debuginfo-path and/or on the --debuginfo-server, but
3053 only in the case where --allow-mismatched-debuginfo=yes.
3054 This is dangerous in that (1) it gives no assurance that the
3055 debuginfo object matches the main one, and hence (2) we will
3056 very likely get an assertion in the code below, if indeed
3057 there is a mismatch. Hence it is disabled by default
3058 (--allow-mismatched-debuginfo=no). Nevertheless it's
3059 sometimes a useful way of getting out of a tight spot.
3061 Note that we're ignoring the name in the .gnu_debuglink
3062 section here, and just looking for a file of the same name
3063 either the extra-path or on the server. */
3064 if (dimg
== NULL
&& VG_(clo_allow_mismatched_debuginfo
)) {
3065 dimg
= find_debug_file_ad_hoc( di
, di
->fsm
.filename
);
3069 /* If we were successful in finding a debug image, pull various
3070 SVMA/bias/size and image addresses out of it. */
3071 if (dimg
!= NULL
&& is_elf_object_file_by_DiImage(dimg
, False
)) {
3073 /* Pull out and validate program header and section header info */
3074 DiOffT ehdr_dioff
= 0;
3075 ElfXX_Ehdr ehdr_dimg
;
3076 ML_(img_get
)(&ehdr_dimg
, dimg
, ehdr_dioff
, sizeof(ehdr_dimg
));
3078 DiOffT phdr_dioff
= ehdr_dimg
.e_phoff
;
3079 UWord phdr_dnent
= ehdr_dimg
.e_phnum
;
3080 UWord phdr_dent_szB
= ehdr_dimg
.e_phentsize
;
3082 DiOffT shdr_dioff
= ehdr_dimg
.e_shoff
;
3083 UWord shdr_dnent
= ehdr_dimg
.e_shnum
;
3084 UWord shdr_dent_szB
= ehdr_dimg
.e_shentsize
;
3086 DiOffT shdr_strtab_dioff
= DiOffT_INVALID
;
3088 /* SVMAs covered by rx and rw segments and corresponding bias. */
3089 Addr rx_dsvma_limit
= 0;
3090 PtrdiffT rx_dbias
= 0;
3091 Addr rw_dsvma_limit
= 0;
3092 PtrdiffT rw_dbias
= 0;
3094 Bool need_symtab
, need_dwarf2
, need_dwarf1
;
3097 || !ML_(img_valid
)(dimg
, phdr_dioff
,
3098 phdr_dnent
* phdr_dent_szB
)) {
3099 ML_(symerr
)(di
, True
,
3100 "Missing or invalid ELF Program Header Table"
3101 " (debuginfo file)");
3106 || !ML_(img_valid
)(dimg
, shdr_dioff
,
3107 shdr_dnent
* shdr_dent_szB
)) {
3108 ML_(symerr
)(di
, True
,
3109 "Missing or invalid ELF Section Header Table"
3110 " (debuginfo file)");
3114 /* Also find the section header's string table, and validate. */
3115 /* checked previously by is_elf_object_file: */
3116 vg_assert(ehdr_dimg
.e_shstrndx
!= SHN_UNDEF
);
3118 // shdr_dioff is the offset of the section header table
3119 // and we need the ehdr_dimg.e_shstrndx'th entry
3120 { ElfXX_Shdr a_shdr
;
3121 ML_(img_get
)(&a_shdr
, dimg
,
3122 INDEX_BIS(shdr_dioff
, ehdr_dimg
.e_shstrndx
,
3125 shdr_strtab_dioff
= a_shdr
.sh_offset
;
3126 if (!ML_(img_valid
)(dimg
, shdr_strtab_dioff
,
3127 1/*bogus, but we don't know the real size*/)) {
3128 ML_(symerr
)(di
, True
,
3129 "Invalid ELF Section Header String Table"
3130 " (debuginfo file)");
3135 for (i
= 0; i
< ehdr_dimg
.e_phnum
; i
++) {
3137 ML_(img_get
)(&a_phdr
, dimg
, INDEX_BIS(ehdr_dimg
.e_phoff
,
3140 if (a_phdr
.p_type
== PT_LOAD
) {
3141 for (j
= 0; j
< VG_(sizeXA
)(di
->fsm
.maps
); j
++) {
3142 const DebugInfoMapping
* map
= VG_(indexXA
)(di
->fsm
.maps
, j
);
3143 if ( a_phdr
.p_offset
>= map
->foff
3144 && a_phdr
.p_offset
< map
->foff
+ map
->size
3145 && a_phdr
.p_offset
+ a_phdr
.p_filesz
3146 < map
->foff
+ map
->size
) {
3147 if (map
->rx
&& rx_dsvma_limit
== 0) {
3148 rx_dsvma_limit
= a_phdr
.p_vaddr
+ a_phdr
.p_memsz
;
3149 rx_dbias
= map
->avma
- map
->foff
+ a_phdr
.p_offset
3152 if (map
->rw
&& rw_dsvma_limit
== 0) {
3153 rw_dsvma_limit
= a_phdr
.p_vaddr
+ a_phdr
.p_memsz
;
3154 rw_dbias
= map
->avma
- map
->foff
+ a_phdr
.p_offset
3163 need_symtab
= (symtab_escn
.img
== NULL
);
3164 need_dwarf2
= (debug_info_escn
.img
== NULL
);
3165 need_dwarf1
= (dwarf1d_escn
.img
== NULL
);
3167 /* Find all interesting sections in the debug image */
3168 for (i
= 0; i
< ehdr_dimg
.e_shnum
; i
++) {
3170 /* Find debug svma and bias information for sections
3171 we found in the main file. */
3173 # define FIND(_sec, _seg) \
3175 ElfXX_Shdr a_shdr; \
3176 ML_(img_get)(&a_shdr, dimg, \
3177 INDEX_BIS(shdr_dioff, i, shdr_dent_szB), \
3179 if (di->_sec##_present \
3180 && 0 == ML_(img_strcmp_c)(dimg, shdr_strtab_dioff \
3181 + a_shdr.sh_name, "." #_sec)) { \
3182 vg_assert(di->_sec##_size == a_shdr.sh_size); \
3183 /* JRS 2013-Jun-01: the following assert doesn't contain */ \
3184 /* any ==s, which seems to me to be suspicious. */ \
3185 vg_assert(di->_sec##_avma + a_shdr.sh_addr + _seg##_dbias); \
3186 /* Assume we have a correct value for the main */ \
3187 /* object's bias. Use that to derive the debuginfo */ \
3188 /* object's bias, by adding the difference in SVMAs */ \
3189 /* for the corresponding sections in the two files. */ \
3190 /* That should take care of all prelinking effects. */ \
3191 di->_sec##_debug_svma = a_shdr.sh_addr; \
3192 di->_sec##_debug_bias \
3193 = di->_sec##_bias + \
3194 di->_sec##_svma - di->_sec##_debug_svma; \
3195 TRACE_SYMTAB("acquiring ." #_sec \
3196 " debug svma = %#lx .. %#lx\n", \
3197 di->_sec##_debug_svma, \
3198 di->_sec##_debug_svma + di->_sec##_size - 1); \
3199 TRACE_SYMTAB("acquiring ." #_sec " debug bias = %#lx\n", \
3200 (UWord)di->_sec##_debug_bias); \
3204 /* SECTION SEGMENT */
3214 /* Same deal as previous FIND, except only do it for those
3215 sections which we didn't find in the main file. */
3217 # define FIND(_condition, _sec_name, _sec_escn) \
3219 ElfXX_Shdr a_shdr; \
3220 ML_(img_get)(&a_shdr, dimg, \
3221 INDEX_BIS(shdr_dioff, i, shdr_dent_szB), \
3224 && 0 == ML_(img_strcmp_c)(dimg, shdr_strtab_dioff \
3225 + a_shdr.sh_name, _sec_name)) { \
3227 if (_sec_escn.img != NULL) { \
3228 ML_(symerr)(di, True, \
3229 " debuginfo section duplicates a" \
3230 " section in the main ELF file"); \
3233 _sec_escn.img = dimg; \
3234 _sec_escn.ioff = (DiOffT)a_shdr.sh_offset; \
3235 _sec_escn.szB = a_shdr.sh_size; \
3236 if (!check_compression(&a_shdr, &_sec_escn)) { \
3237 ML_(symerr)(di, True, " Compression type is unsupported"); \
3240 nobits = a_shdr.sh_type == SHT_NOBITS; \
3241 vg_assert(_sec_escn.img != NULL); \
3242 vg_assert(_sec_escn.ioff != DiOffT_INVALID); \
3243 TRACE_SYMTAB( "%-18s: dioff %llu .. %llu\n", \
3245 (ULong)a_shdr.sh_offset, \
3246 ((ULong)a_shdr.sh_offset) + a_shdr.sh_size - 1); \
3247 /* SHT_NOBITS sections have zero size in the file. */ \
3248 if (!nobits && a_shdr.sh_offset \
3249 + a_shdr.sh_size > ML_(img_real_size)(_sec_escn.img)) { \
3250 ML_(symerr)(di, True, \
3251 " section beyond image end?!"); \
3257 /* NEEDED? NAME ElfSec */
3258 FIND( need_symtab
, ".symtab", symtab_escn
)
3259 FIND( need_symtab
, ".strtab", strtab_escn
)
3260 FIND( need_dwarf2
, ".debug_line", debug_line_escn
)
3261 if (!ML_(sli_is_valid
)(debug_line_escn
))
3262 FIND(need_dwarf2
, ".zdebug_line", debug_line_escn
)
3264 FIND( need_dwarf2
, ".debug_info", debug_info_escn
)
3265 if (!ML_(sli_is_valid
)(debug_info_escn
))
3266 FIND(need_dwarf2
, ".zdebug_info", debug_info_escn
)
3268 FIND( need_dwarf2
, ".debug_types", debug_types_escn
)
3269 if (!ML_(sli_is_valid
)(debug_types_escn
))
3270 FIND(need_dwarf2
, ".zdebug_types", debug_types_escn
)
3272 FIND( need_dwarf2
, ".debug_abbrev", debug_abbv_escn
)
3273 if (!ML_(sli_is_valid
)(debug_abbv_escn
))
3274 FIND(need_dwarf2
, ".zdebug_abbrev", debug_abbv_escn
)
3276 FIND( need_dwarf2
, ".debug_str", debug_str_escn
)
3277 if (!ML_(sli_is_valid
)(debug_str_escn
))
3278 FIND(need_dwarf2
, ".zdebug_str", debug_str_escn
)
3280 FIND( need_dwarf2
, ".debug_line_str", debug_line_str_escn
)
3281 if (!ML_(sli_is_valid
)(debug_line_str_escn
))
3282 FIND(need_dwarf2
, ".zdebug_line_str", debug_line_str_escn
)
3284 FIND( need_dwarf2
, ".debug_ranges", debug_ranges_escn
)
3285 if (!ML_(sli_is_valid
)(debug_ranges_escn
))
3286 FIND(need_dwarf2
, ".zdebug_ranges", debug_ranges_escn
)
3288 FIND( need_dwarf2
, ".debug_rnglists", debug_rnglists_escn
)
3289 if (!ML_(sli_is_valid
)(debug_rnglists_escn
))
3290 FIND(need_dwarf2
, ".zdebug_rnglists", debug_rnglists_escn
)
3292 FIND( need_dwarf2
, ".debug_loclists", debug_loclists_escn
)
3293 if (!ML_(sli_is_valid
)(debug_loclists_escn
))
3294 FIND(need_dwarf2
, ".zdebug_loclists", debug_loclists_escn
)
3296 FIND( need_dwarf2
, ".debug_loc", debug_loc_escn
)
3297 if (!ML_(sli_is_valid
)(debug_loc_escn
))
3298 FIND(need_dwarf2
, ".zdebug_loc", debug_loc_escn
)
3300 FIND( need_dwarf2
, ".debug_frame", debug_frame_escn
)
3301 if (!ML_(sli_is_valid
)(debug_frame_escn
))
3302 FIND(need_dwarf2
, ".zdebug_frame", debug_frame_escn
)
3304 FIND( need_dwarf2
, ".debug_addr", debug_addr_escn
)
3305 if (!ML_(sli_is_valid
)(debug_addr_escn
))
3306 FIND(need_dwarf2
, ".zdebug_addr", debug_addr_escn
)
3308 FIND( need_dwarf2
, ".debug_str_offsets", debug_str_offsets_escn
)
3309 if (!ML_(sli_is_valid
)(debug_str_offsets_escn
))
3310 FIND(need_dwarf2
, ".zdebug_str_offsets", debug_str_offsets_escn
)
3312 if (!ML_(sli_is_valid
)(debugaltlink_escn
))
3313 FIND( need_dwarf2
, ".gnu_debugaltlink", debugaltlink_escn
)
3315 FIND( need_dwarf1
, ".debug", dwarf1d_escn
)
3316 FIND( need_dwarf1
, ".line", dwarf1l_escn
)
3319 } /* Find all interesting sections */
3320 } /* do we have a debug image? */
3323 /* Look for alternate debug image, and if found, connect |aimg|
3325 vg_assert(aimg
== NULL
);
3327 if (debugaltlink_escn
.img
!= NULL
) {
3328 HChar
* altfile_str_m
3329 = ML_(img_strdup
)(debugaltlink_escn
.img
,
3330 "di.fbi.3", debugaltlink_escn
.ioff
);
3331 UInt buildid_offset
= ML_(img_strlen
)(debugaltlink_escn
.img
,
3332 debugaltlink_escn
.ioff
)+1;
3334 vg_assert(buildid_offset
< debugaltlink_escn
.szB
);
3337 = ML_(dinfo_zalloc
)("di.fbi.4",
3338 (debugaltlink_escn
.szB
- buildid_offset
)
3341 /* The altfile might be relative to the debug file or main file.
3342 Make sure that we got the real file, not a symlink. */
3343 HChar
*dbgname
= di
->fsm
.dbgname
? di
->fsm
.dbgname
: di
->fsm
.filename
;
3344 HChar
* rdbgname
= readlink_path (dbgname
);
3345 if (rdbgname
== NULL
)
3346 rdbgname
= ML_(dinfo_strdup
)("rdbgname", dbgname
);
3348 for (j
= 0; j
< debugaltlink_escn
.szB
- buildid_offset
; j
++)
3350 altbuildid
+ 2 * j
, "%02x",
3351 (UInt
)ML_(img_get_UChar
)(debugaltlink_escn
.img
,
3352 debugaltlink_escn
.ioff
3353 + buildid_offset
+ j
));
3355 /* See if we can find a matching debug file */
3356 aimg
= find_debug_file( di
, rdbgname
, altbuildid
,
3357 altfile_str_m
, 0, True
);
3359 ML_(dinfo_free
)(rdbgname
);
3362 ML_(dinfo_free
)(altfile_str_m
);
3363 ML_(dinfo_free
)(altbuildid
);
3367 /* If we were successful in finding alternate debug image, pull various
3368 size and image addresses out of it. */
3369 if (aimg
!= NULL
&& is_elf_object_file_by_DiImage(aimg
, True
)) {
3371 /* Pull out and validate program header and section header info */
3372 DiOffT ehdr_aioff
= 0;
3373 ElfXX_Ehdr ehdr_aimg
;
3374 ML_(img_get
)(&ehdr_aimg
, aimg
, ehdr_aioff
, sizeof(ehdr_aimg
));
3376 DiOffT shdr_aioff
= ehdr_aimg
.e_shoff
;
3377 UWord shdr_anent
= ehdr_aimg
.e_shnum
;
3378 UWord shdr_aent_szB
= ehdr_aimg
.e_shentsize
;
3380 DiOffT shdr_strtab_aioff
= DiOffT_INVALID
;
3383 || !ML_(img_valid
)(aimg
, shdr_aioff
,
3384 shdr_anent
* shdr_aent_szB
)) {
3385 ML_(symerr
)(di
, True
,
3386 "Missing or invalid ELF Section Header Table"
3387 " (alternate debuginfo file)");
3391 /* Also find the section header's string table, and validate. */
3392 /* checked previously by is_elf_object_file: */
3393 vg_assert(ehdr_aimg
.e_shstrndx
!= SHN_UNDEF
);
3395 // shdr_aioff is the offset of the section header table
3396 // and we need the ehdr_aimg.e_shstrndx'th entry
3397 { ElfXX_Shdr a_shdr
;
3398 ML_(img_get
)(&a_shdr
, aimg
,
3399 INDEX_BIS(shdr_aioff
, ehdr_aimg
.e_shstrndx
,
3402 shdr_strtab_aioff
= a_shdr
.sh_offset
;
3403 if (!ML_(img_valid
)(aimg
, shdr_strtab_aioff
,
3404 1/*bogus, but we don't know the real size*/)) {
3405 ML_(symerr
)(di
, True
,
3406 "Invalid ELF Section Header String Table"
3407 " (alternate debuginfo file)");
3412 /* Find all interesting sections */
3413 for (i
= 0; i
< ehdr_aimg
.e_shnum
; i
++) {
3415 # define FIND(_sec_name, _sec_escn) \
3417 ElfXX_Shdr a_shdr; \
3418 ML_(img_get)(&a_shdr, aimg, \
3419 INDEX_BIS(shdr_aioff, i, shdr_aent_szB), \
3421 if (0 == ML_(img_strcmp_c)(aimg, shdr_strtab_aioff \
3422 + a_shdr.sh_name, _sec_name)) { \
3423 if (_sec_escn.img != NULL) { \
3424 ML_(symerr)(di, True, \
3425 " alternate debuginfo section duplicates a" \
3426 " section in the main ELF file"); \
3429 _sec_escn.img = aimg; \
3430 _sec_escn.ioff = (DiOffT)a_shdr.sh_offset; \
3431 _sec_escn.szB = a_shdr.sh_size; \
3432 if (!check_compression(&a_shdr, &_sec_escn)) { \
3433 ML_(symerr)(di, True, " Compression type is " \
3437 vg_assert(_sec_escn.img != NULL); \
3438 vg_assert(_sec_escn.ioff != DiOffT_INVALID); \
3439 TRACE_SYMTAB( "%-18s: aioff %llu .. %llu\n", \
3441 (ULong)a_shdr.sh_offset, \
3442 ((ULong)a_shdr.sh_offset) + a_shdr.sh_size - 1); \
3447 FIND(".debug_line", debug_line_alt_escn
)
3448 if (!ML_(sli_is_valid
)(debug_line_alt_escn
))
3449 FIND(".zdebug_line", debug_line_alt_escn
)
3451 FIND(".debug_info", debug_info_alt_escn
)
3452 if (!ML_(sli_is_valid
)(debug_info_alt_escn
))
3453 FIND(".zdebug_info", debug_info_alt_escn
)
3455 FIND(".debug_abbrev", debug_abbv_alt_escn
)
3456 if (!ML_(sli_is_valid
)(debug_abbv_alt_escn
))
3457 FIND(".zdebug_abbrev", debug_abbv_alt_escn
)
3459 FIND(".debug_str", debug_str_alt_escn
)
3460 if (!ML_(sli_is_valid
)(debug_str_alt_escn
))
3461 FIND(".zdebug_str", debug_str_alt_escn
)
3464 } /* Find all interesting sections */
3465 } /* do we have a debug image? */
3469 /* Check some sizes */
3470 vg_assert((dynsym_escn
.szB
% sizeof(ElfXX_Sym
)) == 0);
3471 vg_assert((symtab_escn
.szB
% sizeof(ElfXX_Sym
)) == 0);
3472 # if defined(VGO_solaris)
3473 vg_assert((ldynsym_escn
.szB
% sizeof(ElfXX_Sym
)) == 0);
3479 void (*read_elf_symtab
)(struct _DebugInfo
*, const HChar
*,
3480 DiSlice
*, DiSlice
*, DiSlice
*, Bool
);
3481 Bool symtab_in_debug
;
3482 # if defined(VGP_ppc64be_linux)
3483 read_elf_symtab
= read_elf_symtab__ppc64be_linux
;
3485 read_elf_symtab
= read_elf_symtab__normal
;
3487 symtab_in_debug
= symtab_escn
.img
== dimg
;
3488 read_elf_symtab(di
, "symbol table",
3489 &symtab_escn
, &strtab_escn
, &opd_escn
,
3491 read_elf_symtab(di
, "dynamic symbol table",
3492 &dynsym_escn
, &dynstr_escn
, &opd_escn
,
3494 # if defined(VGO_solaris)
3495 read_elf_symtab(di
, "local dynamic symbol table",
3496 &ldynsym_escn
, &dynstr_escn
, &opd_escn
,
3502 /* Read .eh_frame and .debug_frame (call-frame-info) if any. Do
3503 the .eh_frame section(s) first. */
3504 vg_assert(di
->n_ehframe
>= 0 && di
->n_ehframe
<= N_EHFRAME_SECTS
);
3505 for (i
= 0; i
< di
->n_ehframe
; i
++) {
3506 /* see Comment_on_EH_FRAME_MULTIPLE_INSTANCES above for why
3507 this next assertion should hold. */
3508 vg_assert(ML_(sli_is_valid
)(ehframe_escn
[i
]));
3509 vg_assert(ehframe_escn
[i
].szB
== di
->ehframe_size
[i
]);
3510 ML_(read_callframe_info_dwarf3
)( di
,
3512 di
->ehframe_avma
[i
],
3513 True
/*is_ehframe*/ );
3515 if (ML_(sli_is_valid
)(debug_frame_escn
)) {
3516 ML_(read_callframe_info_dwarf3
)( di
,
3518 0/*assume zero avma*/,
3519 False
/*!is_ehframe*/ );
3523 /* jrs 2006-01-01: icc-8.1 has been observed to generate
3524 binaries without debug_str sections. Don't preclude
3525 debuginfo reading for that reason, but, in
3526 read_unitinfo_dwarf2, do check that debugstr is non-NULL
3528 if (ML_(sli_is_valid
)(debug_info_escn
)
3529 && ML_(sli_is_valid
)(debug_abbv_escn
)
3530 && ML_(sli_is_valid
)(debug_line_escn
)) {
3531 /* The old reader: line numbers and unwind info only */
3532 ML_(read_debuginfo_dwarf3
) ( di
,
3539 debug_line_str_escn
);
3540 /* The new reader: read the DIEs in .debug_info to acquire
3541 information on variable types and locations or inline info.
3542 But only if the tool asks for it, or the user requests it on
3543 the command line. */
3544 if (VG_(clo_read_var_info
) /* the user or tool asked for it */
3545 || VG_(clo_read_inline_info
)) {
3546 ML_(new_dwarf3_reader
)(
3547 di
, debug_info_escn
, debug_types_escn
,
3548 debug_abbv_escn
, debug_line_escn
,
3549 debug_str_escn
, debug_ranges_escn
,
3550 debug_rnglists_escn
, debug_loclists_escn
,
3551 debug_loc_escn
, debug_info_alt_escn
,
3552 debug_abbv_alt_escn
, debug_line_alt_escn
,
3553 debug_str_alt_escn
, debug_line_str_escn
,
3554 debug_addr_escn
, debug_str_offsets_escn
3560 // JRS 31 July 2014: dwarf-1 reading is currently broken and
3561 // therefore deactivated.
3562 //if (dwarf1d_img && dwarf1l_img) {
3563 // ML_(read_debuginfo_dwarf1) ( di, dwarf1d_img, dwarf1d_sz,
3564 // dwarf1l_img, dwarf1l_sz );
3567 # if defined(VGA_arm)
3569 /* ARM32 only: read .exidx/.extab if present. Note we are
3570 reading these directly out of the mapped in (running) image.
3571 Also, read these only if no CFI based unwind info was
3572 acquired for this file.
3574 An .exidx section is always required, but the .extab section
3575 can be optionally omitted, provided that .exidx does not
3576 refer to it. If the .exidx is erroneous and does refer to
3577 .extab even though .extab is missing, the range checks done
3578 by GET_EX_U32 in ExtabEntryExtract in readexidx.c should
3579 prevent any invalid memory accesses, and cause the .extab to
3580 be rejected as invalid.
3583 * check with m_aspacemgr that the entire [exidx_avma, +exidx_size)
3584 and [extab_avma, +extab_size) areas are readable, since we're
3585 reading this stuff out of the running image (not from a file/socket)
3586 and we don't want to segfault.
3587 * DebugInfo::exidx_bias and use text_bias instead.
3588 I think it's always the same.
3589 * remove DebugInfo::{extab_bias, exidx_svma, extab_svma} since
3590 they are never used.
3592 if (di
->exidx_present
3593 && di
->cfsi_used
== 0
3594 && di
->text_present
&& di
->text_size
> 0) {
3595 Addr text_last_svma
= di
->text_svma
+ di
->text_size
- 1;
3596 ML_(read_exidx
)( di
, (UChar
*)di
->exidx_avma
, di
->exidx_size
,
3597 (UChar
*)di
->extab_avma
, di
->extab_size
,
3601 # endif /* defined(VGA_arm) */
3603 } /* "Find interesting sections, read the symbol table(s), read any debug
3604 information" (a local scope) */
3609 /* If reading Dwarf3 variable type/location info, print a line
3610 showing the number of variables read for each object.
3611 (Currently disabled -- is a sanity-check mechanism for
3613 if (0 && VG_(clo_read_var_info
)) {
3616 for (j
= 0; j
< VG_(sizeXA
)(di
->varinfo
); j
++) {
3617 OSet
* /* of DiAddrRange */ scope
3618 = *(OSet
**)VG_(indexXA
)(di
->varinfo
, j
);
3620 VG_(OSetGen_ResetIter
)( scope
);
3622 DiAddrRange
* range
= VG_(OSetGen_Next
)( scope
);
3624 vg_assert(range
->vars
);
3625 Word w
= VG_(sizeXA
)(range
->vars
);
3627 if (0) VG_(printf
)("range %#lx %#lx %ld\n",
3628 range
->aMin
, range
->aMax
, w
);
3633 VG_(umsg
)("VARINFO: %7lu vars %7lu text_size %s\n",
3634 nVars
, di
->text_size
, di
->fsm
.filename
);
3640 /* Last, but not least, detach from the image(s). */
3641 if (mimg
) ML_(img_done
)(mimg
);
3642 if (dimg
) ML_(img_done
)(dimg
);
3643 if (aimg
) ML_(img_done
)(aimg
);
3645 if (svma_ranges
) VG_(deleteXA
)(svma_ranges
);
3653 Bool
ML_(check_elf_and_get_rw_loads
) ( Int fd
, const HChar
* filename
, Int
* rw_load_count
)
3657 DiImage
* mimg
= NULL
;
3658 DiOffT ehdr_mioff
= 0;
3659 DiOffT phdr_mioff
= 0;
3660 UWord phdr_mnent
= 0U;
3661 UWord phdr_ment_szB
= 0U;
3665 mimg
= ML_(img_from_fd
)(fd
, filename
);
3667 VG_(message
)(Vg_UserMsg
, "warning: connection to image %s failed\n",
3669 VG_(message
)(Vg_UserMsg
, " cannot read program headers \n" );
3673 ok
= is_elf_object_file_by_DiImage(mimg
, False
);
3680 #if defined(VGA_amd64) || defined(VGA_ppc64be) || defined(VGA_ppc64le) || defined(VGA_arm) || defined(VGA_arm64)
3686 #if defined(VGO_solaris)
3690 vg_assert(ehdr_mioff
== 0); // ensured by its initialisation
3691 ok
= ML_(img_valid
)(mimg
, ehdr_mioff
, sizeof(ehdr_m
));
3692 vg_assert(ok
); // ML_(is_elf_object_file) should ensure this
3693 ML_(img_get
)(&ehdr_m
, mimg
, ehdr_mioff
, sizeof(ehdr_m
));
3695 phdr_mioff
= ehdr_mioff
+ ehdr_m
.e_phoff
;
3696 phdr_mnent
= ehdr_m
.e_phnum
;
3697 phdr_ment_szB
= ehdr_m
.e_phentsize
;
3699 for (i
= 0U; i
< phdr_mnent
; i
++) {
3701 ML_(img_get
)(&a_phdr
, mimg
,
3702 INDEX_BIS(phdr_mioff
, i
, phdr_ment_szB
),
3705 if (a_phdr
.p_type
== PT_LOAD
) {
3706 if (a_phdr
.p_memsz
> 0) {
3707 if (((a_phdr
.p_flags
& (PF_R
| PF_W
)) == (PF_R
| PF_W
)) &&
3708 ((a_phdr
.p_flags
& flag_x
) == 0)) {
3714 * Just because The ELF file contains 2 RW PT_LOAD segments it
3715 * doesn't mean that Valgrind will also make 2 calls to
3716 * VG_(di_notify_mmap). If the stars are all aligned
3717 * (which usually means that the ELF file is the client
3718 * executable with the segment offset for the
3719 * second PT_LOAD falls exactly on 0x1000) then the NSegements
3720 * will get merged and VG_(di_notify_mmap) only gets called once. */
3721 if (*rw_load_count
== 2 &&
3722 ehdr_m
.e_type
== ET_EXEC
&&
3723 a_phdr
.p_offset
== VG_PGROUNDDN(a_phdr
.p_offset
) )
3729 } /* for (i = 0; i < phdr_Mnent; i++) ... */
3735 /* Last, but not least, detach from the image(s). */
3736 if (mimg
) ML_(img_free
)(mimg
);
3746 #endif // defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd)
3748 /*--------------------------------------------------------------------*/
3750 /*--------------------------------------------------------------------*/