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