The original patch,
e6f372ba66
Since recently c.slli64, c.srai64, and c.srli64 have been removed from the
riscv-isa-manual, c.slli, c.srli, and c.srai with 0 immediate are now listed
as hints,
https://github.com/riscv/riscv-isa-manual/pull/1942 and https://github.com/riscv/riscv-isa-manual/pull/2093
So allow c.slli, c.srli, and c.srai with 0 immediate as a hint. Also allow to
assemble slli, srli and srai with 0 immediate to hint c.slli, c.srli and c.srai
when rvc is enabled. The c.slli64, c.srai64, and c.srli64 should be kept as
aliases, so dis-assembler should disassemble to c.slli, c.srli, and c.srai with
0 immediate.
Passed rv32/64-elf/linux binutils testcases.
gas/
PR 33216
* testsuite/gas/riscv/c-zero-imm.d: Updated since allow c.slli64,
c.srai64, and c.srli64 with 0 immediate as a hint.
* testsuite/gas/riscv/c-zero-imm.s: Likewise.
* testsuite/gas/riscv/zca.d: Likewise.
opcodes/
PR 33216
* riscv-opc.c (riscv_opcodes): Updated since allow c.slli64, c.srai64,
and c.srli64 with 0 immediate as a hint.
The custom parsing done there and in one of its callers allowed various
bogus constructs to be accepted. Insist on a non-zero leading digit when
parsing numbers, don't lose upper bits, and insist on proper separation
of operands.
Commit 1ac26e9f7a replaced ISSPACE with is_whitespace, but the
former returns true on EOL while the latter does not. Sprinkle
is_end_of_stmt tests to fix this bug.
The same segfault can be triggered by a ".relax_hint" with no
following instructions. Fix that too.
* config/tc-nds32.c (nds32_lookup_pseudo_opcode): Use
is_end_of_stmt along with is_whitespace.
(nds32_relax_relocs, nds32_relax_hint, nds32_flag),
(ict_model: Likewise.
(nds32_elf_append_relax_relocs): Return on no opcode.
* testsuite/gas/nds32/nds32.exp: Find .d files automatically.
* testsuite/gas/nds32/pr33229.d,
* testsuite/gas/nds32/pr33229.s: New test.
over gas directive to emit .sframe section.
Fix PR gas/33175 sframe: --gsframe=no does not disable when
.cfi_sections directive with .sframe
--gsframe=no should also disable generation of SFrame section when
explicit CFI directive:
.cfi_sections .sframe
is specified in the input. This means we need to track whether SFrame
generation was explicitly disabled by the user. Introduce a new enum to
facilitate disambiguation between GEN_SFRAME_DEFAULT_NONE and
GEN_SFRAME_DISABLED.
While fixing the bug by adding the enum, keep the upcoming requirement
in mind: we will also need to disambiguate between
--enable-default-sframe and user-specified --gsframe/--gsframe=yes. The
intent is to not display SFrame related warnings or errors like:
as_bad (_(".sframe not supported for target"));
for unsupported targets if --enable-default-sframe is in effect.
This implies we need to have a four state enum (
GEN_SFRAME_DEFAULT_NONE, GEN_SFRAME_CONFIG_ENABLED,
GEN_SFRAME_DISABLED, GEN_SFRAME_ENABLED)
gas/
PR gas/33175
* dw2gencfi.c (cfi_finish): Check state of flag_gen_sframe to
determine whether any SFrame section is generated.
* as.h (enum gen_sframe_option): New definition.
* as.c (parse_args): Keep track of whether the flag is
explicitly enabled or disabled
gas/testsuite/
PR gas/33175
* gas/cfi-sframe/cfi-sframe-common-1.d: Remove redundant
--gsframe.
* gas/cfi-sframe/cfi-sframe.exp: Add new test.
* gas/cfi-sframe/cfi-sframe-common-1c.d: New test. No SFrame
section if explicit --gsframe=no.
* gas/cfi-sframe/cfi-sframe-common-1c.s: New test.
SFrame generation code assumes that since DW_CFA_restore means
restoration of the state of the register to the one at the beginning of
the function, there must be a state to restore to (hence the gas_assert
(cie_fre)).
This assumption needs adjustment. DW_CFA_restore may be present in the
very beginning of a (e.g., cold) function, with no initialized state for
SFrame functions to restore to.
gas/
PR gas/33170
* gas/gen-sframe.c (sframe_xlate_do_restore): Use current FRE if
CIE FRE is not yet setup.
gas/testsuite/
PR gas/33170
* gas/cfi-sframe/cfi-sframe.exp: New test.
* gas/cfi-sframe/cfi-sframe-x86_64-pr33170.d: New test.
* gas/cfi-sframe/cfi-sframe-x86_64-pr33170.s: New test.
Move gas_sframe_check to binutils-common.exp so that it can be used in
linker tests to check if a target assembler supports --gsframe.
binutils/
PR ld/33146
* testsuite/lib/binutils-common.exp (gas_sframe_check): Moved
from cfi-sframe.exp. Replace gas_host_run with remote_exec.
gas/
PR ld/33146
* testsuite/gas/cfi-sframe/cfi-sframe.exp (gas_sframe_check):
Moved to binutils-common.exp.
Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
Process a new aarch64-specific CFI directive: .cfi_mte_tagged_frame
(LLVM uses this CFI directive already). The CFI directive, when
present for a function, indicates that the stack frame for the
function may modify the MTE tags of the stack space it uses. The
assembler emits char 'G' in the CIE augmentation string to indicate
the same.
ChangeLog:
* gas/config/tc-aarch64.c (s_aarch64_mte_tagged_frame): New
definition.
* gas/config/tc-aarch64.h (tc_fde_entry_extras): Add
memtag_frame_p.
(tc_cie_entry_extras): Likewise.
(tc_fde_entry_init_extra): Likewise.
(tc_cie_fde_equivalent_extra): Likewise.
(tc_cie_entry_init_extra): Likewise.
* gas/doc/c-aarch64.texi: Add documentation for
.cfi_mte_tagged_frame directive.
* gas/testsuite/gas/aarch64/mte_tagged_stack.d: New test.
* gas/testsuite/gas/aarch64/mte_tagged_stack.s: New test.
Add a new flag -menable-sysreg-checking to restore previous behaviour.
This existing behaviour is quite inconsistent, so the gating will
probably be updated in the future. (In particular, many system
registers are currently gated with the architecture version they were
released with instead of the lower architecture version that they
actually require).
This patch retains the +d128 requirement for msrr/mrrs.
Co-Authored-By: Srinath Parvathaneni <srinath.parvathaneni@arm.com>
By default, NIL qualifiers are treated as matching any qualifier when
checking operand constraints. For many SVE instructions, this would
allow operands with missing type suffixes to be assembled as if they had
any explicit type specified. To prevent this, the F_STRICT flag is used
to specify that NIL qualifiers should match only NIL qualifiers.
Unfortunately, several SVE instructions incorrectly omitted this
F_STRICT flag. The bug has existed in the *MATMUL_SVE* macros since
they were added in 2019. The macro LUT_SVE2_INSN was added last year,
and the other incorrect macros are new in this release.
LUTv2_SME2_INSN and LUTv2_SME2p1_INSN were not actually broken, because
we reject untyped vector lists already during parsing. However, I have
added the F_STRICT flag here anyway, since this is more consistent and
would be more robust if those operands start accepting untyped vector
lists in the future. The new luti4 tests are the only ones that were
already rejected before this change.
BFLOAT16_SVE_INSN has been unused since it was originally added, so I
just deleted the macro.
The SVE LUT instructions were using the lut instruction class, which
has special handling only for SIMD operands, and isn't recognised by
aarch64_decode_variant_using_iclass (which sets the qualifiers during
decode for most SVE instructions). To prevent these instructions
failing to disassemble, I changed their instruction class to sve_misc.
Previously the choice of error message for an invalid movprfx sequence
used the architecture requirements to determine whether an instruction
was an SVE instruction or not. This meant specifying SVE or SVE2 as an
explicit architecture requirement for all SVE instructions, even when
this was already implied by another feature. As more architecture
features are added and with the partial removal of the SME->SVE2
dependency, these extra feature requirements were getting messier and
easier to forget.
Instead, we now look at the operand types. If there is an SVE_REG,
SVE_REGLIST or PRED_REG operand, then we treat the instruction as an SVE
instruction. This does change behaviour slightly, but it only affects
the choice of error message and the new choice should be a bit more
consistent.
There is one testsuite update required, because Ezra's SVE_AES2 patch
temporarily broke classification of FEAT_SVE_AES instructions. This
patch restores the original behaviour.
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.
This corrects the DTPREL_HI16/LO16 and TPREL_HI16/LO16 howtos to use
_bfd_mips_elf_{hi,lo}16_reloc special functions, in order to support
addends outside the range [0,32767] on these relocations.
R_MIPS_GOT_HI16, R_MIPS_GOT_LO16, R_MIPS_CALL_HI16 and R_MIPS_CALL_LO16
are left alone as it seems that we (quite reasonably) only support
zero addends for those relocs.
PR 19977
bfd/
* elf32-mips.c (elf_mips_howto_table_rel): Set special_function
to _bfd_mips_elf_hi16_reloc for R_MIPS_TLS_DTPREL_HI16 and
R_MIPS_TLS_TPREL_HI16. Set special_function to
_bfd_mips_elf_lo16_reloc for R_MIPS_TLS_DTPREL_LO16 and
R_MIPS_TLS_TPREL_LO16
(elf_mips16_howto_table_rel): Likewise for
R_MIPS16_TLS_DTPREL_HI16, R_MIPS16_TLS_DTPREL_LO16,
R_MIPS16_TLS_TPREL_HI16 and R_MIPS16_TLS_TPREL_LO16.
(elf_micromips_howto_table_rel): Likewise for
R_MICROMIPS_TLS_DTPREL_HI16, R_MICROMIPS_TLS_DTPREL_LO16,
R_MICROMIPS_TLS_TPREL_HI16 and R_MICROMIPS_TLS_TPREL_LO16.
* elf64-mips.c (mips_elf64_howto_table_rel): Similarly.
(mips16_elf64_howto_table_rel): Similarly.
(micromips_elf64_howto_table_rel): Similarly.
* elfn32-mips.c: As for elf64-mips.c.
gas/
* testsuite/gas/mips/pr19977.d,
* testsuite/gas/mips/pr19977.s: New test.
* testsuite/gas/mips/mips.exp: Run it.
Just as with all HI/LO 16-bit partial relocations the newly-introduced
MIPSr6 PC-relative R_MIPS_PCHI16 and R_MIPS_PCLO16 relocations require
pairing for correct borrow propagation from the low part to the high
part with REL targets, another case for PR 19977.
Unlike with absolute relocation, there is a complication here in that
both parts represent a calculation that is relative to the PC at the
individual relocation's location rather than both referring to the
location of the R_MIPS_PCHI16 relocation, normally applied to an AUIPC
instruction, the location of which is used for the run-time calculation
executed by hardware.
To take this semantics into account, the addend of the R_MIPS_PCLO16
relocation matching a given R_MIPS_PCHI16 relocation is expected to be
adjusted in the source assembly file for the distance between the two
relocations in a single pair, so that once both relocations have been
calculated by the linker, the expression calculated at run time is such
as if the combined 32-bit immediate was added at the location of the
AUIPC instruction.
So for matching R_MIPS_PCHI16 and R_MIPS_PCLO16 relocations into pairs
GAS needs to check for the distance between the two relocations to be
equal to the difference between the addends supplied, and then the
linker has to subtract the low part of the distance between the two
relocations from the low part in calculating the high part, so as to
factor in any borrow.
A further complication is that `_bfd_mips_elf_lo16_reloc' handler is
supplied with the addend differently depending on whether it has been
called by GAS via `bfd_install_relocation', or by the generic linker via
`bfd_perform_relocation'. In the former case the addend is supplied
with the relocation itself while in the latter one it comes from the
field being relocated.
We currently ignore the addend supplied with the relocation and it works
for calculating absolute high-part relocations, because the same addend
has been previously supplied with them when `_bfd_mips_elf_hi16_reloc'
was called, however this approach does not work for the PC-relative case
because as noted above the low-part addend is different and we need to
consistently apply the distance adjustment both with GAS and LD.
Since the supplied addend and one retrieved from field being relocated
won't ever be both nonzero, just use the sum of the two values.
The low-part addend in `mips_elf_add_lo16_rel_addend' always comes from
the field being relocated, so there's no complication there, we just
need to apply the same adjustment.
New linker test cases verify that the same ultimate machine code is
produced both for ELF and S-record output formats, ensuring that the
both the MIPS/ELF linker and the generic linker behave in the correct
way, consistent with each other.
FEAT_SVE_AES2 implements the SVE multi-vector Advanced Encryption
Standard and 128-bit destination element polynomial multiply long
instructions, when the PE is not in Streaming SVE mode.
FEAT_PCDPHINT - Producer-consumer data placement hints - is an optional
ISA extension that provides hint instructions to indicate:
- a store in the current execution thread is generating data at a specific
location, which a thread of execution on one or more other observers is
waiting on.
- the thread of execution on the current PE will read a location that may not
yet have been written with the value to be consumed.
This extension introduces:
- STSHH, a hint instruction, with operands (policies) keep and strm
- PRFM *IR*, a new prefetch memory operand.
Port x86-64 test for handling of .cfi_def_cfa_register from commit
3602da6fa2 ("gas: sframe: fix handling of .cfi_def_cfa_register")
to s390x.
gas/testsuite/
PR gas/32879
* gas/cfi-sframe/cfi-sframe.exp: Add new test for handling of
.cfi_def_cfa_register on s390x.
* gas/cfi-sframe/cfi-sframe-s390x-3.d: Likewise.
* gas/cfi-sframe/cfi-sframe-s390x-3.s: Likewise.
Bug: https://sourceware.org/PR32879
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
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
b52c4ee466 ("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 entry of "zce imply zcf" needs check_implicit_for_zcf, so it needs to be
placed after the entries of "whatever imply f". Otherwise the implicit zcf
may be missed. Also merge the march-implu-zce* testcases into imply testcases.
This also fix the imply result for .option rvc.
Imply zcf when c and f and rv32
Imply zcd when c and d
Imply zca when c
Changed INSN_CLASS_C to INSN_CLASS_ZCA
Changed INSN_CLASS_F_AND_C to INSN_CLASS_ZCF
Changed INSN_CLASS_D_AND_C to INSN_CLASS_ZCD
Changed INSN_CLASS_ZIHINTNTL_AND_C to INSN_CLASS_ZIHINTNTL_AND_ZCA
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.
Expand test coverage for HI/LO relocation handling and add conventional
MIPS and microMIPS GAS tests as well as conventional MIPS, microMIPS,
and MIPS16e2 LD tests, covering R_MIPS_HI16, R_MIPS_LO16, R_MIPS16_HI16,
R_MIPS16_LO16, R_MICROMIPS_HI16, and R_MICROMIPS_LO16 relocations, as
well as 64-bit R_MIPS_HIGHEST, R_MIPS_HIGHER, R_MICROMIPS_HIGHEST, and
R_MICROMIPS_HIGHER relocations.
Modify the linker script so as to retain the `.MIPS.abiflags' section so
as to disassemble MIPS16e2 code correctly, as MIPS16e2 ASE information
is only carried in that section and not in ELF file header's `e_flags'.
MIPS16e2 and microMIPS code requires at least the MIPS32r2 ISA (or the
MIPS64r2 one for the n32 and n64 ABIs), which is incompatible with the
`mips:5900' linker output architecture and causes link failures such as:
./ld-new: tmpdir/mips-hilo1.o: linking mips:isa32r2 module with previous mips:5900 modules
./ld-new: failed to merge target specific data of file tmpdir/mips-hilo1.o
Therefore exclude `mips*el-ps2-elf*' targets from microMIPS and MIPS16e2
LD testing.
Fix a couple of places in MIPS GAS and LD R_MIPS16_HI16/R_MIPS16_LO16
relocation tests where the %hi operator has been incorrectly used, but
the %lo operator is expected to complement the preceding %hi operation.
Rather than having people resort to indirect means to issue a certain
kind of diagnostic conditionally upon an expression which can (or
should) only be evaluated when all sections were sized and all symbols
had their final values established, provide directives to directly
achieve this.
It has been more than once that I would have wanted to have a way to
know the gas version in assembly sources, perhaps for use with .if. Add
such a pre-defined symbol, introducing the common pattern GAS(<symbol>)
for any such symbols. The use of parentheses is to keep the risk of
collisions with users' symbols as low as possible. (Possible future
arch-specific symbols may want to use GAS(<arch>:<symbol>).)
Similarly permit determining whether the assembler is a released
version. The exact value probably isn't of much use, it's more the
defined-ness that one might care about. Yet the symbol needs to have
some value anyway.
While by default pre-defined symbols won't be emitted to the symbol
table, introduce -emit-local-absolute to allow requesting this. Re-
purpose flag_strip_local_absolute to become tristate, with a negative
value indicating to also emit pre-defined symbols.
Using such abbreviations is fine when written on an interactive command
line by a human. In scripts and alike, doing so risks colliding with
later option additions, as is about to occur for gas: Shortly there'll
be --emit-local-absolute.
This patch add support for FEAT_PoPS feature which can be enabled
through +pops command line flag.
This patch also adds support for following DC instructions and the
spec can be found here [1].
1. "dc cigdvaps" enabled on passing +memtag+pops command line flags.
2. "dc civaps" enabled on passing +pops command line flag.
[1]: https://developer.arm.com/documentation/ddi0601/2025-03/AArch64-Instructions?lang=en
Disclaimer: this issue cannot occur with Object Attributes v1 (OAv1) while
using the GNU binutils because a value of '\0' (empty string) for a tag
with a string value is considered as the default value for the attribute,
and consequently is eliminated by gas from the output object file during
the serialization.
An empty string is a valid value for a NTBS tag in both OAv1 and OAv2 [1]
cases. However, contrarily to OAv1, a OAv2 subsection can be required and
so, tags in this subsection might have to be present even if the value is
the default. To comply with this requirement, the OAv2 serializer won't
drop the default values.
In the case where a NTBS tag has the value '\0' and is last in the object
attributes section, the current code in readelf used for dumping the object
attributes incorrectly detects an overflow, and prints out an error message
for a corrupted string tag.
This patch fixes the detection of the overflow so that it now accept an
empty string in the last tag of the object attributes section.
It also fixes the previous tests for the empty NTBS case and the non-null
terminated string one. The fix was also tested in the context of OAv2's
patch series [1] where the issue was originally detected. No regression
was found.
[1]: https://inbox.sourceware.org/binutils/20250509151319.88725-1-matthieu
.longo@arm.com/
The current testsuite for gas/readelf lacked two tests for EABI build
attributes:
- one when the final attribute is an empty string.
- one when the final attribute is a string missing the NULL terminator.
Those two issues cannot occur with Object Attributes v1 (OAv1) sections
created by the GNU binutils. Indeed a value of '\0' (empty string) for a
tag with a string value is considered as the default value for the
attribute, and consequently is eliminated by Gas from the output object
file during the serialization.
However, readelf should be able to process correctly files of an unknown
origin that could contain those two use cases.
This patch adds the two tests mentioned above. The first one is marked
as XFAIL because the empty string is not processed correctly by readelf
when it is in the last position. The second one passes, but simply print
out "[...]" without mentioning that the NTBS is corrupted.
A following patch will fix the bug in readelf, and will amend the newly
introduced tests.
This patch adds support for the RISC-V Profiles RVA23S64 and RVB23S64.
Version log:
Fix wrong test for rvb23s.
bfd/ChangeLog:
* elfxx-riscv.c: New Profiles.
gas/ChangeLog:
* testsuite/gas/riscv/attribute-rva23s.d: New test.
* testsuite/gas/riscv/attribute-rvb23s.d: New test.
Update the Profiles string in RV23 to include the extensions 'b' and 'supm'.
bfd/ChangeLog:
* elfxx-riscv.c: Update Profiles string in RV23.
gas/ChangeLog:
* testsuite/gas/riscv/attribute-19.d: Update test string.
* testsuite/gas/riscv/attribute-20.d: Ditto.
This patch adds support for following system registers and the spec
can be found here[1].
1. PMBSR_EL12, PMBSR_EL2, PMBSR_EL3, PMBMAR_EL1 depends on FEAT_SPE
and Armv9.5-A architecture and these are enabled by passing
-march=armv9.5-a+profile.
2. TRBSR_EL12, TRBSR_EL2, and TRBSR_EL3 depends Armv9.5-A architecture
and these are enabled by passing -march=armv9.5-a.
3. HFGITR2_EL2 depends on Armv8.8-A architecture and enabled by passing
-march=armv8.8-a.
[1]: https://developer.arm.com/documentation/ddi0601/2025-03/AArch64-Registers?lang=en
FEAT_SVE_F16F32MM introduces the SVE half-precision floating-point
matrix multiply-accumulate to single-precision instruction.
FEAT_F8F32MM introduces the Advanced SIMD 8-bit floating-point matrix
multiply-accumulate to single-precision instruction.
FEAT_F8F16MM introduces the Advanced SIMD 8-bit floating-point matrix
multiply-accumulate to half-precision instruction.
FEAT_CMPBR - Compare and branch instructions. This patch adds these
instructions:
- CB<CC> (register)
- CB<CC> (immediate)
- CBH<CC>
- CBB<CC>
where CC is one of the following:
- EQ
- NE
- GT
- GE
- LT
- LE
- HI
- HS
- LO
- LS
FEAT_OCCMO support was introduced, but the feature flags were missing.
This patch adds these flags, as well as splitting up the tests to test
occmo vs occmo+memtag operands.
FEAT_SVE_BFSCALE introduces the SVE BFSCALE instruction, when the PE is not in
Streaming SVE mode. If FEAT_SME2 is implemented, FEAT_SVE_BFSCALE also
introduces SME multi-vector Z-targeting BFloat16 scaling instructions, BFSCALE
and BFMUL.