readelf.c revision 160d5a82d2d5d7d0964140dea17751c1daa3315e
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-2008 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_debuginfo.h"
40#include "pub_core_libcbase.h"
41#include "pub_core_libcprint.h"
42#include "pub_core_libcassert.h"
43#include "pub_core_libcfile.h"
44#include "pub_core_aspacemgr.h"    /* for mmaping debuginfo files */
45#include "pub_core_machine.h"      /* VG_ELF_CLASS */
46#include "pub_core_options.h"
47#include "pub_core_oset.h"
48#include "pub_core_tooliface.h"    /* VG_(needs) */
49#include "pub_core_xarray.h"
50#include "priv_misc.h"             /* dinfo_zalloc/free/strdup */
51#include "priv_d3basics.h"
52#include "priv_tytypes.h"
53#include "priv_storage.h"
54#include "priv_readelf.h"          /* self */
55#include "priv_readdwarf.h"        /* 'cos ELF contains DWARF */
56#include "priv_readdwarf3.h"
57#include "priv_readstabs.h"        /* and stabs, if we're unlucky */
58
59/* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
60#include <elf.h>
61/* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
62
63/*------------------------------------------------------------*/
64/*--- 32/64-bit parameterisation                           ---*/
65/*------------------------------------------------------------*/
66
67/* For all the ELF macros and types which specify '32' or '64',
68   select the correct variant for this platform and give it
69   an 'XX' name.  Then use the 'XX' variant consistently in
70   the rest of this file.
71*/
72#if VG_WORDSIZE == 4
73#  define  ElfXX_Ehdr     Elf32_Ehdr
74#  define  ElfXX_Shdr     Elf32_Shdr
75#  define  ElfXX_Phdr     Elf32_Phdr
76#  define  ElfXX_Sym      Elf32_Sym
77#  define  ElfXX_Word     Elf32_Word
78#  define  ElfXX_Addr     Elf32_Addr
79#  define  ElfXX_Dyn      Elf32_Dyn
80#  define  ELFXX_ST_BIND  ELF32_ST_BIND
81#  define  ELFXX_ST_TYPE  ELF32_ST_TYPE
82
83#elif VG_WORDSIZE == 8
84#  define  ElfXX_Ehdr     Elf64_Ehdr
85#  define  ElfXX_Shdr     Elf64_Shdr
86#  define  ElfXX_Phdr     Elf64_Phdr
87#  define  ElfXX_Sym      Elf64_Sym
88#  define  ElfXX_Word     Elf64_Word
89#  define  ElfXX_Addr     Elf64_Addr
90#  define  ElfXX_Dyn      Elf64_Dyn
91#  define  ELFXX_ST_BIND  ELF64_ST_BIND
92#  define  ELFXX_ST_TYPE  ELF64_ST_TYPE
93
94#else
95# error "VG_WORDSIZE should be 4 or 8"
96#endif
97
98
99/*------------------------------------------------------------*/
100/*---                                                      ---*/
101/*--- Read symbol table and line info from ELF files.      ---*/
102/*---                                                      ---*/
103/*------------------------------------------------------------*/
104
105/* readelf.c parses ELF files and acquires symbol table info from
106   them.  It calls onwards to readdwarf.c to read DWARF2/3 line number
107   and call frame info found. */
108
109
110/* Identify an ELF object file by peering at the first few bytes of
111   it. */
112
113Bool ML_(is_elf_object_file)( void* image, SizeT n_image )
114{
115   ElfXX_Ehdr* ehdr = (ElfXX_Ehdr*)image;
116   Int ok = 1;
117
118   if (n_image < sizeof(ElfXX_Ehdr))
119      return False;
120
121   ok &= (ehdr->e_ident[EI_MAG0] == 0x7F
122          && ehdr->e_ident[EI_MAG1] == 'E'
123          && ehdr->e_ident[EI_MAG2] == 'L'
124          && ehdr->e_ident[EI_MAG3] == 'F');
125   ok &= (ehdr->e_ident[EI_CLASS] == VG_ELF_CLASS
126          && ehdr->e_ident[EI_DATA] == VG_ELF_DATA2XXX
127          && ehdr->e_ident[EI_VERSION] == EV_CURRENT);
128   ok &= (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN);
129   ok &= (ehdr->e_machine == VG_ELF_MACHINE);
130   ok &= (ehdr->e_version == EV_CURRENT);
131   ok &= (ehdr->e_shstrndx != SHN_UNDEF);
132   ok &= (ehdr->e_shoff != 0 && ehdr->e_shnum != 0);
133   ok &= (ehdr->e_phoff != 0 && ehdr->e_phnum != 0);
134
135   if (ok)
136      return True;
137   else
138      return False;
139}
140
141
142/* Show a raw ELF symbol, given its in-image address and name. */
143
144static
145void show_raw_elf_symbol ( Int i,
146                           ElfXX_Sym* sym, Char* sym_name, Addr sym_svma,
147                           Bool ppc64_linux_format )
148{
149   HChar* space = ppc64_linux_format ? "                  " : "";
150   VG_(printf)("raw symbol [%4d]: ", i);
151   switch (ELFXX_ST_BIND(sym->st_info)) {
152      case STB_LOCAL:  VG_(printf)("LOC "); break;
153      case STB_GLOBAL: VG_(printf)("GLO "); break;
154      case STB_WEAK:   VG_(printf)("WEA "); break;
155      case STB_LOPROC: VG_(printf)("lop "); break;
156      case STB_HIPROC: VG_(printf)("hip "); break;
157      default:         VG_(printf)("??? "); break;
158   }
159   switch (ELFXX_ST_TYPE(sym->st_info)) {
160      case STT_NOTYPE:  VG_(printf)("NOT "); break;
161      case STT_OBJECT:  VG_(printf)("OBJ "); break;
162      case STT_FUNC:    VG_(printf)("FUN "); break;
163      case STT_SECTION: VG_(printf)("SEC "); break;
164      case STT_FILE:    VG_(printf)("FIL "); break;
165      case STT_LOPROC:  VG_(printf)("lop "); break;
166      case STT_HIPROC:  VG_(printf)("hip "); break;
167      default:          VG_(printf)("??? "); break;
168   }
169   VG_(printf)(": svma %#010lx, %ssz %4ld  %s\n",
170               sym_svma, space, sym->st_size + 0UL,
171               ( sym->st_name ? sym_name : (Char*)"NONAME" ) );
172}
173
174
175/* Decide whether SYM is something we should collect, and if so, copy
176   relevant info to the _OUT arguments.  For {x86,amd64,ppc32}-linux
177   this is straightforward - the name, address, size are copied out
178   unchanged.
179
180   There is a bit of a kludge re data symbols (see KLUDGED BSS CHECK
181   below): we assume that the .bss is mapped immediately after .data,
182   and so accept any data symbol which exists in the range [start of
183   .data, size of .data + size of .bss).  I don't know if this is
184   really correct/justifiable, or not.
185
186   For ppc64-linux it's more complex.  If the symbol is seen to be in
187   the .opd section, it is taken to be a function descriptor, and so
188   a dereference is attempted, in order to get hold of the real entry
189   point address.  Also as part of the dereference, there is an attempt
190   to calculate the TOC pointer (R2 value) associated with the symbol.
191
192   To support the ppc64-linux pre-"dotless" ABI (prior to gcc 4.0.0),
193   if the symbol is seen to be outside the .opd section and its name
194   starts with a dot, an .opd deference is not attempted, and no TOC
195   pointer is calculated, but the the leading dot is removed from the
196   name.
197
198   As a result, on ppc64-linux, the caller of this function may have
199   to piece together the real size, address, name of the symbol from
200   multiple calls to this function.  Ugly and confusing.
201*/
202static
203Bool get_elf_symbol_info (
204        /* INPUTS */
205        struct _DebugInfo* di, /* containing DebugInfo */
206        ElfXX_Sym* sym,        /* ELF symbol */
207        Char*      sym_name,   /* name */
208        Addr       sym_svma,   /* address as stated in the object file */
209        UChar*     opd_img,    /* oimage of .opd sec (ppc64-linux only) */
210        PtrdiffT   opd_bias,   /* for biasing AVMAs found in .opd */
211        /* OUTPUTS */
212        Char** sym_name_out,   /* name we should record */
213        Addr*  sym_avma_out,   /* addr we should record */
214        Int*   sym_size_out,   /* symbol size */
215        Addr*  sym_tocptr_out, /* ppc64-linux only: R2 value to be
216                                  used on entry */
217        Bool*  from_opd_out,   /* ppc64-linux only: did we deref an
218                                  .opd entry? */
219        Bool*  is_text_out     /* is this a text symbol? */
220     )
221{
222   Bool plausible, is_in_opd;
223   Bool in_text, in_data, in_sdata, in_rodata, in_bss, in_sbss;
224
225   /* Set defaults */
226   *sym_name_out   = sym_name;
227   *sym_avma_out   = sym_svma; /* we will bias this shortly */
228   *is_text_out    = True;
229   *sym_size_out   = (Int)sym->st_size;
230   *sym_tocptr_out = 0; /* unknown/inapplicable */
231   *from_opd_out   = False;
232
233   /* Figure out if we're interested in the symbol.  Firstly, is it of
234      the right flavour?  */
235   plausible
236      = (ELFXX_ST_BIND(sym->st_info) == STB_GLOBAL
237         || ELFXX_ST_BIND(sym->st_info) == STB_LOCAL
238         || ELFXX_ST_BIND(sym->st_info) == STB_WEAK
239        )
240        &&
241        (ELFXX_ST_TYPE(sym->st_info) == STT_FUNC
242         || ELFXX_ST_TYPE(sym->st_info) == STT_OBJECT
243        );
244
245   /* Now bias sym_avma_out accordingly */
246#if 0
247   /* This works, but seems a bit crude */
248   if (ELFXX_ST_TYPE(sym->st_info) == STT_OBJECT) {
249      *is_text_out = False;
250      *sym_avma_out += di->data_bias;
251   } else {
252      *is_text_out = True;
253      *sym_avma_out += di->text_bias;
254   }
255#else
256   /* Try to figure out exactly which section the symbol is from and
257      bias accordingly.  Screws up if the previously deduced section
258      svma address ranges are wrong. */
259   if (di->text_present
260       && di->text_size > 0
261       && sym_svma >= di->text_svma
262       && sym_svma < di->text_svma + di->text_size) {
263      *is_text_out = True;
264      *sym_avma_out += di->text_bias;
265   } else
266   if (di->data_present
267       && di->data_size > 0
268       && sym_svma >= di->data_svma
269       && sym_svma < di->data_svma + di->data_size) {
270      *is_text_out = False;
271      *sym_avma_out += di->data_bias;
272   } else
273   if (di->sdata_present
274       && di->sdata_size > 0
275       && sym_svma >= di->sdata_svma
276       && sym_svma < di->sdata_svma + di->sdata_size) {
277      *is_text_out = False;
278      *sym_avma_out += di->sdata_bias;
279   } else
280   if (di->rodata_present
281       && di->rodata_size > 0
282       && sym_svma >= di->rodata_svma
283       && sym_svma < di->rodata_svma + di->rodata_size) {
284      *is_text_out = False;
285      *sym_avma_out += di->rodata_bias;
286   } else
287   if (di->bss_present
288       && di->bss_size > 0
289       && sym_svma >= di->bss_svma
290       && sym_svma < di->bss_svma + di->bss_size) {
291      *is_text_out = False;
292      *sym_avma_out += di->bss_bias;
293   } else
294   if (di->sbss_present
295       && di->sbss_size > 0
296       && sym_svma >= di->sbss_svma
297       && sym_svma < di->sbss_svma + di->sbss_size) {
298      *is_text_out = False;
299      *sym_avma_out += di->sbss_bias;
300   } else {
301      /* Assume it's in .text.  Is this a good idea? */
302      *is_text_out = True;
303      *sym_avma_out += di->text_bias;
304   }
305#endif
306
307#  if defined(VGP_ppc64_linux)
308   /* Allow STT_NOTYPE in the very special case where we're running on
309      ppc64-linux and the symbol is one which the .opd-chasing hack
310      below will chase. */
311   if (!plausible
312       && *is_text_out
313       && ELFXX_ST_TYPE(sym->st_info) == STT_NOTYPE
314       && sym->st_size > 0
315       && di->opd_present
316       && di->opd_size > 0
317       && *sym_avma_out >= di->opd_avma
318       && *sym_avma_out <  di->opd_avma + di->opd_size)
319      plausible = True;
320#  endif
321
322   if (!plausible)
323      return False;
324
325   /* Ignore if nameless, or zero-sized. */
326   if (sym->st_name == (ElfXX_Word)0
327       || /* VG_(strlen)(sym_name) == 0 */
328          /* equivalent but cheaper ... */
329          sym_name[0] == 0
330       || sym->st_size == 0) {
331      TRACE_SYMTAB("    ignore -- size=0: %s\n", sym_name);
332      return False;
333   }
334
335   /* This seems to significantly reduce the number of junk
336      symbols, and particularly reduces the number of
337      overlapping address ranges.  Don't ask me why ... */
338   if ((Int)sym->st_value == 0) {
339      TRACE_SYMTAB( "    ignore -- valu=0: %s\n", sym_name);
340      return False;
341   }
342
343   /* If it's apparently in a GOT or PLT, it's really a reference to a
344      symbol defined elsewhere, so ignore it. */
345   if (di->got_present
346       && di->got_size > 0
347       && *sym_avma_out >= di->got_avma
348       && *sym_avma_out <  di->got_avma + di->got_size) {
349      TRACE_SYMTAB("    ignore -- in GOT: %s\n", sym_name);
350      return False;
351   }
352   if (di->plt_present
353       && di->plt_size > 0
354       && *sym_avma_out >= di->plt_avma
355       && *sym_avma_out <  di->plt_avma + di->plt_size) {
356      TRACE_SYMTAB("    ignore -- in PLT: %s\n", sym_name);
357      return False;
358   }
359
360   /* ppc64-linux nasty hack: if the symbol is in an .opd section,
361      then really what we have is the address of a function
362      descriptor.  So use the first word of that as the function's
363      text.
364
365      See thread starting at
366      http://gcc.gnu.org/ml/gcc-patches/2004-08/msg00557.html
367   */
368   is_in_opd = False;
369
370   if (di->opd_present
371       && di->opd_size > 0
372       && *sym_avma_out >= di->opd_avma
373       && *sym_avma_out <  di->opd_avma + di->opd_size) {
374#     if !defined(VGP_ppc64_linux)
375      TRACE_SYMTAB("    ignore -- in OPD: %s\n", sym_name);
376      return False;
377#     else
378      Int    offset_in_opd;
379      ULong* fn_descr;
380      Bool   details = 1||False;
381
382      if (details)
383         TRACE_SYMTAB("opdXXX: opd_bias %p, sym_svma_out %p\n",
384                      (void*)(opd_bias), (void*)*sym_avma_out);
385
386      if (!VG_IS_8_ALIGNED(*sym_avma_out)) {
387         TRACE_SYMTAB("    ignore -- not 8-aligned: %s\n", sym_name);
388         return False;
389      }
390
391      /* *sym_avma_out is a vma pointing into the .opd section.  We
392         know the vma of the opd section start, so we can figure out
393         how far into the opd section this is. */
394
395      offset_in_opd = (Addr)(*sym_avma_out) - (Addr)(di->opd_avma);
396      if (offset_in_opd < 0 || offset_in_opd >= di->opd_size) {
397         TRACE_SYMTAB("    ignore -- invalid OPD offset: %s\n", sym_name);
398         return False;
399      }
400
401      /* Now we want to know what's at that offset in the .opd
402         section.  We can't look in the running image since it won't
403         necessarily have been mapped.  But we can consult the oimage.
404         opd_img is the start address of the .opd in the oimage.
405         Hence: */
406
407      fn_descr = (ULong*)(opd_img + offset_in_opd);
408
409      if (details)
410         TRACE_SYMTAB("opdXXY: offset %d,  fn_descr %p\n",
411                      offset_in_opd, fn_descr);
412      if (details)
413         TRACE_SYMTAB("opdXXZ: *fn_descr %p\n", (void*)(fn_descr[0]));
414
415      /* opd_bias is the what we have to add to SVMAs found in .opd to
416         get plausible .text AVMAs for the entry point, and .data
417         AVMAs (presumably) for the TOC locations.  We use the caller
418         supplied value (which is di->text_bias) for both of these.
419         Not sure why that is correct - it seems to work, and sounds
420         OK for fn_descr[0], but surely we need to use the data bias
421         and not the text bias for fn_descr[1] ?  Oh Well.
422      */
423      *sym_avma_out   = fn_descr[0] + opd_bias;
424      *sym_tocptr_out = fn_descr[1] + opd_bias;
425      *from_opd_out   = True;
426      is_in_opd = True;
427
428      /* Do a final sanity check: if the symbol falls outside the
429         DebugInfo's mapped range, ignore it.  Since *sym_avma_out has
430         been updated, that can be achieved simply by falling through
431         to the test below. */
432
433#     endif /* ppc64-linux nasty hack */
434   }
435
436   /* Here's yet another ppc64-linux hack.  Get rid of leading dot if
437      the symbol is outside .opd. */
438#  if defined(VGP_ppc64_linux)
439   if (di->opd_size > 0
440       && !is_in_opd
441       && sym_name[0] == '.') {
442      vg_assert(!(*from_opd_out));
443      *sym_name_out = &sym_name[1];
444   }
445#  endif
446
447   /* If no part of the symbol falls within the mapped range,
448      ignore it. */
449
450   in_text
451      = di->text_present
452        && di->text_size > 0
453        && !(*sym_avma_out + *sym_size_out <= di->text_avma
454             || *sym_avma_out >= di->text_avma + di->text_size);
455
456   in_data
457      = di->data_present
458        && di->data_size > 0
459        && !(*sym_avma_out + *sym_size_out <= di->data_avma
460             || *sym_avma_out >= di->data_avma + di->data_size);
461
462   in_sdata
463      = di->sdata_present
464        && di->sdata_size > 0
465        && !(*sym_avma_out + *sym_size_out <= di->sdata_avma
466             || *sym_avma_out >= di->sdata_avma + di->sdata_size);
467
468   in_rodata
469      = di->rodata_present
470        && di->rodata_size > 0
471        && !(*sym_avma_out + *sym_size_out <= di->rodata_avma
472             || *sym_avma_out >= di->rodata_avma + di->rodata_size);
473
474   in_bss
475      = di->bss_present
476        && di->bss_size > 0
477        && !(*sym_avma_out + *sym_size_out <= di->bss_avma
478             || *sym_avma_out >= di->bss_avma + di->bss_size);
479
480   in_sbss
481      = di->sbss_present
482        && di->sbss_size > 0
483        && !(*sym_avma_out + *sym_size_out <= di->sbss_avma
484             || *sym_avma_out >= di->sbss_avma + di->sbss_size);
485
486
487   if (*is_text_out) {
488      /* This used to reject any symbol falling outside the text
489         segment ("if (!in_text) ...").  Now it is relaxed slightly,
490         to reject only symbols which fall outside the area mapped
491         r-x.  This is in accordance with r7427.  See
492         "Comment_Regarding_Text_Range_Checks" in storage.c for
493         background. */
494      Bool in_rx;
495      vg_assert(di->have_rx_map);
496      in_rx = (!(*sym_avma_out + *sym_size_out <= di->rx_map_avma
497                 || *sym_avma_out >= di->rx_map_avma + di->rx_map_size));
498      if (in_text)
499         vg_assert(in_rx);
500      if (!in_rx) {
501         TRACE_SYMTAB(
502            "ignore -- %#lx .. %#lx outside .text svma range %#lx .. %#lx\n",
503            *sym_avma_out, *sym_avma_out + *sym_size_out,
504            di->text_avma,
505            di->text_avma + di->text_size);
506         return False;
507      }
508   } else {
509     if (!(in_data || in_sdata || in_rodata || in_bss || in_sbss)) {
510         TRACE_SYMTAB(
511            "ignore -- %#lx .. %#lx outside .data / .sdata / .rodata / .bss / .sbss svma ranges\n",
512            *sym_avma_out, *sym_avma_out + *sym_size_out);
513         return False;
514      }
515   }
516
517#  if defined(VGP_ppc64_linux)
518   /* It's crucial that we never add symbol addresses in the .opd
519      section.  This would completely mess up function redirection and
520      intercepting.  This assert ensures that any symbols that make it
521      into the symbol table on ppc64-linux don't point into .opd. */
522   if (di->opd_present && di->opd_size > 0) {
523      vg_assert(*sym_avma_out + *sym_size_out <= di->opd_avma
524                || *sym_avma_out >= di->opd_avma + di->opd_size);
525   }
526#  endif
527
528   /* Acquire! */
529   return True;
530}
531
532
533/* Read an ELF symbol table (normal or dynamic).  This one is for the
534   "normal" case ({x86,amd64,ppc32}-linux). */
535static
536__attribute__((unused)) /* not referred to on all targets */
537void read_elf_symtab__normal(
538        struct _DebugInfo* di, UChar* tab_name,
539        ElfXX_Sym* symtab_img, SizeT symtab_szB,
540        UChar*     strtab_img, SizeT strtab_szB,
541        UChar*     opd_img /* ppc64-linux only */
542     )
543{
544   Word       i;
545   Addr       sym_svma, sym_avma_really;
546   Char      *sym_name, *sym_name_really;
547   Int        sym_size;
548   Addr       sym_tocptr;
549   Bool       from_opd, is_text;
550   DiSym      risym;
551   ElfXX_Sym *sym;
552
553   if (strtab_img == NULL || symtab_img == NULL) {
554      Char buf[80];
555      vg_assert(VG_(strlen)(tab_name) < 40);
556      VG_(sprintf)(buf, "   object doesn't have a %s", tab_name);
557      ML_(symerr)(di, False, buf);
558      return;
559   }
560
561   TRACE_SYMTAB("\n--- Reading (ELF, standard) %s (%ld entries) ---\n",
562                tab_name, symtab_szB/sizeof(ElfXX_Sym) );
563
564   /* Perhaps should start at i = 1; ELF docs suggest that entry
565      0 always denotes 'unknown symbol'. */
566   for (i = 1; i < (Word)(symtab_szB/sizeof(ElfXX_Sym)); i++) {
567      sym      = & symtab_img[i];
568      sym_name = (UChar*)(strtab_img + sym->st_name);
569      sym_svma = sym->st_value;
570
571      if (di->trace_symtab)
572         show_raw_elf_symbol(i, sym, sym_name, sym_svma, False);
573
574      if (get_elf_symbol_info(di, sym, sym_name, sym_svma,
575                              opd_img, di->text_bias,
576                              &sym_name_really,
577                              &sym_avma_really,
578                              &sym_size,
579                              &sym_tocptr,
580                              &from_opd, &is_text)) {
581
582         risym.addr   = sym_avma_really;
583         risym.size   = sym_size;
584         risym.name   = ML_(addStr) ( di, sym_name_really, -1 );
585         risym.tocptr = sym_tocptr;
586         risym.isText = is_text;
587         vg_assert(risym.name != NULL);
588         vg_assert(risym.tocptr == 0); /* has no role except on ppc64-linux */
589         ML_(addSym) ( di, &risym );
590
591         if (di->trace_symtab) {
592            VG_(printf)("    rec(%c) [%4ld]:          "
593                        "  val %#010lx, sz %4d  %s\n",
594                        is_text ? 't' : 'd',
595                        i,
596                        risym.addr,
597                        (Int)risym.size,
598                        (HChar*)risym.name
599            );
600         }
601
602      }
603   }
604}
605
606
607/* Read an ELF symbol table (normal or dynamic).  This one is for
608   ppc64-linux, which requires special treatment. */
609
610typedef
611   struct {
612      Addr   addr;
613      UChar* name;
614   }
615   TempSymKey;
616
617typedef
618   struct {
619      TempSymKey key;
620      Addr       tocptr;
621      Int        size;
622      Bool       from_opd;
623      Bool       is_text;
624   }
625   TempSym;
626
627static Word cmp_TempSymKey ( TempSymKey* key1, TempSym* elem2 ) {
628   if (key1->addr < elem2->key.addr) return -1;
629   if (key1->addr > elem2->key.addr) return 1;
630   return (Word)VG_(strcmp)(key1->name, elem2->key.name);
631}
632
633static
634__attribute__((unused)) /* not referred to on all targets */
635void read_elf_symtab__ppc64_linux(
636        struct _DebugInfo* di, UChar* tab_name,
637        ElfXX_Sym* symtab_img, SizeT symtab_szB,
638        UChar*     strtab_img, SizeT strtab_szB,
639        UChar*     opd_img /* ppc64-linux only */
640     )
641{
642   Word        i;
643   Int         old_size;
644   Addr        sym_svma, sym_avma_really;
645   Char       *sym_name, *sym_name_really;
646   Int         sym_size;
647   Addr        sym_tocptr, old_tocptr;
648   Bool        from_opd, modify_size, modify_tocptr, is_text;
649   DiSym       risym;
650   ElfXX_Sym  *sym;
651   OSet       *oset;
652   TempSymKey  key;
653   TempSym    *elem;
654   TempSym    *prev;
655
656   if (strtab_img == NULL || symtab_img == NULL) {
657      Char buf[80];
658      vg_assert(VG_(strlen)(tab_name) < 40);
659      VG_(sprintf)(buf, "   object doesn't have a %s", tab_name);
660      ML_(symerr)(di, False, buf);
661      return;
662   }
663
664   TRACE_SYMTAB("\n--- Reading (ELF, ppc64-linux) %s (%ld entries) ---\n",
665                tab_name, symtab_szB/sizeof(ElfXX_Sym) );
666
667   oset = VG_(OSetGen_Create)( offsetof(TempSym,key),
668                               (OSetCmp_t)cmp_TempSymKey,
669                               ML_(dinfo_zalloc), "di.respl.1",
670                               ML_(dinfo_free) );
671   vg_assert(oset);
672
673   /* Perhaps should start at i = 1; ELF docs suggest that entry
674      0 always denotes 'unknown symbol'. */
675   for (i = 1; i < (Word)(symtab_szB/sizeof(ElfXX_Sym)); i++) {
676      sym      = & symtab_img[i];
677      sym_name = (Char*)(strtab_img + sym->st_name);
678      sym_svma = sym->st_value;
679
680      if (di->trace_symtab)
681         show_raw_elf_symbol(i, sym, sym_name, sym_svma, True);
682
683      if (get_elf_symbol_info(di, sym, sym_name, sym_svma,
684                              opd_img, di->text_bias,
685                              &sym_name_really,
686                              &sym_avma_really,
687                              &sym_size,
688                              &sym_tocptr,
689                              &from_opd, &is_text)) {
690
691         /* Check if we've seen this (name,addr) key before. */
692         key.addr = sym_avma_really;
693         key.name = sym_name_really;
694         prev = VG_(OSetGen_Lookup)( oset, &key );
695
696         if (prev) {
697
698            /* Seen it before.  Fold in whatever new info we can. */
699            modify_size   = False;
700            modify_tocptr = False;
701            old_size   = 0;
702            old_tocptr = 0;
703
704            if (prev->from_opd && !from_opd
705                && (prev->size == 24 || prev->size == 16)
706                && sym_size != prev->size) {
707               /* Existing one is an opd-redirect, with a bogus size,
708                  so the only useful new fact we have is the real size
709                  of the symbol. */
710               modify_size = True;
711               old_size = prev->size;
712               prev->size = sym_size;
713            }
714            else
715            if (!prev->from_opd && from_opd
716                && (sym_size == 24 || sym_size == 16)) {
717               /* Existing one is non-opd, new one is opd.  What we
718                  can acquire from the new one is the TOC ptr to be
719                  used.  Since the existing sym is non-toc, it
720                  shouldn't currently have an known TOC ptr. */
721               vg_assert(prev->tocptr == 0);
722               modify_tocptr = True;
723               old_tocptr = prev->tocptr;
724               prev->tocptr = sym_tocptr;
725            }
726            else {
727               /* ignore. can we do better here? */
728            }
729
730            /* Only one or the other is possible (I think) */
731            vg_assert(!(modify_size && modify_tocptr));
732
733            if (modify_size && di->trace_symtab) {
734               VG_(printf)("    modify (old sz %4d)    "
735                           " val %#010lx, toc %#010lx, sz %4d  %s\n",
736                           old_size,
737                           prev->key.addr,
738                           prev->tocptr,
739                           (Int)   prev->size,
740                           (HChar*)prev->key.name
741               );
742            }
743            if (modify_tocptr && di->trace_symtab) {
744               VG_(printf)("    modify (upd tocptr)     "
745                           " val %#010lx, toc %#010lx, sz %4d  %s\n",
746                           prev->key.addr,
747                           prev->tocptr,
748                           (Int)   prev->size,
749                           (HChar*)prev->key.name
750               );
751            }
752
753         } else {
754
755            /* A new (name,addr) key.  Add and continue. */
756            elem = VG_(OSetGen_AllocNode)(oset, sizeof(TempSym));
757            vg_assert(elem);
758            elem->key      = key;
759            elem->tocptr   = sym_tocptr;
760            elem->size     = sym_size;
761            elem->from_opd = from_opd;
762            elem->is_text  = is_text;
763            VG_(OSetGen_Insert)(oset, elem);
764            if (di->trace_symtab) {
765               VG_(printf)("   to-oset [%4ld]:          "
766                           "  val %#010lx, toc %#010lx, sz %4d  %s\n",
767                           i,
768                           elem->key.addr,
769                           elem->tocptr,
770                           (Int)   elem->size,
771                           (HChar*)elem->key.name
772               );
773            }
774
775         }
776      }
777   }
778
779   /* All the syms that matter are in the oset.  Now pull them out,
780      build a "standard" symbol table, and nuke the oset. */
781
782   i = 0;
783   VG_(OSetGen_ResetIter)( oset );
784
785   while ( (elem = VG_(OSetGen_Next)(oset)) ) {
786      risym.addr   = elem->key.addr;
787      risym.size   = elem->size;
788      risym.name   = ML_(addStr) ( di, elem->key.name, -1 );
789      risym.tocptr = elem->tocptr;
790      risym.isText = elem->is_text;
791      vg_assert(risym.name != NULL);
792
793      ML_(addSym) ( di, &risym );
794      if (di->trace_symtab) {
795         VG_(printf)("    rec(%c) [%4ld]:          "
796                     "   val %#010lx, toc %#010lx, sz %4d  %s\n",
797                     risym.isText ? 't' : 'd',
798                     i,
799                     risym.addr,
800                     risym.tocptr,
801                     (Int)   risym.size,
802                     (HChar*)risym.name
803               );
804      }
805      i++;
806   }
807
808   VG_(OSetGen_Destroy)( oset );
809}
810
811
812/*
813 * This routine for calculating the CRC for a separate debug file
814 * is GPLed code borrowed from GNU binutils.
815 */
816static UInt
817calc_gnu_debuglink_crc32(UInt crc, const UChar *buf, Int len)
818{
819  static const UInt crc32_table[256] =
820    {
821      0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
822      0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
823      0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
824      0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
825      0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
826      0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
827      0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
828      0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
829      0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
830      0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
831      0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
832      0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
833      0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
834      0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
835      0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
836      0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
837      0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
838      0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
839      0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
840      0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
841      0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
842      0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
843      0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
844      0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
845      0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
846      0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
847      0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
848      0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
849      0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
850      0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
851      0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
852      0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
853      0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
854      0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
855      0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
856      0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
857      0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
858      0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
859      0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
860      0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
861      0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
862      0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
863      0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
864      0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
865      0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
866      0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
867      0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
868      0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
869      0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
870      0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
871      0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
872      0x2d02ef8d
873    };
874  const UChar *end;
875
876  crc = ~crc & 0xffffffff;
877  for (end = buf + len; buf < end; ++ buf)
878    crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
879  return ~crc & 0xffffffff;;
880}
881
882/*
883 * Try and open a separate debug file, ignoring any where the CRC does
884 * not match the value from the main object file.
885 */
886static
887Addr open_debug_file( Char* name, UInt crc, /*OUT*/UWord* size )
888{
889   SysRes fd, sres;
890   struct vg_stat stat_buf;
891   UInt calccrc;
892
893   fd = VG_(open)(name, VKI_O_RDONLY, 0);
894   if (fd.isError)
895      return 0;
896
897   if (VG_(fstat)(fd.res, &stat_buf) != 0) {
898      VG_(close)(fd.res);
899      return 0;
900   }
901
902   if (VG_(clo_verbosity) > 1)
903      VG_(message)(Vg_DebugMsg, "Reading debug info from %s ..", name);
904
905   *size = stat_buf.st_size;
906
907   sres = VG_(am_mmap_file_float_valgrind)
908             ( *size, VKI_PROT_READ, fd.res, 0 );
909
910   VG_(close)(fd.res);
911
912   if (sres.isError)
913      return 0;
914
915   calccrc = calc_gnu_debuglink_crc32(0, (UChar*)sres.res, *size);
916   if (calccrc != crc) {
917      SysRes res = VG_(am_munmap_valgrind)(sres.res, *size);
918      vg_assert(!res.isError);
919      if (VG_(clo_verbosity) > 1)
920         VG_(message)(Vg_DebugMsg,
921            ".. CRC mismatch (computed %08x wanted %08x)", calccrc, crc);
922      return 0;
923   }
924
925   return sres.res;
926}
927
928/*
929 * Try to find a separate debug file for a given object file.
930 */
931static
932Addr find_debug_file( struct _DebugInfo* di,
933                      Char* objpath, Char* debugname,
934                      UInt crc, /*OUT*/UWord* size )
935{
936   Char *objdir = ML_(dinfo_strdup)("di.fdf.1", objpath);
937   Char *objdirptr;
938   Char *debugpath;
939   Addr addr = 0;
940
941   if ((objdirptr = VG_(strrchr)(objdir, '/')) != NULL)
942      *objdirptr = '\0';
943
944   debugpath = ML_(dinfo_zalloc)(
945                  "di.fdf.2",
946                  VG_(strlen)(objdir) + VG_(strlen)(debugname) + 32);
947
948   VG_(sprintf)(debugpath, "%s/%s", objdir, debugname);
949
950   if ((addr = open_debug_file(debugpath, crc, size)) == 0) {
951      VG_(sprintf)(debugpath, "%s/.debug/%s", objdir, debugname);
952      if ((addr = open_debug_file(debugpath, crc, size)) == 0) {
953         VG_(sprintf)(debugpath, "/usr/lib/debug%s/%s", objdir, debugname);
954         addr = open_debug_file(debugpath, crc, size);
955      }
956   }
957
958   if (addr) {
959      TRACE_SYMTAB("\n");
960      TRACE_SYMTAB("------ Found a debuginfo file: %s\n", debugpath);
961   }
962
963   ML_(dinfo_free)(debugpath);
964   ML_(dinfo_free)(objdir);
965
966   return addr;
967}
968
969
970static Bool contained_within ( Addr outer, UWord n_outer,
971                               Addr inner, UWord n_inner )
972{
973   if (n_outer == 0 || n_inner == 0)
974      return False;
975   /* Simplistic .. assumes no wraparound (reasonably enough) */
976   if (inner >= outer && inner+n_inner <= outer+n_outer)
977      return True;
978   return False;
979}
980
981static void* INDEX_BIS ( void* base, Word idx, Word scale ) {
982   return (void*)( ((UChar*)base) + idx * scale );
983}
984
985
986/* Find the file offset corresponding to SVMA by using the program
987   headers.  This is taken from binutils-2.17/binutils/readelf.c
988   offset_from_vma(). */
989static
990Word file_offset_from_svma ( /*OUT*/Bool* ok,
991                             Addr         svma,
992                             ElfXX_Phdr*  phdr_img,
993                             Word         phdr_nent,
994                             Word         phdr_ent_szB )
995{
996   Word        i;
997   ElfXX_Phdr* seg;
998   for (i = 0; i < phdr_nent; i++) {
999      seg = INDEX_BIS( phdr_img, i, phdr_ent_szB );
1000      if (seg->p_type != PT_LOAD)
1001         continue;
1002      if (svma >= (seg->p_vaddr & -seg->p_align)
1003          && svma + 1 <= seg->p_vaddr + seg->p_filesz) {
1004         *ok = True;
1005         return svma - seg->p_vaddr + seg->p_offset;
1006      }
1007   }
1008   *ok = False;
1009   return 0;
1010}
1011
1012/* The central function for reading ELF debug info.  For the
1013   object/exe specified by the DebugInfo, find ELF sections, then read
1014   the symbols, line number info, file name info, CFA (stack-unwind
1015   info) and anything else we want, into the tables within the
1016   supplied DebugInfo.
1017*/
1018Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
1019{
1020   Bool          res, ok;
1021   SysRes        fd, sres;
1022   Word          i;
1023
1024   /* Image addresses for the ELF file we're working with. */
1025   Addr          oimage   = 0;
1026   UWord         n_oimage = 0;
1027
1028   /* Ditto for any ELF debuginfo file that we might happen to load. */
1029   Addr          dimage   = 0;
1030   UWord         n_dimage = 0;
1031
1032   /* ELF header for the main file.  Should == oimage since is at
1033      start of file. */
1034   ElfXX_Ehdr* ehdr_img = NULL;
1035
1036   /* Program header table image addr, # entries, entry size */
1037   ElfXX_Phdr* phdr_img     = NULL;
1038   UWord       phdr_nent    = 0;
1039   UWord       phdr_ent_szB = 0;
1040
1041   /* Section header image addr, # entries, entry size.  Also the
1042      associated string table. */
1043   ElfXX_Shdr* shdr_img        = NULL;
1044   UWord       shdr_nent       = 0;
1045   UWord       shdr_ent_szB    = 0;
1046   UChar*      shdr_strtab_img = NULL;
1047
1048   /* SVMAs covered by rx and rw segments and corresponding bias. */
1049   Addr     rx_svma_base = 0;
1050   Addr     rx_svma_limit = 0;
1051   PtrdiffT rx_bias = 0;
1052   Addr     rw_svma_base = 0;
1053   Addr     rw_svma_limit = 0;
1054   PtrdiffT rw_bias = 0;
1055
1056   vg_assert(di);
1057   vg_assert(di->have_rx_map == True);
1058   vg_assert(di->have_rw_map == True);
1059   vg_assert(di->rx_map_size > 0);
1060   vg_assert(di->rw_map_size > 0);
1061   vg_assert(di->have_dinfo == False);
1062   vg_assert(di->filename);
1063   vg_assert(!di->memname);
1064   vg_assert(!di->symtab);
1065   vg_assert(!di->loctab);
1066   vg_assert(!di->cfsi);
1067   vg_assert(!di->cfsi_exprs);
1068   vg_assert(!di->strchunks);
1069   vg_assert(!di->soname);
1070
1071   /* If these don't hold true, it means that m_syswrap/m_aspacemgr
1072      managed to do a mapping where the start isn't page aligned.
1073      Which sounds pretty bogus to me. */
1074   vg_assert(VG_IS_PAGE_ALIGNED(di->rx_map_avma));
1075   vg_assert(VG_IS_PAGE_ALIGNED(di->rw_map_avma));
1076
1077   /* ----------------------------------------------------------
1078      At this point, there is very little information in the
1079      DebugInfo.  We only know that something that looks like an ELF
1080      file has been mapped rx-ishly as recorded with the di->*rx_map*
1081      fields and has also been mapped rw-ishly as recorded with the
1082      di->*rw_map* fields.  First we examine the file's ELF Program
1083      Header, and, by comparing that against the di->*r{w,x}_map*
1084      info, try to figure out the AVMAs for the sections we care
1085      about, that should have been mapped: text, data, sdata, bss got,
1086      plt, and toc.
1087      ---------------------------------------------------------- */
1088
1089   oimage = (Addr)NULL;
1090   if (VG_(clo_verbosity) > 1 || VG_(clo_trace_redir))
1091      VG_(message)(Vg_DebugMsg, "Reading syms from %s (%#lx)",
1092                                di->filename, di->rx_map_avma );
1093
1094   /* mmap the object image aboard, so that we can read symbols and
1095      line number info out of it.  It will be munmapped immediately
1096      thereafter; it is only aboard transiently. */
1097
1098   fd = VG_(open)(di->filename, VKI_O_RDONLY, 0);
1099   if (fd.isError) {
1100      ML_(symerr)(di, True, "Can't open .so/.exe to read symbols?!");
1101      return False;
1102   }
1103
1104   { Long n_oimageLL = VG_(fsize)(fd.res);
1105     if (n_oimageLL <= 0) {
1106        ML_(symerr)(di, True, "Can't stat .so/.exe (to determine its size)?!");
1107        VG_(close)(fd.res);
1108        return False;
1109     }
1110     n_oimage = (UWord)(ULong)n_oimageLL;
1111   }
1112
1113   sres = VG_(am_mmap_file_float_valgrind)
1114             ( n_oimage, VKI_PROT_READ, fd.res, 0 );
1115
1116   VG_(close)(fd.res);
1117
1118   if (sres.isError) {
1119      VG_(message)(Vg_UserMsg, "warning: mmap failed on %s", di->filename );
1120      VG_(message)(Vg_UserMsg, "         no symbols or debug info loaded" );
1121      return False;
1122   }
1123
1124   oimage = sres.res;
1125   /* Check against wraparound.  am_mmap_file_float_valgrind should
1126      not produce a wrapped-around mapping. */
1127   vg_assert(n_oimage > 0);
1128   vg_assert(oimage + n_oimage > oimage);
1129
1130   if (0) {
1131      VG_(printf)("read_elf_debug_info: OIMAGE = %p - %p\n",
1132                  (void*)oimage, (void*)(oimage + (UWord)n_oimage));
1133   }
1134
1135   /* Ok, the object image is safely in oimage[0 .. n_oimage-1].  Now
1136      verify that it is a valid ELF .so or executable image. */
1137   res      = False;
1138   ok       = (n_oimage >= sizeof(ElfXX_Ehdr));
1139   ehdr_img = (ElfXX_Ehdr*)oimage;
1140
1141   if (ok)
1142      ok &= ML_(is_elf_object_file)(ehdr_img, n_oimage);
1143
1144   if (!ok) {
1145      ML_(symerr)(di, True, "Invalid ELF Header");
1146      goto out;
1147   }
1148
1149   /* Find where the program and section header tables are, and give
1150      up if either is missing or outside the image (bogus). */
1151   phdr_img     = (ElfXX_Phdr*)( ((UChar*)ehdr_img) + ehdr_img->e_phoff );
1152   phdr_nent    = ehdr_img->e_phnum;
1153   phdr_ent_szB = ehdr_img->e_phentsize;
1154
1155   shdr_img     = (ElfXX_Shdr*)( ((UChar*)ehdr_img) + ehdr_img->e_shoff );
1156   shdr_nent    = ehdr_img->e_shnum;
1157   shdr_ent_szB = ehdr_img->e_shentsize;
1158
1159   TRACE_SYMTAB("------ Basic facts about the object ------\n");
1160   TRACE_SYMTAB("object: img %p n_oimage %ld\n",
1161               (void*)oimage, n_oimage);
1162   TRACE_SYMTAB("phdr:   img %p nent %ld ent_szB %ld\n",
1163               phdr_img, phdr_nent, phdr_ent_szB);
1164   TRACE_SYMTAB("shdr:   img %p nent %ld ent_szB %ld\n",
1165               shdr_img, shdr_nent, shdr_ent_szB);
1166
1167   if (phdr_nent == 0
1168       || !contained_within(
1169             oimage, n_oimage,
1170             (Addr)phdr_img, phdr_nent * phdr_ent_szB)) {
1171      ML_(symerr)(di, True, "Missing or invalid ELF Program Header Table");
1172      goto out;
1173   }
1174
1175   if (shdr_nent == 0
1176       || !contained_within(
1177             oimage, n_oimage,
1178             (Addr)shdr_img, shdr_nent * shdr_ent_szB)) {
1179      ML_(symerr)(di, True, "Missing or invalid ELF Section Header Table");
1180      goto out;
1181   }
1182
1183   /* Also find the section header's string table, and validate. */
1184   /* checked previously by is_elf_object_file: */
1185   vg_assert( ehdr_img->e_shstrndx != SHN_UNDEF );
1186
1187   shdr_strtab_img
1188      = (UChar*)( ((UChar*)ehdr_img)
1189                  + shdr_img[ehdr_img->e_shstrndx].sh_offset);
1190   if (!contained_within( oimage, n_oimage,
1191                          (Addr)shdr_strtab_img,
1192                          1/*bogus, but we don't know the real size*/ )) {
1193      ML_(symerr)(di, True, "Invalid ELF Section Header String Table");
1194      goto out;
1195   }
1196
1197   TRACE_SYMTAB("shdr:   string table at %p\n", shdr_strtab_img );
1198
1199   /* Do another amazingly tedious thing: find out the .soname for
1200      this object.  Apparently requires looking through the program
1201      header table. */
1202   TRACE_SYMTAB("\n");
1203   TRACE_SYMTAB("------ Looking for the soname ------\n");
1204   vg_assert(di->soname == NULL);
1205   {
1206      ElfXX_Addr prev_svma = 0;
1207
1208      for (i = 0; i < phdr_nent; i++) {
1209         ElfXX_Phdr* phdr = INDEX_BIS( phdr_img, i, phdr_ent_szB );
1210
1211         /* Make sure the PT_LOADable entries are in order */
1212         if (phdr->p_type == PT_LOAD) {
1213            TRACE_SYMTAB("PT_LOAD in order?: %#lx %#lx\n",
1214                         prev_svma + 0UL,
1215                         phdr->p_vaddr + 0UL);
1216            if (phdr->p_vaddr < prev_svma) {
1217               ML_(symerr)(di, True,
1218                           "ELF Program Headers are not in ascending order");
1219               goto out;
1220            }
1221            prev_svma = phdr->p_vaddr;
1222            if (rx_svma_limit == 0
1223                && phdr->p_offset >= di->rx_map_foff
1224                && phdr->p_offset < di->rx_map_foff + di->rx_map_size
1225                && phdr->p_offset + phdr->p_filesz <= di->rx_map_foff + di->rx_map_size) {
1226               rx_svma_base = phdr->p_vaddr;
1227               rx_svma_limit = phdr->p_vaddr + phdr->p_memsz;
1228               rx_bias = di->rx_map_avma - di->rx_map_foff + phdr->p_offset - phdr->p_vaddr;
1229            }
1230            else if (rw_svma_limit == 0
1231                     && phdr->p_offset >= di->rw_map_foff
1232                     && phdr->p_offset < di->rw_map_foff + di->rw_map_size
1233                     && phdr->p_offset + phdr->p_filesz <= di->rw_map_foff + di->rw_map_size) {
1234               rw_svma_base = phdr->p_vaddr;
1235               rw_svma_limit = phdr->p_vaddr + phdr->p_memsz;
1236               rw_bias = di->rw_map_avma - di->rw_map_foff + phdr->p_offset - phdr->p_vaddr;
1237            }
1238         }
1239
1240         /* Try to get the soname.  If there isn't one, use "NONE".
1241            The seginfo needs to have some kind of soname in order to
1242            facilitate writing redirect functions, since all redirect
1243            specifications require a soname (pattern). */
1244         if (phdr->p_type == PT_DYNAMIC && di->soname == NULL) {
1245            ElfXX_Dyn* dyn_img = (ElfXX_Dyn*)( ((UChar*)ehdr_img)
1246                                               + phdr->p_offset);
1247            Word   stroff = -1;
1248            UChar* strtab = NULL;
1249            Word   j;
1250            for (j = 0; dyn_img[j].d_tag != DT_NULL; j++) {
1251               switch (dyn_img[j].d_tag) {
1252                  case DT_SONAME: {
1253                     stroff = dyn_img[j].d_un.d_val;
1254                     break;
1255                  }
1256                  case DT_STRTAB: {
1257                     Bool ok2 = False;
1258                     Word offset = file_offset_from_svma(
1259                                      &ok2,
1260                                      dyn_img[j].d_un.d_ptr,
1261                                      phdr_img,
1262                                      phdr_nent, phdr_ent_szB
1263                                   );
1264                     if (ok2 && strtab == NULL) {
1265                        vg_assert(offset >= 0 && offset <= n_oimage);
1266                        strtab = ((UChar*)ehdr_img) + offset;
1267                     }
1268                     break;
1269                  }
1270                  default:
1271                     break;
1272               }
1273            }
1274            if (stroff != -1 && strtab != NULL) {
1275               TRACE_SYMTAB("Found soname = %s\n", strtab+stroff);
1276               di->soname = ML_(dinfo_strdup)("di.redi.1", strtab+stroff);
1277            }
1278         }
1279      } /* for (i = 0; i < phdr_nent; i++) ... */
1280   } /* look for the soname */
1281
1282   /* If, after looking at all the program headers, we still didn't
1283      find a soname, add a fake one. */
1284   if (di->soname == NULL) {
1285      TRACE_SYMTAB("No soname found; using (fake) \"NONE\"\n");
1286      di->soname = "NONE";
1287   }
1288
1289   vg_assert(rx_svma_limit != 0);
1290   vg_assert(rw_svma_limit != 0);
1291
1292   /* Now read the section table. */
1293   TRACE_SYMTAB("\n");
1294   TRACE_SYMTAB("------ Examining the section headers "
1295                "and program headers ------\n");
1296   TRACE_SYMTAB("rx: at %#lx are mapped foffsets %ld .. %ld\n",
1297               di->rx_map_avma,
1298               di->rx_map_foff, di->rx_map_foff + di->rx_map_size - 1 );
1299   TRACE_SYMTAB("rx: contains svmas %#lx .. %#lx with bias %#lx\n",
1300                rx_svma_base, rx_svma_limit - 1, rx_bias );
1301   TRACE_SYMTAB("rw: at %#lx are mapped foffsets %ld .. %ld\n",
1302               di->rw_map_avma,
1303               di->rw_map_foff, di->rw_map_foff + di->rw_map_size - 1 );
1304   TRACE_SYMTAB("rw: contains svmas %#lx .. %#lx with bias %#lx\n",
1305                rw_svma_base, rw_svma_limit - 1, rw_bias );
1306
1307   for (i = 0; i < shdr_nent; i++) {
1308      ElfXX_Shdr* shdr = INDEX_BIS( shdr_img, i, shdr_ent_szB );
1309      UChar* name = shdr_strtab_img + shdr->sh_name;
1310      Addr   svma = shdr->sh_addr;
1311      OffT   foff = shdr->sh_offset;
1312      UWord  size = shdr->sh_size;
1313      UInt   alyn = shdr->sh_addralign;
1314      Bool   bits = !(shdr->sh_type == SHT_NOBITS);
1315      Bool   inrx = svma >= rx_svma_base && svma < rx_svma_limit;
1316      Bool   inrw = svma >= rw_svma_base && svma < rw_svma_limit;
1317
1318      TRACE_SYMTAB(" [sec %2ld]  %s %s  al%2u  foff %6ld .. %6ld  "
1319                  "  svma %p  name \"%s\"\n",
1320                  i, inrx ? "rx" : "  ", inrw ? "rw" : "  ", alyn,
1321                  foff, foff+size-1, (void*)svma, name );
1322
1323      /* Check for sane-sized segments.  SHT_NOBITS sections have zero
1324         size in the file. */
1325      if ((foff >= n_oimage) || (foff + (bits ? size : 0) > n_oimage)) {
1326         ML_(symerr)(di, True, "ELF Section extends beyond image end");
1327         goto out;
1328      }
1329
1330      /* Check for a sane alignment value. */
1331      if (alyn > 0 && -1 == VG_(log2)(alyn)) {
1332         ML_(symerr)(di, True, "ELF Section contains invalid "
1333                               ".sh_addralign value");
1334         goto out;
1335      }
1336
1337#     define BAD(_secname)                                 \
1338         do { ML_(symerr)(di, True,                        \
1339                          "Can't make sense of " _secname  \
1340                          " section mapping");             \
1341              goto out;                                    \
1342         } while (0)
1343
1344      /* Find avma-s for: .text .data .sdata .rodata .bss .sbss .plt .got .opd
1345         and .eh_frame */
1346
1347      /* Accept .text where mapped as rx (code) */
1348      if (0 == VG_(strcmp)(name, ".text")) {
1349         if (inrx && size > 0 && !di->text_present) {
1350            di->text_present = True;
1351            di->text_svma = svma;
1352            di->text_avma = svma + rx_bias;
1353            di->text_size = size;
1354            di->text_bias = rx_bias;
1355            TRACE_SYMTAB("acquiring .text svma = %#lx .. %#lx\n",
1356                         di->text_svma,
1357                         di->text_svma + di->text_size - 1);
1358            TRACE_SYMTAB("acquiring .text avma = %#lx .. %#lx\n",
1359                         di->text_avma,
1360                         di->text_avma + di->text_size - 1);
1361            TRACE_SYMTAB("acquiring .text bias = %#lx\n", di->text_bias);
1362         } else {
1363            BAD(".text");
1364         }
1365      }
1366
1367      /* Accept .data where mapped as rw (data), even if zero-sized */
1368      if (0 == VG_(strcmp)(name, ".data")) {
1369         if (inrw && size >= 0 && !di->data_present) {
1370            di->data_present = True;
1371            di->data_svma = svma;
1372            di->data_avma = svma + rw_bias;
1373            di->data_size = size;
1374            di->data_bias = rw_bias;
1375            TRACE_SYMTAB("acquiring .data svma = %#lx .. %#lx\n",
1376                         di->data_svma,
1377                         di->data_svma + di->data_size - 1);
1378            TRACE_SYMTAB("acquiring .data avma = %#lx .. %#lx\n",
1379                         di->data_avma,
1380                         di->data_avma + di->data_size - 1);
1381            TRACE_SYMTAB("acquiring .data bias = %#lx\n", di->data_bias);
1382         } else {
1383            BAD(".data");
1384         }
1385      }
1386
1387      /* Accept .sdata where mapped as rw (data) */
1388      if (0 == VG_(strcmp)(name, ".sdata")) {
1389         if (inrw && size > 0 && !di->sdata_present) {
1390            di->sdata_present = True;
1391            di->sdata_svma = svma;
1392            di->sdata_avma = svma + rw_bias;
1393            di->sdata_size = size;
1394            di->sdata_bias = rw_bias;
1395            TRACE_SYMTAB("acquiring .sdata svma = %#lx .. %#lx\n",
1396                         di->sdata_svma,
1397                         di->sdata_svma + di->sdata_size - 1);
1398            TRACE_SYMTAB("acquiring .sdata avma = %#lx .. %#lx\n",
1399                         di->sdata_avma,
1400                         di->sdata_avma + di->sdata_size - 1);
1401            TRACE_SYMTAB("acquiring .sdata bias = %#lx\n", di->sdata_bias);
1402         } else {
1403            BAD(".sdata");
1404         }
1405      }
1406
1407      /* Accept .rodata where mapped as rx (data), even if zero-sized */
1408      if (0 == VG_(strcmp)(name, ".rodata")) {
1409         if (inrx && size >= 0 && !di->rodata_present) {
1410            di->rodata_present = True;
1411            di->rodata_svma = svma;
1412            di->rodata_avma = svma + rx_bias;
1413            di->rodata_size = size;
1414            di->rodata_bias = rx_bias;
1415            TRACE_SYMTAB("acquiring .rodata svma = %#lx .. %#lx\n",
1416                         di->rodata_svma,
1417                         di->rodata_svma + di->rodata_size - 1);
1418            TRACE_SYMTAB("acquiring .rodata avma = %#lx .. %#lx\n",
1419                         di->rodata_avma,
1420                         di->rodata_avma + di->rodata_size - 1);
1421            TRACE_SYMTAB("acquiring .rodata bias = %#lx\n", di->rodata_bias);
1422         } else {
1423            BAD(".rodata");
1424         }
1425      }
1426
1427      /* Accept .bss where mapped as rw (data), even if zero-sized */
1428      if (0 == VG_(strcmp)(name, ".bss")) {
1429         if (inrw && size >= 0 && !di->bss_present) {
1430            di->bss_present = True;
1431            di->bss_svma = svma;
1432            di->bss_avma = svma + rw_bias;
1433            di->bss_size = size;
1434            di->bss_bias = rw_bias;
1435            TRACE_SYMTAB("acquiring .bss svma = %#lx .. %#lx\n",
1436                         di->bss_svma,
1437                         di->bss_svma + di->bss_size - 1);
1438            TRACE_SYMTAB("acquiring .bss avma = %#lx .. %#lx\n",
1439                         di->bss_avma,
1440                         di->bss_avma + di->bss_size - 1);
1441            TRACE_SYMTAB("acquiring .bss bias = %#lx\n", di->bss_bias);
1442         } else
1443
1444         /* Now one from the wtf?! department ... */
1445         if (inrx && (!inrw) && size >= 0 && !di->bss_present) {
1446            /* File contains a .bss, but it got mapped as rx only.
1447               This is very strange.  For now, just pretend we didn't
1448               see it :-) */
1449            di->bss_present = False;
1450            di->bss_svma = 0;
1451            di->bss_avma = 0;
1452            di->bss_size = 0;
1453            di->bss_bias = 0;
1454            if (!VG_(clo_xml)) {
1455               VG_(message)(Vg_UserMsg, "Warning: the following file's .bss is "
1456                                       "mapped r-x only - ignoring .bss syms");
1457               VG_(message)(Vg_UserMsg,   " %s", di->filename
1458                                                    ? di->filename
1459                                                    : (UChar*)"(null?!)" );
1460            }
1461         } else
1462
1463         if ((!inrw) && (!inrx) && size > 0 && !di->bss_present) {
1464            /* File contains a .bss, but it didn't get mapped.  Ignore. */
1465            di->bss_present = False;
1466            di->bss_svma = 0;
1467            di->bss_avma = 0;
1468            di->bss_size = 0;
1469            di->bss_bias = 0;
1470         } else {
1471            BAD(".bss");
1472         }
1473      }
1474
1475      /* Accept .sbss where mapped as rw (data) */
1476      if (0 == VG_(strcmp)(name, ".sbss")) {
1477         if (inrw && size > 0 && !di->sbss_present) {
1478            di->sbss_present = True;
1479            di->sbss_svma = svma;
1480            di->sbss_avma = svma + rw_bias;
1481            di->sbss_size = size;
1482            di->sbss_bias = rw_bias;
1483            TRACE_SYMTAB("acquiring .sbss svma = %#lx .. %#lx\n",
1484                         di->sbss_svma,
1485                         di->sbss_svma + di->sbss_size - 1);
1486            TRACE_SYMTAB("acquiring .sbss avma = %#lx .. %#lx\n",
1487                         di->sbss_avma,
1488                         di->sbss_avma + di->sbss_size - 1);
1489            TRACE_SYMTAB("acquiring .sbss bias = %#lx\n", di->sbss_bias);
1490         } else {
1491            BAD(".sbss");
1492         }
1493      }
1494
1495      /* Accept .got where mapped as rw (data) */
1496      if (0 == VG_(strcmp)(name, ".got")) {
1497         if (inrw && size > 0 && !di->got_present) {
1498            di->got_present = True;
1499            di->got_avma = svma + rw_bias;
1500            di->got_size = size;
1501            TRACE_SYMTAB("acquiring .got avma = %#lx\n", di->got_avma);
1502         } else {
1503            BAD(".got");
1504         }
1505      }
1506
1507      /* Accept .got.plt where mapped as rw (data) */
1508      if (0 == VG_(strcmp)(name, ".got.plt")) {
1509         if (inrw && size > 0 && !di->gotplt_present) {
1510            di->gotplt_present = True;
1511            di->gotplt_avma = svma + rw_bias;
1512            di->gotplt_size = size;
1513            TRACE_SYMTAB("acquiring .got.plt avma = %#lx\n", di->gotplt_avma);
1514         } else if (size != 0) {
1515            BAD(".got.plt");
1516         }
1517      }
1518
1519      /* PLT is different on different platforms, it seems. */
1520#     if defined(VGP_x86_linux) || defined(VGP_amd64_linux)
1521      /* Accept .plt where mapped as rx (code) */
1522      if (0 == VG_(strcmp)(name, ".plt")) {
1523         if (inrx && size > 0 && !di->plt_present) {
1524            di->plt_present = True;
1525            di->plt_avma = svma + rx_bias;
1526            di->plt_size = size;
1527            TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
1528         } else {
1529            BAD(".plt");
1530         }
1531      }
1532#     elif defined(VGP_ppc32_linux)
1533      /* Accept .plt where mapped as rw (data) */
1534      if (0 == VG_(strcmp)(name, ".plt")) {
1535         if (inrw && size > 0 && !di->plt_present) {
1536            di->plt_present = True;
1537            di->plt_avma = svma + rw_bias;
1538            di->plt_size = size;
1539            TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
1540         } else {
1541            BAD(".plt");
1542         }
1543      }
1544#     elif defined(VGP_ppc64_linux)
1545      /* Accept .plt where mapped as rw (data), or unmapped */
1546      if (0 == VG_(strcmp)(name, ".plt")) {
1547         if (inrw && size > 0 && !di->plt_present) {
1548            di->plt_present = True;
1549            di->plt_avma = svma + rw_bias;
1550            di->plt_size = size;
1551            TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
1552         } else
1553         if ((!inrw) && (!inrx) && size > 0 && !di->plt_present) {
1554            /* File contains a .plt, but it didn't get mapped.
1555               Presumably it is not required on this platform.  At
1556               least don't reject the situation as invalid. */
1557            di->plt_present = True;
1558            di->plt_avma = 0;
1559            di->plt_size = 0;
1560         } else {
1561            BAD(".plt");
1562         }
1563      }
1564#     else
1565#       error "Unsupported platform"
1566#     endif
1567
1568      /* Accept .opd where mapped as rw (data) */
1569      if (0 == VG_(strcmp)(name, ".opd")) {
1570         if (inrw && size > 0 && !di->opd_present) {
1571            di->opd_present = True;
1572            di->opd_avma = svma + rw_bias;
1573            di->opd_size = size;
1574            TRACE_SYMTAB("acquiring .opd avma = %#lx\n", di->opd_avma);
1575         } else {
1576            BAD(".opd");
1577         }
1578      }
1579
1580      /* Accept .eh_frame where mapped as rx (code).  This seems to be
1581         the common case.  However, if that doesn't pan out, try for
1582         rw (data) instead. */
1583      if (0 == VG_(strcmp)(name, ".eh_frame")) {
1584         if (inrx && size > 0 && !di->ehframe_present) {
1585            di->ehframe_present = True;
1586            di->ehframe_avma = svma + rx_bias;
1587            di->ehframe_size = size;
1588            TRACE_SYMTAB("acquiring .eh_frame avma = %#lx\n", di->ehframe_avma);
1589         } else
1590         if (inrw && size > 0 && !di->ehframe_present) {
1591            di->ehframe_present = True;
1592            di->ehframe_avma = svma + rw_bias;
1593            di->ehframe_size = size;
1594            TRACE_SYMTAB("acquiring .eh_frame avma = %#lx\n", di->ehframe_avma);
1595         } else {
1596            BAD(".eh_frame");
1597         }
1598      }
1599
1600#    undef BAD
1601
1602   }
1603
1604   if (0) VG_(printf)("YYYY text_: avma %#lx  size %ld  bias %#lx\n",
1605                      di->text_avma, di->text_size, di->text_bias);
1606
1607   if (VG_(clo_verbosity) > 2 || VG_(clo_trace_redir))
1608      VG_(message)(Vg_DebugMsg, "   svma %#010lx, avma %#010lx",
1609                                di->text_avma - di->text_bias,
1610                                di->text_avma );
1611
1612   TRACE_SYMTAB("\n");
1613   TRACE_SYMTAB("------ Finding image addresses "
1614                "for debug-info sections ------\n");
1615
1616   /* Find interesting sections, read the symbol table(s), read any debug
1617      information */
1618   {
1619      /* IMAGE addresses: pointers to start of sections in the
1620         transiently loaded oimage, not in the fragments of the file
1621         mapped in by the guest's dynamic linker. */
1622      UChar*     strtab_img       = NULL; /* .strtab */
1623      ElfXX_Sym* symtab_img       = NULL; /* .symtab */
1624      UChar*     dynstr_img       = NULL; /* .dynstr */
1625      ElfXX_Sym* dynsym_img       = NULL; /* .dynsym */
1626      UChar*     debuglink_img    = NULL; /* .gnu_debuglink */
1627      UChar*     stab_img         = NULL; /* .stab         (stabs)  */
1628      UChar*     stabstr_img      = NULL; /* .stabstr      (stabs)  */
1629      UChar*     debug_line_img   = NULL; /* .debug_line   (dwarf2) */
1630      UChar*     debug_info_img   = NULL; /* .debug_info   (dwarf2) */
1631      UChar*     debug_abbv_img   = NULL; /* .debug_abbrev (dwarf2) */
1632      UChar*     debug_str_img    = NULL; /* .debug_str    (dwarf2) */
1633      UChar*     debug_ranges_img = NULL; /* .debug_ranges (dwarf2) */
1634      UChar*     debug_loc_img    = NULL; /* .debug_loc    (dwarf2) */
1635      UChar*     dwarf1d_img      = NULL; /* .debug        (dwarf1) */
1636      UChar*     dwarf1l_img      = NULL; /* .line         (dwarf1) */
1637      UChar*     ehframe_img      = NULL; /* .eh_frame     (dwarf2) */
1638      UChar*     opd_img          = NULL; /* .opd (dwarf2,
1639                                                   ppc64-linux) */
1640      /* Section sizes, in bytes */
1641      SizeT      strtab_sz       = 0;
1642      SizeT      symtab_sz       = 0;
1643      SizeT      dynstr_sz       = 0;
1644      SizeT      dynsym_sz       = 0;
1645      SizeT      debuglink_sz    = 0;
1646      SizeT      stab_sz         = 0;
1647      SizeT      stabstr_sz      = 0;
1648      SizeT      debug_line_sz   = 0;
1649      SizeT      debug_info_sz   = 0;
1650      SizeT      debug_abbv_sz   = 0;
1651      SizeT      debug_str_sz    = 0;
1652      SizeT      debug_ranges_sz = 0;
1653      SizeT      debug_loc_sz    = 0;
1654      SizeT      dwarf1d_sz      = 0;
1655      SizeT      dwarf1l_sz      = 0;
1656      SizeT      ehframe_sz      = 0;
1657      SizeT      opd_sz_unused   = 0;
1658
1659      /* Find all interesting sections */
1660
1661      /* What FIND does: it finds the section called SEC_NAME.  The
1662         size of it is assigned to SEC_SIZE.  The address of the
1663         section in the transiently loaded oimage is assigned to
1664         SEC_FILEA.  Even for sections which are marked loadable, the
1665         client's ld.so may not have loaded them yet, so there is no
1666         guarantee that we can safely prod around in any such area).
1667         Because the entire object file is transiently mapped aboard
1668         for inspection, it's always safe to inspect that area. */
1669
1670      for (i = 0; i < ehdr_img->e_shnum; i++) {
1671
1672#        define FIND(sec_name, sec_size, sec_img) \
1673         do { ElfXX_Shdr* shdr \
1674                 = INDEX_BIS( shdr_img, i, shdr_ent_szB ); \
1675            if (0 == VG_(strcmp)(sec_name, shdr_strtab_img \
1676                                           + shdr->sh_name)) { \
1677               Bool nobits; \
1678               sec_img  = (void*)(oimage + shdr->sh_offset); \
1679               sec_size = shdr->sh_size; \
1680               nobits   = shdr->sh_type == SHT_NOBITS; \
1681               TRACE_SYMTAB( "%18s:  img %p .. %p\n", \
1682                             sec_name, (UChar*)sec_img, \
1683                             ((UChar*)sec_img) + sec_size - 1); \
1684               /* SHT_NOBITS sections have zero size in the file. */ \
1685               if ( shdr->sh_offset \
1686                    + (nobits ? 0 : sec_size) > n_oimage ) { \
1687                  ML_(symerr)(di, True, \
1688                              "   section beyond image end?!"); \
1689                  goto out; \
1690               } \
1691            } \
1692         } while (0);
1693
1694         /*   NAME              SIZE             IMAGE addr */
1695         FIND(".dynsym",        dynsym_sz,       dynsym_img)
1696         FIND(".dynstr",        dynstr_sz,       dynstr_img)
1697         FIND(".symtab",        symtab_sz,       symtab_img)
1698         FIND(".strtab",        strtab_sz,       strtab_img)
1699
1700         FIND(".gnu_debuglink", debuglink_sz,    debuglink_img)
1701
1702         FIND(".stab",          stab_sz,         stab_img)
1703         FIND(".stabstr",       stabstr_sz,      stabstr_img)
1704
1705         FIND(".debug_line",    debug_line_sz,   debug_line_img)
1706         FIND(".debug_info",    debug_info_sz,   debug_info_img)
1707         FIND(".debug_abbrev",  debug_abbv_sz,   debug_abbv_img)
1708         FIND(".debug_str",     debug_str_sz,    debug_str_img)
1709         FIND(".debug_ranges",  debug_ranges_sz, debug_ranges_img)
1710         FIND(".debug_loc",     debug_loc_sz,    debug_loc_img)
1711
1712         FIND(".debug",         dwarf1d_sz,      dwarf1d_img)
1713         FIND(".line",          dwarf1l_sz,      dwarf1l_img)
1714         FIND(".eh_frame",      ehframe_sz,      ehframe_img)
1715
1716         FIND(".opd",           opd_sz_unused,   opd_img)
1717
1718#        undef FIND
1719      }
1720
1721      /* Did we find a debuglink section? */
1722      if (debuglink_img != NULL) {
1723         UInt crc_offset = VG_ROUNDUP(VG_(strlen)(debuglink_img)+1, 4);
1724         UInt crc;
1725
1726         vg_assert(crc_offset + sizeof(UInt) <= debuglink_sz);
1727
1728         /* Extract the CRC from the debuglink section */
1729         crc = *(UInt *)(debuglink_img + crc_offset);
1730
1731         /* See if we can find a matching debug file */
1732         dimage = find_debug_file( di, di->filename, debuglink_img,
1733                                   crc, &n_dimage );
1734
1735         if (dimage != 0
1736             && n_dimage >= sizeof(ElfXX_Ehdr)
1737             && ML_(is_elf_object_file)((void*)dimage, n_dimage)) {
1738
1739            /* Pull out and validate program header and section header info */
1740            ElfXX_Ehdr* ehdr_dimg     = (ElfXX_Ehdr*)dimage;
1741            ElfXX_Phdr* phdr_dimg     = (ElfXX_Phdr*)( ((UChar*)ehdr_dimg)
1742                                                       + ehdr_dimg->e_phoff );
1743            UWord       phdr_dnent    = ehdr_dimg->e_phnum;
1744            UWord       phdr_dent_szB = ehdr_dimg->e_phentsize;
1745            ElfXX_Shdr* shdr_dimg     = (ElfXX_Shdr*)( ((UChar*)ehdr_dimg)
1746                                                       + ehdr_dimg->e_shoff );
1747            UWord       shdr_dnent       = ehdr_dimg->e_shnum;
1748            UWord       shdr_dent_szB    = ehdr_dimg->e_shentsize;
1749            UChar*      shdr_strtab_dimg = NULL;
1750
1751            Bool need_symtab, need_stabs, need_dwarf2, need_dwarf1;
1752
1753            if (phdr_dnent == 0
1754                || !contained_within(
1755                       dimage, n_dimage,
1756                       (Addr)phdr_dimg, phdr_dnent * phdr_dent_szB)) {
1757               ML_(symerr)(di, True,
1758                           "Missing or invalid ELF Program Header Table"
1759                           " (debuginfo file)");
1760               goto out;
1761            }
1762
1763            if (shdr_dnent == 0
1764                || !contained_within(
1765                       dimage, n_dimage,
1766                       (Addr)shdr_dimg, shdr_dnent * shdr_dent_szB)) {
1767               ML_(symerr)(di, True,
1768                           "Missing or invalid ELF Section Header Table"
1769                           " (debuginfo file)");
1770               goto out;
1771            }
1772
1773            /* Also find the section header's string table, and validate. */
1774            /* checked previously by is_elf_object_file: */
1775            vg_assert( ehdr_dimg->e_shstrndx != SHN_UNDEF );
1776
1777            shdr_strtab_dimg
1778               = (UChar*)( ((UChar*)ehdr_dimg)
1779                           + shdr_dimg[ehdr_dimg->e_shstrndx].sh_offset);
1780            if (!contained_within(
1781                    dimage, n_dimage,
1782                    (Addr)shdr_strtab_dimg,
1783                    1/*bogus, but we don't know the real size*/ )) {
1784               ML_(symerr)(di, True,
1785                           "Invalid ELF Section Header String Table"
1786                           " (debuginfo file)");
1787               goto out;
1788            }
1789
1790            need_symtab = (NULL == symtab_img);
1791            need_stabs  = (NULL == stab_img);
1792            need_dwarf2 = (NULL == debug_info_img);
1793            need_dwarf1 = (NULL == dwarf1d_img);
1794
1795            for (i = 0; i < ehdr_dimg->e_phnum; i++) {
1796               ElfXX_Phdr* phdr
1797                  = INDEX_BIS( (void*)(dimage + ehdr_dimg->e_phoff),
1798                                          i, phdr_ent_szB );
1799               if (phdr->p_type == PT_LOAD) {
1800                  //offset_dimage = di->text_avma - phdr->p_vaddr;
1801                  // FIXME: update di->text_bias at this point?
1802                  // or can we assume the SVMAs in the debuginfo
1803                  // file (hence, the biases) are the same as
1804                  // established from the main file?
1805                  break;
1806               }
1807            }
1808
1809            /* Same deal as previous FIND, except only do it for those
1810               sections for which we didn't find anything useful in
1811               the main file. */
1812
1813            /* Find all interesting sections */
1814            for (i = 0; i < ehdr_dimg->e_shnum; i++) {
1815
1816#              define FIND(condition, sec_name, sec_size, sec_img) \
1817               do { ElfXX_Shdr* shdr \
1818                       = INDEX_BIS( shdr_dimg, i, shdr_dent_szB ); \
1819                  if (condition \
1820                      && 0 == VG_(strcmp)(sec_name, \
1821                                          shdr_strtab_dimg + shdr->sh_name)) { \
1822                     Bool nobits; \
1823                     if (0 != sec_img) \
1824                        VG_(core_panic)("repeated section!\n"); \
1825                     sec_img  = (void*)(dimage + shdr->sh_offset); \
1826                     sec_size = shdr->sh_size; \
1827                     nobits   = shdr->sh_type == SHT_NOBITS; \
1828                     TRACE_SYMTAB( "%18s: dimg %p .. %p\n", \
1829                                   sec_name, \
1830                                   (UChar*)sec_img, \
1831                                   ((UChar*)sec_img) + sec_size - 1); \
1832                     /* SHT_NOBITS sections have zero size in the file. */ \
1833                     if ( shdr->sh_offset \
1834                          + (nobits ? 0 : sec_size) > n_dimage ) { \
1835                        ML_(symerr)(di, True, \
1836                                    "   section beyond image end?!"); \
1837                        goto out; \
1838                     } \
1839                  } \
1840               } while (0);
1841
1842               /* NEEDED?        NAME             SIZE           IMAGE addr */
1843               FIND(need_symtab, ".symtab",       symtab_sz,     symtab_img)
1844               FIND(need_symtab, ".strtab",       strtab_sz,     strtab_img)
1845               FIND(need_stabs,  ".stab",         stab_sz,       stab_img)
1846               FIND(need_stabs,  ".stabstr",      stabstr_sz,    stabstr_img)
1847               FIND(need_dwarf2, ".debug_line",   debug_line_sz, debug_line_img)
1848               FIND(need_dwarf2, ".debug_info",   debug_info_sz, debug_info_img)
1849               FIND(need_dwarf2, ".debug_abbrev", debug_abbv_sz, debug_abbv_img)
1850               FIND(need_dwarf2, ".debug_str",    debug_str_sz,  debug_str_img)
1851               FIND(need_dwarf2, ".debug_ranges", debug_ranges_sz,
1852                                                               debug_ranges_img)
1853               FIND(need_dwarf2, ".debug_loc",    debug_loc_sz,  debug_loc_img)
1854               FIND(need_dwarf1, ".debug",        dwarf1d_sz,    dwarf1d_img)
1855               FIND(need_dwarf1, ".line",         dwarf1l_sz,    dwarf1l_img)
1856
1857#              undef FIND
1858            }
1859         }
1860      }
1861
1862      /* Check some sizes */
1863      vg_assert((dynsym_sz % sizeof(ElfXX_Sym)) == 0);
1864      vg_assert((symtab_sz % sizeof(ElfXX_Sym)) == 0);
1865
1866      /* Read symbols */
1867      {
1868         void (*read_elf_symtab)(struct _DebugInfo*,UChar*,
1869                                 ElfXX_Sym*,SizeT,
1870                                 UChar*,SizeT,
1871                                 UChar*);
1872#        if defined(VGP_ppc64_linux)
1873         read_elf_symtab = read_elf_symtab__ppc64_linux;
1874#        else
1875         read_elf_symtab = read_elf_symtab__normal;
1876#        endif
1877         read_elf_symtab(di, "symbol table",
1878                         symtab_img, symtab_sz,
1879                         strtab_img, strtab_sz,
1880                         opd_img);
1881
1882         read_elf_symtab(di, "dynamic symbol table",
1883                         dynsym_img, dynsym_sz,
1884                         dynstr_img, dynstr_sz,
1885                         opd_img);
1886      }
1887
1888      /* Read .eh_frame (call-frame-info) if any */
1889      if (ehframe_img) {
1890         vg_assert(ehframe_sz == di->ehframe_size);
1891         ML_(read_callframe_info_dwarf3)( di, ehframe_img );
1892      }
1893
1894      /* Read the stabs and/or dwarf2 debug information, if any.  It
1895         appears reading stabs stuff on amd64-linux doesn't work, so
1896         we ignore it. */
1897#     if !defined(VGP_amd64_linux)
1898      if (stab_img && stabstr_img) {
1899         ML_(read_debuginfo_stabs) ( di, di->text_bias, stab_img, stab_sz,
1900                                         stabstr_img, stabstr_sz );
1901      }
1902#     endif
1903      /* jrs 2006-01-01: icc-8.1 has been observed to generate
1904         binaries without debug_str sections.  Don't preclude
1905         debuginfo reading for that reason, but, in
1906         read_unitinfo_dwarf2, do check that debugstr is non-NULL
1907         before using it. */
1908      if (debug_info_img && debug_abbv_img && debug_line_img
1909                                           /* && debug_str_img */) {
1910
1911         /* The old reader: line numbers and unwind info only */
1912         ML_(read_debuginfo_dwarf3) ( di,
1913                                      debug_info_img, debug_info_sz,
1914                                      debug_abbv_img, debug_abbv_sz,
1915                                      debug_line_img, debug_line_sz,
1916                                      debug_str_img,  debug_str_sz );
1917
1918         /* The new reader: read the DIEs in .debug_info to acquire
1919            information on variable types and locations.  But only if
1920            the tool asks for it, or the user requests it on the
1921            command line. */
1922         if (VG_(needs).var_info /* the tool requires it */
1923             || VG_(clo_read_var_info) /* the user asked for it */) {
1924            ML_(new_dwarf3_reader)(
1925               di, debug_info_img,   debug_info_sz,
1926                   debug_abbv_img,   debug_abbv_sz,
1927                   debug_line_img,   debug_line_sz,
1928                   debug_str_img,    debug_str_sz,
1929                   debug_ranges_img, debug_ranges_sz,
1930                   debug_loc_img,    debug_loc_sz
1931            );
1932         }
1933      }
1934      if (dwarf1d_img && dwarf1l_img) {
1935         ML_(read_debuginfo_dwarf1) ( di, dwarf1d_img, dwarf1d_sz,
1936                                          dwarf1l_img, dwarf1l_sz );
1937      }
1938   }
1939   res = True;
1940
1941  out: {
1942   SysRes m_res;
1943
1944   /* Last, but not least, heave the image(s) back overboard. */
1945   if (dimage) {
1946      m_res = VG_(am_munmap_valgrind) ( dimage, n_dimage );
1947      vg_assert(!m_res.isError);
1948   }
1949   m_res = VG_(am_munmap_valgrind) ( oimage, n_oimage );
1950   vg_assert(!m_res.isError);
1951   return res;
1952  }
1953}
1954
1955
1956/*--------------------------------------------------------------------*/
1957/*--- end                                                          ---*/
1958/*--------------------------------------------------------------------*/
1959