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