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