Char/HChar fixups for m_debuginfo and m_gdbserver.
[ambi/valgrind.git] / coregrind / m_debuginfo / readelf.c
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
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
148 void show_raw_elf_symbol ( Int i, 
149                            ElfXX_Sym* sym, const HChar* 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 : "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 
206 Bool get_elf_symbol_info ( 
207         /* INPUTS */
208         struct _DebugInfo* di, /* containing DebugInfo */
209         ElfXX_Sym* sym,        /* ELF symbol */
210         HChar*     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         HChar** 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 */
615 void read_elf_symtab__normal( 
616         struct _DebugInfo* di, const HChar* tab_name,
617         ElfXX_Sym* symtab_img, SizeT symtab_szB,
618         HChar*     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    HChar     *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       HChar 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 = 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       HChar* 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
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 */
718 void read_elf_symtab__ppc64_linux( 
719         struct _DebugInfo* di, const HChar* tab_name,
720         ElfXX_Sym* symtab_img, SizeT symtab_szB,
721         HChar*     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    HChar      *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       HChar 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 = 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
905 HChar *find_buildid(Addr image, UWord n_image, Bool rel_ok)
906 {
907    HChar* 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                HChar *name = (HChar *)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                HChar *name = (HChar *)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
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
1061 Addr open_debug_file( const HChar* name, const HChar* buildid, UInt crc,
1062                       Bool rel_ok, /*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       HChar* 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
1130 Bool find_ad_hoc_debug_image( struct _DebugInfo* di, 
1131                               HChar* 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
1208 void find_debug_file( struct _DebugInfo* di,
1209                       const HChar* objpath, const HChar* buildid,
1210                       const HChar* debugname, UInt crc, Bool rel_ok,
1211                       /*OUT*/Addr*  dimage,
1212                       /*OUT*/SizeT* n_dimage )
1213 {
1214    HChar* 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       HChar *objdir = ML_(dinfo_strdup)("di.fdf.2", objpath);
1237       HChar *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             addr = open_debug_file(debugpath, NULL, crc, rel_ok, &size);
1253          }
1254       }
1255
1256       ML_(dinfo_free)(objdir);
1257    }
1258
1259    if (addr > 0 && size > 0) {
1260       TRACE_SYMTAB("\n");
1261       TRACE_SYMTAB("------ Found a debuginfo file: %s\n", debugpath);
1262       *dimage = addr;
1263       *n_dimage = size;
1264    }
1265
1266    ML_(dinfo_free)(debugpath);
1267 }
1268
1269
1270 static Bool contained_within ( Addr outer, UWord n_outer,
1271                                Addr inner, UWord n_inner )
1272 {
1273    if (n_outer == 0 || n_inner == 0)
1274       return False;
1275    /* Simplistic .. assumes no wraparound (reasonably enough) */
1276    if (inner >= outer && inner+n_inner <= outer+n_outer)
1277       return True;
1278    return False;
1279 }
1280
1281 static void* INDEX_BIS ( void* base, Word idx, Word scale ) {
1282    return (void*)( ((UChar*)base) + idx * scale );
1283 }
1284
1285
1286 /* Find the file offset corresponding to SVMA by using the program
1287    headers.  This is taken from binutils-2.17/binutils/readelf.c
1288    offset_from_vma(). */
1289 static
1290 Word file_offset_from_svma ( /*OUT*/Bool* ok,
1291                              Addr         svma,
1292                              ElfXX_Phdr*  phdr_img,
1293                              Word         phdr_nent,
1294                              Word         phdr_ent_szB )
1295 {
1296    Word        i;
1297    ElfXX_Phdr* seg;
1298    for (i = 0; i < phdr_nent; i++) {
1299       seg = INDEX_BIS( phdr_img, i, phdr_ent_szB );
1300       if (seg->p_type != PT_LOAD)
1301          continue;
1302       if (svma >= (seg->p_vaddr & -seg->p_align)
1303           && svma + 1 <= seg->p_vaddr + seg->p_filesz) {
1304          *ok = True;
1305          return svma - seg->p_vaddr + seg->p_offset;
1306       }
1307    }
1308    *ok = False;
1309    return 0;
1310 }
1311
1312
1313 /* The central function for reading ELF debug info.  For the
1314    object/exe specified by the DebugInfo, find ELF sections, then read
1315    the symbols, line number info, file name info, CFA (stack-unwind
1316    info) and anything else we want, into the tables within the
1317    supplied DebugInfo.
1318 */
1319
1320 Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
1321 {
1322    /* This function is long and complex.  That, and the presence of
1323       nested scopes, means it's not always easy to see which parts are
1324       in loops/conditionals and which aren't.  To make it easier to
1325       follow, points executed exactly once -- that is, those which are
1326       the top level of the function -- are marked TOPLEVEL.
1327    */
1328    /* TOPLEVEL */
1329    Bool          res, ok;
1330    SysRes        fd, sres;
1331    Word          i, j;
1332    Bool          dynbss_present = False;
1333    Bool          sdynbss_present = False;
1334
1335    /* Image addresses for the ELF file we're working with. */
1336    Addr          oimage   = 0;
1337    UWord         n_oimage = 0;
1338
1339    /* Ditto for any ELF debuginfo file that we might happen to load. */
1340    Addr          dimage   = 0;
1341    UWord         n_dimage = 0;
1342
1343    /* Ditto for alternate ELF debuginfo file that we might happen to load. */
1344    Addr          aimage   = 0;
1345    UWord         n_aimage = 0;
1346
1347    /* ELF header for the main file.  Should == oimage since is at
1348       start of file. */
1349    ElfXX_Ehdr* ehdr_img = NULL;
1350
1351    /* Program header table image addr, # entries, entry size */
1352    ElfXX_Phdr* phdr_img     = NULL;
1353    UWord       phdr_nent    = 0;
1354    UWord       phdr_ent_szB = 0;
1355
1356    /* Section header image addr, # entries, entry size.  Also the
1357       associated string table. */
1358    ElfXX_Shdr* shdr_img        = NULL;
1359    UWord       shdr_nent       = 0;
1360    UWord       shdr_ent_szB    = 0;
1361    HChar*      shdr_strtab_img = NULL;
1362
1363    /* SVMAs covered by rx and rw segments and corresponding biases.
1364       Normally each object would provide just one rx and one rw area,
1365       but various ELF mangling tools create objects with multiple
1366       such entries, hence the generality. */
1367    typedef
1368       struct {
1369          Addr     svma_base;
1370          Addr     svma_limit;
1371          PtrdiffT bias;
1372          Bool     exec;
1373       }
1374       RangeAndBias;
1375
1376    XArray* /* of RangeAndBias */ svma_ranges = NULL;
1377
1378    /* Build ID */
1379    HChar* buildid = NULL;
1380
1381    vg_assert(di);
1382    vg_assert(di->fsm.have_rx_map == True);
1383    vg_assert(di->fsm.have_rw_map == True);
1384    vg_assert(di->have_dinfo == False);
1385    vg_assert(di->fsm.filename);
1386    vg_assert(!di->symtab);
1387    vg_assert(!di->loctab);
1388    vg_assert(!di->cfsi);
1389    vg_assert(!di->cfsi_exprs);
1390    vg_assert(!di->strchunks);
1391    vg_assert(!di->soname);
1392
1393    {
1394       Bool has_nonempty_rx = False;
1395       Bool has_nonempty_rw = False;
1396       for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1397          struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
1398          if (!map->rx && !map->rw)
1399             continue;
1400          if (map->rx && map->size > 0)
1401             has_nonempty_rx = True;
1402          if (map->rw && map->size > 0)
1403             has_nonempty_rw = True;
1404          /* If this doesn't hold true, it means that m_syswrap/m_aspacemgr
1405             managed to do a mapping where the start isn't page aligned.
1406             Which sounds pretty bogus to me. */
1407          vg_assert(VG_IS_PAGE_ALIGNED(map->avma));
1408       }
1409       vg_assert(has_nonempty_rx);
1410       vg_assert(has_nonempty_rw);
1411    }
1412
1413    /* ----------------------------------------------------------
1414       At this point, there is very little information in the
1415       DebugInfo.  We only know that something that looks like an ELF
1416       file has been mapped rx-ishly and rw-ishly as recorded in the
1417       di->fsm.maps array items.  First we examine the file's ELF
1418       Program Header, and, by comparing that against the di->fsm.maps
1419       info, try to figure out the AVMAs for the sections we care
1420       about, that should have been mapped: text, data, sdata, bss,
1421       got, plt, and toc.
1422       ---------------------------------------------------------- */
1423
1424    res = False;
1425
1426    oimage = (Addr)NULL;
1427    if (VG_(clo_verbosity) > 1 || VG_(clo_trace_redir))
1428       VG_(message)(Vg_DebugMsg, "Reading syms from %s\n",
1429                                 di->fsm.filename );
1430
1431    /* mmap the object image aboard, so that we can read symbols and
1432       line number info out of it.  It will be munmapped immediately
1433       thereafter; it is only aboard transiently. */
1434
1435    fd = VG_(open)(di->fsm.filename, VKI_O_RDONLY, 0);
1436    if (sr_isError(fd)) {
1437       ML_(symerr)(di, True, "Can't open .so/.exe to read symbols?!");
1438       return False;
1439    }
1440
1441    { Long n_oimageLL = VG_(fsize)(sr_Res(fd));
1442      if (n_oimageLL <= 0) {
1443         ML_(symerr)(di, True, "Can't stat .so/.exe (to determine its size)?!");
1444         VG_(close)(sr_Res(fd));
1445         return False;
1446      }
1447      n_oimage = (UWord)(ULong)n_oimageLL;
1448    }
1449
1450    sres = VG_(am_mmap_file_float_valgrind)
1451              ( n_oimage, VKI_PROT_READ, sr_Res(fd), 0 );
1452
1453    VG_(close)(sr_Res(fd));
1454
1455    if (sr_isError(sres)) {
1456       VG_(message)(Vg_UserMsg, "warning: mmap failed on %s\n",
1457                                di->fsm.filename );
1458       VG_(message)(Vg_UserMsg, "         no symbols or debug info loaded\n" );
1459       return False;
1460    }
1461
1462    oimage = sr_Res(sres);
1463    /* Check against wraparound.  am_mmap_file_float_valgrind should
1464       not produce a wrapped-around mapping. */
1465    vg_assert(n_oimage > 0);
1466    vg_assert(oimage + n_oimage > oimage);
1467
1468    if (0) {
1469       VG_(printf)("read_elf_debug_info: OIMAGE = %p - %p\n", 
1470                   (void*)oimage, (void*)(oimage + (UWord)n_oimage));
1471    }
1472
1473    /* Ok, the object image is safely in oimage[0 .. n_oimage-1].  Now
1474       verify that it is a valid ELF .so or executable image. */
1475    res      = False;
1476    ok       = (n_oimage >= sizeof(ElfXX_Ehdr));
1477    ehdr_img = (ElfXX_Ehdr*)oimage;
1478
1479    if (ok)
1480       ok &= ML_(is_elf_object_file)(ehdr_img, n_oimage, False);
1481
1482    if (!ok) {
1483       ML_(symerr)(di, True, "Invalid ELF Header");
1484       goto out;
1485    }
1486
1487    /* Find where the program and section header tables are, and give
1488       up if either is missing or outside the image (bogus). */
1489    phdr_img     = (ElfXX_Phdr*)( ((UChar*)ehdr_img) + ehdr_img->e_phoff );
1490    phdr_nent    = ehdr_img->e_phnum;
1491    phdr_ent_szB = ehdr_img->e_phentsize;
1492
1493    shdr_img     = (ElfXX_Shdr*)( ((UChar*)ehdr_img) + ehdr_img->e_shoff );
1494    shdr_nent    = ehdr_img->e_shnum;
1495    shdr_ent_szB = ehdr_img->e_shentsize;
1496
1497    TRACE_SYMTAB("------ Basic facts about the object ------\n");
1498    TRACE_SYMTAB("object:  img %p n_oimage %ld\n",
1499                (void*)oimage, n_oimage);
1500    TRACE_SYMTAB("phdr:    img %p nent %ld ent_szB %ld\n",
1501                phdr_img, phdr_nent, phdr_ent_szB);
1502    TRACE_SYMTAB("shdr:    img %p nent %ld ent_szB %ld\n",
1503                shdr_img, shdr_nent, shdr_ent_szB);
1504    for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1505       struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
1506       if (map->rx)
1507          TRACE_SYMTAB("rx_map:  avma %#lx   size %lu  foff %lu\n",
1508                       map->avma, map->size, map->foff);
1509    }
1510    for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1511       struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
1512       if (map->rw)
1513          TRACE_SYMTAB("rw_map:  avma %#lx   size %lu  foff %lu\n",
1514                       map->avma, map->size, map->foff);
1515    }
1516
1517    if (phdr_nent == 0
1518        || !contained_within(
1519              oimage, n_oimage,
1520              (Addr)phdr_img, phdr_nent * phdr_ent_szB)) {
1521       ML_(symerr)(di, True, "Missing or invalid ELF Program Header Table");
1522       goto out;
1523    }
1524
1525    if (shdr_nent == 0
1526        || !contained_within(
1527              oimage, n_oimage,
1528              (Addr)shdr_img, shdr_nent * shdr_ent_szB)) {
1529       ML_(symerr)(di, True, "Missing or invalid ELF Section Header Table");
1530       goto out;
1531    }
1532
1533    /* Also find the section header's string table, and validate. */
1534    /* checked previously by is_elf_object_file: */
1535    vg_assert( ehdr_img->e_shstrndx != SHN_UNDEF );
1536
1537    shdr_strtab_img
1538       = ((HChar*)ehdr_img)
1539                   + shdr_img[ehdr_img->e_shstrndx].sh_offset;
1540    if (!contained_within( oimage, n_oimage,
1541                           (Addr)shdr_strtab_img,
1542                           1/*bogus, but we don't know the real size*/ )) {
1543       ML_(symerr)(di, True, "Invalid ELF Section Header String Table");
1544       goto out;
1545    }
1546
1547    TRACE_SYMTAB("shdr:    string table at %p\n", shdr_strtab_img );
1548
1549    svma_ranges = VG_(newXA)(ML_(dinfo_zalloc), "di.relfdi.1",
1550                             ML_(dinfo_free), sizeof(RangeAndBias));
1551
1552    /* TOPLEVEL */
1553    /* Look through the program header table, and:
1554       - copy information from suitable PT_LOAD entries into svma_ranges
1555       - find (or fake up) the .soname for this object.
1556    */
1557    TRACE_SYMTAB("\n");
1558    TRACE_SYMTAB("------ Examining the program headers ------\n");
1559    vg_assert(di->soname == NULL);
1560    {
1561       /* TOPLEVEL */
1562       ElfXX_Addr prev_svma = 0;
1563
1564       for (i = 0; i < phdr_nent; i++) {
1565          ElfXX_Phdr* phdr = INDEX_BIS( phdr_img, i, phdr_ent_szB );
1566
1567          /* Make sure the PT_LOADable entries are in order and
1568             non-overlapping.  This in turn means the address ranges
1569             slurped into svma_ranges are in order and
1570             non-overlapping. */
1571
1572          if (phdr->p_type == PT_LOAD) {
1573             TRACE_SYMTAB("PT_LOAD[%ld]: p_vaddr %#lx (prev %#lx)\n",
1574                          i, (UWord)phdr->p_vaddr, (UWord)prev_svma);
1575             TRACE_SYMTAB("PT_LOAD[%ld]:   p_offset %lu, p_filesz %lu,"
1576                          " perms %c%c%c\n",
1577                          i, (UWord)phdr->p_offset, (UWord)phdr->p_filesz,
1578                          phdr->p_flags & PF_R ? 'r' : '-',
1579                          phdr->p_flags & PF_W ? 'w' : '-',
1580                          phdr->p_flags & PF_X ? 'x' : '-');
1581             if (phdr->p_vaddr < prev_svma) {
1582                ML_(symerr)(di, True,
1583                            "ELF Program Headers are not in ascending order");
1584                goto out;
1585             }
1586             prev_svma = phdr->p_vaddr;
1587             if (phdr->p_memsz > 0) {
1588                Bool loaded = False;
1589                for (j = 0; j < VG_(sizeXA)(di->fsm.maps); j++) {
1590                   struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, j);
1591                   if (   (map->rx || map->rw)
1592                       && phdr->p_offset >= map->foff
1593                       && phdr->p_offset <  map->foff + map->size
1594                       && phdr->p_offset + phdr->p_filesz <= map->foff
1595                                                             + map->size) {
1596                      RangeAndBias item;
1597                      item.svma_base  = phdr->p_vaddr;
1598                      item.svma_limit = phdr->p_vaddr + phdr->p_memsz;
1599                      item.bias       = map->avma - map->foff
1600                                        + phdr->p_offset - phdr->p_vaddr;
1601                      if (   map->rw
1602                          && (phdr->p_flags & (PF_R | PF_W)) == (PF_R | PF_W)) {
1603                         item.exec = False;
1604                         VG_(addToXA)(svma_ranges, &item);
1605                         TRACE_SYMTAB("PT_LOAD[%ld]:   acquired as rw\n", i);
1606                         loaded = True;
1607                      }
1608                      if (   map->rx
1609                          && (phdr->p_flags & (PF_R | PF_X)) == (PF_R | PF_X)) {
1610                         item.exec = True;
1611                         VG_(addToXA)(svma_ranges, &item);
1612                         TRACE_SYMTAB("PT_LOAD[%ld]:   acquired as rx\n", i);
1613                         loaded = True;
1614                      }
1615                   }
1616                }
1617                if (!loaded) {
1618                   ML_(symerr)(di, False,
1619                               "ELF section outside all mapped regions");
1620                   goto out;
1621                }
1622             }
1623          }
1624
1625          /* Try to get the soname.  If there isn't one, use "NONE".
1626             The seginfo needs to have some kind of soname in order to
1627             facilitate writing redirect functions, since all redirect
1628             specifications require a soname (pattern). */
1629          if (phdr->p_type == PT_DYNAMIC && di->soname == NULL) {
1630             ElfXX_Dyn* dyn_img = (ElfXX_Dyn*)( ((UChar*)ehdr_img)
1631                                                + phdr->p_offset);
1632             Word   stroff = -1;
1633             HChar* strtab = NULL;
1634             for (j = 0; dyn_img[j].d_tag != DT_NULL; j++) {
1635                switch (dyn_img[j].d_tag) {
1636                   case DT_SONAME: {
1637                      stroff = dyn_img[j].d_un.d_val;
1638                      break;
1639                   }
1640                   case DT_STRTAB: {
1641                      Bool ok2 = False;
1642                      Word offset = file_offset_from_svma(
1643                                       &ok2,
1644                                       dyn_img[j].d_un.d_ptr,
1645                                       phdr_img,
1646                                       phdr_nent, phdr_ent_szB
1647                                    );
1648                      if (ok2 && strtab == NULL) {
1649                         vg_assert(offset >= 0 && offset <= n_oimage);
1650                         strtab = ((HChar*)ehdr_img) + offset;
1651                      }
1652                      break;
1653                   }
1654                   default:
1655                      break;
1656                }
1657             }
1658             if (stroff != -1 && strtab != NULL) {
1659                TRACE_SYMTAB("Found soname = %s\n", strtab+stroff);
1660                di->soname = ML_(dinfo_strdup)("di.redi.1", strtab+stroff);
1661             }
1662          }
1663       } /* for (i = 0; i < phdr_nent; i++) ... */
1664       /* TOPLEVEL */
1665
1666    } /* examine the program headers (local scope) */
1667
1668    /* TOPLEVEL */
1669
1670    /* If, after looking at all the program headers, we still didn't 
1671       find a soname, add a fake one. */
1672    if (di->soname == NULL) {
1673       TRACE_SYMTAB("No soname found; using (fake) \"NONE\"\n");
1674       di->soname = ML_(dinfo_strdup)("di.redi.2", "NONE");
1675    }
1676
1677    vg_assert(VG_(sizeXA)(svma_ranges) != 0);
1678
1679    /* Now read the section table. */
1680    TRACE_SYMTAB("\n");
1681    TRACE_SYMTAB("------ Examining the section headers ------\n");
1682    for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1683       struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
1684       if (map->rx)
1685          TRACE_SYMTAB("rx: at %#lx are mapped foffsets %ld .. %ld\n",
1686                       map->avma, map->foff, map->foff + map->size - 1 );
1687    }
1688    TRACE_SYMTAB("rx: contains these svma regions:\n");
1689    for (i = 0; i < VG_(sizeXA)(svma_ranges); i++) {
1690       RangeAndBias* reg = VG_(indexXA)(svma_ranges, i);
1691       if (reg->exec)
1692          TRACE_SYMTAB("  svmas %#lx .. %#lx with bias %#lx\n",
1693                       reg->svma_base, reg->svma_limit - 1, reg->bias );
1694    }
1695    for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1696       struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
1697       if (map->rw)
1698          TRACE_SYMTAB("rw: at %#lx are mapped foffsets %ld .. %ld\n",
1699                       map->avma, map->foff, map->foff + map->size - 1 );
1700    }
1701    TRACE_SYMTAB("rw: contains these svma regions:\n");
1702    for (i = 0; i < VG_(sizeXA)(svma_ranges); i++) {
1703       RangeAndBias* reg = VG_(indexXA)(svma_ranges, i);
1704       if (!reg->exec)
1705          TRACE_SYMTAB("  svmas %#lx .. %#lx with bias %#lx\n",
1706                       reg->svma_base, reg->svma_limit - 1, reg->bias );
1707    }
1708
1709    /* TOPLEVEL */
1710    /* Iterate over section headers */
1711    for (i = 0; i < shdr_nent; i++) {
1712       ElfXX_Shdr* shdr = INDEX_BIS( shdr_img, i, shdr_ent_szB );
1713       HChar* name = shdr_strtab_img + shdr->sh_name;
1714       Addr   svma = shdr->sh_addr;
1715       OffT   foff = shdr->sh_offset;
1716       UWord  size = shdr->sh_size; /* Do not change this to be signed. */
1717       UInt   alyn = shdr->sh_addralign;
1718       Bool   bits = !(shdr->sh_type == SHT_NOBITS);
1719       /* Look through our collection of info obtained from the PT_LOAD
1720          headers, and make 'inrx' and 'inrw' point to the first entry
1721          in each that intersects 'avma'.  If in each case none is found,
1722          leave the relevant pointer at NULL. */
1723       RangeAndBias* inrx = NULL;
1724       RangeAndBias* inrw = NULL;
1725       for (j = 0; j < VG_(sizeXA)(svma_ranges); j++) {
1726          RangeAndBias* rng = VG_(indexXA)(svma_ranges, j);
1727          if (svma >= rng->svma_base && svma < rng->svma_limit) {
1728             if (!inrx && rng->exec) {
1729                inrx = rng;
1730             } else if (!inrw && !rng->exec) {
1731                inrw = rng;
1732             }
1733             if (inrx && inrw)
1734                break;
1735          }
1736       }
1737
1738       TRACE_SYMTAB(" [sec %2ld]  %s %s  al%2u  foff %6ld .. %6ld  "
1739                   "  svma %p  name \"%s\"\n", 
1740                   i, inrx ? "rx" : "  ", inrw ? "rw" : "  ", alyn,
1741                   foff, foff+size-1, (void*)svma, name );
1742
1743       /* Check for sane-sized segments.  SHT_NOBITS sections have zero
1744          size in the file. */
1745       if ((foff >= n_oimage) || (foff + (bits ? size : 0) > n_oimage)) {
1746          ML_(symerr)(di, True, "ELF Section extends beyond image end");
1747          goto out;
1748       }
1749
1750       /* Check for a sane alignment value. */
1751       if (alyn > 0 && -1 == VG_(log2)(alyn)) {
1752          ML_(symerr)(di, True, "ELF Section contains invalid "
1753                                ".sh_addralign value");
1754          goto out;
1755       }
1756
1757       /* Ignore zero sized sections. */
1758       if (size == 0) {
1759          TRACE_SYMTAB("zero sized section \"%s\", ignoring\n", name);
1760          continue;
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 && !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 && !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 && !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 && !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 && !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 && 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 && !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) && !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                                                       : "(null?!)" );
1936             }
1937          } else
1938
1939          if ((!inrw) && (!inrx) && !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 && !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 && 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 && !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 && !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 && !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 && !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 && !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 && !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 && !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 && 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 && 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       HChar*     strtab_img       = NULL; /* .strtab */
2141       ElfXX_Sym* symtab_img       = NULL; /* .symtab */
2142       HChar*     dynstr_img       = NULL; /* .dynstr */
2143       ElfXX_Sym* dynsym_img       = NULL; /* .dynsym */
2144       HChar*     debuglink_img    = NULL; /* .gnu_debuglink */
2145       UChar*     debugaltlink_img = NULL; /* .gnu_debugaltlink */
2146       UChar*     stab_img         = NULL; /* .stab         (stabs)  */
2147       HChar*     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       HChar*     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       HChar*     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, (HChar *)(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)((UChar *)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                                        (HChar *)(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                                        (HChar *)(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)((HChar *)debugaltlink_img)+1;
2531
2532          vg_assert(buildid_offset < debugaltlink_sz);
2533
2534          HChar *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                                     (HChar *)(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*, const HChar*,
2630                                  ElfXX_Sym*,SizeT,
2631                                  HChar*,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 /*--------------------------------------------------------------------*/