From 135719b57e969a96fc9e56ec23aaf443d93790df Mon Sep 17 00:00:00 2001 From: Philippe Waroquiers Date: Wed, 13 Aug 2014 21:25:45 +0000 Subject: [PATCH] Reduce memory needed for symbols, by having the tocptr and local_ep (used for ppc64 platforms) #ifdef-ed and accessed by macros that becomes NOP on non ppc64 platforms. This decreases the debuginfo memory by about 2.5 Mb on a big 32 bit application. Note : doing that, some questions were encountered in the way tocptr and local_ep have (or do not have) to be copied/maintained in storage.c canonicaliseSymtab git-svn-id: svn://svn.valgrind.org/valgrind/trunk@14273 --- coregrind/m_debuginfo/debuginfo.c | 40 +++--- coregrind/m_debuginfo/priv_storage.h | 8 +- coregrind/m_debuginfo/readelf.c | 159 +++++++++++------------ coregrind/m_debuginfo/readmacho.c | 5 +- coregrind/m_debuginfo/readpdb.c | 28 ++-- coregrind/m_debuginfo/storage.c | 58 +++++---- coregrind/m_gdbserver/valgrind-low-arm.c | 11 +- coregrind/m_redir.c | 32 +++-- coregrind/pub_core_debuginfo.h | 53 +++++++- include/pub_tool_debuginfo.h | 19 --- 10 files changed, 219 insertions(+), 194 deletions(-) diff --git a/coregrind/m_debuginfo/debuginfo.c b/coregrind/m_debuginfo/debuginfo.c index 9afbf7333d..4ad9b7a333 100644 --- a/coregrind/m_debuginfo/debuginfo.c +++ b/coregrind/m_debuginfo/debuginfo.c @@ -1654,7 +1654,7 @@ Bool get_sym_name ( Bool do_cxx_demangling, Bool do_z_demangling, { VG_(strncpy_safely)(buf, "(below main)", nbuf); } - offset = a - di->symtab[sno].addr; + offset = a - di->symtab[sno].avmas.main; if (offsetP) *offsetP = offset; if (show_offset && offset != 0) { @@ -1684,6 +1684,7 @@ Bool get_sym_name ( Bool do_cxx_demangling, Bool do_z_demangling, guest_code_addr. Returns 0 if not known. */ Addr VG_(get_tocptr) ( Addr guest_code_addr ) { +#if defined(VGA_ppc64be) || defined(VGA_ppc64le) DebugInfo* si; Word sno; search_all_symtabs ( guest_code_addr, @@ -1693,7 +1694,10 @@ Addr VG_(get_tocptr) ( Addr guest_code_addr ) if (si == NULL) return 0; else - return si->symtab[sno].tocptr; + return GET_TOCPTR_AVMA(si->symtab[sno].avmas); +#else + return 0; +#endif } /* This is available to tools... always demangle C++ names, @@ -1990,8 +1994,7 @@ Bool VG_(get_filename_linenum) ( Addr a, Therefore specify "*" to search all the objects. On TOC-afflicted platforms, a symbol is deemed to be found only if it has a nonzero TOC pointer. */ -Bool VG_(lookup_symbol_SLOW)(const HChar* sopatt, HChar* name, - Addr* pEnt, Addr* pToc) +Bool VG_(lookup_symbol_SLOW)(const HChar* sopatt, HChar* name, SymAVMAs* avmas) { Bool require_pToc = False; Int i; @@ -2012,9 +2015,8 @@ Bool VG_(lookup_symbol_SLOW)(const HChar* sopatt, HChar* name, HChar* pri_name = si->symtab[i].pri_name; tl_assert(pri_name); if (0==VG_(strcmp)(name, pri_name) - && (require_pToc ? si->symtab[i].tocptr : True)) { - *pEnt = si->symtab[i].addr; - *pToc = si->symtab[i].tocptr; + && (require_pToc ? GET_TOCPTR_AVMA(si->symtab[i].avmas) : True)) { + *avmas = si->symtab[i].avmas; return True; } HChar** sec_names = si->symtab[i].sec_names; @@ -2022,9 +2024,9 @@ Bool VG_(lookup_symbol_SLOW)(const HChar* sopatt, HChar* name, tl_assert(sec_names[0]); while (*sec_names) { if (0==VG_(strcmp)(name, *sec_names) - && (require_pToc ? si->symtab[i].tocptr : True)) { - *pEnt = si->symtab[i].addr; - *pToc = si->symtab[i].tocptr; + && (require_pToc + ? GET_TOCPTR_AVMA(si->symtab[i].avmas) : True)) { + *avmas = si->symtab[i].avmas; return True; } sec_names++; @@ -4138,19 +4140,15 @@ Int VG_(DebugInfo_syms_howmany) ( const DebugInfo *si ) void VG_(DebugInfo_syms_getidx) ( const DebugInfo *si, Int idx, - /*OUT*/Addr* avma, - /*OUT*/Addr* tocptr, - /*OUT*/Addr* local_ep, - /*OUT*/UInt* size, - /*OUT*/HChar** pri_name, - /*OUT*/HChar*** sec_names, - /*OUT*/Bool* isText, - /*OUT*/Bool* isIFunc ) + /*OUT*/SymAVMAs* avmas, + /*OUT*/UInt* size, + /*OUT*/HChar** pri_name, + /*OUT*/HChar*** sec_names, + /*OUT*/Bool* isText, + /*OUT*/Bool* isIFunc ) { vg_assert(idx >= 0 && idx < si->symtab_used); - if (avma) *avma = si->symtab[idx].addr; - if (tocptr) *tocptr = si->symtab[idx].tocptr; - if (local_ep) *local_ep = si->symtab[idx].local_ep; + if (avmas) *avmas = si->symtab[idx].avmas; if (size) *size = si->symtab[idx].size; if (pri_name) *pri_name = si->symtab[idx].pri_name; if (sec_names) *sec_names = (HChar **)si->symtab[idx].sec_names; // FIXME diff --git a/coregrind/m_debuginfo/priv_storage.h b/coregrind/m_debuginfo/priv_storage.h index b79587f793..21ca438615 100644 --- a/coregrind/m_debuginfo/priv_storage.h +++ b/coregrind/m_debuginfo/priv_storage.h @@ -69,10 +69,10 @@ sec_names[] does not need to be allocated. */ typedef - struct { - Addr addr; /* lowest address of entity */ - Addr tocptr; /* ppc64be-linux only: value that R2 should have */ - Addr local_ep; /* address for local entry point, ppc64le */ + struct { + SymAVMAs avmas; /* Symbol Actual VMAs: lowest address of entity, + + platform specific fields, to access with + the macros defined in pub_core_debuginfo.h */ HChar* pri_name; /* primary name, never NULL */ HChar** sec_names; /* NULL, or a NULL term'd array of other names */ // XXX: this could be shrunk (on 32-bit platforms) by using 30 diff --git a/coregrind/m_debuginfo/readelf.c b/coregrind/m_debuginfo/readelf.c index 27b7a6498a..8cb14fb842 100644 --- a/coregrind/m_debuginfo/readelf.c +++ b/coregrind/m_debuginfo/readelf.c @@ -234,17 +234,12 @@ Bool get_elf_symbol_info ( PtrdiffT opd_bias, /* for biasing AVMAs found in .opd */ /* OUTPUTS */ DiOffT* sym_name_out_ioff, /* name (in strtab) we should record */ - Addr* sym_avma_out, /* addr we should record */ + SymAVMAs* sym_avmas_out, /* sym avmas we should record */ Int* sym_size_out, /* symbol size */ - Addr* sym_tocptr_out, /* ppc64be-linux only: R2 value to be - used on entry */ Bool* from_opd_out, /* ppc64be-linux only: did we deref an .opd entry? */ Bool* is_text_out, /* is this a text symbol? */ - Bool* is_ifunc, /* is this a STT_GNU_IFUNC function ?*/ - Addr* sym_local_ep /* addr for local entry point. PPC64 LE - supports a local and global entry points. - Use this value to return the entry point. */ + Bool* is_ifunc /* is this a STT_GNU_IFUNC function ?*/ ) { Bool plausible; @@ -257,12 +252,12 @@ Bool get_elf_symbol_info ( /* Set defaults */ *sym_name_out_ioff = sym_name_ioff; - *sym_avma_out = sym_svma; /* we will bias this shortly */ + (*sym_avmas_out).main = sym_svma; /* we will bias this shortly */ *is_text_out = True; - *sym_tocptr_out = 0; /* unknown/inapplicable */ + SET_TOCPTR_AVMA(*sym_avmas_out, 0); /* default to unknown/inapplicable */ + SET_LOCAL_EP_AVMA(*sym_avmas_out, 0); /* default to unknown/inapplicable */ *from_opd_out = False; *is_ifunc = False; - *sym_local_ep = 0; /* unknown/inapplicable */ /* Get the symbol size, but restrict it to fit in a signed 32 bit int. Also, deal with the stupid case of negative size by making @@ -322,7 +317,7 @@ Bool get_elf_symbol_info ( sbss_bias = di->sbss_bias; } - /* Now bias sym_avma_out accordingly by figuring out exactly which + /* Now bias (*sym_avmas_out).main accordingly by figuring out exactly which section the symbol is from and bias accordingly. Screws up if the previously deduced section svma address ranges are wrong. */ if (di->text_present @@ -330,46 +325,46 @@ Bool get_elf_symbol_info ( && sym_svma >= text_svma && sym_svma < text_svma + di->text_size) { *is_text_out = True; - *sym_avma_out += text_bias; + (*sym_avmas_out).main += text_bias; } else if (di->data_present && di->data_size > 0 && sym_svma >= data_svma && sym_svma < data_svma + di->data_size) { *is_text_out = False; - *sym_avma_out += data_bias; + (*sym_avmas_out).main += data_bias; } else if (di->sdata_present && di->sdata_size > 0 && sym_svma >= sdata_svma && sym_svma < sdata_svma + di->sdata_size) { *is_text_out = False; - *sym_avma_out += sdata_bias; + (*sym_avmas_out).main += sdata_bias; } else if (di->rodata_present && di->rodata_size > 0 && sym_svma >= rodata_svma && sym_svma < rodata_svma + di->rodata_size) { *is_text_out = False; - *sym_avma_out += rodata_bias; + (*sym_avmas_out).main += rodata_bias; } else if (di->bss_present && di->bss_size > 0 && sym_svma >= bss_svma && sym_svma < bss_svma + di->bss_size) { *is_text_out = False; - *sym_avma_out += bss_bias; + (*sym_avmas_out).main += bss_bias; } else if (di->sbss_present && di->sbss_size > 0 && sym_svma >= sbss_svma && sym_svma < sbss_svma + di->sbss_size) { *is_text_out = False; - *sym_avma_out += sbss_bias; + (*sym_avmas_out).main += sbss_bias; } else { /* Assume it's in .text. Is this a good idea? */ *is_text_out = True; - *sym_avma_out += text_bias; + (*sym_avmas_out).main += text_bias; } # ifdef STT_GNU_IFUNC @@ -390,8 +385,8 @@ Bool get_elf_symbol_info ( && *sym_size_out > 0 && di->opd_present && di->opd_size > 0 - && *sym_avma_out >= di->opd_avma - && *sym_avma_out < di->opd_avma + di->opd_size) + && (*sym_avmas_out).main >= di->opd_avma + && (*sym_avmas_out).main < di->opd_avma + di->opd_size) plausible = True; # endif @@ -456,8 +451,8 @@ Bool get_elf_symbol_info ( symbol defined elsewhere, so ignore it. */ if (di->got_present && di->got_size > 0 - && *sym_avma_out >= di->got_avma - && *sym_avma_out < di->got_avma + di->got_size) { + && (*sym_avmas_out).main >= di->got_avma + && (*sym_avmas_out).main < di->got_avma + di->got_size) { if (TRACE_SYMTAB_ENABLED) { HChar* sym_name = ML_(img_strdup)(escn_strtab->img, "di.gesi.4", sym_name_ioff); @@ -468,8 +463,8 @@ Bool get_elf_symbol_info ( } if (di->plt_present && di->plt_size > 0 - && *sym_avma_out >= di->plt_avma - && *sym_avma_out < di->plt_avma + di->plt_size) { + && (*sym_avmas_out).main >= di->plt_avma + && (*sym_avmas_out).main < di->plt_avma + di->plt_size) { if (TRACE_SYMTAB_ENABLED) { HChar* sym_name = ML_(img_strdup)(escn_strtab->img, "di.gesi.5", sym_name_ioff); @@ -494,8 +489,8 @@ Bool get_elf_symbol_info ( if (di->opd_present && di->opd_size > 0 - && *sym_avma_out >= di->opd_avma - && *sym_avma_out < di->opd_avma + di->opd_size) { + && (*sym_avmas_out).main >= di->opd_avma + && (*sym_avmas_out).main < di->opd_avma + di->opd_size) { # if !defined(VGP_ppc64be_linux) if (TRACE_SYMTAB_ENABLED) { HChar* sym_name = ML_(img_strdup)(escn_strtab->img, @@ -510,9 +505,9 @@ Bool get_elf_symbol_info ( if (details) TRACE_SYMTAB("opdXXX: opd_bias %p, sym_svma_out %p\n", - (void*)(opd_bias), (void*)*sym_avma_out); + (void*)(opd_bias), (void*)(*sym_avmas_out).main); - if (!VG_IS_8_ALIGNED(*sym_avma_out)) { + if (!VG_IS_8_ALIGNED((*sym_avmas_out).main)) { if (TRACE_SYMTAB_ENABLED) { HChar* sym_name = ML_(img_strdup)(escn_strtab->img, "di.gesi.6a", sym_name_ioff); @@ -522,11 +517,11 @@ Bool get_elf_symbol_info ( return False; } - /* *sym_avma_out is a vma pointing into the .opd section. We + /* (*sym_avmas_out).main is a avma pointing into the .opd section. We know the vma of the opd section start, so we can figure out how far into the opd section this is. */ - offset_in_opd = (Addr)(*sym_avma_out) - (Addr)(di->opd_avma); + offset_in_opd = (Addr)(*sym_avmas_out).main - (Addr)(di->opd_avma); if (offset_in_opd < 0 || offset_in_opd >= di->opd_size) { if (TRACE_SYMTAB_ENABLED) { HChar* sym_name = ML_(img_strdup)(escn_strtab->img, @@ -576,13 +571,13 @@ Bool get_elf_symbol_info ( OK for fn_descr[0], but surely we need to use the data bias and not the text bias for fn_descr[1] ? Oh Well. */ - *sym_avma_out = fn_descr[0] + opd_bias; - *sym_tocptr_out = fn_descr[1] + opd_bias; + (*sym_avmas_out).main = fn_descr[0] + opd_bias; + SET_TOCPTR_AVMA(*sym_avmas_out, fn_descr[1] + opd_bias); *from_opd_out = True; is_in_opd = True; /* Do a final sanity check: if the symbol falls outside the - DebugInfo's mapped range, ignore it. Since *sym_avma_out has + DebugInfo's mapped range, ignore it. Since (*sym_avmas_out).main has been updated, that can be achieved simply by falling through to the test below. */ @@ -607,38 +602,38 @@ Bool get_elf_symbol_info ( in_text = di->text_present && di->text_size > 0 - && !(*sym_avma_out + *sym_size_out <= di->text_avma - || *sym_avma_out >= di->text_avma + di->text_size); + && !((*sym_avmas_out).main + *sym_size_out <= di->text_avma + || (*sym_avmas_out).main >= di->text_avma + di->text_size); in_data = di->data_present && di->data_size > 0 - && !(*sym_avma_out + *sym_size_out <= di->data_avma - || *sym_avma_out >= di->data_avma + di->data_size); + && !((*sym_avmas_out).main + *sym_size_out <= di->data_avma + || (*sym_avmas_out).main >= di->data_avma + di->data_size); in_sdata = di->sdata_present && di->sdata_size > 0 - && !(*sym_avma_out + *sym_size_out <= di->sdata_avma - || *sym_avma_out >= di->sdata_avma + di->sdata_size); + && !((*sym_avmas_out).main + *sym_size_out <= di->sdata_avma + || (*sym_avmas_out).main >= di->sdata_avma + di->sdata_size); in_rodata = di->rodata_present && di->rodata_size > 0 - && !(*sym_avma_out + *sym_size_out <= di->rodata_avma - || *sym_avma_out >= di->rodata_avma + di->rodata_size); + && !((*sym_avmas_out).main + *sym_size_out <= di->rodata_avma + || (*sym_avmas_out).main >= di->rodata_avma + di->rodata_size); in_bss = di->bss_present && di->bss_size > 0 - && !(*sym_avma_out + *sym_size_out <= di->bss_avma - || *sym_avma_out >= di->bss_avma + di->bss_size); + && !((*sym_avmas_out).main + *sym_size_out <= di->bss_avma + || (*sym_avmas_out).main >= di->bss_avma + di->bss_size); in_sbss = di->sbss_present && di->sbss_size > 0 - && !(*sym_avma_out + *sym_size_out <= di->sbss_avma - || *sym_avma_out >= di->sbss_avma + di->sbss_size); + && !((*sym_avmas_out).main + *sym_size_out <= di->sbss_avma + || (*sym_avmas_out).main >= di->sbss_avma + di->sbss_size); if (*is_text_out) { @@ -653,14 +648,16 @@ Bool get_elf_symbol_info ( /* This could actually wrap around and cause ML_(find_rx_mapping) to assert. But that seems so unlikely, let's wait for it to happen before fixing it. */ - in_rx = (ML_(find_rx_mapping)(di, *sym_avma_out, - *sym_avma_out + *sym_size_out) != NULL); + in_rx = (ML_(find_rx_mapping)( + di, + (*sym_avmas_out).main, + (*sym_avmas_out).main + *sym_size_out) != NULL); if (in_text) vg_assert(in_rx); if (!in_rx) { TRACE_SYMTAB( "ignore -- %#lx .. %#lx outside .text svma range %#lx .. %#lx\n", - *sym_avma_out, *sym_avma_out + *sym_size_out, + (*sym_avmas_out).main, (*sym_avmas_out).main + *sym_size_out, di->text_avma, di->text_avma + di->text_size); return False; @@ -670,15 +667,15 @@ Bool get_elf_symbol_info ( TRACE_SYMTAB( "ignore -- %#lx .. %#lx outside .data / .sdata / .rodata " "/ .bss / .sbss svma ranges\n", - *sym_avma_out, *sym_avma_out + *sym_size_out); + (*sym_avmas_out).main, (*sym_avmas_out).main + *sym_size_out); return False; } } # if defined(VGP_ppc64be_linux) if (di->opd_present && di->opd_size > 0) { - vg_assert(*sym_avma_out + *sym_size_out <= di->opd_avma - || *sym_avma_out >= di->opd_avma + di->opd_size); + vg_assert((*sym_avmas_out).main + *sym_size_out <= di->opd_avma + || (*sym_avmas_out).main >= di->opd_avma + di->opd_size); } #endif @@ -717,13 +714,15 @@ Bool get_elf_symbol_info ( if ((bit_field > 0) && (bit_field < 7)) { /* store the local entry point address */ dist_to_local_entry = ((1 << bit_field) >> 2) << 2; - *sym_local_ep = *sym_avma_out + dist_to_local_entry; + SET_LOCAL_EP_AVMA(*sym_avmas_out, + (*sym_avmas_out).main + dist_to_local_entry); if (TRACE_SYMTAB_ENABLED) { HChar* sym_name = ML_(img_strdup)(escn_strtab->img, "di.gesi.5", sym_name_ioff); VG_(printf)("Local entry point: %s at %#010x\n", - sym_name, (unsigned int)*sym_local_ep); + sym_name, + (unsigned int)GET_LOCAL_EP_AVMA(*sym_avmas_out)); } } } @@ -771,29 +770,26 @@ void read_elf_symtab__normal( show_raw_elf_symbol(escn_strtab->img, i, &sym, sym_name, sym_svma, False); - Addr sym_avma_really = 0; + SymAVMAs sym_avmas_really; Int sym_size = 0; - Addr sym_tocptr = 0; - Addr local_ep = 0; Bool from_opd = False, is_text = False, is_ifunc = False; DiOffT sym_name_really = DiOffT_INVALID; + sym_avmas_really.main = 0; + SET_TOCPTR_AVMA(sym_avmas_really, 0); + SET_LOCAL_EP_AVMA(sym_avmas_really, 0); if (get_elf_symbol_info(di, &sym, sym_name, escn_strtab, sym_svma, symtab_in_debug, escn_opd, di->text_bias, &sym_name_really, - &sym_avma_really, + &sym_avmas_really, &sym_size, - &sym_tocptr, - &from_opd, &is_text, &is_ifunc, - &local_ep)) { + &from_opd, &is_text, &is_ifunc)) { DiSym disym; VG_(memset)(&disym, 0, sizeof(disym)); HChar* cstr = ML_(img_strdup)(escn_strtab->img, "di.res__n.1", sym_name_really); - disym.addr = sym_avma_really; - disym.tocptr = sym_tocptr; - disym.local_ep = local_ep; + disym.avmas = sym_avmas_really; disym.pri_name = ML_(addStr) ( di, cstr, -1 ); disym.sec_names = NULL; disym.size = sym_size; @@ -801,7 +797,8 @@ void read_elf_symtab__normal( disym.isIFunc = is_ifunc; if (cstr) { ML_(dinfo_free)(cstr); cstr = NULL; } vg_assert(disym.pri_name); - vg_assert(disym.tocptr == 0); /* has no role except on ppc64be-linux */ + vg_assert(GET_TOCPTR_AVMA(disym.avmas) == 0); + /* has no role except on ppc64be-linux */ ML_(addSym) ( di, &disym ); if (TRACE_SYMTAB_ENABLED) { @@ -809,13 +806,13 @@ void read_elf_symtab__normal( " val %#010lx, sz %4d %s\n", is_text ? 't' : 'd', i, - disym.addr, + disym.avmas.main, (Int)disym.size, (HChar*)disym.pri_name ); - if (local_ep != 0) { + if (GET_LOCAL_EP_AVMA(disym.avmas) != 0) { TRACE_SYMTAB(" local entry point %#010lx\n", - local_ep) + GET_LOCAL_EP_AVMA(disym.avmas)); } } @@ -909,26 +906,25 @@ void read_elf_symtab__ppc64be_linux( show_raw_elf_symbol(escn_strtab->img, i, &sym, sym_name, sym_svma, True); - Addr sym_avma_really = 0; + SymAVMAs sym_avmas_really; Int sym_size = 0; - Addr sym_tocptr = 0; - Addr sym_local_ep = 0; Bool from_opd = False, is_text = False, is_ifunc = False; DiOffT sym_name_really = DiOffT_INVALID; DiSym disym; VG_(memset)(&disym, 0, sizeof(disym)); + sym_avmas_really.main = 0; + SET_TOCPTR_AVMA(sym_avmas_really, 0); + SET_LOCAL_EP_AVMA(sym_avmas_really, 0); if (get_elf_symbol_info(di, &sym, sym_name, escn_strtab, sym_svma, symtab_in_debug, escn_opd, di->text_bias, &sym_name_really, - &sym_avma_really, + &sym_avmas_really, &sym_size, - &sym_tocptr, - &from_opd, &is_text, &is_ifunc, - &sym_local_ep)) { + &from_opd, &is_text, &is_ifunc)) { /* Check if we've seen this (name,addr) key before. */ - key.addr = sym_avma_really; + key.addr = sym_avmas_really.main; key.name = sym_name_really; key.img = escn_strtab->img; prev = VG_(OSetGen_Lookup)( oset, &key ); @@ -959,7 +955,7 @@ void read_elf_symtab__ppc64be_linux( shouldn't currently have an known TOC ptr. */ vg_assert(prev->tocptr == 0); modify_tocptr = True; - prev->tocptr = sym_tocptr; + prev->tocptr = GET_TOCPTR_AVMA(sym_avmas_really); } else { /* ignore. can we do better here? */ @@ -994,7 +990,7 @@ void read_elf_symtab__ppc64be_linux( elem = VG_(OSetGen_AllocNode)(oset, sizeof(TempSym)); vg_assert(elem); elem->key = key; - elem->tocptr = sym_tocptr; + elem->tocptr = GET_TOCPTR_AVMA(sym_avmas_really); elem->size = sym_size; elem->from_opd = from_opd; elem->is_text = is_text; @@ -1029,8 +1025,9 @@ void read_elf_symtab__ppc64be_linux( VG_(memset)(&disym, 0, sizeof(disym)); HChar* cstr = ML_(img_strdup)(escn_strtab->img, "di.res__ppc64.1", elem->key.name); - disym.addr = elem->key.addr; - disym.tocptr = elem->tocptr; + disym.avmas.main = elem->key.addr; + SET_TOCPTR_AVMA(disym.avmas, elem->tocptr); + SET_LOCAL_EP_AVMA(disym.avmas, 0); // ppc64be does not use local_ep. disym.pri_name = ML_(addStr) ( di, cstr, -1 ); disym.sec_names = NULL; disym.size = elem->size; @@ -1045,8 +1042,8 @@ void read_elf_symtab__ppc64be_linux( " val %#010lx, toc %#010lx, sz %4d %s\n", disym.isText ? 't' : 'd', i, - disym.addr, - disym.tocptr, + disym.avmas.main, + GET_TOCPTR_AVMA(disym.avmas), (Int) disym.size, (HChar*)disym.pri_name ); diff --git a/coregrind/m_debuginfo/readmacho.c b/coregrind/m_debuginfo/readmacho.c index 95b665c659..8c614e9fe1 100644 --- a/coregrind/m_debuginfo/readmacho.c +++ b/coregrind/m_debuginfo/readmacho.c @@ -356,8 +356,9 @@ void read_symtab( /*OUT*/XArray* /* DiSym */ syms, continue; } - disym.addr = sym_addr; - disym.tocptr = 0; + disym.main = sym_addr; + SET_TOCPTR_AVMA(disym, 0); + SET_LOCAL_EP_AVMA(disym, 0); disym.pri_name = ML_(addStr)(di, name, -1); disym.sec_names = NULL; disym.size = // let canonicalize fix it diff --git a/coregrind/m_debuginfo/readpdb.c b/coregrind/m_debuginfo/readpdb.c index 6304d1a212..011c1dac11 100644 --- a/coregrind/m_debuginfo/readpdb.c +++ b/coregrind/m_debuginfo/readpdb.c @@ -1264,9 +1264,9 @@ static ULong DEBUG_SnarfCodeView( if (0 /*VG_(needs).data_syms*/) { nmstr = ML_(addStr)(di, symname, sym->data_v1.p_name.namelen); - vsym.addr = bias + sectp[sym->data_v1.segment-1].VirtualAddress + vsym.avmas.main = bias + sectp[sym->data_v1.segment-1].VirtualAddress + sym->data_v1.offset; - vsym.tocptr = 0; + SET_TOCPTR_AVMA(vsym.avmas, 0); vsym.pri_name = nmstr; vsym.sec_names = NULL; vsym.size = sym->data_v1.p_name.namelen; @@ -1290,9 +1290,9 @@ static ULong DEBUG_SnarfCodeView( if (sym->generic.id==S_PUB_V2 /*VG_(needs).data_syms*/) { nmstr = ML_(addStr)(di, symname, k); - vsym.addr = bias + sectp[sym->data_v2.segment-1].VirtualAddress + vsym.avmas.main = bias + sectp[sym->data_v2.segment-1].VirtualAddress + sym->data_v2.offset; - vsym.tocptr = 0; + SET_TOCPTR_AVMA(vsym.avmas, 0); vsym.pri_name = nmstr; vsym.sec_names = NULL; vsym.size = 4000; @@ -1324,9 +1324,9 @@ static ULong DEBUG_SnarfCodeView( if (1 /*sym->generic.id==S_PUB_FUNC1_V3 || sym->generic.id==S_PUB_FUNC2_V3*/) { nmstr = ML_(addStr)(di, symname, k); - vsym.addr = bias + sectp[sym->public_v3.segment-1].VirtualAddress + vsym.avmas.main = bias + sectp[sym->public_v3.segment-1].VirtualAddress + sym->public_v3.offset; - vsym.tocptr = 0; + SET_TOCPTR_AVMA(vsym.avmas, 0); vsym.pri_name = nmstr; vsym.sec_names = NULL; vsym.size = 4000; @@ -1360,9 +1360,9 @@ static ULong DEBUG_SnarfCodeView( sym->proc_v1.p_name.namelen); symname[sym->proc_v1.p_name.namelen] = '\0'; nmstr = ML_(addStr)(di, symname, sym->proc_v1.p_name.namelen); - vsym.addr = bias + sectp[sym->proc_v1.segment-1].VirtualAddress + vsym.avmas.main = bias + sectp[sym->proc_v1.segment-1].VirtualAddress + sym->proc_v1.offset; - vsym.tocptr = 0; + SET_TOCPTR_AVMA(vsym.avmas, 0); vsym.pri_name = nmstr; vsym.sec_names = NULL; vsym.size = sym->proc_v1.proc_len; @@ -1371,7 +1371,7 @@ static ULong DEBUG_SnarfCodeView( if (debug) VG_(message)(Vg_UserMsg, " Adding function %s addr=%#lx length=%d\n", - symname, vsym.addr, vsym.size ); + symname, vsym.avmas.main, vsym.size ); ML_(addSym)( di, &vsym ); n_syms_read++; break; @@ -1382,9 +1382,9 @@ static ULong DEBUG_SnarfCodeView( sym->proc_v2.p_name.namelen); symname[sym->proc_v2.p_name.namelen] = '\0'; nmstr = ML_(addStr)(di, symname, sym->proc_v2.p_name.namelen); - vsym.addr = bias + sectp[sym->proc_v2.segment-1].VirtualAddress + vsym.avmas.main = bias + sectp[sym->proc_v2.segment-1].VirtualAddress + sym->proc_v2.offset; - vsym.tocptr = 0; + SET_TOCPTR_AVMA(vsym.avmas, 0); vsym.pri_name = nmstr; vsym.sec_names = NULL; vsym.size = sym->proc_v2.proc_len; @@ -1393,7 +1393,7 @@ static ULong DEBUG_SnarfCodeView( if (debug) VG_(message)(Vg_UserMsg, " Adding function %s addr=%#lx length=%d\n", - symname, vsym.addr, vsym.size ); + symname, vsym.avmas.main, vsym.size ); ML_(addSym)( di, &vsym ); n_syms_read++; break; @@ -1406,9 +1406,9 @@ static ULong DEBUG_SnarfCodeView( if (1) { nmstr = ML_(addStr)(di, sym->proc_v3.name, VG_(strlen)(sym->proc_v3.name)); - vsym.addr = bias + sectp[sym->proc_v3.segment-1].VirtualAddress + vsym.avmas.main = bias + sectp[sym->proc_v3.segment-1].VirtualAddress + sym->proc_v3.offset; - vsym.tocptr = 0; + SET_TOCPTR_AVMA(vsym.avmas, 0); vsym.pri_name = nmstr; vsym.sec_names = NULL; vsym.size = sym->proc_v3.proc_len; diff --git a/coregrind/m_debuginfo/storage.c b/coregrind/m_debuginfo/storage.c index 705331c8ea..9c35c569ea 100644 --- a/coregrind/m_debuginfo/storage.c +++ b/coregrind/m_debuginfo/storage.c @@ -102,8 +102,8 @@ void ML_(ppSym) ( Int idx, DiSym* sym ) idx, sym->isText ? 'T' : '-', sym->isIFunc ? 'I' : '-', - sym->addr, - sym->addr + sym->size - 1, sym->size, + sym->avmas.main, + sym->avmas.main + sym->size - 1, sym->size, sym->pri_name, sec_names ? " " : "" ); if (sec_names) { while (*sec_names) { @@ -1388,8 +1388,8 @@ static Int compare_DiSym ( const void* va, const void* vb ) { const DiSym* a = va; const DiSym* b = vb; - if (a->addr < b->addr) return -1; - if (a->addr > b->addr) return 1; + if (a->avmas.main < b->avmas.main) return -1; + if (a->avmas.main > b->avmas.main) return 1; return 0; } @@ -1656,9 +1656,9 @@ static void canonicaliseSymtab ( struct _DebugInfo* di ) /* A pass merging entries together */ for (r = 1; r < di->symtab_used; r++) { vg_assert(w < r); - if ( di->symtab[w].addr == di->symtab[r].addr - && di->symtab[w].size == di->symtab[r].size - && !!di->symtab[w].isText == !!di->symtab[r].isText) { + if ( di->symtab[w].avmas.main == di->symtab[r].avmas.main + && di->symtab[w].size == di->symtab[r].size + && !!di->symtab[w].isText == !!di->symtab[r].isText) { /* merge the two into one */ n_merged++; /* Add r names to w if r has secondary names @@ -1707,11 +1707,11 @@ static void canonicaliseSymtab ( struct _DebugInfo* di ) for (i = 0; i < ((Word)di->symtab_used) -1; i++) { - vg_assert(di->symtab[i].addr <= di->symtab[i+1].addr); + vg_assert(di->symtab[i].avmas.main <= di->symtab[i+1].avmas.main); /* Check for common (no overlap) case. */ - if (di->symtab[i].addr + di->symtab[i].size - <= di->symtab[i+1].addr) + if (di->symtab[i].avmas.main + di->symtab[i].size + <= di->symtab[i+1].avmas.main) continue; /* There's an overlap. Truncate one or the other. */ @@ -1724,17 +1724,19 @@ static void canonicaliseSymtab ( struct _DebugInfo* di ) } /* Truncate one or the other. */ - sta1 = di->symtab[i].addr; + sta1 = di->symtab[i].avmas.main; end1 = sta1 + di->symtab[i].size - 1; - toc1 = di->symtab[i].tocptr; + toc1 = GET_TOCPTR_AVMA(di->symtab[i].avmas); + // aren't we missing local_ep here ???? pri1 = di->symtab[i].pri_name; sec1 = di->symtab[i].sec_names; ist1 = di->symtab[i].isText; isf1 = di->symtab[i].isIFunc; - sta2 = di->symtab[i+1].addr; + sta2 = di->symtab[i+1].avmas.main; end2 = sta2 + di->symtab[i+1].size - 1; - toc2 = di->symtab[i+1].tocptr; + toc2 = GET_TOCPTR_AVMA(di->symtab[i+1].avmas); + // aren't we missing local_ep here ???? pri2 = di->symtab[i+1].pri_name; sec2 = di->symtab[i+1].sec_names; ist2 = di->symtab[i+1].isText; @@ -1757,17 +1759,19 @@ static void canonicaliseSymtab ( struct _DebugInfo* di ) up back at cleanup_more, which will take care of it. */ } } - di->symtab[i].addr = sta1; - di->symtab[i].size = end1 - sta1 + 1; - di->symtab[i].tocptr = toc1; + di->symtab[i].avmas.main = sta1; + di->symtab[i].size = end1 - sta1 + 1; + SET_TOCPTR_AVMA(di->symtab[i].avmas, toc1); + // missing local_ep ??? di->symtab[i].pri_name = pri1; di->symtab[i].sec_names = sec1; di->symtab[i].isText = ist1; di->symtab[i].isIFunc = isf1; - di->symtab[i+1].addr = sta2; - di->symtab[i+1].size = end2 - sta2 + 1; - di->symtab[i+1].tocptr = toc2; + di->symtab[i+1].avmas.main = sta2; + di->symtab[i+1].size = end2 - sta2 + 1; + SET_TOCPTR_AVMA(di->symtab[i+1].avmas, toc2); + // missing local_ep ??? di->symtab[i+1].pri_name = pri2; di->symtab[i+1].sec_names = sec2; di->symtab[i+1].isText = ist2; @@ -1780,7 +1784,7 @@ static void canonicaliseSymtab ( struct _DebugInfo* di ) along to maintain the address order requirement. */ j = i+1; while (j < ((Word)di->symtab_used)-1 - && di->symtab[j].addr > di->symtab[j+1].addr) { + && di->symtab[j].avmas.main > di->symtab[j+1].avmas.main) { SWAP(DiSym,di->symtab[j],di->symtab[j+1]); j++; } @@ -1794,10 +1798,10 @@ static void canonicaliseSymtab ( struct _DebugInfo* di ) /* No zero-sized symbols. */ vg_assert(di->symtab[i].size > 0); /* In order. */ - vg_assert(di->symtab[i].addr < di->symtab[i+1].addr); + vg_assert(di->symtab[i].avmas.main < di->symtab[i+1].avmas.main); /* No overlaps. */ - vg_assert(di->symtab[i].addr + di->symtab[i].size - 1 - < di->symtab[i+1].addr); + vg_assert(di->symtab[i].avmas.main + di->symtab[i].size - 1 + < di->symtab[i+1].avmas.main); /* Names are sane(ish) */ vg_assert(di->symtab[i].pri_name); if (di->symtab[i].sec_names) { @@ -1834,7 +1838,7 @@ static void canonicaliseSymtab ( struct _DebugInfo* di ) /* Choose the most favoured. */ Word best = 0; for (j = 1; j < n_tmp; j++) { - if (preferName(di, tmp[best], tmp[j], di->symtab[i].addr)) { + if (preferName(di, tmp[best], tmp[j], di->symtab[i].avmas.main)) { /* best is unchanged */ } else { best = j; @@ -2283,11 +2287,11 @@ Word ML_(search_one_symtab) ( struct _DebugInfo* di, Addr ptr, /* current unsearched space is from lo to hi, inclusive. */ if (lo > hi) return -1; /* not found */ mid = (lo + hi) / 2; - a_mid_lo = di->symtab[mid].addr; + a_mid_lo = di->symtab[mid].avmas.main; size = ( match_anywhere_in_sym ? di->symtab[mid].size : 1); - a_mid_hi = ((Addr)di->symtab[mid].addr) + size - 1; + a_mid_hi = ((Addr)di->symtab[mid].avmas.main) + size - 1; if (ptr < a_mid_lo) { hi = mid-1; continue; } if (ptr > a_mid_hi) { lo = mid+1; continue; } diff --git a/coregrind/m_gdbserver/valgrind-low-arm.c b/coregrind/m_gdbserver/valgrind-low-arm.c index d95f2d33ce..255fe79881 100644 --- a/coregrind/m_gdbserver/valgrind-low-arm.c +++ b/coregrind/m_gdbserver/valgrind-low-arm.c @@ -145,18 +145,17 @@ Addr thumb_pc (Addr pc) // pc aligned on 4 bytes. We need to use debug info. { HChar fnname[200]; // ??? max size - Addr entrypoint; - Addr ptoc; // unused but needed. + SymAVMAs avmas; // If this is a thumb instruction, we need to ask // the debug info with the bit0 set // (why can't debug info do that for us ???) // (why if this is a 4 bytes thumb instruction ???) if (VG_(get_fnname_raw) (pc | 1, fnname, 200)) { - if (VG_(lookup_symbol_SLOW)( "*", fnname, &entrypoint, &ptoc )) { + if (VG_(lookup_symbol_SLOW)( "*", fnname, &avmas )) { dlog (1, "fnname %s lookupsym %p => %p %s.\n", - fnname, C2v(entrypoint), C2v(pc), - (entrypoint & 1 ? "thumb" : "arm")); - if (entrypoint & 1) + fnname, C2v(avmas.main), C2v(pc), + (avmas.main & 1 ? "thumb" : "arm")); + if (avmas.main & 1) return pc | 1; else return pc; diff --git a/coregrind/m_redir.c b/coregrind/m_redir.c index de70360ee1..9e6a10c70e 100644 --- a/coregrind/m_redir.c +++ b/coregrind/m_redir.c @@ -397,7 +397,7 @@ void VG_(redir_notify_new_DebugInfo)( DebugInfo* newdi ) TopSpec* newts; HChar* sym_name_pri; HChar** sym_names_sec; - Addr sym_addr, sym_toc, local_ep; + SymAVMAs sym_avmas; HChar demangled_sopatt[N_DEMANGLED]; HChar demangled_fnpatt[N_DEMANGLED]; Bool check_ppcTOCs = False; @@ -499,7 +499,7 @@ void VG_(redir_notify_new_DebugInfo)( DebugInfo* newdi ) nsyms = VG_(DebugInfo_syms_howmany)( newdi ); for (i = 0; i < nsyms; i++) { - VG_(DebugInfo_syms_getidx)( newdi, i, &sym_addr, &sym_toc, &local_ep, + VG_(DebugInfo_syms_getidx)( newdi, i, &sym_avmas, NULL, &sym_name_pri, &sym_names_sec, &isText, NULL ); /* Set up to conveniently iterate over all names for this symbol. */ @@ -518,10 +518,10 @@ void VG_(redir_notify_new_DebugInfo)( DebugInfo* newdi ) if (!ok) { /* It's not a full-scale redirect, but perhaps it is a load-notify fn? Let the load-notify department see it. */ - handle_maybe_load_notifier( newdi_soname, *names, sym_addr ); + handle_maybe_load_notifier( newdi_soname, *names, sym_avmas.main ); continue; } - if (check_ppcTOCs && sym_toc == 0) { + if (check_ppcTOCs && GET_TOCPTR_AVMA(sym_avmas) == 0) { /* This platform uses toc pointers, but none could be found for this symbol, so we can't safely redirect/wrap to it. Just skip it; we'll make a second pass over the symbols in @@ -576,12 +576,12 @@ void VG_(redir_notify_new_DebugInfo)( DebugInfo* newdi ) spec->from_fnpatt = dinfo_strdup("redir.rnnD.3", demangled_fnpatt); vg_assert(spec->from_sopatt); vg_assert(spec->from_fnpatt); - spec->to_addr = sym_addr; + spec->to_addr = sym_avmas.main; spec->isWrap = isWrap; spec->becTag = becTag; spec->becPrio = becPrio; /* check we're not adding manifestly stupid destinations */ - vg_assert(is_plausible_guest_addr(sym_addr)); + vg_assert(is_plausible_guest_addr(sym_avmas.main)); spec->next = specList; spec->mark = False; /* not significant */ spec->done = False; /* not significant */ @@ -592,7 +592,7 @@ void VG_(redir_notify_new_DebugInfo)( DebugInfo* newdi ) if (check_ppcTOCs) { for (i = 0; i < nsyms; i++) { - VG_(DebugInfo_syms_getidx)( newdi, i, &sym_addr, &sym_toc, &local_ep, + VG_(DebugInfo_syms_getidx)( newdi, i, &sym_avmas, NULL, &sym_name_pri, &sym_names_sec, &isText, NULL ); HChar* twoslots[2]; @@ -607,7 +607,7 @@ void VG_(redir_notify_new_DebugInfo)( DebugInfo* newdi ) if (!ok) /* not a redirect. Ignore. */ continue; - if (sym_toc != 0) + if (GET_TOCPTR_AVMA(sym_avmas) != 0) /* has a valid toc pointer. Ignore. */ continue; @@ -732,7 +732,7 @@ void generate_and_add_actives ( Bool anyMark, isText, isIFunc; Active act; Int nsyms, i; - Addr sym_addr; + SymAVMAs sym_avmas; HChar* sym_name_pri; HChar** sym_names_sec; @@ -755,9 +755,7 @@ void generate_and_add_actives ( of trashing the caches less. */ nsyms = VG_(DebugInfo_syms_howmany)( di ); for (i = 0; i < nsyms; i++) { - Addr local_ep = 0; - - VG_(DebugInfo_syms_getidx)( di, i, &sym_addr, NULL, &local_ep, + VG_(DebugInfo_syms_getidx)( di, i, &sym_avmas, NULL, &sym_name_pri, &sym_names_sec, &isText, &isIFunc ); HChar* twoslots[2]; @@ -775,7 +773,7 @@ void generate_and_add_actives ( continue; /* soname doesn't match */ if (VG_(string_match)( sp->from_fnpatt, *names )) { /* got a new binding. Add to collection. */ - act.from_addr = sym_addr; + act.from_addr = sym_avmas.main; act.to_addr = sp->to_addr; act.parent_spec = parent_spec; act.parent_sym = parent_sym; @@ -790,10 +788,10 @@ void generate_and_add_actives ( * redirect it to the global entry point. The redirection * must save and setup r2 then setup r12 for the new function. * On return, r2 must be restored. Local entry points used - * used in PPC64 Little Endian. + * in PPC64 Little Endian. */ - if (local_ep != 0) { - act.from_addr = local_ep; + if (GET_LOCAL_EP_AVMA(sym_avmas) != 0) { + act.from_addr = GET_LOCAL_EP_AVMA(sym_avmas); maybe_add_active( act ); } @@ -1604,7 +1602,7 @@ static void handle_require_text_symbols ( DebugInfo* di ) Bool isText = False; HChar* sym_name_pri = NULL; HChar** sym_names_sec = NULL; - VG_(DebugInfo_syms_getidx)( di, j, NULL, NULL, NULL, + VG_(DebugInfo_syms_getidx)( di, j, NULL, NULL, &sym_name_pri, &sym_names_sec, &isText, NULL ); HChar* twoslots[2]; diff --git a/coregrind/pub_core_debuginfo.h b/coregrind/pub_core_debuginfo.h index 5e93793ca8..a455d74166 100644 --- a/coregrind/pub_core_debuginfo.h +++ b/coregrind/pub_core_debuginfo.h @@ -153,12 +153,60 @@ extern Bool VG_(use_FPO_info) ( /*MOD*/Addr* ipP, Addr min_accessible, Addr max_accessible ); +/* AVMAs for a symbol. Usually only the lowest address of the entity. + On ppc64 platforms, also contains tocptr and local_ep. + These fields should only be accessed using the macros + GET_TOCPTR_AVMA/SET_TOCPTR_AVMA/GET_LOCAL_EP_AVMA/SET_LOCAL_EP_AVMA. */ +typedef + struct { + Addr main; /* lowest address of entity */ +# if defined(VGA_ppc64be) || defined(VGA_ppc64le) + Addr tocptr; /* ppc64be/le-linux only: value that R2 should have */ +# endif +# if defined(VGA_ppc64le) + Addr local_ep; /* address for local entry point, ppc64le only */ +# endif + } + SymAVMAs; + +#if defined(VGA_ppc64be) || defined(VGA_ppc64le) +# define GET_TOCPTR_AVMA(_sym_avmas) (_sym_avmas).tocptr +# define SET_TOCPTR_AVMA(_sym_avmas, _val) (_sym_avmas).tocptr = (_val) +#else +# define GET_TOCPTR_AVMA(_sym_avmas) ((Addr)0) +# define SET_TOCPTR_AVMA(_sym_avmas, _val) /* */ +#endif + +#if defined(VGA_ppc64le) +# define GET_LOCAL_EP_AVMA(_sym_avmas) (_sym_avmas).local_ep +# define SET_LOCAL_EP_AVMA(_sym_avmas, _val) (_sym_avmas).local_ep = (_val) +#else +# define GET_LOCAL_EP_AVMA(_sym_avmas) ((Addr)0) +# define SET_LOCAL_EP_AVMA(_sym_avmas, _val) /* */ +#endif + +/* Functions for traversing all the symbols in a DebugInfo. _howmany + tells how many symbol table entries there are. _getidx retrieves + the n'th entry, for n in 0 .. _howmany-1. You may not modify the + function names thereby acquired; if you want to do so, first strdup + them. The primary name is returned in *pri_name, and *sec_names is + set either to NULL or to a NULL terminated vector containing + pointers to the secondary names. */ +Int VG_(DebugInfo_syms_howmany) ( const DebugInfo *di ); +void VG_(DebugInfo_syms_getidx) ( const DebugInfo *di, + Int idx, + /*OUT*/SymAVMAs* ad, + /*OUT*/UInt* size, + /*OUT*/HChar** pri_name, + /*OUT*/HChar*** sec_names, + /*OUT*/Bool* isText, + /*OUT*/Bool* isIFunc ); /* ppc64-linux only: find the TOC pointer (R2 value) that should be in force at the entry point address of the function containing guest_code_addr. Returns 0 if not known. */ extern Addr VG_(get_tocptr) ( Addr guest_code_addr ); -/* Map a function name to its entry point and toc pointer. Is done by +/* Map a function name to its SymAVMAs. Is done by sequential search of all symbol tables, so is very slow. To mitigate the worst performance effects, you may specify a soname pattern, and only objects matching that pattern are searched. @@ -166,8 +214,7 @@ extern Addr VG_(get_tocptr) ( Addr guest_code_addr ); platforms, a symbol is deemed to be found only if it has a nonzero TOC pointer. */ extern -Bool VG_(lookup_symbol_SLOW)(const HChar* sopatt, HChar* name, Addr* pEnt, - Addr* pToc); +Bool VG_(lookup_symbol_SLOW)(const HChar* sopatt, HChar* name, SymAVMAs* avmas); #endif // __PUB_CORE_DEBUGINFO_H diff --git a/include/pub_tool_debuginfo.h b/include/pub_tool_debuginfo.h index 9beb5122a5..f47669e6c1 100644 --- a/include/pub_tool_debuginfo.h +++ b/include/pub_tool_debuginfo.h @@ -237,25 +237,6 @@ PtrdiffT VG_(DebugInfo_get_text_bias) ( const DebugInfo *di ); of the list stays constant. */ const DebugInfo* VG_(next_DebugInfo) ( const DebugInfo *di ); -/* Functions for traversing all the symbols in a DebugInfo. _howmany - tells how many symbol table entries there are. _getidx retrieves - the n'th entry, for n in 0 .. _howmany-1. You may not modify the - function names thereby acquired; if you want to do so, first strdup - them. The primary name is returned in *pri_name, and *sec_names is - set either to NULL or to a NULL terminated vector containing - pointers to the secondary names. */ -Int VG_(DebugInfo_syms_howmany) ( const DebugInfo *di ); -void VG_(DebugInfo_syms_getidx) ( const DebugInfo *di, - Int idx, - /*OUT*/Addr* avma, - /*OUT*/Addr* tocptr, - /*OUT*/Addr* local_ep, - /*OUT*/UInt* size, - /*OUT*/HChar** pri_name, - /*OUT*/HChar*** sec_names, - /*OUT*/Bool* isText, - /*OUT*/Bool* isIFunc ); - /* A simple enumeration to describe the 'kind' of various kinds of segments that arise from the mapping of object files. */ typedef -- 2.47.2