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