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