Index: lib/MC/MCELFObjectTargetWriter.cpp =================================================================== --- lib/MC/MCELFObjectTargetWriter.cpp +++ lib/MC/MCELFObjectTargetWriter.cpp @@ -8,14 +8,40 @@ //===----------------------------------------------------------------------===// #include "llvm/MC/MCELFObjectWriter.h" +#include "llvm/Support/CommandLine.h" using namespace llvm; +enum class ELFRelocationFormat { Default, Rel, Rela }; +static cl::opt RelocationFormat( + "elf-relocation-format", + cl::desc("Select whether to use REL or " + "RELA for relocations in the output object"), + cl::values(clEnumValN(ELFRelocationFormat::Default, "default", + "Use the default kind for the current target"), + clEnumValN(ELFRelocationFormat::Rel, "rel", + "Always emit REL relocations"), + clEnumValN(ELFRelocationFormat::Rela, "rela", + "Always emit RELA relocations")), + cl::init(ELFRelocationFormat::Default), cl::Hidden); + +static bool shouldUseRelocationAddend(bool Default) { + switch (RelocationFormat) { + case ELFRelocationFormat::Rel: + return false; + case ELFRelocationFormat::Rela: + return true; + default: + return Default; + } +} + MCELFObjectTargetWriter::MCELFObjectTargetWriter(bool Is64Bit_, uint8_t OSABI_, uint16_t EMachine_, bool HasRelocationAddend_) : OSABI(OSABI_), EMachine(EMachine_), - HasRelocationAddend(HasRelocationAddend_), Is64Bit(Is64Bit_) {} + HasRelocationAddend(shouldUseRelocationAddend(HasRelocationAddend_)), + Is64Bit(Is64Bit_) {} bool MCELFObjectTargetWriter::needsRelocateWithSymbol(const MCSymbol &Sym, unsigned Type) const { Index: test/MC/AArch64/elf-override-rela-and-rel.s =================================================================== --- /dev/null +++ test/MC/AArch64/elf-override-rela-and-rel.s @@ -0,0 +1,45 @@ +// Check that we can override whether to ouput Elf_Rel vs Elf_Rela relocations + +// By default we use Elf_Rela relocations: +// RUN: llvm-mc -filetype=obj -triple aarch64-none-linux-gnu %s -o - | \ +// RUN: llvm-readobj -r -s -section-data - | FileCheck %s -check-prefix RELA + +// RELA: Section { +// RELA: Name: .data +// RELA: SectionData ( +// RELA-NEXT: 0000: 00000000 00000000 |........| +// RELA-NEXT: ) +// RELA: Relocations [ +// RELA-NEXT: Section (4) .rela.data { +// RELA-NEXT: 0x0 R_AARCH64_ABS64 foo 0x123456 +// RELA-NEXT: } +// RELA-NEXT: ] + +// RUN: llvm-mc -filetype=obj -triple aarch64-none-linux-gnu %s -o - -elf-relocation-format=rel | \ +// RUN: llvm-readobj -r -s -section-data - | FileCheck %s -check-prefix REL +// REL: Section { +// REL: Name: .data +// REL: SectionData ( +// REL-NEXT: 0000: 56341200 00000000 |V4......| +// ^---- Addend 0x123456 for the relocation below +// REL-NEXT: ) +// REL: Relocations [ +// REL-NEXT: Section (4) .rel.data { +// The real addend is not printed for REL as it is in .data +// REL-NEXT: 0x0 R_AARCH64_ABS64 foo 0x0 +// REL-NEXT: } +// REL-NEXT: ] + +// RUN: llvm-mc -filetype=obj -triple aarch64-none-linux-gnu %s -o - -elf-relocation-format=rela | \ +// RUN: llvm-readobj -r -s -section-data - | FileCheck %s -check-prefix RELA +// RUN: llvm-mc -filetype=obj -triple aarch64-none-linux-gnu %s -o - -elf-relocation-format=default | \ +// RUN: llvm-readobj -r -s -section-data - | FileCheck %s -check-prefix RELA + +// Check that we only accept rela, rel, and default for the -elf-relocation-format flag +// RUN: not llvm-mc -filetype=obj -triple aarch64-none-linux-gnu %s -o - \ +// RUN: -elf-relocation-format=none 2>&1 | FileCheck %s -check-prefix ERR +// ERR: llvm-mc: for the -elf-relocation-format option: Cannot find option named 'none' +.extern foo + +.data +.quad foo + 0x123456 \ No newline at end of file