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 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/m_debuginfo/debuginfo.c b/coregrind/m_debuginfo/debuginfo.c
index 9afbf73..4ad9b7a 100644
--- a/coregrind/m_debuginfo/debuginfo.c
+++ b/coregrind/m_debuginfo/debuginfo.c
@@ -1654,7 +1654,7 @@
{
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 b79587f..21ca438 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 27b7a64..8cb14fb 100644
--- a/coregrind/m_debuginfo/readelf.c
+++ b/coregrind/m_debuginfo/readelf.c
@@ -234,17 +234,12 @@
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 @@
/* 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 @@
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 @@
&& 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 @@
&& *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 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
/* 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 @@
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 @@
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 @@
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 @@
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 @@
" 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 @@
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 @@
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 @@
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 @@
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 @@
" 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 95b665c..8c614e9 100644
--- a/coregrind/m_debuginfo/readmacho.c
+++ b/coregrind/m_debuginfo/readmacho.c
@@ -356,8 +356,9 @@
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 6304d1a..011c1da 100644
--- a/coregrind/m_debuginfo/readpdb.c
+++ b/coregrind/m_debuginfo/readpdb.c
@@ -1264,9 +1264,9 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 705331c..9c35c56 100644
--- a/coregrind/m_debuginfo/storage.c
+++ b/coregrind/m_debuginfo/storage.c
@@ -102,8 +102,8 @@
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 @@
{
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 @@
/* 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 @@
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 @@
}
/* 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 @@
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 @@
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 @@
/* 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 @@
/* 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 @@
/* 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 d95f2d3..255fe79 100644
--- a/coregrind/m_gdbserver/valgrind-low-arm.c
+++ b/coregrind/m_gdbserver/valgrind-low-arm.c
@@ -145,18 +145,17 @@
// 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 de70360..9e6a10c 100644
--- a/coregrind/m_redir.c
+++ b/coregrind/m_redir.c
@@ -397,7 +397,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
* 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 @@
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 5e93793..a455d74 100644
--- a/coregrind/pub_core_debuginfo.h
+++ b/coregrind/pub_core_debuginfo.h
@@ -153,12 +153,60 @@
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 @@
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 9beb512..f47669e 100644
--- a/include/pub_tool_debuginfo.h
+++ b/include/pub_tool_debuginfo.h
@@ -237,25 +237,6 @@
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