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