Skip to content

Commit

Permalink
[MC] Change ELFOSABI_NONE to ELFOSABI_GNU for SHF_GNU_RETAIN
Browse files Browse the repository at this point in the history
GNU ld does not give SHF_GNU_RETAIN GC root semantics for ELFOSABI_NONE.
(https://sourceware.org/pipermail/binutils/2021-March/115581.html)

This allows GNU ld to interpret SHF_GNU_RETAIN and avoids a gold quirk
https://sourceware.org/bugzilla/show_bug.cgi?id=27490

Because ELFObjectWriter is in an anonymous namespace, I have to place
`markGnuAbi` in the parent MCObjectWriter.

Differential Revision: https://reviews.llvm.org/D97976
  • Loading branch information
MaskRay committed Mar 9, 2021
1 parent 24c0ad7 commit 42e3f97
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 9 deletions.
5 changes: 0 additions & 5 deletions lld/test/ELF/gc-sections-retain.s
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,6 @@
# RUN: ld.lld -r -e _start --gc-sections --print-gc-sections %t.o -o %t.ro | count 0
# RUN: llvm-readobj -hS %t.ro | FileCheck %s

## SHF_GNU_RETAIN has no significance in executables/shared objects. Multiple
## OSABI values can benefit from this flag. Test that we don't change EI_OSABI,
## even for relocatable output.
# CHECK: OS/ABI: SystemV (0x0)

# CHECK: Name: .retain
# CHECK-NEXT: Type: SHT_PROGBITS
# CHECK-NEXT: Flags [
Expand Down
3 changes: 3 additions & 0 deletions llvm/include/llvm/MC/MCObjectWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ class MCObjectWriter {
bool InSet,
bool IsPCRel) const;

/// ELF only. Mark that we have seen GNU ABI usage (e.g. SHF_GNU_RETAIN).
virtual void markGnuAbi() {}

/// Tell the object writer to emit an address-significance table during
/// writeObject(). If this function is not called, all symbols are treated as
/// address-significant.
Expand Down
9 changes: 8 additions & 1 deletion llvm/lib/MC/ELFObjectWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ class ELFObjectWriter : public MCObjectWriter {

DenseMap<const MCSymbolELF *, const MCSymbolELF *> Renames;

bool SeenGnuAbi = false;
bool EmitAddrsigSection = false;
std::vector<const MCSymbol *> AddrsigSyms;

Expand All @@ -237,6 +238,7 @@ class ELFObjectWriter : public MCObjectWriter {
: TargetObjectWriter(std::move(MOTW)) {}

void reset() override {
SeenGnuAbi = false;
Relocations.clear();
Renames.clear();
MCObjectWriter::reset();
Expand All @@ -260,6 +262,8 @@ class ELFObjectWriter : public MCObjectWriter {
void executePostLayoutBinding(MCAssembler &Asm,
const MCAsmLayout &Layout) override;

void markGnuAbi() override { SeenGnuAbi = true; }
bool seenGnuAbi() const { return SeenGnuAbi; }
void emitAddrsigSection() override { EmitAddrsigSection = true; }
void addAddrsigSymbol(const MCSymbol *Sym) override {
AddrsigSyms.push_back(Sym);
Expand Down Expand Up @@ -412,7 +416,10 @@ void ELFWriter::writeHeader(const MCAssembler &Asm) {

W.OS << char(ELF::EV_CURRENT); // e_ident[EI_VERSION]
// e_ident[EI_OSABI]
W.OS << char(OWriter.TargetObjectWriter->getOSABI());
uint8_t OSABI = OWriter.TargetObjectWriter->getOSABI();
W.OS << char(OSABI == ELF::ELFOSABI_NONE && OWriter.seenGnuAbi()
? ELF::ELFOSABI_GNU
: OSABI);
// e_ident[EI_ABIVERSION]
W.OS << char(OWriter.TargetObjectWriter->getABIVersion());

Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/MC/MCELFStreamer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ void MCELFStreamer::changeSection(MCSection *Section,
const MCSymbol *Grp = SectionELF->getGroup();
if (Grp)
Asm.registerSymbol(*Grp);
if (SectionELF->getFlags() & ELF::SHF_GNU_RETAIN)
Asm.getWriter().markGnuAbi();

changeSectionImpl(Section, Subsection);
Asm.registerSymbol(*Section->getBeginSymbol());
Expand Down
8 changes: 5 additions & 3 deletions llvm/test/MC/ELF/section-gnu.s
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
# RUN: llvm-mc -triple=x86_64 %s | FileCheck %s --check-prefix=ASM
# RUN: llvm-mc -filetype=obj -triple=x86_64 %s | llvm-readobj -hS - | FileCheck %s --check-prefix=OBJ
# RUN: llvm-mc -filetype=obj -triple=x86_64 %s | llvm-readobj -hS - | FileCheck %s --check-prefixes=GNU,OBJ
# RUN: llvm-mc -filetype=obj -triple=aarch64-freebsd %s | llvm-readobj -hS - | FileCheck %s --check-prefixes=FREEBSD,OBJ

# ASM: .section retain,"aR",@progbits

## Note: GNU as sets OSABI to GNU.
# OBJ: OS/ABI: SystemV (0x0)
## ELFOSABI_NONE is changed to ELFOSABI_GNU. Other OSABI values are unchanged.
# GNU: OS/ABI: GNU/Linux
# FREEBSD: OS/ABI: FreeBSD

# OBJ: Name: retain
# OBJ-NEXT: Type: SHT_PROGBITS
Expand Down

0 comments on commit 42e3f97

Please sign in to comment.