1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 18:42:46 +02:00

ELFObjectWriter: Make STT_FILE precede associated local symbols

This commit is contained in:
Fangrui Song 2021-02-07 17:51:40 -08:00
parent 1562efaac2
commit ec15133790
4 changed files with 44 additions and 26 deletions

View File

@ -119,7 +119,7 @@ private:
std::vector<std::vector<std::string>> LinkerOptions;
/// List of declared file names
std::vector<std::string> FileNames;
std::vector<std::pair<std::string, size_t>> FileNames;
MCDwarfLineTableParams LTParams;
@ -445,11 +445,15 @@ public:
void registerSymbol(const MCSymbol &Symbol, bool *Created = nullptr);
ArrayRef<std::string> getFileNames() { return FileNames; }
MutableArrayRef<std::pair<std::string, size_t>> getFileNames() {
return FileNames;
}
void addFileName(StringRef FileName) {
if (!is_contained(FileNames, FileName))
FileNames.push_back(std::string(FileName));
for (const std::pair<std::string, size_t> &F : FileNames)
if (F.first == FileName)
return;
FileNames.emplace_back(std::string(FileName), Symbols.size());
}
/// Write the necessary bundle padding to \p OS.

View File

@ -116,8 +116,9 @@ struct ELFWriter {
/// Helper struct for containing some precomputed information on symbols.
struct ELFSymbolData {
const MCSymbolELF *Symbol;
uint32_t SectionIndex;
StringRef Name;
uint32_t SectionIndex;
uint32_t Order;
// Support lexicographic sorting.
bool operator<(const ELFSymbolData &RHS) const {
@ -626,11 +627,15 @@ void ELFWriter::computeSymbolTable(
std::vector<ELFSymbolData> LocalSymbolData;
std::vector<ELFSymbolData> ExternalSymbolData;
MutableArrayRef<std::pair<std::string, size_t>> FileNames =
Asm.getFileNames();
for (const std::pair<std::string, size_t> &F : FileNames)
StrTabBuilder.add(F.first);
// Add the data for the symbols.
bool HasLargeSectionIndex = false;
for (const MCSymbol &S : Asm.symbols()) {
const auto &Symbol = cast<MCSymbolELF>(S);
for (auto It : llvm::enumerate(Asm.symbols())) {
const auto &Symbol = cast<MCSymbolELF>(It.value());
bool Used = Symbol.isUsedInReloc();
bool WeakrefUsed = Symbol.isWeakrefUsedInReloc();
bool isSignature = Symbol.isSignature();
@ -646,6 +651,7 @@ void ELFWriter::computeSymbolTable(
ELFSymbolData MSD;
MSD.Symbol = cast<MCSymbolELF>(&Symbol);
MSD.Order = It.index();
bool Local = Symbol.getBinding() == ELF::STB_LOCAL;
assert(Local || !Symbol.isTemporary());
@ -716,34 +722,40 @@ void ELFWriter::computeSymbolTable(
SymtabShndxSection->setAlignment(Align(4));
}
ArrayRef<std::string> FileNames = Asm.getFileNames();
for (const std::string &Name : FileNames)
StrTabBuilder.add(Name);
StrTabBuilder.finalize();
// File symbols are emitted first and handled separately from normal symbols,
// i.e. a non-STT_FILE symbol with the same name may appear.
for (const std::string &Name : FileNames)
Writer.writeSymbol(StrTabBuilder.getOffset(Name),
ELF::STT_FILE | ELF::STB_LOCAL, 0, 0, ELF::STV_DEFAULT,
ELF::SHN_ABS, true);
// Symbols are required to be in lexicographic order.
//array_pod_sort(LocalSymbolData.begin(), LocalSymbolData.end());
array_pod_sort(ExternalSymbolData.begin(), ExternalSymbolData.end());
// Set the symbol indices. Local symbols must come before all other
// symbols with non-local bindings.
unsigned Index = FileNames.size() + 1;
// Make the first STT_FILE precede previous local symbols.
unsigned Index = 1;
auto FileNameIt = FileNames.begin();
if (!FileNames.empty())
FileNames[0].second = 0;
for (ELFSymbolData &MSD : LocalSymbolData) {
// Emit STT_FILE symbols before their associated local symbols.
for (; FileNameIt != FileNames.end() && FileNameIt->second <= MSD.Order;
++FileNameIt) {
Writer.writeSymbol(StrTabBuilder.getOffset(FileNameIt->first),
ELF::STT_FILE | ELF::STB_LOCAL, 0, 0, ELF::STV_DEFAULT,
ELF::SHN_ABS, true);
++Index;
}
unsigned StringIndex = MSD.Symbol->getType() == ELF::STT_SECTION
? 0
: StrTabBuilder.getOffset(MSD.Name);
MSD.Symbol->setIndex(Index++);
writeSymbol(Writer, StringIndex, MSD, Layout);
}
for (; FileNameIt != FileNames.end(); ++FileNameIt) {
Writer.writeSymbol(StrTabBuilder.getOffset(FileNameIt->first),
ELF::STT_FILE | ELF::STB_LOCAL, 0, 0, ELF::STV_DEFAULT,
ELF::SHN_ABS, true);
++Index;
}
// Write the symbol table entries.
LastLocalSymbolIndex = Index;

View File

@ -852,8 +852,9 @@ static std::time_t getTime() {
// Create .file symbols.
void WinCOFFObjectWriter::createFileSymbols(MCAssembler &Asm) {
for (const std::string &Name : Asm.getFileNames()) {
for (const std::pair<std::string, size_t> &It : Asm.getFileNames()) {
// round up to calculate the number of auxiliary symbols required
const std::string &Name = It.first;
unsigned SymbolSize = UseBigObj ? COFF::Symbol32Size : COFF::Symbol16Size;
unsigned Count = (Name.size() + SymbolSize - 1) / SymbolSize;

View File

@ -2,10 +2,10 @@
# CHECK: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
# CHECK-NEXT: 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS foo.c
# CHECK-NEXT: 2: 0000000000000000 0 FILE LOCAL DEFAULT ABS bar.c
# CHECK-NEXT: 3: 0000000000000000 0 SECTION LOCAL DEFAULT 2 .text
# CHECK-NEXT: 4: 0000000000000000 0 SECTION LOCAL DEFAULT 4 foo
# CHECK-NEXT: 5: 0000000000000000 0 NOTYPE LOCAL DEFAULT 4 local0
# CHECK-NEXT: 2: 0000000000000000 0 SECTION LOCAL DEFAULT 2 .text
# CHECK-NEXT: 3: 0000000000000000 0 SECTION LOCAL DEFAULT 4 foo
# CHECK-NEXT: 4: 0000000000000000 0 NOTYPE LOCAL DEFAULT 4 local0
# CHECK-NEXT: 5: 0000000000000000 0 FILE LOCAL DEFAULT ABS bar.c
# CHECK-NEXT: 6: 0000000000000000 0 SECTION LOCAL DEFAULT 6 bar0
# CHECK-NEXT: 7: 0000000000000000 0 NOTYPE LOCAL DEFAULT 6 local1
# CHECK-NEXT: 8: 0000000000000000 0 SECTION LOCAL DEFAULT 8 bar1
@ -23,6 +23,7 @@ foo.c:
local0:
.quad foo
## STT_FILE "bar.c" precedes subsequently defined local symbols.
.file "bar.c"
.section bar0,"a"
.globl bar.c