[llvm] 0929464 - ELFObjectWriter: Make STT_FILE precede associated local symbols
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Sun Feb 7 17:51:51 PST 2021
Author: Fangrui Song
Date: 2021-02-07T17:51:40-08:00
New Revision: 09294642bea177a45c2431b7f77781f3f898f30e
URL: https://github.com/llvm/llvm-project/commit/09294642bea177a45c2431b7f77781f3f898f30e
DIFF: https://github.com/llvm/llvm-project/commit/09294642bea177a45c2431b7f77781f3f898f30e.diff
LOG: ELFObjectWriter: Make STT_FILE precede associated local symbols
Added:
Modified:
llvm/include/llvm/MC/MCAssembler.h
llvm/lib/MC/ELFObjectWriter.cpp
llvm/lib/MC/WinCOFFObjectWriter.cpp
llvm/test/MC/ELF/file.s
Removed:
################################################################################
diff --git a/llvm/include/llvm/MC/MCAssembler.h b/llvm/include/llvm/MC/MCAssembler.h
index 1b76559d33b3..cbda472d0bb5 100644
--- a/llvm/include/llvm/MC/MCAssembler.h
+++ b/llvm/include/llvm/MC/MCAssembler.h
@@ -119,7 +119,7 @@ class MCAssembler {
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 @@ class MCAssembler {
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.
diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp
index 74eb7b64c8a4..a21194f52da5 100644
--- a/llvm/lib/MC/ELFObjectWriter.cpp
+++ b/llvm/lib/MC/ELFObjectWriter.cpp
@@ -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;
diff --git a/llvm/lib/MC/WinCOFFObjectWriter.cpp b/llvm/lib/MC/WinCOFFObjectWriter.cpp
index 901d2c06e716..2a69a30a86c7 100644
--- a/llvm/lib/MC/WinCOFFObjectWriter.cpp
+++ b/llvm/lib/MC/WinCOFFObjectWriter.cpp
@@ -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;
diff --git a/llvm/test/MC/ELF/file.s b/llvm/test/MC/ELF/file.s
index 6c8185b05577..9ede62948cfb 100644
--- a/llvm/test/MC/ELF/file.s
+++ b/llvm/test/MC/ELF/file.s
@@ -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
More information about the llvm-commits
mailing list