readelf.c revision 4ee4f98c6dd3dd9517954efc628753bf46811d2d
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-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_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_vma != 0
237       && sym_addr >= si->opd_start_vma
238       && sym_addr <  si->opd_start_vma + 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_vma != 0
266       && sym_addr >= si->got_start_vma
267       && sym_addr <  si->got_start_vma + si->got_size) {
268      TRACE_SYMTAB("    ignore -- in GOT: %s\n", sym_name);
269      return False;
270   }
271   if (si->plt_start_vma != 0
272       && sym_addr >= si->plt_start_vma
273       && sym_addr <  si->plt_start_vma + 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_vma != 0
289       && sym_addr >= si->opd_start_vma
290       && sym_addr <  si->opd_start_vma + 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_vma);
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_vma != 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->start
360       || *sym_addr_out >= si->start+si->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->start, si->start+si->size);
364      return False;
365   }
366
367#  if defined(VGP_ppc64_linux)
368   /* It's crucial that we never add symbol addresses in the .opd
369      section.  This would completely mess up function redirection and
370      intercepting.  This assert ensures that any symbols that make it
371      into the symbol table on ppc64-linux don't point into .opd. */
372   if (si->opd_start_vma != 0) {
373      vg_assert(*sym_addr_out + *sym_size_out <= si->opd_start_vma
374                || *sym_addr_out >= si->opd_start_vma + si->opd_size);
375   }
376#  endif
377
378   /* Acquire! */
379   return True;
380}
381
382
383/* Read an ELF symbol table (normal or dynamic).  This one is for the
384   "normal" case ({x86,amd64,ppc32}-linux). */
385static
386__attribute__((unused)) /* not referred to on all targets */
387void read_elf_symtab__normal(
388        struct _SegInfo* si, UChar* tab_name,
389        ElfXX_Sym* o_symtab, UInt o_symtab_sz, OffT o_symtab_offset,
390        UChar*     o_strtab, UInt o_strtab_sz,
391        UChar*     opd_filea, OffT opd_offset /* ppc64-linux only */
392     )
393{
394   Int        i;
395   Addr       sym_addr, sym_addr_really;
396   Char      *sym_name, *sym_name_really;
397   Int        sym_size;
398   Addr       sym_tocptr;
399   Bool       from_opd;
400   DiSym      risym;
401   ElfXX_Sym *sym;
402
403   if (o_strtab == NULL || o_symtab == NULL) {
404      Char buf[80];
405      vg_assert(VG_(strlen)(tab_name) < 40);
406      VG_(sprintf)(buf, "   object doesn't have a %s", tab_name);
407      ML_(symerr)(buf);
408      return;
409   }
410
411   TRACE_SYMTAB("\nReading (ELF, standard) %s (%d entries)\n", tab_name,
412                o_symtab_sz/sizeof(ElfXX_Sym) );
413
414   /* Perhaps should start at i = 1; ELF docs suggest that entry
415      0 always denotes 'unknown symbol'. */
416   for (i = 1; i < (Int)(o_symtab_sz/sizeof(ElfXX_Sym)); i++) {
417      sym      = & o_symtab[i];
418      sym_name = (Char*)(o_strtab + sym->st_name);
419      sym_addr = o_symtab_offset + sym->st_value;
420
421      if (VG_(clo_trace_symtab))
422         show_raw_elf_symbol(i, sym, sym_name, sym_addr, False);
423
424      if (get_elf_symbol_info(si, sym, sym_name, sym_addr,
425                              opd_filea, opd_offset,
426                              &sym_name_really,
427                              &sym_addr_really,
428                              &sym_size,
429                              &sym_tocptr,
430                              &from_opd)) {
431
432         risym.addr   = sym_addr_really;
433         risym.size   = sym_size;
434         risym.name   = ML_(addStr) ( si, sym_name_really, -1 );
435         risym.tocptr = sym_tocptr;
436         vg_assert(risym.name != NULL);
437         vg_assert(risym.tocptr == 0); /* has no role except on ppc64-linux */
438         ML_(addSym) ( si, &risym );
439
440         if (VG_(clo_trace_symtab)) {
441            VG_(printf)("    record [%4d]:          "
442                        " val %010p, sz %4d  %s\n",
443                        i, (void*)risym.addr, (Int)risym.size,
444                           (HChar*)risym.name
445            );
446         }
447
448      }
449   }
450}
451
452
453/* Read an ELF symbol table (normal or dynamic).  This one is for
454   ppc64-linux, which requires special treatment. */
455
456typedef
457   struct {
458      Addr   addr;
459      UChar* name;
460   }
461   TempSymKey;
462
463typedef
464   struct {
465      TempSymKey key;
466      Addr       tocptr;
467      Int        size;
468      Bool       from_opd;
469   }
470   TempSym;
471
472static Word cmp_TempSymKey ( TempSymKey* key1, TempSym* elem2 ) {
473   if (key1->addr < elem2->key.addr) return -1;
474   if (key1->addr > elem2->key.addr) return 1;
475   return (Word)VG_(strcmp)(key1->name, elem2->key.name);
476}
477static void* oset_malloc ( SizeT szB ) {
478   return VG_(arena_malloc)(VG_AR_SYMTAB, szB);
479}
480static void oset_free ( void* p ) {
481   VG_(arena_free)(VG_AR_SYMTAB, p);
482}
483
484static
485__attribute__((unused)) /* not referred to on all targets */
486void read_elf_symtab__ppc64_linux(
487        struct _SegInfo* si, UChar* tab_name,
488        ElfXX_Sym* o_symtab, UInt o_symtab_sz, OffT o_symtab_offset,
489        UChar*     o_strtab, UInt o_strtab_sz,
490        UChar*     opd_filea, OffT opd_offset /* ppc64-linux only */
491     )
492{
493   Int         i, old_size;
494   Addr        sym_addr, sym_addr_really;
495   Char       *sym_name, *sym_name_really;
496   Int         sym_size;
497   Addr        sym_tocptr, old_tocptr;
498   Bool        from_opd, modify_size, modify_tocptr;
499   DiSym       risym;
500   ElfXX_Sym  *sym;
501   OSet       *oset;
502   TempSymKey  key;
503   TempSym    *elem;
504   TempSym    *prev;
505
506   if (o_strtab == NULL || o_symtab == NULL) {
507      Char buf[80];
508      vg_assert(VG_(strlen)(tab_name) < 40);
509      VG_(sprintf)(buf, "   object doesn't have a %s", tab_name);
510      ML_(symerr)(buf);
511      return;
512   }
513
514   TRACE_SYMTAB("\nReading (ELF, ppc64-linux) %s (%d entries)\n", tab_name,
515                o_symtab_sz/sizeof(ElfXX_Sym) );
516
517   oset = VG_(OSet_Create)( offsetof(TempSym,key),
518                            (OSetCmp_t)cmp_TempSymKey,
519                            oset_malloc, oset_free );
520   vg_assert(oset);
521
522   /* Perhaps should start at i = 1; ELF docs suggest that entry
523      0 always denotes 'unknown symbol'. */
524   for (i = 1; i < (Int)(o_symtab_sz/sizeof(ElfXX_Sym)); i++) {
525      sym      = & o_symtab[i];
526      sym_name = (Char*)(o_strtab + sym->st_name);
527      sym_addr = o_symtab_offset + sym->st_value;
528
529      if (VG_(clo_trace_symtab))
530         show_raw_elf_symbol(i, sym, sym_name, sym_addr, True);
531
532      if (get_elf_symbol_info(si, sym, sym_name, sym_addr,
533                              opd_filea, opd_offset,
534                              &sym_name_really,
535                              &sym_addr_really,
536                              &sym_size,
537                              &sym_tocptr,
538                              &from_opd)) {
539
540         /* Check if we've seen this (name,addr) key before. */
541         key.addr = sym_addr_really;
542         key.name = sym_name_really;
543         prev = VG_(OSet_Lookup)( oset, &key );
544
545         if (prev) {
546
547            /* Seen it before.  Fold in whatever new info we can. */
548            modify_size   = False;
549            modify_tocptr = False;
550            old_size   = 0;
551	    old_tocptr = 0;
552
553            if (prev->from_opd && !from_opd
554                && (prev->size == 24 || prev->size == 16)
555                && sym_size != prev->size) {
556               /* Existing one is an opd-redirect, with a bogus size,
557                  so the only useful new fact we have is the real size
558                  of the symbol. */
559               modify_size = True;
560               old_size = prev->size;
561               prev->size = sym_size;
562            }
563            else
564            if (!prev->from_opd && from_opd
565                && (sym_size == 24 || sym_size == 16)) {
566               /* Existing one is non-opd, new one is opd.  What we
567                  can acquire from the new one is the TOC ptr to be
568                  used.  Since the existing sym is non-toc, it
569                  shouldn't currently have an known TOC ptr. */
570               vg_assert(prev->tocptr == 0);
571               modify_tocptr = True;
572               old_tocptr = prev->tocptr;
573               prev->tocptr = sym_tocptr;
574            }
575            else {
576               /* ignore. can we do better here? */
577            }
578
579            /* Only one or the other is possible (I think) */
580	    vg_assert(!(modify_size && modify_tocptr));
581
582            if (modify_size && VG_(clo_trace_symtab)) {
583               VG_(printf)("    modify (old sz %4d)    "
584                           " val %010p, toc %010p, sz %4d  %s\n",
585                           old_size,
586                           (void*) prev->key.addr,
587                           (void*) prev->tocptr,
588                           (Int)   prev->size,
589                           (HChar*)prev->key.name
590               );
591            }
592            if (modify_tocptr && VG_(clo_trace_symtab)) {
593               VG_(printf)("    modify (upd tocptr)     "
594                           " val %010p, toc %010p, sz %4d  %s\n",
595                            (void*) prev->key.addr,
596                            (void*) prev->tocptr,
597                            (Int)   prev->size,
598                            (HChar*)prev->key.name
599               );
600            }
601
602         } else {
603
604            /* A new (name,addr) key.  Add and continue. */
605            elem = VG_(OSet_AllocNode)(oset, sizeof(TempSym));
606            vg_assert(elem);
607            elem->key      = key;
608            elem->tocptr   = sym_tocptr;
609            elem->size     = sym_size;
610            elem->from_opd = from_opd;
611            VG_(OSet_Insert)(oset, elem);
612            if (VG_(clo_trace_symtab)) {
613               VG_(printf)("   to-oset [%4d]:          "
614                           " val %010p, toc %010p, sz %4d  %s\n",
615                           i, (void*) elem->key.addr,
616                              (void*) elem->tocptr,
617                              (Int)   elem->size,
618                              (HChar*)elem->key.name
619               );
620            }
621
622         }
623      }
624   }
625
626   /* All the syms that matter are in the oset.  Now pull them out,
627      build a "standard" symbol table, and nuke the oset. */
628
629   i = 0;
630   VG_(OSet_ResetIter)( oset );
631
632   while ( (elem = VG_(OSet_Next)(oset)) ) {
633      risym.addr   = elem->key.addr;
634      risym.size   = elem->size;
635      risym.name   = ML_(addStr) ( si, elem->key.name, -1 );
636      risym.tocptr = elem->tocptr;
637      vg_assert(risym.name != NULL);
638
639      ML_(addSym) ( si, &risym );
640      if (VG_(clo_trace_symtab)) {
641         VG_(printf)("    record [%4d]:          "
642                     " val %010p, toc %010p, sz %4d  %s\n",
643                     i, (void*) risym.addr,
644                        (void*) risym.tocptr,
645                        (Int)   risym.size,
646                        (HChar*)risym.name
647               );
648      }
649      i++;
650   }
651
652   VG_(OSet_Destroy)( oset, NULL );
653}
654
655
656/*
657 * This routine for calculating the CRC for a separate debug file
658 * is GPLed code borrowed from GNU binutils.
659 */
660static UInt
661calc_gnu_debuglink_crc32(UInt crc, const UChar *buf, Int len)
662{
663  static const UInt crc32_table[256] =
664    {
665      0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
666      0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
667      0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
668      0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
669      0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
670      0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
671      0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
672      0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
673      0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
674      0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
675      0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
676      0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
677      0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
678      0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
679      0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
680      0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
681      0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
682      0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
683      0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
684      0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
685      0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
686      0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
687      0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
688      0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
689      0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
690      0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
691      0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
692      0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
693      0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
694      0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
695      0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
696      0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
697      0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
698      0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
699      0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
700      0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
701      0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
702      0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
703      0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
704      0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
705      0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
706      0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
707      0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
708      0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
709      0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
710      0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
711      0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
712      0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
713      0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
714      0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
715      0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
716      0x2d02ef8d
717    };
718  const UChar *end;
719
720  crc = ~crc & 0xffffffff;
721  for (end = buf + len; buf < end; ++ buf)
722    crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
723  return ~crc & 0xffffffff;;
724}
725
726/*
727 * Try and open a separate debug file, ignoring any where the CRC does
728 * not match the value from the main object file.
729 */
730static
731Addr open_debug_file( Char* name, UInt crc, UInt* size )
732{
733   SysRes fd, sres;
734   struct vki_stat stat_buf;
735   UInt calccrc;
736
737   fd = VG_(open)(name, VKI_O_RDONLY, 0);
738   if (fd.isError)
739      return 0;
740
741   if (VG_(fstat)(fd.res, &stat_buf) != 0) {
742      VG_(close)(fd.res);
743      return 0;
744   }
745
746   if (VG_(clo_verbosity) > 1)
747      VG_(message)(Vg_DebugMsg, "Reading debug info from %s...", name);
748
749   *size = stat_buf.st_size;
750
751   sres = VG_(am_mmap_file_float_valgrind)
752             ( *size, VKI_PROT_READ, fd.res, 0 );
753
754   VG_(close)(fd.res);
755
756   if (sres.isError)
757      return 0;
758
759   calccrc = calc_gnu_debuglink_crc32(0, (UChar*)sres.res, *size);
760   if (calccrc != crc) {
761      SysRes res = VG_(am_munmap_valgrind)(sres.res, *size);
762      vg_assert(!res.isError);
763      if (VG_(clo_verbosity) > 1)
764	 VG_(message)(Vg_DebugMsg, "... CRC mismatch (computed %08x wanted %08x)", calccrc, crc);
765      return 0;
766   }
767
768   return sres.res;
769}
770
771/*
772 * Try to find a separate debug file for a given object file.
773 */
774static
775Addr find_debug_file( Char* objpath, Char* debugname, UInt crc, UInt* size )
776{
777   Char *objdir = VG_(arena_strdup)(VG_AR_SYMTAB, objpath);
778   Char *objdirptr;
779   Char *debugpath;
780   Addr addr = 0;
781
782   if ((objdirptr = VG_(strrchr)(objdir, '/')) != NULL)
783      *objdirptr = '\0';
784
785   debugpath = VG_(arena_malloc)(VG_AR_SYMTAB, VG_(strlen)(objdir) + VG_(strlen)(debugname) + 16);
786
787   VG_(sprintf)(debugpath, "%s/%s", objdir, debugname);
788
789   if ((addr = open_debug_file(debugpath, crc, size)) == 0) {
790      VG_(sprintf)(debugpath, "%s/.debug/%s", objdir, debugname);
791      if ((addr = open_debug_file(debugpath, crc, size)) == 0) {
792         VG_(sprintf)(debugpath, "/usr/lib/debug%s/%s", objdir, debugname);
793         addr = open_debug_file(debugpath, crc, size);
794      }
795   }
796
797   VG_(arena_free)(VG_AR_SYMTAB, debugpath);
798   VG_(arena_free)(VG_AR_SYMTAB, objdir);
799
800   return addr;
801}
802
803
804/* The central function for reading ELF debug info.  For the
805   object/exe specified by the SegInfo, find ELF sections, then read
806   the symbols, line number info, file name info, CFA (stack-unwind
807   info) and anything else we want, into the tables within the
808   supplied SegInfo.
809*/
810Bool ML_(read_elf_debug_info) ( struct _SegInfo* si )
811{
812   Bool          res;
813   ElfXX_Ehdr*   ehdr;       /* The ELF header                   */
814   ElfXX_Shdr*   shdr;       /* The section table                */
815   UChar*        sh_strtab;  /* The section table's string table */
816   SysRes        fd, sres;
817   Int           i;
818   Bool          ok;
819   Addr          oimage;
820   UInt          n_oimage;
821   OffT          offset_oimage = 0;
822   Addr          dimage = 0;
823   UInt          n_dimage = 0;
824   OffT          offset_dimage = 0;
825
826   oimage = (Addr)NULL;
827   if (VG_(clo_verbosity) > 1 || VG_(clo_trace_redir))
828      VG_(message)(Vg_DebugMsg, "Reading syms from %s (%p)",
829                                si->filename, si->start );
830
831   /* mmap the object image aboard, so that we can read symbols and
832      line number info out of it.  It will be munmapped immediately
833      thereafter; it is only aboard transiently. */
834
835   fd = VG_(open)(si->filename, VKI_O_RDONLY, 0);
836   if (fd.isError) {
837      ML_(symerr)("Can't open .so/.exe to read symbols?!");
838      return False;
839   }
840
841   n_oimage = VG_(fsize)(fd.res);
842   if (n_oimage < 0) {
843      ML_(symerr)("Can't stat .so/.exe (to determine its size)?!");
844      VG_(close)(fd.res);
845      return False;
846   }
847
848   sres = VG_(am_mmap_file_float_valgrind)
849             ( n_oimage, VKI_PROT_READ, fd.res, 0 );
850
851   VG_(close)(fd.res);
852
853   if (sres.isError) {
854      VG_(message)(Vg_UserMsg, "warning: mmap failed on %s", si->filename );
855      VG_(message)(Vg_UserMsg, "         no symbols or debug info loaded" );
856      return False;
857   }
858
859   oimage = sres.res;
860
861   /* Ok, the object image is safely in oimage[0 .. n_oimage-1].
862      Now verify that it is a valid ELF .so or executable image.
863   */
864   res = False;
865   ok = (n_oimage >= sizeof(ElfXX_Ehdr));
866   ehdr = (ElfXX_Ehdr*)oimage;
867
868   if (ok)
869      ok &= ML_(is_elf_object_file)(ehdr);
870
871   if (!ok) {
872      ML_(symerr)("Invalid ELF header, or missing stringtab/sectiontab.");
873      goto out;
874   }
875
876   /* Walk the LOAD headers in the phdr and update the SegInfo to
877      include them all, so that this segment also contains data and
878      bss memory.  Also computes correct symbol offset value for this
879      ELF file. */
880   if (ehdr->e_phoff + ehdr->e_phnum*sizeof(ElfXX_Phdr) > n_oimage) {
881      ML_(symerr)("ELF program header is beyond image end?!");
882      goto out;
883   }
884   {
885      Bool offset_set = False;
886      ElfXX_Addr prev_addr = 0;
887      Addr baseaddr = 0;
888
889      vg_assert(si->soname == NULL);
890
891      for (i = 0; i < ehdr->e_phnum; i++) {
892	 ElfXX_Phdr *o_phdr;
893	 ElfXX_Addr mapped, mapped_end;
894
895	 o_phdr = &((ElfXX_Phdr *)(oimage + ehdr->e_phoff))[i];
896
897         /* Try to get the soname.  If there isn't one, use "NONE".
898            The seginfo needs to have some kind of soname in order to
899            facilitate writing redirect functions, since all redirect
900            specifications require a soname (pattern). */
901	 if (o_phdr->p_type == PT_DYNAMIC && si->soname == NULL) {
902	    const ElfXX_Dyn *dyn = (const ElfXX_Dyn *)(oimage + o_phdr->p_offset);
903	    Int stroff = -1;
904	    Char *strtab = NULL;
905	    Int j;
906
907	    for(j = 0; dyn[j].d_tag != DT_NULL; j++) {
908	       switch(dyn[j].d_tag) {
909	       case DT_SONAME:
910		  stroff = dyn[j].d_un.d_val;
911		  break;
912
913	       case DT_STRTAB:
914		  strtab = (Char *)oimage + dyn[j].d_un.d_ptr - baseaddr;
915		  break;
916	       }
917	    }
918
919	    if (stroff != -1 && strtab != 0) {
920	       TRACE_SYMTAB("soname=%s\n", strtab+stroff);
921	       si->soname = VG_(arena_strdup)(VG_AR_SYMTAB, strtab+stroff);
922	    }
923	 }
924
925	 if (o_phdr->p_type != PT_LOAD)
926	    continue;
927
928	 if (!offset_set) {
929	    offset_set = True;
930	    offset_oimage = si->start - o_phdr->p_vaddr;
931	    baseaddr = o_phdr->p_vaddr;
932	 }
933
934         // Make sure the Phdrs are in order
935	 if (o_phdr->p_vaddr < prev_addr) {
936	    ML_(symerr)("ELF Phdrs are out of order!?");
937            goto out;
938	 }
939	 prev_addr = o_phdr->p_vaddr;
940
941         // Get the data and bss start/size if appropriate
942	 mapped = o_phdr->p_vaddr + offset_oimage;
943	 mapped_end = mapped + o_phdr->p_memsz;
944	 if (si->data_start_vma == 0 &&
945	     (o_phdr->p_flags & (PF_R|PF_W|PF_X)) == (PF_R|PF_W)) {
946	    si->data_start_vma = mapped;
947	    si->data_size      = o_phdr->p_filesz;
948	    si->bss_start_vma  = mapped + o_phdr->p_filesz;
949	    if (o_phdr->p_memsz > o_phdr->p_filesz)
950	       si->bss_size = o_phdr->p_memsz - o_phdr->p_filesz;
951	    else
952	       si->bss_size = 0;
953	 }
954
955         mapped = mapped & ~(VKI_PAGE_SIZE-1);
956	 mapped_end = (mapped_end + VKI_PAGE_SIZE - 1) & ~(VKI_PAGE_SIZE-1);
957
958	 if (VG_(needs).data_syms &&
959	     (mapped >= si->start && mapped <= (si->start+si->size)) &&
960	     (mapped_end > (si->start+si->size))) {
961	    UInt newsz = mapped_end - si->start;
962	    if (newsz > si->size) {
963	       if (0)
964		  VG_(printf)("extending mapping %p..%p %d -> ..%p %d\n",
965			      si->start, si->start+si->size, si->size,
966			      si->start+newsz, newsz);
967
968	       si->size = newsz;
969	    }
970	 }
971      }
972   }
973
974   si->offset = offset_oimage;
975
976   /* If, after looking at all the program headers, we still didn't
977      find a soname, add a fake one. */
978   if (si->soname == NULL) {
979      TRACE_SYMTAB("soname(fake)=\"NONE\"\n");
980      si->soname = "NONE";
981   }
982
983   TRACE_SYMTAB("shoff = %d,  shnum = %d,  size = %d,  n_vg_oimage = %d\n",
984                ehdr->e_shoff, ehdr->e_shnum, sizeof(ElfXX_Shdr), n_oimage );
985
986   if (ehdr->e_shoff + ehdr->e_shnum*sizeof(ElfXX_Shdr) > n_oimage) {
987      ML_(symerr)("ELF section header is beyond image end?!");
988      goto out;
989   }
990
991   shdr = (ElfXX_Shdr*)(oimage + ehdr->e_shoff);
992   sh_strtab = (UChar*)(oimage + shdr[ehdr->e_shstrndx].sh_offset);
993
994   /* Find interesting sections, read the symbol table(s), read any debug
995      information */
996   {
997      /* Pointers to start of sections (in the oimage, not in the
998	 running image) */
999      UChar*     o_strtab     = NULL; /* .strtab */
1000      ElfXX_Sym* o_symtab     = NULL; /* .symtab */
1001      UChar*     o_dynstr     = NULL; /* .dynstr */
1002      ElfXX_Sym* o_dynsym     = NULL; /* .dynsym */
1003      Char*      debuglink    = NULL; /* .gnu_debuglink */
1004      UChar*     stab         = NULL; /* .stab         (stabs)  */
1005      UChar*     stabstr      = NULL; /* .stabstr      (stabs)  */
1006      UChar*     debug_line   = NULL; /* .debug_line   (dwarf2) */
1007      UChar*     debug_info   = NULL; /* .debug_info   (dwarf2) */
1008      UChar*     debug_abbv   = NULL; /* .debug_abbrev (dwarf2) */
1009      UChar*     debug_str    = NULL; /* .debug_str    (dwarf2) */
1010      UChar*     dwarf1d      = NULL; /* .debug        (dwarf1) */
1011      UChar*     dwarf1l      = NULL; /* .line         (dwarf1) */
1012      UChar*     ehframe      = NULL; /* .eh_frame     (dwarf2) */
1013      UChar*     opd_filea    = NULL; /* .opd          (dwarf2, ppc64-linux) */
1014      UChar*     dummy_filea  = NULL;
1015
1016      OffT       o_symtab_offset = offset_oimage;
1017      OffT       o_dynsym_offset = offset_oimage;
1018      OffT       debug_offset    = offset_oimage;
1019      OffT       opd_offset      = offset_oimage;
1020
1021      /* Section sizes, in bytes */
1022      UInt       o_strtab_sz     = 0;
1023      UInt       o_symtab_sz     = 0;
1024      UInt       o_dynstr_sz     = 0;
1025      UInt       o_dynsym_sz     = 0;
1026      UInt       debuglink_sz    = 0;
1027      UInt       stab_sz         = 0;
1028      UInt       stabstr_sz      = 0;
1029      UInt       debug_line_sz   = 0;
1030      UInt       debug_info_sz   = 0;
1031      UInt       debug_abbv_sz   = 0;
1032      UInt       debug_str_sz    = 0;
1033      UInt       dwarf1d_sz      = 0;
1034      UInt       dwarf1l_sz      = 0;
1035      UInt       ehframe_sz      = 0;
1036
1037      /* Section virtual addresses */
1038      Addr       dummy_vma       = 0;
1039      Addr       ehframe_vma     = 0;
1040
1041      /* Find all interesting sections */
1042
1043      /* What FIND does: it finds the section called SEC_NAME.  The
1044	 size of it is assigned to SEC_SIZE.  The address that it will
1045	 appear in the running image is assigned to SEC_VMA (note,
1046	 this will be meaningless for sections which are not marked
1047	 loadable.  Even for sections which are marked loadable, the
1048	 client's ld.so may not have loaded them yet, so there is no
1049	 guarantee that we can safely prod around in any such area)
1050	 The address of the section in the transiently loaded oimage
1051	 is assigned to SEC_FILEA.  Because the entire object file is
1052	 transiently mapped aboard for inspection, it's always safe to
1053	 inspect that area. */
1054
1055      for (i = 0; i < ehdr->e_shnum; i++) {
1056
1057#        define FIND(sec_name, sec_size, sec_filea, sec_vma) \
1058         if (0 == VG_(strcmp)(sec_name, sh_strtab + shdr[i].sh_name)) { \
1059            Bool nobits; \
1060            sec_vma   = (Addr)(offset_oimage + shdr[i].sh_addr); \
1061            sec_filea = (void*)(oimage + shdr[i].sh_offset); \
1062            sec_size  = shdr[i].sh_size; \
1063            nobits = shdr[i].sh_type == SHT_NOBITS; \
1064            TRACE_SYMTAB( "%18s: filea %p .. %p, vma %p .. %p\n", \
1065                          sec_name, (UChar*)sec_filea, \
1066                                    ((UChar*)sec_filea) + sec_size - 1, \
1067                          sec_vma, sec_vma + sec_size - 1); \
1068            /* SHT_NOBITS sections have zero size in the file. */ \
1069            if ( shdr[i].sh_offset + (nobits ? 0 : sec_size) > n_oimage ) { \
1070               ML_(symerr)("   section beyond image end?!"); \
1071               goto out; \
1072            } \
1073         }
1074
1075         /* Nb: must find where .got and .plt sections will be in the
1076          * executable image, not in the object image transiently loaded. */
1077         /*   NAME              SIZE           ADDR_IN_OIMAGE  ADDR_WHEN_MAPPED */
1078         FIND(".dynsym",        o_dynsym_sz,   o_dynsym,       dummy_vma)
1079         FIND(".dynstr",        o_dynstr_sz,   o_dynstr,       dummy_vma)
1080         FIND(".symtab",        o_symtab_sz,   o_symtab,       dummy_vma)
1081         FIND(".strtab",        o_strtab_sz,   o_strtab,       dummy_vma)
1082
1083         FIND(".gnu_debuglink", debuglink_sz,  debuglink,      dummy_vma)
1084
1085         FIND(".stab",          stab_sz,       stab,           dummy_vma)
1086         FIND(".stabstr",       stabstr_sz,    stabstr,        dummy_vma)
1087
1088         FIND(".debug_line",    debug_line_sz, debug_line,     dummy_vma)
1089         FIND(".debug_info",    debug_info_sz, debug_info,     dummy_vma)
1090         FIND(".debug_abbrev",  debug_abbv_sz, debug_abbv,     dummy_vma)
1091         FIND(".debug_str",     debug_str_sz,  debug_str,      dummy_vma)
1092
1093         FIND(".debug",         dwarf1d_sz,    dwarf1d,        dummy_vma)
1094         FIND(".line",          dwarf1l_sz,    dwarf1l,        dummy_vma)
1095         FIND(".eh_frame",      ehframe_sz,    ehframe,        ehframe_vma)
1096
1097         FIND(".got",           si->got_size,  dummy_filea,    si->got_start_vma)
1098         FIND(".plt",           si->plt_size,  dummy_filea,    si->plt_start_vma)
1099         FIND(".opd",           si->opd_size,  opd_filea,      si->opd_start_vma)
1100
1101#        undef FIND
1102      }
1103
1104      /* Did we find a debuglink section? */
1105      if (debuglink != NULL) {
1106         UInt crc_offset = VG_ROUNDUP(VG_(strlen)(debuglink)+1, 4);
1107         UInt crc;
1108
1109         vg_assert(crc_offset + sizeof(UInt) <= debuglink_sz);
1110
1111         /* Extract the CRC from the debuglink section */
1112         crc = *(UInt *)(debuglink + crc_offset);
1113
1114         /* See if we can find a matching debug file */
1115         if ((dimage = find_debug_file(si->filename, debuglink, crc, &n_dimage)) != 0) {
1116            ehdr = (ElfXX_Ehdr*)dimage;
1117
1118            if (n_dimage >= sizeof(ElfXX_Ehdr)
1119                && ML_(is_elf_object_file(ehdr))
1120                && ehdr->e_phoff + ehdr->e_phnum*sizeof(ElfXX_Phdr) <= n_dimage
1121                && ehdr->e_shoff + ehdr->e_shnum*sizeof(ElfXX_Shdr) <= n_dimage)
1122            {
1123               Bool need_symtab = (NULL == o_symtab);
1124
1125               for (i = 0; i < ehdr->e_phnum; i++) {
1126                  ElfXX_Phdr *o_phdr = &((ElfXX_Phdr *)(dimage + ehdr->e_phoff))[i];
1127                  if (o_phdr->p_type == PT_LOAD) {
1128                     offset_dimage = si->start - o_phdr->p_vaddr;
1129                     break;
1130                  }
1131               }
1132
1133               debug_offset = offset_dimage;
1134               if (need_symtab)
1135                  o_symtab_offset = offset_dimage;
1136
1137               shdr = (ElfXX_Shdr*)(dimage + ehdr->e_shoff);
1138               sh_strtab = (UChar*)(dimage + shdr[ehdr->e_shstrndx].sh_offset);
1139
1140               /* Same deal as previous FIND, except simpler - doesn't
1141                  look for vma, only oimage address. */
1142
1143               /* Find all interesting sections */
1144               for (i = 0; i < ehdr->e_shnum; i++) {
1145
1146#                 define FIND(condition, sec_name, sec_size, sec_filea)	\
1147                  if (condition \
1148                      && 0 == VG_(strcmp)(sec_name, sh_strtab + shdr[i].sh_name)) { \
1149                     Bool nobits; \
1150                     if (0 != sec_filea) \
1151                        VG_(core_panic)("repeated section!\n"); \
1152                     sec_filea = (void*)(dimage + shdr[i].sh_offset); \
1153                     sec_size  = shdr[i].sh_size; \
1154                     nobits = shdr[i].sh_type == SHT_NOBITS; \
1155                     TRACE_SYMTAB( "%18s: filea %p .. %p\n", \
1156                                   sec_name, (UChar*)sec_filea, \
1157                                             ((UChar*)sec_filea) + sec_size - 1); \
1158                     /* SHT_NOBITS sections have zero size in the file. */ \
1159                     if ( shdr[i].sh_offset + (nobits ? 0 : sec_size) > n_dimage ) { \
1160                        ML_(symerr)("   section beyond image end?!"); \
1161                        goto out; \
1162                     } \
1163                  }
1164
1165                  FIND(need_symtab, ".symtab",       o_symtab_sz,   o_symtab)
1166                  FIND(need_symtab, ".strtab",       o_strtab_sz,   o_strtab)
1167                  FIND(1,           ".stab",         stab_sz,       stab)
1168                  FIND(1,           ".stabstr",      stabstr_sz,    stabstr)
1169                  FIND(1,           ".debug_line",   debug_line_sz, debug_line)
1170                  FIND(1,           ".debug_info",   debug_info_sz, debug_info)
1171                  FIND(1,           ".debug_abbrev", debug_abbv_sz, debug_abbv)
1172                  FIND(1,           ".debug_str",    debug_str_sz,  debug_str)
1173                  FIND(1,           ".debug",        dwarf1d_sz,    dwarf1d)
1174                  FIND(1,           ".line",         dwarf1l_sz,    dwarf1l)
1175
1176#                 undef FIND
1177               }
1178            }
1179         }
1180      }
1181
1182      /* Check some sizes */
1183      vg_assert((o_dynsym_sz % sizeof(ElfXX_Sym)) == 0);
1184      vg_assert((o_symtab_sz % sizeof(ElfXX_Sym)) == 0);
1185
1186      /* Read symbols */
1187      {
1188         void (*read_elf_symtab)(struct _SegInfo*,UChar*,ElfXX_Sym*,
1189                                 UInt,OffT,UChar*,UInt,UChar*,OffT);
1190#        if defined(VGP_ppc64_linux)
1191         read_elf_symtab = read_elf_symtab__ppc64_linux;
1192#        else
1193         read_elf_symtab = read_elf_symtab__normal;
1194#        endif
1195         read_elf_symtab(si, "symbol table",
1196                         o_symtab, o_symtab_sz, o_symtab_offset,
1197                         o_strtab, o_strtab_sz, opd_filea, opd_offset);
1198
1199         read_elf_symtab(si, "dynamic symbol table",
1200                         o_dynsym, o_dynsym_sz, o_dynsym_offset,
1201                         o_dynstr, o_dynstr_sz, opd_filea, opd_offset);
1202      }
1203
1204      /* Read .eh_frame (call-frame-info) if any */
1205      if (ehframe) {
1206         ML_(read_callframe_info_dwarf2) ( si, ehframe, ehframe_sz, ehframe_vma );
1207      }
1208
1209      /* Read the stabs and/or dwarf2 debug information, if any.  It
1210         appears reading stabs stuff on amd64-linux doesn't work, so
1211         we ignore it. */
1212#     if !defined(VGP_amd64_linux)
1213      if (stab && stabstr) {
1214         ML_(read_debuginfo_stabs) ( si, debug_offset, stab, stab_sz,
1215                                         stabstr, stabstr_sz );
1216      }
1217#     endif
1218      /* jrs 2006-01-01: icc-8.1 has been observed to generate
1219         binaries without debug_str sections.  Don't preclude
1220         debuginfo reading for that reason, but, in
1221         read_unitinfo_dwarf2, do check that debugstr is non-NULL
1222         before using it. */
1223      if (debug_info && debug_abbv && debug_line /* && debug_str */) {
1224         ML_(read_debuginfo_dwarf2) ( si, debug_offset,
1225                                      debug_info,   debug_info_sz,
1226                                      debug_abbv,
1227                                      debug_line,   debug_line_sz,
1228                                      debug_str );
1229      }
1230      if (dwarf1d && dwarf1l) {
1231         ML_(read_debuginfo_dwarf1) ( si, dwarf1d, dwarf1d_sz,
1232                                          dwarf1l, dwarf1l_sz );
1233      }
1234   }
1235   res = True;
1236
1237  out: {
1238   SysRes m_res;
1239   /* Last, but not least, heave the image(s) back overboard. */
1240   if (dimage) {
1241      m_res = VG_(am_munmap_valgrind) ( dimage, n_dimage );
1242      vg_assert(!m_res.isError);
1243   }
1244   m_res = VG_(am_munmap_valgrind) ( oimage, n_oimage );
1245   vg_assert(!m_res.isError);
1246   return res;
1247  }
1248}
1249
1250
1251/*--------------------------------------------------------------------*/
1252/*--- end                                                          ---*/
1253/*--------------------------------------------------------------------*/
1254