readelf.c revision abe8793d216293af960a0334401795bf74945705
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, Char* sym_name, Addr sym_svma,
150                           Bool ppc64_linux_format )
151{
152   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 : (Char*)"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        Char*      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        Char** 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, UChar* tab_name,
617        ElfXX_Sym* symtab_img, SizeT symtab_szB,
618        UChar*     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   Char      *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      Char 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 = (UChar*)(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      UChar* 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, UChar* tab_name,
720        ElfXX_Sym* symtab_img, SizeT symtab_szB,
721        UChar*     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   Char       *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      Char 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 = (Char*)(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
905Char *find_buildid(Addr image, UWord n_image, Bool rel_ok)
906{
907   Char* 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               Char* name = (Char *)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      if (buildid || !rel_ok)
948         return buildid;
949
950      for (i = 0; i < ehdr->e_shnum; i++) {
951         ElfXX_Shdr* shdr
952            = (ElfXX_Shdr*)(image + ehdr->e_shoff + i * ehdr->e_shentsize);
953
954         if (shdr->sh_type == SHT_NOTE) {
955            ElfXX_Off offset =  shdr->sh_offset;
956
957            while (offset < shdr->sh_offset + shdr->sh_size) {
958               ElfXX_Nhdr* note = (ElfXX_Nhdr*)(image + offset);
959               Char* name = (Char *)note + sizeof(ElfXX_Nhdr);
960               UChar *desc = (UChar *)name + ((note->n_namesz + 3) & ~3);
961               Word j;
962
963               if (VG_(strcmp)(name, ELF_NOTE_GNU) == 0 &&
964                   note->n_type == NT_GNU_BUILD_ID) {
965                  buildid = ML_(dinfo_zalloc)("di.fbi.1",
966                                              note->n_descsz * 2 + 1);
967
968                  for (j = 0; j < note->n_descsz; j++) {
969                     VG_(sprintf)(buildid + VG_(strlen)(buildid),
970                                  "%02x", desc[j]);
971                  }
972               }
973
974               offset = offset + sizeof(ElfXX_Nhdr)
975                               + ((note->n_namesz + 3) & ~3)
976                               + ((note->n_descsz + 3) & ~3);
977            }
978         }
979      }
980   }
981#endif
982
983   return buildid;
984}
985
986/*
987 * This routine for calculating the CRC for a separate debug file
988 * is GPLed code borrowed from GNU binutils.
989 */
990static UInt
991calc_gnu_debuglink_crc32(UInt crc, const UChar *buf, Int len)
992{
993  static const UInt crc32_table[256] =
994    {
995      0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
996      0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
997      0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
998      0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
999      0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
1000      0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
1001      0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
1002      0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
1003      0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
1004      0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
1005      0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
1006      0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
1007      0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
1008      0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
1009      0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
1010      0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
1011      0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
1012      0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
1013      0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
1014      0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
1015      0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
1016      0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
1017      0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
1018      0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
1019      0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
1020      0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
1021      0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
1022      0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
1023      0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
1024      0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
1025      0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
1026      0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
1027      0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
1028      0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
1029      0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
1030      0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
1031      0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
1032      0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
1033      0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
1034      0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
1035      0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
1036      0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
1037      0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
1038      0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
1039      0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
1040      0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
1041      0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
1042      0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
1043      0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
1044      0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
1045      0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
1046      0x2d02ef8d
1047    };
1048  const UChar *end;
1049
1050  crc = ~crc & 0xffffffff;
1051  for (end = buf + len; buf < end; ++ buf)
1052    crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
1053  return ~crc & 0xffffffff;;
1054}
1055
1056/*
1057 * Try and open a separate debug file, ignoring any where the CRC does
1058 * not match the value from the main object file.
1059 */
1060static
1061Addr open_debug_file( Char* name, Char* buildid, UInt crc, Bool rel_ok,
1062                      /*OUT*/UWord* size )
1063{
1064   SysRes fd, sres;
1065   struct vg_stat stat_buf;
1066   UInt calccrc;
1067
1068   fd = VG_(open)(name, VKI_O_RDONLY, 0);
1069   if (sr_isError(fd))
1070      return 0;
1071
1072   if (VG_(fstat)(sr_Res(fd), &stat_buf) != 0) {
1073      VG_(close)(sr_Res(fd));
1074      return 0;
1075   }
1076
1077   if (VG_(clo_verbosity) > 1)
1078      VG_(message)(Vg_DebugMsg, "  Considering %s ..\n", name);
1079
1080   *size = stat_buf.size;
1081
1082   sres = VG_(am_mmap_file_float_valgrind)
1083             ( *size, VKI_PROT_READ, sr_Res(fd), 0 );
1084
1085   VG_(close)(sr_Res(fd));
1086
1087   if (sr_isError(sres))
1088      return 0;
1089
1090   if (buildid) {
1091      Char* debug_buildid = find_buildid(sr_Res(sres), *size, rel_ok);
1092      if (debug_buildid == NULL || VG_(strcmp)(buildid, debug_buildid) != 0) {
1093         SysRes res = VG_(am_munmap_valgrind)(sr_Res(sres), *size);
1094         vg_assert(!sr_isError(res));
1095         if (VG_(clo_verbosity) > 1)
1096            VG_(message)(Vg_DebugMsg,
1097               "  .. build-id mismatch (found %s wanted %s)\n",
1098               debug_buildid, buildid);
1099         ML_(dinfo_free)(debug_buildid);
1100         return 0;
1101      }
1102      ML_(dinfo_free)(debug_buildid);
1103
1104      if (VG_(clo_verbosity) > 1)
1105         VG_(message)(Vg_DebugMsg, "  .. build-id is valid\n");
1106   } else {
1107      calccrc = calc_gnu_debuglink_crc32(0, (UChar*)sr_Res(sres), *size);
1108      if (calccrc != crc) {
1109         SysRes res = VG_(am_munmap_valgrind)(sr_Res(sres), *size);
1110         vg_assert(!sr_isError(res));
1111         if (VG_(clo_verbosity) > 1)
1112            VG_(message)(Vg_DebugMsg,
1113               "  .. CRC mismatch (computed %08x wanted %08x)\n", calccrc, crc);
1114         return 0;
1115      }
1116
1117      if (VG_(clo_verbosity) > 1)
1118         VG_(message)(Vg_DebugMsg, "  .. CRC is valid\n");
1119   }
1120
1121   return sr_Res(sres);
1122}
1123
1124
1125/* Try to find and map in a debuginfo file by some totally ad-hoc
1126   scheme.  If successful, set *dimage and *n_dimage to point to the
1127   image, and return True, else return False.  A temporary hack for
1128   Android; does nothing on any other platform. */
1129static
1130Bool find_ad_hoc_debug_image( struct _DebugInfo* di,
1131                              Char* filename,
1132                              /*OUT*/Addr* dimage,
1133                              /*OUT*/SizeT* n_dimage )
1134{
1135   vg_assert(*dimage == 0 && *n_dimage == 0);
1136
1137#  if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android)
1138   return False; /* we don't know narfink */
1139
1140#  else /* android specific hacks; look away now. */
1141
1142   /* The deal is: if we're looking for for a debuginfo file for some
1143      object /path/to/object (which can be any path), see if we can
1144      find the file /sdcard/symbols/path/to/object.  So for example it
1145      produces the following mappings, both of which are important for
1146      Memcheck:
1147
1148      /system/bin/linker  --> /sdcard/symbols/system/bin/linker
1149      /system/lib/libc.so --> /sdcard/symbols/system/lib/libc.so
1150
1151      These /symbols files come from the AOSP build tree for your
1152      device, for example out/target/product/crespo/symbols/system
1153      (for a Nexus S), so one simple thing you can do is take the tree
1154      rooted at out/target/product/crespo/symbols/system on the host
1155      and park it at /sdcard/symbols/system on the device.  Then,
1156      assuming it matches what's actually running on the device,
1157      you'll have full debuginfo for all the libraries on the device.
1158
1159      But beware: there is no checking that the debuginfo file, if
1160      found, matches the main file in any way.
1161   */
1162   if (!filename || *filename != '/')
1163      return False;
1164
1165   HChar* nm = ML_(dinfo_zalloc)("di.fahdi.1",
1166                                 50 + VG_(strlen)(filename));
1167   VG_(sprintf)(nm, "/sdcard/symbols%s", filename);
1168
1169   SysRes fd = VG_(open)(nm, VKI_O_RDONLY, 0);
1170   if (sr_isError(fd)) goto fail;
1171
1172   struct vg_stat stat_buf;
1173   if (VG_(fstat)(sr_Res(fd), &stat_buf) != 0) {
1174      VG_(close)(sr_Res(fd));
1175      goto fail;
1176   }
1177
1178   *n_dimage = stat_buf.size;
1179
1180   SysRes sres = VG_(am_mmap_file_float_valgrind)
1181                    ( *n_dimage, VKI_PROT_READ, sr_Res(fd), 0 );
1182
1183   VG_(close)(sr_Res(fd));
1184   if (sr_isError(sres))
1185     goto fail;
1186
1187   *dimage = sr_Res(sres);
1188
1189   if (VG_(clo_verbosity) > 1)
1190      VG_(dmsg)("  Using debuginfo from %s\n", nm);
1191
1192   ML_(dinfo_free)(nm);
1193   return True;
1194
1195  fail:
1196   if (nm) ML_(dinfo_free)(nm);
1197   return False;
1198
1199#  endif
1200}
1201
1202
1203/* Try to find a separate debug file for a given object file.  If
1204   found, it will be mapped in and the address and size returned in
1205   *dimage and *n_dimage.  If not, *dimage and *n_dimage will be
1206   unchanged.  The caller should set them to zero before the call. */
1207static
1208void find_debug_file( struct _DebugInfo* di,
1209                      Char* objpath, Char* buildid,
1210                      Char* debugname, UInt crc, Bool rel_ok,
1211                      /*OUT*/Addr*  dimage,
1212                      /*OUT*/SizeT* n_dimage )
1213{
1214   Char* debugpath = NULL;
1215   Addr  addr = 0;
1216   UWord size = 0;
1217
1218   vg_assert(*dimage == 0 && *n_dimage == 0);
1219
1220   if (buildid != NULL) {
1221      debugpath = ML_(dinfo_zalloc)(
1222                     "di.fdf.1",
1223                     VG_(strlen)(buildid) + 33);
1224
1225      VG_(sprintf)(debugpath, "/usr/lib/debug/.build-id/%c%c/%s.debug",
1226                   buildid[0], buildid[1], buildid + 2);
1227
1228      if ((addr = open_debug_file(debugpath, buildid, 0,
1229                                  rel_ok, &size)) == 0) {
1230         ML_(dinfo_free)(debugpath);
1231         debugpath = NULL;
1232      }
1233   }
1234
1235   if (addr == 0 && debugname != NULL && !rel_ok) {
1236      Char *objdir = ML_(dinfo_strdup)("di.fdf.2", objpath);
1237      Char *objdirptr;
1238
1239      if ((objdirptr = VG_(strrchr)(objdir, '/')) != NULL)
1240         *objdirptr = '\0';
1241
1242      debugpath = ML_(dinfo_zalloc)(
1243                     "di.fdf.3",
1244                     VG_(strlen)(objdir) + VG_(strlen)(debugname) + 32);
1245
1246      VG_(sprintf)(debugpath, "%s/%s", objdir, debugname);
1247
1248      if ((addr = open_debug_file(debugpath, NULL, crc, rel_ok, &size)) == 0) {
1249         VG_(sprintf)(debugpath, "%s/.debug/%s", objdir, debugname);
1250         if ((addr = open_debug_file(debugpath, NULL, crc, rel_ok, &size)) == 0) {
1251            VG_(sprintf)(debugpath, "/usr/lib/debug%s/%s", objdir, debugname);
1252            addr = open_debug_file(debugpath, NULL, crc, rel_ok, &size);
1253         }
1254      }
1255
1256      ML_(dinfo_free)(objdir);
1257   }
1258
1259   if (addr > 0 && size > 0) {
1260      TRACE_SYMTAB("\n");
1261      TRACE_SYMTAB("------ Found a debuginfo file: %s\n", debugpath);
1262      *dimage = addr;
1263      *n_dimage = size;
1264   }
1265
1266   ML_(dinfo_free)(debugpath);
1267}
1268
1269
1270static Bool contained_within ( Addr outer, UWord n_outer,
1271                               Addr inner, UWord n_inner )
1272{
1273   if (n_outer == 0 || n_inner == 0)
1274      return False;
1275   /* Simplistic .. assumes no wraparound (reasonably enough) */
1276   if (inner >= outer && inner+n_inner <= outer+n_outer)
1277      return True;
1278   return False;
1279}
1280
1281static void* INDEX_BIS ( void* base, Word idx, Word scale ) {
1282   return (void*)( ((UChar*)base) + idx * scale );
1283}
1284
1285
1286/* Find the file offset corresponding to SVMA by using the program
1287   headers.  This is taken from binutils-2.17/binutils/readelf.c
1288   offset_from_vma(). */
1289static
1290Word file_offset_from_svma ( /*OUT*/Bool* ok,
1291                             Addr         svma,
1292                             ElfXX_Phdr*  phdr_img,
1293                             Word         phdr_nent,
1294                             Word         phdr_ent_szB )
1295{
1296   Word        i;
1297   ElfXX_Phdr* seg;
1298   for (i = 0; i < phdr_nent; i++) {
1299      seg = INDEX_BIS( phdr_img, i, phdr_ent_szB );
1300      if (seg->p_type != PT_LOAD)
1301         continue;
1302      if (svma >= (seg->p_vaddr & -seg->p_align)
1303          && svma + 1 <= seg->p_vaddr + seg->p_filesz) {
1304         *ok = True;
1305         return svma - seg->p_vaddr + seg->p_offset;
1306      }
1307   }
1308   *ok = False;
1309   return 0;
1310}
1311
1312
1313/* The central function for reading ELF debug info.  For the
1314   object/exe specified by the DebugInfo, find ELF sections, then read
1315   the symbols, line number info, file name info, CFA (stack-unwind
1316   info) and anything else we want, into the tables within the
1317   supplied DebugInfo.
1318*/
1319
1320Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
1321{
1322   /* This function is long and complex.  That, and the presence of
1323      nested scopes, means it's not always easy to see which parts are
1324      in loops/conditionals and which aren't.  To make it easier to
1325      follow, points executed exactly once -- that is, those which are
1326      the top level of the function -- are marked TOPLEVEL.
1327   */
1328   /* TOPLEVEL */
1329   Bool          res, ok;
1330   SysRes        fd, sres;
1331   Word          i, j;
1332   Bool          dynbss_present = False;
1333   Bool          sdynbss_present = False;
1334
1335   /* Image addresses for the ELF file we're working with. */
1336   Addr          oimage   = 0;
1337   UWord         n_oimage = 0;
1338
1339   /* Ditto for any ELF debuginfo file that we might happen to load. */
1340   Addr          dimage   = 0;
1341   UWord         n_dimage = 0;
1342
1343   /* Ditto for alternate ELF debuginfo file that we might happen to load. */
1344   Addr          aimage   = 0;
1345   UWord         n_aimage = 0;
1346
1347   /* ELF header for the main file.  Should == oimage since is at
1348      start of file. */
1349   ElfXX_Ehdr* ehdr_img = NULL;
1350
1351   /* Program header table image addr, # entries, entry size */
1352   ElfXX_Phdr* phdr_img     = NULL;
1353   UWord       phdr_nent    = 0;
1354   UWord       phdr_ent_szB = 0;
1355
1356   /* Section header image addr, # entries, entry size.  Also the
1357      associated string table. */
1358   ElfXX_Shdr* shdr_img        = NULL;
1359   UWord       shdr_nent       = 0;
1360   UWord       shdr_ent_szB    = 0;
1361   UChar*      shdr_strtab_img = NULL;
1362
1363   /* SVMAs covered by rx and rw segments and corresponding biases.
1364      Normally each object would provide just one rx and one rw area,
1365      but various ELF mangling tools create objects with multiple
1366      such entries, hence the generality. */
1367   typedef
1368      struct {
1369         Addr     svma_base;
1370         Addr     svma_limit;
1371         PtrdiffT bias;
1372         Bool     exec;
1373      }
1374      RangeAndBias;
1375
1376   XArray* /* of RangeAndBias */ svma_ranges = NULL;
1377
1378   /* Build ID */
1379   Char* buildid = NULL;
1380
1381   vg_assert(di);
1382   vg_assert(di->fsm.have_rx_map == True);
1383   vg_assert(di->fsm.have_rw_map == True);
1384   vg_assert(di->have_dinfo == False);
1385   vg_assert(di->fsm.filename);
1386   vg_assert(!di->symtab);
1387   vg_assert(!di->loctab);
1388   vg_assert(!di->cfsi);
1389   vg_assert(!di->cfsi_exprs);
1390   vg_assert(!di->strchunks);
1391   vg_assert(!di->soname);
1392
1393   {
1394      Bool has_nonempty_rx = False;
1395      Bool has_nonempty_rw = False;
1396      for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1397         struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
1398         if (!map->rx && !map->rw)
1399            continue;
1400         if (map->rx && map->size > 0)
1401            has_nonempty_rx = True;
1402         if (map->rw && map->size > 0)
1403            has_nonempty_rw = True;
1404         /* If this doesn't hold true, it means that m_syswrap/m_aspacemgr
1405            managed to do a mapping where the start isn't page aligned.
1406            Which sounds pretty bogus to me. */
1407         vg_assert(VG_IS_PAGE_ALIGNED(map->avma));
1408      }
1409      vg_assert(has_nonempty_rx);
1410      vg_assert(has_nonempty_rw);
1411   }
1412
1413   /* ----------------------------------------------------------
1414      At this point, there is very little information in the
1415      DebugInfo.  We only know that something that looks like an ELF
1416      file has been mapped rx-ishly and rw-ishly as recorded in the
1417      di->fsm.maps array items.  First we examine the file's ELF
1418      Program Header, and, by comparing that against the di->fsm.maps
1419      info, try to figure out the AVMAs for the sections we care
1420      about, that should have been mapped: text, data, sdata, bss,
1421      got, plt, and toc.
1422      ---------------------------------------------------------- */
1423
1424   res = False;
1425
1426   oimage = (Addr)NULL;
1427   if (VG_(clo_verbosity) > 1 || VG_(clo_trace_redir))
1428      VG_(message)(Vg_DebugMsg, "Reading syms from %s\n",
1429                                di->fsm.filename );
1430
1431   /* mmap the object image aboard, so that we can read symbols and
1432      line number info out of it.  It will be munmapped immediately
1433      thereafter; it is only aboard transiently. */
1434
1435   fd = VG_(open)(di->fsm.filename, VKI_O_RDONLY, 0);
1436   if (sr_isError(fd)) {
1437      ML_(symerr)(di, True, "Can't open .so/.exe to read symbols?!");
1438      return False;
1439   }
1440
1441   { Long n_oimageLL = VG_(fsize)(sr_Res(fd));
1442     if (n_oimageLL <= 0) {
1443        ML_(symerr)(di, True, "Can't stat .so/.exe (to determine its size)?!");
1444        VG_(close)(sr_Res(fd));
1445        return False;
1446     }
1447     n_oimage = (UWord)(ULong)n_oimageLL;
1448   }
1449
1450   sres = VG_(am_mmap_file_float_valgrind)
1451             ( n_oimage, VKI_PROT_READ, sr_Res(fd), 0 );
1452
1453   VG_(close)(sr_Res(fd));
1454
1455   if (sr_isError(sres)) {
1456      VG_(message)(Vg_UserMsg, "warning: mmap failed on %s\n",
1457                               di->fsm.filename );
1458      VG_(message)(Vg_UserMsg, "         no symbols or debug info loaded\n" );
1459      return False;
1460   }
1461
1462   oimage = sr_Res(sres);
1463   /* Check against wraparound.  am_mmap_file_float_valgrind should
1464      not produce a wrapped-around mapping. */
1465   vg_assert(n_oimage > 0);
1466   vg_assert(oimage + n_oimage > oimage);
1467
1468   if (0) {
1469      VG_(printf)("read_elf_debug_info: OIMAGE = %p - %p\n",
1470                  (void*)oimage, (void*)(oimage + (UWord)n_oimage));
1471   }
1472
1473   /* Ok, the object image is safely in oimage[0 .. n_oimage-1].  Now
1474      verify that it is a valid ELF .so or executable image. */
1475   res      = False;
1476   ok       = (n_oimage >= sizeof(ElfXX_Ehdr));
1477   ehdr_img = (ElfXX_Ehdr*)oimage;
1478
1479   if (ok)
1480      ok &= ML_(is_elf_object_file)(ehdr_img, n_oimage, False);
1481
1482   if (!ok) {
1483      ML_(symerr)(di, True, "Invalid ELF Header");
1484      goto out;
1485   }
1486
1487   /* Find where the program and section header tables are, and give
1488      up if either is missing or outside the image (bogus). */
1489   phdr_img     = (ElfXX_Phdr*)( ((UChar*)ehdr_img) + ehdr_img->e_phoff );
1490   phdr_nent    = ehdr_img->e_phnum;
1491   phdr_ent_szB = ehdr_img->e_phentsize;
1492
1493   shdr_img     = (ElfXX_Shdr*)( ((UChar*)ehdr_img) + ehdr_img->e_shoff );
1494   shdr_nent    = ehdr_img->e_shnum;
1495   shdr_ent_szB = ehdr_img->e_shentsize;
1496
1497   TRACE_SYMTAB("------ Basic facts about the object ------\n");
1498   TRACE_SYMTAB("object:  img %p n_oimage %ld\n",
1499               (void*)oimage, n_oimage);
1500   TRACE_SYMTAB("phdr:    img %p nent %ld ent_szB %ld\n",
1501               phdr_img, phdr_nent, phdr_ent_szB);
1502   TRACE_SYMTAB("shdr:    img %p nent %ld ent_szB %ld\n",
1503               shdr_img, shdr_nent, shdr_ent_szB);
1504   for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1505      struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
1506      if (map->rx)
1507         TRACE_SYMTAB("rx_map:  avma %#lx   size %lu  foff %lu\n",
1508                      map->avma, map->size, map->foff);
1509   }
1510   for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1511      struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
1512      if (map->rw)
1513         TRACE_SYMTAB("rw_map:  avma %#lx   size %lu  foff %lu\n",
1514                      map->avma, map->size, map->foff);
1515   }
1516
1517   if (phdr_nent == 0
1518       || !contained_within(
1519             oimage, n_oimage,
1520             (Addr)phdr_img, phdr_nent * phdr_ent_szB)) {
1521      ML_(symerr)(di, True, "Missing or invalid ELF Program Header Table");
1522      goto out;
1523   }
1524
1525   if (shdr_nent == 0
1526       || !contained_within(
1527             oimage, n_oimage,
1528             (Addr)shdr_img, shdr_nent * shdr_ent_szB)) {
1529      ML_(symerr)(di, True, "Missing or invalid ELF Section Header Table");
1530      goto out;
1531   }
1532
1533   /* Also find the section header's string table, and validate. */
1534   /* checked previously by is_elf_object_file: */
1535   vg_assert( ehdr_img->e_shstrndx != SHN_UNDEF );
1536
1537   shdr_strtab_img
1538      = (UChar*)( ((UChar*)ehdr_img)
1539                  + shdr_img[ehdr_img->e_shstrndx].sh_offset);
1540   if (!contained_within( oimage, n_oimage,
1541                          (Addr)shdr_strtab_img,
1542                          1/*bogus, but we don't know the real size*/ )) {
1543      ML_(symerr)(di, True, "Invalid ELF Section Header String Table");
1544      goto out;
1545   }
1546
1547   TRACE_SYMTAB("shdr:    string table at %p\n", shdr_strtab_img );
1548
1549   svma_ranges = VG_(newXA)(ML_(dinfo_zalloc), "di.relfdi.1",
1550                            ML_(dinfo_free), sizeof(RangeAndBias));
1551
1552   /* TOPLEVEL */
1553   /* Look through the program header table, and:
1554      - copy information from suitable PT_LOAD entries into svma_ranges
1555      - find (or fake up) the .soname for this object.
1556   */
1557   TRACE_SYMTAB("\n");
1558   TRACE_SYMTAB("------ Examining the program headers ------\n");
1559   vg_assert(di->soname == NULL);
1560   {
1561      /* TOPLEVEL */
1562      ElfXX_Addr prev_svma = 0;
1563
1564      for (i = 0; i < phdr_nent; i++) {
1565         ElfXX_Phdr* phdr = INDEX_BIS( phdr_img, i, phdr_ent_szB );
1566
1567         /* Make sure the PT_LOADable entries are in order and
1568            non-overlapping.  This in turn means the address ranges
1569            slurped into svma_ranges are in order and
1570            non-overlapping. */
1571
1572         if (phdr->p_type == PT_LOAD) {
1573            TRACE_SYMTAB("PT_LOAD[%ld]: p_vaddr %#lx (prev %#lx)\n",
1574                         i, (UWord)phdr->p_vaddr, (UWord)prev_svma);
1575            TRACE_SYMTAB("PT_LOAD[%ld]:   p_offset %lu, p_filesz %lu,"
1576                         " perms %c%c%c\n",
1577                         i, (UWord)phdr->p_offset, (UWord)phdr->p_filesz,
1578                         phdr->p_flags & PF_R ? 'r' : '-',
1579                         phdr->p_flags & PF_W ? 'w' : '-',
1580                         phdr->p_flags & PF_X ? 'x' : '-');
1581            if (phdr->p_vaddr < prev_svma) {
1582               ML_(symerr)(di, True,
1583                           "ELF Program Headers are not in ascending order");
1584               goto out;
1585            }
1586            prev_svma = phdr->p_vaddr;
1587            if (phdr->p_memsz > 0) {
1588               Bool loaded = False;
1589               for (j = 0; j < VG_(sizeXA)(di->fsm.maps); j++) {
1590                  struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, j);
1591                  if (   (map->rx || map->rw)
1592                      && phdr->p_offset >= map->foff
1593                      && phdr->p_offset <  map->foff + map->size
1594                      && phdr->p_offset + phdr->p_filesz <= map->foff
1595                                                            + map->size) {
1596                     RangeAndBias item;
1597                     item.svma_base  = phdr->p_vaddr;
1598                     item.svma_limit = phdr->p_vaddr + phdr->p_memsz;
1599                     item.bias       = map->avma - map->foff
1600                                       + phdr->p_offset - phdr->p_vaddr;
1601                     if (   map->rw
1602                         && (phdr->p_flags & (PF_R | PF_W)) == (PF_R | PF_W)) {
1603                        item.exec = False;
1604                        VG_(addToXA)(svma_ranges, &item);
1605                        TRACE_SYMTAB("PT_LOAD[%ld]:   acquired as rw\n", i);
1606                        loaded = True;
1607                     }
1608                     if (   map->rx
1609                         && (phdr->p_flags & (PF_R | PF_X)) == (PF_R | PF_X)) {
1610                        item.exec = True;
1611                        VG_(addToXA)(svma_ranges, &item);
1612                        TRACE_SYMTAB("PT_LOAD[%ld]:   acquired as rx\n", i);
1613                        loaded = True;
1614                     }
1615                  }
1616               }
1617               if (!loaded) {
1618                  ML_(symerr)(di, False,
1619                              "ELF section outside all mapped regions");
1620                  goto out;
1621               }
1622            }
1623         }
1624
1625         /* Try to get the soname.  If there isn't one, use "NONE".
1626            The seginfo needs to have some kind of soname in order to
1627            facilitate writing redirect functions, since all redirect
1628            specifications require a soname (pattern). */
1629         if (phdr->p_type == PT_DYNAMIC && di->soname == NULL) {
1630            ElfXX_Dyn* dyn_img = (ElfXX_Dyn*)( ((UChar*)ehdr_img)
1631                                               + phdr->p_offset);
1632            Word   stroff = -1;
1633            UChar* strtab = NULL;
1634            for (j = 0; dyn_img[j].d_tag != DT_NULL; j++) {
1635               switch (dyn_img[j].d_tag) {
1636                  case DT_SONAME: {
1637                     stroff = dyn_img[j].d_un.d_val;
1638                     break;
1639                  }
1640                  case DT_STRTAB: {
1641                     Bool ok2 = False;
1642                     Word offset = file_offset_from_svma(
1643                                      &ok2,
1644                                      dyn_img[j].d_un.d_ptr,
1645                                      phdr_img,
1646                                      phdr_nent, phdr_ent_szB
1647                                   );
1648                     if (ok2 && strtab == NULL) {
1649                        vg_assert(offset >= 0 && offset <= n_oimage);
1650                        strtab = ((UChar*)ehdr_img) + offset;
1651                     }
1652                     break;
1653                  }
1654                  default:
1655                     break;
1656               }
1657            }
1658            if (stroff != -1 && strtab != NULL) {
1659               TRACE_SYMTAB("Found soname = %s\n", strtab+stroff);
1660               di->soname = ML_(dinfo_strdup)("di.redi.1", strtab+stroff);
1661            }
1662         }
1663      } /* for (i = 0; i < phdr_nent; i++) ... */
1664      /* TOPLEVEL */
1665
1666   } /* examine the program headers (local scope) */
1667
1668   /* TOPLEVEL */
1669
1670   /* If, after looking at all the program headers, we still didn't
1671      find a soname, add a fake one. */
1672   if (di->soname == NULL) {
1673      TRACE_SYMTAB("No soname found; using (fake) \"NONE\"\n");
1674      di->soname = ML_(dinfo_strdup)("di.redi.2", "NONE");
1675   }
1676
1677   vg_assert(VG_(sizeXA)(svma_ranges) != 0);
1678
1679   /* Now read the section table. */
1680   TRACE_SYMTAB("\n");
1681   TRACE_SYMTAB("------ Examining the section headers ------\n");
1682   for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1683      struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
1684      if (map->rx)
1685         TRACE_SYMTAB("rx: at %#lx are mapped foffsets %ld .. %ld\n",
1686                      map->avma, map->foff, map->foff + map->size - 1 );
1687   }
1688   TRACE_SYMTAB("rx: contains these svma regions:\n");
1689   for (i = 0; i < VG_(sizeXA)(svma_ranges); i++) {
1690      RangeAndBias* reg = VG_(indexXA)(svma_ranges, i);
1691      if (reg->exec)
1692         TRACE_SYMTAB("  svmas %#lx .. %#lx with bias %#lx\n",
1693                      reg->svma_base, reg->svma_limit - 1, reg->bias );
1694   }
1695   for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1696      struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
1697      if (map->rw)
1698         TRACE_SYMTAB("rw: at %#lx are mapped foffsets %ld .. %ld\n",
1699                      map->avma, map->foff, map->foff + map->size - 1 );
1700   }
1701   TRACE_SYMTAB("rw: 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
1709   /* TOPLEVEL */
1710   /* Iterate over section headers */
1711   for (i = 0; i < shdr_nent; i++) {
1712      ElfXX_Shdr* shdr = INDEX_BIS( shdr_img, i, shdr_ent_szB );
1713      UChar* name = shdr_strtab_img + shdr->sh_name;
1714      Addr   svma = shdr->sh_addr;
1715      OffT   foff = shdr->sh_offset;
1716      UWord  size = shdr->sh_size; /* Do not change this to be signed. */
1717      UInt   alyn = shdr->sh_addralign;
1718      Bool   bits = !(shdr->sh_type == SHT_NOBITS);
1719      /* Look through our collection of info obtained from the PT_LOAD
1720         headers, and make 'inrx' and 'inrw' point to the first entry
1721         in each that intersects 'avma'.  If in each case none is found,
1722         leave the relevant pointer at NULL. */
1723      RangeAndBias* inrx = NULL;
1724      RangeAndBias* inrw = NULL;
1725      for (j = 0; j < VG_(sizeXA)(svma_ranges); j++) {
1726         RangeAndBias* rng = VG_(indexXA)(svma_ranges, j);
1727         if (svma >= rng->svma_base && svma < rng->svma_limit) {
1728            if (!inrx && rng->exec) {
1729               inrx = rng;
1730            } else if (!inrw && !rng->exec) {
1731               inrw = rng;
1732            }
1733            if (inrx && inrw)
1734               break;
1735         }
1736      }
1737
1738      TRACE_SYMTAB(" [sec %2ld]  %s %s  al%2u  foff %6ld .. %6ld  "
1739                  "  svma %p  name \"%s\"\n",
1740                  i, inrx ? "rx" : "  ", inrw ? "rw" : "  ", alyn,
1741                  foff, foff+size-1, (void*)svma, name );
1742
1743      /* Check for sane-sized segments.  SHT_NOBITS sections have zero
1744         size in the file. */
1745      if ((foff >= n_oimage) || (foff + (bits ? size : 0) > n_oimage)) {
1746         ML_(symerr)(di, True, "ELF Section extends beyond image end");
1747         goto out;
1748      }
1749
1750      /* Check for a sane alignment value. */
1751      if (alyn > 0 && -1 == VG_(log2)(alyn)) {
1752         ML_(symerr)(di, True, "ELF Section contains invalid "
1753                               ".sh_addralign value");
1754         goto out;
1755      }
1756
1757      /* Ignore zero sized sections. */
1758      if (size == 0) {
1759         TRACE_SYMTAB("zero sized section \"%s\", ignoring\n", name);
1760         continue;
1761      }
1762
1763#     define BAD(_secname)                                 \
1764         do { ML_(symerr)(di, True,                        \
1765                          "Can't make sense of " _secname  \
1766                          " section mapping");             \
1767              /* make sure we don't assert if we find */   \
1768              /* ourselves back in this routine later, */  \
1769              /* with the same di */                       \
1770              di->soname = NULL;                           \
1771              goto out;                                    \
1772         } while (0)
1773
1774      /* Find avma-s for: .text .data .sdata .rodata .bss .sbss .plt .got .opd
1775         and .eh_frame */
1776
1777      /* Accept .text where mapped as rx (code), even if zero-sized */
1778      if (0 == VG_(strcmp)(name, ".text")) {
1779         if (inrx && !di->text_present) {
1780            di->text_present = True;
1781            di->text_svma = svma;
1782            di->text_avma = svma + inrx->bias;
1783            di->text_size = size;
1784            di->text_bias = inrx->bias;
1785            di->text_debug_svma = svma;
1786            di->text_debug_bias = inrx->bias;
1787            TRACE_SYMTAB("acquiring .text svma = %#lx .. %#lx\n",
1788                         di->text_svma,
1789                         di->text_svma + di->text_size - 1);
1790            TRACE_SYMTAB("acquiring .text avma = %#lx .. %#lx\n",
1791                         di->text_avma,
1792                         di->text_avma + di->text_size - 1);
1793            TRACE_SYMTAB("acquiring .text bias = %#lx\n", di->text_bias);
1794         } else {
1795            BAD(".text");
1796         }
1797      }
1798
1799      /* Accept .data where mapped as rw (data), even if zero-sized */
1800      if (0 == VG_(strcmp)(name, ".data")) {
1801         if (inrw && !di->data_present) {
1802            di->data_present = True;
1803            di->data_svma = svma;
1804            di->data_avma = svma + inrw->bias;
1805            di->data_size = size;
1806            di->data_bias = inrw->bias;
1807            di->data_debug_svma = svma;
1808            di->data_debug_bias = inrw->bias;
1809            TRACE_SYMTAB("acquiring .data svma = %#lx .. %#lx\n",
1810                         di->data_svma,
1811                         di->data_svma + di->data_size - 1);
1812            TRACE_SYMTAB("acquiring .data avma = %#lx .. %#lx\n",
1813                         di->data_avma,
1814                         di->data_avma + di->data_size - 1);
1815            TRACE_SYMTAB("acquiring .data bias = %#lx\n", di->data_bias);
1816         } else {
1817            BAD(".data");
1818         }
1819      }
1820
1821      /* Accept .sdata where mapped as rw (data) */
1822      if (0 == VG_(strcmp)(name, ".sdata")) {
1823         if (inrw && !di->sdata_present) {
1824            di->sdata_present = True;
1825            di->sdata_svma = svma;
1826            di->sdata_avma = svma + inrw->bias;
1827            di->sdata_size = size;
1828            di->sdata_bias = inrw->bias;
1829            di->sdata_debug_svma = svma;
1830            di->sdata_debug_bias = inrw->bias;
1831            TRACE_SYMTAB("acquiring .sdata svma = %#lx .. %#lx\n",
1832                         di->sdata_svma,
1833                         di->sdata_svma + di->sdata_size - 1);
1834            TRACE_SYMTAB("acquiring .sdata avma = %#lx .. %#lx\n",
1835                         di->sdata_avma,
1836                         di->sdata_avma + di->sdata_size - 1);
1837            TRACE_SYMTAB("acquiring .sdata bias = %#lx\n", di->sdata_bias);
1838         } else {
1839            BAD(".sdata");
1840         }
1841      }
1842
1843      /* Accept .rodata where mapped as rx (data), even if zero-sized */
1844      if (0 == VG_(strcmp)(name, ".rodata")) {
1845         if (inrx && !di->rodata_present) {
1846            di->rodata_present = True;
1847            di->rodata_svma = svma;
1848            di->rodata_avma = svma + inrx->bias;
1849            di->rodata_size = size;
1850            di->rodata_bias = inrx->bias;
1851            di->rodata_debug_svma = svma;
1852            di->rodata_debug_bias = inrx->bias;
1853                                    /* NB was 'inrw' prior to r11794 */
1854            TRACE_SYMTAB("acquiring .rodata svma = %#lx .. %#lx\n",
1855                         di->rodata_svma,
1856                         di->rodata_svma + di->rodata_size - 1);
1857            TRACE_SYMTAB("acquiring .rodata avma = %#lx .. %#lx\n",
1858                         di->rodata_avma,
1859                         di->rodata_avma + di->rodata_size - 1);
1860            TRACE_SYMTAB("acquiring .rodata bias = %#lx\n", di->rodata_bias);
1861         } else {
1862            BAD(".rodata");
1863         }
1864      }
1865
1866      if (0 == VG_(strcmp)(name, ".dynbss")) {
1867         if (inrw && !di->bss_present) {
1868            dynbss_present = True;
1869            di->bss_present = True;
1870            di->bss_svma = svma;
1871            di->bss_avma = svma + inrw->bias;
1872            di->bss_size = size;
1873            di->bss_bias = inrw->bias;
1874            di->bss_debug_svma = svma;
1875            di->bss_debug_bias = inrw->bias;
1876            TRACE_SYMTAB("acquiring .dynbss svma = %#lx .. %#lx\n",
1877                         di->bss_svma,
1878                         di->bss_svma + di->bss_size - 1);
1879            TRACE_SYMTAB("acquiring .dynbss avma = %#lx .. %#lx\n",
1880                         di->bss_avma,
1881                         di->bss_avma + di->bss_size - 1);
1882            TRACE_SYMTAB("acquiring .dynbss bias = %#lx\n", di->bss_bias);
1883         }
1884      }
1885
1886      /* Accept .bss where mapped as rw (data), even if zero-sized */
1887      if (0 == VG_(strcmp)(name, ".bss")) {
1888         if (inrw && dynbss_present) {
1889            vg_assert(di->bss_present);
1890            dynbss_present = False;
1891            vg_assert(di->bss_svma + di->bss_size == svma);
1892            di->bss_size += size;
1893            TRACE_SYMTAB("acquiring .bss svma = %#lx .. %#lx\n",
1894                         svma, svma + size - 1);
1895            TRACE_SYMTAB("acquiring .bss avma = %#lx .. %#lx\n",
1896                         svma + inrw->bias, svma + inrw->bias + size - 1);
1897            TRACE_SYMTAB("acquiring .bss bias = %#lx\n", di->bss_bias);
1898         } else
1899
1900         if (inrw && !di->bss_present) {
1901            di->bss_present = True;
1902            di->bss_svma = svma;
1903            di->bss_avma = svma + inrw->bias;
1904            di->bss_size = size;
1905            di->bss_bias = inrw->bias;
1906            di->bss_debug_svma = svma;
1907            di->bss_debug_bias = inrw->bias;
1908            TRACE_SYMTAB("acquiring .bss svma = %#lx .. %#lx\n",
1909                         di->bss_svma,
1910                         di->bss_svma + di->bss_size - 1);
1911            TRACE_SYMTAB("acquiring .bss avma = %#lx .. %#lx\n",
1912                         di->bss_avma,
1913                         di->bss_avma + di->bss_size - 1);
1914            TRACE_SYMTAB("acquiring .bss bias = %#lx\n", di->bss_bias);
1915         } else
1916
1917         /* Now one from the wtf?! department ... */
1918         if (inrx && (!inrw) && !di->bss_present) {
1919            /* File contains a .bss, but it got mapped as rx only.
1920               This is very strange.  For now, just pretend we didn't
1921               see it :-) */
1922            di->bss_present = False;
1923            di->bss_svma = 0;
1924            di->bss_avma = 0;
1925            di->bss_size = 0;
1926            di->bss_bias = 0;
1927            di->bss_debug_svma = 0;
1928            di->bss_debug_bias = 0;
1929            if (!VG_(clo_xml)) {
1930               VG_(message)(Vg_UserMsg,
1931                            "Warning: the following file's .bss is "
1932                            "mapped r-x only - ignoring .bss syms\n");
1933               VG_(message)(Vg_UserMsg,   " %s\n", di->fsm.filename
1934                                                      ? di->fsm.filename
1935                                                      : (UChar*)"(null?!)" );
1936            }
1937         } else
1938
1939         if ((!inrw) && (!inrx) && !di->bss_present) {
1940            /* File contains a .bss, but it didn't get mapped.  Ignore. */
1941            di->bss_present = False;
1942            di->bss_svma = 0;
1943            di->bss_avma = 0;
1944            di->bss_size = 0;
1945            di->bss_bias = 0;
1946         } else {
1947            BAD(".bss");
1948         }
1949      }
1950
1951      if (0 == VG_(strcmp)(name, ".sdynbss")) {
1952         if (inrw && !di->sbss_present) {
1953            sdynbss_present = True;
1954            di->sbss_present = True;
1955            di->sbss_svma = svma;
1956            di->sbss_avma = svma + inrw->bias;
1957            di->sbss_size = size;
1958            di->sbss_bias = inrw->bias;
1959            di->sbss_debug_svma = svma;
1960            di->sbss_debug_bias = inrw->bias;
1961            TRACE_SYMTAB("acquiring .sdynbss svma = %#lx .. %#lx\n",
1962                         di->sbss_svma,
1963                         di->sbss_svma + di->sbss_size - 1);
1964            TRACE_SYMTAB("acquiring .sdynbss avma = %#lx .. %#lx\n",
1965                         di->sbss_avma,
1966                         di->sbss_avma + di->sbss_size - 1);
1967            TRACE_SYMTAB("acquiring .sdynbss bias = %#lx\n", di->sbss_bias);
1968         }
1969      }
1970
1971      /* Accept .sbss where mapped as rw (data) */
1972      if (0 == VG_(strcmp)(name, ".sbss")) {
1973         if (inrw && sdynbss_present) {
1974            vg_assert(di->sbss_present);
1975            sdynbss_present = False;
1976            vg_assert(di->sbss_svma + di->sbss_size == svma);
1977            di->sbss_size += size;
1978            TRACE_SYMTAB("acquiring .sbss svma = %#lx .. %#lx\n",
1979                         svma, svma + size - 1);
1980            TRACE_SYMTAB("acquiring .sbss avma = %#lx .. %#lx\n",
1981                         svma + inrw->bias, svma + inrw->bias + size - 1);
1982            TRACE_SYMTAB("acquiring .sbss bias = %#lx\n", di->sbss_bias);
1983         } else
1984
1985         if (inrw && !di->sbss_present) {
1986            di->sbss_present = True;
1987            di->sbss_svma = svma;
1988            di->sbss_avma = svma + inrw->bias;
1989            di->sbss_size = size;
1990            di->sbss_bias = inrw->bias;
1991            di->sbss_debug_svma = svma;
1992            di->sbss_debug_bias = inrw->bias;
1993            TRACE_SYMTAB("acquiring .sbss svma = %#lx .. %#lx\n",
1994                         di->sbss_svma,
1995                         di->sbss_svma + di->sbss_size - 1);
1996            TRACE_SYMTAB("acquiring .sbss avma = %#lx .. %#lx\n",
1997                         di->sbss_avma,
1998                         di->sbss_avma + di->sbss_size - 1);
1999            TRACE_SYMTAB("acquiring .sbss bias = %#lx\n", di->sbss_bias);
2000         } else {
2001            BAD(".sbss");
2002         }
2003      }
2004
2005      /* Accept .got where mapped as rw (data) */
2006      if (0 == VG_(strcmp)(name, ".got")) {
2007         if (inrw && !di->got_present) {
2008            di->got_present = True;
2009            di->got_avma = svma + inrw->bias;
2010            di->got_size = size;
2011            TRACE_SYMTAB("acquiring .got avma = %#lx\n", di->got_avma);
2012         } else {
2013            BAD(".got");
2014         }
2015      }
2016
2017      /* Accept .got.plt where mapped as rw (data) */
2018      if (0 == VG_(strcmp)(name, ".got.plt")) {
2019         if (inrw && !di->gotplt_present) {
2020            di->gotplt_present = True;
2021            di->gotplt_avma = svma + inrw->bias;
2022            di->gotplt_size = size;
2023            TRACE_SYMTAB("acquiring .got.plt avma = %#lx\n", di->gotplt_avma);
2024         } else if (size != 0) {
2025            BAD(".got.plt");
2026         }
2027      }
2028
2029      /* PLT is different on different platforms, it seems. */
2030#     if defined(VGP_x86_linux) || defined(VGP_amd64_linux) \
2031         || defined(VGP_arm_linux) || defined (VGP_s390x_linux) \
2032         || defined(VGP_mips32_linux)
2033      /* Accept .plt where mapped as rx (code) */
2034      if (0 == VG_(strcmp)(name, ".plt")) {
2035         if (inrx && !di->plt_present) {
2036            di->plt_present = True;
2037            di->plt_avma = svma + inrx->bias;
2038            di->plt_size = size;
2039            TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
2040         } else {
2041            BAD(".plt");
2042         }
2043      }
2044#     elif defined(VGP_ppc32_linux)
2045      /* Accept .plt where mapped as rw (data) */
2046      if (0 == VG_(strcmp)(name, ".plt")) {
2047         if (inrw && !di->plt_present) {
2048            di->plt_present = True;
2049            di->plt_avma = svma + inrw->bias;
2050            di->plt_size = size;
2051            TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
2052         } else {
2053            BAD(".plt");
2054         }
2055      }
2056#     elif defined(VGP_ppc64_linux)
2057      /* Accept .plt where mapped as rw (data), or unmapped */
2058      if (0 == VG_(strcmp)(name, ".plt")) {
2059         if (inrw && !di->plt_present) {
2060            di->plt_present = True;
2061            di->plt_avma = svma + inrw->bias;
2062            di->plt_size = size;
2063            TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
2064         } else
2065         if ((!inrw) && (!inrx) && size > 0 && !di->plt_present) {
2066            /* File contains a .plt, but it didn't get mapped.
2067               Presumably it is not required on this platform.  At
2068               least don't reject the situation as invalid. */
2069            di->plt_present = True;
2070            di->plt_avma = 0;
2071            di->plt_size = 0;
2072         } else {
2073            BAD(".plt");
2074         }
2075      }
2076#     else
2077#       error "Unsupported platform"
2078#     endif
2079
2080      /* Accept .opd where mapped as rw (data) */
2081      if (0 == VG_(strcmp)(name, ".opd")) {
2082         if (inrw && !di->opd_present) {
2083            di->opd_present = True;
2084            di->opd_avma = svma + inrw->bias;
2085            di->opd_size = size;
2086            TRACE_SYMTAB("acquiring .opd avma = %#lx\n", di->opd_avma);
2087         } else {
2088            BAD(".opd");
2089         }
2090      }
2091
2092      /* Accept .eh_frame where mapped as rx (code).  This seems to be
2093         the common case.  However, if that doesn't pan out, try for
2094         rw (data) instead.  We can handle up to N_EHFRAME_SECTS per
2095         ELF object. */
2096      if (0 == VG_(strcmp)(name, ".eh_frame")) {
2097         if (inrx && di->n_ehframe < N_EHFRAME_SECTS) {
2098            di->ehframe_avma[di->n_ehframe] = svma + inrx->bias;
2099            di->ehframe_size[di->n_ehframe] = size;
2100            TRACE_SYMTAB("acquiring .eh_frame avma = %#lx\n",
2101                         di->ehframe_avma[di->n_ehframe]);
2102            di->n_ehframe++;
2103         } else
2104         if (inrw && di->n_ehframe < N_EHFRAME_SECTS) {
2105            di->ehframe_avma[di->n_ehframe] = svma + inrw->bias;
2106            di->ehframe_size[di->n_ehframe] = size;
2107            TRACE_SYMTAB("acquiring .eh_frame avma = %#lx\n",
2108                         di->ehframe_avma[di->n_ehframe]);
2109            di->n_ehframe++;
2110         } else {
2111            BAD(".eh_frame");
2112         }
2113      }
2114
2115#    undef BAD
2116
2117   } /* iterate over the section headers */
2118
2119   /* TOPLEVEL */
2120   if (0) VG_(printf)("YYYY text_: avma %#lx  size %ld  bias %#lx\n",
2121                      di->text_avma, di->text_size, di->text_bias);
2122
2123   if (VG_(clo_verbosity) > 2 || VG_(clo_trace_redir))
2124      VG_(message)(Vg_DebugMsg, "   svma %#010lx, avma %#010lx\n",
2125                                di->text_avma - di->text_bias,
2126                                di->text_avma );
2127
2128   TRACE_SYMTAB("\n");
2129   TRACE_SYMTAB("------ Finding image addresses "
2130                "for debug-info sections ------\n");
2131
2132   /* TOPLEVEL */
2133   /* Find interesting sections, read the symbol table(s), read any debug
2134      information */
2135   {
2136      /* IMAGE addresses: pointers to start of sections in the
2137         transiently loaded oimage, not in the fragments of the file
2138         mapped in by the guest's dynamic linker. */
2139      /* TOPLEVEL */
2140      UChar*     strtab_img       = NULL; /* .strtab */
2141      ElfXX_Sym* symtab_img       = NULL; /* .symtab */
2142      UChar*     dynstr_img       = NULL; /* .dynstr */
2143      ElfXX_Sym* dynsym_img       = NULL; /* .dynsym */
2144      UChar*     debuglink_img    = NULL; /* .gnu_debuglink */
2145      UChar*     debugaltlink_img = NULL; /* .gnu_debugaltlink */
2146      UChar*     stab_img         = NULL; /* .stab         (stabs)  */
2147      UChar*     stabstr_img      = NULL; /* .stabstr      (stabs)  */
2148      UChar*     debug_line_img   = NULL; /* .debug_line   (dwarf2) */
2149      UChar*     debug_info_img   = NULL; /* .debug_info   (dwarf2) */
2150      UChar*     debug_types_img  = NULL; /* .debug_types  (dwarf4) */
2151      UChar*     debug_abbv_img   = NULL; /* .debug_abbrev (dwarf2) */
2152      UChar*     debug_str_img    = NULL; /* .debug_str    (dwarf2) */
2153      UChar*     debug_ranges_img = NULL; /* .debug_ranges (dwarf2) */
2154      UChar*     debug_loc_img    = NULL; /* .debug_loc    (dwarf2) */
2155      UChar*     debug_frame_img  = NULL; /* .debug_frame  (dwarf2) */
2156      UChar*     debug_line_alt_img = NULL; /* .debug_line (alternate) */
2157      UChar*     debug_info_alt_img = NULL; /* .debug_info (alternate) */
2158      UChar*     debug_abbv_alt_img = NULL; /* .debug_abbrev (alternate) */
2159      UChar*     debug_str_alt_img = NULL; /* .debug_str   (alternate) */
2160      UChar*     dwarf1d_img      = NULL; /* .debug        (dwarf1) */
2161      UChar*     dwarf1l_img      = NULL; /* .line         (dwarf1) */
2162      UChar*     opd_img          = NULL; /* .opd (dwarf2,
2163                                                   ppc64-linux) */
2164      UChar*     ehframe_img[N_EHFRAME_SECTS]; /* .eh_frame (dwarf2) */
2165
2166      /* Section sizes, in bytes */
2167      SizeT      strtab_sz       = 0;
2168      SizeT      symtab_sz       = 0;
2169      SizeT      dynstr_sz       = 0;
2170      SizeT      dynsym_sz       = 0;
2171      SizeT      debuglink_sz    = 0;
2172      SizeT      debugaltlink_sz = 0;
2173      SizeT      stab_sz         = 0;
2174      SizeT      stabstr_sz      = 0;
2175      SizeT      debug_line_sz   = 0;
2176      SizeT      debug_info_sz   = 0;
2177      SizeT      debug_types_sz  = 0;
2178      SizeT      debug_abbv_sz   = 0;
2179      SizeT      debug_str_sz    = 0;
2180      SizeT      debug_ranges_sz = 0;
2181      SizeT      debug_loc_sz    = 0;
2182      SizeT      debug_frame_sz  = 0;
2183      SizeT      debug_line_alt_sz = 0;
2184      SizeT      debug_info_alt_sz = 0;
2185      SizeT      debug_abbv_alt_sz = 0;
2186      SizeT      debug_str_alt_sz = 0;
2187      SizeT      dwarf1d_sz      = 0;
2188      SizeT      dwarf1l_sz      = 0;
2189      SizeT      opd_sz_unused   = 0;
2190      SizeT      ehframe_sz[N_EHFRAME_SECTS];
2191
2192      for (i = 0; i < N_EHFRAME_SECTS; i++) {
2193         ehframe_img[i] = NULL;
2194         ehframe_sz[i]  = 0;
2195      }
2196
2197      /* Find all interesting sections */
2198
2199      UInt ehframe_ix = 0;
2200
2201      /* What FIND does: it finds the section called _SEC_NAME.  The
2202         size of it is assigned to _SEC_SIZE.  The address of the
2203         section in the transiently loaded oimage is assigned to
2204         _SEC_IMG.  If the section is found, _POST_FX is executed
2205         after _SEC_NAME and _SEC_SIZE have been assigned to.
2206
2207         Even for sections which are marked loadable, the client's
2208         ld.so may not have loaded them yet, so there is no guarantee
2209         that we can safely prod around in any such area).  Because
2210         the entire object file is transiently mapped aboard for
2211         inspection, it's always safe to inspect that area. */
2212
2213      /* TOPLEVEL */
2214      /* Iterate over section headers (again) */
2215      for (i = 0; i < ehdr_img->e_shnum; i++) {
2216
2217#        define FINDX(_sec_name, _sec_size, _sec_img, _post_fx)     \
2218         do { ElfXX_Shdr* shdr \
2219                 = INDEX_BIS( shdr_img, i, shdr_ent_szB ); \
2220            if (0 == VG_(strcmp)(_sec_name, shdr_strtab_img \
2221                                            + shdr->sh_name)) { \
2222               Bool nobits; \
2223               _sec_img  = (void*)(oimage + shdr->sh_offset); \
2224               _sec_size = shdr->sh_size; \
2225               nobits    = shdr->sh_type == SHT_NOBITS; \
2226               TRACE_SYMTAB( "%18s:  img %p .. %p\n", \
2227                             _sec_name, (UChar*)_sec_img, \
2228                             ((UChar*)_sec_img) + _sec_size - 1); \
2229               /* SHT_NOBITS sections have zero size in the file. */ \
2230               if ( shdr->sh_offset \
2231                    + (nobits ? 0 : _sec_size) > n_oimage ) { \
2232                  ML_(symerr)(di, True, \
2233                              "   section beyond image end?!"); \
2234                  goto out; \
2235               } \
2236               _post_fx; \
2237            } \
2238         } while (0);
2239
2240         /* Version with no post-effects */
2241#        define FIND(_sec_name, _sec_size, _sec_img) \
2242            FINDX(_sec_name, _sec_size, _sec_img, /**/)
2243
2244         /*   NAME              SIZE             IMAGE addr */
2245         FIND(".dynsym",        dynsym_sz,       dynsym_img)
2246         FIND(".dynstr",        dynstr_sz,       dynstr_img)
2247         FIND(".symtab",        symtab_sz,       symtab_img)
2248         FIND(".strtab",        strtab_sz,       strtab_img)
2249
2250         FIND(".gnu_debuglink", debuglink_sz,    debuglink_img)
2251         FIND(".gnu_debugaltlink", debugaltlink_sz, debugaltlink_img)
2252
2253         FIND(".stab",          stab_sz,         stab_img)
2254         FIND(".stabstr",       stabstr_sz,      stabstr_img)
2255
2256         FIND(".debug_line",    debug_line_sz,   debug_line_img)
2257         FIND(".debug_info",    debug_info_sz,   debug_info_img)
2258         FIND(".debug_types",   debug_types_sz,  debug_types_img)
2259         FIND(".debug_abbrev",  debug_abbv_sz,   debug_abbv_img)
2260         FIND(".debug_str",     debug_str_sz,    debug_str_img)
2261         FIND(".debug_ranges",  debug_ranges_sz, debug_ranges_img)
2262         FIND(".debug_loc",     debug_loc_sz,    debug_loc_img)
2263         FIND(".debug_frame",   debug_frame_sz,  debug_frame_img)
2264
2265         FIND(".debug",         dwarf1d_sz,      dwarf1d_img)
2266         FIND(".line",          dwarf1l_sz,      dwarf1l_img)
2267
2268         FIND(".opd",           opd_sz_unused,   opd_img)
2269
2270         FINDX(".eh_frame",     ehframe_sz[ehframe_ix],
2271                                                 ehframe_img[ehframe_ix],
2272               do { ehframe_ix++; vg_assert(ehframe_ix <= N_EHFRAME_SECTS); }
2273                    while (0)
2274         )
2275         /* Comment_on_EH_FRAME_MULTIPLE_INSTANCES: w.r.t. .eh_frame
2276            multi-instance kludgery, how are we assured that the order
2277            in which we fill in ehframe_sz[] and ehframe_img[] is
2278            consistent with the order in which we previously filled in
2279            di->ehframe_avma[] and di->ehframe_size[] ?  By the fact
2280            that in both cases, these arrays were filled in by
2281            iterating over the section headers top-to-bottom.  So both
2282            loops (this one and the previous one) encounter the
2283            .eh_frame entries in the same order and so fill in these
2284            arrays in a consistent order.
2285         */
2286
2287#        undef FINDX
2288#        undef FIND
2289      } /* Iterate over section headers (again) */
2290
2291      /* TOPLEVEL */
2292      /* Now, see if we can find a debuginfo object, and if so map it in, and
2293         put the mapping address and size in dimage and n_dimage. */
2294      vg_assert(dimage == 0 && n_dimage == 0);
2295
2296      /* Look for a build-id */
2297      buildid = find_buildid(oimage, n_oimage, False);
2298
2299      /* Look for a debug image */
2300      if (buildid != NULL || debuglink_img != NULL) {
2301         /* Do have a debuglink section? */
2302         if (debuglink_img != NULL) {
2303            UInt crc_offset = VG_ROUNDUP(VG_(strlen)(debuglink_img)+1, 4);
2304            UInt crc;
2305
2306            vg_assert(crc_offset + sizeof(UInt) <= debuglink_sz);
2307
2308            /* Extract the CRC from the debuglink section */
2309            crc = ML_(read_UInt)(debuglink_img + crc_offset);
2310
2311            /* See if we can find a matching debug file */
2312            find_debug_file( di, di->fsm.filename, buildid,
2313                             debuglink_img, crc, False, &dimage, &n_dimage );
2314         } else {
2315            /* See if we can find a matching debug file */
2316            find_debug_file( di, di->fsm.filename, buildid,
2317                             NULL, 0, False, &dimage, &n_dimage );
2318         }
2319      }
2320
2321      if (buildid) {
2322         ML_(dinfo_free)(buildid);
2323         buildid = NULL; /* paranoia */
2324      }
2325
2326      /* Still no luck?  Let's have one last roll of the dice. */
2327      if (dimage == 0) {
2328         vg_assert(n_dimage == 0);
2329         Bool found = find_ad_hoc_debug_image( di, di->fsm.filename,
2330                                               &dimage, &n_dimage );
2331         if (found)
2332            vg_assert(dimage != 0);
2333      }
2334
2335      /* TOPLEVEL */
2336      /* If we were successful in finding a debug image, pull various
2337         SVMA/bias/size and image addresses out of it. */
2338      if (dimage != 0
2339          && n_dimage >= sizeof(ElfXX_Ehdr)
2340          && ML_(is_elf_object_file)((void*)dimage, n_dimage, False)) {
2341
2342         /* Pull out and validate program header and section header info */
2343         ElfXX_Ehdr* ehdr_dimg     = (ElfXX_Ehdr*)dimage;
2344         ElfXX_Phdr* phdr_dimg     = (ElfXX_Phdr*)( ((UChar*)ehdr_dimg)
2345                                                       + ehdr_dimg->e_phoff );
2346         UWord       phdr_dnent    = ehdr_dimg->e_phnum;
2347         UWord       phdr_dent_szB = ehdr_dimg->e_phentsize;
2348         ElfXX_Shdr* shdr_dimg     = (ElfXX_Shdr*)( ((UChar*)ehdr_dimg)
2349                                                       + ehdr_dimg->e_shoff );
2350         UWord       shdr_dnent       = ehdr_dimg->e_shnum;
2351         UWord       shdr_dent_szB    = ehdr_dimg->e_shentsize;
2352         UChar*      shdr_strtab_dimg = NULL;
2353
2354         /* SVMAs covered by rx and rw segments and corresponding bias. */
2355         Addr     rx_dsvma_limit = 0;
2356         PtrdiffT rx_dbias = 0;
2357         Addr     rw_dsvma_limit = 0;
2358         PtrdiffT rw_dbias = 0;
2359
2360         Bool need_symtab, need_stabs, need_dwarf2, need_dwarf1;
2361
2362         if (phdr_dnent == 0
2363             || !contained_within(
2364                    dimage, n_dimage,
2365                    (Addr)phdr_dimg, phdr_dnent * phdr_dent_szB)) {
2366            ML_(symerr)(di, True,
2367                        "Missing or invalid ELF Program Header Table"
2368                        " (debuginfo file)");
2369            goto out;
2370         }
2371
2372         if (shdr_dnent == 0
2373             || !contained_within(
2374                    dimage, n_dimage,
2375                    (Addr)shdr_dimg, shdr_dnent * shdr_dent_szB)) {
2376            ML_(symerr)(di, True,
2377                        "Missing or invalid ELF Section Header Table"
2378                        " (debuginfo file)");
2379            goto out;
2380         }
2381
2382         /* Also find the section header's string table, and validate. */
2383         /* checked previously by is_elf_object_file: */
2384         vg_assert( ehdr_dimg->e_shstrndx != SHN_UNDEF );
2385
2386         shdr_strtab_dimg
2387            = (UChar*)( ((UChar*)ehdr_dimg)
2388                        + shdr_dimg[ehdr_dimg->e_shstrndx].sh_offset);
2389         if (!contained_within(
2390                 dimage, n_dimage,
2391                 (Addr)shdr_strtab_dimg,
2392                 1/*bogus, but we don't know the real size*/ )) {
2393            ML_(symerr)(di, True,
2394                        "Invalid ELF Section Header String Table"
2395                        " (debuginfo file)");
2396            goto out;
2397         }
2398
2399         need_symtab = (NULL == symtab_img);
2400         need_stabs  = (NULL == stab_img);
2401         need_dwarf2 = (NULL == debug_info_img);
2402         need_dwarf1 = (NULL == dwarf1d_img);
2403
2404         for (i = 0; i < ehdr_dimg->e_phnum; i++) {
2405            ElfXX_Phdr* phdr
2406               = INDEX_BIS( (void*)(dimage + ehdr_dimg->e_phoff),
2407                                       i, phdr_ent_szB );
2408            if (phdr->p_type == PT_LOAD) {
2409               for (j = 0; j < VG_(sizeXA)(di->fsm.maps); j++) {
2410                  struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, j);
2411                  if (   phdr->p_offset >= map->foff
2412                      && phdr->p_offset <  map->foff + map->size
2413                      && phdr->p_offset + phdr->p_filesz < map->foff
2414                                                           + map->size) {
2415                     if (map->rx && rx_dsvma_limit == 0) {
2416                        rx_dsvma_limit = phdr->p_vaddr + phdr->p_memsz;
2417                        rx_dbias = map->avma - map->foff + phdr->p_offset
2418                                   - phdr->p_vaddr;
2419                     }
2420                     if (map->rw && rw_dsvma_limit == 0) {
2421                        rw_dsvma_limit = phdr->p_vaddr + phdr->p_memsz;
2422                        rw_dbias = map->avma - map->foff + phdr->p_offset
2423                                   - phdr->p_vaddr;
2424                     }
2425                     break;
2426                  }
2427               }
2428            }
2429         }
2430
2431         /* Find all interesting sections */
2432         for (i = 0; i < ehdr_dimg->e_shnum; i++) {
2433
2434            /* Find debug svma and bias information for sections
2435               we found in the main file. */
2436
2437#           define FIND(sec, seg) \
2438            do { ElfXX_Shdr* shdr \
2439                    = INDEX_BIS( shdr_dimg, i, shdr_dent_szB ); \
2440               if (di->sec##_present \
2441                   && 0 == VG_(strcmp)("." #sec, \
2442                                       shdr_strtab_dimg + shdr->sh_name)) { \
2443                  vg_assert(di->sec##_size == shdr->sh_size); \
2444                  vg_assert(di->sec##_avma +  shdr->sh_addr + seg##_dbias); \
2445                  /* Assume we have a correct value for the main */ \
2446                  /* object's bias.  Use that to derive the debuginfo */ \
2447                  /* object's bias, by adding the difference in SVMAs */ \
2448                  /* for the corresponding sections in the two files. */ \
2449                  /* That should take care of all prelinking effects. */ \
2450                  di->sec##_debug_svma = shdr->sh_addr; \
2451                  di->sec##_debug_bias \
2452                     = di->sec##_bias + \
2453                       di->sec##_svma - di->sec##_debug_svma; \
2454                  TRACE_SYMTAB("acquiring ." #sec \
2455                               " debug svma = %#lx .. %#lx\n",       \
2456                               di->sec##_debug_svma, \
2457                               di->sec##_debug_svma + di->sec##_size - 1); \
2458                  TRACE_SYMTAB("acquiring ." #sec " debug bias = %#lx\n", \
2459                               di->sec##_debug_bias); \
2460               } \
2461            } while (0);
2462
2463            /* SECTION   SEGMENT */
2464            FIND(text,   rx)
2465            FIND(data,   rw)
2466            FIND(sdata,  rw)
2467            FIND(rodata, rw)
2468            FIND(bss,    rw)
2469            FIND(sbss,   rw)
2470
2471#           undef FIND
2472
2473            /* Same deal as previous FIND, except only do it for those
2474               sections for which we didn't find anything useful in
2475               the main file. */
2476
2477#           define FIND(condition, sec_name, sec_size, sec_img) \
2478            do { ElfXX_Shdr* shdr \
2479                    = INDEX_BIS( shdr_dimg, i, shdr_dent_szB ); \
2480               if (condition \
2481                   && 0 == VG_(strcmp)(sec_name, \
2482                                       shdr_strtab_dimg + shdr->sh_name)) { \
2483                  Bool nobits; \
2484                  if (0 != sec_img) \
2485                     VG_(core_panic)("repeated section!\n"); \
2486                  sec_img  = (void*)(dimage + shdr->sh_offset); \
2487                  sec_size = shdr->sh_size; \
2488                  nobits   = shdr->sh_type == SHT_NOBITS; \
2489                  TRACE_SYMTAB( "%18s: dimg %p .. %p\n", \
2490                                sec_name, \
2491                                (UChar*)sec_img, \
2492                                ((UChar*)sec_img) + sec_size - 1); \
2493                  /* SHT_NOBITS sections have zero size in the file. */ \
2494                  if ( shdr->sh_offset \
2495                       + (nobits ? 0 : sec_size) > n_dimage ) { \
2496                     ML_(symerr)(di, True, \
2497                                 "   section beyond image end?!"); \
2498                     goto out; \
2499                  } \
2500               } \
2501            } while (0);
2502
2503            /* NEEDED?        NAME             SIZE           IMAGE addr */
2504            FIND(need_symtab, ".symtab",       symtab_sz,     symtab_img)
2505            FIND(need_symtab, ".strtab",       strtab_sz,     strtab_img)
2506            FIND(need_stabs,  ".stab",         stab_sz,       stab_img)
2507            FIND(need_stabs,  ".stabstr",      stabstr_sz,    stabstr_img)
2508            FIND(need_dwarf2, ".debug_line",   debug_line_sz, debug_line_img)
2509            FIND(need_dwarf2, ".debug_info",   debug_info_sz, debug_info_img)
2510            FIND(need_dwarf2, ".debug_types",  debug_types_sz,
2511		                                            debug_types_img)
2512            FIND(need_dwarf2, ".debug_abbrev", debug_abbv_sz, debug_abbv_img)
2513            FIND(need_dwarf2, ".debug_str",    debug_str_sz,  debug_str_img)
2514            FIND(need_dwarf2, ".debug_ranges", debug_ranges_sz,
2515                                                            debug_ranges_img)
2516            FIND(need_dwarf2, ".debug_loc",    debug_loc_sz,  debug_loc_img)
2517            FIND(need_dwarf2, ".debug_frame",  debug_frame_sz,
2518                                                            debug_frame_img)
2519            FIND(need_dwarf2, ".gnu_debugaltlink", debugaltlink_sz,
2520                                                            debugaltlink_img)
2521            FIND(need_dwarf1, ".debug",        dwarf1d_sz,    dwarf1d_img)
2522            FIND(need_dwarf1, ".line",         dwarf1l_sz,    dwarf1l_img)
2523
2524#           undef FIND
2525         } /* Find all interesting sections */
2526      } /* do we have a debug image? */
2527
2528      /* Look for alternate debug image */
2529      if (debugaltlink_img != NULL) {
2530         UInt buildid_offset = VG_(strlen)(debugaltlink_img)+1;
2531
2532         vg_assert(buildid_offset < debugaltlink_sz);
2533
2534         Char *altbuildid
2535            = ML_(dinfo_zalloc)("di.fbi.4",
2536                                (debugaltlink_sz - buildid_offset)
2537                                * 2 + 1);
2538
2539         for (j = 0; j < debugaltlink_sz - buildid_offset; j++)
2540            VG_(sprintf)(altbuildid + 2 * j,
2541                         "%02x", debugaltlink_img[buildid_offset + j]);
2542
2543         /* See if we can find a matching debug file */
2544         find_debug_file( di, di->fsm.filename, altbuildid,
2545                          NULL, 0, True, &aimage, &n_aimage );
2546
2547         ML_(dinfo_free)(altbuildid);
2548      }
2549
2550      /* TOPLEVEL */
2551      /* If we were successful in finding alternate debug image, pull various
2552         size and image addresses out of it. */
2553      if (aimage != 0
2554          && n_aimage >= sizeof(ElfXX_Ehdr)
2555          && ML_(is_elf_object_file)((void*)aimage, n_aimage, True)) {
2556
2557         /* Pull out and validate program header and section header info */
2558         ElfXX_Ehdr* ehdr_aimg     = (ElfXX_Ehdr*)aimage;
2559         ElfXX_Shdr* shdr_aimg     = (ElfXX_Shdr*)( ((UChar*)ehdr_aimg)
2560                                                       + ehdr_aimg->e_shoff );
2561         UWord       shdr_dnent       = ehdr_aimg->e_shnum;
2562         UWord       shdr_dent_szB    = ehdr_aimg->e_shentsize;
2563         UChar*      shdr_strtab_aimg = NULL;
2564
2565         if (shdr_dnent == 0
2566             || !contained_within(
2567                    aimage, n_aimage,
2568                    (Addr)shdr_aimg, shdr_dnent * shdr_dent_szB)) {
2569            ML_(symerr)(di, True,
2570                        "Missing or invalid ELF Section Header Table"
2571                        " (alternate debuginfo file)");
2572            goto out;
2573         }
2574
2575         /* Also find the section header's string table, and validate. */
2576         /* checked previously by is_elf_object_file: */
2577         vg_assert( ehdr_aimg->e_shstrndx != SHN_UNDEF );
2578
2579         shdr_strtab_aimg
2580            = (UChar*)( ((UChar*)ehdr_aimg)
2581                        + shdr_aimg[ehdr_aimg->e_shstrndx].sh_offset);
2582         if (!contained_within(
2583                 aimage, n_aimage,
2584                 (Addr)shdr_strtab_aimg,
2585                 1/*bogus, but we don't know the real size*/ )) {
2586            ML_(symerr)(di, True,
2587                        "Invalid ELF Section Header String Table"
2588                        " (alternate debuginfo file)");
2589            goto out;
2590         }
2591
2592         /* Find all interesting sections */
2593         for (i = 0; i < ehdr_aimg->e_shnum; i++) {
2594
2595#           define FIND(sec_name, sec_size, sec_img) \
2596            do { ElfXX_Shdr* shdr \
2597                    = INDEX_BIS( shdr_aimg, i, shdr_dent_szB ); \
2598               if (0 == VG_(strcmp)(sec_name, \
2599                                    shdr_strtab_aimg + shdr->sh_name)) { \
2600                  if (0 != sec_img) \
2601                     VG_(core_panic)("repeated section!\n"); \
2602                  sec_img  = (void*)(aimage + shdr->sh_offset); \
2603                  sec_size = shdr->sh_size; \
2604                  TRACE_SYMTAB( "%18s: aimg %p .. %p\n", \
2605                                sec_name, \
2606                                (UChar*)sec_img, \
2607                                ((UChar*)sec_img) + sec_size - 1); \
2608               } \
2609            } while (0);
2610
2611            /*   NAME             SIZE           IMAGE addr */
2612            FIND(".debug_line",   debug_line_alt_sz, debug_line_alt_img)
2613            FIND(".debug_info",   debug_info_alt_sz, debug_info_alt_img)
2614            FIND(".debug_abbrev", debug_abbv_alt_sz, debug_abbv_alt_img)
2615            FIND(".debug_str",    debug_str_alt_sz,  debug_str_alt_img)
2616
2617#           undef FIND
2618         } /* Find all interesting sections */
2619      } /* do we have a debug image? */
2620
2621
2622      /* TOPLEVEL */
2623      /* Check some sizes */
2624      vg_assert((dynsym_sz % sizeof(ElfXX_Sym)) == 0);
2625      vg_assert((symtab_sz % sizeof(ElfXX_Sym)) == 0);
2626
2627      /* Read symbols */
2628      {
2629         void (*read_elf_symtab)(struct _DebugInfo*,UChar*,
2630                                 ElfXX_Sym*,SizeT,
2631                                 UChar*,SizeT,
2632                                 Bool,UChar*);
2633         Bool symtab_in_debug;
2634#        if defined(VGP_ppc64_linux)
2635         read_elf_symtab = read_elf_symtab__ppc64_linux;
2636#        else
2637         read_elf_symtab = read_elf_symtab__normal;
2638#        endif
2639         symtab_in_debug = (Addr)symtab_img >= dimage
2640                           && (Addr)symtab_img < dimage + n_dimage;
2641         read_elf_symtab(di, "symbol table",
2642                         symtab_img, symtab_sz,
2643                         strtab_img, strtab_sz,
2644                         symtab_in_debug, opd_img);
2645
2646         read_elf_symtab(di, "dynamic symbol table",
2647                         dynsym_img, dynsym_sz,
2648                         dynstr_img, dynstr_sz,
2649                         False, opd_img);
2650      } /* Read symbols */
2651
2652      /* TOPLEVEL */
2653      /* Read .eh_frame and .debug_frame (call-frame-info) if any.  Do
2654         the .eh_frame section(s) first. */
2655      vg_assert(di->n_ehframe >= 0 && di->n_ehframe <= N_EHFRAME_SECTS);
2656      for (i = 0; i < di->n_ehframe; i++) {
2657         /* see Comment_on_EH_FRAME_MULTIPLE_INSTANCES above for why
2658            this next assertion should hold. */
2659         vg_assert(ehframe_sz[i] == di->ehframe_size[i]);
2660         ML_(read_callframe_info_dwarf3)( di,
2661                                          ehframe_img[i],
2662                                          ehframe_sz[i],
2663                                          di->ehframe_avma[i],
2664                                          True/*is_ehframe*/ );
2665      }
2666      if (debug_frame_sz) {
2667         ML_(read_callframe_info_dwarf3)( di,
2668                                          debug_frame_img, debug_frame_sz,
2669                                          0/*assume zero avma*/,
2670                                          False/*!is_ehframe*/ );
2671      }
2672
2673      /* Read the stabs and/or dwarf2 debug information, if any.  It
2674         appears reading stabs stuff on amd64-linux doesn't work, so
2675         we ignore it.  On s390x stabs also doesnt work and we always
2676         have the dwarf info in the eh_frame.  We also segfault on
2677         ppc64-linux when reading stabs, so skip that.  ppc32-linux
2678         seems OK though.  Also skip on Android. */
2679#     if !defined(VGP_amd64_linux) \
2680         && !defined(VGP_s390x_linux) \
2681         && !defined(VGP_ppc64_linux) \
2682         && !defined(VGPV_arm_linux_android) \
2683         && !defined(VGPV_x86_linux_android)
2684      if (stab_img && stabstr_img) {
2685         ML_(read_debuginfo_stabs) ( di, stab_img, stab_sz,
2686                                         stabstr_img, stabstr_sz );
2687      }
2688#     endif
2689      /* jrs 2006-01-01: icc-8.1 has been observed to generate
2690         binaries without debug_str sections.  Don't preclude
2691         debuginfo reading for that reason, but, in
2692         read_unitinfo_dwarf2, do check that debugstr is non-NULL
2693         before using it. */
2694      if (debug_info_img && debug_abbv_img && debug_line_img
2695                                           /* && debug_str_img */) {
2696
2697         /* The old reader: line numbers and unwind info only */
2698         ML_(read_debuginfo_dwarf3) ( di,
2699                                      debug_info_img, debug_info_sz,
2700                                      debug_types_img, debug_types_sz,
2701                                      debug_abbv_img, debug_abbv_sz,
2702                                      debug_line_img, debug_line_sz,
2703                                      debug_str_img,  debug_str_sz,
2704                                      debug_str_alt_img, debug_str_alt_sz );
2705
2706         /* The new reader: read the DIEs in .debug_info to acquire
2707            information on variable types and locations.  But only if
2708            the tool asks for it, or the user requests it on the
2709            command line. */
2710         if (VG_(needs).var_info /* the tool requires it */
2711             || VG_(clo_read_var_info) /* the user asked for it */) {
2712            ML_(new_dwarf3_reader)(
2713               di, 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_ranges_img, debug_ranges_sz,
2719                   debug_loc_img,    debug_loc_sz,
2720                   debug_info_alt_img, debug_info_alt_sz,
2721                   debug_abbv_alt_img, debug_abbv_alt_sz,
2722                   debug_line_alt_img, debug_line_alt_sz,
2723                   debug_str_alt_img,  debug_str_alt_sz
2724            );
2725         }
2726      }
2727      if (dwarf1d_img && dwarf1l_img) {
2728         ML_(read_debuginfo_dwarf1) ( di, dwarf1d_img, dwarf1d_sz,
2729                                          dwarf1l_img, dwarf1l_sz );
2730      }
2731      /* TOPLEVEL */
2732
2733   } /* "Find interesting sections, read the symbol table(s), read any debug
2734        information" (a local scope) */
2735
2736   /* TOPLEVEL */
2737   res = True;
2738
2739   /* If reading Dwarf3 variable type/location info, print a line
2740      showing the number of variables read for each object.
2741      (Currently disabled -- is a sanity-check mechanism for
2742      exp-sgcheck.) */
2743   if (0 && (VG_(needs).var_info || VG_(clo_read_var_info))) {
2744      UWord nVars = 0;
2745      if (di->varinfo) {
2746         for (j = 0; j < VG_(sizeXA)(di->varinfo); j++) {
2747            OSet* /* of DiAddrRange */ scope
2748               = *(OSet**)VG_(indexXA)(di->varinfo, j);
2749            vg_assert(scope);
2750            VG_(OSetGen_ResetIter)( scope );
2751            while (True) {
2752               DiAddrRange* range  = VG_(OSetGen_Next)( scope );
2753               if (!range) break;
2754               vg_assert(range->vars);
2755               Word w = VG_(sizeXA)(range->vars);
2756               vg_assert(w >= 0);
2757               if (0) VG_(printf)("range %#lx %#lx %ld\n",
2758                                  range->aMin, range->aMax, w);
2759               nVars += (UWord)w;
2760            }
2761         }
2762      }
2763      VG_(umsg)("VARINFO: %7lu vars   %7ld text_size   %s\n",
2764                nVars, di->text_size, di->fsm.filename);
2765   }
2766   /* TOPLEVEL */
2767
2768  out:
2769   {
2770      SysRes m_res;
2771      /* Last, but not least, heave the image(s) back overboard. */
2772      if (dimage) {
2773         m_res = VG_(am_munmap_valgrind) ( dimage, n_dimage );
2774         vg_assert(!sr_isError(m_res));
2775      }
2776      m_res = VG_(am_munmap_valgrind) ( oimage, n_oimage );
2777      vg_assert(!sr_isError(m_res));
2778
2779      if (svma_ranges)
2780         VG_(deleteXA)(svma_ranges);
2781
2782      return res;
2783   } /* out: */
2784
2785   /* NOTREACHED */
2786}
2787
2788#endif // defined(VGO_linux)
2789
2790/*--------------------------------------------------------------------*/
2791/*--- end                                                          ---*/
2792/*--------------------------------------------------------------------*/
2793