readelf.c revision 417d737cd710046f1c865b618f5f9b73b8969e45
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)( void* image, SizeT n_image, Bool rel_ok )
113{
114   ElfXX_Ehdr* ehdr = (ElfXX_Ehdr*)image;
115   Int ok = 1;
116
117   if (n_image < sizeof(ElfXX_Ehdr))
118      return False;
119
120   ok &= (ehdr->e_ident[EI_MAG0] == 0x7F
121          && ehdr->e_ident[EI_MAG1] == 'E'
122          && ehdr->e_ident[EI_MAG2] == 'L'
123          && ehdr->e_ident[EI_MAG3] == 'F');
124   ok &= (ehdr->e_ident[EI_CLASS] == VG_ELF_CLASS
125          && ehdr->e_ident[EI_DATA] == VG_ELF_DATA2XXX
126          && ehdr->e_ident[EI_VERSION] == EV_CURRENT);
127   ok &= (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN
128          || (rel_ok && ehdr->e_type == ET_REL));
129   ok &= (ehdr->e_machine == VG_ELF_MACHINE);
130   ok &= (ehdr->e_version == EV_CURRENT);
131   ok &= (ehdr->e_shstrndx != SHN_UNDEF);
132   ok &= (ehdr->e_shoff != 0 && ehdr->e_shnum != 0);
133   ok &= ((ehdr->e_phoff != 0 && ehdr->e_phnum != 0)
134          || ehdr->e_type == ET_REL);
135
136   return ok ? True : False;
137}
138
139
140/* The same thing, but operating on a DiImage instead. */
141
142static Bool is_elf_object_file_by_DiImage( DiImage* img, Bool rel_ok )
143{
144   /* Be sure this doesn't make the frame too big. */
145   vg_assert(sizeof(ElfXX_Ehdr) <= 512);
146
147   ElfXX_Ehdr ehdr;
148   if (!ML_(img_valid)(img, 0, sizeof(ehdr)))
149      return False;
150
151   ML_(img_get)(&ehdr, img, 0, sizeof(ehdr));
152   return ML_(is_elf_object_file)( &ehdr, sizeof(ehdr), rel_ok );
153}
154
155
156/* Show a raw ELF symbol, given its in-image address and name. */
157
158static
159void show_raw_elf_symbol ( DiImage* strtab_img,
160                           Int i,
161                           ElfXX_Sym* sym,
162                           DiOffT sym_name_ioff, Addr sym_svma,
163                           Bool ppc64_linux_format )
164{
165   const HChar* space = ppc64_linux_format ? "                  " : "";
166   VG_(printf)("raw symbol [%4d]: ", i);
167   switch (ELFXX_ST_BIND(sym->st_info)) {
168      case STB_LOCAL:  VG_(printf)("LOC "); break;
169      case STB_GLOBAL: VG_(printf)("GLO "); break;
170      case STB_WEAK:   VG_(printf)("WEA "); break;
171      case STB_LOPROC: VG_(printf)("lop "); break;
172      case STB_HIPROC: VG_(printf)("hip "); break;
173      default:         VG_(printf)("??? "); break;
174   }
175   switch (ELFXX_ST_TYPE(sym->st_info)) {
176      case STT_NOTYPE:  VG_(printf)("NOT "); break;
177      case STT_OBJECT:  VG_(printf)("OBJ "); break;
178      case STT_FUNC:    VG_(printf)("FUN "); break;
179      case STT_SECTION: VG_(printf)("SEC "); break;
180      case STT_FILE:    VG_(printf)("FIL "); break;
181      case STT_LOPROC:  VG_(printf)("lop "); break;
182      case STT_HIPROC:  VG_(printf)("hip "); break;
183      default:          VG_(printf)("??? "); break;
184   }
185   HChar* sym_name = NULL;
186   if (sym->st_name)
187      sym_name = ML_(img_strdup)(strtab_img, "di.sres.1", sym_name_ioff);
188   VG_(printf)(": svma %#010lx, %ssz %4ld  %s\n",
189               sym_svma, space, sym->st_size + 0UL,
190               (sym_name ? sym_name : "NONAME") );
191   if (sym_name)
192      ML_(dinfo_free)(sym_name);
193}
194
195
196/* Decide whether SYM is something we should collect, and if so, copy
197   relevant info to the _OUT arguments.  For {x86,amd64,ppc32}-linux
198   this is straightforward - the name, address, size are copied out
199   unchanged.
200
201   There is a bit of a kludge re data symbols (see KLUDGED BSS CHECK
202   below): we assume that the .bss is mapped immediately after .data,
203   and so accept any data symbol which exists in the range [start of
204   .data, size of .data + size of .bss).  I don't know if this is
205   really correct/justifiable, or not.
206
207   For 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        ElfXX_Sym* sym,        /* ELF symbol */
228        DiOffT     sym_name_ioff, /* name, may be absent (DiOffT_INVALID) */
229        DiSlice*   escn_strtab,   /* holds the name */
230        Addr       sym_svma,   /* address as stated in the object file */
231        Bool       symtab_in_debug, /* symbol table is in the debug file */
232        DiSlice*   escn_opd,   /* the .opd (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];
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                         (HChar*)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 ( TempSymKey* key1, 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];
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                     (HChar*)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( struct _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         struct _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      struct _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      struct _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                  struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, j);
1692                  if (   (map->rx || map->rw)
1693                      && a_phdr.p_offset >= map->foff
1694                      && a_phdr.p_offset <  map->foff + map->size
1695                      && a_phdr.p_offset + a_phdr.p_filesz
1696                         <= map->foff + map->size) {
1697                     RangeAndBias item;
1698                     item.svma_base  = a_phdr.p_vaddr;
1699                     item.svma_limit = a_phdr.p_vaddr + a_phdr.p_memsz;
1700                     item.bias       = map->avma - map->foff
1701                                       + a_phdr.p_offset - a_phdr.p_vaddr;
1702                     if (map->rw
1703                         && (a_phdr.p_flags & (PF_R | PF_W))
1704                            == (PF_R | PF_W)) {
1705                        item.exec = False;
1706                        VG_(addToXA)(svma_ranges, &item);
1707                        TRACE_SYMTAB("PT_LOAD[%ld]:   acquired as rw\n", i);
1708                        loaded = True;
1709                     }
1710                     if (map->rx
1711                         && (a_phdr.p_flags & (PF_R | PF_X))
1712                            == (PF_R | PF_X)) {
1713                        item.exec = True;
1714                        VG_(addToXA)(svma_ranges, &item);
1715                        TRACE_SYMTAB("PT_LOAD[%ld]:   acquired as rx\n", i);
1716                        loaded = True;
1717                     }
1718                  }
1719               }
1720               if (!loaded) {
1721                  ML_(symerr)(di, False,
1722                              "ELF section outside all mapped regions");
1723                  /* This problem might be solved by further memory mappings.
1724                     Avoid the vg_assert(!di->soname) at the beginning of this
1725                     function if DYNAMIC section has been already processed. */
1726                  if (di->soname) {
1727                     ML_(dinfo_free)(di->soname);
1728                     di->soname = NULL;
1729                  }
1730                  goto out;
1731               }
1732            }
1733         }
1734
1735         /* Try to get the soname.  If there isn't one, use "NONE".
1736            The seginfo needs to have some kind of soname in order to
1737            facilitate writing redirect functions, since all redirect
1738            specifications require a soname (pattern). */
1739         if (a_phdr.p_type == PT_DYNAMIC && di->soname == NULL) {
1740            Word   stroff       = -1;
1741            DiOffT strtab_mioff = DiOffT_INVALID;
1742            for (j = 0; True/*exit check is in the loop*/; j++) {
1743               ElfXX_Dyn t_dyn_m; /* dyn_img[j] */
1744               ML_(img_get)(&t_dyn_m, mimg,
1745                            INDEX_BIS(ehdr_mioff + a_phdr.p_offset,
1746                                      j, sizeof(ElfXX_Dyn)),
1747                            sizeof(t_dyn_m));
1748               if (t_dyn_m.d_tag == DT_NULL)
1749                  break;
1750
1751               switch (t_dyn_m.d_tag) {
1752                  case DT_SONAME: {
1753                     stroff = t_dyn_m.d_un.d_val;
1754                     break;
1755                  }
1756                  case DT_STRTAB: {
1757                     Bool ok2 = False;
1758                     Word offset = file_offset_from_svma(
1759                                      &ok2, t_dyn_m.d_un.d_ptr, mimg,
1760                                      phdr_mioff, phdr_mnent, phdr_ment_szB
1761                                   );
1762                     if (ok2 && strtab_mioff == DiOffT_INVALID) {
1763                        // Check for obviously bogus offsets.
1764                        if (!ML_(img_valid)(mimg, offset, 1)) {
1765                           ML_(symerr)(di, True, "Invalid DT_STRTAB offset");
1766                           goto out;
1767                        }
1768                        strtab_mioff = ehdr_mioff + offset;
1769                        vg_assert(ehdr_mioff == 0); // should always be
1770                     }
1771                     break;
1772                  }
1773                  default:
1774                     break;
1775               }
1776            }
1777            if (stroff != -1 && strtab_mioff != DiOffT_INVALID) {
1778               di->soname = ML_(img_strdup)(mimg, "di.redi.1",
1779                                            strtab_mioff + stroff);
1780               TRACE_SYMTAB("Found soname = %s\n", di->soname);
1781            }
1782         }
1783      } /* for (i = 0; i < phdr_Mnent; i++) ... */
1784      /* TOPLEVEL */
1785
1786   } /* examine the program headers (local scope) */
1787
1788   /* TOPLEVEL */
1789
1790   /* If, after looking at all the program headers, we still didn't
1791      find a soname, add a fake one. */
1792   if (di->soname == NULL) {
1793      TRACE_SYMTAB("No soname found; using (fake) \"NONE\"\n");
1794      di->soname = ML_(dinfo_strdup)("di.redi.2", "NONE");
1795   }
1796
1797   vg_assert(VG_(sizeXA)(svma_ranges) != 0);
1798
1799   /* Now read the section table. */
1800   TRACE_SYMTAB("\n");
1801   TRACE_SYMTAB("------ Examining the section headers ------\n");
1802   for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1803      struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
1804      if (map->rx)
1805         TRACE_SYMTAB("rx: at %#lx are mapped foffsets %ld .. %ld\n",
1806                      map->avma, map->foff, map->foff + map->size - 1 );
1807   }
1808   TRACE_SYMTAB("rx: contains these svma regions:\n");
1809   for (i = 0; i < VG_(sizeXA)(svma_ranges); i++) {
1810      RangeAndBias* reg = VG_(indexXA)(svma_ranges, i);
1811      if (reg->exec)
1812         TRACE_SYMTAB("  svmas %#lx .. %#lx with bias %#lx\n",
1813                      reg->svma_base, reg->svma_limit - 1, reg->bias );
1814   }
1815   for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1816      struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
1817      if (map->rw)
1818         TRACE_SYMTAB("rw: at %#lx are mapped foffsets %ld .. %ld\n",
1819                      map->avma, map->foff, map->foff + map->size - 1 );
1820   }
1821   TRACE_SYMTAB("rw: contains these svma regions:\n");
1822   for (i = 0; i < VG_(sizeXA)(svma_ranges); i++) {
1823      RangeAndBias* reg = VG_(indexXA)(svma_ranges, i);
1824      if (!reg->exec)
1825         TRACE_SYMTAB("  svmas %#lx .. %#lx with bias %#lx\n",
1826                      reg->svma_base, reg->svma_limit - 1, reg->bias );
1827   }
1828
1829   /* TOPLEVEL */
1830   /* Iterate over section headers */
1831   for (i = 0; i < shdr_mnent; i++) {
1832      ElfXX_Shdr a_shdr;
1833      ML_(img_get)(&a_shdr, mimg,
1834                   INDEX_BIS(shdr_mioff, i, shdr_ment_szB), sizeof(a_shdr));
1835      DiOffT name_mioff = shdr_strtab_mioff + a_shdr.sh_name;
1836      HChar* name = ML_(img_strdup)(mimg, "di.redi_name.1", name_mioff);
1837      Addr   svma = a_shdr.sh_addr;
1838      OffT   foff = a_shdr.sh_offset;
1839      UWord  size = a_shdr.sh_size; /* Do not change this to be signed. */
1840      UInt   alyn = a_shdr.sh_addralign;
1841      Bool   bits = !(a_shdr.sh_type == SHT_NOBITS);
1842      /* Look through our collection of info obtained from the PT_LOAD
1843         headers, and make 'inrx' and 'inrw' point to the first entry
1844         in each that intersects 'avma'.  If in each case none is found,
1845         leave the relevant pointer at NULL. */
1846      RangeAndBias* inrx = NULL;
1847      RangeAndBias* inrw = NULL;
1848      for (j = 0; j < VG_(sizeXA)(svma_ranges); j++) {
1849         RangeAndBias* rng = VG_(indexXA)(svma_ranges, j);
1850         if (svma >= rng->svma_base && svma < rng->svma_limit) {
1851            if (!inrx && rng->exec) {
1852               inrx = rng;
1853            } else if (!inrw && !rng->exec) {
1854               inrw = rng;
1855            }
1856            if (inrx && inrw)
1857               break;
1858         }
1859      }
1860
1861      TRACE_SYMTAB(" [sec %2ld]  %s %s  al%2u  foff %6ld .. %6ld  "
1862                   "  svma %p  name \"%s\"\n",
1863                   i, inrx ? "rx" : "  ", inrw ? "rw" : "  ", alyn,
1864                   foff, foff+size-1, (void*)svma, name);
1865
1866      /* Check for sane-sized segments.  SHT_NOBITS sections have zero
1867         size in the file. */
1868      if ((foff >= ML_(img_size)(mimg))
1869          || (foff + (bits ? size : 0) > ML_(img_size)(mimg))) {
1870         ML_(symerr)(di, True, "ELF Section extends beyond image end");
1871         goto out;
1872      }
1873
1874      /* Check for a sane alignment value. */
1875      if (alyn > 0 && -1 == VG_(log2)(alyn)) {
1876         ML_(symerr)(di, True, "ELF Section contains invalid "
1877                               ".sh_addralign value");
1878         goto out;
1879      }
1880
1881      /* Ignore zero sized sections. */
1882      if (size == 0) {
1883         TRACE_SYMTAB("zero sized section \"%s\", ignoring\n", name);
1884         ML_(dinfo_free)(name);
1885         continue;
1886      }
1887
1888#     define BAD(_secname)                                 \
1889         do { ML_(symerr)(di, True,                        \
1890                          "Can't make sense of " _secname  \
1891                          " section mapping");             \
1892              /* make sure we don't assert if we find */   \
1893              /* ourselves back in this routine later, */  \
1894              /* with the same di */                       \
1895              di->soname = NULL;                           \
1896              goto out;                                    \
1897         } while (0)
1898
1899      /* Find avma-s for: .text .data .sdata .rodata .bss .sbss .plt .got .opd
1900         and .eh_frame */
1901
1902      /* Accept .text where mapped as rx (code), even if zero-sized */
1903      if (0 == VG_(strcmp)(name, ".text")) {
1904         if (inrx && !di->text_present) {
1905            di->text_present = True;
1906            di->text_svma = svma;
1907            di->text_avma = svma + inrx->bias;
1908            di->text_size = size;
1909            di->text_bias = inrx->bias;
1910            di->text_debug_svma = svma;
1911            di->text_debug_bias = inrx->bias;
1912            TRACE_SYMTAB("acquiring .text svma = %#lx .. %#lx\n",
1913                         di->text_svma,
1914                         di->text_svma + di->text_size - 1);
1915            TRACE_SYMTAB("acquiring .text avma = %#lx .. %#lx\n",
1916                         di->text_avma,
1917                         di->text_avma + di->text_size - 1);
1918            TRACE_SYMTAB("acquiring .text bias = %#lx\n", di->text_bias);
1919         } else {
1920            BAD(".text");
1921         }
1922      }
1923
1924      /* Accept .data where mapped as rw (data), even if zero-sized */
1925      if (0 == VG_(strcmp)(name, ".data")) {
1926         if (inrw && !di->data_present) {
1927            di->data_present = True;
1928            di->data_svma = svma;
1929            di->data_avma = svma + inrw->bias;
1930            di->data_size = size;
1931            di->data_bias = inrw->bias;
1932            di->data_debug_svma = svma;
1933            di->data_debug_bias = inrw->bias;
1934            TRACE_SYMTAB("acquiring .data svma = %#lx .. %#lx\n",
1935                         di->data_svma,
1936                         di->data_svma + di->data_size - 1);
1937            TRACE_SYMTAB("acquiring .data avma = %#lx .. %#lx\n",
1938                         di->data_avma,
1939                         di->data_avma + di->data_size - 1);
1940            TRACE_SYMTAB("acquiring .data bias = %#lx\n", di->data_bias);
1941         } else {
1942            BAD(".data");
1943         }
1944      }
1945
1946      /* Accept .sdata where mapped as rw (data) */
1947      if (0 == VG_(strcmp)(name, ".sdata")) {
1948         if (inrw && !di->sdata_present) {
1949            di->sdata_present = True;
1950            di->sdata_svma = svma;
1951            di->sdata_avma = svma + inrw->bias;
1952            di->sdata_size = size;
1953            di->sdata_bias = inrw->bias;
1954            di->sdata_debug_svma = svma;
1955            di->sdata_debug_bias = inrw->bias;
1956            TRACE_SYMTAB("acquiring .sdata svma = %#lx .. %#lx\n",
1957                         di->sdata_svma,
1958                         di->sdata_svma + di->sdata_size - 1);
1959            TRACE_SYMTAB("acquiring .sdata avma = %#lx .. %#lx\n",
1960                         di->sdata_avma,
1961                         di->sdata_avma + di->sdata_size - 1);
1962            TRACE_SYMTAB("acquiring .sdata bias = %#lx\n", di->sdata_bias);
1963         } else {
1964            BAD(".sdata");
1965         }
1966      }
1967
1968      /* Accept .rodata where mapped as rx (data), even if zero-sized */
1969      if (0 == VG_(strcmp)(name, ".rodata")) {
1970         if (inrx && !di->rodata_present) {
1971            di->rodata_present = True;
1972            di->rodata_svma = svma;
1973            di->rodata_avma = svma + inrx->bias;
1974            di->rodata_size = size;
1975            di->rodata_bias = inrx->bias;
1976            di->rodata_debug_svma = svma;
1977            di->rodata_debug_bias = inrx->bias;
1978                                    /* NB was 'inrw' prior to r11794 */
1979            TRACE_SYMTAB("acquiring .rodata svma = %#lx .. %#lx\n",
1980                         di->rodata_svma,
1981                         di->rodata_svma + di->rodata_size - 1);
1982            TRACE_SYMTAB("acquiring .rodata avma = %#lx .. %#lx\n",
1983                         di->rodata_avma,
1984                         di->rodata_avma + di->rodata_size - 1);
1985            TRACE_SYMTAB("acquiring .rodata bias = %#lx\n", di->rodata_bias);
1986         } else {
1987            BAD(".rodata");
1988         }
1989      }
1990
1991      if (0 == VG_(strcmp)(name, ".dynbss")) {
1992         if (inrw && !di->bss_present) {
1993            dynbss_present = True;
1994            di->bss_present = True;
1995            di->bss_svma = svma;
1996            di->bss_avma = svma + inrw->bias;
1997            di->bss_size = size;
1998            di->bss_bias = inrw->bias;
1999            di->bss_debug_svma = svma;
2000            di->bss_debug_bias = inrw->bias;
2001            TRACE_SYMTAB("acquiring .dynbss svma = %#lx .. %#lx\n",
2002                         di->bss_svma,
2003                         di->bss_svma + di->bss_size - 1);
2004            TRACE_SYMTAB("acquiring .dynbss avma = %#lx .. %#lx\n",
2005                         di->bss_avma,
2006                         di->bss_avma + di->bss_size - 1);
2007            TRACE_SYMTAB("acquiring .dynbss bias = %#lx\n", di->bss_bias);
2008         }
2009      }
2010
2011      /* Accept .bss where mapped as rw (data), even if zero-sized */
2012      if (0 == VG_(strcmp)(name, ".bss")) {
2013         if (inrw && dynbss_present) {
2014            vg_assert(di->bss_present);
2015            dynbss_present = False;
2016            vg_assert(di->bss_svma + di->bss_size == svma);
2017            di->bss_size += size;
2018            TRACE_SYMTAB("acquiring .bss svma = %#lx .. %#lx\n",
2019                         svma, svma + size - 1);
2020            TRACE_SYMTAB("acquiring .bss avma = %#lx .. %#lx\n",
2021                         svma + inrw->bias, svma + inrw->bias + size - 1);
2022            TRACE_SYMTAB("acquiring .bss bias = %#lx\n", di->bss_bias);
2023         } else
2024
2025         if (inrw && !di->bss_present) {
2026            di->bss_present = True;
2027            di->bss_svma = svma;
2028            di->bss_avma = svma + inrw->bias;
2029            di->bss_size = size;
2030            di->bss_bias = inrw->bias;
2031            di->bss_debug_svma = svma;
2032            di->bss_debug_bias = inrw->bias;
2033            TRACE_SYMTAB("acquiring .bss svma = %#lx .. %#lx\n",
2034                         di->bss_svma,
2035                         di->bss_svma + di->bss_size - 1);
2036            TRACE_SYMTAB("acquiring .bss avma = %#lx .. %#lx\n",
2037                         di->bss_avma,
2038                         di->bss_avma + di->bss_size - 1);
2039            TRACE_SYMTAB("acquiring .bss bias = %#lx\n", di->bss_bias);
2040         } else
2041
2042         /* Now one from the wtf?! department ... */
2043         if (inrx && (!inrw) && !di->bss_present) {
2044            /* File contains a .bss, but it got mapped as rx only.
2045               This is very strange.  For now, just pretend we didn't
2046               see it :-) */
2047            di->bss_present = False;
2048            di->bss_svma = 0;
2049            di->bss_avma = 0;
2050            di->bss_size = 0;
2051            di->bss_bias = 0;
2052            di->bss_debug_svma = 0;
2053            di->bss_debug_bias = 0;
2054            if (!VG_(clo_xml)) {
2055               VG_(message)(Vg_UserMsg,
2056                            "Warning: the following file's .bss is "
2057                            "mapped r-x only - ignoring .bss syms\n");
2058               VG_(message)(Vg_UserMsg,   " %s\n", di->fsm.filename
2059                                                      ? di->fsm.filename
2060                                                      : "(null?!)" );
2061            }
2062         } else
2063
2064         if ((!inrw) && (!inrx) && !di->bss_present) {
2065            /* File contains a .bss, but it didn't get mapped.  Ignore. */
2066            di->bss_present = False;
2067            di->bss_svma = 0;
2068            di->bss_avma = 0;
2069            di->bss_size = 0;
2070            di->bss_bias = 0;
2071         } else {
2072            BAD(".bss");
2073         }
2074      }
2075
2076      if (0 == VG_(strcmp)(name, ".sdynbss")) {
2077         if (inrw && !di->sbss_present) {
2078            sdynbss_present = True;
2079            di->sbss_present = True;
2080            di->sbss_svma = svma;
2081            di->sbss_avma = svma + inrw->bias;
2082            di->sbss_size = size;
2083            di->sbss_bias = inrw->bias;
2084            di->sbss_debug_svma = svma;
2085            di->sbss_debug_bias = inrw->bias;
2086            TRACE_SYMTAB("acquiring .sdynbss svma = %#lx .. %#lx\n",
2087                         di->sbss_svma,
2088                         di->sbss_svma + di->sbss_size - 1);
2089            TRACE_SYMTAB("acquiring .sdynbss avma = %#lx .. %#lx\n",
2090                         di->sbss_avma,
2091                         di->sbss_avma + di->sbss_size - 1);
2092            TRACE_SYMTAB("acquiring .sdynbss bias = %#lx\n", di->sbss_bias);
2093         }
2094      }
2095
2096      /* Accept .sbss where mapped as rw (data) */
2097      if (0 == VG_(strcmp)(name, ".sbss")) {
2098         if (inrw && sdynbss_present) {
2099            vg_assert(di->sbss_present);
2100            sdynbss_present = False;
2101            vg_assert(di->sbss_svma + di->sbss_size == svma);
2102            di->sbss_size += size;
2103            TRACE_SYMTAB("acquiring .sbss svma = %#lx .. %#lx\n",
2104                         svma, svma + size - 1);
2105            TRACE_SYMTAB("acquiring .sbss avma = %#lx .. %#lx\n",
2106                         svma + inrw->bias, svma + inrw->bias + size - 1);
2107            TRACE_SYMTAB("acquiring .sbss bias = %#lx\n", di->sbss_bias);
2108         } else
2109
2110         if (inrw && !di->sbss_present) {
2111            di->sbss_present = True;
2112            di->sbss_svma = svma;
2113            di->sbss_avma = svma + inrw->bias;
2114            di->sbss_size = size;
2115            di->sbss_bias = inrw->bias;
2116            di->sbss_debug_svma = svma;
2117            di->sbss_debug_bias = inrw->bias;
2118            TRACE_SYMTAB("acquiring .sbss svma = %#lx .. %#lx\n",
2119                         di->sbss_svma,
2120                         di->sbss_svma + di->sbss_size - 1);
2121            TRACE_SYMTAB("acquiring .sbss avma = %#lx .. %#lx\n",
2122                         di->sbss_avma,
2123                         di->sbss_avma + di->sbss_size - 1);
2124            TRACE_SYMTAB("acquiring .sbss bias = %#lx\n", di->sbss_bias);
2125         } else {
2126            BAD(".sbss");
2127         }
2128      }
2129
2130      /* Accept .got where mapped as rw (data) */
2131      if (0 == VG_(strcmp)(name, ".got")) {
2132         if (inrw && !di->got_present) {
2133            di->got_present = True;
2134            di->got_avma = svma + inrw->bias;
2135            di->got_size = size;
2136            TRACE_SYMTAB("acquiring .got avma = %#lx\n", di->got_avma);
2137         } else {
2138            BAD(".got");
2139         }
2140      }
2141
2142      /* Accept .got.plt where mapped as rw (data) */
2143      if (0 == VG_(strcmp)(name, ".got.plt")) {
2144         if (inrw && !di->gotplt_present) {
2145            di->gotplt_present = True;
2146            di->gotplt_avma = svma + inrw->bias;
2147            di->gotplt_size = size;
2148            TRACE_SYMTAB("acquiring .got.plt avma = %#lx\n", di->gotplt_avma);
2149         } else if (size != 0) {
2150            BAD(".got.plt");
2151         }
2152      }
2153
2154      /* PLT is different on different platforms, it seems. */
2155#     if defined(VGP_x86_linux) || defined(VGP_amd64_linux) \
2156         || defined(VGP_arm_linux) || defined (VGP_s390x_linux) \
2157         || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
2158         || defined(VGP_arm64_linux)
2159      /* Accept .plt where mapped as rx (code) */
2160      if (0 == VG_(strcmp)(name, ".plt")) {
2161         if (inrx && !di->plt_present) {
2162            di->plt_present = True;
2163            di->plt_avma = svma + inrx->bias;
2164            di->plt_size = size;
2165            TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
2166         } else {
2167            BAD(".plt");
2168         }
2169      }
2170#     elif defined(VGP_ppc32_linux)
2171      /* Accept .plt where mapped as rw (data) */
2172      if (0 == VG_(strcmp)(name, ".plt")) {
2173         if (inrw && !di->plt_present) {
2174            di->plt_present = True;
2175            di->plt_avma = svma + inrw->bias;
2176            di->plt_size = size;
2177            TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
2178         } else {
2179            BAD(".plt");
2180         }
2181      }
2182#     elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
2183      /* Accept .plt where mapped as rw (data), or unmapped */
2184      if (0 == VG_(strcmp)(name, ".plt")) {
2185         if (inrw && !di->plt_present) {
2186            di->plt_present = True;
2187            di->plt_avma = svma + inrw->bias;
2188            di->plt_size = size;
2189            TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
2190         } else
2191         if ((!inrw) && (!inrx) && size > 0 && !di->plt_present) {
2192            /* File contains a .plt, but it didn't get mapped.
2193               Presumably it is not required on this platform.  At
2194               least don't reject the situation as invalid. */
2195            di->plt_present = True;
2196            di->plt_avma = 0;
2197            di->plt_size = 0;
2198         } else {
2199            BAD(".plt");
2200         }
2201      }
2202#     else
2203#       error "Unsupported platform"
2204#     endif
2205
2206      /* Accept .opd where mapped as rw (data) */
2207      if (0 == VG_(strcmp)(name, ".opd")) {
2208         if (inrw && !di->opd_present) {
2209            di->opd_present = True;
2210            di->opd_avma = svma + inrw->bias;
2211            di->opd_size = size;
2212            TRACE_SYMTAB("acquiring .opd avma = %#lx\n", di->opd_avma);
2213         } else {
2214            BAD(".opd");
2215         }
2216      }
2217
2218      /* Accept .eh_frame where mapped as rx (code).  This seems to be
2219         the common case.  However, if that doesn't pan out, try for
2220         rw (data) instead.  We can handle up to N_EHFRAME_SECTS per
2221         ELF object. */
2222      if (0 == VG_(strcmp)(name, ".eh_frame")) {
2223         if (inrx && di->n_ehframe < N_EHFRAME_SECTS) {
2224            di->ehframe_avma[di->n_ehframe] = svma + inrx->bias;
2225            di->ehframe_size[di->n_ehframe] = size;
2226            TRACE_SYMTAB("acquiring .eh_frame avma = %#lx\n",
2227                         di->ehframe_avma[di->n_ehframe]);
2228            di->n_ehframe++;
2229         } else
2230         if (inrw && di->n_ehframe < N_EHFRAME_SECTS) {
2231            di->ehframe_avma[di->n_ehframe] = svma + inrw->bias;
2232            di->ehframe_size[di->n_ehframe] = size;
2233            TRACE_SYMTAB("acquiring .eh_frame avma = %#lx\n",
2234                         di->ehframe_avma[di->n_ehframe]);
2235            di->n_ehframe++;
2236         } else {
2237            BAD(".eh_frame");
2238         }
2239      }
2240
2241      /* Accept .ARM.exidx where mapped as rx (code). */
2242      /* FIXME: make sure the entire section is mapped in, not just
2243         the first address. */
2244      if (0 == VG_(strcmp)(name, ".ARM.exidx")) {
2245         if (inrx && !di->exidx_present) {
2246            di->exidx_present = True;
2247            di->exidx_svma = svma;
2248            di->exidx_avma = svma + inrx->bias;
2249            di->exidx_size = size;
2250            di->exidx_bias = inrx->bias;
2251            TRACE_SYMTAB("acquiring .exidx svma = %#lx .. %#lx\n",
2252                         di->exidx_svma,
2253                         di->exidx_svma + di->exidx_size - 1);
2254            TRACE_SYMTAB("acquiring .exidx avma = %#lx .. %#lx\n",
2255                         di->exidx_avma,
2256                         di->exidx_avma + di->exidx_size - 1);
2257            TRACE_SYMTAB("acquiring .exidx bias = %#lx\n", di->exidx_bias);
2258         } else {
2259            BAD(".ARM.exidx");
2260         }
2261      }
2262
2263      /* Accept .ARM.extab where mapped as rx (code). */
2264      /* FIXME: make sure the entire section is mapped in, not just
2265         the first address. */
2266      if (0 == VG_(strcmp)(name, ".ARM.extab")) {
2267         if (inrx && !di->extab_present) {
2268            di->extab_present = True;
2269            di->extab_svma = svma;
2270            di->extab_avma = svma + inrx->bias;
2271            di->extab_size = size;
2272            di->extab_bias = inrx->bias;
2273            TRACE_SYMTAB("acquiring .extab svma = %#lx .. %#lx\n",
2274                         di->extab_svma,
2275                         di->extab_svma + di->extab_size - 1);
2276            TRACE_SYMTAB("acquiring .extab avma = %#lx .. %#lx\n",
2277                         di->extab_avma,
2278                         di->extab_avma + di->extab_size - 1);
2279            TRACE_SYMTAB("acquiring .extab bias = %#lx\n", di->extab_bias);
2280         } else {
2281            BAD(".ARM.extab");
2282         }
2283      }
2284
2285      ML_(dinfo_free)(name);
2286
2287#     undef BAD
2288
2289   } /* iterate over the section headers */
2290
2291   /* TOPLEVEL */
2292   if (0) VG_(printf)("YYYY text_: avma %#lx  size %ld  bias %#lx\n",
2293                      di->text_avma, di->text_size, di->text_bias);
2294
2295   if (VG_(clo_verbosity) > 2 || VG_(clo_trace_redir))
2296      VG_(message)(Vg_DebugMsg, "   svma %#010lx, avma %#010lx\n",
2297                                di->text_avma - di->text_bias,
2298                                di->text_avma );
2299
2300   TRACE_SYMTAB("\n");
2301   TRACE_SYMTAB("------ Finding image addresses "
2302                "for debug-info sections ------\n");
2303
2304   /* TOPLEVEL */
2305   /* Find interesting sections, read the symbol table(s), read any
2306      debug information.  Each section is located either in the main,
2307      debug or alt-debug files, but only in one.  For each section,
2308      |section_escn| records which of |mimg|, |dimg| or |aimg| we
2309      found it in, along with the section's image offset and its size.
2310      The triples (section_img, section_ioff, section_szB) are
2311      consistent, in that they are always either (NULL,
2312      DiOffT_INVALID, 0), or refer to the same image, and are all
2313      assigned together. */
2314   {
2315      /* TOPLEVEL */
2316      DiSlice strtab_escn         = DiSlice_INVALID; // .strtab
2317      DiSlice symtab_escn         = DiSlice_INVALID; // .symtab
2318      DiSlice dynstr_escn         = DiSlice_INVALID; // .dynstr
2319      DiSlice dynsym_escn         = DiSlice_INVALID; // .dynsym
2320      DiSlice debuglink_escn      = DiSlice_INVALID; // .gnu_debuglink
2321      DiSlice debugaltlink_escn   = DiSlice_INVALID; // .gnu_debugaltlink
2322      DiSlice debug_line_escn     = DiSlice_INVALID; // .debug_line   (dwarf2)
2323      DiSlice debug_info_escn     = DiSlice_INVALID; // .debug_info   (dwarf2)
2324      DiSlice debug_types_escn    = DiSlice_INVALID; // .debug_types  (dwarf4)
2325      DiSlice debug_abbv_escn     = DiSlice_INVALID; // .debug_abbrev (dwarf2)
2326      DiSlice debug_str_escn      = DiSlice_INVALID; // .debug_str    (dwarf2)
2327      DiSlice debug_ranges_escn   = DiSlice_INVALID; // .debug_ranges (dwarf2)
2328      DiSlice debug_loc_escn      = DiSlice_INVALID; // .debug_loc    (dwarf2)
2329      DiSlice debug_frame_escn    = DiSlice_INVALID; // .debug_frame  (dwarf2)
2330      DiSlice debug_line_alt_escn = DiSlice_INVALID; // .debug_line   (alt)
2331      DiSlice debug_info_alt_escn = DiSlice_INVALID; // .debug_info   (alt)
2332      DiSlice debug_abbv_alt_escn = DiSlice_INVALID; // .debug_abbrev (alt)
2333      DiSlice debug_str_alt_escn  = DiSlice_INVALID; // .debug_str    (alt)
2334      DiSlice dwarf1d_escn        = DiSlice_INVALID; // .debug        (dwarf1)
2335      DiSlice dwarf1l_escn        = DiSlice_INVALID; // .line         (dwarf1)
2336      DiSlice opd_escn            = DiSlice_INVALID; // .opd (dwarf2,
2337                                                     //       ppc64be-linux)
2338      DiSlice ehframe_escn[N_EHFRAME_SECTS];         // .eh_frame (dwarf2)
2339
2340      for (i = 0; i < N_EHFRAME_SECTS; i++)
2341         ehframe_escn[i] = DiSlice_INVALID;
2342
2343      /* Find all interesting sections */
2344
2345      UInt ehframe_mix = 0;
2346
2347      /* What FIND does: it finds the section called _SEC_NAME.  The
2348         size of it is assigned to _SEC_SIZE.  The address of the
2349         section in the transiently loaded oimage is assigned to
2350         _SEC_IMG.  If the section is found, _POST_FX is executed
2351         after _SEC_NAME and _SEC_SIZE have been assigned to.
2352
2353         Even for sections which are marked loadable, the client's
2354         ld.so may not have loaded them yet, so there is no guarantee
2355         that we can safely prod around in any such area).  Because
2356         the entire object file is transiently mapped aboard for
2357         inspection, it's always safe to inspect that area. */
2358
2359      /* TOPLEVEL */
2360      /* Iterate over section headers (again) */
2361      for (i = 0; i < ehdr_m.e_shnum; i++) {
2362
2363#        define FINDX(_sec_name, _sec_escn, _post_fx) \
2364         do { \
2365            ElfXX_Shdr a_shdr; \
2366            ML_(img_get)(&a_shdr, mimg, \
2367                         INDEX_BIS(shdr_mioff, i, shdr_ment_szB), \
2368                         sizeof(a_shdr)); \
2369            if (0 == ML_(img_strcmp_c)(mimg, shdr_strtab_mioff \
2370                                              + a_shdr.sh_name, _sec_name)) { \
2371               Bool nobits; \
2372               _sec_escn.img  = mimg; \
2373               _sec_escn.ioff = (DiOffT)a_shdr.sh_offset; \
2374               _sec_escn.szB  = a_shdr.sh_size; \
2375               nobits         = a_shdr.sh_type == SHT_NOBITS; \
2376               vg_assert(_sec_escn.img  != NULL); \
2377               vg_assert(_sec_escn.ioff != DiOffT_INVALID); \
2378               TRACE_SYMTAB( "%18s:  ioff %llu .. %llu\n", \
2379                             _sec_name, (ULong)_sec_escn.ioff, \
2380                             ((ULong)_sec_escn.ioff) + _sec_escn.szB - 1); \
2381               /* SHT_NOBITS sections have zero size in the file. */ \
2382               if ( a_shdr.sh_offset \
2383                    + (nobits ? 0 : _sec_escn.szB) > ML_(img_size)(mimg) ) { \
2384                  ML_(symerr)(di, True, \
2385                              "   section beyond image end?!"); \
2386                  goto out; \
2387               } \
2388               _post_fx; \
2389            } \
2390         } while (0);
2391
2392         /* Version with no post-effects */
2393#        define FIND(_sec_name, _sec_escn) \
2394            FINDX(_sec_name, _sec_escn, /**/)
2395
2396         /*   NAME                  ElfSec */
2397         FIND(".dynsym",            dynsym_escn)
2398         FIND(".dynstr",            dynstr_escn)
2399         FIND(".symtab",            symtab_escn)
2400         FIND(".strtab",            strtab_escn)
2401
2402         FIND(".gnu_debuglink",     debuglink_escn)
2403         FIND(".gnu_debugaltlink",  debugaltlink_escn)
2404
2405         FIND(".debug_line",        debug_line_escn)
2406         FIND(".debug_info",        debug_info_escn)
2407         FIND(".debug_types",       debug_types_escn)
2408         FIND(".debug_abbrev",      debug_abbv_escn)
2409         FIND(".debug_str",         debug_str_escn)
2410         FIND(".debug_ranges",      debug_ranges_escn)
2411         FIND(".debug_loc",         debug_loc_escn)
2412         FIND(".debug_frame",       debug_frame_escn)
2413
2414         FIND(".debug",             dwarf1d_escn)
2415         FIND(".line",              dwarf1l_escn)
2416
2417         FIND(".opd",               opd_escn)
2418
2419         FINDX(".eh_frame",         ehframe_escn[ehframe_mix],
2420               do { ehframe_mix++; vg_assert(ehframe_mix <= N_EHFRAME_SECTS);
2421               } while (0)
2422         )
2423         /* Comment_on_EH_FRAME_MULTIPLE_INSTANCES: w.r.t. .eh_frame
2424            multi-instance kludgery, how are we assured that the order
2425            in which we fill in ehframe_escn[] is consistent with the
2426            order in which we previously filled in di->ehframe_avma[]
2427            and di->ehframe_size[] ?  By the fact that in both cases,
2428            these arrays were filled in by iterating over the section
2429            headers top-to-bottom.  So both loops (this one and the
2430            previous one) encounter the .eh_frame entries in the same
2431            order and so fill in these arrays in a consistent order.
2432         */
2433
2434#        undef FINDX
2435#        undef FIND
2436      } /* Iterate over section headers (again) */
2437
2438      /* TOPLEVEL */
2439      /* Now, see if we can find a debuginfo object, and if so connect
2440         |dimg| to it. */
2441      vg_assert(dimg == NULL && aimg == NULL);
2442
2443      /* Look for a build-id */
2444      HChar* buildid = find_buildid(mimg, False, False);
2445
2446      /* Look for a debug image that matches either the build-id or
2447         the debuglink-CRC32 in the main image.  If the main image
2448         doesn't contain either of those then this won't even bother
2449         to try looking.  This looks in all known places, including
2450         the --extra-debuginfo-path if specified and on the
2451         --debuginfo-server if specified. */
2452      if (buildid != NULL || debuglink_escn.img != NULL) {
2453         /* Do have a debuglink section? */
2454         if (debuglink_escn.img != NULL) {
2455            UInt crc_offset
2456               = VG_ROUNDUP(ML_(img_strlen)(debuglink_escn.img,
2457                                            debuglink_escn.ioff)+1, 4);
2458            vg_assert(crc_offset + sizeof(UInt) <= debuglink_escn.szB);
2459
2460            /* Extract the CRC from the debuglink section */
2461            UInt crc = ML_(img_get_UInt)(debuglink_escn.img,
2462                                         debuglink_escn.ioff + crc_offset);
2463
2464            /* See if we can find a matching debug file */
2465            HChar* debuglink_str_m
2466               = ML_(img_strdup)(debuglink_escn.img,
2467                                 "di.redi_dlk.1", debuglink_escn.ioff);
2468            dimg = find_debug_file( di, di->fsm.filename, buildid,
2469                                    debuglink_str_m, crc, False );
2470            if (debuglink_str_m)
2471               ML_(dinfo_free)(debuglink_str_m);
2472         } else {
2473            /* See if we can find a matching debug file */
2474            dimg = find_debug_file( di, di->fsm.filename, buildid,
2475                                    NULL, 0, False );
2476         }
2477      }
2478
2479      if (buildid) {
2480         ML_(dinfo_free)(buildid);
2481         buildid = NULL; /* paranoia */
2482      }
2483
2484      /* As a last-ditch measure, try looking for in the
2485         --extra-debuginfo-path and/or on the --debuginfo-server, but
2486         only in the case where --allow-mismatched-debuginfo=yes.
2487         This is dangerous in that (1) it gives no assurance that the
2488         debuginfo object matches the main one, and hence (2) we will
2489         very likely get an assertion in the code below, if indeed
2490         there is a mismatch.  Hence it is disabled by default
2491         (--allow-mismatched-debuginfo=no).  Nevertheless it's
2492         sometimes a useful way of getting out of a tight spot.
2493
2494         Note that we're ignoring the name in the .gnu_debuglink
2495         section here, and just looking for a file of the same name
2496         either the extra-path or on the server. */
2497      if (dimg == NULL && VG_(clo_allow_mismatched_debuginfo)) {
2498         dimg = find_debug_file_ad_hoc( di, di->fsm.filename );
2499      }
2500
2501      /* TOPLEVEL */
2502      /* If we were successful in finding a debug image, pull various
2503         SVMA/bias/size and image addresses out of it. */
2504      if (dimg != NULL && is_elf_object_file_by_DiImage(dimg, False)) {
2505
2506         /* Pull out and validate program header and section header info */
2507         DiOffT      ehdr_dioff = 0;
2508         ElfXX_Ehdr  ehdr_dimg;
2509         ML_(img_get)(&ehdr_dimg, dimg, ehdr_dioff, sizeof(ehdr_dimg));
2510
2511         DiOffT   phdr_dioff        = ehdr_dimg.e_phoff;
2512         UWord    phdr_dnent        = ehdr_dimg.e_phnum;
2513         UWord    phdr_dent_szB     = ehdr_dimg.e_phentsize;
2514
2515         DiOffT   shdr_dioff        = ehdr_dimg.e_shoff;
2516         UWord    shdr_dnent        = ehdr_dimg.e_shnum;
2517         UWord    shdr_dent_szB     = ehdr_dimg.e_shentsize;
2518
2519         DiOffT   shdr_strtab_dioff = DiOffT_INVALID;
2520
2521         /* SVMAs covered by rx and rw segments and corresponding bias. */
2522         Addr     rx_dsvma_limit = 0;
2523         PtrdiffT rx_dbias = 0;
2524         Addr     rw_dsvma_limit = 0;
2525         PtrdiffT rw_dbias = 0;
2526
2527         Bool need_symtab, need_dwarf2, need_dwarf1;
2528
2529         if (phdr_dnent == 0
2530             || !ML_(img_valid)(dimg, phdr_dioff,
2531                                phdr_dnent * phdr_dent_szB)) {
2532            ML_(symerr)(di, True,
2533                        "Missing or invalid ELF Program Header Table"
2534                        " (debuginfo file)");
2535            goto out;
2536         }
2537
2538         if (shdr_dnent == 0
2539             || !ML_(img_valid)(dimg, shdr_dioff,
2540                                shdr_dnent * shdr_dent_szB)) {
2541            ML_(symerr)(di, True,
2542                        "Missing or invalid ELF Section Header Table"
2543                        " (debuginfo file)");
2544            goto out;
2545         }
2546
2547         /* Also find the section header's string table, and validate. */
2548         /* checked previously by is_elf_object_file: */
2549         vg_assert(ehdr_dimg.e_shstrndx != SHN_UNDEF);
2550
2551         // shdr_dioff is the offset of the section header table
2552         // and we need the ehdr_dimg.e_shstrndx'th entry
2553         { ElfXX_Shdr a_shdr;
2554           ML_(img_get)(&a_shdr, dimg,
2555                        INDEX_BIS(shdr_dioff, ehdr_dimg.e_shstrndx,
2556                                              shdr_dent_szB),
2557                        sizeof(a_shdr));
2558           shdr_strtab_dioff = a_shdr.sh_offset;
2559           if (!ML_(img_valid)(dimg, shdr_strtab_dioff,
2560                               1/*bogus, but we don't know the real size*/)) {
2561              ML_(symerr)(di, True,
2562                          "Invalid ELF Section Header String Table"
2563                          " (debuginfo file)");
2564              goto out;
2565           }
2566         }
2567
2568         for (i = 0; i < ehdr_dimg.e_phnum; i++) {
2569            ElfXX_Phdr a_phdr;
2570            ML_(img_get)(&a_phdr, dimg, INDEX_BIS(ehdr_dimg.e_phoff,
2571                                                  i, phdr_dent_szB),
2572                           sizeof(a_phdr));
2573            if (a_phdr.p_type == PT_LOAD) {
2574               for (j = 0; j < VG_(sizeXA)(di->fsm.maps); j++) {
2575                  struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, j);
2576                  if (   a_phdr.p_offset >= map->foff
2577                      && a_phdr.p_offset <  map->foff + map->size
2578                      && a_phdr.p_offset + a_phdr.p_filesz
2579                         < map->foff + map->size) {
2580                     if (map->rx && rx_dsvma_limit == 0) {
2581                        rx_dsvma_limit = a_phdr.p_vaddr + a_phdr.p_memsz;
2582                        rx_dbias = map->avma - map->foff + a_phdr.p_offset
2583                                   - a_phdr.p_vaddr;
2584                     }
2585                     if (map->rw && rw_dsvma_limit == 0) {
2586                        rw_dsvma_limit = a_phdr.p_vaddr + a_phdr.p_memsz;
2587                        rw_dbias = map->avma - map->foff + a_phdr.p_offset
2588                                   - a_phdr.p_vaddr;
2589                     }
2590                     break;
2591                  }
2592               }
2593            }
2594         }
2595
2596         need_symtab = (symtab_escn.img == NULL);
2597         need_dwarf2 = (debug_info_escn.img == NULL);
2598         need_dwarf1 = (dwarf1d_escn.img == NULL);
2599
2600         /* Find all interesting sections in the debug image */
2601         for (i = 0; i < ehdr_dimg.e_shnum; i++) {
2602
2603            /* Find debug svma and bias information for sections
2604               we found in the main file. */
2605
2606#           define FIND(_sec, _seg) \
2607            do { \
2608               ElfXX_Shdr a_shdr; \
2609               ML_(img_get)(&a_shdr, dimg, \
2610                            INDEX_BIS(shdr_dioff, i, shdr_dent_szB), \
2611                            sizeof(a_shdr)); \
2612               if (di->_sec##_present \
2613                   && 0 == ML_(img_strcmp_c)(dimg, shdr_strtab_dioff \
2614                                             + a_shdr.sh_name, "." #_sec)) { \
2615                  vg_assert(di->_sec##_size == a_shdr.sh_size); \
2616                  /* JRS 2013-Jun-01: the following assert doesn't contain */ \
2617                  /* any ==s, which seems to me to be suspicious. */ \
2618                  vg_assert(di->_sec##_avma +  a_shdr.sh_addr + _seg##_dbias); \
2619                  /* Assume we have a correct value for the main */ \
2620                  /* object's bias.  Use that to derive the debuginfo */ \
2621                  /* object's bias, by adding the difference in SVMAs */ \
2622                  /* for the corresponding sections in the two files. */ \
2623                  /* That should take care of all prelinking effects. */ \
2624                  di->_sec##_debug_svma = a_shdr.sh_addr; \
2625                  di->_sec##_debug_bias \
2626                     = di->_sec##_bias + \
2627                       di->_sec##_svma - di->_sec##_debug_svma; \
2628                  TRACE_SYMTAB("acquiring ." #_sec \
2629                               " debug svma = %#lx .. %#lx\n",       \
2630                               di->_sec##_debug_svma, \
2631                               di->_sec##_debug_svma + di->_sec##_size - 1); \
2632                  TRACE_SYMTAB("acquiring ." #_sec " debug bias = %#lx\n", \
2633                               di->_sec##_debug_bias); \
2634               } \
2635            } while (0);
2636
2637            /* SECTION   SEGMENT */
2638            FIND(text,   rx)
2639            FIND(data,   rw)
2640            FIND(sdata,  rw)
2641            FIND(rodata, rw)
2642            FIND(bss,    rw)
2643            FIND(sbss,   rw)
2644
2645#           undef FIND
2646
2647            /* Same deal as previous FIND, except only do it for those
2648               sections which we didn't find in the main file. */
2649
2650#           define FIND(_condition, _sec_name, _sec_escn) \
2651            do { \
2652               ElfXX_Shdr a_shdr; \
2653               ML_(img_get)(&a_shdr, dimg, \
2654                            INDEX_BIS(shdr_dioff, i, shdr_dent_szB), \
2655                            sizeof(a_shdr)); \
2656               if (_condition \
2657                   && 0 == ML_(img_strcmp_c)(dimg, shdr_strtab_dioff \
2658                                             + a_shdr.sh_name, _sec_name)) { \
2659                  Bool nobits; \
2660                  if (_sec_escn.img != NULL) { \
2661                     ML_(symerr)(di, True, \
2662                                 "   debuginfo section duplicates a" \
2663                                 " section in the main ELF file"); \
2664                     goto out; \
2665                  } \
2666                  _sec_escn.img  = dimg; \
2667                  _sec_escn.ioff = (DiOffT)a_shdr.sh_offset;  \
2668                  _sec_escn.szB  = a_shdr.sh_size; \
2669                  nobits         = a_shdr.sh_type == SHT_NOBITS; \
2670                  vg_assert(_sec_escn.img  != NULL); \
2671                  vg_assert(_sec_escn.ioff != DiOffT_INVALID); \
2672                  TRACE_SYMTAB( "%18s: dioff %llu .. %llu\n", \
2673                                _sec_name, \
2674                                (ULong)_sec_escn.ioff, \
2675                                ((ULong)_sec_escn.ioff) + _sec_escn.szB - 1); \
2676                  /* SHT_NOBITS sections have zero size in the file. */ \
2677                  if (a_shdr.sh_offset \
2678                      + (nobits ? 0 : _sec_escn.szB) > ML_(img_size)(dimg)) { \
2679                     ML_(symerr)(di, True, \
2680                                 "   section beyond image end?!"); \
2681                     goto out; \
2682                  } \
2683               } \
2684            } while (0);
2685
2686            /* NEEDED?        NAME             ElfSec */
2687            FIND(need_symtab, ".symtab",       symtab_escn)
2688            FIND(need_symtab, ".strtab",       strtab_escn)
2689            FIND(need_dwarf2, ".debug_line",   debug_line_escn)
2690            FIND(need_dwarf2, ".debug_info",   debug_info_escn)
2691            FIND(need_dwarf2, ".debug_types",  debug_types_escn)
2692
2693            FIND(need_dwarf2, ".debug_abbrev", debug_abbv_escn)
2694            FIND(need_dwarf2, ".debug_str",    debug_str_escn)
2695            FIND(need_dwarf2, ".debug_ranges", debug_ranges_escn)
2696
2697            FIND(need_dwarf2, ".debug_loc",    debug_loc_escn)
2698            FIND(need_dwarf2, ".debug_frame",  debug_frame_escn)
2699
2700            FIND(need_dwarf2, ".gnu_debugaltlink", debugaltlink_escn)
2701
2702            FIND(need_dwarf1, ".debug",        dwarf1d_escn)
2703            FIND(need_dwarf1, ".line",         dwarf1l_escn)
2704
2705#           undef FIND
2706         } /* Find all interesting sections */
2707      } /* do we have a debug image? */
2708
2709      /* TOPLEVEL */
2710      /* Look for alternate debug image, and if found, connect |aimg|
2711         to it. */
2712      vg_assert(aimg == NULL);
2713
2714      if (debugaltlink_escn.img != NULL) {
2715         HChar* altfile_str_m
2716             = ML_(img_strdup)(debugaltlink_escn.img,
2717                               "di.fbi.3", debugaltlink_escn.ioff);
2718         UInt buildid_offset = ML_(img_strlen)(debugaltlink_escn.img,
2719                                               debugaltlink_escn.ioff)+1;
2720
2721         vg_assert(buildid_offset < debugaltlink_escn.szB);
2722
2723         HChar *altbuildid
2724            = ML_(dinfo_zalloc)("di.fbi.4",
2725                                (debugaltlink_escn.szB - buildid_offset)
2726                                * 2 + 1);
2727
2728         /* The altfile might be relative to the debug file or main file. */
2729         HChar *dbgname = di->fsm.dbgname ? di->fsm.dbgname : di->fsm.filename;
2730
2731         for (j = 0; j < debugaltlink_escn.szB - buildid_offset; j++)
2732            VG_(sprintf)(
2733               altbuildid + 2 * j, "%02x",
2734               (UInt)ML_(img_get_UChar)(debugaltlink_escn.img,
2735                                        debugaltlink_escn.ioff
2736                                        + buildid_offset + j));
2737
2738         /* See if we can find a matching debug file */
2739         aimg = find_debug_file( di, dbgname, altbuildid,
2740                                 altfile_str_m, 0, True );
2741
2742         if (altfile_str_m)
2743            ML_(dinfo_free)(altfile_str_m);
2744         ML_(dinfo_free)(altbuildid);
2745      }
2746
2747      /* TOPLEVEL */
2748      /* If we were successful in finding alternate debug image, pull various
2749         size and image addresses out of it. */
2750      if (aimg != NULL && is_elf_object_file_by_DiImage(aimg, True)) {
2751
2752         /* Pull out and validate program header and section header info */
2753         DiOffT      ehdr_aioff = 0;
2754         ElfXX_Ehdr  ehdr_aimg;
2755         ML_(img_get)(&ehdr_aimg, aimg, ehdr_aioff, sizeof(ehdr_aimg));
2756
2757         DiOffT   shdr_aioff        = ehdr_aimg.e_shoff;
2758         UWord    shdr_anent        = ehdr_aimg.e_shnum;
2759         UWord    shdr_aent_szB     = ehdr_aimg.e_shentsize;
2760
2761         DiOffT   shdr_strtab_aioff = DiOffT_INVALID;
2762
2763         if (shdr_anent == 0
2764             || !ML_(img_valid)(aimg, shdr_aioff,
2765                                shdr_anent * shdr_aent_szB)) {
2766            ML_(symerr)(di, True,
2767                        "Missing or invalid ELF Section Header Table"
2768                        " (alternate debuginfo file)");
2769            goto out;
2770         }
2771
2772         /* Also find the section header's string table, and validate. */
2773         /* checked previously by is_elf_object_file: */
2774         vg_assert(ehdr_aimg.e_shstrndx != SHN_UNDEF);
2775
2776         // shdr_aioff is the offset of the section header table
2777         // and we need the ehdr_aimg.e_shstrndx'th entry
2778         { ElfXX_Shdr a_shdr;
2779           ML_(img_get)(&a_shdr, aimg,
2780                        INDEX_BIS(shdr_aioff, ehdr_aimg.e_shstrndx,
2781                                              shdr_aent_szB),
2782                        sizeof(a_shdr));
2783           shdr_strtab_aioff = a_shdr.sh_offset;
2784           if (!ML_(img_valid)(aimg, shdr_strtab_aioff,
2785                               1/*bogus, but we don't know the real size*/)) {
2786              ML_(symerr)(di, True,
2787                          "Invalid ELF Section Header String Table"
2788                          " (alternate debuginfo file)");
2789              goto out;
2790           }
2791         }
2792
2793         /* Find all interesting sections */
2794         for (i = 0; i < ehdr_aimg.e_shnum; i++) {
2795
2796#           define FIND(_sec_name, _sec_escn) \
2797            do { \
2798               ElfXX_Shdr a_shdr; \
2799               ML_(img_get)(&a_shdr, aimg, \
2800                            INDEX_BIS(shdr_aioff, i, shdr_aent_szB), \
2801                            sizeof(a_shdr)); \
2802               if (0 == ML_(img_strcmp_c)(aimg, shdr_strtab_aioff \
2803                                          + a_shdr.sh_name, _sec_name)) { \
2804                  if (_sec_escn.img != NULL) { \
2805                     ML_(symerr)(di, True, \
2806                                 "   alternate debuginfo section duplicates a" \
2807                                 " section in the main ELF file"); \
2808                     goto out; \
2809                  } \
2810                  _sec_escn.img  = aimg; \
2811                  _sec_escn.ioff = (DiOffT)a_shdr.sh_offset; \
2812                  _sec_escn.szB  = a_shdr.sh_size; \
2813                  vg_assert(_sec_escn.img  != NULL); \
2814                  vg_assert(_sec_escn.ioff != DiOffT_INVALID); \
2815                  TRACE_SYMTAB( "%18s: aioff %llu .. %llu\n", \
2816                                _sec_name, \
2817                                (ULong)_sec_escn.ioff, \
2818                                ((ULong)_sec_escn.ioff) + _sec_escn.szB - 1); \
2819               } \
2820            } while (0);
2821
2822            /*   NAME             ElfSec */
2823            FIND(".debug_line",   debug_line_alt_escn)
2824            FIND(".debug_info",   debug_info_alt_escn)
2825            FIND(".debug_abbrev", debug_abbv_alt_escn)
2826            FIND(".debug_str",    debug_str_alt_escn)
2827
2828#           undef FIND
2829         } /* Find all interesting sections */
2830      } /* do we have a debug image? */
2831
2832
2833      /* TOPLEVEL */
2834      /* Check some sizes */
2835      vg_assert((dynsym_escn.szB % sizeof(ElfXX_Sym)) == 0);
2836      vg_assert((symtab_escn.szB % sizeof(ElfXX_Sym)) == 0);
2837
2838      /* TOPLEVEL */
2839      /* Read symbols */
2840      {
2841         void (*read_elf_symtab)(struct _DebugInfo*, const HChar*,
2842                                 DiSlice*, DiSlice*, DiSlice*, Bool);
2843         Bool symtab_in_debug;
2844#        if defined(VGP_ppc64be_linux)
2845         read_elf_symtab = read_elf_symtab__ppc64be_linux;
2846#        else
2847         read_elf_symtab = read_elf_symtab__normal;
2848#        endif
2849         symtab_in_debug = symtab_escn.img == dimg;
2850         read_elf_symtab(di, "symbol table",
2851                         &symtab_escn, &strtab_escn, &opd_escn,
2852                         symtab_in_debug);
2853         read_elf_symtab(di, "dynamic symbol table",
2854                         &dynsym_escn, &dynstr_escn, &opd_escn,
2855                         False);
2856      }
2857
2858      /* TOPLEVEL */
2859      /* Read .eh_frame and .debug_frame (call-frame-info) if any.  Do
2860         the .eh_frame section(s) first. */
2861      vg_assert(di->n_ehframe >= 0 && di->n_ehframe <= N_EHFRAME_SECTS);
2862      for (i = 0; i < di->n_ehframe; i++) {
2863         /* see Comment_on_EH_FRAME_MULTIPLE_INSTANCES above for why
2864            this next assertion should hold. */
2865         vg_assert(ML_(sli_is_valid)(ehframe_escn[i]));
2866         vg_assert(ehframe_escn[i].szB == di->ehframe_size[i]);
2867         ML_(read_callframe_info_dwarf3)( di,
2868                                          ehframe_escn[i],
2869                                          di->ehframe_avma[i],
2870                                          True/*is_ehframe*/ );
2871      }
2872      if (ML_(sli_is_valid)(debug_frame_escn)) {
2873         ML_(read_callframe_info_dwarf3)( di,
2874                                          debug_frame_escn,
2875                                          0/*assume zero avma*/,
2876                                          False/*!is_ehframe*/ );
2877      }
2878
2879      /* TOPLEVEL */
2880      /* jrs 2006-01-01: icc-8.1 has been observed to generate
2881         binaries without debug_str sections.  Don't preclude
2882         debuginfo reading for that reason, but, in
2883         read_unitinfo_dwarf2, do check that debugstr is non-NULL
2884         before using it. */
2885      if (ML_(sli_is_valid)(debug_info_escn)
2886          && ML_(sli_is_valid)(debug_abbv_escn)
2887          && ML_(sli_is_valid)(debug_line_escn)) {
2888         /* The old reader: line numbers and unwind info only */
2889         ML_(read_debuginfo_dwarf3) ( di,
2890                                      debug_info_escn,
2891                                      debug_types_escn,
2892                                      debug_abbv_escn,
2893                                      debug_line_escn,
2894                                      debug_str_escn,
2895                                      debug_str_alt_escn );
2896         /* The new reader: read the DIEs in .debug_info to acquire
2897            information on variable types and locations or inline info.
2898            But only if the tool asks for it, or the user requests it on
2899            the command line. */
2900         if (VG_(clo_read_var_info) /* the user or tool asked for it */
2901             || VG_(clo_read_inline_info)) {
2902            ML_(new_dwarf3_reader)(
2903               di, debug_info_escn,     debug_types_escn,
2904                   debug_abbv_escn,     debug_line_escn,
2905                   debug_str_escn,      debug_ranges_escn,
2906                   debug_loc_escn,      debug_info_alt_escn,
2907                   debug_abbv_alt_escn, debug_line_alt_escn,
2908                   debug_str_alt_escn
2909            );
2910         }
2911      }
2912
2913      /* TOPLEVEL */
2914      // JRS 31 July 2014: dwarf-1 reading is currently broken and
2915      // therefore deactivated.
2916      //if (dwarf1d_img && dwarf1l_img) {
2917      //   ML_(read_debuginfo_dwarf1) ( di, dwarf1d_img, dwarf1d_sz,
2918      //                                    dwarf1l_img, dwarf1l_sz );
2919      //}
2920
2921#     if defined(VGA_arm)
2922      /* TOPLEVEL */
2923      /* ARM32 only: read .exidx/.extab if present.  Note we are
2924         reading these directly out of the mapped in (running) image.
2925         Also, read these only if no CFI based unwind info was
2926         acquired for this file.
2927
2928         An .exidx section is always required, but the .extab section
2929         can be optionally omitted, provided that .exidx does not
2930         refer to it.  If the .exidx is erroneous and does refer to
2931         .extab even though .extab is missing, the range checks done
2932         by GET_EX_U32 in ExtabEntryExtract in readexidx.c should
2933         prevent any invalid memory accesses, and cause the .extab to
2934         be rejected as invalid.
2935
2936         FIXME:
2937         * check with m_aspacemgr that the entire [exidx_avma, +exidx_size)
2938           and [extab_avma, +extab_size) areas are readable, since we're
2939           reading this stuff out of the running image (not from a file/socket)
2940           and we don't want to segfault.
2941         * DebugInfo::exidx_bias and use text_bias instead.
2942           I think it's always the same.
2943         * remove DebugInfo::{extab_bias, exidx_svma, extab_svma} since
2944           they are never used.
2945      */
2946      if (di->exidx_present
2947          && di->cfsi_used == 0
2948          && di->text_present && di->text_size > 0) {
2949         Addr text_last_svma = di->text_svma + di->text_size - 1;
2950         ML_(read_exidx)( di, (UChar*)di->exidx_avma, di->exidx_size,
2951                              (UChar*)di->extab_avma, di->extab_size,
2952                              text_last_svma,
2953                              di->exidx_bias );
2954      }
2955#     endif /* defined(VGA_arm) */
2956
2957   } /* "Find interesting sections, read the symbol table(s), read any debug
2958        information" (a local scope) */
2959
2960   /* TOPLEVEL */
2961   res = True;
2962
2963   /* If reading Dwarf3 variable type/location info, print a line
2964      showing the number of variables read for each object.
2965      (Currently disabled -- is a sanity-check mechanism for
2966      exp-sgcheck.) */
2967   if (0 &&  VG_(clo_read_var_info)) {
2968      UWord nVars = 0;
2969      if (di->varinfo) {
2970         for (j = 0; j < VG_(sizeXA)(di->varinfo); j++) {
2971            OSet* /* of DiAddrRange */ scope
2972               = *(OSet**)VG_(indexXA)(di->varinfo, j);
2973            vg_assert(scope);
2974            VG_(OSetGen_ResetIter)( scope );
2975            while (True) {
2976               DiAddrRange* range  = VG_(OSetGen_Next)( scope );
2977               if (!range) break;
2978               vg_assert(range->vars);
2979               Word w = VG_(sizeXA)(range->vars);
2980               vg_assert(w >= 0);
2981               if (0) VG_(printf)("range %#lx %#lx %ld\n",
2982                                  range->aMin, range->aMax, w);
2983               nVars += (UWord)w;
2984            }
2985         }
2986      }
2987      VG_(umsg)("VARINFO: %7lu vars   %7ld text_size   %s\n",
2988                nVars, di->text_size, di->fsm.filename);
2989   }
2990   /* TOPLEVEL */
2991
2992  out:
2993   {
2994      /* Last, but not least, detach from the image(s). */
2995      if (mimg) ML_(img_done)(mimg);
2996      if (dimg) ML_(img_done)(dimg);
2997      if (aimg) ML_(img_done)(aimg);
2998
2999      if (svma_ranges) VG_(deleteXA)(svma_ranges);
3000
3001      return res;
3002   } /* out: */
3003
3004   /* NOTREACHED */
3005}
3006
3007#endif // defined(VGO_linux)
3008
3009/*--------------------------------------------------------------------*/
3010/*--- end                                                          ---*/
3011/*--------------------------------------------------------------------*/
3012