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