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