]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
[gdb/symtab] Use unrelocated addresses in call_site
authorSimon Marchi <simon.marchi@polymtl.ca>
Mon, 4 Oct 2021 16:16:40 +0000 (18:16 +0200)
committerTom de Vries <tdevries@suse.de>
Mon, 4 Oct 2021 16:16:40 +0000 (18:16 +0200)
Consider test-case gdb.trace/entry-values.exp with target board
unix/-fPIE/-pie.

Using this command we have an abbreviated version, and can see the correct
@entry values for foo:
...
$ gdb -q -batch outputs/gdb.trace/entry-values/entry-values \
  -ex start \
  -ex "break foo" \
  -ex "set print entry-values both" \
  -ex continue
Temporary breakpoint 1 at 0x679

Temporary breakpoint 1, 0x0000555555554679 in main ()
Breakpoint 2 at 0x55555555463e

Breakpoint 2, 0x000055555555463e in foo (i=0, i@entry=2, j=2, j@entry=3)
...

Now, let's try the same again, but run directly to foo rather than stopping at
main:
...
$ gdb -q -batch outputs/gdb.trace/entry-values/entry-values \
  -ex "break foo" \
  -ex "set print entry-values both" \
  -ex run
Breakpoint 1 at 0x63e

Breakpoint 1, 0x000055555555463e in foo (i=0, i@entry=<optimized out>, \
  j=2, j@entry=<optimized out>)
...

So, what explains the difference?  Noteworthy, this is a dwarf assembly
test-case, with debug info for foo and bar, but not for main.

In the first case:
- we run to main
- this does not trigger expanding debug info, because there's none for main
- we set a breakpoint at foo
- this triggers expanding debug info.  Relocated addresses are used in
  call_site info (because the exec is started)
- we continue to foo, and manage to find the call_site info

In the second case:
- we set a breakpoint at foo
- this triggers expanding debug info.  Unrelocated addresses are used in
  call_site info (because the exec is not started)
- we run to foo
- this triggers objfile_relocate1, but it doesn't update the call_site
  info addresses
- we don't manage to find the call_site info

We could fix this by adding the missing call_site relocation in
objfile_relocate1.

This solution however is counter-trend in the sense that we're trying to
work towards the situation where when starting two instances of an executable,
we need only one instance of debug information, implying the use of
unrelocated addresses.

So, fix this instead by using unrelocated addresses in call_site info.

Tested on x86_64-linux.

This fixes all remaining unix/-fno-PIE/-no-pie vs unix/-fPIE/-pie
regressions, like f.i. PR24892.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=24892

Co-Authored-By: Tom de Vries <tdevries@suse.de>
gdb/dwarf2/loc.c
gdb/dwarf2/read.c
gdb/gdbtypes.c
gdb/gdbtypes.h
gdb/symtab.c

index 27a1c97682ae93803f1fa557a9794e8ea7d5bf16..16e0be73d027ca3545ffd9246145fb6b3ec9d1b4 100644 (file)
@@ -713,7 +713,14 @@ call_site_to_target_addr (struct gdbarch *call_site_gdbarch,
       }
 
     case FIELD_LOC_KIND_PHYSADDR:
-      return FIELD_STATIC_PHYSADDR (call_site->target);
+      {
+       dwarf2_per_objfile *per_objfile = call_site->per_objfile;
+       compunit_symtab *cust = per_objfile->get_symtab (call_site->per_cu);
+       int sect_idx = COMPUNIT_BLOCK_LINE_SECTION (cust);
+       CORE_ADDR delta = per_objfile->objfile->section_offsets[sect_idx];
+
+       return FIELD_STATIC_PHYSADDR (call_site->target) + delta;
+      }
 
     default:
       internal_error (__FILE__, __LINE__, _("invalid call site target kind"));
index 230eb6a04b174edc8eb026c431ac8fb818e6e78e..e036b2eac637aef8aa6f00b6ec93185edec5746f 100644 (file)
@@ -13363,6 +13363,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
     }
   pc = attr->as_address () + baseaddr;
   pc = gdbarch_adjust_dwarf2_addr (gdbarch, pc);
+  pc -= baseaddr;
 
   if (cu->call_site_htab == NULL)
     cu->call_site_htab = htab_create_alloc_ex (16, call_site::hash,
@@ -13519,7 +13520,8 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
                       sect_offset_str (die->sect_off), objfile_name (objfile));
          else
            {
-             lowpc = gdbarch_adjust_dwarf2_addr (gdbarch, lowpc + baseaddr);
+             lowpc = (gdbarch_adjust_dwarf2_addr (gdbarch, lowpc + baseaddr)
+                      - baseaddr);
              SET_FIELD_PHYSADDR (call_site->target, lowpc);
            }
        }
index 8954c370b7b7a6e2d1f97ee47ced1e5a03f80de8..853532838a2e24634791bbd91d701e23483f7358 100644 (file)
@@ -6314,7 +6314,10 @@ objfile_type (struct objfile *objfile)
 CORE_ADDR
 call_site::pc () const
 {
-  return m_pc;
+  compunit_symtab *cust = this->per_objfile->get_symtab (this->per_cu);
+  CORE_ADDR delta
+       = this->per_objfile->objfile->section_offsets[COMPUNIT_BLOCK_LINE_SECTION (cust)];
+  return m_unrelocated_pc + delta;
 }
 
 void _initialize_gdbtypes ();
index 5fe10cb7f1e0ec1325c63ec56aa5caeb8becfa0b..4e5b2f1a92f3fe2f318dc63b62e402504a2e49fc 100644 (file)
@@ -1795,19 +1795,19 @@ struct call_site
   {
     call_site (CORE_ADDR pc, dwarf2_per_cu_data *per_cu,
               dwarf2_per_objfile *per_objfile)
-      : per_cu (per_cu), per_objfile (per_objfile), m_pc (pc)
+      : per_cu (per_cu), per_objfile (per_objfile), m_unrelocated_pc (pc)
     {}
 
     static int
     eq (const call_site *a, const call_site *b)
     {
-      return core_addr_eq (&a->m_pc, &b->m_pc);
+      return core_addr_eq (&a->m_unrelocated_pc, &b->m_unrelocated_pc);
     }
 
     static hashval_t
     hash (const call_site *a)
     {
-      return core_addr_hash (&a->m_pc);
+      return core_addr_hash (&a->m_unrelocated_pc);
     }
 
     static int
@@ -1849,8 +1849,8 @@ struct call_site
     dwarf2_per_objfile *const per_objfile = nullptr;
 
   private:
-    /* Address of the first instruction after this call.  */
-    const CORE_ADDR m_pc;
+    /* Unrelocated address of the first instruction after this call.  */
+    const CORE_ADDR m_unrelocated_pc;
 
   public:
     /* * Describe DW_TAG_call_site's DW_TAG_formal_parameter.  */
index cb583846efa4570fa98d5887b66712ee55f5d338..85e6b084551836017398900f161823452f8af78f 100644 (file)
@@ -337,7 +337,11 @@ compunit_symtab::find_call_site (CORE_ADDR pc) const
   if (m_call_site_htab == nullptr)
     return nullptr;
 
-  struct call_site call_site_local (pc, nullptr, nullptr);
+  CORE_ADDR delta
+    = this->objfile->section_offsets[COMPUNIT_BLOCK_LINE_SECTION (this)];
+  CORE_ADDR unrelocated_pc = pc - delta;
+
+  struct call_site call_site_local (unrelocated_pc, nullptr, nullptr);
   void **slot
     = htab_find_slot (m_call_site_htab, &call_site_local, NO_INSERT);
   if (slot == nullptr)