readelf.c revision 402c9eed11b9b60c6e134d05db938e395466cf99
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), even if zero-sized */
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            di->text_debug_svma = svma;
1356            di->text_debug_bias = rx_bias;
1357            TRACE_SYMTAB("acquiring .text svma = %#lx .. %#lx\n",
1358                         di->text_svma,
1359                         di->text_svma + di->text_size - 1);
1360            TRACE_SYMTAB("acquiring .text avma = %#lx .. %#lx\n",
1361                         di->text_avma,
1362                         di->text_avma + di->text_size - 1);
1363            TRACE_SYMTAB("acquiring .text bias = %#lx\n", di->text_bias);
1364         } else {
1365            BAD(".text");
1366         }
1367      }
1368
1369      /* Accept .data where mapped as rw (data), even if zero-sized */
1370      if (0 == VG_(strcmp)(name, ".data")) {
1371         if (inrw && size >= 0 && !di->data_present) {
1372            di->data_present = True;
1373            di->data_svma = svma;
1374            di->data_avma = svma + rw_bias;
1375            di->data_size = size;
1376            di->data_bias = rw_bias;
1377            di->data_debug_svma = svma;
1378            di->data_debug_bias = rw_bias;
1379            TRACE_SYMTAB("acquiring .data svma = %#lx .. %#lx\n",
1380                         di->data_svma,
1381                         di->data_svma + di->data_size - 1);
1382            TRACE_SYMTAB("acquiring .data avma = %#lx .. %#lx\n",
1383                         di->data_avma,
1384                         di->data_avma + di->data_size - 1);
1385            TRACE_SYMTAB("acquiring .data bias = %#lx\n", di->data_bias);
1386         } else {
1387            BAD(".data");
1388         }
1389      }
1390
1391      /* Accept .sdata where mapped as rw (data) */
1392      if (0 == VG_(strcmp)(name, ".sdata")) {
1393         if (inrw && size > 0 && !di->sdata_present) {
1394            di->sdata_present = True;
1395            di->sdata_svma = svma;
1396            di->sdata_avma = svma + rw_bias;
1397            di->sdata_size = size;
1398            di->sdata_bias = rw_bias;
1399            di->sdata_debug_svma = svma;
1400            di->sdata_debug_bias = rw_bias;
1401            TRACE_SYMTAB("acquiring .sdata svma = %#lx .. %#lx\n",
1402                         di->sdata_svma,
1403                         di->sdata_svma + di->sdata_size - 1);
1404            TRACE_SYMTAB("acquiring .sdata avma = %#lx .. %#lx\n",
1405                         di->sdata_avma,
1406                         di->sdata_avma + di->sdata_size - 1);
1407            TRACE_SYMTAB("acquiring .sdata bias = %#lx\n", di->sdata_bias);
1408         } else {
1409            BAD(".sdata");
1410         }
1411      }
1412
1413      /* Accept .rodata where mapped as rx (data), even if zero-sized */
1414      if (0 == VG_(strcmp)(name, ".rodata")) {
1415         if (inrx && size >= 0 && !di->rodata_present) {
1416            di->rodata_present = True;
1417            di->rodata_svma = svma;
1418            di->rodata_avma = svma + rx_bias;
1419            di->rodata_size = size;
1420            di->rodata_bias = rx_bias;
1421            di->rodata_debug_svma = svma;
1422            di->rodata_debug_bias = rw_bias;
1423            TRACE_SYMTAB("acquiring .rodata svma = %#lx .. %#lx\n",
1424                         di->rodata_svma,
1425                         di->rodata_svma + di->rodata_size - 1);
1426            TRACE_SYMTAB("acquiring .rodata avma = %#lx .. %#lx\n",
1427                         di->rodata_avma,
1428                         di->rodata_avma + di->rodata_size - 1);
1429            TRACE_SYMTAB("acquiring .rodata bias = %#lx\n", di->rodata_bias);
1430         } else {
1431            BAD(".rodata");
1432         }
1433      }
1434
1435      /* Accept .bss where mapped as rw (data), even if zero-sized */
1436      if (0 == VG_(strcmp)(name, ".bss")) {
1437         if (inrw && size >= 0 && !di->bss_present) {
1438            di->bss_present = True;
1439            di->bss_svma = svma;
1440            di->bss_avma = svma + rw_bias;
1441            di->bss_size = size;
1442            di->bss_bias = rw_bias;
1443            di->bss_debug_svma = svma;
1444            di->bss_debug_bias = rw_bias;
1445            TRACE_SYMTAB("acquiring .bss svma = %#lx .. %#lx\n",
1446                         di->bss_svma,
1447                         di->bss_svma + di->bss_size - 1);
1448            TRACE_SYMTAB("acquiring .bss avma = %#lx .. %#lx\n",
1449                         di->bss_avma,
1450                         di->bss_avma + di->bss_size - 1);
1451            TRACE_SYMTAB("acquiring .bss bias = %#lx\n", di->bss_bias);
1452         } else
1453
1454         /* Now one from the wtf?! department ... */
1455         if (inrx && (!inrw) && size >= 0 && !di->bss_present) {
1456            /* File contains a .bss, but it got mapped as rx only.
1457               This is very strange.  For now, just pretend we didn't
1458               see it :-) */
1459            di->bss_present = False;
1460            di->bss_svma = 0;
1461            di->bss_avma = 0;
1462            di->bss_size = 0;
1463            di->bss_bias = 0;
1464            di->bss_debug_svma = 0;
1465            di->bss_debug_bias = 0;
1466            if (!VG_(clo_xml)) {
1467               VG_(message)(Vg_UserMsg, "Warning: the following file's .bss is "
1468                                       "mapped r-x only - ignoring .bss syms");
1469               VG_(message)(Vg_UserMsg,   " %s", di->filename
1470                                                    ? di->filename
1471                                                    : (UChar*)"(null?!)" );
1472            }
1473         } else
1474
1475         if ((!inrw) && (!inrx) && size >= 0 && !di->bss_present) {
1476            /* File contains a .bss, but it didn't get mapped.  Ignore. */
1477            di->bss_present = False;
1478            di->bss_svma = 0;
1479            di->bss_avma = 0;
1480            di->bss_size = 0;
1481            di->bss_bias = 0;
1482         } else {
1483            BAD(".bss");
1484         }
1485      }
1486
1487      /* Accept .sbss where mapped as rw (data) */
1488      if (0 == VG_(strcmp)(name, ".sbss")) {
1489         if (inrw && size > 0 && !di->sbss_present) {
1490            di->sbss_present = True;
1491            di->sbss_svma = svma;
1492            di->sbss_avma = svma + rw_bias;
1493            di->sbss_size = size;
1494            di->sbss_bias = rw_bias;
1495            di->sbss_debug_svma = svma;
1496            di->sbss_debug_bias = rw_bias;
1497            TRACE_SYMTAB("acquiring .sbss svma = %#lx .. %#lx\n",
1498                         di->sbss_svma,
1499                         di->sbss_svma + di->sbss_size - 1);
1500            TRACE_SYMTAB("acquiring .sbss avma = %#lx .. %#lx\n",
1501                         di->sbss_avma,
1502                         di->sbss_avma + di->sbss_size - 1);
1503            TRACE_SYMTAB("acquiring .sbss bias = %#lx\n", di->sbss_bias);
1504         } else {
1505            BAD(".sbss");
1506         }
1507      }
1508
1509      /* Accept .got where mapped as rw (data) */
1510      if (0 == VG_(strcmp)(name, ".got")) {
1511         if (inrw && size > 0 && !di->got_present) {
1512            di->got_present = True;
1513            di->got_avma = svma + rw_bias;
1514            di->got_size = size;
1515            TRACE_SYMTAB("acquiring .got avma = %#lx\n", di->got_avma);
1516         } else {
1517            BAD(".got");
1518         }
1519      }
1520
1521      /* Accept .got.plt where mapped as rw (data) */
1522      if (0 == VG_(strcmp)(name, ".got.plt")) {
1523         if (inrw && size > 0 && !di->gotplt_present) {
1524            di->gotplt_present = True;
1525            di->gotplt_avma = svma + rw_bias;
1526            di->gotplt_size = size;
1527            TRACE_SYMTAB("acquiring .got.plt avma = %#lx\n", di->gotplt_avma);
1528         } else if (size != 0) {
1529            BAD(".got.plt");
1530         }
1531      }
1532
1533      /* PLT is different on different platforms, it seems. */
1534#     if defined(VGP_x86_linux) || defined(VGP_amd64_linux)
1535      /* Accept .plt where mapped as rx (code) */
1536      if (0 == VG_(strcmp)(name, ".plt")) {
1537         if (inrx && size > 0 && !di->plt_present) {
1538            di->plt_present = True;
1539            di->plt_avma = svma + rx_bias;
1540            di->plt_size = size;
1541            TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
1542         } else {
1543            BAD(".plt");
1544         }
1545      }
1546#     elif defined(VGP_ppc32_linux)
1547      /* Accept .plt where mapped as rw (data) */
1548      if (0 == VG_(strcmp)(name, ".plt")) {
1549         if (inrw && size > 0 && !di->plt_present) {
1550            di->plt_present = True;
1551            di->plt_avma = svma + rw_bias;
1552            di->plt_size = size;
1553            TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
1554         } else {
1555            BAD(".plt");
1556         }
1557      }
1558#     elif defined(VGP_ppc64_linux)
1559      /* Accept .plt where mapped as rw (data), or unmapped */
1560      if (0 == VG_(strcmp)(name, ".plt")) {
1561         if (inrw && size > 0 && !di->plt_present) {
1562            di->plt_present = True;
1563            di->plt_avma = svma + rw_bias;
1564            di->plt_size = size;
1565            TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
1566         } else
1567         if ((!inrw) && (!inrx) && size > 0 && !di->plt_present) {
1568            /* File contains a .plt, but it didn't get mapped.
1569               Presumably it is not required on this platform.  At
1570               least don't reject the situation as invalid. */
1571            di->plt_present = True;
1572            di->plt_avma = 0;
1573            di->plt_size = 0;
1574         } else {
1575            BAD(".plt");
1576         }
1577      }
1578#     else
1579#       error "Unsupported platform"
1580#     endif
1581
1582      /* Accept .opd where mapped as rw (data) */
1583      if (0 == VG_(strcmp)(name, ".opd")) {
1584         if (inrw && size > 0 && !di->opd_present) {
1585            di->opd_present = True;
1586            di->opd_avma = svma + rw_bias;
1587            di->opd_size = size;
1588            TRACE_SYMTAB("acquiring .opd avma = %#lx\n", di->opd_avma);
1589         } else {
1590            BAD(".opd");
1591         }
1592      }
1593
1594      /* Accept .eh_frame where mapped as rx (code).  This seems to be
1595         the common case.  However, if that doesn't pan out, try for
1596         rw (data) instead. */
1597      if (0 == VG_(strcmp)(name, ".eh_frame")) {
1598         if (inrx && size > 0 && !di->ehframe_present) {
1599            di->ehframe_present = True;
1600            di->ehframe_avma = svma + rx_bias;
1601            di->ehframe_size = size;
1602            TRACE_SYMTAB("acquiring .eh_frame avma = %#lx\n", di->ehframe_avma);
1603         } else
1604         if (inrw && size > 0 && !di->ehframe_present) {
1605            di->ehframe_present = True;
1606            di->ehframe_avma = svma + rw_bias;
1607            di->ehframe_size = size;
1608            TRACE_SYMTAB("acquiring .eh_frame avma = %#lx\n", di->ehframe_avma);
1609         } else {
1610            BAD(".eh_frame");
1611         }
1612      }
1613
1614#    undef BAD
1615
1616   }
1617
1618   if (0) VG_(printf)("YYYY text_: avma %#lx  size %ld  bias %#lx\n",
1619                      di->text_avma, di->text_size, di->text_bias);
1620
1621   if (VG_(clo_verbosity) > 2 || VG_(clo_trace_redir))
1622      VG_(message)(Vg_DebugMsg, "   svma %#010lx, avma %#010lx",
1623                                di->text_avma - di->text_bias,
1624                                di->text_avma );
1625
1626   TRACE_SYMTAB("\n");
1627   TRACE_SYMTAB("------ Finding image addresses "
1628                "for debug-info sections ------\n");
1629
1630   /* Find interesting sections, read the symbol table(s), read any debug
1631      information */
1632   {
1633      /* IMAGE addresses: pointers to start of sections in the
1634         transiently loaded oimage, not in the fragments of the file
1635         mapped in by the guest's dynamic linker. */
1636      UChar*     strtab_img       = NULL; /* .strtab */
1637      ElfXX_Sym* symtab_img       = NULL; /* .symtab */
1638      UChar*     dynstr_img       = NULL; /* .dynstr */
1639      ElfXX_Sym* dynsym_img       = NULL; /* .dynsym */
1640      UChar*     debuglink_img    = NULL; /* .gnu_debuglink */
1641      UChar*     stab_img         = NULL; /* .stab         (stabs)  */
1642      UChar*     stabstr_img      = NULL; /* .stabstr      (stabs)  */
1643      UChar*     debug_line_img   = NULL; /* .debug_line   (dwarf2) */
1644      UChar*     debug_info_img   = NULL; /* .debug_info   (dwarf2) */
1645      UChar*     debug_abbv_img   = NULL; /* .debug_abbrev (dwarf2) */
1646      UChar*     debug_str_img    = NULL; /* .debug_str    (dwarf2) */
1647      UChar*     debug_ranges_img = NULL; /* .debug_ranges (dwarf2) */
1648      UChar*     debug_loc_img    = NULL; /* .debug_loc    (dwarf2) */
1649      UChar*     dwarf1d_img      = NULL; /* .debug        (dwarf1) */
1650      UChar*     dwarf1l_img      = NULL; /* .line         (dwarf1) */
1651      UChar*     ehframe_img      = NULL; /* .eh_frame     (dwarf2) */
1652      UChar*     opd_img          = NULL; /* .opd (dwarf2,
1653                                                   ppc64-linux) */
1654      /* Section sizes, in bytes */
1655      SizeT      strtab_sz       = 0;
1656      SizeT      symtab_sz       = 0;
1657      SizeT      dynstr_sz       = 0;
1658      SizeT      dynsym_sz       = 0;
1659      SizeT      debuglink_sz    = 0;
1660      SizeT      stab_sz         = 0;
1661      SizeT      stabstr_sz      = 0;
1662      SizeT      debug_line_sz   = 0;
1663      SizeT      debug_info_sz   = 0;
1664      SizeT      debug_abbv_sz   = 0;
1665      SizeT      debug_str_sz    = 0;
1666      SizeT      debug_ranges_sz = 0;
1667      SizeT      debug_loc_sz    = 0;
1668      SizeT      dwarf1d_sz      = 0;
1669      SizeT      dwarf1l_sz      = 0;
1670      SizeT      ehframe_sz      = 0;
1671      SizeT      opd_sz_unused   = 0;
1672
1673      /* Find all interesting sections */
1674
1675      /* What FIND does: it finds the section called SEC_NAME.  The
1676         size of it is assigned to SEC_SIZE.  The address of the
1677         section in the transiently loaded oimage is assigned to
1678         SEC_FILEA.  Even for sections which are marked loadable, the
1679         client's ld.so may not have loaded them yet, so there is no
1680         guarantee that we can safely prod around in any such area).
1681         Because the entire object file is transiently mapped aboard
1682         for inspection, it's always safe to inspect that area. */
1683
1684      for (i = 0; i < ehdr_img->e_shnum; i++) {
1685
1686#        define FIND(sec_name, sec_size, sec_img) \
1687         do { ElfXX_Shdr* shdr \
1688                 = INDEX_BIS( shdr_img, i, shdr_ent_szB ); \
1689            if (0 == VG_(strcmp)(sec_name, shdr_strtab_img \
1690                                           + shdr->sh_name)) { \
1691               Bool nobits; \
1692               sec_img  = (void*)(oimage + shdr->sh_offset); \
1693               sec_size = shdr->sh_size; \
1694               nobits   = shdr->sh_type == SHT_NOBITS; \
1695               TRACE_SYMTAB( "%18s:  img %p .. %p\n", \
1696                             sec_name, (UChar*)sec_img, \
1697                             ((UChar*)sec_img) + sec_size - 1); \
1698               /* SHT_NOBITS sections have zero size in the file. */ \
1699               if ( shdr->sh_offset \
1700                    + (nobits ? 0 : sec_size) > n_oimage ) { \
1701                  ML_(symerr)(di, True, \
1702                              "   section beyond image end?!"); \
1703                  goto out; \
1704               } \
1705            } \
1706         } while (0);
1707
1708         /*   NAME              SIZE             IMAGE addr */
1709         FIND(".dynsym",        dynsym_sz,       dynsym_img)
1710         FIND(".dynstr",        dynstr_sz,       dynstr_img)
1711         FIND(".symtab",        symtab_sz,       symtab_img)
1712         FIND(".strtab",        strtab_sz,       strtab_img)
1713
1714         FIND(".gnu_debuglink", debuglink_sz,    debuglink_img)
1715
1716         FIND(".stab",          stab_sz,         stab_img)
1717         FIND(".stabstr",       stabstr_sz,      stabstr_img)
1718
1719         FIND(".debug_line",    debug_line_sz,   debug_line_img)
1720         FIND(".debug_info",    debug_info_sz,   debug_info_img)
1721         FIND(".debug_abbrev",  debug_abbv_sz,   debug_abbv_img)
1722         FIND(".debug_str",     debug_str_sz,    debug_str_img)
1723         FIND(".debug_ranges",  debug_ranges_sz, debug_ranges_img)
1724         FIND(".debug_loc",     debug_loc_sz,    debug_loc_img)
1725
1726         FIND(".debug",         dwarf1d_sz,      dwarf1d_img)
1727         FIND(".line",          dwarf1l_sz,      dwarf1l_img)
1728         FIND(".eh_frame",      ehframe_sz,      ehframe_img)
1729
1730         FIND(".opd",           opd_sz_unused,   opd_img)
1731
1732#        undef FIND
1733      }
1734
1735      /* Did we find a debuglink section? */
1736      if (debuglink_img != NULL) {
1737         UInt crc_offset = VG_ROUNDUP(VG_(strlen)(debuglink_img)+1, 4);
1738         UInt crc;
1739
1740         vg_assert(crc_offset + sizeof(UInt) <= debuglink_sz);
1741
1742         /* Extract the CRC from the debuglink section */
1743         crc = *(UInt *)(debuglink_img + crc_offset);
1744
1745         /* See if we can find a matching debug file */
1746         dimage = find_debug_file( di, di->filename, debuglink_img,
1747                                   crc, &n_dimage );
1748
1749         if (dimage != 0
1750             && n_dimage >= sizeof(ElfXX_Ehdr)
1751             && ML_(is_elf_object_file)((void*)dimage, n_dimage)) {
1752
1753            /* Pull out and validate program header and section header info */
1754            ElfXX_Ehdr* ehdr_dimg     = (ElfXX_Ehdr*)dimage;
1755            ElfXX_Phdr* phdr_dimg     = (ElfXX_Phdr*)( ((UChar*)ehdr_dimg)
1756                                                       + ehdr_dimg->e_phoff );
1757            UWord       phdr_dnent    = ehdr_dimg->e_phnum;
1758            UWord       phdr_dent_szB = ehdr_dimg->e_phentsize;
1759            ElfXX_Shdr* shdr_dimg     = (ElfXX_Shdr*)( ((UChar*)ehdr_dimg)
1760                                                       + ehdr_dimg->e_shoff );
1761            UWord       shdr_dnent       = ehdr_dimg->e_shnum;
1762            UWord       shdr_dent_szB    = ehdr_dimg->e_shentsize;
1763            UChar*      shdr_strtab_dimg = NULL;
1764
1765            /* SVMAs covered by rx and rw segments and corresponding bias. */
1766            Addr     rx_dsvma_base = 0;
1767            Addr     rx_dsvma_limit = 0;
1768            PtrdiffT rx_dbias = 0;
1769            Addr     rw_dsvma_base = 0;
1770            Addr     rw_dsvma_limit = 0;
1771            PtrdiffT rw_dbias = 0;
1772
1773            Bool need_symtab, need_stabs, need_dwarf2, need_dwarf1;
1774
1775            if (phdr_dnent == 0
1776                || !contained_within(
1777                       dimage, n_dimage,
1778                       (Addr)phdr_dimg, phdr_dnent * phdr_dent_szB)) {
1779               ML_(symerr)(di, True,
1780                           "Missing or invalid ELF Program Header Table"
1781                           " (debuginfo file)");
1782               goto out;
1783            }
1784
1785            if (shdr_dnent == 0
1786                || !contained_within(
1787                       dimage, n_dimage,
1788                       (Addr)shdr_dimg, shdr_dnent * shdr_dent_szB)) {
1789               ML_(symerr)(di, True,
1790                           "Missing or invalid ELF Section Header Table"
1791                           " (debuginfo file)");
1792               goto out;
1793            }
1794
1795            /* Also find the section header's string table, and validate. */
1796            /* checked previously by is_elf_object_file: */
1797            vg_assert( ehdr_dimg->e_shstrndx != SHN_UNDEF );
1798
1799            shdr_strtab_dimg
1800               = (UChar*)( ((UChar*)ehdr_dimg)
1801                           + shdr_dimg[ehdr_dimg->e_shstrndx].sh_offset);
1802            if (!contained_within(
1803                    dimage, n_dimage,
1804                    (Addr)shdr_strtab_dimg,
1805                    1/*bogus, but we don't know the real size*/ )) {
1806               ML_(symerr)(di, True,
1807                           "Invalid ELF Section Header String Table"
1808                           " (debuginfo file)");
1809               goto out;
1810            }
1811
1812            need_symtab = (NULL == symtab_img);
1813            need_stabs  = (NULL == stab_img);
1814            need_dwarf2 = (NULL == debug_info_img);
1815            need_dwarf1 = (NULL == dwarf1d_img);
1816
1817            for (i = 0; i < ehdr_dimg->e_phnum; i++) {
1818               ElfXX_Phdr* phdr
1819                  = INDEX_BIS( (void*)(dimage + ehdr_dimg->e_phoff),
1820                                          i, phdr_ent_szB );
1821               if (phdr->p_type == PT_LOAD) {
1822                  if (rx_dsvma_limit == 0
1823                      && phdr->p_offset >= di->rx_map_foff
1824                      && phdr->p_offset < di->rx_map_foff + di->rx_map_size
1825                      && phdr->p_offset + phdr->p_filesz <= di->rx_map_foff + di->rx_map_size) {
1826                     rx_dsvma_base = phdr->p_vaddr;
1827                     rx_dsvma_limit = phdr->p_vaddr + phdr->p_memsz;
1828                     rx_dbias = di->rx_map_avma - di->rx_map_foff + phdr->p_offset - phdr->p_vaddr;
1829                  }
1830                  else if (rw_dsvma_limit == 0
1831                           && phdr->p_offset >= di->rw_map_foff
1832                           && phdr->p_offset < di->rw_map_foff + di->rw_map_size
1833                           && phdr->p_offset + phdr->p_filesz <= di->rw_map_foff + di->rw_map_size) {
1834                     rw_dsvma_base = phdr->p_vaddr;
1835                     rw_dsvma_limit = phdr->p_vaddr + phdr->p_memsz;
1836                     rw_dbias = di->rw_map_avma - di->rw_map_foff + phdr->p_offset - phdr->p_vaddr;
1837                  }
1838               }
1839            }
1840
1841            /* Find all interesting sections */
1842            for (i = 0; i < ehdr_dimg->e_shnum; i++) {
1843
1844               /* Find debug svma and bias information for sections
1845                  we found in the main file. */
1846
1847#              define FIND(sec, seg) \
1848               do { ElfXX_Shdr* shdr \
1849                       = INDEX_BIS( shdr_dimg, i, shdr_dent_szB ); \
1850                  if (di->sec##_present \
1851                      && 0 == VG_(strcmp)("." #sec, \
1852                                          shdr_strtab_dimg + shdr->sh_name)) { \
1853                     vg_assert(di->sec##_size == shdr->sh_size); \
1854                     vg_assert(di->sec##_avma +  shdr->sh_addr + seg##_dbias); \
1855                     di->sec##_debug_svma = shdr->sh_addr; \
1856                     di->sec##_debug_bias = seg##_dbias; \
1857                     TRACE_SYMTAB("acquiring ." #sec " debug svma = %#lx .. %#lx\n", \
1858                                  di->sec##_debug_svma, \
1859                                  di->sec##_debug_svma + di->sec##_size - 1); \
1860                     TRACE_SYMTAB("acquiring ." #sec " debug bias = %#lx\n", \
1861                                  di->sec##_debug_bias); \
1862                  } \
1863               } while (0);
1864
1865               /* SECTION   SEGMENT */
1866               FIND(text,   rx)
1867               FIND(data,   rw)
1868               FIND(sdata,  rw)
1869               FIND(rodata, rw)
1870               FIND(bss,    rw)
1871               FIND(sbss,   rw)
1872
1873#              undef FIND
1874
1875               /* Same deal as previous FIND, except only do it for those
1876                  sections for which we didn't find anything useful in
1877                  the main file. */
1878
1879#              define FIND(condition, sec_name, sec_size, sec_img) \
1880               do { ElfXX_Shdr* shdr \
1881                       = INDEX_BIS( shdr_dimg, i, shdr_dent_szB ); \
1882                  if (condition \
1883                      && 0 == VG_(strcmp)(sec_name, \
1884                                          shdr_strtab_dimg + shdr->sh_name)) { \
1885                     Bool nobits; \
1886                     if (0 != sec_img) \
1887                        VG_(core_panic)("repeated section!\n"); \
1888                     sec_img  = (void*)(dimage + shdr->sh_offset); \
1889                     sec_size = shdr->sh_size; \
1890                     nobits   = shdr->sh_type == SHT_NOBITS; \
1891                     TRACE_SYMTAB( "%18s: dimg %p .. %p\n", \
1892                                   sec_name, \
1893                                   (UChar*)sec_img, \
1894                                   ((UChar*)sec_img) + sec_size - 1); \
1895                     /* SHT_NOBITS sections have zero size in the file. */ \
1896                     if ( shdr->sh_offset \
1897                          + (nobits ? 0 : sec_size) > n_dimage ) { \
1898                        ML_(symerr)(di, True, \
1899                                    "   section beyond image end?!"); \
1900                        goto out; \
1901                     } \
1902                  } \
1903               } while (0);
1904
1905               /* NEEDED?        NAME             SIZE           IMAGE addr */
1906               FIND(need_symtab, ".symtab",       symtab_sz,     symtab_img)
1907               FIND(need_symtab, ".strtab",       strtab_sz,     strtab_img)
1908               FIND(need_stabs,  ".stab",         stab_sz,       stab_img)
1909               FIND(need_stabs,  ".stabstr",      stabstr_sz,    stabstr_img)
1910               FIND(need_dwarf2, ".debug_line",   debug_line_sz, debug_line_img)
1911               FIND(need_dwarf2, ".debug_info",   debug_info_sz, debug_info_img)
1912               FIND(need_dwarf2, ".debug_abbrev", debug_abbv_sz, debug_abbv_img)
1913               FIND(need_dwarf2, ".debug_str",    debug_str_sz,  debug_str_img)
1914               FIND(need_dwarf2, ".debug_ranges", debug_ranges_sz,
1915                                                               debug_ranges_img)
1916               FIND(need_dwarf2, ".debug_loc",    debug_loc_sz,  debug_loc_img)
1917               FIND(need_dwarf1, ".debug",        dwarf1d_sz,    dwarf1d_img)
1918               FIND(need_dwarf1, ".line",         dwarf1l_sz,    dwarf1l_img)
1919
1920#              undef FIND
1921            }
1922         }
1923      }
1924
1925      /* Check some sizes */
1926      vg_assert((dynsym_sz % sizeof(ElfXX_Sym)) == 0);
1927      vg_assert((symtab_sz % sizeof(ElfXX_Sym)) == 0);
1928
1929      /* Read symbols */
1930      {
1931         void (*read_elf_symtab)(struct _DebugInfo*,UChar*,
1932                                 ElfXX_Sym*,SizeT,
1933                                 UChar*,SizeT,
1934                                 UChar*);
1935#        if defined(VGP_ppc64_linux)
1936         read_elf_symtab = read_elf_symtab__ppc64_linux;
1937#        else
1938         read_elf_symtab = read_elf_symtab__normal;
1939#        endif
1940         read_elf_symtab(di, "symbol table",
1941                         symtab_img, symtab_sz,
1942                         strtab_img, strtab_sz,
1943                         opd_img);
1944
1945         read_elf_symtab(di, "dynamic symbol table",
1946                         dynsym_img, dynsym_sz,
1947                         dynstr_img, dynstr_sz,
1948                         opd_img);
1949      }
1950
1951      /* Read .eh_frame (call-frame-info) if any */
1952      if (ehframe_img) {
1953         vg_assert(ehframe_sz == di->ehframe_size);
1954         ML_(read_callframe_info_dwarf3)( di, ehframe_img );
1955      }
1956
1957      /* Read the stabs and/or dwarf2 debug information, if any.  It
1958         appears reading stabs stuff on amd64-linux doesn't work, so
1959         we ignore it. */
1960#     if !defined(VGP_amd64_linux)
1961      if (stab_img && stabstr_img) {
1962         ML_(read_debuginfo_stabs) ( di, stab_img, stab_sz,
1963                                         stabstr_img, stabstr_sz );
1964      }
1965#     endif
1966      /* jrs 2006-01-01: icc-8.1 has been observed to generate
1967         binaries without debug_str sections.  Don't preclude
1968         debuginfo reading for that reason, but, in
1969         read_unitinfo_dwarf2, do check that debugstr is non-NULL
1970         before using it. */
1971      if (debug_info_img && debug_abbv_img && debug_line_img
1972                                           /* && debug_str_img */) {
1973
1974         /* The old reader: line numbers and unwind info only */
1975         ML_(read_debuginfo_dwarf3) ( di,
1976                                      debug_info_img, debug_info_sz,
1977                                      debug_abbv_img, debug_abbv_sz,
1978                                      debug_line_img, debug_line_sz,
1979                                      debug_str_img,  debug_str_sz );
1980
1981         /* The new reader: read the DIEs in .debug_info to acquire
1982            information on variable types and locations.  But only if
1983            the tool asks for it, or the user requests it on the
1984            command line. */
1985         if (VG_(needs).var_info /* the tool requires it */
1986             || VG_(clo_read_var_info) /* the user asked for it */) {
1987            ML_(new_dwarf3_reader)(
1988               di, debug_info_img,   debug_info_sz,
1989                   debug_abbv_img,   debug_abbv_sz,
1990                   debug_line_img,   debug_line_sz,
1991                   debug_str_img,    debug_str_sz,
1992                   debug_ranges_img, debug_ranges_sz,
1993                   debug_loc_img,    debug_loc_sz
1994            );
1995         }
1996      }
1997      if (dwarf1d_img && dwarf1l_img) {
1998         ML_(read_debuginfo_dwarf1) ( di, dwarf1d_img, dwarf1d_sz,
1999                                          dwarf1l_img, dwarf1l_sz );
2000      }
2001   }
2002   res = True;
2003
2004  out: {
2005   SysRes m_res;
2006
2007   /* Last, but not least, heave the image(s) back overboard. */
2008   if (dimage) {
2009      m_res = VG_(am_munmap_valgrind) ( dimage, n_dimage );
2010      vg_assert(!m_res.isError);
2011   }
2012   m_res = VG_(am_munmap_valgrind) ( oimage, n_oimage );
2013   vg_assert(!m_res.isError);
2014   return res;
2015  }
2016}
2017
2018
2019/*--------------------------------------------------------------------*/
2020/*--- end                                                          ---*/
2021/*--------------------------------------------------------------------*/
2022