This is an archive of the discontinued LLVM Phabricator instance.

[AArch64] Force relocations for all ADRP instructions
ClosedPublic

Authored by mstorsjo on Jul 18 2017, 4:01 AM.

Details

Summary

This generalizes an existing fix from ELF to MachO and COFF.

Test that an ADRP to a local symbol whose offset is known at assembly time still produces relocations, both for MachO and COFF. Test that an ADRP without a @page modifier on MachO fails (previously it didn't).

Diff Detail

Event Timeline

mstorsjo created this revision.Jul 18 2017, 4:01 AM

I'd be interested in knowing why this isn't done by default (i.e. why this doesn't need to be done at all for MachO) btw, if someone has got time to explain.

t.p.northover edited edge metadata.Jul 18 2017, 7:39 AM

I'd be interested in knowing why this isn't done by default (i.e. why this doesn't need to be done at all for MachO) btw, if someone has got time to explain.

I'm pretty sure that's a bug, I get the wrong answer when I actually try out this function on iOS:

        .text
        .global _foo
        .p2align 12
_foo:
        .fill 1023, 4, 0xd503201f
        adrp x0, Lthere
Lthere:
        ret

I suspect it hasn't come up on MachO because CodeGen never used ADRP to address objects in the __text section so you need assembly to trigger it.

So would you mind putting that function into the base AArch64AsmBackend?

mgrang added inline comments.Jul 18 2017, 11:01 AM
lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
585

Period at the end of comment.

test/MC/AArch64/adrp-relocation-coff.s
1 ↗(On Diff #107053)

There's already a test case for coff relocations: test/MC/AArch64/coff-relocations.s. Would you mind adding to the same file instead of creating a new one just for adrp relocs?

mstorsjo added inline comments.Jul 18 2017, 12:08 PM
lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
585

I'll move the ELFAArch64AsmBackend implementation up to the superclass, so this comment will go away altogether.

test/MC/AArch64/adrp-relocation-coff.s
1 ↗(On Diff #107053)

Sure, I can do that. Although since this fix is getting generalized for MachO as well, I'd like to test that as well. Should I try to add that into some MachO specific file as well, or have an adrp specific test file? The current one (adrp-relocation.s) tests some relocations that I don't think all are supported in COFF at least, which was why I tried to create a new one here.

I'd be interested in knowing why this isn't done by default (i.e. why this doesn't need to be done at all for MachO) btw, if someone has got time to explain.

I'm pretty sure that's a bug, I get the wrong answer when I actually try out this function on iOS:

        .text
        .global _foo
        .p2align 12
_foo:
        .fill 1023, 4, 0xd503201f
        adrp x0, Lthere
Lthere:
        ret

I suspect it hasn't come up on MachO because CodeGen never used ADRP to address objects in the __text section so you need assembly to trigger it.

I did a quick test like this:

static int the_func(int a);
                
void *get_func(void) {
        return the_func;
}

static int the_func(int a) {
        return 2*a;
}

and got this:

$ clang test.c -c -o test.o -O3 -target arm64-apple-darwin
$ llvm-objdump -d -r test.o

test.o:  file format Mach-O arm64

Disassembly of section __TEXT,__text:
ltmp0:
       0:       00 00 00 90     adrp    x0, #0
                0000000000000000:  ARM64_RELOC_PAGE21   _the_func
       4:       00 00 00 91     add     x0, x0, #0
                0000000000000004:  ARM64_RELOC_PAGEOFF12        _the_func
       8:       c0 03 5f d6     ret

_the_func:
       c:       00 78 1f 53     lsl     w0, w0, #1
      10:       c0 03 5f d6     ret

So it seems to me like it actually does use ADRP, but probably via some other codepath, since it does generate a relocation. But fixing it for handwritten assembly obviously also is worthwhile.

So would you mind putting that function into the base AArch64AsmBackend?

Sure, will do.

I'd be interested in knowing why this isn't done by default (i.e. why this doesn't need to be done at all for MachO) btw, if someone has got time to explain.

I'm pretty sure that's a bug, I get the wrong answer when I actually try out this function on iOS:

        .text
        .global _foo
        .p2align 12
_foo:
        .fill 1023, 4, 0xd503201f
        adrp x0, Lthere
Lthere:
        ret

I suspect it hasn't come up on MachO because CodeGen never used ADRP to address objects in the __text section so you need assembly to trigger it.

So would you mind putting that function into the base AArch64AsmBackend?

Actually, when I try to move the function from ELFAArch64AsmBackend to AArch64AsmBackend, I suddenly started getting the following errors when assembling your test snippet:

test.s:7:9: error: ADR/ADRP relocations must be GOT relative
        adrp x0, Lthere
        ^
test.s:7:9: error: unknown AArch64 fixup kind!
        adrp x0, Lthere

So it seems to me like it actually does use ADRP, but probably via some other codepath, since it does generate a relocation. But fixing it for handwritten assembly obviously also is worthwhile.

MachO always splits up the __text section by its global symbols (sorry, I realise I was a bit vague earlier), so it emits a relocation for those reasons. You'd need to convince LLVM to use ADRP for something in the same function to see the effect. I'm not aware of any LLVM or C code that would do that (aside from inline asm, of course).

Actually, when I try to move the function from ELFAArch64AsmBackend to AArch64AsmBackend, I suddenly started getting the following errors when assembling your test snippet:

Ah, interesting! I actually think that's correct behaviour. The MachO adrp always has a textual tag for the kind of relocation you want. For example adrp x0, Lthere@PAGE. So without that function we silently miscompiled invalid code instead of diagnosing it; with your change it survives to the relocation phase to be reported.

Technically we should probably diagnose it earlier (AsmParser), but for your purposes just checking that there is an error in the MachO case is probably the right thing to do.

Actually, when I try to move the function from ELFAArch64AsmBackend to AArch64AsmBackend, I suddenly started getting the following errors when assembling your test snippet:

Ah, interesting! I actually think that's correct behaviour. The MachO adrp always has a textual tag for the kind of relocation you want. For example adrp x0, Lthere@PAGE. So without that function we silently miscompiled invalid code instead of diagnosing it; with your change it survives to the relocation phase to be reported.

Technically we should probably diagnose it earlier (AsmParser), but for your purposes just checking that there is an error in the MachO case is probably the right thing to do.

Oh, indeed, I forgot that MachO has a different syntax for these. I'll update with tests for both of these cases.

mstorsjo updated this revision to Diff 107277.Jul 19 2017, 3:48 AM
mstorsjo retitled this revision from [COFF, ARM64] Force ADRP relocations to [AArch64] Force relocations for all ADRP instructions.
mstorsjo edited the summary of this revision. (Show Details)

Moved the fix from ELF to the base class, added tests for COFF and MachO.

t.p.northover accepted this revision.Jul 19 2017, 6:33 AM

Looks fine to me other than a nit about the MachO test. Unless the fix to that gets weird and you want to confirm it's right you can commit without uploading another revision.

test/MC/AArch64/macho-adrp-missing-reloc.s
3

This isn't really a failure. The usual way to check error messages is something like:

; RUN: not llvm-mc < %s -triple arm64-apple-darwin 2>&1 | FileCheck %s
; CHECK: error: ADR/ADRP relocations must be GOT relative

The "not" means it's acceptable for llvm-mc to "fail", and the FileCheck makes sure we get a vaguely sensible error message rather than a crash or some other nonsense.

This revision is now accepted and ready to land.Jul 19 2017, 6:33 AM
This revision was automatically updated to reflect the committed changes.