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-2013 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_machine.h"      /* VG_ELF_CLASS */
     41 #include "pub_core_options.h"
     42 #include "pub_core_oset.h"
     43 #include "pub_core_tooliface.h"    /* VG_(needs) */
     44 #include "pub_core_xarray.h"
     45 #include "priv_misc.h"             /* dinfo_zalloc/free/strdup */
     46 #include "priv_image.h"
     47 #include "priv_d3basics.h"
     48 #include "priv_tytypes.h"
     49 #include "priv_storage.h"
     50 #include "priv_readelf.h"          /* self */
     51 #include "priv_readdwarf.h"        /* 'cos ELF contains DWARF */
     52 #include "priv_readdwarf3.h"
     53 #include "priv_readexidx.h"
     54 
     55 /* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
     56 #include <elf.h>
     57 /* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
     58 
     59 /*------------------------------------------------------------*/
     60 /*--- 32/64-bit parameterisation                           ---*/
     61 /*------------------------------------------------------------*/
     62 
     63 /* For all the ELF macros and types which specify '32' or '64',
     64    select the correct variant for this platform and give it
     65    an 'XX' name.  Then use the 'XX' variant consistently in
     66    the rest of this file.
     67 */
     68 #if VG_WORDSIZE == 4
     69 #  define  ElfXX_Ehdr     Elf32_Ehdr
     70 #  define  ElfXX_Shdr     Elf32_Shdr
     71 #  define  ElfXX_Phdr     Elf32_Phdr
     72 #  define  ElfXX_Nhdr     Elf32_Nhdr
     73 #  define  ElfXX_Sym      Elf32_Sym
     74 #  define  ElfXX_Off      Elf32_Off
     75 #  define  ElfXX_Word     Elf32_Word
     76 #  define  ElfXX_Addr     Elf32_Addr
     77 #  define  ElfXX_Dyn      Elf32_Dyn
     78 #  define  ELFXX_ST_BIND  ELF32_ST_BIND
     79 #  define  ELFXX_ST_TYPE  ELF32_ST_TYPE
     80 
     81 #elif VG_WORDSIZE == 8
     82 #  define  ElfXX_Ehdr     Elf64_Ehdr
     83 #  define  ElfXX_Shdr     Elf64_Shdr
     84 #  define  ElfXX_Phdr     Elf64_Phdr
     85 #  define  ElfXX_Nhdr     Elf64_Nhdr
     86 #  define  ElfXX_Sym      Elf64_Sym
     87 #  define  ElfXX_Off      Elf64_Off
     88 #  define  ElfXX_Word     Elf64_Word
     89 #  define  ElfXX_Addr     Elf64_Addr
     90 #  define  ElfXX_Dyn      Elf64_Dyn
     91 #  define  ELFXX_ST_BIND  ELF64_ST_BIND
     92 #  define  ELFXX_ST_TYPE  ELF64_ST_TYPE
     93 
     94 #else
     95 # error "VG_WORDSIZE should be 4 or 8"
     96 #endif
     97 
     98 
     99 /*------------------------------------------------------------*/
    100 /*---                                                      ---*/
    101 /*--- Read symbol table and line info from ELF files.      ---*/
    102 /*---                                                      ---*/
    103 /*------------------------------------------------------------*/
    104 
    105 /* readelf.c parses ELF files and acquires symbol table info from
    106    them.  It calls onwards to readdwarf.c to read DWARF2/3 line number
    107    and call frame info found. */
    108 
    109 /* Identify an ELF object file by peering at the first few bytes of
    110    it. */
    111 
    112 Bool ML_(is_elf_object_file)( const void* image, SizeT n_image, Bool rel_ok )
    113 {
    114    const ElfXX_Ehdr* ehdr = image;
    115    Int ok = 1;
    116 
    117    if (n_image < sizeof(ElfXX_Ehdr))
    118       return False;
    119 
    120    ok &= (ehdr->e_ident[EI_MAG0] == 0x7F
    121           && ehdr->e_ident[EI_MAG1] == 'E'
    122           && ehdr->e_ident[EI_MAG2] == 'L'
    123           && ehdr->e_ident[EI_MAG3] == 'F');
    124    ok &= (ehdr->e_ident[EI_CLASS] == VG_ELF_CLASS
    125           && ehdr->e_ident[EI_DATA] == VG_ELF_DATA2XXX
    126           && ehdr->e_ident[EI_VERSION] == EV_CURRENT);
    127    ok &= (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN
    128           || (rel_ok && ehdr->e_type == ET_REL));
    129    ok &= (ehdr->e_machine == VG_ELF_MACHINE);
    130    ok &= (ehdr->e_version == EV_CURRENT);
    131    ok &= (ehdr->e_shstrndx != SHN_UNDEF);
    132    ok &= (ehdr->e_shoff != 0 && ehdr->e_shnum != 0);
    133    ok &= ((ehdr->e_phoff != 0 && ehdr->e_phnum != 0)
    134           || ehdr->e_type == ET_REL);
    135 
    136    return ok ? True : False;
    137 }
    138 
    139 
    140 /* The same thing, but operating on a DiImage instead. */
    141 
    142 static Bool is_elf_object_file_by_DiImage( DiImage* img, Bool rel_ok )
    143 {
    144    /* Be sure this doesn't make the frame too big. */
    145    vg_assert(sizeof(ElfXX_Ehdr) <= 512);
    146 
    147    ElfXX_Ehdr ehdr;
    148    if (!ML_(img_valid)(img, 0, sizeof(ehdr)))
    149       return False;
    150 
    151    ML_(img_get)(&ehdr, img, 0, sizeof(ehdr));
    152    return ML_(is_elf_object_file)( &ehdr, sizeof(ehdr), rel_ok );
    153 }
    154 
    155 
    156 /* Show a raw ELF symbol, given its in-image address and name. */
    157 
    158 static
    159 void show_raw_elf_symbol ( DiImage* strtab_img,
    160                            Int i,
    161                            const ElfXX_Sym* sym,
    162                            DiOffT sym_name_ioff, Addr sym_svma,
    163                            Bool ppc64_linux_format )
    164 {
    165    const HChar* space = ppc64_linux_format ? "                  " : "";
    166    VG_(printf)("raw symbol [%4d]: ", i);
    167    switch (ELFXX_ST_BIND(sym->st_info)) {
    168       case STB_LOCAL:  VG_(printf)("LOC "); break;
    169       case STB_GLOBAL: VG_(printf)("GLO "); break;
    170       case STB_WEAK:   VG_(printf)("WEA "); break;
    171       case STB_LOPROC: VG_(printf)("lop "); break;
    172       case STB_HIPROC: VG_(printf)("hip "); break;
    173       default:         VG_(printf)("??? "); break;
    174    }
    175    switch (ELFXX_ST_TYPE(sym->st_info)) {
    176       case STT_NOTYPE:  VG_(printf)("NOT "); break;
    177       case STT_OBJECT:  VG_(printf)("OBJ "); break;
    178       case STT_FUNC:    VG_(printf)("FUN "); break;
    179       case STT_SECTION: VG_(printf)("SEC "); break;
    180       case STT_FILE:    VG_(printf)("FIL "); break;
    181       case STT_LOPROC:  VG_(printf)("lop "); break;
    182       case STT_HIPROC:  VG_(printf)("hip "); break;
    183       default:          VG_(printf)("??? "); break;
    184    }
    185    HChar* sym_name = NULL;
    186    if (sym->st_name)
    187       sym_name = ML_(img_strdup)(strtab_img, "di.sres.1", sym_name_ioff);
    188    VG_(printf)(": svma %#010lx, %ssz %4llu  %s\n",
    189                sym_svma, space, (ULong)(sym->st_size + 0UL),
    190                (sym_name ? sym_name : "NONAME") );
    191    if (sym_name)
    192       ML_(dinfo_free)(sym_name);
    193 }
    194 
    195 
    196 /* Decide whether SYM is something we should collect, and if so, copy
    197    relevant info to the _OUT arguments.  For {x86,amd64,ppc32}-linux
    198    this is straightforward - the name, address, size are copied out
    199    unchanged.
    200 
    201    There is a bit of a kludge re data symbols (see KLUDGED BSS CHECK
    202    below): we assume that the .bss is mapped immediately after .data,
    203    and so accept any data symbol which exists in the range [start of
    204    .data, size of .data + size of .bss).  I don't know if this is
    205    really correct/justifiable, or not.
    206 
    207    For ppc64be-linux it's more complex.  If the symbol is seen to be in
    208    the .opd section, it is taken to be a function descriptor, and so
    209    a dereference is attempted, in order to get hold of the real entry
    210    point address.  Also as part of the dereference, there is an attempt
    211    to calculate the TOC pointer (R2 value) associated with the symbol.
    212 
    213    To support the ppc64be-linux pre-"dotless" ABI (prior to gcc 4.0.0),
    214    if the symbol is seen to be outside the .opd section and its name
    215    starts with a dot, an .opd deference is not attempted, and no TOC
    216    pointer is calculated, but the leading dot is removed from the
    217    name.
    218 
    219    As a result, on ppc64be-linux, the caller of this function may have
    220    to piece together the real size, address, name of the symbol from
    221    multiple calls to this function.  Ugly and confusing.
    222 */
    223 static
    224 Bool get_elf_symbol_info (
    225         /* INPUTS */
    226         struct _DebugInfo* di, /* containing DebugInfo */
    227         const ElfXX_Sym* sym,        /* ELF symbol */
    228         DiOffT     sym_name_ioff, /* name, may be absent (DiOffT_INVALID) */
    229         const DiSlice*   escn_strtab,   /* holds the name */
    230         Addr       sym_svma,   /* address as stated in the object file */
    231         Bool       symtab_in_debug, /* symbol table is in the debug file */
    232         const DiSlice*   escn_opd,   /* the .opd (ppc64be-linux only) */
    233         PtrdiffT   opd_bias,   /* for biasing AVMAs found in .opd */
    234         /* OUTPUTS */
    235         DiOffT* sym_name_out_ioff, /* name (in strtab) we should record */
    236         SymAVMAs* sym_avmas_out,     /* sym avmas we should record */
    237         Int*    sym_size_out,   /* symbol size */
    238         Bool*   from_opd_out,   /* ppc64be-linux only: did we deref an
    239                                   .opd entry? */
    240         Bool*   is_text_out,    /* is this a text symbol? */
    241         Bool*   is_ifunc        /* is this a  STT_GNU_IFUNC function ?*/
    242      )
    243 {
    244    Bool plausible;
    245 #  if defined(VGP_ppc64be_linux)
    246    Bool is_in_opd;
    247 #  endif
    248    Bool in_text, in_data, in_sdata, in_rodata, in_bss, in_sbss;
    249    Addr text_svma, data_svma, sdata_svma, rodata_svma, bss_svma, sbss_svma;
    250    PtrdiffT text_bias, data_bias, sdata_bias, rodata_bias, bss_bias, sbss_bias;
    251 
    252    /* Set defaults */
    253    *sym_name_out_ioff = sym_name_ioff;
    254    (*sym_avmas_out).main   = sym_svma; /* we will bias this shortly */
    255    *is_text_out       = True;
    256    SET_TOCPTR_AVMA(*sym_avmas_out, 0);   /* default to unknown/inapplicable */
    257    SET_LOCAL_EP_AVMA(*sym_avmas_out, 0); /* default to unknown/inapplicable */
    258    *from_opd_out      = False;
    259    *is_ifunc          = False;
    260 
    261    /* Get the symbol size, but restrict it to fit in a signed 32 bit
    262       int.  Also, deal with the stupid case of negative size by making
    263       the size be 1.  Note that sym->st_size has type UWord,
    264       effectively. */
    265    { Word size_tmp = (Word)sym->st_size;
    266      Word max_Int  = (1LL << 31) - 1;
    267      if (size_tmp < 0)       size_tmp = 1;
    268      if (size_tmp > max_Int) size_tmp = max_Int;
    269      *sym_size_out = (Int)size_tmp;
    270    }
    271    /* After this point refer only to *sym_size_out and not to
    272       sym->st_size. */
    273 
    274    /* Figure out if we're interested in the symbol.  Firstly, is it of
    275       the right flavour?  */
    276    plausible
    277       = (ELFXX_ST_BIND(sym->st_info) == STB_GLOBAL
    278          || ELFXX_ST_BIND(sym->st_info) == STB_LOCAL
    279          || ELFXX_ST_BIND(sym->st_info) == STB_WEAK
    280         )
    281         &&
    282         (ELFXX_ST_TYPE(sym->st_info) == STT_FUNC
    283          || ELFXX_ST_TYPE(sym->st_info) == STT_OBJECT
    284 #        ifdef STT_GNU_IFUNC
    285          || ELFXX_ST_TYPE(sym->st_info) == STT_GNU_IFUNC
    286 #        endif
    287         );
    288 
    289    /* Work out the svma and bias for each section as it will appear in
    290       addresses in the symbol table. */
    291    if (symtab_in_debug) {
    292       text_svma = di->text_debug_svma;
    293       text_bias = di->text_debug_bias;
    294       data_svma = di->data_debug_svma;
    295       data_bias = di->data_debug_bias;
    296       sdata_svma = di->sdata_debug_svma;
    297       sdata_bias = di->sdata_debug_bias;
    298       rodata_svma = di->rodata_debug_svma;
    299       rodata_bias = di->rodata_debug_bias;
    300       bss_svma = di->bss_debug_svma;
    301       bss_bias = di->bss_debug_bias;
    302       sbss_svma = di->sbss_debug_svma;
    303       sbss_bias = di->sbss_debug_bias;
    304    } else {
    305       text_svma = di->text_svma;
    306       text_bias = di->text_bias;
    307       data_svma = di->data_svma;
    308       data_bias = di->data_bias;
    309       sdata_svma = di->sdata_svma;
    310       sdata_bias = di->sdata_bias;
    311       rodata_svma = di->rodata_svma;
    312       rodata_bias = di->rodata_bias;
    313       bss_svma = di->bss_svma;
    314       bss_bias = di->bss_bias;
    315       sbss_svma = di->sbss_svma;
    316       sbss_bias = di->sbss_bias;
    317    }
    318 
    319    /* Now bias (*sym_avmas_out).main accordingly by figuring out exactly which
    320       section the symbol is from and bias accordingly.  Screws up if
    321       the previously deduced section svma address ranges are wrong. */
    322    if (di->text_present
    323        && di->text_size > 0
    324        && sym_svma >= text_svma
    325        && sym_svma < text_svma + di->text_size) {
    326       *is_text_out = True;
    327       (*sym_avmas_out).main += text_bias;
    328    } else
    329    if (di->data_present
    330        && di->data_size > 0
    331        && sym_svma >= data_svma
    332        && sym_svma < data_svma + di->data_size) {
    333       *is_text_out = False;
    334       (*sym_avmas_out).main += data_bias;
    335    } else
    336    if (di->sdata_present
    337        && di->sdata_size > 0
    338        && sym_svma >= sdata_svma
    339        && sym_svma < sdata_svma + di->sdata_size) {
    340       *is_text_out = False;
    341       (*sym_avmas_out).main += sdata_bias;
    342    } else
    343    if (di->rodata_present
    344        && di->rodata_size > 0
    345        && sym_svma >= rodata_svma
    346        && sym_svma < rodata_svma + di->rodata_size) {
    347       *is_text_out = False;
    348       (*sym_avmas_out).main += rodata_bias;
    349    } else
    350    if (di->bss_present
    351        && di->bss_size > 0
    352        && sym_svma >= bss_svma
    353        && sym_svma < bss_svma + di->bss_size) {
    354       *is_text_out = False;
    355       (*sym_avmas_out).main += bss_bias;
    356    } else
    357    if (di->sbss_present
    358        && di->sbss_size > 0
    359        && sym_svma >= sbss_svma
    360        && sym_svma < sbss_svma + di->sbss_size) {
    361       *is_text_out = False;
    362       (*sym_avmas_out).main += sbss_bias;
    363    } else {
    364       /* Assume it's in .text.  Is this a good idea? */
    365       *is_text_out = True;
    366       (*sym_avmas_out).main += text_bias;
    367    }
    368 
    369 #  ifdef STT_GNU_IFUNC
    370    /* Check for indirect functions. */
    371    if (*is_text_out
    372        && ELFXX_ST_TYPE(sym->st_info) == STT_GNU_IFUNC) {
    373        *is_ifunc = True;
    374    }
    375 #  endif
    376 
    377 #  if defined(VGP_ppc64be_linux)
    378    /* Allow STT_NOTYPE in the very special case where we're running on
    379       ppc64be-linux and the symbol is one which the .opd-chasing hack
    380       below will chase. */
    381    if (!plausible
    382        && *is_text_out
    383        && ELFXX_ST_TYPE(sym->st_info) == STT_NOTYPE
    384        && *sym_size_out > 0
    385        && di->opd_present
    386        && di->opd_size > 0
    387        && (*sym_avmas_out).main >= di->opd_avma
    388        && (*sym_avmas_out).main <  di->opd_avma + di->opd_size)
    389       plausible = True;
    390 #  endif
    391 
    392    if (!plausible)
    393       return False;
    394 
    395    /* Ignore if nameless. */
    396    if (sym_name_ioff == DiOffT_INVALID
    397        || /* VG_(strlen)(sym_name) == 0 */
    398           /* equivalent but cheaper ... */
    399           ML_(img_get_UChar)(escn_strtab->img, sym_name_ioff) == '\0') {
    400       if (TRACE_SYMTAB_ENABLED) {
    401          HChar* sym_name = ML_(img_strdup)(escn_strtab->img,
    402                                            "di.gesi.1", sym_name_ioff);
    403          TRACE_SYMTAB("    ignore -- nameless: %s\n", sym_name);
    404          if (sym_name) ML_(dinfo_free)(sym_name);
    405       }
    406       return False;
    407    }
    408 
    409    /* Ignore if zero-sized.  Except on Android:
    410 
    411       On Android 2.3.5, some of the symbols that Memcheck needs to
    412       intercept (for noise reduction purposes) have zero size, due to
    413       lack of .size directives in handwritten assembly sources.  So we
    414       can't reject them out of hand -- instead give them a bogusly
    415       large size and let canonicaliseSymtab trim them so they don't
    416       overlap any following symbols.  At least the following symbols
    417       are known to be affected:
    418 
    419       in /system/lib/libc.so: strlen strcmp strcpy memcmp memcpy
    420       in /system/bin/linker:  __dl_strcmp __dl_strlen
    421    */
    422    if (*sym_size_out == 0) {
    423 #     if defined(VGPV_arm_linux_android) \
    424          || defined(VGPV_x86_linux_android) \
    425          || defined(VGPV_mips32_linux_android) \
    426          || defined(VGPV_arm64_linux_android)
    427       *sym_size_out = 2048;
    428 #     else
    429       if (TRACE_SYMTAB_ENABLED) {
    430          HChar* sym_name = ML_(img_strdup)(escn_strtab->img,
    431                                            "di.gesi.2", sym_name_ioff);
    432          TRACE_SYMTAB("    ignore -- size=0: %s\n", sym_name);
    433          if (sym_name) ML_(dinfo_free)(sym_name);
    434       }
    435       return False;
    436 #     endif
    437    }
    438 
    439    /* This seems to significantly reduce the number of junk
    440       symbols, and particularly reduces the number of
    441       overlapping address ranges.  Don't ask me why ... */
    442    if ((Int)sym->st_value == 0) {
    443       if (TRACE_SYMTAB_ENABLED) {
    444          HChar* sym_name = ML_(img_strdup)(escn_strtab->img,
    445                                            "di.gesi.3", sym_name_ioff);
    446          TRACE_SYMTAB( "    ignore -- valu=0: %s\n", sym_name);
    447          if (sym_name) ML_(dinfo_free)(sym_name);
    448       }
    449       return False;
    450    }
    451 
    452    /* If it's apparently in a GOT or PLT, it's really a reference to a
    453       symbol defined elsewhere, so ignore it. */
    454    if (di->got_present
    455        && di->got_size > 0
    456        && (*sym_avmas_out).main >= di->got_avma
    457        && (*sym_avmas_out).main <  di->got_avma + di->got_size) {
    458       if (TRACE_SYMTAB_ENABLED) {
    459          HChar* sym_name = ML_(img_strdup)(escn_strtab->img,
    460                                            "di.gesi.4", sym_name_ioff);
    461          TRACE_SYMTAB("    ignore -- in GOT: %s\n", sym_name);
    462          if (sym_name) ML_(dinfo_free)(sym_name);
    463       }
    464       return False;
    465    }
    466    if (di->plt_present
    467        && di->plt_size > 0
    468        && (*sym_avmas_out).main >= di->plt_avma
    469        && (*sym_avmas_out).main <  di->plt_avma + di->plt_size) {
    470       if (TRACE_SYMTAB_ENABLED) {
    471          HChar* sym_name = ML_(img_strdup)(escn_strtab->img,
    472                                            "di.gesi.5", sym_name_ioff);
    473          TRACE_SYMTAB("    ignore -- in PLT: %s\n", sym_name);
    474          if (sym_name) ML_(dinfo_free)(sym_name);
    475       }
    476       return False;
    477    }
    478 
    479    /* ppc64be-linux nasty hack: if the symbol is in an .opd section,
    480       then really what we have is the address of a function
    481       descriptor.  So use the first word of that as the function's
    482       text.
    483 
    484       See thread starting at
    485       http://gcc.gnu.org/ml/gcc-patches/2004-08/msg00557.html
    486    */
    487 #  if defined(VGP_ppc64be_linux)
    488    /* Host and guest may have different Endianess, used by BE only */
    489    is_in_opd = False;
    490 #  endif
    491 
    492    if (di->opd_present
    493        && di->opd_size > 0
    494        && (*sym_avmas_out).main >= di->opd_avma
    495        && (*sym_avmas_out).main <  di->opd_avma + di->opd_size) {
    496 #     if !defined(VGP_ppc64be_linux)
    497       if (TRACE_SYMTAB_ENABLED) {
    498          HChar* sym_name = ML_(img_strdup)(escn_strtab->img,
    499                                            "di.gesi.6", sym_name_ioff);
    500          TRACE_SYMTAB("    ignore -- in OPD: %s\n", sym_name);
    501          if (sym_name) ML_(dinfo_free)(sym_name);
    502       }
    503       return False;
    504 #     else
    505       Int    offset_in_opd;
    506       Bool   details = 1||False;
    507 
    508       if (details)
    509          TRACE_SYMTAB("opdXXX: opd_bias %p, sym_svma_out %p\n",
    510                       (void*)(opd_bias), (void*)(*sym_avmas_out).main);
    511 
    512       if (!VG_IS_8_ALIGNED((*sym_avmas_out).main)) {
    513          if (TRACE_SYMTAB_ENABLED) {
    514             HChar* sym_name = ML_(img_strdup)(escn_strtab->img,
    515                                               "di.gesi.6a", sym_name_ioff);
    516             TRACE_SYMTAB("    ignore -- not 8-aligned: %s\n", sym_name);
    517             if (sym_name) ML_(dinfo_free)(sym_name);
    518          }
    519          return False;
    520       }
    521 
    522       /* (*sym_avmas_out).main is a avma pointing into the .opd section.  We
    523          know the vma of the opd section start, so we can figure out
    524          how far into the opd section this is. */
    525 
    526       offset_in_opd = (Addr)(*sym_avmas_out).main - (Addr)(di->opd_avma);
    527       if (offset_in_opd < 0 || offset_in_opd >= di->opd_size) {
    528          if (TRACE_SYMTAB_ENABLED) {
    529             HChar* sym_name = ML_(img_strdup)(escn_strtab->img,
    530                                               "di.gesi.6a", sym_name_ioff);
    531             TRACE_SYMTAB("    ignore -- invalid OPD offset: %s\n", sym_name);
    532             if (sym_name) ML_(dinfo_free)(sym_name);
    533          }
    534          return False;
    535       }
    536 
    537       /* Now we want to know what's at that offset in the .opd
    538          section.  We can't look in the running image since it won't
    539          necessarily have been mapped.  But we can consult the oimage.
    540          opd_img is the start address of the .opd in the oimage.
    541          Hence: */
    542 
    543       ULong fn_descr[2]; /* is actually 3 words, but we need only 2 */
    544       if (!ML_(img_valid)(escn_opd->img, escn_opd->ioff + offset_in_opd,
    545                           sizeof(fn_descr))) {
    546          if (TRACE_SYMTAB_ENABLED) {
    547             HChar* sym_name = ML_(img_strdup)(escn_strtab->img,
    548                                               "di.gesi.6b", sym_name_ioff);
    549             TRACE_SYMTAB("    ignore -- invalid OPD fn_descr offset: %s\n",
    550                          sym_name);
    551             if (sym_name) ML_(dinfo_free)(sym_name);
    552 
    553          }
    554          return False;
    555       }
    556 
    557       /* This can't fail now, because we just checked the offset
    558          above. */
    559       ML_(img_get)(&fn_descr[0], escn_opd->img,
    560                    escn_opd->ioff + offset_in_opd, sizeof(fn_descr));
    561 
    562       if (details)
    563          TRACE_SYMTAB("opdXXY: offset %d,  fn_descr %p\n",
    564                       offset_in_opd, fn_descr);
    565       if (details)
    566          TRACE_SYMTAB("opdXXZ: *fn_descr %p\n", (void*)(fn_descr[0]));
    567 
    568       /* opd_bias is the what we have to add to SVMAs found in .opd to
    569          get plausible .text AVMAs for the entry point, and .data
    570          AVMAs (presumably) for the TOC locations.  We use the caller
    571          supplied value (which is di->text_bias) for both of these.
    572          Not sure why that is correct - it seems to work, and sounds
    573          OK for fn_descr[0], but surely we need to use the data bias
    574          and not the text bias for fn_descr[1] ?  Oh Well.
    575       */
    576       (*sym_avmas_out).main   = fn_descr[0] + opd_bias;
    577       SET_TOCPTR_AVMA(*sym_avmas_out, fn_descr[1] + opd_bias);
    578       *from_opd_out   = True;
    579       is_in_opd = True;
    580 
    581       /* Do a final sanity check: if the symbol falls outside the
    582          DebugInfo's mapped range, ignore it.  Since (*sym_avmas_out).main has
    583          been updated, that can be achieved simply by falling through
    584          to the test below. */
    585 
    586 #     endif /* ppc64-linux nasty hack */
    587    }
    588 
    589    /* Here's yet another ppc64-linux hack.  Get rid of leading dot if
    590       the symbol is outside .opd. */
    591 #  if defined(VGP_ppc64be_linux)
    592    if (di->opd_size > 0
    593        && !is_in_opd
    594        && *sym_name_out_ioff != DiOffT_INVALID
    595        && ML_(img_get_UChar)(escn_strtab->img, *sym_name_out_ioff) == '.') {
    596       vg_assert(!(*from_opd_out));
    597       (*sym_name_out_ioff)++;
    598    }
    599 #  endif
    600 
    601    /* If no part of the symbol falls within the mapped range,
    602       ignore it. */
    603 
    604    in_text
    605       = di->text_present
    606         && di->text_size > 0
    607         && !((*sym_avmas_out).main + *sym_size_out <= di->text_avma
    608              || (*sym_avmas_out).main >= di->text_avma + di->text_size);
    609 
    610    in_data
    611       = di->data_present
    612         && di->data_size > 0
    613         && !((*sym_avmas_out).main + *sym_size_out <= di->data_avma
    614              || (*sym_avmas_out).main >= di->data_avma + di->data_size);
    615 
    616    in_sdata
    617       = di->sdata_present
    618         && di->sdata_size > 0
    619         && !((*sym_avmas_out).main + *sym_size_out <= di->sdata_avma
    620              || (*sym_avmas_out).main >= di->sdata_avma + di->sdata_size);
    621 
    622    in_rodata
    623       = di->rodata_present
    624         && di->rodata_size > 0
    625         && !((*sym_avmas_out).main + *sym_size_out <= di->rodata_avma
    626              || (*sym_avmas_out).main >= di->rodata_avma + di->rodata_size);
    627 
    628    in_bss
    629       = di->bss_present
    630         && di->bss_size > 0
    631         && !((*sym_avmas_out).main + *sym_size_out <= di->bss_avma
    632              || (*sym_avmas_out).main >= di->bss_avma + di->bss_size);
    633 
    634    in_sbss
    635       = di->sbss_present
    636         && di->sbss_size > 0
    637         && !((*sym_avmas_out).main + *sym_size_out <= di->sbss_avma
    638              || (*sym_avmas_out).main >= di->sbss_avma + di->sbss_size);
    639 
    640 
    641    if (*is_text_out) {
    642       /* This used to reject any symbol falling outside the text
    643          segment ("if (!in_text) ...").  Now it is relaxed slightly,
    644          to reject only symbols which fall outside the area mapped
    645          r-x.  This is in accordance with r7427.  See
    646          "Comment_Regarding_Text_Range_Checks" in storage.c for
    647          background. */
    648       Bool in_rx;
    649       vg_assert(di->fsm.have_rx_map);
    650       /* This could actually wrap around and cause
    651          ML_(find_rx_mapping) to assert.  But that seems so unlikely,
    652          let's wait for it to happen before fixing it. */
    653       in_rx = (ML_(find_rx_mapping)(
    654                       di,
    655                       (*sym_avmas_out).main,
    656                       (*sym_avmas_out).main + *sym_size_out) != NULL);
    657       if (in_text)
    658          vg_assert(in_rx);
    659       if (!in_rx) {
    660          TRACE_SYMTAB(
    661             "ignore -- %#lx .. %#lx outside .text svma range %#lx .. %#lx\n",
    662             (*sym_avmas_out).main, (*sym_avmas_out).main + *sym_size_out,
    663             di->text_avma,
    664             di->text_avma + di->text_size);
    665          return False;
    666       }
    667    } else {
    668      if (!(in_data || in_sdata || in_rodata || in_bss || in_sbss)) {
    669          TRACE_SYMTAB(
    670             "ignore -- %#lx .. %#lx outside .data / .sdata / .rodata "
    671             "/ .bss / .sbss svma ranges\n",
    672             (*sym_avmas_out).main, (*sym_avmas_out).main + *sym_size_out);
    673          return False;
    674       }
    675    }
    676 
    677 #  if defined(VGP_ppc64be_linux)
    678    if (di->opd_present && di->opd_size > 0) {
    679       vg_assert((*sym_avmas_out).main + *sym_size_out <= di->opd_avma
    680                 || (*sym_avmas_out).main >= di->opd_avma + di->opd_size);
    681    }
    682 #endif
    683 
    684 #  if defined(VGP_ppc64le_linux)
    685    /* PPC64 LE ABI uses three bits in the st_other field to indicate the number
    686     * of instructions between the function's global and local entry points. An
    687     * offset of 0 indicates that there is one entry point.  The value must be:
    688     *
    689     * 0 - one entry point, local and global are the same
    690     * 1 - reserved
    691     * 2 - local entry point is one instruction after the global entry point
    692     * 3 - local entry point is two instructions after the global entry point
    693     * 4 - local entry point is four instructions after the global entry point
    694     * 5 - local entry point is eight instructions after the global entry point
    695     * 6 - local entry point is sixteen instructions after the global entry point
    696     * 7 - reserved
    697     *
    698     *  Extract the three bit field from the other field is done by:
    699     *        (other_field & STO_PPC64_LOCAL_MASK) >> STO_PPC_LOCAL_BIT
    700     *
    701     *  where the #define values are given in include/elf/powerpc.h file for
    702     *  the PPC binutils.
    703     *
    704     * conversion of the three bit field to bytes is given by
    705     *
    706     *       ((1 << bit_field) >> 2) << 2
    707     */
    708 
    709    #define STO_PPC64_LOCAL_BIT             5
    710    #define STO_PPC64_LOCAL_MASK            (7 << STO_PPC64_LOCAL_BIT)
    711    {
    712       unsigned int bit_field, dist_to_local_entry;
    713       /* extract the other filed */
    714       bit_field = (sym->st_other & STO_PPC64_LOCAL_MASK) >> STO_PPC64_LOCAL_BIT;
    715 
    716       if ((bit_field > 0) && (bit_field < 7)) {
    717          /* store the local entry point address */
    718          dist_to_local_entry = ((1 << bit_field) >> 2) << 2;
    719          SET_LOCAL_EP_AVMA(*sym_avmas_out,
    720                            (*sym_avmas_out).main + dist_to_local_entry);
    721 
    722          if (TRACE_SYMTAB_ENABLED) {
    723             HChar* sym_name = ML_(img_strdup)(escn_strtab->img,
    724                                              "di.gesi.5", sym_name_ioff);
    725             VG_(printf)("Local entry point: %s at %#010x\n",
    726 			sym_name,
    727                         (unsigned int)GET_LOCAL_EP_AVMA(*sym_avmas_out));
    728          }
    729       }
    730    }
    731 #  endif
    732 
    733    /* Acquire! */
    734    return True;
    735 }
    736 
    737 
    738 /* Read an ELF symbol table (normal or dynamic).  This one is for the
    739    "normal" case ({x86,amd64,ppc32,arm,mips32,mips64, ppc64le}-linux). */
    740 static
    741 __attribute__((unused)) /* not referred to on all targets */
    742 void read_elf_symtab__normal(
    743         struct _DebugInfo* di, const HChar* tab_name,
    744         DiSlice*   escn_symtab,
    745         DiSlice*   escn_strtab,
    746         DiSlice*   escn_opd, /* ppc64be-linux only */
    747         Bool       symtab_in_debug
    748      )
    749 {
    750    if (escn_strtab->img == NULL || escn_symtab->img == NULL) {
    751       HChar buf[VG_(strlen)(tab_name) + 40];
    752       VG_(sprintf)(buf, "   object doesn't have a %s", tab_name);
    753       ML_(symerr)(di, False, buf);
    754       return;
    755    }
    756 
    757    TRACE_SYMTAB("\n--- Reading (ELF, standard) %s (%lld entries) ---\n",
    758                 tab_name, escn_symtab->szB/sizeof(ElfXX_Sym) );
    759 
    760    /* Perhaps should start at i = 1; ELF docs suggest that entry
    761       0 always denotes 'unknown symbol'. */
    762    Word i;
    763    for (i = 1; i < (Word)(escn_symtab->szB/sizeof(ElfXX_Sym)); i++) {
    764       ElfXX_Sym sym;
    765       ML_(img_get)(&sym, escn_symtab->img,
    766                    escn_symtab->ioff + i * sizeof(ElfXX_Sym), sizeof(sym));
    767       DiOffT sym_name = escn_strtab->ioff + sym.st_name;
    768       Addr   sym_svma = sym.st_value;
    769 
    770       if (di->trace_symtab)
    771         show_raw_elf_symbol(escn_strtab->img, i,
    772                             &sym, sym_name, sym_svma, False);
    773 
    774       SymAVMAs sym_avmas_really;
    775       Int    sym_size = 0;
    776       Bool   from_opd = False, is_text = False, is_ifunc = False;
    777       DiOffT sym_name_really = DiOffT_INVALID;
    778       sym_avmas_really.main = 0;
    779       SET_TOCPTR_AVMA(sym_avmas_really, 0);
    780       SET_LOCAL_EP_AVMA(sym_avmas_really, 0);
    781       if (get_elf_symbol_info(di, &sym, sym_name, escn_strtab,
    782                               sym_svma, symtab_in_debug,
    783                               escn_opd, di->text_bias,
    784                               &sym_name_really,
    785                               &sym_avmas_really,
    786                               &sym_size,
    787                               &from_opd, &is_text, &is_ifunc)) {
    788 
    789          DiSym  disym;
    790          VG_(memset)(&disym, 0, sizeof(disym));
    791          HChar* cstr = ML_(img_strdup)(escn_strtab->img,
    792                                        "di.res__n.1", sym_name_really);
    793          disym.avmas  = sym_avmas_really;
    794          disym.pri_name  = ML_(addStr) ( di, cstr, -1 );
    795          disym.sec_names = NULL;
    796          disym.size      = sym_size;
    797          disym.isText    = is_text;
    798          disym.isIFunc   = is_ifunc;
    799          if (cstr) { ML_(dinfo_free)(cstr); cstr = NULL; }
    800          vg_assert(disym.pri_name);
    801          vg_assert(GET_TOCPTR_AVMA(disym.avmas) == 0);
    802          /* has no role except on ppc64be-linux */
    803          ML_(addSym) ( di, &disym );
    804 
    805          if (TRACE_SYMTAB_ENABLED) {
    806             TRACE_SYMTAB("    rec(%c) [%4ld]:          "
    807                          "  val %#010lx, sz %4d  %s\n",
    808                          is_text ? 't' : 'd',
    809                          i,
    810                          disym.avmas.main,
    811                          (Int)disym.size,
    812                          disym.pri_name
    813             );
    814 	    if (GET_LOCAL_EP_AVMA(disym.avmas) != 0) {
    815                TRACE_SYMTAB("               local entry point %#010lx\n",
    816                             GET_LOCAL_EP_AVMA(disym.avmas));
    817 	    }
    818          }
    819 
    820       }
    821    }
    822 }
    823 
    824 
    825 /* Read an ELF symbol table (normal or dynamic).  This one is for
    826    ppc64be-linux, which requires special treatment. */
    827 
    828 typedef
    829    struct {
    830       Addr   addr;
    831       DiOffT name;
    832       /* We have to store also the DiImage* so as to give context for
    833          |name|.  This is not part of the key (in terms of lookup) but
    834          there's no easy other way to do this.  Ugly. */
    835       DiImage* img;
    836    }
    837    TempSymKey;
    838 
    839 typedef
    840    struct {
    841       TempSymKey key;
    842       Addr       tocptr;
    843       Int        size;
    844       Bool       from_opd;
    845       Bool       is_text;
    846       Bool       is_ifunc;
    847    }
    848    TempSym;
    849 
    850 static Word cmp_TempSymKey ( const TempSymKey* key1, const TempSym* elem2 )
    851 {
    852    /* Stay sane ... */
    853    vg_assert(key1->img == elem2->key.img);
    854    vg_assert(key1->img != NULL);
    855    if (key1->addr < elem2->key.addr) return -1;
    856    if (key1->addr > elem2->key.addr) return 1;
    857    vg_assert(key1->name != DiOffT_INVALID);
    858    vg_assert(elem2->key.name != DiOffT_INVALID);
    859    return (Word)ML_(img_strcmp)(key1->img, key1->name, elem2->key.name);
    860 }
    861 
    862 static
    863 __attribute__((unused)) /* not referred to on all targets */
    864 void read_elf_symtab__ppc64be_linux(
    865         struct _DebugInfo* di, const HChar* tab_name,
    866         DiSlice*   escn_symtab,
    867         DiSlice*   escn_strtab,
    868         DiSlice*   escn_opd, /* ppc64be-linux only */
    869         Bool       symtab_in_debug
    870      )
    871 {
    872    Word        i;
    873    Int         old_size;
    874    Bool        modify_size, modify_tocptr;
    875    OSet       *oset;
    876    TempSymKey  key;
    877    TempSym    *elem;
    878    TempSym    *prev;
    879 
    880    if (escn_strtab->img == NULL || escn_symtab->img == NULL) {
    881       HChar buf[VG_(strlen)(tab_name) + 40];
    882       VG_(sprintf)(buf, "   object doesn't have a %s", tab_name);
    883       ML_(symerr)(di, False, buf);
    884       return;
    885    }
    886 
    887    TRACE_SYMTAB("\n--- Reading (ELF, ppc64be-linux) %s (%lld entries) ---\n",
    888                 tab_name, escn_symtab->szB/sizeof(ElfXX_Sym) );
    889 
    890    oset = VG_(OSetGen_Create)( offsetof(TempSym,key),
    891                                (OSetCmp_t)cmp_TempSymKey,
    892                                ML_(dinfo_zalloc), "di.respl.1",
    893                                ML_(dinfo_free) );
    894 
    895    /* Perhaps should start at i = 1; ELF docs suggest that entry
    896       0 always denotes 'unknown symbol'. */
    897    for (i = 1; i < (Word)(escn_symtab->szB/sizeof(ElfXX_Sym)); i++) {
    898       ElfXX_Sym sym;
    899       ML_(img_get)(&sym, escn_symtab->img,
    900                    escn_symtab->ioff + i * sizeof(ElfXX_Sym), sizeof(sym));
    901       DiOffT sym_name = escn_strtab->ioff + sym.st_name;
    902       Addr   sym_svma = sym.st_value;
    903 
    904       if (di->trace_symtab)
    905          show_raw_elf_symbol(escn_strtab->img, i,
    906                              &sym, sym_name, sym_svma, True);
    907 
    908       SymAVMAs sym_avmas_really;
    909       Int    sym_size = 0;
    910       Bool   from_opd = False, is_text = False, is_ifunc = False;
    911       DiOffT sym_name_really = DiOffT_INVALID;
    912       DiSym  disym;
    913       VG_(memset)(&disym, 0, sizeof(disym));
    914       sym_avmas_really.main = 0;
    915       SET_TOCPTR_AVMA(sym_avmas_really, 0);
    916       SET_LOCAL_EP_AVMA(sym_avmas_really, 0);
    917       if (get_elf_symbol_info(di, &sym, sym_name, escn_strtab,
    918                               sym_svma, symtab_in_debug,
    919                               escn_opd, di->text_bias,
    920                               &sym_name_really,
    921                               &sym_avmas_really,
    922                               &sym_size,
    923                               &from_opd, &is_text, &is_ifunc)) {
    924 
    925          /* Check if we've seen this (name,addr) key before. */
    926          key.addr = sym_avmas_really.main;
    927          key.name = sym_name_really;
    928          key.img  = escn_strtab->img;
    929          prev = VG_(OSetGen_Lookup)( oset, &key );
    930 
    931          if (prev) {
    932 
    933             /* Seen it before.  Fold in whatever new info we can. */
    934             modify_size   = False;
    935             modify_tocptr = False;
    936             old_size   = 0;
    937 
    938             if (prev->from_opd && !from_opd
    939                 && (prev->size == 24 || prev->size == 16)
    940                 && sym_size != prev->size) {
    941                /* Existing one is an opd-redirect, with a bogus size,
    942                   so the only useful new fact we have is the real size
    943                   of the symbol. */
    944                modify_size = True;
    945                old_size = prev->size;
    946                prev->size = sym_size;
    947             }
    948             else
    949             if (!prev->from_opd && from_opd
    950                 && (sym_size == 24 || sym_size == 16)) {
    951                /* Existing one is non-opd, new one is opd.  What we
    952                   can acquire from the new one is the TOC ptr to be
    953                   used.  Since the existing sym is non-toc, it
    954                   shouldn't currently have an known TOC ptr. */
    955                vg_assert(prev->tocptr == 0);
    956                modify_tocptr = True;
    957                prev->tocptr = GET_TOCPTR_AVMA(sym_avmas_really);
    958             }
    959             else {
    960                /* ignore. can we do better here? */
    961             }
    962 
    963             /* Only one or the other is possible (I think) */
    964             vg_assert(!(modify_size && modify_tocptr));
    965 
    966             if (modify_size && di->trace_symtab) {
    967                VG_(printf)("    modify (old sz %4d)    "
    968                            " val %#010lx, toc %#010lx, sz %4d  %lld\n",
    969                            old_size,
    970                            prev->key.addr,
    971                            prev->tocptr,
    972                            (Int)  prev->size,
    973                            (ULong)prev->key.name
    974                );
    975             }
    976             if (modify_tocptr && di->trace_symtab) {
    977                VG_(printf)("    modify (upd tocptr)     "
    978                            " val %#010lx, toc %#010lx, sz %4d  %lld\n",
    979                            prev->key.addr,
    980                            prev->tocptr,
    981                            (Int)  prev->size,
    982                            (ULong)prev->key.name
    983                );
    984             }
    985 
    986          } else {
    987 
    988             /* A new (name,addr) key.  Add and continue. */
    989             elem = VG_(OSetGen_AllocNode)(oset, sizeof(TempSym));
    990             elem->key      = key;
    991             elem->tocptr   = GET_TOCPTR_AVMA(sym_avmas_really);
    992             elem->size     = sym_size;
    993             elem->from_opd = from_opd;
    994             elem->is_text  = is_text;
    995             elem->is_ifunc = is_ifunc;
    996             VG_(OSetGen_Insert)(oset, elem);
    997             if (di->trace_symtab) {
    998                HChar* str = ML_(img_strdup)(escn_strtab->img, "di.respl.2",
    999                                             elem->key.name);
   1000                VG_(printf)("   to-oset [%4ld]:          "
   1001                            "  val %#010lx, toc %#010lx, sz %4d  %s\n",
   1002                            i,
   1003                            elem->key.addr,
   1004                            elem->tocptr,
   1005                            (Int)  elem->size,
   1006                            str
   1007                );
   1008                if (str) ML_(dinfo_free)(str);
   1009             }
   1010 
   1011          }
   1012       }
   1013    }
   1014 
   1015    /* All the syms that matter are in the oset.  Now pull them out,
   1016       build a "standard" symbol table, and nuke the oset. */
   1017 
   1018    i = 0;
   1019    VG_(OSetGen_ResetIter)( oset );
   1020 
   1021    while ( (elem = VG_(OSetGen_Next)(oset)) ) {
   1022       DiSym disym;
   1023       VG_(memset)(&disym, 0, sizeof(disym));
   1024       HChar* cstr = ML_(img_strdup)(escn_strtab->img,
   1025                                     "di.res__ppc64.1", elem->key.name);
   1026       disym.avmas.main = elem->key.addr;
   1027       SET_TOCPTR_AVMA(disym.avmas, elem->tocptr);
   1028       SET_LOCAL_EP_AVMA(disym.avmas, 0); // ppc64be does not use local_ep.
   1029       disym.pri_name  = ML_(addStr) ( di, cstr, -1 );
   1030       disym.sec_names = NULL;
   1031       disym.size      = elem->size;
   1032       disym.isText    = elem->is_text;
   1033       disym.isIFunc   = elem->is_ifunc;
   1034       if (cstr) { ML_(dinfo_free)(cstr); cstr = NULL; }
   1035       vg_assert(disym.pri_name != NULL);
   1036 
   1037       ML_(addSym) ( di, &disym );
   1038       if (di->trace_symtab) {
   1039          VG_(printf)("    rec(%c) [%4ld]:          "
   1040                      "   val %#010lx, toc %#010lx, sz %4d  %s\n",
   1041                      disym.isText ? 't' : 'd',
   1042                      i,
   1043                      disym.avmas.main,
   1044                      GET_TOCPTR_AVMA(disym.avmas),
   1045                      (Int)   disym.size,
   1046                      disym.pri_name
   1047                );
   1048       }
   1049       i++;
   1050    }
   1051 
   1052    VG_(OSetGen_Destroy)( oset );
   1053 }
   1054 
   1055 
   1056 /*
   1057  * Look for a build-id in an ELF image. The build-id specification
   1058  * can be found here:
   1059  *
   1060  * http://fedoraproject.org/wiki/RolandMcGrath/BuildID
   1061  *
   1062  * Returned string must be freed by the caller.
   1063  */
   1064 static
   1065 HChar* find_buildid(DiImage* img, Bool rel_ok, Bool search_shdrs)
   1066 {
   1067    HChar* buildid = NULL;
   1068 
   1069 #  ifdef NT_GNU_BUILD_ID
   1070    if (is_elf_object_file_by_DiImage(img, rel_ok)) {
   1071       Word i;
   1072 
   1073       ElfXX_Ehdr ehdr;
   1074       ML_(img_get)(&ehdr, img, 0, sizeof(ehdr));
   1075       for (i = 0; i < ehdr.e_phnum; i++) {
   1076          ElfXX_Phdr phdr;
   1077          ML_(img_get)(&phdr, img,
   1078                       ehdr.e_phoff + i * ehdr.e_phentsize, sizeof(phdr));
   1079 
   1080          if (phdr.p_type == PT_NOTE) {
   1081             ElfXX_Off note_ioff = phdr.p_offset;
   1082 
   1083             while (note_ioff < phdr.p_offset + phdr.p_filesz) {
   1084                ElfXX_Nhdr note;
   1085                ML_(img_get)(&note, img, (DiOffT)note_ioff, sizeof(note));
   1086                DiOffT name_ioff = note_ioff + sizeof(ElfXX_Nhdr);
   1087                DiOffT desc_ioff = name_ioff + ((note.n_namesz + 3) & ~3);
   1088                if (ML_(img_strcmp_c)(img, name_ioff, ELF_NOTE_GNU) == 0
   1089                    && note.n_type == NT_GNU_BUILD_ID) {
   1090                   buildid = ML_(dinfo_zalloc)("di.fbi.1",
   1091                                               note.n_descsz * 2 + 1);
   1092                   Word j;
   1093                   for (j = 0; j < note.n_descsz; j++) {
   1094                      UChar desc_j = ML_(img_get_UChar)(img, desc_ioff + j);
   1095                      VG_(sprintf)(buildid + VG_(strlen)(buildid),
   1096                                   "%02x", (UInt)desc_j);
   1097                   }
   1098                }
   1099 
   1100                note_ioff = note_ioff + sizeof(ElfXX_Nhdr)
   1101                                      + ((note.n_namesz + 3) & ~3)
   1102                                      + ((note.n_descsz + 3) & ~3);
   1103             }
   1104          }
   1105       }
   1106 
   1107       /* Normally we would only search shdrs for ET_REL files, but when
   1108          we search for a separate .debug file phdrs might not be there
   1109          (they are never loaded) or have been corrupted, so try again
   1110          against shdrs. */
   1111       if (buildid || (!rel_ok && !search_shdrs))
   1112          return buildid;
   1113 
   1114       for (i = 0; i < ehdr.e_shnum; i++) {
   1115          ElfXX_Shdr shdr;
   1116          ML_(img_get)(&shdr, img,
   1117                       ehdr.e_shoff + i * ehdr.e_shentsize, sizeof(shdr));
   1118 
   1119          if (shdr.sh_type == SHT_NOTE) {
   1120             ElfXX_Off note_ioff = shdr.sh_offset;
   1121 
   1122             while (note_ioff < shdr.sh_offset + shdr.sh_size) {
   1123                ElfXX_Nhdr note;
   1124                ML_(img_get)(&note, img, (DiOffT)note_ioff, sizeof(note));
   1125                DiOffT name_ioff = note_ioff + sizeof(ElfXX_Nhdr);
   1126                DiOffT desc_ioff = name_ioff + ((note.n_namesz + 3) & ~3);
   1127 
   1128                if (ML_(img_strcmp_c)(img, name_ioff, ELF_NOTE_GNU) == 0
   1129                    && note.n_type == NT_GNU_BUILD_ID) {
   1130                   buildid = ML_(dinfo_zalloc)("di.fbi.2",
   1131                                               note.n_descsz * 2 + 1);
   1132                   Word j;
   1133                   for (j = 0; j < note.n_descsz; j++) {
   1134                      UChar desc_j = ML_(img_get_UChar)(img, desc_ioff + j);
   1135                      VG_(sprintf)(buildid + VG_(strlen)(buildid),
   1136                                   "%02x", (UInt)desc_j);
   1137                   }
   1138                }
   1139 
   1140                note_ioff = note_ioff + sizeof(ElfXX_Nhdr)
   1141                                      + ((note.n_namesz + 3) & ~3)
   1142                                      + ((note.n_descsz + 3) & ~3);
   1143             }
   1144          }
   1145       }
   1146    }
   1147 #  endif /* def NT_GNU_BUILD_ID */
   1148 
   1149    return buildid;
   1150 }
   1151 
   1152 
   1153 /* Try and open a separate debug file, ignoring any where the CRC does
   1154    not match the value from the main object file.  Returned DiImage
   1155    must be discarded by the caller.
   1156 
   1157    If |serverAddr| is NULL, |name| is expected to be a fully qualified
   1158    (absolute) path to the file in the local filesystem.  If
   1159    |serverAddr| is non-NULL, it is expected to be an IPv4 and port
   1160    spec of the form "d.d.d.d:d" or "d.d.d.d", and |name| is expected
   1161    to be a plain filename (no path components at all).
   1162  */
   1163 static
   1164 DiImage* open_debug_file( const HChar* name, const HChar* buildid, UInt crc,
   1165                           Bool rel_ok, const HChar* serverAddr )
   1166 {
   1167    DiImage* dimg
   1168      = serverAddr ? ML_(img_from_di_server)(name, serverAddr)
   1169                   : ML_(img_from_local_file)(name);
   1170    if (dimg == NULL)
   1171       return NULL;
   1172 
   1173    if (VG_(clo_verbosity) > 1) {
   1174       if (serverAddr)
   1175          VG_(message)(Vg_DebugMsg, "  Considering %s on server %s ..\n",
   1176                                    name, serverAddr);
   1177       else
   1178          VG_(message)(Vg_DebugMsg, "  Considering %s ..\n", name);
   1179    }
   1180 
   1181    /* We will always check the crc if we have one (altfiles don't have one)
   1182       for now because we might be opening the main file again by any other
   1183       name, and that obviously also has the same buildid. More efficient
   1184       would be an fstat bases check or a check that the file actually
   1185       contains .debug* sections. */
   1186    if (buildid && crc == 0) {
   1187       HChar* debug_buildid = find_buildid(dimg, rel_ok, True);
   1188       if (debug_buildid == NULL || VG_(strcmp)(buildid, debug_buildid) != 0) {
   1189          ML_(img_done)(dimg);
   1190          if (VG_(clo_verbosity) > 1)
   1191             VG_(message)(Vg_DebugMsg,
   1192                "  .. build-id mismatch (found %s wanted %s)\n",
   1193                debug_buildid, buildid);
   1194          ML_(dinfo_free)(debug_buildid);
   1195          return NULL;
   1196       }
   1197       ML_(dinfo_free)(debug_buildid);
   1198       if (VG_(clo_verbosity) > 1)
   1199          VG_(message)(Vg_DebugMsg, "  .. build-id is valid\n");
   1200    } else {
   1201       UInt calccrc = ML_(img_calc_gnu_debuglink_crc32)(dimg);
   1202       if (calccrc != crc) {
   1203          ML_(img_done)(dimg);
   1204          if (VG_(clo_verbosity) > 1)
   1205             VG_(message)(Vg_DebugMsg,
   1206                "  .. CRC mismatch (computed %08x wanted %08x)\n", calccrc, crc);
   1207          return NULL;
   1208       }
   1209 
   1210       if (VG_(clo_verbosity) > 1)
   1211          VG_(message)(Vg_DebugMsg, "  .. CRC is valid\n");
   1212    }
   1213 
   1214    return dimg;
   1215 }
   1216 
   1217 
   1218 /* Try to find a separate debug file for a given object file.  If
   1219    found, return its DiImage, which should be freed by the caller.  If
   1220    |buildid| is non-NULL, then a debug object matching it is
   1221    acceptable.  If |buildid| is NULL or doesn't specify a findable
   1222    debug object, then we look in various places to find a file with
   1223    the specified CRC.  And if that doesn't work out then we give
   1224    up. */
   1225 static
   1226 DiImage* find_debug_file( struct _DebugInfo* di,
   1227                           const HChar* objpath, const HChar* buildid,
   1228                           const HChar* debugname, UInt crc, Bool rel_ok )
   1229 {
   1230    const HChar* extrapath  = VG_(clo_extra_debuginfo_path);
   1231    const HChar* serverpath = VG_(clo_debuginfo_server);
   1232 
   1233    DiImage* dimg      = NULL; /* the img that we found */
   1234    HChar*   debugpath = NULL; /* where we found it */
   1235 
   1236    if (buildid != NULL) {
   1237       debugpath = ML_(dinfo_zalloc)("di.fdf.1",
   1238                                     VG_(strlen)(buildid) + 33);
   1239 
   1240       VG_(sprintf)(debugpath, "/usr/lib/debug/.build-id/%c%c/%s.debug",
   1241                    buildid[0], buildid[1], buildid + 2);
   1242 
   1243       dimg = open_debug_file(debugpath, buildid, 0, rel_ok, NULL);
   1244       if (!dimg) {
   1245          ML_(dinfo_free)(debugpath);
   1246          debugpath = NULL;
   1247       }
   1248    }
   1249 
   1250    if (dimg == NULL && debugname != NULL) {
   1251       HChar *objdir = ML_(dinfo_strdup)("di.fdf.2", objpath);
   1252       HChar *objdirptr;
   1253 
   1254       if ((objdirptr = VG_(strrchr)(objdir, '/')) != NULL)
   1255          *objdirptr = '\0';
   1256 
   1257       debugpath = ML_(dinfo_zalloc)(
   1258                      "di.fdf.3",
   1259                      VG_(strlen)(objdir) + VG_(strlen)(debugname) + 64
   1260                      + (extrapath ? VG_(strlen)(extrapath) : 0)
   1261                      + (serverpath ? VG_(strlen)(serverpath) : 0));
   1262 
   1263       VG_(sprintf)(debugpath, "%s/%s", objdir, debugname);
   1264       dimg = open_debug_file(debugpath, buildid, crc, rel_ok, NULL);
   1265       if (dimg != NULL) goto dimg_ok;
   1266 
   1267       VG_(sprintf)(debugpath, "%s/.debug/%s", objdir, debugname);
   1268       dimg = open_debug_file(debugpath, buildid, crc, rel_ok, NULL);
   1269       if (dimg != NULL) goto dimg_ok;
   1270 
   1271       VG_(sprintf)(debugpath, "/usr/lib/debug%s/%s", objdir, debugname);
   1272       dimg = open_debug_file(debugpath, buildid, crc, rel_ok, NULL);
   1273       if (dimg != NULL) goto dimg_ok;
   1274 
   1275       if (extrapath) {
   1276          VG_(sprintf)(debugpath, "%s%s/%s", extrapath,
   1277                                             objdir, debugname);
   1278          dimg = open_debug_file(debugpath, buildid, crc, rel_ok, NULL);
   1279          if (dimg != NULL) goto dimg_ok;
   1280       }
   1281 
   1282       if (serverpath) {
   1283          /* When looking on the debuginfo server, always just pass the
   1284             basename. */
   1285          const HChar* basename = debugname;
   1286          if (VG_(strstr)(basename, "/") != NULL) {
   1287             basename = VG_(strrchr)(basename, '/') + 1;
   1288          }
   1289          VG_(sprintf)(debugpath, "%s on %s", basename, serverpath);
   1290          dimg = open_debug_file(basename, buildid, crc, rel_ok, serverpath);
   1291          if (dimg) goto dimg_ok;
   1292       }
   1293 
   1294       dimg_ok:
   1295 
   1296       ML_(dinfo_free)(objdir);
   1297    }
   1298 
   1299    if (dimg != NULL) {
   1300       vg_assert(debugpath);
   1301       TRACE_SYMTAB("\n");
   1302       TRACE_SYMTAB("------ Found a debuginfo file: %s\n", debugpath);
   1303 
   1304       /* Only set once, we might be called again for opening the altfile. */
   1305       if (di->fsm.dbgname == NULL)
   1306          di->fsm.dbgname = ML_(dinfo_strdup)("di.fdf.4", debugpath);
   1307    }
   1308 
   1309    if (debugpath)
   1310       ML_(dinfo_free)(debugpath);
   1311 
   1312    return dimg;
   1313 }
   1314 
   1315 
   1316 /* Try to find a separate debug file for a given object file, in a
   1317    hacky and dangerous way: check only the --extra-debuginfo-path and
   1318    the --debuginfo-server.  And don't do a consistency check. */
   1319 static
   1320 DiImage* find_debug_file_ad_hoc( const DebugInfo* di,
   1321                                  const HChar* objpath )
   1322 {
   1323    const HChar* extrapath  = VG_(clo_extra_debuginfo_path);
   1324    const HChar* serverpath = VG_(clo_debuginfo_server);
   1325 
   1326    DiImage* dimg      = NULL; /* the img that we found */
   1327    HChar*   debugpath = NULL; /* where we found it */
   1328 
   1329    HChar *objdir = ML_(dinfo_strdup)("di.fdfah.1", objpath);
   1330    HChar *objdirptr;
   1331 
   1332    if ((objdirptr = VG_(strrchr)(objdir, '/')) != NULL)
   1333       *objdirptr = '\0';
   1334 
   1335    debugpath = ML_(dinfo_zalloc)(
   1336                   "di.fdfah.3",
   1337                   VG_(strlen)(objdir) + 64
   1338                   + (extrapath ? VG_(strlen)(extrapath) : 0)
   1339                   + (serverpath ? VG_(strlen)(serverpath) : 0));
   1340 
   1341    if (extrapath) {
   1342       VG_(sprintf)(debugpath, "%s/%s", extrapath, objpath);
   1343       dimg = ML_(img_from_local_file)(debugpath);
   1344       if (dimg != NULL) {
   1345          if (VG_(clo_verbosity) > 1) {
   1346             VG_(message)(Vg_DebugMsg, "  Using (POSSIBLY MISMATCHED) %s\n",
   1347                                       debugpath);
   1348          }
   1349          goto dimg_ok;
   1350       }
   1351    }
   1352    if (serverpath) {
   1353       /* When looking on the debuginfo server, always just pass the
   1354          basename. */
   1355       const HChar* basename = objpath;
   1356       if (VG_(strstr)(basename, "/") != NULL) {
   1357          basename = VG_(strrchr)(basename, '/') + 1;
   1358       }
   1359       VG_(sprintf)(debugpath, "%s on %s", basename, serverpath);
   1360       dimg = ML_(img_from_di_server)(basename, serverpath);
   1361       if (dimg != NULL) {
   1362          if (VG_(clo_verbosity) > 1) {
   1363             VG_(message)(Vg_DebugMsg, "  Using (POSSIBLY MISMATCHED) %s\n",
   1364                                       debugpath);
   1365          }
   1366          goto dimg_ok;
   1367       }
   1368    }
   1369 
   1370    dimg_ok:
   1371 
   1372    ML_(dinfo_free)(objdir);
   1373 
   1374    if (dimg != NULL) {
   1375       vg_assert(debugpath);
   1376       TRACE_SYMTAB("\n");
   1377       TRACE_SYMTAB("------ Found an ad_hoc debuginfo file: %s\n", debugpath);
   1378    }
   1379 
   1380    if (debugpath)
   1381       ML_(dinfo_free)(debugpath);
   1382 
   1383    return dimg;
   1384 }
   1385 
   1386 
   1387 static DiOffT INDEX_BIS ( DiOffT base, UWord idx, UWord scale ) {
   1388    // This is a bit stupid.  Really, idx and scale ought to be
   1389    // 64-bit quantities, always.
   1390    return base + (DiOffT)idx * (DiOffT)scale;
   1391 }
   1392 
   1393 
   1394 /* Find the file offset corresponding to SVMA by using the program
   1395    headers.  This is taken from binutils-2.17/binutils/readelf.c
   1396    offset_from_vma(). */
   1397 static
   1398 Word file_offset_from_svma ( /*OUT*/Bool* ok,
   1399                              Addr         svma,
   1400                              DiImage*     img,
   1401                              DiOffT       phdr_ioff,
   1402                              Word         phdr_nent,
   1403                              Word         phdr_ent_szB )
   1404 {
   1405    Word i;
   1406    for (i = 0; i < phdr_nent; i++) {
   1407       ElfXX_Phdr seg;
   1408       ML_(img_get)(&seg, img,
   1409                    INDEX_BIS(phdr_ioff, i, phdr_ent_szB), sizeof(seg));
   1410       if (seg.p_type != PT_LOAD)
   1411          continue;
   1412       if (svma >= (seg.p_vaddr & -seg.p_align)
   1413           && svma + 1 <= seg.p_vaddr + seg.p_filesz) {
   1414          *ok = True;
   1415          return svma - seg.p_vaddr + seg.p_offset;
   1416       }
   1417    }
   1418    *ok = False;
   1419    return 0;
   1420 }
   1421 
   1422 
   1423 /* The central function for reading ELF debug info.  For the
   1424    object/exe specified by the DebugInfo, find ELF sections, then read
   1425    the symbols, line number info, file name info, CFA (stack-unwind
   1426    info) and anything else we want, into the tables within the
   1427    supplied DebugInfo.
   1428 */
   1429 
   1430 Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
   1431 {
   1432    /* This function is long and complex.  That, and the presence of
   1433       nested scopes, means it's not always easy to see which parts are
   1434       in loops/conditionals and which aren't.  To make it easier to
   1435       follow, points executed exactly once -- that is, those which are
   1436       the top level of the function -- are marked TOPLEVEL.
   1437    */
   1438    /* Consistent terminology for local variable names, without which
   1439       it's almost unfollowably complex:
   1440 
   1441       In which file?
   1442          in the main ELF file         *_m*
   1443          in the debuginfo file        *_d*
   1444          in the alt debuginfo file    *_a*
   1445 
   1446       What kind of thing?
   1447          _{m,d,a}img       a DiImage*
   1448          _{m,d,a}ioff      an offset in the image (DiOffT)
   1449          _{m,d,a}nent      "number of entries"
   1450          _{m,d,a}ent_szB   "size in bytes of an entry"
   1451          ehdr_{m,d,a}      ELF header
   1452          phdr              Program header
   1453          shdr              Section header
   1454          a_X               a temporary X
   1455          _escn             an DiSlice (elf section info) variable
   1456          szB               size in bytes
   1457    */
   1458 
   1459 
   1460    /* TOPLEVEL */
   1461    Bool     res, ok;
   1462    Word     i, j;
   1463    Bool     dynbss_present = False;
   1464    Bool     sdynbss_present = False;
   1465 
   1466    /* Image for the main ELF file we're working with. */
   1467    DiImage* mimg = NULL;
   1468 
   1469    /* Ditto for any ELF debuginfo file that we might happen to load. */
   1470    DiImage* dimg = NULL;
   1471 
   1472    /* Ditto for alternate ELF debuginfo file that we might happen to load. */
   1473    DiImage* aimg = NULL;
   1474 
   1475    /* ELF header offset for the main file.  Should be zero since the
   1476       ELF header is at start of file. */
   1477    DiOffT   ehdr_mioff = 0;
   1478 
   1479    /* Program header table image addr, # entries, entry size */
   1480    DiOffT   phdr_mioff    = 0;
   1481    UWord    phdr_mnent    = 0;
   1482    UWord    phdr_ment_szB = 0;
   1483 
   1484    /* Section header image addr, # entries, entry size.  Also the
   1485       associated string table. */
   1486    DiOffT   shdr_mioff        = 0;
   1487    UWord    shdr_mnent        = 0;
   1488    UWord    shdr_ment_szB     = 0;
   1489    DiOffT   shdr_strtab_mioff = 0;
   1490 
   1491    /* SVMAs covered by rx and rw segments and corresponding biases.
   1492       Normally each object would provide just one rx and one rw area,
   1493       but various ELF mangling tools create objects with multiple
   1494       such entries, hence the generality. */
   1495    typedef
   1496       struct {
   1497          Addr     svma_base;
   1498          Addr     svma_limit;
   1499          PtrdiffT bias;
   1500          Bool     exec;
   1501       }
   1502       RangeAndBias;
   1503 
   1504    XArray* /* of RangeAndBias */ svma_ranges = NULL;
   1505 
   1506    vg_assert(di);
   1507    vg_assert(di->fsm.have_rx_map == True);
   1508    vg_assert(di->fsm.have_rw_map == True);
   1509    vg_assert(di->have_dinfo == False);
   1510    vg_assert(di->fsm.filename);
   1511    vg_assert(!di->symtab);
   1512    vg_assert(!di->loctab);
   1513    vg_assert(!di->inltab);
   1514    vg_assert(!di->cfsi_base);
   1515    vg_assert(!di->cfsi_m_ix);
   1516    vg_assert(!di->cfsi_rd);
   1517    vg_assert(!di->cfsi_exprs);
   1518    vg_assert(!di->strpool);
   1519    vg_assert(!di->fndnpool);
   1520    vg_assert(!di->soname);
   1521 
   1522    {
   1523       Bool has_nonempty_rx = False;
   1524       Bool has_nonempty_rw = False;
   1525       for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
   1526          DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
   1527          if (!map->rx && !map->rw)
   1528             continue;
   1529          if (map->rx && map->size > 0)
   1530             has_nonempty_rx = True;
   1531          if (map->rw && map->size > 0)
   1532             has_nonempty_rw = True;
   1533          /* If this doesn't hold true, it means that m_syswrap/m_aspacemgr
   1534             managed to do a mapping where the start isn't page aligned.
   1535             Which sounds pretty bogus to me. */
   1536          vg_assert(VG_IS_PAGE_ALIGNED(map->avma));
   1537       }
   1538       vg_assert(has_nonempty_rx);
   1539       vg_assert(has_nonempty_rw);
   1540    }
   1541 
   1542    /* ----------------------------------------------------------
   1543       At this point, there is very little information in the
   1544       DebugInfo.  We only know that something that looks like an ELF
   1545       file has been mapped rx-ishly and rw-ishly as recorded in the
   1546       di->fsm.maps array items.  First we examine the file's ELF
   1547       Program Header, and, by comparing that against the di->fsm.maps
   1548       info, try to figure out the AVMAs for the sections we care
   1549       about, that should have been mapped: text, data, sdata, bss,
   1550       got, plt, and toc.
   1551       ---------------------------------------------------------- */
   1552 
   1553    res = False;
   1554 
   1555    if (VG_(clo_verbosity) > 1 || VG_(clo_trace_redir))
   1556       VG_(message)(Vg_DebugMsg, "Reading syms from %s\n",
   1557                                 di->fsm.filename );
   1558 
   1559    /* Connect to the primary object image, so that we can read symbols
   1560       and line number info out of it.  It will be disconnected
   1561       immediately thereafter; it is only connected transiently. */
   1562    mimg = ML_(img_from_local_file)(di->fsm.filename);
   1563    if (mimg == NULL) {
   1564       VG_(message)(Vg_UserMsg, "warning: connection to image %s failed\n",
   1565                                di->fsm.filename );
   1566       VG_(message)(Vg_UserMsg, "         no symbols or debug info loaded\n" );
   1567       return False;
   1568    }
   1569 
   1570    /* Ok, the object image is available.  Now verify that it is a
   1571       valid ELF .so or executable image. */
   1572    ok = is_elf_object_file_by_DiImage(mimg, False);
   1573    if (!ok) {
   1574       ML_(symerr)(di, True, "Invalid ELF Header");
   1575       goto out;
   1576    }
   1577 
   1578    /* Find where the program and section header tables are, and give
   1579       up if either is missing or outside the image (bogus). */
   1580    ElfXX_Ehdr ehdr_m;
   1581    vg_assert(ehdr_mioff == 0); // ensured by its initialisation
   1582    ok = ML_(img_valid)(mimg, ehdr_mioff, sizeof(ehdr_m));
   1583    vg_assert(ok); // ML_(is_elf_object_file) should ensure this
   1584    ML_(img_get)(&ehdr_m, mimg, ehdr_mioff, sizeof(ehdr_m));
   1585 
   1586    phdr_mioff    = ehdr_mioff + ehdr_m.e_phoff;
   1587    phdr_mnent    = ehdr_m.e_phnum;
   1588    phdr_ment_szB = ehdr_m.e_phentsize;
   1589 
   1590    shdr_mioff    = ehdr_mioff + ehdr_m.e_shoff;
   1591    shdr_mnent    = ehdr_m.e_shnum;
   1592    shdr_ment_szB = ehdr_m.e_shentsize;
   1593 
   1594    TRACE_SYMTAB("------ Basic facts about the object ------\n");
   1595    TRACE_SYMTAB("object:  n_oimage %llu\n",
   1596                 (ULong)ML_(img_size)(mimg));
   1597    TRACE_SYMTAB("phdr:    ioff %llu nent %ld ent_szB %ld\n",
   1598                phdr_mioff, phdr_mnent, phdr_ment_szB);
   1599    TRACE_SYMTAB("shdr:    ioff %llu nent %ld ent_szB %ld\n",
   1600                shdr_mioff, shdr_mnent, shdr_ment_szB);
   1601    for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
   1602       const DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
   1603       if (map->rx)
   1604          TRACE_SYMTAB("rx_map:  avma %#lx   size %lu  foff %lu\n",
   1605                       map->avma, map->size, map->foff);
   1606    }
   1607    for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
   1608       const DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
   1609       if (map->rw)
   1610          TRACE_SYMTAB("rw_map:  avma %#lx   size %lu  foff %lu\n",
   1611                       map->avma, map->size, map->foff);
   1612    }
   1613 
   1614    if (phdr_mnent == 0
   1615        || !ML_(img_valid)(mimg, phdr_mioff, phdr_mnent * phdr_ment_szB)) {
   1616       ML_(symerr)(di, True, "Missing or invalid ELF Program Header Table");
   1617       goto out;
   1618    }
   1619 
   1620    if (shdr_mnent == 0
   1621        || !ML_(img_valid)(mimg, shdr_mioff, shdr_mnent * shdr_ment_szB)) {
   1622       ML_(symerr)(di, True, "Missing or invalid ELF Section Header Table");
   1623       goto out;
   1624    }
   1625 
   1626    /* Also find the section header's string table, and validate. */
   1627    /* checked previously by is_elf_object_file: */
   1628    vg_assert(ehdr_m.e_shstrndx != SHN_UNDEF);
   1629 
   1630    // shdr_mioff is the offset of the section header table
   1631    // and we need the ehdr_m.e_shstrndx'th entry
   1632    { ElfXX_Shdr a_shdr;
   1633      ML_(img_get)(&a_shdr, mimg,
   1634                   INDEX_BIS(shdr_mioff, ehdr_m.e_shstrndx, shdr_ment_szB),
   1635                   sizeof(a_shdr));
   1636      shdr_strtab_mioff
   1637         = ehdr_mioff /* isn't this always zero? */ + a_shdr.sh_offset;
   1638 
   1639      if (!ML_(img_valid)(mimg, shdr_strtab_mioff,
   1640                          1/*bogus, but we don't know the real size*/ )) {
   1641         ML_(symerr)(di, True, "Invalid ELF Section Header String Table");
   1642         goto out;
   1643      }
   1644    }
   1645 
   1646    TRACE_SYMTAB("shdr:    string table at %llu\n", shdr_strtab_mioff);
   1647 
   1648    svma_ranges = VG_(newXA)(ML_(dinfo_zalloc), "di.relfdi.1",
   1649                             ML_(dinfo_free), sizeof(RangeAndBias));
   1650 
   1651    /* TOPLEVEL */
   1652    /* Look through the program header table, and:
   1653       - copy information from suitable PT_LOAD entries into svma_ranges
   1654       - find (or fake up) the .soname for this object.
   1655    */
   1656    TRACE_SYMTAB("\n");
   1657    TRACE_SYMTAB("------ Examining the program headers ------\n");
   1658    vg_assert(di->soname == NULL);
   1659    {
   1660       /* TOPLEVEL */
   1661       ElfXX_Addr prev_svma = 0;
   1662 
   1663       for (i = 0; i < phdr_mnent; i++) {
   1664          ElfXX_Phdr a_phdr;
   1665          ML_(img_get)(&a_phdr, mimg,
   1666                       INDEX_BIS(phdr_mioff, i, phdr_ment_szB),
   1667                       sizeof(a_phdr));
   1668 
   1669          /* Make sure the PT_LOADable entries are in order and
   1670             non-overlapping.  This in turn means the address ranges
   1671             slurped into svma_ranges are in order and
   1672             non-overlapping. */
   1673 
   1674          if (a_phdr.p_type == PT_LOAD) {
   1675             TRACE_SYMTAB("PT_LOAD[%ld]: p_vaddr %#lx (prev %#lx)\n",
   1676                          i, (UWord)a_phdr.p_vaddr, (UWord)prev_svma);
   1677             TRACE_SYMTAB("PT_LOAD[%ld]:   p_offset %lu, p_filesz %lu,"
   1678                          " perms %c%c%c\n",
   1679                          i, (UWord)a_phdr.p_offset, (UWord)a_phdr.p_filesz,
   1680                          a_phdr.p_flags & PF_R ? 'r' : '-',
   1681                          a_phdr.p_flags & PF_W ? 'w' : '-',
   1682                          a_phdr.p_flags & PF_X ? 'x' : '-');
   1683             if (a_phdr.p_vaddr < prev_svma) {
   1684                ML_(symerr)(di, True,
   1685                            "ELF Program Headers are not in ascending order");
   1686                goto out;
   1687             }
   1688             prev_svma = a_phdr.p_vaddr;
   1689             if (a_phdr.p_memsz > 0) {
   1690                Bool loaded = False;
   1691                for (j = 0; j < VG_(sizeXA)(di->fsm.maps); j++) {
   1692                   const DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, j);
   1693                   if (   (map->rx || map->rw)
   1694                       && map->size > 0 /* stay sane */
   1695                       && a_phdr.p_offset >= map->foff
   1696                       && a_phdr.p_offset <  map->foff + map->size
   1697                       && a_phdr.p_offset + a_phdr.p_filesz
   1698                          <= map->foff + map->size) {
   1699                      RangeAndBias item;
   1700                      item.svma_base  = a_phdr.p_vaddr;
   1701                      item.svma_limit = a_phdr.p_vaddr + a_phdr.p_memsz;
   1702                      item.bias       = map->avma - map->foff
   1703                                        + a_phdr.p_offset - a_phdr.p_vaddr;
   1704                      if (map->rw
   1705                          && (a_phdr.p_flags & (PF_R | PF_W))
   1706                             == (PF_R | PF_W)) {
   1707                         item.exec = False;
   1708                         VG_(addToXA)(svma_ranges, &item);
   1709                         TRACE_SYMTAB(
   1710                            "PT_LOAD[%ld]:   acquired as rw, bias 0x%lx\n",
   1711                            i, item.bias);
   1712                         loaded = True;
   1713                      }
   1714                      if (map->rx
   1715                          && (a_phdr.p_flags & (PF_R | PF_X))
   1716                             == (PF_R | PF_X)) {
   1717                         item.exec = True;
   1718                         VG_(addToXA)(svma_ranges, &item);
   1719                         TRACE_SYMTAB(
   1720                            "PT_LOAD[%ld]:   acquired as rx, bias 0x%lx\n",
   1721                            i, item.bias);
   1722                         loaded = True;
   1723                      }
   1724                   }
   1725                }
   1726                if (!loaded) {
   1727                   ML_(symerr)(di, False,
   1728                               "ELF section outside all mapped regions");
   1729                   /* This problem might be solved by further memory mappings.
   1730                      Avoid the vg_assert(!di->soname) at the beginning of this
   1731                      function if DYNAMIC section has been already processed. */
   1732                   if (di->soname) {
   1733                      ML_(dinfo_free)(di->soname);
   1734                      di->soname = NULL;
   1735                   }
   1736                   goto out;
   1737                }
   1738             }
   1739          }
   1740 
   1741          /* Try to get the soname.  If there isn't one, use "NONE".
   1742             The seginfo needs to have some kind of soname in order to
   1743             facilitate writing redirect functions, since all redirect
   1744             specifications require a soname (pattern). */
   1745          if (a_phdr.p_type == PT_DYNAMIC && di->soname == NULL) {
   1746             Word   stroff       = -1;
   1747             DiOffT strtab_mioff = DiOffT_INVALID;
   1748             for (j = 0; True/*exit check is in the loop*/; j++) {
   1749                ElfXX_Dyn t_dyn_m; /* dyn_img[j] */
   1750                ML_(img_get)(&t_dyn_m, mimg,
   1751                             INDEX_BIS(ehdr_mioff + a_phdr.p_offset,
   1752                                       j, sizeof(ElfXX_Dyn)),
   1753                             sizeof(t_dyn_m));
   1754                if (t_dyn_m.d_tag == DT_NULL)
   1755                   break;
   1756 
   1757                switch (t_dyn_m.d_tag) {
   1758                   case DT_SONAME: {
   1759                      stroff = t_dyn_m.d_un.d_val;
   1760                      break;
   1761                   }
   1762                   case DT_STRTAB: {
   1763                      Bool ok2 = False;
   1764                      Word offset = file_offset_from_svma(
   1765                                       &ok2, t_dyn_m.d_un.d_ptr, mimg,
   1766                                       phdr_mioff, phdr_mnent, phdr_ment_szB
   1767                                    );
   1768                      if (ok2 && strtab_mioff == DiOffT_INVALID) {
   1769                         // Check for obviously bogus offsets.
   1770                         if (!ML_(img_valid)(mimg, offset, 1)) {
   1771                            ML_(symerr)(di, True, "Invalid DT_STRTAB offset");
   1772                            goto out;
   1773                         }
   1774                         strtab_mioff = ehdr_mioff + offset;
   1775                         vg_assert(ehdr_mioff == 0); // should always be
   1776                      }
   1777                      break;
   1778                   }
   1779                   default:
   1780                      break;
   1781                }
   1782             }
   1783             if (stroff != -1 && strtab_mioff != DiOffT_INVALID) {
   1784                di->soname = ML_(img_strdup)(mimg, "di.redi.1",
   1785                                             strtab_mioff + stroff);
   1786                TRACE_SYMTAB("Found soname = %s\n", di->soname);
   1787             }
   1788          }
   1789       } /* for (i = 0; i < phdr_Mnent; i++) ... */
   1790       /* TOPLEVEL */
   1791 
   1792    } /* examine the program headers (local scope) */
   1793 
   1794    /* TOPLEVEL */
   1795 
   1796    /* If, after looking at all the program headers, we still didn't
   1797       find a soname, add a fake one. */
   1798    if (di->soname == NULL) {
   1799       TRACE_SYMTAB("No soname found; using (fake) \"NONE\"\n");
   1800       di->soname = ML_(dinfo_strdup)("di.redi.2", "NONE");
   1801    }
   1802 
   1803    vg_assert(VG_(sizeXA)(svma_ranges) != 0);
   1804 
   1805    /* Now read the section table. */
   1806    TRACE_SYMTAB("\n");
   1807    TRACE_SYMTAB("------ Examining the section headers ------\n");
   1808    for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
   1809       const DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
   1810       if (map->rx)
   1811          TRACE_SYMTAB("rx: at %#lx are mapped foffsets %ld .. %ld\n",
   1812                       map->avma, map->foff, map->foff + map->size - 1 );
   1813    }
   1814    TRACE_SYMTAB("rx: contains these svma regions:\n");
   1815    for (i = 0; i < VG_(sizeXA)(svma_ranges); i++) {
   1816       const RangeAndBias* reg = VG_(indexXA)(svma_ranges, i);
   1817       if (reg->exec)
   1818          TRACE_SYMTAB("  svmas %#lx .. %#lx with bias %#lx\n",
   1819                       reg->svma_base, reg->svma_limit - 1, reg->bias );
   1820    }
   1821    for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
   1822       const DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
   1823       if (map->rw)
   1824          TRACE_SYMTAB("rw: at %#lx are mapped foffsets %ld .. %ld\n",
   1825                       map->avma, map->foff, map->foff + map->size - 1 );
   1826    }
   1827    TRACE_SYMTAB("rw: contains these svma regions:\n");
   1828    for (i = 0; i < VG_(sizeXA)(svma_ranges); i++) {
   1829       const RangeAndBias* reg = VG_(indexXA)(svma_ranges, i);
   1830       if (!reg->exec)
   1831          TRACE_SYMTAB("  svmas %#lx .. %#lx with bias %#lx\n",
   1832                       reg->svma_base, reg->svma_limit - 1, reg->bias );
   1833    }
   1834 
   1835    /* TOPLEVEL */
   1836    /* Iterate over section headers */
   1837    for (i = 0; i < shdr_mnent; i++) {
   1838       ElfXX_Shdr a_shdr;
   1839       ML_(img_get)(&a_shdr, mimg,
   1840                    INDEX_BIS(shdr_mioff, i, shdr_ment_szB), sizeof(a_shdr));
   1841       DiOffT name_mioff = shdr_strtab_mioff + a_shdr.sh_name;
   1842       HChar* name = ML_(img_strdup)(mimg, "di.redi_name.1", name_mioff);
   1843       Addr   svma = a_shdr.sh_addr;
   1844       OffT   foff = a_shdr.sh_offset;
   1845       UWord  size = a_shdr.sh_size; /* Do not change this to be signed. */
   1846       UInt   alyn = a_shdr.sh_addralign;
   1847       Bool   bits = !(a_shdr.sh_type == SHT_NOBITS);
   1848       /* Look through our collection of info obtained from the PT_LOAD
   1849          headers, and make 'inrx' and 'inrw' point to the first entry
   1850          in each that intersects 'avma'.  If in each case none is found,
   1851          leave the relevant pointer at NULL. */
   1852       RangeAndBias* inrx = NULL;
   1853       RangeAndBias* inrw = NULL;
   1854       for (j = 0; j < VG_(sizeXA)(svma_ranges); j++) {
   1855          RangeAndBias* rng = VG_(indexXA)(svma_ranges, j);
   1856          if (svma >= rng->svma_base && svma < rng->svma_limit) {
   1857             if (!inrx && rng->exec) {
   1858                inrx = rng;
   1859             } else if (!inrw && !rng->exec) {
   1860                inrw = rng;
   1861             }
   1862             if (inrx && inrw)
   1863                break;
   1864          }
   1865       }
   1866 
   1867       TRACE_SYMTAB(" [sec %2ld]  %s %s  al%2u  foff %6ld .. %6ld  "
   1868                    "  svma %p  name \"%s\"\n",
   1869                    i, inrx ? "rx" : "  ", inrw ? "rw" : "  ", alyn,
   1870                    foff, foff+size-1, (void*)svma, name);
   1871 
   1872       /* Check for sane-sized segments.  SHT_NOBITS sections have zero
   1873          size in the file. */
   1874       if ((foff >= ML_(img_size)(mimg))
   1875           || (foff + (bits ? size : 0) > ML_(img_size)(mimg))) {
   1876          ML_(symerr)(di, True, "ELF Section extends beyond image end");
   1877          goto out;
   1878       }
   1879 
   1880       /* Check for a sane alignment value. */
   1881       if (alyn > 0 && -1 == VG_(log2)(alyn)) {
   1882          ML_(symerr)(di, True, "ELF Section contains invalid "
   1883                                ".sh_addralign value");
   1884          goto out;
   1885       }
   1886 
   1887       /* Ignore zero sized sections. */
   1888       if (size == 0) {
   1889          TRACE_SYMTAB("zero sized section \"%s\", ignoring\n", name);
   1890          ML_(dinfo_free)(name);
   1891          continue;
   1892       }
   1893 
   1894 #     define BAD(_secname)                                 \
   1895          do { ML_(symerr)(di, True,                        \
   1896                           "Can't make sense of " _secname  \
   1897                           " section mapping");             \
   1898               /* make sure we don't assert if we find */   \
   1899               /* ourselves back in this routine later, */  \
   1900               /* with the same di */                       \
   1901               di->soname = NULL;                           \
   1902               goto out;                                    \
   1903          } while (0)
   1904 
   1905       /* Find avma-s for: .text .data .sdata .rodata .bss .sbss .plt .got .opd
   1906          and .eh_frame */
   1907 
   1908       /* Accept .text where mapped as rx (code), even if zero-sized */
   1909       if (0 == VG_(strcmp)(name, ".text")) {
   1910          if (inrx && !di->text_present) {
   1911             di->text_present = True;
   1912             di->text_svma = svma;
   1913             di->text_avma = svma + inrx->bias;
   1914             di->text_size = size;
   1915             di->text_bias = inrx->bias;
   1916             di->text_debug_svma = svma;
   1917             di->text_debug_bias = inrx->bias;
   1918             TRACE_SYMTAB("acquiring .text svma = %#lx .. %#lx\n",
   1919                          di->text_svma,
   1920                          di->text_svma + di->text_size - 1);
   1921             TRACE_SYMTAB("acquiring .text avma = %#lx .. %#lx\n",
   1922                          di->text_avma,
   1923                          di->text_avma + di->text_size - 1);
   1924             TRACE_SYMTAB("acquiring .text bias = %#lx\n", di->text_bias);
   1925          } else {
   1926             BAD(".text");
   1927          }
   1928       }
   1929 
   1930       /* Accept .data where mapped as rw (data), even if zero-sized */
   1931       if (0 == VG_(strcmp)(name, ".data")) {
   1932          if (inrw && !di->data_present) {
   1933             di->data_present = True;
   1934             di->data_svma = svma;
   1935             di->data_avma = svma + inrw->bias;
   1936             di->data_size = size;
   1937             di->data_bias = inrw->bias;
   1938             di->data_debug_svma = svma;
   1939             di->data_debug_bias = inrw->bias;
   1940             TRACE_SYMTAB("acquiring .data svma = %#lx .. %#lx\n",
   1941                          di->data_svma,
   1942                          di->data_svma + di->data_size - 1);
   1943             TRACE_SYMTAB("acquiring .data avma = %#lx .. %#lx\n",
   1944                          di->data_avma,
   1945                          di->data_avma + di->data_size - 1);
   1946             TRACE_SYMTAB("acquiring .data bias = %#lx\n", di->data_bias);
   1947          } else {
   1948             BAD(".data");
   1949          }
   1950       }
   1951 
   1952       /* Accept .sdata where mapped as rw (data) */
   1953       if (0 == VG_(strcmp)(name, ".sdata")) {
   1954          if (inrw && !di->sdata_present) {
   1955             di->sdata_present = True;
   1956             di->sdata_svma = svma;
   1957             di->sdata_avma = svma + inrw->bias;
   1958             di->sdata_size = size;
   1959             di->sdata_bias = inrw->bias;
   1960             di->sdata_debug_svma = svma;
   1961             di->sdata_debug_bias = inrw->bias;
   1962             TRACE_SYMTAB("acquiring .sdata svma = %#lx .. %#lx\n",
   1963                          di->sdata_svma,
   1964                          di->sdata_svma + di->sdata_size - 1);
   1965             TRACE_SYMTAB("acquiring .sdata avma = %#lx .. %#lx\n",
   1966                          di->sdata_avma,
   1967                          di->sdata_avma + di->sdata_size - 1);
   1968             TRACE_SYMTAB("acquiring .sdata bias = %#lx\n", di->sdata_bias);
   1969          } else {
   1970             BAD(".sdata");
   1971          }
   1972       }
   1973 
   1974       /* Accept .rodata where mapped as rx (data), even if zero-sized */
   1975       if (0 == VG_(strcmp)(name, ".rodata")) {
   1976          if (inrx && !di->rodata_present) {
   1977             di->rodata_present = True;
   1978             di->rodata_svma = svma;
   1979             di->rodata_avma = svma + inrx->bias;
   1980             di->rodata_size = size;
   1981             di->rodata_bias = inrx->bias;
   1982             di->rodata_debug_svma = svma;
   1983             di->rodata_debug_bias = inrx->bias;
   1984                                     /* NB was 'inrw' prior to r11794 */
   1985             TRACE_SYMTAB("acquiring .rodata svma = %#lx .. %#lx\n",
   1986                          di->rodata_svma,
   1987                          di->rodata_svma + di->rodata_size - 1);
   1988             TRACE_SYMTAB("acquiring .rodata avma = %#lx .. %#lx\n",
   1989                          di->rodata_avma,
   1990                          di->rodata_avma + di->rodata_size - 1);
   1991             TRACE_SYMTAB("acquiring .rodata bias = %#lx\n", di->rodata_bias);
   1992          } else {
   1993             BAD(".rodata");
   1994          }
   1995       }
   1996 
   1997       if (0 == VG_(strcmp)(name, ".dynbss")) {
   1998          if (inrw && !di->bss_present) {
   1999             dynbss_present = True;
   2000             di->bss_present = True;
   2001             di->bss_svma = svma;
   2002             di->bss_avma = svma + inrw->bias;
   2003             di->bss_size = size;
   2004             di->bss_bias = inrw->bias;
   2005             di->bss_debug_svma = svma;
   2006             di->bss_debug_bias = inrw->bias;
   2007             TRACE_SYMTAB("acquiring .dynbss svma = %#lx .. %#lx\n",
   2008                          di->bss_svma,
   2009                          di->bss_svma + di->bss_size - 1);
   2010             TRACE_SYMTAB("acquiring .dynbss avma = %#lx .. %#lx\n",
   2011                          di->bss_avma,
   2012                          di->bss_avma + di->bss_size - 1);
   2013             TRACE_SYMTAB("acquiring .dynbss bias = %#lx\n", di->bss_bias);
   2014          }
   2015       }
   2016 
   2017       /* Accept .bss where mapped as rw (data), even if zero-sized */
   2018       if (0 == VG_(strcmp)(name, ".bss")) {
   2019          if (inrw && dynbss_present) {
   2020             vg_assert(di->bss_present);
   2021             dynbss_present = False;
   2022             vg_assert(di->bss_svma + di->bss_size == svma);
   2023             di->bss_size += size;
   2024             TRACE_SYMTAB("acquiring .bss svma = %#lx .. %#lx\n",
   2025                          svma, svma + size - 1);
   2026             TRACE_SYMTAB("acquiring .bss avma = %#lx .. %#lx\n",
   2027                          svma + inrw->bias, svma + inrw->bias + size - 1);
   2028             TRACE_SYMTAB("acquiring .bss bias = %#lx\n", di->bss_bias);
   2029          } else
   2030 
   2031          if (inrw && !di->bss_present) {
   2032             di->bss_present = True;
   2033             di->bss_svma = svma;
   2034             di->bss_avma = svma + inrw->bias;
   2035             di->bss_size = size;
   2036             di->bss_bias = inrw->bias;
   2037             di->bss_debug_svma = svma;
   2038             di->bss_debug_bias = inrw->bias;
   2039             TRACE_SYMTAB("acquiring .bss svma = %#lx .. %#lx\n",
   2040                          di->bss_svma,
   2041                          di->bss_svma + di->bss_size - 1);
   2042             TRACE_SYMTAB("acquiring .bss avma = %#lx .. %#lx\n",
   2043                          di->bss_avma,
   2044                          di->bss_avma + di->bss_size - 1);
   2045             TRACE_SYMTAB("acquiring .bss bias = %#lx\n", di->bss_bias);
   2046          } else
   2047 
   2048          /* Now one from the wtf?! department ... */
   2049          if (inrx && (!inrw) && !di->bss_present) {
   2050             /* File contains a .bss, but it got mapped as rx only.
   2051                This is very strange.  For now, just pretend we didn't
   2052                see it :-) */
   2053             di->bss_present = False;
   2054             di->bss_svma = 0;
   2055             di->bss_avma = 0;
   2056             di->bss_size = 0;
   2057             di->bss_bias = 0;
   2058             di->bss_debug_svma = 0;
   2059             di->bss_debug_bias = 0;
   2060             if (!VG_(clo_xml)) {
   2061                VG_(message)(Vg_UserMsg,
   2062                             "Warning: the following file's .bss is "
   2063                             "mapped r-x only - ignoring .bss syms\n");
   2064                VG_(message)(Vg_UserMsg,   " %s\n", di->fsm.filename
   2065                                                       ? di->fsm.filename
   2066                                                       : "(null?!)" );
   2067             }
   2068          } else
   2069 
   2070          if ((!inrw) && (!inrx) && !di->bss_present) {
   2071             /* File contains a .bss, but it didn't get mapped.  Ignore. */
   2072             di->bss_present = False;
   2073             di->bss_svma = 0;
   2074             di->bss_avma = 0;
   2075             di->bss_size = 0;
   2076             di->bss_bias = 0;
   2077          } else {
   2078             BAD(".bss");
   2079          }
   2080       }
   2081 
   2082       if (0 == VG_(strcmp)(name, ".sdynbss")) {
   2083          if (inrw && !di->sbss_present) {
   2084             sdynbss_present = True;
   2085             di->sbss_present = True;
   2086             di->sbss_svma = svma;
   2087             di->sbss_avma = svma + inrw->bias;
   2088             di->sbss_size = size;
   2089             di->sbss_bias = inrw->bias;
   2090             di->sbss_debug_svma = svma;
   2091             di->sbss_debug_bias = inrw->bias;
   2092             TRACE_SYMTAB("acquiring .sdynbss svma = %#lx .. %#lx\n",
   2093                          di->sbss_svma,
   2094                          di->sbss_svma + di->sbss_size - 1);
   2095             TRACE_SYMTAB("acquiring .sdynbss avma = %#lx .. %#lx\n",
   2096                          di->sbss_avma,
   2097                          di->sbss_avma + di->sbss_size - 1);
   2098             TRACE_SYMTAB("acquiring .sdynbss bias = %#lx\n", di->sbss_bias);
   2099          }
   2100       }
   2101 
   2102       /* Accept .sbss where mapped as rw (data) */
   2103       if (0 == VG_(strcmp)(name, ".sbss")) {
   2104          if (inrw && sdynbss_present) {
   2105             vg_assert(di->sbss_present);
   2106             sdynbss_present = False;
   2107             vg_assert(di->sbss_svma + di->sbss_size == svma);
   2108             di->sbss_size += size;
   2109             TRACE_SYMTAB("acquiring .sbss svma = %#lx .. %#lx\n",
   2110                          svma, svma + size - 1);
   2111             TRACE_SYMTAB("acquiring .sbss avma = %#lx .. %#lx\n",
   2112                          svma + inrw->bias, svma + inrw->bias + size - 1);
   2113             TRACE_SYMTAB("acquiring .sbss bias = %#lx\n", di->sbss_bias);
   2114          } else
   2115 
   2116          if (inrw && !di->sbss_present) {
   2117             di->sbss_present = True;
   2118             di->sbss_svma = svma;
   2119             di->sbss_avma = svma + inrw->bias;
   2120             di->sbss_size = size;
   2121             di->sbss_bias = inrw->bias;
   2122             di->sbss_debug_svma = svma;
   2123             di->sbss_debug_bias = inrw->bias;
   2124             TRACE_SYMTAB("acquiring .sbss svma = %#lx .. %#lx\n",
   2125                          di->sbss_svma,
   2126                          di->sbss_svma + di->sbss_size - 1);
   2127             TRACE_SYMTAB("acquiring .sbss avma = %#lx .. %#lx\n",
   2128                          di->sbss_avma,
   2129                          di->sbss_avma + di->sbss_size - 1);
   2130             TRACE_SYMTAB("acquiring .sbss bias = %#lx\n", di->sbss_bias);
   2131          } else {
   2132             BAD(".sbss");
   2133          }
   2134       }
   2135 
   2136       /* Accept .got where mapped as rw (data) */
   2137       if (0 == VG_(strcmp)(name, ".got")) {
   2138          if (inrw && !di->got_present) {
   2139             di->got_present = True;
   2140             di->got_avma = svma + inrw->bias;
   2141             di->got_size = size;
   2142             TRACE_SYMTAB("acquiring .got avma = %#lx\n", di->got_avma);
   2143          } else {
   2144             BAD(".got");
   2145          }
   2146       }
   2147 
   2148       /* Accept .got.plt where mapped as rw (data) */
   2149       if (0 == VG_(strcmp)(name, ".got.plt")) {
   2150          if (inrw && !di->gotplt_present) {
   2151             di->gotplt_present = True;
   2152             di->gotplt_avma = svma + inrw->bias;
   2153             di->gotplt_size = size;
   2154             TRACE_SYMTAB("acquiring .got.plt avma = %#lx\n", di->gotplt_avma);
   2155          } else if (size != 0) {
   2156             BAD(".got.plt");
   2157          }
   2158       }
   2159 
   2160       /* PLT is different on different platforms, it seems. */
   2161 #     if defined(VGP_x86_linux) || defined(VGP_amd64_linux) \
   2162          || defined(VGP_arm_linux) || defined (VGP_s390x_linux) \
   2163          || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
   2164          || defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
   2165       /* Accept .plt where mapped as rx (code) */
   2166       if (0 == VG_(strcmp)(name, ".plt")) {
   2167          if (inrx && !di->plt_present) {
   2168             di->plt_present = True;
   2169             di->plt_avma = svma + inrx->bias;
   2170             di->plt_size = size;
   2171             TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
   2172          } else {
   2173             BAD(".plt");
   2174          }
   2175       }
   2176 #     elif defined(VGP_ppc32_linux)
   2177       /* Accept .plt where mapped as rw (data) */
   2178       if (0 == VG_(strcmp)(name, ".plt")) {
   2179          if (inrw && !di->plt_present) {
   2180             di->plt_present = True;
   2181             di->plt_avma = svma + inrw->bias;
   2182             di->plt_size = size;
   2183             TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
   2184          } else {
   2185             BAD(".plt");
   2186          }
   2187       }
   2188 #     elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
   2189       /* Accept .plt where mapped as rw (data), or unmapped */
   2190       if (0 == VG_(strcmp)(name, ".plt")) {
   2191          if (inrw && !di->plt_present) {
   2192             di->plt_present = True;
   2193             di->plt_avma = svma + inrw->bias;
   2194             di->plt_size = size;
   2195             TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma);
   2196          } else
   2197          if ((!inrw) && (!inrx) && size > 0 && !di->plt_present) {
   2198             /* File contains a .plt, but it didn't get mapped.
   2199                Presumably it is not required on this platform.  At
   2200                least don't reject the situation as invalid. */
   2201             di->plt_present = True;
   2202             di->plt_avma = 0;
   2203             di->plt_size = 0;
   2204          } else {
   2205             BAD(".plt");
   2206          }
   2207       }
   2208 #     else
   2209 #       error "Unsupported platform"
   2210 #     endif
   2211 
   2212       /* Accept .opd where mapped as rw (data) */
   2213       if (0 == VG_(strcmp)(name, ".opd")) {
   2214          if (inrw && !di->opd_present) {
   2215             di->opd_present = True;
   2216             di->opd_avma = svma + inrw->bias;
   2217             di->opd_size = size;
   2218             TRACE_SYMTAB("acquiring .opd avma = %#lx\n", di->opd_avma);
   2219          } else {
   2220             BAD(".opd");
   2221          }
   2222       }
   2223 
   2224       /* Accept .eh_frame where mapped as rx (code).  This seems to be
   2225          the common case.  However, if that doesn't pan out, try for
   2226          rw (data) instead.  We can handle up to N_EHFRAME_SECTS per
   2227          ELF object. */
   2228       if (0 == VG_(strcmp)(name, ".eh_frame")) {
   2229          if (inrx && di->n_ehframe < N_EHFRAME_SECTS) {
   2230             di->ehframe_avma[di->n_ehframe] = svma + inrx->bias;
   2231             di->ehframe_size[di->n_ehframe] = size;
   2232             TRACE_SYMTAB("acquiring .eh_frame avma = %#lx\n",
   2233                          di->ehframe_avma[di->n_ehframe]);
   2234             di->n_ehframe++;
   2235          } else
   2236          if (inrw && di->n_ehframe < N_EHFRAME_SECTS) {
   2237             di->ehframe_avma[di->n_ehframe] = svma + inrw->bias;
   2238             di->ehframe_size[di->n_ehframe] = size;
   2239             TRACE_SYMTAB("acquiring .eh_frame avma = %#lx\n",
   2240                          di->ehframe_avma[di->n_ehframe]);
   2241             di->n_ehframe++;
   2242          } else {
   2243             BAD(".eh_frame");
   2244          }
   2245       }
   2246 
   2247       /* Accept .ARM.exidx where mapped as rx (code). */
   2248       /* FIXME: make sure the entire section is mapped in, not just
   2249          the first address. */
   2250       if (0 == VG_(strcmp)(name, ".ARM.exidx")) {
   2251          if (inrx && !di->exidx_present) {
   2252             di->exidx_present = True;
   2253             di->exidx_svma = svma;
   2254             di->exidx_avma = svma + inrx->bias;
   2255             di->exidx_size = size;
   2256             di->exidx_bias = inrx->bias;
   2257             TRACE_SYMTAB("acquiring .exidx svma = %#lx .. %#lx\n",
   2258                          di->exidx_svma,
   2259                          di->exidx_svma + di->exidx_size - 1);
   2260             TRACE_SYMTAB("acquiring .exidx avma = %#lx .. %#lx\n",
   2261                          di->exidx_avma,
   2262                          di->exidx_avma + di->exidx_size - 1);
   2263             TRACE_SYMTAB("acquiring .exidx bias = %#lx\n", di->exidx_bias);
   2264          } else {
   2265             BAD(".ARM.exidx");
   2266          }
   2267       }
   2268 
   2269       /* Accept .ARM.extab where mapped as rx (code). */
   2270       /* FIXME: make sure the entire section is mapped in, not just
   2271          the first address. */
   2272       if (0 == VG_(strcmp)(name, ".ARM.extab")) {
   2273          if (inrx && !di->extab_present) {
   2274             di->extab_present = True;
   2275             di->extab_svma = svma;
   2276             di->extab_avma = svma + inrx->bias;
   2277             di->extab_size = size;
   2278             di->extab_bias = inrx->bias;
   2279             TRACE_SYMTAB("acquiring .extab svma = %#lx .. %#lx\n",
   2280                          di->extab_svma,
   2281                          di->extab_svma + di->extab_size - 1);
   2282             TRACE_SYMTAB("acquiring .extab avma = %#lx .. %#lx\n",
   2283                          di->extab_avma,
   2284                          di->extab_avma + di->extab_size - 1);
   2285             TRACE_SYMTAB("acquiring .extab bias = %#lx\n", di->extab_bias);
   2286          } else {
   2287             BAD(".ARM.extab");
   2288          }
   2289       }
   2290 
   2291       ML_(dinfo_free)(name);
   2292 
   2293 #     undef BAD
   2294 
   2295    } /* iterate over the section headers */
   2296 
   2297    /* TOPLEVEL */
   2298    if (0) VG_(printf)("YYYY text_: avma %#lx  size %ld  bias %#lx\n",
   2299                       di->text_avma, di->text_size, di->text_bias);
   2300 
   2301    if (VG_(clo_verbosity) > 2 || VG_(clo_trace_redir))
   2302       VG_(message)(Vg_DebugMsg, "   svma %#010lx, avma %#010lx\n",
   2303                                 di->text_avma - di->text_bias,
   2304                                 di->text_avma );
   2305 
   2306    TRACE_SYMTAB("\n");
   2307    TRACE_SYMTAB("------ Finding image addresses "
   2308                 "for debug-info sections ------\n");
   2309 
   2310    /* TOPLEVEL */
   2311    /* Find interesting sections, read the symbol table(s), read any
   2312       debug information.  Each section is located either in the main,
   2313       debug or alt-debug files, but only in one.  For each section,
   2314       |section_escn| records which of |mimg|, |dimg| or |aimg| we
   2315       found it in, along with the section's image offset and its size.
   2316       The triples (section_img, section_ioff, section_szB) are
   2317       consistent, in that they are always either (NULL,
   2318       DiOffT_INVALID, 0), or refer to the same image, and are all
   2319       assigned together. */
   2320    {
   2321       /* TOPLEVEL */
   2322       DiSlice strtab_escn         = DiSlice_INVALID; // .strtab
   2323       DiSlice symtab_escn         = DiSlice_INVALID; // .symtab
   2324       DiSlice dynstr_escn         = DiSlice_INVALID; // .dynstr
   2325       DiSlice dynsym_escn         = DiSlice_INVALID; // .dynsym
   2326       DiSlice debuglink_escn      = DiSlice_INVALID; // .gnu_debuglink
   2327       DiSlice debugaltlink_escn   = DiSlice_INVALID; // .gnu_debugaltlink
   2328       DiSlice debug_line_escn     = DiSlice_INVALID; // .debug_line   (dwarf2)
   2329       DiSlice debug_info_escn     = DiSlice_INVALID; // .debug_info   (dwarf2)
   2330       DiSlice debug_types_escn    = DiSlice_INVALID; // .debug_types  (dwarf4)
   2331       DiSlice debug_abbv_escn     = DiSlice_INVALID; // .debug_abbrev (dwarf2)
   2332       DiSlice debug_str_escn      = DiSlice_INVALID; // .debug_str    (dwarf2)
   2333       DiSlice debug_ranges_escn   = DiSlice_INVALID; // .debug_ranges (dwarf2)
   2334       DiSlice debug_loc_escn      = DiSlice_INVALID; // .debug_loc    (dwarf2)
   2335       DiSlice debug_frame_escn    = DiSlice_INVALID; // .debug_frame  (dwarf2)
   2336       DiSlice debug_line_alt_escn = DiSlice_INVALID; // .debug_line   (alt)
   2337       DiSlice debug_info_alt_escn = DiSlice_INVALID; // .debug_info   (alt)
   2338       DiSlice debug_abbv_alt_escn = DiSlice_INVALID; // .debug_abbrev (alt)
   2339       DiSlice debug_str_alt_escn  = DiSlice_INVALID; // .debug_str    (alt)
   2340       DiSlice dwarf1d_escn        = DiSlice_INVALID; // .debug        (dwarf1)
   2341       DiSlice dwarf1l_escn        = DiSlice_INVALID; // .line         (dwarf1)
   2342       DiSlice opd_escn            = DiSlice_INVALID; // .opd (dwarf2,
   2343                                                      //       ppc64be-linux)
   2344       DiSlice ehframe_escn[N_EHFRAME_SECTS];         // .eh_frame (dwarf2)
   2345 
   2346       for (i = 0; i < N_EHFRAME_SECTS; i++)
   2347          ehframe_escn[i] = DiSlice_INVALID;
   2348 
   2349       /* Find all interesting sections */
   2350 
   2351       UInt ehframe_mix = 0;
   2352 
   2353       /* What FIND does: it finds the section called _SEC_NAME.  The
   2354          size of it is assigned to _SEC_SIZE.  The address of the
   2355          section in the transiently loaded oimage is assigned to
   2356          _SEC_IMG.  If the section is found, _POST_FX is executed
   2357          after _SEC_NAME and _SEC_SIZE have been assigned to.
   2358 
   2359          Even for sections which are marked loadable, the client's
   2360          ld.so may not have loaded them yet, so there is no guarantee
   2361          that we can safely prod around in any such area).  Because
   2362          the entire object file is transiently mapped aboard for
   2363          inspection, it's always safe to inspect that area. */
   2364 
   2365       /* TOPLEVEL */
   2366       /* Iterate over section headers (again) */
   2367       for (i = 0; i < ehdr_m.e_shnum; i++) {
   2368 
   2369 #        define FINDX(_sec_name, _sec_escn, _post_fx) \
   2370          do { \
   2371             ElfXX_Shdr a_shdr; \
   2372             ML_(img_get)(&a_shdr, mimg, \
   2373                          INDEX_BIS(shdr_mioff, i, shdr_ment_szB), \
   2374                          sizeof(a_shdr)); \
   2375             if (0 == ML_(img_strcmp_c)(mimg, shdr_strtab_mioff \
   2376                                               + a_shdr.sh_name, _sec_name)) { \
   2377                Bool nobits; \
   2378                _sec_escn.img  = mimg; \
   2379                _sec_escn.ioff = (DiOffT)a_shdr.sh_offset; \
   2380                _sec_escn.szB  = a_shdr.sh_size; \
   2381                nobits         = a_shdr.sh_type == SHT_NOBITS; \
   2382                vg_assert(_sec_escn.img  != NULL); \
   2383                vg_assert(_sec_escn.ioff != DiOffT_INVALID); \
   2384                TRACE_SYMTAB( "%-18s:  ioff %llu .. %llu\n", \
   2385                              _sec_name, (ULong)_sec_escn.ioff, \
   2386                              ((ULong)_sec_escn.ioff) + _sec_escn.szB - 1); \
   2387                /* SHT_NOBITS sections have zero size in the file. */ \
   2388                if ( a_shdr.sh_offset \
   2389                     + (nobits ? 0 : _sec_escn.szB) > ML_(img_size)(mimg) ) { \
   2390                   ML_(symerr)(di, True, \
   2391                               "   section beyond image end?!"); \
   2392                   goto out; \
   2393                } \
   2394                _post_fx; \
   2395             } \
   2396          } while (0);
   2397 
   2398          /* Version with no post-effects */
   2399 #        define FIND(_sec_name, _sec_escn) \
   2400             FINDX(_sec_name, _sec_escn, /**/)
   2401 
   2402          /*   NAME                  ElfSec */
   2403          FIND(".dynsym",            dynsym_escn)
   2404          FIND(".dynstr",            dynstr_escn)
   2405          FIND(".symtab",            symtab_escn)
   2406          FIND(".strtab",            strtab_escn)
   2407 
   2408          FIND(".gnu_debuglink",     debuglink_escn)
   2409          FIND(".gnu_debugaltlink",  debugaltlink_escn)
   2410 
   2411          FIND(".debug_line",        debug_line_escn)
   2412          FIND(".debug_info",        debug_info_escn)
   2413          FIND(".debug_types",       debug_types_escn)
   2414          FIND(".debug_abbrev",      debug_abbv_escn)
   2415          FIND(".debug_str",         debug_str_escn)
   2416          FIND(".debug_ranges",      debug_ranges_escn)
   2417          FIND(".debug_loc",         debug_loc_escn)
   2418          FIND(".debug_frame",       debug_frame_escn)
   2419 
   2420          FIND(".debug",             dwarf1d_escn)
   2421          FIND(".line",              dwarf1l_escn)
   2422 
   2423          FIND(".opd",               opd_escn)
   2424 
   2425          FINDX(".eh_frame",         ehframe_escn[ehframe_mix],
   2426                do { ehframe_mix++; vg_assert(ehframe_mix <= N_EHFRAME_SECTS);
   2427                } while (0)
   2428          )
   2429          /* Comment_on_EH_FRAME_MULTIPLE_INSTANCES: w.r.t. .eh_frame
   2430             multi-instance kludgery, how are we assured that the order
   2431             in which we fill in ehframe_escn[] is consistent with the
   2432             order in which we previously filled in di->ehframe_avma[]
   2433             and di->ehframe_size[] ?  By the fact that in both cases,
   2434             these arrays were filled in by iterating over the section
   2435             headers top-to-bottom.  So both loops (this one and the
   2436             previous one) encounter the .eh_frame entries in the same
   2437             order and so fill in these arrays in a consistent order.
   2438          */
   2439 
   2440 #        undef FINDX
   2441 #        undef FIND
   2442       } /* Iterate over section headers (again) */
   2443 
   2444       /* TOPLEVEL */
   2445       /* Now, see if we can find a debuginfo object, and if so connect
   2446          |dimg| to it. */
   2447       vg_assert(dimg == NULL && aimg == NULL);
   2448 
   2449       /* Look for a build-id */
   2450       HChar* buildid = find_buildid(mimg, False, False);
   2451 
   2452       /* Look for a debug image that matches either the build-id or
   2453          the debuglink-CRC32 in the main image.  If the main image
   2454          doesn't contain either of those then this won't even bother
   2455          to try looking.  This looks in all known places, including
   2456          the --extra-debuginfo-path if specified and on the
   2457          --debuginfo-server if specified. */
   2458       if (buildid != NULL || debuglink_escn.img != NULL) {
   2459          /* Do have a debuglink section? */
   2460          if (debuglink_escn.img != NULL) {
   2461             UInt crc_offset
   2462                = VG_ROUNDUP(ML_(img_strlen)(debuglink_escn.img,
   2463                                             debuglink_escn.ioff)+1, 4);
   2464             vg_assert(crc_offset + sizeof(UInt) <= debuglink_escn.szB);
   2465 
   2466             /* Extract the CRC from the debuglink section */
   2467             UInt crc = ML_(img_get_UInt)(debuglink_escn.img,
   2468                                          debuglink_escn.ioff + crc_offset);
   2469 
   2470             /* See if we can find a matching debug file */
   2471             HChar* debuglink_str_m
   2472                = ML_(img_strdup)(debuglink_escn.img,
   2473                                  "di.redi_dlk.1", debuglink_escn.ioff);
   2474             dimg = find_debug_file( di, di->fsm.filename, buildid,
   2475                                     debuglink_str_m, crc, False );
   2476             if (debuglink_str_m)
   2477                ML_(dinfo_free)(debuglink_str_m);
   2478          } else {
   2479             /* See if we can find a matching debug file */
   2480             dimg = find_debug_file( di, di->fsm.filename, buildid,
   2481                                     NULL, 0, False );
   2482          }
   2483       }
   2484 
   2485       if (buildid) {
   2486          ML_(dinfo_free)(buildid);
   2487          buildid = NULL; /* paranoia */
   2488       }
   2489 
   2490       /* As a last-ditch measure, try looking for in the
   2491          --extra-debuginfo-path and/or on the --debuginfo-server, but
   2492          only in the case where --allow-mismatched-debuginfo=yes.
   2493          This is dangerous in that (1) it gives no assurance that the
   2494          debuginfo object matches the main one, and hence (2) we will
   2495          very likely get an assertion in the code below, if indeed
   2496          there is a mismatch.  Hence it is disabled by default
   2497          (--allow-mismatched-debuginfo=no).  Nevertheless it's
   2498          sometimes a useful way of getting out of a tight spot.
   2499 
   2500          Note that we're ignoring the name in the .gnu_debuglink
   2501          section here, and just looking for a file of the same name
   2502          either the extra-path or on the server. */
   2503       if (dimg == NULL && VG_(clo_allow_mismatched_debuginfo)) {
   2504          dimg = find_debug_file_ad_hoc( di, di->fsm.filename );
   2505       }
   2506 
   2507       /* TOPLEVEL */
   2508       /* If we were successful in finding a debug image, pull various
   2509          SVMA/bias/size and image addresses out of it. */
   2510       if (dimg != NULL && is_elf_object_file_by_DiImage(dimg, False)) {
   2511 
   2512          /* Pull out and validate program header and section header info */
   2513          DiOffT      ehdr_dioff = 0;
   2514          ElfXX_Ehdr  ehdr_dimg;
   2515          ML_(img_get)(&ehdr_dimg, dimg, ehdr_dioff, sizeof(ehdr_dimg));
   2516 
   2517          DiOffT   phdr_dioff        = ehdr_dimg.e_phoff;
   2518          UWord    phdr_dnent        = ehdr_dimg.e_phnum;
   2519          UWord    phdr_dent_szB     = ehdr_dimg.e_phentsize;
   2520 
   2521          DiOffT   shdr_dioff        = ehdr_dimg.e_shoff;
   2522          UWord    shdr_dnent        = ehdr_dimg.e_shnum;
   2523          UWord    shdr_dent_szB     = ehdr_dimg.e_shentsize;
   2524 
   2525          DiOffT   shdr_strtab_dioff = DiOffT_INVALID;
   2526 
   2527          /* SVMAs covered by rx and rw segments and corresponding bias. */
   2528          Addr     rx_dsvma_limit = 0;
   2529          PtrdiffT rx_dbias = 0;
   2530          Addr     rw_dsvma_limit = 0;
   2531          PtrdiffT rw_dbias = 0;
   2532 
   2533          Bool need_symtab, need_dwarf2, need_dwarf1;
   2534 
   2535          if (phdr_dnent == 0
   2536              || !ML_(img_valid)(dimg, phdr_dioff,
   2537                                 phdr_dnent * phdr_dent_szB)) {
   2538             ML_(symerr)(di, True,
   2539                         "Missing or invalid ELF Program Header Table"
   2540                         " (debuginfo file)");
   2541             goto out;
   2542          }
   2543 
   2544          if (shdr_dnent == 0
   2545              || !ML_(img_valid)(dimg, shdr_dioff,
   2546                                 shdr_dnent * shdr_dent_szB)) {
   2547             ML_(symerr)(di, True,
   2548                         "Missing or invalid ELF Section Header Table"
   2549                         " (debuginfo file)");
   2550             goto out;
   2551          }
   2552 
   2553          /* Also find the section header's string table, and validate. */
   2554          /* checked previously by is_elf_object_file: */
   2555          vg_assert(ehdr_dimg.e_shstrndx != SHN_UNDEF);
   2556 
   2557          // shdr_dioff is the offset of the section header table
   2558          // and we need the ehdr_dimg.e_shstrndx'th entry
   2559          { ElfXX_Shdr a_shdr;
   2560            ML_(img_get)(&a_shdr, dimg,
   2561                         INDEX_BIS(shdr_dioff, ehdr_dimg.e_shstrndx,
   2562                                               shdr_dent_szB),
   2563                         sizeof(a_shdr));
   2564            shdr_strtab_dioff = a_shdr.sh_offset;
   2565            if (!ML_(img_valid)(dimg, shdr_strtab_dioff,
   2566                                1/*bogus, but we don't know the real size*/)) {
   2567               ML_(symerr)(di, True,
   2568                           "Invalid ELF Section Header String Table"
   2569                           " (debuginfo file)");
   2570               goto out;
   2571            }
   2572          }
   2573 
   2574          for (i = 0; i < ehdr_dimg.e_phnum; i++) {
   2575             ElfXX_Phdr a_phdr;
   2576             ML_(img_get)(&a_phdr, dimg, INDEX_BIS(ehdr_dimg.e_phoff,
   2577                                                   i, phdr_dent_szB),
   2578                            sizeof(a_phdr));
   2579             if (a_phdr.p_type == PT_LOAD) {
   2580                for (j = 0; j < VG_(sizeXA)(di->fsm.maps); j++) {
   2581                   const DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, j);
   2582                   if (   a_phdr.p_offset >= map->foff
   2583                       && a_phdr.p_offset <  map->foff + map->size
   2584                       && a_phdr.p_offset + a_phdr.p_filesz
   2585                          < map->foff + map->size) {
   2586                      if (map->rx && rx_dsvma_limit == 0) {
   2587                         rx_dsvma_limit = a_phdr.p_vaddr + a_phdr.p_memsz;
   2588                         rx_dbias = map->avma - map->foff + a_phdr.p_offset
   2589                                    - a_phdr.p_vaddr;
   2590                      }
   2591                      if (map->rw && rw_dsvma_limit == 0) {
   2592                         rw_dsvma_limit = a_phdr.p_vaddr + a_phdr.p_memsz;
   2593                         rw_dbias = map->avma - map->foff + a_phdr.p_offset
   2594                                    - a_phdr.p_vaddr;
   2595                      }
   2596                      break;
   2597                   }
   2598                }
   2599             }
   2600          }
   2601 
   2602          need_symtab = (symtab_escn.img == NULL);
   2603          need_dwarf2 = (debug_info_escn.img == NULL);
   2604          need_dwarf1 = (dwarf1d_escn.img == NULL);
   2605 
   2606          /* Find all interesting sections in the debug image */
   2607          for (i = 0; i < ehdr_dimg.e_shnum; i++) {
   2608 
   2609             /* Find debug svma and bias information for sections
   2610                we found in the main file. */
   2611 
   2612 #           define FIND(_sec, _seg) \
   2613             do { \
   2614                ElfXX_Shdr a_shdr; \
   2615                ML_(img_get)(&a_shdr, dimg, \
   2616                             INDEX_BIS(shdr_dioff, i, shdr_dent_szB), \
   2617                             sizeof(a_shdr)); \
   2618                if (di->_sec##_present \
   2619                    && 0 == ML_(img_strcmp_c)(dimg, shdr_strtab_dioff \
   2620                                              + a_shdr.sh_name, "." #_sec)) { \
   2621                   vg_assert(di->_sec##_size == a_shdr.sh_size); \
   2622                   /* JRS 2013-Jun-01: the following assert doesn't contain */ \
   2623                   /* any ==s, which seems to me to be suspicious. */ \
   2624                   vg_assert(di->_sec##_avma +  a_shdr.sh_addr + _seg##_dbias); \
   2625                   /* Assume we have a correct value for the main */ \
   2626                   /* object's bias.  Use that to derive the debuginfo */ \
   2627                   /* object's bias, by adding the difference in SVMAs */ \
   2628                   /* for the corresponding sections in the two files. */ \
   2629                   /* That should take care of all prelinking effects. */ \
   2630                   di->_sec##_debug_svma = a_shdr.sh_addr; \
   2631                   di->_sec##_debug_bias \
   2632                      = di->_sec##_bias + \
   2633                        di->_sec##_svma - di->_sec##_debug_svma; \
   2634                   TRACE_SYMTAB("acquiring ." #_sec \
   2635                                " debug svma = %#lx .. %#lx\n",       \
   2636                                di->_sec##_debug_svma, \
   2637                                di->_sec##_debug_svma + di->_sec##_size - 1); \
   2638                   TRACE_SYMTAB("acquiring ." #_sec " debug bias = %#lx\n", \
   2639                                di->_sec##_debug_bias); \
   2640                } \
   2641             } while (0);
   2642 
   2643             /* SECTION   SEGMENT */
   2644             FIND(text,   rx)
   2645             FIND(data,   rw)
   2646             FIND(sdata,  rw)
   2647             FIND(rodata, rw)
   2648             FIND(bss,    rw)
   2649             FIND(sbss,   rw)
   2650 
   2651 #           undef FIND
   2652 
   2653             /* Same deal as previous FIND, except only do it for those
   2654                sections which we didn't find in the main file. */
   2655 
   2656 #           define FIND(_condition, _sec_name, _sec_escn) \
   2657             do { \
   2658                ElfXX_Shdr a_shdr; \
   2659                ML_(img_get)(&a_shdr, dimg, \
   2660                             INDEX_BIS(shdr_dioff, i, shdr_dent_szB), \
   2661                             sizeof(a_shdr)); \
   2662                if (_condition \
   2663                    && 0 == ML_(img_strcmp_c)(dimg, shdr_strtab_dioff \
   2664                                              + a_shdr.sh_name, _sec_name)) { \
   2665                   Bool nobits; \
   2666                   if (_sec_escn.img != NULL) { \
   2667                      ML_(symerr)(di, True, \
   2668                                  "   debuginfo section duplicates a" \
   2669                                  " section in the main ELF file"); \
   2670                      goto out; \
   2671                   } \
   2672                   _sec_escn.img  = dimg; \
   2673                   _sec_escn.ioff = (DiOffT)a_shdr.sh_offset;  \
   2674                   _sec_escn.szB  = a_shdr.sh_size; \
   2675                   nobits         = a_shdr.sh_type == SHT_NOBITS; \
   2676                   vg_assert(_sec_escn.img  != NULL); \
   2677                   vg_assert(_sec_escn.ioff != DiOffT_INVALID); \
   2678                   TRACE_SYMTAB( "%-18s: dioff %llu .. %llu\n", \
   2679                                 _sec_name, \
   2680                                 (ULong)_sec_escn.ioff, \
   2681                                 ((ULong)_sec_escn.ioff) + _sec_escn.szB - 1); \
   2682                   /* SHT_NOBITS sections have zero size in the file. */ \
   2683                   if (a_shdr.sh_offset \
   2684                       + (nobits ? 0 : _sec_escn.szB) > ML_(img_size)(dimg)) { \
   2685                      ML_(symerr)(di, True, \
   2686                                  "   section beyond image end?!"); \
   2687                      goto out; \
   2688                   } \
   2689                } \
   2690             } while (0);
   2691 
   2692             /* NEEDED?        NAME             ElfSec */
   2693             FIND(need_symtab, ".symtab",       symtab_escn)
   2694             FIND(need_symtab, ".strtab",       strtab_escn)
   2695             FIND(need_dwarf2, ".debug_line",   debug_line_escn)
   2696             FIND(need_dwarf2, ".debug_info",   debug_info_escn)
   2697             FIND(need_dwarf2, ".debug_types",  debug_types_escn)
   2698 
   2699             FIND(need_dwarf2, ".debug_abbrev", debug_abbv_escn)
   2700             FIND(need_dwarf2, ".debug_str",    debug_str_escn)
   2701             FIND(need_dwarf2, ".debug_ranges", debug_ranges_escn)
   2702 
   2703             FIND(need_dwarf2, ".debug_loc",    debug_loc_escn)
   2704             FIND(need_dwarf2, ".debug_frame",  debug_frame_escn)
   2705 
   2706             FIND(need_dwarf2, ".gnu_debugaltlink", debugaltlink_escn)
   2707 
   2708             FIND(need_dwarf1, ".debug",        dwarf1d_escn)
   2709             FIND(need_dwarf1, ".line",         dwarf1l_escn)
   2710 
   2711 #           undef FIND
   2712          } /* Find all interesting sections */
   2713       } /* do we have a debug image? */
   2714 
   2715       /* TOPLEVEL */
   2716       /* Look for alternate debug image, and if found, connect |aimg|
   2717          to it. */
   2718       vg_assert(aimg == NULL);
   2719 
   2720       if (debugaltlink_escn.img != NULL) {
   2721          HChar* altfile_str_m
   2722              = ML_(img_strdup)(debugaltlink_escn.img,
   2723                                "di.fbi.3", debugaltlink_escn.ioff);
   2724          UInt buildid_offset = ML_(img_strlen)(debugaltlink_escn.img,
   2725                                                debugaltlink_escn.ioff)+1;
   2726 
   2727          vg_assert(buildid_offset < debugaltlink_escn.szB);
   2728 
   2729          HChar *altbuildid
   2730             = ML_(dinfo_zalloc)("di.fbi.4",
   2731                                 (debugaltlink_escn.szB - buildid_offset)
   2732                                 * 2 + 1);
   2733 
   2734          /* The altfile might be relative to the debug file or main file. */
   2735          HChar *dbgname = di->fsm.dbgname ? di->fsm.dbgname : di->fsm.filename;
   2736 
   2737          for (j = 0; j < debugaltlink_escn.szB - buildid_offset; j++)
   2738             VG_(sprintf)(
   2739                altbuildid + 2 * j, "%02x",
   2740                (UInt)ML_(img_get_UChar)(debugaltlink_escn.img,
   2741                                         debugaltlink_escn.ioff
   2742                                         + buildid_offset + j));
   2743 
   2744          /* See if we can find a matching debug file */
   2745          aimg = find_debug_file( di, dbgname, altbuildid,
   2746                                  altfile_str_m, 0, True );
   2747 
   2748          if (altfile_str_m)
   2749             ML_(dinfo_free)(altfile_str_m);
   2750          ML_(dinfo_free)(altbuildid);
   2751       }
   2752 
   2753       /* TOPLEVEL */
   2754       /* If we were successful in finding alternate debug image, pull various
   2755          size and image addresses out of it. */
   2756       if (aimg != NULL && is_elf_object_file_by_DiImage(aimg, True)) {
   2757 
   2758          /* Pull out and validate program header and section header info */
   2759          DiOffT      ehdr_aioff = 0;
   2760          ElfXX_Ehdr  ehdr_aimg;
   2761          ML_(img_get)(&ehdr_aimg, aimg, ehdr_aioff, sizeof(ehdr_aimg));
   2762 
   2763          DiOffT   shdr_aioff        = ehdr_aimg.e_shoff;
   2764          UWord    shdr_anent        = ehdr_aimg.e_shnum;
   2765          UWord    shdr_aent_szB     = ehdr_aimg.e_shentsize;
   2766 
   2767          DiOffT   shdr_strtab_aioff = DiOffT_INVALID;
   2768 
   2769          if (shdr_anent == 0
   2770              || !ML_(img_valid)(aimg, shdr_aioff,
   2771                                 shdr_anent * shdr_aent_szB)) {
   2772             ML_(symerr)(di, True,
   2773                         "Missing or invalid ELF Section Header Table"
   2774                         " (alternate debuginfo file)");
   2775             goto out;
   2776          }
   2777 
   2778          /* Also find the section header's string table, and validate. */
   2779          /* checked previously by is_elf_object_file: */
   2780          vg_assert(ehdr_aimg.e_shstrndx != SHN_UNDEF);
   2781 
   2782          // shdr_aioff is the offset of the section header table
   2783          // and we need the ehdr_aimg.e_shstrndx'th entry
   2784          { ElfXX_Shdr a_shdr;
   2785            ML_(img_get)(&a_shdr, aimg,
   2786                         INDEX_BIS(shdr_aioff, ehdr_aimg.e_shstrndx,
   2787                                               shdr_aent_szB),
   2788                         sizeof(a_shdr));
   2789            shdr_strtab_aioff = a_shdr.sh_offset;
   2790            if (!ML_(img_valid)(aimg, shdr_strtab_aioff,
   2791                                1/*bogus, but we don't know the real size*/)) {
   2792               ML_(symerr)(di, True,
   2793                           "Invalid ELF Section Header String Table"
   2794                           " (alternate debuginfo file)");
   2795               goto out;
   2796            }
   2797          }
   2798 
   2799          /* Find all interesting sections */
   2800          for (i = 0; i < ehdr_aimg.e_shnum; i++) {
   2801 
   2802 #           define FIND(_sec_name, _sec_escn) \
   2803             do { \
   2804                ElfXX_Shdr a_shdr; \
   2805                ML_(img_get)(&a_shdr, aimg, \
   2806                             INDEX_BIS(shdr_aioff, i, shdr_aent_szB), \
   2807                             sizeof(a_shdr)); \
   2808                if (0 == ML_(img_strcmp_c)(aimg, shdr_strtab_aioff \
   2809                                           + a_shdr.sh_name, _sec_name)) { \
   2810                   if (_sec_escn.img != NULL) { \
   2811                      ML_(symerr)(di, True, \
   2812                                  "   alternate debuginfo section duplicates a" \
   2813                                  " section in the main ELF file"); \
   2814                      goto out; \
   2815                   } \
   2816                   _sec_escn.img  = aimg; \
   2817                   _sec_escn.ioff = (DiOffT)a_shdr.sh_offset; \
   2818                   _sec_escn.szB  = a_shdr.sh_size; \
   2819                   vg_assert(_sec_escn.img  != NULL); \
   2820                   vg_assert(_sec_escn.ioff != DiOffT_INVALID); \
   2821                   TRACE_SYMTAB( "%-18s: aioff %llu .. %llu\n", \
   2822                                 _sec_name, \
   2823                                 (ULong)_sec_escn.ioff, \
   2824                                 ((ULong)_sec_escn.ioff) + _sec_escn.szB - 1); \
   2825                } \
   2826             } while (0);
   2827 
   2828             /*   NAME             ElfSec */
   2829             FIND(".debug_line",   debug_line_alt_escn)
   2830             FIND(".debug_info",   debug_info_alt_escn)
   2831             FIND(".debug_abbrev", debug_abbv_alt_escn)
   2832             FIND(".debug_str",    debug_str_alt_escn)
   2833 
   2834 #           undef FIND
   2835          } /* Find all interesting sections */
   2836       } /* do we have a debug image? */
   2837 
   2838 
   2839       /* TOPLEVEL */
   2840       /* Check some sizes */
   2841       vg_assert((dynsym_escn.szB % sizeof(ElfXX_Sym)) == 0);
   2842       vg_assert((symtab_escn.szB % sizeof(ElfXX_Sym)) == 0);
   2843 
   2844       /* TOPLEVEL */
   2845       /* Read symbols */
   2846       {
   2847          void (*read_elf_symtab)(struct _DebugInfo*, const HChar*,
   2848                                  DiSlice*, DiSlice*, DiSlice*, Bool);
   2849          Bool symtab_in_debug;
   2850 #        if defined(VGP_ppc64be_linux)
   2851          read_elf_symtab = read_elf_symtab__ppc64be_linux;
   2852 #        else
   2853          read_elf_symtab = read_elf_symtab__normal;
   2854 #        endif
   2855          symtab_in_debug = symtab_escn.img == dimg;
   2856          read_elf_symtab(di, "symbol table",
   2857                          &symtab_escn, &strtab_escn, &opd_escn,
   2858                          symtab_in_debug);
   2859          read_elf_symtab(di, "dynamic symbol table",
   2860                          &dynsym_escn, &dynstr_escn, &opd_escn,
   2861                          False);
   2862       }
   2863 
   2864       /* TOPLEVEL */
   2865       /* Read .eh_frame and .debug_frame (call-frame-info) if any.  Do
   2866          the .eh_frame section(s) first. */
   2867       vg_assert(di->n_ehframe >= 0 && di->n_ehframe <= N_EHFRAME_SECTS);
   2868       for (i = 0; i < di->n_ehframe; i++) {
   2869          /* see Comment_on_EH_FRAME_MULTIPLE_INSTANCES above for why
   2870             this next assertion should hold. */
   2871          vg_assert(ML_(sli_is_valid)(ehframe_escn[i]));
   2872          vg_assert(ehframe_escn[i].szB == di->ehframe_size[i]);
   2873          ML_(read_callframe_info_dwarf3)( di,
   2874                                           ehframe_escn[i],
   2875                                           di->ehframe_avma[i],
   2876                                           True/*is_ehframe*/ );
   2877       }
   2878       if (ML_(sli_is_valid)(debug_frame_escn)) {
   2879          ML_(read_callframe_info_dwarf3)( di,
   2880                                           debug_frame_escn,
   2881                                           0/*assume zero avma*/,
   2882                                           False/*!is_ehframe*/ );
   2883       }
   2884 
   2885       /* TOPLEVEL */
   2886       /* jrs 2006-01-01: icc-8.1 has been observed to generate
   2887          binaries without debug_str sections.  Don't preclude
   2888          debuginfo reading for that reason, but, in
   2889          read_unitinfo_dwarf2, do check that debugstr is non-NULL
   2890          before using it. */
   2891       if (ML_(sli_is_valid)(debug_info_escn)
   2892           && ML_(sli_is_valid)(debug_abbv_escn)
   2893           && ML_(sli_is_valid)(debug_line_escn)) {
   2894          /* The old reader: line numbers and unwind info only */
   2895          ML_(read_debuginfo_dwarf3) ( di,
   2896                                       debug_info_escn,
   2897                                       debug_types_escn,
   2898                                       debug_abbv_escn,
   2899                                       debug_line_escn,
   2900                                       debug_str_escn,
   2901                                       debug_str_alt_escn );
   2902          /* The new reader: read the DIEs in .debug_info to acquire
   2903             information on variable types and locations or inline info.
   2904             But only if the tool asks for it, or the user requests it on
   2905             the command line. */
   2906          if (VG_(clo_read_var_info) /* the user or tool asked for it */
   2907              || VG_(clo_read_inline_info)) {
   2908             ML_(new_dwarf3_reader)(
   2909                di, debug_info_escn,     debug_types_escn,
   2910                    debug_abbv_escn,     debug_line_escn,
   2911                    debug_str_escn,      debug_ranges_escn,
   2912                    debug_loc_escn,      debug_info_alt_escn,
   2913                    debug_abbv_alt_escn, debug_line_alt_escn,
   2914                    debug_str_alt_escn
   2915             );
   2916          }
   2917       }
   2918 
   2919       /* TOPLEVEL */
   2920       // JRS 31 July 2014: dwarf-1 reading is currently broken and
   2921       // therefore deactivated.
   2922       //if (dwarf1d_img && dwarf1l_img) {
   2923       //   ML_(read_debuginfo_dwarf1) ( di, dwarf1d_img, dwarf1d_sz,
   2924       //                                    dwarf1l_img, dwarf1l_sz );
   2925       //}
   2926 
   2927 #     if defined(VGA_arm)
   2928       /* TOPLEVEL */
   2929       /* ARM32 only: read .exidx/.extab if present.  Note we are
   2930          reading these directly out of the mapped in (running) image.
   2931          Also, read these only if no CFI based unwind info was
   2932          acquired for this file.
   2933 
   2934          An .exidx section is always required, but the .extab section
   2935          can be optionally omitted, provided that .exidx does not
   2936          refer to it.  If the .exidx is erroneous and does refer to
   2937          .extab even though .extab is missing, the range checks done
   2938          by GET_EX_U32 in ExtabEntryExtract in readexidx.c should
   2939          prevent any invalid memory accesses, and cause the .extab to
   2940          be rejected as invalid.
   2941 
   2942          FIXME:
   2943          * check with m_aspacemgr that the entire [exidx_avma, +exidx_size)
   2944            and [extab_avma, +extab_size) areas are readable, since we're
   2945            reading this stuff out of the running image (not from a file/socket)
   2946            and we don't want to segfault.
   2947          * DebugInfo::exidx_bias and use text_bias instead.
   2948            I think it's always the same.
   2949          * remove DebugInfo::{extab_bias, exidx_svma, extab_svma} since
   2950            they are never used.
   2951       */
   2952       if (di->exidx_present
   2953           && di->cfsi_used == 0
   2954           && di->text_present && di->text_size > 0) {
   2955          Addr text_last_svma = di->text_svma + di->text_size - 1;
   2956          ML_(read_exidx)( di, (UChar*)di->exidx_avma, di->exidx_size,
   2957                               (UChar*)di->extab_avma, di->extab_size,
   2958                               text_last_svma,
   2959                               di->exidx_bias );
   2960       }
   2961 #     endif /* defined(VGA_arm) */
   2962 
   2963    } /* "Find interesting sections, read the symbol table(s), read any debug
   2964         information" (a local scope) */
   2965 
   2966    /* TOPLEVEL */
   2967    res = True;
   2968 
   2969    /* If reading Dwarf3 variable type/location info, print a line
   2970       showing the number of variables read for each object.
   2971       (Currently disabled -- is a sanity-check mechanism for
   2972       exp-sgcheck.) */
   2973    if (0 &&  VG_(clo_read_var_info)) {
   2974       UWord nVars = 0;
   2975       if (di->varinfo) {
   2976          for (j = 0; j < VG_(sizeXA)(di->varinfo); j++) {
   2977             OSet* /* of DiAddrRange */ scope
   2978                = *(OSet**)VG_(indexXA)(di->varinfo, j);
   2979             vg_assert(scope);
   2980             VG_(OSetGen_ResetIter)( scope );
   2981             while (True) {
   2982                DiAddrRange* range  = VG_(OSetGen_Next)( scope );
   2983                if (!range) break;
   2984                vg_assert(range->vars);
   2985                Word w = VG_(sizeXA)(range->vars);
   2986                vg_assert(w >= 0);
   2987                if (0) VG_(printf)("range %#lx %#lx %ld\n",
   2988                                   range->aMin, range->aMax, w);
   2989                nVars += (UWord)w;
   2990             }
   2991          }
   2992       }
   2993       VG_(umsg)("VARINFO: %7lu vars   %7ld text_size   %s\n",
   2994                 nVars, di->text_size, di->fsm.filename);
   2995    }
   2996    /* TOPLEVEL */
   2997 
   2998   out:
   2999    {
   3000       /* Last, but not least, detach from the image(s). */
   3001       if (mimg) ML_(img_done)(mimg);
   3002       if (dimg) ML_(img_done)(dimg);
   3003       if (aimg) ML_(img_done)(aimg);
   3004 
   3005       if (svma_ranges) VG_(deleteXA)(svma_ranges);
   3006 
   3007       return res;
   3008    } /* out: */
   3009 
   3010    /* NOTREACHED */
   3011 }
   3012 
   3013 #endif // defined(VGO_linux)
   3014 
   3015 /*--------------------------------------------------------------------*/
   3016 /*--- end                                                          ---*/
   3017 /*--------------------------------------------------------------------*/
   3018