31 Commits

Author SHA1 Message Date
Indu Bhagat
b91966e2df libsframe: rename encoder to ectx for readability
Addressing (an old) review comment suggesting this housekeeping item.
Use consistent naming style in libsframe.  sframe_decoder_ctx objects
are named 'dctx', so use 'ectx' for sframe_encoder_ctx objects.

Make necessary changes in all the applicable declarations and definitions.

Reviewed-by: Jens Remus <jremus@linux.ibm.com>
2025-11-09 00:34:27 -08:00
Indu Bhagat
dfb31cd02b include: sframe: fix minor typos in sframe_decode
Change argument names (in declaration) to SF_BUF and SF_SIZE (instead of
the current CF_BUF and CF_SIZE respectively).

include/
        * sframe-api.h (sframe_decode): Fix typos.  Use same name as
	used for the definition.
2025-11-04 23:28:43 -08:00
Jens Remus
6ca8915c61 include: libsframe: Add API to get RA undefined
SFrame FREs without any offsets will later be used to represent an
undefined return address (RA) in SFrame.  This API can then be used,
for instance by libsframe when dumping SFrame stack trace information
(e.g. in objdump and readelf), to test for RA undefined.  Other users
of libsframe need the same capability.

include/
	* sframe-api.h (sframe_fre_get_ra_undefined_p): New declaration.

libsframe/
	* libsframe.ver (sframe_fre_get_ra_undefined_p): List new API.
	* sframe.c (sframe_fre_get_ra_undefined_p): New definition.

Signed-off-by: Jens Remus <jremus@linux.ibm.com>
2025-10-15 17:45:48 +02:00
Indu Bhagat
6a959b1270 libsframe: bump version to 2.0
Remove LIBSFRAME_1.1, LIBSFRAME_1.0 nodes and add a new LIBSFRAME_2.0
node (non-inheritance version) to create new global versioned symbols.
Also announce libsframe.so.2 in NEWS.

New APIs:
     sframe_decoder_get_flags;
     sframe_decoder_get_offsetof_fde_start_addr;
     sframe_encoder_get_flags;
     sframe_encoder_get_offsetof_fde_start_addr;

Removed APIs: (already deprecated since X-2 release)
     sframe_get_funcdesc_with_addr;

APIs with changed semantics:
     sframe_decoder_get_funcdesc_v2;
     sframe_encoder_add_funcdesc_v2;
     sframe_encoder_write;

lisbframe/
	* libsframe.ver: Define new LIBSFRAME_2.0.
	* libtool-version: Bump the 'current' numeral to indicate a binary
	incompatible release.
include/
	* sframe-api.h (sframe_get_funcdesc_with_addr): Remove
	deprecated interface.
libsframe/
	* sframe.c (sframe_get_funcdesc_with_addr): Likewise.
binutils/
	* NEWS: Announce new versioned release of libsframe.
2025-07-12 01:09:17 -07:00
Jens Remus
955570f097 s390: Represent FP without RA saved in SFrame
If an architecture uses both SFrame RA and FP tracking SFrame assumes
that the RA offset is the 2nd offset and the FP offset is the 3rd offset
following a SFrame FRE.  An architecture does not necessarily need to
save both on the stack (or in register) at the same time or even at all.
SFrame cannot represent FP without RA saved on stack (or in a register),
since it cannot distinguish whether the 2nd offset is the RA or FP
offset.

For s390x use an invalid SFrame RA offset from CFA value of zero as
padding to represent the FP being saved when the RA is not saved.  This
aligns with the existing invalid SFrame fixed RA offset from CFA value
of zero.  In a stack tracer this then also naturally falls into place,
as it can skip restoring the RA in the topmost frame, if both the fixed
RA offset (from SFrame header) and the RA offset (from FDE) are zero,
without any need to test architecture-specific flags.

include/
	* sframe.h (SFRAME_FRE_RA_OFFSET_INVALID): New define.  Used as
	padding offset.
	* sframe-api.h (sframe_fre_get_ra_offset): Add comment that for
	s390x an offset value of SFRAME_FRE_RA_OFFSET_INVALID indicates
	that the RA is not saved.

gas/
	* gen-sframe.c (get_fre_num_offsets): For s390x account padding
	RA offset, if FP without RA saved.
	(sframe_get_fre_offset_size): Likewise.
	(output_sframe_row_entry): For s390x write a padding RA offset,
	if FP without RA needs to be represented.
	(sframe_do_fde): Enable FP without RA saved to be represented
	on s390x.

libsframe/
	* sframe.c (sframe_fre_get_ra_offset): Add comment that for
	s390x an offset value of SFRAME_FRE_RA_OFFSET_INVALID indicates
	that the RA is not saved.
	* sframe-dump.c (dump_sframe_func_with_fres): Treat invalid
	RA offsets as if they were undefined.  Display them as "U"
	to distinguish them.
	* doc/sframe-spec.texi (s390x): Document s390x-specific use of
	SFRAME_FRE_RA_OFFSET_INVALID to represent FP without RA saved.

gas/testsuite/
	* gas/cfi-sframe/cfi-sframe.exp: Rename s390x-specific tests.
	* gas/cfi-sframe/cfi-sframe-s390x-fpra-offset-err-1.s: Rename
	to ...
	* cfi-sframe/cfi-sframe-s390x-fpra-offset-err-1.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-s390x-fpra-offset-2.s: This.
	* gas/cfi-sframe/cfi-sframe-s390x-fpra-offset-2.d: Likewise.
	Update test verification pattern accordingly.
	* cfi-sframe/cfi-sframe-s390x-fpra-register-err-1.s: Rename
	to ...
	* cfi-sframe/cfi-sframe-s390x-fpra-register-err-1.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-s390x-fpra-register-2.s: This.
	* gas/cfi-sframe/cfi-sframe-s390x-fpra-register-2.d: Likewise.
	Update test verification pattern accordingly.

Signed-off-by: Jens Remus <jremus@linux.ibm.com>
2025-07-11 10:29:40 +02:00
Jens Remus
61b808e087 s390: Represent FP/RA saved in register in SFrame
GCC on s390x, when in a leaf function, can be observed to save the
frame pointer (FP) and/or return address (RA) register in a floating-
point registers (FPR) instead of on the stack.  This is declared using
the following CFI directive:

  .cfi_register <fp/ra-regnum>, <fpr-regnum>

SFrame cannot represent the FP and/or RA being saved in another
register.  It does only track the CFA base register (SP/FP), CFA offset
from CFA base register, and FP and RA save area offsets from CFA.

On s390x the FP and/or RA are only saved in another FPR when in a leaf
function.  That is a function that does not call any other function.
Therefore it can ever only be the topmost function in a call chain.
An unwinder by default has access to all registers of the function that
is the topmost on the call stack.  Therefore no further information
is required to restore FP/RA from the FPR.

Represent FP/RA saved in another register on s390x, by encoding the
DWARF register number shifted by one to the left with the least-
significant bit set in the offset as follows:

  offset = (regnum << 1) | 1

The use of the least-significant bit of the offset as indication is
possible, as the stack pointer (SP), the CFA, and any register save
area slots are 8-byte aligned according to the s390x ELF ABI:
- The stack pointer (SP) "shall maintain an 8-byte alignment". [1]
- The CFA is defined as SP at call site +160. [2]
- Pointers and 8-byte integers, such as general register values, must
  be 8-byte aligned. [3]
SFrame FP and RA stack offsets must therefore always be a multiple of
8 on s390x.  Note that for the same reason the DWARF data alignment
factor is -8 on s390x (see DWARF2_CIE_DATA_ALIGNMENT).

Add s390x-specific SFrame (error) tests for FP/RA saved in FPRs in leaf
function.

[1]: s390x ELF ABI, sections "Register Roles" and "Stack Frame
     Allocation", https://github.com/IBM/s390x-abi/releases
[2]: s390x ELF ABI, commit 4e38ad9c8a88 ("Document the CFA"),
     https://github.com/IBM/s390x-abi/commit/4e38ad9c8a88
[3]: s390x ELF ABI, section "Fundamental Types", table "Scalar types",
     https://github.com/IBM/s390x-abi/releases

include/
	* sframe.h (SFRAME_V2_S390X_OFFSET_IS_REGNUM): New s390x-
	specific macro to test whether an SFrame FP/RA offset is a DWARF
	register number.
	(SFRAME_V2_S390X_OFFSET_ENCODE_REGNUM): New s390x-specific macro
	to encode a DWARF register number into an SFrame FP/RA offset.
	(SFRAME_V2_S390X_OFFSET_DECODE_REGNUM): New s390x-specific macro
	to decode an SFrame FP/RA offset into a DWARF register number.
	* sframe-api.h (sframe_fre_get_fp_offset,
	sframe_fre_get_fp_offset): Add comment that for s390x the offset
	may be an encoded register number.

gas/
	* gen-sframe.c (s390_sframe_xlate_do_register): New S390-
	specific function.  Uses SFRAME_V2_S390X_OFFSET_ENCODE_REGNUM to
	represent FP/RA saved in another register on s390x.
	(sframe_xlate_do_register): Invoke s390_sframe_xlate_do_register
	on s390x.

libsframe/
	* sframe.c (sframe_fre_get_fp_offset, sframe_fre_get_fp_offset):
	Add comment that for s390x the offset may be an encoded register
	number.
	* sframe-dump.c (is_sframe_abi_arch_s390x): New helper to test
	whether ABI/arch is s390x.
	(dump_sframe_func_with_fres): Use
	SFRAME_V2_S390X_OFFSET_IS_REGNUM and
	SFRAME_V2_S390X_OFFSET_DECODE_REGNUM to dump FP/RA saved in
	another register on s390x.
	* doc/sframe-spec.texi (s390x): Document s390x-specific
	representation of FP/RA saved in another register.

gas/testsuite/
	* gas/cfi-sframe/cfi-sframe.exp: Update s390x-specific SFrame
	(error) tests.
	* gas/cfi-sframe/cfi-sframe-s390x-fpra-register-err-2.s: Rename
	to ...
	* gas/cfi-sframe/cfi-sframe-s390x-fpra-register-err-2.d:
	Likewise.
	* gas/cfi-sframe/cfi-sframe-s390x-fpra-register-1.s: This.  Test
	no longer triggers a warning, as SFrame can represent FP and RA
	saved in registers.
	* gas/cfi-sframe/cfi-sframe-s390x-fpra-register-1.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-s390x-fpra-register-err-1.d: Test
	now triggers a different warning, as SFrame can represent FP and
	RA saved in registers, but not FP without RA saved in register.

Signed-off-by: Jens Remus <jremus@linux.ibm.com>
2025-07-11 10:29:40 +02:00
Indu Bhagat
61be442011 gas: ld: sframe: add new internal header
for SFRAME_V2_GNU_AS_LD_ENCODING_FLAGS.

The intention of creating an abstraction like
SFRAME_V2_GNU_AS_LD_ENCODING_FLAGS is to address the concern that there
should be a central place to enforce harmonious flags between GNU as and
ld.  At the moment, the only flag that needs to be enforced is
SFRAME_F_FDE_FUNC_START_PCREL.

sframe.h and sframe-api.h are installed headers by libsframe for the
specification and implementation respectively.  Adding a definition like
SFRAME_V2_GNU_AS_LD_ENCODING_FLAGS does not fit in either.  Create a
new internal header instead to keep the definition uncoupled from
sframe.h and sframe-api.h.  Rename the previously added
SFRAME_F_LD_MUSTHAVE_FLAGS to define the new
SFRAME_V2_GNU_AS_LD_ENCODING_FLAGS.

bfd/
	* elf-sframe.c (_bfd_elf_merge_section_sframe): Use the new
	internal header and SFRAME_V2_GNU_AS_LD_ENCODING_FLAGS.
gas/
	* gen-sframe.c (output_sframe_internal): Likewise.
include/
	* sframe-api.h (SFRAME_F_LD_MUSTHAVE_FLAGS): Move from..
	* sframe-internal.h: ..to here.  New file.
2025-07-09 01:40:41 -07:00
Indu Bhagat
0b1bf2fc98 bfd: gas: ld: libsframe: adopt new encoding for FDE func start addr field
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_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_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_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) 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_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_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_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_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 may 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_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_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_PCREL flag.
	* libsframe/testsuite/libsframe.encode/encode-1.c: Use flag
	SFRAME_F_FDE_FUNC_START_PCREL.
2025-07-06 12:53:03 -07:00
Indu Bhagat
72dac98050 include: libsframe: add APIs for offsetof FDE func start addr field
These APIs will be later used by the linker to arrange SFrame FDEs in
the output SFrame section.

include/
        * sframe-api.h (sframe_decoder_get_offsetof_fde_start_addr): New
	declaration.
        (sframe_encoder_get_offsetof_fde_start_addr): Likewise.

libsframe/
        * libsframe.ver: List the new APIs.
        * sframe.c (sframe_decoder_get_offsetof_fde_start_addr): New
	definition.
        (sframe_encoder_get_offsetof_fde_start_addr): Likewise.
2025-07-06 12:53:03 -07:00
Indu Bhagat
251c6789b3 include: libsframe: add APIs for SFrame header flags
Add new APIs, one each for getting flags from the SFrame decoder and
SFrame encoder context objects respectively.

These will later be used by the linker to uniformly access the flags,
given the SFrame decoder and SFrame encoder objects.

Use the new API, where applicable, within libsframe.

include/
        * sframe-api.h (sframe_decoder_get_flags): New declaration.
        (sframe_encoder_get_flags): Likewise.
libsframe/
	* libsframe.ver: List new APIs.
        * sframe.c (sframe_decoder_get_flags): New definition.
	(sframe_encoder_get_flags): Likewise.
        (sframe_get_funcdesc_with_addr_internal): Use the new API.
        (sframe_encoder_get_flags): Likewise.
        (sframe_encoder_write_sframe): Likewise.
2025-07-06 12:53:03 -07:00
Alan Modra
e8e7cf2abe Update year range in copyright notice of binutils files 2025-01-01 18:29:57 +10:30
Alan Modra
fd67aa1129 Update year range in copyright notice of binutils files
Adds two new external authors to etc/update-copyright.py to cover
bfd/ax_tls.m4, and adds gprofng to dirs handled automatically, then
updates copyright messages as follows:

1) Update cgen/utils.scm emitted copyrights.
2) Run "etc/update-copyright.py --this-year" with an extra external
   author I haven't committed, 'Kalray SA.', to cover gas testsuite
   files (which should have their copyright message removed).
3) Build with --enable-maintainer-mode --enable-cgen-maint=yes.
4) Check out */po/*.pot which we don't update frequently.
2024-01-04 22:58:12 +10:30
Indu Bhagat
ce9a87252c sframe: bfd: gas: ld: format bump to SFrame version 2
SFrame version 2 encodes the size of repetitive insn block explicitly
in the format.  Add information in the SFrame FDE to convey the size
of the block of repeating instructions.  This information is used only
for SFrame FDEs of type SFRAME_FDE_TYPE_PCMASK.

Introduce two extra bytes for padding: this ensures that the memory
accesses to the members of the SFrame Frame Descriptor Entry (FDE) are
naturally aligned.

gas generates SFrame section with version SFRAME_VERSION_2 by default.

libsframe provides two new APIs to:
  - get an SFrame FDE data from the decoder context, and
  - add an SFrame FDE to the encoder context.
The additional argument (for rep_block_size) is useful for SFrame FDEs
where FDE type is SFRAME_FDE_TYPE_PCMASK.

The linker will generate the output SFrame sections in the
SFRAME_VERSION_2 format.  If the input sections offered to the linker
are not all in the SFRAME_VERSION_2 format, the linker issues an error
to the user.

objdump/readelf will show the following message to the user if .sframe
section in SFRAME_VERSION_1 format is seen:

 "No further information can be displayed.  SFrame version not
 supported."

In other words, like the rest of the binutils, only the current SFrame
format version, i.e., SFRAME_VERSION_2 is supported by the textual dump
facilities.

bfd/
	* elf-sframe.c (_bfd_elf_merge_section_sframe): Generate an
	output SFrame section with version SFRAME_VERSION_2.  Also,
	error out if the SFrame sections do not all have
	SFRAME_VERSION_2.
	* elfxx-x86.c (_bfd_x86_elf_create_sframe_plt): Generate SFrame
	section for plt entries with version SFRAME_VERSION_2.
gas/
	* gen-sframe.c (sframe_set_version): Update to SFRAME_VERSION_2.
	(output_sframe): Likewise.
gas/testsuite/
	* gas/cfi-sframe/cfi-sframe-aarch64-1.d: Use SFRAME_VERSION_2.
	* gas/cfi-sframe/cfi-sframe-aarch64-2.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-aarch64-pac-ab-key-1.d: Likewise.
	* gas/cfi-sframe/cfi-sframe-common-1.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-x86_64-1.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.
ld/testsuite/
	* ld-aarch64/sframe-simple-1.d: Adjust for SFRAME_VERSION_2.
	* ld-x86-64/sframe-plt-1.d: Likewise.
	* ld-x86-64/sframe-simple-1.d: Likewise.
libsframe/
	* libsframe.ver: Add the new APIs.
	* sframe.c (sframe_decoder_get_funcdesc_v2): New definition.
	(sframe_encoder_add_funcdesc_v2): Likewise.
	(sframe_header_sanity_check_p): Include SFRAME_VERSION_2.
	(sframe_fre_check_range_p): Get rep_block_size info from SFrame
	FDE.
	* sframe-dump.c (dump_sframe_header): Add support for
	SFRAME_VERSION_2.
	(dump_sframe): Inform user if SFrame section in SFRAME_VERSION_1
	format is seen.
libsframe/testsuite/
	* libsframe.decode/DATA-BE: Regenerated data file.
	* libsframe.decode/DATA1: Likewise.
	* libsframe.decode/DATA2: Likewise.
	* libsframe.find/plt-findfre-1.c: Use new API in the testcase.
include/
	* sframe.h: Add member to encode size of the code block of
	repeating instructions.  Add 2 bytes of padding.
	* sframe-api.h (sframe_decoder_get_funcdesc_v2): New
	declaration.
	(sframe_encoder_add_funcdesc_v2): Likewise.
2023-06-29 16:31:58 -07:00
Indu Bhagat
9f71b60bd4 libsframe: add new APIs to get SFrame version
While the SFrame preamble is guaranteed to not change between versions,
providing these access APIs from the SFrame decoder and encoder APIs is
for convenience only.  The linker may want to use these APIs as the
format evolves.

include/
	* sframe-api.h (sframe_decoder_get_version): New declaration.
	(sframe_encoder_get_version): Likewise.

libsframe/
	* libsframe/libsframe.ver: Add new APIs.
	* libsframe/sframe.c (sframe_decoder_get_version): New
	definition.
	(sframe_encoder_get_version): Likewise.
2023-06-29 16:28:56 -07:00
Indu Bhagat
df6f1afb6d libsframe: bfd: use uint32_t for return type of get_num_fidx APIs
Keep the data types usage in libsframe look consistent.

bfd/
	* elf-sframe.c (_bfd_elf_merge_section_sframe): Use uint32_t
	type alias.
	* libsframe/sframe.c (sframe_decoder_get_funcdesc_at_index):
	Likewise.
	(sframe_decoder_get_num_fidx): Likewise.
	(sframe_encoder_get_num_fidx): Likewise.
include/
	* sframe-api.h (sframe_decoder_get_num_fidx): Likewise.
	(sframe_encoder_get_num_fidx): Likewise.
2023-06-27 12:01:56 -07:00
Indu Bhagat
3412dcec61 libsframe: use appropriate data types for args of sframe_encode
include/
	* sframe-api.h (sframe_encode): Use of uint8_t is more
	appropriate.
libsframe/
	* sframe.c (sframe_encode): Likewise.
2023-06-27 12:01:56 -07:00
Indu Bhagat
a9f1da26da libsframe: use uint8_t for return type of sframe_fre_get_base_reg_id
Use a more appropriate data type.

include/
	* sframe-api.h (sframe_fre_get_base_reg_id): Use uint8_t as
	return type.
libsframe/
	* sframe-dump.c (dump_sframe_func_with_fres): Use uint8_t type
	for base reg id.
	* sframe.c (sframe_fre_get_base_reg_id): Use uin8_t as return
	type.
2023-06-27 12:01:56 -07:00
Indu Bhagat
de4879feca libsframe: use uint8_t instead of unsigned char for abi_arch
Use uint8_t consistently for identifying ABI/arch in SFrame format.

bfd/
	* elf-sframe.c (_bfd_elf_merge_section_sframe):
libsframe/
	* sframe-dump.c (is_sframe_abi_arch_aarch64): Use uint8_t for
	local variable.
	* sframe.c (sframe_decoder_get_abi_arch): Update return type to
	uint8_t.
	(sframe_encoder_get_abi_arch): Likewise.
include/
	* sframe-api.h (sframe_decoder_get_abi_arch): Likewise.
	(sframe_encoder_get_abi_arch): Likewise.
2023-06-27 12:01:56 -07:00
Indu Bhagat
49e4485cba libsframe: bfd: use uint32_t for return type of sframe_calc_fre_type
Use uint32_t type alias consistently for all APIs in libsframe.

bfd/
	* elfxx-x86.c (_bfd_x86_elf_create_sframe_plt): Adjust for the
	changed return type.
libsframe/
	* sframe.c (sframe_calc_fre_type): Use uint32_t for return type.
include/
	* sframe-api.h (sframe_calc_fre_type): Likewise.
2023-06-27 12:01:56 -07:00
Indu Bhagat
100d405dae libsframe: use uint32_t for fre_type and fde_type function args
The API sframe_fde_create_func_info is provided by libsframe.  Current
users are the bfd linker.  Adjust the argument type for the variables
carrying the SFrame FRE type and SFrame FDE type to consistenly use
uint32_t type alias.

include/
	* sframe-api.h (sframe_fde_create_func_info): Use uint32_t
	instead of unsigned int.
libsframe/
	* sframe.c (sframe_get_fre_type): Likewise.
	(sframe_get_fde_type): Likewise.
	(flip_fre_start_address): Likewise.
	(sframe_fre_start_addr_size): Likewise.
	(sframe_fre_entry_size): Likewise.
	(flip_fre): Likewise.
	(flip_sframe): Likewise.
	(sframe_fde_create_func_info): Likewise.
	(sframe_calc_fre_type): Likewise.
	(sframe_decode_fre_start_address): Likewise.
	(sframe_decode_fre): Likewise.
	(sframe_find_fre): Likewise.
	(sframe_decoder_get_fre): Likewise.
	(sframe_encoder_add_fre): Likewise.
	(sframe_encoder_write_fre_start_addr): Likewise.
	(sframe_encoder_write_fre): Likewise.
	(sframe_encoder_write_sframe): Likewise.
2023-06-27 12:01:56 -07:00
Indu Bhagat
852bb8c10d libsframe: remove sframe_get_funcdesc_with_addr API
This is an incompatible ABI change in libsframe.

The interface provided by this function is not a healthy abstraction to
expose: the return type sframe_func_desc_entry, which is defined in
include/sframe.h (the SFrame binary format definition).  This ties up
the library in a undesirable way.  Most importantly, this function
should technically not be directly necessary for a stack tracer.  A
stack tracer will likely only need to do a sframe_find_fre ().

Rename the API to continue to use the functionality internally in the
library.  bfd/linker does not use this function.

Change the return type of the previous definition and make a note about
its planned deprecation.

include/
	* sframe-api.h:  Change return type of sframe_get_funcdesc_with_addr.
	Add comment for intention to deprecate.
libsframe/
	*sframe.c (sframe_get_funcdesc_with_addr): Change return type
	and set error code. This API is deprecated.
        (sframe_get_funcdesc_with_addr_internal): New definition for
	internal use.
	(sframe_find_fre): Use sframe_get_funcdesc_with_addr_internal
	instead.
2023-06-27 12:01:56 -07:00
Indu Bhagat
f4af42724b libsframe: fix cosmetic issues and typos
include/
	* sframe-api.h (sframe_decoder_get_num_fidx): Use extern.
libsframe/
	* sframe-dump.c (dump_sframe_func_with_fres): Fix line length.
	* sframe.c (sframe_frame_row_entry_copy): Likewise.
	(sframe_decode_fre_start_address): Use the intended type uint32_t.
2023-06-06 10:50:07 -07:00
Indu Bhagat
d987df5c95 libsframe: avoid using magic number
Define a new constant for the maximum number of stack offsets handled in
libsframe, and use it.  Note that the SFrame format does not define such
a constant (limit).  This is an implmentation-defined constant in
libsframe.

include/
	* sframe-api.h (MAX_NUM_STACK_OFFSETS): New definition.
libsframe/
	* sframe.c (sframe_fre_sanity_check_p): Use it.
2023-06-01 09:41:04 -07:00
Indu Bhagat
725a19bfd1 sframe: fix the defined SFRAME_FRE_TYPE_*_LIMIT constants
An earlier commit 3f107464 defined the SFRAME_FRE_TYPE_*_LIMIT
constants.  These constants are used (by gas and libsframe) to pick an
SFrame FRE type based on the function size.  Those constants, however,
were buggy, causing the generated SFrame sections to be bloated as
SFRAME_FRE_TYPE_ADDR2/SFRAME_FRE_TYPE_ADDR4 got chosen more often than
necessary.

gas/
	* sframe-opt.c (sframe_estimate_size_before_relax): Use
	typecast.
	(sframe_convert_frag): Likewise.

libsframe/
	* sframe.c (sframe_calc_fre_type): Use a more appropriate type
	for argument.  Adjust the check for SFRAME_FRE_TYPE_ADDR4_LIMIT
	to keep it warning-free but meaningful.

include/
	* sframe-api.h (sframe_calc_fre_type): Use a more appropriate
	type for the argument.
	* sframe.h (SFRAME_FRE_TYPE_ADDR1_LIMIT): Correct the constant.
	(SFRAME_FRE_TYPE_ADDR2_LIMIT): Likewise.
	(SFRAME_FRE_TYPE_ADDR4_LIMIT): Likewise.
2023-01-06 09:30:56 -08:00
Alan Modra
d87bef3a7b Update year range in copyright notice of binutils files
The newer update-copyright.py fixes file encoding too, removing cr/lf
on binutils/bfdtest2.c and ld/testsuite/ld-cygwin/exe-export.exp, and
embedded cr in binutils/testsuite/binutils-all/ar.exp string match.
2023-01-01 21:50:11 +10:30
Indu Bhagat
9c4b163cb5 libsframe: provide new access API for mangled RA bit
include/ChangeLog:

	* sframe-api.h (sframe_fre_get_ra_mangled_p): New declaration.

ChangeLog:

	* libsframe/sframe.c (sframe_get_fre_ra_mangled_p): New
	definition.
	(sframe_fre_get_ra_mangled_p): New static function.
2022-12-16 22:01:57 -08:00
Indu Bhagat
8c078abdc2 libsframe asan: avoid generating misaligned loads
There are two places where unaligned loads were seen on aarch64:
  - #1. access to the SFrame FRE stack offsets in the in-memory
    representation/abstraction provided by libsframe.
  - #2. access to the SFrame FRE start address in the on-disk representation
    of the frame row entry.

For #1, we can fix this by reordering the struct members of
sframe_frame_row_entry in libsframe/sframe-api.h.

For #2, we need to default to using memcpy instead, and copy out the bytes
to a location for output.

SFrame format is an unaligned on-disk format. As such, there are other blobs
of memory in the on-disk SFrame FRE that are on not on their natural
boundaries.  But that does not pose further problems yet, because the users
are provided access to the on-disk SFrame FRE data via libsframe's
sframe_frame_row_entry, the latter has its' struct members aligned on their
respective natural boundaries (and initialized using memcpy).

PR 29856 libsframe asan: load misaligned at sframe.c:516

ChangeLog:

	PR libsframe/29856
	* bfd/elf64-x86-64.c: Adjust as the struct members have been
	reordered.
	* libsframe/sframe.c (sframe_decode_fre_start_address): Use
	memcpy to perform 16-bit/32-bit reads.
	* libsframe/testsuite/libsframe.encode/encode-1.c: Adjust as the
	struct members have been reordered.

include/ChangeLog:

	PR libsframe/29856
	* sframe-api.h: Reorder fre_offsets for natural alignment.
2022-12-15 13:12:01 -08:00
Indu Bhagat
b659fb3585 libsframe: rename API sframe_fde_func_info to sframe_fde_create_func_info
The new name better reflects the purpose of the function.

ChangeLog:

	* bfd/elfxx-x86.c (_bfd_x86_elf_create_sframe_plt): Use new
	name.
	* libsframe/sframe.c (sframe_fde_create_func_info): Rename
	sframe_fde_func_info to this.
	* libsframe/testsuite/libsframe.encode/encode-1.c: Use new name.

include/ChangeLog:

	* sframe-api.h (sframe_fde_create_func_info): Rename
	sframe_fde_func_info to this.
2022-12-09 10:25:31 -08:00
Indu Bhagat
42b6953bba readelf/objdump: support for SFrame section
This patch adds support for SFrame in readelf and objdump. The arguments
of --sframe are optional for both readelf and objdump.

include/ChangeLog:

	* sframe-api.h (dump_sframe): New function declaration.

ChangeLog:

	* binutils/Makefile.am: Add dependency on libsframe for
	readelf and objdump.
	* binutils/Makefile.in: Regenerate.
	* binutils/doc/binutils.texi: Document --sframe=[section].
	* binutils/doc/sframe.options.texi: New file.
	* binutils/objdump.c: Add support for SFrame format.
	* binutils/readelf.c: Likewise.
	* include/sframe-api.h: Add new API for dumping .sframe
	section.
	* libsframe/Makefile.am: Add sframe-dump.c.
	* libsframe/Makefile.in: Regenerate.
	* libsframe/sframe-dump.c: New file.
2022-11-15 15:50:05 -08:00
Indu Bhagat
cf0e0a0ba9 bfd: linker: merge .sframe sections
The linker merges all the input .sframe sections.  When merging, the
linker verifies that all the input .sframe sections have the same
abi/arch.

The linker uses libsframe library to perform key actions on the
.sframe sections - decode, read, and create output data.  This
implies buildsystem changes to make and install libsframe before
libbfd.

The linker places the output .sframe section in a new segment of its
own: PT_GNU_SFRAME.  A new segment is not added, however, if the
generated .sframe section is empty.

When a section is discarded from the final link, the corresponding
entries in the .sframe section for those functions are also deleted.

The linker sorts the SFrame FDEs on start address by default and sets
the SFRAME_F_FDE_SORTED flag in the .sframe section.

This patch also adds support for generation of SFrame unwind
information for the .plt* sections on x86_64.  SFrame unwind info is
generated for IBT enabled PLT, lazy/non-lazy PLT.

The existing linker option --no-ld-generated-unwind-info has been
adapted to include the control of whether .sframe unwind information
will be generated for the linker generated sections like PLT.

Changes to the linker script have been made as necessary.

ChangeLog:

	* Makefile.def: Add install dependency on libsframe for libbfd.
	* Makefile.in: Regenerated.
	* bfd/Makefile.am: Add elf-sframe.c
	* bfd/Makefile.in: Regenerated.
	* bfd/bfd-in2.h (SEC_INFO_TYPE_SFRAME): Regenerated.
	* bfd/configure: Regenerate.
	* bfd/configure.ac: Add elf-sframe.lo.
	* bfd/elf-bfd.h (struct sframe_func_bfdinfo): New struct.
	(struct sframe_dec_info): Likewise.
	(struct sframe_enc_info): Likewise.
	(struct elf_link_hash_table): New member for encoded .sframe
	object.
	(struct output_elf_obj_tdata): New member.
	(elf_sframe): New access macro.
	(_bfd_elf_set_section_sframe): New declaration.
	* bfd/elf.c (get_segment_type): Handle new segment
	PT_GNU_SFRAME.
	(bfd_section_from_phdr): Likewise.
	(get_program_header_size): Likewise.
	(_bfd_elf_map_sections_to_segments): Likewise.
	* bfd/elf64-x86-64.c (elf_x86_64_link_setup_gnu_properties): Add
	contents to the .sframe sections or .plt* entries.
	* bfd/elflink.c (elf_section_ignore_discarded_relocs): Handle
	SEC_INFO_TYPE_SFRAME.
	(_bfd_elf_default_action_discarded): Handle .sframe section.
	(elf_link_input_bfd): Merge .sframe section.
	(bfd_elf_final_link): Write the output .sframe section.
	(bfd_elf_discard_info): Handle discarding .sframe section.
	* bfd/elfxx-x86.c (_bfd_x86_elf_size_dynamic_sections): Create
	.sframe section for .plt and .plt.sec.
	(_bfd_x86_elf_finish_dynamic_sections): Handle .sframe from
	.plt* sections.
	* bfd/elfxx-x86.h (PLT_SFRAME_FDE_START_OFFSET): New
	definition.
	(SFRAME_PLT0_MAX_NUM_FRES): Likewise.
	(SFRAME_PLTN_MAX_NUM_FRES): Likewise.
	(struct elf_x86_sframe_plt): New structure.
	(struct elf_x86_link_hash_table): New member.
	(struct elf_x86_init_table): New members for .sframe
	creation.
	* bfd/section.c: Add new definition SEC_INFO_TYPE_SFRAME.
	* binutils/readelf.c (get_segment_type): Handle new segment
	PT_GNU_SFRAME.
	* ld/ld.texi: Update documentation for
	--no-ld-generated-unwind-info.
	* ld/scripttempl/elf.sc: Support .sframe sections.
	* ld/Makefile.am (TESTSFRAMELIB): Use it.
	(check-DEJAGNU): Likewise.
	* ld/Makefile.in: Regenerated.
	* ld/configure.ac (TESTSFRAMELIB): Set to the .so or .a like TESTBFDLIB.
	* ld/configure: Regenerated.
	* bfd/elf-sframe.c: New file.

include/ChangeLog:

	* elf/common.h (PT_GNU_SFRAME): New definition.
	* elf/internal.h (struct elf_segment_map): Handle new segment
	type PT_GNU_SFRAME.

ld/testsuite/ChangeLog:

	* ld/testsuite/ld-bootstrap/bootstrap.exp: Add SFRAMELIB.
	* ld/testsuite/ld-aarch64/aarch64-elf.exp: Add new test
	  sframe-simple-1.
	* ld/testsuite/ld-aarch64/sframe-bar.s: New file.
	* ld/testsuite/ld-aarch64/sframe-foo.s: Likewise.
	* ld/testsuite/ld-aarch64/sframe-simple-1.d: Likewise.
	* ld/testsuite/ld-sframe/sframe-empty.d: New test.
	* ld/testsuite/ld-sframe/sframe-empty.s: New file.
	* ld/testsuite/ld-sframe/sframe.exp: New testsuite.
	* ld/testsuite/ld-x86-64/sframe-bar.s: New file.
	* ld/testsuite/ld-x86-64/sframe-foo.s: Likewise.
	* ld/testsuite/ld-x86-64/sframe-simple-1.d: Likewise.
	* ld/testsuite/ld-x86-64/sframe-plt-1.d: Likewise.
	* ld/testsuite/ld-x86-64/sframe-simple-1.d: Likewise.
	* ld/testsuite/ld-x86-64/x86-64.exp: Add new tests -
	  sframe-simple-1, sframe-plt-1.
	* ld/testsuite/lib/ld-lib.exp: Add new proc to check if
	  assembler supports SFrame section.
	* ld/testsuite/ld-sframe/discard.d: New file.
	* ld/testsuite/ld-sframe/discard.ld: Likewise.
	* ld/testsuite/ld-sframe/discard.s: Likewise.
2022-11-15 15:49:47 -08:00
Weimin Pan
19e559f1c9 libsframe: add the SFrame library
libsframe is a library that allows you to:
- decode a .sframe section
- probe and inspect a .sframe section
- encode (and eventually write) a .sframe section.

This library is currently being used by the linker, readelf, objdump.
This library will also be used by the SFrame unwinder which is still
to be upstream'd.

The file include/sframe-api.h defines the user-facing APIs for decoding,
encoding and probing .sframe sections. A set of error codes together
with their error message strings are also defined.

Endian flipping is performed automatically at read and write time, if
cross-endianness is detected.

ChangeLog:

	* Makefile.def: Add libsframe as new module with its
	dependencies.
	* Makefile.in: Regenerated.
	* binutils/Makefile.am: Add libsframe.
	* binutils/Makefile.in: Regenerated.
	* configure: Regenerated
	* configure.ac: Add libsframe to host_libs.
	* libsframe/Makefile.am: New file.
	* libsframe/Makefile.in: New file.
	* libsframe/aclocal.m4: New file.
	* libsframe/config.h.in: New file.
	* libsframe/configure: New file.
	* libsframe/configure.ac: New file.
	* libsframe/sframe-error.c: New file.
	* libsframe/sframe-impl.h: New file.
	* libsframe/sframe.c: New file.

include/ChangeLog:

	* sframe-api.h: New file.

testsuite/ChangeLog:

	* libsframe/testsuite/Makefile.am: New file.
	* libsframe/testsuite/Makefile.in: Regenerated.
	* libsframe/testsuite/libsframe.decode/Makefile.am: New
	  file.
	* libsframe/testsuite/libsframe.decode/Makefile.in:
	  Regenerated.
	* libsframe/testsuite/libsframe.decode/decode.exp: New file.
	* libsframe/testsuite/libsframe.encode/Makefile.am:
	  Likewise.
	* libsframe/testsuite/libsframe.encode/Makefile.in:
	  Regenerated.
	* libsframe/testsuite/libsframe.encode/encode.exp: New file.
	* libsframe/testsuite/libsframe.encode/encode-1.c: Likewise.
	* libsframe/testsuite/libsframe.decode/be-flipping.c: Likewise.
	* libsframe/testsuite/libsframe.decode/frecnt-1.c: Likewise.
	* libsframe/testsuite/libsframe.decode/frecnt-2.c: Likewise.
	* libsframe/testsuite/libsframe.decode/DATA-BE: New file.
	* libsframe/testsuite/libsframe.decode/DATA1: Likewise.
	* libsframe/testsuite/libsframe.decode/DATA2: Likewise.
2022-11-15 15:24:29 -08:00