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