Age | Commit message (Collapse) | Author | Files | Lines |
|
Add DRAFT marker to be emitted in the info, pdf and html outputs. This
is done in two places: one in the @ifnottex block meant for PDF output
and another in @titlepage block meant for info and html output.
While at it, also add date to non-pdf outputs.
The marker lines:
@center @strong{*** DRAFT - NOT FOR DISTRIBUTION ***}
should be removed before a release.
libsframe/doc/
* sframe-spec.texi: Add marker for DRAFT.
|
|
As reported in PR libsframe/33168, the libsframe tests don't build on
Solaris. The failure is
In file included from libsframe/testsuite/libsframe.decode/be-flipping.c:28:
/usr/include/dejagnu.h:48:1: error: conflicting types for ‘wait’; have ‘void(void)’
48 | wait (void)
| ^~~~
In file included from /usr/include/stdlib.h:16,
from libsframe/testsuite/libsframe.decode/be-flipping.c:21:
/usr/include/sys/wait.h:85:14: note: previous declaration of ‘wait’ with type ‘pid_t(int *)’ {aka ‘long int(int *)’}
85 | extern pid_t wait(int *);
| ^~~~
We have a combination of two factors here:
* Solaris <stdlib.h> has
and configure.ac predefines __EXTENSIONS__ due to the use of
AC_USE_SYSTEM_EXTENSIONS.
* This conflicts with <dejagnu.h>'s definition
void
wait (void)
{
...
}
While this version of wait was removed in upstream DejaGnu, the removal
only happened after the latest release, 1.6.3.
To avoid this, I've moved all testsuite includes into a new
sframe-test.h, adding a workaround for the wait conflict.
-Wall and -I$(srcdir) have been removed from AM_CPPFLAGS since they
don't seem to be needed. To fix the Makefile fragment duplication, the
local.mk files now use $(testsuite_LDADD) and $(testsuite_CPPFLAGS)
throughout.
Tested on {i386,amd64}-pc-solaris2.11, {sparc,sparcv9}-sun-solaris2.11,
{x86_64,i686}-pc-linux-gnu, and amd64-pc-freebsd14.0.
Coauthored-By: Alan Modra <amodra@gmail.com>
2025-08-31 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
Alan Modra <amodra@gmail.com>
libsframe:
PR libsframe/33168
* testsuite/sframe-test.h: New file.
* testsuite/libsframe.decode/be-flipping.c: Replace includes by
sframe-test.h.
* testsuite/libsframe.decode/frecnt-1.c: Likewise.
* testsuite/libsframe.decode/frecnt-2.c: Likewise.
* testsuite/libsframe.encode/encode-1.c: Likewise.
* testsuite/libsframe.find/findfre-1.c: Likewise.
* testsuite/libsframe.find/findfunc-1.c: Likewise.
* testsuite/libsframe.find/plt-findfre-1.c: Likewise.
* testsuite/libsframe.find/plt-findfre-2.c: Likewise.
* Makefile.am (AM_CPPFLAGS): Remove -I$(srcdir).
* Makefile.in: Regenerate.
* testsuite/local.mk (testsuite_LDADD): New variable.
(testsuite_CPPFLAGS): Likewise.
* testsuite/libsframe.decode/local.mk: Use $(testsuite_LDADD),
$(testsuite_CPPFLAGS).
* testsuite/libsframe.encode/local.mk: Likewise.
* testsuite/libsframe.find/local.mk: Likewise.
|
|
In SFrame format, the SFrame FDEs begin at an offset 'sfh_fdeoff' from
the end of the SFrame header. Similarly, the SFrame FREs begin at an
offset 'sfh_freoff' from the end of the SFrame header.
While the GNU assembler generates these subsections such that sfd_fdeoff
is zero, the correct way to decode the SFrame section (conforming with
the specification) is to use both sfh_fdeoff and sfh_freoff in
sframe_decode.
libsframe/
* sframe.c (sframe_decode): Use offsets to SFrame FDE and FRE
sub-sections as applicable.
|
|
Use sframe_encoder_add_funcdesc_v2 instead of sframe_encoder_add_funcdesc.
Similarly, use sframe_decoder_get_funcdesc_v2 instead of
sframe_decoder_get_funcdesc.
sframe_encoder_add_funcdesc, and sframe_decoder_get_funcdesc were first
added for SFrame V1. For the purpose of these testcases, the two V2
APIs are (almost) functionally equivalent. In future, we may want to
make sframe_encoder_add_funcdesc and sframe_decoder_get_funcdesc
internal to libsframe only. Using the V2 named APIs is better for
clarity as well.
libsframe/testsuite/
* libsframe.encode/encode-1.c: Use V2 named APIs instead.
* libsframe.find/findfre-1.c: Likewise.
* libsframe.find/findfunc-1.c: Likewise.
* libsframe.decode/be-flipping.c: Likewise.
* libsframe.decode/frecnt-1.c: Likewise.
* libsframe.decode/frecnt-2.c: Likewise.
|
|
Previously, some of the libsframe tests were updated to reduce the usage
of magic numbers. This patch makes encode-1.c follow similar coding
style as other tests, reducing the number of magic constants.
libsframe/testsuite/
* libsframe.encode/encode-1.c: Avoid magic numbers.
|
|
With the changes of an added flag SFRAME_F_FDE_FUNC_START_PCREL, s390x
support and new section type SHT_GNU_SFRAME, indicate that this document
specifies the errata 1 of SFrame version 2. This will help distinguish
the document / specification better from previous releases.
libsframe/doc/
* sframe-spec.texi: Mention errata 1 of SFrame version 2.
|
|
Fix PR ld/33131 Failed assertion when linking gccgo
Make amendments in both sframe_decoder_get_fre and
sframe_encoder_add_fre.
Since GNU as and the dw2gencfi code generally accepts such CFI, its best
to allow in SFrame FREs too.
libsframe/
PR ld/33131.
* sframe.c (sframe_decoder_get_fre): Relax the assertion a bit.
(sframe_encoder_add_fre): Likewise.
|
|
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.
|
|
Also, use ATTRIBUTE_UNUSED consistently.
libsframe/
* sframe.c (sframe_encoder_add_funcdesc): Fix function-level
comment and use ATTRIBUTE_UNUSED consistently.
(sframe_encoder_add_funcdesc_v2): Use ATTRIBUTE_UNUSED
consistently.
|
|
So far, SFrame sections were of type SHT_PROGBITS.
As per ELF specification, SHT_PROGBITS indicates that the section holds
information defined by the program, whose format and meaning are
determined solely by the program.
On the linker side, SHT_PROGBITS should be reserved for the simple "cat
contents after applying relocs" semantics.
Currently, the only way to know that a section contains SFrame stack
trace data is if consumer checks for section name. Such a check for
section name is not quite conformant to ELF principles.
Some of this was discussed here
https://sourceware.org/pipermail/binutils/2025-March/140181.html
With this change, the SFrame sections generated by gas, ld will have
section type set to SHT_GNU_SFRAME. The new section type is defined in
the SHT_LOOS/SHT_HIOS space. The SFrame parsing routine
_bfd_elf_parse_sframe () now admits sections only when the the section
type is SHT_GNU_SFRAME.
No special handling / validation is done at the moment for the case of
manual creation of SFrame sections via obj_elf_section (). Add function
level comments for now to add a note about this.
Although the default handling for (sh_type >= SHT_LOOS && sh_type <=
SHT_HIOS) is sufficient when SHT_GNU_SFRAME is in that range, it makes
sense to add it as a case of its own.
bfd/
* elf-sframe.c (_bfd_elf_parse_sframe): Check if section type is
SHT_GNU_SFRAME.
(_bfd_elf_set_section_sframe): Set SHT_GNU_SFRAME for output
SFrame section.
* elflink.c (obj_elf_section): Use section type for check
instead of section name.
* elfxx-x86.c: Set SHT_GNU_SFRAME for SFrame sections for
.plt* sections.
* elf.c (bfd_section_from_shdr): Add case for SHT_GNU_SFRAME.
binutils/
* readelf.c (get_os_specific_section_type_name): Add
SHT_GNU_SFRAME.
gas/
* NEWS: Announce emitted SFrame sections have SHT_GNU_SFRAME
set.
* config/obj-elf.c (obj_elf_attach_to_group): Add comments to
indicate no special handling for SFrame yet.
* dw2gencfi.c (cfi_finish): Set SHT_GNU_SFRAME for emitted
SFrame section.
ld/
* NEWS: Announce emitted SFrame sections have SHT_GNU_SFRAME
set.
gas/testsuite/
* gas/cfi-sframe/cfi-sframe.exp: Add new test.
* gas/cfi-sframe/cfi-sframe-common-1b.d: New test.
* gas/cfi-sframe/cfi-sframe-common-1b.s: New test.
include/
* elf/common.h (SHT_GNU_SFRAME): Add new section type for SFrame
stack trace information.
libsframe/doc/
* sframe-spec.texi: Add expected ELF section type.
|
|
Commit 0d4d5a2633f missed some necessary adjustments to the testcase
after rebase. SFrame FDE function start address data is now an offset
in PCREL encoding; reflect with a new flag SFRAME_F_FDE_START_ADDR_PCREL
in the header.
Adjust the newly added testcase.
PR libsframe/33140 SFrame test failures on x86-64
libsframe/testsuite/
* libsframe.find/plt-findfre-2.c: Adjust for the new FDE func
start addr encoding.
|
|
In SFrame V2 the size of the offsets following an SFrame FRE can be
either signed 8-bit, 16-bit, or 32-bit integer, with the largest offset
determining their size:
1. CFA offset from CFA base register
2. RA (stack save slot) offset from CFA, usually -48 on s390x if saved
3. FP (stack save slot) offset from CFA, usually -72 on s390x if saved
The FP and RA offsets from CFA, when FP/RA saved on the stack, usually
have fixed values that fit into signed 8-bit SFrame offsets. Likewise
the DWARF register numbers on s390x of general registers (GR; 0-15) and
floating-point registers (FPR; 16-31), when FP/RA saved in registers.
With that the CFA offset from CFA base register has the greatest impact
on the signed SFrame offset size.
The s390x ELF ABI defines the stack pointer (SP) to be 8-byte aligned
[1] and the CFA as SP at call site + 160 [2]. The CFA offset from CFA
base register is therefore always a multiple of 8.
On s390x store the SFrame CFA offset from CFA base register scaled down
by the s390x-specific CFA alignment factor of 8, in addition to the
adjustment by the s390x-specific CFA adjustment of -160, to further
improve the use of signed 8-bit SFrame offsets. This is similar to the
DWARF data alignment factor getting factored out from certain offsets
stored in DWARF CFI.
[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
include/
* sframe.h (SFRAME_S390X_CFA_OFFSET_ALIGNMENT_FACTOR): Define
s390x-specific CFA offset alignment factor.
(SFRAME_V2_S390X_CFA_OFFSET_ENCODE,
SFRAME_V2_S390X_CFA_OFFSET_DECODE): Scale down/up by
SFRAME_S390X_CFA_OFFSET_ALIGNMENT_FACTOR.
libsframe/
* doc/sframe-spec.texi (s390x,
SFRAME_S390X_CFA_OFFSET_ALIGNMENT_FACTOR): Document s390x-
specific CFA offset alignment factor.
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
|
|
In SFrame V2 the size of the offsets following an SFrame FRE can be
either signed 8-bit, 16-bit, or 32-bit integer, with the largest offset
determining their size:
1. CFA offset from CFA base register
2. RA (stack save slot) offset from CFA, usually -48 on s390x if saved
3. FP (stack save slot) offset from CFA, usually -72 on s390x if saved
The FP and RA offsets from CFA, when FP/RA saved on the stack, usually
have fixed values that fit into signed 8-bit SFrame offsets. Likewise
the DWARF register numbers on s390x of general registers (GR; 0-15) and
floating-point registers (FPR; 16-31), when FP/RA saved in registers.
With that the CFA offset from CFA base register has the greatest impact
on the signed SFrame offset size.
The s390x ELF ABI [1] defines the CFA as stack pointer (SP) at call
site +160. [2] Therefore the minimum CFA offset from CFA base register
on s390x is 160. This does not fit into a signed 8-bit integer and
therefore effectively prevents any use of signed 8-bit SFrame offsets
on s390x.
For s390x store the CFA offset from CFA base register adjusted by -160
to enable the use of signed 8-bit SFrame offsets.
[1]: s390x ELF ABI, https://github.com/IBM/s390x-abi/releases
[2]: s390x ELF ABI, commit 4e38ad9c8a88 ("Document the CFA"),
https://github.com/IBM/s390x-abi/commit/4e38ad9c8a88
include/
* sframe.h (SFRAME_S390X_CFA_OFFSET_ADJUSTMENT): Define
s390x-specific CFA offset adjustment.
(SFRAME_V2_S390X_CFA_OFFSET_ENCODE,
SFRAME_V2_S390X_CFA_OFFSET_DECODE): New s390x-specific
macros. Use SFRAME_S390X_CFA_OFFSET_ADJUSTMENT to en-/decode
CFA offset.
bfd/
* elf64-s390.c (elf_s390x_sframe_plt_fre): Use
SFRAME_V2_S390X_CFA_OFFSET_ENCODE on CFA offset to store it
adjusted and switch to 8-bit offsets.
gas/
* gen-sframe.c (sframe_fre_set_cfa_offset): For s390x use
SFRAME_V2_S390X_CFA_OFFSET_ENCODE on CFA offset to store it
adjusted.
(sframe_fre_get_cfa_offset): New helper. For s390x use
SFRAME_V2_S390X_CFA_OFFSET_DECODE on CFA offset to undo its
adjustment.
(sframe_xlate_do_def_cfa_register): Use new helper
sframe_fre_get_cfa_offset.
libsframe/
* sframe.c (sframe_fre_get_cfa_offset): For s390x use
SFRAME_V2_S390X_CFA_OFFSET_DECODE on CFA offset to undo its
adjustment.
* doc/sframe-spec.texi (s390x,
SFRAME_S390X_CFA_OFFSET_ADJUSTMENT,
SFRAME_V2_S390X_CFA_OFFSET_ENCODE,
SFRAME_V2_S390X_CFA_OFFSET_DECODE): Document s390x-specific
adjustment of CFA offset.
libsframe/testsuite/
* libsframe.find/plt-findfre-2.c (add_plt0_fde, add_pltn_fde):
Use SFRAME_V2_S390X_CFA_OFFSET_ENCODE to enable use of 1-byte
SFrame offsets.
Suggested-by: Indu Bhagat <indu.bhagat@oracle.com>
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
|
|
On s390x the PLT0 and PLTN entries are described with one SFrame FRE
each. Add a test case for this particularity.
libsframe/testsuite/
* libsframe.find/find.exp (plt-findfre-2): Add new test.
* libsframe.find/plt-findfre-2.c: New test for PLT0 and PLTN
with only one FRE each.
* libsframe.find/local.mk (plt-findfre-2): Add new test.
libsframe/
* Makefile.in: Regenerate.
|
|
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>
|
|
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>
|
|
This introduces initial support to generate .sframe from CFI directives
in assembler on s390 64-bit (s390x). Due to SFrame V2 format
limitations it has the following limitations, some of them getting
addressed by subsequent patches, which cause generation of SFrame FDE
to be skipped:
- SFrame FP/RA tracking only supports register contents being saved on
the stack (i.e. .cfi_offset). It does not support FP/RA register
contents being saved in other registers (i.e. .cfi_register). GCC on
s390x can be observed to save the FP/RA register contents in floating-
point registers, but only in leaf functions.
This issue is detailed further and resolved in the subsequent commit
"s390: Represent FP/RA saved in register in SFrame".
- SFrame FP/RA tracking cannot represent FP without RA saved. This is
because the format assumes SFrame FDE offset2 to be the RA offset, if
there are two offsets, and offset3 to be the FP offset, if there are
three offsets. There is no mean to distinguish whether offset2 is the
RA or FP offset, if there are only two offsets.
This issue is detailed further and resolved in the subsequent commit
"s390: Represent FP without RA saved in SFrame".
- SFrame assumes a dedicated FP register number. The s390x ELF ABI [1]
does only designate register 11 as preferred FP register number. In
general GCC and Clang on s390x use register 11 as frame pointer.
GCC on s390x can be observed to use register 14 as frame pointer in
the stack clash protector in the function prologue.
glibc on s390x contains hand-written assembler code that uses
register 12 as frame pointer.
This s390x support is largely based on the AArch64 support from commit
b52c4ee46657 ("gas: generate .sframe from CFI directives").
The SFrame ABI/arch identifier SFRAME_ABI_S390X_ENDIAN_BIG is introduced
for s390x and added to the SFrame format specification.
The s390x ELF ABI [1] specifies the following C calling conventions for
s390x architecture:
- Register 15 is the stack pointer (SP).
- Register 14 contains the return address (RA) at function entry.
- There is no dedicated frame pointer register. Register 11 is the
preferred frame pointer (FP). [2] GCC and Clang in general use
register 11 as frame pointer.
- The CFA is defined as SP at call site +160. [3] The SP at call site
can therefore be derived from the CFA using a SP value offset from CFA
of -160.
The s390x ELF ABI [1] does not assign any standard save slot to each
register in the register save area of a stack frame. Neither the
return address (RA, r14) nor preferred frame pointer (FP, r11)
necessarily need to be saved. Therefore SFrame RA and FP tracking is
used.
Support for SFrame on s390 is only enabled for the 64-bit s390x ELF ABI
(z/Architecture with 64-bit addressing mode). It is disabled for the
32-bit s390 ELF ABI (ESA/390 or z/Architecture with 32-bit addressing
mode).
s390x-specific SFrame assembler and linker tests are added, including
error tests for use of a non-preferred frame pointer (FP) register and
specification of a non-default return address (RA) register.
[1]: s390x ELF ABI, https://github.com/IBM/s390x-abi/releases
[2]: s390x ELF ABI, commit f00421825979 ("Add information about the frame
pointer register"),
https://github.com/IBM/s390x-abi/commit/f00421825979
[3]: s390x ELF ABI, commit 4e38ad9c8a88 ("Document the CFA"),
https://github.com/IBM/s390x-abi/commit/4e38ad9c8a88
include/
* sframe.h: Add reference to s390x architecture in comments.
(SFRAME_ABI_S390X_ENDIAN_BIG): Define SFrame ABI/arch identifier
for s390x.
(SFRAME_S390X_SP_VAL_OFFSET): Define s390x-specific SP value
offset from CFA.
libsframe/
* sframe.c (need_swapping): Add SFRAME_ABI_S390X_ENDIAN_BIG.
* doc/sframe-spec.texi (SFRAME_ABI_S390X_ENDIAN_BIG, s390x,
SFRAME_S390X_SP_VAL_OFFSET): Document SFrame ABI/arch identifier
for s390x, add references to s390x architecture, and document
s390x-specifics, such as the SP value offset from CFA of -160.
gas/
* config/tc-s390.h: s390x support to generate .sframe from CFI
directives in assembler.
(support_sframe_p): Define.
(SFRAME_CFA_SP_REG, SFRAME_CFA_FP_REG, SFRAME_CFA_RA_REG):
Define.
(sframe_ra_tracking_p): Define.
(sframe_cfa_ra_offset): Define.
(sframe_get_abi_arch): Define.
* config/tc-s390.c: s390x support to generate .sframe from CFI
directives in assembler.
(s390_sframe_cfa_sp_reg, s390_sframe_cfa_fp_reg,
s390_sframe_cfa_ra_reg): New. Initialize to DWARF register
numbers of stack pointer (SP, r15), preferred frame pointer
(FP, r11), and return address (RA, r14) registers.
(s390_support_sframe_p): New function. Return true if s390x.
(s390_sframe_ra_tracking_p): New function. Return true.
(s390_sframe_cfa_ra_offset): New function. Return
SFRAME_CFA_FIXED_RA_INVALID.
(s390_sframe_get_abi_arch): New function. Return
SFRAME_ABI_S390X_ENDIAN_BIG if s390x, otherwise zero.
* gen-sframe.c: Add reference to s390x architecture in comments.
(sframe_xlate_do_val_offset): Add support for s390x-specific
SFRAME_S390X_SP_VAL_OFFSET.
* NEWS: Add news entry.
gas/testsuite/
* gas/cfi-sframe/cfi-sframe.exp: Enable common SFrame tests for
s390x. Add s390x-specific SFrame (error) tests.
* gas/cfi-sframe/cfi-sframe-s390x-1.d: New s390x-specific SFrame
test.
* gas/cfi-sframe/cfi-sframe-s390x-1.s: Likewise.
* gas/cfi-sframe/cfi-sframe-s390x-2.d: Likewise.
* gas/cfi-sframe/cfi-sframe-s390x-2.s: Likewise.
* gas/cfi-sframe/cfi-sframe-s390x-err-1.d: New s390x-specific
SFrame error test that uses a non-default frame-pointer register
as CFA base register.
* gas/cfi-sframe/cfi-sframe-s390x-err-1.s: Likewise.
* gas/cfi-sframe/cfi-sframe-s390x-err-2.d: Likewise.
* gas/cfi-sframe/cfi-sframe-s390x-err-2.s: Likewise.
* gas/cfi-sframe/cfi-sframe-s390x-err-3.d: New s390x-specific
SFrame error test that uses a non-default return address
register.
* gas/cfi-sframe/cfi-sframe-s390x-err-3.s: Likewise.
* gas/cfi-sframe/cfi-sframe-s390x-fpra-offset-1.d: New s390x-
specific SFrame test that saves RA and FP individually on the
stack.
* gas/cfi-sframe/cfi-sframe-s390x-fpra-offset-1.s: Likewise.
* gas/cfi-sframe/cfi-sframe-s390x-fpra-offset-err-1.d: New
s390x-specific SFrame error test that saves FP and RA
individually, to trigger FP without RA saved.
* gas/cfi-sframe/cfi-sframe-s390x-fpra-offset-err-1.s: Likewise.
* gas/cfi-sframe/cfi-sframe-s390x-fpra-register-err-1.d: New
s390x-specific SFrame error test that saves FP and RA
individually in registers.
* gas/cfi-sframe/cfi-sframe-s390x-fpra-register-err-1.s:
Likewise.
* gas/cfi-sframe/cfi-sframe-s390x-fpra-register-err-2.d: New
s390x-specific SFrame error test that saves RA and FP
individually in registers.
* gas/cfi-sframe/cfi-sframe-s390x-fpra-register-err-2.s:
Likewise.
ld/testsuite/
* ld-s390/s390.exp: Add simple SFrame test.
* ld-s390/sframe-simple-1.d: New simple SFrame test.
* ld-s390/sframe-bar.s: Likewise.
* ld-s390/sframe-foo.s: Likewise.
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
|
|
The .sframe section may have a trailing padding due to the architecture-
specific default section alignment. Do not treat this padding as error
when converting between target and host endianness.
This can be observed when building Binutils with SFrame s390x support on
x86-64 for s390x using configure option "--target=s390x-ibm-linux-gnu"
and running the GAS test suite.
While at it reuse the determined SFrame section header size.
libsframe/
* sframe.c (flip_sframe): Ignore .sframe section padding. Reuse
SFrame header size.
Reported-by: Indu Bhagat <indu.bhagat@oracle.com>
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
|
|
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.
|
|
Add a new flag SFRAME_F_FDE_FUNC_START_PCREL to SFrame stack trace
format. If set, this flag indicates that the function start address
field (sfde_func_start_address) is the offset to the function start
address from the SFrame FDE function start address field itself.
Such an encoding is friendlier to the exisitng PC-REL relocations
available in the ABIs supported in SFrame: AMD64 (R_X86_64_PC32) and
AArch64 (R_AARCH64_PREL32). In subsequent patches, we will make the
implementation in gas and ld to both:
- emit the values in the same (above-mentioned) encoding uniformly.
- set the flag SFRAME_F_FDE_FUNC_START_PCREL in the SFrame header
for consumers to be able to distinguish.
Define SFRAME_V2_F_ALL_FLAGS in sframe.h to help keep the implementation
less error-prone by keeping a set of all defined flags at a central
place. Adjust the check in sframe_header_sanity_check_p () to use the
SFRAME_V2_F_ALL_FLAGS instead.
Add documentation for SFRAME_F_FDE_FUNC_START_PCREL. Update the
documentation about the encoding of the sfde_func_start_address field.
Also, update the section "Changes from Version 1 to Version 2" to
include the specification of the new flag SFRAME_F_FDE_FUNC_START_PCREL
as an erratum to the SFrame Version 2 specification.
include/
* sframe.h (SFRAME_F_FDE_FUNC_START_PCREL): New definition.
(SFRAME_V2_F_ALL_FLAGS): Likewise.
libsframe/
* sframe-dump.c (dump_sframe_header_flags): Update to include
the new flag SFRAME_F_FDE_FUNC_START_PCREL.
* sframe.c (sframe_header_sanity_check_p): Use
SFRAME_V2_F_ALL_FLAGS.
libsframe/doc/
* sframe-spec.texi: Add details about the new flag. Also update
the defails about the sfde_func_start_address encoding.
|
|
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.
|
|
To prepare code for accommodating new flag additions easily as the
format evolves.
libsframe/
* sframe-dump.c (SFRAME_HEADER_FLAGS_STR_MAX_LEN): Remove.
(dump_sframe_header_flags): .. to here. New definition.
(PRINT_FLAG): New definition.
(dump_sframe_header): Move some implementation from here ..
|
|
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.
|
|
When sanity check of SFrame header fails, set error code to
SFRAME_ERR_BUF_INVAL instead of the current SFRAME_ERR_NOMEM.
|
|
Fix PR libsframe/Bug 33051 - ASAN: heap-buffer-overflow
../../src/libsframe/sframe.c:1054 in
sframe_get_funcdesc_with_addr_internal
The previous commit 9d2a24349e2 (libsframe: correct binary search for
SFrame FDE) adapted the binary search logic in
sframe_get_funcdesc_with_addr_internal. Adjusting the upper end of the
search index was missed.
The search must only be done for FDEs starting at index 0 and up until
num_fdes - 1. Prior logic of searching (before commit 9d2a24349e2) was
a bit different.
libsframe/
* sframe.c: Use the correct high index.
|
|
libsframe/doc/
* sframe-spec.texi: Include date with each publication.
|
|
The SFrame FRE start address (fre_start_addr) is defined as unsigned
32-bit integer, as it is an offset from SFrame FDE function start
address (sfde_func_start_address) and functions only grow upwards
(towards higher addresses).
The SFrame FRE start IP offset is a synonym to the SFrame FRE start
address. The SFrame FRE end IP offset is either the value of the
subsequent FDE start address minus one, if that exists, or the FDE
function size minus one otherwise. Both should therefore be handled
as unsigned 32-bit integer.
In libsframe the "lookup PC" (pc) and SFrame FDE function start address
(sfde_func_start_address) are both signed integers, as they are actually
offsets from the SFrame section. The unsigned FDE start/end IP offsets
may therefore only be safely compared against the offset of the lookup
PC from FDE function start address if the FDE function start address is
lower or equal to the lookup PC, as this guarantees the offset to be
always positive:
Given:
lookup_pc = pc - sframe_addr
sfde_func_start_address = func_start_addr - sframe_addr
If the FDE function start address is lower or equal than the lookup PC,
which both are signed offsets from SFrame section, then the function
start address is also lower or equal to the PC, which are both unsigned:
sfde_func_start_address <= lookup_pc
func_start_addr - sframe_addr <= pc - sframe_addr
func_start_addr <= pc
With that the offset of the lookup PC from FDE function start address
(lookup_pc - sfde_func_start_address) must always be positive, if
FDE function start address is lower or equal to the lookup PC:
lookup_pc - sfde_func_start_address
= pc - sframe_addr - (func_start_addr - sframe_addr)
= pc - func_start_addr
libsframe/
* sframe.c (sframe_find_fre): Define and handle start_ip_offset
and end_ip_offset as unsigned (same as FRE fre_start_addr).
(sframe_fre_check_range_p): Likewise. Define PC offset (from
function start address) as unsigned.
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
|
|
The SFrame FREs for an SFrame FDE are sorted on their start address.
Therefore the linear search for a matching SFrame FRE can be stopped,
if its start address is greater than the searched for PC.
libsframe/
* sframe.c (sframe_find_fre): Stop search if FRE's start IP is
greater than PC.
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
|
|
sframe_get_funcdesc_with_addr_internal erroneously returns the last FDE,
if its function start address is lower than the searched for address.
Simplify the binary search for a SFrame FDE for a given address. Only
return an FDE, if the searched for address is within the bounds of the
FDE function start address and function size.
libsframe/
* sframe.c (sframe_get_funcdesc_with_addr_internal): Correct
binary search for SFrame FDE.
libsframe/testsuite/
* libsframe.find/plt-findfre-1.c: Add test for out of range
PLT6.
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
|
|
The testcase had usages of some magic numbers, making it difficult to
keep up when format changes come along.
libsframe/testsuite/
* libsframe.find/findfunc-1.c: Restructure a bit. Run test for two
ways of placement of .sframe and .text.
|
|
The testcase had usages of some magic numbers, making it difficult to
keep up when format changes come along.
libsframe/testsuite/
* libsframe.find/findfre-1.c: Restructure a bit. Run test for two
ways of placement of .sframe and .text.
|
|
SFrame FDEs of type SFRAME_FDE_TYPE_PCMASK are used for repetitive code
patterns, e.g., pltN entries. For SFrame FDEs of type
SFRAME_FDE_TYPE_PCMASK, sframe_fre_check_range_p erroneously tested the
given PC instead of the masked PC offset from function start address.
Therefore it only worked correctly by chance, e.g., if the function start
address was aligned on the repetition block size.
For regular SFrame FDEs the PC offset from function start address must
be within a SFrame FRE's start IP offset and end IP offset. For SFrame
FDEs of type SFRAME_FDE_TYPE_PCMASK, the masked PC offset must be within
that range.
SFrame FRE start/end IP offsets are relative to the SFrame FDE function
start address. For regular SFrame FDEs, the PC offset from function
start address must be within a SFrame FRE's start IP offset and end IP
offset. For SFRAME_FDE_TYPE_PCMASK type FDEs, the masked PC offset must
be within that range.
Exercise the testcase for a variety of placements; without the fix some
of these tests will fail. Also, make the testcase itself easier to
follow by adding appropriate vars where applicable.
libsframe/
* sframe.c (sframe_fre_check_range_p): Fix logic for
SFRAME_FDE_TYPE_PCMASK type FDE.
libsframe/testsuite/
* libsframe.find/plt-findfre-1.c: Adjust the test for a variety
of placements of .sframe and .plt.
Co-Authored-by: Jens Remus <jremus@linux.ibm.com>
|
|
The function start address in a SFrame FDE (sfde_func_start_address)
is encoded as a signed offset to the function start address from the
SFrame section.
The PC range start address in a SFrame FRE (sfre_start_address) is
encoded as an unsigned offset to the range from the function start
address.
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
|
|
|
|
The regeneration was made with Ubuntu automake which has this runstatedir
additional variable, compared to the usual automake.
|
|
Libsframe was missing AC_CANONICAL_TARGET, meaning that --target was
ignored. This could prevent libsframe.a to be installed in some cases,
the host fetching its canonical value while the target isn't. Both
having a different value, INSTALL_LIBBFD would be false.
|
|
Add an appendix to provide a rough outline to show how to generate stack
traces using the SFrame format. Such content should hopefully aid the
reader assimmilate the information in the specification.
libsframe/
* doc/sframe-spec.texi: Add new appendix.
|
|
The recipe to interpret the SFrame FRE stack offsets is
ABI/arch-specific.
Although, there is other information in the specification that is
ABI-specific (like pauth_key usage in AArch64), those pieces of
information are now assimmilated in the SFrame specification in a way
that it is fairly difficult to carve then out into a ABI/arch-specific
section without confusing the readers.
For future though, the specification must strive to keep the generic
parts and ABI/arch-specific parts clearly laid out in separate sections.
libsframe/
* doc/sframe-spec.texi: Reorder and adapt the contents.
|
|
For the SFrame FRE frame-pointer (FP) offset from CFA a 'u' is displayed
if it is unavailable.
For the SFrame FRE return-address (RA) offset from CFA a 'u' was
displayed if the ABI uses a fixed RA offset from CFA. By chance a
'u' was also displayed if the RA offset is unavailable, as the string
buffer was not initialized after formatting the FP offset. Note that it
could not occur that the FP offset was erroneously displayed as RA
offset, as the SFrame format cannot have a FRE with FP offset without
RA offset.
For the FRE RA offset display 'f' if the ABI uses a fixed RA offset
from CFA. Display a 'u' if it is unavailable.
libsframe/
* sframe-dump.c: Display SFrame fixed RA offset as 'f' in dump.
gas/testsuite/
* gas/cfi-sframe/cfi-sframe-common-4.d: Test for RA displayed
either as 'u' (if RA tracking) or as 'f' (fixed RA offset if no
RA tracking).
* 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: Test for RA displayed
as 'f' (fixed RA offset), as x86-64 does not use RA tracking.
* gas/scfi/x86_64/scfi-cfi-sections-1.d: Likewise.
* gas/scfi/x86_64/scfi-dyn-stack-1.d: Likewise.
ld/testsuite/
* ld-x86-64/sframe-plt-1.d: Test for RA displayed as 'f' (fixed
RA offset), as x86-64 does not use RA tracking.
* ld-x86-64/sframe-simple-1.d: Likewise.
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
|
|
The SFrame format allows architectures to specify fixed offsets from the
CFA, if any, from which the frame pointer (FP) and/or return address
(RA) may be recovered. These offsets are stored in the SFrame header.
For instance the SFrame generation in the assembler for x86 AMD64
specifies a fixed offset from the CFA, from which the return address
(RA) may be recovered.
When dumping the SFrame header, for instance in readelf/objdump with
option --sframe, do also dump the specified fixed offsets from the CFA,
if any, from which the frame pointer (FP) and return address (RA) may
be recovered.
Update the common SFrame test case verification patterns to allow for
the optional dumping of the CFA fixed FP/RA offsets. Update the x86-
specific SFrame and SCFI test case verification patterns to require a
CFA fixed RA offset of -8.
libsframe/
* sframe-dump.c: Dump CFA fixed FP and RA offsets.
gas/testsuite/
* gas/cfi-sframe/cfi-sframe-common-1.d: Test for optional fixed
FP and RA offsets.
* 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: Test for fixed
RA offset.
* gas/cfi-sframe/common-empty-1.d: Test for optional fixed
FP and RA offsets.
* 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: Test for SFrame fixed
RA offset.
* gas/scfi/x86_64/scfi-dyn-stack-1.d: Likewise.
ld/testsuite/
* ld-x86-64/sframe-plt-1.d: Test for SFrame fixed RA offset.
* ld-x86-64/sframe-simple-1.d: Likewise.
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
|
|
Update some of the content to make the specification document hopefully
clearer:
- Fix some typos.
- Use Title case consistently for headings.
- Update text around detection of foreign endianness.
- Split the structure field "Name" in each table to two separate
colunms for additional attention: "Type" and "Name".
- Rename "SFrame endianness" section to "SFrame magic number and
endianness"
- Update text around provisions for extending SFrame for future
ABIs/architectures. Make it clear by tagging all provisions with an
explicit index item "Provisions for future ABIs".
- Add a paragraph on sort order of SFrame FDEs.
- Add a statement for SFRAME_F_FRAME_POINTER flag.
- Add a statement to assert that SFrame version 1 is now obsolete and
should not be used.
libsframe/
* doc/sframe-spec.texi: Small improvements for readability.
|
|
https://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.72/autoconf.html#index-AC_005fINIT-2
|
|
When -fsanitize=address,undefined is used to build, the mmap configure
check failed with
=================================================================
==231796==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 4096 byte(s) in 1 object(s) allocated from:
#0 0x7cdd3d0defdf in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
#1 0x5750c7f6d72b in main /home/alan/build/gas-san/all/bfd/conftest.c:239
Direct leak of 4096 byte(s) in 1 object(s) allocated from:
#0 0x7cdd3d0defdf in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
#1 0x5750c7f6d2e1 in main /home/alan/build/gas-san/all/bfd/conftest.c:190
SUMMARY: AddressSanitizer: 8192 byte(s) leaked in 2 allocation(s).
Replace AC_FUNC_MMAP with GCC_AC_FUNC_MMAP to avoid the sanitizer
configure check failure.
bfd/
* configure.ac: Replace AC_FUNC_MMAP with GCC_AC_FUNC_MMAP.
* Makefile.in: Regenerated.
* aclocal.m4: Likewise.
* configure: Likewise.
binutils/
* configure.ac: Replace AC_FUNC_MMAP with GCC_AC_FUNC_MMAP.
* Makefile.in: Regenerated.
* aclocal.m4: Likewise.
* configure: Likewise.
ld/
* configure.ac: Replace AC_FUNC_MMAP with GCC_AC_FUNC_MMAP.
* Makefile.in: Regenerated.
* aclocal.m4: Likewise.
* configure: Likewise.
libctf/
* configure.ac: Replace AC_FUNC_MMAP with GCC_AC_FUNC_MMAP.
* Makefile.in: Regenerated.
* aclocal.m4: Likewise.
* configure: Likewise.
libsframe/
* configure.ac: Replace AC_FUNC_MMAP with GCC_AC_FUNC_MMAP.
* Makefile.in: Regenerated.
* aclocal.m4: Likewise.
* configure: Likewise.
|
|
GCC14 warns about the order of the arguments to calloc
libsframe/sframe-dump.c: In function ‘dump_sframe_header’:
libsframe/sframe-dump.c:70:39: warning: ‘calloc’ sizes specified with ‘sizeof’ in the earlier argument and not in the later argument [-Wcalloc-transposed-args]
70 | flags_str = (char*) calloc (sizeof (char), SFRAME_HEADER_FLAGS_STR_MAX_LEN);
| ^~~~
libsframe/sframe-dump.c:70:39: note: earlier argument should specify number of elements, later size of each element
Fix this by swapping the size and count arguments.
libsframe/
* sframe-dump.c (dump_sframe_header): Swap arguments to calloc
|
|
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.
|
|
This regenerates config files changed by the previous 44 commits.
Note that subject lines in these commits mostly match the gcc git
originating commit.
|
|
Add details for the changes made from Version 1 to Version 2 of the format.
Also add details about alignment in the SFrame format. A portion of the
SFrame stack trace format has an unaligned on-disk representation. Add
description at relevant points in the specificatin to clarify the
alignment related details.
|
|
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.
|
|
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.
|
|
For a toy application on x86_64, for example, following is the SFrame
stack trace information for the 3 pltN entries of 16 bytes each:
func idx [1]: pc = 0x401030, size = 48 bytes
STARTPC[m] CFA FP RA
0000000000000000 sp+8 u u
000000000000000b sp+16 u u
The data in first column is the start_ip_offset. Also note that the FDE
is of type SFRAME_FDE_TYPE_PCMASK (denoted by the [m] on LHS).
Where each pltN (note: excluding plt0 entry) entry looks like:
401030: jmp *0x2fca(%rip)
401036: push $0x0
40103b: jmp 401020<_init+0x20>
401040: jmp *0x2fc2(%rip)
401046: push $0x1
40104b: jmp 401020<_init+0x20>
401050: jmp *0x2fba(%rip)
401056: push $0x2
40105b: jmp 401020<_init+0x20>
Now, to find SFrame stack trace information from an FDE of type
SFRAME_FDE_TYPE_PCMASK, sframe_find_fre () was doing an operation
like,
(start_ip_offset & 0xf) >= (pc & 0xf)
This works for pltN entry of size, say, less than 16 bytes. But if the
pltN entries or similar code stubs (for which SFrame FDE of type
SFRAME_FDE_TYPE_PCMASK may be used), evolve to be of size > 16 bytes,
this will cease to work.
To match the range covered by the SFrame FRE, one should instead perform
a modulo operation. The constant for the modulo operation must be the
size of the pltN entry. Further, this constant should ideally be
encoded in the format, as it may be different for each ABI.
In SFrame Version 2 of the format, we will move towards encoding it
explicitly in the SFrame FDE. For now, fix up the logic to at least
move towards modulo operation.
libsframe/
* sframe.c (sframe_fre_check_range_p): New definition.
(sframe_find_fre): Refactor a bit and use the new definition
above.
include/
* sframe.h (SFRAME_FDE_TYPE_PCMASK): Update comment.
libsframe/doc/
* sframe-spec.texi: Fix the text for SFRAME_FDE_TYPE_PCMASK FDE
type.
|