[PATCH][gdb/symtab] Relocate call_site_htab
Tom de Vries
tdevries@suse.de
Thu Sep 30 09:56:10 GMT 2021
[ CC-ing maintainers that reviewed previous submission. ]
Hi,
When running test-case gdb.arch/amd64-entry-value-inline.exp with target board
unix/-no-pie/-fno-PIE we have:
...
(gdb) continue^M
Continuing.^M
^M
Breakpoint 2, fn2 (y=y@entry=25, x=x@entry=6) at \
gdb.arch/amd64-entry-value-inline.c:32^M
32 y = -2 + x; /* break-here */^M
(gdb) PASS: gdb.arch/amd64-entry-value-inline.exp: \
continue to breakpoint: break-here
p y^M
$1 = 25^M
(gdb) PASS: gdb.arch/amd64-entry-value-inline.exp: p y
...
But with target board unix/-pie/-fPIE we have instead:
...
p y^M
$1 = <optimized out>^M
(gdb) FAIL: gdb.arch/amd64-entry-value-inline.exp: p y
...
The test-case uses a .S file, which was generated using gcc 4.8.0, but I can
reproduce the same problem using the original C file and gcc 4.8.5.
The problem is that in order to access the value, call_site information is
accessed, which is both:
- unrelocated, and
- accessed as if it were relocated.
I've submitted an attempt at fixing this before, trying to handle this at all
points where the information is used (
https://sourceware.org/pipermail/gdb-patches/2019-August/159631.html ).
Instead, fix this more reliably by relocating the call_site information.
This fixes for me all remaining regressions for unix/-pie/-fPIE vs
unix/-no-pie/-fno-PIE (not counting ada compilation FAILs).
Tested on x86_64-linux.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=24892
Any comments?
Thanks,
- Tom
[gdb/symtab] Relocate call_site_htab
---
gdb/objfiles.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 58 insertions(+)
diff --git a/gdb/objfiles.c b/gdb/objfiles.c
index b65fa8820ca..ceff0fcfba4 100644
--- a/gdb/objfiles.c
+++ b/gdb/objfiles.c
@@ -626,6 +626,60 @@ relocate_one_symbol (struct symbol *sym, struct objfile *objfile,
}
}
+/* Relocate call_site S using offset DELTA. */
+
+static void
+call_site_relocate (struct call_site *s, CORE_ADDR delta)
+{
+ s->pc += delta;
+ if (FIELD_LOC_KIND (s->target) == FIELD_LOC_KIND_PHYSADDR)
+ FIELD_STATIC_PHYSADDR (s->target) += delta;
+}
+
+/* Relocate HTAB, which is a COMPUNIT_CALL_SITE_HTAB using offset DELTA. */
+
+static void
+compunit_call_site_htab_relocate (htab_t htab, CORE_ADDR delta)
+{
+ /* Changing the pc field changes the hashcode, so we can't just update the
+ elements. Instead, we move them to this var, and then reinsert them. */
+ std::vector<struct call_site *> tmp;
+
+ /* Copy elements to tmp. */
+ auto visitor_func
+ = [] (void **slot, void *info) -> int
+ {
+ /* Copy element to tmp. */
+ struct call_site *s = (struct call_site *) *slot;
+ std::vector<struct call_site *> *tmp_ptr
+ = (std::vector<struct call_site *> *)info;
+ tmp_ptr->push_back (s);
+
+ /* Keep going. */
+ return 1;
+ };
+ htab_traverse (htab, visitor_func, &tmp);
+
+ /* Make hashtable empty. This does not destroy the elements because the
+ hashtable is created with del_f == nullptr. */
+ htab_empty (htab);
+
+ /* Relocate and reinsert elements. */
+ for (struct call_site *s : tmp) {
+ /* Relocate element. */
+ call_site_relocate (s, delta);
+
+ /* Reinsert element. */
+ struct call_site call_site_local;
+ call_site_local.pc = s->pc;
+ void **slot
+ = htab_find_slot (htab, &call_site_local, INSERT);
+ gdb_assert (slot != NULL);
+ gdb_assert (*slot == NULL);
+ *slot = s;
+ }
+}
+
/* Relocate OBJFILE to NEW_OFFSETS. There should be OBJFILE->NUM_SECTIONS
entries in new_offsets. SEPARATE_DEBUG_OBJFILE is not touched here.
Return non-zero iff any change happened. */
@@ -697,6 +751,10 @@ objfile_relocate1 (struct objfile *objfile,
relocate_one_symbol (sym, objfile, delta);
}
}
+
+ if (COMPUNIT_CALL_SITE_HTAB (cust) != nullptr)
+ compunit_call_site_htab_relocate (COMPUNIT_CALL_SITE_HTAB (cust),
+ delta[block_line_section]);
}
}
More information about the Gdb-patches
mailing list