]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
bfd: gas: ld: libsframe: adopt new encoding for FDE func start addr field
authorIndu Bhagat <indu.bhagat@oracle.com>
Mon, 26 May 2025 22:06:31 +0000 (15:06 -0700)
committerIndu Bhagat <indu.bhagat@oracle.com>
Wed, 25 Jun 2025 19:56:19 +0000 (12:56 -0700)
This patch convenes a set of changes in bfd, gas, ld, libsframe towards
moving to the new encoding for the 'sfde_func_start_address' field in
SFrame FDE.

First, gas must now mark all SFrame sections with the new flag
SFRAME_F_FDE_FUNC_START_ADDR_PCREL.  gas was already emitting the field
in the said encoding.

* gas/gen-sframe.c (output_sframe_internal): Emit the flag
SFRAME_F_FDE_FUNC_START_ADDR_PCREL.

Similarly for ld, adopt the new semantics of sfde_func_start_address
consistently.  This means:
  - When merging SFrame sections, check that all input SFrame sections
    have the SFRAME_F_FDE_FUNC_START_ADDR_PCREL flag set.  If the check
    fails, ld errors out.
  - When merging SFrame sections, keep even the in-memory contents of
    the FDE function start address (buffer passed to libsframe
    sframe_encoder_write () for writing out) are encoded in the new
    semantics.  While it is, in theory, possible that instead of doing this
    change here, we adjust the value of sfde_func_start_address at the final
    write (sframe_encoder_write) time.  But latter is not favorable for
    maintenanance and may be generally confusing for developers.
  - When creating SFrame for PLT entries, emit flag
    SFRAME_F_FDE_FUNC_START_ADDR_PCREL.

include/
        * sframe-api.h (SFRAME_F_LD_MUSTHAVE_FLAGS): New definition.
bfd/
* elf-sframe.c (_bfd_elf_merge_section_sframe): Check for flag
combinatation SFRAME_F_LD_MUSTHAVE_FLAGS set for all input and
output SFrame sections.  If not, error out.  Also, adopt the new
        semantics of function start address encoding.
* bfd/elfxx-x86.c (_bfd_x86_elf_create_sframe_plt): Emit flag
SFRAME_F_FDE_FUNC_START_ADDR_PCREL.

Next, for dumping SFrame sections, now that we are emitting the same
encoding in GAS, non-relocatable and relocatable SFrame links, it is the
time to set relocate to TRUE in debug_displays[].

binutils/
* dwarf.c (struct dwarf_section_display): Allow sframe sections
  to now be relocated.
gas/testsuite/
* gas/cfi-sframe/cfi-sframe-aarch64-pac-ab-key-1.d: Update the
test.  Relocatable SFrame sections now display non-zero value
(appropriate function start address).

Now, as the SFrame sections on-disk and in-memory use the new semantics of
sfde_func_start_address encoding (i.e., function start address is the
offset from the sfde_func_start_address field to the start PC), the
calculation to make it human readable (i.e., relatable to the addresses
in .text sections) needs adjustment.

libsframe/
* sframe-dump.c (dump_sframe_func_with_fres): Adjust the
function start address for dumping.

Now that both the emission of the new encoding, and the relocation of
sections before dumping them is in place, it is time to adjust the
testcases.

gas/testsuite/
* gas/cfi-sframe/cfi-sframe-aarch64-1.d: Update expected output
to include SFRAME_F_FDE_FUNC_START_ADDR_PCREL instead of NONE.
* gas/cfi-sframe/cfi-sframe-aarch64-2.d: Likewise.
* gas/cfi-sframe/cfi-sframe-aarch64-3.d: Likewise.
* gas/cfi-sframe/cfi-sframe-aarch64-4.d: Likewise.
* gas/cfi-sframe/cfi-sframe-common-1.d: Likewise.
* gas/cfi-sframe/cfi-sframe-common-10.d: Likewise.
* gas/cfi-sframe/cfi-sframe-common-11.d: Likewise.
* gas/cfi-sframe/cfi-sframe-common-2.d: Likewise.
* gas/cfi-sframe/cfi-sframe-common-3.d: Likewise.
* gas/cfi-sframe/cfi-sframe-common-4.d: Likewise.
* gas/cfi-sframe/cfi-sframe-common-5.d: Likewise.
* gas/cfi-sframe/cfi-sframe-common-6.d: Likewise.
* gas/cfi-sframe/cfi-sframe-common-7.d: Likewise.
* gas/cfi-sframe/cfi-sframe-common-8.d: Likewise.
* gas/cfi-sframe/cfi-sframe-common-9.d: Likewise.
* gas/cfi-sframe/cfi-sframe-x86_64-1.d: Likewise.
* gas/cfi-sframe/cfi-sframe-x86_64-2.d: Likewise.
* gas/cfi-sframe/cfi-sframe-x86_64-empty-1.d: Likewise.
* gas/cfi-sframe/cfi-sframe-x86_64-empty-2.d: Likewise.
* gas/cfi-sframe/cfi-sframe-x86_64-empty-3.d: Likewise.
* gas/cfi-sframe/cfi-sframe-x86_64-empty-4.d: Likewise.
* gas/cfi-sframe/common-empty-1.d: Likewise.
* gas/cfi-sframe/common-empty-2.d: Likewise.
* gas/cfi-sframe/common-empty-3.d: Likewise.
* gas/scfi/x86_64/scfi-cfi-sections-1.d: Likewise.
* gas/scfi/x86_64/scfi-dyn-stack-1.d: Likewise.
ld/testsuite/
* ld-aarch64/sframe-simple-1.d: Update expected output to
include SFRAME_F_FDE_FUNC_START_ADDR_PCREL.
* ld-x86-64/sframe-ibt-plt-1.d: Likewise.
* ld-x86-64/sframe-plt-1.d: Likewise.
* ld-x86-64/sframe-pltgot-1.d: Likewise.
* ld-x86-64/sframe-pltgot-2.d: Likewise.
* ld-x86-64/sframe-simple-1.d: Likewise.

Naturally, the change of semantics for 'SFrame FDE function start address'
has consequences on the implementation in libsframe.  As per the new
semantics:
  - Function start address in the SFrame FDE (sfde_func_start_address)
    is an offset from the FDE function start address field to the start
    PC of the associated function.

Note that, the libsframe library brings the SFrame section contents into
its own memory to create a sframe_decoder_ctx object via sframe_decode
().  Many internal and user-interfacing APIs then use sframe_decoder_ctx
object to interact and fulfill the work.

In context of changing semantics for sfde_func_start_address, following
relevant examples may help understand the impact:
  - sframe_find_fre () finds a the SFrame stack trace data (SFrame FRE)
    given a lookup offset (offset of lookup_pc from the start of SFrame
    section).  Now that the sfde_func_start_address includes the
    distance from the sfde_func_start_address field to the start of
    SFrame section itself, the comparison checks of
    sfde_func_start_address with the incoming lookup offset need
    adjustment.
  - Some internal functions (sframe_get_funcdesc_with_addr_internal ()
    finds SFrame FDE by using binary seach comparing
    sfde_func_start_address fields, etc.) need adjustments.
  - sframe_encoder_write () sorts the SFrame FDEs before writing out
    the SFrame data.  Sorting of SFrame FDE via the internal function
    sframe_sort_funcdesc() needs adjustments: the new encoding of
    sfde_func_start_address means the distances are not from the same
    anchor, so cannot be sorted directly.

This patch takes the approach of adding a new internal function:
  - sframe_decoder_get_secrel_func_start_addr (): This function returns
    the offset of the start PC of the function from the start of SFrame
    section, i.e., it gives a section-relative offset.

As the sframe_decoder_get_secrel_func_start_addr () API needs the value
of the function index in the FDE list, another internal API needs
sframe_fre_check_range_p () adjustments too.

Sorting the FDEs (via sframe_sort_funcdesc ()) is done by first bringing
all offsets in sfde_func_start_address relative to start of SFrame
section, followed by sorting, and then readjusting the offsets accroding
to the new position in the FDE list.

libsframe/
* sframe.c (sframe_decoder_get_secrel_func_start_addr): New
static function.
        (sframe_fre_check_range_p): Adjust the interface a bit.
(sframe_get_funcdesc_with_addr_internal): Use
sframe_decoder_get_secrel_func_start_addr () when comparing
sfde_func_start_address with user input offset.
        (sframe_find_fre): Adopt the new semantics.
        (sframe_sort_funcdesc): Likewise.

For the libsframe testsuite, use the new encoding for FDE func start
addr: distance between the FDE sfde_func_start_address field and the
start PC of the function itself.

Use SFRAME_F_FDE_FUNC_START_ADDR_PCREL flag, though the sframe_encode ()
interface in libsframe applies no sanity checks for the encoding itself.

libsframe/testsuite/
* libsframe.find/findfre-1.c: Adjust to use the new
SFRAME_F_FDE_FUNC_START_ADDR_PCREL specific encoding.
* libsframe.find/findfunc-1.c: Likewise.
* libsframe.find/plt-findfre-1.c: Likewise.
* libsframe/testsuite/libsframe.decode/DATA2: Update data file
due to usage of new SFRAME_F_FDE_FUNC_START_ADDR_PCREL flag.
* libsframe/testsuite/libsframe.encode/encode-1.c: Use flag
SFRAME_F_FDE_FUNC_START_ADDR_PCREL.

---
[Changes in V4]
  - Define new SFRAME_F_LD_MUSTHAVE_FLAGS.  This will be the set of
    flags that must be the same for all input SFrame decoder objects and
    output SFrame encoder object.
  - Use condensed form of check "(dctx_flags ^ ectx_flags) &
    SFRAME_F_LD_MUSTHAVE_FLAGS" to enforce that decoder and encoder
    flags are harmonious.
  - Update commit log to weave in SFRAME_F_LD_MUSTHAVE_FLAGS.
  - Add explicit check in sframe_encode () for the flag
    SFRAME_F_FDE_FUNC_START_ADDR_PCREL to be set.  The write APIs of the
    SFrame encoder object are doing the right thing only for the case
    when SFRAME_F_FDE_FUNC_START_ADDR_PCREL is set.
  - Explicitly set SFRAME_F_FDE_FUNC_START_ADDR_PCREL before call to
    sframe_encode () in _bfd_elf_merge_section_sframe ().
  - Fix encode-1.c testcase to use SFRAME_F_FDE_FUNC_START_ADDR_PCREL
    flag.  This was uncovered due to the changes related to usage of
    SFRAME_F_FDE_FUNC_START_ADDR_PCREL for invocation of and inside
    sframe_encode ().
  - Update code comments on why special handling of SFRAME_F_FDE_SORTED
    before sframe_encode () call in _bfd_elf_merge_section_sframe ().
  - Removed the TBD for libsframe versioning.  The plan is to create a
LIBSFRAME_2.0 {
   global:
     sframe_decoder_get_flags;
     sframe_decoder_get_offsetof_fde_start_addr;
     sframe_encoder_get_flags;
     sframe_encoder_get_offsetof_fde_start_addr;

     ... // list all the APIs.
};
     before the 2.45 release.
[End of changes in V4]

[No changes in V3]
[No changes in V2]

45 files changed:
bfd/elf-sframe.c
bfd/elfxx-x86.c
binutils/dwarf.c
gas/gen-sframe.c
gas/testsuite/gas/cfi-sframe/cfi-sframe-aarch64-1.d
gas/testsuite/gas/cfi-sframe/cfi-sframe-aarch64-2.d
gas/testsuite/gas/cfi-sframe/cfi-sframe-aarch64-3.d
gas/testsuite/gas/cfi-sframe/cfi-sframe-aarch64-4.d
gas/testsuite/gas/cfi-sframe/cfi-sframe-aarch64-pac-ab-key-1.d
gas/testsuite/gas/cfi-sframe/cfi-sframe-common-1.d
gas/testsuite/gas/cfi-sframe/cfi-sframe-common-10.d
gas/testsuite/gas/cfi-sframe/cfi-sframe-common-11.d
gas/testsuite/gas/cfi-sframe/cfi-sframe-common-2.d
gas/testsuite/gas/cfi-sframe/cfi-sframe-common-3.d
gas/testsuite/gas/cfi-sframe/cfi-sframe-common-4.d
gas/testsuite/gas/cfi-sframe/cfi-sframe-common-5.d
gas/testsuite/gas/cfi-sframe/cfi-sframe-common-6.d
gas/testsuite/gas/cfi-sframe/cfi-sframe-common-7.d
gas/testsuite/gas/cfi-sframe/cfi-sframe-common-8.d
gas/testsuite/gas/cfi-sframe/cfi-sframe-common-9.d
gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-1.d
gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-2.d
gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-1.d
gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-2.d
gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-3.d
gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-4.d
gas/testsuite/gas/cfi-sframe/common-empty-1.d
gas/testsuite/gas/cfi-sframe/common-empty-2.d
gas/testsuite/gas/cfi-sframe/common-empty-3.d
gas/testsuite/gas/scfi/x86_64/scfi-cfi-sections-1.d
gas/testsuite/gas/scfi/x86_64/scfi-dyn-stack-1.d
include/sframe-api.h
ld/testsuite/ld-aarch64/sframe-simple-1.d
ld/testsuite/ld-x86-64/sframe-ibt-plt-1.d
ld/testsuite/ld-x86-64/sframe-plt-1.d
ld/testsuite/ld-x86-64/sframe-pltgot-1.d
ld/testsuite/ld-x86-64/sframe-pltgot-2.d
ld/testsuite/ld-x86-64/sframe-simple-1.d
libsframe/sframe-dump.c
libsframe/sframe.c
libsframe/testsuite/libsframe.decode/DATA2
libsframe/testsuite/libsframe.encode/encode-1.c
libsframe/testsuite/libsframe.find/findfre-1.c
libsframe/testsuite/libsframe.find/findfunc-1.c
libsframe/testsuite/libsframe.find/plt-findfre-1.c

index 97e00734515244f46f4f98d3910735769840907d..7a79ff784335fe0150c1593aae7c5936d4469acd 100644 (file)
@@ -328,6 +328,8 @@ _bfd_elf_merge_section_sframe (bfd *abfd,
   int8_t sfd_ctx_fixed_ra_offset;
   uint8_t dctx_version;
   uint8_t ectx_version;
+  uint8_t dctx_flags;
+  uint8_t ectx_flags;
   int encerr = 0;
 
   struct elf_link_hash_table *htab;
@@ -351,6 +353,8 @@ _bfd_elf_merge_section_sframe (bfd *abfd,
   if (sfd_ctx == NULL || sfe_info == NULL)
     return false;
 
+  dctx_flags = sframe_decoder_get_flags (sfd_ctx);
+
   if (htab->sfe_info.sfe_ctx == NULL)
     {
       sfd_ctx_abi_arch = sframe_decoder_get_abi_arch (sfd_ctx);
@@ -361,8 +365,18 @@ _bfd_elf_merge_section_sframe (bfd *abfd,
       if (!sfd_ctx_abi_arch)
        return false;
 
+      /* In-memory FDEs in the encoder object are unsorted during linking and
+        will be sorted before emission.  Reset SFRAME_F_FDE_SORTED to aptly
+        reflect that (doing so has no other functional value at this time
+        though).  */
+      uint8_t tflags = dctx_flags & ~SFRAME_F_FDE_SORTED;
+      /* ld always generates an output section with
+        SFRAME_F_FDE_FUNC_START_ADDR_PCREL flag set.  Later using
+        SFRAME_F_LD_MUSTHAVE_FLAGS, it is enforced that the provided input
+        sections also have this flag set.  */
+      tflags |= SFRAME_F_FDE_FUNC_START_ADDR_PCREL;
       htab->sfe_info.sfe_ctx = sframe_encode (SFRAME_VERSION_2,
-                                             0, /* SFrame flags.  */
+                                             tflags, /* SFrame flags.  */
                                              sfd_ctx_abi_arch,
                                              sfd_ctx_fixed_fp_offset,
                                              sfd_ctx_fixed_ra_offset,
@@ -410,7 +424,15 @@ _bfd_elf_merge_section_sframe (bfd *abfd,
          " .sframe generation"));
       return false;
     }
-
+  /* Check that all SFrame sections being linked have harmonious flags.  */
+  ectx_flags = sframe_encoder_get_flags (sfe_ctx);
+  if ((dctx_flags ^ ectx_flags) & SFRAME_F_LD_MUSTHAVE_FLAGS)
+    {
+      _bfd_error_handler
+       (_("input SFrame sections with different FDE encoding prevent"
+         " .sframe generation"));
+      return false;
+    }
 
   /* Iterate over the function descriptor entries and the FREs of the
      function from the decoder context.  Add each of them to the encoder
@@ -431,6 +453,7 @@ _bfd_elf_merge_section_sframe (bfd *abfd,
       bool pltn_reloc_by_hand = false;
       unsigned int pltn_r_offset = 0;
       uint8_t rep_block_size = 0;
+      uint32_t offsetof_fde_in_sec = 0;
 
       if (!sframe_decoder_get_funcdesc_v2 (sfd_ctx, i, &num_fres, &func_size,
                                           &func_start_addr, &func_info,
@@ -481,6 +504,15 @@ _bfd_elf_merge_section_sframe (bfd *abfd,
                address += sframe_read_value (abfd, contents,
                                              pltn_r_offset, 4);
              address += (sec->output_offset + r_offset);
+             /* SFrame FDE function start address is an offset from the
+                sfde_func_start_address field to the start PC.  The
+                calculation below is the distance of sfde_func_start_address
+                field from the start of the output SFrame section.  */
+             offsetof_fde_in_sec
+               = sframe_encoder_get_offsetof_fde_start_addr (sfe_ctx,
+                                                             cur_fidx + num_enc_fidx,
+                                                             NULL);
+             address -= offsetof_fde_in_sec;
 
              /* FIXME For testing only. Cleanup later.  */
              // address += (sec->output_section->vma);
index bc9bb7010ce061d5ed47c1ed66bb36d3badc4123..d55eecdccebd14e150b02d79de65598f0d9a8c27 100644 (file)
@@ -1891,7 +1891,7 @@ _bfd_x86_elf_create_sframe_plt (bfd *output_bfd,
     }
 
   *ectx = sframe_encode (SFRAME_VERSION_2,
-                        0,
+                        SFRAME_F_FDE_FUNC_START_ADDR_PCREL,
                         SFRAME_ABI_AMD64_ENDIAN_LITTLE,
                         SFRAME_CFA_FIXED_FP_INVALID,
                         -8, /*  Fixed RA offset.  */
index 29fbf541149831dc841427ee8ba9639346559c07..fe51f015901ce02ba0374c429cd8f5c686fc1613 100644 (file)
@@ -12863,7 +12863,7 @@ struct dwarf_section_display debug_displays[] =
   { { ".debug_weaknames",   ".zdebug_weaknames",     "",        NO_ABBREVS },      display_debug_not_supported, NULL,          false },
   { { ".gdb_index",        "",                      "",         NO_ABBREVS },      display_gdb_index,      &do_gdb_index,      false },
   { { ".debug_names",      "",                      "",         NO_ABBREVS },      display_debug_names,    &do_gdb_index,      false },
-  { { ".sframe",           "",                      "",         NO_ABBREVS },      display_sframe,         &do_sframe,         false },
+  { { ".sframe",           "",                      "",         NO_ABBREVS },      display_sframe,         &do_sframe,         true },
   { { ".trace_info",       "",                      "",         ABBREV (trace_abbrev) }, display_trace_info, &do_trace_info,   true },
   { { ".trace_abbrev",     "",                      "",         NO_ABBREVS },      display_debug_abbrev,   &do_trace_abbrevs,  false },
   { { ".trace_aranges",            "",                      "",         NO_ABBREVS },      display_debug_aranges,  &do_trace_aranges,  false },
index 2d1c1961fd7ed32fec46332a2fd8964458b1089a..0137ea600a65be8d42834fde6c6bfd05a1ac6d7d 100644 (file)
@@ -665,6 +665,10 @@ output_sframe_internal (void)
   /* The function descriptor entries as dumped by the assembler are not
      sorted on PCs.  */
   unsigned char sframe_flags = 0;
+  /* Fix PR ld/32666 - Incorrect .rela.sframe when using ld -r.
+     With the fix now in place, we indicate the new encoding with an additional
+     flag in SFrame Version 2.  */
+  sframe_flags |= SFRAME_F_FDE_FUNC_START_ADDR_PCREL;
 
   unsigned int num_fdes = get_num_sframe_fdes ();
   unsigned int num_fres = get_num_sframe_fres ();
index 8ae46217117c6bd0bca905f8be19987cafd34041..194a9fbba5178d3be7591bc0531d69628e917df5 100644 (file)
@@ -6,7 +6,7 @@ Contents of the SFrame section .sframe:
   Header :
 
     Version: SFRAME_VERSION_2
-    Flags: NONE
+    Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
     Num FDEs: 1
     Num FREs: 3
 
index b7834d53b075c138dc90213cabc0c78ec1146ba7..45e64dc424812a44af58c71e190590aeb8f2abcc 100644 (file)
@@ -7,7 +7,7 @@ Contents of the SFrame section .sframe:
   Header :
 
     Version: SFRAME_VERSION_2
-    Flags: NONE
+    Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
     Num FDEs: 1
     Num FREs: 2
 
index f72b70a970ac819602f597968e33a9e274549d98..7a7fa5e29264327de206d198b7f6a936b8101dc9 100644 (file)
@@ -7,7 +7,7 @@ Contents of the SFrame section .sframe:
   Header :
 
     Version: SFRAME_VERSION_2
-    Flags: NONE
+    Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
     Num FDEs: 1
     Num FREs: 2
 
index 51fad9c08932e10938040eeb1fa7223fb3af8382..73433a0a9b917e82806ffe8dced91dffcdc5e2df 100644 (file)
@@ -16,7 +16,7 @@ Contents of the SFrame section .sframe:
   Header :
 
     Version: SFRAME_VERSION_2
-    Flags: NONE
+    Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
     Num FDEs: 0
     Num FREs: 0
 
index 599d4c4e795c8af50018bd03cf0653175379f433..5d676bd312a12a190207d38a342c7e86569830b7 100644 (file)
@@ -7,7 +7,7 @@ Contents of the SFrame section .sframe:
   Header :
 
     Version: SFRAME_VERSION_2
-    Flags: NONE
+    Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
     Num FDEs: 2
     Num FREs: 6
 
@@ -18,10 +18,10 @@ Contents of the SFrame section .sframe:
     0+0004 +sp\+0 +u +u\[s\] +
     0+0008 +sp\+16 +c-16 +c-8\[s\] +
 
-    func idx \[1\]: pc = 0x0, size = 20 bytes, pauth = B key
+    func idx \[1\]: pc = 0xc, size = 20 bytes, pauth = B key
     STARTPC + CFA + FP +  RA +
-    0+0000 +sp\+0 +u +u +
-    0+0004 +sp\+0 +u +u\[s\] +
-    0+0008 +sp\+16 +c-16 +c-8\[s\] +
+    0+000c +sp\+0 +u +u +
+    0+0010 +sp\+0 +u +u\[s\] +
+    0+0014 +sp\+16 +c-16 +c-8\[s\] +
 
 #pass
index 5f4ae00747deefdce2f69490e9672fc3275ef1be..676641fa574e8b128ce6887796a211b3168e5338 100644 (file)
@@ -7,7 +7,7 @@ Contents of the SFrame section .sframe:
   Header :
 
     Version: SFRAME_VERSION_2
-    Flags: NONE
+    Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
 #?    CFA fixed FP offset: \-?\d+
 #?    CFA fixed RA offset: \-?\d+
     Num FDEs: 1
index 106e05d160b6fc9efb3e8992757942fd1907f951..737ceba1aa1bc4872ffe568273489ac634fd5102 100644 (file)
@@ -7,7 +7,7 @@ Contents of the SFrame section .sframe:
   Header :
 
     Version: SFRAME_VERSION_2
-    Flags: NONE
+    Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
 #?    CFA fixed FP offset: \-?\d+
 #?    CFA fixed RA offset: \-?\d+
     Num FDEs: 1
index 258481501350948f010536f6b720bd9dd73c9ca8..bca05d4d19160c025a4016deb6ea1f24091fd78d 100644 (file)
@@ -7,7 +7,7 @@ Contents of the SFrame section .sframe:
   Header :
 
     Version: SFRAME_VERSION_2
-    Flags: NONE
+    Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
 #?    CFA fixed FP offset: \-?\d+
 #?    CFA fixed RA offset: \-?\d+
     Num FDEs: 1
index ded8c450a94281d9a5638256be8d4187510cef06..bf142e1fe32c6c92924f95245e273f58544bdd90 100644 (file)
@@ -7,7 +7,7 @@ Contents of the SFrame section .sframe:
   Header :
 
     Version: SFRAME_VERSION_2
-    Flags: NONE
+    Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
 #?    CFA fixed FP offset: \-?\d+
 #?    CFA fixed RA offset: \-?\d+
     Num FDEs: 1
index d23fd9790f631197ea2c2c9af86bef922b2e5172..d69fc3758fe9a4858680c6e2a6d02cf3c83ddcd6 100644 (file)
@@ -7,7 +7,7 @@ Contents of the SFrame section .sframe:
   Header :
 
     Version: SFRAME_VERSION_2
-    Flags: NONE
+    Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
 #?    CFA fixed FP offset: \-?\d+
 #?    CFA fixed RA offset: \-?\d+
     Num FDEs: 1
index 8632613f532f52cfd0bc657784d5648a9b910988..7be3cafb259c38aa010836f5ff73ac262ff1ff70 100644 (file)
@@ -7,7 +7,7 @@ Contents of the SFrame section .sframe:
   Header :
 
     Version: SFRAME_VERSION_2
-    Flags: NONE
+    Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
 #?    CFA fixed FP offset: \-?\d+
 #?    CFA fixed RA offset: \-?\d+
     Num FDEs: 1
index dd2c32d3d9fcc491ccb675cb52063123dbf293cf..b3fe0c15499eae89577e1c87ce940bdf32064898 100644 (file)
@@ -7,7 +7,7 @@ Contents of the SFrame section .sframe:
   Header :
 
     Version: SFRAME_VERSION_2
-    Flags: NONE
+    Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
 #?    CFA fixed FP offset: \-?\d+
 #?    CFA fixed RA offset: \-?\d+
     Num FDEs: 1
index 34390c46a0743f8c2f9a710d9097ffb79c34097b..30824b05eea2279af058d88291dd9565f8faa7aa 100644 (file)
@@ -7,7 +7,7 @@ Contents of the SFrame section .sframe:
   Header :
 
     Version: SFRAME_VERSION_2
-    Flags: NONE
+    Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
 #?    CFA fixed FP offset: \-?\d+
 #?    CFA fixed RA offset: \-?\d+
     Num FDEs: 1
index 61efb9c4ed129221486d35b2b69f74bf735b7717..bac4d46d30a1b1b364d1bae8a70340698de76d8a 100644 (file)
@@ -7,7 +7,7 @@ Contents of the SFrame section .sframe:
   Header :
 
     Version: SFRAME_VERSION_2
-    Flags: NONE
+    Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
 #?    CFA fixed FP offset: \-?\d+
 #?    CFA fixed RA offset: \-?\d+
     Num FDEs: 1
index d77645636b36aee3382e2cfe42d7ff6a14ba6617..ec3afb6f6bd02d06d6640328508074fb46add6e9 100644 (file)
@@ -7,7 +7,7 @@ Contents of the SFrame section .sframe:
   Header :
 
     Version: SFRAME_VERSION_2
-    Flags: NONE
+    Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
 #?    CFA fixed FP offset: \-?\d+
 #?    CFA fixed RA offset: \-?\d+
     Num FDEs: 1
index 80c9235707325c244136bab9006be2260316f0fb..877dfafaae92535a40b60c2016ba6aec77e4935d 100644 (file)
@@ -7,7 +7,7 @@ Contents of the SFrame section .sframe:
   Header :
 
     Version: SFRAME_VERSION_2
-    Flags: NONE
+    Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
 #?    CFA fixed FP offset: \-?\d+
 #?    CFA fixed RA offset: \-?\d+
     Num FDEs: 1
index 88b4cc63dbaa00d39e17910ec2a6f36bc1b75127..3d8e93619d1b5a28c5f73173b589c5b2d0a2f779 100644 (file)
@@ -7,7 +7,7 @@ Contents of the SFrame section .sframe:
   Header :
 
     Version: SFRAME_VERSION_2
-    Flags: NONE
+    Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
     CFA fixed RA offset: \-8
     Num FDEs: 1
     Num FREs: 4
index d779b6d126ec5ad9ce3d95d18c1aba04ac67e208..44210368e04dde581241b673348f96fbac8273f6 100644 (file)
@@ -7,7 +7,7 @@ Contents of the SFrame section .sframe:
   Header :
 
     Version: SFRAME_VERSION_2
-    Flags: NONE
+    Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
 #?    CFA fixed FP offset: \-?\d+
 #?    CFA fixed RA offset: \-?\d+
     Num FDEs: 1
index 0bae4b95b31da7fcdc1f4c97ecae4db8b5944c8f..1cf47aae36583b21f5d0cf18deafdc25f02ca79d 100644 (file)
@@ -8,7 +8,7 @@ Contents of the SFrame section .sframe:
   Header :
 
     Version: SFRAME_VERSION_2
-    Flags: NONE
+    Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
 #?    CFA fixed FP offset: \-?\d+
 #?    CFA fixed RA offset: \-?\d+
     Num FDEs: 0
index f1ba0443273e338ccc9ee4faffc889dfa2506afb..24b7e2ae0b5c5603db91f206e7252eee1b421a17 100644 (file)
@@ -8,7 +8,7 @@ Contents of the SFrame section .sframe:
   Header :
 
     Version: SFRAME_VERSION_2
-    Flags: NONE
+    Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
 #?    CFA fixed FP offset: \-?\d+
 #?    CFA fixed RA offset: \-?\d+
     Num FDEs: 0
index c8fc7a43dd4f89e2ae3797d89cf8bd4233da7e82..4ad3efbb1e12469eaaf3a04f4d59723a2c9cc6df 100644 (file)
@@ -8,7 +8,7 @@ Contents of the SFrame section .sframe:
   Header :
 
     Version: SFRAME_VERSION_2
-    Flags: NONE
+    Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
 #?    CFA fixed FP offset: \-?\d+
 #?    CFA fixed RA offset: \-?\d+
     Num FDEs: 0
index 43f09e09d27f421278f474293d68c8a0f49b8f37..2e746147b24c2aafdbbeed7a3de4dd5a6af7b978 100644 (file)
@@ -8,7 +8,7 @@ Contents of the SFrame section .sframe:
   Header :
 
     Version: SFRAME_VERSION_2
-    Flags: NONE
+    Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
 #?    CFA fixed FP offset: \-?\d+
 #?    CFA fixed RA offset: \-?\d+
     Num FDEs: 0
index 736aea87505525d1131611e9f37a7324f266dea5..ee351b058236ea32ac9439cd13f1f24a898cebd2 100644 (file)
@@ -8,7 +8,7 @@ Contents of the SFrame section .sframe:
   Header :
 
     Version: SFRAME_VERSION_2
-    Flags: NONE
+    Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
 #?    CFA fixed FP offset: \-?\d+
 #?    CFA fixed RA offset: \-?\d+
     Num FDEs: 0
index 163b504a687337a3eae5299db8a17495bb45521c..f268bcf0d76e71e89fcaa9dc277201ac6aaad23c 100644 (file)
@@ -8,7 +8,7 @@ Contents of the SFrame section .sframe:
   Header :
 
     Version: SFRAME_VERSION_2
-    Flags: NONE
+    Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
 #?    CFA fixed FP offset: \-?\d+
 #?    CFA fixed RA offset: \-?\d+
     Num FDEs: 0
index 39caad5a1d45b5899552badf1c30482bdf5700c1..c4a0fd85dd24b8642b3c85516b519d49e426c4dd 100644 (file)
@@ -8,7 +8,7 @@ Contents of the SFrame section .sframe:
   Header :
 
     Version: SFRAME_VERSION_2
-    Flags: NONE
+    Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
 #?    CFA fixed FP offset: \-?\d+
 #?    CFA fixed RA offset: \-?\d+
     Num FDEs: 0
index 7c247e33a6e80a49858c7d518808b8e20d45ef13..b81ee062733237eb7e141b16e37dab98fe370b8b 100644 (file)
@@ -7,7 +7,7 @@ Contents of the SFrame section .sframe:
   Header :
 
     Version: SFRAME_VERSION_2
-    Flags: NONE
+    Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
     CFA fixed RA offset: \-8
     Num FDEs: 1
     Num FREs: 5
index c6a9b53f4e09f02f883f64f4167a9c28bc46d7a8..44796668f10951e3d52b24e99639d1daa2472a09 100644 (file)
@@ -8,7 +8,7 @@ Contents of the SFrame section .sframe:
   Header :
 
     Version: SFRAME_VERSION_2
-    Flags: NONE
+    Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
     CFA fixed RA offset: \-8
     Num FDEs: 1
     Num FREs: 4
index 0dfdd289b82f1680f74f704dd2800bc782a5ae05..1e21dfab1a08c8379087de11ae3ce5b9cf94c87b 100644 (file)
@@ -44,6 +44,11 @@ typedef struct sframe_encoder_ctx sframe_encoder_ctx;
   (SFRAME_F_FDE_SORTED | SFRAME_F_FRAME_POINTER \
    | SFRAME_F_FDE_FUNC_START_ADDR_PCREL)
 
+/* Set of flags that are required to be harmonious between all decoder and
+   encoder objects participating in a link.  */
+#define SFRAME_F_LD_MUSTHAVE_FLAGS \
+  (SFRAME_F_FDE_FUNC_START_ADDR_PCREL)
+
 /* User interfacing SFrame Row Entry.
    An abstraction provided by libsframe so the consumer is decoupled from
    the binary format representation of the same.
index 6ab8c2ab46ac47c1f7eb87e50d59632dca496028..27c8a330c59a8b5d7aaefc6ac35b97083e8391f6 100644 (file)
@@ -11,7 +11,8 @@ Contents of the SFrame section .sframe:
   Header :
 
     Version: SFRAME_VERSION_2
-    Flags: SFRAME_F_FDE_SORTED
+    Flags: SFRAME_F_FDE_SORTED,
+           SFRAME_F_FDE_FUNC_START_ADDR_PCREL
     Num FDEs: 2
     Num FREs: 2
 
index f8682421245bc6c260b6de2b192bb2e2a7787a37..8a767aca685c9d0b1e99e08249f165344d07fdc6 100644 (file)
@@ -10,7 +10,8 @@ Contents of the SFrame section .sframe:
   Header :
 
     Version: SFRAME_VERSION_2
-    Flags: SFRAME_F_FDE_SORTED
+    Flags: SFRAME_F_FDE_SORTED,
+           SFRAME_F_FDE_FUNC_START_ADDR_PCREL
     CFA fixed RA offset: \-8
 #...
 
index 2918ccba1ebcc2df306429ca69d795395fa88195..916bf96aacb79de1e96f6223de350043c4c0e076 100644 (file)
@@ -11,7 +11,8 @@ Contents of the SFrame section .sframe:
   Header :
 
     Version: SFRAME_VERSION_2
-    Flags: SFRAME_F_FDE_SORTED
+    Flags: SFRAME_F_FDE_SORTED,
+           SFRAME_F_FDE_FUNC_START_ADDR_PCREL
     CFA fixed RA offset: \-8
 #...
 
index 6c47770c2b59cc865fdb7de2fb52d9b1309cf762..3193107cdf4c7e1c175a8749fd5eba8f0d0ba484 100644 (file)
@@ -10,7 +10,8 @@ Contents of the SFrame section .sframe:
   Header :
 
     Version: SFRAME_VERSION_2
-    Flags: SFRAME_F_FDE_SORTED
+    Flags: SFRAME_F_FDE_SORTED,
+           SFRAME_F_FDE_FUNC_START_ADDR_PCREL
     CFA fixed RA offset: \-8
 #...
 
index 141be2922302e68af44846b4cbc5cc56ba8f5b75..4a97389f2ebb4e09647024374c4c0e2b4d82ca26 100644 (file)
@@ -10,7 +10,8 @@ Contents of the SFrame section .sframe:
   Header :
 
     Version: SFRAME_VERSION_2
-    Flags: SFRAME_F_FDE_SORTED
+    Flags: SFRAME_F_FDE_SORTED,
+           SFRAME_F_FDE_FUNC_START_ADDR_PCREL
     CFA fixed RA offset: \-8
 #...
 
index 3effdbf05290d96c4dd378c12b40a2ea89587d6c..f2a1ef7fbd8c04afce77627497c349e37e98da1a 100644 (file)
@@ -11,7 +11,8 @@ Contents of the SFrame section .sframe:
   Header :
 
     Version: SFRAME_VERSION_2
-    Flags: SFRAME_F_FDE_SORTED
+    Flags: SFRAME_F_FDE_SORTED,
+           SFRAME_F_FDE_FUNC_START_ADDR_PCREL
     CFA fixed RA offset: \-8
 #...
 
index bc0d5e46b039e6ff622575dcca5adcd6de5ac9e3..9048931a8ba4f778c14ee92b3ead846dc8c83330 100644 (file)
@@ -133,8 +133,15 @@ dump_sframe_func_with_fres (sframe_decoder_ctx *sfd_ctx,
   /* Get the SFrame function descriptor.  */
   sframe_decoder_get_funcdesc (sfd_ctx, funcidx, &num_fres,
                               &func_size, &func_start_address, &func_info);
-  /* Calculate the virtual memory address for function start pc.  */
+/* Calculate the virtual memory address for function start pc.  Some older
+   SFrame V2 sections in ET_DYN or ET_EXEC may still have the
+   SFRAME_F_FDE_FUNC_START_ADDR_PCREL flag unset, and hence may be using the
+   old encoding.  Continue to support dumping the sections at least.  */
   func_start_pc_vma = func_start_address + sec_addr;
+  if (sframe_decoder_get_flags (sfd_ctx) & SFRAME_F_FDE_FUNC_START_ADDR_PCREL)
+    func_start_pc_vma += sframe_decoder_get_offsetof_fde_start_addr (sfd_ctx,
+                                                                    funcidx,
+                                                                    NULL);
 
   /* Mark FDEs with [m] where the FRE start address is interpreted as a
      mask.  */
index 8be7bec8917170caecbbbbee66779f11a1299eec..946b3cf16b38315070331f5075f79c99e8809e35 100644 (file)
@@ -363,25 +363,47 @@ sframe_decoder_get_funcdesc_at_index (sframe_decoder_ctx *ctx,
   return fdep;
 }
 
+/* Get the offset of the start PC of the SFrame FDE at FUNC_IDX from the start
+   of the SFrame section.  This section-relative offset is used within
+   libsframe for sorting the SFrame FDEs, and also information lookup routines
+   like sframe_find_fre.
+
+   If FUNC_IDX is not a valid index in the given decoder object, returns 0.  */
+
+static int32_t
+sframe_decoder_get_secrel_func_start_addr (sframe_decoder_ctx *dctx,
+                                          uint32_t func_idx)
+{
+  int err = 0;
+  int32_t offsetof_fde_in_sec
+    = sframe_decoder_get_offsetof_fde_start_addr (dctx, func_idx, &err);
+  /* If func_idx is not a valid index, return 0.  */
+  if (err)
+    return 0;
+
+  int32_t func_start_addr = dctx->sfd_funcdesc[func_idx].sfde_func_start_address;
+
+  return func_start_addr + offsetof_fde_in_sec;
+}
+
 /* Check whether for the given FDEP, the SFrame Frame Row Entry identified via
    the START_IP_OFFSET and the END_IP_OFFSET, provides the stack trace
    information for the PC.  */
 
 static bool
-sframe_fre_check_range_p (sframe_func_desc_entry *fdep,
+sframe_fre_check_range_p (sframe_decoder_ctx *dctx, uint32_t func_idx,
                          uint32_t start_ip_offset, uint32_t end_ip_offset,
                          int32_t pc)
 {
+  sframe_func_desc_entry *fdep;
   int32_t func_start_addr;
   uint8_t rep_block_size;
   uint32_t fde_type;
   uint32_t pc_offset;
   bool mask_p;
 
-  if (!fdep)
-    return false;
-
-  func_start_addr = fdep->sfde_func_start_address;
+  fdep = &dctx->sfd_funcdesc[func_idx];
+  func_start_addr = sframe_decoder_get_secrel_func_start_addr (dctx, func_idx);
   fde_type = sframe_get_fde_type (fdep);
   mask_p = (fde_type == SFRAME_FDE_TYPE_PCMASK);
   rep_block_size = fdep->sfde_func_rep_size;
@@ -1055,7 +1077,7 @@ sframe_get_funcdesc_with_addr (sframe_decoder_ctx *ctx __attribute__ ((unused)),
 
 static sframe_func_desc_entry *
 sframe_get_funcdesc_with_addr_internal (sframe_decoder_ctx *ctx, int32_t addr,
-                                       int *errp)
+                                       int *errp, uint32_t *func_idx)
 {
   sframe_header *dhp;
   sframe_func_desc_entry *fdp;
@@ -1083,12 +1105,15 @@ sframe_get_funcdesc_with_addr_internal (sframe_decoder_ctx *ctx, int32_t addr,
 
       /* Given sfde_func_start_address <= addr,
         addr - sfde_func_start_address must be positive.  */
-      if (fdp[mid].sfde_func_start_address <= addr
-         && ((uint32_t)(addr - fdp[mid].sfde_func_start_address)
+      if (sframe_decoder_get_secrel_func_start_addr (ctx, mid) <= addr
+         && ((uint32_t)(addr - sframe_decoder_get_secrel_func_start_addr (ctx, mid))
              < fdp[mid].sfde_func_size))
-       return fdp + mid;
+       {
+         *func_idx = mid;
+         return fdp + mid;
+       }
 
-      if (fdp[mid].sfde_func_start_address < addr)
+      if (sframe_decoder_get_secrel_func_start_addr (ctx, mid) < addr)
        low = mid + 1;
       else
        high = mid - 1;
@@ -1132,6 +1157,7 @@ sframe_find_fre (sframe_decoder_ctx *ctx, int32_t pc,
 {
   sframe_frame_row_entry cur_fre;
   sframe_func_desc_entry *fdep;
+  uint32_t func_idx;
   uint32_t fre_type, i;
   int32_t func_start_addr;
   uint32_t start_ip_offset, end_ip_offset;
@@ -1143,14 +1169,14 @@ sframe_find_fre (sframe_decoder_ctx *ctx, int32_t pc,
     return sframe_set_errno (&err, SFRAME_ERR_INVAL);
 
   /* Find the FDE which contains the PC, then scan its fre entries.  */
-  fdep = sframe_get_funcdesc_with_addr_internal (ctx, pc, &err);
+  fdep = sframe_get_funcdesc_with_addr_internal (ctx, pc, &err, &func_idx);
   if (fdep == NULL || ctx->sfd_fres == NULL)
     return sframe_set_errno (&err, SFRAME_ERR_DCTX_INVAL);
 
   fre_type = sframe_get_fre_type (fdep);
 
   fres = ctx->sfd_fres + fdep->sfde_func_start_fre_off;
-  func_start_addr = fdep->sfde_func_start_address;
+  func_start_addr = sframe_decoder_get_secrel_func_start_addr (ctx, func_idx);
 
   for (i = 0; i < fdep->sfde_func_num_fres; i++)
    {
@@ -1166,7 +1192,7 @@ sframe_find_fre (sframe_decoder_ctx *ctx, int32_t pc,
      if (start_ip_offset > (uint32_t)(pc - func_start_addr))
        return sframe_set_errno (&err, SFRAME_ERR_FRE_INVAL);
 
-     if (sframe_fre_check_range_p (fdep, start_ip_offset, end_ip_offset, pc))
+     if (sframe_fre_check_range_p (ctx, func_idx, start_ip_offset, end_ip_offset, pc))
        {
         sframe_frame_row_entry_copy (frep, &cur_fre);
         return 0;
@@ -1362,6 +1388,12 @@ sframe_encode (uint8_t ver, uint8_t flags, uint8_t abi_arch,
   hp->sfh_preamble.sfp_magic = SFRAME_MAGIC;
   hp->sfh_preamble.sfp_flags = flags;
 
+  /* Implementation in the SFrame encoder APIs, e.g.,
+     sframe_encoder_write_sframe assume flag SFRAME_F_FDE_FUNC_START_ADDR_PCREL
+     set.  */
+  if (!(flags & SFRAME_F_FDE_FUNC_START_ADDR_PCREL))
+   return sframe_ret_set_errno (errp, SFRAME_ERR_ECTX_INVAL);
+
   hp->sfh_abi_arch = abi_arch;
   hp->sfh_cfa_fixed_fp_offset = fixed_fp_offset;
   hp->sfh_cfa_fixed_ra_offset = fixed_ra_offset;
@@ -1691,15 +1723,23 @@ sframe_encoder_add_funcdesc_v2 (sframe_encoder_ctx *encoder,
 static int
 sframe_sort_funcdesc (sframe_encoder_ctx *encoder)
 {
-  sframe_header *ehp;
+  sframe_header *ehp = sframe_encoder_get_header (encoder);
 
-  ehp = sframe_encoder_get_header (encoder);
   /* Sort and write out the FDE table.  */
   sf_fde_tbl *fd_info = encoder->sfe_funcdesc;
   if (fd_info)
     {
+      for (unsigned int i = 0; i < fd_info->count; i++)
+       fd_info->entry[i].sfde_func_start_address
+         += sframe_encoder_get_offsetof_fde_start_addr (encoder, i, NULL);
+
       qsort (fd_info->entry, fd_info->count,
             sizeof (sframe_func_desc_entry), fde_func);
+
+      for (unsigned int i = 0; i < fd_info->count; i++)
+       fd_info->entry[i].sfde_func_start_address
+         -= sframe_encoder_get_offsetof_fde_start_addr (encoder, i, NULL);
+
       /* Update preamble's flags.  */
       ehp->sfh_preamble.sfp_flags |= SFRAME_F_FDE_SORTED;
     }
index 472f736f872a0bb23b8f075a2b6da8d3aeaabbcd..90649e2716947e16bd51f42d8cb58ab75a69fd4f 100644 (file)
Binary files a/libsframe/testsuite/libsframe.decode/DATA2 and b/libsframe/testsuite/libsframe.decode/DATA2 differ
index 3c2df7619b8f7e148ca418add86fc216808ebb4e..ffc332d2d25b2c09e361e338eefd13443bcb12ac 100644 (file)
@@ -41,7 +41,7 @@ add_fde1 (sframe_encoder_ctx *encode, int idx)
 
   unsigned char finfo = sframe_fde_create_func_info (SFRAME_FRE_TYPE_ADDR1,
                                                     SFRAME_FDE_TYPE_PCINC);
-  err = sframe_encoder_add_funcdesc (encode, 0xfffff03e, 0x1b, finfo, 4);
+  err = sframe_encoder_add_funcdesc (encode, 0xfffff022, 0x1b, finfo, 4);
   if (err == -1)
     return err;
 
@@ -66,7 +66,7 @@ add_fde2 (sframe_encoder_ctx *encode, int idx)
 
   unsigned char finfo = sframe_fde_create_func_info (SFRAME_FRE_TYPE_ADDR1,
                                                     SFRAME_FDE_TYPE_PCINC);
-  err = sframe_encoder_add_funcdesc (encode, 0xfffff059, 0x10, finfo, 4);
+  err = sframe_encoder_add_funcdesc (encode, 0xfffff029, 0x10, finfo, 4);
   if (err == -1)
     return err;
 
@@ -145,7 +145,8 @@ int main (void)
     }                                                                         \
     while (0)
 
-  encode = sframe_encode (SFRAME_VERSION, 0,
+  encode = sframe_encode (SFRAME_VERSION,
+                         SFRAME_F_FDE_FUNC_START_ADDR_PCREL,
                          SFRAME_ABI_AMD64_ENDIAN_LITTLE,
                          SFRAME_CFA_FIXED_FP_INVALID,
                          -8, /* Fixed RA offset for AMD64.  */
index 94fe2e9493ff93a0324e1f02c564d3e05c3d45df..b2ab045ae7ea6787d8ee4ee1a47e20554aef8584 100644 (file)
@@ -43,7 +43,10 @@ add_fde1 (sframe_encoder_ctx *encode, uint32_t start_pc_vaddr,
     fre_start_addr of the last FRE above (0x38).  */
   *func_size = 0x40;
 
-  int32_t func1_start_addr = start_pc_vaddr - sframe_vaddr;
+  uint32_t offsetof_fde_in_sec
+    = sframe_encoder_get_offsetof_fde_start_addr (encode, idx, NULL);
+  int32_t func1_start_addr = (start_pc_vaddr
+                             - (sframe_vaddr + offsetof_fde_in_sec));
   unsigned char finfo = sframe_fde_create_func_info (SFRAME_FRE_TYPE_ADDR1,
                                                     SFRAME_FDE_TYPE_PCINC);
   int err = sframe_encoder_add_funcdesc (encode, func1_start_addr, *func_size,
@@ -74,7 +77,10 @@ add_fde2 (sframe_encoder_ctx *encode, uint32_t start_pc_vaddr,
     fre_start_addr of the last FRE above (0x20).  */
   *func_size = 0x60;
 
-  int32_t func2_start_addr = start_pc_vaddr - sframe_vaddr;
+  uint32_t offsetof_fde_in_sec
+    = sframe_encoder_get_offsetof_fde_start_addr (encode, idx, NULL);
+  int32_t func2_start_addr = (start_pc_vaddr
+                             - (sframe_vaddr + offsetof_fde_in_sec));
   unsigned char finfo = sframe_fde_create_func_info (SFRAME_FRE_TYPE_ADDR1,
                                                     SFRAME_FDE_TYPE_PCINC);
   int err = sframe_encoder_add_funcdesc (encode, func2_start_addr, *func_size,
@@ -115,7 +121,8 @@ void test_text_findfre (uint32_t text_vaddr, uint32_t sframe_vaddr)
     }                                                                         \
     while (0)
 
-  encode = sframe_encode (SFRAME_VERSION, 0,
+  encode = sframe_encode (SFRAME_VERSION,
+                         SFRAME_F_FDE_FUNC_START_ADDR_PCREL,
                          SFRAME_ABI_AMD64_ENDIAN_LITTLE,
                          SFRAME_CFA_FIXED_FP_INVALID,
                          -8, /* Fixed RA offset for AMD64.  */
index 3cdcdb6631ec495a65cc602cd863ec91b374673a..f9b92c18333c6c40eb44c6f2603e250655bb4839 100644 (file)
@@ -50,7 +50,10 @@ add_fde1 (sframe_encoder_ctx *encode, uint32_t start_pc_vaddr,
     fre_start_addr of the last FRE above (0x38).  */
   *func_size = 0x40;
 
-  int32_t func1_start_addr = start_pc_vaddr - sframe_vaddr;
+  uint32_t offsetof_fde_in_sec
+    = sframe_encoder_get_offsetof_fde_start_addr (encode, idx, NULL);
+  int32_t func1_start_addr = (start_pc_vaddr
+                             - (sframe_vaddr + offsetof_fde_in_sec));
   unsigned char finfo = sframe_fde_create_func_info (SFRAME_FRE_TYPE_ADDR1,
                                                     SFRAME_FDE_TYPE_PCINC);
   int err = sframe_encoder_add_funcdesc (encode, func1_start_addr, *func_size,
@@ -81,7 +84,10 @@ add_fde2 (sframe_encoder_ctx *encode, uint32_t start_pc_vaddr,
     fre_start_addr of the last FRE above (0x20).  */
   *func_size = 0x60;
 
-  int32_t func2_start_addr = start_pc_vaddr - sframe_vaddr;
+  uint32_t offsetof_fde_in_sec
+    = sframe_encoder_get_offsetof_fde_start_addr (encode, idx, NULL);
+  int32_t func2_start_addr = (start_pc_vaddr
+                             - (sframe_vaddr + offsetof_fde_in_sec));
   unsigned char finfo = sframe_fde_create_func_info (SFRAME_FRE_TYPE_ADDR1,
                                                     SFRAME_FDE_TYPE_PCINC);
   int err = sframe_encoder_add_funcdesc (encode, func2_start_addr, *func_size,
@@ -112,7 +118,10 @@ add_fde3 (sframe_encoder_ctx *encode, uint32_t start_pc_vaddr,
     fre_start_addr of the last FRE above (0x38).  */
   *func_size = 0x40;
 
-  int32_t func3_start_addr = start_pc_vaddr - sframe_vaddr;
+  uint32_t offsetof_fde_in_sec
+    = sframe_encoder_get_offsetof_fde_start_addr (encode, idx, NULL);
+  int32_t func3_start_addr = (start_pc_vaddr
+                             - (sframe_vaddr + offsetof_fde_in_sec));
   unsigned char finfo = sframe_fde_create_func_info (SFRAME_FRE_TYPE_ADDR1,
                                                     SFRAME_FDE_TYPE_PCINC);
   int err = sframe_encoder_add_funcdesc (encode, func3_start_addr, *func_size,
@@ -155,7 +164,8 @@ void test_text_findfre (uint32_t text_vaddr, uint32_t sframe_vaddr)
     }                                                                         \
     while (0)
 
-  encode = sframe_encode (SFRAME_VERSION, 0,
+  encode = sframe_encode (SFRAME_VERSION,
+                         SFRAME_F_FDE_FUNC_START_ADDR_PCREL,
                          SFRAME_ABI_AMD64_ENDIAN_LITTLE,
                          SFRAME_CFA_FIXED_FP_INVALID,
                          -8, /* Fixed RA offset for AMD64.  */
index 89ca4661922ea8d76340f19e420c6ec4c203ecae..710cc6d8352f28917be7ac8a30ca974dd76b70c1 100644 (file)
@@ -42,7 +42,10 @@ add_plt_fde1 (sframe_encoder_ctx *ectx, uint32_t plt_vaddr,
 
   unsigned char finfo = sframe_fde_create_func_info (SFRAME_FRE_TYPE_ADDR1,
                                                     SFRAME_FDE_TYPE_PCMASK);
-  int32_t func_start_addr = plt_vaddr - sframe_vaddr;
+  uint32_t offsetof_fde_in_sec
+    = sframe_encoder_get_offsetof_fde_start_addr (ectx, idx, NULL);
+  int32_t func_start_addr = (plt_vaddr
+                            - (sframe_vaddr + offsetof_fde_in_sec));
 
   /* 5 pltN entries of 16 bytes each.  */
   int err = sframe_encoder_add_funcdesc_v2 (ectx, func_start_addr,
@@ -81,7 +84,8 @@ void test_plt_findfre (uint32_t plt_vaddr, uint32_t sframe_vaddr)
     }                                                                         \
     while (0)
 
-  ectx = sframe_encode (SFRAME_VERSION, 0, SFRAME_ABI_AMD64_ENDIAN_LITTLE,
+  ectx = sframe_encode (SFRAME_VERSION, SFRAME_F_FDE_FUNC_START_ADDR_PCREL,
+                       SFRAME_ABI_AMD64_ENDIAN_LITTLE,
                        SFRAME_CFA_FIXED_FP_INVALID,
                        -8, /* Fixed RA offset for AMD64.  */
                        &err);