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