mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 04:40:38 +00:00
Add back commits r219835 and a fixed version of r219829.
The only difference from r219829 is using getOrCreateSectionSymbol(*ELFSec) instead of GetOrCreateSymbol(ELFSec->getSectionName()) in ELFObjectWriter which causes us to use the correct section symbol even if we have multiple sections with the same name. Original messages: r219829: Correctly handle references to section symbols. When processing assembly like .long .text we were creating a new undefined symbol .text. GAS on the other hand would handle that as a reference to the .text section. This patch implements that by creating the section symbols earlier so that they are visible during asm parsing. The patch also updates llvm-readobj to print the symbol number in the relocation dump so that the test can differentiate between two sections with the same name. r219835: Allow forward references to section symbols. llvm-svn: 220021
This commit is contained in:
parent
c2cd819583
commit
62145bfaad
@ -73,6 +73,10 @@ namespace llvm {
|
||||
/// Symbols - Bindings of names to symbols.
|
||||
SymbolTable Symbols;
|
||||
|
||||
/// ELF sections can have a corresponding symbol. This maps one to the
|
||||
/// other.
|
||||
DenseMap<const MCSectionELF*, MCSymbol*> SectionSymbols;
|
||||
|
||||
/// A maping from a local label number and an instance count to a symbol.
|
||||
/// For example, in the assembly
|
||||
/// 1:
|
||||
@ -231,6 +235,8 @@ namespace llvm {
|
||||
MCSymbol *GetOrCreateSymbol(StringRef Name);
|
||||
MCSymbol *GetOrCreateSymbol(const Twine &Name);
|
||||
|
||||
MCSymbol *getOrCreateSectionSymbol(const MCSectionELF &Section);
|
||||
|
||||
/// LookupSymbol - Get the symbol for \p Name, or null.
|
||||
MCSymbol *LookupSymbol(StringRef Name) const;
|
||||
MCSymbol *LookupSymbol(const Twine &Name) const;
|
||||
|
@ -81,23 +81,13 @@ public:
|
||||
|
||||
struct ELFRelocationEntry {
|
||||
uint64_t Offset; // Where is the relocation.
|
||||
bool UseSymbol; // Relocate with a symbol, not the section.
|
||||
union {
|
||||
const MCSymbol *Symbol; // The symbol to relocate with.
|
||||
const MCSectionData *Section; // The section to relocate with.
|
||||
};
|
||||
const MCSymbol *Symbol; // The symbol to relocate with.
|
||||
unsigned Type; // The type of the relocation.
|
||||
uint64_t Addend; // The addend to use.
|
||||
|
||||
ELFRelocationEntry(uint64_t Offset, const MCSymbol *Symbol, unsigned Type,
|
||||
uint64_t Addend)
|
||||
: Offset(Offset), UseSymbol(true), Symbol(Symbol), Type(Type),
|
||||
Addend(Addend) {}
|
||||
|
||||
ELFRelocationEntry(uint64_t Offset, const MCSectionData *Section,
|
||||
unsigned Type, uint64_t Addend)
|
||||
: Offset(Offset), UseSymbol(false), Section(Section), Type(Type),
|
||||
Addend(Addend) {}
|
||||
: Offset(Offset), Symbol(Symbol), Type(Type), Addend(Addend) {}
|
||||
};
|
||||
|
||||
class ELFObjectWriter : public MCObjectWriter {
|
||||
@ -137,6 +127,14 @@ class ELFObjectWriter : public MCObjectWriter {
|
||||
|
||||
// Support lexicographic sorting.
|
||||
bool operator<(const ELFSymbolData &RHS) const {
|
||||
unsigned LHSType = MCELF::GetType(*SymbolData);
|
||||
unsigned RHSType = MCELF::GetType(*RHS.SymbolData);
|
||||
if (LHSType == ELF::STT_SECTION && RHSType != ELF::STT_SECTION)
|
||||
return false;
|
||||
if (LHSType != ELF::STT_SECTION && RHSType == ELF::STT_SECTION)
|
||||
return true;
|
||||
if (LHSType == ELF::STT_SECTION && RHSType == ELF::STT_SECTION)
|
||||
return SectionIndex < RHS.SectionIndex;
|
||||
return Name < RHS.Name;
|
||||
}
|
||||
};
|
||||
@ -651,22 +649,6 @@ void ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF,
|
||||
WriteSymbol(Writer, MSD, Layout);
|
||||
}
|
||||
|
||||
// Write out a symbol table entry for each regular section.
|
||||
for (MCAssembler::const_iterator i = Asm.begin(), e = Asm.end(); i != e;
|
||||
++i) {
|
||||
const MCSectionELF &Section =
|
||||
static_cast<const MCSectionELF&>(i->getSection());
|
||||
if (Section.getType() == ELF::SHT_RELA ||
|
||||
Section.getType() == ELF::SHT_REL ||
|
||||
Section.getType() == ELF::SHT_STRTAB ||
|
||||
Section.getType() == ELF::SHT_SYMTAB ||
|
||||
Section.getType() == ELF::SHT_SYMTAB_SHNDX)
|
||||
continue;
|
||||
Writer.writeSymbol(0, ELF::STT_SECTION, 0, 0, ELF::STV_DEFAULT,
|
||||
SectionIndexMap.lookup(&Section), false);
|
||||
LastLocalSymbolIndex++;
|
||||
}
|
||||
|
||||
for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) {
|
||||
ELFSymbolData &MSD = ExternalSymbolData[i];
|
||||
MCSymbolData &Data = *MSD.SymbolData;
|
||||
@ -882,8 +864,11 @@ void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm,
|
||||
if (!RelocateWithSymbol) {
|
||||
const MCSection *SecA =
|
||||
(SymA && !SymA->isUndefined()) ? &SymA->getSection() : nullptr;
|
||||
const MCSectionData *SecAD = SecA ? &Asm.getSectionData(*SecA) : nullptr;
|
||||
ELFRelocationEntry Rec(FixupOffset, SecAD, Type, Addend);
|
||||
auto *ELFSec = cast_or_null<MCSectionELF>(SecA);
|
||||
MCSymbol *SectionSymbol =
|
||||
ELFSec ? Asm.getContext().getOrCreateSectionSymbol(*ELFSec)
|
||||
: nullptr;
|
||||
ELFRelocationEntry Rec(FixupOffset, SectionSymbol, Type, Addend);
|
||||
Relocations[FixupSection].push_back(Rec);
|
||||
return;
|
||||
}
|
||||
@ -1061,7 +1046,10 @@ ELFObjectWriter::computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout,
|
||||
Buf += Name.substr(Pos + Skip);
|
||||
Name = Buf;
|
||||
}
|
||||
MSD.Name = StrTabBuilder.add(Name);
|
||||
|
||||
// Sections have their own string table
|
||||
if (MCELF::GetType(SD) != ELF::STT_SECTION)
|
||||
MSD.Name = StrTabBuilder.add(Name);
|
||||
|
||||
if (MSD.SectionIndex == ELF::SHN_UNDEF)
|
||||
UndefinedSymbolData.push_back(MSD);
|
||||
@ -1079,9 +1067,11 @@ ELFObjectWriter::computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout,
|
||||
for (auto i = Asm.file_names_begin(), e = Asm.file_names_end(); i != e; ++i)
|
||||
FileSymbolData.push_back(StrTabBuilder.getOffset(*i));
|
||||
|
||||
for (ELFSymbolData& MSD : LocalSymbolData)
|
||||
MSD.StringIndex = StrTabBuilder.getOffset(MSD.Name);
|
||||
for (ELFSymbolData& MSD : ExternalSymbolData)
|
||||
for (ELFSymbolData &MSD : LocalSymbolData)
|
||||
MSD.StringIndex = MCELF::GetType(*MSD.SymbolData) == ELF::STT_SECTION
|
||||
? 0
|
||||
: StrTabBuilder.getOffset(MSD.Name);
|
||||
for (ELFSymbolData &MSD : ExternalSymbolData)
|
||||
MSD.StringIndex = StrTabBuilder.getOffset(MSD.Name);
|
||||
for (ELFSymbolData& MSD : UndefinedSymbolData)
|
||||
MSD.StringIndex = StrTabBuilder.getOffset(MSD.Name);
|
||||
@ -1097,8 +1087,6 @@ ELFObjectWriter::computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout,
|
||||
for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i)
|
||||
LocalSymbolData[i].SymbolData->setIndex(Index++);
|
||||
|
||||
Index += NumRegularSections;
|
||||
|
||||
for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i)
|
||||
ExternalSymbolData[i].SymbolData->setIndex(Index++);
|
||||
for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i)
|
||||
@ -1354,18 +1342,8 @@ void ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm,
|
||||
|
||||
for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
|
||||
const ELFRelocationEntry &Entry = Relocs[e - i - 1];
|
||||
|
||||
unsigned Index;
|
||||
if (Entry.UseSymbol) {
|
||||
Index = getSymbolIndexInSymbolTable(Asm, Entry.Symbol);
|
||||
} else {
|
||||
const MCSectionData *Sec = Entry.Section;
|
||||
if (Sec)
|
||||
Index = Sec->getOrdinal() + FileSymbolData.size() +
|
||||
LocalSymbolData.size() + 1;
|
||||
else
|
||||
Index = 0;
|
||||
}
|
||||
unsigned Index =
|
||||
Entry.Symbol ? getSymbolIndexInSymbolTable(Asm, Entry.Symbol) : 0;
|
||||
|
||||
if (is64Bit()) {
|
||||
write(*F, Entry.Offset);
|
||||
|
@ -113,6 +113,30 @@ MCSymbol *MCContext::GetOrCreateSymbol(StringRef Name) {
|
||||
return Sym;
|
||||
}
|
||||
|
||||
MCSymbol *MCContext::getOrCreateSectionSymbol(const MCSectionELF &Section) {
|
||||
MCSymbol *&Sym = SectionSymbols[&Section];
|
||||
if (Sym)
|
||||
return Sym;
|
||||
|
||||
StringRef Name = Section.getSectionName();
|
||||
|
||||
StringMapEntry<MCSymbol*> &Entry = Symbols.GetOrCreateValue(Name);
|
||||
MCSymbol *OldSym = Entry.getValue();
|
||||
if (OldSym && OldSym->isUndefined()) {
|
||||
Sym = OldSym;
|
||||
return OldSym;
|
||||
}
|
||||
|
||||
StringMapEntry<bool> *NameEntry = &UsedNames.GetOrCreateValue(Name);
|
||||
NameEntry->setValue(true);
|
||||
Sym = new (*this) MCSymbol(NameEntry->getKey(), /*isTemporary*/ false);
|
||||
|
||||
if (!Entry.getValue())
|
||||
Entry.setValue(Sym);
|
||||
|
||||
return Sym;
|
||||
}
|
||||
|
||||
MCSymbol *MCContext::CreateSymbol(StringRef Name) {
|
||||
// Determine whether this is an assembler temporary or normal label, if used.
|
||||
bool isTemporary = false;
|
||||
|
@ -92,10 +92,19 @@ void MCELFStreamer::ChangeSection(const MCSection *Section,
|
||||
MCSectionData *CurSection = getCurrentSectionData();
|
||||
if (CurSection && CurSection->isBundleLocked())
|
||||
report_fatal_error("Unterminated .bundle_lock when changing a section");
|
||||
const MCSymbol *Grp = static_cast<const MCSectionELF *>(Section)->getGroup();
|
||||
|
||||
MCAssembler &Asm = getAssembler();
|
||||
auto *SectionELF = static_cast<const MCSectionELF *>(Section);
|
||||
const MCSymbol *Grp = SectionELF->getGroup();
|
||||
if (Grp)
|
||||
getAssembler().getOrCreateSymbolData(*Grp);
|
||||
Asm.getOrCreateSymbolData(*Grp);
|
||||
|
||||
this->MCObjectStreamer::ChangeSection(Section, Subsection);
|
||||
MCSymbol *SectionSymbol = getContext().getOrCreateSectionSymbol(*SectionELF);
|
||||
if (SectionSymbol->isUndefined()) {
|
||||
EmitLabel(SectionSymbol);
|
||||
MCELF::SetType(Asm.getSymbolData(*SectionSymbol), ELF::STT_SECTION);
|
||||
}
|
||||
}
|
||||
|
||||
void MCELFStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {
|
||||
|
@ -41,7 +41,7 @@
|
||||
// CHECK-NEXT: Offset: 0x54
|
||||
// CHECK-NEXT: Size: 12
|
||||
// CHECK-NEXT: Link: 13
|
||||
// CHECK-NEXT: Info: 13
|
||||
// CHECK-NEXT: Info: 10
|
||||
// CHECK-NEXT: AddressAlignment: 4
|
||||
// CHECK-NEXT: EntrySize: 4
|
||||
// CHECK-NEXT: }
|
||||
|
6
test/MC/ELF/section-sym-err.s
Normal file
6
test/MC/ELF/section-sym-err.s
Normal file
@ -0,0 +1,6 @@
|
||||
// RUN: not llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o %t.o 2>&1 | FileCheck %s
|
||||
|
||||
.section foo
|
||||
foo:
|
||||
|
||||
// CHECK: error: invalid symbol redefinition
|
91
test/MC/ELF/section-sym.s
Normal file
91
test/MC/ELF/section-sym.s
Normal file
@ -0,0 +1,91 @@
|
||||
// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | llvm-readobj -s -t -r --expand-relocs | FileCheck %s
|
||||
|
||||
.section foo, "aG", @progbits, f1, comdat
|
||||
.section foo, "G", @progbits, f2, comdat
|
||||
.section bar
|
||||
.long foo
|
||||
|
||||
// Test that the relocation points to the first section foo.
|
||||
|
||||
// The first seciton foo has index 6
|
||||
// CHECK: Section {
|
||||
// CHECK: Index: 6
|
||||
// CHECK-NEXT: Name: foo (28)
|
||||
// CHECK-NEXT: Type: SHT_PROGBITS (0x1)
|
||||
// CHECK-NEXT: Flags [ (0x202)
|
||||
// CHECK-NEXT: SHF_ALLOC (0x2)
|
||||
// CHECK-NEXT: SHF_GROUP (0x200)
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: Address: 0x0
|
||||
// CHECK-NEXT: Offset: 0x50
|
||||
// CHECK-NEXT: Size: 0
|
||||
// CHECK-NEXT: Link: 0
|
||||
// CHECK-NEXT: Info: 0
|
||||
// CHECK-NEXT: AddressAlignment: 1
|
||||
// CHECK-NEXT: EntrySize: 0
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: Section {
|
||||
// CHECK-NEXT: Index: 7
|
||||
// CHECK-NEXT: Name: foo (28)
|
||||
// CHECK-NEXT: Type: SHT_PROGBITS (0x1)
|
||||
// CHECK-NEXT: Flags [ (0x200)
|
||||
// CHECK-NEXT: SHF_GROUP (0x200)
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: Address: 0x0
|
||||
// CHECK-NEXT: Offset: 0x50
|
||||
// CHECK-NEXT: Size: 0
|
||||
// CHECK-NEXT: Link: 0
|
||||
// CHECK-NEXT: Info: 0
|
||||
// CHECK-NEXT: AddressAlignment: 1
|
||||
// CHECK-NEXT: EntrySize: 0
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// The relocation points to symbol 6
|
||||
// CHECK: Relocations [
|
||||
// CHECK-NEXT: Section (9) .relabar {
|
||||
// CHECK-NEXT: Relocation {
|
||||
// CHECK-NEXT: Offset: 0x0
|
||||
// CHECK-NEXT: Type: R_X86_64_32 (10)
|
||||
// CHECK-NEXT: Symbol: foo (6)
|
||||
// CHECK-NEXT: Addend: 0x0
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ]
|
||||
|
||||
|
||||
// The symbol 6 corresponds section 6
|
||||
// CHECK: Symbols [
|
||||
|
||||
// symbol 0
|
||||
// CHECK-NOT: Name
|
||||
// CHECK: Name:
|
||||
|
||||
// symbol 1
|
||||
// CHECK-NOT: Name
|
||||
// CHECK: Name: f1
|
||||
|
||||
// symbol 2
|
||||
// CHECK-NOT: Name
|
||||
// CHECK: Name: f2
|
||||
|
||||
// symbol 3
|
||||
// CHECK-NOT: Name
|
||||
// CHECK: Name: .text
|
||||
|
||||
// symbol 4
|
||||
// CHECK-NOT: Name
|
||||
// CHECK: Name: .data
|
||||
|
||||
// symbol 5
|
||||
// CHECK-NOT: Name
|
||||
// CHECK: Name: .bss
|
||||
|
||||
// symbol 6
|
||||
// CHECK-NOT: Name
|
||||
// CHECK: Name: foo
|
||||
// CHECK: Section: foo (0x6)
|
||||
|
||||
// symbol 7
|
||||
// CHECK-NOT: Name
|
||||
// CHECK: Name: foo
|
||||
// CHECK: Section: foo (0x7)
|
28
test/MC/ELF/section-sym2.s
Normal file
28
test/MC/ELF/section-sym2.s
Normal file
@ -0,0 +1,28 @@
|
||||
// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | llvm-readobj -t -r --expand-relocs | FileCheck %s
|
||||
|
||||
// Test that we can forward reference a section.
|
||||
|
||||
mov .rodata, %rsi
|
||||
.section .rodata
|
||||
|
||||
// CHECK:Relocations [
|
||||
// CHECK: Section (2) .rela.text {
|
||||
// CHECK: Relocation {
|
||||
// CHECK: Offset: 0x4
|
||||
// CHECK: Type: R_X86_64_32S (11)
|
||||
// CHECK: Symbol: .rodata
|
||||
// CHECK: Addend: 0x0
|
||||
// CHECK: }
|
||||
// CHECK: }
|
||||
// CHECK:]
|
||||
|
||||
// There is only one .rodata symbol
|
||||
|
||||
// CHECK:Symbols [
|
||||
// CHECK-NOT: Name: .rodata
|
||||
// CHECK: Name: .rodata
|
||||
// CHECK-NEXT: Value: 0x0
|
||||
// CHECK-NEXT: Size: 0
|
||||
// CHECK-NEXT: Binding: Local (0x0)
|
||||
// CHECK-NEXT: Type: Section (0x3)
|
||||
// CHECK-NOT: Name: .rodata
|
Loading…
Reference in New Issue
Block a user