**Change relanded after feedback on failures and improvements to the
check of the addend. Original PR #111970**
Changes from original patch:
- The value that is being checked has changed, it is now correctly
checking any Addend for the instruction, rather than the Value. The
addend is kept within the Target data structure from my investigation.
- Removed changes to the following tests due to the original behaviour
being correct, and my original patch causing unexpected errors
- llvm/test/MC/ARM/Windows/mov32t-range.s
- llvm/test/MC/MachO/ARM/thumb2-movw-fixup.s
As per the ARM ABI, the MOVT and MOVW instructions should have addends
that fall within a 16bit signed range. LLVM does not check this so it is
possible to use addends that are beyond the accepted range. These
addends are silently truncated.
A new check is added to ensure the addend falls within the expected
range, rejecting an addend that falls outside with an error.
Information relating to the ABI requirements can be found here:
https://github.com/ARM-software/abi-aa/blob/main/aaelf32/aaelf32.rst#addends-and-pc-bias-compensation
… (#111970)"
I was made aware of breakages in Windows/ARM, so reverting while I
investigate.
This reverts commit f3aebe623b49b7ae14d0f0996999114aac052e4b.
Previously, any value could be used for the MOVT and MOVW instructions,
however the ARM ABI dictates that the addend should be a signed 16 bit
value. To ensure this is followed, the Assembler will now check that
when using these instructions, the addend is a 16bit signed value, and
throw an error if this is not the case.
Information relating to the ABI requirements can be found here:
https://github.com/ARM-software/abi-aa/blob/main/aaelf32/aaelf32.rst#addends-and-pc-bias-compensation
This PR adds checks that any addends attached to branch instructions are
valid, and can be properly encoded in the branch instruction. Before
this fix, the assembler would silently truncate or round invalid addend
values, creating incorrect branch instructions.
LR is R14, but this data structure is indexed by MCRegister not
encoding. It's in a debug message so I guess no one ever noticed.
Found while auditing places that should use MCRegister.
This adds the same kind of verification for ARM, as was added for
AArch64 in 1e7f592a890aad860605cf5220530b3744e107ba. This allows
catching issues at assembly time, instead of having the linker
misinterpret the relocations (as the linker ignores the symbol offset).
This verifies that the issue fixed by
8dd065d5bc81b0c8ab57f365bb169a5d92928f25 really is fixed, and points out
explicitly if the same issue appears elsewhere.
Note that the parameter Value in the adjustFixupValue function is offset
by 4 from the value that is stored as immediate in the instructions, so
we compare with 4, when we want to make sure that the written immediate
will be zero.
Rebase of #84114. I've only included the core changes to frame layout
calculation & CFI generation which sidesteps the regressions found after
merging #84114. Since these changes are a necessary precursor to the
overall fix and are themselves slightly beneficial as CFI is now
generated correctly, I think it is reasonable to merge this first step.
---
For very large stack frames, the offset from the stack pointer to a
local can be more than 2^31 which overflows various `int` offsets in the
frame lowering code.
This patch updates the frame lowering code to calculate the offsets as
64-bit values and fixes CFI to use the corrected sizes.
After this patch, additional work is needed to fix offset truncations in
each target's codegen.
fixupNeedsRelaxation is a simple implementation for
fixupNeedsRelaxationAdvanced. Its users do not utilize MCAsmLayout or
MCRelaxableFragment.
Follow-up to 22c7317f1e954b34a46640db5d509bae1c633348
("[MC] Remove the MCAsmLayout parameter from relocation related functions").
For very large stack frames, the offset from the stack pointer to a local can be more than 2^31 which overflows various `int` offsets in the frame lowering code.
This patch updates the frame lowering code to calculate the offsets as 64-bit values and resolves the overflows, resulting in the correct codegen for very large frames.
Fixes#48911
Linux kernel fs/binfmt_elf_fdpic.c supports FDPIC for MMU-less systems.
GCC/binutils/qemu support FDPIC ABI for ARM
(https://github.com/mickael-guene/fdpic_doc).
_ARM FDPIC Toolchain and ABI_ provides a summary.
This patch implements FDPIC relocations to the integrated assembler.
There are 6 static relocations and 2 dynamic relocations, with
R_ARM_FUNCDESC as both static and dynamic.
gas requires `--fdpic` to assemble data relocations like `.word f(FUNCDESC)`.
This patch adds `MCTargetOptions::FDPIC` and reports an error if FDPIC
is not set.
Pull Request: https://github.com/llvm/llvm-project/pull/82187
Removes logic that caused some fixups to be marked as resolved in the
assembler without actually resolving them. Assembler must either resolve
the fixup, reject the code (error out) or defer the resolution to the
linker. In general assembler can resolve offsets in pcrel instructions
if the symbol referred to is in the same section and it cannot make
assumptions about relative position of sections. For example, when LDRD
instruction in arm mode is encountered, fixup_arm_pcrel_10_unscaled is
raised. Prior to https://github.com/llvm/llvm-project/pull/72873/ the
assembler would always mark it as resolved without generating a
relocation. The resulting code would likely be incorrect whenever the
label referred to is in a different section.
This patch finishes the series to prevent incorrect code being generated
for pcrel instructions referring to labels in different sections. This
kind of assembly code is very rare and most likely a user error, so both
options (relocation or error) are acceptable. In previous patches this
was resolved by adding relocations. Here, for VLDR instructions an error
is generated as relocation does not exist for Thumb mode and we wanted
the tool's behaviour to be consistent across modes. In the LDRD case,
Thumb mode does not have a relocation and errors out, but LDRD in Arm
mode generates R_ARM_LDRS_PC_G0 relocation because its fixup kind is
shared with other instructions.
It also fixed the case when ADR is used in the big-endian mode, which is
not covered by the ADR patch.
Patch series:
https://github.com/llvm/llvm-project/pull/72873 - LDRx
https://github.com/llvm/llvm-project/pull/73834 - ADR
this PR - LDRD and VLDR
Follow-up on https://github.com/llvm/llvm-project/pull/72873/
When ADR/LDR instructions reference a label in a different section, the
offset is not known until link time, however, the assembler assumes it
can resolve them in some cases.
The previous patch addressed the issue for most LDR instructions,
focusing on little-endian targets.
This patch addresses the remaining work for ADRs and big-endian targets.
It's possible (though inadvisable) to use LDR and refer to labels in
different
sections. In the Arm state, the assembler resolves the LDR instruction
without
emitting a relocation. That's incorrect because the assembler cannot
make any
assumptions about the relative position of the sections and the compiler
output
is therefore wrong.
This patch ensures relocations are generated for all `LDR <Rt...>,
label`
instructions in the Arm state (little endian). This is not necessary
when the
label is in the same section but the relocation is now generated
regardless.
Instructions that now generate relocations have been removed from the
pcrel-global.s test.
Fortunately, LLD already implements the generated relocations and can
fix LDR
instructions when the symbol is in a different section, or report an
error if
the offset is too large for the immediate field in the particular LDR's
encoding.
The patch to address this problem for big endian targets will follow, as
well
as a fix for ADR that exhibits a similar behavior.
Note that llvm::support::endianness has been renamed to
llvm::endianness while becoming an enum class as opposed to an
enum. This patch replaces support::{big,little,native} with
llvm::endianness::{big,little,native}.
Now that llvm::support::endianness has been renamed to
llvm::endianness, we can use the shorter form. This patch replaces
support::endianness with llvm::endianness.
This patch adds the LLVM-side plumbing for the following relocations:
- R_ARM_THM_ALU_ABS_G0_NC
- R_ARM_THM_ALU_ABS_G1_NC
- R_ARM_THM_ALU_ABS_G2_NC
- R_ARM_THM_ALU_ABS_G3
(see section 5.6.1.5, Static Thumb16 relocations, of the AArch32 ELF Arm ABI:
844a79fd4c/aaelf32/aaelf32.rst (5615static-thumb16-relocations))
Which can respectivly be generated by prefixing assembly symbols with:
- :lower0_7:
- :lower8_15:
- :upper0_7:
- :upper8_15:
LLD support for these relocations will be added in a follow-up patch
Reviewed By: john.brawn, MaskRay
Differential Revision: https://reviews.llvm.org/D149443
Reasons for rolling forward:
- the crash reported from Chromium was fixed in D151824 (not related to this patch at all)
- since D152824 was committed, it should now be safe to roll this forward.
New change:
- add an additional _ in name check
This reverts commit 4980eead4d0b4666d53dad07afb091375b3a13a0.
Details: https://github.com/rust-lang/rust/issues/102754
The MachO format uses 2 bits to encode these personality funtions, with 0 reserved for "no-personality".
This means we can only have up to 3 personality. There are already three popular personalities: __gxx_personality_v0, __gcc_personality_v0, and __objc_personality_v0.
As a result, any system that needs custom-personality will run into a problem.
This patch implemented jyknight's proposal to simply force DWARFs for all non-canonical personality functions.
Differential Revision: https://reviews.llvm.org/D144999
For a .quad/.8byte directive that needs a relocation, Mach-O emits one error
while ELF emits two. Emit just one for ELF and change the diagnostic to match
other ports.
This patch mechanically replaces None with std::nullopt where the
compiler would warn if None were deprecated. The intent is to reduce
the amount of manual work required in migrating from Optional to
std::optional.
This is part of an effort to migrate from llvm::Optional to
std::optional:
https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
On some architectures such as Arm and X86 the encoding for a nop may
change depending on the subtarget in operation at the time of
encoding. This change replaces the per module MCSubtargetInfo retained
by the targets AsmBackend in favour of passing through the local
MCSubtargetInfo in operation at the time.
On Arm using the architectural NOP instruction can have a performance
benefit on some implementations.
For Arm I've deleted the copy of the AsmBackend's MCSubtargetInfo to
limit the chances of this causing problems in the future. I've not
done this for other targets such as X86 as there is more frequent use
of the MCSubtargetInfo and it looks to be for stable properties that
we would not expect to vary per function.
This change required threading STI through MCNopsFragment and
MCBoundaryAlignFragment.
I've attempted to take into account the in tree experimental backends.
Differential Revision: https://reviews.llvm.org/D45962
Currently the ARM backend only accpets constant expressions as the
immediate operand in load and store instructions. This allows the
result of symbolic expressions to be used in memory instructions. For
example,
0:
.space 2048
strb r2, [r0, #(.-0b)]
would be assembled into the following instructions.
strb r2, [r0, #2048]
This only adds support to ldr, ldrb, str, and strb in arm mode to
address the build failure of Linux kernel for now, but should facilitate
adding support to similar instructions in the future if the need arises.
Link:
https://github.com/ClangBuiltLinux/linux/issues/1329
Reviewed By: peter.smith, nickdesaulniers
Differential Revision: https://reviews.llvm.org/D98916
Negations are incorrectly added in numerous places and the code just happens to work.
Also fix a missed DW_CFA_def_cfa_offset negation in c693b9c321d5a40d012340619674cf790c9ac86c:
ARMAsmBackendDarwin::generateCompactUnwindEncoding
Summary:
In 2e24219d3cbf, a number of ARM pcrel fixups were resolved at assembly
time, to solve PR44929. This only covered little-endian ARM however, so
add similar fixups for big-endian ARM. Also extend the test case to
cover big-endian ARM.
Reviewers: hans, psmith, MaskRay
Reviewed By: psmith, MaskRay
Subscribers: kristof.beyls, hiraditya, danielkiss, emaste, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D79774
Summary:
This commit recommits the reversion of https://reviews.llvm.org/D75039.
Concensus appears to be in favour of assembly-time resolution of
these ADR and LDR relocations, in line with GNU. The previous
backout broke many lld tests, now fixed by Peter Smith in
61bccda9d9d920c72f49025f11e8601daeb096ec.
Reviewers: psmith
Subscribers: kristof.beyls, hiraditya, danielkiss, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D78301
Summary:
Before this patch, `relaxInstruction` takes three arguments, the first
argument refers to the instruction before relaxation and the third
argument is the output instruction after relaxation. There are two quite
strange things:
1) The first argument's type is `const MCInst &`, the third
argument's type is `MCInst &`, but they may be aliased to the same
variable
2) The backends of ARM, AMDGPU, RISC-V, Hexagon assume that the third
argument is a fresh uninitialized `MCInst` even if `relaxInstruction`
may be called like `relaxInstruction(Relaxed, STI, Relaxed)` in a
loop.
In this patch, we drop the thrid argument, and let `relaxInstruction`
directly modify the given instruction. Also, this patch fixes the bug https://bugs.llvm.org/show_bug.cgi?id=45580, which is introduced by D77851, and
breaks the assumption of ARM, AMDGPU, RISC-V, Hexagon.
Reviewers: Razer6, MaskRay, jyknight, asb, luismarques, enderby, rtaylor, colinl, bcain
Reviewed By: Razer6, MaskRay, bcain
Subscribers: bcain, nickdesaulniers, nathanchance, wuzish, annita.zhang, arsenm, dschuff, jyknight, dylanmckay, sdardis, nemanjai, jvesely, nhaehnle, tpr, sbc100, jgravelle-google, kristof.beyls, hiraditya, aheejin, kbarton, fedor.sergeev, asb, rbar, johnrusso, simoncook, sabuasal, niosHD, jrtc27, MaskRay, zzheng, edward-jones, atanasyan, rogfer01, MartinMosbeck, brucehoult, the_o, PkmX, jocewei, Jim, lenary, s.egerton, pzheng, sameer.abuasal, apazos, luismarques, kerbowa, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D78364
Summary:
This commit reverts https://reviews.llvm.org/D75039. Concensus appears to
be in favour of assembly-time resolution of these ADR and LDR relocations,
in line with GNU.
Reviewers: psmith
Subscribers: kristof.beyls, hiraditya, danielkiss, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D78301
Generalizes D61992. In GNU as, the .reloc directive supports arbitrary relocation types.
A MCFixupKind value `V` larger than or equal to FirstLiteralRelocationKind
is used to represent the relocation type whose number is V-FirstLiteralRelocationKind.
This is useful for linker tests. Without the feature the assembler
cannot produce certain relocation records (e.g. R_ARM_ALU_PC_G0/R_ARM_LDR_PC_G0)
This helps move forward D75349 and D76575.
Differential Revision: https://reviews.llvm.org/D76746
Add ELF relocations for the following fixups:
fixup_thumb_adr_pcrel_10 -> R_ARM_THM_PC8
fixup_thumb_cp -> R_ARM_THM_PC8
fixup_t2_adr_pcrel_12 -> R_ARM_THM_PREL_11_0
fixup_t2_ldst_pcrel_12 -> R_ARM_THM_PC12
While these relocations are short-ranged there is support in the open
source ELF linker's in binutils and soon to be in LLD. MC will no longer
resolve pc-relative fixups to global symbols due to interpositioning
concerns. We can handle these at link time by implementing the relocations.
The R_ARM_THM_PC8 has some extra encoding rules for addends that llvm-mc
sidesteps by not supporting addends for these instructions, using the wide
Thumb 2 instruction if it is available. I think that this is a reasonable
compromise given that these are rare.
This partiall reverts D72892, the Thumb fixups no longer need to be
evaluated at assembly time.
Differential Revision: https://reviews.llvm.org/D75039