mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-20 14:29:27 +00:00
Implement unique sections with an unique ID.
This allows the compiler/assembly programmer to switch back to a section. This in turn fixes the bootstrap failure on powerpc (tested on gcc110) without changing the ppc codegen at all. I will try to cleanup the various getELFSection overloads in a followup patch. Just using a default argument now would lead to ambiguities. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@234099 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ffcb79bea1
commit
903f4a2051
@ -165,6 +165,29 @@ and ``.bar`` is associated to ``.foo``.
|
||||
.section .foo,"bw",discard, "sym"
|
||||
.section .bar,"rd",associative, "sym"
|
||||
|
||||
|
||||
ELF-Dependent
|
||||
-------------
|
||||
|
||||
``.section`` Directive
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
In order to support creating multiple sections with the same name and comdat,
|
||||
it is possible to add an unique number at the end of the ``.seciton`` directive.
|
||||
For example, the following code creates two sections named ``.text``.
|
||||
|
||||
.. code-block:: gas
|
||||
|
||||
.section .text,"ax",@progbits,unique 1
|
||||
nop
|
||||
|
||||
.section .text,"ax",@progbits,unique 2
|
||||
nop
|
||||
|
||||
|
||||
The unique number is not present in the resulting object at all. It is just used
|
||||
in the assembler to differentiate the sections.
|
||||
|
||||
Target Specific Behaviour
|
||||
=========================
|
||||
|
||||
|
@ -34,6 +34,7 @@ namespace llvm {
|
||||
|
||||
class TargetLoweringObjectFileELF : public TargetLoweringObjectFile {
|
||||
bool UseInitArray;
|
||||
mutable unsigned NextUniqueID = 0;
|
||||
|
||||
public:
|
||||
TargetLoweringObjectFileELF() : UseInitArray(false) {}
|
||||
|
@ -165,12 +165,17 @@ namespace llvm {
|
||||
struct ELFSectionKey {
|
||||
std::string SectionName;
|
||||
StringRef GroupName;
|
||||
ELFSectionKey(StringRef SectionName, StringRef GroupName)
|
||||
: SectionName(SectionName), GroupName(GroupName) {}
|
||||
unsigned UniqueID;
|
||||
ELFSectionKey(StringRef SectionName, StringRef GroupName,
|
||||
unsigned UniqueID)
|
||||
: SectionName(SectionName), GroupName(GroupName), UniqueID(UniqueID) {
|
||||
}
|
||||
bool operator<(const ELFSectionKey &Other) const {
|
||||
if (SectionName != Other.SectionName)
|
||||
return SectionName < Other.SectionName;
|
||||
return GroupName < Other.GroupName;
|
||||
if (GroupName != Other.GroupName)
|
||||
return GroupName < Other.GroupName;
|
||||
return UniqueID < Other.UniqueID;
|
||||
}
|
||||
};
|
||||
|
||||
@ -303,7 +308,7 @@ namespace llvm {
|
||||
|
||||
const MCSectionELF *getELFSection(StringRef Section, unsigned Type,
|
||||
unsigned Flags, unsigned EntrySize,
|
||||
StringRef Group, bool Unique,
|
||||
StringRef Group, unsigned UniqueID,
|
||||
const char *BeginSymName = nullptr);
|
||||
|
||||
const MCSectionELF *createELFRelSection(StringRef Name, unsigned Type,
|
||||
|
@ -39,11 +39,10 @@ private:
|
||||
mutable MCSymbol *End;
|
||||
|
||||
protected:
|
||||
MCSection(SectionVariant V, SectionKind K, MCSymbol *Begin, bool Unique)
|
||||
: Begin(Begin), End(nullptr), Variant(V), Kind(K), Unique(Unique) {}
|
||||
MCSection(SectionVariant V, SectionKind K, MCSymbol *Begin)
|
||||
: Begin(Begin), End(nullptr), Variant(V), Kind(K) {}
|
||||
SectionVariant Variant;
|
||||
SectionKind Kind;
|
||||
bool Unique;
|
||||
|
||||
public:
|
||||
virtual ~MCSection();
|
||||
@ -55,7 +54,6 @@ public:
|
||||
MCSymbol *getBeginSymbol() const { return Begin; }
|
||||
MCSymbol *getEndSymbol(MCContext &Ctx) const;
|
||||
bool hasEnded() const;
|
||||
bool isUnique() const { return Unique; }
|
||||
|
||||
virtual void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS,
|
||||
const MCExpr *Subsection) const = 0;
|
||||
|
@ -47,7 +47,7 @@ class MCSymbol;
|
||||
MCSectionCOFF(StringRef Section, unsigned Characteristics,
|
||||
MCSymbol *COMDATSymbol, int Selection, SectionKind K,
|
||||
MCSymbol *Begin)
|
||||
: MCSection(SV_COFF, K, Begin, /*Unique*/ false), SectionName(Section),
|
||||
: MCSection(SV_COFF, K, Begin), SectionName(Section),
|
||||
Characteristics(Characteristics), COMDATSymbol(COMDATSymbol),
|
||||
Selection(Selection) {
|
||||
assert ((Characteristics & 0x00F00000) == 0 &&
|
||||
|
@ -39,6 +39,8 @@ class MCSectionELF : public MCSection {
|
||||
/// below.
|
||||
unsigned Flags;
|
||||
|
||||
unsigned UniqueID;
|
||||
|
||||
/// EntrySize - The size of each entry in this section. This size only
|
||||
/// makes sense for sections that contain fixed-sized entries. If a
|
||||
/// section does not contain fixed-sized entries 'EntrySize' will be 0.
|
||||
@ -49,10 +51,10 @@ class MCSectionELF : public MCSection {
|
||||
private:
|
||||
friend class MCContext;
|
||||
MCSectionELF(StringRef Section, unsigned type, unsigned flags, SectionKind K,
|
||||
unsigned entrySize, const MCSymbol *group, bool Unique,
|
||||
unsigned entrySize, const MCSymbol *group, unsigned UniqueID,
|
||||
MCSymbol *Begin)
|
||||
: MCSection(SV_ELF, K, Begin, Unique), SectionName(Section), Type(type),
|
||||
Flags(flags), EntrySize(entrySize), Group(group) {}
|
||||
: MCSection(SV_ELF, K, Begin), SectionName(Section), Type(type),
|
||||
Flags(flags), UniqueID(UniqueID), EntrySize(entrySize), Group(group) {}
|
||||
~MCSectionELF();
|
||||
|
||||
void setSectionName(StringRef Name) { SectionName = Name; }
|
||||
@ -74,6 +76,9 @@ public:
|
||||
bool UseCodeAlign() const override;
|
||||
bool isVirtualSection() const override;
|
||||
|
||||
bool isUnique() const { return UniqueID != ~0U; }
|
||||
unsigned getUniqueID() const { return UniqueID; }
|
||||
|
||||
static bool classof(const MCSection *S) {
|
||||
return S->getVariant() == SV_ELF;
|
||||
}
|
||||
|
@ -245,9 +245,11 @@ static StringRef getSectionPrefixForGlobal(SectionKind Kind) {
|
||||
return ".data.rel.ro";
|
||||
}
|
||||
|
||||
static const MCSectionELF *selectELFSectionForGlobal(
|
||||
MCContext &Ctx, const GlobalValue *GV, SectionKind Kind, Mangler &Mang,
|
||||
const TargetMachine &TM, bool EmitUniqueSection, unsigned Flags) {
|
||||
static const MCSectionELF *
|
||||
selectELFSectionForGlobal(MCContext &Ctx, const GlobalValue *GV,
|
||||
SectionKind Kind, Mangler &Mang,
|
||||
const TargetMachine &TM, bool EmitUniqueSection,
|
||||
unsigned Flags, unsigned *NextUniqueID) {
|
||||
unsigned EntrySize = 0;
|
||||
if (Kind.isMergeableCString()) {
|
||||
if (Kind.isMergeable2ByteCString()) {
|
||||
@ -297,9 +299,13 @@ static const MCSectionELF *selectELFSectionForGlobal(
|
||||
Name.push_back('.');
|
||||
TM.getNameWithPrefix(Name, GV, Mang, true);
|
||||
}
|
||||
unsigned UniqueID = ~0;
|
||||
if (EmitUniqueSection && !UniqueSectionNames) {
|
||||
UniqueID = *NextUniqueID;
|
||||
(*NextUniqueID)++;
|
||||
}
|
||||
return Ctx.getELFSection(Name, getELFSectionType(Name, Kind), Flags,
|
||||
EntrySize, Group,
|
||||
EmitUniqueSection && !UniqueSectionNames);
|
||||
EntrySize, Group, UniqueID);
|
||||
}
|
||||
|
||||
const MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal(
|
||||
@ -319,7 +325,7 @@ const MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal(
|
||||
EmitUniqueSection |= GV->hasComdat();
|
||||
|
||||
return selectELFSectionForGlobal(getContext(), GV, Kind, Mang, TM,
|
||||
EmitUniqueSection, Flags);
|
||||
EmitUniqueSection, Flags, &NextUniqueID);
|
||||
}
|
||||
|
||||
const MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable(
|
||||
@ -332,7 +338,8 @@ const MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable(
|
||||
return ReadOnlySection;
|
||||
|
||||
return selectELFSectionForGlobal(getContext(), &F, SectionKind::getReadOnly(),
|
||||
Mang, TM, EmitUniqueSection, ELF::SHF_ALLOC);
|
||||
Mang, TM, EmitUniqueSection, ELF::SHF_ALLOC,
|
||||
&NextUniqueID);
|
||||
}
|
||||
|
||||
bool TargetLoweringObjectFileELF::shouldPutJumpTableInFunctionSection(
|
||||
|
@ -273,9 +273,12 @@ void MCContext::renameELFSection(const MCSectionELF *Section, StringRef Name) {
|
||||
if (const MCSymbol *Group = Section->getGroup())
|
||||
GroupName = Group->getName();
|
||||
|
||||
ELFUniquingMap.erase(ELFSectionKey{Section->getSectionName(), GroupName});
|
||||
auto I = ELFUniquingMap.insert(std::make_pair(ELFSectionKey{Name, GroupName},
|
||||
Section)).first;
|
||||
unsigned UniqueID = Section->getUniqueID();
|
||||
ELFUniquingMap.erase(
|
||||
ELFSectionKey{Section->getSectionName(), GroupName, UniqueID});
|
||||
auto I = ELFUniquingMap.insert(std::make_pair(
|
||||
ELFSectionKey{Name, GroupName, UniqueID},
|
||||
Section)).first;
|
||||
StringRef CachedName = I->first.SectionName;
|
||||
const_cast<MCSectionELF*>(Section)->setSectionName(CachedName);
|
||||
}
|
||||
@ -294,7 +297,7 @@ MCContext::createELFRelSection(StringRef Name, unsigned Type, unsigned Flags,
|
||||
|
||||
const MCSectionELF *MCContext::getELFSection(StringRef Section, unsigned Type,
|
||||
unsigned Flags, unsigned EntrySize,
|
||||
StringRef Group, bool Unique,
|
||||
StringRef Group, unsigned UniqueID,
|
||||
const char *BeginSymName) {
|
||||
MCSymbol *GroupSym = nullptr;
|
||||
if (!Group.empty()) {
|
||||
@ -304,9 +307,9 @@ const MCSectionELF *MCContext::getELFSection(StringRef Section, unsigned Type,
|
||||
|
||||
// Do the lookup, if we have a hit, return it.
|
||||
auto IterBool = ELFUniquingMap.insert(
|
||||
std::make_pair(ELFSectionKey{Section, Group}, nullptr));
|
||||
std::make_pair(ELFSectionKey{Section, Group, UniqueID}, nullptr));
|
||||
auto &Entry = *IterBool.first;
|
||||
if (!IterBool.second && !Unique)
|
||||
if (!IterBool.second)
|
||||
return Entry.second;
|
||||
|
||||
StringRef CachedName = Entry.first.SectionName;
|
||||
@ -322,9 +325,8 @@ const MCSectionELF *MCContext::getELFSection(StringRef Section, unsigned Type,
|
||||
Begin = createTempSymbol(BeginSymName, false);
|
||||
|
||||
MCSectionELF *Result = new (*this) MCSectionELF(
|
||||
CachedName, Type, Flags, Kind, EntrySize, GroupSym, Unique, Begin);
|
||||
if (!Unique)
|
||||
Entry.second = Result;
|
||||
CachedName, Type, Flags, Kind, EntrySize, GroupSym, UniqueID, Begin);
|
||||
Entry.second = Result;
|
||||
return Result;
|
||||
}
|
||||
|
||||
@ -332,14 +334,14 @@ const MCSectionELF *MCContext::getELFSection(StringRef Section, unsigned Type,
|
||||
unsigned Flags, unsigned EntrySize,
|
||||
StringRef Group,
|
||||
const char *BeginSymName) {
|
||||
return getELFSection(Section, Type, Flags, EntrySize, Group, false,
|
||||
return getELFSection(Section, Type, Flags, EntrySize, Group, ~0,
|
||||
BeginSymName);
|
||||
}
|
||||
|
||||
const MCSectionELF *MCContext::CreateELFGroupSection() {
|
||||
MCSectionELF *Result = new (*this)
|
||||
MCSectionELF(".group", ELF::SHT_GROUP, 0, SectionKind::getReadOnly(), 4,
|
||||
nullptr, false, nullptr);
|
||||
nullptr, ~0, nullptr);
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
@ -379,7 +379,7 @@ bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) {
|
||||
const MCExpr *Subsection = nullptr;
|
||||
bool UseLastGroup = false;
|
||||
StringRef UniqueStr;
|
||||
bool Unique = false;
|
||||
int64_t UniqueID = ~0;
|
||||
|
||||
// Set the defaults first.
|
||||
if (SectionName == ".fini" || SectionName == ".init" ||
|
||||
@ -470,7 +470,12 @@ bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) {
|
||||
return TokError("expected identifier in directive");
|
||||
if (UniqueStr != "unique")
|
||||
return TokError("expected 'unique'");
|
||||
Unique = true;
|
||||
if (getParser().parseAbsoluteExpression(UniqueID))
|
||||
return true;
|
||||
if (UniqueID < 0)
|
||||
return TokError("unique id must be positive");
|
||||
if (!isUInt<32>(UniqueID) || UniqueID == ~0U)
|
||||
return TokError("unique id is too large");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -520,7 +525,7 @@ EndStmt:
|
||||
}
|
||||
|
||||
const MCSection *ELFSection = getContext().getELFSection(
|
||||
SectionName, Type, Flags, Size, GroupName, Unique);
|
||||
SectionName, Type, Flags, Size, GroupName, UniqueID);
|
||||
getStreamer().SwitchSection(ELFSection, Subsection);
|
||||
|
||||
if (getContext().getGenDwarfForAssembly()) {
|
||||
|
@ -24,7 +24,7 @@ MCSectionELF::~MCSectionELF() {} // anchor.
|
||||
bool MCSectionELF::ShouldOmitSectionDirective(StringRef Name,
|
||||
const MCAsmInfo &MAI) const {
|
||||
|
||||
if (Unique)
|
||||
if (isUnique())
|
||||
return false;
|
||||
|
||||
// FIXME: Does .section .bss/.data/.text work everywhere??
|
||||
@ -148,8 +148,8 @@ void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI,
|
||||
OS << ",comdat";
|
||||
}
|
||||
|
||||
if (Unique)
|
||||
OS << ",unique";
|
||||
if (isUnique())
|
||||
OS << ",unique " << UniqueID;
|
||||
|
||||
OS << '\n';
|
||||
|
||||
|
@ -72,7 +72,7 @@ ENTRY(nullptr /*FIXME*/, S_ATTR_LOC_RELOC)
|
||||
MCSectionMachO::MCSectionMachO(StringRef Segment, StringRef Section,
|
||||
unsigned TAA, unsigned reserved2, SectionKind K,
|
||||
MCSymbol *Begin)
|
||||
: MCSection(SV_MachO, K, Begin, /*Unique*/ false), TypeAndAttributes(TAA),
|
||||
: MCSection(SV_MachO, K, Begin), TypeAndAttributes(TAA),
|
||||
Reserved2(reserved2) {
|
||||
assert(Segment.size() <= 16 && Section.size() <= 16 &&
|
||||
"Segment or section string too long");
|
||||
|
@ -669,12 +669,6 @@ void MCStreamer::SwitchSection(const MCSection *Section,
|
||||
MCSectionSubPair curSection = SectionStack.back().first;
|
||||
SectionStack.back().second = curSection;
|
||||
if (MCSectionSubPair(Section, Subsection) != curSection) {
|
||||
const MCSection *CurSec = curSection.first;
|
||||
if (CurSec && CurSec->isUnique()) {
|
||||
MCSymbol *Sym = curSection.first->getEndSymbol(Context);
|
||||
if (!Sym->isInSection())
|
||||
EmitLabel(Sym);
|
||||
}
|
||||
SectionStack.back().first = MCSectionSubPair(Section, Subsection);
|
||||
assert(!Section->hasEnded() && "Section already ended");
|
||||
ChangeSection(Section, Subsection);
|
||||
|
@ -26,8 +26,7 @@ namespace llvm {
|
||||
class NVPTXSection : public MCSection {
|
||||
virtual void anchor();
|
||||
public:
|
||||
NVPTXSection(SectionVariant V, SectionKind K)
|
||||
: MCSection(V, K, nullptr, /*Unique*/ false) {}
|
||||
NVPTXSection(SectionVariant V, SectionKind K) : MCSection(V, K, nullptr) {}
|
||||
virtual ~NVPTXSection() {}
|
||||
|
||||
/// Override this as NVPTX has its own way of printing switching
|
||||
|
@ -36,7 +36,6 @@ bb5:
|
||||
; LINUX-SECTIONS-SHORT: .section .text,"axG",@progbits,F1,comdat
|
||||
; LINUX-SECTIONS-SHORT: .size F1,
|
||||
; LINUX-SECTIONS-SHORT-NEXT: .cfi_endproc
|
||||
; LINUX-SECTIONS-SHORT-NEXT: .Lsec_end0:
|
||||
; LINUX-SECTIONS-SHORT-NEXT: .section .rodata,"aG",@progbits,F1,comdat
|
||||
|
||||
$G16 = comdat any
|
||||
|
5
test/MC/ELF/section-unique-err1.s
Normal file
5
test/MC/ELF/section-unique-err1.s
Normal file
@ -0,0 +1,5 @@
|
||||
// RUN: not llvm-mc -triple x86_64-pc-linux-gnu %s -o - 2>&1 | FileCheck %s
|
||||
|
||||
// CHECK: error: expected absolute expression
|
||||
|
||||
.section .text,"ax",@progbits,unique "abc"
|
5
test/MC/ELF/section-unique-err2.s
Normal file
5
test/MC/ELF/section-unique-err2.s
Normal file
@ -0,0 +1,5 @@
|
||||
// RUN: not llvm-mc -triple x86_64-pc-linux-gnu %s -o - 2>&1 | FileCheck %s
|
||||
|
||||
// CHECK: error: unique id must be positive
|
||||
|
||||
.section .text,"ax",@progbits,unique -1
|
5
test/MC/ELF/section-unique-err3.s
Normal file
5
test/MC/ELF/section-unique-err3.s
Normal file
@ -0,0 +1,5 @@
|
||||
// RUN: not llvm-mc -triple x86_64-pc-linux-gnu %s -o - 2>&1 | FileCheck %s
|
||||
|
||||
// CHECK: error: unique id is too large
|
||||
|
||||
.section .text,"ax",@progbits,unique 4294967295
|
@ -1,22 +1,22 @@
|
||||
// RUN: llvm-mc -triple x86_64-pc-linux-gnu %s -o - | FileCheck %s
|
||||
// RUN: llvm-mc -triple x86_64-pc-linux-gnu %s -filetype=obj -o - | llvm-readobj -t | FileCheck %s --check-prefix=OBJ
|
||||
|
||||
.section .text,"ax",@progbits,unique
|
||||
.section .text,"ax",@progbits,unique 4294967293
|
||||
.globl f
|
||||
f:
|
||||
nop
|
||||
|
||||
.section .text,"ax",@progbits,unique
|
||||
.section .text,"ax",@progbits,unique 4294967294
|
||||
.globl g
|
||||
g:
|
||||
nop
|
||||
|
||||
// test that f and g are in different sections.
|
||||
|
||||
// CHECK: .section .text,"ax",@progbits,unique
|
||||
// CHECK: .section .text,"ax",@progbits,unique 4294967293
|
||||
// CHECK: f:
|
||||
|
||||
// CHECK: .section .text,"ax",@progbits,unique
|
||||
// CHECK: .section .text,"ax",@progbits,unique 4294967294
|
||||
// CHECK: g:
|
||||
|
||||
// OBJ: Symbol {
|
||||
|
Loading…
x
Reference in New Issue
Block a user