Fix gdb.dwarf2/amd64-entry-value-param.exp with -fPIE/-pie

Message ID 20190809075424.GA15972@delia
State New, archived
Headers

Commit Message

Tom de Vries Aug. 9, 2019, 7:54 a.m. UTC
  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

Jan Kratochvil Aug. 9, 2019, 8:33 a.m. UTC | #1
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 Tromey Aug. 9, 2019, 6:16 p.m. UTC | #2
>>>>> "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
  

Patch

diff --git a/gdb/block.c b/gdb/block.c
index 5c6faa8504..eece1c5171 100644
--- a/gdb/block.c
+++ b/gdb/block.c
@@ -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)
     {
diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
index 63643cb45d..885412f7ef 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -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"));
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index de9755f6ce..a3ae7c93e2 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -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