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