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