Commit c7205748 authored by Silviu Baranga's avatar Silviu Baranga
Browse files

[Morello] Add MC support for the descriptor ABI

parent a8d207f9
Pipeline #13676 passed with stages
in 162 minutes and 46 seconds
......@@ -152,6 +152,19 @@ ELF_RELOC(R_MORELLO_TLSDESC_ADR_PAGE20, 0xe100)
ELF_RELOC(R_MORELLO_TLSDESC_LD128_LO12, 0xe101)
ELF_RELOC(R_MORELLO_TLSDESC_CALL, 0xe102)
// Descriptor ABI relocations
ELF_RELOC(R_MORELLO_DESC_GLOBAL_CALL26, 0xe200)
ELF_RELOC(R_MORELLO_DESC_GLOBAL_JUMP26, 0xe201)
ELF_RELOC(R_AARCH64_DESC_GLOBAL_CALL26, 0xe202)
ELF_RELOC(R_AARCH64_DESC_GLOBAL_JUMP26, 0xe203)
ELF_RELOC(R_MORELLO_DESC_ADR_PREL_PG_HI20, 0xe204)
ELF_RELOC(R_MORELLO_DESC_ADR_PREL_PG_HI20_NC, 0xe205)
ELF_RELOC(R_MORELLO_DESC_ADR_GOT_PAGE, 0xe206)
ELF_RELOC(R_MORELLO_DESC_LD128_GOT_LO12_NC, 0xe207)
ELF_RELOC(R_MORELLO_DESC_CAPINIT, 0xe208)
ELF_RELOC(R_MORELLO_DESC_CALL, 0xe209)
ELF_RELOC(R_MORELLO_DESC_TCALL, 0xe20a)
// Dynamic Relocations
ELF_RELOC(R_MORELLO_CAPINIT, 0xe800)
ELF_RELOC(R_MORELLO_GLOB_DAT, 0xe801)
......
......@@ -105,6 +105,15 @@ def stlxr_fatptr : PatFrag<(ops node:$val, node:$ptr),
return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::iFATPTR128;
}]>;
let hasSideEffects = 1 in {
def DESCCALL : Pseudo<(outs), (ins i64imm:$sym), []>, Sched<[]> {
let AsmString = ".desccall $sym";
}
def DESCTCALL : Pseudo<(outs), (ins i64imm:$sym), []>, Sched<[]> {
let AsmString = ".desctcall $sym";
}
}
//===------------------------------------
// Atomic infrastructure for capabilities
//===------------------------------------
......
......@@ -174,6 +174,7 @@ private:
bool parseDirectiveTLSDescCall(SMLoc L);
bool parseDirectiveCapInit(SMLoc L);
bool parseDirectiveDescCall(SMLoc L, bool Tail);
bool parseDirectiveLOH(StringRef LOH, SMLoc L);
bool parseDirectiveLtorg(SMLoc L);
......@@ -5750,6 +5751,10 @@ bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
parseDirectiveUnreq(Loc);
else if (IDVal == ".capinit")
parseDirectiveCapInit(Loc);
else if (IDVal == ".desccall")
parseDirectiveDescCall(Loc, false);
else if (IDVal == ".desctcall")
parseDirectiveDescCall(Loc, true);
else if (IDVal == ".inst")
parseDirectiveInst(Loc);
else if (IDVal == ".cfi_negate_ra_state")
......@@ -5920,6 +5925,28 @@ bool AArch64AsmParser::parseFeatures(StringRef ExtensionString,
return false;
}
// parseDirectiveDescCall:
// ::= .desccall symbol
// ::= .desctcall symbol
bool AArch64AsmParser::parseDirectiveDescCall(SMLoc L, bool Tail) {
StringRef Name;
if (check(getParser().parseIdentifier(Name), L,
"expected symbol after directive") ||
parseToken(AsmToken::EndOfStatement))
return true;
MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
const MCExpr *Expr = MCSymbolRefExpr::create(Sym, getContext());
Expr = AArch64MCExpr::create(Expr, AArch64MCExpr::VK_ABS, getContext());
MCInst Inst;
Inst.setOpcode(Tail ? AArch64::DESCCALL : AArch64::DESCTCALL);
Inst.addOperand(MCOperand::createExpr(Expr));
getParser().getStreamer().emitInstruction(Inst, getSTI());
return false;
}
/// parseDirectiveCapInit
/// ::= .capinit Expr
bool AArch64AsmParser::parseDirectiveCapInit(SMLoc L) {
......
......@@ -72,6 +72,8 @@ public:
{"fixup_aarch64_pcrel_call26", 0, 26, PCRelFlagVal},
{"fixup_morello_pcrel_branch26", 0, 26, PCRelFlagVal },
{"fixup_morello_pcrel_call26", 0, 26, PCRelFlagVal },
{"fixup_morello_desc_call", 0, 0, 0},
{"fixup_morello_desc_tcall", 0, 0, 0},
{"fixup_aarch64_tlsdesc_call", 0, 0, 0},
{"fixup_morello_tlsdesc_call", 0, 0, 0},
{"fixup_morello_pcrel_branch14", 5, 14, PCRelFlagVal},
......@@ -126,6 +128,8 @@ static unsigned getFixupKindNumBytes(unsigned Kind) {
case AArch64::fixup_aarch64_tlsdesc_call:
case AArch64::fixup_morello_tlsdesc_call:
case AArch64::fixup_morello_desc_call:
case AArch64::fixup_morello_desc_tcall:
return 0;
case FK_Data_1:
......@@ -407,6 +411,8 @@ unsigned AArch64AsmBackend::getFixupKindContainereSizeInBytes(unsigned Kind) con
case AArch64::fixup_aarch64_tlsdesc_call:
case AArch64::fixup_morello_tlsdesc_call:
case AArch64::fixup_morello_desc_call:
case AArch64::fixup_morello_desc_tcall:
case AArch64::fixup_aarch64_movw:
case AArch64::fixup_aarch64_pcrel_branch14:
case AArch64::fixup_morello_pcrel_branch14:
......
......@@ -20,6 +20,7 @@
#include "llvm/MC/MCFixup.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCValue.h"
#include "llvm/MC/MCTargetOptions.h"
#include "llvm/Support/ErrorHandling.h"
#include <cassert>
#include <cstdint>
......@@ -51,6 +52,7 @@ bool AArch64ELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym,
return false;
case ELF::R_MORELLO_CAPINIT:
case ELF::R_MORELLO_DESC_CAPINIT:
return true;
}
}
......@@ -126,6 +128,9 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
static_cast<AArch64MCExpr::VariantKind>(Target.getRefKind());
AArch64MCExpr::VariantKind SymLoc = AArch64MCExpr::getSymbolLoc(RefKind);
bool IsNC = AArch64MCExpr::isNotChecked(RefKind);
bool IsDescABI =
(MCTargetOptions::cheriCapabilityTableABI() ==
CheriCapabilityTableABI::FunctionDescriptor);
assert((!Target.getSymA() ||
Target.getSymA()->getKind() == MCSymbolRefExpr::VK_None ||
......@@ -168,11 +173,17 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
return ELF::R_AARCH64_NONE;
}
if (SymLoc == AArch64MCExpr::VK_ABS && !IsNC)
return ELF::R_MORELLO_ADR_PREL_PG_HI20;
return IsDescABI
? ELF::R_MORELLO_DESC_ADR_PREL_PG_HI20
: ELF::R_MORELLO_ADR_PREL_PG_HI20;
if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
return ELF::R_MORELLO_ADR_PREL_PG_HI20_NC;
return IsDescABI
? ELF::R_MORELLO_DESC_ADR_PREL_PG_HI20_NC
: ELF::R_MORELLO_ADR_PREL_PG_HI20_NC;
if (SymLoc == AArch64MCExpr::VK_GOT && !IsNC)
return ELF::R_MORELLO_ADR_GOT_PAGE;
return IsDescABI
? ELF::R_MORELLO_DESC_ADR_GOT_PAGE
: ELF::R_MORELLO_ADR_GOT_PAGE;
if (SymLoc == AArch64MCExpr::VK_TLSDESC && !IsNC)
return ELF::R_MORELLO_TLSDESC_ADR_PAGE20;
Ctx.reportError(Fixup.getLoc(),
......@@ -201,13 +212,21 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
"invalid symbol kind for ADRP relocation");
return ELF::R_AARCH64_NONE;
case AArch64::fixup_aarch64_pcrel_branch26:
return R_CLS(JUMP26);
return IsDescABI
? ELF::R_AARCH64_DESC_GLOBAL_JUMP26
: R_CLS(JUMP26);
case AArch64::fixup_aarch64_pcrel_call26:
return R_CLS(CALL26);
return IsDescABI
? ELF::R_AARCH64_DESC_GLOBAL_CALL26
: R_CLS(CALL26);
case AArch64::fixup_morello_pcrel_branch26:
return ELF::R_MORELLO_JUMP26;
return IsDescABI
? ELF::R_MORELLO_DESC_GLOBAL_JUMP26
: ELF::R_MORELLO_JUMP26;
case AArch64::fixup_morello_pcrel_call26:
return ELF::R_MORELLO_CALL26;
return IsDescABI
? ELF::R_MORELLO_DESC_GLOBAL_CALL26
: ELF::R_MORELLO_CALL26;
case AArch64::fixup_aarch64_ldr_pcrel_imm17_scale16:
if (SymLoc == AArch64MCExpr::VK_GOTTPREL ||
SymLoc == AArch64MCExpr::VK_GOT) {
......@@ -253,7 +272,10 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
return ELF::R_AARCH64_NONE;
} else
switch (SymLoc) {
case AArch64MCExpr::VK_CAPINIT: return ELF::R_MORELLO_CAPINIT;
case AArch64MCExpr::VK_CAPINIT:
return IsDescABI
? ELF::R_MORELLO_DESC_CAPINIT
: ELF::R_MORELLO_CAPINIT;
default: return ELF::R_AARCH64_ABS64;
}
case AArch64::fixup_aarch64_add_imm12:
......@@ -423,7 +445,9 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC)
return R_CLS(TLSLE_LDST128_TPREL_LO12_NC);
if (SymLoc == AArch64MCExpr::VK_GOT && IsNC)
return ELF::R_MORELLO_LD128_GOT_LO12_NC;
return IsDescABI
? ELF::R_MORELLO_DESC_LD128_GOT_LO12_NC
: ELF::R_MORELLO_LD128_GOT_LO12_NC;
if (SymLoc == AArch64MCExpr::VK_TLSDESC)
return ELF::R_MORELLO_TLSDESC_LD128_LO12;
......@@ -497,6 +521,10 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
return R_CLS(TLSDESC_CALL);
case AArch64::fixup_morello_tlsdesc_call:
return ELF::R_MORELLO_TLSDESC_CALL;
case AArch64::fixup_morello_desc_call:
return ELF::R_MORELLO_DESC_CALL;
case AArch64::fixup_morello_desc_tcall:
return ELF::R_MORELLO_DESC_TCALL;
default:
Ctx.reportError(Fixup.getLoc(), "Unknown ELF relocation type");
return ELF::R_AARCH64_NONE;
......
......@@ -64,6 +64,9 @@ enum Fixups {
fixup_morello_pcrel_branch26,
fixup_morello_pcrel_call26,
fixup_morello_desc_call,
fixup_morello_desc_tcall,
// zero-space placeholder for the ELF R_AARCH64_TLSDESC_CALL relocation.
fixup_aarch64_tlsdesc_call,
......
......@@ -671,6 +671,16 @@ void AArch64MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
return;
}
if (MI.getOpcode() == AArch64::DESCCALL ||
MI.getOpcode() == AArch64::DESCTCALL) {
// Same as R_AARCH64_TLSDESC_CALL, these don't emit any code.
MCFixupKind Fixup = MCFixupKind(MI.getOpcode() == AArch64::DESCCALL
? AArch64::fixup_morello_desc_call
: AArch64::fixup_morello_desc_tcall);
Fixups.push_back(MCFixup::create(0, MI.getOperand(0).getExpr(), Fixup));
return;
}
if (MI.getOpcode() == AArch64::CompilerBarrier ||
MI.getOpcode() == AArch64::SPACE) {
// CompilerBarrier just prevents the compiler from reordering accesses, and
......
// RUN: llvm-mc -triple=arm64 -mattr=+morello,+c64 -target-abi purecap -cheri-cap-table-abi=fn-desc %s -o - -filetype=obj | llvm-readobj -r | FileCheck %s --check-prefix=RELOCS
// RUN: llvm-mc -triple=arm64 -mattr=+morello,+c64 -target-abi purecap -cheri-cap-table-abi=fn-desc %s -show-encoding -o - | FileCheck %s --check-prefix=ASM
// RELOCS: Section (3) .rela.text {
// RELOCS: 0x0 R_MORELLO_DESC_ADR_PREL_PG_HI20 foo 0xC
// RELOCS: 0x4 R_MORELLO_DESC_ADR_GOT_PAGE foo 0x0
// RELOCS: 0x8 R_MORELLO_DESC_LD128_GOT_LO12_NC foo 0x0
// RELOCS: 0xC R_MORELLO_TLSDESC_ADR_PAGE20 var 0x0
// RELOCS: 0x10 R_MORELLO_TLSDESC_LD128_LO12 tlsvar 0x0
// RELOCS: 0x14 R_AARCH64_TLSDESC_ADD_LO12 tlsvar 0x0
// RELOCS: 0x18 R_MORELLO_DESC_TCALL bar 0x0
// RELOCS: 0x1C R_MORELLO_DESC_CALL bar 0x0
// RELOCS: 0x20 R_MORELLO_DESC_TCALL .text 0x18
// RELOCS: 0x24 R_MORELLO_DESC_CALL .text 0x18
// RELOCS: }
// RELOCS: Section (5) .rela.data {
// RELOCS: 0x10 R_MORELLO_DESC_CAPINIT str 0x8
// RELOCS: 0x20 R_MORELLO_DESC_CAPINIT str 0x0
// RELOCS: }
// ASM: adrp c0, foo+12 // encoding: [A,A,0x80'A',0x90'A']
// ASM-NEXT: // fixup A - offset: 0, value: foo+12, kind: fixup_aarch64_pcrel_adrp_imm20
// ASM-NEXT: adrp c0, :got:foo // encoding: [A,A,0x80'A',0x90'A']
// ASM-NEXT: // fixup A - offset: 0, value: :got:foo, kind: fixup_aarch64_pcrel_adrp_imm20
// ASM-NEXT: ldr c0, [c0, :got_lo12:foo] // encoding: [0x00,0bAAAAAA00,0b01AAAAAA,0xc2]
// ASM-NEXT: // fixup A - offset: 0, value: :got_lo12:foo, kind: fixup_aarch64_ldst_imm12_scale16
// ASM-NEXT: adrp c0, :tlsdesc:var // encoding: [A,A,0x80'A',0x90'A']
// ASM-NEXT: // fixup A - offset: 0, value: :tlsdesc:var, kind: fixup_aarch64_pcrel_adrp_imm20
// ASM-NEXT: ldr c1, [c0, :tlsdesc_lo12:tlsvar] // encoding: [0x01,0bAAAAAA00,0b01AAAAAA,0xc2]
// ASM-NEXT: // fixup A - offset: 0, value: :tlsdesc_lo12:tlsvar, kind: fixup_aarch64_ldst_imm12_scale16
// ASM-NEXT: add c0, c0, :tlsdesc_lo12:tlsvar // encoding: [0x00,0bAAAAAA00,0b00AAAAAA,0x02]
// ASM-NEXT: // fixup A - offset: 0, value: :tlsdesc_lo12:tlsvar, kind: fixup_aarch64_add_imm12
// ASM-LABEL: baz:
// ASM-NEXT: .desctcall bar // encoding: []
// ASM-NEXT: // fixup A - offset: 0, value: bar, kind: fixup_morello_desc_tcall
// ASM: .desccall bar // encoding: []
// ASM-NEXT: // fixup A - offset: 0, value: bar, kind: fixup_morello_desc_call
// ASM: .desctcall baz // encoding: []
// ASM-NEXT: // fixup A - offset: 0, value: baz, kind: fixup_morello_desc_tcall
// ASM: .desccall baz // encoding: []
// ASM-NEXT: // fixup A - offset: 0, value: baz, kind: fixup_morello_desc_call
adrp c0, foo+12
adrp c0, :got:foo
ldr c0, [c0, :got_lo12:foo]
adrp c0, :tlsdesc:var
ldr c1, [c0, #:tlsdesc_lo12:tlsvar]
add c0, c0, #:tlsdesc_lo12:tlsvar
baz:
.desccall bar
add c0, c0, #1
.desctcall bar
add c0, c0, #1
.desccall baz
add c0, c0, #1
.desctcall baz
add c0, c0, #1
.type str,@object
.data
.globl str
str:
.asciz "foo bar baz"
.size str, 12
.type ptr1,@object
.globl ptr1
.p2align 4
ptr1:
.capinit str+8
.xword 0
.xword 0
.size ptr1, 16
.type ptr2,@object
.globl ptr2
.p2align 4
ptr2:
.capinit str
.xword 0
.xword 0
.size ptr2, 16
.type .L.str,@object
.section .rodata.str1.1,"aMS",@progbits,1
.L.str:
.asciz "%d\n"
.size .L.str, 4
// RUN: llvm-mc -triple=aarch64-none-elf -mattr=+morello -target-abi purecap -cheri-cap-table-abi=fn-desc %s -filetype=obj -o - | llvm-objdump --mattr=+morello -d - -r | FileCheck %s
.arch armv8-a+c64
.globl biz
.type biz, @function
biz:
// CHECK: bl 0x0
// CHECK-NEXT: R_MORELLO_DESC_GLOBAL_CALL26 bar
bl bar
// CHECK: b 0x4
// CHECK-NEXT: R_MORELLO_DESC_GLOBAL_JUMP26 baz
b baz
.arch morello
.globl bif
.type bif, @function
bif:
// CHECK: bl 0x8
// CHECK-NEXT: R_AARCH64_DESC_GLOBAL_CALL26 bar
bl bar
// CHECK: b 0xc
// CHECK-NEXT: R_AARCH64_DESC_GLOBAL_JUMP26 baz
b baz
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment