1eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--------------------------------------------------------------------*/ 3eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- Format-neutral storage of and querying of info acquired from ---*/ 472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj/*--- ELF/XCOFF stabs/dwarf1/dwarf2/dwarf3 debug info. ---*/ 5eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- storage.c ---*/ 6eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--------------------------------------------------------------------*/ 7eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 8eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* 9eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj This file is part of Valgrind, a dynamic binary instrumentation 10eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj framework. 11eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 120f157ddb404bcde7815a1c5bf2d7e41c114f3d73sewardj Copyright (C) 2000-2013 Julian Seward 13eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj jseward@acm.org 14eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 15eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj This program is free software; you can redistribute it and/or 16eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj modify it under the terms of the GNU General Public License as 17eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj published by the Free Software Foundation; either version 2 of the 18eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj License, or (at your option) any later version. 19eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 20eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj This program is distributed in the hope that it will be useful, but 21eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj WITHOUT ANY WARRANTY; without even the implied warranty of 22eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj General Public License for more details. 24eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 25eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj You should have received a copy of the GNU General Public License 26eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj along with this program; if not, write to the Free Software 27eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 28eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 02111-1307, USA. 29eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 30eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj The GNU General Public License is contained in the file COPYING. 31eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj*/ 32eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 33eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* This file manages the data structures built by the debuginfo 34eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj system. These are: the top level SegInfo list. For each SegInfo, 35eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj there are tables for for address-to-symbol mappings, 36eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj address-to-src-file/line mappings, and address-to-CFI-info 37eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj mappings. 38eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj*/ 39eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 40eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_basics.h" 41eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_options.h" /* VG_(clo_verbosity) */ 42588658b13b5ad77672f323d48fe9da0ca60b0bcbtom#include "pub_core_debuginfo.h" 435c3dba227192de63d86f65ec7d9597c132818c37philippe#include "pub_core_debuglog.h" 44eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_libcassert.h" 45eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_libcbase.h" 46eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_libcprint.h" 4772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj#include "pub_core_xarray.h" 48b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_oset.h" 497293d2530f8c60c1060f9f003e214cc341d35266philippe#include "pub_core_deduppoolalloc.h" 50b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 51b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "priv_misc.h" /* dinfo_zalloc/free/strdup */ 525d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj#include "priv_image.h" 53b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "priv_d3basics.h" /* ML_(pp_GX) */ 54b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "priv_tytypes.h" 55b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "priv_storage.h" /* self */ 56eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 57eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 58eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 59eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- Misc (printing, errors) ---*/ 60eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 61eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 62205a42f1b48012de8b9633982d3a2d21cb26e006florian/* Show a non-fatal debug info reading error. Use VG_(core_panic) for 63205a42f1b48012de8b9633982d3a2d21cb26e006florian fatal errors. 'serious' errors are shown regardless of the 64b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj verbosity setting. */ 65518850bf0da07ed3e2244e307268ae0fd80e93a8florianvoid ML_(symerr) ( const DebugInfo* di, Bool serious, const HChar* msg ) 66eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 67b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* XML mode hides everything :-( */ 68b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (VG_(clo_xml)) 69b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return; 70b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 71b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (serious) { 72b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 73b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(message)(Vg_DebugMsg, "WARNING: Serious error when " 74738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "reading debug info\n"); 75b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (True || VG_(clo_verbosity) < 2) { 76b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Need to show what the file name is, at verbosity levels 2 77b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj or below, since that won't already have been shown */ 78b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(message)(Vg_DebugMsg, 79738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "When reading debug info from %s:\n", 80a5acac39bf3be7546222b1316faee5ee524be0d1sewardj (di && di->fsm.filename) ? di->fsm.filename 811636d33c13958b9c0e7d3059cdd5005746418eb2florian : "???"); 82b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 83738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_DebugMsg, "%s\n", msg); 84b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 85b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { /* !serious */ 86b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 87b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (VG_(clo_verbosity) >= 2) 88738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_DebugMsg, "%s\n", msg); 89b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 90b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 91eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 92eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 93b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 94eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Print a symbol. */ 95518850bf0da07ed3e2244e307268ae0fd80e93a8florianvoid ML_(ppSym) ( Int idx, const DiSym* sym ) 96eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 971ef70c6f00ab1b50d1936f77037e9923d8ed8c59florian const HChar** sec_names = sym->sec_names; 98a5cace0c2a3e212931badbf6398a0cd98393121asewardj vg_assert(sym->pri_name); 99a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (sec_names) 100a5cace0c2a3e212931badbf6398a0cd98393121asewardj vg_assert(sec_names); 1017cf235b7622757d6a29b9a61d9698f7eda9d1ed1sewardj VG_(printf)( "%5d: %c%c %#8lx .. %#8lx (%d) %s%s", 102738856f99eea33d86ce91dcb1d6cd5b151e307casewardj idx, 1037cf235b7622757d6a29b9a61d9698f7eda9d1ed1sewardj sym->isText ? 'T' : '-', 1047cf235b7622757d6a29b9a61d9698f7eda9d1ed1sewardj sym->isIFunc ? 'I' : '-', 1054cace66777ca9ee73ea156210c04e9d4cc178395philippe sym->avmas.main, 1064cace66777ca9ee73ea156210c04e9d4cc178395philippe sym->avmas.main + sym->size - 1, sym->size, 107a5cace0c2a3e212931badbf6398a0cd98393121asewardj sym->pri_name, sec_names ? " " : "" ); 108a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (sec_names) { 109a5cace0c2a3e212931badbf6398a0cd98393121asewardj while (*sec_names) { 110a5cace0c2a3e212931badbf6398a0cd98393121asewardj VG_(printf)("%s%s", *sec_names, *(sec_names+1) ? " " : ""); 111a5cace0c2a3e212931badbf6398a0cd98393121asewardj sec_names++; 112a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 113a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 114a5cace0c2a3e212931badbf6398a0cd98393121asewardj VG_(printf)("\n"); 115eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 116eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 117eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Print a call-frame-info summary. */ 118518850bf0da07ed3e2244e307268ae0fd80e93a8florianvoid ML_(ppDiCfSI) ( const XArray* /* of CfiExpr */ exprs, 1195c3dba227192de63d86f65ec7d9597c132818c37philippe Addr base, UInt len, 120518850bf0da07ed3e2244e307268ae0fd80e93a8florian const DiCfSI_m* si_m ) 121eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 122eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# define SHOW_HOW(_how, _off) \ 123eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj do { \ 124eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (_how == CFIR_UNKNOWN) { \ 125eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(printf)("Unknown"); \ 126eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else \ 127eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (_how == CFIR_SAME) { \ 128eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(printf)("Same"); \ 129eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else \ 130eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (_how == CFIR_CFAREL) { \ 131eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(printf)("cfa+%d", _off); \ 132eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else \ 133eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (_how == CFIR_MEMCFAREL) { \ 134eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(printf)("*(cfa+%d)", _off); \ 13572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } else \ 13672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj if (_how == CFIR_EXPR) { \ 13772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj VG_(printf)("{"); \ 13872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj ML_(ppCfiExpr)(exprs, _off); \ 13972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj VG_(printf)("}"); \ 140eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else { \ 14172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj vg_assert(0+0); \ 142eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } \ 143eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } while (0) 144eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1455c3dba227192de63d86f65ec7d9597c132818c37philippe VG_(printf)("[%#lx .. %#lx]: ", base, 1465c3dba227192de63d86f65ec7d9597c132818c37philippe base + (UWord)len - 1); 1475c3dba227192de63d86f65ec7d9597c132818c37philippe switch (si_m->cfa_how) { 1483026f71684a930286186aa10fef266c304672e8fsewardj case CFIC_IA_SPREL: 1495c3dba227192de63d86f65ec7d9597c132818c37philippe VG_(printf)("let cfa=oldSP+%d", si_m->cfa_off); 15072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; 1513026f71684a930286186aa10fef266c304672e8fsewardj case CFIC_IA_BPREL: 1525c3dba227192de63d86f65ec7d9597c132818c37philippe VG_(printf)("let cfa=oldBP+%d", si_m->cfa_off); 1533026f71684a930286186aa10fef266c304672e8fsewardj break; 1543026f71684a930286186aa10fef266c304672e8fsewardj case CFIC_ARM_R13REL: 1555c3dba227192de63d86f65ec7d9597c132818c37philippe VG_(printf)("let cfa=oldR13+%d", si_m->cfa_off); 1563026f71684a930286186aa10fef266c304672e8fsewardj break; 1573026f71684a930286186aa10fef266c304672e8fsewardj case CFIC_ARM_R12REL: 1585c3dba227192de63d86f65ec7d9597c132818c37philippe VG_(printf)("let cfa=oldR12+%d", si_m->cfa_off); 1593026f71684a930286186aa10fef266c304672e8fsewardj break; 1603026f71684a930286186aa10fef266c304672e8fsewardj case CFIC_ARM_R11REL: 1615c3dba227192de63d86f65ec7d9597c132818c37philippe VG_(printf)("let cfa=oldR11+%d", si_m->cfa_off); 16272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; 163b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case CFIR_SAME: 164b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj VG_(printf)("let cfa=Same"); 165b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj break; 166fa5ce5616a17e79828fbc79f30b02b5085151e3csewardj case CFIC_ARM_R7REL: 1675c3dba227192de63d86f65ec7d9597c132818c37philippe VG_(printf)("let cfa=oldR7+%d", si_m->cfa_off); 168fa5ce5616a17e79828fbc79f30b02b5085151e3csewardj break; 169821283b2110420321fd3f60afcc799b287788c68sewardj case CFIC_ARM64_SPREL: 1705c3dba227192de63d86f65ec7d9597c132818c37philippe VG_(printf)("let cfa=oldSP+%d", si_m->cfa_off); 171821283b2110420321fd3f60afcc799b287788c68sewardj break; 172821283b2110420321fd3f60afcc799b287788c68sewardj case CFIC_ARM64_X29REL: 1735c3dba227192de63d86f65ec7d9597c132818c37philippe VG_(printf)("let cfa=oldX29+%d", si_m->cfa_off); 174821283b2110420321fd3f60afcc799b287788c68sewardj break; 17572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case CFIC_EXPR: 17672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj VG_(printf)("let cfa={"); 1775c3dba227192de63d86f65ec7d9597c132818c37philippe ML_(ppCfiExpr)(exprs, si_m->cfa_off); 17872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj VG_(printf)("}"); 17972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; 18072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: 18172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj vg_assert(0); 18272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 18372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 184eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(printf)(" in RA="); 1855c3dba227192de63d86f65ec7d9597c132818c37philippe SHOW_HOW(si_m->ra_how, si_m->ra_off); 1863026f71684a930286186aa10fef266c304672e8fsewardj# if defined(VGA_x86) || defined(VGA_amd64) 187eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(printf)(" SP="); 1885c3dba227192de63d86f65ec7d9597c132818c37philippe SHOW_HOW(si_m->sp_how, si_m->sp_off); 1893026f71684a930286186aa10fef266c304672e8fsewardj VG_(printf)(" BP="); 1905c3dba227192de63d86f65ec7d9597c132818c37philippe SHOW_HOW(si_m->bp_how, si_m->bp_off); 1913026f71684a930286186aa10fef266c304672e8fsewardj# elif defined(VGA_arm) 1923026f71684a930286186aa10fef266c304672e8fsewardj VG_(printf)(" R14="); 1935c3dba227192de63d86f65ec7d9597c132818c37philippe SHOW_HOW(si_m->r14_how, si_m->r14_off); 1943026f71684a930286186aa10fef266c304672e8fsewardj VG_(printf)(" R13="); 1955c3dba227192de63d86f65ec7d9597c132818c37philippe SHOW_HOW(si_m->r13_how, si_m->r13_off); 1963026f71684a930286186aa10fef266c304672e8fsewardj VG_(printf)(" R12="); 1975c3dba227192de63d86f65ec7d9597c132818c37philippe SHOW_HOW(si_m->r12_how, si_m->r12_off); 1983026f71684a930286186aa10fef266c304672e8fsewardj VG_(printf)(" R11="); 1995c3dba227192de63d86f65ec7d9597c132818c37philippe SHOW_HOW(si_m->r11_how, si_m->r11_off); 200fa5ce5616a17e79828fbc79f30b02b5085151e3csewardj VG_(printf)(" R7="); 2015c3dba227192de63d86f65ec7d9597c132818c37philippe SHOW_HOW(si_m->r7_how, si_m->r7_off); 202582d58245637ab05272d89fb94b12fd0f18fa0f8carll# elif defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le) 2034df0bfc0614379192c780c944415dc420d9cfe8epetarj# elif defined(VGA_s390x) || defined(VGA_mips32) || defined(VGA_mips64) 204b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj VG_(printf)(" SP="); 2055c3dba227192de63d86f65ec7d9597c132818c37philippe SHOW_HOW(si_m->sp_how, si_m->sp_off); 206b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj VG_(printf)(" FP="); 2075c3dba227192de63d86f65ec7d9597c132818c37philippe SHOW_HOW(si_m->fp_how, si_m->fp_off); 208f0c1250e324f6684757c6a15545366447ef1d64fsewardj# elif defined(VGA_arm64) 209821283b2110420321fd3f60afcc799b287788c68sewardj VG_(printf)(" SP="); 2105c3dba227192de63d86f65ec7d9597c132818c37philippe SHOW_HOW(si_m->sp_how, si_m->sp_off); 211821283b2110420321fd3f60afcc799b287788c68sewardj VG_(printf)(" X30="); 2125c3dba227192de63d86f65ec7d9597c132818c37philippe SHOW_HOW(si_m->x30_how, si_m->x30_off); 213821283b2110420321fd3f60afcc799b287788c68sewardj VG_(printf)(" X29="); 2145c3dba227192de63d86f65ec7d9597c132818c37philippe SHOW_HOW(si_m->x29_how, si_m->x29_off); 215112711afefcfcd43680c7c4aa8d38ef180e8811esewardj# elif defined(VGA_tilegx) 216112711afefcfcd43680c7c4aa8d38ef180e8811esewardj VG_(printf)(" SP="); 217112711afefcfcd43680c7c4aa8d38ef180e8811esewardj SHOW_HOW(si_m->sp_how, si_m->sp_off); 218112711afefcfcd43680c7c4aa8d38ef180e8811esewardj VG_(printf)(" FP="); 219112711afefcfcd43680c7c4aa8d38ef180e8811esewardj SHOW_HOW(si_m->fp_how, si_m->fp_off); 2203026f71684a930286186aa10fef266c304672e8fsewardj# else 2213026f71684a930286186aa10fef266c304672e8fsewardj# error "Unknown arch" 2223026f71684a930286186aa10fef266c304672e8fsewardj# endif 223eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(printf)("\n"); 224eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# undef SHOW_HOW 225eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 226eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 227eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 228eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 229eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- Adding stuff ---*/ 230eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 231eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 232eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Add a str to the string table, including terminating zero, and 233eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return pointer to the string in vg_strtab. Unless it's been seen 234eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj recently, in which case we find the old pointer and return that. 235eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj This avoids the most egregious duplications. 236eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 237eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj JSGF: changed from returning an index to a pointer, and changed to 238eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj a chunking memory allocator rather than reallocating, so the 239eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj pointers are stable. 240eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj*/ 2411ef70c6f00ab1b50d1936f77037e9923d8ed8c59florianconst HChar* ML_(addStr) ( DebugInfo* di, const HChar* str, Int len ) 242eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 243b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (len == -1) { 244eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj len = VG_(strlen)(str); 245b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 246b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(len >= 0); 247b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2487293d2530f8c60c1060f9f003e214cc341d35266philippe if (UNLIKELY(di->strpool == NULL)) 2497293d2530f8c60c1060f9f003e214cc341d35266philippe di->strpool = VG_(newDedupPA)(SEGINFO_STRPOOLSIZE, 2507293d2530f8c60c1060f9f003e214cc341d35266philippe 1, 2517293d2530f8c60c1060f9f003e214cc341d35266philippe ML_(dinfo_zalloc), 2527293d2530f8c60c1060f9f003e214cc341d35266philippe "di.storage.addStr.1", 2537293d2530f8c60c1060f9f003e214cc341d35266philippe ML_(dinfo_free)); 2541ef70c6f00ab1b50d1936f77037e9923d8ed8c59florian return VG_(allocEltDedupPA) (di->strpool, len+1, str); 255eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 256eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 25759e1f3c79e870a978d24add86db6d8c5450c8b63philippeUInt ML_(addFnDn) (struct _DebugInfo* di, 25859e1f3c79e870a978d24add86db6d8c5450c8b63philippe const HChar* filename, 25959e1f3c79e870a978d24add86db6d8c5450c8b63philippe const HChar* dirname) 26059e1f3c79e870a978d24add86db6d8c5450c8b63philippe{ 26159e1f3c79e870a978d24add86db6d8c5450c8b63philippe FnDn fndn; 26259e1f3c79e870a978d24add86db6d8c5450c8b63philippe UInt fndn_ix; 26359e1f3c79e870a978d24add86db6d8c5450c8b63philippe 26459e1f3c79e870a978d24add86db6d8c5450c8b63philippe if (UNLIKELY(di->fndnpool == NULL)) 26559e1f3c79e870a978d24add86db6d8c5450c8b63philippe di->fndnpool = VG_(newDedupPA)(500, 26659e1f3c79e870a978d24add86db6d8c5450c8b63philippe vg_alignof(FnDn), 26759e1f3c79e870a978d24add86db6d8c5450c8b63philippe ML_(dinfo_zalloc), 26859e1f3c79e870a978d24add86db6d8c5450c8b63philippe "di.storage.addFnDn.1", 26959e1f3c79e870a978d24add86db6d8c5450c8b63philippe ML_(dinfo_free)); 27059e1f3c79e870a978d24add86db6d8c5450c8b63philippe fndn.filename = ML_(addStr)(di, filename, -1); 27159e1f3c79e870a978d24add86db6d8c5450c8b63philippe fndn.dirname = dirname ? ML_(addStr)(di, dirname, -1) : NULL; 27259e1f3c79e870a978d24add86db6d8c5450c8b63philippe fndn_ix = VG_(allocFixedEltDedupPA) (di->fndnpool, sizeof(FnDn), &fndn); 27359e1f3c79e870a978d24add86db6d8c5450c8b63philippe return fndn_ix; 27459e1f3c79e870a978d24add86db6d8c5450c8b63philippe} 275eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 276518850bf0da07ed3e2244e307268ae0fd80e93a8florianconst HChar* ML_(fndn_ix2filename) (const DebugInfo* di, 277666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe UInt fndn_ix) 278666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe{ 279666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe FnDn *fndn; 280666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe if (fndn_ix == 0) 281666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe return "???"; 282666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe else { 283666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe fndn = VG_(indexEltNumber) (di->fndnpool, fndn_ix); 284666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe return fndn->filename; 285666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe } 286666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe} 287666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe 288518850bf0da07ed3e2244e307268ae0fd80e93a8florianconst HChar* ML_(fndn_ix2dirname) (const DebugInfo* di, 289666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe UInt fndn_ix) 290666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe{ 291666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe FnDn *fndn; 292666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe if (fndn_ix == 0) 293666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe return ""; 294666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe else { 295666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe fndn = VG_(indexEltNumber) (di->fndnpool, fndn_ix); 296666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe if (fndn->dirname) 297666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe return fndn->dirname; 298666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe else 299666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe return ""; 300666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe } 301666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe} 302666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe 3035d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* Add a string to the string table of a DebugInfo, by copying the 3045d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj string from the given DiCursor. Measures the length of the string 3055d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj itself. */ 3061ef70c6f00ab1b50d1936f77037e9923d8ed8c59florianconst HChar* ML_(addStrFromCursor)( DebugInfo* di, DiCursor c ) 3075d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj{ 3085d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj /* This is a less-than-stellar implementation, but it should 3095d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj work. */ 3105d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj vg_assert(ML_(cur_is_valid)(c)); 3115d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj HChar* str = ML_(cur_read_strdup)(c, "di.addStrFromCursor.1"); 3121ef70c6f00ab1b50d1936f77037e9923d8ed8c59florian const HChar* res = ML_(addStr)(di, str, -1); 3135d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj ML_(dinfo_free)(str); 3145d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj return res; 3155d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj} 3165d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj 3175d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj 318a5cace0c2a3e212931badbf6398a0cd98393121asewardj/* Add a symbol to the symbol table, by copying *sym. 'sym' may only 319a5cace0c2a3e212931badbf6398a0cd98393121asewardj have one name, so there's no complexities to do with deep vs 320a5cace0c2a3e212931badbf6398a0cd98393121asewardj shallow copying of the sec_name array. This is checked. 321eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj*/ 322b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid ML_(addSym) ( struct _DebugInfo* di, DiSym* sym ) 323eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 324eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj UInt new_sz, i; 325eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj DiSym* new_tab; 326eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 327a5cace0c2a3e212931badbf6398a0cd98393121asewardj vg_assert(sym->pri_name != NULL); 328a5cace0c2a3e212931badbf6398a0cd98393121asewardj vg_assert(sym->sec_names == NULL); 329a5cace0c2a3e212931badbf6398a0cd98393121asewardj 330eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* Ignore zero-sized syms. */ 331eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (sym->size == 0) return; 332eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 333b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->symtab_used == di->symtab_size) { 334b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj new_sz = 2 * di->symtab_size; 335eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (new_sz == 0) new_sz = 500; 3369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj new_tab = ML_(dinfo_zalloc)( "di.storage.addSym.1", 3379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj new_sz * sizeof(DiSym) ); 338b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->symtab != NULL) { 339b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (i = 0; i < di->symtab_used; i++) 340b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj new_tab[i] = di->symtab[i]; 341b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(dinfo_free)(di->symtab); 342eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 343b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->symtab = new_tab; 344b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->symtab_size = new_sz; 345eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 346eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 347a5cace0c2a3e212931badbf6398a0cd98393121asewardj di->symtab[di->symtab_used++] = *sym; 348b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di->symtab_used <= di->symtab_size); 349eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 350eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 351518850bf0da07ed3e2244e307268ae0fd80e93a8florianUInt ML_(fndn_ix) (const DebugInfo* di, Word locno) 35259e1f3c79e870a978d24add86db6d8c5450c8b63philippe{ 35359e1f3c79e870a978d24add86db6d8c5450c8b63philippe UInt fndn_ix; 35459e1f3c79e870a978d24add86db6d8c5450c8b63philippe 35559e1f3c79e870a978d24add86db6d8c5450c8b63philippe switch(di->sizeof_fndn_ix) { 35659e1f3c79e870a978d24add86db6d8c5450c8b63philippe case 1: fndn_ix = ((UChar*) di->loctab_fndn_ix)[locno]; break; 35759e1f3c79e870a978d24add86db6d8c5450c8b63philippe case 2: fndn_ix = ((UShort*) di->loctab_fndn_ix)[locno]; break; 35859e1f3c79e870a978d24add86db6d8c5450c8b63philippe case 4: fndn_ix = ((UInt*) di->loctab_fndn_ix)[locno]; break; 35959e1f3c79e870a978d24add86db6d8c5450c8b63philippe default: vg_assert(0); 36059e1f3c79e870a978d24add86db6d8c5450c8b63philippe } 36159e1f3c79e870a978d24add86db6d8c5450c8b63philippe return fndn_ix; 36259e1f3c79e870a978d24add86db6d8c5450c8b63philippe} 36359e1f3c79e870a978d24add86db6d8c5450c8b63philippe 36459e1f3c79e870a978d24add86db6d8c5450c8b63philippestatic inline void set_fndn_ix (struct _DebugInfo* di, Word locno, UInt fndn_ix) 36559e1f3c79e870a978d24add86db6d8c5450c8b63philippe{ 36659e1f3c79e870a978d24add86db6d8c5450c8b63philippe Word i; 36759e1f3c79e870a978d24add86db6d8c5450c8b63philippe 36859e1f3c79e870a978d24add86db6d8c5450c8b63philippe switch(di->sizeof_fndn_ix) { 36959e1f3c79e870a978d24add86db6d8c5450c8b63philippe case 1: 37059e1f3c79e870a978d24add86db6d8c5450c8b63philippe if (LIKELY (fndn_ix <= 255)) { 37159e1f3c79e870a978d24add86db6d8c5450c8b63philippe ((UChar*) di->loctab_fndn_ix)[locno] = fndn_ix; 37259e1f3c79e870a978d24add86db6d8c5450c8b63philippe return; 37359e1f3c79e870a978d24add86db6d8c5450c8b63philippe } 37459e1f3c79e870a978d24add86db6d8c5450c8b63philippe { 37559e1f3c79e870a978d24add86db6d8c5450c8b63philippe UChar* old = (UChar*) di->loctab_fndn_ix; 37659e1f3c79e870a978d24add86db6d8c5450c8b63philippe UShort* new = ML_(dinfo_zalloc)( "di.storage.sfix.1", 37759e1f3c79e870a978d24add86db6d8c5450c8b63philippe di->loctab_size * 2 ); 37859e1f3c79e870a978d24add86db6d8c5450c8b63philippe for (i = 0; i < di->loctab_used; i++) 37959e1f3c79e870a978d24add86db6d8c5450c8b63philippe new[i] = old[i]; 38059e1f3c79e870a978d24add86db6d8c5450c8b63philippe ML_(dinfo_free)(old); 38159e1f3c79e870a978d24add86db6d8c5450c8b63philippe di->sizeof_fndn_ix = 2; 38259e1f3c79e870a978d24add86db6d8c5450c8b63philippe di->loctab_fndn_ix = new; 38359e1f3c79e870a978d24add86db6d8c5450c8b63philippe } 38459e1f3c79e870a978d24add86db6d8c5450c8b63philippe // Fallthrough 38559e1f3c79e870a978d24add86db6d8c5450c8b63philippe 38659e1f3c79e870a978d24add86db6d8c5450c8b63philippe case 2: 38759e1f3c79e870a978d24add86db6d8c5450c8b63philippe if (LIKELY (fndn_ix <= 65535)) { 38859e1f3c79e870a978d24add86db6d8c5450c8b63philippe ((UShort*) di->loctab_fndn_ix)[locno] = fndn_ix; 38959e1f3c79e870a978d24add86db6d8c5450c8b63philippe return; 39059e1f3c79e870a978d24add86db6d8c5450c8b63philippe } 39159e1f3c79e870a978d24add86db6d8c5450c8b63philippe { 39259e1f3c79e870a978d24add86db6d8c5450c8b63philippe UShort* old = (UShort*) di->loctab_fndn_ix; 39359e1f3c79e870a978d24add86db6d8c5450c8b63philippe UInt* new = ML_(dinfo_zalloc)( "di.storage.sfix.2", 39459e1f3c79e870a978d24add86db6d8c5450c8b63philippe di->loctab_size * 4 ); 39559e1f3c79e870a978d24add86db6d8c5450c8b63philippe for (i = 0; i < di->loctab_used; i++) 39659e1f3c79e870a978d24add86db6d8c5450c8b63philippe new[i] = old[i]; 39759e1f3c79e870a978d24add86db6d8c5450c8b63philippe ML_(dinfo_free)(old); 39859e1f3c79e870a978d24add86db6d8c5450c8b63philippe di->sizeof_fndn_ix = 4; 39959e1f3c79e870a978d24add86db6d8c5450c8b63philippe di->loctab_fndn_ix = new; 40059e1f3c79e870a978d24add86db6d8c5450c8b63philippe } 40159e1f3c79e870a978d24add86db6d8c5450c8b63philippe // Fallthrough 40259e1f3c79e870a978d24add86db6d8c5450c8b63philippe 40359e1f3c79e870a978d24add86db6d8c5450c8b63philippe case 4: 40459e1f3c79e870a978d24add86db6d8c5450c8b63philippe ((UInt*) di->loctab_fndn_ix)[locno] = fndn_ix; 40559e1f3c79e870a978d24add86db6d8c5450c8b63philippe return; 40659e1f3c79e870a978d24add86db6d8c5450c8b63philippe 40759e1f3c79e870a978d24add86db6d8c5450c8b63philippe default: vg_assert(0); 40859e1f3c79e870a978d24add86db6d8c5450c8b63philippe } 40959e1f3c79e870a978d24add86db6d8c5450c8b63philippe} 410eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 411eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Add a location to the location table. 412eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj*/ 41359e1f3c79e870a978d24add86db6d8c5450c8b63philippestatic void addLoc ( struct _DebugInfo* di, DiLoc* loc, UInt fndn_ix ) 414eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 415eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* Zero-sized locs should have been ignored earlier */ 416eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert(loc->size > 0); 417eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 418b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->loctab_used == di->loctab_size) { 41959e1f3c79e870a978d24add86db6d8c5450c8b63philippe UInt new_sz; 42059e1f3c79e870a978d24add86db6d8c5450c8b63philippe DiLoc* new_loctab; 42159e1f3c79e870a978d24add86db6d8c5450c8b63philippe void* new_loctab_fndn_ix; 42259e1f3c79e870a978d24add86db6d8c5450c8b63philippe 423b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj new_sz = 2 * di->loctab_size; 424eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (new_sz == 0) new_sz = 500; 42559e1f3c79e870a978d24add86db6d8c5450c8b63philippe new_loctab = ML_(dinfo_zalloc)( "di.storage.addLoc.1", 42659e1f3c79e870a978d24add86db6d8c5450c8b63philippe new_sz * sizeof(DiLoc) ); 42759e1f3c79e870a978d24add86db6d8c5450c8b63philippe if (di->sizeof_fndn_ix == 0) 42859e1f3c79e870a978d24add86db6d8c5450c8b63philippe di->sizeof_fndn_ix = 1; // To start with. 42959e1f3c79e870a978d24add86db6d8c5450c8b63philippe new_loctab_fndn_ix = ML_(dinfo_zalloc)( "di.storage.addLoc.2", 43059e1f3c79e870a978d24add86db6d8c5450c8b63philippe new_sz * di->sizeof_fndn_ix ); 431b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->loctab != NULL) { 43259e1f3c79e870a978d24add86db6d8c5450c8b63philippe VG_(memcpy)(new_loctab, di->loctab, 43359e1f3c79e870a978d24add86db6d8c5450c8b63philippe di->loctab_used * sizeof(DiLoc)); 43459e1f3c79e870a978d24add86db6d8c5450c8b63philippe VG_(memcpy)(new_loctab_fndn_ix, di->loctab_fndn_ix, 43559e1f3c79e870a978d24add86db6d8c5450c8b63philippe di->loctab_used * di->sizeof_fndn_ix); 436b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(dinfo_free)(di->loctab); 43759e1f3c79e870a978d24add86db6d8c5450c8b63philippe ML_(dinfo_free)(di->loctab_fndn_ix); 438eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 43959e1f3c79e870a978d24add86db6d8c5450c8b63philippe di->loctab = new_loctab; 44059e1f3c79e870a978d24add86db6d8c5450c8b63philippe di->loctab_fndn_ix = new_loctab_fndn_ix; 441b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->loctab_size = new_sz; 442eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 443eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 444b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->loctab[di->loctab_used] = *loc; 44559e1f3c79e870a978d24add86db6d8c5450c8b63philippe set_fndn_ix (di, di->loctab_used, fndn_ix); 446b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->loctab_used++; 447b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di->loctab_used <= di->loctab_size); 448eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 449eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 450eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 451796e4b25100561a9e953cfe4dad83130b0153ce5sewardj/* Resize the LocTab (line number table) to save memory, by removing 452796e4b25100561a9e953cfe4dad83130b0153ce5sewardj (and, potentially, allowing m_mallocfree to unmap) any unused space 4530b9d0646949bd382758763664d3bf2d6115993aephilippe at the end of the table. */ 454796e4b25100561a9e953cfe4dad83130b0153ce5sewardjstatic void shrinkLocTab ( struct _DebugInfo* di ) 455f76d27a697a7b0bf3b84490baf60623fc96a23afnjn{ 456796e4b25100561a9e953cfe4dad83130b0153ce5sewardj UWord new_sz = di->loctab_used; 457f76d27a697a7b0bf3b84490baf60623fc96a23afnjn if (new_sz == di->loctab_size) return; 458796e4b25100561a9e953cfe4dad83130b0153ce5sewardj vg_assert(new_sz < di->loctab_size); 4590b9d0646949bd382758763664d3bf2d6115993aephilippe ML_(dinfo_shrink_block)( di->loctab, new_sz * sizeof(DiLoc)); 46059e1f3c79e870a978d24add86db6d8c5450c8b63philippe ML_(dinfo_shrink_block)( di->loctab_fndn_ix, new_sz * di->sizeof_fndn_ix); 461f76d27a697a7b0bf3b84490baf60623fc96a23afnjn di->loctab_size = new_sz; 462f76d27a697a7b0bf3b84490baf60623fc96a23afnjn} 463f76d27a697a7b0bf3b84490baf60623fc96a23afnjn 464f76d27a697a7b0bf3b84490baf60623fc96a23afnjn 465eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Top-level place to call to add a source-location mapping entry. 466eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj*/ 467b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid ML_(addLineInfo) ( struct _DebugInfo* di, 46859e1f3c79e870a978d24add86db6d8c5450c8b63philippe UInt fndn_ix, 469eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Addr this, 470eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Addr next, 471eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Int lineno, 472eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Int entry /* only needed for debug printing */ 473eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj ) 474eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 475eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj static const Bool debug = False; 476eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj DiLoc loc; 477c1d946eb075492d55397d0070349e3b8461bd793sewardj UWord size = next - this; 478eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 479eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* Ignore zero-sized locs */ 480eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (this == next) return; 481eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 48259e1f3c79e870a978d24add86db6d8c5450c8b63philippe if (debug) { 48359e1f3c79e870a978d24add86db6d8c5450c8b63philippe FnDn *fndn = VG_(indexEltNumber) (di->fndnpool, fndn_ix); 48459e1f3c79e870a978d24add86db6d8c5450c8b63philippe VG_(printf)( " src ix %u %s %s line %d %#lx-%#lx\n", 48559e1f3c79e870a978d24add86db6d8c5450c8b63philippe fndn_ix, 48659e1f3c79e870a978d24add86db6d8c5450c8b63philippe fndn->dirname ? fndn->dirname : "(unknown)", 48759e1f3c79e870a978d24add86db6d8c5450c8b63philippe fndn->filename, lineno, this, next ); 48859e1f3c79e870a978d24add86db6d8c5450c8b63philippe } 489eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 490eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* Maximum sanity checking. Some versions of GNU as do a shabby 491eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj * job with stabs entries; if anything looks suspicious, revert to 492eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj * a size of 1. This should catch the instruction of interest 493eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj * (since if using asm-level debug info, one instruction will 494eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj * correspond to one line, unlike with C-level debug info where 495eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj * multiple instructions can map to the one line), but avoid 496eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj * catching any other instructions bogusly. */ 497eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (this > next) { 498eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (VG_(clo_verbosity) > 2) { 499eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(message)(Vg_DebugMsg, 500eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj "warning: line info addresses out of order " 501738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "at entry %d: 0x%lx 0x%lx\n", entry, this, next); 502eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 503eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj size = 1; 504eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 505eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 506eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (size > MAX_LOC_SIZE) { 507eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (0) 508eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(message)(Vg_DebugMsg, 509eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj "warning: line info address range too large " 510c1d946eb075492d55397d0070349e3b8461bd793sewardj "at entry %d: %lu\n", entry, size); 511eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj size = 1; 512eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 513eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 514c1d946eb075492d55397d0070349e3b8461bd793sewardj /* At this point, we know that the original value for |size|, viz 515c1d946eb075492d55397d0070349e3b8461bd793sewardj |next - this|, will only still be used in the case where 516c1d946eb075492d55397d0070349e3b8461bd793sewardj |this| <u |next|, so it can't have underflowed. Considering 517c1d946eb075492d55397d0070349e3b8461bd793sewardj that and the three checks that follow it, the following must 518c1d946eb075492d55397d0070349e3b8461bd793sewardj hold. */ 519c1d946eb075492d55397d0070349e3b8461bd793sewardj vg_assert(size >= 1); 520c1d946eb075492d55397d0070349e3b8461bd793sewardj vg_assert(size <= MAX_LOC_SIZE); 521c1d946eb075492d55397d0070349e3b8461bd793sewardj 522b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Rule out ones which are completely outside the r-x mapped area. 523b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj See "Comment_Regarding_Text_Range_Checks" elsewhere in this file 524b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for background and rationale. */ 525a5acac39bf3be7546222b1316faee5ee524be0d1sewardj vg_assert(di->fsm.have_rx_map && di->fsm.have_rw_map); 526c1d946eb075492d55397d0070349e3b8461bd793sewardj if (ML_(find_rx_mapping)(di, this, this + size - 1) == NULL) { 527eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (0) 528eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(message)(Vg_DebugMsg, 529eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj "warning: ignoring line info entry falling " 530738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "outside current DebugInfo: %#lx %#lx %#lx %#lx\n", 531b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->text_avma, 532b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->text_avma + di->text_size, 533c1d946eb075492d55397d0070349e3b8461bd793sewardj this, this + size - 1); 534eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return; 535eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 536eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 537eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert(lineno >= 0); 538eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (lineno > MAX_LINENO) { 539eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj static Bool complained = False; 540eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (!complained) { 541eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj complained = True; 542eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(message)(Vg_UserMsg, 543eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj "warning: ignoring line info entry with " 544738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "huge line number (%d)\n", lineno); 545eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(message)(Vg_UserMsg, 546eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj " Can't handle line numbers " 547738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "greater than %d, sorry\n", MAX_LINENO); 548eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(message)(Vg_UserMsg, 549738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "(Nb: this message is only shown once)\n"); 550eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 551eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return; 552eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 553eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 554eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj loc.addr = this; 555eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj loc.size = (UShort)size; 556eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj loc.lineno = lineno; 557eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 558eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (0) VG_(message)(Vg_DebugMsg, 55959e1f3c79e870a978d24add86db6d8c5450c8b63philippe "addLoc: addr %#lx, size %lu, line %d, fndn_ix %u\n", 56059e1f3c79e870a978d24add86db6d8c5450c8b63philippe this,size,lineno,fndn_ix); 561eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 56259e1f3c79e870a978d24add86db6d8c5450c8b63philippe addLoc ( di, &loc, fndn_ix ); 563eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 564eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 565a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe/* Add an inlined call info to the inlined call table. 566a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe*/ 567a0a73939b0398b6608fd6dbde49820ce6530d12cphilippestatic void addInl ( struct _DebugInfo* di, DiInlLoc* inl ) 568a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{ 569a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe UInt new_sz, i; 570a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe DiInlLoc* new_tab; 571a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 572a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /* empty inl should have been ignored earlier */ 573a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe vg_assert(inl->addr_lo < inl->addr_hi); 574a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 575a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (di->inltab_used == di->inltab_size) { 576a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe new_sz = 2 * di->inltab_size; 577a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (new_sz == 0) new_sz = 500; 578a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe new_tab = ML_(dinfo_zalloc)( "di.storage.addInl.1", 579a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe new_sz * sizeof(DiInlLoc) ); 580a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (di->inltab != NULL) { 581a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe for (i = 0; i < di->inltab_used; i++) 582a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe new_tab[i] = di->inltab[i]; 583a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ML_(dinfo_free)(di->inltab); 584a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 585a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe di->inltab = new_tab; 586a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe di->inltab_size = new_sz; 587a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 588a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 589a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe di->inltab[di->inltab_used] = *inl; 590a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (inl->addr_hi - inl->addr_lo > di->maxinl_codesz) 591a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe di->maxinl_codesz = inl->addr_hi - inl->addr_lo; 592a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe di->inltab_used++; 593a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe vg_assert(di->inltab_used <= di->inltab_size); 594a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe} 595a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 596a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 597a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe/* Resize the InlTab (inlined call table) to save memory, by removing 598a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe (and, potentially, allowing m_mallocfree to unmap) any unused space 5990b9d0646949bd382758763664d3bf2d6115993aephilippe at the end of the table. */ 600a0a73939b0398b6608fd6dbde49820ce6530d12cphilippestatic void shrinkInlTab ( struct _DebugInfo* di ) 601a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{ 602a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe UWord new_sz = di->inltab_used; 603a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (new_sz == di->inltab_size) return; 604a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe vg_assert(new_sz < di->inltab_size); 6050b9d0646949bd382758763664d3bf2d6115993aephilippe ML_(dinfo_shrink_block)( di->inltab, new_sz * sizeof(DiInlLoc)); 606a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe di->inltab_size = new_sz; 607a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe} 608a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 609a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe/* Top-level place to call to add a addr-to-inlined fn info. */ 610a0a73939b0398b6608fd6dbde49820ce6530d12cphilippevoid ML_(addInlInfo) ( struct _DebugInfo* di, 611a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Addr addr_lo, Addr addr_hi, 612a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe const HChar* inlinedfn, 613666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe UInt fndn_ix, 614a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Int lineno, UShort level) 615a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{ 616a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe DiInlLoc inl; 617a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 618a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /* Similar paranoia as in ML_(addLineInfo). Unclear if needed. */ 619a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (addr_lo >= addr_hi) { 620a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (VG_(clo_verbosity) > 2) { 621a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe VG_(message)(Vg_DebugMsg, 622a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe "warning: inlined info addresses out of order " 623a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe "at: 0x%lx 0x%lx\n", addr_lo, addr_hi); 624a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 625a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe addr_hi = addr_lo + 1; 626a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 627a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 628a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe vg_assert(lineno >= 0); 629a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (lineno > MAX_LINENO) { 630a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe static Bool complained = False; 631a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (!complained) { 632a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe complained = True; 633a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe VG_(message)(Vg_UserMsg, 634a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe "warning: ignoring inlined call info entry with " 635a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe "huge line number (%d)\n", lineno); 636a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe VG_(message)(Vg_UserMsg, 637a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe " Can't handle line numbers " 638a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe "greater than %d, sorry\n", MAX_LINENO); 639a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe VG_(message)(Vg_UserMsg, 640a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe "(Nb: this message is only shown once)\n"); 641a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 642a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return; 643a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 644a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 645a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // code resulting from inlining of inlinedfn: 646a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe inl.addr_lo = addr_lo; 647a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe inl.addr_hi = addr_hi; 648a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe inl.inlinedfn = inlinedfn; 649a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // caller: 650666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe inl.fndn_ix = fndn_ix; 651a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe inl.lineno = lineno; 652a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe inl.level = level; 653a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 654a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (0) VG_(message) 655a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe (Vg_DebugMsg, 656a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe "addInlInfo: fn %s inlined as addr_lo %#lx,addr_hi %#lx," 657666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe "caller fndn_ix %d %s:%d\n", 658666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe inlinedfn, addr_lo, addr_hi, fndn_ix, 659666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe ML_(fndn_ix2filename) (di, fndn_ix), lineno); 660a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 661a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe addInl ( di, &inl ); 662a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe} 663a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 664518850bf0da07ed3e2244e307268ae0fd80e93a8florianDiCfSI_m* ML_(get_cfsi_m) (const DebugInfo* di, UInt pos) 6655c3dba227192de63d86f65ec7d9597c132818c37philippe{ 6665c3dba227192de63d86f65ec7d9597c132818c37philippe UInt cfsi_m_ix; 6675c3dba227192de63d86f65ec7d9597c132818c37philippe 6685c3dba227192de63d86f65ec7d9597c132818c37philippe vg_assert(pos >= 0 && pos < di->cfsi_used); 66959e1f3c79e870a978d24add86db6d8c5450c8b63philippe switch (di->sizeof_cfsi_m_ix) { 6705c3dba227192de63d86f65ec7d9597c132818c37philippe case 1: cfsi_m_ix = ((UChar*) di->cfsi_m_ix)[pos]; break; 6715c3dba227192de63d86f65ec7d9597c132818c37philippe case 2: cfsi_m_ix = ((UShort*) di->cfsi_m_ix)[pos]; break; 6725c3dba227192de63d86f65ec7d9597c132818c37philippe case 4: cfsi_m_ix = ((UInt*) di->cfsi_m_ix)[pos]; break; 6735c3dba227192de63d86f65ec7d9597c132818c37philippe default: vg_assert(0); 6745c3dba227192de63d86f65ec7d9597c132818c37philippe } 6755c3dba227192de63d86f65ec7d9597c132818c37philippe if (cfsi_m_ix == 0) 6765c3dba227192de63d86f65ec7d9597c132818c37philippe return NULL; // cfi hole 6775c3dba227192de63d86f65ec7d9597c132818c37philippe else 6785c3dba227192de63d86f65ec7d9597c132818c37philippe return VG_(indexEltNumber) (di->cfsi_m_pool, cfsi_m_ix); 6795c3dba227192de63d86f65ec7d9597c132818c37philippe} 680eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 681eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Top-level place to call to add a CFI summary record. The supplied 6825c3dba227192de63d86f65ec7d9597c132818c37philippe DiCfSI_m is copied. */ 6835c3dba227192de63d86f65ec7d9597c132818c37philippevoid ML_(addDiCfSI) ( struct _DebugInfo* di, 6845c3dba227192de63d86f65ec7d9597c132818c37philippe Addr base, UInt len, DiCfSI_m* cfsi_m ) 685eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 686eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj static const Bool debug = False; 6875c3dba227192de63d86f65ec7d9597c132818c37philippe UInt new_sz; 688eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj DiCfSI* new_tab; 68910deba428bd24d2105dbbe5bf58469385cc740besewardj SSizeT delta; 690518850bf0da07ed3e2244e307268ae0fd80e93a8florian DebugInfoMapping* map; 691518850bf0da07ed3e2244e307268ae0fd80e93a8florian DebugInfoMapping* map2; 69210deba428bd24d2105dbbe5bf58469385cc740besewardj 693eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (debug) { 694eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(printf)("adding DiCfSI: "); 6955c3dba227192de63d86f65ec7d9597c132818c37philippe ML_(ppDiCfSI)(di->cfsi_exprs, base, len, cfsi_m); 696eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 697eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 6982e54028ae63b2e4be7f737300a87d70f17b85edbsewardj /* sanity */ 6995c3dba227192de63d86f65ec7d9597c132818c37philippe vg_assert(len > 0); 7009b54074df0311ae2509cda596b388b065d101b67florian /* Issue a warning if LEN is unexpectedly large (exceeds 5 million). 7019b54074df0311ae2509cda596b388b065d101b67florian The implication is you have a single procedure 7022e54028ae63b2e4be7f737300a87d70f17b85edbsewardj with more than 5 million bytes of code. Which is pretty 7032e54028ae63b2e4be7f737300a87d70f17b85edbsewardj unlikely. Either that, or the debuginfo reader is somehow 70410deba428bd24d2105dbbe5bf58469385cc740besewardj broken. 5 million is of course arbitrary; but it's big enough 70510deba428bd24d2105dbbe5bf58469385cc740besewardj to be bigger than the size of any plausible piece of code that 7069b54074df0311ae2509cda596b388b065d101b67florian would fall within a single procedure. But occasionally it does 7079b54074df0311ae2509cda596b388b065d101b67florian happen (c.f. BZ #339542). */ 7089b54074df0311ae2509cda596b388b065d101b67florian if (len >= 5000000) 7099b54074df0311ae2509cda596b388b065d101b67florian VG_(message)(Vg_DebugMsg, 7109b54074df0311ae2509cda596b388b065d101b67florian "warning: DiCfSI %#lx .. %#lx is huge; length = %u (%s)\n", 7119b54074df0311ae2509cda596b388b065d101b67florian base, base + len - 1, len, di->soname); 71210deba428bd24d2105dbbe5bf58469385cc740besewardj 713a5acac39bf3be7546222b1316faee5ee524be0d1sewardj vg_assert(di->fsm.have_rx_map && di->fsm.have_rw_map); 7146b5625bb609b154766d2e138b61e15655f60b710sewardj /* Find mapping where at least one end of the CFSI falls into. */ 7155c3dba227192de63d86f65ec7d9597c132818c37philippe map = ML_(find_rx_mapping)(di, base, base); 7165c3dba227192de63d86f65ec7d9597c132818c37philippe map2 = ML_(find_rx_mapping)(di, base + len - 1, 7175c3dba227192de63d86f65ec7d9597c132818c37philippe base + len - 1); 7186b5625bb609b154766d2e138b61e15655f60b710sewardj if (map == NULL) 7196b5625bb609b154766d2e138b61e15655f60b710sewardj map = map2; 7206b5625bb609b154766d2e138b61e15655f60b710sewardj else if (map2 == NULL) 7216b5625bb609b154766d2e138b61e15655f60b710sewardj map2 = map; 7226b5625bb609b154766d2e138b61e15655f60b710sewardj 7236b5625bb609b154766d2e138b61e15655f60b710sewardj /* Rule out ones which are completely outside the r-x mapped area 7246b5625bb609b154766d2e138b61e15655f60b710sewardj (or which span across different areas). 725b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj See "Comment_Regarding_Text_Range_Checks" elsewhere in this file 726b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for background and rationale. */ 7276b5625bb609b154766d2e138b61e15655f60b710sewardj if (map == NULL || map != map2) { 728b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj static Int complaints = 10; 729eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (VG_(clo_trace_cfi) || complaints > 0) { 730eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj complaints--; 731eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (VG_(clo_verbosity) > 1) { 732eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(message)( 733eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Vg_DebugMsg, 734ade2eddf567a868bafad9110ed92acf7373a972bsewardj "warning: DiCfSI %#lx .. %#lx outside mapped rx segments (%s)\n", 7355c3dba227192de63d86f65ec7d9597c132818c37philippe base, 7365c3dba227192de63d86f65ec7d9597c132818c37philippe base + len - 1, 7376b5625bb609b154766d2e138b61e15655f60b710sewardj di->soname 738eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj ); 739eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 740eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (VG_(clo_trace_cfi)) 7415c3dba227192de63d86f65ec7d9597c132818c37philippe ML_(ppDiCfSI)(di->cfsi_exprs, base, len, cfsi_m); 742eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 743eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return; 744eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 745eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 74610deba428bd24d2105dbbe5bf58469385cc740besewardj /* Now we know the range is at least partially inside the r-x 74710deba428bd24d2105dbbe5bf58469385cc740besewardj mapped area. That implies that at least one of the ends of the 74810deba428bd24d2105dbbe5bf58469385cc740besewardj range falls inside the area. If necessary, clip it so it is 74910deba428bd24d2105dbbe5bf58469385cc740besewardj completely within the area. If we don't do this, 75010deba428bd24d2105dbbe5bf58469385cc740besewardj check_CFSI_related_invariants() in debuginfo.c (invariant #2) 75110deba428bd24d2105dbbe5bf58469385cc740besewardj will fail. See 75210deba428bd24d2105dbbe5bf58469385cc740besewardj "Comment_on_IMPORTANT_CFSI_REPRESENTATIONAL_INVARIANTS" in 75310deba428bd24d2105dbbe5bf58469385cc740besewardj priv_storage.h for background. */ 7545c3dba227192de63d86f65ec7d9597c132818c37philippe if (base < map->avma) { 75510deba428bd24d2105dbbe5bf58469385cc740besewardj /* Lower end is outside the mapped area. Hence upper end must 75610deba428bd24d2105dbbe5bf58469385cc740besewardj be inside it. */ 75710deba428bd24d2105dbbe5bf58469385cc740besewardj if (0) VG_(printf)("XXX truncate lower\n"); 7585c3dba227192de63d86f65ec7d9597c132818c37philippe vg_assert(base + len - 1 >= map->avma); 7595c3dba227192de63d86f65ec7d9597c132818c37philippe delta = (SSizeT)(map->avma - base); 76010deba428bd24d2105dbbe5bf58469385cc740besewardj vg_assert(delta > 0); 7615c3dba227192de63d86f65ec7d9597c132818c37philippe vg_assert(delta < (SSizeT)len); 7625c3dba227192de63d86f65ec7d9597c132818c37philippe base += delta; 7635c3dba227192de63d86f65ec7d9597c132818c37philippe len -= delta; 76410deba428bd24d2105dbbe5bf58469385cc740besewardj } 76510deba428bd24d2105dbbe5bf58469385cc740besewardj else 7665c3dba227192de63d86f65ec7d9597c132818c37philippe if (base + len - 1 > map->avma + map->size - 1) { 76710deba428bd24d2105dbbe5bf58469385cc740besewardj /* Upper end is outside the mapped area. Hence lower end must be 76810deba428bd24d2105dbbe5bf58469385cc740besewardj inside it. */ 76910deba428bd24d2105dbbe5bf58469385cc740besewardj if (0) VG_(printf)("XXX truncate upper\n"); 7705c3dba227192de63d86f65ec7d9597c132818c37philippe vg_assert(base <= map->avma + map->size - 1); 7715c3dba227192de63d86f65ec7d9597c132818c37philippe delta = (SSizeT)( (base + len - 1) 7726b5625bb609b154766d2e138b61e15655f60b710sewardj - (map->avma + map->size - 1) ); 7736b5625bb609b154766d2e138b61e15655f60b710sewardj vg_assert(delta > 0); 7745c3dba227192de63d86f65ec7d9597c132818c37philippe vg_assert(delta < (SSizeT)len); 7755c3dba227192de63d86f65ec7d9597c132818c37philippe len -= delta; 77610deba428bd24d2105dbbe5bf58469385cc740besewardj } 77710deba428bd24d2105dbbe5bf58469385cc740besewardj 77810deba428bd24d2105dbbe5bf58469385cc740besewardj /* Final checks */ 77910deba428bd24d2105dbbe5bf58469385cc740besewardj 78010deba428bd24d2105dbbe5bf58469385cc740besewardj /* Because: either cfsi was entirely inside the range, in which 78110deba428bd24d2105dbbe5bf58469385cc740besewardj case we asserted that len > 0 at the start, OR it fell partially 78210deba428bd24d2105dbbe5bf58469385cc740besewardj inside the range, in which case we reduced it by some size 78310deba428bd24d2105dbbe5bf58469385cc740besewardj (delta) which is < its original size. */ 7845c3dba227192de63d86f65ec7d9597c132818c37philippe vg_assert(len > 0); 78510deba428bd24d2105dbbe5bf58469385cc740besewardj 78610deba428bd24d2105dbbe5bf58469385cc740besewardj /* Similar logic applies for the next two assertions. */ 7875c3dba227192de63d86f65ec7d9597c132818c37philippe vg_assert(base >= map->avma); 7885c3dba227192de63d86f65ec7d9597c132818c37philippe vg_assert(base + len - 1 7896b5625bb609b154766d2e138b61e15655f60b710sewardj <= map->avma + map->size - 1); 79010deba428bd24d2105dbbe5bf58469385cc740besewardj 791b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->cfsi_used == di->cfsi_size) { 792b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj new_sz = 2 * di->cfsi_size; 793eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (new_sz == 0) new_sz = 20; 7949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj new_tab = ML_(dinfo_zalloc)( "di.storage.addDiCfSI.1", 7959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj new_sz * sizeof(DiCfSI) ); 7965c3dba227192de63d86f65ec7d9597c132818c37philippe if (di->cfsi_rd != NULL) { 7975c3dba227192de63d86f65ec7d9597c132818c37philippe VG_(memcpy)(new_tab, di->cfsi_rd, 7985c3dba227192de63d86f65ec7d9597c132818c37philippe di->cfsi_used * sizeof(DiCfSI)); 7995c3dba227192de63d86f65ec7d9597c132818c37philippe ML_(dinfo_free)(di->cfsi_rd); 800eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 8015c3dba227192de63d86f65ec7d9597c132818c37philippe di->cfsi_rd = new_tab; 802b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->cfsi_size = new_sz; 8035c3dba227192de63d86f65ec7d9597c132818c37philippe if (di->cfsi_m_pool == NULL) 8045c3dba227192de63d86f65ec7d9597c132818c37philippe di->cfsi_m_pool = VG_(newDedupPA)(1000 * sizeof(DiCfSI_m), 8055c3dba227192de63d86f65ec7d9597c132818c37philippe vg_alignof(DiCfSI_m), 8065c3dba227192de63d86f65ec7d9597c132818c37philippe ML_(dinfo_zalloc), 8075c3dba227192de63d86f65ec7d9597c132818c37philippe "di.storage.DiCfSI_m_pool", 8085c3dba227192de63d86f65ec7d9597c132818c37philippe ML_(dinfo_free)); 8095c3dba227192de63d86f65ec7d9597c132818c37philippe } 8105c3dba227192de63d86f65ec7d9597c132818c37philippe 8115c3dba227192de63d86f65ec7d9597c132818c37philippe di->cfsi_rd[di->cfsi_used].base = base; 8125c3dba227192de63d86f65ec7d9597c132818c37philippe di->cfsi_rd[di->cfsi_used].len = len; 8135c3dba227192de63d86f65ec7d9597c132818c37philippe di->cfsi_rd[di->cfsi_used].cfsi_m_ix 8145c3dba227192de63d86f65ec7d9597c132818c37philippe = VG_(allocFixedEltDedupPA)(di->cfsi_m_pool, 8155c3dba227192de63d86f65ec7d9597c132818c37philippe sizeof(DiCfSI_m), 8165c3dba227192de63d86f65ec7d9597c132818c37philippe cfsi_m); 817b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->cfsi_used++; 818b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di->cfsi_used <= di->cfsi_size); 819eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 820eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 821eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 82272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardjInt ML_(CfiExpr_Undef)( XArray* dst ) 82372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj{ 82472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj CfiExpr e; 82572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj VG_(memset)( &e, 0, sizeof(e) ); 82672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj e.tag = Cex_Undef; 827bee43c15c5aed57d25df177308347224aa461d9csewardj return (Int)VG_(addToXA)( dst, &e ); 82872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj} 82972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardjInt ML_(CfiExpr_Deref)( XArray* dst, Int ixAddr ) 83072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj{ 83172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj CfiExpr e; 83272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj VG_(memset)( &e, 0, sizeof(e) ); 83372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj e.tag = Cex_Deref; 83472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj e.Cex.Deref.ixAddr = ixAddr; 835bee43c15c5aed57d25df177308347224aa461d9csewardj return (Int)VG_(addToXA)( dst, &e ); 83672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj} 83772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardjInt ML_(CfiExpr_Const)( XArray* dst, UWord con ) 83872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj{ 83972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj CfiExpr e; 84072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj VG_(memset)( &e, 0, sizeof(e) ); 84172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj e.tag = Cex_Const; 84272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj e.Cex.Const.con = con; 843bee43c15c5aed57d25df177308347224aa461d9csewardj return (Int)VG_(addToXA)( dst, &e ); 84472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj} 84540628facff2285b0fce592381c6e26fdcd2a1252tomInt ML_(CfiExpr_Unop)( XArray* dst, CfiUnop op, Int ix ) 84640628facff2285b0fce592381c6e26fdcd2a1252tom{ 84740628facff2285b0fce592381c6e26fdcd2a1252tom CfiExpr e; 84840628facff2285b0fce592381c6e26fdcd2a1252tom VG_(memset)( &e, 0, sizeof(e) ); 84940628facff2285b0fce592381c6e26fdcd2a1252tom e.tag = Cex_Unop; 85040628facff2285b0fce592381c6e26fdcd2a1252tom e.Cex.Unop.op = op; 85140628facff2285b0fce592381c6e26fdcd2a1252tom e.Cex.Unop.ix = ix; 85240628facff2285b0fce592381c6e26fdcd2a1252tom return (Int)VG_(addToXA)( dst, &e ); 85340628facff2285b0fce592381c6e26fdcd2a1252tom} 854f6716dd8f025c9ace67541f3360d7f4523496d8atomInt ML_(CfiExpr_Binop)( XArray* dst, CfiBinop op, Int ixL, Int ixR ) 85572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj{ 85672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj CfiExpr e; 85772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj VG_(memset)( &e, 0, sizeof(e) ); 85872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj e.tag = Cex_Binop; 85972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj e.Cex.Binop.op = op; 86072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj e.Cex.Binop.ixL = ixL; 86172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj e.Cex.Binop.ixR = ixR; 862bee43c15c5aed57d25df177308347224aa461d9csewardj return (Int)VG_(addToXA)( dst, &e ); 86372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj} 86472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardjInt ML_(CfiExpr_CfiReg)( XArray* dst, CfiReg reg ) 86572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj{ 86672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj CfiExpr e; 86772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj VG_(memset)( &e, 0, sizeof(e) ); 86872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj e.tag = Cex_CfiReg; 86972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj e.Cex.CfiReg.reg = reg; 870bee43c15c5aed57d25df177308347224aa461d9csewardj return (Int)VG_(addToXA)( dst, &e ); 87172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj} 87272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardjInt ML_(CfiExpr_DwReg)( XArray* dst, Int reg ) 87372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj{ 87472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj CfiExpr e; 87572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj VG_(memset)( &e, 0, sizeof(e) ); 87672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj e.tag = Cex_DwReg; 87772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj e.Cex.DwReg.reg = reg; 878bee43c15c5aed57d25df177308347224aa461d9csewardj return (Int)VG_(addToXA)( dst, &e ); 87972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj} 88072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 88140628facff2285b0fce592381c6e26fdcd2a1252tomstatic void ppCfiUnop ( CfiUnop op ) 88240628facff2285b0fce592381c6e26fdcd2a1252tom{ 88340628facff2285b0fce592381c6e26fdcd2a1252tom switch (op) { 88440628facff2285b0fce592381c6e26fdcd2a1252tom case Cunop_Abs: VG_(printf)("abs"); break; 88540628facff2285b0fce592381c6e26fdcd2a1252tom case Cunop_Neg: VG_(printf)("-"); break; 88640628facff2285b0fce592381c6e26fdcd2a1252tom case Cunop_Not: VG_(printf)("~"); break; 88740628facff2285b0fce592381c6e26fdcd2a1252tom default: vg_assert(0); 88840628facff2285b0fce592381c6e26fdcd2a1252tom } 88940628facff2285b0fce592381c6e26fdcd2a1252tom} 89040628facff2285b0fce592381c6e26fdcd2a1252tom 891f6716dd8f025c9ace67541f3360d7f4523496d8atomstatic void ppCfiBinop ( CfiBinop op ) 89272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj{ 89372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj switch (op) { 894f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Add: VG_(printf)("+"); break; 895f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Sub: VG_(printf)("-"); break; 896f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_And: VG_(printf)("&"); break; 897f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Mul: VG_(printf)("*"); break; 898f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Shl: VG_(printf)("<<"); break; 899f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Shr: VG_(printf)(">>"); break; 900f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Eq: VG_(printf)("=="); break; 901f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Ge: VG_(printf)(">="); break; 902f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Gt: VG_(printf)(">"); break; 903f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Le: VG_(printf)("<="); break; 904f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Lt: VG_(printf)("<"); break; 905f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Ne: VG_(printf)("!="); break; 906f6716dd8f025c9ace67541f3360d7f4523496d8atom default: vg_assert(0); 90772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 90872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj} 90972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 91072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardjstatic void ppCfiReg ( CfiReg reg ) 91172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj{ 91272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj switch (reg) { 913ade2eddf567a868bafad9110ed92acf7373a972bsewardj case Creg_INVALID: VG_(printf)("Creg_INVALID"); break; 914821283b2110420321fd3f60afcc799b287788c68sewardj case Creg_IA_SP: VG_(printf)("xSP"); break; 915821283b2110420321fd3f60afcc799b287788c68sewardj case Creg_IA_BP: VG_(printf)("xBP"); break; 916821283b2110420321fd3f60afcc799b287788c68sewardj case Creg_IA_IP: VG_(printf)("xIP"); break; 917821283b2110420321fd3f60afcc799b287788c68sewardj case Creg_ARM_R13: VG_(printf)("R13"); break; 918821283b2110420321fd3f60afcc799b287788c68sewardj case Creg_ARM_R12: VG_(printf)("R12"); break; 919821283b2110420321fd3f60afcc799b287788c68sewardj case Creg_ARM_R15: VG_(printf)("R15"); break; 920821283b2110420321fd3f60afcc799b287788c68sewardj case Creg_ARM_R14: VG_(printf)("R14"); break; 921ade2eddf567a868bafad9110ed92acf7373a972bsewardj case Creg_ARM_R7: VG_(printf)("R7"); break; 922821283b2110420321fd3f60afcc799b287788c68sewardj case Creg_ARM64_X30: VG_(printf)("X30"); break; 923821283b2110420321fd3f60afcc799b287788c68sewardj case Creg_MIPS_RA: VG_(printf)("RA"); break; 924b6ba6d288e6000a8f95fba1dea671e0b53e26043florian case Creg_S390_IA: VG_(printf)("IA"); break; 925b6ba6d288e6000a8f95fba1dea671e0b53e26043florian case Creg_S390_SP: VG_(printf)("SP"); break; 926b6ba6d288e6000a8f95fba1dea671e0b53e26043florian case Creg_S390_FP: VG_(printf)("FP"); break; 927b6ba6d288e6000a8f95fba1dea671e0b53e26043florian case Creg_S390_LR: VG_(printf)("LR"); break; 928112711afefcfcd43680c7c4aa8d38ef180e8811esewardj case Creg_TILEGX_IP: VG_(printf)("PC"); break; 929112711afefcfcd43680c7c4aa8d38ef180e8811esewardj case Creg_TILEGX_SP: VG_(printf)("SP"); break; 930112711afefcfcd43680c7c4aa8d38ef180e8811esewardj case Creg_TILEGX_BP: VG_(printf)("BP"); break; 931112711afefcfcd43680c7c4aa8d38ef180e8811esewardj case Creg_TILEGX_LR: VG_(printf)("R55"); break; 93272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: vg_assert(0); 93372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 93472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj} 93572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 936518850bf0da07ed3e2244e307268ae0fd80e93a8florianvoid ML_(ppCfiExpr)( const XArray* src, Int ix ) 93772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj{ 93872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /* VG_(indexXA) checks for invalid src/ix values, so we can 93972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj use it indiscriminately. */ 9403297124fa2116737066ac3cd709f18fdd5405163florian const CfiExpr* e = VG_(indexXA)( src, ix ); 94172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj switch (e->tag) { 94272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cex_Undef: 94372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj VG_(printf)("Undef"); 94472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; 94572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cex_Deref: 94672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj VG_(printf)("*("); 94772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj ML_(ppCfiExpr)(src, e->Cex.Deref.ixAddr); 94872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj VG_(printf)(")"); 94972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; 95072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cex_Const: 95172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj VG_(printf)("0x%lx", e->Cex.Const.con); 95272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; 95340628facff2285b0fce592381c6e26fdcd2a1252tom case Cex_Unop: 95440628facff2285b0fce592381c6e26fdcd2a1252tom ppCfiUnop(e->Cex.Unop.op); 95540628facff2285b0fce592381c6e26fdcd2a1252tom VG_(printf)("("); 95640628facff2285b0fce592381c6e26fdcd2a1252tom ML_(ppCfiExpr)(src, e->Cex.Unop.ix); 95740628facff2285b0fce592381c6e26fdcd2a1252tom VG_(printf)(")"); 95840628facff2285b0fce592381c6e26fdcd2a1252tom break; 95972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cex_Binop: 96072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj VG_(printf)("("); 96172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj ML_(ppCfiExpr)(src, e->Cex.Binop.ixL); 96272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj VG_(printf)(")"); 963f6716dd8f025c9ace67541f3360d7f4523496d8atom ppCfiBinop(e->Cex.Binop.op); 96472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj VG_(printf)("("); 96572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj ML_(ppCfiExpr)(src, e->Cex.Binop.ixR); 96672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj VG_(printf)(")"); 96772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; 96872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cex_CfiReg: 96972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj ppCfiReg(e->Cex.CfiReg.reg); 97072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; 97172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cex_DwReg: 97272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj VG_(printf)("dwr%d", e->Cex.DwReg.reg); 97372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; 97472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: 97572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj VG_(core_panic)("ML_(ppCfiExpr)"); 97672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /*NOTREACHED*/ 97772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; 97872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 97972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj} 98072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 98172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 982b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjWord ML_(cmp_for_DiAddrRange_range) ( const void* keyV, 983b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj const void* elemV ) { 984b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj const Addr* key = (const Addr*)keyV; 985b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj const DiAddrRange* elem = (const DiAddrRange*)elemV; 986b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (0) 987a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart VG_(printf)("cmp_for_DiAddrRange_range: %#lx vs %#lx\n", 988b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *key, elem->aMin); 989b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ((*key) < elem->aMin) return -1; 990b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ((*key) > elem->aMax) return 1; 991b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return 0; 992b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 993b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 994b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic 9956bd9dc18c043927c1196caba20a327238a179c42florianvoid show_scope ( OSet* /* of DiAddrRange */ scope, const HChar* who ) 996b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 997b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiAddrRange* range; 998b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("Scope \"%s\" = {\n", who); 999b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(OSetGen_ResetIter)( scope ); 1000b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while (True) { 1001b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj range = VG_(OSetGen_Next)( scope ); 1002b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!range) break; 1003a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart VG_(printf)(" %#lx .. %#lx: %lu vars\n", range->aMin, range->aMax, 1004b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj range->vars ? VG_(sizeXA)(range->vars) : 0); 1005b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1006b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("}\n"); 1007b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 1008b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1009b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Add the variable 'var' to 'scope' for the address range [aMin,aMax] 1010b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj (inclusive of aMin and aMax). Split existing ranges as required if 1011b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj aMin or aMax or both don't match existing range boundaries, and add 1012b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 'var' to all required ranges. Take great care to preserve the 1013b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj invariant that the ranges in 'scope' cover the entire address range 1014b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj exactly once, with no overlaps and no holes. */ 1015b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void add_var_to_arange ( 1016b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*MOD*/OSet* /* of DiAddrRange */ scope, 1017b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr aMin, 1018b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr aMax, 1019b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable* var 1020b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ) 1021b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 1022b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiAddrRange *first, *last, *range; 1023b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* These xx variables are for assertion checking only; they don't 1024b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj contribute anything to the actual work of this function. */ 1025b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiAddrRange *xxRangep, *xxFirst, *xxLast; 1026b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj UWord xxIters; 1027b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1028b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(aMin <= aMax); 1029b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1030a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart if (0) VG_(printf)("add_var_to_arange: %#lx .. %#lx\n", aMin, aMax); 1031b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (0) show_scope( scope, "add_var_to_arange(1)" ); 1032b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1033b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* See if the lower end of the range (aMin) falls exactly on an 1034b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj existing range boundary. If not, find the range it does fall 1035b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj into, and split it (copying the variables in the process), so 1036b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj that aMin does exactly fall on a range boundary. */ 1037b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj first = VG_(OSetGen_Lookup)( scope, &aMin ); 1038b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* It must be present, since the presented OSet must cover 1039b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj the entire address range. */ 1040b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(first); 1041b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(first->aMin <= first->aMax); 1042b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(first->aMin <= aMin && aMin <= first->aMax); 1043b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1044b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Fast track common case, which is that the range specified for 1045b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj the variable exactly coincides with one already-existing 1046b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj range. */ 1047b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (first->aMin == aMin && first->aMax == aMax) { 1048b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(first->vars); 1049b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(addToXA)( first->vars, var ); 1050b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return; 1051b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1052b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1053b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* We have to get into splitting ranges, which is complex 1054b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj and slow. */ 1055b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (first->aMin < aMin) { 1056b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiAddrRange* nyu; 1057b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Ok. We'll have to split 'first'. */ 1058b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* truncate the upper end of 'first' */ 1059b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr tmp = first->aMax; 1060b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj first->aMax = aMin-1; 1061b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(first->aMin <= first->aMax); 1062b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* create a new range */ 1063b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj nyu = VG_(OSetGen_AllocNode)( scope, sizeof(DiAddrRange) ); 1064b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj nyu->aMin = aMin; 1065b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj nyu->aMax = tmp; 1066b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(nyu->aMin <= nyu->aMax); 1067b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* copy vars into it */ 1068b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(first->vars); 10699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj nyu->vars = VG_(cloneXA)( "di.storage.avta.1", first->vars ); 1070b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(OSetGen_Insert)( scope, nyu ); 1071b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj first = nyu; 1072b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1073b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1074b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(first->aMin == aMin); 1075b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1076b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Now do exactly the same for the upper end (aMax): if it doesn't 1077b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj fall on a boundary, cause it to do so by splitting the range it 1078b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj does currently fall into. */ 1079b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj last = VG_(OSetGen_Lookup)( scope, &aMax ); 1080b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(last->aMin <= last->aMax); 1081b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(last->aMin <= aMax && aMax <= last->aMax); 1082b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1083b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (aMax < last->aMax) { 1084b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiAddrRange* nyu; 1085b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* We have to split 'last'. */ 1086b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* truncate the lower end of 'last' */ 1087b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr tmp = last->aMin; 1088b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj last->aMin = aMax+1; 1089b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(last->aMin <= last->aMax); 1090b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* create a new range */ 1091b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj nyu = VG_(OSetGen_AllocNode)( scope, sizeof(DiAddrRange) ); 1092b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj nyu->aMin = tmp; 1093b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj nyu->aMax = aMax; 1094b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(nyu->aMin <= nyu->aMax); 1095b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* copy vars into it */ 1096b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(last->vars); 10979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj nyu->vars = VG_(cloneXA)( "di.storage.avta.2", last->vars ); 1098b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(OSetGen_Insert)( scope, nyu ); 1099b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj last = nyu; 1100b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1101b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1102b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(aMax == last->aMax); 1103b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1104b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj xxFirst = (DiAddrRange*)VG_(OSetGen_Lookup)(scope, &aMin); 1105b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj xxLast = (DiAddrRange*)VG_(OSetGen_Lookup)(scope, &aMax); 1106b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(xxFirst); 1107b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(xxLast); 1108b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(xxFirst->aMin == aMin); 1109b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(xxLast->aMax == aMax); 1110b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (xxFirst != xxLast) 1111b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(xxFirst->aMax < xxLast->aMin); 1112b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1113b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Great. Now we merely need to iterate over the segments from 1114b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 'first' to 'last' inclusive, and add 'var' to the variable set 1115b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj of each of them. */ 1116b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (0) { 1117b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj static UWord ctr = 0; 1118b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ctr++; 1119b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("ctr = %lu\n", ctr); 1120b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (ctr >= 33263) show_scope( scope, "add_var_to_arange(2)" ); 1121b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1122b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1123b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj xxIters = 0; 1124b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj range = xxRangep = NULL; 1125b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(OSetGen_ResetIterAt)( scope, &aMin ); 1126b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while (True) { 1127b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj xxRangep = range; 1128b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj range = VG_(OSetGen_Next)( scope ); 1129b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!range) break; 1130b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (range->aMin > aMax) break; 1131b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj xxIters++; 1132a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart if (0) VG_(printf)("have range %#lx %#lx\n", 1133b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj range->aMin, range->aMax); 1134b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1135b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Sanity checks */ 1136b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!xxRangep) { 1137b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* This is the first in the range */ 1138b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(range->aMin == aMin); 1139b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 1140b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(xxRangep->aMax + 1 == range->aMin); 1141b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1142b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1143b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(range->vars); 1144b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(addToXA)( range->vars, var ); 1145b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1146b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Done. We should have seen at least one range. */ 1147b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(xxIters >= 1); 1148b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (xxIters == 1) vg_assert(xxFirst == xxLast); 1149b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (xxFirst == xxLast) vg_assert(xxIters == 1); 1150b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(xxRangep); 1151b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(xxRangep->aMax == aMax); 1152b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(xxRangep == xxLast); 1153b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 1154b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1155b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1156b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Top-level place to call to add a variable description (as extracted 1157b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj from a DWARF3 .debug_info section. */ 1158b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid ML_(addVar)( struct _DebugInfo* di, 1159b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int level, 1160b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr aMin, 1161b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr aMax, 11621ef70c6f00ab1b50d1936f77037e9923d8ed8c59florian const HChar* name, /* in di's .strpool */ 11639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj UWord typeR, /* a cuOff */ 11643297124fa2116737066ac3cd709f18fdd5405163florian const GExpr* gexpr, 11653297124fa2116737066ac3cd709f18fdd5405163florian const GExpr* fbGX, 1166666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe UInt fndn_ix, /* where decl'd - may be zero. 1167666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe index in in di's .fndnpool */ 1168b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int lineNo, /* where decl'd - may be zero */ 1169b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool show ) 1170b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 1171b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj OSet* /* of DiAddrRange */ scope; 1172b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable var; 1173b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool all; 11749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TyEnt* ent; 117550fde23467d92281b32dd537d0d9a590263628c3sewardj MaybeULong mul; 11766bd9dc18c043927c1196caba20a327238a179c42florian const HChar* badness; 11779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 1178e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(di && di->admin_tyents); 1179b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1180b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (0) { 1181a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart VG_(printf)(" ML_(addVar): level %d %#lx-%#lx %s :: ", 1182b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj level, aMin, aMax, name ); 11839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(pp_TyEnt_C_ishly)( di->admin_tyents, typeR ); 1184b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("\n Var="); 1185b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(pp_GX)(gexpr); 1186b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("\n"); 1187b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (fbGX) { 1188b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)(" FrB="); 1189b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(pp_GX)( fbGX ); 1190b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("\n"); 1191b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 1192b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)(" FrB=none\n"); 1193b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1194b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("\n"); 1195b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1196b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1197b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(level >= 0); 1198b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(aMin <= aMax); 1199b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(name); 1200b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(gexpr); 1201b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 12029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ent = ML_(TyEnts__index_by_cuOff)( di->admin_tyents, NULL, typeR); 1203e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(ent); 12049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(ML_(TyEnt__is_type)(ent)); 12059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 1206b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* "Comment_Regarding_Text_Range_Checks" (is referred to elsewhere) 1207b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ---------------------------------------------------------------- 1208b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Ignore any variables whose aMin .. aMax (that is, range of text 1209b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj addresses for which they actually exist) falls outside the text 1210b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj segment. Is this indicative of a bug in the reader? Maybe. 1211b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj (LATER): instead of restricting strictly to the .text segment, 1212b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj be a bit more relaxed, and accept any variable whose text range 1213b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj falls inside the r-x mapped area. This is useful because .text 1214b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is not always the only instruction-carrying segment: others are: 1215b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj .init .plt __libc_freeres_fn and .fini. This implicitly assumes 1216b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj that those extra sections have the same bias as .text, but that 1217b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj seems a reasonable assumption to me. */ 1218b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* This is assured us by top level steering logic in debuginfo.c, 1219b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj and it is re-checked at the start of 1220b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(read_elf_debug_info). */ 1221a5acac39bf3be7546222b1316faee5ee524be0d1sewardj vg_assert(di->fsm.have_rx_map && di->fsm.have_rw_map); 12226b5625bb609b154766d2e138b61e15655f60b710sewardj if (level > 0 && ML_(find_rx_mapping)(di, aMin, aMax) == NULL) { 1223b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (VG_(clo_verbosity) >= 0) { 1224b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(message)(Vg_DebugMsg, 1225a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart "warning: addVar: in range %#lx .. %#lx outside " 12266b5625bb609b154766d2e138b61e15655f60b710sewardj "all rx mapped areas (%s)\n", 12276b5625bb609b154766d2e138b61e15655f60b710sewardj aMin, aMax, name 1228b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ); 1229b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1230b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return; 1231b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1232b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1233b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* If the type's size is zero (which can mean unknown size), ignore 1234b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj it. We will never be able to actually relate a data address to 1235b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj a data object with zero size, so there's no point in storing 123650fde23467d92281b32dd537d0d9a590263628c3sewardj info on it. On 32-bit platforms, also reject types whose size 123750fde23467d92281b32dd537d0d9a590263628c3sewardj is 2^32 bytes or large. (It's amazing what junk shows up ..) */ 123850fde23467d92281b32dd537d0d9a590263628c3sewardj mul = ML_(sizeOfType)(di->admin_tyents, typeR); 123950fde23467d92281b32dd537d0d9a590263628c3sewardj 124050fde23467d92281b32dd537d0d9a590263628c3sewardj badness = NULL; 124150fde23467d92281b32dd537d0d9a590263628c3sewardj if (mul.b != True) 124250fde23467d92281b32dd537d0d9a590263628c3sewardj badness = "unknown size"; 124350fde23467d92281b32dd537d0d9a590263628c3sewardj else if (mul.ul == 0) 124450fde23467d92281b32dd537d0d9a590263628c3sewardj badness = "zero size "; 124550fde23467d92281b32dd537d0d9a590263628c3sewardj else if (sizeof(void*) == 4 && mul.ul >= (1ULL<<32)) 124650fde23467d92281b32dd537d0d9a590263628c3sewardj badness = "implausibly large"; 124750fde23467d92281b32dd537d0d9a590263628c3sewardj 124850fde23467d92281b32dd537d0d9a590263628c3sewardj if (badness) { 1249b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj static Int complaints = 10; 1250b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (VG_(clo_verbosity) >= 2 && complaints > 0) { 1251738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_DebugMsg, "warning: addVar: %s (%s)\n", 125250fde23467d92281b32dd537d0d9a590263628c3sewardj badness, name ); 1253b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj complaints--; 1254b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1255b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return; 1256b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1257b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1258b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->varinfo) { 12599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di->varinfo = VG_(newXA)( ML_(dinfo_zalloc), 12609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj "di.storage.addVar.1", 12619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(dinfo_free), 1262b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sizeof(OSet*) ); 1263b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1264b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1265b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(level < 256); /* arbitrary; stay sane */ 1266b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Expand the top level array enough to map this level */ 1267b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while ( VG_(sizeXA)(di->varinfo) <= level ) { 1268b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiAddrRange* nyu; 1269b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj scope = VG_(OSetGen_Create)( offsetof(DiAddrRange,aMin), 1270b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(cmp_for_DiAddrRange_range), 12719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(dinfo_zalloc), "di.storage.addVar.2", 12729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(dinfo_free) ); 1273b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (0) VG_(printf)("create: scope = %p, adding at %ld\n", 1274b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj scope, VG_(sizeXA)(di->varinfo)); 1275b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(addToXA)( di->varinfo, &scope ); 1276b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Add a single range covering the entire address space. At 1277b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj level 0 we require this doesn't get split. At levels above 0 1278b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj we require that any additions to it cause it to get split. 1279b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj All of these invariants get checked both add_var_to_arange 1280b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj and after reading is complete, in canonicaliseVarInfo. */ 1281b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj nyu = VG_(OSetGen_AllocNode)( scope, sizeof(DiAddrRange) ); 1282b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj nyu->aMin = (Addr)0; 1283b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj nyu->aMax = ~(Addr)0; 12849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj nyu->vars = VG_(newXA)( ML_(dinfo_zalloc), "di.storage.addVar.3", 12859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(dinfo_free), 1286b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sizeof(DiVariable) ); 1287b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(OSetGen_Insert)( scope, nyu ); 1288b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1289b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1290b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert( VG_(sizeXA)(di->varinfo) > level ); 1291b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj scope = *(OSet**)VG_(indexXA)( di->varinfo, level ); 1292b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(scope); 1293b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1294b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj var.name = name; 12959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var.typeR = typeR; 1296b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj var.gexpr = gexpr; 1297b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj var.fbGX = fbGX; 1298666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe var.fndn_ix = fndn_ix; 1299b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj var.lineNo = lineNo; 1300b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1301b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj all = aMin == (Addr)0 && aMax == ~(Addr)0; 1302b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(level == 0 ? all : !all); 1303b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1304b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj add_var_to_arange( /*MOD*/scope, aMin, aMax, &var ); 1305b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 1306b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1307b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1308b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* This really just checks the constructed data structure, as there is 1309b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj no canonicalisation to do. */ 1310b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void canonicaliseVarInfo ( struct _DebugInfo* di ) 1311b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 1312b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word i, nInThisScope; 1313b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1314b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->varinfo) 1315b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return; 1316b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1317b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (i = 0; i < VG_(sizeXA)(di->varinfo); i++) { 1318b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1319b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiAddrRange *range, *rangep; 1320b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj OSet* scope = *(OSet**)VG_(indexXA)(di->varinfo, i); 1321b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!scope) continue; 1322b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1323b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Deal with the global-scope case. */ 1324b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (i == 0) { 1325b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr zero = 0; 1326b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(VG_(OSetGen_Size)( scope ) == 1); 1327b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj range = VG_(OSetGen_Lookup)( scope, &zero ); 1328b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(range); 1329b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(range->aMin == (Addr)0); 1330b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(range->aMax == ~(Addr)0); 1331b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 1332b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1333b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1334b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* All the rest of this is for the local-scope case. */ 1335b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* iterate over all entries in 'scope' */ 1336b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj nInThisScope = 0; 13374c245e595b9f6300d3120408ca873f7115d9cc7dnjn rangep = NULL; 1338b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(OSetGen_ResetIter)(scope); 1339b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while (True) { 1340b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj range = VG_(OSetGen_Next)(scope); 1341b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!range) { 1342b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* We just saw the last one. There must have been at 1343b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj least one entry in the range. */ 1344b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(rangep); 1345b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(rangep->aMax == ~(Addr)0); 1346b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 1347b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1348b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1349b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(range->aMin <= range->aMax); 1350b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(range->vars); 1351b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1352b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!rangep) { 1353b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* This is the first entry in the range. */ 1354b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(range->aMin == 0); 1355b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 1356b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(rangep->aMax + 1 == range->aMin); 1357b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1358b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1359b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj rangep = range; 1360b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj nInThisScope++; 1361b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } /* iterating over ranges in a given scope */ 1362b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1363b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* If there's only one entry in this (local) scope, it must 1364b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj cover the entire address space (obviously), but it must not 1365b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj contain any vars. */ 1366b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1367b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(nInThisScope > 0); 1368b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (nInThisScope == 1) { 1369b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr zero = 0; 1370b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(VG_(OSetGen_Size)( scope ) == 1); 1371b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj range = VG_(OSetGen_Lookup)( scope, &zero ); 1372b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(range); 1373b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(range->aMin == (Addr)0); 1374b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(range->aMax == ~(Addr)0); 1375b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(range->vars); 1376b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(VG_(sizeXA)(range->vars) == 0); 1377b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1378b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1379b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } /* iterate over scopes */ 1380b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 1381b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1382b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1383eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 1384eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- Canonicalisers ---*/ 1385eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 1386eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1387eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Sort the symtab by starting address, and emit warnings if any 1388eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj symbols have overlapping address ranges. We use that old chestnut, 1389eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj shellsort. Mash the table around so as to establish the property 1390eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj that addresses are in order and the ranges to not overlap. This 1391eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj facilitates using binary search to map addresses to symbols when we 1392eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj come to query the table. 1393eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj*/ 13946bd9dc18c043927c1196caba20a327238a179c42florianstatic Int compare_DiSym ( const void* va, const void* vb ) 1395eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 13966bd9dc18c043927c1196caba20a327238a179c42florian const DiSym* a = va; 13976bd9dc18c043927c1196caba20a327238a179c42florian const DiSym* b = vb; 13984cace66777ca9ee73ea156210c04e9d4cc178395philippe if (a->avmas.main < b->avmas.main) return -1; 13994cace66777ca9ee73ea156210c04e9d4cc178395philippe if (a->avmas.main > b->avmas.main) return 1; 1400eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return 0; 1401eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1402eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1403eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1404a5cace0c2a3e212931badbf6398a0cd98393121asewardj/* An address is associated with more than one name. Which do we 1405a5cace0c2a3e212931badbf6398a0cd98393121asewardj prefer as the "display" name (that we show the user in stack 1406a5cace0c2a3e212931badbf6398a0cd98393121asewardj traces)? In order: 1407eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 140827a0024216fb483fb1d68b8dca116549c7e27385njn - Prefer "PMPI_<foo>" over "MPI_<foo>". 140927a0024216fb483fb1d68b8dca116549c7e27385njn 1410a5cace0c2a3e212931badbf6398a0cd98393121asewardj - Else, prefer a non-empty name over an empty one. 141127a0024216fb483fb1d68b8dca116549c7e27385njn 141227a0024216fb483fb1d68b8dca116549c7e27385njn - Else, prefer a non-whitespace name over an all-whitespace name. 141327a0024216fb483fb1d68b8dca116549c7e27385njn 141427a0024216fb483fb1d68b8dca116549c7e27385njn - Else, prefer the shorter symbol name. If the symbol contains a 141527a0024216fb483fb1d68b8dca116549c7e27385njn version symbol ('@' on Linux, other platforms may differ), which means it 141627a0024216fb483fb1d68b8dca116549c7e27385njn is versioned, then the length up to the version symbol is used for length 141727a0024216fb483fb1d68b8dca116549c7e27385njn comparison purposes (so "foo@GLIBC_2.4.2" is considered shorter than 141827a0024216fb483fb1d68b8dca116549c7e27385njn "foobar"). 141927a0024216fb483fb1d68b8dca116549c7e27385njn 142027a0024216fb483fb1d68b8dca116549c7e27385njn - Else, if two symbols have the same length, prefer a versioned symbol over 142127a0024216fb483fb1d68b8dca116549c7e27385njn a non-versioned symbol. 142227a0024216fb483fb1d68b8dca116549c7e27385njn 142327a0024216fb483fb1d68b8dca116549c7e27385njn - Else, use alphabetical ordering. 142427a0024216fb483fb1d68b8dca116549c7e27385njn 1425a5cace0c2a3e212931badbf6398a0cd98393121asewardj - Otherwise, they must be the same; use the name with the lower address. 1426eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1427eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Very occasionally this goes wrong (eg. 'memcmp' and 'bcmp' are 1428eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj aliases in glibc, we choose the 'bcmp' symbol because it's shorter, 1429eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj so we can misdescribe memcmp() as bcmp()). This is hard to avoid. 1430eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj It's mentioned in the FAQ file. 1431a5cace0c2a3e212931badbf6398a0cd98393121asewardj 1432a5cace0c2a3e212931badbf6398a0cd98393121asewardj Returned value is True if a_name is preferred, False if b_name is 1433a5cace0c2a3e212931badbf6398a0cd98393121asewardj preferred. 1434eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj */ 1435a5cace0c2a3e212931badbf6398a0cd98393121asewardjstatic 1436518850bf0da07ed3e2244e307268ae0fd80e93a8florianBool preferName ( const DebugInfo* di, 14371ef70c6f00ab1b50d1936f77037e9923d8ed8c59florian const HChar* a_name, const HChar* b_name, 1438a5cace0c2a3e212931badbf6398a0cd98393121asewardj Addr sym_avma/*exposition only*/ ) 1439eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1440f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word cmp; 1441f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word vlena, vlenb; /* length without version */ 14421636d33c13958b9c0e7d3059cdd5005746418eb2florian const HChar *vpa, *vpb; 1443eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1444b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool preferA = False; 1445b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool preferB = False; 1446b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1447a5cace0c2a3e212931badbf6398a0cd98393121asewardj vg_assert(a_name); 1448a5cace0c2a3e212931badbf6398a0cd98393121asewardj vg_assert(b_name); 14497293d2530f8c60c1060f9f003e214cc341d35266philippe // vg_assert(a_name != b_name); 14507293d2530f8c60c1060f9f003e214cc341d35266philippe // ???? now the pointers can be equal but is that 14517293d2530f8c60c1060f9f003e214cc341d35266philippe // ???? not the indication of a latent bug ???? 1452b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1453a5cace0c2a3e212931badbf6398a0cd98393121asewardj vlena = VG_(strlen)(a_name); 1454a5cace0c2a3e212931badbf6398a0cd98393121asewardj vlenb = VG_(strlen)(b_name); 1455eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1456a5cace0c2a3e212931badbf6398a0cd98393121asewardj# if defined(VGO_linux) 1457a5cace0c2a3e212931badbf6398a0cd98393121asewardj# define VERSION_CHAR '@' 1458a5cace0c2a3e212931badbf6398a0cd98393121asewardj# elif defined(VGO_darwin) 1459a5cace0c2a3e212931badbf6398a0cd98393121asewardj# define VERSION_CHAR '$' 1460a5cace0c2a3e212931badbf6398a0cd98393121asewardj# else 1461a5cace0c2a3e212931badbf6398a0cd98393121asewardj# error Unknown OS 1462a5cace0c2a3e212931badbf6398a0cd98393121asewardj# endif 1463a5cace0c2a3e212931badbf6398a0cd98393121asewardj 1464a5cace0c2a3e212931badbf6398a0cd98393121asewardj vpa = VG_(strchr)(a_name, VERSION_CHAR); 1465a5cace0c2a3e212931badbf6398a0cd98393121asewardj vpb = VG_(strchr)(b_name, VERSION_CHAR); 146627a0024216fb483fb1d68b8dca116549c7e27385njn 1467a5cace0c2a3e212931badbf6398a0cd98393121asewardj# undef VERSION_CHAR 1468eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1469eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (vpa) 1470a5cace0c2a3e212931badbf6398a0cd98393121asewardj vlena = vpa - a_name; 1471eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (vpb) 1472a5cace0c2a3e212931badbf6398a0cd98393121asewardj vlenb = vpb - b_name; 1473eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1474eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* MPI hack: prefer PMPI_Foo over MPI_Foo */ 1475a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (0==VG_(strncmp)(a_name, "MPI_", 4) 1476a5cace0c2a3e212931badbf6398a0cd98393121asewardj && 0==VG_(strncmp)(b_name, "PMPI_", 5) 1477a5cace0c2a3e212931badbf6398a0cd98393121asewardj && 0==VG_(strcmp)(a_name, 1+b_name)) { 1478b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj preferB = True; goto out; 1479b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1480a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (0==VG_(strncmp)(b_name, "MPI_", 4) 1481a5cace0c2a3e212931badbf6398a0cd98393121asewardj && 0==VG_(strncmp)(a_name, "PMPI_", 5) 1482a5cace0c2a3e212931badbf6398a0cd98393121asewardj && 0==VG_(strcmp)(b_name, 1+a_name)) { 1483b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj preferA = True; goto out; 1484b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1485eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 148627a0024216fb483fb1d68b8dca116549c7e27385njn /* Prefer non-empty name. */ 148727a0024216fb483fb1d68b8dca116549c7e27385njn if (vlena && !vlenb) { 148827a0024216fb483fb1d68b8dca116549c7e27385njn preferA = True; goto out; 148927a0024216fb483fb1d68b8dca116549c7e27385njn } 149027a0024216fb483fb1d68b8dca116549c7e27385njn if (vlenb && !vlena) { 149127a0024216fb483fb1d68b8dca116549c7e27385njn preferB = True; goto out; 149227a0024216fb483fb1d68b8dca116549c7e27385njn } 149327a0024216fb483fb1d68b8dca116549c7e27385njn 149427a0024216fb483fb1d68b8dca116549c7e27385njn /* Prefer non-whitespace name. */ 149527a0024216fb483fb1d68b8dca116549c7e27385njn { 149627a0024216fb483fb1d68b8dca116549c7e27385njn Bool blankA = True; 149727a0024216fb483fb1d68b8dca116549c7e27385njn Bool blankB = True; 14981ef70c6f00ab1b50d1936f77037e9923d8ed8c59florian const HChar *s; 1499a5cace0c2a3e212931badbf6398a0cd98393121asewardj s = a_name; 150027a0024216fb483fb1d68b8dca116549c7e27385njn while (*s) { 150127a0024216fb483fb1d68b8dca116549c7e27385njn if (!VG_(isspace)(*s++)) { 150227a0024216fb483fb1d68b8dca116549c7e27385njn blankA = False; 150327a0024216fb483fb1d68b8dca116549c7e27385njn break; 150427a0024216fb483fb1d68b8dca116549c7e27385njn } 150527a0024216fb483fb1d68b8dca116549c7e27385njn } 1506a5cace0c2a3e212931badbf6398a0cd98393121asewardj s = b_name; 150727a0024216fb483fb1d68b8dca116549c7e27385njn while (*s) { 150827a0024216fb483fb1d68b8dca116549c7e27385njn if (!VG_(isspace)(*s++)) { 150927a0024216fb483fb1d68b8dca116549c7e27385njn blankB = False; 151027a0024216fb483fb1d68b8dca116549c7e27385njn break; 151127a0024216fb483fb1d68b8dca116549c7e27385njn } 151227a0024216fb483fb1d68b8dca116549c7e27385njn } 151327a0024216fb483fb1d68b8dca116549c7e27385njn 151427a0024216fb483fb1d68b8dca116549c7e27385njn if (!blankA && blankB) { 151527a0024216fb483fb1d68b8dca116549c7e27385njn preferA = True; goto out; 151627a0024216fb483fb1d68b8dca116549c7e27385njn } 151727a0024216fb483fb1d68b8dca116549c7e27385njn if (!blankB && blankA) { 151827a0024216fb483fb1d68b8dca116549c7e27385njn preferB = True; goto out; 151927a0024216fb483fb1d68b8dca116549c7e27385njn } 152027a0024216fb483fb1d68b8dca116549c7e27385njn } 152127a0024216fb483fb1d68b8dca116549c7e27385njn 1522eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* Select the shortest unversioned name */ 1523b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (vlena < vlenb) { 1524b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj preferA = True; goto out; 1525b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1526b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (vlenb < vlena) { 1527b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj preferB = True; goto out; 1528b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1529eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1530eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* Equal lengths; select the versioned name */ 1531b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (vpa && !vpb) { 1532b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj preferA = True; goto out; 1533b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1534b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (vpb && !vpa) { 1535b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj preferB = True; goto out; 1536b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1537eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1538eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* Either both versioned or neither is versioned; select them 1539eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj alphabetically */ 1540a5cace0c2a3e212931badbf6398a0cd98393121asewardj cmp = VG_(strcmp)(a_name, b_name); 1541b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (cmp < 0) { 1542b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj preferA = True; goto out; 1543b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1544b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (cmp > 0) { 1545b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj preferB = True; goto out; 1546b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1547f76d27a697a7b0bf3b84490baf60623fc96a23afnjn 154827a0024216fb483fb1d68b8dca116549c7e27385njn /* If we get here, they are the same name. */ 154927a0024216fb483fb1d68b8dca116549c7e27385njn 155027a0024216fb483fb1d68b8dca116549c7e27385njn /* In this case we could choose either (arbitrarily), but might as 1551b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj well choose the one with the lowest DiSym* address, so as to try 1552b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj and make the comparison mechanism more stable (a la sorting 1553b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj parlance). Also, skip the diagnostic printing in this case. */ 1554a5cace0c2a3e212931badbf6398a0cd98393121asewardj return a_name <= b_name ? True : False; 1555b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1556b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*NOTREACHED*/ 1557b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(0); 1558b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj out: 1559b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (preferA && !preferB) { 1560a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart TRACE_SYMTAB("sym at %#lx: prefer '%s' to '%s'\n", 1561a5cace0c2a3e212931badbf6398a0cd98393121asewardj sym_avma, a_name, b_name ); 1562a5cace0c2a3e212931badbf6398a0cd98393121asewardj return True; 1563b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1564b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (preferB && !preferA) { 1565a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart TRACE_SYMTAB("sym at %#lx: prefer '%s' to '%s'\n", 1566a5cace0c2a3e212931badbf6398a0cd98393121asewardj sym_avma, b_name, a_name ); 1567a5cace0c2a3e212931badbf6398a0cd98393121asewardj return False; 1568b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1569b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*NOTREACHED*/ 1570b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(0); 1571eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1572eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1573a5cace0c2a3e212931badbf6398a0cd98393121asewardj 1574a5cace0c2a3e212931badbf6398a0cd98393121asewardj/* Add the names in FROM to the names in TO. */ 1575a5cace0c2a3e212931badbf6398a0cd98393121asewardjstatic 1576518850bf0da07ed3e2244e307268ae0fd80e93a8florianvoid add_DiSym_names_to_from ( const DebugInfo* di, DiSym* to, 1577518850bf0da07ed3e2244e307268ae0fd80e93a8florian const DiSym* from ) 1578a5cace0c2a3e212931badbf6398a0cd98393121asewardj{ 1579a5cace0c2a3e212931badbf6398a0cd98393121asewardj vg_assert(to->pri_name); 1580a5cace0c2a3e212931badbf6398a0cd98393121asewardj vg_assert(from->pri_name); 1581a5cace0c2a3e212931badbf6398a0cd98393121asewardj /* Figure out how many names there will be in the new combined 1582a5cace0c2a3e212931badbf6398a0cd98393121asewardj secondary vector. */ 15831ef70c6f00ab1b50d1936f77037e9923d8ed8c59florian const HChar** to_sec = to->sec_names; 15841ef70c6f00ab1b50d1936f77037e9923d8ed8c59florian const HChar** from_sec = from->sec_names; 1585a5cace0c2a3e212931badbf6398a0cd98393121asewardj Word n_new_sec = 1; 1586a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (from_sec) { 1587a5cace0c2a3e212931badbf6398a0cd98393121asewardj while (*from_sec) { 1588a5cace0c2a3e212931badbf6398a0cd98393121asewardj n_new_sec++; 1589a5cace0c2a3e212931badbf6398a0cd98393121asewardj from_sec++; 1590a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 1591a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 1592a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (to_sec) { 1593a5cace0c2a3e212931badbf6398a0cd98393121asewardj while (*to_sec) { 1594a5cace0c2a3e212931badbf6398a0cd98393121asewardj n_new_sec++; 1595a5cace0c2a3e212931badbf6398a0cd98393121asewardj to_sec++; 1596a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 1597a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 1598a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (0) 1599a5cace0c2a3e212931badbf6398a0cd98393121asewardj TRACE_SYMTAB("merge: -> %ld\n", n_new_sec); 1600a5cace0c2a3e212931badbf6398a0cd98393121asewardj /* Create the new sec and copy stuff into it, putting the new 1601a5cace0c2a3e212931badbf6398a0cd98393121asewardj entries at the end. */ 16021ef70c6f00ab1b50d1936f77037e9923d8ed8c59florian const HChar** new_sec = ML_(dinfo_zalloc)( "di.storage.aDntf.1", 16031ef70c6f00ab1b50d1936f77037e9923d8ed8c59florian (n_new_sec+1) * sizeof(HChar*) ); 1604a5cace0c2a3e212931badbf6398a0cd98393121asewardj from_sec = from->sec_names; 1605a5cace0c2a3e212931badbf6398a0cd98393121asewardj to_sec = to->sec_names; 1606a5cace0c2a3e212931badbf6398a0cd98393121asewardj Word i = 0; 1607a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (to_sec) { 1608a5cace0c2a3e212931badbf6398a0cd98393121asewardj while (*to_sec) { 1609a5cace0c2a3e212931badbf6398a0cd98393121asewardj new_sec[i++] = *to_sec; 1610a5cace0c2a3e212931badbf6398a0cd98393121asewardj to_sec++; 1611a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 1612a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 1613a5cace0c2a3e212931badbf6398a0cd98393121asewardj new_sec[i++] = from->pri_name; 1614a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (from_sec) { 1615a5cace0c2a3e212931badbf6398a0cd98393121asewardj while (*from_sec) { 1616a5cace0c2a3e212931badbf6398a0cd98393121asewardj new_sec[i++] = *from_sec; 1617a5cace0c2a3e212931badbf6398a0cd98393121asewardj from_sec++; 1618a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 1619a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 1620a5cace0c2a3e212931badbf6398a0cd98393121asewardj vg_assert(i == n_new_sec); 1621a5cace0c2a3e212931badbf6398a0cd98393121asewardj vg_assert(new_sec[i] == NULL); 1622a5cace0c2a3e212931badbf6398a0cd98393121asewardj /* If we're replacing an existing secondary vector, free it. */ 1623a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (to->sec_names) { 1624a5cace0c2a3e212931badbf6398a0cd98393121asewardj ML_(dinfo_free)(to->sec_names); 1625a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 1626a5cace0c2a3e212931badbf6398a0cd98393121asewardj to->sec_names = new_sec; 1627a5cace0c2a3e212931badbf6398a0cd98393121asewardj} 1628a5cace0c2a3e212931badbf6398a0cd98393121asewardj 1629a5cace0c2a3e212931badbf6398a0cd98393121asewardj 1630b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void canonicaliseSymtab ( struct _DebugInfo* di ) 1631eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1632a5cace0c2a3e212931badbf6398a0cd98393121asewardj Word i, j, n_truncated; 1633a5cace0c2a3e212931badbf6398a0cd98393121asewardj Addr sta1, sta2, end1, end2, toc1, toc2; 16341ef70c6f00ab1b50d1936f77037e9923d8ed8c59florian const HChar *pri1, *pri2, **sec1, **sec2; 1635a5cace0c2a3e212931badbf6398a0cd98393121asewardj Bool ist1, ist2, isf1, isf2; 1636eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1637eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# define SWAP(ty,aa,bb) \ 1638eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj do { ty tt = (aa); (aa) = (bb); (bb) = tt; } while (0) 1639eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1640b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->symtab_used == 0) 1641eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return; 1642eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1643a5cace0c2a3e212931badbf6398a0cd98393121asewardj /* Check initial invariants */ 1644a5cace0c2a3e212931badbf6398a0cd98393121asewardj for (i = 0; i < di->symtab_used; i++) { 1645a5cace0c2a3e212931badbf6398a0cd98393121asewardj DiSym* sym = &di->symtab[i]; 1646a5cace0c2a3e212931badbf6398a0cd98393121asewardj vg_assert(sym->pri_name); 1647a5cace0c2a3e212931badbf6398a0cd98393121asewardj vg_assert(!sym->sec_names); 1648a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 1649a5cace0c2a3e212931badbf6398a0cd98393121asewardj 1650a5cace0c2a3e212931badbf6398a0cd98393121asewardj /* Sort by address. */ 1651b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(ssort)(di->symtab, di->symtab_used, 1652b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sizeof(*di->symtab), compare_DiSym); 1653eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1654eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj cleanup_more: 1655eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1656426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj /* BEGIN Detect and "fix" identical address ranges. */ 1657a5cace0c2a3e212931badbf6398a0cd98393121asewardj while (1) { 1658a5cace0c2a3e212931badbf6398a0cd98393121asewardj Word r, w, n_merged; 1659eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj n_merged = 0; 1660a5cace0c2a3e212931badbf6398a0cd98393121asewardj w = 0; 1661426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj /* A pass merging entries together in the case where they agree 1662426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj on .isText -- that is, either: both are .isText or both are 1663426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj not .isText. They are merged into a single entry, but both 1664426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj sets of names are preserved, so we end up knowing all the 1665426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj names for that particular address range.*/ 1666a5cace0c2a3e212931badbf6398a0cd98393121asewardj for (r = 1; r < di->symtab_used; r++) { 1667a5cace0c2a3e212931badbf6398a0cd98393121asewardj vg_assert(w < r); 16684cace66777ca9ee73ea156210c04e9d4cc178395philippe if ( di->symtab[w].avmas.main == di->symtab[r].avmas.main 16694cace66777ca9ee73ea156210c04e9d4cc178395philippe && di->symtab[w].size == di->symtab[r].size 16704cace66777ca9ee73ea156210c04e9d4cc178395philippe && !!di->symtab[w].isText == !!di->symtab[r].isText) { 1671eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* merge the two into one */ 1672a5cace0c2a3e212931badbf6398a0cd98393121asewardj n_merged++; 1673d483f8006a37e056d49c0fa131e5103848ce8312philippe /* Add r names to w if r has secondary names 1674d483f8006a37e056d49c0fa131e5103848ce8312philippe or r and w primary names differ. */ 1675d483f8006a37e056d49c0fa131e5103848ce8312philippe if (di->symtab[r].sec_names 1676d483f8006a37e056d49c0fa131e5103848ce8312philippe || (0 != VG_(strcmp)(di->symtab[r].pri_name, 1677d483f8006a37e056d49c0fa131e5103848ce8312philippe di->symtab[w].pri_name))) { 1678d483f8006a37e056d49c0fa131e5103848ce8312philippe add_DiSym_names_to_from(di, &di->symtab[w], &di->symtab[r]); 1679d483f8006a37e056d49c0fa131e5103848ce8312philippe } 1680732b3583236d760c7c54cfe6d5ed5b957be96d9dtom /* mark w as an IFunc if either w or r are */ 1681732b3583236d760c7c54cfe6d5ed5b957be96d9dtom di->symtab[w].isIFunc = di->symtab[w].isIFunc || di->symtab[r].isIFunc; 1682a5cace0c2a3e212931badbf6398a0cd98393121asewardj /* and use ::pri_names to indicate this slot is no longer in use */ 1683a5cace0c2a3e212931badbf6398a0cd98393121asewardj di->symtab[r].pri_name = NULL; 1684a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (di->symtab[r].sec_names) { 1685a5cace0c2a3e212931badbf6398a0cd98393121asewardj ML_(dinfo_free)(di->symtab[r].sec_names); 1686a5cace0c2a3e212931badbf6398a0cd98393121asewardj di->symtab[r].sec_names = NULL; 1687a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 1688a5cace0c2a3e212931badbf6398a0cd98393121asewardj /* Completely zap the entry -- paranoia to make it more 1689a5cace0c2a3e212931badbf6398a0cd98393121asewardj likely we'll notice if we inadvertantly use it 1690a5cace0c2a3e212931badbf6398a0cd98393121asewardj again. */ 1691a5cace0c2a3e212931badbf6398a0cd98393121asewardj VG_(memset)(&di->symtab[r], 0, sizeof(DiSym)); 1692eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else { 1693a5cace0c2a3e212931badbf6398a0cd98393121asewardj w = r; 1694eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1695eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1696426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj 1697426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj /* A second pass merging entries together where one .isText but 1698426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj the other isn't. In such cases, just ignore the non-.isText 1699426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj one (a heuristic hack.) */ 1700426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj for (r = 1; r < di->symtab_used; r++) { 1701426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj /* Either of the symbols might already have been zapped by 1702426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj the previous pass, so we first have to check that. */ 1703426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj if (di->symtab[r-1].pri_name == NULL) continue; 1704426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj if (di->symtab[r-0].pri_name == NULL) continue; 1705426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj /* ok, they are both still valid. Identical address ranges? */ 1706426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj if (di->symtab[r-1].avmas.main != di->symtab[r-0].avmas.main) continue; 1707426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj if (di->symtab[r-1].size != di->symtab[r-0].size) continue; 1708426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj /* Identical address ranges. They must disagree on .isText 1709426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj since if they agreed, the previous pass would have merged 1710426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj them. */ 1711426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj if (di->symtab[r-1].isText && di->symtab[r-0].isText) vg_assert(0); 1712426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj if (!di->symtab[r-1].isText && !di->symtab[r-0].isText) vg_assert(0); 1713426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj Word to_zap = di->symtab[r-1].isText ? (r-0) : (r-1); 1714426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj Word to_keep = di->symtab[r-1].isText ? (r-1) : (r-0); 1715426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj vg_assert(!di->symtab[to_zap].isText); 1716426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj vg_assert(di->symtab[to_keep].isText); 1717426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj /* Add to_zap's names to to_keep if to_zap has secondary names 1718426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj or to_zap's and to_keep's primary names differ. */ 1719426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj if (di->symtab[to_zap].sec_names 1720426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj || (0 != VG_(strcmp)(di->symtab[to_zap].pri_name, 1721426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj di->symtab[to_keep].pri_name))) { 1722426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj add_DiSym_names_to_from(di, &di->symtab[to_keep], 1723426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj &di->symtab[to_zap]); 1724426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj } 1725426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj /* Mark to_zap as not-in use in the same way as in the 1726426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj previous loop. */ 1727426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj di->symtab[to_zap].pri_name = NULL; 1728426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj if (di->symtab[to_zap].sec_names) { 1729426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj ML_(dinfo_free)(di->symtab[to_zap].sec_names); 1730426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj di->symtab[to_zap].sec_names = NULL; 1731426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj } 1732426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj VG_(memset)(&di->symtab[to_zap], 0, sizeof(DiSym)); 1733426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj n_merged++; 1734426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj } 1735426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj 1736f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj TRACE_SYMTAB( "canonicaliseSymtab: %ld symbols merged\n", n_merged); 1737a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (n_merged == 0) 1738a5cace0c2a3e212931badbf6398a0cd98393121asewardj break; 1739a5cace0c2a3e212931badbf6398a0cd98393121asewardj /* Now a pass to squeeze out any unused ones */ 1740a5cace0c2a3e212931badbf6398a0cd98393121asewardj w = 0; 1741a5cace0c2a3e212931badbf6398a0cd98393121asewardj for (r = 0; r < di->symtab_used; r++) { 1742a5cace0c2a3e212931badbf6398a0cd98393121asewardj vg_assert(w <= r); 1743a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (di->symtab[r].pri_name == NULL) 1744a5cace0c2a3e212931badbf6398a0cd98393121asewardj continue; 1745a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (w < r) { 1746a5cace0c2a3e212931badbf6398a0cd98393121asewardj di->symtab[w] = di->symtab[r]; 1747a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 1748a5cace0c2a3e212931badbf6398a0cd98393121asewardj w++; 1749a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 1750a5cace0c2a3e212931badbf6398a0cd98393121asewardj vg_assert(w + n_merged == di->symtab_used); 1751a5cace0c2a3e212931badbf6398a0cd98393121asewardj di->symtab_used = w; 1752426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj } /* while (1) */ 1753426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj /* END Detect and "fix" identical address ranges. */ 1754eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1755426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj /* BEGIN Detect and "fix" overlapping address ranges. */ 1756eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj n_truncated = 0; 1757eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1758f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj for (i = 0; i < ((Word)di->symtab_used) -1; i++) { 1759eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 17604cace66777ca9ee73ea156210c04e9d4cc178395philippe vg_assert(di->symtab[i].avmas.main <= di->symtab[i+1].avmas.main); 1761eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1762eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* Check for common (no overlap) case. */ 17634cace66777ca9ee73ea156210c04e9d4cc178395philippe if (di->symtab[i].avmas.main + di->symtab[i].size 17644cace66777ca9ee73ea156210c04e9d4cc178395philippe <= di->symtab[i+1].avmas.main) 1765eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj continue; 1766eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1767eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* There's an overlap. Truncate one or the other. */ 1768b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->trace_symtab) { 1769eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(printf)("overlapping address ranges in symbol table\n\t"); 1770b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(ppSym)( i, &di->symtab[i] ); 1771eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(printf)("\t"); 1772b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(ppSym)( i+1, &di->symtab[i+1] ); 1773eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(printf)("\n"); 1774eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1775eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1776eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* Truncate one or the other. */ 17774cace66777ca9ee73ea156210c04e9d4cc178395philippe sta1 = di->symtab[i].avmas.main; 1778a5cace0c2a3e212931badbf6398a0cd98393121asewardj end1 = sta1 + di->symtab[i].size - 1; 17794cace66777ca9ee73ea156210c04e9d4cc178395philippe toc1 = GET_TOCPTR_AVMA(di->symtab[i].avmas); 17804cace66777ca9ee73ea156210c04e9d4cc178395philippe // aren't we missing local_ep here ???? 1781a5cace0c2a3e212931badbf6398a0cd98393121asewardj pri1 = di->symtab[i].pri_name; 1782a5cace0c2a3e212931badbf6398a0cd98393121asewardj sec1 = di->symtab[i].sec_names; 1783a5cace0c2a3e212931badbf6398a0cd98393121asewardj ist1 = di->symtab[i].isText; 1784a5cace0c2a3e212931badbf6398a0cd98393121asewardj isf1 = di->symtab[i].isIFunc; 1785a5cace0c2a3e212931badbf6398a0cd98393121asewardj 17864cace66777ca9ee73ea156210c04e9d4cc178395philippe sta2 = di->symtab[i+1].avmas.main; 1787a5cace0c2a3e212931badbf6398a0cd98393121asewardj end2 = sta2 + di->symtab[i+1].size - 1; 17884cace66777ca9ee73ea156210c04e9d4cc178395philippe toc2 = GET_TOCPTR_AVMA(di->symtab[i+1].avmas); 17894cace66777ca9ee73ea156210c04e9d4cc178395philippe // aren't we missing local_ep here ???? 1790a5cace0c2a3e212931badbf6398a0cd98393121asewardj pri2 = di->symtab[i+1].pri_name; 1791a5cace0c2a3e212931badbf6398a0cd98393121asewardj sec2 = di->symtab[i+1].sec_names; 1792a5cace0c2a3e212931badbf6398a0cd98393121asewardj ist2 = di->symtab[i+1].isText; 1793a5cace0c2a3e212931badbf6398a0cd98393121asewardj isf2 = di->symtab[i+1].isIFunc; 1794a5cace0c2a3e212931badbf6398a0cd98393121asewardj 1795a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (sta1 < sta2) { 1796a5cace0c2a3e212931badbf6398a0cd98393121asewardj end1 = sta2 - 1; 1797eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else { 1798a5cace0c2a3e212931badbf6398a0cd98393121asewardj vg_assert(sta1 == sta2); 1799a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (end1 > end2) { 1800a5cace0c2a3e212931badbf6398a0cd98393121asewardj sta1 = end2 + 1; 1801a5cace0c2a3e212931badbf6398a0cd98393121asewardj SWAP(Addr,sta1,sta2); SWAP(Addr,end1,end2); SWAP(Addr,toc1,toc2); 18021ef70c6f00ab1b50d1936f77037e9923d8ed8c59florian SWAP(const HChar*,pri1,pri2); SWAP(const HChar**,sec1,sec2); 1803a5cace0c2a3e212931badbf6398a0cd98393121asewardj SWAP(Bool,ist1,ist2); SWAP(Bool,isf1,isf2); 1804eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else 1805a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (end1 < end2) { 1806a5cace0c2a3e212931badbf6398a0cd98393121asewardj sta2 = end1 + 1; 1807eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else { 1808a5cace0c2a3e212931badbf6398a0cd98393121asewardj /* end1 == end2. Identical addr ranges. We'll eventually wind 1809eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj up back at cleanup_more, which will take care of it. */ 1810eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1811eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 18124cace66777ca9ee73ea156210c04e9d4cc178395philippe di->symtab[i].avmas.main = sta1; 18134cace66777ca9ee73ea156210c04e9d4cc178395philippe di->symtab[i].size = end1 - sta1 + 1; 18144cace66777ca9ee73ea156210c04e9d4cc178395philippe SET_TOCPTR_AVMA(di->symtab[i].avmas, toc1); 18154cace66777ca9ee73ea156210c04e9d4cc178395philippe // missing local_ep ??? 1816a5cace0c2a3e212931badbf6398a0cd98393121asewardj di->symtab[i].pri_name = pri1; 1817a5cace0c2a3e212931badbf6398a0cd98393121asewardj di->symtab[i].sec_names = sec1; 1818a5cace0c2a3e212931badbf6398a0cd98393121asewardj di->symtab[i].isText = ist1; 1819a5cace0c2a3e212931badbf6398a0cd98393121asewardj di->symtab[i].isIFunc = isf1; 1820a5cace0c2a3e212931badbf6398a0cd98393121asewardj 18214cace66777ca9ee73ea156210c04e9d4cc178395philippe di->symtab[i+1].avmas.main = sta2; 18224cace66777ca9ee73ea156210c04e9d4cc178395philippe di->symtab[i+1].size = end2 - sta2 + 1; 18234cace66777ca9ee73ea156210c04e9d4cc178395philippe SET_TOCPTR_AVMA(di->symtab[i+1].avmas, toc2); 18244cace66777ca9ee73ea156210c04e9d4cc178395philippe // missing local_ep ??? 1825a5cace0c2a3e212931badbf6398a0cd98393121asewardj di->symtab[i+1].pri_name = pri2; 1826a5cace0c2a3e212931badbf6398a0cd98393121asewardj di->symtab[i+1].sec_names = sec2; 1827a5cace0c2a3e212931badbf6398a0cd98393121asewardj di->symtab[i+1].isText = ist2; 1828a5cace0c2a3e212931badbf6398a0cd98393121asewardj di->symtab[i+1].isIFunc = isf2; 1829a5cace0c2a3e212931badbf6398a0cd98393121asewardj 1830a5cace0c2a3e212931badbf6398a0cd98393121asewardj vg_assert(sta1 <= sta2); 1831b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di->symtab[i].size > 0); 1832b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di->symtab[i+1].size > 0); 1833eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* It may be that the i+1 entry now needs to be moved further 1834eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj along to maintain the address order requirement. */ 1835eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj j = i+1; 1836f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj while (j < ((Word)di->symtab_used)-1 18374cace66777ca9ee73ea156210c04e9d4cc178395philippe && di->symtab[j].avmas.main > di->symtab[j+1].avmas.main) { 1838b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj SWAP(DiSym,di->symtab[j],di->symtab[j+1]); 1839eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj j++; 1840eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1841eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj n_truncated++; 1842eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1843426e6a2ca4c94127fdbb0d0f9e89a831695f6cdbsewardj /* END Detect and "fix" overlapping address ranges. */ 1844eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1845eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (n_truncated > 0) goto cleanup_more; 1846eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1847eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* Ensure relevant postconditions hold. */ 1848f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj for (i = 0; i < ((Word)di->symtab_used)-1; i++) { 1849eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* No zero-sized symbols. */ 1850b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di->symtab[i].size > 0); 1851eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* In order. */ 18524cace66777ca9ee73ea156210c04e9d4cc178395philippe vg_assert(di->symtab[i].avmas.main < di->symtab[i+1].avmas.main); 1853eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* No overlaps. */ 18544cace66777ca9ee73ea156210c04e9d4cc178395philippe vg_assert(di->symtab[i].avmas.main + di->symtab[i].size - 1 18554cace66777ca9ee73ea156210c04e9d4cc178395philippe < di->symtab[i+1].avmas.main); 1856a5cace0c2a3e212931badbf6398a0cd98393121asewardj /* Names are sane(ish) */ 1857a5cace0c2a3e212931badbf6398a0cd98393121asewardj vg_assert(di->symtab[i].pri_name); 1858a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (di->symtab[i].sec_names) { 1859a5cace0c2a3e212931badbf6398a0cd98393121asewardj vg_assert(di->symtab[i].sec_names[0]); 1860a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 1861a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 1862a5cace0c2a3e212931badbf6398a0cd98393121asewardj 1863a5cace0c2a3e212931badbf6398a0cd98393121asewardj /* For each symbol that has more than one name, use preferName to 1864a5cace0c2a3e212931badbf6398a0cd98393121asewardj select the primary name. This is a complete kludge in that 1865a5cace0c2a3e212931badbf6398a0cd98393121asewardj doing it properly requires making a total ordering on the 1866a5cace0c2a3e212931badbf6398a0cd98393121asewardj candidate names, whilst what we have to work with is an ad-hoc 1867a5cace0c2a3e212931badbf6398a0cd98393121asewardj binary relation (preferName) that certainly doesn't have the 1868a5cace0c2a3e212931badbf6398a0cd98393121asewardj relevant transitivity etc properties that are needed to induce a 1869a5cace0c2a3e212931badbf6398a0cd98393121asewardj legitimate total order. Doesn't matter though if it doesn't 1870a5cace0c2a3e212931badbf6398a0cd98393121asewardj always work right since this is only used to generate names to 1871a5cace0c2a3e212931badbf6398a0cd98393121asewardj show the user. */ 1872a5cace0c2a3e212931badbf6398a0cd98393121asewardj for (i = 0; i < ((Word)di->symtab_used)-1; i++) { 1873a5cace0c2a3e212931badbf6398a0cd98393121asewardj DiSym* sym = &di->symtab[i]; 18741ef70c6f00ab1b50d1936f77037e9923d8ed8c59florian const HChar** sec = sym->sec_names; 1875a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (!sec) 1876a5cace0c2a3e212931badbf6398a0cd98393121asewardj continue; 1877a5cace0c2a3e212931badbf6398a0cd98393121asewardj /* Slow but simple. Copy all the cands into a temp array, 1878a5cace0c2a3e212931badbf6398a0cd98393121asewardj choose the primary name, and copy them all back again. */ 1879a5cace0c2a3e212931badbf6398a0cd98393121asewardj Word n_tmp = 1; 1880a5cace0c2a3e212931badbf6398a0cd98393121asewardj while (*sec) { n_tmp++; sec++; } 1881a5cace0c2a3e212931badbf6398a0cd98393121asewardj j = 0; 18821ef70c6f00ab1b50d1936f77037e9923d8ed8c59florian const HChar** tmp = ML_(dinfo_zalloc)( "di.storage.cS.1", 18831ef70c6f00ab1b50d1936f77037e9923d8ed8c59florian (n_tmp+1) * sizeof(HChar*) ); 1884a5cace0c2a3e212931badbf6398a0cd98393121asewardj tmp[j++] = sym->pri_name; 1885a5cace0c2a3e212931badbf6398a0cd98393121asewardj sec = sym->sec_names; 1886a5cace0c2a3e212931badbf6398a0cd98393121asewardj while (*sec) { tmp[j++] = *sec; sec++; } 1887a5cace0c2a3e212931badbf6398a0cd98393121asewardj vg_assert(j == n_tmp); 1888a5cace0c2a3e212931badbf6398a0cd98393121asewardj vg_assert(tmp[n_tmp] == NULL); /* because of zalloc */ 1889a5cace0c2a3e212931badbf6398a0cd98393121asewardj /* Choose the most favoured. */ 1890a5cace0c2a3e212931badbf6398a0cd98393121asewardj Word best = 0; 1891a5cace0c2a3e212931badbf6398a0cd98393121asewardj for (j = 1; j < n_tmp; j++) { 18924cace66777ca9ee73ea156210c04e9d4cc178395philippe if (preferName(di, tmp[best], tmp[j], di->symtab[i].avmas.main)) { 1893a5cace0c2a3e212931badbf6398a0cd98393121asewardj /* best is unchanged */ 1894a5cace0c2a3e212931badbf6398a0cd98393121asewardj } else { 1895a5cace0c2a3e212931badbf6398a0cd98393121asewardj best = j; 1896a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 1897a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 1898a5cace0c2a3e212931badbf6398a0cd98393121asewardj vg_assert(best >= 0 && best < n_tmp); 1899a5cace0c2a3e212931badbf6398a0cd98393121asewardj /* Copy back */ 1900a5cace0c2a3e212931badbf6398a0cd98393121asewardj sym->pri_name = tmp[best]; 19011ef70c6f00ab1b50d1936f77037e9923d8ed8c59florian const HChar** cursor = sym->sec_names; 1902a5cace0c2a3e212931badbf6398a0cd98393121asewardj for (j = 0; j < n_tmp; j++) { 1903a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (j == best) 1904a5cace0c2a3e212931badbf6398a0cd98393121asewardj continue; 1905a5cace0c2a3e212931badbf6398a0cd98393121asewardj *cursor = tmp[j]; 1906a5cace0c2a3e212931badbf6398a0cd98393121asewardj cursor++; 1907a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 1908a5cace0c2a3e212931badbf6398a0cd98393121asewardj vg_assert(*cursor == NULL); 1909a5cace0c2a3e212931badbf6398a0cd98393121asewardj ML_(dinfo_free)( tmp ); 1910eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1911a5cace0c2a3e212931badbf6398a0cd98393121asewardj 1912eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# undef SWAP 1913eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1914eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1915eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 191659e1f3c79e870a978d24add86db6d8c5450c8b63philippestatic DiLoc* sorting_loctab = NULL; 191759e1f3c79e870a978d24add86db6d8c5450c8b63philippestatic Int compare_DiLoc_via_ix ( const void* va, const void* vb ) 1918eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 19198eebf23c35d97489c0d3c8b41dd542e00ae6acbdflorian const DiLoc* a = &sorting_loctab[*(const UInt*)va]; 19208eebf23c35d97489c0d3c8b41dd542e00ae6acbdflorian const DiLoc* b = &sorting_loctab[*(const UInt*)vb]; 1921eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (a->addr < b->addr) return -1; 1922eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (a->addr > b->addr) return 1; 1923eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return 0; 1924eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 192559e1f3c79e870a978d24add86db6d8c5450c8b63philippestatic void sort_loctab_and_loctab_fndn_ix (struct _DebugInfo* di ) 192659e1f3c79e870a978d24add86db6d8c5450c8b63philippe{ 192759e1f3c79e870a978d24add86db6d8c5450c8b63philippe /* We have to sort the array loctab by addr 192859e1f3c79e870a978d24add86db6d8c5450c8b63philippe together with its "parallel" array loctab_fndn_ix. 192959e1f3c79e870a978d24add86db6d8c5450c8b63philippe We first build sort_ix : an array of indexes in loctab, 193059e1f3c79e870a978d24add86db6d8c5450c8b63philippe that we sort by loctab address. Then we can reorder both 193159e1f3c79e870a978d24add86db6d8c5450c8b63philippe arrays according to sort_ix. */ 193259e1f3c79e870a978d24add86db6d8c5450c8b63philippe UInt *sort_ix = ML_(dinfo_zalloc)("di.storage.six", 193359e1f3c79e870a978d24add86db6d8c5450c8b63philippe di->loctab_used*sizeof(UInt)); 193459e1f3c79e870a978d24add86db6d8c5450c8b63philippe Word i, j, k; 193559e1f3c79e870a978d24add86db6d8c5450c8b63philippe 193659e1f3c79e870a978d24add86db6d8c5450c8b63philippe for (i = 0; i < di->loctab_used; i++) sort_ix[i] = i; 193759e1f3c79e870a978d24add86db6d8c5450c8b63philippe sorting_loctab = di->loctab; 193859e1f3c79e870a978d24add86db6d8c5450c8b63philippe VG_(ssort)(sort_ix, di->loctab_used, 193959e1f3c79e870a978d24add86db6d8c5450c8b63philippe sizeof(*sort_ix), compare_DiLoc_via_ix); 194059e1f3c79e870a978d24add86db6d8c5450c8b63philippe sorting_loctab = NULL; 194159e1f3c79e870a978d24add86db6d8c5450c8b63philippe 194259e1f3c79e870a978d24add86db6d8c5450c8b63philippe // Permute in place, using the sort_ix. 194359e1f3c79e870a978d24add86db6d8c5450c8b63philippe for (i=0; i < di->loctab_used; i++) { 194459e1f3c79e870a978d24add86db6d8c5450c8b63philippe DiLoc tmp_diloc; 194559e1f3c79e870a978d24add86db6d8c5450c8b63philippe UInt tmp_fndn_ix; 194659e1f3c79e870a978d24add86db6d8c5450c8b63philippe 194759e1f3c79e870a978d24add86db6d8c5450c8b63philippe if (i == sort_ix[i]) 194859e1f3c79e870a978d24add86db6d8c5450c8b63philippe continue; // i already at the good place 194959e1f3c79e870a978d24add86db6d8c5450c8b63philippe 195059e1f3c79e870a978d24add86db6d8c5450c8b63philippe tmp_diloc = di->loctab[i]; 195159e1f3c79e870a978d24add86db6d8c5450c8b63philippe tmp_fndn_ix = ML_(fndn_ix)(di, i); 195259e1f3c79e870a978d24add86db6d8c5450c8b63philippe j = i; 195359e1f3c79e870a978d24add86db6d8c5450c8b63philippe for (;;) { 195459e1f3c79e870a978d24add86db6d8c5450c8b63philippe k = sort_ix[j]; 195559e1f3c79e870a978d24add86db6d8c5450c8b63philippe sort_ix[j] = j; 195659e1f3c79e870a978d24add86db6d8c5450c8b63philippe if (k == i) 195759e1f3c79e870a978d24add86db6d8c5450c8b63philippe break; 195859e1f3c79e870a978d24add86db6d8c5450c8b63philippe di->loctab[j] = di->loctab[k]; 195959e1f3c79e870a978d24add86db6d8c5450c8b63philippe set_fndn_ix (di, j, ML_(fndn_ix)(di, k)); 196059e1f3c79e870a978d24add86db6d8c5450c8b63philippe j = k; 196159e1f3c79e870a978d24add86db6d8c5450c8b63philippe } 196259e1f3c79e870a978d24add86db6d8c5450c8b63philippe di->loctab[j] = tmp_diloc; 196359e1f3c79e870a978d24add86db6d8c5450c8b63philippe set_fndn_ix (di, j, tmp_fndn_ix); 196459e1f3c79e870a978d24add86db6d8c5450c8b63philippe } 196559e1f3c79e870a978d24add86db6d8c5450c8b63philippe ML_(dinfo_free)(sort_ix); 196659e1f3c79e870a978d24add86db6d8c5450c8b63philippe} 1967eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 196859e1f3c79e870a978d24add86db6d8c5450c8b63philippe/* Sort the location table by starting address. Mash the table around 196959e1f3c79e870a978d24add86db6d8c5450c8b63philippe so as to establish the property that addresses are in order and the 197059e1f3c79e870a978d24add86db6d8c5450c8b63philippe ranges do not overlap. This facilitates using binary search to map 197159e1f3c79e870a978d24add86db6d8c5450c8b63philippe addresses to locations when we come to query the table. 197259e1f3c79e870a978d24add86db6d8c5450c8b63philippe*/ 1973b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void canonicaliseLoctab ( struct _DebugInfo* di ) 1974eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1975f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word i, j; 1976eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1977b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->loctab_used == 0) 1978eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return; 1979eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 198059e1f3c79e870a978d24add86db6d8c5450c8b63philippe /* sort loctab and loctab_fndn_ix by addr. */ 198159e1f3c79e870a978d24add86db6d8c5450c8b63philippe sort_loctab_and_loctab_fndn_ix (di); 1982eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1983eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* If two adjacent entries overlap, truncate the first. */ 1984f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj for (i = 0; i < ((Word)di->loctab_used)-1; i++) { 1985b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di->loctab[i].size < 10000); 1986b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->loctab[i].addr + di->loctab[i].size > di->loctab[i+1].addr) { 1987eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* Do this in signed int32 because the actual .size fields 1988eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj are only 12 bits. */ 1989b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int new_size = di->loctab[i+1].addr - di->loctab[i].addr; 1990eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (new_size < 0) { 1991b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->loctab[i].size = 0; 1992eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else 1993eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (new_size > MAX_LOC_SIZE) { 1994b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->loctab[i].size = MAX_LOC_SIZE; 1995eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else { 1996b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->loctab[i].size = (UShort)new_size; 1997eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1998eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1999eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2000eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2001eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* Zap any zero-sized entries resulting from the truncation 2002eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj process. */ 2003eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj j = 0; 2004f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj for (i = 0; i < (Word)di->loctab_used; i++) { 2005b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->loctab[i].size > 0) { 200659e1f3c79e870a978d24add86db6d8c5450c8b63philippe if (j != i) { 2007b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->loctab[j] = di->loctab[i]; 200859e1f3c79e870a978d24add86db6d8c5450c8b63philippe set_fndn_ix(di, j, ML_(fndn_ix)(di, i)); 200959e1f3c79e870a978d24add86db6d8c5450c8b63philippe } 2010eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj j++; 2011eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2012eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2013b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->loctab_used = j; 2014eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2015eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* Ensure relevant postconditions hold. */ 2016f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj for (i = 0; i < ((Word)di->loctab_used)-1; i++) { 201759e1f3c79e870a978d24add86db6d8c5450c8b63philippe if (0) 201859e1f3c79e870a978d24add86db6d8c5450c8b63philippe VG_(printf)("%lu 0x%p lno:%d sz:%d fndn_ix:%d i+1 0x%p\n", 201959e1f3c79e870a978d24add86db6d8c5450c8b63philippe i, 202059e1f3c79e870a978d24add86db6d8c5450c8b63philippe (void*)di->loctab[i].addr, 202159e1f3c79e870a978d24add86db6d8c5450c8b63philippe di->loctab[i].lineno, 202259e1f3c79e870a978d24add86db6d8c5450c8b63philippe di->loctab[i].size, 202359e1f3c79e870a978d24add86db6d8c5450c8b63philippe ML_(fndn_ix)(di, i), 202459e1f3c79e870a978d24add86db6d8c5450c8b63philippe (void*)di->loctab[i+1].addr); 202559e1f3c79e870a978d24add86db6d8c5450c8b63philippe 2026eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* No zero-sized symbols. */ 2027b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di->loctab[i].size > 0); 2028eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* In order. */ 2029b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di->loctab[i].addr < di->loctab[i+1].addr); 2030eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* No overlaps. */ 2031b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di->loctab[i].addr + di->loctab[i].size - 1 2032b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj < di->loctab[i+1].addr); 2033eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2034796e4b25100561a9e953cfe4dad83130b0153ce5sewardj 2035796e4b25100561a9e953cfe4dad83130b0153ce5sewardj /* Free up unused space at the end of the table. */ 2036796e4b25100561a9e953cfe4dad83130b0153ce5sewardj shrinkLocTab(di); 2037eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2038eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2039a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe/* Sort the inlined call table by starting address. Mash the table around 2040a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe so as to establish the property that addresses are in order. 2041a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe This facilitates using binary search to map addresses to locations when 2042a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe we come to query the table. 2043a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Note : ranges can overlap, multiple ranges can start at an address, 2044a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe multiple ranges can end at an address. 2045a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe*/ 2046a0a73939b0398b6608fd6dbde49820ce6530d12cphilippestatic Int compare_DiInlLoc ( const void* va, const void* vb ) 2047a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{ 2048a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe const DiInlLoc* a = va; 2049a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe const DiInlLoc* b = vb; 2050a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (a->addr_lo < b->addr_lo) return -1; 2051a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (a->addr_lo > b->addr_lo) return 1; 2052a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return 0; 2053a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe} 2054a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 2055a0a73939b0398b6608fd6dbde49820ce6530d12cphilippestatic void canonicaliseInltab ( struct _DebugInfo* di ) 2056a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{ 2057a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Word i; 2058a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 2059a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (di->inltab_used == 0) 2060a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return; 2061a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 2062a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /* Sort by start address. */ 2063a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe VG_(ssort)(di->inltab, di->inltab_used, 2064a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe sizeof(*di->inltab), compare_DiInlLoc); 2065a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 2066a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /* Ensure relevant postconditions hold. */ 2067a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe for (i = 0; i < ((Word)di->inltab_used)-1; i++) { 2068a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /* No zero-sized inlined call. */ 2069a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe vg_assert(di->inltab[i].addr_lo < di->inltab[i].addr_hi); 2070a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /* In order, but we can have duplicates and overlapping ranges. */ 2071a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe vg_assert(di->inltab[i].addr_lo <= di->inltab[i+1].addr_lo); 2072a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 2073a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 2074a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /* Free up unused space at the end of the table. */ 2075a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe shrinkInlTab(di); 2076a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe} 2077a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 2078eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 20795c3dba227192de63d86f65ec7d9597c132818c37philippe/* Sort the call-frame-info cfsi_rd by starting address. Mash the table 2080eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj around so as to establish the property that addresses are in order 2081eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj and the ranges do not overlap. This facilitates using binary 2082eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj search to map addresses to locations when we come to query the 2083eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj table. 2084eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2085eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Also, set cfisi_minaddr and cfisi_maxaddr to be the min and max of 2086eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj any of the address ranges contained in cfisi[0 .. cfisi_used-1], so 2087eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj as to facilitate rapidly skipping this SegInfo when looking for an 2088eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj address which falls outside that range. 2089eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj*/ 20906bd9dc18c043927c1196caba20a327238a179c42florianstatic Int compare_DiCfSI ( const void* va, const void* vb ) 2091eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 20926bd9dc18c043927c1196caba20a327238a179c42florian const DiCfSI* a = va; 20936bd9dc18c043927c1196caba20a327238a179c42florian const DiCfSI* b = vb; 2094eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (a->base < b->base) return -1; 2095eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (a->base > b->base) return 1; 2096eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return 0; 2097eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2098eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2099518850bf0da07ed3e2244e307268ae0fd80e93a8florianstatic void get_cfsi_rd_stats ( const DebugInfo* di, 21005c3dba227192de63d86f65ec7d9597c132818c37philippe UWord *n_mergeables, UWord *n_holes ) 21015c3dba227192de63d86f65ec7d9597c132818c37philippe{ 21025c3dba227192de63d86f65ec7d9597c132818c37philippe Word i; 21035c3dba227192de63d86f65ec7d9597c132818c37philippe 21045c3dba227192de63d86f65ec7d9597c132818c37philippe *n_mergeables = 0; 21055c3dba227192de63d86f65ec7d9597c132818c37philippe *n_holes = 0; 21065c3dba227192de63d86f65ec7d9597c132818c37philippe 21075c3dba227192de63d86f65ec7d9597c132818c37philippe vg_assert (di->cfsi_used == 0 || di->cfsi_rd); 21085c3dba227192de63d86f65ec7d9597c132818c37philippe for (i = 1; i < (Word)di->cfsi_used; i++) { 21095c3dba227192de63d86f65ec7d9597c132818c37philippe Addr here_min = di->cfsi_rd[i].base; 21105c3dba227192de63d86f65ec7d9597c132818c37philippe Addr prev_max = di->cfsi_rd[i-1].base + di->cfsi_rd[i-1].len - 1; 21115c3dba227192de63d86f65ec7d9597c132818c37philippe Addr sep = here_min - prev_max; 21125c3dba227192de63d86f65ec7d9597c132818c37philippe if (sep > 1) 21135c3dba227192de63d86f65ec7d9597c132818c37philippe (*n_holes)++; 21145c3dba227192de63d86f65ec7d9597c132818c37philippe if (sep == 1 && di->cfsi_rd[i-1].cfsi_m_ix == di->cfsi_rd[i].cfsi_m_ix) 21155c3dba227192de63d86f65ec7d9597c132818c37philippe (*n_mergeables)++; 21165c3dba227192de63d86f65ec7d9597c132818c37philippe } 21175c3dba227192de63d86f65ec7d9597c132818c37philippe} 21185c3dba227192de63d86f65ec7d9597c132818c37philippe 21193c9cf3442185b5891e15450d6e3058aeff6796fetomvoid ML_(canonicaliseCFI) ( struct _DebugInfo* di ) 2120eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2121f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word i, j; 2122b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj const Addr minAvma = 0; 2123b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj const Addr maxAvma = ~minAvma; 2124eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2125b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Note: take care in here. di->cfsi can be NULL, in which 2126eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj case _used and _size fields will be zero. */ 21275c3dba227192de63d86f65ec7d9597c132818c37philippe if (di->cfsi_rd == NULL) { 2128b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di->cfsi_used == 0); 2129b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di->cfsi_size == 0); 21305c3dba227192de63d86f65ec7d9597c132818c37philippe vg_assert(di->cfsi_m_pool == NULL); 21315c3dba227192de63d86f65ec7d9597c132818c37philippe } else { 21325c3dba227192de63d86f65ec7d9597c132818c37philippe vg_assert(di->cfsi_size != 0); 21335c3dba227192de63d86f65ec7d9597c132818c37philippe vg_assert(di->cfsi_m_pool != NULL); 2134eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2135eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2136b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Set cfsi_minavma and cfsi_maxavma to summarise the entire 21375c3dba227192de63d86f65ec7d9597c132818c37philippe address range contained in cfsi_rd[0 .. cfsi_used-1]. */ 2138b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->cfsi_minavma = maxAvma; 2139b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->cfsi_maxavma = minAvma; 2140f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj for (i = 0; i < (Word)di->cfsi_used; i++) { 21415c3dba227192de63d86f65ec7d9597c132818c37philippe Addr here_min = di->cfsi_rd[i].base; 21425c3dba227192de63d86f65ec7d9597c132818c37philippe Addr here_max = di->cfsi_rd[i].base + di->cfsi_rd[i].len - 1; 2143b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (here_min < di->cfsi_minavma) 2144b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->cfsi_minavma = here_min; 2145b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (here_max > di->cfsi_maxavma) 2146b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->cfsi_maxavma = here_max; 2147b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2148b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2149b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->trace_cfi) 2150f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj VG_(printf)("canonicaliseCfiSI: %ld entries, %#lx .. %#lx\n", 2151b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->cfsi_used, 2152b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->cfsi_minavma, di->cfsi_maxavma); 2153eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 21545c3dba227192de63d86f65ec7d9597c132818c37philippe /* Sort the cfsi_rd array by base address. */ 21555c3dba227192de63d86f65ec7d9597c132818c37philippe VG_(ssort)(di->cfsi_rd, di->cfsi_used, sizeof(*di->cfsi_rd), compare_DiCfSI); 2156eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2157eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* If two adjacent entries overlap, truncate the first. */ 2158f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj for (i = 0; i < (Word)di->cfsi_used-1; i++) { 21595c3dba227192de63d86f65ec7d9597c132818c37philippe if (di->cfsi_rd[i].base + di->cfsi_rd[i].len > di->cfsi_rd[i+1].base) { 21605c3dba227192de63d86f65ec7d9597c132818c37philippe Word new_len = di->cfsi_rd[i+1].base - di->cfsi_rd[i].base; 2161eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* how could it be otherwise? The entries are sorted by the 2162eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj .base field. */ 2163eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert(new_len >= 0); 21645c3dba227192de63d86f65ec7d9597c132818c37philippe vg_assert(new_len <= di->cfsi_rd[i].len); 21655c3dba227192de63d86f65ec7d9597c132818c37philippe di->cfsi_rd[i].len = new_len; 2166eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2167eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2168eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2169eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* Zap any zero-sized entries resulting from the truncation 2170eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj process. */ 2171eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj j = 0; 2172f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj for (i = 0; i < (Word)di->cfsi_used; i++) { 21735c3dba227192de63d86f65ec7d9597c132818c37philippe if (di->cfsi_rd[i].len > 0) { 2174eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (j != i) 21755c3dba227192de63d86f65ec7d9597c132818c37philippe di->cfsi_rd[j] = di->cfsi_rd[i]; 2176eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj j++; 2177eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2178eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2179b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* VG_(printf)("XXXXXXXXXXXXX %d %d\n", di->cfsi_used, j); */ 2180b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->cfsi_used = j; 2181eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2182eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* Ensure relevant postconditions hold. */ 2183f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj for (i = 0; i < (Word)di->cfsi_used; i++) { 2184eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* No zero-length ranges. */ 21855c3dba227192de63d86f65ec7d9597c132818c37philippe vg_assert(di->cfsi_rd[i].len > 0); 2186eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* Makes sense w.r.t. summary address range */ 21875c3dba227192de63d86f65ec7d9597c132818c37philippe vg_assert(di->cfsi_rd[i].base >= di->cfsi_minavma); 21885c3dba227192de63d86f65ec7d9597c132818c37philippe vg_assert(di->cfsi_rd[i].base + di->cfsi_rd[i].len - 1 2189b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj <= di->cfsi_maxavma); 2190eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2191b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (i < di->cfsi_used - 1) { 2192eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* 2193b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!(di->cfsi[i].base < di->cfsi[i+1].base)) { 2194eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(printf)("\nOOO cfsis:\n"); 2195b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(ppCfiSI)(&di->cfsi[i]); 2196b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(ppCfiSI)(&di->cfsi[i+1]); 2197eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2198eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj */ 2199eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* In order. */ 22005c3dba227192de63d86f65ec7d9597c132818c37philippe vg_assert(di->cfsi_rd[i].base < di->cfsi_rd[i+1].base); 2201eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* No overlaps. */ 22025c3dba227192de63d86f65ec7d9597c132818c37philippe vg_assert(di->cfsi_rd[i].base + di->cfsi_rd[i].len - 1 22035c3dba227192de63d86f65ec7d9597c132818c37philippe < di->cfsi_rd[i+1].base); 22045c3dba227192de63d86f65ec7d9597c132818c37philippe } 22055c3dba227192de63d86f65ec7d9597c132818c37philippe } 22065c3dba227192de63d86f65ec7d9597c132818c37philippe 22072386069c3a117630ebda167cef4ce747a1511eecphilippe if (VG_(clo_stats) && VG_(clo_verbosity) >= 3) { 22085c3dba227192de63d86f65ec7d9597c132818c37philippe UWord n_mergeables, n_holes; 22095c3dba227192de63d86f65ec7d9597c132818c37philippe get_cfsi_rd_stats (di, &n_mergeables, &n_holes); 22105c3dba227192de63d86f65ec7d9597c132818c37philippe VG_(dmsg)("CFSI total %lu mergeables %lu holes %lu uniq cfsi_m %u\n", 22115c3dba227192de63d86f65ec7d9597c132818c37philippe di->cfsi_used, n_mergeables, n_holes, 221205c459ea63c50a072cf1eb0868590e9c0b362f30philippe di->cfsi_m_pool ? VG_(sizeDedupPA) (di->cfsi_m_pool) : 0); 22135c3dba227192de63d86f65ec7d9597c132818c37philippe } 22145c3dba227192de63d86f65ec7d9597c132818c37philippe} 22155c3dba227192de63d86f65ec7d9597c132818c37philippe 22165c3dba227192de63d86f65ec7d9597c132818c37philippevoid ML_(finish_CFSI_arrays) ( struct _DebugInfo* di ) 22175c3dba227192de63d86f65ec7d9597c132818c37philippe{ 22185c3dba227192de63d86f65ec7d9597c132818c37philippe UWord n_mergeables, n_holes; 22195c3dba227192de63d86f65ec7d9597c132818c37philippe UWord new_used; 22205c3dba227192de63d86f65ec7d9597c132818c37philippe UWord i; 22215c3dba227192de63d86f65ec7d9597c132818c37philippe UWord pos; 22225c3dba227192de63d86f65ec7d9597c132818c37philippe UWord f_mergeables, f_holes; 22235c3dba227192de63d86f65ec7d9597c132818c37philippe UInt sz_cfsi_m_pool; 22245c3dba227192de63d86f65ec7d9597c132818c37philippe 22255c3dba227192de63d86f65ec7d9597c132818c37philippe get_cfsi_rd_stats (di, &n_mergeables, &n_holes); 22265c3dba227192de63d86f65ec7d9597c132818c37philippe 22275c3dba227192de63d86f65ec7d9597c132818c37philippe if (di->cfsi_used == 0) { 22285c3dba227192de63d86f65ec7d9597c132818c37philippe vg_assert (di->cfsi_rd == NULL); 22295c3dba227192de63d86f65ec7d9597c132818c37philippe vg_assert (di->cfsi_m_pool == NULL); 22305c3dba227192de63d86f65ec7d9597c132818c37philippe vg_assert (n_mergeables == 0); 22315c3dba227192de63d86f65ec7d9597c132818c37philippe vg_assert (n_holes == 0); 22325c3dba227192de63d86f65ec7d9597c132818c37philippe return; 22335c3dba227192de63d86f65ec7d9597c132818c37philippe } 22345c3dba227192de63d86f65ec7d9597c132818c37philippe 22355c3dba227192de63d86f65ec7d9597c132818c37philippe vg_assert (di->cfsi_used > n_mergeables); 22365c3dba227192de63d86f65ec7d9597c132818c37philippe new_used = di->cfsi_used - n_mergeables + n_holes; 22375c3dba227192de63d86f65ec7d9597c132818c37philippe 22385c3dba227192de63d86f65ec7d9597c132818c37philippe sz_cfsi_m_pool = VG_(sizeDedupPA)(di->cfsi_m_pool); 22395c3dba227192de63d86f65ec7d9597c132818c37philippe vg_assert (sz_cfsi_m_pool > 0); 22405c3dba227192de63d86f65ec7d9597c132818c37philippe if (sz_cfsi_m_pool <= 255) 224159e1f3c79e870a978d24add86db6d8c5450c8b63philippe di->sizeof_cfsi_m_ix = 1; 22425c3dba227192de63d86f65ec7d9597c132818c37philippe else if (sz_cfsi_m_pool <= 65535) 224359e1f3c79e870a978d24add86db6d8c5450c8b63philippe di->sizeof_cfsi_m_ix = 2; 22445c3dba227192de63d86f65ec7d9597c132818c37philippe else 224559e1f3c79e870a978d24add86db6d8c5450c8b63philippe di->sizeof_cfsi_m_ix = 4; 22465c3dba227192de63d86f65ec7d9597c132818c37philippe 22475c3dba227192de63d86f65ec7d9597c132818c37philippe di->cfsi_base = ML_(dinfo_zalloc)( "di.storage.finCfSI.1", 22485c3dba227192de63d86f65ec7d9597c132818c37philippe new_used * sizeof(Addr) ); 22495c3dba227192de63d86f65ec7d9597c132818c37philippe di->cfsi_m_ix = ML_(dinfo_zalloc)( "di.storage.finCfSI.2", 225059e1f3c79e870a978d24add86db6d8c5450c8b63philippe new_used * sizeof(UChar)*di->sizeof_cfsi_m_ix); 22515c3dba227192de63d86f65ec7d9597c132818c37philippe 22525c3dba227192de63d86f65ec7d9597c132818c37philippe pos = 0; 22535c3dba227192de63d86f65ec7d9597c132818c37philippe f_mergeables = 0; 22545c3dba227192de63d86f65ec7d9597c132818c37philippe f_holes = 0; 22555c3dba227192de63d86f65ec7d9597c132818c37philippe for (i = 0; i < (Word)di->cfsi_used; i++) { 22565c3dba227192de63d86f65ec7d9597c132818c37philippe if (i > 0) { 22575c3dba227192de63d86f65ec7d9597c132818c37philippe Addr here_min = di->cfsi_rd[i].base; 22585c3dba227192de63d86f65ec7d9597c132818c37philippe Addr prev_max = di->cfsi_rd[i-1].base + di->cfsi_rd[i-1].len - 1; 22595c3dba227192de63d86f65ec7d9597c132818c37philippe SizeT sep = here_min - prev_max; 22605c3dba227192de63d86f65ec7d9597c132818c37philippe 22615c3dba227192de63d86f65ec7d9597c132818c37philippe // Skip a mergeable entry. 22625c3dba227192de63d86f65ec7d9597c132818c37philippe if (sep == 1) { 22635c3dba227192de63d86f65ec7d9597c132818c37philippe if (di->cfsi_rd[i-1].cfsi_m_ix == di->cfsi_rd[i].cfsi_m_ix) { 22645c3dba227192de63d86f65ec7d9597c132818c37philippe f_mergeables++; 22655c3dba227192de63d86f65ec7d9597c132818c37philippe continue; 22665c3dba227192de63d86f65ec7d9597c132818c37philippe } 22675c3dba227192de63d86f65ec7d9597c132818c37philippe } 22685c3dba227192de63d86f65ec7d9597c132818c37philippe // Insert a hole if needed. 22695c3dba227192de63d86f65ec7d9597c132818c37philippe if (sep > 1) { 22705c3dba227192de63d86f65ec7d9597c132818c37philippe f_holes++; 22715c3dba227192de63d86f65ec7d9597c132818c37philippe di->cfsi_base[pos] = prev_max + 1; 227259e1f3c79e870a978d24add86db6d8c5450c8b63philippe switch (di->sizeof_cfsi_m_ix) { 22735c3dba227192de63d86f65ec7d9597c132818c37philippe case 1: ((UChar*) di->cfsi_m_ix)[pos] = 0; break; 22745c3dba227192de63d86f65ec7d9597c132818c37philippe case 2: ((UShort*)di->cfsi_m_ix)[pos] = 0; break; 22755c3dba227192de63d86f65ec7d9597c132818c37philippe case 4: ((UInt*) di->cfsi_m_ix)[pos] = 0; break; 22765c3dba227192de63d86f65ec7d9597c132818c37philippe default: vg_assert(0); 22775c3dba227192de63d86f65ec7d9597c132818c37philippe } 22785c3dba227192de63d86f65ec7d9597c132818c37philippe pos++; 22795c3dba227192de63d86f65ec7d9597c132818c37philippe } 2280eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 22815c3dba227192de63d86f65ec7d9597c132818c37philippe 22825c3dba227192de63d86f65ec7d9597c132818c37philippe // Insert the cfsi entry i. 22835c3dba227192de63d86f65ec7d9597c132818c37philippe di->cfsi_base[pos] = di->cfsi_rd[i].base; 228459e1f3c79e870a978d24add86db6d8c5450c8b63philippe switch (di->sizeof_cfsi_m_ix) { 22855c3dba227192de63d86f65ec7d9597c132818c37philippe case 1: ((UChar*) di->cfsi_m_ix)[pos] = di->cfsi_rd[i].cfsi_m_ix; break; 22865c3dba227192de63d86f65ec7d9597c132818c37philippe case 2: ((UShort*)di->cfsi_m_ix)[pos] = di->cfsi_rd[i].cfsi_m_ix; break; 22875c3dba227192de63d86f65ec7d9597c132818c37philippe case 4: ((UInt*) di->cfsi_m_ix)[pos] = di->cfsi_rd[i].cfsi_m_ix; break; 22885c3dba227192de63d86f65ec7d9597c132818c37philippe default: vg_assert(0); 22895c3dba227192de63d86f65ec7d9597c132818c37philippe } 22905c3dba227192de63d86f65ec7d9597c132818c37philippe pos++; 2291eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2292eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 22935c3dba227192de63d86f65ec7d9597c132818c37philippe vg_assert (f_mergeables == n_mergeables); 22945c3dba227192de63d86f65ec7d9597c132818c37philippe vg_assert (f_holes == n_holes); 22955c3dba227192de63d86f65ec7d9597c132818c37philippe vg_assert (pos == new_used); 22965c3dba227192de63d86f65ec7d9597c132818c37philippe 22975c3dba227192de63d86f65ec7d9597c132818c37philippe di->cfsi_used = new_used; 22985c3dba227192de63d86f65ec7d9597c132818c37philippe di->cfsi_size = new_used; 22995c3dba227192de63d86f65ec7d9597c132818c37philippe ML_(dinfo_free) (di->cfsi_rd); 23005c3dba227192de63d86f65ec7d9597c132818c37philippe di->cfsi_rd = NULL; 2301eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2302eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2303eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2304b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Canonicalise the tables held by 'di', in preparation for use. Call 2305eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj this after finishing adding entries to these tables. */ 2306b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid ML_(canonicaliseTables) ( struct _DebugInfo* di ) 2307eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2308b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj canonicaliseSymtab ( di ); 2309b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj canonicaliseLoctab ( di ); 2310a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe canonicaliseInltab ( di ); 23113c9cf3442185b5891e15450d6e3058aeff6796fetom ML_(canonicaliseCFI) ( di ); 23125c3dba227192de63d86f65ec7d9597c132818c37philippe if (di->cfsi_m_pool) 23135c3dba227192de63d86f65ec7d9597c132818c37philippe VG_(freezeDedupPA) (di->cfsi_m_pool, ML_(dinfo_shrink_block)); 2314b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj canonicaliseVarInfo ( di ); 23157293d2530f8c60c1060f9f003e214cc341d35266philippe if (di->strpool) 23160b9d0646949bd382758763664d3bf2d6115993aephilippe VG_(freezeDedupPA) (di->strpool, ML_(dinfo_shrink_block)); 231759e1f3c79e870a978d24add86db6d8c5450c8b63philippe if (di->fndnpool) 231859e1f3c79e870a978d24add86db6d8c5450c8b63philippe VG_(freezeDedupPA) (di->fndnpool, ML_(dinfo_shrink_block)); 2319eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2320eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2321eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2322eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 2323eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- Searching the tables ---*/ 2324eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 2325eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2326eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Find a symbol-table index containing the specified pointer, or -1 2327eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if not found. Binary search. */ 2328eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2329518850bf0da07ed3e2244e307268ae0fd80e93a8florianWord ML_(search_one_symtab) ( const DebugInfo* di, Addr ptr, 2330f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Bool match_anywhere_in_sym, 2331f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Bool findText ) 2332eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2333eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Addr a_mid_lo, a_mid_hi; 2334b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word mid, size, 2335eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj lo = 0, 2336b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj hi = di->symtab_used-1; 2337eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj while (True) { 2338eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* current unsearched space is from lo to hi, inclusive. */ 2339eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (lo > hi) return -1; /* not found */ 2340eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj mid = (lo + hi) / 2; 23414cace66777ca9ee73ea156210c04e9d4cc178395philippe a_mid_lo = di->symtab[mid].avmas.main; 2342b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj size = ( match_anywhere_in_sym 2343b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ? di->symtab[mid].size 2344eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj : 1); 23454cace66777ca9ee73ea156210c04e9d4cc178395philippe a_mid_hi = ((Addr)di->symtab[mid].avmas.main) + size - 1; 2346eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2347eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (ptr < a_mid_lo) { hi = mid-1; continue; } 2348eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (ptr > a_mid_hi) { lo = mid+1; continue; } 2349eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert(ptr >= a_mid_lo && ptr <= a_mid_hi); 2350b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Found a symbol with the correct address range. But is it 2351b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj of the right kind (text vs data) ? */ 2352b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( findText && di->symtab[mid].isText ) return mid; 2353b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( (!findText) && (!di->symtab[mid].isText) ) return mid; 2354b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return -1; 2355eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2356eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2357eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2358eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2359eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Find a location-table index containing the specified pointer, or -1 2360eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if not found. Binary search. */ 2361eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2362518850bf0da07ed3e2244e307268ae0fd80e93a8florianWord ML_(search_one_loctab) ( const DebugInfo* di, Addr ptr ) 2363eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2364eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Addr a_mid_lo, a_mid_hi; 2365b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word mid, 2366eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj lo = 0, 2367b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj hi = di->loctab_used-1; 2368eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj while (True) { 2369eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* current unsearched space is from lo to hi, inclusive. */ 2370eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (lo > hi) return -1; /* not found */ 2371eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj mid = (lo + hi) / 2; 2372b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj a_mid_lo = di->loctab[mid].addr; 2373b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj a_mid_hi = ((Addr)di->loctab[mid].addr) + di->loctab[mid].size - 1; 2374eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2375eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (ptr < a_mid_lo) { hi = mid-1; continue; } 2376eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (ptr > a_mid_hi) { lo = mid+1; continue; } 2377eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert(ptr >= a_mid_lo && ptr <= a_mid_hi); 2378eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return mid; 2379eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2380eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2381eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2382eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2383eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Find a CFI-table index containing the specified pointer, or -1 2384eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if not found. Binary search. */ 2385eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2386518850bf0da07ed3e2244e307268ae0fd80e93a8florianWord ML_(search_one_cfitab) ( const DebugInfo* di, Addr ptr ) 2387eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 23885c3dba227192de63d86f65ec7d9597c132818c37philippe Word mid, 2389eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj lo = 0, 2390b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj hi = di->cfsi_used-1; 23915c3dba227192de63d86f65ec7d9597c132818c37philippe 23925c3dba227192de63d86f65ec7d9597c132818c37philippe while (lo <= hi) { 23930b260824e9bea1fd6d2d6fabd4d112af124ecde6philippe /* Invariants : hi == cfsi_used-1 || ptr < cfsi_base[hi+1] 23940b260824e9bea1fd6d2d6fabd4d112af124ecde6philippe lo == 0 || ptr > cfsi_base[lo-1] 23950b260824e9bea1fd6d2d6fabd4d112af124ecde6philippe (the first part of the invariants is similar to considering 23960b260824e9bea1fd6d2d6fabd4d112af124ecde6philippe that cfsi_base[-1] is 0 and cfsi_base[cfsi_used] is ~0) */ 2397eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj mid = (lo + hi) / 2; 23985c3dba227192de63d86f65ec7d9597c132818c37philippe if (ptr < di->cfsi_base[mid]) { hi = mid-1; continue; } 23995c3dba227192de63d86f65ec7d9597c132818c37philippe if (ptr > di->cfsi_base[mid]) { lo = mid+1; continue; } 24000b260824e9bea1fd6d2d6fabd4d112af124ecde6philippe lo = mid+1; break; 2401eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 24025c3dba227192de63d86f65ec7d9597c132818c37philippe 24035c3dba227192de63d86f65ec7d9597c132818c37philippe#if 0 24045c3dba227192de63d86f65ec7d9597c132818c37philippe for (mid = 0; mid <= di->cfsi_used-1; mid++) 24055c3dba227192de63d86f65ec7d9597c132818c37philippe if (ptr < di->cfsi_base[mid]) 24065c3dba227192de63d86f65ec7d9597c132818c37philippe break; 24075c3dba227192de63d86f65ec7d9597c132818c37philippe vg_assert (lo - 1 == mid - 1); 24085c3dba227192de63d86f65ec7d9597c132818c37philippe#endif 24095c3dba227192de63d86f65ec7d9597c132818c37philippe return lo - 1; 2410eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2411eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2412eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2413c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/* Find a FPO-table index containing the specified pointer, or -1 2414c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if not found. Binary search. */ 2415c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2416518850bf0da07ed3e2244e307268ae0fd80e93a8florianWord ML_(search_one_fpotab) ( const DebugInfo* di, Addr ptr ) 2417c8259b85b701d25d72aabe9dc0a8154517f96913sewardj{ 241854c45db2f978055aeca91aaccb05aac825523e6csewardj Addr const addr = ptr - di->fpo_base_avma; 2419c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Addr a_mid_lo, a_mid_hi; 2420c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Word mid, size, 2421c8259b85b701d25d72aabe9dc0a8154517f96913sewardj lo = 0, 2422c8259b85b701d25d72aabe9dc0a8154517f96913sewardj hi = di->fpo_size-1; 2423c8259b85b701d25d72aabe9dc0a8154517f96913sewardj while (True) { 2424c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* current unsearched space is from lo to hi, inclusive. */ 2425c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (lo > hi) return -1; /* not found */ 2426c8259b85b701d25d72aabe9dc0a8154517f96913sewardj mid = (lo + hi) / 2; 2427c8259b85b701d25d72aabe9dc0a8154517f96913sewardj a_mid_lo = di->fpo[mid].ulOffStart; 2428c8259b85b701d25d72aabe9dc0a8154517f96913sewardj size = di->fpo[mid].cbProcSize; 2429c8259b85b701d25d72aabe9dc0a8154517f96913sewardj a_mid_hi = a_mid_lo + size - 1; 2430c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(a_mid_hi >= a_mid_lo); 2431c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (addr < a_mid_lo) { hi = mid-1; continue; } 2432c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (addr > a_mid_hi) { lo = mid+1; continue; } 2433c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(addr >= a_mid_lo && addr <= a_mid_hi); 2434c8259b85b701d25d72aabe9dc0a8154517f96913sewardj return mid; 2435c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 2436c8259b85b701d25d72aabe9dc0a8154517f96913sewardj} 2437c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2438eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--------------------------------------------------------------------*/ 2439eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- end ---*/ 2440eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--------------------------------------------------------------------*/ 2441