Fix gdb.dwarf2/amd64-entry-value-param.exp with -fPIE/-pie
Commit Message
Hi,
When running gdb.dwarf2/amd64-entry-value-param.exp with target board
unix/-fPIE/-pie, we get:
...
FAIL: gdb.arch/amd64-entry-value-param.exp: call 1: p y
...
The problem is that read_call_site_scope attempts to put relocated addresses
in cu->call_site_htab, for both the pc field:
...
baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
...
pc = attr_value_as_address (attr) + baseaddr;
pc = gdbarch_adjust_dwarf2_addr (gdbarch, pc);
...
call_site->pc = pc;
...
and the target field:
...
lowpc = gdbarch_adjust_dwarf2_addr (gdbarch, lowpc + baseaddr);
SET_FIELD_PHYSADDR (call_site->target, lowpc);
...
but fails to do so because it is called before objfile_relocate, making
baseaddr 0.
Fix this by eliminating baseaddr from read_call_site_scope, and handling the
relocation offset at the use sites in call_site_for_pc and
call_site_to_target_addr.
Tested on x86_64-linux, both with and without -fPIE/-pie.
OK for trunk?
Thanks,
- Tom
[gdb] Fix gdb.dwarf2/amd64-entry-value-param.exp with -fPIE/-pie
gdb/ChangeLog:
2019-08-09 Tom de Vries <tdevries@suse.de>
PR gdb/24892
* block.c (call_site_for_pc): Substract relocation offset before
finding pc in COMPUNIT_CALL_SITE_HTAB.
* dwarf2loc.c (call_site_to_target_addr): Add relocation offset to
FIELD_STATIC_PHYSADDR (call_site->target).
* dwarf2read.c (read_call_site_scope): Eliminate baseaddr.
---
gdb/block.c | 17 ++++++++++++++++-
gdb/dwarf2loc.c | 12 +++++++++++-
gdb/dwarf2read.c | 12 +++---------
3 files changed, 30 insertions(+), 11 deletions(-)
Comments
On Fri, 09 Aug 2019 09:54:26 +0200, Tom de Vries wrote:
> Fix this by eliminating baseaddr from read_call_site_scope, and handling the
> relocation offset at the use sites in call_site_for_pc and
> call_site_to_target_addr.
It sure looks correct to me that way, thanks. This is not a commit approval.
Thanks,
Jan Kratochvil
>>>>> "Tom" == Tom de Vries <tdevries@suse.de> writes:
Tom> Fix this by eliminating baseaddr from read_call_site_scope, and handling the
Tom> relocation offset at the use sites in call_site_for_pc and
Tom> call_site_to_target_addr.
I like this approach, since it represents some small progress on the
objfile splitting project.
Tom> + {
Tom> + struct obj_section *sec;
Tom> + sec = find_pc_section (pc);
Tom> + if (sec != NULL)
Tom> + {
Tom> + struct objfile *objfile = sec->objfile;
Tom> + CORE_ADDR baseaddr
Tom> + = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
Why SECT_OFF_TEXT rather than the section "sec"?
Tom> + CORE_ADDR pc_unrelocated
Tom> + = gdbarch_adjust_dwarf2_addr (gdbarch, pc - baseaddr);
I am not sure gdbarch_adjust_dwarf2_addr can be used "bidirectionally"
like this. It is probably fine in practice but I wonder about the
documented contract.
Tom> + CORE_ADDR baseaddr
Tom> + = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
I guess this assumes the text section - but then can the call to
find_pc_section give anything else? Maybe it's just something to
comment and move on.
Tom> - pc = attr_value_as_address (attr) + baseaddr;
Tom> - pc = gdbarch_adjust_dwarf2_addr (gdbarch, pc);
Tom> + pc = attr_value_as_address (attr);
The approach taken elsewhere in dwarf2read.c is to bias, adjust, then
unbias:
CORE_ADDR low
= (gdbarch_adjust_dwarf2_addr (gdbarch, best_lowpc + baseaddr)
- baseaddr);
Maybe this would be better here as well, or at least consistent.
Tom
@@ -226,7 +226,22 @@ call_site_for_pc (struct gdbarch *gdbarch, CORE_ADDR pc)
cust = find_pc_compunit_symtab (pc - 1);
if (cust != NULL && COMPUNIT_CALL_SITE_HTAB (cust) != NULL)
- slot = htab_find_slot (COMPUNIT_CALL_SITE_HTAB (cust), &pc, NO_INSERT);
+ {
+ struct obj_section *sec;
+ sec = find_pc_section (pc);
+ if (sec != NULL)
+ {
+ struct objfile *objfile = sec->objfile;
+ CORE_ADDR baseaddr
+ = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ CORE_ADDR pc_unrelocated
+ = gdbarch_adjust_dwarf2_addr (gdbarch, pc - baseaddr);
+
+ slot = htab_find_slot (COMPUNIT_CALL_SITE_HTAB (cust),
+ &pc_unrelocated, NO_INSERT);
+ }
+ }
+
if (slot == NULL)
{
@@ -855,7 +855,17 @@ call_site_to_target_addr (struct gdbarch *call_site_gdbarch,
}
case FIELD_LOC_KIND_PHYSADDR:
- return FIELD_STATIC_PHYSADDR (call_site->target);
+ {
+ CORE_ADDR addr = FIELD_STATIC_PHYSADDR (call_site->target);
+ struct dwarf2_per_objfile *dwarf2_per_objfile
+ = call_site->per_cu->dwarf2_per_objfile;
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ CORE_ADDR baseaddr
+ = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ addr
+ = gdbarch_adjust_dwarf2_addr (call_site_gdbarch, addr + baseaddr);
+ return addr;
+ }
default:
internal_error (__FILE__, __LINE__, _("invalid call site target kind"));
@@ -13844,15 +13844,13 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
struct gdbarch *gdbarch = get_objfile_arch (objfile);
- CORE_ADDR pc, baseaddr;
+ CORE_ADDR pc;
struct attribute *attr;
struct call_site *call_site, call_site_local;
void **slot;
int nparams;
struct die_info *child_die;
- baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
-
attr = dwarf2_attr (die, DW_AT_call_return_pc, cu);
if (attr == NULL)
{
@@ -13867,8 +13865,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
sect_offset_str (die->sect_off), objfile_name (objfile));
return;
}
- pc = attr_value_as_address (attr) + baseaddr;
- pc = gdbarch_adjust_dwarf2_addr (gdbarch, pc);
+ pc = attr_value_as_address (attr);
if (cu->call_site_htab == NULL)
cu->call_site_htab = htab_create_alloc_ex (16, core_addr_hash, core_addr_eq,
@@ -14019,10 +14016,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
"low pc, for referencing DIE %s [in module %s]"),
sect_offset_str (die->sect_off), objfile_name (objfile));
else
- {
- lowpc = gdbarch_adjust_dwarf2_addr (gdbarch, lowpc + baseaddr);
- SET_FIELD_PHYSADDR (call_site->target, lowpc);
- }
+ SET_FIELD_PHYSADDR (call_site->target, lowpc);
}
}
else