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