Skip to content

Commit

Permalink
[PowerPC] Support .reloc *, R_PPC{,64}_NONE, *
Browse files Browse the repository at this point in the history
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.

llvm-svn: 360990
  • Loading branch information
MaskRay committed May 17, 2019
1 parent ec6dc30 commit ad7199f
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 28 deletions.
74 changes: 46 additions & 28 deletions llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp
Expand Up @@ -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:
Expand All @@ -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:
Expand Down Expand Up @@ -137,9 +140,11 @@ class PPCAsmBackend : public MCAsmBackend {

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
Expand Down Expand Up @@ -194,36 +199,49 @@ class PPCAsmBackend : public MCAsmBackend {

// 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 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);
}
};

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 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,
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp
Expand Up @@ -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;
Expand Down
26 changes: 26 additions & 0 deletions llvm/test/MC/PowerPC/ppc32-reloc-directive.s
@@ -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
28 changes: 28 additions & 0 deletions llvm/test/MC/PowerPC/ppc64-reloc-directive.s
@@ -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

0 comments on commit ad7199f

Please sign in to comment.