Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[aaelf64][pauthabi64] Remove addend in GDAT relocation operation #272

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

smithp35
Copy link
Contributor

@smithp35 smithp35 commented Jul 2, 2024

The GDAT(S + A) relocation operation requires a static linker to create a GOT entry for (S + A). Requiring at least one GOT entry for each unique tuple (S, A). Unfortunately no known static linker has implemented this correctly, with one of two forms being implemented instead:

  • GDAT(S) with the addend ignored.
  • GDAT(S) + A with a single GOT entry per S, and A added to the value of GDAT(S). These implementations are correct and consistent only for an addend (A) of zero.

No known compiler uses non-zero addends in relocations that use the GDAT(S+A) operation, although it is possible to generate them using assembly language.

This change synchronizes the ABI with the behavior of existing static linker implementations. The benefit of permitting code generators [*] to use a non zero addend in GDAT(S + A) is judged to be lower than implementing GDAT(S + A) correctly in existing static linkers, many of which assume that there is a single GOT entry per unique symbol S.

It is QoI whether a static linker gives an error if a non zero addend is used for a relocation that uses the GDAT(S) operation.

Fixes #217 Also resolves #247

[*] The most common use case for a non-zero addend is in constructing a C++ object with a vtable. The first two entries in the vtable are the offset to top and a pointer to RTTI, the vtable pointer in the object starts at offset 0x10. This offset can be encoded in the relocation addend. We would save an add instruction for each construction of a C++ object with a vtable if addends were permitted.

The GDAT(S + A) relocation operation requires a static linker to
create a GOT entry for (S + A). Requiring at least one GOT entry
for each unique tuple (S, A). Unfortunately no known static linker
has implemented this correctly, with one of two forms being
implemented instead:
* GDAT(S) with the addend ignored.
* GDAT(S) + A with a single GOT entry per S, and A added to the
  value of GDAT(S).
These implementations are correct and consistent only for an
addend (A) of zero.

No known compiler uses non-zero addends in relocations that use
the GDAT(S+A) operation, although it is possible to generate
them using assembly language.

This change synchronizes the ABI with the behavior of existing
static linker implementations. The benefit of permitting code
generators [*] to use a non zero addend in GDAT(S + A) is judged
to be lower than implementing GDAT(S + A) correctly in existing
static linkers, many of which assume that there is a single
GOT entry per unique symbol S.

It is QoI whether a static linker gives an error if a non zero
addend is used for a relocation that uses the GDAT(S) operation.

Fixes ARM-software#217
Also resolves ARM-software#247

[*] The most common use case for a non-zero addend is in
constructing a C++ object with a vtable. The first two entries
in the vtable are the offset to top and a pointer to RTTI, the
vtable pointer in the object starts at offset 0x10. This offset
can be encoded in the relocation addend. We would save an add
instruction for each construction of a C++ object with a vtable
if addends were permitted.
Copy link
Contributor

@MaskRay MaskRay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

LLVM before https://reviews.llvm.org/D158577 could produce a non-zero addend for hand-written assembly, but to the best of my knowledge its code generator does not produce such assembly. D158577 was a corner case that was incompatible with static linkers.

@MaskRay
Copy link
Contributor

MaskRay commented Aug 9, 2024

Looks like this issue is still pending :)

@smithp35
Copy link
Contributor Author

smithp35 commented Aug 9, 2024

Looks like this issue is still pending :)

Yes, my apologies, I am a bit behind at the moment. Will hopefully get this merged next week.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

static linkers (lld and GNU ld) out of sync with aaelf64 for GOT relocations with addends.
2 participants