This is an archive of the discontinued LLVM Phabricator instance.

[AArch64][ELF] Support R_AARCH64_AUTH_ABS64 static relocation
ClosedPublic

Authored by kovdan01 on Jul 27 2023, 10:58 PM.

Details

Summary

The patch adds parser, MCExpr, and emitter support for the authenticated
pointer auth relocation.

In assembly, this is expressed using:

.quad <symbol>@AUTH(<key>, <discriminator> [, addr])

For example:

.quad _g3@AUTH(ib, 1234, addr)

The optional 'addr' specifier represents whether the generated pointer
authentication code will also include address diversity (by blending the
address of the storage location of the relocated pointer with the
user-specified constant discriminator).

The @AUTH expression lowers to R_AARCH64_AUTH_ABS64 ELF relocation.

The signing schema is encoded in the place of relocation to be applied
as follows:

| 63                | 62 | 61:60 | 59:48 |  47:32        | 31:0   |
| ----------------- | -- | ----- | ----- | ------------- | ------ |
| address diversity | 0  | key   | 0     | discriminator | addend |

See the following for details:
https://github.com/ARM-software/abi-aa/blob/main/pauthabielf64/pauthabielf64.rst#static-relocations

Co-authored-by: Ahmed Bougacha <ahmed@bougacha.org>
Co-authored-by: Peter Collingbourne <peter@pcc.me.uk>

Diff Detail

Event Timeline

kovdan01 created this revision.Jul 27 2023, 10:58 PM
Herald added a project: Restricted Project. · View Herald TranscriptJul 27 2023, 10:58 PM
kovdan01 requested review of this revision.Jul 27 2023, 10:58 PM
Herald added a project: Restricted Project. · View Herald TranscriptJul 27 2023, 10:58 PM
kovdan01 added a subscriber: asl.Jul 27 2023, 11:28 PM
kovdan01 updated this revision to Diff 545181.Jul 28 2023, 8:51 AM

Will try and look at this next week (will be out of the office for a most of it so it could slip to the week after), happy to let others approve in my absence if they are happy with it.

MaskRay added a subscriber: MaskRay.Aug 2 2023, 8:35 PM
MaskRay added inline comments.
lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
7522 ↗(On Diff #545181)

Many of the error messages are untested.

7539 ↗(On Diff #545181)

itostr requires including StringExtras.h. That said, you can use Twine(Discriminator) here.

Also, this error should be covered by a test.

7555 ↗(On Diff #545181)

The error message is not tested.

I think a simple "expected ')'" is sufficient. The integrated assembler marks the column that an error occurs, so it's obvious that this message applies to @AUTH.

7561 ↗(On Diff #545181)

nit: delete blank line

lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
326 ↗(On Diff #545181)

Nit

test/MC/AArch64/arm64-ptrauth-elf-reloc.s
1 ↗(On Diff #545181)

Did you not use git format-patch -1 or git diff to create a diff?

This creates a directory under llvm-project, instead of using llvm/test/

1 ↗(On Diff #545181)

llvm-mc doesn't need < %s. Just use %s

1 ↗(On Diff #545181)

The test name should omit arm64- prefix, which is redundant for a file under MC/AArch64.

4 ↗(On Diff #545181)

Prefer aarch64 for Linux target triples: https://nickdesaulniers.github.io/blog/2023/03/10/disambiguating-arm/

aarch64 (generic ELF) is better than *-linux as the former applies to other ELF OSes like *BSD.

5 ↗(On Diff #545181)

llvm-readobj is quite verbose. Tabular output from llvm-readelf -S -r may look better. Use -x sectionname for content.

112 ↗(On Diff #545181)

While here, consider making some _g* symbols defined or give them a local binding to add some variance.

114 ↗(On Diff #545181)

A test involving more modifiers like a@PLT@AUTH(ib,0) may be interesting to add.

MaskRay added inline comments.Aug 2 2023, 8:38 PM
docs/PointerAuth.md
331 ↗(On Diff #545181)

At the object file level, ...

"binary object file" is not a term.

333 ↗(On Diff #545181)

ARM64_RELOC_AUTHENTICATED_POINTER is from Mach-O, but the sentence is written in the context of ELF. You need extra words to mean that this resembles ARM64_RELOC_AUTHENTICATED_POINTER from Mach-O.

344 ↗(On Diff #545181)

delete trailing blank line

kovdan01 updated this revision to Diff 547060.Aug 3 2023, 5:21 PM
kovdan01 marked 9 inline comments as done.

Address several review comments

@MaskRay Thanks for such a detailed review! I've uploaded a new "intermediate" version with all the fixes except enhancing tests (e.g. adding missing ones). Marked the corresponding comments as done, feel free to re-open them if further discussion is needed. Regarding tests enhancements - I'll upload the patch fixing that shortly.

docs/PointerAuth.md
333 ↗(On Diff #545181)

ARM64_RELOC_AUTHENTICATED_POINTER is from Mach-O, but the sentence is written in the context of ELF. You need extra words to mean that this resembles ARM64_RELOC_AUTHENTICATED_POINTER from Mach-O.

The sentence was supposed to mention R_AARCH64_AUTH_ABS64, thanks for noticing this. I think we should not mention the MachO relocation in context of the patch: (a) the patch only adds support for the ELF reloc; (b) AFAIK, a different signing schema encoding is used for the MachO reloc. So, just replaced ARM64_RELOC_AUTHENTICATED_POINTER -> R_AARCH64_AUTH_ABS64 as initially intended.

test/MC/AArch64/arm64-ptrauth-elf-reloc.s
1 ↗(On Diff #545181)

Did you not use git format-patch -1 or git diff to create a diff?

This creates a directory under llvm-project, instead of using llvm/test/

Thanks for bringing attention to this, fixed. It's quite strange though since I usually use git show HEAD -U999999 > mypatch.patch (as described here https://llvm.org/docs/Phabricator.html#requesting-a-review-via-the-web-interface) which works fine.

kovdan01 updated this revision to Diff 547663.Aug 7 2023, 12:51 AM
kovdan01 marked 6 inline comments as done.

Fix various review comments:

  • Add missing tests for error messages
  • Enhance tests readability
  • Minor nits

@MaskRay Fixed the issues you've mentioned. Would be glad to see your review on new version of the patch.

test/MC/AArch64/arm64-ptrauth-elf-reloc.s
114 ↗(On Diff #545181)

Explicitly marked such combinations as unsupported.

kovdan01 added inline comments.Aug 7 2023, 12:53 AM
lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
7555 ↗(On Diff #545181)

I think a simple "expected ')'" is sufficient. The integrated assembler marks the column that an error occurs, so it's obvious that this message applies to @AUTH.

It makes sense. Deleted similar redundant info from other error messages as well.

test/MC/AArch64/arm64-ptrauth-elf-reloc.s
5 ↗(On Diff #545181)

Thanks, llvm-readelf's output definitely looks better in our case

Not much to add to what MaskRay has already said. Some suggestions to improve error messages and comments.

llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
7541

Similar error messages use out of range. Ideally we should give the permitted range in the error message.
integer discriminator <Discrimator> is out of range, [0, 65535] expected

llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
338

I'm not sure if MC can easily generate a REL relocation for AArch64. IIRC REL format may occur in the dynamic case, for RELATIVE compression and REL format dynamic relocations (lld -z rel).

343

Worth saying what the range is in the error message? For example there are other error messages with fixup value out of range [-0xFFFF, 0xFFFF]"); For example:
"out of range addend <Value> in auth relocation. Permitted range [-2,147,483,648, -2,147,483,647]"

kovdan01 updated this revision to Diff 548161.Aug 8 2023, 5:15 AM
kovdan01 marked 3 inline comments as done.

Fix issues mentioned by @pcc

llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
7541

It makes sense, changed the message, thanks. I used hex values since they look nicer and more readable in this context.

llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
338

I added a TODO for checking if such case is even possible. I think that the if statement should be kept since the ABI explicitly says that those bits are used for addend on platforms with rel.

Thanks for mentioning the dynamic case (lld -z rel). I'll check it, but it's out of scope of this patch so mark the comment as done. Feel free to re-open it if needed.

343

Fixed, thanks. I also used hex values here: although most people are familiar with decimal representation of these values, they are more messy than their hex variants.

@MaskRay @pcc I've addressed all the comments. Please let me know if there are some issues which must be fixed or the patch can be approved. Thanks!

@MaskRay @pcc I've addressed all the comments. Please let me know if there are some issues which must be fixed or the patch can be approved. Thanks!

It looks OK on my side, MaskRay had more substantitive comments so I'm happy when he is.

FYI I'm not pcc, I'm psmith or peter.smith. Same first name as pcc which can be confusing!

FYI I'm not pcc, I'm psmith or peter.smith. Same first name as pcc which can be confusing!

Ah, my fault, sorry for that mistake.

kovdan01 updated this revision to Diff 549958.Aug 14 2023, 8:30 AM

Rebase to current mainline

MaskRay added inline comments.Aug 14 2023, 11:15 PM
llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp
201

delete blank line

llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h
216

unneeded?

llvm/test/MC/AArch64/ptrauth-elf-reloc.s
94 ↗(On Diff #549958)

llvm-mc has error recovery. You can test all errors in one llvm-mc invocation, instead of using many err*.s

95 ↗(On Diff #549958)

continuation lines are indented by 2 by convention

97 ↗(On Diff #549958)

Newer tests are recommended to test the line/column information like:

// ERR: :[[#@LINE+1]]:10: error: expected '('
.quad sym@AUTH)ia,42)
kovdan01 updated this revision to Diff 550372.Aug 15 2023, 9:47 AM
kovdan01 marked 5 inline comments as done.

Fix issues mentioned by @MaskRay

llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp
201

Done

llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h
216

This is needed for cast operation in adjustFixupValue in AArch64AsmBackend.cpp:341. But the check was not correct, fixed that. Decided to use a combination of isa + cast instead of a single dyn_cast since it results in a more elegant one-liner.

llvm/test/MC/AArch64/ptrauth-elf-reloc.s
94 ↗(On Diff #549958)

Fixed, thanks

95 ↗(On Diff #549958)

Fixed, thanks

97 ↗(On Diff #549958)

Applied this, thanks

MaskRay added a comment.EditedAug 16 2023, 10:39 PM

Being unable to reuse the generic AsmParser::parsePrimaryExpr if (!MAI.useParensForSymbolVariant()) makes me nervous, but I think this is probably fine.
However, I think we need some unary/binary operator tests like 1 + sym@AUTH(ia,42) + 1, sym@AUTH(ia,0) + sym@AUTH(ia,0). It's possible that many lead to errors.

llvm/docs/PointerAuth.md
308

This file is a Markdown. Single backquotes are more commonly used.

llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
7541

Peter's suggestion does not contain a period, which is more conventional.

Other used formats include is not within [..., ...] (.subsections) and is not in [..., ...] (lld/ELF)

llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
338

You can delete TODO.

AArch64ELFObjectWriter uses /*HasRelocationAddend*/ true.

You may use an assert instead.

343

Sorry for the bikeshedding, but I think out-of-range diagnostics don't usually contain a period.

Something like auth relocation addend <Value> out of range [...,...] may be better.

349

The two used-once variables can be removed.

351

delete blank line

418

I think this condition can be removed if we move custom code adjustFixupValue to this function. See the next comment.

428

We shouldn't have two conditions for FK_Data_8.

We probably should move the custom code from adjustFixupValue to here.

llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp
158

delete

llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h
21

clang-format should move Casting.h before ErrorHandling.h

180
190

These annotations provide very little value. I think we discourage them for newer code to make classes more compact.

198

ditto

llvm/test/MC/AArch64/ptrauth-elf-reloc.s
94 ↗(On Diff #549958)

Sorry that I didn't mention another point. When we have just one patch of negative tests, we can just wrap them with

.ifdef ERR
...
...
.endif

and then we can avoid invoking split-file.

You can grep def ERR in test/MC to find many newer tests I added.

97 ↗(On Diff #549958)

[[#@LINE-77]] may not be a good choice. If we add more lines before the checks, the -77 part will need adjustment.

My original suggestion is

// ERR: :[[#@LINE+1]]:10: error: expected '('
.quad sym@AUTH)ia,42)

// ERR: :[[#@LINE+1]]:10: error: ...
.quad ...
1 ↗(On Diff #550372)

To following the convention of test naming, this probably should be elf-reloc-ptrauth.s

6 ↗(On Diff #550372)

ditto

actually, this line is so short that we should not use continuation

9 ↗(On Diff #550372)

continuation lines are indented by 2 by convention

kovdan01 updated this revision to Diff 551521.Aug 18 2023, 8:17 AM
kovdan01 marked 16 inline comments as done.

Fix some of @MaskRay's comment

TODO: add more unary/binary operator tests like 1 + sym@AUTH(ia,42) + 1, sym@AUTH(ia,0) + sym@AUTH(ia,0).

llvm/docs/PointerAuth.md
308

I agree with that, but double backquotes are already used in other places in this file.
I suggest to leave this 'as is' in context of current patch and submit a small subsequent patch changing double- to single backquote all over the file.

llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
7541

Changed to integer discriminator <disc> out of range [..., ...] as such variant seems to be both compact and widely-used in lld. Thanks for providing the examples.

llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
338

If I got your point correctly, we can even check that the value is exactly 0. With rela, the value must be exactly 0, not just a 32-bit integer. Please let me know if I got you right.

343

Got it, thanks. Fixed other error messages. This one seems to be obsolete when keeping the following in mind:

You can delete TODO.
AArch64ELFObjectWriter uses /*HasRelocationAddend*/ true.
You may use an assert instead.

349

Fixed

351

Fixed

418

This is more convenient, fixed, thanks.

llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp
158

Done

llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h
21

Fixed, thanks. I avoided running clang-format on this particular file since it broke custom spacing before = sign in enum VariantKind below.

180

Done

190

OK, got it. I added them since the surrounding code was already using them, but I agree that they do not make much sense.

llvm/test/MC/AArch64/ptrauth-elf-reloc.s
94 ↗(On Diff #549958)

Applied this approach, thanks!

97 ↗(On Diff #549958)

It's a nice approach, fixed, thanks

1 ↗(On Diff #550372)

Fixed

6 ↗(On Diff #550372)

Fixed

9 ↗(On Diff #550372)

Fixed

MaskRay accepted this revision.Aug 19 2023, 2:58 PM

TODO: add more unary/binary operator tests like 1 + sym@AUTH(ia,42) + 1, sym@AUTH(ia,0) + sym@AUTH(ia,0).

Yes, we should add the coverage, otherwise this looks good to me.

llvm/docs/PointerAuth.md
308

Adding double quotes than applying another patch changing double quotes to single quotes is not a good idea.
We can add single quotes directly.

The existing places can be fixed separately. I shall also mention that .rst is more commonly used and helps cross-doc links.

This revision is now accepted and ready to land.Aug 19 2023, 2:58 PM
kovdan01 updated this revision to Diff 552562.Aug 22 2023, 6:46 PM

Propose additional unary/binary operator tests like 1 + sym@AUTH(ia,42) + 1, sym@AUTH(ia,0) + sym@AUTH(ia,0):

  • Parsing assembly code
  • Producing errors when emitting object file

To make the latter work properly, altered EvaluateSymbolicAdd. Without the change, incorrect relocations were emitted instead of producing an error. @MaskRay would be glad if you could look through this before landing since I consider these changes non-trivial.

kovdan01 marked 2 inline comments as done.Aug 22 2023, 6:47 PM
kovdan01 added inline comments.
llvm/docs/PointerAuth.md
308

OK, changed to single-quotes. After this lands, I'll send an NFC patch changing double-quotes in other places in this file

MaskRay accepted this revision.Aug 22 2023, 9:16 PM
MaskRay added inline comments.
llvm/test/MC/AArch64/elf-reloc-ptrauth.s
87

By MCONLY you mean this is only used for -filetype=asm (default for llvm-mc)? I think using "MC" in this context is confusing.

ASMONLY may be better since -filetype=asm uses MCAsmStreamer, different from MCObjectStreamer used by -filetype=obj.

100

An subtraction expression test will be interesting as well.

The addition of two non-absolute symbols cannot be represented in the relocatable object file while the subtractions can often be represented.

kovdan01 updated this revision to Diff 553144.Aug 24 2023, 8:35 AM
kovdan01 marked an inline comment as done.

Add a subtraction expression test

kovdan01 marked an inline comment as done.Aug 24 2023, 8:38 AM
kovdan01 added inline comments.
llvm/test/MC/AArch64/elf-reloc-ptrauth.s
87

Changed to ASMONLY, it suites the case better, thanks

100

Implemented a one. Left a TODO regarding subtraction of an AUTH and non-AUTH symbols. Currently we emit an error in such a case, but we might not want such behavior since there is no difference whether the symbol is AUTH or not when computing compile-time-known distance. Please let me know your thought regarding that.

This revision was landed with ongoing or failed builds.Aug 24 2023, 8:59 AM
This revision was automatically updated to reflect the committed changes.
kovdan01 marked an inline comment as done.