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