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#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
1236      VG_(sprintf)(debugpath, "/data/local/symbols%s/%s", objdir, debugname);
1237      dimg = open_debug_file(debugpath, NULL, crc, rel_ok, NULL);
1238      if (dimg != NULL) goto dimg_ok;
1239#endif
1240
1241      dimg_ok:
1242
1243      ML_(dinfo_free)(objdir);
1244   }
1245
1246   if (dimg != NULL) {
1247      vg_assert(debugpath);
1248      TRACE_SYMTAB("\n");
1249      TRACE_SYMTAB("------ Found a debuginfo file: %s\n", debugpath);
1250   }
1251
1252   if (debugpath)
1253      ML_(dinfo_free)(debugpath);
1254
1255   return dimg;
1256}
1257
1258
1259/* Try to find a separate debug file for a given object file, in a
1260   hacky and dangerous way: check only the --extra-debuginfo-path and
1261   the --debuginfo-server.  And don't do a consistency check. */
1262static
1263DiImage* find_debug_file_ad_hoc( struct _DebugInfo* di,
1264                                 const HChar* objpath )
1265{
1266   const HChar* extrapath  = VG_(clo_extra_debuginfo_path);
1267   const HChar* serverpath = VG_(clo_debuginfo_server);
1268
1269   DiImage* dimg      = NULL; /* the img that we found */
1270   HChar*   debugpath = NULL; /* where we found it */
1271
1272   HChar *objdir = ML_(dinfo_strdup)("di.fdfah.1", objpath);
1273   HChar *objdirptr;
1274
1275   if ((objdirptr = VG_(strrchr)(objdir, '/')) != NULL)
1276      *objdirptr = '\0';
1277
1278   debugpath = ML_(dinfo_zalloc)(
1279                  "di.fdfah.3",
1280                  VG_(strlen)(objdir) + 64
1281                  + (extrapath ? VG_(strlen)(extrapath) : 0)
1282                  + (serverpath ? VG_(strlen)(serverpath) : 0));
1283
1284   if (extrapath) {
1285      VG_(sprintf)(debugpath, "%s/%s", extrapath, objpath);
1286      dimg = ML_(img_from_local_file)(debugpath);
1287      if (dimg != NULL) {
1288         if (VG_(clo_verbosity) > 1) {
1289            VG_(message)(Vg_DebugMsg, "  Using (POSSIBLY MISMATCHED) %s\n",
1290                                      debugpath);
1291         }
1292         goto dimg_ok;
1293      }
1294   }
1295   if (serverpath) {
1296      /* When looking on the debuginfo server, always just pass the
1297         basename. */
1298      const HChar* basename = objpath;
1299      if (VG_(strstr)(basename, "/") != NULL) {
1300         basename = VG_(strrchr)(basename, '/') + 1;
1301      }
1302      VG_(sprintf)(debugpath, "%s on %s", basename, serverpath);
1303      dimg = ML_(img_from_di_server)(basename, serverpath);
1304      if (dimg != NULL) {
1305         if (VG_(clo_verbosity) > 1) {
1306            VG_(message)(Vg_DebugMsg, "  Using (POSSIBLY MISMATCHED) %s\n",
1307                                      debugpath);
1308         }
1309         goto dimg_ok;
1310      }
1311   }
1312
1313   dimg_ok:
1314
1315   ML_(dinfo_free)(objdir);
1316
1317   if (dimg != NULL) {
1318      vg_assert(debugpath);
1319      TRACE_SYMTAB("\n");
1320      TRACE_SYMTAB("------ Found an ad_hoc debuginfo file: %s\n", debugpath);
1321   }
1322
1323   if (debugpath)
1324      ML_(dinfo_free)(debugpath);
1325
1326   return dimg;
1327}
1328
1329
1330static DiOffT INDEX_BIS ( DiOffT base, UWord idx, UWord scale ) {
1331   // This is a bit stupid.  Really, idx and scale ought to be
1332   // 64-bit quantities, always.
1333   return base + (DiOffT)idx * (DiOffT)scale;
1334}
1335
1336
1337/* Find the file offset corresponding to SVMA by using the program
1338   headers.  This is taken from binutils-2.17/binutils/readelf.c
1339   offset_from_vma(). */
1340static
1341Word file_offset_from_svma ( /*OUT*/Bool* ok,
1342                             Addr         svma,
1343                             DiImage*     img,
1344                             DiOffT       phdr_ioff,
1345                             Word         phdr_nent,
1346                             Word         phdr_ent_szB )
1347{
1348   Word i;
1349   for (i = 0; i < phdr_nent; i++) {
1350      ElfXX_Phdr seg;
1351      ML_(img_get)(&seg, img,
1352                   INDEX_BIS(phdr_ioff, i, phdr_ent_szB), sizeof(seg));
1353      if (seg.p_type != PT_LOAD)
1354         continue;
1355      if (svma >= (seg.p_vaddr & -seg.p_align)
1356          && svma + 1 <= seg.p_vaddr + seg.p_filesz) {
1357         *ok = True;
1358         return svma - seg.p_vaddr + seg.p_offset;
1359      }
1360   }
1361   *ok = False;
1362   return 0;
1363}
1364
1365
1366/* The central function for reading ELF debug info.  For the
1367   object/exe specified by the DebugInfo, find ELF sections, then read
1368   the symbols, line number info, file name info, CFA (stack-unwind
1369   info) and anything else we want, into the tables within the
1370   supplied DebugInfo.
1371*/
1372
1373Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
1374{
1375   /* This function is long and complex.  That, and the presence of
1376      nested scopes, means it's not always easy to see which parts are
1377      in loops/conditionals and which aren't.  To make it easier to
1378      follow, points executed exactly once -- that is, those which are
1379      the top level of the function -- are marked TOPLEVEL.
1380   */
1381   /* Consistent terminology for local variable names, without which
1382      it's almost unfollowably complex:
1383
1384      In which file?
1385         in the main ELF file         *_m*
1386         in the debuginfo file        *_d*
1387         in the alt debuginfo file    *_a*
1388
1389      What kind of thing?
1390         _{m,d,a}img       a DiImage*
1391         _{m,d,a}ioff      an offset in the image (DiOffT)
1392         _{m,d,a}nent      "number of entries"
1393         _{m,d,a}ent_szB   "size in bytes of an entry"
1394         ehdr_{m,d,a}      ELF header
1395         phdr              Program header
1396         shdr              Section header
1397         a_X               a temporary X
1398         _escn             an DiSlice (elf section info) variable
1399         szB               size in bytes
1400   */
1401
1402
1403   /* TOPLEVEL */
1404   Bool     res, ok;
1405   Word     i, j;
1406   Bool     dynbss_present = False;
1407   Bool     sdynbss_present = False;
1408
1409   /* Image for the main ELF file we're working with. */
1410   DiImage* mimg = NULL;
1411
1412   /* Ditto for any ELF debuginfo file that we might happen to load. */
1413   DiImage* dimg = NULL;
1414
1415   /* Ditto for alternate ELF debuginfo file that we might happen to load. */
1416   DiImage* aimg = NULL;
1417
1418   /* ELF header offset for the main file.  Should be zero since the
1419      ELF header is at start of file. */
1420   DiOffT   ehdr_mioff = 0;
1421
1422   /* Program header table image addr, # entries, entry size */
1423   DiOffT   phdr_mioff    = 0;
1424   UWord    phdr_mnent    = 0;
1425   UWord    phdr_ment_szB = 0;
1426
1427   /* Section header image addr, # entries, entry size.  Also the
1428      associated string table. */
1429   DiOffT   shdr_mioff        = 0;
1430   UWord    shdr_mnent        = 0;
1431   UWord    shdr_ment_szB     = 0;
1432   DiOffT   shdr_strtab_mioff = 0;
1433
1434   /* SVMAs covered by rx and rw segments and corresponding biases.
1435      Normally each object would provide just one rx and one rw area,
1436      but various ELF mangling tools create objects with multiple
1437      such entries, hence the generality. */
1438   typedef
1439      struct {
1440         Addr     svma_base;
1441         Addr     svma_limit;
1442         PtrdiffT bias;
1443         Bool     exec;
1444      }
1445      RangeAndBias;
1446
1447   XArray* /* of RangeAndBias */ svma_ranges = NULL;
1448
1449   vg_assert(di);
1450   vg_assert(di->fsm.have_rx_map == True);
1451   vg_assert(di->fsm.have_rw_map == True);
1452   vg_assert(di->have_dinfo == False);
1453   vg_assert(di->fsm.filename);
1454   vg_assert(!di->symtab);
1455   vg_assert(!di->loctab);
1456   vg_assert(!di->cfsi);
1457   vg_assert(!di->cfsi_exprs);
1458   vg_assert(!di->strchunks);
1459   vg_assert(!di->soname);
1460
1461   {
1462      Bool has_nonempty_rx = False;
1463      Bool has_nonempty_rw = False;
1464      for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1465         struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
1466         if (!map->rx && !map->rw)
1467            continue;
1468         if (map->rx && map->size > 0)
1469            has_nonempty_rx = True;
1470         if (map->rw && map->size > 0)
1471            has_nonempty_rw = True;
1472         /* If this doesn't hold true, it means that m_syswrap/m_aspacemgr
1473            managed to do a mapping where the start isn't page aligned.
1474            Which sounds pretty bogus to me. */
1475         vg_assert(VG_IS_PAGE_ALIGNED(map->avma));
1476      }
1477      vg_assert(has_nonempty_rx);
1478      vg_assert(has_nonempty_rw);
1479   }
1480
1481   /* ----------------------------------------------------------
1482      At this point, there is very little information in the
1483      DebugInfo.  We only know that something that looks like an ELF
1484      file has been mapped rx-ishly and rw-ishly as recorded in the
1485      di->fsm.maps array items.  First we examine the file's ELF
1486      Program Header, and, by comparing that against the di->fsm.maps
1487      info, try to figure out the AVMAs for the sections we care
1488      about, that should have been mapped: text, data, sdata, bss,
1489      got, plt, and toc.
1490      ---------------------------------------------------------- */
1491
1492   res = False;
1493
1494   if (VG_(clo_verbosity) > 1 || VG_(clo_trace_redir))
1495      VG_(message)(Vg_DebugMsg, "Reading syms from %s\n",
1496                                di->fsm.filename );
1497
1498   /* Connect to the primary object image, so that we can read symbols
1499      and line number info out of it.  It will be disconnected
1500      immediately thereafter; it is only connected transiently. */
1501   mimg = ML_(img_from_local_file)(di->fsm.filename);
1502   if (mimg == NULL) {
1503      VG_(message)(Vg_UserMsg, "warning: connection to image %s failed\n",
1504                               di->fsm.filename );
1505      VG_(message)(Vg_UserMsg, "         no symbols or debug info loaded\n" );
1506      return False;
1507   }
1508
1509   /* Ok, the object image is available.  Now verify that it is a
1510      valid ELF .so or executable image. */
1511   ok = is_elf_object_file_by_DiImage(mimg, False);
1512   if (!ok) {
1513      ML_(symerr)(di, True, "Invalid ELF Header");
1514      goto out;
1515   }
1516
1517   /* Find where the program and section header tables are, and give
1518      up if either is missing or outside the image (bogus). */
1519   ElfXX_Ehdr ehdr_m;
1520   vg_assert(ehdr_mioff == 0); // ensured by its initialisation
1521   ok = ML_(img_valid)(mimg, ehdr_mioff, sizeof(ehdr_m));
1522   vg_assert(ok); // ML_(is_elf_object_file) should ensure this
1523   ML_(img_get)(&ehdr_m, mimg, ehdr_mioff, sizeof(ehdr_m));
1524
1525   phdr_mioff    = ehdr_mioff + ehdr_m.e_phoff;
1526   phdr_mnent    = ehdr_m.e_phnum;
1527   phdr_ment_szB = ehdr_m.e_phentsize;
1528
1529   shdr_mioff    = ehdr_mioff + ehdr_m.e_shoff;
1530   shdr_mnent    = ehdr_m.e_shnum;
1531   shdr_ment_szB = ehdr_m.e_shentsize;
1532
1533   TRACE_SYMTAB("------ Basic facts about the object ------\n");
1534   TRACE_SYMTAB("object:  n_oimage %llu\n",
1535                (ULong)ML_(img_size)(mimg));
1536   TRACE_SYMTAB("phdr:    ioff %llu nent %ld ent_szB %ld\n",
1537               phdr_mioff, phdr_mnent, phdr_ment_szB);
1538   TRACE_SYMTAB("shdr:    ioff %llu nent %ld ent_szB %ld\n",
1539               shdr_mioff, shdr_mnent, shdr_ment_szB);
1540   for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1541      struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
1542      if (map->rx)
1543         TRACE_SYMTAB("rx_map:  avma %#lx   size %lu  foff %lu\n",
1544                      map->avma, map->size, map->foff);
1545   }
1546   for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1547      struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
1548      if (map->rw)
1549         TRACE_SYMTAB("rw_map:  avma %#lx   size %lu  foff %lu\n",
1550                      map->avma, map->size, map->foff);
1551   }
1552
1553   if (phdr_mnent == 0
1554       || !ML_(img_valid)(mimg, phdr_mioff, phdr_mnent * phdr_ment_szB)) {
1555      ML_(symerr)(di, True, "Missing or invalid ELF Program Header Table");
1556      goto out;
1557   }
1558
1559   if (shdr_mnent == 0
1560       || !ML_(img_valid)(mimg, shdr_mioff, shdr_mnent * shdr_ment_szB)) {
1561      ML_(symerr)(di, True, "Missing or invalid ELF Section Header Table");
1562      goto out;
1563   }
1564
1565   /* Also find the section header's string table, and validate. */
1566   /* checked previously by is_elf_object_file: */
1567   vg_assert(ehdr_m.e_shstrndx != SHN_UNDEF);
1568
1569   // shdr_mioff is the offset of the section header table
1570   // and we need the ehdr_m.e_shstrndx'th entry
1571   { ElfXX_Shdr a_shdr;
1572     ML_(img_get)(&a_shdr, mimg,
1573                  INDEX_BIS(shdr_mioff, ehdr_m.e_shstrndx, shdr_ment_szB),
1574                  sizeof(a_shdr));
1575     shdr_strtab_mioff
1576        = ehdr_mioff /* isn't this always zero? */ + a_shdr.sh_offset;
1577
1578     if (!ML_(img_valid)(mimg, shdr_strtab_mioff,
1579                         1/*bogus, but we don't know the real size*/ )) {
1580        ML_(symerr)(di, True, "Invalid ELF Section Header String Table");
1581        goto out;
1582     }
1583   }
1584
1585   TRACE_SYMTAB("shdr:    string table at %llu\n", shdr_strtab_mioff);
1586
1587   svma_ranges = VG_(newXA)(ML_(dinfo_zalloc), "di.relfdi.1",
1588                            ML_(dinfo_free), sizeof(RangeAndBias));
1589
1590   /* TOPLEVEL */
1591   /* Look through the program header table, and:
1592      - copy information from suitable PT_LOAD entries into svma_ranges
1593      - find (or fake up) the .soname for this object.
1594   */
1595   TRACE_SYMTAB("\n");
1596   TRACE_SYMTAB("------ Examining the program headers ------\n");
1597   vg_assert(di->soname == NULL);
1598   {
1599      /* TOPLEVEL */
1600      ElfXX_Addr prev_svma = 0;
1601
1602      for (i = 0; i < phdr_mnent; i++) {
1603         ElfXX_Phdr a_phdr;
1604         ML_(img_get)(&a_phdr, mimg,
1605                      INDEX_BIS(phdr_mioff, i, phdr_ment_szB),
1606                      sizeof(a_phdr));
1607
1608         /* Make sure the PT_LOADable entries are in order and
1609            non-overlapping.  This in turn means the address ranges
1610            slurped into svma_ranges are in order and
1611            non-overlapping. */
1612
1613         if (a_phdr.p_type == PT_LOAD) {
1614            TRACE_SYMTAB("PT_LOAD[%ld]: p_vaddr %#lx (prev %#lx)\n",
1615                         i, (UWord)a_phdr.p_vaddr, (UWord)prev_svma);
1616            TRACE_SYMTAB("PT_LOAD[%ld]:   p_offset %lu, p_filesz %lu,"
1617                         " perms %c%c%c\n",
1618                         i, (UWord)a_phdr.p_offset, (UWord)a_phdr.p_filesz,
1619                         a_phdr.p_flags & PF_R ? 'r' : '-',
1620                         a_phdr.p_flags & PF_W ? 'w' : '-',
1621                         a_phdr.p_flags & PF_X ? 'x' : '-');
1622            if (a_phdr.p_vaddr < prev_svma) {
1623               ML_(symerr)(di, True,
1624                           "ELF Program Headers are not in ascending order");
1625               goto out;
1626            }
1627            prev_svma = a_phdr.p_vaddr;
1628            if (a_phdr.p_memsz > 0) {
1629               Bool loaded = False;
1630               for (j = 0; j < VG_(sizeXA)(di->fsm.maps); j++) {
1631                  struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, j);
1632                  if (   (map->rx || map->rw)
1633                      && a_phdr.p_offset >= map->foff
1634                      && a_phdr.p_offset <  map->foff + map->size
1635                      && a_phdr.p_offset + a_phdr.p_filesz
1636                         <= map->foff + map->size) {
1637                     RangeAndBias item;
1638                     item.svma_base  = a_phdr.p_vaddr;
1639                     item.svma_limit = a_phdr.p_vaddr + a_phdr.p_memsz;
1640                     item.bias       = map->avma - map->foff
1641                                       + a_phdr.p_offset - a_phdr.p_vaddr;
1642                     if (map->rw
1643                         && (a_phdr.p_flags & (PF_R | PF_W))
1644                            == (PF_R | PF_W)) {
1645                        item.exec = False;
1646                        VG_(addToXA)(svma_ranges, &item);
1647                        TRACE_SYMTAB("PT_LOAD[%ld]:   acquired as rw\n", i);
1648                        loaded = True;
1649                     }
1650                     if (map->rx
1651                         && (a_phdr.p_flags & (PF_R | PF_X))
1652                            == (PF_R | PF_X)) {
1653                        item.exec = True;
1654                        VG_(addToXA)(svma_ranges, &item);
1655                        TRACE_SYMTAB("PT_LOAD[%ld]:   acquired as rx\n", i);
1656                        loaded = True;
1657                     }
1658                  }
1659               }
1660               if (!loaded) {
1661                  ML_(symerr)(di, False,
1662                              "ELF section outside all mapped regions");
1663                  /* This problem might be solved by further memory mappings.
1664                     Avoid the vg_assert(!di->soname) at the beginning of this
1665                     function if DYNAMIC section has been already processed. */
1666                  if (di->soname) {
1667                     ML_(dinfo_free)(di->soname);
1668                     di->soname = NULL;
1669                  }
1670                  goto out;
1671               }
1672            }
1673         }
1674
1675         /* Try to get the soname.  If there isn't one, use "NONE".
1676            The seginfo needs to have some kind of soname in order to
1677            facilitate writing redirect functions, since all redirect
1678            specifications require a soname (pattern). */
1679         if (a_phdr.p_type == PT_DYNAMIC && di->soname == NULL) {
1680            Word   stroff       = -1;
1681            DiOffT strtab_mioff = DiOffT_INVALID;
1682            for (j = 0; True/*exit check is in the loop*/; j++) {
1683               ElfXX_Dyn t_dyn_m; /* dyn_img[j] */
1684               ML_(img_get)(&t_dyn_m, mimg,
1685                            INDEX_BIS(ehdr_mioff + a_phdr.p_offset,
1686                                      j, sizeof(ElfXX_Dyn)),
1687                            sizeof(t_dyn_m));
1688               if (t_dyn_m.d_tag == DT_NULL)
1689                  break;
1690
1691               switch (t_dyn_m.d_tag) {
1692                  case DT_SONAME: {
1693                     stroff = t_dyn_m.d_un.d_val;
1694                     break;
1695                  }
1696                  case DT_STRTAB: {
1697                     Bool ok2 = False;
1698                     Word offset = file_offset_from_svma(
1699                                      &ok2, t_dyn_m.d_un.d_ptr, mimg,
1700                                      phdr_mioff, phdr_mnent, phdr_ment_szB
1701                                   );
1702                     if (ok2 && strtab_mioff == DiOffT_INVALID) {
1703                        // Check for obviously bogus offsets.
1704                        if (!ML_(img_valid)(mimg, offset, 1)) {
1705                           ML_(symerr)(di, True, "Invalid DT_STRTAB offset");
1706                           goto out;
1707                        }
1708                        strtab_mioff = ehdr_mioff + offset;
1709                        vg_assert(ehdr_mioff == 0); // should always be
1710                     }
1711                     break;
1712                  }
1713                  default:
1714                     break;
1715               }
1716            }
1717            if (stroff != -1 && strtab_mioff != DiOffT_INVALID) {
1718               di->soname = ML_(img_strdup)(mimg, "di.redi.1",
1719                                            strtab_mioff + stroff);
1720               TRACE_SYMTAB("Found soname = %s\n", di->soname);
1721            }
1722         }
1723      } /* for (i = 0; i < phdr_Mnent; i++) ... */
1724      /* TOPLEVEL */
1725
1726   } /* examine the program headers (local scope) */
1727
1728   /* TOPLEVEL */
1729
1730   /* If, after looking at all the program headers, we still didn't
1731      find a soname, add a fake one. */
1732   if (di->soname == NULL) {
1733      TRACE_SYMTAB("No soname found; using (fake) \"NONE\"\n");
1734      di->soname = ML_(dinfo_strdup)("di.redi.2", "NONE");
1735   }
1736
1737   vg_assert(VG_(sizeXA)(svma_ranges) != 0);
1738
1739   /* Now read the section table. */
1740   TRACE_SYMTAB("\n");
1741   TRACE_SYMTAB("------ Examining the section headers ------\n");
1742   for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1743      struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
1744      if (map->rx)
1745         TRACE_SYMTAB("rx: at %#lx are mapped foffsets %ld .. %ld\n",
1746                      map->avma, map->foff, map->foff + map->size - 1 );
1747   }
1748   TRACE_SYMTAB("rx: contains these svma regions:\n");
1749   for (i = 0; i < VG_(sizeXA)(svma_ranges); i++) {
1750      RangeAndBias* reg = VG_(indexXA)(svma_ranges, i);
1751      if (reg->exec)
1752         TRACE_SYMTAB("  svmas %#lx .. %#lx with bias %#lx\n",
1753                      reg->svma_base, reg->svma_limit - 1, reg->bias );
1754   }
1755   for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1756      struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
1757      if (map->rw)
1758         TRACE_SYMTAB("rw: at %#lx are mapped foffsets %ld .. %ld\n",
1759                      map->avma, map->foff, map->foff + map->size - 1 );
1760   }
1761   TRACE_SYMTAB("rw: contains these svma regions:\n");
1762   for (i = 0; i < VG_(sizeXA)(svma_ranges); i++) {
1763      RangeAndBias* reg = VG_(indexXA)(svma_ranges, i);
1764      if (!reg->exec)
1765         TRACE_SYMTAB("  svmas %#lx .. %#lx with bias %#lx\n",
1766                      reg->svma_base, reg->svma_limit - 1, reg->bias );
1767   }
1768
1769   /* TOPLEVEL */
1770   /* Iterate over section headers */
1771   for (i = 0; i < shdr_mnent; i++) {
1772      ElfXX_Shdr a_shdr;
1773      ML_(img_get)(&a_shdr, mimg,
1774                   INDEX_BIS(shdr_mioff, i, shdr_ment_szB), sizeof(a_shdr));
1775      DiOffT name_mioff = shdr_strtab_mioff + a_shdr.sh_name;
1776      HChar* name = ML_(img_strdup)(mimg, "di.redi_name.1", name_mioff);
1777      Addr   svma = a_shdr.sh_addr;
1778      OffT   foff = a_shdr.sh_offset;
1779      UWord  size = a_shdr.sh_size; /* Do not change this to be signed. */
1780      UInt   alyn = a_shdr.sh_addralign;
1781      Bool   bits = !(a_shdr.sh_type == SHT_NOBITS);
1782      /* Look through our collection of info obtained from the PT_LOAD
1783         headers, and make 'inrx' and 'inrw' point to the first entry
1784         in each that intersects 'avma'.  If in each case none is found,
1785         leave the relevant pointer at NULL. */
1786      RangeAndBias* inrx = NULL;
1787      RangeAndBias* inrw = NULL;
1788      for (j = 0; j < VG_(sizeXA)(svma_ranges); j++) {
1789         RangeAndBias* rng = VG_(indexXA)(svma_ranges, j);
1790         if (svma >= rng->svma_base && svma < rng->svma_limit) {
1791            if (!inrx && rng->exec) {
1792               inrx = rng;
1793            } else if (!inrw && !rng->exec) {
1794               inrw = rng;
1795            }
1796            if (inrx && inrw)
1797               break;
1798         }
1799      }
1800
1801      TRACE_SYMTAB(" [sec %2ld]  %s %s  al%2u  foff %6ld .. %6ld  "
1802                   "  svma %p  name \"%s\"\n",
1803                   i, inrx ? "rx" : "  ", inrw ? "rw" : "  ", alyn,
1804                   foff, foff+size-1, (void*)svma, name);
1805
1806      /* Check for sane-sized segments.  SHT_NOBITS sections have zero
1807         size in the file. */
1808      if ((foff >= ML_(img_size)(mimg))
1809          || (foff + (bits ? size : 0) > ML_(img_size)(mimg))) {
1810         ML_(symerr)(di, True, "ELF Section extends beyond image end");
1811         goto out;
1812      }
1813
1814      /* Check for a sane alignment value. */
1815      if (alyn > 0 && -1 == VG_(log2)(alyn)) {
1816         ML_(symerr)(di, True, "ELF Section contains invalid "
1817                               ".sh_addralign value");
1818         goto out;
1819      }
1820
1821      /* Ignore zero sized sections. */
1822      if (size == 0) {
1823         TRACE_SYMTAB("zero sized section \"%s\", ignoring\n", name);
1824         ML_(dinfo_free)(name);
1825         continue;
1826      }
1827
1828#     define BAD(_secname)                                 \
1829         do { ML_(symerr)(di, True,                        \
1830                          "Can't make sense of " _secname  \
1831                          " section mapping");             \
1832              /* make sure we don't assert if we find */   \
1833              /* ourselves back in this routine later, */  \
1834              /* with the same di */                       \
1835              di->soname = NULL;                           \
1836              goto out;                                    \
1837         } while (0)
1838
1839      /* Find avma-s for: .text .data .sdata .rodata .bss .sbss .plt .got .opd
1840         and .eh_frame */
1841
1842      /* Accept .text where mapped as rx (code), even if zero-sized */
1843      if (0 == VG_(strcmp)(name, ".text")) {
1844         if (inrx && !di->text_present) {
1845            di->text_present = True;
1846            di->text_svma = svma;
1847            di->text_avma = svma + inrx->bias;
1848            di->text_size = size;
1849            di->text_bias = inrx->bias;
1850            di->text_debug_svma = svma;
1851            di->text_debug_bias = inrx->bias;
1852            TRACE_SYMTAB("acquiring .text svma = %#lx .. %#lx\n",
1853                         di->text_svma,
1854                         di->text_svma + di->text_size - 1);
1855            TRACE_SYMTAB("acquiring .text avma = %#lx .. %#lx\n",
1856                         di->text_avma,
1857                         di->text_avma + di->text_size - 1);
1858            TRACE_SYMTAB("acquiring .text bias = %#lx\n", di->text_bias);
1859         } else {
1860            BAD(".text");
1861         }
1862      }
1863
1864      /* Accept .data where mapped as rw (data), even if zero-sized */
1865      if (0 == VG_(strcmp)(name, ".data")) {
1866         if (inrw && !di->data_present) {
1867            di->data_present = True;
1868            di->data_svma = svma;
1869            di->data_avma = svma + inrw->bias;
1870            di->data_size = size;
1871            di->data_bias = inrw->bias;
1872            di->data_debug_svma = svma;
1873            di->data_debug_bias = inrw->bias;
1874            TRACE_SYMTAB("acquiring .data svma = %#lx .. %#lx\n",
1875                         di->data_svma,
1876                         di->data_svma + di->data_size - 1);
1877            TRACE_SYMTAB("acquiring .data avma = %#lx .. %#lx\n",
1878                         di->data_avma,
1879                         di->data_avma + di->data_size - 1);
1880            TRACE_SYMTAB("acquiring .data bias = %#lx\n", di->data_bias);
1881         } else {
1882            BAD(".data");
1883         }
1884      }
1885
1886      /* Accept .sdata where mapped as rw (data) */
1887      if (0 == VG_(strcmp)(name, ".sdata")) {
1888         if (inrw && !di->sdata_present) {
1889            di->sdata_present = True;
1890            di->sdata_svma = svma;
1891            di->sdata_avma = svma + inrw->bias;
1892            di->sdata_size = size;
1893            di->sdata_bias = inrw->bias;
1894            di->sdata_debug_svma = svma;
1895            di->sdata_debug_bias = inrw->bias;
1896            TRACE_SYMTAB("acquiring .sdata svma = %#lx .. %#lx\n",
1897                         di->sdata_svma,
1898                         di->sdata_svma + di->sdata_size - 1);
1899            TRACE_SYMTAB("acquiring .sdata avma = %#lx .. %#lx\n",
1900                         di->sdata_avma,
1901                         di->sdata_avma + di->sdata_size - 1);
1902            TRACE_SYMTAB("acquiring .sdata bias = %#lx\n", di->sdata_bias);
1903         } else {
1904            BAD(".sdata");
1905         }
1906      }
1907
1908      /* Accept .rodata where mapped as rx (data), even if zero-sized */
1909      if (0 == VG_(strcmp)(name, ".rodata")) {
1910         if (inrx && !di->rodata_present) {
1911            di->rodata_present = True;
1912            di->rodata_svma = svma;
1913            di->rodata_avma = svma + inrx->bias;
1914            di->rodata_size = size;
1915            di->rodata_bias = inrx->bias;
1916            di->rodata_debug_svma = svma;
1917            di->rodata_debug_bias = inrx->bias;
1918                                    /* NB was 'inrw' prior to r11794 */
1919            TRACE_SYMTAB("acquiring .rodata svma = %#lx .. %#lx\n",
1920                         di->rodata_svma,
1921                         di->rodata_svma + di->rodata_size - 1);
1922            TRACE_SYMTAB("acquiring .rodata avma = %#lx .. %#lx\n",
1923                         di->rodata_avma,
1924                         di->rodata_avma + di->rodata_size - 1);
1925            TRACE_SYMTAB("acquiring .rodata bias = %#lx\n", di->rodata_bias);
1926         } else {
1927            BAD(".rodata");
1928         }
1929      }
1930
1931      if (0 == VG_(strcmp)(name, ".dynbss")) {
1932         if (inrw && !di->bss_present) {
1933            dynbss_present = True;
1934            di->bss_present = True;
1935            di->bss_svma = svma;
1936            di->bss_avma = svma + inrw->bias;
1937            di->bss_size = size;
1938            di->bss_bias = inrw->bias;
1939            di->bss_debug_svma = svma;
1940            di->bss_debug_bias = inrw->bias;
1941            TRACE_SYMTAB("acquiring .dynbss svma = %#lx .. %#lx\n",
1942                         di->bss_svma,
1943                         di->bss_svma + di->bss_size - 1);
1944            TRACE_SYMTAB("acquiring .dynbss avma = %#lx .. %#lx\n",
1945                         di->bss_avma,
1946                         di->bss_avma + di->bss_size - 1);
1947            TRACE_SYMTAB("acquiring .dynbss bias = %#lx\n", di->bss_bias);
1948         }
1949      }
1950
1951      /* Accept .bss where mapped as rw (data), even if zero-sized */
1952      if (0 == VG_(strcmp)(name, ".bss")) {
1953         if (inrw && dynbss_present) {
1954            vg_assert(di->bss_present);
1955            dynbss_present = False;
1956            vg_assert(di->bss_svma + di->bss_size == svma);
1957            di->bss_size += size;
1958            TRACE_SYMTAB("acquiring .bss svma = %#lx .. %#lx\n",
1959                         svma, svma + size - 1);
1960            TRACE_SYMTAB("acquiring .bss avma = %#lx .. %#lx\n",
1961                         svma + inrw->bias, svma + inrw->bias + size - 1);
1962            TRACE_SYMTAB("acquiring .bss bias = %#lx\n", di->bss_bias);
1963         } else
1964
1965         if (inrw && !di->bss_present) {
1966            di->bss_present = True;
1967            di->bss_svma = svma;
1968            di->bss_avma = svma + inrw->bias;
1969            di->bss_size = size;
1970            di->bss_bias = inrw->bias;
1971            di->bss_debug_svma = svma;
1972            di->bss_debug_bias = inrw->bias;
1973            TRACE_SYMTAB("acquiring .bss svma = %#lx .. %#lx\n",
1974                         di->bss_svma,
1975                         di->bss_svma + di->bss_size - 1);
1976            TRACE_SYMTAB("acquiring .bss avma = %#lx .. %#lx\n",
1977                         di->bss_avma,
1978                         di->bss_avma + di->bss_size - 1);
1979            TRACE_SYMTAB("acquiring .bss bias = %#lx\n", di->bss_bias);
1980         } else
1981
1982         /* Now one from the wtf?! department ... */
1983         if (inrx && (!inrw) && !di->bss_present) {
1984            /* File contains a .bss, but it got mapped as rx only.
1985               This is very strange.  For now, just pretend we didn't
1986               see it :-) */
1987            di->bss_present = False;
1988            di->bss_svma = 0;
1989            di->bss_avma = 0;
1990            di->bss_size = 0;
1991            di->bss_bias = 0;
1992            di->bss_debug_svma = 0;
1993            di->bss_debug_bias = 0;
1994            if (!VG_(clo_xml)) {
1995               VG_(message)(Vg_UserMsg,
1996                            "Warning: the following file's .bss is "
1997                            "mapped r-x only - ignoring .bss syms\n");
1998               VG_(message)(Vg_UserMsg,   " %s\n", di->fsm.filename
1999                                                      ? di->fsm.filename
2000                                                      : "(null?!)" );
2001            }
2002         } else
2003
2004         if ((!inrw) && (!inrx) && !di->bss_present) {
2005            /* File contains a .bss, but it didn't get mapped.  Ignore. */
2006            di->bss_present = False;
2007            di->bss_svma = 0;
2008            di->bss_avma = 0;
2009            di->bss_size = 0;
2010            di->bss_bias = 0;
2011         } else {
2012            BAD(".bss");
2013         }
2014      }
2015
2016      if (0 == VG_(strcmp)(name, ".sdynbss")) {
2017         if (inrw && !di->sbss_present) {
2018            sdynbss_present = True;
2019            di->sbss_present = True;
2020            di->sbss_svma = svma;
2021            di->sbss_avma = svma + inrw->bias;
2022            di->sbss_size = size;
2023            di->sbss_bias = inrw->bias;
2024            di->sbss_debug_svma = svma;
2025            di->sbss_debug_bias = inrw->bias;
2026            TRACE_SYMTAB("acquiring .sdynbss svma = %#lx .. %#lx\n",
2027                         di->sbss_svma,
2028                         di->sbss_svma + di->sbss_size - 1);
2029            TRACE_SYMTAB("acquiring .sdynbss avma = %#lx .. %#lx\n",
2030                         di->sbss_avma,
2031                         di->sbss_avma + di->sbss_size - 1);
2032            TRACE_SYMTAB("acquiring .sdynbss bias = %#lx\n", di->sbss_bias);
2033         }
2034      }
2035
2036      /* Accept .sbss where mapped as rw (data) */
2037      if (0 == VG_(strcmp)(name, ".sbss")) {
2038         if (inrw && sdynbss_present) {
2039            vg_assert(di->sbss_present);
2040            sdynbss_present = False;
2041            vg_assert(di->sbss_svma + di->sbss_size == svma);
2042            di->sbss_size += size;
2043            TRACE_SYMTAB("acquiring .sbss svma = %#lx .. %#lx\n",
2044                         svma, svma + size - 1);
2045            TRACE_SYMTAB("acquiring .sbss avma = %#lx .. %#lx\n",
2046                         svma + inrw->bias, svma + inrw->bias + size - 1);
2047            TRACE_SYMTAB("acquiring .sbss bias = %#lx\n", di->sbss_bias);
2048         } else
2049
2050         if (inrw && !di->sbss_present) {
2051            di->sbss_present = True;
2052            di->sbss_svma = svma;
2053            di->sbss_avma = svma + inrw->bias;
2054            di->sbss_size = size;
2055            di->sbss_bias = inrw->bias;
2056            di->sbss_debug_svma = svma;
2057            di->sbss_debug_bias = inrw->bias;
2058            TRACE_SYMTAB("acquiring .sbss svma = %#lx .. %#lx\n",
2059                         di->sbss_svma,
2060                         di->sbss_svma + di->sbss_size - 1);
2061            TRACE_SYMTAB("acquiring .sbss avma = %#lx .. %#lx\n",
2062                         di->sbss_avma,
2063                         di->sbss_avma + di->sbss_size - 1);
2064            TRACE_SYMTAB("acquiring .sbss bias = %#lx\n", di->sbss_bias);
2065         } else {
2066            BAD(".sbss");
2067         }
2068      }
2069
2070      /* Accept .got where mapped as rw (data) */
2071      if (0 == VG_(strcmp)(name, ".got")) {
2072         if (inrw && !di->got_present) {
2073            di->got_present = True;
2074            di->got_avma = svma + inrw->bias;
2075            di->got_size = size;
2076            TRACE_SYMTAB("acquiring .got avma = %#lx\n", di->got_avma);
2077         } else {
2078            BAD(".got");
2079         }
2080      }
2081
2082      /* Accept .got.plt where mapped as rw (data) */
2083      if (0 == VG_(strcmp)(name, ".got.plt")) {
2084         if (inrw && !di->gotplt_present) {
2085            di->gotplt_present = True;
2086            di->gotplt_avma = svma + inrw->bias;
2087            di->gotplt_size = size;
2088            TRACE_SYMTAB("acquiring .got.plt avma = %#lx\n", di->gotplt_avma);
2089         } else if (size != 0) {
2090            BAD(".got.plt");
2091         }
2092      }
2093
2094      /* PLT is different on different platforms, it seems. */
2095#     if defined(VGP_x86_linux) || defined(VGP_amd64_linux) \
2096         || defined(VGP_arm_linux) || defined (VGP_s390x_linux) \
2097         || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
2098         || defined(VGP_arm64_linux)
2099      /* Accept .plt where mapped as rx (code) */
2100      if (0 == VG_(strcmp)(name, ".plt")) {
2101         if (inrx && !di->plt_present) {
2102            di->plt_present = True;
2103            di->plt_avma = svma + inrx->bias;
2104            di->plt_size = size;
2105            TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
2106         } else {
2107            BAD(".plt");
2108         }
2109      }
2110#     elif defined(VGP_ppc32_linux)
2111      /* Accept .plt where mapped as rw (data) */
2112      if (0 == VG_(strcmp)(name, ".plt")) {
2113         if (inrw && !di->plt_present) {
2114            di->plt_present = True;
2115            di->plt_avma = svma + inrw->bias;
2116            di->plt_size = size;
2117            TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
2118         } else {
2119            BAD(".plt");
2120         }
2121      }
2122#     elif defined(VGP_ppc64_linux)
2123      /* Accept .plt where mapped as rw (data), or unmapped */
2124      if (0 == VG_(strcmp)(name, ".plt")) {
2125         if (inrw && !di->plt_present) {
2126            di->plt_present = True;
2127            di->plt_avma = svma + inrw->bias;
2128            di->plt_size = size;
2129            TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
2130         } else
2131         if ((!inrw) && (!inrx) && size > 0 && !di->plt_present) {
2132            /* File contains a .plt, but it didn't get mapped.
2133               Presumably it is not required on this platform.  At
2134               least don't reject the situation as invalid. */
2135            di->plt_present = True;
2136            di->plt_avma = 0;
2137            di->plt_size = 0;
2138         } else {
2139            BAD(".plt");
2140         }
2141      }
2142#     else
2143#       error "Unsupported platform"
2144#     endif
2145
2146      /* Accept .opd where mapped as rw (data) */
2147      if (0 == VG_(strcmp)(name, ".opd")) {
2148         if (inrw && !di->opd_present) {
2149            di->opd_present = True;
2150            di->opd_avma = svma + inrw->bias;
2151            di->opd_size = size;
2152            TRACE_SYMTAB("acquiring .opd avma = %#lx\n", di->opd_avma);
2153         } else {
2154            BAD(".opd");
2155         }
2156      }
2157
2158      /* Accept .eh_frame where mapped as rx (code).  This seems to be
2159         the common case.  However, if that doesn't pan out, try for
2160         rw (data) instead.  We can handle up to N_EHFRAME_SECTS per
2161         ELF object. */
2162      if (0 == VG_(strcmp)(name, ".eh_frame")) {
2163         if (inrx && di->n_ehframe < N_EHFRAME_SECTS) {
2164            di->ehframe_avma[di->n_ehframe] = svma + inrx->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         if (inrw && di->n_ehframe < N_EHFRAME_SECTS) {
2171            di->ehframe_avma[di->n_ehframe] = svma + inrw->bias;
2172            di->ehframe_size[di->n_ehframe] = size;
2173            TRACE_SYMTAB("acquiring .eh_frame avma = %#lx\n",
2174                         di->ehframe_avma[di->n_ehframe]);
2175            di->n_ehframe++;
2176         } else {
2177            BAD(".eh_frame");
2178         }
2179      }
2180
2181      ML_(dinfo_free)(name);
2182
2183#     undef BAD
2184
2185   } /* iterate over the section headers */
2186
2187   /* TOPLEVEL */
2188   if (0) VG_(printf)("YYYY text_: avma %#lx  size %ld  bias %#lx\n",
2189                      di->text_avma, di->text_size, di->text_bias);
2190
2191   if (VG_(clo_verbosity) > 2 || VG_(clo_trace_redir))
2192      VG_(message)(Vg_DebugMsg, "   svma %#010lx, avma %#010lx\n",
2193                                di->text_avma - di->text_bias,
2194                                di->text_avma );
2195
2196   TRACE_SYMTAB("\n");
2197   TRACE_SYMTAB("------ Finding image addresses "
2198                "for debug-info sections ------\n");
2199
2200   /* TOPLEVEL */
2201   /* Find interesting sections, read the symbol table(s), read any
2202      debug information.  Each section is located either in the main,
2203      debug or alt-debug files, but only in one.  For each section,
2204      |section_escn| records which of |mimg|, |dimg| or |aimg| we
2205      found it in, along with the section's image offset and its size.
2206      The triples (section_img, section_ioff, section_szB) are
2207      consistent, in that they are always either (NULL,
2208      DiOffT_INVALID, 0), or refer to the same image, and are all
2209      assigned together. */
2210   {
2211      /* TOPLEVEL */
2212      DiSlice strtab_escn         = DiSlice_INVALID; // .strtab
2213      DiSlice symtab_escn         = DiSlice_INVALID; // .symtab
2214      DiSlice dynstr_escn         = DiSlice_INVALID; // .dynstr
2215      DiSlice dynsym_escn         = DiSlice_INVALID; // .dynsym
2216      DiSlice debuglink_escn      = DiSlice_INVALID; // .gnu_debuglink
2217      DiSlice debugaltlink_escn   = DiSlice_INVALID; // .gnu_debugaltlink
2218      DiSlice stab_escn           = DiSlice_INVALID; // .stab         (stabs)
2219      DiSlice stabstr_escn        = DiSlice_INVALID; // .stabstr      (stabs)
2220      DiSlice debug_line_escn     = DiSlice_INVALID; // .debug_line   (dwarf2)
2221      DiSlice debug_info_escn     = DiSlice_INVALID; // .debug_info   (dwarf2)
2222      DiSlice debug_types_escn    = DiSlice_INVALID; // .debug_types  (dwarf4)
2223      DiSlice debug_abbv_escn     = DiSlice_INVALID; // .debug_abbrev (dwarf2)
2224      DiSlice debug_str_escn      = DiSlice_INVALID; // .debug_str    (dwarf2)
2225      DiSlice debug_ranges_escn   = DiSlice_INVALID; // .debug_ranges (dwarf2)
2226      DiSlice debug_loc_escn      = DiSlice_INVALID; // .debug_loc    (dwarf2)
2227      DiSlice debug_frame_escn    = DiSlice_INVALID; // .debug_frame  (dwarf2)
2228      DiSlice debug_line_alt_escn = DiSlice_INVALID; // .debug_line   (alt)
2229      DiSlice debug_info_alt_escn = DiSlice_INVALID; // .debug_info   (alt)
2230      DiSlice debug_abbv_alt_escn = DiSlice_INVALID; // .debug_abbrev (alt)
2231      DiSlice debug_str_alt_escn  = DiSlice_INVALID; // .debug_str    (alt)
2232      DiSlice dwarf1d_escn        = DiSlice_INVALID; // .debug        (dwarf1)
2233      DiSlice dwarf1l_escn        = DiSlice_INVALID; // .line         (dwarf1)
2234      DiSlice opd_escn            = DiSlice_INVALID; // .opd (dwarf2,
2235                                                     //       ppc64-linux)
2236      DiSlice ehframe_escn[N_EHFRAME_SECTS];         // .eh_frame (dwarf2)
2237
2238      for (i = 0; i < N_EHFRAME_SECTS; i++)
2239         ehframe_escn[i] = DiSlice_INVALID;
2240
2241      /* Find all interesting sections */
2242
2243      UInt ehframe_mix = 0;
2244
2245      /* What FIND does: it finds the section called _SEC_NAME.  The
2246         size of it is assigned to _SEC_SIZE.  The address of the
2247         section in the transiently loaded oimage is assigned to
2248         _SEC_IMG.  If the section is found, _POST_FX is executed
2249         after _SEC_NAME and _SEC_SIZE have been assigned to.
2250
2251         Even for sections which are marked loadable, the client's
2252         ld.so may not have loaded them yet, so there is no guarantee
2253         that we can safely prod around in any such area).  Because
2254         the entire object file is transiently mapped aboard for
2255         inspection, it's always safe to inspect that area. */
2256
2257      /* TOPLEVEL */
2258      /* Iterate over section headers (again) */
2259      for (i = 0; i < ehdr_m.e_shnum; i++) {
2260
2261#        define FINDX(_sec_name, _sec_escn, _post_fx) \
2262         do { \
2263            ElfXX_Shdr a_shdr; \
2264            ML_(img_get)(&a_shdr, mimg, \
2265                         INDEX_BIS(shdr_mioff, i, shdr_ment_szB), \
2266                         sizeof(a_shdr)); \
2267            if (0 == ML_(img_strcmp_c)(mimg, shdr_strtab_mioff \
2268                                              + a_shdr.sh_name, _sec_name)) { \
2269               Bool nobits; \
2270               _sec_escn.img  = mimg; \
2271               _sec_escn.ioff = (DiOffT)a_shdr.sh_offset; \
2272               _sec_escn.szB  = a_shdr.sh_size; \
2273               nobits         = a_shdr.sh_type == SHT_NOBITS; \
2274               vg_assert(_sec_escn.img  != NULL); \
2275               vg_assert(_sec_escn.ioff != DiOffT_INVALID); \
2276               TRACE_SYMTAB( "%18s:  ioff %llu .. %llu\n", \
2277                             _sec_name, (ULong)_sec_escn.ioff, \
2278                             ((ULong)_sec_escn.ioff) + _sec_escn.szB - 1); \
2279               /* SHT_NOBITS sections have zero size in the file. */ \
2280               if ( a_shdr.sh_offset \
2281                    + (nobits ? 0 : _sec_escn.szB) > ML_(img_size)(mimg) ) { \
2282                  ML_(symerr)(di, True, \
2283                              "   section beyond image end?!"); \
2284                  goto out; \
2285               } \
2286               _post_fx; \
2287            } \
2288         } while (0);
2289
2290         /* Version with no post-effects */
2291#        define FIND(_sec_name, _sec_escn) \
2292            FINDX(_sec_name, _sec_escn, /**/)
2293
2294         /*   NAME                  ElfSec */
2295         FIND(".dynsym",            dynsym_escn)
2296         FIND(".dynstr",            dynstr_escn)
2297         FIND(".symtab",            symtab_escn)
2298         FIND(".strtab",            strtab_escn)
2299
2300         FIND(".gnu_debuglink",     debuglink_escn)
2301         FIND(".gnu_debugaltlink",  debugaltlink_escn)
2302
2303         FIND(".stab",              stab_escn)
2304         FIND(".stabstr",           stabstr_escn)
2305
2306         FIND(".debug_line",        debug_line_escn)
2307         FIND(".debug_info",        debug_info_escn)
2308         FIND(".debug_types",       debug_types_escn)
2309         FIND(".debug_abbrev",      debug_abbv_escn)
2310         FIND(".debug_str",         debug_str_escn)
2311         FIND(".debug_ranges",      debug_ranges_escn)
2312         FIND(".debug_loc",         debug_loc_escn)
2313         FIND(".debug_frame",       debug_frame_escn)
2314
2315         FIND(".debug",             dwarf1d_escn)
2316         FIND(".line",              dwarf1l_escn)
2317
2318         FIND(".opd",               opd_escn)
2319
2320         FINDX(".eh_frame",         ehframe_escn[ehframe_mix],
2321               do { ehframe_mix++; vg_assert(ehframe_mix <= N_EHFRAME_SECTS);
2322               } while (0)
2323         )
2324         /* Comment_on_EH_FRAME_MULTIPLE_INSTANCES: w.r.t. .eh_frame
2325            multi-instance kludgery, how are we assured that the order
2326            in which we fill in ehframe_escn[] is consistent with the
2327            order in which we previously filled in di->ehframe_avma[]
2328            and di->ehframe_size[] ?  By the fact that in both cases,
2329            these arrays were filled in by iterating over the section
2330            headers top-to-bottom.  So both loops (this one and the
2331            previous one) encounter the .eh_frame entries in the same
2332            order and so fill in these arrays in a consistent order.
2333         */
2334
2335#        undef FINDX
2336#        undef FIND
2337      } /* Iterate over section headers (again) */
2338
2339      /* TOPLEVEL */
2340      /* Now, see if we can find a debuginfo object, and if so connect
2341         |dimg| to it. */
2342      vg_assert(dimg == NULL && aimg == NULL);
2343
2344      /* Look for a build-id */
2345      HChar* buildid = find_buildid(mimg, False, False);
2346
2347      /* Look for a debug image that matches either the build-id or
2348         the debuglink-CRC32 in the main image.  If the main image
2349         doesn't contain either of those then this won't even bother
2350         to try looking.  This looks in all known places, including
2351         the --extra-debuginfo-path if specified and on the
2352         --debuginfo-server if specified. */
2353      if (buildid != NULL || debuglink_escn.img != NULL) {
2354         /* Do have a debuglink section? */
2355         if (debuglink_escn.img != NULL) {
2356            UInt crc_offset
2357               = VG_ROUNDUP(ML_(img_strlen)(debuglink_escn.img,
2358                                            debuglink_escn.ioff)+1, 4);
2359            vg_assert(crc_offset + sizeof(UInt) <= debuglink_escn.szB);
2360
2361            /* Extract the CRC from the debuglink section */
2362            UInt crc = ML_(img_get_UInt)(debuglink_escn.img,
2363                                         debuglink_escn.ioff + crc_offset);
2364
2365            /* See if we can find a matching debug file */
2366            HChar* debuglink_str_m
2367               = ML_(img_strdup)(debuglink_escn.img,
2368                                 "di.redi_dlk.1", debuglink_escn.ioff);
2369            dimg = find_debug_file( di, di->fsm.filename, buildid,
2370                                    debuglink_str_m, crc, False );
2371            if (debuglink_str_m)
2372               ML_(dinfo_free)(debuglink_str_m);
2373         } else {
2374            /* See if we can find a matching debug file */
2375            dimg = find_debug_file( di, di->fsm.filename, buildid,
2376                                    NULL, 0, False );
2377         }
2378      }
2379
2380      if (buildid) {
2381         ML_(dinfo_free)(buildid);
2382         buildid = NULL; /* paranoia */
2383      }
2384
2385      /* As a last-ditch measure, try looking for in the
2386         --extra-debuginfo-path and/or on the --debuginfo-server, but
2387         only in the case where --allow-mismatched-debuginfo=yes.
2388         This is dangerous in that (1) it gives no assurance that the
2389         debuginfo object matches the main one, and hence (2) we will
2390         very likely get an assertion in the code below, if indeed
2391         there is a mismatch.  Hence it is disabled by default
2392         (--allow-mismatched-debuginfo=no).  Nevertheless it's
2393         sometimes a useful way of getting out of a tight spot.
2394
2395         Note that we're ignoring the name in the .gnu_debuglink
2396         section here, and just looking for a file of the same name
2397         either the extra-path or on the server. */
2398      if (dimg == NULL && VG_(clo_allow_mismatched_debuginfo)) {
2399         dimg = find_debug_file_ad_hoc( di, di->fsm.filename );
2400      }
2401
2402      /* TOPLEVEL */
2403      /* If we were successful in finding a debug image, pull various
2404         SVMA/bias/size and image addresses out of it. */
2405      if (dimg != NULL && is_elf_object_file_by_DiImage(dimg, False)) {
2406
2407         /* Pull out and validate program header and section header info */
2408         DiOffT      ehdr_dioff = 0;
2409         ElfXX_Ehdr  ehdr_dimg;
2410         ML_(img_get)(&ehdr_dimg, dimg, ehdr_dioff, sizeof(ehdr_dimg));
2411
2412         DiOffT   phdr_dioff        = ehdr_dimg.e_phoff;
2413         UWord    phdr_dnent        = ehdr_dimg.e_phnum;
2414         UWord    phdr_dent_szB     = ehdr_dimg.e_phentsize;
2415
2416         DiOffT   shdr_dioff        = ehdr_dimg.e_shoff;
2417         UWord    shdr_dnent        = ehdr_dimg.e_shnum;
2418         UWord    shdr_dent_szB     = ehdr_dimg.e_shentsize;
2419
2420         DiOffT   shdr_strtab_dioff = DiOffT_INVALID;
2421
2422         /* SVMAs covered by rx and rw segments and corresponding bias. */
2423         Addr     rx_dsvma_limit = 0;
2424         PtrdiffT rx_dbias = 0;
2425         Addr     rw_dsvma_limit = 0;
2426         PtrdiffT rw_dbias = 0;
2427
2428         Bool need_symtab, need_stabs, need_dwarf2, need_dwarf1;
2429
2430         if (phdr_dnent == 0
2431             || !ML_(img_valid)(dimg, phdr_dioff,
2432                                phdr_dnent * phdr_dent_szB)) {
2433            ML_(symerr)(di, True,
2434                        "Missing or invalid ELF Program Header Table"
2435                        " (debuginfo file)");
2436            goto out;
2437         }
2438
2439         if (shdr_dnent == 0
2440             || !ML_(img_valid)(dimg, shdr_dioff,
2441                                shdr_dnent * shdr_dent_szB)) {
2442            ML_(symerr)(di, True,
2443                        "Missing or invalid ELF Section Header Table"
2444                        " (debuginfo file)");
2445            goto out;
2446         }
2447
2448         /* Also find the section header's string table, and validate. */
2449         /* checked previously by is_elf_object_file: */
2450         vg_assert(ehdr_dimg.e_shstrndx != SHN_UNDEF);
2451
2452         // shdr_dioff is the offset of the section header table
2453         // and we need the ehdr_dimg.e_shstrndx'th entry
2454         { ElfXX_Shdr a_shdr;
2455           ML_(img_get)(&a_shdr, dimg,
2456                        INDEX_BIS(shdr_dioff, ehdr_dimg.e_shstrndx,
2457                                              shdr_dent_szB),
2458                        sizeof(a_shdr));
2459           shdr_strtab_dioff = a_shdr.sh_offset;
2460           if (!ML_(img_valid)(dimg, shdr_strtab_dioff,
2461                               1/*bogus, but we don't know the real size*/)) {
2462              ML_(symerr)(di, True,
2463                          "Invalid ELF Section Header String Table"
2464                          " (debuginfo file)");
2465              goto out;
2466           }
2467         }
2468
2469         for (i = 0; i < ehdr_dimg.e_phnum; i++) {
2470            ElfXX_Phdr a_phdr;
2471            ML_(img_get)(&a_phdr, dimg, INDEX_BIS(ehdr_dimg.e_phoff,
2472                                                  i, phdr_dent_szB),
2473                           sizeof(a_phdr));
2474            if (a_phdr.p_type == PT_LOAD) {
2475               for (j = 0; j < VG_(sizeXA)(di->fsm.maps); j++) {
2476                  struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, j);
2477                  if (   a_phdr.p_offset >= map->foff
2478                      && a_phdr.p_offset <  map->foff + map->size
2479                      && a_phdr.p_offset + a_phdr.p_filesz
2480                         < map->foff + map->size) {
2481                     if (map->rx && rx_dsvma_limit == 0) {
2482                        rx_dsvma_limit = a_phdr.p_vaddr + a_phdr.p_memsz;
2483                        rx_dbias = map->avma - map->foff + a_phdr.p_offset
2484                                   - a_phdr.p_vaddr;
2485                     }
2486                     if (map->rw && rw_dsvma_limit == 0) {
2487                        rw_dsvma_limit = a_phdr.p_vaddr + a_phdr.p_memsz;
2488                        rw_dbias = map->avma - map->foff + a_phdr.p_offset
2489                                   - a_phdr.p_vaddr;
2490                     }
2491                     break;
2492                  }
2493               }
2494            }
2495         }
2496
2497         need_symtab = (symtab_escn.img == NULL);
2498         need_stabs  = (stab_escn.img == NULL);
2499         need_dwarf2 = (debug_info_escn.img == NULL);
2500         need_dwarf1 = (dwarf1d_escn.img == NULL);
2501
2502         /* Find all interesting sections in the debug image */
2503         for (i = 0; i < ehdr_dimg.e_shnum; i++) {
2504
2505            /* Find debug svma and bias information for sections
2506               we found in the main file. */
2507
2508#           define FIND(_sec, _seg) \
2509            do { \
2510               ElfXX_Shdr a_shdr; \
2511               ML_(img_get)(&a_shdr, dimg, \
2512                            INDEX_BIS(shdr_dioff, i, shdr_dent_szB), \
2513                            sizeof(a_shdr)); \
2514               if (di->_sec##_present \
2515                   && 0 == ML_(img_strcmp_c)(dimg, shdr_strtab_dioff \
2516                                             + a_shdr.sh_name, "." #_sec)) { \
2517                  vg_assert(di->_sec##_size == a_shdr.sh_size); \
2518                  /* JRS 2013-Jun-01: the following assert doesn't contain */ \
2519                  /* any ==s, which seems to me to be suspicious. */ \
2520                  vg_assert(di->_sec##_avma +  a_shdr.sh_addr + _seg##_dbias); \
2521                  /* Assume we have a correct value for the main */ \
2522                  /* object's bias.  Use that to derive the debuginfo */ \
2523                  /* object's bias, by adding the difference in SVMAs */ \
2524                  /* for the corresponding sections in the two files. */ \
2525                  /* That should take care of all prelinking effects. */ \
2526                  di->_sec##_debug_svma = a_shdr.sh_addr; \
2527                  di->_sec##_debug_bias \
2528                     = di->_sec##_bias + \
2529                       di->_sec##_svma - di->_sec##_debug_svma; \
2530                  TRACE_SYMTAB("acquiring ." #_sec \
2531                               " debug svma = %#lx .. %#lx\n",       \
2532                               di->_sec##_debug_svma, \
2533                               di->_sec##_debug_svma + di->_sec##_size - 1); \
2534                  TRACE_SYMTAB("acquiring ." #_sec " debug bias = %#lx\n", \
2535                               di->_sec##_debug_bias); \
2536               } \
2537            } while (0);
2538
2539            /* SECTION   SEGMENT */
2540            FIND(text,   rx)
2541            FIND(data,   rw)
2542            FIND(sdata,  rw)
2543            FIND(rodata, rw)
2544            FIND(bss,    rw)
2545            FIND(sbss,   rw)
2546
2547#           undef FIND
2548
2549            /* Same deal as previous FIND, except only do it for those
2550               sections which we didn't find in the main file. */
2551
2552#           define FIND(_condition, _sec_name, _sec_escn) \
2553            do { \
2554               ElfXX_Shdr a_shdr; \
2555               ML_(img_get)(&a_shdr, dimg, \
2556                            INDEX_BIS(shdr_dioff, i, shdr_dent_szB), \
2557                            sizeof(a_shdr)); \
2558               if (_condition \
2559                   && 0 == ML_(img_strcmp_c)(dimg, shdr_strtab_dioff \
2560                                             + a_shdr.sh_name, _sec_name)) { \
2561                  Bool nobits; \
2562                  if (_sec_escn.img != NULL) { \
2563                     ML_(symerr)(di, True, \
2564                                 "   debuginfo section duplicates a" \
2565                                 " section in the main ELF file"); \
2566                     goto out; \
2567                  } \
2568                  _sec_escn.img  = dimg; \
2569                  _sec_escn.ioff = (DiOffT)a_shdr.sh_offset;  \
2570                  _sec_escn.szB  = a_shdr.sh_size; \
2571                  nobits         = a_shdr.sh_type == SHT_NOBITS; \
2572                  vg_assert(_sec_escn.img  != NULL); \
2573                  vg_assert(_sec_escn.ioff != DiOffT_INVALID); \
2574                  TRACE_SYMTAB( "%18s: dioff %llu .. %llu\n", \
2575                                _sec_name, \
2576                                (ULong)_sec_escn.ioff, \
2577                                ((ULong)_sec_escn.ioff) + _sec_escn.szB - 1); \
2578                  /* SHT_NOBITS sections have zero size in the file. */ \
2579                  if (a_shdr.sh_offset \
2580                      + (nobits ? 0 : _sec_escn.szB) > ML_(img_size)(dimg)) { \
2581                     ML_(symerr)(di, True, \
2582                                 "   section beyond image end?!"); \
2583                     goto out; \
2584                  } \
2585               } \
2586            } while (0);
2587
2588            /* NEEDED?        NAME             ElfSec */
2589            FIND(need_symtab, ".symtab",       symtab_escn)
2590            FIND(need_symtab, ".strtab",       strtab_escn)
2591            FIND(need_stabs,  ".stab",         stab_escn)
2592            FIND(need_stabs,  ".stabstr",      stabstr_escn)
2593            FIND(need_dwarf2, ".debug_line",   debug_line_escn)
2594            FIND(need_dwarf2, ".debug_info",   debug_info_escn)
2595            FIND(need_dwarf2, ".debug_types",  debug_types_escn)
2596
2597            FIND(need_dwarf2, ".debug_abbrev", debug_abbv_escn)
2598            FIND(need_dwarf2, ".debug_str",    debug_str_escn)
2599            FIND(need_dwarf2, ".debug_ranges", debug_ranges_escn)
2600
2601            FIND(need_dwarf2, ".debug_loc",    debug_loc_escn)
2602            FIND(need_dwarf2, ".debug_frame",  debug_frame_escn)
2603
2604            FIND(need_dwarf2, ".gnu_debugaltlink", debugaltlink_escn)
2605
2606            FIND(need_dwarf1, ".debug",        dwarf1d_escn)
2607            FIND(need_dwarf1, ".line",         dwarf1l_escn)
2608
2609#           undef FIND
2610         } /* Find all interesting sections */
2611      } /* do we have a debug image? */
2612
2613      /* TOPLEVEL */
2614      /* Look for alternate debug image, and if found, connect |aimg|
2615         to it. */
2616      vg_assert(aimg == NULL);
2617
2618      if (debugaltlink_escn.img != NULL) {
2619         UInt buildid_offset = ML_(img_strlen)(debugaltlink_escn.img,
2620                                               debugaltlink_escn.ioff)+1;
2621
2622         vg_assert(buildid_offset < debugaltlink_escn.szB);
2623
2624         HChar *altbuildid
2625            = ML_(dinfo_zalloc)("di.fbi.4",
2626                                (debugaltlink_escn.szB - buildid_offset)
2627                                * 2 + 1);
2628
2629         for (j = 0; j < debugaltlink_escn.szB - buildid_offset; j++)
2630            VG_(sprintf)(
2631               altbuildid + 2 * j, "%02x",
2632               (UInt)ML_(img_get_UChar)(debugaltlink_escn.img,
2633                                        debugaltlink_escn.ioff
2634                                        + buildid_offset + j));
2635
2636         /* See if we can find a matching debug file */
2637         aimg = find_debug_file( di, di->fsm.filename, altbuildid,
2638                                 NULL, 0, True );
2639
2640         ML_(dinfo_free)(altbuildid);
2641      }
2642
2643      /* TOPLEVEL */
2644      /* If we were successful in finding alternate debug image, pull various
2645         size and image addresses out of it. */
2646      if (aimg != NULL && is_elf_object_file_by_DiImage(aimg, True)) {
2647
2648         /* Pull out and validate program header and section header info */
2649         DiOffT      ehdr_aioff = 0;
2650         ElfXX_Ehdr  ehdr_aimg;
2651         ML_(img_get)(&ehdr_aimg, aimg, ehdr_aioff, sizeof(ehdr_aimg));
2652
2653         DiOffT   shdr_aioff        = ehdr_aimg.e_shoff;
2654         UWord    shdr_anent        = ehdr_aimg.e_shnum;
2655         UWord    shdr_aent_szB     = ehdr_aimg.e_shentsize;
2656
2657         DiOffT   shdr_strtab_aioff = DiOffT_INVALID;
2658
2659         if (shdr_anent == 0
2660             || !ML_(img_valid)(aimg, shdr_aioff,
2661                                shdr_anent * shdr_aent_szB)) {
2662            ML_(symerr)(di, True,
2663                        "Missing or invalid ELF Section Header Table"
2664                        " (alternate debuginfo file)");
2665            goto out;
2666         }
2667
2668         /* Also find the section header's string table, and validate. */
2669         /* checked previously by is_elf_object_file: */
2670         vg_assert(ehdr_aimg.e_shstrndx != SHN_UNDEF);
2671
2672         // shdr_aioff is the offset of the section header table
2673         // and we need the ehdr_aimg.e_shstrndx'th entry
2674         { ElfXX_Shdr a_shdr;
2675           ML_(img_get)(&a_shdr, aimg,
2676                        INDEX_BIS(shdr_aioff, ehdr_aimg.e_shstrndx,
2677                                              shdr_aent_szB),
2678                        sizeof(a_shdr));
2679           shdr_strtab_aioff = a_shdr.sh_offset;
2680           if (!ML_(img_valid)(aimg, shdr_strtab_aioff,
2681                               1/*bogus, but we don't know the real size*/)) {
2682              ML_(symerr)(di, True,
2683                          "Invalid ELF Section Header String Table"
2684                          " (alternate debuginfo file)");
2685              goto out;
2686           }
2687         }
2688
2689         /* Find all interesting sections */
2690         for (i = 0; i < ehdr_aimg.e_shnum; i++) {
2691
2692#           define FIND(_sec_name, _sec_escn) \
2693            do { \
2694               ElfXX_Shdr a_shdr; \
2695               ML_(img_get)(&a_shdr, aimg, \
2696                            INDEX_BIS(shdr_aioff, i, shdr_aent_szB), \
2697                            sizeof(a_shdr)); \
2698               if (0 == ML_(img_strcmp_c)(aimg, shdr_strtab_aioff \
2699                                          + a_shdr.sh_name, _sec_name)) { \
2700                  if (_sec_escn.img != NULL) { \
2701                     ML_(symerr)(di, True, \
2702                                 "   alternate debuginfo section duplicates a" \
2703                                 " section in the main ELF file"); \
2704                     goto out; \
2705                  } \
2706                  _sec_escn.img  = aimg; \
2707                  _sec_escn.ioff = (DiOffT)a_shdr.sh_offset; \
2708                  _sec_escn.szB  = a_shdr.sh_size; \
2709                  vg_assert(_sec_escn.img  != NULL); \
2710                  vg_assert(_sec_escn.ioff != DiOffT_INVALID); \
2711                  TRACE_SYMTAB( "%18s: aioff %llu .. %llu\n", \
2712                                _sec_name, \
2713                                (ULong)_sec_escn.ioff, \
2714                                ((ULong)_sec_escn.ioff) + _sec_escn.szB - 1); \
2715               } \
2716            } while (0);
2717
2718            /*   NAME             ElfSec */
2719            FIND(".debug_line",   debug_line_alt_escn)
2720            FIND(".debug_info",   debug_info_alt_escn)
2721            FIND(".debug_abbrev", debug_abbv_alt_escn)
2722            FIND(".debug_str",    debug_str_alt_escn)
2723
2724#           undef FIND
2725         } /* Find all interesting sections */
2726      } /* do we have a debug image? */
2727
2728
2729      /* TOPLEVEL */
2730      /* Check some sizes */
2731      vg_assert((dynsym_escn.szB % sizeof(ElfXX_Sym)) == 0);
2732      vg_assert((symtab_escn.szB % sizeof(ElfXX_Sym)) == 0);
2733
2734      /* Read symbols */
2735      {
2736         void (*read_elf_symtab)(struct _DebugInfo*, const HChar*,
2737                                 DiSlice*, DiSlice*, DiSlice*, Bool);
2738         Bool symtab_in_debug;
2739#        if defined(VGP_ppc64_linux)
2740         read_elf_symtab = read_elf_symtab__ppc64_linux;
2741#        else
2742         read_elf_symtab = read_elf_symtab__normal;
2743#        endif
2744         symtab_in_debug = symtab_escn.img == dimg;
2745         read_elf_symtab(di, "symbol table",
2746                         &symtab_escn, &strtab_escn, &opd_escn,
2747                         symtab_in_debug);
2748         read_elf_symtab(di, "dynamic symbol table",
2749                         &dynsym_escn, &dynstr_escn, &opd_escn,
2750                         False);
2751      } /* Read symbols */
2752
2753      /* TOPLEVEL */
2754      /* Read .eh_frame and .debug_frame (call-frame-info) if any.  Do
2755         the .eh_frame section(s) first. */
2756      vg_assert(di->n_ehframe >= 0 && di->n_ehframe <= N_EHFRAME_SECTS);
2757      for (i = 0; i < di->n_ehframe; i++) {
2758         /* see Comment_on_EH_FRAME_MULTIPLE_INSTANCES above for why
2759            this next assertion should hold. */
2760         vg_assert(ML_(sli_is_valid)(ehframe_escn[i]));
2761         vg_assert(ehframe_escn[i].szB == di->ehframe_size[i]);
2762         ML_(read_callframe_info_dwarf3)( di,
2763                                          ehframe_escn[i],
2764                                          di->ehframe_avma[i],
2765                                          True/*is_ehframe*/ );
2766      }
2767      if (ML_(sli_is_valid)(debug_frame_escn)) {
2768         ML_(read_callframe_info_dwarf3)( di,
2769                                          debug_frame_escn,
2770                                          0/*assume zero avma*/,
2771                                          False/*!is_ehframe*/ );
2772      }
2773
2774      /* Read the stabs and/or dwarf2 debug information, if any.  It
2775         appears reading stabs stuff on amd64-linux doesn't work, so
2776         we ignore it.  On s390x stabs also doesnt work and we always
2777         have the dwarf info in the eh_frame.  We also segfault on
2778         ppc64-linux when reading stabs, so skip that.  ppc32-linux
2779         seems OK though.  Also skip on Android. */
2780#     if !defined(VGP_amd64_linux) \
2781         && !defined(VGP_s390x_linux) \
2782         && !defined(VGP_ppc64_linux) \
2783         && !defined(VGPV_arm_linux_android) \
2784         && !defined(VGPV_x86_linux_android) \
2785         && !defined(VGP_mips64_linux)
2786#if 0
2787      if (stab_img && stabstr_img) {
2788         ML_(read_debuginfo_stabs) ( di, stab_img, stab_sz,
2789                                         stabstr_img, stabstr_sz );
2790      }
2791#endif
2792#     endif
2793      /* jrs 2006-01-01: icc-8.1 has been observed to generate
2794         binaries without debug_str sections.  Don't preclude
2795         debuginfo reading for that reason, but, in
2796         read_unitinfo_dwarf2, do check that debugstr is non-NULL
2797         before using it. */
2798      if (ML_(sli_is_valid)(debug_info_escn)
2799          && ML_(sli_is_valid)(debug_abbv_escn)
2800          && ML_(sli_is_valid)(debug_line_escn)) {
2801         /* The old reader: line numbers and unwind info only */
2802         ML_(read_debuginfo_dwarf3) ( di,
2803                                      debug_info_escn,
2804                                      debug_types_escn,
2805                                      debug_abbv_escn,
2806                                      debug_line_escn,
2807                                      debug_str_escn,
2808                                      debug_str_alt_escn );
2809         /* The new reader: read the DIEs in .debug_info to acquire
2810            information on variable types and locations.  But only if
2811            the tool asks for it, or the user requests it on the
2812            command line. */
2813         if (VG_(needs).var_info /* the tool requires it */
2814             || VG_(clo_read_var_info) /* the user asked for it */) {
2815            ML_(new_dwarf3_reader)(
2816               di, debug_info_escn,     debug_types_escn,
2817                   debug_abbv_escn,     debug_line_escn,
2818                   debug_str_escn,      debug_ranges_escn,
2819                   debug_loc_escn,      debug_info_alt_escn,
2820                   debug_abbv_alt_escn, debug_line_alt_escn,
2821                   debug_str_alt_escn
2822            );
2823         }
2824      }
2825#if 0
2826      if (dwarf1d_img && dwarf1l_img) {
2827         ML_(read_debuginfo_dwarf1) ( di, dwarf1d_img, dwarf1d_sz,
2828                                          dwarf1l_img, dwarf1l_sz );
2829      }
2830#endif
2831      /* TOPLEVEL */
2832
2833   } /* "Find interesting sections, read the symbol table(s), read any debug
2834        information" (a local scope) */
2835
2836   /* TOPLEVEL */
2837   res = True;
2838
2839   /* If reading Dwarf3 variable type/location info, print a line
2840      showing the number of variables read for each object.
2841      (Currently disabled -- is a sanity-check mechanism for
2842      exp-sgcheck.) */
2843   if (0 && (VG_(needs).var_info || VG_(clo_read_var_info))) {
2844      UWord nVars = 0;
2845      if (di->varinfo) {
2846         for (j = 0; j < VG_(sizeXA)(di->varinfo); j++) {
2847            OSet* /* of DiAddrRange */ scope
2848               = *(OSet**)VG_(indexXA)(di->varinfo, j);
2849            vg_assert(scope);
2850            VG_(OSetGen_ResetIter)( scope );
2851            while (True) {
2852               DiAddrRange* range  = VG_(OSetGen_Next)( scope );
2853               if (!range) break;
2854               vg_assert(range->vars);
2855               Word w = VG_(sizeXA)(range->vars);
2856               vg_assert(w >= 0);
2857               if (0) VG_(printf)("range %#lx %#lx %ld\n",
2858                                  range->aMin, range->aMax, w);
2859               nVars += (UWord)w;
2860            }
2861         }
2862      }
2863      VG_(umsg)("VARINFO: %7lu vars   %7ld text_size   %s\n",
2864                nVars, di->text_size, di->fsm.filename);
2865   }
2866   /* TOPLEVEL */
2867
2868  out:
2869   {
2870      /* Last, but not least, detach from the image(s). */
2871      if (mimg) ML_(img_done)(mimg);
2872      if (dimg) ML_(img_done)(dimg);
2873      if (aimg) ML_(img_done)(aimg);
2874
2875      if (svma_ranges) VG_(deleteXA)(svma_ranges);
2876
2877      return res;
2878   } /* out: */
2879
2880   /* NOTREACHED */
2881}
2882
2883#endif // defined(VGO_linux)
2884
2885/*--------------------------------------------------------------------*/
2886/*--- end                                                          ---*/
2887/*--------------------------------------------------------------------*/
2888