[PowerPC] Support .reloc *, R_PPC{,64}_NONE, *

This can be used to create references among sections. When --gc-sections
is used, the referenced section will be retained if the origin section
is retained.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@360990 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Fangrui Song 2019-05-17 06:04:11 +00:00
parent b334d02c14
commit b8552574f3
4 changed files with 100 additions and 25 deletions

View File

@ -28,6 +28,7 @@ static uint64_t adjustFixupValue(unsigned Kind, uint64_t Value) {
switch (Kind) {
default:
llvm_unreachable("Unknown fixup kind!");
case FK_NONE:
case FK_Data_1:
case FK_Data_2:
case FK_Data_4:
@ -51,6 +52,8 @@ static unsigned getFixupKindNumBytes(unsigned Kind) {
switch (Kind) {
default:
llvm_unreachable("Unknown fixup kind!");
case FK_NONE:
return 0;
case FK_Data_1:
return 1;
case FK_Data_2:
@ -137,9 +140,11 @@ public:
bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
const MCValue &Target) override {
switch ((PPC::Fixups)Fixup.getKind()) {
switch ((unsigned)Fixup.getKind()) {
default:
return false;
case FK_NONE:
return true;
case PPC::fixup_ppc_br24:
case PPC::fixup_ppc_br24abs:
// If the target symbol has a local entry point we must not attempt
@ -194,36 +199,49 @@ public:
// FIXME: This should be in a separate file.
namespace {
class DarwinPPCAsmBackend : public PPCAsmBackend {
public:
DarwinPPCAsmBackend(const Target &T, const Triple &TT)
: PPCAsmBackend(T, TT) {}
std::unique_ptr<MCObjectTargetWriter>
createObjectTargetWriter() const override {
bool Is64 = TT.isPPC64();
return createPPCMachObjectWriter(
/*Is64Bit=*/Is64,
(Is64 ? MachO::CPU_TYPE_POWERPC64 : MachO::CPU_TYPE_POWERPC),
MachO::CPU_SUBTYPE_POWERPC_ALL);
}
};
class DarwinPPCAsmBackend : public PPCAsmBackend {
public:
DarwinPPCAsmBackend(const Target &T, const Triple &TT)
: PPCAsmBackend(T, TT) {}
class ELFPPCAsmBackend : public PPCAsmBackend {
public:
ELFPPCAsmBackend(const Target &T, const Triple &TT)
: PPCAsmBackend(T, TT) {}
std::unique_ptr<MCObjectTargetWriter>
createObjectTargetWriter() const override {
bool Is64 = TT.isPPC64();
return createPPCMachObjectWriter(
/*Is64Bit=*/Is64,
(Is64 ? MachO::CPU_TYPE_POWERPC64 : MachO::CPU_TYPE_POWERPC),
MachO::CPU_SUBTYPE_POWERPC_ALL);
}
};
std::unique_ptr<MCObjectTargetWriter>
createObjectTargetWriter() const override {
uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS());
bool Is64 = TT.isPPC64();
return createPPCELFObjectWriter(Is64, OSABI);
}
};
class ELFPPCAsmBackend : public PPCAsmBackend {
public:
ELFPPCAsmBackend(const Target &T, const Triple &TT) : PPCAsmBackend(T, TT) {}
std::unique_ptr<MCObjectTargetWriter>
createObjectTargetWriter() const override {
uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS());
bool Is64 = TT.isPPC64();
return createPPCELFObjectWriter(Is64, OSABI);
}
Optional<MCFixupKind> getFixupKind(StringRef Name) const override;
};
} // end anonymous namespace
Optional<MCFixupKind> ELFPPCAsmBackend::getFixupKind(StringRef Name) const {
if (TT.isPPC64()) {
if (Name == "R_PPC64_NONE")
return FK_NONE;
} else {
if (Name == "R_PPC_NONE")
return FK_NONE;
}
return MCAsmBackend::getFixupKind(Name);
}
MCAsmBackend *llvm::createPPCAsmBackend(const Target &T,
const MCSubtargetInfo &STI,
const MCRegisterInfo &MRI,

View File

@ -133,6 +133,9 @@ unsigned PPCELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
} else {
switch ((unsigned)Fixup.getKind()) {
default: llvm_unreachable("invalid fixup kind!");
case FK_NONE:
Type = ELF::R_PPC_NONE;
break;
case PPC::fixup_ppc_br24abs:
Type = ELF::R_PPC_ADDR24;
break;

View File

@ -0,0 +1,26 @@
# RUN: llvm-mc -triple=powerpc-linux-musl %s | FileCheck --check-prefix=PRINT %s
# RUN: llvm-mc -filetype=obj -triple=powerpc-linux-musl %s | llvm-readobj -r | FileCheck %s
# PRINT: .reloc 8, R_PPC_NONE, .data
# PRINT: .reloc 4, R_PPC_NONE, foo+4
# PRINT: .reloc 0, R_PPC_NONE, 8
# CHECK: 0x8 R_PPC_NONE .data 0x0
# CHECK-NEXT: 0x4 R_PPC_NONE foo 0x4
# CHECK-NEXT: 0x0 R_PPC_NONE - 0x8
.text
blr
nop
nop
.reloc 8, R_PPC_NONE, .data
.reloc 4, R_PPC_NONE, foo+4
.reloc 0, R_PPC_NONE, 8
.data
.globl foo
foo:
.word 0
.word 0
.word 0

View File

@ -0,0 +1,28 @@
# RUN: llvm-mc -triple=powerpc64-linux-musl %s | FileCheck --check-prefix=PRINT %s
# RUN: llvm-mc -triple=powerpc64le-linux-musl %s | FileCheck --check-prefix=PRINT %s
# RUN: llvm-mc -filetype=obj -triple=powerpc64-linux-musl %s | llvm-readobj -r | FileCheck %s
# RUN: llvm-mc -filetype=obj -triple=powerpc64le-linux-musl %s | llvm-readobj -r | FileCheck %s
# PRINT: .reloc 8, R_PPC64_NONE, .data
# PRINT: .reloc 4, R_PPC64_NONE, foo+4
# PRINT: .reloc 0, R_PPC64_NONE, 8
# CHECK: 0x8 R_PPC64_NONE .data 0x0
# CHECK-NEXT: 0x4 R_PPC64_NONE foo 0x4
# CHECK-NEXT: 0x0 R_PPC64_NONE - 0x8
.text
blr
nop
nop
.reloc 8, R_PPC64_NONE, .data
.reloc 4, R_PPC64_NONE, foo+4
.reloc 0, R_PPC64_NONE, 8
.data
.globl foo
foo:
.word 0
.word 0
.word 0