blob: e3318e6b71d78edd45944479c7e13a32f7f1c8ac [file] [log] [blame]
sewardjeadcd862006-04-04 15:12:44 +00001
2/*--------------------------------------------------------------------*/
3/*--- Reading of syms & debug info from ELF .so/executable files. ---*/
4/*--- readelf.c ---*/
5/*--------------------------------------------------------------------*/
6
7/*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
10
11 Copyright (C) 2000-2006 Julian Seward
12 jseward@acm.org
13
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License as
16 published by the Free Software Foundation; either version 2 of the
17 License, or (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27 02111-1307, USA.
28
29 The GNU General Public License is contained in the file COPYING.
30*/
31/*
32 Stabs reader greatly improved by Nick Nethercote, Apr 02.
33 This module was also extensively hacked on by Jeremy Fitzhardinge
34 and Tom Hughes.
35*/
36
37#include "pub_core_basics.h"
38#include "pub_core_libcbase.h"
39#include "pub_core_libcprint.h"
40#include "pub_core_libcassert.h"
41#include "pub_core_libcfile.h"
42#include "pub_core_aspacemgr.h" /* for mmaping debuginfo files */
43#include "pub_core_machine.h" /* VG_ELF_CLASS */
44#include "pub_core_mallocfree.h"
45#include "pub_core_options.h"
46#include "pub_core_oset.h"
47#include "pub_core_tooliface.h" /* VG_(needs) */
48#include "priv_storage.h"
49#include "priv_readelf.h" /* self */
50#include "priv_readdwarf.h" /* 'cos ELF contains DWARF */
51#include "priv_readstabs.h" /* and stabs, if we're unlucky */
52
53/* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
54#include <elf.h>
55/* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
56
57/*------------------------------------------------------------*/
58/*--- 32/64-bit parameterisation ---*/
59/*------------------------------------------------------------*/
60
61/* For all the ELF macros and types which specify '32' or '64',
62 select the correct variant for this platform and give it
63 an 'XX' name. Then use the 'XX' variant consistently in
64 the rest of this file.
65*/
66#if VG_WORDSIZE == 4
67# define ElfXX_Ehdr Elf32_Ehdr
68# define ElfXX_Shdr Elf32_Shdr
69# define ElfXX_Phdr Elf32_Phdr
70# define ElfXX_Sym Elf32_Sym
71# define ElfXX_Word Elf32_Word
72# define ElfXX_Addr Elf32_Addr
73# define ElfXX_Dyn Elf32_Dyn
74# define ELFXX_ST_BIND ELF32_ST_BIND
75# define ELFXX_ST_TYPE ELF32_ST_TYPE
76
77#elif VG_WORDSIZE == 8
78# define ElfXX_Ehdr Elf64_Ehdr
79# define ElfXX_Shdr Elf64_Shdr
80# define ElfXX_Phdr Elf64_Phdr
81# define ElfXX_Sym Elf64_Sym
82# define ElfXX_Word Elf64_Word
83# define ElfXX_Addr Elf64_Addr
84# define ElfXX_Dyn Elf64_Dyn
85# define ELFXX_ST_BIND ELF64_ST_BIND
86# define ELFXX_ST_TYPE ELF64_ST_TYPE
87
88#else
89# error "VG_WORDSIZE should be 4 or 8"
90#endif
91
92
93/*------------------------------------------------------------*/
94/*--- ---*/
95/*--- Read symbol table and line info from ELF files. ---*/
96/*--- ---*/
97/*------------------------------------------------------------*/
98
99/* readelf.c parses ELF files and acquires symbol table info from
100 them. It calls onwards to readdwarf.c to read DWARF2/3 line number
101 and call frame info found. */
102
103
104/* Identify an ELF object file by peering at the first few bytes of
105 it. */
106
107Bool ML_(is_elf_object_file)( const void* buf )
108{
109 ElfXX_Ehdr* ehdr = (ElfXX_Ehdr*)buf;
110 Int ok = 1;
111
112 ok &= (ehdr->e_ident[EI_MAG0] == 0x7F
113 && ehdr->e_ident[EI_MAG1] == 'E'
114 && ehdr->e_ident[EI_MAG2] == 'L'
115 && ehdr->e_ident[EI_MAG3] == 'F');
116 ok &= (ehdr->e_ident[EI_CLASS] == VG_ELF_CLASS
117 && ehdr->e_ident[EI_DATA] == VG_ELF_DATA2XXX
118 && ehdr->e_ident[EI_VERSION] == EV_CURRENT);
119 ok &= (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN);
120 ok &= (ehdr->e_machine == VG_ELF_MACHINE);
121 ok &= (ehdr->e_version == EV_CURRENT);
122 ok &= (ehdr->e_shstrndx != SHN_UNDEF);
123 ok &= (ehdr->e_shoff != 0 && ehdr->e_shnum != 0);
124 ok &= (ehdr->e_phoff != 0 && ehdr->e_phnum != 0);
125
126 if (ok)
127 return True;
128 else
129 return False;
130}
131
132
133/* Show a raw ELF symbol, given its in-image address and name. */
134
135static
136void show_raw_elf_symbol ( Int i,
137 ElfXX_Sym* sym, Char* sym_name, Addr sym_addr,
138 Bool ppc64_linux_format )
139{
140 HChar* space = ppc64_linux_format ? " " : "";
141 VG_(printf)("raw symbol [%4d]: ", i);
142 switch (ELFXX_ST_BIND(sym->st_info)) {
143 case STB_LOCAL: VG_(printf)("LOC "); break;
144 case STB_GLOBAL: VG_(printf)("GLO "); break;
145 case STB_WEAK: VG_(printf)("WEA "); break;
146 case STB_LOPROC: VG_(printf)("lop "); break;
147 case STB_HIPROC: VG_(printf)("hip "); break;
148 default: VG_(printf)("??? "); break;
149 }
150 switch (ELFXX_ST_TYPE(sym->st_info)) {
151 case STT_NOTYPE: VG_(printf)("NOT "); break;
152 case STT_OBJECT: VG_(printf)("OBJ "); break;
153 case STT_FUNC: VG_(printf)("FUN "); break;
154 case STT_SECTION: VG_(printf)("SEC "); break;
155 case STT_FILE: VG_(printf)("FIL "); break;
156 case STT_LOPROC: VG_(printf)("lop "); break;
157 case STT_HIPROC: VG_(printf)("hip "); break;
158 default: VG_(printf)("??? "); break;
159 }
160 VG_(printf)(": val %010p, %ssz %4d %s\n",
161 sym_addr, space, sym->st_size,
162 ( sym->st_name ? sym_name : (Char*)"NONAME" ) );
163}
164
165
166/* Decide whether SYM is something we should collect, and if so, copy
167 relevant info to the _OUT arguments. For {x86,amd64,ppc32}-linux
168 this is straightforward - the name, address, size are copied out
169 unchanged.
170
171 For ppc64-linux it's more complex. If the symbol is seen to be in
172 the .opd section, it is taken to be a function descriptor, and so
173 a dereference is attempted, in order to get hold of the real entry
174 point address. Also as part of the dereference, there is an attempt
175 to calculate the TOC pointer (R2 value) associated with the symbol.
176
177 To support the ppc64-linux pre-"dotless" ABI (prior to gcc 4.0.0),
178 if the symbol is seen to be outside the .opd section and its name
179 starts with a dot, an .opd deference is not attempted, and no TOC
180 pointer is calculated, but the the leading dot is removed from the
181 name.
182
183 As a result, on ppc64-linux, the caller of this function may have
184 to piece together the real size, address, name of the symbol from
185 multiple calls to this function. Ugly and confusing.
186*/
187static
188Bool get_elf_symbol_info (
189 /* INPUTS */
190 struct _SegInfo* si, /* containing SegInfo */
191 ElfXX_Sym* sym, /* ELF symbol */
192 Char* sym_name, /* name */
193 Addr sym_addr, /* declared address */
194 UChar* opd_filea, /* oimage of .opd sec (ppc64-linux only) */
sewardj534e2012006-04-12 10:08:05 +0000195 OffT opd_offset, /* base address assumed in oimage */
sewardjeadcd862006-04-04 15:12:44 +0000196 /* OUTPUTS */
197 Char** sym_name_out, /* name we should record */
198 Addr* sym_addr_out, /* addr we should record */
199 Int* sym_size_out, /* symbol size */
200 Addr* sym_tocptr_out, /* ppc64-linux only: R2 value to be
201 used on entry */
202 Bool* from_opd_out /* ppc64-linux only: did we deref an
203 .opd entry? */
204 )
205{
206 Bool plausible, is_in_opd;
207
208 /* Set defaults */
209 *sym_name_out = sym_name;
210 *sym_addr_out = sym_addr;
211 *sym_size_out = (Int)sym->st_size;
212 *sym_tocptr_out = 0; /* unknown/inapplicable */
213 *from_opd_out = False;
214
215 /* Figure out if we're interested in the symbol. Firstly, is it of
216 the right flavour? */
217 plausible
218 = (ELFXX_ST_BIND(sym->st_info) == STB_GLOBAL
219 || ELFXX_ST_BIND(sym->st_info) == STB_LOCAL
220 || ELFXX_ST_BIND(sym->st_info) == STB_WEAK
221 )
222 &&
223 (ELFXX_ST_TYPE(sym->st_info) == STT_FUNC
224 || (VG_(needs).data_syms
225 && ELFXX_ST_TYPE(sym->st_info) == STT_OBJECT)
226 );
227
228# if defined(VGP_ppc64_linux)
229 /* Allow STT_NOTYPE in the very special case where we're running on
230 ppc64-linux and the symbol is one which the .opd-chasing hack
231 below will chase. */
232 if (!plausible
233 && ELFXX_ST_TYPE(sym->st_info) == STT_NOTYPE
234 && sym->st_size > 0
235 && si->opd_start_vma != 0
236 && sym_addr >= si->opd_start_vma
237 && sym_addr < si->opd_start_vma + si->opd_size)
238 plausible = True;
239# endif
240
241 if (!plausible)
242 return False;
243
244 /* Ignore if nameless, or zero-sized. */
245 if (sym->st_name == (ElfXX_Word)NULL
246 || /* VG_(strlen)(sym_name) == 0 */
247 /* equivalent but cheaper ... */
248 sym_name[0] == 0
249 || sym->st_size == 0) {
250 TRACE_SYMTAB(" ignore -- size=0: %s\n", sym_name);
251 return False;
252 }
253
254 /* This seems to significantly reduce the number of junk
255 symbols, and particularly reduces the number of
256 overlapping address ranges. Don't ask me why ... */
257 if ((Int)sym->st_value == 0) {
258 TRACE_SYMTAB( " ignore -- valu=0: %s\n", sym_name);
259 return False;
260 }
261
262 /* If it's apparently in a GOT or PLT, it's really a reference to a
263 symbol defined elsewhere, so ignore it. */
264 if (si->got_start_vma != 0
265 && sym_addr >= si->got_start_vma
266 && sym_addr < si->got_start_vma + si->got_size) {
267 TRACE_SYMTAB(" ignore -- in GOT: %s\n", sym_name);
268 return False;
269 }
270 if (si->plt_start_vma != 0
271 && sym_addr >= si->plt_start_vma
272 && sym_addr < si->plt_start_vma + si->plt_size) {
273 TRACE_SYMTAB(" ignore -- in PLT: %s\n", sym_name);
274 return False;
275 }
276
277 /* ppc64-linux nasty hack: if the symbol is in an .opd section,
278 then really what we have is the address of a function
279 descriptor. So use the first word of that as the function's
280 text.
281
282 See thread starting at
283 http://gcc.gnu.org/ml/gcc-patches/2004-08/msg00557.html
284 */
285 is_in_opd = False;
286
287 if (si->opd_start_vma != 0
288 && sym_addr >= si->opd_start_vma
289 && sym_addr < si->opd_start_vma + si->opd_size) {
290# if !defined(VGP_ppc64_linux)
291 TRACE_SYMTAB(" ignore -- in OPD: %s\n", sym_name);
292 return False;
293# else
294 Int offset_in_opd;
295 ULong* fn_descr;
296
sewardj534e2012006-04-12 10:08:05 +0000297 if (0) VG_(printf)("opdXXX: opd_offset %p, sym_addr %p\n",
298 (void*)(opd_offset), (void*)sym_addr);
sewardjeadcd862006-04-04 15:12:44 +0000299
300 if (!VG_IS_8_ALIGNED(sym_addr)) {
301 TRACE_SYMTAB(" ignore -- not 8-aligned: %s\n", sym_name);
302 return False;
303 }
304
305 /* sym_addr is a vma pointing into the .opd section. We know
306 the vma of the opd section start, so we can figure out how
307 far into the opd section this is. */
308
309 offset_in_opd = (Addr)sym_addr - (Addr)(si->opd_start_vma);
310 if (offset_in_opd < 0 || offset_in_opd >= si->opd_size) {
311 TRACE_SYMTAB(" ignore -- invalid OPD offset: %s\n", sym_name);
312 return False;
313 }
314
315 /* Now we want to know what's at that offset in the .opd
316 section. We can't look in the running image since it won't
317 necessarily have been mapped. But we can consult the oimage.
318 opd_filea is the start address of the .opd in the oimage.
319 Hence: */
320
321 fn_descr = (ULong*)(opd_filea + offset_in_opd);
322
323 if (0) VG_(printf)("opdXXY: offset %d, fn_descr %p\n",
324 offset_in_opd, fn_descr);
325 if (0) VG_(printf)("opdXXZ: *fn_descr %p\n", (void*)(fn_descr[0]));
326
sewardj534e2012006-04-12 10:08:05 +0000327 /* opd_offset is the difference between si->start (where the
328 library got mapped) and the address space used for addresses
329 within the library file. */
sewardjeadcd862006-04-04 15:12:44 +0000330
sewardj534e2012006-04-12 10:08:05 +0000331 sym_addr = fn_descr[0] + opd_offset;
sewardjeadcd862006-04-04 15:12:44 +0000332 *sym_addr_out = sym_addr;
sewardj534e2012006-04-12 10:08:05 +0000333 *sym_tocptr_out = fn_descr[1] + opd_offset;
sewardjeadcd862006-04-04 15:12:44 +0000334 *from_opd_out = True;
335 is_in_opd = True;
336
337 /* Do a final sanity check: if the symbol falls outside the
338 SegInfo's mapped range, ignore it. Since sym_addr has been
339 updated, that can be achieved simply by falling through to
340 the test below. */
341
342# endif /* ppc64-linux nasty hack */
343 }
344
345 /* Here's yet another ppc64-linux hack. Get rid of leading dot if
346 the symbol is outside .opd. */
347# if defined(VGP_ppc64_linux)
348 if (si->opd_start_vma != 0
349 && !is_in_opd
350 && sym_name[0] == '.') {
351 vg_assert(!(*from_opd_out));
352 *sym_name_out = &sym_name[1];
353 }
354# endif
355
356 /* If no part of the symbol falls within the mapped range,
357 ignore it. */
358 if (*sym_addr_out + *sym_size_out <= si->start
359 || *sym_addr_out >= si->start+si->size) {
sewardj534e2012006-04-12 10:08:05 +0000360 TRACE_SYMTAB( "ignore -- %p .. %p outside mapped range %p .. %p\n",
361 *sym_addr_out, *sym_addr_out + *sym_size_out,
362 si->start, si->start+si->size);
sewardjeadcd862006-04-04 15:12:44 +0000363 return False;
364 }
365
366# if defined(VGP_ppc64_linux)
367 /* It's crucial that we never add symbol addresses in the .opd
368 section. This would completely mess up function redirection and
369 intercepting. This assert ensures that any symbols that make it
370 into the symbol table on ppc64-linux don't point into .opd. */
371 if (si->opd_start_vma != 0) {
372 vg_assert(*sym_addr_out + *sym_size_out <= si->opd_start_vma
373 || *sym_addr_out >= si->opd_start_vma + si->opd_size);
374 }
375# endif
376
377 /* Acquire! */
378 return True;
379}
380
381
382/* Read an ELF symbol table (normal or dynamic). This one is for the
383 "normal" case ({x86,amd64,ppc32}-linux). */
384static
385__attribute__((unused)) /* not referred to on all targets */
386void read_elf_symtab__normal(
sewardj72c84c92006-04-06 13:31:17 +0000387 struct _SegInfo* si, UChar* tab_name,
sewardj534e2012006-04-12 10:08:05 +0000388 ElfXX_Sym* o_symtab, UInt o_symtab_sz, OffT o_symtab_offset,
sewardjeadcd862006-04-04 15:12:44 +0000389 UChar* o_strtab, UInt o_strtab_sz,
sewardj534e2012006-04-12 10:08:05 +0000390 UChar* opd_filea, OffT opd_offset /* ppc64-linux only */
sewardjeadcd862006-04-04 15:12:44 +0000391 )
392{
393 Int i;
394 Addr sym_addr, sym_addr_really;
395 Char *sym_name, *sym_name_really;
396 Int sym_size;
397 Addr sym_tocptr;
398 Bool from_opd;
399 DiSym risym;
400 ElfXX_Sym *sym;
401
402 if (o_strtab == NULL || o_symtab == NULL) {
403 Char buf[80];
404 vg_assert(VG_(strlen)(tab_name) < 40);
405 VG_(sprintf)(buf, " object doesn't have a %s", tab_name);
406 ML_(symerr)(buf);
407 return;
408 }
409
410 TRACE_SYMTAB("\nReading (ELF, standard) %s (%d entries)\n", tab_name,
411 o_symtab_sz/sizeof(ElfXX_Sym) );
412
413 /* Perhaps should start at i = 1; ELF docs suggest that entry
414 0 always denotes 'unknown symbol'. */
415 for (i = 1; i < (Int)(o_symtab_sz/sizeof(ElfXX_Sym)); i++) {
416 sym = & o_symtab[i];
417 sym_name = (Char*)(o_strtab + sym->st_name);
sewardj534e2012006-04-12 10:08:05 +0000418 sym_addr = o_symtab_offset + sym->st_value;
sewardjeadcd862006-04-04 15:12:44 +0000419
420 if (VG_(clo_trace_symtab))
421 show_raw_elf_symbol(i, sym, sym_name, sym_addr, False);
422
sewardj534e2012006-04-12 10:08:05 +0000423 if (get_elf_symbol_info(si, sym, sym_name, sym_addr,
424 opd_filea, opd_offset,
sewardjeadcd862006-04-04 15:12:44 +0000425 &sym_name_really,
426 &sym_addr_really,
427 &sym_size,
428 &sym_tocptr,
429 &from_opd)) {
430
431 risym.addr = sym_addr_really;
432 risym.size = sym_size;
433 risym.name = ML_(addStr) ( si, sym_name_really, -1 );
434 risym.tocptr = sym_tocptr;
435 vg_assert(risym.name != NULL);
436 vg_assert(risym.tocptr == 0); /* has no role except on ppc64-linux */
437 ML_(addSym) ( si, &risym );
438
439 if (VG_(clo_trace_symtab)) {
440 VG_(printf)(" record [%4d]: "
441 " val %010p, sz %4d %s\n",
442 i, (void*)risym.addr, (Int)risym.size,
443 (HChar*)risym.name
444 );
445 }
446
447 }
448 }
449}
450
451
452/* Read an ELF symbol table (normal or dynamic). This one is for
453 ppc64-linux, which requires special treatment. */
454
455typedef
456 struct {
457 Addr addr;
458 UChar* name;
459 }
460 TempSymKey;
461
462typedef
463 struct {
464 TempSymKey key;
465 Addr tocptr;
466 Int size;
467 Bool from_opd;
468 }
469 TempSym;
470
471static Word cmp_TempSymKey ( TempSymKey* key1, TempSym* elem2 ) {
472 if (key1->addr < elem2->key.addr) return -1;
473 if (key1->addr > elem2->key.addr) return 1;
474 return (Word)VG_(strcmp)(key1->name, elem2->key.name);
475}
476static void* oset_malloc ( SizeT szB ) {
477 return VG_(arena_malloc)(VG_AR_SYMTAB, szB);
478}
479static void oset_free ( void* p ) {
480 VG_(arena_free)(VG_AR_SYMTAB, p);
481}
482
483static
484__attribute__((unused)) /* not referred to on all targets */
485void read_elf_symtab__ppc64_linux(
486 struct _SegInfo* si, UChar* tab_name,
sewardj534e2012006-04-12 10:08:05 +0000487 ElfXX_Sym* o_symtab, UInt o_symtab_sz, OffT o_symtab_offset,
sewardjeadcd862006-04-04 15:12:44 +0000488 UChar* o_strtab, UInt o_strtab_sz,
sewardj534e2012006-04-12 10:08:05 +0000489 UChar* opd_filea, OffT opd_offset /* ppc64-linux only */
sewardjeadcd862006-04-04 15:12:44 +0000490 )
491{
492 Int i, old_size;
493 Addr sym_addr, sym_addr_really;
494 Char *sym_name, *sym_name_really;
495 Int sym_size;
496 Addr sym_tocptr, old_tocptr;
497 Bool from_opd, modify_size, modify_tocptr;
498 DiSym risym;
499 ElfXX_Sym *sym;
500 OSet *oset;
501 TempSymKey key;
502 TempSym *elem;
503 TempSym *prev;
504
505 if (o_strtab == NULL || o_symtab == NULL) {
506 Char buf[80];
507 vg_assert(VG_(strlen)(tab_name) < 40);
508 VG_(sprintf)(buf, " object doesn't have a %s", tab_name);
509 ML_(symerr)(buf);
510 return;
511 }
512
513 TRACE_SYMTAB("\nReading (ELF, ppc64-linux) %s (%d entries)\n", tab_name,
514 o_symtab_sz/sizeof(ElfXX_Sym) );
515
516 oset = VG_(OSet_Create)( offsetof(TempSym,key),
517 (OSetCmp_t)cmp_TempSymKey,
518 oset_malloc, oset_free );
519 vg_assert(oset);
520
521 /* Perhaps should start at i = 1; ELF docs suggest that entry
522 0 always denotes 'unknown symbol'. */
523 for (i = 1; i < (Int)(o_symtab_sz/sizeof(ElfXX_Sym)); i++) {
524 sym = & o_symtab[i];
525 sym_name = (Char*)(o_strtab + sym->st_name);
sewardj534e2012006-04-12 10:08:05 +0000526 sym_addr = o_symtab_offset + sym->st_value;
sewardjeadcd862006-04-04 15:12:44 +0000527
528 if (VG_(clo_trace_symtab))
529 show_raw_elf_symbol(i, sym, sym_name, sym_addr, True);
530
sewardj534e2012006-04-12 10:08:05 +0000531 if (get_elf_symbol_info(si, sym, sym_name, sym_addr,
532 opd_filea, opd_offset,
sewardjeadcd862006-04-04 15:12:44 +0000533 &sym_name_really,
534 &sym_addr_really,
535 &sym_size,
536 &sym_tocptr,
537 &from_opd)) {
538
539 /* Check if we've seen this (name,addr) key before. */
540 key.addr = sym_addr_really;
541 key.name = sym_name_really;
542 prev = VG_(OSet_Lookup)( oset, &key );
543
544 if (prev) {
545
546 /* Seen it before. Fold in whatever new info we can. */
547 modify_size = False;
548 modify_tocptr = False;
549 old_size = 0;
550 old_tocptr = 0;
551
552 if (prev->from_opd && !from_opd
553 && (prev->size == 24 || prev->size == 16)
554 && sym_size != prev->size) {
555 /* Existing one is an opd-redirect, with a bogus size,
556 so the only useful new fact we have is the real size
557 of the symbol. */
558 modify_size = True;
559 old_size = prev->size;
560 prev->size = sym_size;
561 }
562 else
563 if (!prev->from_opd && from_opd
564 && (sym_size == 24 || sym_size == 16)) {
565 /* Existing one is non-opd, new one is opd. What we
566 can acquire from the new one is the TOC ptr to be
567 used. Since the existing sym is non-toc, it
568 shouldn't currently have an known TOC ptr. */
569 vg_assert(prev->tocptr == 0);
570 modify_tocptr = True;
571 old_tocptr = prev->tocptr;
572 prev->tocptr = sym_tocptr;
573 }
574 else {
575 /* ignore. can we do better here? */
576 }
577
578 /* Only one or the other is possible (I think) */
579 vg_assert(!(modify_size && modify_tocptr));
580
581 if (modify_size && VG_(clo_trace_symtab)) {
582 VG_(printf)(" modify (old sz %4d) "
583 " val %010p, toc %010p, sz %4d %s\n",
584 old_size,
585 (void*) prev->key.addr,
586 (void*) prev->tocptr,
587 (Int) prev->size,
588 (HChar*)prev->key.name
589 );
590 }
591 if (modify_tocptr && VG_(clo_trace_symtab)) {
592 VG_(printf)(" modify (upd tocptr) "
593 " val %010p, toc %010p, sz %4d %s\n",
594 (void*) prev->key.addr,
595 (void*) prev->tocptr,
596 (Int) prev->size,
597 (HChar*)prev->key.name
598 );
599 }
600
601 } else {
602
603 /* A new (name,addr) key. Add and continue. */
604 elem = VG_(OSet_AllocNode)(oset, sizeof(TempSym));
605 vg_assert(elem);
606 elem->key = key;
607 elem->tocptr = sym_tocptr;
608 elem->size = sym_size;
609 elem->from_opd = from_opd;
610 VG_(OSet_Insert)(oset, elem);
611 if (VG_(clo_trace_symtab)) {
612 VG_(printf)(" to-oset [%4d]: "
613 " val %010p, toc %010p, sz %4d %s\n",
614 i, (void*) elem->key.addr,
615 (void*) elem->tocptr,
616 (Int) elem->size,
617 (HChar*)elem->key.name
618 );
619 }
620
621 }
622 }
623 }
624
625 /* All the syms that matter are in the oset. Now pull them out,
626 build a "standard" symbol table, and nuke the oset. */
627
628 i = 0;
629 VG_(OSet_ResetIter)( oset );
630
631 while ( (elem = VG_(OSet_Next)(oset)) ) {
632 risym.addr = elem->key.addr;
633 risym.size = elem->size;
634 risym.name = ML_(addStr) ( si, elem->key.name, -1 );
635 risym.tocptr = elem->tocptr;
636 vg_assert(risym.name != NULL);
637
638 ML_(addSym) ( si, &risym );
639 if (VG_(clo_trace_symtab)) {
640 VG_(printf)(" record [%4d]: "
641 " val %010p, toc %010p, sz %4d %s\n",
642 i, (void*) risym.addr,
643 (void*) risym.tocptr,
644 (Int) risym.size,
645 (HChar*)risym.name
646 );
647 }
648 i++;
649 }
650
651 VG_(OSet_Destroy)( oset, NULL );
652}
653
654
655/*
656 * This routine for calculating the CRC for a separate debug file
657 * is GPLed code borrowed from GNU binutils.
658 */
659static UInt
660calc_gnu_debuglink_crc32(UInt crc, const UChar *buf, Int len)
661{
662 static const UInt crc32_table[256] =
663 {
664 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
665 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
666 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
667 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
668 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
669 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
670 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
671 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
672 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
673 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
674 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
675 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
676 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
677 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
678 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
679 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
680 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
681 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
682 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
683 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
684 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
685 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
686 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
687 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
688 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
689 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
690 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
691 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
692 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
693 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
694 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
695 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
696 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
697 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
698 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
699 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
700 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
701 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
702 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
703 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
704 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
705 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
706 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
707 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
708 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
709 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
710 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
711 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
712 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
713 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
714 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
715 0x2d02ef8d
716 };
717 const UChar *end;
718
719 crc = ~crc & 0xffffffff;
720 for (end = buf + len; buf < end; ++ buf)
721 crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
722 return ~crc & 0xffffffff;;
723}
724
725/*
726 * Try and open a separate debug file, ignoring any where the CRC does
727 * not match the value from the main object file.
728 */
729static
730Addr open_debug_file( Char* name, UInt crc, UInt* size )
731{
732 SysRes fd, sres;
733 struct vki_stat stat_buf;
734 UInt calccrc;
735
736 fd = VG_(open)(name, VKI_O_RDONLY, 0);
737 if (fd.isError)
738 return 0;
739
740 if (VG_(fstat)(fd.val, &stat_buf) != 0) {
741 VG_(close)(fd.val);
742 return 0;
743 }
744
745 if (VG_(clo_verbosity) > 1)
746 VG_(message)(Vg_DebugMsg, "Reading debug info from %s...", name);
747
748 *size = stat_buf.st_size;
749
750 sres = VG_(am_mmap_file_float_valgrind)
751 ( *size, VKI_PROT_READ, fd.val, 0 );
752
753 VG_(close)(fd.val);
754
755 if (sres.isError)
756 return 0;
757
758 calccrc = calc_gnu_debuglink_crc32(0, (UChar*)sres.val, *size);
759 if (calccrc != crc) {
760 SysRes res = VG_(am_munmap_valgrind)(sres.val, *size);
761 vg_assert(!res.isError);
762 if (VG_(clo_verbosity) > 1)
763 VG_(message)(Vg_DebugMsg, "... CRC mismatch (computed %08x wanted %08x)", calccrc, crc);
764 return 0;
765 }
766
767 return sres.val;
768}
769
770/*
771 * Try to find a separate debug file for a given object file.
772 */
773static
774Addr find_debug_file( Char* objpath, Char* debugname, UInt crc, UInt* size )
775{
776 Char *objdir = VG_(arena_strdup)(VG_AR_SYMTAB, objpath);
777 Char *objdirptr;
778 Char *debugpath;
779 Addr addr = 0;
780
781 if ((objdirptr = VG_(strrchr)(objdir, '/')) != NULL)
782 *objdirptr = '\0';
783
784 debugpath = VG_(arena_malloc)(VG_AR_SYMTAB, VG_(strlen)(objdir) + VG_(strlen)(debugname) + 16);
785
786 VG_(sprintf)(debugpath, "%s/%s", objdir, debugname);
787
788 if ((addr = open_debug_file(debugpath, crc, size)) == 0) {
789 VG_(sprintf)(debugpath, "%s/.debug/%s", objdir, debugname);
790 if ((addr = open_debug_file(debugpath, crc, size)) == 0) {
791 VG_(sprintf)(debugpath, "/usr/lib/debug%s/%s", objdir, debugname);
792 addr = open_debug_file(debugpath, crc, size);
793 }
794 }
795
796 VG_(arena_free)(VG_AR_SYMTAB, debugpath);
797 VG_(arena_free)(VG_AR_SYMTAB, objdir);
798
799 return addr;
800}
801
802
803/* The central function for reading ELF debug info. For the
804 object/exe specified by the SegInfo, find ELF sections, then read
805 the symbols, line number info, file name info, CFA (stack-unwind
806 info) and anything else we want, into the tables within the
807 supplied SegInfo.
808*/
809Bool ML_(read_elf_debug_info) ( struct _SegInfo* si )
810{
811 Bool res;
812 ElfXX_Ehdr* ehdr; /* The ELF header */
813 ElfXX_Shdr* shdr; /* The section table */
814 UChar* sh_strtab; /* The section table's string table */
815 SysRes fd, sres;
816 Int i;
817 Bool ok;
818 Addr oimage;
819 UInt n_oimage;
sewardj534e2012006-04-12 10:08:05 +0000820 OffT offset_oimage = 0;
sewardjeadcd862006-04-04 15:12:44 +0000821 Addr dimage = 0;
822 UInt n_dimage = 0;
sewardj534e2012006-04-12 10:08:05 +0000823 OffT offset_dimage = 0;
sewardjeadcd862006-04-04 15:12:44 +0000824
825 oimage = (Addr)NULL;
826 if (VG_(clo_verbosity) > 1 || VG_(clo_trace_redir))
827 VG_(message)(Vg_DebugMsg, "Reading syms from %s (%p)",
828 si->filename, si->start );
829
830 /* mmap the object image aboard, so that we can read symbols and
831 line number info out of it. It will be munmapped immediately
832 thereafter; it is only aboard transiently. */
833
sewardjeadcd862006-04-04 15:12:44 +0000834 fd = VG_(open)(si->filename, VKI_O_RDONLY, 0);
835 if (fd.isError) {
836 ML_(symerr)("Can't open .so/.exe to read symbols?!");
837 return False;
838 }
839
tom574b8932006-07-05 17:47:46 +0000840 n_oimage = VG_(fsize)(fd.val);
841 if (n_oimage < 0) {
842 ML_(symerr)("Can't stat .so/.exe (to determine its size)?!");
843 VG_(close)(fd.val);
844 return False;
845 }
846
sewardjeadcd862006-04-04 15:12:44 +0000847 sres = VG_(am_mmap_file_float_valgrind)
848 ( n_oimage, VKI_PROT_READ, fd.val, 0 );
849
850 VG_(close)(fd.val);
851
852 if (sres.isError) {
853 VG_(message)(Vg_UserMsg, "warning: mmap failed on %s", si->filename );
854 VG_(message)(Vg_UserMsg, " no symbols or debug info loaded" );
855 return False;
856 }
857
858 oimage = sres.val;
859
860 /* Ok, the object image is safely in oimage[0 .. n_oimage-1].
861 Now verify that it is a valid ELF .so or executable image.
862 */
863 res = False;
864 ok = (n_oimage >= sizeof(ElfXX_Ehdr));
865 ehdr = (ElfXX_Ehdr*)oimage;
866
867 if (ok)
868 ok &= ML_(is_elf_object_file)(ehdr);
869
870 if (!ok) {
871 ML_(symerr)("Invalid ELF header, or missing stringtab/sectiontab.");
872 goto out;
873 }
874
875 /* Walk the LOAD headers in the phdr and update the SegInfo to
876 include them all, so that this segment also contains data and
877 bss memory. Also computes correct symbol offset value for this
878 ELF file. */
879 if (ehdr->e_phoff + ehdr->e_phnum*sizeof(ElfXX_Phdr) > n_oimage) {
880 ML_(symerr)("ELF program header is beyond image end?!");
881 goto out;
882 }
883 {
884 Bool offset_set = False;
885 ElfXX_Addr prev_addr = 0;
886 Addr baseaddr = 0;
887
sewardjeadcd862006-04-04 15:12:44 +0000888 vg_assert(si->soname == NULL);
889
890 for (i = 0; i < ehdr->e_phnum; i++) {
891 ElfXX_Phdr *o_phdr;
892 ElfXX_Addr mapped, mapped_end;
893
894 o_phdr = &((ElfXX_Phdr *)(oimage + ehdr->e_phoff))[i];
895
896 /* Try to get the soname. If there isn't one, use "NONE".
897 The seginfo needs to have some kind of soname in order to
898 facilitate writing redirect functions, since all redirect
899 specifications require a soname (pattern). */
900 if (o_phdr->p_type == PT_DYNAMIC && si->soname == NULL) {
901 const ElfXX_Dyn *dyn = (const ElfXX_Dyn *)(oimage + o_phdr->p_offset);
902 Int stroff = -1;
903 Char *strtab = NULL;
904 Int j;
905
906 for(j = 0; dyn[j].d_tag != DT_NULL; j++) {
907 switch(dyn[j].d_tag) {
908 case DT_SONAME:
909 stroff = dyn[j].d_un.d_val;
910 break;
911
912 case DT_STRTAB:
913 strtab = (Char *)oimage + dyn[j].d_un.d_ptr - baseaddr;
914 break;
915 }
916 }
917
918 if (stroff != -1 && strtab != 0) {
919 TRACE_SYMTAB("soname=%s\n", strtab+stroff);
920 si->soname = VG_(arena_strdup)(VG_AR_SYMTAB, strtab+stroff);
921 }
922 }
923
924 if (o_phdr->p_type != PT_LOAD)
925 continue;
926
927 if (!offset_set) {
928 offset_set = True;
sewardj534e2012006-04-12 10:08:05 +0000929 offset_oimage = si->start - o_phdr->p_vaddr;
sewardjeadcd862006-04-04 15:12:44 +0000930 baseaddr = o_phdr->p_vaddr;
931 }
932
933 // Make sure the Phdrs are in order
934 if (o_phdr->p_vaddr < prev_addr) {
935 ML_(symerr)("ELF Phdrs are out of order!?");
936 goto out;
937 }
938 prev_addr = o_phdr->p_vaddr;
939
940 // Get the data and bss start/size if appropriate
sewardj534e2012006-04-12 10:08:05 +0000941 mapped = o_phdr->p_vaddr + offset_oimage;
sewardjeadcd862006-04-04 15:12:44 +0000942 mapped_end = mapped + o_phdr->p_memsz;
943 if (si->data_start_vma == 0 &&
944 (o_phdr->p_flags & (PF_R|PF_W|PF_X)) == (PF_R|PF_W)) {
945 si->data_start_vma = mapped;
946 si->data_size = o_phdr->p_filesz;
947 si->bss_start_vma = mapped + o_phdr->p_filesz;
948 if (o_phdr->p_memsz > o_phdr->p_filesz)
949 si->bss_size = o_phdr->p_memsz - o_phdr->p_filesz;
950 else
951 si->bss_size = 0;
952 }
953
954 mapped = mapped & ~(VKI_PAGE_SIZE-1);
955 mapped_end = (mapped_end + VKI_PAGE_SIZE - 1) & ~(VKI_PAGE_SIZE-1);
956
957 if (VG_(needs).data_syms &&
958 (mapped >= si->start && mapped <= (si->start+si->size)) &&
959 (mapped_end > (si->start+si->size))) {
960 UInt newsz = mapped_end - si->start;
961 if (newsz > si->size) {
962 if (0)
963 VG_(printf)("extending mapping %p..%p %d -> ..%p %d\n",
964 si->start, si->start+si->size, si->size,
965 si->start+newsz, newsz);
966
967 si->size = newsz;
968 }
969 }
970 }
971 }
972
sewardj534e2012006-04-12 10:08:05 +0000973 si->offset = offset_oimage;
974
sewardjeadcd862006-04-04 15:12:44 +0000975 /* If, after looking at all the program headers, we still didn't
976 find a soname, add a fake one. */
977 if (si->soname == NULL) {
978 TRACE_SYMTAB("soname(fake)=\"NONE\"\n");
979 si->soname = "NONE";
980 }
981
982 TRACE_SYMTAB("shoff = %d, shnum = %d, size = %d, n_vg_oimage = %d\n",
983 ehdr->e_shoff, ehdr->e_shnum, sizeof(ElfXX_Shdr), n_oimage );
984
985 if (ehdr->e_shoff + ehdr->e_shnum*sizeof(ElfXX_Shdr) > n_oimage) {
986 ML_(symerr)("ELF section header is beyond image end?!");
987 goto out;
988 }
989
990 shdr = (ElfXX_Shdr*)(oimage + ehdr->e_shoff);
991 sh_strtab = (UChar*)(oimage + shdr[ehdr->e_shstrndx].sh_offset);
992
993 /* Find interesting sections, read the symbol table(s), read any debug
994 information */
995 {
996 /* Pointers to start of sections (in the oimage, not in the
997 running image) */
998 UChar* o_strtab = NULL; /* .strtab */
999 ElfXX_Sym* o_symtab = NULL; /* .symtab */
1000 UChar* o_dynstr = NULL; /* .dynstr */
1001 ElfXX_Sym* o_dynsym = NULL; /* .dynsym */
1002 Char* debuglink = NULL; /* .gnu_debuglink */
1003 UChar* stab = NULL; /* .stab (stabs) */
1004 UChar* stabstr = NULL; /* .stabstr (stabs) */
1005 UChar* debug_line = NULL; /* .debug_line (dwarf2) */
1006 UChar* debug_info = NULL; /* .debug_info (dwarf2) */
1007 UChar* debug_abbv = NULL; /* .debug_abbrev (dwarf2) */
1008 UChar* debug_str = NULL; /* .debug_str (dwarf2) */
1009 UChar* dwarf1d = NULL; /* .debug (dwarf1) */
1010 UChar* dwarf1l = NULL; /* .line (dwarf1) */
1011 UChar* ehframe = NULL; /* .eh_frame (dwarf2) */
1012 UChar* opd_filea = NULL; /* .opd (dwarf2, ppc64-linux) */
1013 UChar* dummy_filea = NULL;
1014
sewardj534e2012006-04-12 10:08:05 +00001015 OffT o_symtab_offset = offset_oimage;
1016 OffT o_dynsym_offset = offset_oimage;
1017 OffT debug_offset = offset_oimage;
1018 OffT opd_offset = offset_oimage;
1019
sewardjeadcd862006-04-04 15:12:44 +00001020 /* Section sizes, in bytes */
1021 UInt o_strtab_sz = 0;
1022 UInt o_symtab_sz = 0;
1023 UInt o_dynstr_sz = 0;
1024 UInt o_dynsym_sz = 0;
1025 UInt debuglink_sz = 0;
1026 UInt stab_sz = 0;
1027 UInt stabstr_sz = 0;
1028 UInt debug_line_sz = 0;
1029 UInt debug_info_sz = 0;
1030 UInt debug_abbv_sz = 0;
1031 UInt debug_str_sz = 0;
1032 UInt dwarf1d_sz = 0;
1033 UInt dwarf1l_sz = 0;
1034 UInt ehframe_sz = 0;
1035
1036 /* Section virtual addresses */
1037 Addr dummy_vma = 0;
1038 Addr ehframe_vma = 0;
1039
1040 /* Find all interesting sections */
1041
1042 /* What FIND does: it finds the section called SEC_NAME. The
1043 size of it is assigned to SEC_SIZE. The address that it will
1044 appear in the running image is assigned to SEC_VMA (note,
1045 this will be meaningless for sections which are not marked
1046 loadable. Even for sections which are marked loadable, the
1047 client's ld.so may not have loaded them yet, so there is no
1048 guarantee that we can safely prod around in any such area)
1049 The address of the section in the transiently loaded oimage
1050 is assigned to SEC_FILEA. Because the entire object file is
1051 transiently mapped aboard for inspection, it's always safe to
1052 inspect that area. */
1053
1054 for (i = 0; i < ehdr->e_shnum; i++) {
1055
1056# define FIND(sec_name, sec_size, sec_filea, sec_vma) \
1057 if (0 == VG_(strcmp)(sec_name, sh_strtab + shdr[i].sh_name)) { \
1058 Bool nobits; \
sewardj534e2012006-04-12 10:08:05 +00001059 sec_vma = (Addr)(offset_oimage + shdr[i].sh_addr); \
sewardjeadcd862006-04-04 15:12:44 +00001060 sec_filea = (void*)(oimage + shdr[i].sh_offset); \
1061 sec_size = shdr[i].sh_size; \
1062 nobits = shdr[i].sh_type == SHT_NOBITS; \
1063 TRACE_SYMTAB( "%18s: filea %p .. %p, vma %p .. %p\n", \
1064 sec_name, (UChar*)sec_filea, \
1065 ((UChar*)sec_filea) + sec_size - 1, \
1066 sec_vma, sec_vma + sec_size - 1); \
1067 /* SHT_NOBITS sections have zero size in the file. */ \
1068 if ( shdr[i].sh_offset + (nobits ? 0 : sec_size) > n_oimage ) { \
1069 ML_(symerr)(" section beyond image end?!"); \
1070 goto out; \
1071 } \
1072 }
1073
1074 /* Nb: must find where .got and .plt sections will be in the
1075 * executable image, not in the object image transiently loaded. */
1076 /* NAME SIZE ADDR_IN_OIMAGE ADDR_WHEN_MAPPED */
1077 FIND(".dynsym", o_dynsym_sz, o_dynsym, dummy_vma)
1078 FIND(".dynstr", o_dynstr_sz, o_dynstr, dummy_vma)
1079 FIND(".symtab", o_symtab_sz, o_symtab, dummy_vma)
1080 FIND(".strtab", o_strtab_sz, o_strtab, dummy_vma)
1081
1082 FIND(".gnu_debuglink", debuglink_sz, debuglink, dummy_vma)
1083
1084 FIND(".stab", stab_sz, stab, dummy_vma)
1085 FIND(".stabstr", stabstr_sz, stabstr, dummy_vma)
1086
1087 FIND(".debug_line", debug_line_sz, debug_line, dummy_vma)
1088 FIND(".debug_info", debug_info_sz, debug_info, dummy_vma)
1089 FIND(".debug_abbrev", debug_abbv_sz, debug_abbv, dummy_vma)
1090 FIND(".debug_str", debug_str_sz, debug_str, dummy_vma)
1091
1092 FIND(".debug", dwarf1d_sz, dwarf1d, dummy_vma)
1093 FIND(".line", dwarf1l_sz, dwarf1l, dummy_vma)
1094 FIND(".eh_frame", ehframe_sz, ehframe, ehframe_vma)
1095
1096 FIND(".got", si->got_size, dummy_filea, si->got_start_vma)
1097 FIND(".plt", si->plt_size, dummy_filea, si->plt_start_vma)
1098 FIND(".opd", si->opd_size, opd_filea, si->opd_start_vma)
1099
1100# undef FIND
1101 }
1102
sewardjeadcd862006-04-04 15:12:44 +00001103 /* Did we find a debuglink section? */
1104 if (debuglink != NULL) {
1105 UInt crc_offset = VG_ROUNDUP(VG_(strlen)(debuglink)+1, 4);
1106 UInt crc;
1107
1108 vg_assert(crc_offset + sizeof(UInt) <= debuglink_sz);
1109
1110 /* Extract the CRC from the debuglink section */
1111 crc = *(UInt *)(debuglink + crc_offset);
1112
1113 /* See if we can find a matching debug file */
1114 if ((dimage = find_debug_file(si->filename, debuglink, crc, &n_dimage)) != 0) {
1115 ehdr = (ElfXX_Ehdr*)dimage;
1116
1117 if (n_dimage >= sizeof(ElfXX_Ehdr)
sewardj534e2012006-04-12 10:08:05 +00001118 && ML_(is_elf_object_file(ehdr))
1119 && ehdr->e_phoff + ehdr->e_phnum*sizeof(ElfXX_Phdr) <= n_dimage
1120 && ehdr->e_shoff + ehdr->e_shnum*sizeof(ElfXX_Shdr) <= n_dimage)
1121 {
1122 Bool need_symtab = (NULL == o_symtab);
1123
1124 for (i = 0; i < ehdr->e_phnum; i++) {
1125 ElfXX_Phdr *o_phdr = &((ElfXX_Phdr *)(dimage + ehdr->e_phoff))[i];
1126 if (o_phdr->p_type == PT_LOAD) {
1127 offset_dimage = si->start - o_phdr->p_vaddr;
1128 break;
1129 }
1130 }
1131
1132 debug_offset = offset_dimage;
1133 if (need_symtab)
1134 o_symtab_offset = offset_dimage;
1135
sewardjeadcd862006-04-04 15:12:44 +00001136 shdr = (ElfXX_Shdr*)(dimage + ehdr->e_shoff);
1137 sh_strtab = (UChar*)(dimage + shdr[ehdr->e_shstrndx].sh_offset);
1138
1139 /* Same deal as previous FIND, except simpler - doesn't
1140 look for vma, only oimage address. */
1141
1142 /* Find all interesting sections */
1143 for (i = 0; i < ehdr->e_shnum; i++) {
1144
sewardj534e2012006-04-12 10:08:05 +00001145# define FIND(condition, sec_name, sec_size, sec_filea) \
1146 if (condition \
1147 && 0 == VG_(strcmp)(sec_name, sh_strtab + shdr[i].sh_name)) { \
sewardjeadcd862006-04-04 15:12:44 +00001148 Bool nobits; \
1149 if (0 != sec_filea) \
1150 VG_(core_panic)("repeated section!\n"); \
1151 sec_filea = (void*)(dimage + shdr[i].sh_offset); \
1152 sec_size = shdr[i].sh_size; \
1153 nobits = shdr[i].sh_type == SHT_NOBITS; \
1154 TRACE_SYMTAB( "%18s: filea %p .. %p\n", \
1155 sec_name, (UChar*)sec_filea, \
1156 ((UChar*)sec_filea) + sec_size - 1); \
1157 /* SHT_NOBITS sections have zero size in the file. */ \
1158 if ( shdr[i].sh_offset + (nobits ? 0 : sec_size) > n_dimage ) { \
1159 ML_(symerr)(" section beyond image end?!"); \
1160 goto out; \
1161 } \
1162 }
1163
sewardj534e2012006-04-12 10:08:05 +00001164 FIND(need_symtab, ".symtab", o_symtab_sz, o_symtab)
1165 FIND(need_symtab, ".strtab", o_strtab_sz, o_strtab)
1166 FIND(1, ".stab", stab_sz, stab)
1167 FIND(1, ".stabstr", stabstr_sz, stabstr)
1168 FIND(1, ".debug_line", debug_line_sz, debug_line)
1169 FIND(1, ".debug_info", debug_info_sz, debug_info)
1170 FIND(1, ".debug_abbrev", debug_abbv_sz, debug_abbv)
1171 FIND(1, ".debug_str", debug_str_sz, debug_str)
1172 FIND(1, ".debug", dwarf1d_sz, dwarf1d)
1173 FIND(1, ".line", dwarf1l_sz, dwarf1l)
sewardjeadcd862006-04-04 15:12:44 +00001174
1175# undef FIND
1176 }
1177 }
1178 }
1179 }
1180
sewardj534e2012006-04-12 10:08:05 +00001181 /* Check some sizes */
1182 vg_assert((o_dynsym_sz % sizeof(ElfXX_Sym)) == 0);
1183 vg_assert((o_symtab_sz % sizeof(ElfXX_Sym)) == 0);
1184
sewardjeadcd862006-04-04 15:12:44 +00001185 /* Read symbols */
1186 {
sewardj72c84c92006-04-06 13:31:17 +00001187 void (*read_elf_symtab)(struct _SegInfo*,UChar*,ElfXX_Sym*,
sewardj534e2012006-04-12 10:08:05 +00001188 UInt,OffT,UChar*,UInt,UChar*,OffT);
sewardjeadcd862006-04-04 15:12:44 +00001189# if defined(VGP_ppc64_linux)
1190 read_elf_symtab = read_elf_symtab__ppc64_linux;
1191# else
1192 read_elf_symtab = read_elf_symtab__normal;
1193# endif
1194 read_elf_symtab(si, "symbol table",
sewardj534e2012006-04-12 10:08:05 +00001195 o_symtab, o_symtab_sz, o_symtab_offset,
1196 o_strtab, o_strtab_sz, opd_filea, opd_offset);
sewardjeadcd862006-04-04 15:12:44 +00001197
1198 read_elf_symtab(si, "dynamic symbol table",
sewardj534e2012006-04-12 10:08:05 +00001199 o_dynsym, o_dynsym_sz, o_dynsym_offset,
1200 o_dynstr, o_dynstr_sz, opd_filea, opd_offset);
sewardjeadcd862006-04-04 15:12:44 +00001201 }
1202
1203 /* Read .eh_frame (call-frame-info) if any */
1204 if (ehframe) {
1205 ML_(read_callframe_info_dwarf2) ( si, ehframe, ehframe_sz, ehframe_vma );
1206 }
1207
1208 /* Read the stabs and/or dwarf2 debug information, if any. It
1209 appears reading stabs stuff on amd64-linux doesn't work, so
1210 we ignore it. */
1211# if !defined(VGP_amd64_linux)
1212 if (stab && stabstr) {
sewardj534e2012006-04-12 10:08:05 +00001213 ML_(read_debuginfo_stabs) ( si, debug_offset, stab, stab_sz,
sewardjeadcd862006-04-04 15:12:44 +00001214 stabstr, stabstr_sz );
1215 }
1216# endif
1217 /* jrs 2006-01-01: icc-8.1 has been observed to generate
1218 binaries without debug_str sections. Don't preclude
1219 debuginfo reading for that reason, but, in
1220 read_unitinfo_dwarf2, do check that debugstr is non-NULL
1221 before using it. */
1222 if (debug_info && debug_abbv && debug_line /* && debug_str */) {
sewardj534e2012006-04-12 10:08:05 +00001223 ML_(read_debuginfo_dwarf2) ( si, debug_offset,
sewardjeadcd862006-04-04 15:12:44 +00001224 debug_info, debug_info_sz,
1225 debug_abbv,
1226 debug_line, debug_line_sz,
1227 debug_str );
1228 }
1229 if (dwarf1d && dwarf1l) {
1230 ML_(read_debuginfo_dwarf1) ( si, dwarf1d, dwarf1d_sz,
1231 dwarf1l, dwarf1l_sz );
1232 }
1233 }
1234 res = True;
1235
1236 out: {
1237 SysRes m_res;
1238 /* Last, but not least, heave the image(s) back overboard. */
1239 if (dimage) {
1240 m_res = VG_(am_munmap_valgrind) ( dimage, n_dimage );
1241 vg_assert(!m_res.isError);
1242 }
1243 m_res = VG_(am_munmap_valgrind) ( oimage, n_oimage );
1244 vg_assert(!m_res.isError);
1245 return res;
1246 }
1247}
1248
1249
1250/*--------------------------------------------------------------------*/
1251/*--- end ---*/
1252/*--------------------------------------------------------------------*/