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