readelf.c revision 3c9cf3442185b5891e15450d6e3058aeff6796fe
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#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, "Reading debug info from %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   return sr_Res(sres);
968}
969
970/*
971 * Try to find a separate debug file for a given object file.
972 */
973static
974Addr find_debug_file( struct _DebugInfo* di,
975                      Char* objpath, Char* debugname,
976                      UInt crc, /*OUT*/UWord* size )
977{
978   Char *objdir = ML_(dinfo_strdup)("di.fdf.1", objpath);
979   Char *objdirptr;
980   Char *debugpath;
981   Addr addr = 0;
982
983   if ((objdirptr = VG_(strrchr)(objdir, '/')) != NULL)
984      *objdirptr = '\0';
985
986   debugpath = ML_(dinfo_zalloc)(
987                  "di.fdf.2",
988                  VG_(strlen)(objdir) + VG_(strlen)(debugname) + 32);
989
990   VG_(sprintf)(debugpath, "%s/%s", objdir, debugname);
991
992   if ((addr = open_debug_file(debugpath, crc, size)) == 0) {
993      VG_(sprintf)(debugpath, "%s/.debug/%s", objdir, debugname);
994      if ((addr = open_debug_file(debugpath, crc, size)) == 0) {
995         VG_(sprintf)(debugpath, "/usr/lib/debug%s/%s", objdir, debugname);
996         addr = open_debug_file(debugpath, crc, size);
997      }
998   }
999
1000   if (addr) {
1001      TRACE_SYMTAB("\n");
1002      TRACE_SYMTAB("------ Found a debuginfo file: %s\n", debugpath);
1003   }
1004
1005   ML_(dinfo_free)(debugpath);
1006   ML_(dinfo_free)(objdir);
1007
1008   return addr;
1009}
1010
1011
1012static Bool contained_within ( Addr outer, UWord n_outer,
1013                               Addr inner, UWord n_inner )
1014{
1015   if (n_outer == 0 || n_inner == 0)
1016      return False;
1017   /* Simplistic .. assumes no wraparound (reasonably enough) */
1018   if (inner >= outer && inner+n_inner <= outer+n_outer)
1019      return True;
1020   return False;
1021}
1022
1023static void* INDEX_BIS ( void* base, Word idx, Word scale ) {
1024   return (void*)( ((UChar*)base) + idx * scale );
1025}
1026
1027
1028/* Find the file offset corresponding to SVMA by using the program
1029   headers.  This is taken from binutils-2.17/binutils/readelf.c
1030   offset_from_vma(). */
1031static
1032Word file_offset_from_svma ( /*OUT*/Bool* ok,
1033                             Addr         svma,
1034                             ElfXX_Phdr*  phdr_img,
1035                             Word         phdr_nent,
1036                             Word         phdr_ent_szB )
1037{
1038   Word        i;
1039   ElfXX_Phdr* seg;
1040   for (i = 0; i < phdr_nent; i++) {
1041      seg = INDEX_BIS( phdr_img, i, phdr_ent_szB );
1042      if (seg->p_type != PT_LOAD)
1043         continue;
1044      if (svma >= (seg->p_vaddr & -seg->p_align)
1045          && svma + 1 <= seg->p_vaddr + seg->p_filesz) {
1046         *ok = True;
1047         return svma - seg->p_vaddr + seg->p_offset;
1048      }
1049   }
1050   *ok = False;
1051   return 0;
1052}
1053
1054/* The central function for reading ELF debug info.  For the
1055   object/exe specified by the DebugInfo, find ELF sections, then read
1056   the symbols, line number info, file name info, CFA (stack-unwind
1057   info) and anything else we want, into the tables within the
1058   supplied DebugInfo.
1059*/
1060Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
1061{
1062   Bool          res, ok;
1063   SysRes        fd, sres;
1064   Word          i;
1065
1066   /* Image addresses for the ELF file we're working with. */
1067   Addr          oimage   = 0;
1068   UWord         n_oimage = 0;
1069
1070   /* Ditto for any ELF debuginfo file that we might happen to load. */
1071   Addr          dimage   = 0;
1072   UWord         n_dimage = 0;
1073
1074   /* ELF header for the main file.  Should == oimage since is at
1075      start of file. */
1076   ElfXX_Ehdr* ehdr_img = NULL;
1077
1078   /* Program header table image addr, # entries, entry size */
1079   ElfXX_Phdr* phdr_img     = NULL;
1080   UWord       phdr_nent    = 0;
1081   UWord       phdr_ent_szB = 0;
1082
1083   /* Section header image addr, # entries, entry size.  Also the
1084      associated string table. */
1085   ElfXX_Shdr* shdr_img        = NULL;
1086   UWord       shdr_nent       = 0;
1087   UWord       shdr_ent_szB    = 0;
1088   UChar*      shdr_strtab_img = NULL;
1089
1090   /* SVMAs covered by rx and rw segments and corresponding bias. */
1091   Addr     rx_svma_base = 0;
1092   Addr     rx_svma_limit = 0;
1093   PtrdiffT rx_bias = 0;
1094   Addr     rw_svma_base = 0;
1095   Addr     rw_svma_limit = 0;
1096   PtrdiffT rw_bias = 0;
1097
1098   vg_assert(di);
1099   vg_assert(di->have_rx_map == True);
1100   vg_assert(di->have_rw_map == True);
1101   vg_assert(di->rx_map_size > 0);
1102   vg_assert(di->rw_map_size > 0);
1103   vg_assert(di->have_dinfo == False);
1104   vg_assert(di->filename);
1105   vg_assert(!di->memname);
1106   vg_assert(!di->symtab);
1107   vg_assert(!di->loctab);
1108   vg_assert(!di->cfsi);
1109   vg_assert(!di->cfsi_exprs);
1110   vg_assert(!di->strchunks);
1111   vg_assert(!di->soname);
1112
1113   /* If these don't hold true, it means that m_syswrap/m_aspacemgr
1114      managed to do a mapping where the start isn't page aligned.
1115      Which sounds pretty bogus to me. */
1116   vg_assert(VG_IS_PAGE_ALIGNED(di->rx_map_avma));
1117   vg_assert(VG_IS_PAGE_ALIGNED(di->rw_map_avma));
1118
1119   /* ----------------------------------------------------------
1120      At this point, there is very little information in the
1121      DebugInfo.  We only know that something that looks like an ELF
1122      file has been mapped rx-ishly as recorded with the di->*rx_map*
1123      fields and has also been mapped rw-ishly as recorded with the
1124      di->*rw_map* fields.  First we examine the file's ELF Program
1125      Header, and, by comparing that against the di->*r{w,x}_map*
1126      info, try to figure out the AVMAs for the sections we care
1127      about, that should have been mapped: text, data, sdata, bss got,
1128      plt, and toc.
1129      ---------------------------------------------------------- */
1130
1131   res = False;
1132
1133   oimage = (Addr)NULL;
1134   if (VG_(clo_verbosity) > 1 || VG_(clo_trace_redir))
1135      VG_(message)(Vg_DebugMsg, "Reading syms from %s (%#lx)\n",
1136                                di->filename, di->rx_map_avma );
1137
1138   /* mmap the object image aboard, so that we can read symbols and
1139      line number info out of it.  It will be munmapped immediately
1140      thereafter; it is only aboard transiently. */
1141
1142   fd = VG_(open)(di->filename, VKI_O_RDONLY, 0);
1143   if (sr_isError(fd)) {
1144      ML_(symerr)(di, True, "Can't open .so/.exe to read symbols?!");
1145      return False;
1146   }
1147
1148   { Long n_oimageLL = VG_(fsize)(sr_Res(fd));
1149     if (n_oimageLL <= 0) {
1150        ML_(symerr)(di, True, "Can't stat .so/.exe (to determine its size)?!");
1151        VG_(close)(sr_Res(fd));
1152        return False;
1153     }
1154     n_oimage = (UWord)(ULong)n_oimageLL;
1155   }
1156
1157   sres = VG_(am_mmap_file_float_valgrind)
1158             ( n_oimage, VKI_PROT_READ, sr_Res(fd), 0 );
1159
1160   VG_(close)(sr_Res(fd));
1161
1162   if (sr_isError(sres)) {
1163      VG_(message)(Vg_UserMsg, "warning: mmap failed on %s\n", di->filename );
1164      VG_(message)(Vg_UserMsg, "         no symbols or debug info loaded\n" );
1165      return False;
1166   }
1167
1168   oimage = sr_Res(sres);
1169   /* Check against wraparound.  am_mmap_file_float_valgrind should
1170      not produce a wrapped-around mapping. */
1171   vg_assert(n_oimage > 0);
1172   vg_assert(oimage + n_oimage > oimage);
1173
1174   if (0) {
1175      VG_(printf)("read_elf_debug_info: OIMAGE = %p - %p\n",
1176                  (void*)oimage, (void*)(oimage + (UWord)n_oimage));
1177   }
1178
1179   /* Ok, the object image is safely in oimage[0 .. n_oimage-1].  Now
1180      verify that it is a valid ELF .so or executable image. */
1181   res      = False;
1182   ok       = (n_oimage >= sizeof(ElfXX_Ehdr));
1183   ehdr_img = (ElfXX_Ehdr*)oimage;
1184
1185   if (ok)
1186      ok &= ML_(is_elf_object_file)(ehdr_img, n_oimage);
1187
1188   if (!ok) {
1189      ML_(symerr)(di, True, "Invalid ELF Header");
1190      goto out;
1191   }
1192
1193   /* Find where the program and section header tables are, and give
1194      up if either is missing or outside the image (bogus). */
1195   phdr_img     = (ElfXX_Phdr*)( ((UChar*)ehdr_img) + ehdr_img->e_phoff );
1196   phdr_nent    = ehdr_img->e_phnum;
1197   phdr_ent_szB = ehdr_img->e_phentsize;
1198
1199   shdr_img     = (ElfXX_Shdr*)( ((UChar*)ehdr_img) + ehdr_img->e_shoff );
1200   shdr_nent    = ehdr_img->e_shnum;
1201   shdr_ent_szB = ehdr_img->e_shentsize;
1202
1203   TRACE_SYMTAB("------ Basic facts about the object ------\n");
1204   TRACE_SYMTAB("object: img %p n_oimage %ld\n",
1205               (void*)oimage, n_oimage);
1206   TRACE_SYMTAB("phdr:   img %p nent %ld ent_szB %ld\n",
1207               phdr_img, phdr_nent, phdr_ent_szB);
1208   TRACE_SYMTAB("shdr:   img %p nent %ld ent_szB %ld\n",
1209               shdr_img, shdr_nent, shdr_ent_szB);
1210
1211   if (phdr_nent == 0
1212       || !contained_within(
1213             oimage, n_oimage,
1214             (Addr)phdr_img, phdr_nent * phdr_ent_szB)) {
1215      ML_(symerr)(di, True, "Missing or invalid ELF Program Header Table");
1216      goto out;
1217   }
1218
1219   if (shdr_nent == 0
1220       || !contained_within(
1221             oimage, n_oimage,
1222             (Addr)shdr_img, shdr_nent * shdr_ent_szB)) {
1223      ML_(symerr)(di, True, "Missing or invalid ELF Section Header Table");
1224      goto out;
1225   }
1226
1227   /* Also find the section header's string table, and validate. */
1228   /* checked previously by is_elf_object_file: */
1229   vg_assert( ehdr_img->e_shstrndx != SHN_UNDEF );
1230
1231   shdr_strtab_img
1232      = (UChar*)( ((UChar*)ehdr_img)
1233                  + shdr_img[ehdr_img->e_shstrndx].sh_offset);
1234   if (!contained_within( oimage, n_oimage,
1235                          (Addr)shdr_strtab_img,
1236                          1/*bogus, but we don't know the real size*/ )) {
1237      ML_(symerr)(di, True, "Invalid ELF Section Header String Table");
1238      goto out;
1239   }
1240
1241   TRACE_SYMTAB("shdr:   string table at %p\n", shdr_strtab_img );
1242
1243   /* Do another amazingly tedious thing: find out the .soname for
1244      this object.  Apparently requires looking through the program
1245      header table. */
1246   TRACE_SYMTAB("\n");
1247   TRACE_SYMTAB("------ Looking for the soname ------\n");
1248   vg_assert(di->soname == NULL);
1249   {
1250      ElfXX_Addr prev_svma = 0;
1251
1252      for (i = 0; i < phdr_nent; i++) {
1253         ElfXX_Phdr* phdr = INDEX_BIS( phdr_img, i, phdr_ent_szB );
1254
1255         /* Make sure the PT_LOADable entries are in order */
1256         if (phdr->p_type == PT_LOAD) {
1257            TRACE_SYMTAB("PT_LOAD in order?: %#lx %#lx\n",
1258                         prev_svma + 0UL,
1259                         phdr->p_vaddr + 0UL);
1260            if (phdr->p_vaddr < prev_svma) {
1261               ML_(symerr)(di, True,
1262                           "ELF Program Headers are not in ascending order");
1263               goto out;
1264            }
1265            prev_svma = phdr->p_vaddr;
1266            if (rx_svma_limit == 0
1267                && phdr->p_offset >= di->rx_map_foff
1268                && phdr->p_offset < di->rx_map_foff + di->rx_map_size
1269                && phdr->p_offset + phdr->p_filesz <= di->rx_map_foff + di->rx_map_size) {
1270               rx_svma_base = phdr->p_vaddr;
1271               rx_svma_limit = phdr->p_vaddr + phdr->p_memsz;
1272               rx_bias = di->rx_map_avma - di->rx_map_foff + phdr->p_offset - phdr->p_vaddr;
1273            }
1274            else if (rw_svma_limit == 0
1275                     && phdr->p_offset >= di->rw_map_foff
1276                     && phdr->p_offset < di->rw_map_foff + di->rw_map_size
1277                     && phdr->p_offset + phdr->p_filesz <= di->rw_map_foff + di->rw_map_size) {
1278               rw_svma_base = phdr->p_vaddr;
1279               rw_svma_limit = phdr->p_vaddr + phdr->p_memsz;
1280               rw_bias = di->rw_map_avma - di->rw_map_foff + phdr->p_offset - phdr->p_vaddr;
1281            }
1282         }
1283
1284         /* Try to get the soname.  If there isn't one, use "NONE".
1285            The seginfo needs to have some kind of soname in order to
1286            facilitate writing redirect functions, since all redirect
1287            specifications require a soname (pattern). */
1288         if (phdr->p_type == PT_DYNAMIC && di->soname == NULL) {
1289            ElfXX_Dyn* dyn_img = (ElfXX_Dyn*)( ((UChar*)ehdr_img)
1290                                               + phdr->p_offset);
1291            Word   stroff = -1;
1292            UChar* strtab = NULL;
1293            Word   j;
1294            for (j = 0; dyn_img[j].d_tag != DT_NULL; j++) {
1295               switch (dyn_img[j].d_tag) {
1296                  case DT_SONAME: {
1297                     stroff = dyn_img[j].d_un.d_val;
1298                     break;
1299                  }
1300                  case DT_STRTAB: {
1301                     Bool ok2 = False;
1302                     Word offset = file_offset_from_svma(
1303                                      &ok2,
1304                                      dyn_img[j].d_un.d_ptr,
1305                                      phdr_img,
1306                                      phdr_nent, phdr_ent_szB
1307                                   );
1308                     if (ok2 && strtab == NULL) {
1309                        vg_assert(offset >= 0 && offset <= n_oimage);
1310                        strtab = ((UChar*)ehdr_img) + offset;
1311                     }
1312                     break;
1313                  }
1314                  default:
1315                     break;
1316               }
1317            }
1318            if (stroff != -1 && strtab != NULL) {
1319               TRACE_SYMTAB("Found soname = %s\n", strtab+stroff);
1320               di->soname = ML_(dinfo_strdup)("di.redi.1", strtab+stroff);
1321            }
1322         }
1323      } /* for (i = 0; i < phdr_nent; i++) ... */
1324   } /* look for the soname */
1325
1326   /* If, after looking at all the program headers, we still didn't
1327      find a soname, add a fake one. */
1328   if (di->soname == NULL) {
1329      TRACE_SYMTAB("No soname found; using (fake) \"NONE\"\n");
1330      di->soname = "NONE";
1331   }
1332
1333   vg_assert(rx_svma_limit != 0);
1334   vg_assert(rw_svma_limit != 0);
1335
1336   /* Now read the section table. */
1337   TRACE_SYMTAB("\n");
1338   TRACE_SYMTAB("------ Examining the section headers "
1339                "and program headers ------\n");
1340   TRACE_SYMTAB("rx: at %#lx are mapped foffsets %ld .. %ld\n",
1341               di->rx_map_avma,
1342               di->rx_map_foff, di->rx_map_foff + di->rx_map_size - 1 );
1343   TRACE_SYMTAB("rx: contains svmas %#lx .. %#lx with bias %#lx\n",
1344                rx_svma_base, rx_svma_limit - 1, rx_bias );
1345   TRACE_SYMTAB("rw: at %#lx are mapped foffsets %ld .. %ld\n",
1346               di->rw_map_avma,
1347               di->rw_map_foff, di->rw_map_foff + di->rw_map_size - 1 );
1348   TRACE_SYMTAB("rw: contains svmas %#lx .. %#lx with bias %#lx\n",
1349                rw_svma_base, rw_svma_limit - 1, rw_bias );
1350
1351   for (i = 0; i < shdr_nent; i++) {
1352      ElfXX_Shdr* shdr = INDEX_BIS( shdr_img, i, shdr_ent_szB );
1353      UChar* name = shdr_strtab_img + shdr->sh_name;
1354      Addr   svma = shdr->sh_addr;
1355      OffT   foff = shdr->sh_offset;
1356      UWord  size = shdr->sh_size;
1357      UInt   alyn = shdr->sh_addralign;
1358      Bool   bits = !(shdr->sh_type == SHT_NOBITS);
1359      Bool   inrx = svma >= rx_svma_base && svma < rx_svma_limit;
1360      Bool   inrw = svma >= rw_svma_base && svma < rw_svma_limit;
1361
1362      TRACE_SYMTAB(" [sec %2ld]  %s %s  al%2u  foff %6ld .. %6ld  "
1363                  "  svma %p  name \"%s\"\n",
1364                  i, inrx ? "rx" : "  ", inrw ? "rw" : "  ", alyn,
1365                  foff, foff+size-1, (void*)svma, name );
1366
1367      /* Check for sane-sized segments.  SHT_NOBITS sections have zero
1368         size in the file. */
1369      if ((foff >= n_oimage) || (foff + (bits ? size : 0) > n_oimage)) {
1370         ML_(symerr)(di, True, "ELF Section extends beyond image end");
1371         goto out;
1372      }
1373
1374      /* Check for a sane alignment value. */
1375      if (alyn > 0 && -1 == VG_(log2)(alyn)) {
1376         ML_(symerr)(di, True, "ELF Section contains invalid "
1377                               ".sh_addralign value");
1378         goto out;
1379      }
1380
1381#     define BAD(_secname)                                 \
1382         do { ML_(symerr)(di, True,                        \
1383                          "Can't make sense of " _secname  \
1384                          " section mapping");             \
1385              goto out;                                    \
1386         } while (0)
1387
1388      /* Find avma-s for: .text .data .sdata .rodata .bss .sbss .plt .got .opd
1389         and .eh_frame */
1390
1391      /* Accept .text where mapped as rx (code), even if zero-sized */
1392      if (0 == VG_(strcmp)(name, ".text")) {
1393         if (inrx && size >= 0 && !di->text_present) {
1394            di->text_present = True;
1395            di->text_svma = svma;
1396            di->text_avma = svma + rx_bias;
1397            di->text_size = size;
1398            di->text_bias = rx_bias;
1399            di->text_debug_svma = svma;
1400            di->text_debug_bias = rx_bias;
1401            TRACE_SYMTAB("acquiring .text svma = %#lx .. %#lx\n",
1402                         di->text_svma,
1403                         di->text_svma + di->text_size - 1);
1404            TRACE_SYMTAB("acquiring .text avma = %#lx .. %#lx\n",
1405                         di->text_avma,
1406                         di->text_avma + di->text_size - 1);
1407            TRACE_SYMTAB("acquiring .text bias = %#lx\n", di->text_bias);
1408         } else {
1409            BAD(".text");
1410         }
1411      }
1412
1413      /* Accept .data where mapped as rw (data), even if zero-sized */
1414      if (0 == VG_(strcmp)(name, ".data")) {
1415         if (inrw && size >= 0 && !di->data_present) {
1416            di->data_present = True;
1417            di->data_svma = svma;
1418            di->data_avma = svma + rw_bias;
1419            di->data_size = size;
1420            di->data_bias = rw_bias;
1421            di->data_debug_svma = svma;
1422            di->data_debug_bias = rw_bias;
1423            TRACE_SYMTAB("acquiring .data svma = %#lx .. %#lx\n",
1424                         di->data_svma,
1425                         di->data_svma + di->data_size - 1);
1426            TRACE_SYMTAB("acquiring .data avma = %#lx .. %#lx\n",
1427                         di->data_avma,
1428                         di->data_avma + di->data_size - 1);
1429            TRACE_SYMTAB("acquiring .data bias = %#lx\n", di->data_bias);
1430         } else {
1431            BAD(".data");
1432         }
1433      }
1434
1435      /* Accept .sdata where mapped as rw (data) */
1436      if (0 == VG_(strcmp)(name, ".sdata")) {
1437         if (inrw && size > 0 && !di->sdata_present) {
1438            di->sdata_present = True;
1439            di->sdata_svma = svma;
1440            di->sdata_avma = svma + rw_bias;
1441            di->sdata_size = size;
1442            di->sdata_bias = rw_bias;
1443            di->sdata_debug_svma = svma;
1444            di->sdata_debug_bias = rw_bias;
1445            TRACE_SYMTAB("acquiring .sdata svma = %#lx .. %#lx\n",
1446                         di->sdata_svma,
1447                         di->sdata_svma + di->sdata_size - 1);
1448            TRACE_SYMTAB("acquiring .sdata avma = %#lx .. %#lx\n",
1449                         di->sdata_avma,
1450                         di->sdata_avma + di->sdata_size - 1);
1451            TRACE_SYMTAB("acquiring .sdata bias = %#lx\n", di->sdata_bias);
1452         } else {
1453            BAD(".sdata");
1454         }
1455      }
1456
1457      /* Accept .rodata where mapped as rx (data), even if zero-sized */
1458      if (0 == VG_(strcmp)(name, ".rodata")) {
1459         if (inrx && size >= 0 && !di->rodata_present) {
1460            di->rodata_present = True;
1461            di->rodata_svma = svma;
1462            di->rodata_avma = svma + rx_bias;
1463            di->rodata_size = size;
1464            di->rodata_bias = rx_bias;
1465            di->rodata_debug_svma = svma;
1466            di->rodata_debug_bias = rw_bias;
1467            TRACE_SYMTAB("acquiring .rodata svma = %#lx .. %#lx\n",
1468                         di->rodata_svma,
1469                         di->rodata_svma + di->rodata_size - 1);
1470            TRACE_SYMTAB("acquiring .rodata avma = %#lx .. %#lx\n",
1471                         di->rodata_avma,
1472                         di->rodata_avma + di->rodata_size - 1);
1473            TRACE_SYMTAB("acquiring .rodata bias = %#lx\n", di->rodata_bias);
1474         } else {
1475            BAD(".rodata");
1476         }
1477      }
1478
1479      /* Accept .bss where mapped as rw (data), even if zero-sized */
1480      if (0 == VG_(strcmp)(name, ".bss")) {
1481         if (inrw && size >= 0 && !di->bss_present) {
1482            di->bss_present = True;
1483            di->bss_svma = svma;
1484            di->bss_avma = svma + rw_bias;
1485            di->bss_size = size;
1486            di->bss_bias = rw_bias;
1487            di->bss_debug_svma = svma;
1488            di->bss_debug_bias = rw_bias;
1489            TRACE_SYMTAB("acquiring .bss svma = %#lx .. %#lx\n",
1490                         di->bss_svma,
1491                         di->bss_svma + di->bss_size - 1);
1492            TRACE_SYMTAB("acquiring .bss avma = %#lx .. %#lx\n",
1493                         di->bss_avma,
1494                         di->bss_avma + di->bss_size - 1);
1495            TRACE_SYMTAB("acquiring .bss bias = %#lx\n", di->bss_bias);
1496         } else
1497
1498         /* Now one from the wtf?! department ... */
1499         if (inrx && (!inrw) && size >= 0 && !di->bss_present) {
1500            /* File contains a .bss, but it got mapped as rx only.
1501               This is very strange.  For now, just pretend we didn't
1502               see it :-) */
1503            di->bss_present = False;
1504            di->bss_svma = 0;
1505            di->bss_avma = 0;
1506            di->bss_size = 0;
1507            di->bss_bias = 0;
1508            di->bss_debug_svma = 0;
1509            di->bss_debug_bias = 0;
1510            if (!VG_(clo_xml)) {
1511               VG_(message)(Vg_UserMsg,
1512                            "Warning: the following file's .bss is "
1513                            "mapped r-x only - ignoring .bss syms\n");
1514               VG_(message)(Vg_UserMsg,   " %s\n", di->filename
1515                                                      ? di->filename
1516                                                      : (UChar*)"(null?!)" );
1517            }
1518         } else
1519
1520         if ((!inrw) && (!inrx) && size >= 0 && !di->bss_present) {
1521            /* File contains a .bss, but it didn't get mapped.  Ignore. */
1522            di->bss_present = False;
1523            di->bss_svma = 0;
1524            di->bss_avma = 0;
1525            di->bss_size = 0;
1526            di->bss_bias = 0;
1527         } else {
1528            BAD(".bss");
1529         }
1530      }
1531
1532      /* Accept .sbss where mapped as rw (data) */
1533      if (0 == VG_(strcmp)(name, ".sbss")) {
1534         if (inrw && size > 0 && !di->sbss_present) {
1535            di->sbss_present = True;
1536            di->sbss_svma = svma;
1537            di->sbss_avma = svma + rw_bias;
1538            di->sbss_size = size;
1539            di->sbss_bias = rw_bias;
1540            di->sbss_debug_svma = svma;
1541            di->sbss_debug_bias = rw_bias;
1542            TRACE_SYMTAB("acquiring .sbss svma = %#lx .. %#lx\n",
1543                         di->sbss_svma,
1544                         di->sbss_svma + di->sbss_size - 1);
1545            TRACE_SYMTAB("acquiring .sbss avma = %#lx .. %#lx\n",
1546                         di->sbss_avma,
1547                         di->sbss_avma + di->sbss_size - 1);
1548            TRACE_SYMTAB("acquiring .sbss bias = %#lx\n", di->sbss_bias);
1549         } else {
1550            BAD(".sbss");
1551         }
1552      }
1553
1554      /* Accept .got where mapped as rw (data) */
1555      if (0 == VG_(strcmp)(name, ".got")) {
1556         if (inrw && size > 0 && !di->got_present) {
1557            di->got_present = True;
1558            di->got_avma = svma + rw_bias;
1559            di->got_size = size;
1560            TRACE_SYMTAB("acquiring .got avma = %#lx\n", di->got_avma);
1561         } else {
1562            BAD(".got");
1563         }
1564      }
1565
1566      /* Accept .got.plt where mapped as rw (data) */
1567      if (0 == VG_(strcmp)(name, ".got.plt")) {
1568         if (inrw && size > 0 && !di->gotplt_present) {
1569            di->gotplt_present = True;
1570            di->gotplt_avma = svma + rw_bias;
1571            di->gotplt_size = size;
1572            TRACE_SYMTAB("acquiring .got.plt avma = %#lx\n", di->gotplt_avma);
1573         } else if (size != 0) {
1574            BAD(".got.plt");
1575         }
1576      }
1577
1578      /* PLT is different on different platforms, it seems. */
1579#     if defined(VGP_x86_linux) || defined(VGP_amd64_linux)
1580      /* Accept .plt where mapped as rx (code) */
1581      if (0 == VG_(strcmp)(name, ".plt")) {
1582         if (inrx && size > 0 && !di->plt_present) {
1583            di->plt_present = True;
1584            di->plt_avma = svma + rx_bias;
1585            di->plt_size = size;
1586            TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
1587         } else {
1588            BAD(".plt");
1589         }
1590      }
1591#     elif defined(VGP_ppc32_linux)
1592      /* Accept .plt where mapped as rw (data) */
1593      if (0 == VG_(strcmp)(name, ".plt")) {
1594         if (inrw && size > 0 && !di->plt_present) {
1595            di->plt_present = True;
1596            di->plt_avma = svma + rw_bias;
1597            di->plt_size = size;
1598            TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
1599         } else {
1600            BAD(".plt");
1601         }
1602      }
1603#     elif defined(VGP_ppc64_linux)
1604      /* Accept .plt where mapped as rw (data), or unmapped */
1605      if (0 == VG_(strcmp)(name, ".plt")) {
1606         if (inrw && size > 0 && !di->plt_present) {
1607            di->plt_present = True;
1608            di->plt_avma = svma + rw_bias;
1609            di->plt_size = size;
1610            TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
1611         } else
1612         if ((!inrw) && (!inrx) && size > 0 && !di->plt_present) {
1613            /* File contains a .plt, but it didn't get mapped.
1614               Presumably it is not required on this platform.  At
1615               least don't reject the situation as invalid. */
1616            di->plt_present = True;
1617            di->plt_avma = 0;
1618            di->plt_size = 0;
1619         } else {
1620            BAD(".plt");
1621         }
1622      }
1623#     else
1624#       error "Unsupported platform"
1625#     endif
1626
1627      /* Accept .opd where mapped as rw (data) */
1628      if (0 == VG_(strcmp)(name, ".opd")) {
1629         if (inrw && size > 0 && !di->opd_present) {
1630            di->opd_present = True;
1631            di->opd_avma = svma + rw_bias;
1632            di->opd_size = size;
1633            TRACE_SYMTAB("acquiring .opd avma = %#lx\n", di->opd_avma);
1634         } else {
1635            BAD(".opd");
1636         }
1637      }
1638
1639      /* Accept .eh_frame where mapped as rx (code).  This seems to be
1640         the common case.  However, if that doesn't pan out, try for
1641         rw (data) instead. */
1642      if (0 == VG_(strcmp)(name, ".eh_frame")) {
1643         if (inrx && size > 0 && !di->ehframe_present) {
1644            di->ehframe_present = True;
1645            di->ehframe_avma = svma + rx_bias;
1646            di->ehframe_size = size;
1647            TRACE_SYMTAB("acquiring .eh_frame avma = %#lx\n", di->ehframe_avma);
1648         } else
1649         if (inrw && size > 0 && !di->ehframe_present) {
1650            di->ehframe_present = True;
1651            di->ehframe_avma = svma + rw_bias;
1652            di->ehframe_size = size;
1653            TRACE_SYMTAB("acquiring .eh_frame avma = %#lx\n", di->ehframe_avma);
1654         } else {
1655            BAD(".eh_frame");
1656         }
1657      }
1658
1659#    undef BAD
1660
1661   }
1662
1663   if (0) VG_(printf)("YYYY text_: avma %#lx  size %ld  bias %#lx\n",
1664                      di->text_avma, di->text_size, di->text_bias);
1665
1666   if (VG_(clo_verbosity) > 2 || VG_(clo_trace_redir))
1667      VG_(message)(Vg_DebugMsg, "   svma %#010lx, avma %#010lx\n",
1668                                di->text_avma - di->text_bias,
1669                                di->text_avma );
1670
1671   TRACE_SYMTAB("\n");
1672   TRACE_SYMTAB("------ Finding image addresses "
1673                "for debug-info sections ------\n");
1674
1675   /* Find interesting sections, read the symbol table(s), read any debug
1676      information */
1677   {
1678      /* IMAGE addresses: pointers to start of sections in the
1679         transiently loaded oimage, not in the fragments of the file
1680         mapped in by the guest's dynamic linker. */
1681      UChar*     strtab_img       = NULL; /* .strtab */
1682      ElfXX_Sym* symtab_img       = NULL; /* .symtab */
1683      UChar*     dynstr_img       = NULL; /* .dynstr */
1684      ElfXX_Sym* dynsym_img       = NULL; /* .dynsym */
1685      UChar*     debuglink_img    = NULL; /* .gnu_debuglink */
1686      UChar*     stab_img         = NULL; /* .stab         (stabs)  */
1687      UChar*     stabstr_img      = NULL; /* .stabstr      (stabs)  */
1688      UChar*     debug_line_img   = NULL; /* .debug_line   (dwarf2) */
1689      UChar*     debug_info_img   = NULL; /* .debug_info   (dwarf2) */
1690      UChar*     debug_abbv_img   = NULL; /* .debug_abbrev (dwarf2) */
1691      UChar*     debug_str_img    = NULL; /* .debug_str    (dwarf2) */
1692      UChar*     debug_ranges_img = NULL; /* .debug_ranges (dwarf2) */
1693      UChar*     debug_loc_img    = NULL; /* .debug_loc    (dwarf2) */
1694      UChar*     debug_frame_img  = NULL; /* .debug_frame  (dwarf2) */
1695      UChar*     dwarf1d_img      = NULL; /* .debug        (dwarf1) */
1696      UChar*     dwarf1l_img      = NULL; /* .line         (dwarf1) */
1697      UChar*     ehframe_img      = NULL; /* .eh_frame     (dwarf2) */
1698      UChar*     opd_img          = NULL; /* .opd (dwarf2,
1699                                                   ppc64-linux) */
1700      /* Section sizes, in bytes */
1701      SizeT      strtab_sz       = 0;
1702      SizeT      symtab_sz       = 0;
1703      SizeT      dynstr_sz       = 0;
1704      SizeT      dynsym_sz       = 0;
1705      SizeT      debuglink_sz    = 0;
1706      SizeT      stab_sz         = 0;
1707      SizeT      stabstr_sz      = 0;
1708      SizeT      debug_line_sz   = 0;
1709      SizeT      debug_info_sz   = 0;
1710      SizeT      debug_abbv_sz   = 0;
1711      SizeT      debug_str_sz    = 0;
1712      SizeT      debug_ranges_sz = 0;
1713      SizeT      debug_loc_sz    = 0;
1714      SizeT      debug_frame_sz  = 0;
1715      SizeT      dwarf1d_sz      = 0;
1716      SizeT      dwarf1l_sz      = 0;
1717      SizeT      ehframe_sz      = 0;
1718      SizeT      opd_sz_unused   = 0;
1719
1720      /* Find all interesting sections */
1721
1722      /* What FIND does: it finds the section called SEC_NAME.  The
1723         size of it is assigned to SEC_SIZE.  The address of the
1724         section in the transiently loaded oimage is assigned to
1725         SEC_FILEA.  Even for sections which are marked loadable, the
1726         client's ld.so may not have loaded them yet, so there is no
1727         guarantee that we can safely prod around in any such area).
1728         Because the entire object file is transiently mapped aboard
1729         for inspection, it's always safe to inspect that area. */
1730
1731      for (i = 0; i < ehdr_img->e_shnum; i++) {
1732
1733#        define FIND(sec_name, sec_size, sec_img) \
1734         do { ElfXX_Shdr* shdr \
1735                 = INDEX_BIS( shdr_img, i, shdr_ent_szB ); \
1736            if (0 == VG_(strcmp)(sec_name, shdr_strtab_img \
1737                                           + shdr->sh_name)) { \
1738               Bool nobits; \
1739               sec_img  = (void*)(oimage + shdr->sh_offset); \
1740               sec_size = shdr->sh_size; \
1741               nobits   = shdr->sh_type == SHT_NOBITS; \
1742               TRACE_SYMTAB( "%18s:  img %p .. %p\n", \
1743                             sec_name, (UChar*)sec_img, \
1744                             ((UChar*)sec_img) + sec_size - 1); \
1745               /* SHT_NOBITS sections have zero size in the file. */ \
1746               if ( shdr->sh_offset \
1747                    + (nobits ? 0 : sec_size) > n_oimage ) { \
1748                  ML_(symerr)(di, True, \
1749                              "   section beyond image end?!"); \
1750                  goto out; \
1751               } \
1752            } \
1753         } while (0);
1754
1755         /*   NAME              SIZE             IMAGE addr */
1756         FIND(".dynsym",        dynsym_sz,       dynsym_img)
1757         FIND(".dynstr",        dynstr_sz,       dynstr_img)
1758         FIND(".symtab",        symtab_sz,       symtab_img)
1759         FIND(".strtab",        strtab_sz,       strtab_img)
1760
1761         FIND(".gnu_debuglink", debuglink_sz,    debuglink_img)
1762
1763         FIND(".stab",          stab_sz,         stab_img)
1764         FIND(".stabstr",       stabstr_sz,      stabstr_img)
1765
1766         FIND(".debug_line",    debug_line_sz,   debug_line_img)
1767         FIND(".debug_info",    debug_info_sz,   debug_info_img)
1768         FIND(".debug_abbrev",  debug_abbv_sz,   debug_abbv_img)
1769         FIND(".debug_str",     debug_str_sz,    debug_str_img)
1770         FIND(".debug_ranges",  debug_ranges_sz, debug_ranges_img)
1771         FIND(".debug_loc",     debug_loc_sz,    debug_loc_img)
1772         FIND(".debug_frame",   debug_frame_sz,  debug_frame_img)
1773
1774         FIND(".debug",         dwarf1d_sz,      dwarf1d_img)
1775         FIND(".line",          dwarf1l_sz,      dwarf1l_img)
1776         FIND(".eh_frame",      ehframe_sz,      ehframe_img)
1777
1778         FIND(".opd",           opd_sz_unused,   opd_img)
1779
1780#        undef FIND
1781      }
1782
1783      /* Did we find a debuglink section? */
1784      if (debuglink_img != NULL) {
1785         UInt crc_offset = VG_ROUNDUP(VG_(strlen)(debuglink_img)+1, 4);
1786         UInt crc;
1787
1788         vg_assert(crc_offset + sizeof(UInt) <= debuglink_sz);
1789
1790         /* Extract the CRC from the debuglink section */
1791         crc = *(UInt *)(debuglink_img + crc_offset);
1792
1793         /* See if we can find a matching debug file */
1794         dimage = find_debug_file( di, di->filename, debuglink_img,
1795                                   crc, &n_dimage );
1796
1797         if (dimage != 0
1798             && n_dimage >= sizeof(ElfXX_Ehdr)
1799             && ML_(is_elf_object_file)((void*)dimage, n_dimage)) {
1800
1801            /* Pull out and validate program header and section header info */
1802            ElfXX_Ehdr* ehdr_dimg     = (ElfXX_Ehdr*)dimage;
1803            ElfXX_Phdr* phdr_dimg     = (ElfXX_Phdr*)( ((UChar*)ehdr_dimg)
1804                                                       + ehdr_dimg->e_phoff );
1805            UWord       phdr_dnent    = ehdr_dimg->e_phnum;
1806            UWord       phdr_dent_szB = ehdr_dimg->e_phentsize;
1807            ElfXX_Shdr* shdr_dimg     = (ElfXX_Shdr*)( ((UChar*)ehdr_dimg)
1808                                                       + ehdr_dimg->e_shoff );
1809            UWord       shdr_dnent       = ehdr_dimg->e_shnum;
1810            UWord       shdr_dent_szB    = ehdr_dimg->e_shentsize;
1811            UChar*      shdr_strtab_dimg = NULL;
1812
1813            /* SVMAs covered by rx and rw segments and corresponding bias. */
1814            Addr     rx_dsvma_base = 0;
1815            Addr     rx_dsvma_limit = 0;
1816            PtrdiffT rx_dbias = 0;
1817            Addr     rw_dsvma_base = 0;
1818            Addr     rw_dsvma_limit = 0;
1819            PtrdiffT rw_dbias = 0;
1820
1821            Bool need_symtab, need_stabs, need_dwarf2, need_dwarf1;
1822
1823            if (phdr_dnent == 0
1824                || !contained_within(
1825                       dimage, n_dimage,
1826                       (Addr)phdr_dimg, phdr_dnent * phdr_dent_szB)) {
1827               ML_(symerr)(di, True,
1828                           "Missing or invalid ELF Program Header Table"
1829                           " (debuginfo file)");
1830               goto out;
1831            }
1832
1833            if (shdr_dnent == 0
1834                || !contained_within(
1835                       dimage, n_dimage,
1836                       (Addr)shdr_dimg, shdr_dnent * shdr_dent_szB)) {
1837               ML_(symerr)(di, True,
1838                           "Missing or invalid ELF Section Header Table"
1839                           " (debuginfo file)");
1840               goto out;
1841            }
1842
1843            /* Also find the section header's string table, and validate. */
1844            /* checked previously by is_elf_object_file: */
1845            vg_assert( ehdr_dimg->e_shstrndx != SHN_UNDEF );
1846
1847            shdr_strtab_dimg
1848               = (UChar*)( ((UChar*)ehdr_dimg)
1849                           + shdr_dimg[ehdr_dimg->e_shstrndx].sh_offset);
1850            if (!contained_within(
1851                    dimage, n_dimage,
1852                    (Addr)shdr_strtab_dimg,
1853                    1/*bogus, but we don't know the real size*/ )) {
1854               ML_(symerr)(di, True,
1855                           "Invalid ELF Section Header String Table"
1856                           " (debuginfo file)");
1857               goto out;
1858            }
1859
1860            need_symtab = (NULL == symtab_img);
1861            need_stabs  = (NULL == stab_img);
1862            need_dwarf2 = (NULL == debug_info_img);
1863            need_dwarf1 = (NULL == dwarf1d_img);
1864
1865            for (i = 0; i < ehdr_dimg->e_phnum; i++) {
1866               ElfXX_Phdr* phdr
1867                  = INDEX_BIS( (void*)(dimage + ehdr_dimg->e_phoff),
1868                                          i, phdr_ent_szB );
1869               if (phdr->p_type == PT_LOAD) {
1870                  if (rx_dsvma_limit == 0
1871                      && phdr->p_offset >= di->rx_map_foff
1872                      && phdr->p_offset < di->rx_map_foff + di->rx_map_size
1873                      && phdr->p_offset + phdr->p_filesz <= di->rx_map_foff + di->rx_map_size) {
1874                     rx_dsvma_base = phdr->p_vaddr;
1875                     rx_dsvma_limit = phdr->p_vaddr + phdr->p_memsz;
1876                     rx_dbias = di->rx_map_avma - di->rx_map_foff + phdr->p_offset - phdr->p_vaddr;
1877                  }
1878                  else if (rw_dsvma_limit == 0
1879                           && phdr->p_offset >= di->rw_map_foff
1880                           && phdr->p_offset < di->rw_map_foff + di->rw_map_size
1881                           && phdr->p_offset + phdr->p_filesz <= di->rw_map_foff + di->rw_map_size) {
1882                     rw_dsvma_base = phdr->p_vaddr;
1883                     rw_dsvma_limit = phdr->p_vaddr + phdr->p_memsz;
1884                     rw_dbias = di->rw_map_avma - di->rw_map_foff + phdr->p_offset - phdr->p_vaddr;
1885                  }
1886               }
1887            }
1888
1889            /* Find all interesting sections */
1890            for (i = 0; i < ehdr_dimg->e_shnum; i++) {
1891
1892               /* Find debug svma and bias information for sections
1893                  we found in the main file. */
1894
1895#              define FIND(sec, seg) \
1896               do { ElfXX_Shdr* shdr \
1897                       = INDEX_BIS( shdr_dimg, i, shdr_dent_szB ); \
1898                  if (di->sec##_present \
1899                      && 0 == VG_(strcmp)("." #sec, \
1900                                          shdr_strtab_dimg + shdr->sh_name)) { \
1901                     vg_assert(di->sec##_size == shdr->sh_size); \
1902                     vg_assert(di->sec##_avma +  shdr->sh_addr + seg##_dbias); \
1903                     di->sec##_debug_svma = shdr->sh_addr; \
1904                     di->sec##_debug_bias = seg##_dbias; \
1905                     TRACE_SYMTAB("acquiring ." #sec " debug svma = %#lx .. %#lx\n", \
1906                                  di->sec##_debug_svma, \
1907                                  di->sec##_debug_svma + di->sec##_size - 1); \
1908                     TRACE_SYMTAB("acquiring ." #sec " debug bias = %#lx\n", \
1909                                  di->sec##_debug_bias); \
1910                  } \
1911               } while (0);
1912
1913               /* SECTION   SEGMENT */
1914               FIND(text,   rx)
1915               FIND(data,   rw)
1916               FIND(sdata,  rw)
1917               FIND(rodata, rw)
1918               FIND(bss,    rw)
1919               FIND(sbss,   rw)
1920
1921#              undef FIND
1922
1923               /* Same deal as previous FIND, except only do it for those
1924                  sections for which we didn't find anything useful in
1925                  the main file. */
1926
1927#              define FIND(condition, sec_name, sec_size, sec_img) \
1928               do { ElfXX_Shdr* shdr \
1929                       = INDEX_BIS( shdr_dimg, i, shdr_dent_szB ); \
1930                  if (condition \
1931                      && 0 == VG_(strcmp)(sec_name, \
1932                                          shdr_strtab_dimg + shdr->sh_name)) { \
1933                     Bool nobits; \
1934                     if (0 != sec_img) \
1935                        VG_(core_panic)("repeated section!\n"); \
1936                     sec_img  = (void*)(dimage + shdr->sh_offset); \
1937                     sec_size = shdr->sh_size; \
1938                     nobits   = shdr->sh_type == SHT_NOBITS; \
1939                     TRACE_SYMTAB( "%18s: dimg %p .. %p\n", \
1940                                   sec_name, \
1941                                   (UChar*)sec_img, \
1942                                   ((UChar*)sec_img) + sec_size - 1); \
1943                     /* SHT_NOBITS sections have zero size in the file. */ \
1944                     if ( shdr->sh_offset \
1945                          + (nobits ? 0 : sec_size) > n_dimage ) { \
1946                        ML_(symerr)(di, True, \
1947                                    "   section beyond image end?!"); \
1948                        goto out; \
1949                     } \
1950                  } \
1951               } while (0);
1952
1953               /* NEEDED?        NAME             SIZE           IMAGE addr */
1954               FIND(need_symtab, ".symtab",       symtab_sz,     symtab_img)
1955               FIND(need_symtab, ".strtab",       strtab_sz,     strtab_img)
1956               FIND(need_stabs,  ".stab",         stab_sz,       stab_img)
1957               FIND(need_stabs,  ".stabstr",      stabstr_sz,    stabstr_img)
1958               FIND(need_dwarf2, ".debug_line",   debug_line_sz, debug_line_img)
1959               FIND(need_dwarf2, ".debug_info",   debug_info_sz, debug_info_img)
1960               FIND(need_dwarf2, ".debug_abbrev", debug_abbv_sz, debug_abbv_img)
1961               FIND(need_dwarf2, ".debug_str",    debug_str_sz,  debug_str_img)
1962               FIND(need_dwarf2, ".debug_ranges", debug_ranges_sz,
1963                                                               debug_ranges_img)
1964               FIND(need_dwarf2, ".debug_loc",    debug_loc_sz,  debug_loc_img)
1965               FIND(need_dwarf2, ".debug_frame",  debug_frame_sz,
1966                                                               debug_frame_img)
1967               FIND(need_dwarf1, ".debug",        dwarf1d_sz,    dwarf1d_img)
1968               FIND(need_dwarf1, ".line",         dwarf1l_sz,    dwarf1l_img)
1969
1970#              undef FIND
1971            }
1972         }
1973      }
1974
1975      /* Check some sizes */
1976      vg_assert((dynsym_sz % sizeof(ElfXX_Sym)) == 0);
1977      vg_assert((symtab_sz % sizeof(ElfXX_Sym)) == 0);
1978
1979      /* Read symbols */
1980      {
1981         void (*read_elf_symtab)(struct _DebugInfo*,UChar*,
1982                                 ElfXX_Sym*,SizeT,
1983                                 UChar*,SizeT,
1984                                 Bool,UChar*);
1985         Bool symtab_in_debug;
1986#        if defined(VGP_ppc64_linux)
1987         read_elf_symtab = read_elf_symtab__ppc64_linux;
1988#        else
1989         read_elf_symtab = read_elf_symtab__normal;
1990#        endif
1991         symtab_in_debug = (Addr)symtab_img >= dimage
1992                           && (Addr)symtab_img < dimage + n_dimage;
1993         read_elf_symtab(di, "symbol table",
1994                         symtab_img, symtab_sz,
1995                         strtab_img, strtab_sz,
1996                         symtab_in_debug, opd_img);
1997
1998         read_elf_symtab(di, "dynamic symbol table",
1999                         dynsym_img, dynsym_sz,
2000                         dynstr_img, dynstr_sz,
2001                         False, opd_img);
2002      }
2003
2004      /* Read .eh_frame and .debug_frame (call-frame-info) if any */
2005      if (ehframe_img) {
2006         vg_assert(ehframe_sz == di->ehframe_size);
2007         ML_(read_callframe_info_dwarf3)( di, ehframe_img, ehframe_sz, True );
2008      }
2009      if (debug_frame_sz) {
2010         ML_(read_callframe_info_dwarf3)( di, debug_frame_img,
2011                                          debug_frame_sz, False );
2012      }
2013
2014      /* Read the stabs and/or dwarf2 debug information, if any.  It
2015         appears reading stabs stuff on amd64-linux doesn't work, so
2016         we ignore it. */
2017#     if !defined(VGP_amd64_linux)
2018      if (stab_img && stabstr_img) {
2019         ML_(read_debuginfo_stabs) ( di, stab_img, stab_sz,
2020                                         stabstr_img, stabstr_sz );
2021      }
2022#     endif
2023      /* jrs 2006-01-01: icc-8.1 has been observed to generate
2024         binaries without debug_str sections.  Don't preclude
2025         debuginfo reading for that reason, but, in
2026         read_unitinfo_dwarf2, do check that debugstr is non-NULL
2027         before using it. */
2028      if (debug_info_img && debug_abbv_img && debug_line_img
2029                                           /* && debug_str_img */) {
2030
2031         /* The old reader: line numbers and unwind info only */
2032         ML_(read_debuginfo_dwarf3) ( di,
2033                                      debug_info_img, debug_info_sz,
2034                                      debug_abbv_img, debug_abbv_sz,
2035                                      debug_line_img, debug_line_sz,
2036                                      debug_str_img,  debug_str_sz );
2037
2038         /* The new reader: read the DIEs in .debug_info to acquire
2039            information on variable types and locations.  But only if
2040            the tool asks for it, or the user requests it on the
2041            command line. */
2042         if (VG_(needs).var_info /* the tool requires it */
2043             || VG_(clo_read_var_info) /* the user asked for it */) {
2044            ML_(new_dwarf3_reader)(
2045               di, debug_info_img,   debug_info_sz,
2046                   debug_abbv_img,   debug_abbv_sz,
2047                   debug_line_img,   debug_line_sz,
2048                   debug_str_img,    debug_str_sz,
2049                   debug_ranges_img, debug_ranges_sz,
2050                   debug_loc_img,    debug_loc_sz
2051            );
2052         }
2053      }
2054      if (dwarf1d_img && dwarf1l_img) {
2055         ML_(read_debuginfo_dwarf1) ( di, dwarf1d_img, dwarf1d_sz,
2056                                          dwarf1l_img, dwarf1l_sz );
2057      }
2058   }
2059   res = True;
2060
2061  out: {
2062   SysRes m_res;
2063
2064   /* Last, but not least, heave the image(s) back overboard. */
2065   if (dimage) {
2066      m_res = VG_(am_munmap_valgrind) ( dimage, n_dimage );
2067      vg_assert(!sr_isError(m_res));
2068   }
2069   m_res = VG_(am_munmap_valgrind) ( oimage, n_oimage );
2070   vg_assert(!sr_isError(m_res));
2071   return res;
2072  }
2073}
2074
2075#endif // defined(VGO_linux)
2076
2077/*--------------------------------------------------------------------*/
2078/*--- end                                                          ---*/
2079/*--------------------------------------------------------------------*/
2080