On aarch64-linux, I run into:
...
(gdb) info auxv^M
...
26 AT_HWCAP2 Extension of AT_HWCAP 0x181^M
29 ??? 0x0^M
31 AT_EXECFN File name of executable 0xffffffffffb9 ...
...
28 AT_RSEQ_ALIGN rseq allocation alignment 32^M
0 AT_NULL End of vector 0x0^M
(gdb) WARNING: Unrecognized tag value: 29 ... ??? ... 0x0^M
FAIL: gdb.base/auxv.exp: info auxv on live process
...
Fix this by handling AT_HWCAP3 in default_print_auxv_entry. Likewise for
AT_HWCAP4.
Tested on aarch64-linux.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32590
Since glibc 2.39, containing commit 3ab9b88 ("powerpc: Add HWCAP3/HWCAP4 data
to TCB for Power Architecture."), glibc's elf/elf.h contains constants
AT_HWCAP3/AT_HWCAP4.
Add these in elf/common.h.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
This is a test-case to make sure that
8eb1701823
("gdb: fix loading compressed scripts from `.debug_gdb_scripts`-section")
doesn't regress.
The test was mostly implemented by Tom Tromey, with the exception of the
check to make sure that the sections are actually compressed and
corrected compiler flags (-Wl,--compress-debug-sections=zlib-gabi was
missing).
This is an individual patch since the actual fix already landed in the
repository.
Approved-By: Tom Tromey <tom@tromey.com>
Nothing seems to use this anymore. However, the private field is still
used internally by buildsym, so keep it.
Change-Id: Ie6fbd96110a3c5603359a483855bbecc4008e5b4
Approved-By: Tom Tromey <tom@tromey.com>
With the removal of the COFF debug info support, nothing uses
buildsym-legacy anymore, remove it.
Change-Id: I46612509889b6868f5889a4347ad8d0a28d29127
Approved-By: Tom Tromey <tom@tromey.com>
This patch removes support for reading in the COFF debug info.
I am not a specialist of the COFF format, but my understanding is that
debug info in the COFF format consisted of extra symbol table entries
describing the standard symbol table entries. For instance, when
compiling without debug info, a function would get a simple symbol
entry, akin to an ELF symbol. We would create a minimal symbol out of
that. When compiling with debug info, that symbol table entry would be
followed by special additional entries, describing things like
parameters and local variables (what would now be in DWARF). We would
create some full symbols out of that.
This patch removes everything that reads this extra information, on the
basis that any target still used today would not use it anymore, having
switched to DWARF instead. We still read the standard symbol table
entries and create minimal symbols out of that. This can be seen when
loading a Windows executable (the only COFF executable kind I know how
to produce):
$ ./gdb -nx -q --data-directory=data-directory -ex "set debug symtab-create 2" -ex "file a.exe"
...
[symtab-create] record_full: recording minsym: mst_file_bss 0x140008018 6 argv
[symtab-create] record_full: recording minsym: mst_file_bss 0x140008008 6 managedapp
[symtab-create] record_full: recording minsym: mst_text 0x1400013e0 0 WinMainCRTStartup
[symtab-create] record_full: recording minsym: mst_text 0x140001400 0 mainCRTStartup
[symtab-create] record_full: recording minsym: mst_text 0x140001420 0 atexit
[symtab-create] record_full: recording minsym: mst_file_data 0x140005000 3 __EH_FRAME_BEGIN__
[symtab-create] record_full: recording minsym: mst_file_bss 0x140008060 6 obj
...
[symtab-create] install: installing 299 minimal symbols of objfile /home/smarchi/src/binutils-gdb/gdb/a.exe
I did not and can't easily test more than that. At least, the remaining
code is understandable enough that I think we would be able to fix any
bug that comes up.
This change should not alter the debugging experience on Windows.
For more info on the COFF symbol table format:
https://www.delorie.com/djgpp/doc/coff/symtab.html
Change-Id: I83220589b8e5b242a4ac42a842e504a4aa47aada
Approved-By: Tom Tromey <tom@tromey.com>
Replace two uses of bfd_map_over_sections with an iteration over
gdb_bfd_sections.
Re-use cs_to_bfd_section in cs_section_address to simplify it.
Change-Id: I2b8f70cc1deba151b7b286affe78a43ac1a26375
Approved-By: Tom Tromey <tom@tromey.com>
This changes the tracepoint code to use make_unique_xstrdup (and
make_unique_xstrndup). This meant changing the types of some members
of uploaded_tp -- but it seems to me that using array types there did
not add any value.
Approved-By: Andrew Burgess <aburgess@redhat.com>
This replaces a number of uses of 'ptr.reset (xstrdup ())'
with 'ptr = make_unique_xstrdup ()'.
The main motivation for this is that, IMO, it's better to avoid the
reset method when possible.
Approved-By: Andrew Burgess <aburgess@redhat.com>
Continuation of fix to VMLA
Bit 12 of the first halfword in the VMLAS instruction is listed as (0)
in the ARMARM (document DDI0553B.w, version ID07072023).
This means that the instruction does not discriminate between signed
and unsigned types and processing elements do not use the bit.
The encoding used by gas was based on an older version
of the document that made the sign important.
This change makes it possible to use vmlas.i8 (16,32) in addition to
vmlas.u8 and vmlas.s8 mnemonics, with the i8, i16 and i32 aliases becoming
the default when disassembling.
The generated encoding sets bit 12 to 0, compatibly with other
assembler implementations.
This patch adds support for MLB invalidate (MLBI) instruction.
Syntax: MLBI <mlbi_op>{, <Xt>}
This instruction is an alias to "SYS #4, C7, C0, #<op2>{, <Xt>}"
and MLBI being the preferred disassembly.
The following list of MLBI operations are supported in this patch for the
MLBI instructions enabled by "+mpamv2"
* alle1
* vmalle1
* vpide1
* vpmge1
On s390 64-bit (s390x) compilers may save the SP, FP, and RA registers,
which are of interest in SFrame, in other registers, such as floating-
point registers, for instance when in a leaf function.
SFrame does not explicitly track the SP. Instead SFrame relies on the
architecture-specific CFA definition to recover the SP. The s390x ELF
ABI [1] defines the CFA as SP at call site + 160, which results in the
implicit SP recovery rule SP = CFA - 160.
Assuming that CFI on s390 64-bit (s390x) adheres to the CFA definition,
it is safe to ignore any CFI directives, that specify the SP register at
entry to be saved either on the stack or in another register, as the SP
can then always be recovered using the implicit SP recovery rule.
[1]: s390x ELF ABI, https://github.com/IBM/s390x-abi/releases
Committed-by: Indu Bhagat <indu.bhagat@oracle.com>
gas/
* gen-sframe.c (sframe_xlate_do_register): Ignore .cfi_register SP
on s390x.
gas/testsuite/
* gas/cfi-sframe/cfi-sframe.exp (cfi-sframe-s390x-err-4): Rename
test to cfi-sframe-s390x-sp-register.
* gas/cfi-sframe/cfi-sframe-s390x-err-4.d: Rename to ...
* gas/cfi-sframe/cfi-sframe-s390x-err-4.s: Likewise.
* gas/cfi-sframe/cfi-sframe-s390x-sp-register.d: This. Test
that .cfi_register SP is ignored.
* gas/cfi-sframe/cfi-sframe-s390x-sp-register.s: Likewise. Add
minimal assembler sample.
This patch adds two new tests for SFrame V3 changes, focusing on the
newly added flexible FDE TYPE SFRAME_FDE_TYPE_FLEX.
Following tests are added:
- be-flipping-v3.c: Validates that big-endian SFrame V3 data is
correctly endian flipped when run on little-endian hosts. It
verifies the decoding of CFA offsets and the new V3 register/offset
metadata bitfields using the SFRAME_V3_FLEX_FDE_OFFSET_REG_* macros.
- findfre-flex-1.c: Tests a variety of sframe_find_fre lookup
scenarios, apart from checking the basic encoder/decoder APIs.
Documentation for the binary test data DATA-BE-V3 is provided in
README-be-flipping-v3 to ensure reproducibility.
libsframe/
* Makefile.in: Regenerate.
* testsuite/libsframe.decode/DATA-BE-V3: New test data.
* testsuite/libsframe.decode/README-be-flipping-v3: New file.
* testsuite/libsframe.decode/be-flipping-v3.c: New test.
* testsuite/libsframe.decode/decode.exp: Run be-flipping-v3.
* testsuite/libsframe.decode/local.mk: Add be-flipping-v3.
* testsuite/libsframe.find/find.exp: Run findfre-flex-1.
* testsuite/libsframe.find/findfre-flex-1.c: New test.
* testsuite/libsframe.find/local.mk: Add findfre-flex-1.
This commit amalgamates a patch set proposed by Jens Remus to enable the
SFrame Version 3 Flexible FDE Type (SFRAME_FDE_TYPE_FLEX) generation for
the s390x ABI.
Previously, s390x relied on architecture-specific encoding (shifting register
numbers into offset fields) to represent register recovery rules. This limited
the complexity of CFI that could be supported. With Flex FDE enabled:
- s390x can now represent .cfi_def_cfa using non-SP/FP registers.
- The architecture-specific function s390_sframe_xlate_do_register () in GAS
is replaced by the generic Flex FDE generation path.
- The SFrame V3 specific macros for s390x register encoding are removed
from libsframe/include, as the generic Flex FDE format handles explicit
register columns natively.
The testsuite is updated to replace negative tests (which asserted
warnings or empty SFrame generation for these patterns) with positive
tests verifying valid Flex FDE generation.
Co-authored-by: Jens Remus <jremus@linux.ibm.com>
gas/
* config/tc-s390.c (s390_support_flex_fde_p): Return true to
enable Flex FDE generation.
* gen-sframe.c (s390_sframe_xlate_do_register): Disable s390x
specific implementation.
(sframe_xlate_do_register): Invoke generic Flex FDE path now
that flex FDE generation is supported.
gas/testsuite/
* gas/cfi-sframe/cfi-sframe-s390x-err-1.d: Removed.
* gas/cfi-sframe/cfi-sframe-s390x-err-1.s: Moved to...
* gas/cfi-sframe/cfi-sframe-s390x-non-spfp-cfa-1.s: ...here.
* gas/cfi-sframe/cfi-sframe-s390x-err-2.d: Removed.
* gas/cfi-sframe/cfi-sframe-s390x-err-2.s: Moved to...
* gas/cfi-sframe/cfi-sframe-s390x-non-spfp-cfa-2.s: ...here.
* gas/cfi-sframe/cfi-sframe-s390x-fpra-register-1.d: Update to
expect Flex FDE output.
* gas/cfi-sframe/cfi-sframe-s390x-fpra-register-2.d: Likewise.
* gas/cfi-sframe/cfi-sframe.exp: Run renamed tests.
include/
* sframe.h (SFRAME_V3_S390X_OFFSET_IS_REGNUM): Remove.
(SFRAME_V3_S390X_OFFSET_ENCODE_REGNUM): Remove.
(SFRAME_V3_S390X_OFFSET_DECODE_REGNUM): Remove.
libsframe/
* sframe-dump.c (sframe_s390x_offset_regnum_p): Return false
for SFrame V3.
(sframe_s390x_offset_decode_regnum): Remove V3 support.
Update the SFrame specification to document Version 3. This version
introduces fundamental changes to support additional scenarios (e.g.,
s390x register-based recovery, x86_64 DRAP) using a 'Flexible FDE'
definition while maintaining compactness for standard frames.
Key changes documented include:
- The SFrame Function Descriptor Entry (FDE) is split into two
distinct structures:
[sframe_func_desc_idx] Fixed-size index for binary search.
[sframe_func_desc_attr] Variable-location attributes including new
info bytes.
- Flexible FDEs (SFRAME_FDE_TYPE_FLEX)
A new FDE type that interprets FRE bytes not as simple stack
offsets, but as pairs of "Control Data" and "Offset". This
allows encoding complex recovery rules (e.g., "CFA = *(RBP - 8)")
without bloating the format for standard cases.
- Provision for defining new FDE types in future. A total of 5 bits
are reserved for this purpose.
- Make explicit distinction between FDE Types vs. PC Type
[FDE Type] Defines how to interpret stack trace data (Default vs. Flex).
[PC Type] Defines how PCs are advanced for an FDE (Increment vs. Mask).
- Other renames like sfde_func_start_address is renamed to
sfdi_func_start_offset to accurately reflect that it is a relative
offset, not an absolute address.
- Remove SFRAME_F_FRAME_POINTER from SFrame V3. The corresponding bit
is now unused in SFrame V3.
libsframe/doc/
* sframe-spec.texi: Update text for SFrame Version 3.
(Changes from Version 2 to Version 3): New section.
(The SFrame FDE Index): New section documenting sframe_func_desc_idx.
(The SFrame FDE Attribute): New section documenting
sframe_func_desc_attr.
(The SFrame FDE Info Bytes): Expanded to document sfda_func_info and
sfda_func_info2 split.
(The SFrame FDE PC Types): Document SFRAME_V3_FDE_PCTYPE_INC and
SFRAME_V3_FDE_PCTYPE_MASK.
(The SFrame FDE Types): Document SFRAME_FDE_TYPE_DEFAULT and
SFRAME_FDE_TYPE_FLEX.
(Interpretation of SFrame FREs): Split into Default and Flexible
interpretation.
(Flexible FDE Type Interpretation): Document the Control
Data/Offset pair encoding.
SFrame V3 has 8 precious flag bits, two of which are being used. More
flag byte (s) can be added to the auxiliary header when it comes to
that. But for now, it may be worthwhile to use the 8-bits frugally.
SFRAME_F_FRAME_POINTER flag bit was added with the intention of marking
binaries built with frame-pointer preserved. A stack tracer could then
use this information, to unambiguously ascertain whether frame-pointer
based stack traces will be precise. But such a marking of binary will
ideally be done by the linker, and at the moment adding such a framework
is not justified for such small gain. The outcome of this is that
SFRAME_F_FRAME_POINTER is never set in SFrame V2 binaries.
Remove the definition SFRAME_F_FRAME_POINTER for SFrame V3. The
relinquished bit can be used (in future format incarnations) when
reading/dumping SFrame V2 sections are no longer supported by consumers.
Changing the values of existing flags, e.g.,
SFRAME_F_FDE_FUNC_START_PCREL, is not being done for V3, to avoid
version-specific flag bit reading (albeit doable) in consumers.
Related changes to the specification are done in a subsequent commit.
include/
* sframe.h (SFRAME_V3_F_ALL_FLAGS): Remove
SFRAME_F_FRAME_POINTER from the set of V3 flags.
libsframe/
* sframe-dump.c (dump_sframe_header_flags): Add a comment for
clarity.
In this test, two "special" case FDEs are linked:
- Signal frame where the SFrame stack trace data is not
representable.
- _start like outermost frame function.
This is useful test for sframe_encoder's merge input sections
functionality and its associated write code-paths (sframe_encoder_write)
too.
ld/testsuite/
* ld-x86-64/sframe-link-1.d: New test.
* ld-x86-64/sframe-signal.s: New input file.
* ld-x86-64/sframe-start.s: Likewise.
* ld-x86-64/x86-64.exp: Add new test.
Add a new command line option --discard-sframe to the linker.
This option allows users to prevent the linker from generating an output
.sframe section.
The rationale for this option is: Consider the case when say, the distro
is shipped with SFrame sections in the installed binaries/libraries. A
user application using these installed libraries, but not enabling
.sframe for itself just yet, will see an output .sframe corresponding to
the pulled in libraries. This is "partial" .sframe information for the
application. Adding such an option to the linker, gives user a way to
turn off the .sframe section completely without relying on a linker
script.
Previously, the existing --no-ld-generated-unwind-info option
controlled whether (not just .eh_frame for PLT entries, but also) SFrame
for PLT entries. The new command line option,
--discard-sframe now decouples SFrame from other unwind
formats (like .eh_frame), allowing for more control over the output
binary's SFrame data.
The option is added for architectures that currently support SFrame:
AArch64, s390x, and x86_64.
bfd/
* elf-sframe.c (_bfd_elf_parse_sframe): Mark with SEC_EXCLUDE if
--discard-sframe is in effect.
* elf64-s390.c (elf_s390_create_dynamic_sections): Use
discard_sframe to guard .sframe section creation.
* elfxx-x86.c (_bfd_x86_elf_link_setup_gnu_properties): Likewise.
include/
* bfdlink.h (struct bfd_link_info): Add discard_sframe bitfield.
ld/
* ldlex.h (enum option_values): Add OPTION_NO_LD_SFRAME_INFO.
* lexsup.c (elf_sframe_list_options): New function.
(ld_list_options): Add sframe_info argument. Update callers.
* ld.texi: Update documentation.
* emulparams/sframe-info.sh: New file.
* emultempl/aarch64elf.em: Add --discard-sframe option
listing and handling.
* emulparams/elf64_s390.sh: Likewise.
* emulparams/elf_x86_64.sh: Likewise.
* Makefile.am: Update to handle sframe-info.sh and new list options.
* configure.ac: Handle SFRAME_INFO target variable.
* Makefile.in: Regenerate.
* configure: Regenerate.
ld/testsuite/
* ld-x86-64/x86-64.exp: New test.
* ld-x86-64/sframe-command-line-1.d: New test.
* ld-aarch64/aarch64-elf.exp: New test.
* ld-s390/s390.exp: New test.
* ld-x86-64/x86-64.exp: New test.
* ld-aarch64/sframe-command-line-1.d: New test.
* ld-s390/sframe-command-line-1.d: New test.
* ld-x86-64/sframe-command-line-1.d: New test.
This option will allow users to select emission of SFrame stack trace
information as per the SFrame version 3 specification. Currenly, SFrame
version 3 is also the default.
In future, as SFrame evolves, similar command line args may be added for
future versions.
gas/
* as.c (enum gen_sframe_version): New definition.
(parse_args): Add option processing for --gsframe-3.
* as.h (enum gen_sframe_version): New declaration.
* doc/as.texi: Document the new option.
* gen-sframe.c (sframe_set_version): Use enum gen_sframe_version
as version.
(output_sframe): Likewise.
gas/testsuite/
* gas/cfi-sframe/cfi-sframe.exp: New test.
* gas/cfi-sframe/cfi-sframe-common-1d.d: Test new command line
option --gsframe-3.
* gas/cfi-sframe/cfi-sframe-common-1d.s: Likewise.
This patch introduces a structural change to the SFrame V3 format. It
shifts the SFrame Function Descriptor Entry (FDE) (a physical entity in
SFrame V2) into a conceptual one in SFrame V3, such that an FDE is now
split into two distinct parts to optimize the binary search table and
data organization:
- FDE Index (sframe_func_desc_idx_v3): This structure contains the
essential indexing information: the function start address offset,
function size in bytes, and the offset to the SFrame FDE
attribute/Frame Row Entries (FREs) area for the function.
- FDE Attributes (sframe_func_desc_attr_v3): The metadata regarding the
function (number and size of FREs, FDE type, and repetition block
size etc.) is moved to a new structure.
On-Disk Layout: In V3, the "Attributes" are now stored immediately
preceding the SFrame FREs for that function. The sfde_func_start_fre_off
now points to the attr structure, and the actual FREs follow immediately
after. IOW, the "Attributes" are now moved to the FRE sub-section,
located immediately preceding the FREs for the respective function.
The above layout has the advantage that:
a) its cleaner with separation between the index elements vs other data
b) the index has better cache locality (by virtue of it being smaller
than the layout in SFrame V2).
c) As the format evolves, the guarantees of alignment for FDE index
are easier to maintain. FDE attr, being in the SFrame FRE
sub-section, carry no guarantees of alignment.
This had been previously suggested and communicated in an earlier
discussion on binutils mailling list
https://inbox.sourceware.org/binutils/29b1f7b0-61ea-410c-8aca-d5dd6115e668@oracle.com/
The read/write paths in sframe.c are updated to account for this split.
sframe_fde_tbl_init now requires access to the FRE buffer to populate
the internal FDE table, as the attributes are no longer resident in the
FDE section.
flip_sframe is refactored into version-specific handlers (_v2 and _v3)
because the endian-swapping logic now differs significantly. In V3, the
iterator must jump from the FDE table to the FRE section to swap the
attributes.
Lastly, the two entities generating SFrame sections (GAS and GNU ld)
both now must _not_ set the sfde_func_start_fre_off to zero, when the
number of FREs is zero. This is because now there will be some valid
attr data at that location.
Backward Compatibility: Due to the need to support readelf/objdump for
SFrame V2 sections, the patch explicitly maintains V2 support via
separate code paths (e.g., flip_sframe_fdes_with_fres_v2)
Note about alignment: Now that the sframe_func_desc_idx_v3 is refactored
out of the conceptual SFrame FDE, SFrame FDE index member elements are
at aligned boundaries again. The alignment property for SFrame FDE was
broken from an ealier patch "[08/36] sframe: gas: libsframe: use
uint16_t for num_fres of FDE" up until this one.
include/
* sframe.h (sframe_func_desc_entry_v3): Remove sfde_func_num_fres,
sfde_func_info, sfde_func_info2, and sfde_func_rep_size. Rename
to sframe_func_desc_idx_v3.
(sframe_func_desc_attr_v3): New SFrame FDE attribute structure.
libsframe/
* sframe.c (sframe_fde_tbl_init): Add argument for FRE buffer.
Read attributes from the FRE section for V3.
(flip_fde_desc): Rename from flip_fde. Check size against
sframe_func_desc_entry_v3.
(flip_fde_attr_v3): New function.
(sframe_decode_fde_desc_v2): New function extracted from
sframe_decode_fde.
(sframe_decode_fde_desc_v3): New function.
(sframe_decode_fde_attr_v3): New function.
(flip_sframe_fdes_with_fres_v2): New function for V2 flipping.
(flip_sframe_fdes_with_fres_v3): New function for V3 flipping.
(flip_sframe): Dispatch to version-specific flip functions.
(sframe_decode): Pass FRE buffer to sframe_fde_tbl_init.
(sframe_decoder_get_offsetof_fde_start_addr): Adjust for subset
of sframe_func_desc_entry_v3 restructured into
sframe_func_desc_idx_v3.
(sframe_encoder_get_offsetof_fde_start_addr): Likewise.
(sframe_find_fre): Skip attribute size to find FREs in V3.
(sframe_decoder_get_fre): Likewise.
(sframe_decoder_get_fres_buf): Likewise.
(sframe_encoder_add_fre): Add attribute size to byte count.
(sframe_encoder_add_fres_buf): Read attributes from buffer.
(sframe_encoder_write_fde): Write only FDE index fields.
(sframe_encoder_write_func_attr): New function.
(sframe_encoder_write_sframe): Write FDE attributes before FREs.
gas/
* gen-sframe.c (output_sframe_funcdesc): Do not reset
sfde_func_start_fre_off to zero when zero num FREs.
(output_sframe_func_desc_attr): New refactored out function.
(output_sframe_internal): Invoke output_sframe_func_desc_attr.
libsframe/testsuite/
* libsframe.decode/DATA2: Regenerate data file.
At link time, in _bfd_elf_merge_section_sframe (), it suffices to bring
over the all per-function stack trace metadata (all FREs) as a blob into
the SFrame encoder object. There is no need to "decode" each SFrame
FRE, only to add them in a serial fashion.
This is an optimization, and not directly related to any SFrame V3
related changes to the specification. This should also bring us a step
closer to supporting SFrame for targets which use linker relaxations.
Removing the need to decode the input FREs can allow the linker to
simply use the available set of FREs from (relocated) contents. To
support targets using linker relaxations in SFrame, other changes in the
SFrame parse functionality time may also be necessary, but this brings
us just a step closer.
Add two new APIs to accomplish this:
- sframe_decoder_get_fres_buf, and
- sframe_encoder_add_fres_buf
bfd/
* elf-sframe.c (_bfd_elf_merge_section_sframe): Get all FRE data
and add it all in bulk.
libsframe/
* libsframe.ver: Add new APIs.
* sframe.c (sframe_buf_fre_entry_size): New internal API to get
size of one SFrame FRE at the indicated buffer location, without
fully "decoding" the SFrame FRE.
(sframe_decoder_get_fres_buf): New definition.
(sframe_encoder_add_fres_buf): New definition.
include/
* sframe-api.h (sframe_decoder_get_fres_buf): New declaration.
(sframe_encoder_add_fres_buf): New declaration.
With the introduction of flex FDE type, handling .cfi_offset for
RA needs adjustment.
On architectures like x86_64, the return address (RA) is typically saved
at a fixed offset from the CFA. Previous versions of the SFrame format
assumed this fixed offset was invariant for the entire function on such
architectures. Consequently, GAS would warn and suppress SFrame
generation if it encountered a .cfi_offset directive for the RA
register that deviated from this fixed default.
SFrame V3 introduces "Flex FDEs" which allows tracking the RA location
explicitly even on architectures where it is usually fixed.
This patch updates sframe_xlate_do_offset () to leverage Flex FDEs. When
processing a .cfi_offset for the RA register:
- The check for non-representable RA offsets is relaxed. If the ABI
supports Flex FDEs (SFrame V3), GAS proceeds instead of issuing a
warning.
- For ABIs without explicit RA tracking (like AMD64), if the RA
offset differs from the default fixed offset, the FDE is marked as a
Flex FDE, and the new stack location is recorded.
- Logic is added to detect when the RA is restored to its standard
fixed offset. In this case, the tracking state is reset (ra_loc set
to SFRAME_FRE_ELEM_LOC_NONE), deferring to the ABI's default fixed RA
offset behavior.
gas/
* gen-sframe.c (sframe_xlate_do_offset): Support .cfi_offset for RA
by switching to Flex FDEs when necessary.
gas/testsuite/
* gas/cfi-sframe/cfi-sframe-x86_64-6.d: New test.
* gas/cfi-sframe/cfi-sframe-x86_64-6.s: New test to check
transition of location of REG_RA from register to CFA-8 (default
location on AMD64). Flex FDE in effect.
* gas/cfi-sframe/cfi-sframe.exp: Add new test.
SFrame does not track the SP. For recovery of the SP, SFrame relies on
the architecture/ABI's CFA definition:
CFA = SP [+ offset // on s390x]
Which results in the following implicit CFA value offset rule for SP:
SP = CFA [- offset // on s390x]
Where offset is zero for most architectures/ABIs, except s390x.
Therefore .cfi_register SP, reg directives must be rejected, as such
semantics cannot be represented in SFrame yet.
gas/
* gas/gen-sframe.c (s390_sframe_xlate_do_register): Check for
REG_SP and reject while generating a warning.
(sframe_xlate_do_register): Likewise.
gas/testsuite/
* gas/cfi-sframe/cfi-sframe-s390x-err-4.d: New test.
* gas/cfi-sframe/cfi-sframe-s390x-err-4.s: Likewise.
* gas/cfi-sframe/cfi-sframe-x86_64-empty-5.d: Likewise.
* gas/cfi-sframe/cfi-sframe-x86_64-empty-5.s: Likewise.
* gas/cfi-sframe/cfi-sframe.exp: Add new tests.
Use SFrame FDE of type SFRAME_FDE_TYPE_FLEX_TOPMOST_FRAME.
When FP, RA were moved to a general-purpose register, the SFrame
generation previously warned and skipped the FDE (except on s390x).
This patch updates the translator to detect .cfi_register for RA (and
FP), tracks the destination register in the SFrame row entry,
and emits the register in the relevant FRE offsets in SFrame FDE type
SFRAME_FDE_TYPE_FLEX.
gas/
* gen-sframe.c (sframe_row_entry_initialize): Propagate ra_reg
and ra_deref_p.
(sframe_xlate_do_register): Handle .cfi_register for RA/FP on
AMD64 by setting flex_p and recording the register.
gas/testsuite/gas/
* cfi-sframe/cfi-sframe.exp: Run new test.
* cfi-sframe/cfi-sframe-x86_64-5.d: New test.
* cfi-sframe/cfi-sframe-x86_64-5.s: Simple test for checking
FLEX FDE generation for `.cfi_register REG_RA, XX`.
* cfi-sframe/cfi-sframe-x86_64-esc-expr-3.d: New test.
* cfi-sframe/cfi-sframe-x86_64-esc-expr-3.s: New test with DWARF
expression for REG_FP, followed by .cfi_register and .cfi_offset
for REG_FP.
* cfi-sframe/cfi-sframe-x86_64-ra-undefined-flex-1.d: New test.
* cfi-sframe/cfi-sframe-x86_64-ra-undefined-flex-1.s: New test
for FLEX FDE with undefined RA.
gas/testsuite/
* gas/cfi-sframe/cfi-sframe-x86_64-4.d: New test.
* gas/cfi-sframe/cfi-sframe-x86_64-4.s: Non SP/FP based CFA.
* gas/cfi-sframe/cfi-sframe-x86_64-esc-expr-1.d: New test.
* gas/cfi-sframe/cfi-sframe-x86_64-esc-expr-1.s: DRAP pattern
with both CFA expression and FP expression.
* gas/cfi-sframe/cfi-sframe-x86_64-esc-expr-2.d: New test.
* gas/cfi-sframe/cfi-sframe-x86_64-esc-expr-2.s: Test CFA
expression with sleb128.
* gas/cfi-sframe/cfi-sframe.exp: Add new tests.
This patch updates the SFrame generation in GAS to translate specific
.cfi_escape directives into the new SFrame V3 FDE type
SFRAME_FDE_TYPE_FLEX.
The primary goal is to support code patterns where:
- the Canonical Frame Address (CFA) is not defined by a simple offset
from the Stack Pointer (SP) or Frame Pointer (FP), or where the CFA
rule involves a dereference. Such patterns are generated by compilers
for stack realignment (e.g., DRAP on x86_64, or when mixing legacy
codes that keep 4-byte stack alignment with modern codes that keep
16-byte stack alignment for SSE compatibility).
- the Frame Pointer is not defined by a simple offset from the CFA,
but may even involve another register and/or dereferencing.
- the Return Address is not defined by a simple offset from the CFA,
but may even involve another register and/or dereferencing.
Support for non-SP/FP based CFA: Update sframe_xlate_do_def_cfa () and
sframe_xlate_do_def_cfa_register () to detect when a non-SP/FP register
is used for the CFA.
Support for CFA expressions: A vital part of supporting the
above-mentioned cases on AMD64 is support for CFA expressions. Add
sframe_xlate_do_escape_cfa_expr () to parse simple
DW_CFA_def_cfa_expression sequence in .cfi_escape.
Support for FP expressions: Update sframe_xlate_do_escape_expr () to
handle DW_CFA_expression involving DW_OP_breg6 (rbp) on AMD64,
allowing for tracking of the Frame Pointer when it is saved with a
dereference rule in the DRAP pattern.
The "support" for both CFA expressions and FP expressions is quite
minimal, and is tailored to the most commonly seen occurrences generated
by GCC for AMD64.
gas/
* gas/gen-sframe.c (output_sframe_row_entry_offsets):
(sframe_xlate_do_def_cfa): Handle non-SP/FP CFA registers by setting
flex_p for AMD64.
(sframe_xlate_do_def_cfa_register): Likewise.
(sframe_xlate_escape_sleb128_to_int64): New definition.
(sframe_xlate_do_escape_cfa_expr): New function to handle
DW_CFA_def_cfa_expression of specific shapes.
(sframe_xlate_do_escape_expr): Update to handle dereferenced FP rules.
(sframe_xlate_do_cfi_escape): Invoke sframe_xlate_do_escape_cfa_expr ().
(create_sframe_all): In case of error, but when signal frame is
also true, there cannot be a flex FDE.
For the newly added SFrame FDE type SFRAME_FDE_TYPE_FLEX, add a new
backend hook so that the respective ABI/arch can opt out of the
generation of SFRAME_FDE_TYPE_FLEX in GAS.
AArch64 is an example of an ABI for which SFrame is supported, but one
that does not need the flexible FDE representation for any of the
current usecases currently.
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
gas/
* config/tc-aarch64.c (aarch64_support_flex_fde_p): New
definition.
* config/tc-aarch64.h (aarch64_support_flex_fde_p): New
declaration.
(sframe_support_flex_fde_p): Define.
* config/tc-i386.c (x86_support_flex_fde_p): New definition.
* config/tc-i386.h (x86_support_flex_fde_p): New declaration.
(sframe_support_flex_fde_p): Define.
* config/tc-s390.c (s390_support_flex_fde_p): New definition.
* config/tc-s390.h (s390_support_flex_fde_p): New declaration.
(sframe_support_flex_fde_p): Define.
Refactor the SFrame textual dumper in sframe-dump.c to properly handle
the new FDE type.
In SFrame V2, the textual dumper could afford to be oblivious to the
exact DWARF register number for stack-pointer and frame-pointer
registers in each ABI. This is because a single bit was used to
differentiate between the two (irrespective of the ABI), and the dumper
could easily just use a:
const char *base_reg_str[] = {"fp", "sp"};
to get the register name.
With the introduction of new SFrame FDE type SFRAME_FDE_TYPE_FLEX, which
carry DWARF register numbers if applicable, this needs to change. E.g.,
for some patterns on AMD64, one may see CFA is the value at 'r10+0'; or
FP is the value at 'rbp+8'. This means that for textual dump, we now
need a mapping from:
- the ABI-specific frame-pointer to string "fp"
- the ABI-specific stack-pointer to string "sp"
This is done via the SFRAME_ABI_REG_MAP helper macros and the new
sframe_get_reg_name () API.
For registers other than stack-pointer and frame-pointer, the SFrame
textual dump does not print the register name (say, "rax"), but just the
number (i.e., "r0").
Check the func_info2 byte and dispatch the stack frame row entry (FRE)
dumping to the correct function: either dump_sframe_func_fre_simple or
dump_sframe_func_fre_flex.
Ensure the display is consistent to previous semantics. When flex FDE
is in effect, there may not always be an RA offset (after the CFA
offsets). A padding offset for RA is present if FP offsets follow. So
if a padding offset for RA is seen, we will display "U". If no RA
offset is seen, however, we will display a "u" unless its an ABI where
RA offset is fixed (in the latter case we display "f").
libsframe/
* sframe-dump.c (SFRAME_SP): Define mapping from stack-pointer
register number to "sp".
(SFRAME_FP): Define mapping from frame-pointer register number
to "fp".
(SFRAME_ABI_REG_MAP): Helper macro to define per-ABI-arch
mappings.
(sframe_get_reg_name): Helper API to get register name.
(dump_sframe_func_with_fres): Refactor a bit...
(dump_sframe_func_fre_simple): ..into this.
(sframe_format_fre_disp): New definition.
(dump_sframe_func_fre_flex): Likewise.
(dump_sframe): Allow both SFrame version 2 and version 3.
For FDE type SFRAME_FDE_TYPE_FLEX, the offsets are not only laid out
differently, they also have different encoding:
- first data item is of unsigned type, it indicates the "Control Word"
- second data item is of signed type, it indicates the "Offset Word"
(The usage of "Word" above is colloquial, does not indicate a machine word of
a specific size.)
Adjust the APIs in libsframe to get stack frame offsets by adding a new
argument type. Also add a new API to read the data items as unsigned
types of the specified size: sframe_get_fre_udata.
At the moment, like the generation routines in GAS, the textual dump
routines in sframe-dump.c are also unaware of the FDE type
SFRAME_FDE_TYPE_FLEX. In the next commits, these capabilities will be
added.
include/
* sframe-api.h (MAX_NUM_STACK_OFFSETS): Increase the number of
stack offsets to 6 to accommodate the FDE type
SFRAME_FDE_TYPE_FLEX.
(sframe_get_fre_udata): New declaration.
(sframe_fre_get_cfa_offset): Add new arg.
(sframe_fre_get_fp_offset): Likewise.
(sframe_fre_get_ra_offset): Likewise.
libsframe/
* libsframe/sframe-dump.c (dump_sframe_func_with_fres): Pass
SFRAME_FDE_TYPE_DEFAULT for FDE type.
* sframe.c (sframe_fre_get_cfa_offset): Handle FDE type.
(sframe_fre_get_fp_offset): Likewise.
(sframe_fre_get_ra_offset): Likewise.
* libsframe/libsframe.ver: Add new API sframe_get_fre_udata.
libsframe/testsuite/
* libsframe.find/findfre-1.c: Pass SFRAME_FDE_TYPE_DEFAULT for
FDE type.
* libsframe.find/findfunc-1.c: Likewise.
* libsframe.find/plt-findfre-1.c: Likewise.
* libsframe.find/plt-findfre-2.c: Likewise.
This patch updates the routines for emission of the new FDE type
SFRAME_FDE_TYPE_FLEX in the SFrame output section. The support for
generating these flex FDEs themselves is added in a subsequent commit.
Update struct sframe_row_entry to track additional state for CFA,
FP, and RA. Modify output_sframe_row_entry_offsets () to emit
metadata/offset pairs for flexible FDEs or padding where applicable,
ensuring the usual ordering (CFA, RA, FP). The padding data, a.k.a.
SFRAME_FRE_RA_OFFSET_INVALID is emitted in flexible FDEs when RA is
untracked but FP offsets follow. Trailing padding offsets should not
occur. Add a new function get_udata_size_in_bytes () to account for
sizing of unsigned register metadata.
gas/
* gen-sframe.c (get_udata_size_in_bytes): Get size of unsigned
int data in bytes.
(get_fre_num_offsets): Handle SFRAME_FDE_TYPE_FLEX.
(sframe_get_fre_offset_size): Account for register metadata
in flexible FDEs.
(output_sframe_row_entry_offsets): Add logic for flexible
FDE offset pairs.
(output_sframe_row_entry): Reset base register for flex FDEs.
(output_sframe_funcdesc): Emit FDE type in func_info2.
(sframe_xlate_ctx_init): Initialize flex_p.
(sframe_xlate_ctx_finalize): Finalize flex_p status.
(sframe_row_entry_initialize): Copy new deref tracking bits.
(sframe_xlate_do_offset): Set deref bits during translation.
* gen-sframe.h (struct sframe_row_entry): Add cfa_deref_p,
fp_deref_p, and ra_deref_p.
(struct sframe_func_entry): Add fde_flex_p.
(struct sframe_xlate_ctx): Add flex_p.
Up until now, for SFrame stack trace data generation (for default FDE
type), keeping two states sufficed to distinguish between the following
cases:
- the tracked entity is saved on a location on stack (identified by
SFRAME_FRE_ELEM_LOC_STACK)
- the tracked entity is in its designated register (identified by
SFRAME_FRE_ELEM_LOC_REG).
Soon though, we will start to generate a new FDE type
SFRAME_FDE_TYPE_FLEX, where in addition to above:
- the tracked entity may be saved in a temporary register
- the tracked entity may be saved at a "non-standard" location, e.g.,
not a simple CFA+offset based location
- and other cases
To effectively distinguish between the various states (necessary to
track for flex FDEs), define three states to track the location of each
tracked entity:
- SFRAME_FRE_ELEM_LOC_NONE: the entity is in its desginated location
(e.g., in case of AMD64 where the RA is at fixed offset from CFA)
- SFRAME_FRE_ELEM_LOC_REG: the entity is in a location based off a
register
- SFRAME_FRE_ELEM_LOC_STACK: the entity is in a location based off the
CFA
While at it, rather than asserting in sframe_xlate_do_offset (), reset
the fp_reg state to SFRAME_FRE_REG_INVALID. This is in preparation for
upcoming flex FDE generation patches.
Co-Authored-by: Jens Remus <jremus@linux.ibm.com>
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
gas/
* gen-sframe.c (sframe_xlate_do_offset): Reset other state.
(sframe_xlate_do_same_value): Reset to SFRAME_FRE_ELEM_LOC_NONE.
* gen-sframe.h (SFRAME_FRE_ELEM_LOC_REG): New definition.
(SFRAME_FRE_ELEM_LOC_STACK): Likewise.
(SFRAME_FRE_ELEM_LOC_NONE): Likewise.
In SFrame V2, we did use the the term 'FDE Type' for the two designated
'PC Type' for the SFrame FDEs (SFRAME_FDE_TYPE_PCINC,
SFRAME_FDE_TYPE_PCMASK). In hindsight, 'FDE Type' was an inappropriate
term for the said intent. Fix this terminology by defining two new
constants:
- SFRAME_V3_FDE_PCTYPE_MASK
- SFRAME_V3_FDE_PCTYPE_INC
The old constants from V2 (SFRAME_FDE_TYPE_PCINC,
SFRAME_FDE_TYPE_PCMASK) remain, but are now unused in the codebase.
The term 'FDE Type' should be used for the actual FDE Types. In a
subsequent commit, we will add SFRAME_FDE_TYPE_FLEX FDE Type for SFrame
V3.
bfd/
* elf64-s390.c (_bfd_s390_elf_create_sframe_plt): Rename
inappropriate SFRAME_FDE_TYPE_PCINC to SFRAME_V3_FDE_PCTYPE_INC.
* elfxx-x86.c (_bfd_x86_elf_create_sframe_plt): Likewise. Also
rename inappropriate SFRAME_FDE_TYPE_PCMASK to
SFRAME_V3_FDE_PCTYPE_MASK.
gas/
* gen-sframe.c (output_sframe_funcdesc): Likewise.
* sframe-opt.c (sframe_convert_frag): Likewise.
libsframe/
* sframe-dump.c (dump_sframe_func_with_fres): Likewise.
* sframe.c (sframe_fre_check_range_p): Likewise.
(sframe_fde_create_func_info): Likewise.
libsframe/testsuite/
* libsframe.encode/encode-1.c: Likewise.
* libsframe.find/findfre-1.c: Likewise.
* libsframe.find/findfunc-1.c: Likewise.
* libsframe.find/plt-findfre-1.c: Likewise.
* libsframe.find/plt-findfre-2.c: Likewise.
In SFrame V2, the FDE representation caters to the most common cases of
stack trace metadata:
- CFA is SP/FP based,
- FP/RA offsets, if present are CFA based (except some cases in s390x
where reg can be encoded).
Introduce an additional FDE type SFRAME_FDE_TYPE_FLEX, which can encode
a more flexible set of CFA, FP and RA recovery rules. Some of the
patterns supported include:
- CFA may be non-SP/FP based.
- CFA, FP may encode dereferencing of register after offset adjustment
- RA may be in a non-default register.
The important bit here is that since SFrame does not track all
callee-saved registers, the above-mentioned recovery rules must only be
done for topmost frames (by the stack tracer).
Adding a new FDE type does have implications for a stack tracer in that
it needs to:
- Check the FDE type before interpreting the variable length bytes
trailing the SFrame FRE header as stack offsets.
- If the FDE type is SFRAME_FDE_TYPE_FLEX, and the
recovery rules employ the use of any non-SP/FP based register, the
stack tracer must proceed only if it is the topmost frame on stack.
For CFA, RA, and FP, up to two "offsets" may be used. The two offsets
represent the information as follows:
- (minimum 8-bit) offset1 to encode register like:
(regnum << 3) | unused << 2 | deref << 1 | reg_p (=1)
- offset2 to encode offset: offset
reg_p = 1 indicates a register, reg_p = 0 indicates CFA.
The offsets are in the usual order: CFA, RA, FP if present.
For example, for FP/RA tracking,
a) If the reg is REG1 for FP/RA tracking,
- Encoding:
+ offset1 to encode register: (REG1 << 3) | unused << 2 | deref << 1 | reg_p (=1)
+ offset2 to encode offset: offset
- Action:
+ if deref, FP/RA = \*(REG1 + offset) (e.g., seen for FP recovery
with certain DRAP patterns on x86_64)
+ if no deref, FP/RA = REG1 + offset
b) If the reg is CFA for FP/RA tracking,
- Encoding:
+ [=Effectively Padding] offset1 to encode register:
(( 0 << 3 ) | unused << 2 | 0 << 1 | reg_p (=0))
+ offset2 to encode offset: offset
- Action:
+ if deref, FP/RA = *(CFA + offset)
+ if no deref, FP/RA = CFA + offset (pattern shouldnt be seen for
RA)
Next for CFA tracking,
- Action:
+ if deref, CFA = *(reg + offset) (e.g., seen for CFA recovery in
some stack realignment patterns on AMD64)
+ if no deref, CFA = reg + offset (e.g., for .cfi_def_cfa 2, 8, or
.cfi_def_cfa 10, 0)
Expected usage of this FDE type is quite low (DRAP on x86_64).
NB: In SFrame V2, we did use the the term 'FDE Type' for the two
designated 'PC Type' for the SFrame FDEs (SFRAME_FDE_TYPE_PCINC,
SFRAME_FDE_TYPE_PCMASK). In hindsight, 'FDE Type' was inappropriate
term. In a subsequent commit, we will fix this terminology for SFrame
V3.
include/
* sframe.h (SFRAME_FDE_TYPE_FLEX): New SFrame FDE type.
(SFRAME_V3_FDE_TYPE_MASK): New constant definition.
(SFRAME_V3_FDE_TYPE): New macro definition.
(SFRAME_V3_SET_FDE_TYPE): Likewise.
(SFRAME_V3_FLEX_FDE_REG_ENCODE): Macro to encode register in the
SFrame offset data.
(SFRAME_V3_FLEX_FDE_OFFSET_REG_NUM): New definition.
(SFRAME_V3_FLEX_FDE_OFFSET_REG_DEREF_P): Likewise.
(SFRAME_V3_FLEX_FDE_OFFSET_REG_P): Likewise.
The existing field func_info (in the SFrame FDE) is used to convey important
information around the encoding and interpretation of the rest of the
stack trace data for the respective SFrame FDE: the SFrame FRE type,
SFrame FDE PC type, etc.
Currently there is 1 bit left for AArch64, and 2 bits for AMD64, s390x
(and other future ABIs to be supported). Provision some additional
space now (specifically an additional 8-bits) for future needs for V3
and beyond.
Compared to V2, this now increases the size of SFrame FDE by 1 byte in
V3. In this patch, the additional func_info2 byte is not used
functionally yet. Hence, rather mechanical changes in libsframe, bfd
and libsframe/testsuite accompany. We will put func_info2 into use in a
later patch by reserving 5 of these bits for SFrame FDE types.
With the addition of a new byte for additional func info (func_info2),
add a new arg to allow usecases like textual dumper to get all data
members in one API: sframe_decoder_get_funcdesc_v3. To keep the APIs
symmetric looking, add new arg to sframe_encoder_add_funcdesc_v3 too.
Since bfd uses these APIs, carry out the mechanical change in the
respective APIs too. And of course, the testsuite which exercises these
APIs.
bfd/
* elf-sframe.c (_bfd_elf_merge_section_sframe): Get and set
func_info2.
* elf64-s390.c (_bfd_s390_elf_create_sframe_plt): Pass 0 for
func_info2 for SFrame FDE for PLT.
* elfxx-x86.c (_bfd_x86_elf_create_sframe_plt): Likewise.
gas/
* gen-sframe.c (output_sframe_funcdesc): Emit the uint8_t for
func_info2.
libsframe/
* sframe-dump.c (dump_sframe_func_with_fres):
* sframe.c (sframe_fde_tbl_init): Handle the new additional
member.
(sframe_encoder_write_fde): Likewise.
* sframe.c (sframe_decoder_get_funcdesc_v3): Update func_info2.
libsframe/testsuite/
* libsframe.decode/DATA2: Update data file with SFrame section
data.
* libsframe.encode/encode-1.c: Pass 0 for func_info2 arg.
* libsframe.find/findfre-1.c: Likewise.
* libsframe.find/findfunc-1.c: Likewise.
* libsframe.find/plt-findfre-1.c: Likewise.
* libsframe.find/plt-findfre-2.c: Likewise.
include/
* sframe.h: Add new uint8_t sfde_func_info2 to
sframe_func_desc_entry_v3.
* sframe-api.h (sframe_decoder_get_funcdesc_v3): New arg.
(sframe_encoder_add_funcdesc_v3): Likewise.
Update the SFrame generation logic in GAS to emit Function Descriptor Entries
(FDEs) for signal frames even when no Frame Row Entries (FREs) could be
generated.
Previously, create_sframe_all () would discard any FDE that failed
translation or resulted in zero FREs. However, for signal frames (marked
with .cfi_signal_frame), preserving the FDE may be valuable even without
stack offsets. The presence of the SFrame FDE with the 'Signal'
attribute may allow stack tracers to identify the frame as a signal
trampoline and potentially apply fallback handling, rather than treating
the PC range as having no stack trace info at all.
The patch modifies create_sframe_all () to detect translation errors for
signal frames, effectively allowing the generation of an empty FDE (0 FREs)
marked with the 'S' attribute.
gas/
* gen-sframe.c (sframe_fde_free): Add NULL check for safety.
(create_sframe_all): Allow FDEs for signal frames even if translation
encountered errors or produced no FREs.
gas/testsuite/
* gas/cfi-sframe/cfi-sframe.exp: New test.
* gas/cfi-sframe/cfi-sframe-x86_64-signal-1.d: New test ensuring
signal frame FDE is emitted with 0 FREs.
* gas/cfi-sframe/cfi-sframe-x86_64-signal-1.s: New test.
Reserve a bit in function info byte in the SFrame FDE to designate
signal frames.
Also update the SFrame opt code in GAS and dumping routines in libsframe
to handle signal frame bit.
include/
* sframe.h (SFRAME_V3_FDE_SIGNAL_P): Extract signal frame bit.
(SFRAME_V3_FDE_UPDATE_SIGNAL_P): Set signal frame bit.
gas/
* gen-sframe.c (get_dw_fde_signal_p): New function to retrieve signal
frame state from DWARF FDE.
(sframe_v3_set_func_info): Renamed from sframe_v1_set_func_info.
Accept signal_p argument and encode it.
(sframe_set_version): Update ops to use sframe_v3_set_func_info.
(sframe_set_func_info): Pass signal_p to the ops hook.
(output_sframe_funcdesc): Retrieve signal frame marker and pass to
sframe_set_func_info.
* gen-sframe.h (struct sframe_version_ops): Update set_func_info
signature.
* sframe-opt.c (sframe_convert_frag): Preserve signal_p bit during
fragment conversion. While at it, use SFRAME_V3_* macros where
applicable.
libsframe/testsuite/
* gas/cfi-sframe/cfi-sframe-common-13.d: New test.
* gas/cfi-sframe/cfi-sframe-common-13.s: New test.
* gas/cfi-sframe/cfi-sframe.exp: Run new test.
libsframe/
* sframe-dump.c (dump_sframe_func_with_fres): Decode signal frame bit
and print "S" attribute in the dump output.
This change enables support text > 2 GiB in SFrame format.
Each SFrame FDE needs to hold information about the start PC of the
function it pertains to. Currently, the field 'sfde_func_start_address'
in SFrame FDE is encoded as a 32-bit offset to the start PC of the
function from the field itself.
In SFrame V2, this offset was a signed 32-bit offset. The signedness
gives the flexibility of having .sframe ELF section before or after the
.text* sections. But the size of 32-bit puts the limitation that
.sframe togther with the .text* sections must fit the 2 GiB range.
Currently, if the linker sees the offset not representable as 32-bit
signed offset, it issues an error (not seen in the wild, simulated by
forcing a function to align via an '.align 2147483648' directive):
test.o:(.sframe+0x1c): relocation truncated to fit: R_X86_64_PC32 against `.text'
make: *** [Makefile:7: all] Error 1
ATM, EH Frame also suffers with the same issue.
Moving forward, some cloud applications have been shown to be nearing
1.5 GiB threshold. Extending the offset to int64_t now seems to be good
choice to make now for future-proof'ing the sections.
The use of int64_t offset is done for all SFrame V3 sections. This
bump from int32_t to int64_t should not lead to an increase in the size
of SFrame sections, because of the following additional changes to the
SFrame FDE specification:
- Reduce the type of sfde_func_num_fres (from uint32_t to uint16_t)
- Remove the 2 bytes of padding (sfde_func_padding2). These served the
two-fold purpose of keeping FDE data aligned _and_ unused space for
future needs.
Now that the offset is int64_t, start using the
sframe_decoder_get_funcdesc_v3 () instead of
sframe_decoder_get_funcdesc_v2 () in GNU ld.
This patch changes the offset type in the SFrame FDE definition to an
int64_t. No further changes in gas are necessary because the code
already accounts for writing out as per the size of the member of the
struct:
emit_expr (&exp, sizeof_member (sframe_func_desc_entry,
sfde_func_start_offset));
bfd/
* elf-sframe.c (sframe_read_value): Signed offset for start PC
is 8-bytes now.
(_bfd_elf_merge_section_sframe): Likewise.
* elf64-s390.c (_bfd_s390_elf_create_sframe_plt): Use V3 API.
(elf_s390_finish_dynamic_sections): Signed offset for start PC
is 8-bytes now.
* elfxx-x86.c (_bfd_x86_elf_create_sframe_plt): Use V3 API.
(_bfd_x86_elf_finish_dynamic_sections): Signed offset for start
PC is 8-bytes now.
gas/
* sframe.c (output_sframe_funcdesc): Rename to
sfde_func_start_offset.
libsframe/
* libsframe/sframe.c (sframe_fde_tbl_init): Rename to
sfde_func_start_offset.
(flip_fde): Likewise.
(sframe_decoder_get_secrel_func_start_addr): Use int64_t.
(sframe_fre_check_range_p): Likewise.
(sframe_decoder_get_offsetof_fde_start_addr): Rename to
sfde_func_start_offset.
(sframe_get_funcdesc_with_addr_internal): Use int64_t.
(sframe_find_fre): Likewise.
(sframe_encoder_get_offsetof_fde_start_addr): Rename to
sfde_func_start_offset.
(sframe_encoder_add_funcdesc_internal): Use int64_t.
(sframe_encoder_add_funcdesc): Likewise. And rename to
sfde_func_start_offset.
(sframe_encoder_write_fde): Rename to sfde_func_start_offset.
libsframe/testsuite/
* libsframe.decode/DATA2: Regenerate the data file.
* libsframe.encode/encode-1.c: Use int64_t for start pc offset.
* libsframe.find/findfre-1.c: Likewise.
* libsframe.find/findfunc-1.c: Likewise.
* libsframe.find/plt-findfre-1.c: Likewise.
* libsframe.find/plt-findfre-2.c: Likewise.
include/
* sframe-api.h (sframe_find_fre): Update arg type to int64_t.
(sframe_encoder_add_funcdesc): Likewise.
* sframe.h: Change data type to int64_t.
Remove the unused sfde_func_padding2 member from the
sframe_func_desc_entry_v3 structure.
A later patch in this series reorganizes the members of the FDE
structure in a way explicit padding is no longer necessary to keep
natural alignment. So remove the explicit padding now.
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
include/
* sframe.h: Remove sfde_func_padding2 from
sframe_func_desc_entry_v3.
gas/
* gen-sframe.c (output_sframe_funcdesc): Stop writing
sfde_func_padding2.
libsframe/
* sframe.c (sframe_encoder_write_fde): Stop writing
sfde_func_padding2.
* testsuite/libsframe.decode/DATA2: Regenerate binary test data.
Reduce the size of the num_fres field in the Function Descriptor Entry
(FDE) from 32 bits to 16 bits.
The number of Frame Row Entries (FREs) for a single function is extremely
unlikely to exceed 65,535 in real-world scenarios. Reducing this field
saves 2 bytes per FDE, contributing to a smaller overall SFrame section size.
(BTW, these savings will be eaten up by a later commit which adds
support for text > 2 GiB by increasing an offset from int32_t to
int64_t).
Safety checks are added to the assembler to warn and skip SFrame FDE
generation if a function's FRE count exceeds UINT16_MAX.
Note regarding alignment: With the current patch, the members of
sframe_func_desc_entry_v3 are not at aligned boundaries anymore. Recall
that all sframe_func_desc_entry_v3 entries are stored together in the
"SFrame FDE sub-section" forming an index. Only after a later patch in
the series "[29/36] [SFrame-V3] include: gas: libsframe: split FDE into
desc and attr" will the alignment properties of SFrame index will be
restored.
include/
* sframe.h (sframe_func_desc_entry_v3): Change sfde_func_num_fres
type to uint16_t.
gas/
* gen-sframe.c (output_sframe_funcdesc): Write 2 bytes for num_fres
and assert it fits in uint16_t.
(sframe_do_fde): Add check to skip FDE emission if num_fres exceeds
UINT16_MAX.
libsframe/
* sframe.c (sframe_encoder_write_fde): Cast num_fres to uint16_t
to ensure correctly written out data.
* testsuite/libsframe.decode/DATA2: Update binary test data.
(Similar to V2) Add two new APIs for adding and getting SFrame FDE:
- sframe_encoder_add_funcdesc_v3
- sframe_decoder_get_funcdesc_v3
Note the argument for the function start address is int64_t instead of
int32_t (the latter is used in sframe_encoder_add_funcdesc_v2 and
sframe_encoder_get_funcdesc_v2). The new V3 APIs will be used in a
subsequent commit to extend SFrame V3 to support text > 2 GiB by
allowing int64_t offsets by default.
Similar to the analogous V2 APIs, they return 0 on success and
SFRAME_ERR (in case of sframe_decoder_get_funcdesc_v3) or error code (in
case of sframe_encoder_add_funcdesc_v3) on failure.
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
include/
* sframe-api.h (sframe_decoder_get_funcdesc_v3): New
declaration.
(sframe_encoder_add_funcdesc_v3): Likewise.
libsframe/
* libsframe.ver: Add the new APIs.
* sframe.c (sframe_decoder_get_funcdesc_v3): New definition.
(sframe_encoder_add_funcdesc_v3): Likewise.
Consolidate the 2.0 and 2.1 nodes into a new 3.0 node.
In subsequent patches for releasing SFrame V3, libsframe APIs will be
affected. A non-exhaustive list of noteworthy changes are mentioned
next.
Some existing APIs (breaking binary compatibility) by adding an
additional arg to these:
- sframe_fre_get_ra_offset
- sframe_fre_get_fp_offset
- sframe_fre_get_cfa_offset
Change of argument type:
- sframe_find_fre
The behaviour of some APIs will change:
- sframe_encoder_write now writes out V3.
And lastly removal of two APIs:
- sframe_decoder_get_funcdesc
- sframe_encoder_add_funcdesc
Above make this release of the library binary incompatible with previous
release, hence a version bump and new version node 3.0.
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
libsframe/
* libsframe.ver: Create a new 3.0 node. Remove the 2.0 node.
* libtool-version: Bump the so version.
Bump version to SFRAME_VERSION_3. Introduce a new definition of SFrame
FDE for version 3, which is a duplicate of SFrame FDE in V2, for now.
In other words, no changes to the format specification yet.
GNU as emits SFrame V3 by default. SFrame encoder (ld) emits SFrame V3
sections. In a later commit, we will add a new command line option to
gas: --gsframe-3 which will bind the implementation in gas to emit
SFrame V3.
Also, adjust the testcases for the new version string
"SFRAME_VERSION_3".
bfd/
* elf-sframe.c (_bfd_elf_merge_section_sframe): Linker emits
the latest version by default.
* elf64-s390.c (_bfd_s390_elf_create_sframe_plt): Linker emitted
PLT sections are also SFRAME_VERSION_3.
* elfxx-x86.c (_bfd_x86_elf_create_sframe_plt): Likewise.
gas/
* gen-sframe.c (sframe_set_version): GAS emits SFrame V3 by
default.
(output_sframe): Likewise.
libsframe/
* sframe-dump.c (dump_sframe): Enable dumping for both
SFRAME_VERSION_2 and SFRAME_VERSION_3.
include/ChangeLog:
* sframe.h (SFRAME_VERSION_3): New definition.
(SFRAME_VERSION): Current version is now SFRAME_VERSION_3.
(SFRAME_V3_FDE_FUNC_INFO): New definition.
(SFRAME_V3_FDE_FRE_TYPE): Likewise.
(SFRAME_V3_FDE_PC_TYPE): Likewise.
(SFRAME_V3_AARCH64_FDE_PAUTH_KEY): Likewise.
(SFRAME_V3_FDE_UPDATE_PAUTH_KEY): Likewise.
binutils/testsuite/
* all affected tests: Replace SFRAME_VERSION_2 with
SFRAME_VERSION_3.
gas/testsuite/
* all affected tests: Likewise.
ld/testsuite/
* all affected tests: Likewise.
libsframe/testsuite/
* all affected tests: Likewise.
As the library version will be bumped soon, include this change now.
Note the arg names in sframe-dump.c APIs have 'sfd_ctx' instead of the
usual 'dctx'. We can address this cosmetic change at a later time.
Other cosmetic changes, e.g. to make fixing function-level comments more
consistent, are left out of the patch for now.
Additionally, constify the return type of static function
sframe_decoder_get_header, now that the call sites consistently use a
const object.
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
sframe_decoder_get_funcdesc () was added for SFRAME_VERSION_1. This has
since been obsoleted by introduction of SFRAME_VERSION_2 and its
corresponding sframe_decoder_get_funcdesc_v2 API.
Remove from the version script file as well. We will bump the version
of the library to 3.0.0 in a subsequent patch (closer to release) and
consolidate the entries into a new LIBSFRAME_3.0 node.
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
include/
* sframe-api.h (sframe_decoder_get_funcdesc): Remove.
libsframe/
* libsframe.ver: Likewise.
* sframe.c (sframe_decoder_get_funcdesc): Remove definition.