readelf.c revision f1e1aa691d7a2f0f2f933daf060bec5ae6938705
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-2011 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_libcfile.h"
41#include "pub_core_aspacemgr.h"    /* for mmaping debuginfo files */
42#include "pub_core_machine.h"      /* VG_ELF_CLASS */
43#include "pub_core_options.h"
44#include "pub_core_oset.h"
45#include "pub_core_tooliface.h"    /* VG_(needs) */
46#include "pub_core_xarray.h"
47#include "priv_misc.h"             /* dinfo_zalloc/free/strdup */
48#include "priv_d3basics.h"
49#include "priv_tytypes.h"
50#include "priv_storage.h"
51#include "priv_readelf.h"          /* self */
52#include "priv_readdwarf.h"        /* 'cos ELF contains DWARF */
53#include "priv_readdwarf3.h"
54#include "priv_readstabs.h"        /* and stabs, if we're unlucky */
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
111/* Identify an ELF object file by peering at the first few bytes of
112   it. */
113
114Bool ML_(is_elf_object_file)( void* image, SizeT n_image )
115{
116   ElfXX_Ehdr* ehdr = (ElfXX_Ehdr*)image;
117   Int ok = 1;
118
119   if (n_image < sizeof(ElfXX_Ehdr))
120      return False;
121
122   ok &= (ehdr->e_ident[EI_MAG0] == 0x7F
123          && ehdr->e_ident[EI_MAG1] == 'E'
124          && ehdr->e_ident[EI_MAG2] == 'L'
125          && ehdr->e_ident[EI_MAG3] == 'F');
126   ok &= (ehdr->e_ident[EI_CLASS] == VG_ELF_CLASS
127          && ehdr->e_ident[EI_DATA] == VG_ELF_DATA2XXX
128          && ehdr->e_ident[EI_VERSION] == EV_CURRENT);
129   ok &= (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN);
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
136   if (ok)
137      return True;
138   else
139      return False;
140}
141
142
143/* Show a raw ELF symbol, given its in-image address and name. */
144
145static
146void show_raw_elf_symbol ( Int i,
147                           ElfXX_Sym* sym, Char* sym_name, Addr sym_svma,
148                           Bool ppc64_linux_format )
149{
150   HChar* space = ppc64_linux_format ? "                  " : "";
151   VG_(printf)("raw symbol [%4d]: ", i);
152   switch (ELFXX_ST_BIND(sym->st_info)) {
153      case STB_LOCAL:  VG_(printf)("LOC "); break;
154      case STB_GLOBAL: VG_(printf)("GLO "); break;
155      case STB_WEAK:   VG_(printf)("WEA "); break;
156      case STB_LOPROC: VG_(printf)("lop "); break;
157      case STB_HIPROC: VG_(printf)("hip "); break;
158      default:         VG_(printf)("??? "); break;
159   }
160   switch (ELFXX_ST_TYPE(sym->st_info)) {
161      case STT_NOTYPE:  VG_(printf)("NOT "); break;
162      case STT_OBJECT:  VG_(printf)("OBJ "); break;
163      case STT_FUNC:    VG_(printf)("FUN "); break;
164      case STT_SECTION: VG_(printf)("SEC "); break;
165      case STT_FILE:    VG_(printf)("FIL "); break;
166      case STT_LOPROC:  VG_(printf)("lop "); break;
167      case STT_HIPROC:  VG_(printf)("hip "); break;
168      default:          VG_(printf)("??? "); break;
169   }
170   VG_(printf)(": svma %#010lx, %ssz %4ld  %s\n",
171               sym_svma, space, sym->st_size + 0UL,
172               ( sym->st_name ? sym_name : (Char*)"NONAME" ) );
173}
174
175
176/* Decide whether SYM is something we should collect, and if so, copy
177   relevant info to the _OUT arguments.  For {x86,amd64,ppc32}-linux
178   this is straightforward - the name, address, size are copied out
179   unchanged.
180
181   There is a bit of a kludge re data symbols (see KLUDGED BSS CHECK
182   below): we assume that the .bss is mapped immediately after .data,
183   and so accept any data symbol which exists in the range [start of
184   .data, size of .data + size of .bss).  I don't know if this is
185   really correct/justifiable, or not.
186
187   For ppc64-linux it's more complex.  If the symbol is seen to be in
188   the .opd section, it is taken to be a function descriptor, and so
189   a dereference is attempted, in order to get hold of the real entry
190   point address.  Also as part of the dereference, there is an attempt
191   to calculate the TOC pointer (R2 value) associated with the symbol.
192
193   To support the ppc64-linux pre-"dotless" ABI (prior to gcc 4.0.0),
194   if the symbol is seen to be outside the .opd section and its name
195   starts with a dot, an .opd deference is not attempted, and no TOC
196   pointer is calculated, but the the leading dot is removed from the
197   name.
198
199   As a result, on ppc64-linux, the caller of this function may have
200   to piece together the real size, address, name of the symbol from
201   multiple calls to this function.  Ugly and confusing.
202*/
203static
204Bool get_elf_symbol_info (
205        /* INPUTS */
206        struct _DebugInfo* di, /* containing DebugInfo */
207        ElfXX_Sym* sym,        /* ELF symbol */
208        Char*      sym_name,   /* name */
209        Addr       sym_svma,   /* address as stated in the object file */
210        Bool       symtab_in_debug, /* symbol table is in the debug file */
211        UChar*     opd_img,    /* oimage of .opd sec (ppc64-linux only) */
212        PtrdiffT   opd_bias,   /* for biasing AVMAs found in .opd */
213        /* OUTPUTS */
214        Char** sym_name_out,   /* name we should record */
215        Addr*  sym_avma_out,   /* addr we should record */
216        Int*   sym_size_out,   /* symbol size */
217        Addr*  sym_tocptr_out, /* ppc64-linux only: R2 value to be
218                                  used on entry */
219        Bool*  from_opd_out,   /* ppc64-linux only: did we deref an
220                                  .opd entry? */
221        Bool*  is_text_out,    /* is this a text symbol? */
222        Bool*  is_ifunc        /* is this a  STT_GNU_IFUNC function ?*/
223     )
224{
225   Bool plausible;
226#  if defined(VGP_ppc64_linux)
227   Bool is_in_opd;
228#  endif
229   Bool in_text, in_data, in_sdata, in_rodata, in_bss, in_sbss;
230   Addr text_svma, data_svma, sdata_svma, rodata_svma, bss_svma, sbss_svma;
231   PtrdiffT text_bias, data_bias, sdata_bias, rodata_bias, bss_bias, sbss_bias;
232
233   /* Set defaults */
234   *sym_name_out   = sym_name;
235   *sym_avma_out   = sym_svma; /* we will bias this shortly */
236   *is_text_out    = True;
237   *sym_size_out   = (Int)sym->st_size;
238   *sym_tocptr_out = 0; /* unknown/inapplicable */
239   *from_opd_out   = False;
240   *is_ifunc       = False;
241
242   /* Figure out if we're interested in the symbol.  Firstly, is it of
243      the right flavour?  */
244   plausible
245      = (ELFXX_ST_BIND(sym->st_info) == STB_GLOBAL
246         || ELFXX_ST_BIND(sym->st_info) == STB_LOCAL
247         || ELFXX_ST_BIND(sym->st_info) == STB_WEAK
248        )
249        &&
250        (ELFXX_ST_TYPE(sym->st_info) == STT_FUNC
251         || ELFXX_ST_TYPE(sym->st_info) == STT_OBJECT
252#ifdef STT_GNU_IFUNC
253         || ELFXX_ST_TYPE(sym->st_info) == STT_GNU_IFUNC
254#endif
255        );
256
257   /* Work out the svma and bias for each section as it will appear in
258      addresses in the symbol table. */
259   if (symtab_in_debug) {
260      text_svma = di->text_debug_svma;
261      text_bias = di->text_debug_bias;
262      data_svma = di->data_debug_svma;
263      data_bias = di->data_debug_bias;
264      sdata_svma = di->sdata_debug_svma;
265      sdata_bias = di->sdata_debug_bias;
266      rodata_svma = di->rodata_debug_svma;
267      rodata_bias = di->rodata_debug_bias;
268      bss_svma = di->bss_debug_svma;
269      bss_bias = di->bss_debug_bias;
270      sbss_svma = di->sbss_debug_svma;
271      sbss_bias = di->sbss_debug_bias;
272   } else {
273      text_svma = di->text_svma;
274      text_bias = di->text_bias;
275      data_svma = di->data_svma;
276      data_bias = di->data_bias;
277      sdata_svma = di->sdata_svma;
278      sdata_bias = di->sdata_bias;
279      rodata_svma = di->rodata_svma;
280      rodata_bias = di->rodata_bias;
281      bss_svma = di->bss_svma;
282      bss_bias = di->bss_bias;
283      sbss_svma = di->sbss_svma;
284      sbss_bias = di->sbss_bias;
285   }
286
287   /* Now bias sym_avma_out accordingly by figuring out exactly which
288      section the symbol is from and bias accordingly.  Screws up if
289      the previously deduced section svma address ranges are wrong. */
290   if (di->text_present
291       && di->text_size > 0
292       && sym_svma >= text_svma
293       && sym_svma < text_svma + di->text_size) {
294      *is_text_out = True;
295      *sym_avma_out += text_bias;
296   } else
297   if (di->data_present
298       && di->data_size > 0
299       && sym_svma >= data_svma
300       && sym_svma < data_svma + di->data_size) {
301      *is_text_out = False;
302      *sym_avma_out += data_bias;
303   } else
304   if (di->sdata_present
305       && di->sdata_size > 0
306       && sym_svma >= sdata_svma
307       && sym_svma < sdata_svma + di->sdata_size) {
308      *is_text_out = False;
309      *sym_avma_out += sdata_bias;
310   } else
311   if (di->rodata_present
312       && di->rodata_size > 0
313       && sym_svma >= rodata_svma
314       && sym_svma < rodata_svma + di->rodata_size) {
315      *is_text_out = False;
316      *sym_avma_out += rodata_bias;
317   } else
318   if (di->bss_present
319       && di->bss_size > 0
320       && sym_svma >= bss_svma
321       && sym_svma < bss_svma + di->bss_size) {
322      *is_text_out = False;
323      *sym_avma_out += bss_bias;
324   } else
325   if (di->sbss_present
326       && di->sbss_size > 0
327       && sym_svma >= sbss_svma
328       && sym_svma < sbss_svma + di->sbss_size) {
329      *is_text_out = False;
330      *sym_avma_out += sbss_bias;
331   } else {
332      /* Assume it's in .text.  Is this a good idea? */
333      *is_text_out = True;
334      *sym_avma_out += text_bias;
335   }
336
337#  ifdef STT_GNU_IFUNC
338   /* Check for indirect functions. */
339   if (*is_text_out
340       && ELFXX_ST_TYPE(sym->st_info) == STT_GNU_IFUNC) {
341       *is_ifunc = True;
342   }
343#  endif
344
345#  if defined(VGP_ppc64_linux)
346   /* Allow STT_NOTYPE in the very special case where we're running on
347      ppc64-linux and the symbol is one which the .opd-chasing hack
348      below will chase. */
349   if (!plausible
350       && *is_text_out
351       && ELFXX_ST_TYPE(sym->st_info) == STT_NOTYPE
352       && sym->st_size > 0
353       && di->opd_present
354       && di->opd_size > 0
355       && *sym_avma_out >= di->opd_avma
356       && *sym_avma_out <  di->opd_avma + di->opd_size)
357      plausible = True;
358#  endif
359
360   if (!plausible)
361      return False;
362
363   /* Ignore if nameless. */
364   if (sym_name == (ElfXX_Word)0
365       || /* VG_(strlen)(sym_name) == 0 */
366          /* equivalent but cheaper ... */
367          sym_name[0] == 0) {
368      TRACE_SYMTAB("    ignore -- nameless: %s\n", sym_name);
369      return False;
370   }
371
372   /* Ignore if zero-sized.  Except on Android:
373
374      On Android 2.3.5, some of the symbols that Memcheck needs to
375      intercept (for noise reduction purposes) have zero size, due to
376      lack of .size directives in handwritten assembly sources.  So we
377      can't reject them out of hand -- instead give them a bogusly
378      large size and let canonicaliseSymtab trim them so they don't
379      overlap any following symbols.  At least the following symbols
380      are known to be affected:
381
382      in /system/lib/libc.so: strlen strcmp strcpy memcmp memcpy
383      in /system/bin/linker:  __dl_strcmp __dl_strlen
384   */
385   if (sym->st_size == 0) {
386#     if defined(VGPV_arm_linux_android)
387      *sym_size_out = 2048;
388#     else
389      TRACE_SYMTAB("    ignore -- size=0: %s\n", sym_name);
390      return False;
391#     endif
392   }
393
394   /* This seems to significantly reduce the number of junk
395      symbols, and particularly reduces the number of
396      overlapping address ranges.  Don't ask me why ... */
397   if ((Int)sym->st_value == 0) {
398      TRACE_SYMTAB( "    ignore -- valu=0: %s\n", sym_name);
399      return False;
400   }
401
402   /* If it's apparently in a GOT or PLT, it's really a reference to a
403      symbol defined elsewhere, so ignore it. */
404   if (di->got_present
405       && di->got_size > 0
406       && *sym_avma_out >= di->got_avma
407       && *sym_avma_out <  di->got_avma + di->got_size) {
408      TRACE_SYMTAB("    ignore -- in GOT: %s\n", sym_name);
409      return False;
410   }
411   if (di->plt_present
412       && di->plt_size > 0
413       && *sym_avma_out >= di->plt_avma
414       && *sym_avma_out <  di->plt_avma + di->plt_size) {
415      TRACE_SYMTAB("    ignore -- in PLT: %s\n", sym_name);
416      return False;
417   }
418
419   /* ppc64-linux nasty hack: if the symbol is in an .opd section,
420      then really what we have is the address of a function
421      descriptor.  So use the first word of that as the function's
422      text.
423
424      See thread starting at
425      http://gcc.gnu.org/ml/gcc-patches/2004-08/msg00557.html
426   */
427#  if defined(VGP_ppc64_linux)
428   is_in_opd = False;
429#  endif
430
431   if (di->opd_present
432       && di->opd_size > 0
433       && *sym_avma_out >= di->opd_avma
434       && *sym_avma_out <  di->opd_avma + di->opd_size) {
435#     if !defined(VGP_ppc64_linux)
436      TRACE_SYMTAB("    ignore -- in OPD: %s\n", sym_name);
437      return False;
438#     else
439      Int    offset_in_opd;
440      ULong* fn_descr;
441      Bool   details = 1||False;
442
443      if (details)
444         TRACE_SYMTAB("opdXXX: opd_bias %p, sym_svma_out %p\n",
445                      (void*)(opd_bias), (void*)*sym_avma_out);
446
447      if (!VG_IS_8_ALIGNED(*sym_avma_out)) {
448         TRACE_SYMTAB("    ignore -- not 8-aligned: %s\n", sym_name);
449         return False;
450      }
451
452      /* *sym_avma_out is a vma pointing into the .opd section.  We
453         know the vma of the opd section start, so we can figure out
454         how far into the opd section this is. */
455
456      offset_in_opd = (Addr)(*sym_avma_out) - (Addr)(di->opd_avma);
457      if (offset_in_opd < 0 || offset_in_opd >= di->opd_size) {
458         TRACE_SYMTAB("    ignore -- invalid OPD offset: %s\n", sym_name);
459         return False;
460      }
461
462      /* Now we want to know what's at that offset in the .opd
463         section.  We can't look in the running image since it won't
464         necessarily have been mapped.  But we can consult the oimage.
465         opd_img is the start address of the .opd in the oimage.
466         Hence: */
467
468      fn_descr = (ULong*)(opd_img + offset_in_opd);
469
470      if (details)
471         TRACE_SYMTAB("opdXXY: offset %d,  fn_descr %p\n",
472                      offset_in_opd, fn_descr);
473      if (details)
474         TRACE_SYMTAB("opdXXZ: *fn_descr %p\n", (void*)(fn_descr[0]));
475
476      /* opd_bias is the what we have to add to SVMAs found in .opd to
477         get plausible .text AVMAs for the entry point, and .data
478         AVMAs (presumably) for the TOC locations.  We use the caller
479         supplied value (which is di->text_bias) for both of these.
480         Not sure why that is correct - it seems to work, and sounds
481         OK for fn_descr[0], but surely we need to use the data bias
482         and not the text bias for fn_descr[1] ?  Oh Well.
483      */
484      *sym_avma_out   = fn_descr[0] + opd_bias;
485      *sym_tocptr_out = fn_descr[1] + opd_bias;
486      *from_opd_out   = True;
487      is_in_opd = True;
488
489      /* Do a final sanity check: if the symbol falls outside the
490         DebugInfo's mapped range, ignore it.  Since *sym_avma_out has
491         been updated, that can be achieved simply by falling through
492         to the test below. */
493
494#     endif /* ppc64-linux nasty hack */
495   }
496
497   /* Here's yet another ppc64-linux hack.  Get rid of leading dot if
498      the symbol is outside .opd. */
499#  if defined(VGP_ppc64_linux)
500   if (di->opd_size > 0
501       && !is_in_opd
502       && sym_name[0] == '.') {
503      vg_assert(!(*from_opd_out));
504      *sym_name_out = &sym_name[1];
505   }
506#  endif
507
508   /* If no part of the symbol falls within the mapped range,
509      ignore it. */
510
511   in_text
512      = di->text_present
513        && di->text_size > 0
514        && !(*sym_avma_out + *sym_size_out <= di->text_avma
515             || *sym_avma_out >= di->text_avma + di->text_size);
516
517   in_data
518      = di->data_present
519        && di->data_size > 0
520        && !(*sym_avma_out + *sym_size_out <= di->data_avma
521             || *sym_avma_out >= di->data_avma + di->data_size);
522
523   in_sdata
524      = di->sdata_present
525        && di->sdata_size > 0
526        && !(*sym_avma_out + *sym_size_out <= di->sdata_avma
527             || *sym_avma_out >= di->sdata_avma + di->sdata_size);
528
529   in_rodata
530      = di->rodata_present
531        && di->rodata_size > 0
532        && !(*sym_avma_out + *sym_size_out <= di->rodata_avma
533             || *sym_avma_out >= di->rodata_avma + di->rodata_size);
534
535   in_bss
536      = di->bss_present
537        && di->bss_size > 0
538        && !(*sym_avma_out + *sym_size_out <= di->bss_avma
539             || *sym_avma_out >= di->bss_avma + di->bss_size);
540
541   in_sbss
542      = di->sbss_present
543        && di->sbss_size > 0
544        && !(*sym_avma_out + *sym_size_out <= di->sbss_avma
545             || *sym_avma_out >= di->sbss_avma + di->sbss_size);
546
547
548   if (*is_text_out) {
549      /* This used to reject any symbol falling outside the text
550         segment ("if (!in_text) ...").  Now it is relaxed slightly,
551         to reject only symbols which fall outside the area mapped
552         r-x.  This is in accordance with r7427.  See
553         "Comment_Regarding_Text_Range_Checks" in storage.c for
554         background. */
555      Bool in_rx;
556      vg_assert(di->fsm.have_rx_map);
557      in_rx = (!(*sym_avma_out + *sym_size_out <= di->fsm.rx_map_avma
558                 || *sym_avma_out >= di->fsm.rx_map_avma
559                                     + di->fsm.rx_map_size));
560      if (in_text)
561         vg_assert(in_rx);
562      if (!in_rx) {
563         TRACE_SYMTAB(
564            "ignore -- %#lx .. %#lx outside .text svma range %#lx .. %#lx\n",
565            *sym_avma_out, *sym_avma_out + *sym_size_out,
566            di->text_avma,
567            di->text_avma + di->text_size);
568         return False;
569      }
570   } else {
571     if (!(in_data || in_sdata || in_rodata || in_bss || in_sbss)) {
572         TRACE_SYMTAB(
573            "ignore -- %#lx .. %#lx outside .data / .sdata / .rodata "
574            "/ .bss / .sbss svma ranges\n",
575            *sym_avma_out, *sym_avma_out + *sym_size_out);
576         return False;
577      }
578   }
579
580#  if defined(VGP_ppc64_linux)
581   /* It's crucial that we never add symbol addresses in the .opd
582      section.  This would completely mess up function redirection and
583      intercepting.  This assert ensures that anysymbols that make it
584      into the symbol table on ppc64-linux don't point into .opd. */
585   if (di->opd_present && di->opd_size > 0) {
586      vg_assert(*sym_avma_out + *sym_size_out <= di->opd_avma
587                || *sym_avma_out >= di->opd_avma + di->opd_size);
588   }
589#  endif
590
591   /* Acquire! */
592   return True;
593}
594
595
596/* Read an ELF symbol table (normal or dynamic).  This one is for the
597   "normal" case ({x86,amd64,ppc32}-linux). */
598static
599__attribute__((unused)) /* not referred to on all targets */
600void read_elf_symtab__normal(
601        struct _DebugInfo* di, UChar* tab_name,
602        ElfXX_Sym* symtab_img, SizeT symtab_szB,
603        UChar*     strtab_img, SizeT strtab_szB,
604        Bool       symtab_in_debug,
605        UChar*     opd_img /* ppc64-linux only */
606     )
607{
608   Word       i;
609   Addr       sym_svma, sym_avma_really;
610   Char      *sym_name, *sym_name_really;
611   Int        sym_size;
612   Addr       sym_tocptr;
613   Bool       from_opd, is_text, is_ifunc;
614   DiSym      disym;
615   ElfXX_Sym *sym;
616
617   if (strtab_img == NULL || symtab_img == NULL) {
618      Char buf[80];
619      vg_assert(VG_(strlen)(tab_name) < 40);
620      VG_(sprintf)(buf, "   object doesn't have a %s", tab_name);
621      ML_(symerr)(di, False, buf);
622      return;
623   }
624
625   TRACE_SYMTAB("\n--- Reading (ELF, standard) %s (%ld entries) ---\n",
626                tab_name, symtab_szB/sizeof(ElfXX_Sym) );
627
628   /* Perhaps should start at i = 1; ELF docs suggest that entry
629      0 always denotes 'unknown symbol'. */
630   for (i = 1; i < (Word)(symtab_szB/sizeof(ElfXX_Sym)); i++) {
631      sym      = & symtab_img[i];
632      sym_name = (UChar*)(strtab_img + sym->st_name);
633      sym_svma = sym->st_value;
634
635      if (di->trace_symtab)
636         show_raw_elf_symbol(i, sym, sym_name, sym_svma, False);
637
638      if (get_elf_symbol_info(di, sym, sym_name, sym_svma,
639                              symtab_in_debug,
640                              opd_img, di->text_bias,
641                              &sym_name_really,
642                              &sym_avma_really,
643                              &sym_size,
644                              &sym_tocptr,
645                              &from_opd, &is_text, &is_ifunc)) {
646
647         disym.addr      = sym_avma_really;
648         disym.tocptr    = sym_tocptr;
649         disym.pri_name  = ML_(addStr) ( di, sym_name_really, -1 );
650         disym.sec_names = NULL;
651         disym.size      = sym_size;
652         disym.isText    = is_text;
653         disym.isIFunc   = is_ifunc;
654         vg_assert(disym.pri_name);
655         vg_assert(disym.tocptr == 0); /* has no role except on ppc64-linux */
656         ML_(addSym) ( di, &disym );
657
658         if (di->trace_symtab) {
659            VG_(printf)("    rec(%c) [%4ld]:          "
660                        "  val %#010lx, sz %4d  %s\n",
661                        is_text ? 't' : 'd',
662                        i,
663                        disym.addr,
664                        (Int)disym.size,
665                        (HChar*)disym.pri_name
666            );
667         }
668
669      }
670   }
671}
672
673
674/* Read an ELF symbol table (normal or dynamic).  This one is for
675   ppc64-linux, which requires special treatment. */
676
677typedef
678   struct {
679      Addr   addr;
680      UChar* name;
681   }
682   TempSymKey;
683
684typedef
685   struct {
686      TempSymKey key;
687      Addr       tocptr;
688      Int        size;
689      Bool       from_opd;
690      Bool       is_text;
691      Bool       is_ifunc;
692   }
693   TempSym;
694
695static Word cmp_TempSymKey ( TempSymKey* key1, TempSym* elem2 ) {
696   if (key1->addr < elem2->key.addr) return -1;
697   if (key1->addr > elem2->key.addr) return 1;
698   return (Word)VG_(strcmp)(key1->name, elem2->key.name);
699}
700
701static
702__attribute__((unused)) /* not referred to on all targets */
703void read_elf_symtab__ppc64_linux(
704        struct _DebugInfo* di, UChar* tab_name,
705        ElfXX_Sym* symtab_img, SizeT symtab_szB,
706        UChar*     strtab_img, SizeT strtab_szB,
707        Bool       symtab_in_debug,
708        UChar*     opd_img /* ppc64-linux only */
709     )
710{
711   Word        i;
712   Int         old_size;
713   Addr        sym_svma, sym_avma_really;
714   Char       *sym_name, *sym_name_really;
715   Int         sym_size;
716   Addr        sym_tocptr;
717   Bool        from_opd, modify_size, modify_tocptr, is_text, is_ifunc;
718   DiSym       disym;
719   ElfXX_Sym  *sym;
720   OSet       *oset;
721   TempSymKey  key;
722   TempSym    *elem;
723   TempSym    *prev;
724
725   if (strtab_img == NULL || symtab_img == NULL) {
726      Char buf[80];
727      vg_assert(VG_(strlen)(tab_name) < 40);
728      VG_(sprintf)(buf, "   object doesn't have a %s", tab_name);
729      ML_(symerr)(di, False, buf);
730      return;
731   }
732
733   TRACE_SYMTAB("\n--- Reading (ELF, ppc64-linux) %s (%ld entries) ---\n",
734                tab_name, symtab_szB/sizeof(ElfXX_Sym) );
735
736   oset = VG_(OSetGen_Create)( offsetof(TempSym,key),
737                               (OSetCmp_t)cmp_TempSymKey,
738                               ML_(dinfo_zalloc), "di.respl.1",
739                               ML_(dinfo_free) );
740   vg_assert(oset);
741
742   /* Perhaps should start at i = 1; ELF docs suggest that entry
743      0 always denotes 'unknown symbol'. */
744   for (i = 1; i < (Word)(symtab_szB/sizeof(ElfXX_Sym)); i++) {
745      sym      = & symtab_img[i];
746      sym_name = (Char*)(strtab_img + sym->st_name);
747      sym_svma = sym->st_value;
748
749      if (di->trace_symtab)
750         show_raw_elf_symbol(i, sym, sym_name, sym_svma, True);
751
752      if (get_elf_symbol_info(di, sym, sym_name, sym_svma,
753                              symtab_in_debug,
754                              opd_img, di->text_bias,
755                              &sym_name_really,
756                              &sym_avma_really,
757                              &sym_size,
758                              &sym_tocptr,
759                              &from_opd, &is_text, &is_ifunc)) {
760
761         /* Check if we've seen this (name,addr) key before. */
762         key.addr = sym_avma_really;
763         key.name = sym_name_really;
764         prev = VG_(OSetGen_Lookup)( oset, &key );
765
766         if (prev) {
767
768            /* Seen it before.  Fold in whatever new info we can. */
769            modify_size   = False;
770            modify_tocptr = False;
771            old_size   = 0;
772
773            if (prev->from_opd && !from_opd
774                && (prev->size == 24 || prev->size == 16)
775                && sym_size != prev->size) {
776               /* Existing one is an opd-redirect, with a bogus size,
777                  so the only useful new fact we have is the real size
778                  of the symbol. */
779               modify_size = True;
780               old_size = prev->size;
781               prev->size = sym_size;
782            }
783            else
784            if (!prev->from_opd && from_opd
785                && (sym_size == 24 || sym_size == 16)) {
786               /* Existing one is non-opd, new one is opd.  What we
787                  can acquire from the new one is the TOC ptr to be
788                  used.  Since the existing sym is non-toc, it
789                  shouldn't currently have an known TOC ptr. */
790               vg_assert(prev->tocptr == 0);
791               modify_tocptr = True;
792               prev->tocptr = sym_tocptr;
793            }
794            else {
795               /* ignore. can we do better here? */
796            }
797
798            /* Only one or the other is possible (I think) */
799            vg_assert(!(modify_size && modify_tocptr));
800
801            if (modify_size && di->trace_symtab) {
802               VG_(printf)("    modify (old sz %4d)    "
803                           " val %#010lx, toc %#010lx, sz %4d  %s\n",
804                           old_size,
805                           prev->key.addr,
806                           prev->tocptr,
807                           (Int)   prev->size,
808                           (HChar*)prev->key.name
809               );
810            }
811            if (modify_tocptr && di->trace_symtab) {
812               VG_(printf)("    modify (upd tocptr)     "
813                           " val %#010lx, toc %#010lx, sz %4d  %s\n",
814                           prev->key.addr,
815                           prev->tocptr,
816                           (Int)   prev->size,
817                           (HChar*)prev->key.name
818               );
819            }
820
821         } else {
822
823            /* A new (name,addr) key.  Add and continue. */
824            elem = VG_(OSetGen_AllocNode)(oset, sizeof(TempSym));
825            vg_assert(elem);
826            elem->key      = key;
827            elem->tocptr   = sym_tocptr;
828            elem->size     = sym_size;
829            elem->from_opd = from_opd;
830            elem->is_text  = is_text;
831            elem->is_ifunc = is_ifunc;
832            VG_(OSetGen_Insert)(oset, elem);
833            if (di->trace_symtab) {
834               VG_(printf)("   to-oset [%4ld]:          "
835                           "  val %#010lx, toc %#010lx, sz %4d  %s\n",
836                           i,
837                           elem->key.addr,
838                           elem->tocptr,
839                           (Int)   elem->size,
840                           (HChar*)elem->key.name
841               );
842            }
843
844         }
845      }
846   }
847
848   /* All the syms that matter are in the oset.  Now pull them out,
849      build a "standard" symbol table, and nuke the oset. */
850
851   i = 0;
852   VG_(OSetGen_ResetIter)( oset );
853
854   while ( (elem = VG_(OSetGen_Next)(oset)) ) {
855      disym.addr      = elem->key.addr;
856      disym.tocptr    = elem->tocptr;
857      disym.pri_name  = ML_(addStr) ( di, elem->key.name, -1 );
858      disym.sec_names = NULL;
859      disym.size      = elem->size;
860      disym.isText    = elem->is_text;
861      disym.isIFunc   = elem->is_ifunc;
862      vg_assert(disym.pri_name != NULL);
863
864      ML_(addSym) ( di, &disym );
865      if (di->trace_symtab) {
866         VG_(printf)("    rec(%c) [%4ld]:          "
867                     "   val %#010lx, toc %#010lx, sz %4d  %s\n",
868                     disym.isText ? 't' : 'd',
869                     i,
870                     disym.addr,
871                     disym.tocptr,
872                     (Int)   disym.size,
873                     (HChar*)disym.pri_name
874               );
875      }
876      i++;
877   }
878
879   VG_(OSetGen_Destroy)( oset );
880}
881
882
883/*
884 * Look for a build-id in an ELF image. The build-id specification
885 * can be found here:
886 *
887 * http://fedoraproject.org/wiki/RolandMcGrath/BuildID
888 */
889static
890Char *find_buildid(Addr image, UWord n_image)
891{
892   Char* buildid = NULL;
893   __attribute__((unused)) /* on Android, at least */
894   ElfXX_Ehdr* ehdr = (ElfXX_Ehdr*)image;
895
896#ifdef NT_GNU_BUILD_ID
897   if (n_image >= sizeof(ElfXX_Ehdr) &&
898       ML_(is_elf_object_file)(ehdr, n_image)) {
899      Word i;
900
901      for (i = 0; i < ehdr->e_phnum; i++) {
902         ElfXX_Phdr* phdr
903            = (ElfXX_Phdr*)(image + ehdr->e_phoff + i * ehdr->e_phentsize);
904
905         if (phdr->p_type == PT_NOTE) {
906            ElfXX_Off offset =  phdr->p_offset;
907
908            while (offset < phdr->p_offset + phdr->p_filesz) {
909               ElfXX_Nhdr* note = (ElfXX_Nhdr*)(image + offset);
910               Char* name = (Char *)note + sizeof(ElfXX_Nhdr);
911               UChar *desc = (UChar *)name + ((note->n_namesz + 3) & ~3);
912               Word j;
913
914               if (VG_(strcmp)(name, ELF_NOTE_GNU) == 0 &&
915                   note->n_type == NT_GNU_BUILD_ID) {
916                  buildid = ML_(dinfo_zalloc)("di.fbi.1",
917                                              note->n_descsz * 2 + 1);
918
919                  for (j = 0; j < note->n_descsz; j++) {
920                     VG_(sprintf)(buildid + VG_(strlen)(buildid),
921                                  "%02x", desc[j]);
922                  }
923               }
924
925               offset = offset + sizeof(ElfXX_Nhdr)
926                               + ((note->n_namesz + 3) & ~3)
927                               + ((note->n_descsz + 3) & ~3);
928            }
929         }
930      }
931   }
932#endif
933
934   return buildid;
935}
936
937/*
938 * This routine for calculating the CRC for a separate debug file
939 * is GPLed code borrowed from GNU binutils.
940 */
941static UInt
942calc_gnu_debuglink_crc32(UInt crc, const UChar *buf, Int len)
943{
944  static const UInt crc32_table[256] =
945    {
946      0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
947      0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
948      0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
949      0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
950      0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
951      0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
952      0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
953      0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
954      0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
955      0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
956      0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
957      0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
958      0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
959      0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
960      0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
961      0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
962      0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
963      0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
964      0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
965      0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
966      0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
967      0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
968      0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
969      0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
970      0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
971      0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
972      0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
973      0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
974      0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
975      0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
976      0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
977      0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
978      0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
979      0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
980      0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
981      0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
982      0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
983      0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
984      0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
985      0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
986      0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
987      0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
988      0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
989      0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
990      0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
991      0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
992      0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
993      0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
994      0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
995      0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
996      0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
997      0x2d02ef8d
998    };
999  const UChar *end;
1000
1001  crc = ~crc & 0xffffffff;
1002  for (end = buf + len; buf < end; ++ buf)
1003    crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
1004  return ~crc & 0xffffffff;;
1005}
1006
1007/*
1008 * Try and open a separate debug file, ignoring any where the CRC does
1009 * not match the value from the main object file.
1010 */
1011static
1012Addr open_debug_file( Char* name, Char* buildid, UInt crc, /*OUT*/UWord* size )
1013{
1014   SysRes fd, sres;
1015   struct vg_stat stat_buf;
1016   UInt calccrc;
1017
1018   fd = VG_(open)(name, VKI_O_RDONLY, 0);
1019   if (sr_isError(fd))
1020      return 0;
1021
1022   if (VG_(fstat)(sr_Res(fd), &stat_buf) != 0) {
1023      VG_(close)(sr_Res(fd));
1024      return 0;
1025   }
1026
1027   if (VG_(clo_verbosity) > 1)
1028      VG_(message)(Vg_DebugMsg, "  Considering %s ..\n", name);
1029
1030   *size = stat_buf.size;
1031
1032   sres = VG_(am_mmap_file_float_valgrind)
1033             ( *size, VKI_PROT_READ, sr_Res(fd), 0 );
1034
1035   VG_(close)(sr_Res(fd));
1036
1037   if (sr_isError(sres))
1038      return 0;
1039
1040   if (buildid) {
1041      Char* debug_buildid = find_buildid(sr_Res(sres), *size);
1042      if (debug_buildid == NULL || VG_(strcmp)(buildid, debug_buildid) != 0) {
1043         SysRes res = VG_(am_munmap_valgrind)(sr_Res(sres), *size);
1044         vg_assert(!sr_isError(res));
1045         if (VG_(clo_verbosity) > 1)
1046            VG_(message)(Vg_DebugMsg,
1047               "  .. build-id mismatch (found %s wanted %s)\n",
1048               debug_buildid, buildid);
1049         ML_(dinfo_free)(debug_buildid);
1050         return 0;
1051      }
1052      ML_(dinfo_free)(debug_buildid);
1053
1054      if (VG_(clo_verbosity) > 1)
1055         VG_(message)(Vg_DebugMsg, "  .. build-id is valid\n");
1056   } else {
1057      calccrc = calc_gnu_debuglink_crc32(0, (UChar*)sr_Res(sres), *size);
1058      if (calccrc != crc) {
1059         SysRes res = VG_(am_munmap_valgrind)(sr_Res(sres), *size);
1060         vg_assert(!sr_isError(res));
1061         if (VG_(clo_verbosity) > 1)
1062            VG_(message)(Vg_DebugMsg,
1063               "  .. CRC mismatch (computed %08x wanted %08x)\n", calccrc, crc);
1064         return 0;
1065      }
1066
1067      if (VG_(clo_verbosity) > 1)
1068         VG_(message)(Vg_DebugMsg, "  .. CRC is valid\n");
1069   }
1070
1071   return sr_Res(sres);
1072}
1073
1074
1075/* Try to find and map in a debuginfo file by some totally ad-hoc
1076   scheme.  If successful, set *dimage and *n_dimage to point to the
1077   image, and return True, else return False.  A temporary hack for
1078   Android; does nothing on any other platform. */
1079static
1080Bool find_ad_hoc_debug_image( struct _DebugInfo* di,
1081                              Char* filename,
1082                              /*OUT*/Addr* dimage,
1083                              /*OUT*/SizeT* n_dimage )
1084{
1085   vg_assert(*dimage == 0 && *n_dimage == 0);
1086
1087#  if !defined(VGPV_arm_linux_android)
1088   return False; /* we don't know narfink */
1089
1090#  else /* android specific hacks; look away now. */
1091
1092   /* The deal is: if we're looking for for a debuginfo file for some
1093      object /path/to/object (which can be any path), see if we can
1094      find the file /sdcard/symbols/path/to/object.  So for example it
1095      produces the following mappings, both of which are important for
1096      Memcheck:
1097
1098      /system/bin/linker  --> /sdcard/symbols/system/bin/linker
1099      /system/lib/libc.so --> /sdcard/symbols/system/lib/libc.so
1100
1101      These /symbols files come from the AOSP build tree for your
1102      device, for example out/target/product/crespo/symbols/system
1103      (for a Nexus S), so one simple thing you can do is take the tree
1104      rooted at out/target/product/crespo/symbols/system on the host
1105      and park it at /sdcard/symbols/system on the device.  Then,
1106      assuming it matches what's actually running on the device,
1107      you'll have full debuginfo for all the libraries on the device.
1108
1109      But beware: there is no checking that the debuginfo file, if
1110      found, matches the main file in any way.
1111   */
1112   if (!filename || *filename != '/')
1113      return False;
1114
1115   HChar* nm = ML_(dinfo_zalloc)("di.fahdi.1",
1116                                 50 + VG_(strlen)(filename));
1117   VG_(sprintf)(nm, "/sdcard/symbols%s", filename);
1118
1119   SysRes fd = VG_(open)(nm, VKI_O_RDONLY, 0);
1120   if (sr_isError(fd)) goto fail;
1121
1122   struct vg_stat stat_buf;
1123   if (VG_(fstat)(sr_Res(fd), &stat_buf) != 0) {
1124      VG_(close)(sr_Res(fd));
1125      goto fail;
1126   }
1127
1128   *n_dimage = stat_buf.size;
1129
1130   SysRes sres = VG_(am_mmap_file_float_valgrind)
1131                    ( *n_dimage, VKI_PROT_READ, sr_Res(fd), 0 );
1132
1133   VG_(close)(sr_Res(fd));
1134   if (sr_isError(sres))
1135     goto fail;
1136
1137   *dimage = sr_Res(sres);
1138
1139   if (VG_(clo_verbosity) > 1)
1140      VG_(dmsg)("  Using debuginfo from %s\n", nm);
1141
1142   ML_(dinfo_free)(nm);
1143   return True;
1144
1145  fail:
1146   if (nm) ML_(dinfo_free)(nm);
1147   return False;
1148
1149#  endif
1150}
1151
1152
1153/* Try to find a separate debug file for a given object file.  If
1154   found, it will be mapped in and the address and size returned in
1155   *dimage and *n_dimage.  If not, *dimage and *n_dimage will be
1156   unchanged.  The caller should set them to zero before the call. */
1157static
1158void find_debug_file( struct _DebugInfo* di,
1159                      Char* objpath, Char* buildid,
1160                      Char* debugname, UInt crc,
1161                      /*OUT*/Addr*  dimage,
1162                      /*OUT*/SizeT* n_dimage )
1163{
1164   Char* debugpath = NULL;
1165   Addr  addr = 0;
1166   UWord size = 0;
1167
1168   vg_assert(*dimage == 0 && *n_dimage == 0);
1169
1170   if (buildid != NULL) {
1171      debugpath = ML_(dinfo_zalloc)(
1172                     "di.fdf.1",
1173                     VG_(strlen)(buildid) + 33);
1174
1175      VG_(sprintf)(debugpath, "/usr/lib/debug/.build-id/%c%c/%s.debug",
1176                   buildid[0], buildid[1], buildid + 2);
1177
1178      if ((addr = open_debug_file(debugpath, buildid, 0, &size)) == 0) {
1179         ML_(dinfo_free)(debugpath);
1180         debugpath = NULL;
1181      }
1182   }
1183
1184   if (addr == 0 && debugname != NULL) {
1185      Char *objdir = ML_(dinfo_strdup)("di.fdf.2", objpath);
1186      Char *objdirptr;
1187
1188      if ((objdirptr = VG_(strrchr)(objdir, '/')) != NULL)
1189         *objdirptr = '\0';
1190
1191      debugpath = ML_(dinfo_zalloc)(
1192                     "di.fdf.3",
1193                     VG_(strlen)(objdir) + VG_(strlen)(debugname) + 32);
1194
1195      VG_(sprintf)(debugpath, "%s/%s", objdir, debugname);
1196
1197      if ((addr = open_debug_file(debugpath, NULL, crc, &size)) == 0) {
1198         VG_(sprintf)(debugpath, "%s/.debug/%s", objdir, debugname);
1199         if ((addr = open_debug_file(debugpath, NULL, crc, &size)) == 0) {
1200            VG_(sprintf)(debugpath, "/usr/lib/debug%s/%s", objdir, debugname);
1201            addr = open_debug_file(debugpath, NULL, crc, &size);
1202         }
1203      }
1204
1205      ML_(dinfo_free)(objdir);
1206   }
1207
1208   if (addr > 0 && size > 0) {
1209      TRACE_SYMTAB("\n");
1210      TRACE_SYMTAB("------ Found a debuginfo file: %s\n", debugpath);
1211      *dimage = addr;
1212      *n_dimage = size;
1213   }
1214
1215   ML_(dinfo_free)(debugpath);
1216}
1217
1218
1219static Bool contained_within ( Addr outer, UWord n_outer,
1220                               Addr inner, UWord n_inner )
1221{
1222   if (n_outer == 0 || n_inner == 0)
1223      return False;
1224   /* Simplistic .. assumes no wraparound (reasonably enough) */
1225   if (inner >= outer && inner+n_inner <= outer+n_outer)
1226      return True;
1227   return False;
1228}
1229
1230static void* INDEX_BIS ( void* base, Word idx, Word scale ) {
1231   return (void*)( ((UChar*)base) + idx * scale );
1232}
1233
1234
1235/* Find the file offset corresponding to SVMA by using the program
1236   headers.  This is taken from binutils-2.17/binutils/readelf.c
1237   offset_from_vma(). */
1238static
1239Word file_offset_from_svma ( /*OUT*/Bool* ok,
1240                             Addr         svma,
1241                             ElfXX_Phdr*  phdr_img,
1242                             Word         phdr_nent,
1243                             Word         phdr_ent_szB )
1244{
1245   Word        i;
1246   ElfXX_Phdr* seg;
1247   for (i = 0; i < phdr_nent; i++) {
1248      seg = INDEX_BIS( phdr_img, i, phdr_ent_szB );
1249      if (seg->p_type != PT_LOAD)
1250         continue;
1251      if (svma >= (seg->p_vaddr & -seg->p_align)
1252          && svma + 1 <= seg->p_vaddr + seg->p_filesz) {
1253         *ok = True;
1254         return svma - seg->p_vaddr + seg->p_offset;
1255      }
1256   }
1257   *ok = False;
1258   return 0;
1259}
1260
1261
1262/* The central function for reading ELF debug info.  For the
1263   object/exe specified by the DebugInfo, find ELF sections, then read
1264   the symbols, line number info, file name info, CFA (stack-unwind
1265   info) and anything else we want, into the tables within the
1266   supplied DebugInfo.
1267*/
1268
1269/* Temporarily holds information copied out of PT_LOAD entries
1270   in ML_(read_elf_debug_info. */
1271typedef
1272   struct { Addr svma_base; Addr svma_limit; PtrdiffT bias; }
1273   RangeAndBias;
1274
1275Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
1276{
1277   /* This function is long and complex.  That, and the presence of
1278      nested scopes, means it's not always easy to see which parts are
1279      in loops/conditionals and which aren't.  To make it easier to
1280      follow, points executed exactly once -- that is, those which are
1281      the top level of the function -- are marked TOPLEVEL.
1282   */
1283   /* TOPLEVEL */
1284   Bool          res, ok;
1285   SysRes        fd, sres;
1286   Word          i;
1287   Bool          dynbss_present = False;
1288   Bool          sdynbss_present = False;
1289
1290   /* Image addresses for the ELF file we're working with. */
1291   Addr          oimage   = 0;
1292   UWord         n_oimage = 0;
1293
1294   /* Ditto for any ELF debuginfo file that we might happen to load. */
1295   Addr          dimage   = 0;
1296   UWord         n_dimage = 0;
1297
1298   /* ELF header for the main file.  Should == oimage since is at
1299      start of file. */
1300   ElfXX_Ehdr* ehdr_img = NULL;
1301
1302   /* Program header table image addr, # entries, entry size */
1303   ElfXX_Phdr* phdr_img     = NULL;
1304   UWord       phdr_nent    = 0;
1305   UWord       phdr_ent_szB = 0;
1306
1307   /* Section header image addr, # entries, entry size.  Also the
1308      associated string table. */
1309   ElfXX_Shdr* shdr_img        = NULL;
1310   UWord       shdr_nent       = 0;
1311   UWord       shdr_ent_szB    = 0;
1312   UChar*      shdr_strtab_img = NULL;
1313
1314   /* SVMAs covered by rx and rw segments and corresponding biases.
1315      We keep separate lists of rx and rw areas.  Each can have up to
1316      N_RX_RW_AREAS entries.  Normally each object would provide just
1317      one rx and one rw area, but Mike Hommey's elfhack creates
1318      objects with two rx PT_LOAD entries, hence the generality. */
1319   const Int N_RX_RW_AREAS = 2;
1320
1321   RangeAndBias rx[N_RX_RW_AREAS];
1322   RangeAndBias rw[N_RX_RW_AREAS];
1323   Word n_rx = 0; /* 0 .. N_RX_RW_AREAS */
1324   Word n_rw = 0; /* 0 .. N_RX_RW_AREAS */
1325   /* Pointless paranoia: */
1326   VG_(memset)( rx, 0, sizeof(rx) );
1327   VG_(memset)( rw, 0, sizeof(rw) );
1328
1329   /* Build ID */
1330   Char* buildid = NULL;
1331
1332   vg_assert(di);
1333   vg_assert(di->fsm.have_rx_map == True);
1334   vg_assert(di->fsm.have_rw_map == True);
1335   vg_assert(di->fsm.rx_map_size > 0);
1336   vg_assert(di->fsm.rw_map_size > 0);
1337   vg_assert(di->have_dinfo == False);
1338   vg_assert(di->fsm.filename);
1339   vg_assert(!di->symtab);
1340   vg_assert(!di->loctab);
1341   vg_assert(!di->cfsi);
1342   vg_assert(!di->cfsi_exprs);
1343   vg_assert(!di->strchunks);
1344   vg_assert(!di->soname);
1345
1346   /* If these don't hold true, it means that m_syswrap/m_aspacemgr
1347      managed to do a mapping where the start isn't page aligned.
1348      Which sounds pretty bogus to me. */
1349   vg_assert(VG_IS_PAGE_ALIGNED(di->fsm.rx_map_avma));
1350   vg_assert(VG_IS_PAGE_ALIGNED(di->fsm.rw_map_avma));
1351
1352   /* ----------------------------------------------------------
1353      At this point, there is very little information in the
1354      DebugInfo.  We only know that something that looks like an ELF
1355      file has been mapped rx-ishly as recorded with the di->*rx_map*
1356      fields and has also been mapped rw-ishly as recorded with the
1357      di->*rw_map* fields.  First we examine the file's ELF Program
1358      Header, and, by comparing that against the di->*r{w,x}_map*
1359      info, try to figure out the AVMAs for the sections we care
1360      about, that should have been mapped: text, data, sdata, bss,
1361      got, plt, and toc.
1362      ---------------------------------------------------------- */
1363
1364   res = False;
1365
1366   oimage = (Addr)NULL;
1367   if (VG_(clo_verbosity) > 1 || VG_(clo_trace_redir))
1368      VG_(message)(Vg_DebugMsg, "Reading syms from %s (%#lx)\n",
1369                                di->fsm.filename, di->fsm.rx_map_avma );
1370
1371   /* mmap the object image aboard, so that we can read symbols and
1372      line number info out of it.  It will be munmapped immediately
1373      thereafter; it is only aboard transiently. */
1374
1375   fd = VG_(open)(di->fsm.filename, VKI_O_RDONLY, 0);
1376   if (sr_isError(fd)) {
1377      ML_(symerr)(di, True, "Can't open .so/.exe to read symbols?!");
1378      return False;
1379   }
1380
1381   { Long n_oimageLL = VG_(fsize)(sr_Res(fd));
1382     if (n_oimageLL <= 0) {
1383        ML_(symerr)(di, True, "Can't stat .so/.exe (to determine its size)?!");
1384        VG_(close)(sr_Res(fd));
1385        return False;
1386     }
1387     n_oimage = (UWord)(ULong)n_oimageLL;
1388   }
1389
1390   sres = VG_(am_mmap_file_float_valgrind)
1391             ( n_oimage, VKI_PROT_READ, sr_Res(fd), 0 );
1392
1393   VG_(close)(sr_Res(fd));
1394
1395   if (sr_isError(sres)) {
1396      VG_(message)(Vg_UserMsg, "warning: mmap failed on %s\n",
1397                               di->fsm.filename );
1398      VG_(message)(Vg_UserMsg, "         no symbols or debug info loaded\n" );
1399      return False;
1400   }
1401
1402   oimage = sr_Res(sres);
1403   /* Check against wraparound.  am_mmap_file_float_valgrind should
1404      not produce a wrapped-around mapping. */
1405   vg_assert(n_oimage > 0);
1406   vg_assert(oimage + n_oimage > oimage);
1407
1408   if (0) {
1409      VG_(printf)("read_elf_debug_info: OIMAGE = %p - %p\n",
1410                  (void*)oimage, (void*)(oimage + (UWord)n_oimage));
1411   }
1412
1413   /* Ok, the object image is safely in oimage[0 .. n_oimage-1].  Now
1414      verify that it is a valid ELF .so or executable image. */
1415   res      = False;
1416   ok       = (n_oimage >= sizeof(ElfXX_Ehdr));
1417   ehdr_img = (ElfXX_Ehdr*)oimage;
1418
1419   if (ok)
1420      ok &= ML_(is_elf_object_file)(ehdr_img, n_oimage);
1421
1422   if (!ok) {
1423      ML_(symerr)(di, True, "Invalid ELF Header");
1424      goto out;
1425   }
1426
1427   /* Find where the program and section header tables are, and give
1428      up if either is missing or outside the image (bogus). */
1429   phdr_img     = (ElfXX_Phdr*)( ((UChar*)ehdr_img) + ehdr_img->e_phoff );
1430   phdr_nent    = ehdr_img->e_phnum;
1431   phdr_ent_szB = ehdr_img->e_phentsize;
1432
1433   shdr_img     = (ElfXX_Shdr*)( ((UChar*)ehdr_img) + ehdr_img->e_shoff );
1434   shdr_nent    = ehdr_img->e_shnum;
1435   shdr_ent_szB = ehdr_img->e_shentsize;
1436
1437   TRACE_SYMTAB("------ Basic facts about the object ------\n");
1438   TRACE_SYMTAB("object:  img %p n_oimage %ld\n",
1439               (void*)oimage, n_oimage);
1440   TRACE_SYMTAB("phdr:    img %p nent %ld ent_szB %ld\n",
1441               phdr_img, phdr_nent, phdr_ent_szB);
1442   TRACE_SYMTAB("shdr:    img %p nent %ld ent_szB %ld\n",
1443               shdr_img, shdr_nent, shdr_ent_szB);
1444   TRACE_SYMTAB("rx_map:  avma %#lx  size %lu  foff %lu\n",
1445                di->fsm.rx_map_avma, di->fsm.rx_map_size, di->fsm.rx_map_foff);
1446   TRACE_SYMTAB("rw_map:  avma %#lx  size %lu  foff %lu\n",
1447                di->fsm.rw_map_avma, di->fsm.rw_map_size, di->fsm.rw_map_foff);
1448
1449   if (phdr_nent == 0
1450       || !contained_within(
1451             oimage, n_oimage,
1452             (Addr)phdr_img, phdr_nent * phdr_ent_szB)) {
1453      ML_(symerr)(di, True, "Missing or invalid ELF Program Header Table");
1454      goto out;
1455   }
1456
1457   if (shdr_nent == 0
1458       || !contained_within(
1459             oimage, n_oimage,
1460             (Addr)shdr_img, shdr_nent * shdr_ent_szB)) {
1461      ML_(symerr)(di, True, "Missing or invalid ELF Section Header Table");
1462      goto out;
1463   }
1464
1465   /* Also find the section header's string table, and validate. */
1466   /* checked previously by is_elf_object_file: */
1467   vg_assert( ehdr_img->e_shstrndx != SHN_UNDEF );
1468
1469   shdr_strtab_img
1470      = (UChar*)( ((UChar*)ehdr_img)
1471                  + shdr_img[ehdr_img->e_shstrndx].sh_offset);
1472   if (!contained_within( oimage, n_oimage,
1473                          (Addr)shdr_strtab_img,
1474                          1/*bogus, but we don't know the real size*/ )) {
1475      ML_(symerr)(di, True, "Invalid ELF Section Header String Table");
1476      goto out;
1477   }
1478
1479   TRACE_SYMTAB("shdr:    string table at %p\n", shdr_strtab_img );
1480
1481   /* TOPLEVEL */
1482   /* Look through the program header table, and:
1483      - copy information from suitable PT_LOAD entries into rx[] or
1484        rw[]
1485      - find (or fake up) the .soname for this object.
1486   */
1487   TRACE_SYMTAB("\n");
1488   TRACE_SYMTAB("------ Examining the program headers ------\n");
1489   vg_assert(di->soname == NULL);
1490   {
1491      /* TOPLEVEL */
1492      ElfXX_Addr prev_svma = 0;
1493
1494      for (i = 0; i < phdr_nent; i++) {
1495         ElfXX_Phdr* phdr = INDEX_BIS( phdr_img, i, phdr_ent_szB );
1496
1497         /* Make sure the PT_LOADable entries are in order and
1498            non-overlapping.  This in turn means the address ranges
1499            slurped into rx[] and rw[] are in order and
1500            non-overlapping. */
1501         vg_assert(n_rx >= 0 && n_rx <= N_RX_RW_AREAS);
1502         vg_assert(n_rw >= 0 && n_rw <= N_RX_RW_AREAS);
1503
1504         if (phdr->p_type == PT_LOAD) {
1505            TRACE_SYMTAB("PT_LOAD[%ld]: p_vaddr %#lx (prev %#lx)\n",
1506                         i, (UWord)phdr->p_vaddr, (UWord)prev_svma);
1507            TRACE_SYMTAB("PT_LOAD[%ld]:   p_offset %lu, p_filesz %lu,"
1508                         " perms %c%c%c\n",
1509                         i, (UWord)phdr->p_offset, (UWord)phdr->p_filesz,
1510                         phdr->p_flags & PF_R ? 'r' : '-',
1511                         phdr->p_flags & PF_W ? 'w' : '-',
1512                         phdr->p_flags & PF_X ? 'x' : '-');
1513            if (phdr->p_vaddr < prev_svma) {
1514               ML_(symerr)(di, True,
1515                           "ELF Program Headers are not in ascending order");
1516               goto out;
1517            }
1518            prev_svma = phdr->p_vaddr;
1519            if (phdr->p_offset >= di->fsm.rx_map_foff
1520                && phdr->p_offset < di->fsm.rx_map_foff + di->fsm.rx_map_size
1521                && phdr->p_offset + phdr->p_filesz
1522                   <= di->fsm.rx_map_foff + di->fsm.rx_map_size
1523                && (phdr->p_flags & (PF_R | PF_W | PF_X)) == (PF_R | PF_X)) {
1524               if (n_rx == N_RX_RW_AREAS) {
1525                  ML_(symerr)(di, True,
1526                              "N_RX_RW_AREAS is too low; "
1527                              "increase and recompile.");
1528                  goto out;
1529               }
1530               rx[n_rx].svma_base  = phdr->p_vaddr;
1531               rx[n_rx].svma_limit = phdr->p_vaddr + phdr->p_memsz;
1532               rx[n_rx].bias       = di->fsm.rx_map_avma - di->fsm.rx_map_foff
1533                                     + phdr->p_offset - phdr->p_vaddr;
1534               n_rx++;
1535               TRACE_SYMTAB("PT_LOAD[%ld]:   acquired as rx\n", i);
1536            }
1537            else
1538            if (phdr->p_offset >= di->fsm.rw_map_foff
1539                && phdr->p_offset < di->fsm.rw_map_foff + di->fsm.rw_map_size
1540                && phdr->p_offset + phdr->p_filesz
1541                   <= di->fsm.rw_map_foff + di->fsm.rw_map_size
1542                && (phdr->p_flags & (PF_R | PF_W | PF_X)) == (PF_R | PF_W)) {
1543               if (n_rw == N_RX_RW_AREAS) {
1544                  ML_(symerr)(di, True,
1545                              "N_RX_RW_AREAS is too low; "
1546                              "increase and recompile.");
1547                  goto out;
1548               }
1549               rw[n_rw].svma_base  = phdr->p_vaddr;
1550               rw[n_rw].svma_limit = phdr->p_vaddr + phdr->p_memsz;
1551               rw[n_rw].bias       = di->fsm.rw_map_avma - di->fsm.rw_map_foff
1552                                     + phdr->p_offset - phdr->p_vaddr;
1553               n_rw++;
1554               TRACE_SYMTAB("PT_LOAD[%ld]:   acquired as rw\n", i);
1555            }
1556         }
1557
1558         /* Try to get the soname.  If there isn't one, use "NONE".
1559            The seginfo needs to have some kind of soname in order to
1560            facilitate writing redirect functions, since all redirect
1561            specifications require a soname (pattern). */
1562         if (phdr->p_type == PT_DYNAMIC && di->soname == NULL) {
1563            ElfXX_Dyn* dyn_img = (ElfXX_Dyn*)( ((UChar*)ehdr_img)
1564                                               + phdr->p_offset);
1565            Word   stroff = -1;
1566            UChar* strtab = NULL;
1567            Word   j;
1568            for (j = 0; dyn_img[j].d_tag != DT_NULL; j++) {
1569               switch (dyn_img[j].d_tag) {
1570                  case DT_SONAME: {
1571                     stroff = dyn_img[j].d_un.d_val;
1572                     break;
1573                  }
1574                  case DT_STRTAB: {
1575                     Bool ok2 = False;
1576                     Word offset = file_offset_from_svma(
1577                                      &ok2,
1578                                      dyn_img[j].d_un.d_ptr,
1579                                      phdr_img,
1580                                      phdr_nent, phdr_ent_szB
1581                                   );
1582                     if (ok2 && strtab == NULL) {
1583                        vg_assert(offset >= 0 && offset <= n_oimage);
1584                        strtab = ((UChar*)ehdr_img) + offset;
1585                     }
1586                     break;
1587                  }
1588                  default:
1589                     break;
1590               }
1591            }
1592            if (stroff != -1 && strtab != NULL) {
1593               TRACE_SYMTAB("Found soname = %s\n", strtab+stroff);
1594               di->soname = ML_(dinfo_strdup)("di.redi.1", strtab+stroff);
1595            }
1596         }
1597      } /* for (i = 0; i < phdr_nent; i++) ... */
1598      /* TOPLEVEL */
1599
1600   } /* examine the program headers (local scope) */
1601
1602   /* TOPLEVEL */
1603
1604   /* If, after looking at all the program headers, we still didn't
1605      find a soname, add a fake one. */
1606   if (di->soname == NULL) {
1607      TRACE_SYMTAB("No soname found; using (fake) \"NONE\"\n");
1608      di->soname = ML_(dinfo_strdup)("di.redi.2", "NONE");
1609   }
1610
1611   vg_assert(n_rx >= 0 && n_rx <= N_RX_RW_AREAS);
1612   vg_assert(n_rw >= 0 && n_rw <= N_RX_RW_AREAS);
1613   for (i = 0; i < n_rx; i++) {
1614      vg_assert(rx[i].svma_limit != 0);
1615   }
1616   for (i = 0; i < n_rw; i++) {
1617      vg_assert(rw[i].svma_limit != 0);
1618   }
1619
1620   /* Now read the section table. */
1621   TRACE_SYMTAB("\n");
1622   TRACE_SYMTAB("------ Examining the section headers ------\n");
1623   TRACE_SYMTAB("rx: at %#lx are mapped foffsets %ld .. %ld\n",
1624                di->fsm.rx_map_avma,
1625                di->fsm.rx_map_foff,
1626                di->fsm.rx_map_foff + di->fsm.rx_map_size - 1 );
1627   for (i = 0; i < n_rx; i++) {
1628      TRACE_SYMTAB("rx[%ld]: contains svmas %#lx .. %#lx with bias %#lx\n",
1629                   i, rx[i].svma_base, rx[i].svma_limit - 1, rx[i].bias );
1630   }
1631   TRACE_SYMTAB("rw: at %#lx are mapped foffsets %ld .. %ld\n",
1632                di->fsm.rw_map_avma,
1633                di->fsm.rw_map_foff,
1634                di->fsm.rw_map_foff + di->fsm.rw_map_size - 1 );
1635   for (i = 0; i < n_rw; i++) {
1636      TRACE_SYMTAB("rw[%ld]: contains svmas %#lx .. %#lx with bias %#lx\n",
1637                   i, rw[i].svma_base, rw[i].svma_limit - 1, rw[i].bias );
1638   }
1639
1640   /* TOPLEVEL */
1641   /* Iterate over section headers */
1642   for (i = 0; i < shdr_nent; i++) {
1643      ElfXX_Shdr* shdr = INDEX_BIS( shdr_img, i, shdr_ent_szB );
1644      UChar* name = shdr_strtab_img + shdr->sh_name;
1645      Addr   svma = shdr->sh_addr;
1646      OffT   foff = shdr->sh_offset;
1647      UWord  size = shdr->sh_size;
1648      UInt   alyn = shdr->sh_addralign;
1649      Bool   bits = !(shdr->sh_type == SHT_NOBITS);
1650      /* Look through our collection of info obtained from the PT_LOAD
1651         headers, and make 'inrx' and 'inrw' point to the first entry
1652         in each that intersects 'avma'.  If in each case none is found,
1653         leave the relevant pointer at NULL. */
1654      RangeAndBias* inrx = NULL;
1655      RangeAndBias* inrw = NULL;
1656      { Word j;
1657        for (j = 0; j < n_rx; j++) {
1658           if (svma >= rx[j].svma_base && svma < rx[j].svma_limit) {
1659             inrx = &rx[j];
1660             break;
1661           }
1662        }
1663        for (j = 0; j < n_rw; j++) {
1664           if (svma >= rw[j].svma_base && svma < rw[j].svma_limit) {
1665             inrw = &rw[j];
1666             break;
1667           }
1668        }
1669      }
1670
1671      TRACE_SYMTAB(" [sec %2ld]  %s %s  al%2u  foff %6ld .. %6ld  "
1672                  "  svma %p  name \"%s\"\n",
1673                  i, inrx ? "rx" : "  ", inrw ? "rw" : "  ", alyn,
1674                  foff, foff+size-1, (void*)svma, name );
1675
1676      /* Check for sane-sized segments.  SHT_NOBITS sections have zero
1677         size in the file. */
1678      if ((foff >= n_oimage) || (foff + (bits ? size : 0) > n_oimage)) {
1679         ML_(symerr)(di, True, "ELF Section extends beyond image end");
1680         goto out;
1681      }
1682
1683      /* Check for a sane alignment value. */
1684      if (alyn > 0 && -1 == VG_(log2)(alyn)) {
1685         ML_(symerr)(di, True, "ELF Section contains invalid "
1686                               ".sh_addralign value");
1687         goto out;
1688      }
1689
1690#     define BAD(_secname)                                 \
1691         do { ML_(symerr)(di, True,                        \
1692                          "Can't make sense of " _secname  \
1693                          " section mapping");             \
1694              /* make sure we don't assert if we find */   \
1695              /* ourselves back in this routine later, */  \
1696              /* with the same di */                       \
1697              di->soname = NULL;                           \
1698              goto out;                                    \
1699         } while (0)
1700
1701      /* Find avma-s for: .text .data .sdata .rodata .bss .sbss .plt .got .opd
1702         and .eh_frame */
1703
1704      /* Accept .text where mapped as rx (code), even if zero-sized */
1705      if (0 == VG_(strcmp)(name, ".text")) {
1706         if (inrx && size >= 0 && !di->text_present) {
1707            di->text_present = True;
1708            di->text_svma = svma;
1709            di->text_avma = svma + inrx->bias;
1710            di->text_size = size;
1711            di->text_bias = inrx->bias;
1712            di->text_debug_svma = svma;
1713            di->text_debug_bias = inrx->bias;
1714            TRACE_SYMTAB("acquiring .text svma = %#lx .. %#lx\n",
1715                         di->text_svma,
1716                         di->text_svma + di->text_size - 1);
1717            TRACE_SYMTAB("acquiring .text avma = %#lx .. %#lx\n",
1718                         di->text_avma,
1719                         di->text_avma + di->text_size - 1);
1720            TRACE_SYMTAB("acquiring .text bias = %#lx\n", di->text_bias);
1721         } else {
1722            BAD(".text");
1723         }
1724      }
1725
1726      /* Accept .data where mapped as rw (data), even if zero-sized */
1727      if (0 == VG_(strcmp)(name, ".data")) {
1728         if (inrw && size >= 0 && !di->data_present) {
1729            di->data_present = True;
1730            di->data_svma = svma;
1731            di->data_avma = svma + inrw->bias;
1732            di->data_size = size;
1733            di->data_bias = inrw->bias;
1734            di->data_debug_svma = svma;
1735            di->data_debug_bias = inrw->bias;
1736            TRACE_SYMTAB("acquiring .data svma = %#lx .. %#lx\n",
1737                         di->data_svma,
1738                         di->data_svma + di->data_size - 1);
1739            TRACE_SYMTAB("acquiring .data avma = %#lx .. %#lx\n",
1740                         di->data_avma,
1741                         di->data_avma + di->data_size - 1);
1742            TRACE_SYMTAB("acquiring .data bias = %#lx\n", di->data_bias);
1743         } else {
1744            BAD(".data");
1745         }
1746      }
1747
1748      /* Accept .sdata where mapped as rw (data) */
1749      if (0 == VG_(strcmp)(name, ".sdata")) {
1750         if (inrw && size > 0 && !di->sdata_present) {
1751            di->sdata_present = True;
1752            di->sdata_svma = svma;
1753            di->sdata_avma = svma + inrw->bias;
1754            di->sdata_size = size;
1755            di->sdata_bias = inrw->bias;
1756            di->sdata_debug_svma = svma;
1757            di->sdata_debug_bias = inrw->bias;
1758            TRACE_SYMTAB("acquiring .sdata svma = %#lx .. %#lx\n",
1759                         di->sdata_svma,
1760                         di->sdata_svma + di->sdata_size - 1);
1761            TRACE_SYMTAB("acquiring .sdata avma = %#lx .. %#lx\n",
1762                         di->sdata_avma,
1763                         di->sdata_avma + di->sdata_size - 1);
1764            TRACE_SYMTAB("acquiring .sdata bias = %#lx\n", di->sdata_bias);
1765         } else {
1766            BAD(".sdata");
1767         }
1768      }
1769
1770      /* Accept .rodata where mapped as rx (data), even if zero-sized */
1771      if (0 == VG_(strcmp)(name, ".rodata")) {
1772         if (inrx && size >= 0 && !di->rodata_present) {
1773            di->rodata_present = True;
1774            di->rodata_svma = svma;
1775            di->rodata_avma = svma + inrx->bias;
1776            di->rodata_size = size;
1777            di->rodata_bias = inrx->bias;
1778            di->rodata_debug_svma = svma;
1779            di->rodata_debug_bias = inrx->bias;
1780                                    /* NB was 'inrw' prior to r11794 */
1781            TRACE_SYMTAB("acquiring .rodata svma = %#lx .. %#lx\n",
1782                         di->rodata_svma,
1783                         di->rodata_svma + di->rodata_size - 1);
1784            TRACE_SYMTAB("acquiring .rodata avma = %#lx .. %#lx\n",
1785                         di->rodata_avma,
1786                         di->rodata_avma + di->rodata_size - 1);
1787            TRACE_SYMTAB("acquiring .rodata bias = %#lx\n", di->rodata_bias);
1788         } else {
1789            BAD(".rodata");
1790         }
1791      }
1792
1793      if (0 == VG_(strcmp)(name, ".dynbss")) {
1794         if (inrw && size > 0 && !di->bss_present) {
1795            dynbss_present = True;
1796            di->bss_present = True;
1797            di->bss_svma = svma;
1798            di->bss_avma = svma + inrw->bias;
1799            di->bss_size = size;
1800            di->bss_bias = inrw->bias;
1801            di->bss_debug_svma = svma;
1802            di->bss_debug_bias = inrw->bias;
1803            TRACE_SYMTAB("acquiring .dynbss svma = %#lx .. %#lx\n",
1804                         di->bss_svma,
1805                         di->bss_svma + di->bss_size - 1);
1806            TRACE_SYMTAB("acquiring .dynbss avma = %#lx .. %#lx\n",
1807                         di->bss_avma,
1808                         di->bss_avma + di->bss_size - 1);
1809            TRACE_SYMTAB("acquiring .dynbss bias = %#lx\n", di->bss_bias);
1810         }
1811      }
1812
1813      /* Accept .bss where mapped as rw (data), even if zero-sized */
1814      if (0 == VG_(strcmp)(name, ".bss")) {
1815         if (inrw && size > 0 && dynbss_present) {
1816            vg_assert(di->bss_present);
1817            dynbss_present = False;
1818            vg_assert(di->bss_svma + di->bss_size == svma);
1819            di->bss_size += size;
1820            TRACE_SYMTAB("acquiring .bss svma = %#lx .. %#lx\n",
1821                         svma, svma + size - 1);
1822            TRACE_SYMTAB("acquiring .bss avma = %#lx .. %#lx\n",
1823                         svma + inrw->bias, svma + inrw->bias + size - 1);
1824            TRACE_SYMTAB("acquiring .bss bias = %#lx\n", di->bss_bias);
1825         } else
1826
1827         if (inrw && size >= 0 && !di->bss_present) {
1828            di->bss_present = True;
1829            di->bss_svma = svma;
1830            di->bss_avma = svma + inrw->bias;
1831            di->bss_size = size;
1832            di->bss_bias = inrw->bias;
1833            di->bss_debug_svma = svma;
1834            di->bss_debug_bias = inrw->bias;
1835            TRACE_SYMTAB("acquiring .bss svma = %#lx .. %#lx\n",
1836                         di->bss_svma,
1837                         di->bss_svma + di->bss_size - 1);
1838            TRACE_SYMTAB("acquiring .bss avma = %#lx .. %#lx\n",
1839                         di->bss_avma,
1840                         di->bss_avma + di->bss_size - 1);
1841            TRACE_SYMTAB("acquiring .bss bias = %#lx\n", di->bss_bias);
1842         } else
1843
1844         /* Now one from the wtf?! department ... */
1845         if (inrx && (!inrw) && size >= 0 && !di->bss_present) {
1846            /* File contains a .bss, but it got mapped as rx only.
1847               This is very strange.  For now, just pretend we didn't
1848               see it :-) */
1849            di->bss_present = False;
1850            di->bss_svma = 0;
1851            di->bss_avma = 0;
1852            di->bss_size = 0;
1853            di->bss_bias = 0;
1854            di->bss_debug_svma = 0;
1855            di->bss_debug_bias = 0;
1856            if (!VG_(clo_xml)) {
1857               VG_(message)(Vg_UserMsg,
1858                            "Warning: the following file's .bss is "
1859                            "mapped r-x only - ignoring .bss syms\n");
1860               VG_(message)(Vg_UserMsg,   " %s\n", di->fsm.filename
1861                                                      ? di->fsm.filename
1862                                                      : (UChar*)"(null?!)" );
1863            }
1864         } else
1865
1866         if ((!inrw) && (!inrx) && size >= 0 && !di->bss_present) {
1867            /* File contains a .bss, but it didn't get mapped.  Ignore. */
1868            di->bss_present = False;
1869            di->bss_svma = 0;
1870            di->bss_avma = 0;
1871            di->bss_size = 0;
1872            di->bss_bias = 0;
1873         } else {
1874            BAD(".bss");
1875         }
1876      }
1877
1878      if (0 == VG_(strcmp)(name, ".sdynbss")) {
1879         if (inrw && size >= 0 && !di->sbss_present) {
1880            sdynbss_present = True;
1881            di->sbss_present = True;
1882            di->sbss_svma = svma;
1883            di->sbss_avma = svma + inrw->bias;
1884            di->sbss_size = size;
1885            di->sbss_bias = inrw->bias;
1886            di->sbss_debug_svma = svma;
1887            di->sbss_debug_bias = inrw->bias;
1888            TRACE_SYMTAB("acquiring .sdynbss svma = %#lx .. %#lx\n",
1889                         di->sbss_svma,
1890                         di->sbss_svma + di->sbss_size - 1);
1891            TRACE_SYMTAB("acquiring .sdynbss avma = %#lx .. %#lx\n",
1892                         di->sbss_avma,
1893                         di->sbss_avma + di->sbss_size - 1);
1894            TRACE_SYMTAB("acquiring .sdynbss bias = %#lx\n", di->sbss_bias);
1895         }
1896      }
1897
1898      /* Accept .sbss where mapped as rw (data) */
1899      if (0 == VG_(strcmp)(name, ".sbss")) {
1900         if (inrw && size > 0 && sdynbss_present) {
1901            vg_assert(di->sbss_present);
1902            sdynbss_present = False;
1903            vg_assert(di->sbss_svma + di->sbss_size == svma);
1904            di->sbss_size += size;
1905            TRACE_SYMTAB("acquiring .sbss svma = %#lx .. %#lx\n",
1906                         svma, svma + size - 1);
1907            TRACE_SYMTAB("acquiring .sbss avma = %#lx .. %#lx\n",
1908                         svma + inrw->bias, svma + inrw->bias + size - 1);
1909            TRACE_SYMTAB("acquiring .sbss bias = %#lx\n", di->sbss_bias);
1910         } else
1911
1912         if (inrw && size > 0 && !di->sbss_present) {
1913            di->sbss_present = True;
1914            di->sbss_svma = svma;
1915            di->sbss_avma = svma + inrw->bias;
1916            di->sbss_size = size;
1917            di->sbss_bias = inrw->bias;
1918            di->sbss_debug_svma = svma;
1919            di->sbss_debug_bias = inrw->bias;
1920            TRACE_SYMTAB("acquiring .sbss svma = %#lx .. %#lx\n",
1921                         di->sbss_svma,
1922                         di->sbss_svma + di->sbss_size - 1);
1923            TRACE_SYMTAB("acquiring .sbss avma = %#lx .. %#lx\n",
1924                         di->sbss_avma,
1925                         di->sbss_avma + di->sbss_size - 1);
1926            TRACE_SYMTAB("acquiring .sbss bias = %#lx\n", di->sbss_bias);
1927         } else {
1928            BAD(".sbss");
1929         }
1930      }
1931
1932      /* Accept .got where mapped as rw (data) */
1933      if (0 == VG_(strcmp)(name, ".got")) {
1934         if (inrw && size > 0 && !di->got_present) {
1935            di->got_present = True;
1936            di->got_avma = svma + inrw->bias;
1937            di->got_size = size;
1938            TRACE_SYMTAB("acquiring .got avma = %#lx\n", di->got_avma);
1939         } else {
1940            BAD(".got");
1941         }
1942      }
1943
1944      /* Accept .got.plt where mapped as rw (data) */
1945      if (0 == VG_(strcmp)(name, ".got.plt")) {
1946         if (inrw && size > 0 && !di->gotplt_present) {
1947            di->gotplt_present = True;
1948            di->gotplt_avma = svma + inrw->bias;
1949            di->gotplt_size = size;
1950            TRACE_SYMTAB("acquiring .got.plt avma = %#lx\n", di->gotplt_avma);
1951         } else if (size != 0) {
1952            BAD(".got.plt");
1953         }
1954      }
1955
1956      /* PLT is different on different platforms, it seems. */
1957#     if defined(VGP_x86_linux) || defined(VGP_amd64_linux) \
1958         || defined(VGP_arm_linux) || defined (VGP_s390x_linux)
1959      /* Accept .plt where mapped as rx (code) */
1960      if (0 == VG_(strcmp)(name, ".plt")) {
1961         if (inrx && size > 0 && !di->plt_present) {
1962            di->plt_present = True;
1963            di->plt_avma = svma + inrx->bias;
1964            di->plt_size = size;
1965            TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
1966         } else {
1967            BAD(".plt");
1968         }
1969      }
1970#     elif defined(VGP_ppc32_linux)
1971      /* Accept .plt where mapped as rw (data) */
1972      if (0 == VG_(strcmp)(name, ".plt")) {
1973         if (inrw && size > 0 && !di->plt_present) {
1974            di->plt_present = True;
1975            di->plt_avma = svma + inrw->bias;
1976            di->plt_size = size;
1977            TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
1978         } else {
1979            BAD(".plt");
1980         }
1981      }
1982#     elif defined(VGP_ppc64_linux)
1983      /* Accept .plt where mapped as rw (data), or unmapped */
1984      if (0 == VG_(strcmp)(name, ".plt")) {
1985         if (inrw && size > 0 && !di->plt_present) {
1986            di->plt_present = True;
1987            di->plt_avma = svma + inrw->bias;
1988            di->plt_size = size;
1989            TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
1990         } else
1991         if ((!inrw) && (!inrx) && size > 0 && !di->plt_present) {
1992            /* File contains a .plt, but it didn't get mapped.
1993               Presumably it is not required on this platform.  At
1994               least don't reject the situation as invalid. */
1995            di->plt_present = True;
1996            di->plt_avma = 0;
1997            di->plt_size = 0;
1998         } else {
1999            BAD(".plt");
2000         }
2001      }
2002#     else
2003#       error "Unsupported platform"
2004#     endif
2005
2006      /* Accept .opd where mapped as rw (data) */
2007      if (0 == VG_(strcmp)(name, ".opd")) {
2008         if (inrw && size > 0 && !di->opd_present) {
2009            di->opd_present = True;
2010            di->opd_avma = svma + inrw->bias;
2011            di->opd_size = size;
2012            TRACE_SYMTAB("acquiring .opd avma = %#lx\n", di->opd_avma);
2013         } else {
2014            BAD(".opd");
2015         }
2016      }
2017
2018      /* Accept .eh_frame where mapped as rx (code).  This seems to be
2019         the common case.  However, if that doesn't pan out, try for
2020         rw (data) instead.  We can handle up to N_EHFRAME_SECTS per
2021         ELF object. */
2022      if (0 == VG_(strcmp)(name, ".eh_frame")) {
2023         if (inrx && size > 0 && di->n_ehframe < N_EHFRAME_SECTS) {
2024            di->ehframe_avma[di->n_ehframe] = svma + inrx->bias;
2025            di->ehframe_size[di->n_ehframe] = size;
2026            TRACE_SYMTAB("acquiring .eh_frame avma = %#lx\n",
2027                         di->ehframe_avma[di->n_ehframe]);
2028            di->n_ehframe++;
2029         } else
2030         if (inrw && size > 0 && di->n_ehframe < N_EHFRAME_SECTS) {
2031            di->ehframe_avma[di->n_ehframe] = svma + inrw->bias;
2032            di->ehframe_size[di->n_ehframe] = size;
2033            TRACE_SYMTAB("acquiring .eh_frame avma = %#lx\n",
2034                         di->ehframe_avma[di->n_ehframe]);
2035            di->n_ehframe++;
2036         } else {
2037            BAD(".eh_frame");
2038         }
2039      }
2040
2041#    undef BAD
2042
2043   } /* iterate over the section headers */
2044
2045   /* TOPLEVEL */
2046   if (0) VG_(printf)("YYYY text_: avma %#lx  size %ld  bias %#lx\n",
2047                      di->text_avma, di->text_size, di->text_bias);
2048
2049   if (VG_(clo_verbosity) > 2 || VG_(clo_trace_redir))
2050      VG_(message)(Vg_DebugMsg, "   svma %#010lx, avma %#010lx\n",
2051                                di->text_avma - di->text_bias,
2052                                di->text_avma );
2053
2054   TRACE_SYMTAB("\n");
2055   TRACE_SYMTAB("------ Finding image addresses "
2056                "for debug-info sections ------\n");
2057
2058   /* TOPLEVEL */
2059   /* Find interesting sections, read the symbol table(s), read any debug
2060      information */
2061   {
2062      /* IMAGE addresses: pointers to start of sections in the
2063         transiently loaded oimage, not in the fragments of the file
2064         mapped in by the guest's dynamic linker. */
2065      /* TOPLEVEL */
2066      UChar*     strtab_img       = NULL; /* .strtab */
2067      ElfXX_Sym* symtab_img       = NULL; /* .symtab */
2068      UChar*     dynstr_img       = NULL; /* .dynstr */
2069      ElfXX_Sym* dynsym_img       = NULL; /* .dynsym */
2070      UChar*     debuglink_img    = NULL; /* .gnu_debuglink */
2071      UChar*     stab_img         = NULL; /* .stab         (stabs)  */
2072      UChar*     stabstr_img      = NULL; /* .stabstr      (stabs)  */
2073      UChar*     debug_line_img   = NULL; /* .debug_line   (dwarf2) */
2074      UChar*     debug_info_img   = NULL; /* .debug_info   (dwarf2) */
2075      UChar*     debug_abbv_img   = NULL; /* .debug_abbrev (dwarf2) */
2076      UChar*     debug_str_img    = NULL; /* .debug_str    (dwarf2) */
2077      UChar*     debug_ranges_img = NULL; /* .debug_ranges (dwarf2) */
2078      UChar*     debug_loc_img    = NULL; /* .debug_loc    (dwarf2) */
2079      UChar*     debug_frame_img  = NULL; /* .debug_frame  (dwarf2) */
2080      UChar*     dwarf1d_img      = NULL; /* .debug        (dwarf1) */
2081      UChar*     dwarf1l_img      = NULL; /* .line         (dwarf1) */
2082      UChar*     opd_img          = NULL; /* .opd (dwarf2,
2083                                                   ppc64-linux) */
2084      UChar*     ehframe_img[N_EHFRAME_SECTS]; /* .eh_frame (dwarf2) */
2085
2086      /* Section sizes, in bytes */
2087      SizeT      strtab_sz       = 0;
2088      SizeT      symtab_sz       = 0;
2089      SizeT      dynstr_sz       = 0;
2090      SizeT      dynsym_sz       = 0;
2091      SizeT      debuglink_sz    = 0;
2092      SizeT      stab_sz         = 0;
2093      SizeT      stabstr_sz      = 0;
2094      SizeT      debug_line_sz   = 0;
2095      SizeT      debug_info_sz   = 0;
2096      SizeT      debug_abbv_sz   = 0;
2097      SizeT      debug_str_sz    = 0;
2098      SizeT      debug_ranges_sz = 0;
2099      SizeT      debug_loc_sz    = 0;
2100      SizeT      debug_frame_sz  = 0;
2101      SizeT      dwarf1d_sz      = 0;
2102      SizeT      dwarf1l_sz      = 0;
2103      SizeT      opd_sz_unused   = 0;
2104      SizeT      ehframe_sz[N_EHFRAME_SECTS];
2105
2106      for (i = 0; i < N_EHFRAME_SECTS; i++) {
2107         ehframe_img[i] = NULL;
2108         ehframe_sz[i]  = 0;
2109      }
2110
2111      /* Find all interesting sections */
2112
2113      UInt ehframe_ix = 0;
2114
2115      /* What FIND does: it finds the section called _SEC_NAME.  The
2116         size of it is assigned to _SEC_SIZE.  The address of the
2117         section in the transiently loaded oimage is assigned to
2118         _SEC_IMG.  If the section is found, _POST_FX is executed
2119         after _SEC_NAME and _SEC_SIZE have been assigned to.
2120
2121         Even for sections which are marked loadable, the client's
2122         ld.so may not have loaded them yet, so there is no guarantee
2123         that we can safely prod around in any such area).  Because
2124         the entire object file is transiently mapped aboard for
2125         inspection, it's always safe to inspect that area. */
2126
2127      /* TOPLEVEL */
2128      /* Iterate over section headers (again) */
2129      for (i = 0; i < ehdr_img->e_shnum; i++) {
2130
2131#        define FINDX(_sec_name, _sec_size, _sec_img, _post_fx)     \
2132         do { ElfXX_Shdr* shdr \
2133                 = INDEX_BIS( shdr_img, i, shdr_ent_szB ); \
2134            if (0 == VG_(strcmp)(_sec_name, shdr_strtab_img \
2135                                            + shdr->sh_name)) { \
2136               Bool nobits; \
2137               _sec_img  = (void*)(oimage + shdr->sh_offset); \
2138               _sec_size = shdr->sh_size; \
2139               nobits    = shdr->sh_type == SHT_NOBITS; \
2140               TRACE_SYMTAB( "%18s:  img %p .. %p\n", \
2141                             _sec_name, (UChar*)_sec_img, \
2142                             ((UChar*)_sec_img) + _sec_size - 1); \
2143               /* SHT_NOBITS sections have zero size in the file. */ \
2144               if ( shdr->sh_offset \
2145                    + (nobits ? 0 : _sec_size) > n_oimage ) { \
2146                  ML_(symerr)(di, True, \
2147                              "   section beyond image end?!"); \
2148                  goto out; \
2149               } \
2150               _post_fx; \
2151            } \
2152         } while (0);
2153
2154         /* Version with no post-effects */
2155#        define FIND(_sec_name, _sec_size, _sec_img) \
2156            FINDX(_sec_name, _sec_size, _sec_img, /**/)
2157
2158         /*   NAME              SIZE             IMAGE addr */
2159         FIND(".dynsym",        dynsym_sz,       dynsym_img)
2160         FIND(".dynstr",        dynstr_sz,       dynstr_img)
2161         FIND(".symtab",        symtab_sz,       symtab_img)
2162         FIND(".strtab",        strtab_sz,       strtab_img)
2163
2164         FIND(".gnu_debuglink", debuglink_sz,    debuglink_img)
2165
2166         FIND(".stab",          stab_sz,         stab_img)
2167         FIND(".stabstr",       stabstr_sz,      stabstr_img)
2168
2169         FIND(".debug_line",    debug_line_sz,   debug_line_img)
2170         FIND(".debug_info",    debug_info_sz,   debug_info_img)
2171         FIND(".debug_abbrev",  debug_abbv_sz,   debug_abbv_img)
2172         FIND(".debug_str",     debug_str_sz,    debug_str_img)
2173         FIND(".debug_ranges",  debug_ranges_sz, debug_ranges_img)
2174         FIND(".debug_loc",     debug_loc_sz,    debug_loc_img)
2175         FIND(".debug_frame",   debug_frame_sz,  debug_frame_img)
2176
2177         FIND(".debug",         dwarf1d_sz,      dwarf1d_img)
2178         FIND(".line",          dwarf1l_sz,      dwarf1l_img)
2179
2180         FIND(".opd",           opd_sz_unused,   opd_img)
2181
2182         FINDX(".eh_frame",     ehframe_sz[ehframe_ix],
2183                                                 ehframe_img[ehframe_ix],
2184               do { ehframe_ix++; vg_assert(ehframe_ix <= N_EHFRAME_SECTS); }
2185                    while (0)
2186         )
2187         /* Comment_on_EH_FRAME_MULTIPLE_INSTANCES: w.r.t. .eh_frame
2188            multi-instance kludgery, how are we assured that the order
2189            in which we fill in ehframe_sz[] and ehframe_img[] is
2190            consistent with the order in which we previously filled in
2191            di->ehframe_avma[] and di->ehframe_size[] ?  By the fact
2192            that in both cases, these arrays were filled in by
2193            iterating over the section headers top-to-bottom.  So both
2194            loops (this one and the previous one) encounter the
2195            .eh_frame entries in the same order and so fill in these
2196            arrays in a consistent order.
2197         */
2198
2199#        undef FINDX
2200#        undef FIND
2201      } /* Iterate over section headers (again) */
2202
2203      /* TOPLEVEL */
2204      /* Now, see if we can find a debuginfo object, and if so map it in, and
2205         put the mapping address and size in dimage and n_dimage. */
2206      vg_assert(dimage == 0 && n_dimage == 0);
2207
2208      /* Look for a build-id */
2209      buildid = find_buildid(oimage, n_oimage);
2210
2211      /* Look for a debug image */
2212      if (buildid != NULL || debuglink_img != NULL) {
2213         /* Do have a debuglink section? */
2214         if (debuglink_img != NULL) {
2215            UInt crc_offset = VG_ROUNDUP(VG_(strlen)(debuglink_img)+1, 4);
2216            UInt crc;
2217
2218            vg_assert(crc_offset + sizeof(UInt) <= debuglink_sz);
2219
2220            /* Extract the CRC from the debuglink section */
2221            crc = ML_(read_UInt)(debuglink_img + crc_offset);
2222
2223            /* See if we can find a matching debug file */
2224            find_debug_file( di, di->fsm.filename, buildid,
2225                             debuglink_img, crc, &dimage, &n_dimage );
2226         } else {
2227            /* See if we can find a matching debug file */
2228            find_debug_file( di, di->fsm.filename, buildid,
2229                             NULL, 0, &dimage, &n_dimage );
2230         }
2231      }
2232
2233      if (buildid) {
2234         ML_(dinfo_free)(buildid);
2235         buildid = NULL; /* paranoia */
2236      }
2237
2238      /* Still no luck?  Let's have one last roll of the dice. */
2239      if (dimage == 0) {
2240         vg_assert(n_dimage == 0);
2241         Bool found = find_ad_hoc_debug_image( di, di->fsm.filename,
2242                                               &dimage, &n_dimage );
2243         if (found)
2244            vg_assert(dimage != 0);
2245      }
2246
2247      /* TOPLEVEL */
2248      /* If we were successful in finding a debug image, pull various
2249         SVMA/bias/size and image addresses out of it. */
2250      if (dimage != 0
2251          && n_dimage >= sizeof(ElfXX_Ehdr)
2252          && ML_(is_elf_object_file)((void*)dimage, n_dimage)) {
2253
2254         /* Pull out and validate program header and section header info */
2255         ElfXX_Ehdr* ehdr_dimg     = (ElfXX_Ehdr*)dimage;
2256         ElfXX_Phdr* phdr_dimg     = (ElfXX_Phdr*)( ((UChar*)ehdr_dimg)
2257                                                       + ehdr_dimg->e_phoff );
2258         UWord       phdr_dnent    = ehdr_dimg->e_phnum;
2259         UWord       phdr_dent_szB = ehdr_dimg->e_phentsize;
2260         ElfXX_Shdr* shdr_dimg     = (ElfXX_Shdr*)( ((UChar*)ehdr_dimg)
2261                                                       + ehdr_dimg->e_shoff );
2262         UWord       shdr_dnent       = ehdr_dimg->e_shnum;
2263         UWord       shdr_dent_szB    = ehdr_dimg->e_shentsize;
2264         UChar*      shdr_strtab_dimg = NULL;
2265
2266         /* SVMAs covered by rx and rw segments and corresponding bias. */
2267         /* Addr     rx_dsvma_base = 0; */ /* UNUSED */
2268         Addr     rx_dsvma_limit = 0;
2269         PtrdiffT rx_dbias = 0;
2270         /* Addr     rw_dsvma_base = 0; */ /* UNUSED */
2271         Addr     rw_dsvma_limit = 0;
2272         PtrdiffT rw_dbias = 0;
2273
2274         Bool need_symtab, need_stabs, need_dwarf2, need_dwarf1;
2275
2276         if (phdr_dnent == 0
2277             || !contained_within(
2278                    dimage, n_dimage,
2279                    (Addr)phdr_dimg, phdr_dnent * phdr_dent_szB)) {
2280            ML_(symerr)(di, True,
2281                        "Missing or invalid ELF Program Header Table"
2282                        " (debuginfo file)");
2283            goto out;
2284         }
2285
2286         if (shdr_dnent == 0
2287             || !contained_within(
2288                    dimage, n_dimage,
2289                    (Addr)shdr_dimg, shdr_dnent * shdr_dent_szB)) {
2290            ML_(symerr)(di, True,
2291                        "Missing or invalid ELF Section Header Table"
2292                        " (debuginfo file)");
2293            goto out;
2294         }
2295
2296         /* Also find the section header's string table, and validate. */
2297         /* checked previously by is_elf_object_file: */
2298         vg_assert( ehdr_dimg->e_shstrndx != SHN_UNDEF );
2299
2300         shdr_strtab_dimg
2301            = (UChar*)( ((UChar*)ehdr_dimg)
2302                        + shdr_dimg[ehdr_dimg->e_shstrndx].sh_offset);
2303         if (!contained_within(
2304                 dimage, n_dimage,
2305                 (Addr)shdr_strtab_dimg,
2306                 1/*bogus, but we don't know the real size*/ )) {
2307            ML_(symerr)(di, True,
2308                        "Invalid ELF Section Header String Table"
2309                        " (debuginfo file)");
2310            goto out;
2311         }
2312
2313         need_symtab = (NULL == symtab_img);
2314         need_stabs  = (NULL == stab_img);
2315         need_dwarf2 = (NULL == debug_info_img);
2316         need_dwarf1 = (NULL == dwarf1d_img);
2317
2318         for (i = 0; i < ehdr_dimg->e_phnum; i++) {
2319            ElfXX_Phdr* phdr
2320               = INDEX_BIS( (void*)(dimage + ehdr_dimg->e_phoff),
2321                                       i, phdr_ent_szB );
2322            if (phdr->p_type == PT_LOAD) {
2323               if (rx_dsvma_limit == 0
2324                   && phdr->p_offset >= di->fsm.rx_map_foff
2325                   && phdr->p_offset
2326                      < di->fsm.rx_map_foff + di->fsm.rx_map_size
2327                   && phdr->p_offset + phdr->p_filesz
2328                      <= di->fsm.rx_map_foff + di->fsm.rx_map_size) {
2329                  /* rx_dsvma_base = phdr->p_vaddr; */ /* UNUSED */
2330                  rx_dsvma_limit = phdr->p_vaddr + phdr->p_memsz;
2331                  rx_dbias = di->fsm.rx_map_avma - di->fsm.rx_map_foff
2332                             + phdr->p_offset - phdr->p_vaddr;
2333               }
2334               else
2335               if (rw_dsvma_limit == 0
2336                   && phdr->p_offset >= di->fsm.rw_map_foff
2337                   && phdr->p_offset
2338                      < di->fsm.rw_map_foff + di->fsm.rw_map_size
2339                   && phdr->p_offset + phdr->p_filesz
2340                      <= di->fsm.rw_map_foff + di->fsm.rw_map_size) {
2341                  /* rw_dsvma_base = phdr->p_vaddr; */ /* UNUSED */
2342                  rw_dsvma_limit = phdr->p_vaddr + phdr->p_memsz;
2343                  rw_dbias = di->fsm.rw_map_avma - di->fsm.rw_map_foff
2344                             + phdr->p_offset - phdr->p_vaddr;
2345               }
2346            }
2347         }
2348
2349         /* Find all interesting sections */
2350         for (i = 0; i < ehdr_dimg->e_shnum; i++) {
2351
2352            /* Find debug svma and bias information for sections
2353               we found in the main file. */
2354
2355#           define FIND(sec, seg) \
2356            do { ElfXX_Shdr* shdr \
2357                    = INDEX_BIS( shdr_dimg, i, shdr_dent_szB ); \
2358               if (di->sec##_present \
2359                   && 0 == VG_(strcmp)("." #sec, \
2360                                       shdr_strtab_dimg + shdr->sh_name)) { \
2361                  vg_assert(di->sec##_size == shdr->sh_size); \
2362                  vg_assert(di->sec##_avma +  shdr->sh_addr + seg##_dbias); \
2363                  /* Assume we have a correct value for the main */ \
2364                  /* object's bias.  Use that to derive the debuginfo */ \
2365                  /* object's bias, by adding the difference in SVMAs */ \
2366                  /* for the corresponding sections in the two files. */ \
2367                  /* That should take care of all prelinking effects. */ \
2368                  di->sec##_debug_svma = shdr->sh_addr; \
2369                  di->sec##_debug_bias \
2370                     = di->sec##_bias + \
2371                       di->sec##_svma - di->sec##_debug_svma; \
2372                  TRACE_SYMTAB("acquiring ." #sec \
2373                               " debug svma = %#lx .. %#lx\n",       \
2374                               di->sec##_debug_svma, \
2375                               di->sec##_debug_svma + di->sec##_size - 1); \
2376                  TRACE_SYMTAB("acquiring ." #sec " debug bias = %#lx\n", \
2377                               di->sec##_debug_bias); \
2378               } \
2379            } while (0);
2380
2381            /* SECTION   SEGMENT */
2382            FIND(text,   rx)
2383            FIND(data,   rw)
2384            FIND(sdata,  rw)
2385            FIND(rodata, rw)
2386            FIND(bss,    rw)
2387            FIND(sbss,   rw)
2388
2389#           undef FIND
2390
2391            /* Same deal as previous FIND, except only do it for those
2392               sections for which we didn't find anything useful in
2393               the main file. */
2394
2395#           define FIND(condition, sec_name, sec_size, sec_img) \
2396            do { ElfXX_Shdr* shdr \
2397                    = INDEX_BIS( shdr_dimg, i, shdr_dent_szB ); \
2398               if (condition \
2399                   && 0 == VG_(strcmp)(sec_name, \
2400                                       shdr_strtab_dimg + shdr->sh_name)) { \
2401                  Bool nobits; \
2402                  if (0 != sec_img) \
2403                     VG_(core_panic)("repeated section!\n"); \
2404                  sec_img  = (void*)(dimage + shdr->sh_offset); \
2405                  sec_size = shdr->sh_size; \
2406                  nobits   = shdr->sh_type == SHT_NOBITS; \
2407                  TRACE_SYMTAB( "%18s: dimg %p .. %p\n", \
2408                                sec_name, \
2409                                (UChar*)sec_img, \
2410                                ((UChar*)sec_img) + sec_size - 1); \
2411                  /* SHT_NOBITS sections have zero size in the file. */ \
2412                  if ( shdr->sh_offset \
2413                       + (nobits ? 0 : sec_size) > n_dimage ) { \
2414                     ML_(symerr)(di, True, \
2415                                 "   section beyond image end?!"); \
2416                     goto out; \
2417                  } \
2418               } \
2419            } while (0);
2420
2421            /* NEEDED?        NAME             SIZE           IMAGE addr */
2422            FIND(need_symtab, ".symtab",       symtab_sz,     symtab_img)
2423            FIND(need_symtab, ".strtab",       strtab_sz,     strtab_img)
2424            FIND(need_stabs,  ".stab",         stab_sz,       stab_img)
2425            FIND(need_stabs,  ".stabstr",      stabstr_sz,    stabstr_img)
2426            FIND(need_dwarf2, ".debug_line",   debug_line_sz, debug_line_img)
2427            FIND(need_dwarf2, ".debug_info",   debug_info_sz, debug_info_img)
2428            FIND(need_dwarf2, ".debug_abbrev", debug_abbv_sz, debug_abbv_img)
2429            FIND(need_dwarf2, ".debug_str",    debug_str_sz,  debug_str_img)
2430            FIND(need_dwarf2, ".debug_ranges", debug_ranges_sz,
2431                                                            debug_ranges_img)
2432            FIND(need_dwarf2, ".debug_loc",    debug_loc_sz,  debug_loc_img)
2433            FIND(need_dwarf2, ".debug_frame",  debug_frame_sz,
2434                                                            debug_frame_img)
2435            FIND(need_dwarf1, ".debug",        dwarf1d_sz,    dwarf1d_img)
2436            FIND(need_dwarf1, ".line",         dwarf1l_sz,    dwarf1l_img)
2437
2438#           undef FIND
2439         } /* Find all interesting sections */
2440      } /* do we have a debug image? */
2441
2442      /* TOPLEVEL */
2443      /* Check some sizes */
2444      vg_assert((dynsym_sz % sizeof(ElfXX_Sym)) == 0);
2445      vg_assert((symtab_sz % sizeof(ElfXX_Sym)) == 0);
2446
2447      /* Read symbols */
2448      {
2449         void (*read_elf_symtab)(struct _DebugInfo*,UChar*,
2450                                 ElfXX_Sym*,SizeT,
2451                                 UChar*,SizeT,
2452                                 Bool,UChar*);
2453         Bool symtab_in_debug;
2454#        if defined(VGP_ppc64_linux)
2455         read_elf_symtab = read_elf_symtab__ppc64_linux;
2456#        else
2457         read_elf_symtab = read_elf_symtab__normal;
2458#        endif
2459         symtab_in_debug = (Addr)symtab_img >= dimage
2460                           && (Addr)symtab_img < dimage + n_dimage;
2461         read_elf_symtab(di, "symbol table",
2462                         symtab_img, symtab_sz,
2463                         strtab_img, strtab_sz,
2464                         symtab_in_debug, opd_img);
2465
2466         read_elf_symtab(di, "dynamic symbol table",
2467                         dynsym_img, dynsym_sz,
2468                         dynstr_img, dynstr_sz,
2469                         False, opd_img);
2470      } /* Read symbols */
2471
2472      /* TOPLEVEL */
2473      /* Read .eh_frame and .debug_frame (call-frame-info) if any.  Do
2474         the .eh_frame section(s) first. */
2475      vg_assert(di->n_ehframe >= 0 && di->n_ehframe <= N_EHFRAME_SECTS);
2476      for (i = 0; i < di->n_ehframe; i++) {
2477         /* see Comment_on_EH_FRAME_MULTIPLE_INSTANCES above for why
2478            this next assertion should hold. */
2479         vg_assert(ehframe_sz[i] == di->ehframe_size[i]);
2480         ML_(read_callframe_info_dwarf3)( di,
2481                                          ehframe_img[i],
2482                                          ehframe_sz[i],
2483                                          di->ehframe_avma[i],
2484                                          True/*is_ehframe*/ );
2485      }
2486      if (debug_frame_sz) {
2487         ML_(read_callframe_info_dwarf3)( di,
2488                                          debug_frame_img, debug_frame_sz,
2489                                          0/*assume zero avma*/,
2490                                          False/*!is_ehframe*/ );
2491      }
2492
2493      /* Read the stabs and/or dwarf2 debug information, if any.  It
2494         appears reading stabs stuff on amd64-linux doesn't work, so
2495         we ignore it.  On s390x stabs also doesnt work and we always
2496         have the dwarf info in the eh_frame.  We also segfault on
2497         ppc64-linux when reading stabs, so skip that.  ppc32-linux
2498         seems OK though.  Also skip on Android. */
2499#     if !defined(VGP_amd64_linux) \
2500         && !defined(VGP_s390x_linux) \
2501         && !defined(VGP_ppc64_linux) \
2502         && !defined(VGPV_arm_linux_android)
2503      if (stab_img && stabstr_img) {
2504         ML_(read_debuginfo_stabs) ( di, stab_img, stab_sz,
2505                                         stabstr_img, stabstr_sz );
2506      }
2507#     endif
2508      /* jrs 2006-01-01: icc-8.1 has been observed to generate
2509         binaries without debug_str sections.  Don't preclude
2510         debuginfo reading for that reason, but, in
2511         read_unitinfo_dwarf2, do check that debugstr is non-NULL
2512         before using it. */
2513      if (debug_info_img && debug_abbv_img && debug_line_img
2514                                           /* && debug_str_img */) {
2515
2516         /* The old reader: line numbers and unwind info only */
2517         ML_(read_debuginfo_dwarf3) ( di,
2518                                      debug_info_img, debug_info_sz,
2519                                      debug_abbv_img, debug_abbv_sz,
2520                                      debug_line_img, debug_line_sz,
2521                                      debug_str_img,  debug_str_sz );
2522
2523         /* The new reader: read the DIEs in .debug_info to acquire
2524            information on variable types and locations.  But only if
2525            the tool asks for it, or the user requests it on the
2526            command line. */
2527         if (VG_(needs).var_info /* the tool requires it */
2528             || VG_(clo_read_var_info) /* the user asked for it */) {
2529            ML_(new_dwarf3_reader)(
2530               di, debug_info_img,   debug_info_sz,
2531                   debug_abbv_img,   debug_abbv_sz,
2532                   debug_line_img,   debug_line_sz,
2533                   debug_str_img,    debug_str_sz,
2534                   debug_ranges_img, debug_ranges_sz,
2535                   debug_loc_img,    debug_loc_sz
2536            );
2537         }
2538      }
2539      if (dwarf1d_img && dwarf1l_img) {
2540         ML_(read_debuginfo_dwarf1) ( di, dwarf1d_img, dwarf1d_sz,
2541                                          dwarf1l_img, dwarf1l_sz );
2542      }
2543      /* TOPLEVEL */
2544
2545   } /* "Find interesting sections, read the symbol table(s), read any debug
2546        information" (a local scope) */
2547
2548   /* TOPLEVEL */
2549   res = True;
2550
2551   /* If reading Dwarf3 variable type/location info, print a line
2552      showing the number of variables read for each object.
2553      (Currently disabled -- is a sanity-check mechanism for
2554      exp-sgcheck.) */
2555   if (0 && (VG_(needs).var_info || VG_(clo_read_var_info))) {
2556      UWord nVars = 0;
2557      Word  j;
2558      if (di->varinfo) {
2559         for (j = 0; j < VG_(sizeXA)(di->varinfo); j++) {
2560            OSet* /* of DiAddrRange */ scope
2561               = *(OSet**)VG_(indexXA)(di->varinfo, j);
2562            vg_assert(scope);
2563            VG_(OSetGen_ResetIter)( scope );
2564            while (True) {
2565               DiAddrRange* range  = VG_(OSetGen_Next)( scope );
2566               if (!range) break;
2567               vg_assert(range->vars);
2568               Word w = VG_(sizeXA)(range->vars);
2569               vg_assert(w >= 0);
2570               if (0) VG_(printf)("range %#lx %#lx %ld\n",
2571                                  range->aMin, range->aMax, w);
2572               nVars += (UWord)w;
2573            }
2574         }
2575      }
2576      VG_(umsg)("VARINFO: %7lu vars   %7ld text_size   %s\n",
2577                nVars, di->text_size, di->fsm.filename);
2578   }
2579   /* TOPLEVEL */
2580
2581  out:
2582   {
2583      SysRes m_res;
2584      /* Last, but not least, heave the image(s) back overboard. */
2585      if (dimage) {
2586         m_res = VG_(am_munmap_valgrind) ( dimage, n_dimage );
2587         vg_assert(!sr_isError(m_res));
2588      }
2589      m_res = VG_(am_munmap_valgrind) ( oimage, n_oimage );
2590      vg_assert(!sr_isError(m_res));
2591      return res;
2592   } /* out: */
2593
2594   /* NOTREACHED */
2595}
2596
2597#endif // defined(VGO_linux)
2598
2599/*--------------------------------------------------------------------*/
2600/*--- end                                                          ---*/
2601/*--------------------------------------------------------------------*/
2602