readelf.c revision db3f3e6e7bde198592d44642a0da2613a89a8eb5
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;
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#     define BAD(_secname)                                 \
1758         do { ML_(symerr)(di, True,                        \
1759                          "Can't make sense of " _secname  \
1760                          " section mapping");             \
1761              /* make sure we don't assert if we find */   \
1762              /* ourselves back in this routine later, */  \
1763              /* with the same di */                       \
1764              di->soname = NULL;                           \
1765              goto out;                                    \
1766         } while (0)
1767
1768      /* Find avma-s for: .text .data .sdata .rodata .bss .sbss .plt .got .opd
1769         and .eh_frame */
1770
1771      /* Accept .text where mapped as rx (code), even if zero-sized */
1772      if (0 == VG_(strcmp)(name, ".text")) {
1773         if (inrx && size >= 0 && !di->text_present) {
1774            di->text_present = True;
1775            di->text_svma = svma;
1776            di->text_avma = svma + inrx->bias;
1777            di->text_size = size;
1778            di->text_bias = inrx->bias;
1779            di->text_debug_svma = svma;
1780            di->text_debug_bias = inrx->bias;
1781            TRACE_SYMTAB("acquiring .text svma = %#lx .. %#lx\n",
1782                         di->text_svma,
1783                         di->text_svma + di->text_size - 1);
1784            TRACE_SYMTAB("acquiring .text avma = %#lx .. %#lx\n",
1785                         di->text_avma,
1786                         di->text_avma + di->text_size - 1);
1787            TRACE_SYMTAB("acquiring .text bias = %#lx\n", di->text_bias);
1788         } else {
1789            BAD(".text");
1790         }
1791      }
1792
1793      /* Accept .data where mapped as rw (data), even if zero-sized */
1794      if (0 == VG_(strcmp)(name, ".data")) {
1795         if (inrw && size >= 0 && !di->data_present) {
1796            di->data_present = True;
1797            di->data_svma = svma;
1798            di->data_avma = svma + inrw->bias;
1799            di->data_size = size;
1800            di->data_bias = inrw->bias;
1801            di->data_debug_svma = svma;
1802            di->data_debug_bias = inrw->bias;
1803            TRACE_SYMTAB("acquiring .data svma = %#lx .. %#lx\n",
1804                         di->data_svma,
1805                         di->data_svma + di->data_size - 1);
1806            TRACE_SYMTAB("acquiring .data avma = %#lx .. %#lx\n",
1807                         di->data_avma,
1808                         di->data_avma + di->data_size - 1);
1809            TRACE_SYMTAB("acquiring .data bias = %#lx\n", di->data_bias);
1810         } else {
1811            BAD(".data");
1812         }
1813      }
1814
1815      /* Accept .sdata where mapped as rw (data) */
1816      if (0 == VG_(strcmp)(name, ".sdata")) {
1817         if (inrw && size > 0 && !di->sdata_present) {
1818            di->sdata_present = True;
1819            di->sdata_svma = svma;
1820            di->sdata_avma = svma + inrw->bias;
1821            di->sdata_size = size;
1822            di->sdata_bias = inrw->bias;
1823            di->sdata_debug_svma = svma;
1824            di->sdata_debug_bias = inrw->bias;
1825            TRACE_SYMTAB("acquiring .sdata svma = %#lx .. %#lx\n",
1826                         di->sdata_svma,
1827                         di->sdata_svma + di->sdata_size - 1);
1828            TRACE_SYMTAB("acquiring .sdata avma = %#lx .. %#lx\n",
1829                         di->sdata_avma,
1830                         di->sdata_avma + di->sdata_size - 1);
1831            TRACE_SYMTAB("acquiring .sdata bias = %#lx\n", di->sdata_bias);
1832         } else {
1833            BAD(".sdata");
1834         }
1835      }
1836
1837      /* Accept .rodata where mapped as rx (data), even if zero-sized */
1838      if (0 == VG_(strcmp)(name, ".rodata")) {
1839         if (inrx && size >= 0 && !di->rodata_present) {
1840            di->rodata_present = True;
1841            di->rodata_svma = svma;
1842            di->rodata_avma = svma + inrx->bias;
1843            di->rodata_size = size;
1844            di->rodata_bias = inrx->bias;
1845            di->rodata_debug_svma = svma;
1846            di->rodata_debug_bias = inrx->bias;
1847                                    /* NB was 'inrw' prior to r11794 */
1848            TRACE_SYMTAB("acquiring .rodata svma = %#lx .. %#lx\n",
1849                         di->rodata_svma,
1850                         di->rodata_svma + di->rodata_size - 1);
1851            TRACE_SYMTAB("acquiring .rodata avma = %#lx .. %#lx\n",
1852                         di->rodata_avma,
1853                         di->rodata_avma + di->rodata_size - 1);
1854            TRACE_SYMTAB("acquiring .rodata bias = %#lx\n", di->rodata_bias);
1855         } else {
1856            BAD(".rodata");
1857         }
1858      }
1859
1860      if (0 == VG_(strcmp)(name, ".dynbss")) {
1861         if (inrw && size > 0 && !di->bss_present) {
1862            dynbss_present = True;
1863            di->bss_present = True;
1864            di->bss_svma = svma;
1865            di->bss_avma = svma + inrw->bias;
1866            di->bss_size = size;
1867            di->bss_bias = inrw->bias;
1868            di->bss_debug_svma = svma;
1869            di->bss_debug_bias = inrw->bias;
1870            TRACE_SYMTAB("acquiring .dynbss svma = %#lx .. %#lx\n",
1871                         di->bss_svma,
1872                         di->bss_svma + di->bss_size - 1);
1873            TRACE_SYMTAB("acquiring .dynbss avma = %#lx .. %#lx\n",
1874                         di->bss_avma,
1875                         di->bss_avma + di->bss_size - 1);
1876            TRACE_SYMTAB("acquiring .dynbss bias = %#lx\n", di->bss_bias);
1877         }
1878      }
1879
1880      /* Accept .bss where mapped as rw (data), even if zero-sized */
1881      if (0 == VG_(strcmp)(name, ".bss")) {
1882         if (inrw && size > 0 && dynbss_present) {
1883            vg_assert(di->bss_present);
1884            dynbss_present = False;
1885            vg_assert(di->bss_svma + di->bss_size == svma);
1886            di->bss_size += size;
1887            TRACE_SYMTAB("acquiring .bss svma = %#lx .. %#lx\n",
1888                         svma, svma + size - 1);
1889            TRACE_SYMTAB("acquiring .bss avma = %#lx .. %#lx\n",
1890                         svma + inrw->bias, svma + inrw->bias + size - 1);
1891            TRACE_SYMTAB("acquiring .bss bias = %#lx\n", di->bss_bias);
1892         } else
1893
1894         if (inrw && size >= 0 && !di->bss_present) {
1895            di->bss_present = True;
1896            di->bss_svma = svma;
1897            di->bss_avma = svma + inrw->bias;
1898            di->bss_size = size;
1899            di->bss_bias = inrw->bias;
1900            di->bss_debug_svma = svma;
1901            di->bss_debug_bias = inrw->bias;
1902            TRACE_SYMTAB("acquiring .bss svma = %#lx .. %#lx\n",
1903                         di->bss_svma,
1904                         di->bss_svma + di->bss_size - 1);
1905            TRACE_SYMTAB("acquiring .bss avma = %#lx .. %#lx\n",
1906                         di->bss_avma,
1907                         di->bss_avma + di->bss_size - 1);
1908            TRACE_SYMTAB("acquiring .bss bias = %#lx\n", di->bss_bias);
1909         } else
1910
1911         /* Now one from the wtf?! department ... */
1912         if (inrx && (!inrw) && size >= 0 && !di->bss_present) {
1913            /* File contains a .bss, but it got mapped as rx only.
1914               This is very strange.  For now, just pretend we didn't
1915               see it :-) */
1916            di->bss_present = False;
1917            di->bss_svma = 0;
1918            di->bss_avma = 0;
1919            di->bss_size = 0;
1920            di->bss_bias = 0;
1921            di->bss_debug_svma = 0;
1922            di->bss_debug_bias = 0;
1923            if (!VG_(clo_xml)) {
1924               VG_(message)(Vg_UserMsg,
1925                            "Warning: the following file's .bss is "
1926                            "mapped r-x only - ignoring .bss syms\n");
1927               VG_(message)(Vg_UserMsg,   " %s\n", di->fsm.filename
1928                                                      ? di->fsm.filename
1929                                                      : (UChar*)"(null?!)" );
1930            }
1931         } else
1932
1933         if ((!inrw) && (!inrx) && size >= 0 && !di->bss_present) {
1934            /* File contains a .bss, but it didn't get mapped.  Ignore. */
1935            di->bss_present = False;
1936            di->bss_svma = 0;
1937            di->bss_avma = 0;
1938            di->bss_size = 0;
1939            di->bss_bias = 0;
1940         } else {
1941            BAD(".bss");
1942         }
1943      }
1944
1945      if (0 == VG_(strcmp)(name, ".sdynbss")) {
1946         if (inrw && size >= 0 && !di->sbss_present) {
1947            sdynbss_present = True;
1948            di->sbss_present = True;
1949            di->sbss_svma = svma;
1950            di->sbss_avma = svma + inrw->bias;
1951            di->sbss_size = size;
1952            di->sbss_bias = inrw->bias;
1953            di->sbss_debug_svma = svma;
1954            di->sbss_debug_bias = inrw->bias;
1955            TRACE_SYMTAB("acquiring .sdynbss svma = %#lx .. %#lx\n",
1956                         di->sbss_svma,
1957                         di->sbss_svma + di->sbss_size - 1);
1958            TRACE_SYMTAB("acquiring .sdynbss avma = %#lx .. %#lx\n",
1959                         di->sbss_avma,
1960                         di->sbss_avma + di->sbss_size - 1);
1961            TRACE_SYMTAB("acquiring .sdynbss bias = %#lx\n", di->sbss_bias);
1962         }
1963      }
1964
1965      /* Accept .sbss where mapped as rw (data) */
1966      if (0 == VG_(strcmp)(name, ".sbss")) {
1967         if (inrw && size > 0 && sdynbss_present) {
1968            vg_assert(di->sbss_present);
1969            sdynbss_present = False;
1970            vg_assert(di->sbss_svma + di->sbss_size == svma);
1971            di->sbss_size += size;
1972            TRACE_SYMTAB("acquiring .sbss svma = %#lx .. %#lx\n",
1973                         svma, svma + size - 1);
1974            TRACE_SYMTAB("acquiring .sbss avma = %#lx .. %#lx\n",
1975                         svma + inrw->bias, svma + inrw->bias + size - 1);
1976            TRACE_SYMTAB("acquiring .sbss bias = %#lx\n", di->sbss_bias);
1977         } else
1978
1979         if (inrw && size > 0 && !di->sbss_present) {
1980            di->sbss_present = True;
1981            di->sbss_svma = svma;
1982            di->sbss_avma = svma + inrw->bias;
1983            di->sbss_size = size;
1984            di->sbss_bias = inrw->bias;
1985            di->sbss_debug_svma = svma;
1986            di->sbss_debug_bias = inrw->bias;
1987            TRACE_SYMTAB("acquiring .sbss svma = %#lx .. %#lx\n",
1988                         di->sbss_svma,
1989                         di->sbss_svma + di->sbss_size - 1);
1990            TRACE_SYMTAB("acquiring .sbss avma = %#lx .. %#lx\n",
1991                         di->sbss_avma,
1992                         di->sbss_avma + di->sbss_size - 1);
1993            TRACE_SYMTAB("acquiring .sbss bias = %#lx\n", di->sbss_bias);
1994         } else {
1995            BAD(".sbss");
1996         }
1997      }
1998
1999      /* Accept .got where mapped as rw (data) */
2000      if (0 == VG_(strcmp)(name, ".got")) {
2001         if (inrw && size > 0 && !di->got_present) {
2002            di->got_present = True;
2003            di->got_avma = svma + inrw->bias;
2004            di->got_size = size;
2005            TRACE_SYMTAB("acquiring .got avma = %#lx\n", di->got_avma);
2006         } else {
2007            BAD(".got");
2008         }
2009      }
2010
2011      /* Accept .got.plt where mapped as rw (data) */
2012      if (0 == VG_(strcmp)(name, ".got.plt")) {
2013         if (inrw && size > 0 && !di->gotplt_present) {
2014            di->gotplt_present = True;
2015            di->gotplt_avma = svma + inrw->bias;
2016            di->gotplt_size = size;
2017            TRACE_SYMTAB("acquiring .got.plt avma = %#lx\n", di->gotplt_avma);
2018         } else if (size != 0) {
2019            BAD(".got.plt");
2020         }
2021      }
2022
2023      /* PLT is different on different platforms, it seems. */
2024#     if defined(VGP_x86_linux) || defined(VGP_amd64_linux) \
2025         || defined(VGP_arm_linux) || defined (VGP_s390x_linux) \
2026         || defined(VGP_mips32_linux)
2027      /* Accept .plt where mapped as rx (code) */
2028      if (0 == VG_(strcmp)(name, ".plt")) {
2029         if (inrx && size > 0 && !di->plt_present) {
2030            di->plt_present = True;
2031            di->plt_avma = svma + inrx->bias;
2032            di->plt_size = size;
2033            TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
2034         } else {
2035            BAD(".plt");
2036         }
2037      }
2038#     elif defined(VGP_ppc32_linux)
2039      /* Accept .plt where mapped as rw (data) */
2040      if (0 == VG_(strcmp)(name, ".plt")) {
2041         if (inrw && size > 0 && !di->plt_present) {
2042            di->plt_present = True;
2043            di->plt_avma = svma + inrw->bias;
2044            di->plt_size = size;
2045            TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
2046         } else {
2047            BAD(".plt");
2048         }
2049      }
2050#     elif defined(VGP_ppc64_linux)
2051      /* Accept .plt where mapped as rw (data), or unmapped */
2052      if (0 == VG_(strcmp)(name, ".plt")) {
2053         if (inrw && size > 0 && !di->plt_present) {
2054            di->plt_present = True;
2055            di->plt_avma = svma + inrw->bias;
2056            di->plt_size = size;
2057            TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
2058         } else
2059         if ((!inrw) && (!inrx) && size > 0 && !di->plt_present) {
2060            /* File contains a .plt, but it didn't get mapped.
2061               Presumably it is not required on this platform.  At
2062               least don't reject the situation as invalid. */
2063            di->plt_present = True;
2064            di->plt_avma = 0;
2065            di->plt_size = 0;
2066         } else {
2067            BAD(".plt");
2068         }
2069      }
2070#     else
2071#       error "Unsupported platform"
2072#     endif
2073
2074      /* Accept .opd where mapped as rw (data) */
2075      if (0 == VG_(strcmp)(name, ".opd")) {
2076         if (inrw && size > 0 && !di->opd_present) {
2077            di->opd_present = True;
2078            di->opd_avma = svma + inrw->bias;
2079            di->opd_size = size;
2080            TRACE_SYMTAB("acquiring .opd avma = %#lx\n", di->opd_avma);
2081         } else {
2082            BAD(".opd");
2083         }
2084      }
2085
2086      /* Accept .eh_frame where mapped as rx (code).  This seems to be
2087         the common case.  However, if that doesn't pan out, try for
2088         rw (data) instead.  We can handle up to N_EHFRAME_SECTS per
2089         ELF object. */
2090      if (0 == VG_(strcmp)(name, ".eh_frame")) {
2091         if (inrx && size > 0 && di->n_ehframe < N_EHFRAME_SECTS) {
2092            di->ehframe_avma[di->n_ehframe] = svma + inrx->bias;
2093            di->ehframe_size[di->n_ehframe] = size;
2094            TRACE_SYMTAB("acquiring .eh_frame avma = %#lx\n",
2095                         di->ehframe_avma[di->n_ehframe]);
2096            di->n_ehframe++;
2097         } else
2098         if (inrw && size > 0 && di->n_ehframe < N_EHFRAME_SECTS) {
2099            di->ehframe_avma[di->n_ehframe] = svma + inrw->bias;
2100            di->ehframe_size[di->n_ehframe] = size;
2101            TRACE_SYMTAB("acquiring .eh_frame avma = %#lx\n",
2102                         di->ehframe_avma[di->n_ehframe]);
2103            di->n_ehframe++;
2104         } else {
2105            BAD(".eh_frame");
2106         }
2107      }
2108
2109#    undef BAD
2110
2111   } /* iterate over the section headers */
2112
2113   /* TOPLEVEL */
2114   if (0) VG_(printf)("YYYY text_: avma %#lx  size %ld  bias %#lx\n",
2115                      di->text_avma, di->text_size, di->text_bias);
2116
2117   if (VG_(clo_verbosity) > 2 || VG_(clo_trace_redir))
2118      VG_(message)(Vg_DebugMsg, "   svma %#010lx, avma %#010lx\n",
2119                                di->text_avma - di->text_bias,
2120                                di->text_avma );
2121
2122   TRACE_SYMTAB("\n");
2123   TRACE_SYMTAB("------ Finding image addresses "
2124                "for debug-info sections ------\n");
2125
2126   /* TOPLEVEL */
2127   /* Find interesting sections, read the symbol table(s), read any debug
2128      information */
2129   {
2130      /* IMAGE addresses: pointers to start of sections in the
2131         transiently loaded oimage, not in the fragments of the file
2132         mapped in by the guest's dynamic linker. */
2133      /* TOPLEVEL */
2134      UChar*     strtab_img       = NULL; /* .strtab */
2135      ElfXX_Sym* symtab_img       = NULL; /* .symtab */
2136      UChar*     dynstr_img       = NULL; /* .dynstr */
2137      ElfXX_Sym* dynsym_img       = NULL; /* .dynsym */
2138      UChar*     debuglink_img    = NULL; /* .gnu_debuglink */
2139      UChar*     debugaltlink_img = NULL; /* .gnu_debugaltlink */
2140      UChar*     stab_img         = NULL; /* .stab         (stabs)  */
2141      UChar*     stabstr_img      = NULL; /* .stabstr      (stabs)  */
2142      UChar*     debug_line_img   = NULL; /* .debug_line   (dwarf2) */
2143      UChar*     debug_info_img   = NULL; /* .debug_info   (dwarf2) */
2144      UChar*     debug_types_img  = NULL; /* .debug_types  (dwarf4) */
2145      UChar*     debug_abbv_img   = NULL; /* .debug_abbrev (dwarf2) */
2146      UChar*     debug_str_img    = NULL; /* .debug_str    (dwarf2) */
2147      UChar*     debug_ranges_img = NULL; /* .debug_ranges (dwarf2) */
2148      UChar*     debug_loc_img    = NULL; /* .debug_loc    (dwarf2) */
2149      UChar*     debug_frame_img  = NULL; /* .debug_frame  (dwarf2) */
2150      UChar*     debug_line_alt_img = NULL; /* .debug_line (alternate) */
2151      UChar*     debug_info_alt_img = NULL; /* .debug_info (alternate) */
2152      UChar*     debug_abbv_alt_img = NULL; /* .debug_abbrev (alternate) */
2153      UChar*     debug_str_alt_img = NULL; /* .debug_str   (alternate) */
2154      UChar*     dwarf1d_img      = NULL; /* .debug        (dwarf1) */
2155      UChar*     dwarf1l_img      = NULL; /* .line         (dwarf1) */
2156      UChar*     opd_img          = NULL; /* .opd (dwarf2,
2157                                                   ppc64-linux) */
2158      UChar*     ehframe_img[N_EHFRAME_SECTS]; /* .eh_frame (dwarf2) */
2159
2160      /* Section sizes, in bytes */
2161      SizeT      strtab_sz       = 0;
2162      SizeT      symtab_sz       = 0;
2163      SizeT      dynstr_sz       = 0;
2164      SizeT      dynsym_sz       = 0;
2165      SizeT      debuglink_sz    = 0;
2166      SizeT      debugaltlink_sz = 0;
2167      SizeT      stab_sz         = 0;
2168      SizeT      stabstr_sz      = 0;
2169      SizeT      debug_line_sz   = 0;
2170      SizeT      debug_info_sz   = 0;
2171      SizeT      debug_types_sz  = 0;
2172      SizeT      debug_abbv_sz   = 0;
2173      SizeT      debug_str_sz    = 0;
2174      SizeT      debug_ranges_sz = 0;
2175      SizeT      debug_loc_sz    = 0;
2176      SizeT      debug_frame_sz  = 0;
2177      SizeT      debug_line_alt_sz = 0;
2178      SizeT      debug_info_alt_sz = 0;
2179      SizeT      debug_abbv_alt_sz = 0;
2180      SizeT      debug_str_alt_sz = 0;
2181      SizeT      dwarf1d_sz      = 0;
2182      SizeT      dwarf1l_sz      = 0;
2183      SizeT      opd_sz_unused   = 0;
2184      SizeT      ehframe_sz[N_EHFRAME_SECTS];
2185
2186      for (i = 0; i < N_EHFRAME_SECTS; i++) {
2187         ehframe_img[i] = NULL;
2188         ehframe_sz[i]  = 0;
2189      }
2190
2191      /* Find all interesting sections */
2192
2193      UInt ehframe_ix = 0;
2194
2195      /* What FIND does: it finds the section called _SEC_NAME.  The
2196         size of it is assigned to _SEC_SIZE.  The address of the
2197         section in the transiently loaded oimage is assigned to
2198         _SEC_IMG.  If the section is found, _POST_FX is executed
2199         after _SEC_NAME and _SEC_SIZE have been assigned to.
2200
2201         Even for sections which are marked loadable, the client's
2202         ld.so may not have loaded them yet, so there is no guarantee
2203         that we can safely prod around in any such area).  Because
2204         the entire object file is transiently mapped aboard for
2205         inspection, it's always safe to inspect that area. */
2206
2207      /* TOPLEVEL */
2208      /* Iterate over section headers (again) */
2209      for (i = 0; i < ehdr_img->e_shnum; i++) {
2210
2211#        define FINDX(_sec_name, _sec_size, _sec_img, _post_fx)     \
2212         do { ElfXX_Shdr* shdr \
2213                 = INDEX_BIS( shdr_img, i, shdr_ent_szB ); \
2214            if (0 == VG_(strcmp)(_sec_name, shdr_strtab_img \
2215                                            + shdr->sh_name)) { \
2216               Bool nobits; \
2217               _sec_img  = (void*)(oimage + shdr->sh_offset); \
2218               _sec_size = shdr->sh_size; \
2219               nobits    = shdr->sh_type == SHT_NOBITS; \
2220               TRACE_SYMTAB( "%18s:  img %p .. %p\n", \
2221                             _sec_name, (UChar*)_sec_img, \
2222                             ((UChar*)_sec_img) + _sec_size - 1); \
2223               /* SHT_NOBITS sections have zero size in the file. */ \
2224               if ( shdr->sh_offset \
2225                    + (nobits ? 0 : _sec_size) > n_oimage ) { \
2226                  ML_(symerr)(di, True, \
2227                              "   section beyond image end?!"); \
2228                  goto out; \
2229               } \
2230               _post_fx; \
2231            } \
2232         } while (0);
2233
2234         /* Version with no post-effects */
2235#        define FIND(_sec_name, _sec_size, _sec_img) \
2236            FINDX(_sec_name, _sec_size, _sec_img, /**/)
2237
2238         /*   NAME              SIZE             IMAGE addr */
2239         FIND(".dynsym",        dynsym_sz,       dynsym_img)
2240         FIND(".dynstr",        dynstr_sz,       dynstr_img)
2241         FIND(".symtab",        symtab_sz,       symtab_img)
2242         FIND(".strtab",        strtab_sz,       strtab_img)
2243
2244         FIND(".gnu_debuglink", debuglink_sz,    debuglink_img)
2245         FIND(".gnu_debugaltlink", debugaltlink_sz, debugaltlink_img)
2246
2247         FIND(".stab",          stab_sz,         stab_img)
2248         FIND(".stabstr",       stabstr_sz,      stabstr_img)
2249
2250         FIND(".debug_line",    debug_line_sz,   debug_line_img)
2251         FIND(".debug_info",    debug_info_sz,   debug_info_img)
2252         FIND(".debug_types",   debug_types_sz,  debug_types_img)
2253         FIND(".debug_abbrev",  debug_abbv_sz,   debug_abbv_img)
2254         FIND(".debug_str",     debug_str_sz,    debug_str_img)
2255         FIND(".debug_ranges",  debug_ranges_sz, debug_ranges_img)
2256         FIND(".debug_loc",     debug_loc_sz,    debug_loc_img)
2257         FIND(".debug_frame",   debug_frame_sz,  debug_frame_img)
2258
2259         FIND(".debug",         dwarf1d_sz,      dwarf1d_img)
2260         FIND(".line",          dwarf1l_sz,      dwarf1l_img)
2261
2262         FIND(".opd",           opd_sz_unused,   opd_img)
2263
2264         FINDX(".eh_frame",     ehframe_sz[ehframe_ix],
2265                                                 ehframe_img[ehframe_ix],
2266               do { ehframe_ix++; vg_assert(ehframe_ix <= N_EHFRAME_SECTS); }
2267                    while (0)
2268         )
2269         /* Comment_on_EH_FRAME_MULTIPLE_INSTANCES: w.r.t. .eh_frame
2270            multi-instance kludgery, how are we assured that the order
2271            in which we fill in ehframe_sz[] and ehframe_img[] is
2272            consistent with the order in which we previously filled in
2273            di->ehframe_avma[] and di->ehframe_size[] ?  By the fact
2274            that in both cases, these arrays were filled in by
2275            iterating over the section headers top-to-bottom.  So both
2276            loops (this one and the previous one) encounter the
2277            .eh_frame entries in the same order and so fill in these
2278            arrays in a consistent order.
2279         */
2280
2281#        undef FINDX
2282#        undef FIND
2283      } /* Iterate over section headers (again) */
2284
2285      /* TOPLEVEL */
2286      /* Now, see if we can find a debuginfo object, and if so map it in, and
2287         put the mapping address and size in dimage and n_dimage. */
2288      vg_assert(dimage == 0 && n_dimage == 0);
2289
2290      /* Look for a build-id */
2291      buildid = find_buildid(oimage, n_oimage, False);
2292
2293      /* Look for a debug image */
2294      if (buildid != NULL || debuglink_img != NULL) {
2295         /* Do have a debuglink section? */
2296         if (debuglink_img != NULL) {
2297            UInt crc_offset = VG_ROUNDUP(VG_(strlen)(debuglink_img)+1, 4);
2298            UInt crc;
2299
2300            vg_assert(crc_offset + sizeof(UInt) <= debuglink_sz);
2301
2302            /* Extract the CRC from the debuglink section */
2303            crc = ML_(read_UInt)(debuglink_img + crc_offset);
2304
2305            /* See if we can find a matching debug file */
2306            find_debug_file( di, di->fsm.filename, buildid,
2307                             debuglink_img, crc, False, &dimage, &n_dimage );
2308         } else {
2309            /* See if we can find a matching debug file */
2310            find_debug_file( di, di->fsm.filename, buildid,
2311                             NULL, 0, False, &dimage, &n_dimage );
2312         }
2313      }
2314
2315      if (buildid) {
2316         ML_(dinfo_free)(buildid);
2317         buildid = NULL; /* paranoia */
2318      }
2319
2320      /* Still no luck?  Let's have one last roll of the dice. */
2321      if (dimage == 0) {
2322         vg_assert(n_dimage == 0);
2323         Bool found = find_ad_hoc_debug_image( di, di->fsm.filename,
2324                                               &dimage, &n_dimage );
2325         if (found)
2326            vg_assert(dimage != 0);
2327      }
2328
2329      /* TOPLEVEL */
2330      /* If we were successful in finding a debug image, pull various
2331         SVMA/bias/size and image addresses out of it. */
2332      if (dimage != 0
2333          && n_dimage >= sizeof(ElfXX_Ehdr)
2334          && ML_(is_elf_object_file)((void*)dimage, n_dimage, False)) {
2335
2336         /* Pull out and validate program header and section header info */
2337         ElfXX_Ehdr* ehdr_dimg     = (ElfXX_Ehdr*)dimage;
2338         ElfXX_Phdr* phdr_dimg     = (ElfXX_Phdr*)( ((UChar*)ehdr_dimg)
2339                                                       + ehdr_dimg->e_phoff );
2340         UWord       phdr_dnent    = ehdr_dimg->e_phnum;
2341         UWord       phdr_dent_szB = ehdr_dimg->e_phentsize;
2342         ElfXX_Shdr* shdr_dimg     = (ElfXX_Shdr*)( ((UChar*)ehdr_dimg)
2343                                                       + ehdr_dimg->e_shoff );
2344         UWord       shdr_dnent       = ehdr_dimg->e_shnum;
2345         UWord       shdr_dent_szB    = ehdr_dimg->e_shentsize;
2346         UChar*      shdr_strtab_dimg = NULL;
2347
2348         /* SVMAs covered by rx and rw segments and corresponding bias. */
2349         Addr     rx_dsvma_limit = 0;
2350         PtrdiffT rx_dbias = 0;
2351         Addr     rw_dsvma_limit = 0;
2352         PtrdiffT rw_dbias = 0;
2353
2354         Bool need_symtab, need_stabs, need_dwarf2, need_dwarf1;
2355
2356         if (phdr_dnent == 0
2357             || !contained_within(
2358                    dimage, n_dimage,
2359                    (Addr)phdr_dimg, phdr_dnent * phdr_dent_szB)) {
2360            ML_(symerr)(di, True,
2361                        "Missing or invalid ELF Program Header Table"
2362                        " (debuginfo file)");
2363            goto out;
2364         }
2365
2366         if (shdr_dnent == 0
2367             || !contained_within(
2368                    dimage, n_dimage,
2369                    (Addr)shdr_dimg, shdr_dnent * shdr_dent_szB)) {
2370            ML_(symerr)(di, True,
2371                        "Missing or invalid ELF Section Header Table"
2372                        " (debuginfo file)");
2373            goto out;
2374         }
2375
2376         /* Also find the section header's string table, and validate. */
2377         /* checked previously by is_elf_object_file: */
2378         vg_assert( ehdr_dimg->e_shstrndx != SHN_UNDEF );
2379
2380         shdr_strtab_dimg
2381            = (UChar*)( ((UChar*)ehdr_dimg)
2382                        + shdr_dimg[ehdr_dimg->e_shstrndx].sh_offset);
2383         if (!contained_within(
2384                 dimage, n_dimage,
2385                 (Addr)shdr_strtab_dimg,
2386                 1/*bogus, but we don't know the real size*/ )) {
2387            ML_(symerr)(di, True,
2388                        "Invalid ELF Section Header String Table"
2389                        " (debuginfo file)");
2390            goto out;
2391         }
2392
2393         need_symtab = (NULL == symtab_img);
2394         need_stabs  = (NULL == stab_img);
2395         need_dwarf2 = (NULL == debug_info_img);
2396         need_dwarf1 = (NULL == dwarf1d_img);
2397
2398         for (i = 0; i < ehdr_dimg->e_phnum; i++) {
2399            ElfXX_Phdr* phdr
2400               = INDEX_BIS( (void*)(dimage + ehdr_dimg->e_phoff),
2401                                       i, phdr_ent_szB );
2402            if (phdr->p_type == PT_LOAD) {
2403               for (j = 0; j < VG_(sizeXA)(di->fsm.maps); j++) {
2404                  struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, j);
2405                  if (   phdr->p_offset >= map->foff
2406                      && phdr->p_offset <  map->foff + map->size
2407                      && phdr->p_offset + phdr->p_filesz < map->foff
2408                                                           + map->size) {
2409                     if (map->rx && rx_dsvma_limit == 0) {
2410                        rx_dsvma_limit = phdr->p_vaddr + phdr->p_memsz;
2411                        rx_dbias = map->avma - map->foff + phdr->p_offset
2412                                   - phdr->p_vaddr;
2413                     }
2414                     if (map->rw && rw_dsvma_limit == 0) {
2415                        rw_dsvma_limit = phdr->p_vaddr + phdr->p_memsz;
2416                        rw_dbias = map->avma - map->foff + phdr->p_offset
2417                                   - phdr->p_vaddr;
2418                     }
2419                     break;
2420                  }
2421               }
2422            }
2423         }
2424
2425         /* Find all interesting sections */
2426         for (i = 0; i < ehdr_dimg->e_shnum; i++) {
2427
2428            /* Find debug svma and bias information for sections
2429               we found in the main file. */
2430
2431#           define FIND(sec, seg) \
2432            do { ElfXX_Shdr* shdr \
2433                    = INDEX_BIS( shdr_dimg, i, shdr_dent_szB ); \
2434               if (di->sec##_present \
2435                   && 0 == VG_(strcmp)("." #sec, \
2436                                       shdr_strtab_dimg + shdr->sh_name)) { \
2437                  vg_assert(di->sec##_size == shdr->sh_size); \
2438                  vg_assert(di->sec##_avma +  shdr->sh_addr + seg##_dbias); \
2439                  /* Assume we have a correct value for the main */ \
2440                  /* object's bias.  Use that to derive the debuginfo */ \
2441                  /* object's bias, by adding the difference in SVMAs */ \
2442                  /* for the corresponding sections in the two files. */ \
2443                  /* That should take care of all prelinking effects. */ \
2444                  di->sec##_debug_svma = shdr->sh_addr; \
2445                  di->sec##_debug_bias \
2446                     = di->sec##_bias + \
2447                       di->sec##_svma - di->sec##_debug_svma; \
2448                  TRACE_SYMTAB("acquiring ." #sec \
2449                               " debug svma = %#lx .. %#lx\n",       \
2450                               di->sec##_debug_svma, \
2451                               di->sec##_debug_svma + di->sec##_size - 1); \
2452                  TRACE_SYMTAB("acquiring ." #sec " debug bias = %#lx\n", \
2453                               di->sec##_debug_bias); \
2454               } \
2455            } while (0);
2456
2457            /* SECTION   SEGMENT */
2458            FIND(text,   rx)
2459            FIND(data,   rw)
2460            FIND(sdata,  rw)
2461            FIND(rodata, rw)
2462            FIND(bss,    rw)
2463            FIND(sbss,   rw)
2464
2465#           undef FIND
2466
2467            /* Same deal as previous FIND, except only do it for those
2468               sections for which we didn't find anything useful in
2469               the main file. */
2470
2471#           define FIND(condition, sec_name, sec_size, sec_img) \
2472            do { ElfXX_Shdr* shdr \
2473                    = INDEX_BIS( shdr_dimg, i, shdr_dent_szB ); \
2474               if (condition \
2475                   && 0 == VG_(strcmp)(sec_name, \
2476                                       shdr_strtab_dimg + shdr->sh_name)) { \
2477                  Bool nobits; \
2478                  if (0 != sec_img) \
2479                     VG_(core_panic)("repeated section!\n"); \
2480                  sec_img  = (void*)(dimage + shdr->sh_offset); \
2481                  sec_size = shdr->sh_size; \
2482                  nobits   = shdr->sh_type == SHT_NOBITS; \
2483                  TRACE_SYMTAB( "%18s: dimg %p .. %p\n", \
2484                                sec_name, \
2485                                (UChar*)sec_img, \
2486                                ((UChar*)sec_img) + sec_size - 1); \
2487                  /* SHT_NOBITS sections have zero size in the file. */ \
2488                  if ( shdr->sh_offset \
2489                       + (nobits ? 0 : sec_size) > n_dimage ) { \
2490                     ML_(symerr)(di, True, \
2491                                 "   section beyond image end?!"); \
2492                     goto out; \
2493                  } \
2494               } \
2495            } while (0);
2496
2497            /* NEEDED?        NAME             SIZE           IMAGE addr */
2498            FIND(need_symtab, ".symtab",       symtab_sz,     symtab_img)
2499            FIND(need_symtab, ".strtab",       strtab_sz,     strtab_img)
2500            FIND(need_stabs,  ".stab",         stab_sz,       stab_img)
2501            FIND(need_stabs,  ".stabstr",      stabstr_sz,    stabstr_img)
2502            FIND(need_dwarf2, ".debug_line",   debug_line_sz, debug_line_img)
2503            FIND(need_dwarf2, ".debug_info",   debug_info_sz, debug_info_img)
2504            FIND(need_dwarf2, ".debug_types",  debug_types_sz,
2505		                                            debug_types_img)
2506            FIND(need_dwarf2, ".debug_abbrev", debug_abbv_sz, debug_abbv_img)
2507            FIND(need_dwarf2, ".debug_str",    debug_str_sz,  debug_str_img)
2508            FIND(need_dwarf2, ".debug_ranges", debug_ranges_sz,
2509                                                            debug_ranges_img)
2510            FIND(need_dwarf2, ".debug_loc",    debug_loc_sz,  debug_loc_img)
2511            FIND(need_dwarf2, ".debug_frame",  debug_frame_sz,
2512                                                            debug_frame_img)
2513            FIND(need_dwarf2, ".gnu_debugaltlink", debugaltlink_sz,
2514                                                            debugaltlink_img)
2515            FIND(need_dwarf1, ".debug",        dwarf1d_sz,    dwarf1d_img)
2516            FIND(need_dwarf1, ".line",         dwarf1l_sz,    dwarf1l_img)
2517
2518#           undef FIND
2519         } /* Find all interesting sections */
2520      } /* do we have a debug image? */
2521
2522      /* Look for alternate debug image */
2523      if (debugaltlink_img != NULL) {
2524         UInt buildid_offset = VG_(strlen)(debugaltlink_img)+1;
2525
2526         vg_assert(buildid_offset < debugaltlink_sz);
2527
2528         Char *altbuildid
2529            = ML_(dinfo_zalloc)("di.fbi.4",
2530                                (debugaltlink_sz - buildid_offset)
2531                                * 2 + 1);
2532
2533         for (j = 0; j < debugaltlink_sz - buildid_offset; j++)
2534            VG_(sprintf)(altbuildid + 2 * j,
2535                         "%02x", debugaltlink_img[buildid_offset + j]);
2536
2537         /* See if we can find a matching debug file */
2538         find_debug_file( di, di->fsm.filename, altbuildid,
2539                          NULL, 0, True, &aimage, &n_aimage );
2540
2541         ML_(dinfo_free)(altbuildid);
2542      }
2543
2544      /* TOPLEVEL */
2545      /* If we were successful in finding alternate debug image, pull various
2546         size and image addresses out of it. */
2547      if (aimage != 0
2548          && n_aimage >= sizeof(ElfXX_Ehdr)
2549          && ML_(is_elf_object_file)((void*)aimage, n_aimage, True)) {
2550
2551         /* Pull out and validate program header and section header info */
2552         ElfXX_Ehdr* ehdr_aimg     = (ElfXX_Ehdr*)aimage;
2553         ElfXX_Shdr* shdr_aimg     = (ElfXX_Shdr*)( ((UChar*)ehdr_aimg)
2554                                                       + ehdr_aimg->e_shoff );
2555         UWord       shdr_dnent       = ehdr_aimg->e_shnum;
2556         UWord       shdr_dent_szB    = ehdr_aimg->e_shentsize;
2557         UChar*      shdr_strtab_aimg = NULL;
2558
2559         if (shdr_dnent == 0
2560             || !contained_within(
2561                    aimage, n_aimage,
2562                    (Addr)shdr_aimg, shdr_dnent * shdr_dent_szB)) {
2563            ML_(symerr)(di, True,
2564                        "Missing or invalid ELF Section Header Table"
2565                        " (alternate debuginfo file)");
2566            goto out;
2567         }
2568
2569         /* Also find the section header's string table, and validate. */
2570         /* checked previously by is_elf_object_file: */
2571         vg_assert( ehdr_aimg->e_shstrndx != SHN_UNDEF );
2572
2573         shdr_strtab_aimg
2574            = (UChar*)( ((UChar*)ehdr_aimg)
2575                        + shdr_aimg[ehdr_aimg->e_shstrndx].sh_offset);
2576         if (!contained_within(
2577                 aimage, n_aimage,
2578                 (Addr)shdr_strtab_aimg,
2579                 1/*bogus, but we don't know the real size*/ )) {
2580            ML_(symerr)(di, True,
2581                        "Invalid ELF Section Header String Table"
2582                        " (alternate debuginfo file)");
2583            goto out;
2584         }
2585
2586         /* Find all interesting sections */
2587         for (i = 0; i < ehdr_aimg->e_shnum; i++) {
2588
2589#           define FIND(sec_name, sec_size, sec_img) \
2590            do { ElfXX_Shdr* shdr \
2591                    = INDEX_BIS( shdr_aimg, i, shdr_dent_szB ); \
2592               if (0 == VG_(strcmp)(sec_name, \
2593                                    shdr_strtab_aimg + shdr->sh_name)) { \
2594                  if (0 != sec_img) \
2595                     VG_(core_panic)("repeated section!\n"); \
2596                  sec_img  = (void*)(aimage + shdr->sh_offset); \
2597                  sec_size = shdr->sh_size; \
2598                  TRACE_SYMTAB( "%18s: aimg %p .. %p\n", \
2599                                sec_name, \
2600                                (UChar*)sec_img, \
2601                                ((UChar*)sec_img) + sec_size - 1); \
2602               } \
2603            } while (0);
2604
2605            /*   NAME             SIZE           IMAGE addr */
2606            FIND(".debug_line",   debug_line_alt_sz, debug_line_alt_img)
2607            FIND(".debug_info",   debug_info_alt_sz, debug_info_alt_img)
2608            FIND(".debug_abbrev", debug_abbv_alt_sz, debug_abbv_alt_img)
2609            FIND(".debug_str",    debug_str_alt_sz,  debug_str_alt_img)
2610
2611#           undef FIND
2612         } /* Find all interesting sections */
2613      } /* do we have a debug image? */
2614
2615
2616      /* TOPLEVEL */
2617      /* Check some sizes */
2618      vg_assert((dynsym_sz % sizeof(ElfXX_Sym)) == 0);
2619      vg_assert((symtab_sz % sizeof(ElfXX_Sym)) == 0);
2620
2621      /* Read symbols */
2622      {
2623         void (*read_elf_symtab)(struct _DebugInfo*,UChar*,
2624                                 ElfXX_Sym*,SizeT,
2625                                 UChar*,SizeT,
2626                                 Bool,UChar*);
2627         Bool symtab_in_debug;
2628#        if defined(VGP_ppc64_linux)
2629         read_elf_symtab = read_elf_symtab__ppc64_linux;
2630#        else
2631         read_elf_symtab = read_elf_symtab__normal;
2632#        endif
2633         symtab_in_debug = (Addr)symtab_img >= dimage
2634                           && (Addr)symtab_img < dimage + n_dimage;
2635         read_elf_symtab(di, "symbol table",
2636                         symtab_img, symtab_sz,
2637                         strtab_img, strtab_sz,
2638                         symtab_in_debug, opd_img);
2639
2640         read_elf_symtab(di, "dynamic symbol table",
2641                         dynsym_img, dynsym_sz,
2642                         dynstr_img, dynstr_sz,
2643                         False, opd_img);
2644      } /* Read symbols */
2645
2646      /* TOPLEVEL */
2647      /* Read .eh_frame and .debug_frame (call-frame-info) if any.  Do
2648         the .eh_frame section(s) first. */
2649      vg_assert(di->n_ehframe >= 0 && di->n_ehframe <= N_EHFRAME_SECTS);
2650      for (i = 0; i < di->n_ehframe; i++) {
2651         /* see Comment_on_EH_FRAME_MULTIPLE_INSTANCES above for why
2652            this next assertion should hold. */
2653         vg_assert(ehframe_sz[i] == di->ehframe_size[i]);
2654         ML_(read_callframe_info_dwarf3)( di,
2655                                          ehframe_img[i],
2656                                          ehframe_sz[i],
2657                                          di->ehframe_avma[i],
2658                                          True/*is_ehframe*/ );
2659      }
2660      if (debug_frame_sz) {
2661         ML_(read_callframe_info_dwarf3)( di,
2662                                          debug_frame_img, debug_frame_sz,
2663                                          0/*assume zero avma*/,
2664                                          False/*!is_ehframe*/ );
2665      }
2666
2667      /* Read the stabs and/or dwarf2 debug information, if any.  It
2668         appears reading stabs stuff on amd64-linux doesn't work, so
2669         we ignore it.  On s390x stabs also doesnt work and we always
2670         have the dwarf info in the eh_frame.  We also segfault on
2671         ppc64-linux when reading stabs, so skip that.  ppc32-linux
2672         seems OK though.  Also skip on Android. */
2673#     if !defined(VGP_amd64_linux) \
2674         && !defined(VGP_s390x_linux) \
2675         && !defined(VGP_ppc64_linux) \
2676         && !defined(VGPV_arm_linux_android) \
2677         && !defined(VGPV_x86_linux_android)
2678      if (stab_img && stabstr_img) {
2679         ML_(read_debuginfo_stabs) ( di, stab_img, stab_sz,
2680                                         stabstr_img, stabstr_sz );
2681      }
2682#     endif
2683      /* jrs 2006-01-01: icc-8.1 has been observed to generate
2684         binaries without debug_str sections.  Don't preclude
2685         debuginfo reading for that reason, but, in
2686         read_unitinfo_dwarf2, do check that debugstr is non-NULL
2687         before using it. */
2688      if (debug_info_img && debug_abbv_img && debug_line_img
2689                                           /* && debug_str_img */) {
2690
2691         /* The old reader: line numbers and unwind info only */
2692         ML_(read_debuginfo_dwarf3) ( di,
2693                                      debug_info_img, debug_info_sz,
2694                                      debug_types_img, debug_types_sz,
2695                                      debug_abbv_img, debug_abbv_sz,
2696                                      debug_line_img, debug_line_sz,
2697                                      debug_str_img,  debug_str_sz,
2698                                      debug_str_alt_img, debug_str_alt_sz );
2699
2700         /* The new reader: read the DIEs in .debug_info to acquire
2701            information on variable types and locations.  But only if
2702            the tool asks for it, or the user requests it on the
2703            command line. */
2704         if (VG_(needs).var_info /* the tool requires it */
2705             || VG_(clo_read_var_info) /* the user asked for it */) {
2706            ML_(new_dwarf3_reader)(
2707               di, debug_info_img,   debug_info_sz,
2708                   debug_types_img,   debug_types_sz,
2709                   debug_abbv_img,   debug_abbv_sz,
2710                   debug_line_img,   debug_line_sz,
2711                   debug_str_img,    debug_str_sz,
2712                   debug_ranges_img, debug_ranges_sz,
2713                   debug_loc_img,    debug_loc_sz,
2714                   debug_info_alt_img, debug_info_alt_sz,
2715                   debug_abbv_alt_img, debug_abbv_alt_sz,
2716                   debug_line_alt_img, debug_line_alt_sz,
2717                   debug_str_alt_img,  debug_str_alt_sz
2718            );
2719         }
2720      }
2721      if (dwarf1d_img && dwarf1l_img) {
2722         ML_(read_debuginfo_dwarf1) ( di, dwarf1d_img, dwarf1d_sz,
2723                                          dwarf1l_img, dwarf1l_sz );
2724      }
2725      /* TOPLEVEL */
2726
2727   } /* "Find interesting sections, read the symbol table(s), read any debug
2728        information" (a local scope) */
2729
2730   /* TOPLEVEL */
2731   res = True;
2732
2733   /* If reading Dwarf3 variable type/location info, print a line
2734      showing the number of variables read for each object.
2735      (Currently disabled -- is a sanity-check mechanism for
2736      exp-sgcheck.) */
2737   if (0 && (VG_(needs).var_info || VG_(clo_read_var_info))) {
2738      UWord nVars = 0;
2739      if (di->varinfo) {
2740         for (j = 0; j < VG_(sizeXA)(di->varinfo); j++) {
2741            OSet* /* of DiAddrRange */ scope
2742               = *(OSet**)VG_(indexXA)(di->varinfo, j);
2743            vg_assert(scope);
2744            VG_(OSetGen_ResetIter)( scope );
2745            while (True) {
2746               DiAddrRange* range  = VG_(OSetGen_Next)( scope );
2747               if (!range) break;
2748               vg_assert(range->vars);
2749               Word w = VG_(sizeXA)(range->vars);
2750               vg_assert(w >= 0);
2751               if (0) VG_(printf)("range %#lx %#lx %ld\n",
2752                                  range->aMin, range->aMax, w);
2753               nVars += (UWord)w;
2754            }
2755         }
2756      }
2757      VG_(umsg)("VARINFO: %7lu vars   %7ld text_size   %s\n",
2758                nVars, di->text_size, di->fsm.filename);
2759   }
2760   /* TOPLEVEL */
2761
2762  out:
2763   {
2764      SysRes m_res;
2765      /* Last, but not least, heave the image(s) back overboard. */
2766      if (dimage) {
2767         m_res = VG_(am_munmap_valgrind) ( dimage, n_dimage );
2768         vg_assert(!sr_isError(m_res));
2769      }
2770      m_res = VG_(am_munmap_valgrind) ( oimage, n_oimage );
2771      vg_assert(!sr_isError(m_res));
2772
2773      if (svma_ranges)
2774         VG_(deleteXA)(svma_ranges);
2775
2776      return res;
2777   } /* out: */
2778
2779   /* NOTREACHED */
2780}
2781
2782#endif // defined(VGO_linux)
2783
2784/*--------------------------------------------------------------------*/
2785/*--- end                                                          ---*/
2786/*--------------------------------------------------------------------*/
2787