[lld] r365595 - [Coding style change] Rename variables so that they start with a lowercase letter
Rui Ueyama via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 9 22:00:38 PDT 2019
Modified: lld/trunk/ELF/ScriptParser.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/ScriptParser.cpp?rev=365595&r1=365594&r2=365595&view=diff
==============================================================================
--- lld/trunk/ELF/ScriptParser.cpp (original)
+++ lld/trunk/ELF/ScriptParser.cpp Tue Jul 9 22:00:37 2019
@@ -43,15 +43,15 @@ using namespace lld::elf;
namespace {
class ScriptParser final : ScriptLexer {
public:
- ScriptParser(MemoryBufferRef MB) : ScriptLexer(MB) {
+ ScriptParser(MemoryBufferRef mb) : ScriptLexer(mb) {
// Initialize IsUnderSysroot
- if (Config->Sysroot == "")
+ if (config->sysroot == "")
return;
- StringRef Path = MB.getBufferIdentifier();
- for (; !Path.empty(); Path = sys::path::parent_path(Path)) {
- if (!sys::fs::equivalent(Config->Sysroot, Path))
+ StringRef path = mb.getBufferIdentifier();
+ for (; !path.empty(); path = sys::path::parent_path(path)) {
+ if (!sys::fs::equivalent(config->sysroot, path))
continue;
- IsUnderSysroot = true;
+ isUnderSysroot = true;
return;
}
}
@@ -59,10 +59,10 @@ public:
void readLinkerScript();
void readVersionScript();
void readDynamicList();
- void readDefsym(StringRef Name);
+ void readDefsym(StringRef name);
private:
- void addFile(StringRef Path);
+ void addFile(StringRef path);
void readAsNeeded();
void readEntry();
@@ -82,23 +82,23 @@ private:
void readVersion();
void readVersionScriptCommand();
- SymbolAssignment *readSymbolAssignment(StringRef Name);
- ByteCommand *readByteCommand(StringRef Tok);
+ SymbolAssignment *readSymbolAssignment(StringRef name);
+ ByteCommand *readByteCommand(StringRef tok);
std::array<uint8_t, 4> readFill();
- bool readSectionDirective(OutputSection *Cmd, StringRef Tok1, StringRef Tok2);
- void readSectionAddressType(OutputSection *Cmd);
+ bool readSectionDirective(OutputSection *cmd, StringRef tok1, StringRef tok2);
+ void readSectionAddressType(OutputSection *cmd);
OutputSection *readOverlaySectionDescription();
- OutputSection *readOutputSectionDescription(StringRef OutSec);
+ OutputSection *readOutputSectionDescription(StringRef outSec);
std::vector<BaseCommand *> readOverlay();
std::vector<StringRef> readOutputSectionPhdrs();
- InputSectionDescription *readInputSectionDescription(StringRef Tok);
+ InputSectionDescription *readInputSectionDescription(StringRef tok);
StringMatcher readFilePatterns();
std::vector<SectionPattern> readInputSectionsList();
- InputSectionDescription *readInputSectionRules(StringRef FilePattern);
+ InputSectionDescription *readInputSectionRules(StringRef filePattern);
unsigned readPhdrType();
SortSectionPolicy readSortKind();
- SymbolAssignment *readProvideHidden(bool Provide, bool Hidden);
- SymbolAssignment *readAssignment(StringRef Tok);
+ SymbolAssignment *readProvideHidden(bool provide, bool hidden);
+ SymbolAssignment *readAssignment(StringRef tok);
void readSort();
Expr readAssert();
Expr readConstant();
@@ -107,88 +107,88 @@ private:
uint64_t readMemoryAssignment(StringRef, StringRef, StringRef);
std::pair<uint32_t, uint32_t> readMemoryAttributes();
- Expr combine(StringRef Op, Expr L, Expr R);
+ Expr combine(StringRef op, Expr l, Expr r);
Expr readExpr();
- Expr readExpr1(Expr Lhs, int MinPrec);
+ Expr readExpr1(Expr lhs, int minPrec);
StringRef readParenLiteral();
Expr readPrimary();
- Expr readTernary(Expr Cond);
+ Expr readTernary(Expr cond);
Expr readParenExpr();
// For parsing version script.
std::vector<SymbolVersion> readVersionExtern();
void readAnonymousDeclaration();
- void readVersionDeclaration(StringRef VerStr);
+ void readVersionDeclaration(StringRef verStr);
std::pair<std::vector<SymbolVersion>, std::vector<SymbolVersion>>
readSymbols();
// True if a script being read is in a subdirectory specified by -sysroot.
- bool IsUnderSysroot = false;
+ bool isUnderSysroot = false;
// A set to detect an INCLUDE() cycle.
- StringSet<> Seen;
+ StringSet<> seen;
};
} // namespace
-static StringRef unquote(StringRef S) {
- if (S.startswith("\""))
- return S.substr(1, S.size() - 2);
- return S;
+static StringRef unquote(StringRef s) {
+ if (s.startswith("\""))
+ return s.substr(1, s.size() - 2);
+ return s;
}
// Some operations only support one non absolute value. Move the
// absolute one to the right hand side for convenience.
-static void moveAbsRight(ExprValue &A, ExprValue &B) {
- if (A.Sec == nullptr || (A.ForceAbsolute && !B.isAbsolute()))
- std::swap(A, B);
- if (!B.isAbsolute())
- error(A.Loc + ": at least one side of the expression must be absolute");
+static void moveAbsRight(ExprValue &a, ExprValue &b) {
+ if (a.sec == nullptr || (a.forceAbsolute && !b.isAbsolute()))
+ std::swap(a, b);
+ if (!b.isAbsolute())
+ error(a.loc + ": at least one side of the expression must be absolute");
}
-static ExprValue add(ExprValue A, ExprValue B) {
- moveAbsRight(A, B);
- return {A.Sec, A.ForceAbsolute, A.getSectionOffset() + B.getValue(), A.Loc};
+static ExprValue add(ExprValue a, ExprValue b) {
+ moveAbsRight(a, b);
+ return {a.sec, a.forceAbsolute, a.getSectionOffset() + b.getValue(), a.loc};
}
-static ExprValue sub(ExprValue A, ExprValue B) {
+static ExprValue sub(ExprValue a, ExprValue b) {
// The distance between two symbols in sections is absolute.
- if (!A.isAbsolute() && !B.isAbsolute())
- return A.getValue() - B.getValue();
- return {A.Sec, false, A.getSectionOffset() - B.getValue(), A.Loc};
+ if (!a.isAbsolute() && !b.isAbsolute())
+ return a.getValue() - b.getValue();
+ return {a.sec, false, a.getSectionOffset() - b.getValue(), a.loc};
}
-static ExprValue bitAnd(ExprValue A, ExprValue B) {
- moveAbsRight(A, B);
- return {A.Sec, A.ForceAbsolute,
- (A.getValue() & B.getValue()) - A.getSecAddr(), A.Loc};
+static ExprValue bitAnd(ExprValue a, ExprValue b) {
+ moveAbsRight(a, b);
+ return {a.sec, a.forceAbsolute,
+ (a.getValue() & b.getValue()) - a.getSecAddr(), a.loc};
}
-static ExprValue bitOr(ExprValue A, ExprValue B) {
- moveAbsRight(A, B);
- return {A.Sec, A.ForceAbsolute,
- (A.getValue() | B.getValue()) - A.getSecAddr(), A.Loc};
+static ExprValue bitOr(ExprValue a, ExprValue b) {
+ moveAbsRight(a, b);
+ return {a.sec, a.forceAbsolute,
+ (a.getValue() | b.getValue()) - a.getSecAddr(), a.loc};
}
void ScriptParser::readDynamicList() {
- Config->HasDynamicList = true;
+ config->hasDynamicList = true;
expect("{");
- std::vector<SymbolVersion> Locals;
- std::vector<SymbolVersion> Globals;
- std::tie(Locals, Globals) = readSymbols();
+ std::vector<SymbolVersion> locals;
+ std::vector<SymbolVersion> globals;
+ std::tie(locals, globals) = readSymbols();
expect(";");
if (!atEOF()) {
setError("EOF expected, but got " + next());
return;
}
- if (!Locals.empty()) {
+ if (!locals.empty()) {
setError("\"local:\" scope not supported in --dynamic-list");
return;
}
- for (SymbolVersion V : Globals)
- Config->DynamicList.push_back(V);
+ for (SymbolVersion v : globals)
+ config->dynamicList.push_back(v);
}
void ScriptParser::readVersionScript() {
@@ -204,14 +204,14 @@ void ScriptParser::readVersionScriptComm
}
while (!atEOF() && !errorCount() && peek() != "}") {
- StringRef VerStr = next();
- if (VerStr == "{") {
+ StringRef verStr = next();
+ if (verStr == "{") {
setError("anonymous version definition is used in "
"combination with other version definitions");
return;
}
expect("{");
- readVersionDeclaration(VerStr);
+ readVersionDeclaration(verStr);
}
}
@@ -223,135 +223,135 @@ void ScriptParser::readVersion() {
void ScriptParser::readLinkerScript() {
while (!atEOF()) {
- StringRef Tok = next();
- if (Tok == ";")
+ StringRef tok = next();
+ if (tok == ";")
continue;
- if (Tok == "ENTRY") {
+ if (tok == "ENTRY") {
readEntry();
- } else if (Tok == "EXTERN") {
+ } else if (tok == "EXTERN") {
readExtern();
- } else if (Tok == "GROUP") {
+ } else if (tok == "GROUP") {
readGroup();
- } else if (Tok == "INCLUDE") {
+ } else if (tok == "INCLUDE") {
readInclude();
- } else if (Tok == "INPUT") {
+ } else if (tok == "INPUT") {
readInput();
- } else if (Tok == "MEMORY") {
+ } else if (tok == "MEMORY") {
readMemory();
- } else if (Tok == "OUTPUT") {
+ } else if (tok == "OUTPUT") {
readOutput();
- } else if (Tok == "OUTPUT_ARCH") {
+ } else if (tok == "OUTPUT_ARCH") {
readOutputArch();
- } else if (Tok == "OUTPUT_FORMAT") {
+ } else if (tok == "OUTPUT_FORMAT") {
readOutputFormat();
- } else if (Tok == "PHDRS") {
+ } else if (tok == "PHDRS") {
readPhdrs();
- } else if (Tok == "REGION_ALIAS") {
+ } else if (tok == "REGION_ALIAS") {
readRegionAlias();
- } else if (Tok == "SEARCH_DIR") {
+ } else if (tok == "SEARCH_DIR") {
readSearchDir();
- } else if (Tok == "SECTIONS") {
+ } else if (tok == "SECTIONS") {
readSections();
- } else if (Tok == "TARGET") {
+ } else if (tok == "TARGET") {
readTarget();
- } else if (Tok == "VERSION") {
+ } else if (tok == "VERSION") {
readVersion();
- } else if (SymbolAssignment *Cmd = readAssignment(Tok)) {
- Script->SectionCommands.push_back(Cmd);
+ } else if (SymbolAssignment *cmd = readAssignment(tok)) {
+ script->sectionCommands.push_back(cmd);
} else {
- setError("unknown directive: " + Tok);
+ setError("unknown directive: " + tok);
}
}
}
-void ScriptParser::readDefsym(StringRef Name) {
+void ScriptParser::readDefsym(StringRef name) {
if (errorCount())
return;
- Expr E = readExpr();
+ Expr e = readExpr();
if (!atEOF())
setError("EOF expected, but got " + next());
- SymbolAssignment *Cmd = make<SymbolAssignment>(Name, E, getCurrentLocation());
- Script->SectionCommands.push_back(Cmd);
+ SymbolAssignment *cmd = make<SymbolAssignment>(name, e, getCurrentLocation());
+ script->sectionCommands.push_back(cmd);
}
-void ScriptParser::addFile(StringRef S) {
- if (IsUnderSysroot && S.startswith("/")) {
- SmallString<128> PathData;
- StringRef Path = (Config->Sysroot + S).toStringRef(PathData);
- if (sys::fs::exists(Path)) {
- Driver->addFile(Saver.save(Path), /*WithLOption=*/false);
+void ScriptParser::addFile(StringRef s) {
+ if (isUnderSysroot && s.startswith("/")) {
+ SmallString<128> pathData;
+ StringRef path = (config->sysroot + s).toStringRef(pathData);
+ if (sys::fs::exists(path)) {
+ driver->addFile(Saver.save(path), /*WithLOption=*/false);
return;
}
}
- if (S.startswith("/")) {
- Driver->addFile(S, /*WithLOption=*/false);
- } else if (S.startswith("=")) {
- if (Config->Sysroot.empty())
- Driver->addFile(S.substr(1), /*WithLOption=*/false);
+ if (s.startswith("/")) {
+ driver->addFile(s, /*WithLOption=*/false);
+ } else if (s.startswith("=")) {
+ if (config->sysroot.empty())
+ driver->addFile(s.substr(1), /*WithLOption=*/false);
else
- Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1)),
+ driver->addFile(Saver.save(config->sysroot + "/" + s.substr(1)),
/*WithLOption=*/false);
- } else if (S.startswith("-l")) {
- Driver->addLibrary(S.substr(2));
- } else if (sys::fs::exists(S)) {
- Driver->addFile(S, /*WithLOption=*/false);
+ } else if (s.startswith("-l")) {
+ driver->addLibrary(s.substr(2));
+ } else if (sys::fs::exists(s)) {
+ driver->addFile(s, /*WithLOption=*/false);
} else {
- if (Optional<std::string> Path = findFromSearchPaths(S))
- Driver->addFile(Saver.save(*Path), /*WithLOption=*/true);
+ if (Optional<std::string> path = findFromSearchPaths(s))
+ driver->addFile(Saver.save(*path), /*WithLOption=*/true);
else
- setError("unable to find " + S);
+ setError("unable to find " + s);
}
}
void ScriptParser::readAsNeeded() {
expect("(");
- bool Orig = Config->AsNeeded;
- Config->AsNeeded = true;
+ bool orig = config->asNeeded;
+ config->asNeeded = true;
while (!errorCount() && !consume(")"))
addFile(unquote(next()));
- Config->AsNeeded = Orig;
+ config->asNeeded = orig;
}
void ScriptParser::readEntry() {
// -e <symbol> takes predecence over ENTRY(<symbol>).
expect("(");
- StringRef Tok = next();
- if (Config->Entry.empty())
- Config->Entry = Tok;
+ StringRef tok = next();
+ if (config->entry.empty())
+ config->entry = tok;
expect(")");
}
void ScriptParser::readExtern() {
expect("(");
while (!errorCount() && !consume(")"))
- Config->Undefined.push_back(unquote(next()));
+ config->undefined.push_back(unquote(next()));
}
void ScriptParser::readGroup() {
- bool Orig = InputFile::IsInGroup;
- InputFile::IsInGroup = true;
+ bool orig = InputFile::isInGroup;
+ InputFile::isInGroup = true;
readInput();
- InputFile::IsInGroup = Orig;
- if (!Orig)
- ++InputFile::NextGroupId;
+ InputFile::isInGroup = orig;
+ if (!orig)
+ ++InputFile::nextGroupId;
}
void ScriptParser::readInclude() {
- StringRef Tok = unquote(next());
+ StringRef tok = unquote(next());
- if (!Seen.insert(Tok).second) {
+ if (!seen.insert(tok).second) {
setError("there is a cycle in linker script INCLUDEs");
return;
}
- if (Optional<std::string> Path = searchScript(Tok)) {
- if (Optional<MemoryBufferRef> MB = readFile(*Path))
- tokenize(*MB);
+ if (Optional<std::string> path = searchScript(tok)) {
+ if (Optional<MemoryBufferRef> mb = readFile(*path))
+ tokenize(*mb);
return;
}
- setError("cannot find linker script " + Tok);
+ setError("cannot find linker script " + tok);
}
void ScriptParser::readInput() {
@@ -367,9 +367,9 @@ void ScriptParser::readInput() {
void ScriptParser::readOutput() {
// -o <file> takes predecence over OUTPUT(<file>).
expect("(");
- StringRef Tok = next();
- if (Config->OutputFile.empty())
- Config->OutputFile = unquote(Tok);
+ StringRef tok = next();
+ if (config->outputFile.empty())
+ config->outputFile = unquote(tok);
expect(")");
}
@@ -380,8 +380,8 @@ void ScriptParser::readOutputArch() {
skip();
}
-static std::pair<ELFKind, uint16_t> parseBfdName(StringRef S) {
- return StringSwitch<std::pair<ELFKind, uint16_t>>(S)
+static std::pair<ELFKind, uint16_t> parseBfdName(StringRef s) {
+ return StringSwitch<std::pair<ELFKind, uint16_t>>(s)
.Case("elf32-i386", {ELF32LEKind, EM_386})
.Case("elf32-iamcu", {ELF32LEKind, EM_IAMCU})
.Case("elf32-littlearm", {ELF32LEKind, EM_ARM})
@@ -408,16 +408,16 @@ static std::pair<ELFKind, uint16_t> pars
void ScriptParser::readOutputFormat() {
expect("(");
- StringRef Name = unquote(next());
- StringRef S = Name;
- if (S.consume_back("-freebsd"))
- Config->OSABI = ELFOSABI_FREEBSD;
-
- std::tie(Config->EKind, Config->EMachine) = parseBfdName(S);
- if (Config->EMachine == EM_NONE)
- setError("unknown output format name: " + Name);
- if (S == "elf32-ntradlittlemips" || S == "elf32-ntradbigmips")
- Config->MipsN32Abi = true;
+ StringRef name = unquote(next());
+ StringRef s = name;
+ if (s.consume_back("-freebsd"))
+ config->osabi = ELFOSABI_FREEBSD;
+
+ std::tie(config->ekind, config->emachine) = parseBfdName(s);
+ if (config->emachine == EM_NONE)
+ setError("unknown output format name: " + name);
+ if (s == "elf32-ntradlittlemips" || s == "elf32-ntradbigmips")
+ config->mipsN32Abi = true;
if (consume(")"))
return;
@@ -432,46 +432,46 @@ void ScriptParser::readPhdrs() {
expect("{");
while (!errorCount() && !consume("}")) {
- PhdrsCommand Cmd;
- Cmd.Name = next();
- Cmd.Type = readPhdrType();
+ PhdrsCommand cmd;
+ cmd.name = next();
+ cmd.type = readPhdrType();
while (!errorCount() && !consume(";")) {
if (consume("FILEHDR"))
- Cmd.HasFilehdr = true;
+ cmd.hasFilehdr = true;
else if (consume("PHDRS"))
- Cmd.HasPhdrs = true;
+ cmd.hasPhdrs = true;
else if (consume("AT"))
- Cmd.LMAExpr = readParenExpr();
+ cmd.lmaExpr = readParenExpr();
else if (consume("FLAGS"))
- Cmd.Flags = readParenExpr()().getValue();
+ cmd.flags = readParenExpr()().getValue();
else
setError("unexpected header attribute: " + next());
}
- Script->PhdrsCommands.push_back(Cmd);
+ script->phdrsCommands.push_back(cmd);
}
}
void ScriptParser::readRegionAlias() {
expect("(");
- StringRef Alias = unquote(next());
+ StringRef alias = unquote(next());
expect(",");
- StringRef Name = next();
+ StringRef name = next();
expect(")");
- if (Script->MemoryRegions.count(Alias))
- setError("redefinition of memory region '" + Alias + "'");
- if (!Script->MemoryRegions.count(Name))
- setError("memory region '" + Name + "' is not defined");
- Script->MemoryRegions.insert({Alias, Script->MemoryRegions[Name]});
+ if (script->memoryRegions.count(alias))
+ setError("redefinition of memory region '" + alias + "'");
+ if (!script->memoryRegions.count(name))
+ setError("memory region '" + name + "' is not defined");
+ script->memoryRegions.insert({alias, script->memoryRegions[name]});
}
void ScriptParser::readSearchDir() {
expect("(");
- StringRef Tok = next();
- if (!Config->Nostdlib)
- Config->SearchPaths.push_back(unquote(Tok));
+ StringRef tok = next();
+ if (!config->nostdlib)
+ config->searchPaths.push_back(unquote(tok));
expect(")");
}
@@ -483,83 +483,83 @@ std::vector<BaseCommand *> ScriptParser:
// VA and LMA expressions are optional, though for simplicity of
// implementation we assume they are not. That is what OVERLAY was designed
// for first of all: to allow sections with overlapping VAs at different LMAs.
- Expr AddrExpr = readExpr();
+ Expr addrExpr = readExpr();
expect(":");
expect("AT");
- Expr LMAExpr = readParenExpr();
+ Expr lmaExpr = readParenExpr();
expect("{");
- std::vector<BaseCommand *> V;
- OutputSection *Prev = nullptr;
+ std::vector<BaseCommand *> v;
+ OutputSection *prev = nullptr;
while (!errorCount() && !consume("}")) {
// VA is the same for all sections. The LMAs are consecutive in memory
// starting from the base load address specified.
- OutputSection *OS = readOverlaySectionDescription();
- OS->AddrExpr = AddrExpr;
- if (Prev)
- OS->LMAExpr = [=] { return Prev->getLMA() + Prev->Size; };
+ OutputSection *os = readOverlaySectionDescription();
+ os->addrExpr = addrExpr;
+ if (prev)
+ os->lmaExpr = [=] { return prev->getLMA() + prev->size; };
else
- OS->LMAExpr = LMAExpr;
- V.push_back(OS);
- Prev = OS;
+ os->lmaExpr = lmaExpr;
+ v.push_back(os);
+ prev = os;
}
// According to the specification, at the end of the overlay, the location
// counter should be equal to the overlay base address plus size of the
// largest section seen in the overlay.
// Here we want to create the Dot assignment command to achieve that.
- Expr MoveDot = [=] {
- uint64_t Max = 0;
- for (BaseCommand *Cmd : V)
- Max = std::max(Max, cast<OutputSection>(Cmd)->Size);
- return AddrExpr().getValue() + Max;
+ Expr moveDot = [=] {
+ uint64_t max = 0;
+ for (BaseCommand *cmd : v)
+ max = std::max(max, cast<OutputSection>(cmd)->size);
+ return addrExpr().getValue() + max;
};
- V.push_back(make<SymbolAssignment>(".", MoveDot, getCurrentLocation()));
- return V;
+ v.push_back(make<SymbolAssignment>(".", moveDot, getCurrentLocation()));
+ return v;
}
void ScriptParser::readSections() {
- Script->HasSectionsCommand = true;
+ script->hasSectionsCommand = true;
// -no-rosegment is used to avoid placing read only non-executable sections in
// their own segment. We do the same if SECTIONS command is present in linker
// script. See comment for computeFlags().
- Config->SingleRoRx = true;
+ config->singleRoRx = true;
expect("{");
- std::vector<BaseCommand *> V;
+ std::vector<BaseCommand *> v;
while (!errorCount() && !consume("}")) {
- StringRef Tok = next();
- if (Tok == "OVERLAY") {
- for (BaseCommand *Cmd : readOverlay())
- V.push_back(Cmd);
+ StringRef tok = next();
+ if (tok == "OVERLAY") {
+ for (BaseCommand *cmd : readOverlay())
+ v.push_back(cmd);
continue;
- } else if (Tok == "INCLUDE") {
+ } else if (tok == "INCLUDE") {
readInclude();
continue;
}
- if (BaseCommand *Cmd = readAssignment(Tok))
- V.push_back(Cmd);
+ if (BaseCommand *cmd = readAssignment(tok))
+ v.push_back(cmd);
else
- V.push_back(readOutputSectionDescription(Tok));
+ v.push_back(readOutputSectionDescription(tok));
}
if (!atEOF() && consume("INSERT")) {
- std::vector<BaseCommand *> *Dest = nullptr;
+ std::vector<BaseCommand *> *dest = nullptr;
if (consume("AFTER"))
- Dest = &Script->InsertAfterCommands[next()];
+ dest = &script->insertAfterCommands[next()];
else if (consume("BEFORE"))
- Dest = &Script->InsertBeforeCommands[next()];
+ dest = &script->insertBeforeCommands[next()];
else
setError("expected AFTER/BEFORE, but got '" + next() + "'");
- if (Dest)
- Dest->insert(Dest->end(), V.begin(), V.end());
+ if (dest)
+ dest->insert(dest->end(), v.begin(), v.end());
return;
}
- Script->SectionCommands.insert(Script->SectionCommands.end(), V.begin(),
- V.end());
+ script->sectionCommands.insert(script->sectionCommands.end(), v.begin(),
+ v.end());
}
void ScriptParser::readTarget() {
@@ -568,19 +568,19 @@ void ScriptParser::readTarget() {
// for --format. We recognize only /^elf/ and "binary" in the linker
// script as well.
expect("(");
- StringRef Tok = next();
+ StringRef tok = next();
expect(")");
- if (Tok.startswith("elf"))
- Config->FormatBinary = false;
- else if (Tok == "binary")
- Config->FormatBinary = true;
+ if (tok.startswith("elf"))
+ config->formatBinary = false;
+ else if (tok == "binary")
+ config->formatBinary = true;
else
- setError("unknown target: " + Tok);
+ setError("unknown target: " + tok);
}
-static int precedence(StringRef Op) {
- return StringSwitch<int>(Op)
+static int precedence(StringRef op) {
+ return StringSwitch<int>(op)
.Cases("*", "/", "%", 8)
.Cases("+", "-", 7)
.Cases("<<", ">>", 6)
@@ -593,10 +593,10 @@ static int precedence(StringRef Op) {
}
StringMatcher ScriptParser::readFilePatterns() {
- std::vector<StringRef> V;
+ std::vector<StringRef> v;
while (!errorCount() && !consume(")"))
- V.push_back(next());
- return StringMatcher(V);
+ v.push_back(next());
+ return StringMatcher(v);
}
SortSectionPolicy ScriptParser::readSortKind() {
@@ -625,24 +625,24 @@ SortSectionPolicy ScriptParser::readSort
// The semantics of that is section .foo in any file, section .bar in
// any file but a.o, and section .baz in any file but b.o.
std::vector<SectionPattern> ScriptParser::readInputSectionsList() {
- std::vector<SectionPattern> Ret;
+ std::vector<SectionPattern> ret;
while (!errorCount() && peek() != ")") {
- StringMatcher ExcludeFilePat;
+ StringMatcher excludeFilePat;
if (consume("EXCLUDE_FILE")) {
expect("(");
- ExcludeFilePat = readFilePatterns();
+ excludeFilePat = readFilePatterns();
}
- std::vector<StringRef> V;
+ std::vector<StringRef> v;
while (!errorCount() && peek() != ")" && peek() != "EXCLUDE_FILE")
- V.push_back(unquote(next()));
+ v.push_back(unquote(next()));
- if (!V.empty())
- Ret.push_back({std::move(ExcludeFilePat), StringMatcher(V)});
+ if (!v.empty())
+ ret.push_back({std::move(excludeFilePat), StringMatcher(v)});
else
setError("section pattern is expected");
}
- return Ret;
+ return ret;
}
// Reads contents of "SECTIONS" directive. That directive contains a
@@ -657,52 +657,52 @@ std::vector<SectionPattern> ScriptParser
//
// <section-list> is parsed by readInputSectionsList().
InputSectionDescription *
-ScriptParser::readInputSectionRules(StringRef FilePattern) {
- auto *Cmd = make<InputSectionDescription>(FilePattern);
+ScriptParser::readInputSectionRules(StringRef filePattern) {
+ auto *cmd = make<InputSectionDescription>(filePattern);
expect("(");
while (!errorCount() && !consume(")")) {
- SortSectionPolicy Outer = readSortKind();
- SortSectionPolicy Inner = SortSectionPolicy::Default;
- std::vector<SectionPattern> V;
- if (Outer != SortSectionPolicy::Default) {
+ SortSectionPolicy outer = readSortKind();
+ SortSectionPolicy inner = SortSectionPolicy::Default;
+ std::vector<SectionPattern> v;
+ if (outer != SortSectionPolicy::Default) {
expect("(");
- Inner = readSortKind();
- if (Inner != SortSectionPolicy::Default) {
+ inner = readSortKind();
+ if (inner != SortSectionPolicy::Default) {
expect("(");
- V = readInputSectionsList();
+ v = readInputSectionsList();
expect(")");
} else {
- V = readInputSectionsList();
+ v = readInputSectionsList();
}
expect(")");
} else {
- V = readInputSectionsList();
+ v = readInputSectionsList();
}
- for (SectionPattern &Pat : V) {
- Pat.SortInner = Inner;
- Pat.SortOuter = Outer;
+ for (SectionPattern &pat : v) {
+ pat.sortInner = inner;
+ pat.sortOuter = outer;
}
- std::move(V.begin(), V.end(), std::back_inserter(Cmd->SectionPatterns));
+ std::move(v.begin(), v.end(), std::back_inserter(cmd->sectionPatterns));
}
- return Cmd;
+ return cmd;
}
InputSectionDescription *
-ScriptParser::readInputSectionDescription(StringRef Tok) {
+ScriptParser::readInputSectionDescription(StringRef tok) {
// Input section wildcard can be surrounded by KEEP.
// https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep
- if (Tok == "KEEP") {
+ if (tok == "KEEP") {
expect("(");
- StringRef FilePattern = next();
- InputSectionDescription *Cmd = readInputSectionRules(FilePattern);
+ StringRef filePattern = next();
+ InputSectionDescription *cmd = readInputSectionRules(filePattern);
expect(")");
- Script->KeptSections.push_back(Cmd);
- return Cmd;
+ script->keptSections.push_back(cmd);
+ return cmd;
}
- return readInputSectionRules(Tok);
+ return readInputSectionRules(tok);
}
void ScriptParser::readSort() {
@@ -713,33 +713,33 @@ void ScriptParser::readSort() {
Expr ScriptParser::readAssert() {
expect("(");
- Expr E = readExpr();
+ Expr e = readExpr();
expect(",");
- StringRef Msg = unquote(next());
+ StringRef msg = unquote(next());
expect(")");
return [=] {
- if (!E().getValue())
- error(Msg);
- return Script->getDot();
+ if (!e().getValue())
+ error(msg);
+ return script->getDot();
};
}
// Tries to read the special directive for an output section definition which
// can be one of following: "(NOLOAD)", "(COPY)", "(INFO)" or "(OVERLAY)".
// Tok1 and Tok2 are next 2 tokens peeked. See comment for readSectionAddressType below.
-bool ScriptParser::readSectionDirective(OutputSection *Cmd, StringRef Tok1, StringRef Tok2) {
- if (Tok1 != "(")
+bool ScriptParser::readSectionDirective(OutputSection *cmd, StringRef tok1, StringRef tok2) {
+ if (tok1 != "(")
return false;
- if (Tok2 != "NOLOAD" && Tok2 != "COPY" && Tok2 != "INFO" && Tok2 != "OVERLAY")
+ if (tok2 != "NOLOAD" && tok2 != "COPY" && tok2 != "INFO" && tok2 != "OVERLAY")
return false;
expect("(");
if (consume("NOLOAD")) {
- Cmd->Noload = true;
+ cmd->noload = true;
} else {
skip(); // This is "COPY", "INFO" or "OVERLAY".
- Cmd->NonAlloc = true;
+ cmd->nonAlloc = true;
}
expect(")");
return true;
@@ -756,121 +756,121 @@ bool ScriptParser::readSectionDirective(
//
// https://sourceware.org/binutils/docs/ld/Output-Section-Address.html
// https://sourceware.org/binutils/docs/ld/Output-Section-Type.html
-void ScriptParser::readSectionAddressType(OutputSection *Cmd) {
- if (readSectionDirective(Cmd, peek(), peek2()))
+void ScriptParser::readSectionAddressType(OutputSection *cmd) {
+ if (readSectionDirective(cmd, peek(), peek2()))
return;
- Cmd->AddrExpr = readExpr();
- if (peek() == "(" && !readSectionDirective(Cmd, "(", peek2()))
+ cmd->addrExpr = readExpr();
+ if (peek() == "(" && !readSectionDirective(cmd, "(", peek2()))
setError("unknown section directive: " + peek2());
}
-static Expr checkAlignment(Expr E, std::string &Loc) {
+static Expr checkAlignment(Expr e, std::string &loc) {
return [=] {
- uint64_t Alignment = std::max((uint64_t)1, E().getValue());
- if (!isPowerOf2_64(Alignment)) {
- error(Loc + ": alignment must be power of 2");
+ uint64_t alignment = std::max((uint64_t)1, e().getValue());
+ if (!isPowerOf2_64(alignment)) {
+ error(loc + ": alignment must be power of 2");
return (uint64_t)1; // Return a dummy value.
}
- return Alignment;
+ return alignment;
};
}
OutputSection *ScriptParser::readOverlaySectionDescription() {
- OutputSection *Cmd =
- Script->createOutputSection(next(), getCurrentLocation());
- Cmd->InOverlay = true;
+ OutputSection *cmd =
+ script->createOutputSection(next(), getCurrentLocation());
+ cmd->inOverlay = true;
expect("{");
while (!errorCount() && !consume("}"))
- Cmd->SectionCommands.push_back(readInputSectionRules(next()));
- Cmd->Phdrs = readOutputSectionPhdrs();
- return Cmd;
+ cmd->sectionCommands.push_back(readInputSectionRules(next()));
+ cmd->phdrs = readOutputSectionPhdrs();
+ return cmd;
}
-OutputSection *ScriptParser::readOutputSectionDescription(StringRef OutSec) {
- OutputSection *Cmd =
- Script->createOutputSection(OutSec, getCurrentLocation());
+OutputSection *ScriptParser::readOutputSectionDescription(StringRef outSec) {
+ OutputSection *cmd =
+ script->createOutputSection(outSec, getCurrentLocation());
- size_t SymbolsReferenced = Script->ReferencedSymbols.size();
+ size_t symbolsReferenced = script->referencedSymbols.size();
if (peek() != ":")
- readSectionAddressType(Cmd);
+ readSectionAddressType(cmd);
expect(":");
- std::string Location = getCurrentLocation();
+ std::string location = getCurrentLocation();
if (consume("AT"))
- Cmd->LMAExpr = readParenExpr();
+ cmd->lmaExpr = readParenExpr();
if (consume("ALIGN"))
- Cmd->AlignExpr = checkAlignment(readParenExpr(), Location);
+ cmd->alignExpr = checkAlignment(readParenExpr(), location);
if (consume("SUBALIGN"))
- Cmd->SubalignExpr = checkAlignment(readParenExpr(), Location);
+ cmd->subalignExpr = checkAlignment(readParenExpr(), location);
// Parse constraints.
if (consume("ONLY_IF_RO"))
- Cmd->Constraint = ConstraintKind::ReadOnly;
+ cmd->constraint = ConstraintKind::ReadOnly;
if (consume("ONLY_IF_RW"))
- Cmd->Constraint = ConstraintKind::ReadWrite;
+ cmd->constraint = ConstraintKind::ReadWrite;
expect("{");
while (!errorCount() && !consume("}")) {
- StringRef Tok = next();
- if (Tok == ";") {
+ StringRef tok = next();
+ if (tok == ";") {
// Empty commands are allowed. Do nothing here.
- } else if (SymbolAssignment *Assign = readAssignment(Tok)) {
- Cmd->SectionCommands.push_back(Assign);
- } else if (ByteCommand *Data = readByteCommand(Tok)) {
- Cmd->SectionCommands.push_back(Data);
- } else if (Tok == "CONSTRUCTORS") {
+ } else if (SymbolAssignment *assign = readAssignment(tok)) {
+ cmd->sectionCommands.push_back(assign);
+ } else if (ByteCommand *data = readByteCommand(tok)) {
+ cmd->sectionCommands.push_back(data);
+ } else if (tok == "CONSTRUCTORS") {
// CONSTRUCTORS is a keyword to make the linker recognize C++ ctors/dtors
// by name. This is for very old file formats such as ECOFF/XCOFF.
// For ELF, we should ignore.
- } else if (Tok == "FILL") {
+ } else if (tok == "FILL") {
// We handle the FILL command as an alias for =fillexp section attribute,
// which is different from what GNU linkers do.
// https://sourceware.org/binutils/docs/ld/Output-Section-Data.html
- Cmd->Filler = readFill();
- } else if (Tok == "SORT") {
+ cmd->filler = readFill();
+ } else if (tok == "SORT") {
readSort();
- } else if (Tok == "INCLUDE") {
+ } else if (tok == "INCLUDE") {
readInclude();
} else if (peek() == "(") {
- Cmd->SectionCommands.push_back(readInputSectionDescription(Tok));
+ cmd->sectionCommands.push_back(readInputSectionDescription(tok));
} else {
// We have a file name and no input sections description. It is not a
// commonly used syntax, but still acceptable. In that case, all sections
// from the file will be included.
- auto *ISD = make<InputSectionDescription>(Tok);
- ISD->SectionPatterns.push_back({{}, StringMatcher({"*"})});
- Cmd->SectionCommands.push_back(ISD);
+ auto *isd = make<InputSectionDescription>(tok);
+ isd->sectionPatterns.push_back({{}, StringMatcher({"*"})});
+ cmd->sectionCommands.push_back(isd);
}
}
if (consume(">"))
- Cmd->MemoryRegionName = next();
+ cmd->memoryRegionName = next();
if (consume("AT")) {
expect(">");
- Cmd->LMARegionName = next();
+ cmd->lmaRegionName = next();
}
- if (Cmd->LMAExpr && !Cmd->LMARegionName.empty())
+ if (cmd->lmaExpr && !cmd->lmaRegionName.empty())
error("section can't have both LMA and a load region");
- Cmd->Phdrs = readOutputSectionPhdrs();
+ cmd->phdrs = readOutputSectionPhdrs();
if (peek() == "=" || peek().startswith("=")) {
- InExpr = true;
+ inExpr = true;
consume("=");
- Cmd->Filler = readFill();
- InExpr = false;
+ cmd->filler = readFill();
+ inExpr = false;
}
// Consume optional comma following output section command.
consume(",");
- if (Script->ReferencedSymbols.size() > SymbolsReferenced)
- Cmd->ExpressionsUseSymbols = true;
- return Cmd;
+ if (script->referencedSymbols.size() > symbolsReferenced)
+ cmd->expressionsUseSymbols = true;
+ return cmd;
}
// Reads a `=<fillexp>` expression and returns its value as a big-endian number.
@@ -881,59 +881,59 @@ OutputSection *ScriptParser::readOutputS
// size, while ld.gold always handles it as a 32-bit big-endian number.
// We are compatible with ld.gold because it's easier to implement.
std::array<uint8_t, 4> ScriptParser::readFill() {
- uint64_t Value = readExpr()().Val;
- if (Value > UINT32_MAX)
+ uint64_t value = readExpr()().val;
+ if (value > UINT32_MAX)
setError("filler expression result does not fit 32-bit: 0x" +
- Twine::utohexstr(Value));
+ Twine::utohexstr(value));
- std::array<uint8_t, 4> Buf;
- write32be(Buf.data(), (uint32_t)Value);
- return Buf;
+ std::array<uint8_t, 4> buf;
+ write32be(buf.data(), (uint32_t)value);
+ return buf;
}
-SymbolAssignment *ScriptParser::readProvideHidden(bool Provide, bool Hidden) {
+SymbolAssignment *ScriptParser::readProvideHidden(bool provide, bool hidden) {
expect("(");
- SymbolAssignment *Cmd = readSymbolAssignment(next());
- Cmd->Provide = Provide;
- Cmd->Hidden = Hidden;
+ SymbolAssignment *cmd = readSymbolAssignment(next());
+ cmd->provide = provide;
+ cmd->hidden = hidden;
expect(")");
- return Cmd;
+ return cmd;
}
-SymbolAssignment *ScriptParser::readAssignment(StringRef Tok) {
+SymbolAssignment *ScriptParser::readAssignment(StringRef tok) {
// Assert expression returns Dot, so this is equal to ".=."
- if (Tok == "ASSERT")
+ if (tok == "ASSERT")
return make<SymbolAssignment>(".", readAssert(), getCurrentLocation());
- size_t OldPos = Pos;
- SymbolAssignment *Cmd = nullptr;
+ size_t oldPos = pos;
+ SymbolAssignment *cmd = nullptr;
if (peek() == "=" || peek() == "+=")
- Cmd = readSymbolAssignment(Tok);
- else if (Tok == "PROVIDE")
- Cmd = readProvideHidden(true, false);
- else if (Tok == "HIDDEN")
- Cmd = readProvideHidden(false, true);
- else if (Tok == "PROVIDE_HIDDEN")
- Cmd = readProvideHidden(true, true);
-
- if (Cmd) {
- Cmd->CommandString =
- Tok.str() + " " +
- llvm::join(Tokens.begin() + OldPos, Tokens.begin() + Pos, " ");
+ cmd = readSymbolAssignment(tok);
+ else if (tok == "PROVIDE")
+ cmd = readProvideHidden(true, false);
+ else if (tok == "HIDDEN")
+ cmd = readProvideHidden(false, true);
+ else if (tok == "PROVIDE_HIDDEN")
+ cmd = readProvideHidden(true, true);
+
+ if (cmd) {
+ cmd->commandString =
+ tok.str() + " " +
+ llvm::join(tokens.begin() + oldPos, tokens.begin() + pos, " ");
expect(";");
}
- return Cmd;
+ return cmd;
}
-SymbolAssignment *ScriptParser::readSymbolAssignment(StringRef Name) {
- StringRef Op = next();
- assert(Op == "=" || Op == "+=");
- Expr E = readExpr();
- if (Op == "+=") {
- std::string Loc = getCurrentLocation();
- E = [=] { return add(Script->getSymbolValue(Name, Loc), E()); };
+SymbolAssignment *ScriptParser::readSymbolAssignment(StringRef name) {
+ StringRef op = next();
+ assert(op == "=" || op == "+=");
+ Expr e = readExpr();
+ if (op == "+=") {
+ std::string loc = getCurrentLocation();
+ e = [=] { return add(script->getSymbolValue(name, loc), e()); };
}
- return make<SymbolAssignment>(Name, E, getCurrentLocation());
+ return make<SymbolAssignment>(name, e, getCurrentLocation());
}
// This is an operator-precedence parser to parse a linker
@@ -941,178 +941,178 @@ SymbolAssignment *ScriptParser::readSymb
Expr ScriptParser::readExpr() {
// Our lexer is context-aware. Set the in-expression bit so that
// they apply different tokenization rules.
- bool Orig = InExpr;
- InExpr = true;
- Expr E = readExpr1(readPrimary(), 0);
- InExpr = Orig;
- return E;
-}
-
-Expr ScriptParser::combine(StringRef Op, Expr L, Expr R) {
- if (Op == "+")
- return [=] { return add(L(), R()); };
- if (Op == "-")
- return [=] { return sub(L(), R()); };
- if (Op == "*")
- return [=] { return L().getValue() * R().getValue(); };
- if (Op == "/") {
- std::string Loc = getCurrentLocation();
+ bool orig = inExpr;
+ inExpr = true;
+ Expr e = readExpr1(readPrimary(), 0);
+ inExpr = orig;
+ return e;
+}
+
+Expr ScriptParser::combine(StringRef op, Expr l, Expr r) {
+ if (op == "+")
+ return [=] { return add(l(), r()); };
+ if (op == "-")
+ return [=] { return sub(l(), r()); };
+ if (op == "*")
+ return [=] { return l().getValue() * r().getValue(); };
+ if (op == "/") {
+ std::string loc = getCurrentLocation();
return [=]() -> uint64_t {
- if (uint64_t RV = R().getValue())
- return L().getValue() / RV;
- error(Loc + ": division by zero");
+ if (uint64_t rv = r().getValue())
+ return l().getValue() / rv;
+ error(loc + ": division by zero");
return 0;
};
}
- if (Op == "%") {
- std::string Loc = getCurrentLocation();
+ if (op == "%") {
+ std::string loc = getCurrentLocation();
return [=]() -> uint64_t {
- if (uint64_t RV = R().getValue())
- return L().getValue() % RV;
- error(Loc + ": modulo by zero");
+ if (uint64_t rv = r().getValue())
+ return l().getValue() % rv;
+ error(loc + ": modulo by zero");
return 0;
};
}
- if (Op == "<<")
- return [=] { return L().getValue() << R().getValue(); };
- if (Op == ">>")
- return [=] { return L().getValue() >> R().getValue(); };
- if (Op == "<")
- return [=] { return L().getValue() < R().getValue(); };
- if (Op == ">")
- return [=] { return L().getValue() > R().getValue(); };
- if (Op == ">=")
- return [=] { return L().getValue() >= R().getValue(); };
- if (Op == "<=")
- return [=] { return L().getValue() <= R().getValue(); };
- if (Op == "==")
- return [=] { return L().getValue() == R().getValue(); };
- if (Op == "!=")
- return [=] { return L().getValue() != R().getValue(); };
- if (Op == "||")
- return [=] { return L().getValue() || R().getValue(); };
- if (Op == "&&")
- return [=] { return L().getValue() && R().getValue(); };
- if (Op == "&")
- return [=] { return bitAnd(L(), R()); };
- if (Op == "|")
- return [=] { return bitOr(L(), R()); };
+ if (op == "<<")
+ return [=] { return l().getValue() << r().getValue(); };
+ if (op == ">>")
+ return [=] { return l().getValue() >> r().getValue(); };
+ if (op == "<")
+ return [=] { return l().getValue() < r().getValue(); };
+ if (op == ">")
+ return [=] { return l().getValue() > r().getValue(); };
+ if (op == ">=")
+ return [=] { return l().getValue() >= r().getValue(); };
+ if (op == "<=")
+ return [=] { return l().getValue() <= r().getValue(); };
+ if (op == "==")
+ return [=] { return l().getValue() == r().getValue(); };
+ if (op == "!=")
+ return [=] { return l().getValue() != r().getValue(); };
+ if (op == "||")
+ return [=] { return l().getValue() || r().getValue(); };
+ if (op == "&&")
+ return [=] { return l().getValue() && r().getValue(); };
+ if (op == "&")
+ return [=] { return bitAnd(l(), r()); };
+ if (op == "|")
+ return [=] { return bitOr(l(), r()); };
llvm_unreachable("invalid operator");
}
// This is a part of the operator-precedence parser. This function
// assumes that the remaining token stream starts with an operator.
-Expr ScriptParser::readExpr1(Expr Lhs, int MinPrec) {
+Expr ScriptParser::readExpr1(Expr lhs, int minPrec) {
while (!atEOF() && !errorCount()) {
// Read an operator and an expression.
if (consume("?"))
- return readTernary(Lhs);
- StringRef Op1 = peek();
- if (precedence(Op1) < MinPrec)
+ return readTernary(lhs);
+ StringRef op1 = peek();
+ if (precedence(op1) < minPrec)
break;
skip();
- Expr Rhs = readPrimary();
+ Expr rhs = readPrimary();
// Evaluate the remaining part of the expression first if the
// next operator has greater precedence than the previous one.
// For example, if we have read "+" and "3", and if the next
// operator is "*", then we'll evaluate 3 * ... part first.
while (!atEOF()) {
- StringRef Op2 = peek();
- if (precedence(Op2) <= precedence(Op1))
+ StringRef op2 = peek();
+ if (precedence(op2) <= precedence(op1))
break;
- Rhs = readExpr1(Rhs, precedence(Op2));
+ rhs = readExpr1(rhs, precedence(op2));
}
- Lhs = combine(Op1, Lhs, Rhs);
+ lhs = combine(op1, lhs, rhs);
}
- return Lhs;
+ return lhs;
}
Expr ScriptParser::getPageSize() {
- std::string Location = getCurrentLocation();
+ std::string location = getCurrentLocation();
return [=]() -> uint64_t {
- if (Target)
- return Config->CommonPageSize;
- error(Location + ": unable to calculate page size");
+ if (target)
+ return config->commonPageSize;
+ error(location + ": unable to calculate page size");
return 4096; // Return a dummy value.
};
}
Expr ScriptParser::readConstant() {
- StringRef S = readParenLiteral();
- if (S == "COMMONPAGESIZE")
+ StringRef s = readParenLiteral();
+ if (s == "COMMONPAGESIZE")
return getPageSize();
- if (S == "MAXPAGESIZE")
- return [] { return Config->MaxPageSize; };
- setError("unknown constant: " + S);
+ if (s == "MAXPAGESIZE")
+ return [] { return config->maxPageSize; };
+ setError("unknown constant: " + s);
return [] { return 0; };
}
// Parses Tok as an integer. It recognizes hexadecimal (prefixed with
// "0x" or suffixed with "H") and decimal numbers. Decimal numbers may
// have "K" (Ki) or "M" (Mi) suffixes.
-static Optional<uint64_t> parseInt(StringRef Tok) {
+static Optional<uint64_t> parseInt(StringRef tok) {
// Hexadecimal
- uint64_t Val;
- if (Tok.startswith_lower("0x")) {
- if (!to_integer(Tok.substr(2), Val, 16))
+ uint64_t val;
+ if (tok.startswith_lower("0x")) {
+ if (!to_integer(tok.substr(2), val, 16))
return None;
- return Val;
+ return val;
}
- if (Tok.endswith_lower("H")) {
- if (!to_integer(Tok.drop_back(), Val, 16))
+ if (tok.endswith_lower("H")) {
+ if (!to_integer(tok.drop_back(), val, 16))
return None;
- return Val;
+ return val;
}
// Decimal
- if (Tok.endswith_lower("K")) {
- if (!to_integer(Tok.drop_back(), Val, 10))
+ if (tok.endswith_lower("K")) {
+ if (!to_integer(tok.drop_back(), val, 10))
return None;
- return Val * 1024;
+ return val * 1024;
}
- if (Tok.endswith_lower("M")) {
- if (!to_integer(Tok.drop_back(), Val, 10))
+ if (tok.endswith_lower("M")) {
+ if (!to_integer(tok.drop_back(), val, 10))
return None;
- return Val * 1024 * 1024;
+ return val * 1024 * 1024;
}
- if (!to_integer(Tok, Val, 10))
+ if (!to_integer(tok, val, 10))
return None;
- return Val;
+ return val;
}
-ByteCommand *ScriptParser::readByteCommand(StringRef Tok) {
- int Size = StringSwitch<int>(Tok)
+ByteCommand *ScriptParser::readByteCommand(StringRef tok) {
+ int size = StringSwitch<int>(tok)
.Case("BYTE", 1)
.Case("SHORT", 2)
.Case("LONG", 4)
.Case("QUAD", 8)
.Default(-1);
- if (Size == -1)
+ if (size == -1)
return nullptr;
- size_t OldPos = Pos;
- Expr E = readParenExpr();
- std::string CommandString =
- Tok.str() + " " +
- llvm::join(Tokens.begin() + OldPos, Tokens.begin() + Pos, " ");
- return make<ByteCommand>(E, Size, CommandString);
+ size_t oldPos = pos;
+ Expr e = readParenExpr();
+ std::string commandString =
+ tok.str() + " " +
+ llvm::join(tokens.begin() + oldPos, tokens.begin() + pos, " ");
+ return make<ByteCommand>(e, size, commandString);
}
StringRef ScriptParser::readParenLiteral() {
expect("(");
- bool Orig = InExpr;
- InExpr = false;
- StringRef Tok = next();
- InExpr = Orig;
+ bool orig = inExpr;
+ inExpr = false;
+ StringRef tok = next();
+ inExpr = orig;
expect(")");
- return Tok;
+ return tok;
}
-static void checkIfExists(OutputSection *Cmd, StringRef Location) {
- if (Cmd->Location.empty() && Script->ErrorOnMissingSection)
- error(Location + ": undefined section " + Cmd->Name);
+static void checkIfExists(OutputSection *cmd, StringRef location) {
+ if (cmd->location.empty() && script->errorOnMissingSection)
+ error(location + ": undefined section " + cmd->name);
}
Expr ScriptParser::readPrimary() {
@@ -1120,85 +1120,85 @@ Expr ScriptParser::readPrimary() {
return readParenExpr();
if (consume("~")) {
- Expr E = readPrimary();
- return [=] { return ~E().getValue(); };
+ Expr e = readPrimary();
+ return [=] { return ~e().getValue(); };
}
if (consume("!")) {
- Expr E = readPrimary();
- return [=] { return !E().getValue(); };
+ Expr e = readPrimary();
+ return [=] { return !e().getValue(); };
}
if (consume("-")) {
- Expr E = readPrimary();
- return [=] { return -E().getValue(); };
+ Expr e = readPrimary();
+ return [=] { return -e().getValue(); };
}
- StringRef Tok = next();
- std::string Location = getCurrentLocation();
+ StringRef tok = next();
+ std::string location = getCurrentLocation();
// Built-in functions are parsed here.
// https://sourceware.org/binutils/docs/ld/Builtin-Functions.html.
- if (Tok == "ABSOLUTE") {
- Expr Inner = readParenExpr();
+ if (tok == "ABSOLUTE") {
+ Expr inner = readParenExpr();
return [=] {
- ExprValue I = Inner();
- I.ForceAbsolute = true;
- return I;
+ ExprValue i = inner();
+ i.forceAbsolute = true;
+ return i;
};
}
- if (Tok == "ADDR") {
- StringRef Name = readParenLiteral();
- OutputSection *Sec = Script->getOrCreateOutputSection(Name);
- Sec->UsedInExpression = true;
+ if (tok == "ADDR") {
+ StringRef name = readParenLiteral();
+ OutputSection *sec = script->getOrCreateOutputSection(name);
+ sec->usedInExpression = true;
return [=]() -> ExprValue {
- checkIfExists(Sec, Location);
- return {Sec, false, 0, Location};
+ checkIfExists(sec, location);
+ return {sec, false, 0, location};
};
}
- if (Tok == "ALIGN") {
+ if (tok == "ALIGN") {
expect("(");
- Expr E = readExpr();
+ Expr e = readExpr();
if (consume(")")) {
- E = checkAlignment(E, Location);
- return [=] { return alignTo(Script->getDot(), E().getValue()); };
+ e = checkAlignment(e, location);
+ return [=] { return alignTo(script->getDot(), e().getValue()); };
}
expect(",");
- Expr E2 = checkAlignment(readExpr(), Location);
+ Expr e2 = checkAlignment(readExpr(), location);
expect(")");
return [=] {
- ExprValue V = E();
- V.Alignment = E2().getValue();
- return V;
+ ExprValue v = e();
+ v.alignment = e2().getValue();
+ return v;
};
}
- if (Tok == "ALIGNOF") {
- StringRef Name = readParenLiteral();
- OutputSection *Cmd = Script->getOrCreateOutputSection(Name);
+ if (tok == "ALIGNOF") {
+ StringRef name = readParenLiteral();
+ OutputSection *cmd = script->getOrCreateOutputSection(name);
return [=] {
- checkIfExists(Cmd, Location);
- return Cmd->Alignment;
+ checkIfExists(cmd, location);
+ return cmd->alignment;
};
}
- if (Tok == "ASSERT")
+ if (tok == "ASSERT")
return readAssert();
- if (Tok == "CONSTANT")
+ if (tok == "CONSTANT")
return readConstant();
- if (Tok == "DATA_SEGMENT_ALIGN") {
+ if (tok == "DATA_SEGMENT_ALIGN") {
expect("(");
- Expr E = readExpr();
+ Expr e = readExpr();
expect(",");
readExpr();
expect(")");
return [=] {
- return alignTo(Script->getDot(), std::max((uint64_t)1, E().getValue()));
+ return alignTo(script->getDot(), std::max((uint64_t)1, e().getValue()));
};
}
- if (Tok == "DATA_SEGMENT_END") {
+ if (tok == "DATA_SEGMENT_END") {
expect("(");
expect(".");
expect(")");
- return [] { return Script->getDot(); };
+ return [] { return script->getDot(); };
}
- if (Tok == "DATA_SEGMENT_RELRO_END") {
+ if (tok == "DATA_SEGMENT_RELRO_END") {
// GNU linkers implements more complicated logic to handle
// DATA_SEGMENT_RELRO_END. We instead ignore the arguments and
// just align to the next page boundary for simplicity.
@@ -1207,113 +1207,113 @@ Expr ScriptParser::readPrimary() {
expect(",");
readExpr();
expect(")");
- Expr E = getPageSize();
- return [=] { return alignTo(Script->getDot(), E().getValue()); };
+ Expr e = getPageSize();
+ return [=] { return alignTo(script->getDot(), e().getValue()); };
}
- if (Tok == "DEFINED") {
- StringRef Name = readParenLiteral();
- return [=] { return Symtab->find(Name) ? 1 : 0; };
- }
- if (Tok == "LENGTH") {
- StringRef Name = readParenLiteral();
- if (Script->MemoryRegions.count(Name) == 0) {
- setError("memory region not defined: " + Name);
+ if (tok == "DEFINED") {
+ StringRef name = readParenLiteral();
+ return [=] { return symtab->find(name) ? 1 : 0; };
+ }
+ if (tok == "LENGTH") {
+ StringRef name = readParenLiteral();
+ if (script->memoryRegions.count(name) == 0) {
+ setError("memory region not defined: " + name);
return [] { return 0; };
}
- return [=] { return Script->MemoryRegions[Name]->Length; };
+ return [=] { return script->memoryRegions[name]->length; };
}
- if (Tok == "LOADADDR") {
- StringRef Name = readParenLiteral();
- OutputSection *Cmd = Script->getOrCreateOutputSection(Name);
- Cmd->UsedInExpression = true;
+ if (tok == "LOADADDR") {
+ StringRef name = readParenLiteral();
+ OutputSection *cmd = script->getOrCreateOutputSection(name);
+ cmd->usedInExpression = true;
return [=] {
- checkIfExists(Cmd, Location);
- return Cmd->getLMA();
+ checkIfExists(cmd, location);
+ return cmd->getLMA();
};
}
- if (Tok == "MAX" || Tok == "MIN") {
+ if (tok == "MAX" || tok == "MIN") {
expect("(");
- Expr A = readExpr();
+ Expr a = readExpr();
expect(",");
- Expr B = readExpr();
+ Expr b = readExpr();
expect(")");
- if (Tok == "MIN")
- return [=] { return std::min(A().getValue(), B().getValue()); };
- return [=] { return std::max(A().getValue(), B().getValue()); };
- }
- if (Tok == "ORIGIN") {
- StringRef Name = readParenLiteral();
- if (Script->MemoryRegions.count(Name) == 0) {
- setError("memory region not defined: " + Name);
+ if (tok == "MIN")
+ return [=] { return std::min(a().getValue(), b().getValue()); };
+ return [=] { return std::max(a().getValue(), b().getValue()); };
+ }
+ if (tok == "ORIGIN") {
+ StringRef name = readParenLiteral();
+ if (script->memoryRegions.count(name) == 0) {
+ setError("memory region not defined: " + name);
return [] { return 0; };
}
- return [=] { return Script->MemoryRegions[Name]->Origin; };
+ return [=] { return script->memoryRegions[name]->origin; };
}
- if (Tok == "SEGMENT_START") {
+ if (tok == "SEGMENT_START") {
expect("(");
skip();
expect(",");
- Expr E = readExpr();
+ Expr e = readExpr();
expect(")");
- return [=] { return E(); };
+ return [=] { return e(); };
}
- if (Tok == "SIZEOF") {
- StringRef Name = readParenLiteral();
- OutputSection *Cmd = Script->getOrCreateOutputSection(Name);
+ if (tok == "SIZEOF") {
+ StringRef name = readParenLiteral();
+ OutputSection *cmd = script->getOrCreateOutputSection(name);
// Linker script does not create an output section if its content is empty.
// We want to allow SIZEOF(.foo) where .foo is a section which happened to
// be empty.
- return [=] { return Cmd->Size; };
+ return [=] { return cmd->size; };
}
- if (Tok == "SIZEOF_HEADERS")
+ if (tok == "SIZEOF_HEADERS")
return [=] { return elf::getHeaderSize(); };
// Tok is the dot.
- if (Tok == ".")
- return [=] { return Script->getSymbolValue(Tok, Location); };
+ if (tok == ".")
+ return [=] { return script->getSymbolValue(tok, location); };
// Tok is a literal number.
- if (Optional<uint64_t> Val = parseInt(Tok))
- return [=] { return *Val; };
+ if (Optional<uint64_t> val = parseInt(tok))
+ return [=] { return *val; };
// Tok is a symbol name.
- if (!isValidCIdentifier(Tok))
- setError("malformed number: " + Tok);
- Script->ReferencedSymbols.push_back(Tok);
- return [=] { return Script->getSymbolValue(Tok, Location); };
+ if (!isValidCIdentifier(tok))
+ setError("malformed number: " + tok);
+ script->referencedSymbols.push_back(tok);
+ return [=] { return script->getSymbolValue(tok, location); };
}
-Expr ScriptParser::readTernary(Expr Cond) {
- Expr L = readExpr();
+Expr ScriptParser::readTernary(Expr cond) {
+ Expr l = readExpr();
expect(":");
- Expr R = readExpr();
- return [=] { return Cond().getValue() ? L() : R(); };
+ Expr r = readExpr();
+ return [=] { return cond().getValue() ? l() : r(); };
}
Expr ScriptParser::readParenExpr() {
expect("(");
- Expr E = readExpr();
+ Expr e = readExpr();
expect(")");
- return E;
+ return e;
}
std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() {
- std::vector<StringRef> Phdrs;
+ std::vector<StringRef> phdrs;
while (!errorCount() && peek().startswith(":")) {
- StringRef Tok = next();
- Phdrs.push_back((Tok.size() == 1) ? next() : Tok.substr(1));
+ StringRef tok = next();
+ phdrs.push_back((tok.size() == 1) ? next() : tok.substr(1));
}
- return Phdrs;
+ return phdrs;
}
// Read a program header type name. The next token must be a
// name of a program header type or a constant (e.g. "0x3").
unsigned ScriptParser::readPhdrType() {
- StringRef Tok = next();
- if (Optional<uint64_t> Val = parseInt(Tok))
- return *Val;
+ StringRef tok = next();
+ if (Optional<uint64_t> val = parseInt(tok))
+ return *val;
- unsigned Ret = StringSwitch<unsigned>(Tok)
+ unsigned ret = StringSwitch<unsigned>(tok)
.Case("PT_NULL", PT_NULL)
.Case("PT_LOAD", PT_LOAD)
.Case("PT_DYNAMIC", PT_DYNAMIC)
@@ -1330,56 +1330,56 @@ unsigned ScriptParser::readPhdrType() {
.Case("PT_OPENBSD_BOOTDATA", PT_OPENBSD_BOOTDATA)
.Default(-1);
- if (Ret == (unsigned)-1) {
- setError("invalid program header type: " + Tok);
+ if (ret == (unsigned)-1) {
+ setError("invalid program header type: " + tok);
return PT_NULL;
}
- return Ret;
+ return ret;
}
// Reads an anonymous version declaration.
void ScriptParser::readAnonymousDeclaration() {
- std::vector<SymbolVersion> Locals;
- std::vector<SymbolVersion> Globals;
- std::tie(Locals, Globals) = readSymbols();
-
- for (SymbolVersion V : Locals) {
- if (V.Name == "*")
- Config->DefaultSymbolVersion = VER_NDX_LOCAL;
+ std::vector<SymbolVersion> locals;
+ std::vector<SymbolVersion> globals;
+ std::tie(locals, globals) = readSymbols();
+
+ for (SymbolVersion v : locals) {
+ if (v.name == "*")
+ config->defaultSymbolVersion = VER_NDX_LOCAL;
else
- Config->VersionScriptLocals.push_back(V);
+ config->versionScriptLocals.push_back(v);
}
- for (SymbolVersion V : Globals)
- Config->VersionScriptGlobals.push_back(V);
+ for (SymbolVersion v : globals)
+ config->versionScriptGlobals.push_back(v);
expect(";");
}
// Reads a non-anonymous version definition,
// e.g. "VerStr { global: foo; bar; local: *; };".
-void ScriptParser::readVersionDeclaration(StringRef VerStr) {
+void ScriptParser::readVersionDeclaration(StringRef verStr) {
// Read a symbol list.
- std::vector<SymbolVersion> Locals;
- std::vector<SymbolVersion> Globals;
- std::tie(Locals, Globals) = readSymbols();
-
- for (SymbolVersion V : Locals) {
- if (V.Name == "*")
- Config->DefaultSymbolVersion = VER_NDX_LOCAL;
+ std::vector<SymbolVersion> locals;
+ std::vector<SymbolVersion> globals;
+ std::tie(locals, globals) = readSymbols();
+
+ for (SymbolVersion v : locals) {
+ if (v.name == "*")
+ config->defaultSymbolVersion = VER_NDX_LOCAL;
else
- Config->VersionScriptLocals.push_back(V);
+ config->versionScriptLocals.push_back(v);
}
// Create a new version definition and add that to the global symbols.
- VersionDefinition Ver;
- Ver.Name = VerStr;
- Ver.Globals = Globals;
+ VersionDefinition ver;
+ ver.name = verStr;
+ ver.globals = globals;
// User-defined version number starts from 2 because 0 and 1 are
// reserved for VER_NDX_LOCAL and VER_NDX_GLOBAL, respectively.
- Ver.Id = Config->VersionDefinitions.size() + 2;
- Config->VersionDefinitions.push_back(Ver);
+ ver.id = config->versionDefinitions.size() + 2;
+ config->versionDefinitions.push_back(ver);
// Each version may have a parent version. For example, "Ver2"
// defined as "Ver2 { global: foo; local: *; } Ver1;" has "Ver1"
@@ -1391,39 +1391,39 @@ void ScriptParser::readVersionDeclaratio
expect(";");
}
-static bool hasWildcard(StringRef S) {
- return S.find_first_of("?*[") != StringRef::npos;
+static bool hasWildcard(StringRef s) {
+ return s.find_first_of("?*[") != StringRef::npos;
}
// Reads a list of symbols, e.g. "{ global: foo; bar; local: *; };".
std::pair<std::vector<SymbolVersion>, std::vector<SymbolVersion>>
ScriptParser::readSymbols() {
- std::vector<SymbolVersion> Locals;
- std::vector<SymbolVersion> Globals;
- std::vector<SymbolVersion> *V = &Globals;
+ std::vector<SymbolVersion> locals;
+ std::vector<SymbolVersion> globals;
+ std::vector<SymbolVersion> *v = &globals;
while (!errorCount()) {
if (consume("}"))
break;
if (consumeLabel("local")) {
- V = &Locals;
+ v = &locals;
continue;
}
if (consumeLabel("global")) {
- V = &Globals;
+ v = &globals;
continue;
}
if (consume("extern")) {
- std::vector<SymbolVersion> Ext = readVersionExtern();
- V->insert(V->end(), Ext.begin(), Ext.end());
+ std::vector<SymbolVersion> ext = readVersionExtern();
+ v->insert(v->end(), ext.begin(), ext.end());
} else {
- StringRef Tok = next();
- V->push_back({unquote(Tok), false, hasWildcard(Tok)});
+ StringRef tok = next();
+ v->push_back({unquote(tok), false, hasWildcard(tok)});
}
expect(";");
}
- return {Locals, Globals};
+ return {locals, globals};
}
// Reads an "extern C++" directive, e.g.,
@@ -1432,30 +1432,30 @@ ScriptParser::readSymbols() {
// The last semicolon is optional. E.g. this is OK:
// "extern "C++" { ns::*; "f(int, double)" };"
std::vector<SymbolVersion> ScriptParser::readVersionExtern() {
- StringRef Tok = next();
- bool IsCXX = Tok == "\"C++\"";
- if (!IsCXX && Tok != "\"C\"")
+ StringRef tok = next();
+ bool isCXX = tok == "\"C++\"";
+ if (!isCXX && tok != "\"C\"")
setError("Unknown language");
expect("{");
- std::vector<SymbolVersion> Ret;
+ std::vector<SymbolVersion> ret;
while (!errorCount() && peek() != "}") {
- StringRef Tok = next();
- Ret.push_back(
- {unquote(Tok), IsCXX, !Tok.startswith("\"") && hasWildcard(Tok)});
+ StringRef tok = next();
+ ret.push_back(
+ {unquote(tok), isCXX, !tok.startswith("\"") && hasWildcard(tok)});
if (consume("}"))
- return Ret;
+ return ret;
expect(";");
}
expect("}");
- return Ret;
+ return ret;
}
-uint64_t ScriptParser::readMemoryAssignment(StringRef S1, StringRef S2,
- StringRef S3) {
- if (!consume(S1) && !consume(S2) && !consume(S3)) {
- setError("expected one of: " + S1 + ", " + S2 + ", or " + S3);
+uint64_t ScriptParser::readMemoryAssignment(StringRef s1, StringRef s2,
+ StringRef s3) {
+ if (!consume(s1) && !consume(s2) && !consume(s3)) {
+ setError("expected one of: " + s1 + ", " + s2 + ", or " + s3);
return 0;
}
expect("=");
@@ -1469,28 +1469,28 @@ uint64_t ScriptParser::readMemoryAssignm
void ScriptParser::readMemory() {
expect("{");
while (!errorCount() && !consume("}")) {
- StringRef Tok = next();
- if (Tok == "INCLUDE") {
+ StringRef tok = next();
+ if (tok == "INCLUDE") {
readInclude();
continue;
}
- uint32_t Flags = 0;
- uint32_t NegFlags = 0;
+ uint32_t flags = 0;
+ uint32_t negFlags = 0;
if (consume("(")) {
- std::tie(Flags, NegFlags) = readMemoryAttributes();
+ std::tie(flags, negFlags) = readMemoryAttributes();
expect(")");
}
expect(":");
- uint64_t Origin = readMemoryAssignment("ORIGIN", "org", "o");
+ uint64_t origin = readMemoryAssignment("ORIGIN", "org", "o");
expect(",");
- uint64_t Length = readMemoryAssignment("LENGTH", "len", "l");
+ uint64_t length = readMemoryAssignment("LENGTH", "len", "l");
// Add the memory region to the region map.
- MemoryRegion *MR = make<MemoryRegion>(Tok, Origin, Length, Flags, NegFlags);
- if (!Script->MemoryRegions.insert({Tok, MR}).second)
- setError("region '" + Tok + "' already defined");
+ MemoryRegion *mr = make<MemoryRegion>(tok, origin, length, flags, negFlags);
+ if (!script->memoryRegions.insert({tok, mr}).second)
+ setError("region '" + tok + "' already defined");
}
}
@@ -1498,43 +1498,43 @@ void ScriptParser::readMemory() {
// flags when placing output sections in a memory region. These flags
// are only used when an explicit memory region name is not used.
std::pair<uint32_t, uint32_t> ScriptParser::readMemoryAttributes() {
- uint32_t Flags = 0;
- uint32_t NegFlags = 0;
- bool Invert = false;
-
- for (char C : next().lower()) {
- uint32_t Flag = 0;
- if (C == '!')
- Invert = !Invert;
- else if (C == 'w')
- Flag = SHF_WRITE;
- else if (C == 'x')
- Flag = SHF_EXECINSTR;
- else if (C == 'a')
- Flag = SHF_ALLOC;
- else if (C != 'r')
+ uint32_t flags = 0;
+ uint32_t negFlags = 0;
+ bool invert = false;
+
+ for (char c : next().lower()) {
+ uint32_t flag = 0;
+ if (c == '!')
+ invert = !invert;
+ else if (c == 'w')
+ flag = SHF_WRITE;
+ else if (c == 'x')
+ flag = SHF_EXECINSTR;
+ else if (c == 'a')
+ flag = SHF_ALLOC;
+ else if (c != 'r')
setError("invalid memory region attribute");
- if (Invert)
- NegFlags |= Flag;
+ if (invert)
+ negFlags |= flag;
else
- Flags |= Flag;
+ flags |= flag;
}
- return {Flags, NegFlags};
+ return {flags, negFlags};
}
-void elf::readLinkerScript(MemoryBufferRef MB) {
- ScriptParser(MB).readLinkerScript();
+void elf::readLinkerScript(MemoryBufferRef mb) {
+ ScriptParser(mb).readLinkerScript();
}
-void elf::readVersionScript(MemoryBufferRef MB) {
- ScriptParser(MB).readVersionScript();
+void elf::readVersionScript(MemoryBufferRef mb) {
+ ScriptParser(mb).readVersionScript();
}
-void elf::readDynamicList(MemoryBufferRef MB) {
- ScriptParser(MB).readDynamicList();
+void elf::readDynamicList(MemoryBufferRef mb) {
+ ScriptParser(mb).readDynamicList();
}
-void elf::readDefsym(StringRef Name, MemoryBufferRef MB) {
- ScriptParser(MB).readDefsym(Name);
+void elf::readDefsym(StringRef name, MemoryBufferRef mb) {
+ ScriptParser(mb).readDefsym(name);
}
Modified: lld/trunk/ELF/ScriptParser.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/ScriptParser.h?rev=365595&r1=365594&r2=365595&view=diff
==============================================================================
--- lld/trunk/ELF/ScriptParser.h (original)
+++ lld/trunk/ELF/ScriptParser.h Tue Jul 9 22:00:37 2019
@@ -17,15 +17,15 @@ namespace elf {
// Parses a linker script. Calling this function updates
// Config and ScriptConfig.
-void readLinkerScript(MemoryBufferRef MB);
+void readLinkerScript(MemoryBufferRef mb);
// Parses a version script.
-void readVersionScript(MemoryBufferRef MB);
+void readVersionScript(MemoryBufferRef mb);
-void readDynamicList(MemoryBufferRef MB);
+void readDynamicList(MemoryBufferRef mb);
// Parses the defsym expression.
-void readDefsym(StringRef Name, MemoryBufferRef MB);
+void readDefsym(StringRef name, MemoryBufferRef mb);
} // namespace elf
} // namespace lld
Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=365595&r1=365594&r2=365595&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Tue Jul 9 22:00:37 2019
@@ -30,73 +30,73 @@ using namespace llvm::ELF;
using namespace lld;
using namespace lld::elf;
-SymbolTable *elf::Symtab;
+SymbolTable *elf::symtab;
-void SymbolTable::wrap(Symbol *Sym, Symbol *Real, Symbol *Wrap) {
+void SymbolTable::wrap(Symbol *sym, Symbol *real, Symbol *wrap) {
// Swap symbols as instructed by -wrap.
- int &Idx1 = SymMap[CachedHashStringRef(Sym->getName())];
- int &Idx2 = SymMap[CachedHashStringRef(Real->getName())];
- int &Idx3 = SymMap[CachedHashStringRef(Wrap->getName())];
+ int &idx1 = symMap[CachedHashStringRef(sym->getName())];
+ int &idx2 = symMap[CachedHashStringRef(real->getName())];
+ int &idx3 = symMap[CachedHashStringRef(wrap->getName())];
- Idx2 = Idx1;
- Idx1 = Idx3;
+ idx2 = idx1;
+ idx1 = idx3;
// Now renaming is complete. No one refers Real symbol. We could leave
// Real as-is, but if Real is written to the symbol table, that may
// contain irrelevant values. So, we copy all values from Sym to Real.
- StringRef S = Real->getName();
- memcpy(Real, Sym, sizeof(SymbolUnion));
- Real->setName(S);
+ StringRef s = real->getName();
+ memcpy(real, sym, sizeof(SymbolUnion));
+ real->setName(s);
}
// Find an existing symbol or create a new one.
-Symbol *SymbolTable::insert(StringRef Name) {
+Symbol *SymbolTable::insert(StringRef name) {
// <name>@@<version> means the symbol is the default version. In that
// case <name>@@<version> will be used to resolve references to <name>.
//
// Since this is a hot path, the following string search code is
// optimized for speed. StringRef::find(char) is much faster than
// StringRef::find(StringRef).
- size_t Pos = Name.find('@');
- if (Pos != StringRef::npos && Pos + 1 < Name.size() && Name[Pos + 1] == '@')
- Name = Name.take_front(Pos);
-
- auto P = SymMap.insert({CachedHashStringRef(Name), (int)SymVector.size()});
- int &SymIndex = P.first->second;
- bool IsNew = P.second;
-
- if (!IsNew)
- return SymVector[SymIndex];
-
- Symbol *Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
- SymVector.push_back(Sym);
-
- Sym->setName(Name);
- Sym->SymbolKind = Symbol::PlaceholderKind;
- Sym->VersionId = Config->DefaultSymbolVersion;
- Sym->Visibility = STV_DEFAULT;
- Sym->IsUsedInRegularObj = false;
- Sym->ExportDynamic = false;
- Sym->CanInline = true;
- Sym->ScriptDefined = false;
- Sym->Partition = 1;
- return Sym;
+ size_t pos = name.find('@');
+ if (pos != StringRef::npos && pos + 1 < name.size() && name[pos + 1] == '@')
+ name = name.take_front(pos);
+
+ auto p = symMap.insert({CachedHashStringRef(name), (int)symVector.size()});
+ int &symIndex = p.first->second;
+ bool isNew = p.second;
+
+ if (!isNew)
+ return symVector[symIndex];
+
+ Symbol *sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
+ symVector.push_back(sym);
+
+ sym->setName(name);
+ sym->symbolKind = Symbol::PlaceholderKind;
+ sym->versionId = config->defaultSymbolVersion;
+ sym->visibility = STV_DEFAULT;
+ sym->isUsedInRegularObj = false;
+ sym->exportDynamic = false;
+ sym->canInline = true;
+ sym->scriptDefined = false;
+ sym->partition = 1;
+ return sym;
}
Symbol *SymbolTable::addSymbol(const Symbol &New) {
- Symbol *Sym = Symtab->insert(New.getName());
- Sym->resolve(New);
- return Sym;
+ Symbol *sym = symtab->insert(New.getName());
+ sym->resolve(New);
+ return sym;
}
-Symbol *SymbolTable::find(StringRef Name) {
- auto It = SymMap.find(CachedHashStringRef(Name));
- if (It == SymMap.end())
+Symbol *SymbolTable::find(StringRef name) {
+ auto it = symMap.find(CachedHashStringRef(name));
+ if (it == symMap.end())
return nullptr;
- Symbol *Sym = SymVector[It->second];
- if (Sym->isPlaceholder())
+ Symbol *sym = symVector[it->second];
+ if (sym->isPlaceholder())
return nullptr;
- return Sym;
+ return sym;
}
// Initialize DemangledSyms with a map from demangled symbols to symbol
@@ -113,119 +113,119 @@ Symbol *SymbolTable::find(StringRef Name
// So, if "extern C++" feature is used, we need to demangle all known
// symbols.
StringMap<std::vector<Symbol *>> &SymbolTable::getDemangledSyms() {
- if (!DemangledSyms) {
- DemangledSyms.emplace();
- for (Symbol *Sym : SymVector) {
- if (!Sym->isDefined() && !Sym->isCommon())
+ if (!demangledSyms) {
+ demangledSyms.emplace();
+ for (Symbol *sym : symVector) {
+ if (!sym->isDefined() && !sym->isCommon())
continue;
- if (Optional<std::string> S = demangleItanium(Sym->getName()))
- (*DemangledSyms)[*S].push_back(Sym);
+ if (Optional<std::string> s = demangleItanium(sym->getName()))
+ (*demangledSyms)[*s].push_back(sym);
else
- (*DemangledSyms)[Sym->getName()].push_back(Sym);
+ (*demangledSyms)[sym->getName()].push_back(sym);
}
}
- return *DemangledSyms;
+ return *demangledSyms;
}
-std::vector<Symbol *> SymbolTable::findByVersion(SymbolVersion Ver) {
- if (Ver.IsExternCpp)
- return getDemangledSyms().lookup(Ver.Name);
- if (Symbol *B = find(Ver.Name))
- if (B->isDefined() || B->isCommon())
- return {B};
+std::vector<Symbol *> SymbolTable::findByVersion(SymbolVersion ver) {
+ if (ver.isExternCpp)
+ return getDemangledSyms().lookup(ver.name);
+ if (Symbol *b = find(ver.name))
+ if (b->isDefined() || b->isCommon())
+ return {b};
return {};
}
-std::vector<Symbol *> SymbolTable::findAllByVersion(SymbolVersion Ver) {
- std::vector<Symbol *> Res;
- StringMatcher M(Ver.Name);
-
- if (Ver.IsExternCpp) {
- for (auto &P : getDemangledSyms())
- if (M.match(P.first()))
- Res.insert(Res.end(), P.second.begin(), P.second.end());
- return Res;
+std::vector<Symbol *> SymbolTable::findAllByVersion(SymbolVersion ver) {
+ std::vector<Symbol *> res;
+ StringMatcher m(ver.name);
+
+ if (ver.isExternCpp) {
+ for (auto &p : getDemangledSyms())
+ if (m.match(p.first()))
+ res.insert(res.end(), p.second.begin(), p.second.end());
+ return res;
}
- for (Symbol *Sym : SymVector)
- if ((Sym->isDefined() || Sym->isCommon()) && M.match(Sym->getName()))
- Res.push_back(Sym);
- return Res;
+ for (Symbol *sym : symVector)
+ if ((sym->isDefined() || sym->isCommon()) && m.match(sym->getName()))
+ res.push_back(sym);
+ return res;
}
// If there's only one anonymous version definition in a version
// script file, the script does not actually define any symbol version,
// but just specifies symbols visibilities.
void SymbolTable::handleAnonymousVersion() {
- for (SymbolVersion &Ver : Config->VersionScriptGlobals)
- assignExactVersion(Ver, VER_NDX_GLOBAL, "global");
- for (SymbolVersion &Ver : Config->VersionScriptGlobals)
- assignWildcardVersion(Ver, VER_NDX_GLOBAL);
- for (SymbolVersion &Ver : Config->VersionScriptLocals)
- assignExactVersion(Ver, VER_NDX_LOCAL, "local");
- for (SymbolVersion &Ver : Config->VersionScriptLocals)
- assignWildcardVersion(Ver, VER_NDX_LOCAL);
+ for (SymbolVersion &ver : config->versionScriptGlobals)
+ assignExactVersion(ver, VER_NDX_GLOBAL, "global");
+ for (SymbolVersion &ver : config->versionScriptGlobals)
+ assignWildcardVersion(ver, VER_NDX_GLOBAL);
+ for (SymbolVersion &ver : config->versionScriptLocals)
+ assignExactVersion(ver, VER_NDX_LOCAL, "local");
+ for (SymbolVersion &ver : config->versionScriptLocals)
+ assignWildcardVersion(ver, VER_NDX_LOCAL);
}
// Handles -dynamic-list.
void SymbolTable::handleDynamicList() {
- for (SymbolVersion &Ver : Config->DynamicList) {
- std::vector<Symbol *> Syms;
- if (Ver.HasWildcard)
- Syms = findAllByVersion(Ver);
+ for (SymbolVersion &ver : config->dynamicList) {
+ std::vector<Symbol *> syms;
+ if (ver.hasWildcard)
+ syms = findAllByVersion(ver);
else
- Syms = findByVersion(Ver);
+ syms = findByVersion(ver);
- for (Symbol *B : Syms) {
- if (!Config->Shared)
- B->ExportDynamic = true;
- else if (B->includeInDynsym())
- B->IsPreemptible = true;
+ for (Symbol *b : syms) {
+ if (!config->shared)
+ b->exportDynamic = true;
+ else if (b->includeInDynsym())
+ b->isPreemptible = true;
}
}
}
// Set symbol versions to symbols. This function handles patterns
// containing no wildcard characters.
-void SymbolTable::assignExactVersion(SymbolVersion Ver, uint16_t VersionId,
- StringRef VersionName) {
- if (Ver.HasWildcard)
+void SymbolTable::assignExactVersion(SymbolVersion ver, uint16_t versionId,
+ StringRef versionName) {
+ if (ver.hasWildcard)
return;
// Get a list of symbols which we need to assign the version to.
- std::vector<Symbol *> Syms = findByVersion(Ver);
- if (Syms.empty()) {
- if (!Config->UndefinedVersion)
- error("version script assignment of '" + VersionName + "' to symbol '" +
- Ver.Name + "' failed: symbol not defined");
+ std::vector<Symbol *> syms = findByVersion(ver);
+ if (syms.empty()) {
+ if (!config->undefinedVersion)
+ error("version script assignment of '" + versionName + "' to symbol '" +
+ ver.name + "' failed: symbol not defined");
return;
}
// Assign the version.
- for (Symbol *Sym : Syms) {
+ for (Symbol *sym : syms) {
// Skip symbols containing version info because symbol versions
// specified by symbol names take precedence over version scripts.
// See parseSymbolVersion().
- if (Sym->getName().contains('@'))
+ if (sym->getName().contains('@'))
continue;
- if (Sym->VersionId != Config->DefaultSymbolVersion &&
- Sym->VersionId != VersionId)
- error("duplicate symbol '" + Ver.Name + "' in version script");
- Sym->VersionId = VersionId;
+ if (sym->versionId != config->defaultSymbolVersion &&
+ sym->versionId != versionId)
+ error("duplicate symbol '" + ver.name + "' in version script");
+ sym->versionId = versionId;
}
}
-void SymbolTable::assignWildcardVersion(SymbolVersion Ver, uint16_t VersionId) {
- if (!Ver.HasWildcard)
+void SymbolTable::assignWildcardVersion(SymbolVersion ver, uint16_t versionId) {
+ if (!ver.hasWildcard)
return;
// Exact matching takes precendence over fuzzy matching,
// so we set a version to a symbol only if no version has been assigned
// to the symbol. This behavior is compatible with GNU.
- for (Symbol *B : findAllByVersion(Ver))
- if (B->VersionId == Config->DefaultSymbolVersion)
- B->VersionId = VersionId;
+ for (Symbol *b : findAllByVersion(ver))
+ if (b->versionId == config->defaultSymbolVersion)
+ b->versionId = versionId;
}
// This function processes version scripts by updating VersionId
@@ -241,21 +241,21 @@ void SymbolTable::scanVersionScript() {
// First, we assign versions to exact matching symbols,
// i.e. version definitions not containing any glob meta-characters.
- for (VersionDefinition &V : Config->VersionDefinitions)
- for (SymbolVersion &Ver : V.Globals)
- assignExactVersion(Ver, V.Id, V.Name);
+ for (VersionDefinition &v : config->versionDefinitions)
+ for (SymbolVersion &ver : v.globals)
+ assignExactVersion(ver, v.id, v.name);
// Next, we assign versions to fuzzy matching symbols,
// i.e. version definitions containing glob meta-characters.
// Note that because the last match takes precedence over previous matches,
// we iterate over the definitions in the reverse order.
- for (VersionDefinition &V : llvm::reverse(Config->VersionDefinitions))
- for (SymbolVersion &Ver : V.Globals)
- assignWildcardVersion(Ver, V.Id);
+ for (VersionDefinition &v : llvm::reverse(config->versionDefinitions))
+ for (SymbolVersion &ver : v.globals)
+ assignWildcardVersion(ver, v.id);
// Symbol themselves might know their versions because symbols
// can contain versions in the form of <name>@<version>.
// Let them parse and update their names to exclude version suffix.
- for (Symbol *Sym : SymVector)
- Sym->parseSymbolVersion();
+ for (Symbol *sym : symVector)
+ sym->parseSymbolVersion();
}
Modified: lld/trunk/ELF/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=365595&r1=365594&r2=365595&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.h (original)
+++ lld/trunk/ELF/SymbolTable.h Tue Jul 9 22:00:37 2019
@@ -33,41 +33,41 @@ namespace elf {
// is one add* function per symbol type.
class SymbolTable {
public:
- void wrap(Symbol *Sym, Symbol *Real, Symbol *Wrap);
+ void wrap(Symbol *sym, Symbol *real, Symbol *wrap);
- void forEachSymbol(llvm::function_ref<void(Symbol *)> Fn) {
- for (Symbol *Sym : SymVector)
- if (!Sym->isPlaceholder())
- Fn(Sym);
+ void forEachSymbol(llvm::function_ref<void(Symbol *)> fn) {
+ for (Symbol *sym : symVector)
+ if (!sym->isPlaceholder())
+ fn(sym);
}
- Symbol *insert(StringRef Name);
+ Symbol *insert(StringRef name);
Symbol *addSymbol(const Symbol &New);
void scanVersionScript();
- Symbol *find(StringRef Name);
+ Symbol *find(StringRef name);
void handleDynamicList();
// Set of .so files to not link the same shared object file more than once.
- llvm::DenseMap<StringRef, SharedFile *> SoNames;
+ llvm::DenseMap<StringRef, SharedFile *> soNames;
// Comdat groups define "link once" sections. If two comdat groups have the
// same name, only one of them is linked, and the other is ignored. This map
// is used to uniquify them.
- llvm::DenseMap<llvm::CachedHashStringRef, const InputFile *> ComdatGroups;
+ llvm::DenseMap<llvm::CachedHashStringRef, const InputFile *> comdatGroups;
private:
- std::vector<Symbol *> findByVersion(SymbolVersion Ver);
- std::vector<Symbol *> findAllByVersion(SymbolVersion Ver);
+ std::vector<Symbol *> findByVersion(SymbolVersion ver);
+ std::vector<Symbol *> findAllByVersion(SymbolVersion ver);
llvm::StringMap<std::vector<Symbol *>> &getDemangledSyms();
void handleAnonymousVersion();
- void assignExactVersion(SymbolVersion Ver, uint16_t VersionId,
- StringRef VersionName);
- void assignWildcardVersion(SymbolVersion Ver, uint16_t VersionId);
+ void assignExactVersion(SymbolVersion ver, uint16_t versionId,
+ StringRef versionName);
+ void assignWildcardVersion(SymbolVersion ver, uint16_t versionId);
// The order the global symbols are in is not defined. We can use an arbitrary
// order, but it has to be reproducible. That is true even when cross linking.
@@ -76,17 +76,17 @@ private:
// but a bit inefficient.
// FIXME: Experiment with passing in a custom hashing or sorting the symbols
// once symbol resolution is finished.
- llvm::DenseMap<llvm::CachedHashStringRef, int> SymMap;
- std::vector<Symbol *> SymVector;
+ llvm::DenseMap<llvm::CachedHashStringRef, int> symMap;
+ std::vector<Symbol *> symVector;
// A map from demangled symbol names to their symbol objects.
// This mapping is 1:N because two symbols with different versions
// can have the same name. We use this map to handle "extern C++ {}"
// directive in version scripts.
- llvm::Optional<llvm::StringMap<std::vector<Symbol *>>> DemangledSyms;
+ llvm::Optional<llvm::StringMap<std::vector<Symbol *>>> demangledSyms;
};
-extern SymbolTable *Symtab;
+extern SymbolTable *symtab;
} // namespace elf
} // namespace lld
Modified: lld/trunk/ELF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=365595&r1=365594&r2=365595&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.cpp (original)
+++ lld/trunk/ELF/Symbols.cpp Tue Jul 9 22:00:37 2019
@@ -26,36 +26,36 @@ using namespace llvm::ELF;
using namespace lld;
using namespace lld::elf;
-Defined *ElfSym::Bss;
-Defined *ElfSym::Etext1;
-Defined *ElfSym::Etext2;
-Defined *ElfSym::Edata1;
-Defined *ElfSym::Edata2;
-Defined *ElfSym::End1;
-Defined *ElfSym::End2;
-Defined *ElfSym::GlobalOffsetTable;
-Defined *ElfSym::MipsGp;
-Defined *ElfSym::MipsGpDisp;
-Defined *ElfSym::MipsLocalGp;
-Defined *ElfSym::RelaIpltStart;
-Defined *ElfSym::RelaIpltEnd;
-Defined *ElfSym::RISCVGlobalPointer;
-Defined *ElfSym::TlsModuleBase;
+Defined *ElfSym::bss;
+Defined *ElfSym::etext1;
+Defined *ElfSym::etext2;
+Defined *ElfSym::edata1;
+Defined *ElfSym::edata2;
+Defined *ElfSym::end1;
+Defined *ElfSym::end2;
+Defined *ElfSym::globalOffsetTable;
+Defined *ElfSym::mipsGp;
+Defined *ElfSym::mipsGpDisp;
+Defined *ElfSym::mipsLocalGp;
+Defined *ElfSym::relaIpltStart;
+Defined *ElfSym::relaIpltEnd;
+Defined *ElfSym::riscvGlobalPointer;
+Defined *ElfSym::tlsModuleBase;
-static uint64_t getSymVA(const Symbol &Sym, int64_t &Addend) {
- switch (Sym.kind()) {
+static uint64_t getSymVA(const Symbol &sym, int64_t &addend) {
+ switch (sym.kind()) {
case Symbol::DefinedKind: {
- auto &D = cast<Defined>(Sym);
- SectionBase *IS = D.Section;
+ auto &d = cast<Defined>(sym);
+ SectionBase *isec = d.section;
// This is an absolute symbol.
- if (!IS)
- return D.Value;
+ if (!isec)
+ return d.value;
- assert(IS != &InputSection::Discarded);
- IS = IS->Repl;
+ assert(isec != &InputSection::discarded);
+ isec = isec->repl;
- uint64_t Offset = D.Value;
+ uint64_t offset = d.value;
// An object in an SHF_MERGE section might be referenced via a
// section symbol (as a hack for reducing the number of local
@@ -68,9 +68,9 @@ static uint64_t getSymVA(const Symbol &S
// To make this work, we incorporate the addend into the section
// offset (and zero out the addend for later processing) so that
// we find the right object in the section.
- if (D.isSection()) {
- Offset += Addend;
- Addend = 0;
+ if (d.isSection()) {
+ offset += addend;
+ addend = 0;
}
// In the typical case, this is actually very simple and boils
@@ -83,7 +83,7 @@ static uint64_t getSymVA(const Symbol &S
// If you understand the data structures involved with this next
// line (and how they get built), then you have a pretty good
// understanding of the linker.
- uint64_t VA = IS->getVA(Offset);
+ uint64_t va = isec->getVA(offset);
// MIPS relocatable files can mix regular and microMIPS code.
// Linker needs to distinguish such code. To do so microMIPS
@@ -94,29 +94,29 @@ static uint64_t getSymVA(const Symbol &S
// a symbol value as-is (.dynamic section, `Elf_Ehdr::e_entry`
// field etc) do the same trick as compiler uses to mark microMIPS
// for CPU - set the less-significant bit.
- if (Config->EMachine == EM_MIPS && isMicroMips() &&
- ((Sym.StOther & STO_MIPS_MICROMIPS) || Sym.NeedsPltAddr))
- VA |= 1;
+ if (config->emachine == EM_MIPS && isMicroMips() &&
+ ((sym.stOther & STO_MIPS_MICROMIPS) || sym.needsPltAddr))
+ va |= 1;
- if (D.isTls() && !Config->Relocatable) {
+ if (d.isTls() && !config->relocatable) {
// Use the address of the TLS segment's first section rather than the
// segment's address, because segment addresses aren't initialized until
// after sections are finalized. (e.g. Measuring the size of .rela.dyn
// for Android relocation packing requires knowing TLS symbol addresses
// during section finalization.)
- if (!Out::TlsPhdr || !Out::TlsPhdr->FirstSec)
- fatal(toString(D.File) +
+ if (!Out::tlsPhdr || !Out::tlsPhdr->firstSec)
+ fatal(toString(d.file) +
" has an STT_TLS symbol but doesn't have an SHF_TLS section");
- return VA - Out::TlsPhdr->FirstSec->Addr;
+ return va - Out::tlsPhdr->firstSec->addr;
}
- return VA;
+ return va;
}
case Symbol::SharedKind:
case Symbol::UndefinedKind:
return 0;
case Symbol::LazyArchiveKind:
case Symbol::LazyObjectKind:
- assert(Sym.IsUsedInRegularObj && "lazy symbol reached writer");
+ assert(sym.isUsedInRegularObj && "lazy symbol reached writer");
return 0;
case Symbol::CommonKind:
llvm_unreachable("common symbol reached writer");
@@ -126,64 +126,64 @@ static uint64_t getSymVA(const Symbol &S
llvm_unreachable("invalid symbol kind");
}
-uint64_t Symbol::getVA(int64_t Addend) const {
- uint64_t OutVA = getSymVA(*this, Addend);
- return OutVA + Addend;
+uint64_t Symbol::getVA(int64_t addend) const {
+ uint64_t outVA = getSymVA(*this, addend);
+ return outVA + addend;
}
uint64_t Symbol::getGotVA() const {
- if (GotInIgot)
- return In.IgotPlt->getVA() + getGotPltOffset();
- return In.Got->getVA() + getGotOffset();
+ if (gotInIgot)
+ return in.igotPlt->getVA() + getGotPltOffset();
+ return in.got->getVA() + getGotOffset();
}
-uint64_t Symbol::getGotOffset() const { return GotIndex * Config->Wordsize; }
+uint64_t Symbol::getGotOffset() const { return gotIndex * config->wordsize; }
uint64_t Symbol::getGotPltVA() const {
- if (IsInIplt)
- return In.IgotPlt->getVA() + getGotPltOffset();
- return In.GotPlt->getVA() + getGotPltOffset();
+ if (isInIplt)
+ return in.igotPlt->getVA() + getGotPltOffset();
+ return in.gotPlt->getVA() + getGotPltOffset();
}
uint64_t Symbol::getGotPltOffset() const {
- if (IsInIplt)
- return PltIndex * Config->Wordsize;
- return (PltIndex + Target->GotPltHeaderEntriesNum) * Config->Wordsize;
+ if (isInIplt)
+ return pltIndex * config->wordsize;
+ return (pltIndex + target->gotPltHeaderEntriesNum) * config->wordsize;
}
uint64_t Symbol::getPPC64LongBranchOffset() const {
- assert(PPC64BranchltIndex != 0xffff);
- return PPC64BranchltIndex * Config->Wordsize;
+ assert(ppc64BranchltIndex != 0xffff);
+ return ppc64BranchltIndex * config->wordsize;
}
uint64_t Symbol::getPltVA() const {
- PltSection *Plt = IsInIplt ? In.Iplt : In.Plt;
- uint64_t OutVA =
- Plt->getVA() + Plt->HeaderSize + PltIndex * Target->PltEntrySize;
+ PltSection *plt = isInIplt ? in.iplt : in.plt;
+ uint64_t outVA =
+ plt->getVA() + plt->headerSize + pltIndex * target->pltEntrySize;
// While linking microMIPS code PLT code are always microMIPS
// code. Set the less-significant bit to track that fact.
// See detailed comment in the `getSymVA` function.
- if (Config->EMachine == EM_MIPS && isMicroMips())
- OutVA |= 1;
- return OutVA;
+ if (config->emachine == EM_MIPS && isMicroMips())
+ outVA |= 1;
+ return outVA;
}
uint64_t Symbol::getPPC64LongBranchTableVA() const {
- assert(PPC64BranchltIndex != 0xffff);
- return In.PPC64LongBranchTarget->getVA() +
- PPC64BranchltIndex * Config->Wordsize;
+ assert(ppc64BranchltIndex != 0xffff);
+ return in.ppc64LongBranchTarget->getVA() +
+ ppc64BranchltIndex * config->wordsize;
}
uint64_t Symbol::getSize() const {
- if (const auto *DR = dyn_cast<Defined>(this))
- return DR->Size;
- return cast<SharedSymbol>(this)->Size;
+ if (const auto *dr = dyn_cast<Defined>(this))
+ return dr->size;
+ return cast<SharedSymbol>(this)->size;
}
OutputSection *Symbol::getOutputSection() const {
- if (auto *S = dyn_cast<Defined>(this)) {
- if (auto *Sec = S->Section)
- return Sec->Repl->getOutputSection();
+ if (auto *s = dyn_cast<Defined>(this)) {
+ if (auto *sec = s->section)
+ return sec->repl->getOutputSection();
return nullptr;
}
return nullptr;
@@ -192,16 +192,16 @@ OutputSection *Symbol::getOutputSection(
// If a symbol name contains '@', the characters after that is
// a symbol version name. This function parses that.
void Symbol::parseSymbolVersion() {
- StringRef S = getName();
- size_t Pos = S.find('@');
- if (Pos == 0 || Pos == StringRef::npos)
+ StringRef s = getName();
+ size_t pos = s.find('@');
+ if (pos == 0 || pos == StringRef::npos)
return;
- StringRef Verstr = S.substr(Pos + 1);
- if (Verstr.empty())
+ StringRef verstr = s.substr(pos + 1);
+ if (verstr.empty())
return;
// Truncate the symbol name so that it doesn't include the version string.
- NameSize = Pos;
+ nameSize = pos;
// If this is not in this DSO, it is not a definition.
if (!isDefined())
@@ -209,18 +209,18 @@ void Symbol::parseSymbolVersion() {
// '@@' in a symbol name means the default version.
// It is usually the most recent one.
- bool IsDefault = (Verstr[0] == '@');
- if (IsDefault)
- Verstr = Verstr.substr(1);
+ bool isDefault = (verstr[0] == '@');
+ if (isDefault)
+ verstr = verstr.substr(1);
- for (VersionDefinition &Ver : Config->VersionDefinitions) {
- if (Ver.Name != Verstr)
+ for (VersionDefinition &ver : config->versionDefinitions) {
+ if (ver.name != verstr)
continue;
- if (IsDefault)
- VersionId = Ver.Id;
+ if (isDefault)
+ versionId = ver.id;
else
- VersionId = Ver.Id | VERSYM_HIDDEN;
+ versionId = ver.id | VERSYM_HIDDEN;
return;
}
@@ -230,19 +230,19 @@ void Symbol::parseSymbolVersion() {
// so we do not report error in this case. We also do not error
// if the symbol has a local version as it won't be in the dynamic
// symbol table.
- if (Config->Shared && VersionId != VER_NDX_LOCAL)
- error(toString(File) + ": symbol " + S + " has undefined version " +
- Verstr);
+ if (config->shared && versionId != VER_NDX_LOCAL)
+ error(toString(file) + ": symbol " + s + " has undefined version " +
+ verstr);
}
void Symbol::fetch() const {
- if (auto *Sym = dyn_cast<LazyArchive>(this)) {
- cast<ArchiveFile>(Sym->File)->fetch(Sym->Sym);
+ if (auto *sym = dyn_cast<LazyArchive>(this)) {
+ cast<ArchiveFile>(sym->file)->fetch(sym->sym);
return;
}
- if (auto *Sym = dyn_cast<LazyObject>(this)) {
- dyn_cast<LazyObjFile>(Sym->File)->fetch();
+ if (auto *sym = dyn_cast<LazyObject>(this)) {
+ dyn_cast<LazyObjFile>(sym->file)->fetch();
return;
}
@@ -250,59 +250,59 @@ void Symbol::fetch() const {
}
MemoryBufferRef LazyArchive::getMemberBuffer() {
- Archive::Child C = CHECK(
- Sym.getMember(), "could not get the member for symbol " + Sym.getName());
+ Archive::Child c = CHECK(
+ sym.getMember(), "could not get the member for symbol " + sym.getName());
- return CHECK(C.getMemoryBufferRef(),
+ return CHECK(c.getMemoryBufferRef(),
"could not get the buffer for the member defining symbol " +
- Sym.getName());
+ sym.getName());
}
uint8_t Symbol::computeBinding() const {
- if (Config->Relocatable)
- return Binding;
- if (Visibility != STV_DEFAULT && Visibility != STV_PROTECTED)
+ if (config->relocatable)
+ return binding;
+ if (visibility != STV_DEFAULT && visibility != STV_PROTECTED)
return STB_LOCAL;
- if (VersionId == VER_NDX_LOCAL && isDefined() && !IsPreemptible)
+ if (versionId == VER_NDX_LOCAL && isDefined() && !isPreemptible)
return STB_LOCAL;
- if (!Config->GnuUnique && Binding == STB_GNU_UNIQUE)
+ if (!config->gnuUnique && binding == STB_GNU_UNIQUE)
return STB_GLOBAL;
- return Binding;
+ return binding;
}
bool Symbol::includeInDynsym() const {
- if (!Config->HasDynSymTab)
+ if (!config->hasDynSymTab)
return false;
if (computeBinding() == STB_LOCAL)
return false;
// If a PIE binary was not linked against any shared libraries, then we can
// safely drop weak undef symbols from .dynsym.
- if (isUndefWeak() && Config->Pie && SharedFiles.empty())
+ if (isUndefWeak() && config->pie && sharedFiles.empty())
return false;
- return isUndefined() || isShared() || ExportDynamic;
+ return isUndefined() || isShared() || exportDynamic;
}
// Print out a log message for --trace-symbol.
-void elf::printTraceSymbol(const Symbol *Sym) {
- std::string S;
- if (Sym->isUndefined())
- S = ": reference to ";
- else if (Sym->isLazy())
- S = ": lazy definition of ";
- else if (Sym->isShared())
- S = ": shared definition of ";
- else if (Sym->isCommon())
- S = ": common definition of ";
+void elf::printTraceSymbol(const Symbol *sym) {
+ std::string s;
+ if (sym->isUndefined())
+ s = ": reference to ";
+ else if (sym->isLazy())
+ s = ": lazy definition of ";
+ else if (sym->isShared())
+ s = ": shared definition of ";
+ else if (sym->isCommon())
+ s = ": common definition of ";
else
- S = ": definition of ";
+ s = ": definition of ";
- message(toString(Sym->File) + S + Sym->getName());
+ message(toString(sym->file) + s + sym->getName());
}
-void elf::maybeWarnUnorderableSymbol(const Symbol *Sym) {
- if (!Config->WarnSymbolOrdering)
+void elf::maybeWarnUnorderableSymbol(const Symbol *sym) {
+ if (!config->warnSymbolOrdering)
return;
// If UnresolvedPolicy::Ignore is used, no "undefined symbol" error/warning
@@ -310,41 +310,41 @@ void elf::maybeWarnUnorderableSymbol(con
//
// Note, ld.bfd --symbol-ordering-file= does not warn on undefined symbols,
// but we don't have to be compatible here.
- if (Sym->isUndefined() &&
- Config->UnresolvedSymbols == UnresolvedPolicy::Ignore)
+ if (sym->isUndefined() &&
+ config->unresolvedSymbols == UnresolvedPolicy::Ignore)
return;
- const InputFile *File = Sym->File;
- auto *D = dyn_cast<Defined>(Sym);
+ const InputFile *file = sym->file;
+ auto *d = dyn_cast<Defined>(sym);
- auto Report = [&](StringRef S) { warn(toString(File) + S + Sym->getName()); };
+ auto report = [&](StringRef s) { warn(toString(file) + s + sym->getName()); };
- if (Sym->isUndefined())
- Report(": unable to order undefined symbol: ");
- else if (Sym->isShared())
- Report(": unable to order shared symbol: ");
- else if (D && !D->Section)
- Report(": unable to order absolute symbol: ");
- else if (D && isa<OutputSection>(D->Section))
- Report(": unable to order synthetic symbol: ");
- else if (D && !D->Section->Repl->isLive())
- Report(": unable to order discarded symbol: ");
+ if (sym->isUndefined())
+ report(": unable to order undefined symbol: ");
+ else if (sym->isShared())
+ report(": unable to order shared symbol: ");
+ else if (d && !d->section)
+ report(": unable to order absolute symbol: ");
+ else if (d && isa<OutputSection>(d->section))
+ report(": unable to order synthetic symbol: ");
+ else if (d && !d->section->repl->isLive())
+ report(": unable to order discarded symbol: ");
}
// Returns a symbol for an error message.
-std::string lld::toString(const Symbol &B) {
- if (Config->Demangle)
- if (Optional<std::string> S = demangleItanium(B.getName()))
- return *S;
- return B.getName();
+std::string lld::toString(const Symbol &b) {
+ if (config->demangle)
+ if (Optional<std::string> s = demangleItanium(b.getName()))
+ return *s;
+ return b.getName();
}
-static uint8_t getMinVisibility(uint8_t VA, uint8_t VB) {
- if (VA == STV_DEFAULT)
- return VB;
- if (VB == STV_DEFAULT)
- return VA;
- return std::min(VA, VB);
+static uint8_t getMinVisibility(uint8_t va, uint8_t vb) {
+ if (va == STV_DEFAULT)
+ return vb;
+ if (vb == STV_DEFAULT)
+ return va;
+ return std::min(va, vb);
}
// Merge symbol properties.
@@ -352,70 +352,70 @@ static uint8_t getMinVisibility(uint8_t
// When we have many symbols of the same name, we choose one of them,
// and that's the result of symbol resolution. However, symbols that
// were not chosen still affect some symbol properties.
-void Symbol::mergeProperties(const Symbol &Other) {
- if (Other.ExportDynamic)
- ExportDynamic = true;
- if (Other.IsUsedInRegularObj)
- IsUsedInRegularObj = true;
+void Symbol::mergeProperties(const Symbol &other) {
+ if (other.exportDynamic)
+ exportDynamic = true;
+ if (other.isUsedInRegularObj)
+ isUsedInRegularObj = true;
// DSO symbols do not affect visibility in the output.
- if (!Other.isShared())
- Visibility = getMinVisibility(Visibility, Other.Visibility);
+ if (!other.isShared())
+ visibility = getMinVisibility(visibility, other.visibility);
}
-void Symbol::resolve(const Symbol &Other) {
- mergeProperties(Other);
+void Symbol::resolve(const Symbol &other) {
+ mergeProperties(other);
if (isPlaceholder()) {
- replace(Other);
+ replace(other);
return;
}
- switch (Other.kind()) {
+ switch (other.kind()) {
case Symbol::UndefinedKind:
- resolveUndefined(cast<Undefined>(Other));
+ resolveUndefined(cast<Undefined>(other));
break;
case Symbol::CommonKind:
- resolveCommon(cast<CommonSymbol>(Other));
+ resolveCommon(cast<CommonSymbol>(other));
break;
case Symbol::DefinedKind:
- resolveDefined(cast<Defined>(Other));
+ resolveDefined(cast<Defined>(other));
break;
case Symbol::LazyArchiveKind:
- resolveLazy(cast<LazyArchive>(Other));
+ resolveLazy(cast<LazyArchive>(other));
break;
case Symbol::LazyObjectKind:
- resolveLazy(cast<LazyObject>(Other));
+ resolveLazy(cast<LazyObject>(other));
break;
case Symbol::SharedKind:
- resolveShared(cast<SharedSymbol>(Other));
+ resolveShared(cast<SharedSymbol>(other));
break;
case Symbol::PlaceholderKind:
llvm_unreachable("bad symbol kind");
}
}
-void Symbol::resolveUndefined(const Undefined &Other) {
+void Symbol::resolveUndefined(const Undefined &other) {
// An undefined symbol with non default visibility must be satisfied
// in the same DSO.
//
// If this is a non-weak defined symbol in a discarded section, override the
// existing undefined symbol for better error message later.
- if ((isShared() && Other.Visibility != STV_DEFAULT) ||
- (isUndefined() && Other.Binding != STB_WEAK && Other.DiscardedSecIdx)) {
- replace(Other);
+ if ((isShared() && other.visibility != STV_DEFAULT) ||
+ (isUndefined() && other.binding != STB_WEAK && other.discardedSecIdx)) {
+ replace(other);
return;
}
- if (Traced)
- printTraceSymbol(&Other);
+ if (traced)
+ printTraceSymbol(&other);
if (isLazy()) {
// An undefined weak will not fetch archive members. See comment on Lazy in
// Symbols.h for the details.
- if (Other.Binding == STB_WEAK) {
- Binding = STB_WEAK;
- Type = Other.Type;
+ if (other.binding == STB_WEAK) {
+ binding = STB_WEAK;
+ type = other.type;
return;
}
@@ -469,33 +469,33 @@ void Symbol::resolveUndefined(const Unde
// A forms group 0. B form group 1. C and D (including their member object
// files) form group 2. E forms group 3. I think that you can see how this
// group assignment rule simulates the traditional linker's semantics.
- bool Backref = Config->WarnBackrefs && Other.File &&
- File->GroupId < Other.File->GroupId;
+ bool backref = config->warnBackrefs && other.file &&
+ file->groupId < other.file->groupId;
fetch();
// We don't report backward references to weak symbols as they can be
// overridden later.
- if (Backref && !isWeak())
- warn("backward reference detected: " + Other.getName() + " in " +
- toString(Other.File) + " refers to " + toString(File));
+ if (backref && !isWeak())
+ warn("backward reference detected: " + other.getName() + " in " +
+ toString(other.file) + " refers to " + toString(file));
return;
}
// Undefined symbols in a SharedFile do not change the binding.
- if (dyn_cast_or_null<SharedFile>(Other.File))
+ if (dyn_cast_or_null<SharedFile>(other.file))
return;
if (isUndefined()) {
// The binding may "upgrade" from weak to non-weak.
- if (Other.Binding != STB_WEAK)
- Binding = Other.Binding;
- } else if (auto *S = dyn_cast<SharedSymbol>(this)) {
+ if (other.binding != STB_WEAK)
+ binding = other.binding;
+ } else if (auto *s = dyn_cast<SharedSymbol>(this)) {
// The binding of a SharedSymbol will be weak if there is at least one
// reference and all are weak. The binding has one opportunity to change to
// weak: if the first reference is weak.
- if (Other.Binding != STB_WEAK || !S->Referenced)
- Binding = Other.Binding;
- S->Referenced = true;
+ if (other.binding != STB_WEAK || !s->referenced)
+ binding = other.binding;
+ s->referenced = true;
}
}
@@ -505,73 +505,73 @@ void Symbol::resolveUndefined(const Unde
// FIXME: If users can transition to using
// .symver foo,foo@@@VER
// we can delete this hack.
-static int compareVersion(StringRef A, StringRef B) {
- bool X = A.contains("@@");
- bool Y = B.contains("@@");
- if (!X && Y)
+static int compareVersion(StringRef a, StringRef b) {
+ bool x = a.contains("@@");
+ bool y = b.contains("@@");
+ if (!x && y)
return 1;
- if (X && !Y)
+ if (x && !y)
return -1;
return 0;
}
// Compare two symbols. Return 1 if the new symbol should win, -1 if
// the new symbol should lose, or 0 if there is a conflict.
-int Symbol::compare(const Symbol *Other) const {
- assert(Other->isDefined() || Other->isCommon());
+int Symbol::compare(const Symbol *other) const {
+ assert(other->isDefined() || other->isCommon());
if (!isDefined() && !isCommon())
return 1;
- if (int Cmp = compareVersion(getName(), Other->getName()))
- return Cmp;
+ if (int cmp = compareVersion(getName(), other->getName()))
+ return cmp;
- if (Other->isWeak())
+ if (other->isWeak())
return -1;
if (isWeak())
return 1;
- if (isCommon() && Other->isCommon()) {
- if (Config->WarnCommon)
+ if (isCommon() && other->isCommon()) {
+ if (config->warnCommon)
warn("multiple common of " + getName());
return 0;
}
if (isCommon()) {
- if (Config->WarnCommon)
+ if (config->warnCommon)
warn("common " + getName() + " is overridden");
return 1;
}
- if (Other->isCommon()) {
- if (Config->WarnCommon)
+ if (other->isCommon()) {
+ if (config->warnCommon)
warn("common " + getName() + " is overridden");
return -1;
}
- auto *OldSym = cast<Defined>(this);
- auto *NewSym = cast<Defined>(Other);
+ auto *oldSym = cast<Defined>(this);
+ auto *newSym = cast<Defined>(other);
- if (Other->File && isa<BitcodeFile>(Other->File))
+ if (other->file && isa<BitcodeFile>(other->file))
return 0;
- if (!OldSym->Section && !NewSym->Section && OldSym->Value == NewSym->Value &&
- NewSym->Binding == STB_GLOBAL)
+ if (!oldSym->section && !newSym->section && oldSym->value == newSym->value &&
+ newSym->binding == STB_GLOBAL)
return -1;
return 0;
}
-static void reportDuplicate(Symbol *Sym, InputFile *NewFile,
- InputSectionBase *ErrSec, uint64_t ErrOffset) {
- if (Config->AllowMultipleDefinition)
+static void reportDuplicate(Symbol *sym, InputFile *newFile,
+ InputSectionBase *errSec, uint64_t errOffset) {
+ if (config->allowMultipleDefinition)
return;
- Defined *D = cast<Defined>(Sym);
- if (!D->Section || !ErrSec) {
- error("duplicate symbol: " + toString(*Sym) + "\n>>> defined in " +
- toString(Sym->File) + "\n>>> defined in " + toString(NewFile));
+ Defined *d = cast<Defined>(sym);
+ if (!d->section || !errSec) {
+ error("duplicate symbol: " + toString(*sym) + "\n>>> defined in " +
+ toString(sym->file) + "\n>>> defined in " + toString(newFile));
return;
}
@@ -582,75 +582,75 @@ static void reportDuplicate(Symbol *Sym,
// >>> bar.o (/home/alice/src/bar.o)
// >>> defined at baz.c:563
// >>> baz.o in archive libbaz.a
- auto *Sec1 = cast<InputSectionBase>(D->Section);
- std::string Src1 = Sec1->getSrcMsg(*Sym, D->Value);
- std::string Obj1 = Sec1->getObjMsg(D->Value);
- std::string Src2 = ErrSec->getSrcMsg(*Sym, ErrOffset);
- std::string Obj2 = ErrSec->getObjMsg(ErrOffset);
+ auto *sec1 = cast<InputSectionBase>(d->section);
+ std::string src1 = sec1->getSrcMsg(*sym, d->value);
+ std::string obj1 = sec1->getObjMsg(d->value);
+ std::string src2 = errSec->getSrcMsg(*sym, errOffset);
+ std::string obj2 = errSec->getObjMsg(errOffset);
- std::string Msg = "duplicate symbol: " + toString(*Sym) + "\n>>> defined at ";
- if (!Src1.empty())
- Msg += Src1 + "\n>>> ";
- Msg += Obj1 + "\n>>> defined at ";
- if (!Src2.empty())
- Msg += Src2 + "\n>>> ";
- Msg += Obj2;
- error(Msg);
+ std::string msg = "duplicate symbol: " + toString(*sym) + "\n>>> defined at ";
+ if (!src1.empty())
+ msg += src1 + "\n>>> ";
+ msg += obj1 + "\n>>> defined at ";
+ if (!src2.empty())
+ msg += src2 + "\n>>> ";
+ msg += obj2;
+ error(msg);
}
-void Symbol::resolveCommon(const CommonSymbol &Other) {
- int Cmp = compare(&Other);
- if (Cmp < 0)
+void Symbol::resolveCommon(const CommonSymbol &other) {
+ int cmp = compare(&other);
+ if (cmp < 0)
return;
- if (Cmp > 0) {
- replace(Other);
+ if (cmp > 0) {
+ replace(other);
return;
}
- CommonSymbol *OldSym = cast<CommonSymbol>(this);
+ CommonSymbol *oldSym = cast<CommonSymbol>(this);
- OldSym->Alignment = std::max(OldSym->Alignment, Other.Alignment);
- if (OldSym->Size < Other.Size) {
- OldSym->File = Other.File;
- OldSym->Size = Other.Size;
+ oldSym->alignment = std::max(oldSym->alignment, other.alignment);
+ if (oldSym->size < other.size) {
+ oldSym->file = other.file;
+ oldSym->size = other.size;
}
}
-void Symbol::resolveDefined(const Defined &Other) {
- int Cmp = compare(&Other);
- if (Cmp > 0)
- replace(Other);
- else if (Cmp == 0)
- reportDuplicate(this, Other.File,
- dyn_cast_or_null<InputSectionBase>(Other.Section),
- Other.Value);
+void Symbol::resolveDefined(const Defined &other) {
+ int cmp = compare(&other);
+ if (cmp > 0)
+ replace(other);
+ else if (cmp == 0)
+ reportDuplicate(this, other.file,
+ dyn_cast_or_null<InputSectionBase>(other.section),
+ other.value);
}
-template <class LazyT> void Symbol::resolveLazy(const LazyT &Other) {
+template <class LazyT> void Symbol::resolveLazy(const LazyT &other) {
if (!isUndefined())
return;
// An undefined weak will not fetch archive members. See comment on Lazy in
// Symbols.h for the details.
if (isWeak()) {
- uint8_t Ty = Type;
- replace(Other);
- Type = Ty;
- Binding = STB_WEAK;
+ uint8_t ty = type;
+ replace(other);
+ type = ty;
+ binding = STB_WEAK;
return;
}
- Other.fetch();
+ other.fetch();
}
-void Symbol::resolveShared(const SharedSymbol &Other) {
- if (Visibility == STV_DEFAULT && (isUndefined() || isLazy())) {
+void Symbol::resolveShared(const SharedSymbol &other) {
+ if (visibility == STV_DEFAULT && (isUndefined() || isLazy())) {
// An undefined symbol with non default visibility must be satisfied
// in the same DSO.
- uint8_t Bind = Binding;
- replace(Other);
- Binding = Bind;
- cast<SharedSymbol>(this)->Referenced = true;
+ uint8_t bind = binding;
+ replace(other);
+ binding = bind;
+ cast<SharedSymbol>(this)->referenced = true;
}
}
Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=365595&r1=365594&r2=365595&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Tue Jul 9 22:00:37 2019
@@ -44,11 +44,11 @@ namespace elf {
// and the linker doesn't use local symbol names for name resolution. So, we
// use this class to represents strings read from string tables.
struct StringRefZ {
- StringRefZ(const char *S) : Data(S), Size(-1) {}
- StringRefZ(StringRef S) : Data(S.data()), Size(S.size()) {}
+ StringRefZ(const char *s) : data(s), size(-1) {}
+ StringRefZ(StringRef s) : data(s.data()), size(s.size()) {}
- const char *Data;
- const uint32_t Size;
+ const char *data;
+ const uint32_t size;
};
// The base class for real symbol classes.
@@ -64,84 +64,84 @@ public:
LazyObjectKind,
};
- Kind kind() const { return static_cast<Kind>(SymbolKind); }
+ Kind kind() const { return static_cast<Kind>(symbolKind); }
// The file from which this symbol was created.
- InputFile *File;
+ InputFile *file;
protected:
- const char *NameData;
- mutable uint32_t NameSize;
+ const char *nameData;
+ mutable uint32_t nameSize;
public:
- uint32_t DynsymIndex = 0;
- uint32_t GotIndex = -1;
- uint32_t PltIndex = -1;
+ uint32_t dynsymIndex = 0;
+ uint32_t gotIndex = -1;
+ uint32_t pltIndex = -1;
- uint32_t GlobalDynIndex = -1;
+ uint32_t globalDynIndex = -1;
// This field is a index to the symbol's version definition.
- uint32_t VerdefIndex = -1;
+ uint32_t verdefIndex = -1;
// Version definition index.
- uint16_t VersionId;
+ uint16_t versionId;
// An index into the .branch_lt section on PPC64.
- uint16_t PPC64BranchltIndex = -1;
+ uint16_t ppc64BranchltIndex = -1;
// Symbol binding. This is not overwritten by replace() to track
// changes during resolution. In particular:
// - An undefined weak is still weak when it resolves to a shared library.
// - An undefined weak will not fetch archive members, but we have to
// remember it is weak.
- uint8_t Binding;
+ uint8_t binding;
// The following fields have the same meaning as the ELF symbol attributes.
- uint8_t Type; // symbol type
- uint8_t StOther; // st_other field value
+ uint8_t type; // symbol type
+ uint8_t stOther; // st_other field value
- uint8_t SymbolKind;
+ uint8_t symbolKind;
// Symbol visibility. This is the computed minimum visibility of all
// observed non-DSO symbols.
- unsigned Visibility : 2;
+ unsigned visibility : 2;
// True if the symbol was used for linking and thus need to be added to the
// output file's symbol table. This is true for all symbols except for
// unreferenced DSO symbols, lazy (archive) symbols, and bitcode symbols that
// are unreferenced except by other bitcode objects.
- unsigned IsUsedInRegularObj : 1;
+ unsigned isUsedInRegularObj : 1;
// If this flag is true and the symbol has protected or default visibility, it
// will appear in .dynsym. This flag is set by interposable DSO symbols in
// executables, by most symbols in DSOs and executables built with
// --export-dynamic, and by dynamic lists.
- unsigned ExportDynamic : 1;
+ unsigned exportDynamic : 1;
// False if LTO shouldn't inline whatever this symbol points to. If a symbol
// is overwritten after LTO, LTO shouldn't inline the symbol because it
// doesn't know the final contents of the symbol.
- unsigned CanInline : 1;
+ unsigned canInline : 1;
// True if this symbol is specified by --trace-symbol option.
- unsigned Traced : 1;
+ unsigned traced : 1;
inline void replace(const Symbol &New);
bool includeInDynsym() const;
uint8_t computeBinding() const;
- bool isWeak() const { return Binding == llvm::ELF::STB_WEAK; }
+ bool isWeak() const { return binding == llvm::ELF::STB_WEAK; }
- bool isUndefined() const { return SymbolKind == UndefinedKind; }
- bool isCommon() const { return SymbolKind == CommonKind; }
- bool isDefined() const { return SymbolKind == DefinedKind; }
- bool isShared() const { return SymbolKind == SharedKind; }
- bool isPlaceholder() const { return SymbolKind == PlaceholderKind; }
+ bool isUndefined() const { return symbolKind == UndefinedKind; }
+ bool isCommon() const { return symbolKind == CommonKind; }
+ bool isDefined() const { return symbolKind == DefinedKind; }
+ bool isShared() const { return symbolKind == SharedKind; }
+ bool isPlaceholder() const { return symbolKind == PlaceholderKind; }
- bool isLocal() const { return Binding == llvm::ELF::STB_LOCAL; }
+ bool isLocal() const { return binding == llvm::ELF::STB_LOCAL; }
bool isLazy() const {
- return SymbolKind == LazyArchiveKind || SymbolKind == LazyObjectKind;
+ return symbolKind == LazyArchiveKind || symbolKind == LazyObjectKind;
}
// True if this is an undefined weak symbol. This only works once
@@ -152,23 +152,23 @@ public:
}
StringRef getName() const {
- if (NameSize == (uint32_t)-1)
- NameSize = strlen(NameData);
- return {NameData, NameSize};
+ if (nameSize == (uint32_t)-1)
+ nameSize = strlen(nameData);
+ return {nameData, nameSize};
}
- void setName(StringRef S) {
- NameData = S.data();
- NameSize = S.size();
+ void setName(StringRef s) {
+ nameData = s.data();
+ nameSize = s.size();
}
void parseSymbolVersion();
- bool isInGot() const { return GotIndex != -1U; }
- bool isInPlt() const { return PltIndex != -1U; }
- bool isInPPC64Branchlt() const { return PPC64BranchltIndex != 0xffff; }
+ bool isInGot() const { return gotIndex != -1U; }
+ bool isInPlt() const { return pltIndex != -1U; }
+ bool isInPPC64Branchlt() const { return ppc64BranchltIndex != 0xffff; }
- uint64_t getVA(int64_t Addend = 0) const;
+ uint64_t getVA(int64_t addend = 0) const;
uint64_t getGotOffset() const;
uint64_t getGotVA() const;
@@ -193,8 +193,8 @@ public:
//
// For example, if "this" is an undefined symbol and a new symbol is
// a defined symbol, "this" is replaced with the new symbol.
- void mergeProperties(const Symbol &Other);
- void resolve(const Symbol &Other);
+ void mergeProperties(const Symbol &other);
+ void resolve(const Symbol &other);
// If this is a lazy symbol, fetch an input file and add the symbol
// in the file to the symbol table. Calling this function on
@@ -202,83 +202,83 @@ public:
void fetch() const;
private:
- static bool isExportDynamic(Kind K, uint8_t Visibility) {
- if (K == SharedKind)
- return Visibility == llvm::ELF::STV_DEFAULT;
- return Config->Shared || Config->ExportDynamic;
+ static bool isExportDynamic(Kind k, uint8_t visibility) {
+ if (k == SharedKind)
+ return visibility == llvm::ELF::STV_DEFAULT;
+ return config->shared || config->exportDynamic;
}
- void resolveUndefined(const Undefined &Other);
- void resolveCommon(const CommonSymbol &Other);
- void resolveDefined(const Defined &Other);
- template <class LazyT> void resolveLazy(const LazyT &Other);
- void resolveShared(const SharedSymbol &Other);
+ void resolveUndefined(const Undefined &other);
+ void resolveCommon(const CommonSymbol &other);
+ void resolveDefined(const Defined &other);
+ template <class LazyT> void resolveLazy(const LazyT &other);
+ void resolveShared(const SharedSymbol &other);
- int compare(const Symbol *Other) const;
+ int compare(const Symbol *other) const;
inline size_t getSymbolSize() const;
protected:
- Symbol(Kind K, InputFile *File, StringRefZ Name, uint8_t Binding,
- uint8_t StOther, uint8_t Type)
- : File(File), NameData(Name.Data), NameSize(Name.Size), Binding(Binding),
- Type(Type), StOther(StOther), SymbolKind(K), Visibility(StOther & 3),
- IsUsedInRegularObj(!File || File->kind() == InputFile::ObjKind),
- ExportDynamic(isExportDynamic(K, Visibility)), CanInline(false),
- Traced(false), NeedsPltAddr(false), IsInIplt(false), GotInIgot(false),
- IsPreemptible(false), Used(!Config->GcSections), NeedsTocRestore(false),
- ScriptDefined(false) {}
+ Symbol(Kind k, InputFile *file, StringRefZ name, uint8_t binding,
+ uint8_t stOther, uint8_t type)
+ : file(file), nameData(name.data), nameSize(name.size), binding(binding),
+ type(type), stOther(stOther), symbolKind(k), visibility(stOther & 3),
+ isUsedInRegularObj(!file || file->kind() == InputFile::ObjKind),
+ exportDynamic(isExportDynamic(k, visibility)), canInline(false),
+ traced(false), needsPltAddr(false), isInIplt(false), gotInIgot(false),
+ isPreemptible(false), used(!config->gcSections), needsTocRestore(false),
+ scriptDefined(false) {}
public:
// True the symbol should point to its PLT entry.
// For SharedSymbol only.
- unsigned NeedsPltAddr : 1;
+ unsigned needsPltAddr : 1;
// True if this symbol is in the Iplt sub-section of the Plt and the Igot
// sub-section of the .got.plt or .got.
- unsigned IsInIplt : 1;
+ unsigned isInIplt : 1;
// True if this symbol needs a GOT entry and its GOT entry is actually in
// Igot. This will be true only for certain non-preemptible ifuncs.
- unsigned GotInIgot : 1;
+ unsigned gotInIgot : 1;
// True if this symbol is preemptible at load time.
- unsigned IsPreemptible : 1;
+ unsigned isPreemptible : 1;
// True if an undefined or shared symbol is used from a live section.
- unsigned Used : 1;
+ unsigned used : 1;
// True if a call to this symbol needs to be followed by a restore of the
// PPC64 toc pointer.
- unsigned NeedsTocRestore : 1;
+ unsigned needsTocRestore : 1;
// True if this symbol is defined by a linker script.
- unsigned ScriptDefined : 1;
+ unsigned scriptDefined : 1;
// The partition whose dynamic symbol table contains this symbol's definition.
- uint8_t Partition = 1;
+ uint8_t partition = 1;
- bool isSection() const { return Type == llvm::ELF::STT_SECTION; }
- bool isTls() const { return Type == llvm::ELF::STT_TLS; }
- bool isFunc() const { return Type == llvm::ELF::STT_FUNC; }
- bool isGnuIFunc() const { return Type == llvm::ELF::STT_GNU_IFUNC; }
- bool isObject() const { return Type == llvm::ELF::STT_OBJECT; }
- bool isFile() const { return Type == llvm::ELF::STT_FILE; }
+ bool isSection() const { return type == llvm::ELF::STT_SECTION; }
+ bool isTls() const { return type == llvm::ELF::STT_TLS; }
+ bool isFunc() const { return type == llvm::ELF::STT_FUNC; }
+ bool isGnuIFunc() const { return type == llvm::ELF::STT_GNU_IFUNC; }
+ bool isObject() const { return type == llvm::ELF::STT_OBJECT; }
+ bool isFile() const { return type == llvm::ELF::STT_FILE; }
};
// Represents a symbol that is defined in the current output file.
class Defined : public Symbol {
public:
- Defined(InputFile *File, StringRefZ Name, uint8_t Binding, uint8_t StOther,
- uint8_t Type, uint64_t Value, uint64_t Size, SectionBase *Section)
- : Symbol(DefinedKind, File, Name, Binding, StOther, Type), Value(Value),
- Size(Size), Section(Section) {}
-
- static bool classof(const Symbol *S) { return S->isDefined(); }
-
- uint64_t Value;
- uint64_t Size;
- SectionBase *Section;
+ Defined(InputFile *file, StringRefZ name, uint8_t binding, uint8_t stOther,
+ uint8_t type, uint64_t value, uint64_t size, SectionBase *section)
+ : Symbol(DefinedKind, file, name, binding, stOther, type), value(value),
+ size(size), section(section) {}
+
+ static bool classof(const Symbol *s) { return s->isDefined(); }
+
+ uint64_t value;
+ uint64_t size;
+ SectionBase *section;
};
// Represents a common symbol.
@@ -304,40 +304,40 @@ public:
// section. (Therefore, the later passes don't see any CommonSymbols.)
class CommonSymbol : public Symbol {
public:
- CommonSymbol(InputFile *File, StringRefZ Name, uint8_t Binding,
- uint8_t StOther, uint8_t Type, uint64_t Alignment, uint64_t Size)
- : Symbol(CommonKind, File, Name, Binding, StOther, Type),
- Alignment(Alignment), Size(Size) {}
+ CommonSymbol(InputFile *file, StringRefZ name, uint8_t binding,
+ uint8_t stOther, uint8_t type, uint64_t alignment, uint64_t size)
+ : Symbol(CommonKind, file, name, binding, stOther, type),
+ alignment(alignment), size(size) {}
- static bool classof(const Symbol *S) { return S->isCommon(); }
+ static bool classof(const Symbol *s) { return s->isCommon(); }
- uint32_t Alignment;
- uint64_t Size;
+ uint32_t alignment;
+ uint64_t size;
};
class Undefined : public Symbol {
public:
- Undefined(InputFile *File, StringRefZ Name, uint8_t Binding, uint8_t StOther,
- uint8_t Type, uint32_t DiscardedSecIdx = 0)
- : Symbol(UndefinedKind, File, Name, Binding, StOther, Type),
- DiscardedSecIdx(DiscardedSecIdx) {}
+ Undefined(InputFile *file, StringRefZ name, uint8_t binding, uint8_t stOther,
+ uint8_t type, uint32_t discardedSecIdx = 0)
+ : Symbol(UndefinedKind, file, name, binding, stOther, type),
+ discardedSecIdx(discardedSecIdx) {}
- static bool classof(const Symbol *S) { return S->kind() == UndefinedKind; }
+ static bool classof(const Symbol *s) { return s->kind() == UndefinedKind; }
// The section index if in a discarded section, 0 otherwise.
- uint32_t DiscardedSecIdx;
+ uint32_t discardedSecIdx;
};
class SharedSymbol : public Symbol {
public:
- static bool classof(const Symbol *S) { return S->kind() == SharedKind; }
+ static bool classof(const Symbol *s) { return s->kind() == SharedKind; }
- SharedSymbol(InputFile &File, StringRef Name, uint8_t Binding,
- uint8_t StOther, uint8_t Type, uint64_t Value, uint64_t Size,
- uint32_t Alignment, uint32_t VerdefIndex)
- : Symbol(SharedKind, &File, Name, Binding, StOther, Type), Value(Value),
- Size(Size), Alignment(Alignment) {
- this->VerdefIndex = VerdefIndex;
+ SharedSymbol(InputFile &file, StringRef name, uint8_t binding,
+ uint8_t stOther, uint8_t type, uint64_t value, uint64_t size,
+ uint32_t alignment, uint32_t verdefIndex)
+ : Symbol(SharedKind, &file, name, binding, stOther, type), value(value),
+ size(size), alignment(alignment) {
+ this->verdefIndex = verdefIndex;
// GNU ifunc is a mechanism to allow user-supplied functions to
// resolve PLT slot values at load-time. This is contrary to the
// regular symbol resolution scheme in which symbols are resolved just
@@ -354,20 +354,20 @@ public:
// For DSO symbols, we always call them through PLT slots anyway.
// So there's no difference between GNU ifunc and regular function
// symbols if they are in DSOs. So we can handle GNU_IFUNC as FUNC.
- if (this->Type == llvm::ELF::STT_GNU_IFUNC)
- this->Type = llvm::ELF::STT_FUNC;
+ if (this->type == llvm::ELF::STT_GNU_IFUNC)
+ this->type = llvm::ELF::STT_FUNC;
}
- SharedFile &getFile() const { return *cast<SharedFile>(File); }
+ SharedFile &getFile() const { return *cast<SharedFile>(file); }
- uint64_t Value; // st_value
- uint64_t Size; // st_size
- uint32_t Alignment;
+ uint64_t value; // st_value
+ uint64_t size; // st_size
+ uint32_t alignment;
// This is true if there has been at least one undefined reference to the
// symbol. The binding may change to STB_WEAK if the first undefined reference
// is weak.
- bool Referenced = false;
+ bool referenced = false;
};
// LazyArchive and LazyObject represent a symbols that is not yet in the link,
@@ -386,78 +386,78 @@ public:
// symbol.
class LazyArchive : public Symbol {
public:
- LazyArchive(InputFile &File, const llvm::object::Archive::Symbol S)
- : Symbol(LazyArchiveKind, &File, S.getName(), llvm::ELF::STB_GLOBAL,
+ LazyArchive(InputFile &file, const llvm::object::Archive::Symbol s)
+ : Symbol(LazyArchiveKind, &file, s.getName(), llvm::ELF::STB_GLOBAL,
llvm::ELF::STV_DEFAULT, llvm::ELF::STT_NOTYPE),
- Sym(S) {}
+ sym(s) {}
- static bool classof(const Symbol *S) { return S->kind() == LazyArchiveKind; }
+ static bool classof(const Symbol *s) { return s->kind() == LazyArchiveKind; }
MemoryBufferRef getMemberBuffer();
- const llvm::object::Archive::Symbol Sym;
+ const llvm::object::Archive::Symbol sym;
};
// LazyObject symbols represents symbols in object files between
// --start-lib and --end-lib options.
class LazyObject : public Symbol {
public:
- LazyObject(InputFile &File, StringRef Name)
- : Symbol(LazyObjectKind, &File, Name, llvm::ELF::STB_GLOBAL,
+ LazyObject(InputFile &file, StringRef name)
+ : Symbol(LazyObjectKind, &file, name, llvm::ELF::STB_GLOBAL,
llvm::ELF::STV_DEFAULT, llvm::ELF::STT_NOTYPE) {}
- static bool classof(const Symbol *S) { return S->kind() == LazyObjectKind; }
+ static bool classof(const Symbol *s) { return s->kind() == LazyObjectKind; }
};
// Some linker-generated symbols need to be created as
// Defined symbols.
struct ElfSym {
// __bss_start
- static Defined *Bss;
+ static Defined *bss;
// etext and _etext
- static Defined *Etext1;
- static Defined *Etext2;
+ static Defined *etext1;
+ static Defined *etext2;
// edata and _edata
- static Defined *Edata1;
- static Defined *Edata2;
+ static Defined *edata1;
+ static Defined *edata2;
// end and _end
- static Defined *End1;
- static Defined *End2;
+ static Defined *end1;
+ static Defined *end2;
// The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention to
// be at some offset from the base of the .got section, usually 0 or
// the end of the .got.
- static Defined *GlobalOffsetTable;
+ static Defined *globalOffsetTable;
// _gp, _gp_disp and __gnu_local_gp symbols. Only for MIPS.
- static Defined *MipsGp;
- static Defined *MipsGpDisp;
- static Defined *MipsLocalGp;
+ static Defined *mipsGp;
+ static Defined *mipsGpDisp;
+ static Defined *mipsLocalGp;
// __rel{,a}_iplt_{start,end} symbols.
- static Defined *RelaIpltStart;
- static Defined *RelaIpltEnd;
+ static Defined *relaIpltStart;
+ static Defined *relaIpltEnd;
// __global_pointer$ for RISC-V.
- static Defined *RISCVGlobalPointer;
+ static Defined *riscvGlobalPointer;
// _TLS_MODULE_BASE_ on targets that support TLSDESC.
- static Defined *TlsModuleBase;
+ static Defined *tlsModuleBase;
};
// A buffer class that is large enough to hold any Symbol-derived
// object. We allocate memory using this class and instantiate a symbol
// using the placement new.
union SymbolUnion {
- alignas(Defined) char A[sizeof(Defined)];
- alignas(CommonSymbol) char B[sizeof(CommonSymbol)];
- alignas(Undefined) char C[sizeof(Undefined)];
- alignas(SharedSymbol) char D[sizeof(SharedSymbol)];
- alignas(LazyArchive) char E[sizeof(LazyArchive)];
- alignas(LazyObject) char F[sizeof(LazyObject)];
+ alignas(Defined) char a[sizeof(Defined)];
+ alignas(CommonSymbol) char b[sizeof(CommonSymbol)];
+ alignas(Undefined) char c[sizeof(Undefined)];
+ alignas(SharedSymbol) char d[sizeof(SharedSymbol)];
+ alignas(LazyArchive) char e[sizeof(LazyArchive)];
+ alignas(LazyObject) char f[sizeof(LazyObject)];
};
// It is important to keep the size of SymbolUnion small for performance and
@@ -482,7 +482,7 @@ static inline void assertSymbols() {
AssertSymbol<LazyObject>();
}
-void printTraceSymbol(const Symbol *Sym);
+void printTraceSymbol(const Symbol *sym);
size_t Symbol::getSymbolSize() const {
switch (kind()) {
@@ -515,39 +515,39 @@ void Symbol::replace(const Symbol &New)
// non-TLS relocations, so there's a clear distinction between TLS
// and non-TLS symbols. It is an error if the same symbol is defined
// as a TLS symbol in one file and as a non-TLS symbol in other file.
- if (SymbolKind != PlaceholderKind && !isLazy() && !New.isLazy()) {
- bool TlsMismatch = (Type == STT_TLS && New.Type != STT_TLS) ||
- (Type != STT_TLS && New.Type == STT_TLS);
- if (TlsMismatch)
+ if (symbolKind != PlaceholderKind && !isLazy() && !New.isLazy()) {
+ bool tlsMismatch = (type == STT_TLS && New.type != STT_TLS) ||
+ (type != STT_TLS && New.type == STT_TLS);
+ if (tlsMismatch)
error("TLS attribute mismatch: " + toString(*this) + "\n>>> defined in " +
- toString(New.File) + "\n>>> defined in " + toString(File));
+ toString(New.file) + "\n>>> defined in " + toString(file));
}
- Symbol Old = *this;
+ Symbol old = *this;
memcpy(this, &New, New.getSymbolSize());
- VersionId = Old.VersionId;
- Visibility = Old.Visibility;
- IsUsedInRegularObj = Old.IsUsedInRegularObj;
- ExportDynamic = Old.ExportDynamic;
- CanInline = Old.CanInline;
- Traced = Old.Traced;
- IsPreemptible = Old.IsPreemptible;
- ScriptDefined = Old.ScriptDefined;
- Partition = Old.Partition;
+ versionId = old.versionId;
+ visibility = old.visibility;
+ isUsedInRegularObj = old.isUsedInRegularObj;
+ exportDynamic = old.exportDynamic;
+ canInline = old.canInline;
+ traced = old.traced;
+ isPreemptible = old.isPreemptible;
+ scriptDefined = old.scriptDefined;
+ partition = old.partition;
// Symbol length is computed lazily. If we already know a symbol length,
// propagate it.
- if (NameData == Old.NameData && NameSize == 0 && Old.NameSize != 0)
- NameSize = Old.NameSize;
+ if (nameData == old.nameData && nameSize == 0 && old.nameSize != 0)
+ nameSize = old.nameSize;
// Print out a log message if --trace-symbol was specified.
// This is for debugging.
- if (Traced)
+ if (traced)
printTraceSymbol(this);
}
-void maybeWarnUnorderableSymbol(const Symbol *Sym);
+void maybeWarnUnorderableSymbol(const Symbol *sym);
} // namespace elf
} // namespace lld
Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=365595&r1=365594&r2=365595&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Tue Jul 9 22:00:37 2019
@@ -52,17 +52,17 @@ using llvm::support::endian::read32le;
using llvm::support::endian::write32le;
using llvm::support::endian::write64le;
-constexpr size_t MergeNoTailSection::NumShards;
+constexpr size_t MergeNoTailSection::numShards;
-static uint64_t readUint(uint8_t *Buf) {
- return Config->Is64 ? read64(Buf) : read32(Buf);
+static uint64_t readUint(uint8_t *buf) {
+ return config->is64 ? read64(buf) : read32(buf);
}
-static void writeUint(uint8_t *Buf, uint64_t Val) {
- if (Config->Is64)
- write64(Buf, Val);
+static void writeUint(uint8_t *buf, uint64_t val) {
+ if (config->is64)
+ write64(buf, val);
else
- write32(Buf, Val);
+ write32(buf, val);
}
// Returns an LLD version string.
@@ -70,12 +70,12 @@ static ArrayRef<uint8_t> getVersion() {
// Check LLD_VERSION first for ease of testing.
// You can get consistent output by using the environment variable.
// This is only for testing.
- StringRef S = getenv("LLD_VERSION");
- if (S.empty())
- S = Saver.save(Twine("Linker: ") + getLLDVersion());
+ StringRef s = getenv("LLD_VERSION");
+ if (s.empty())
+ s = Saver.save(Twine("Linker: ") + getLLDVersion());
// +1 to include the terminating '\0'.
- return {(const uint8_t *)S.data(), S.size() + 1};
+ return {(const uint8_t *)s.data(), s.size() + 1};
}
// Creates a .comment section containing LLD version info.
@@ -89,79 +89,79 @@ MergeInputSection *elf::createCommentSec
// .MIPS.abiflags section.
template <class ELFT>
-MipsAbiFlagsSection<ELFT>::MipsAbiFlagsSection(Elf_Mips_ABIFlags Flags)
+MipsAbiFlagsSection<ELFT>::MipsAbiFlagsSection(Elf_Mips_ABIFlags flags)
: SyntheticSection(SHF_ALLOC, SHT_MIPS_ABIFLAGS, 8, ".MIPS.abiflags"),
- Flags(Flags) {
- this->Entsize = sizeof(Elf_Mips_ABIFlags);
+ flags(flags) {
+ this->entsize = sizeof(Elf_Mips_ABIFlags);
}
-template <class ELFT> void MipsAbiFlagsSection<ELFT>::writeTo(uint8_t *Buf) {
- memcpy(Buf, &Flags, sizeof(Flags));
+template <class ELFT> void MipsAbiFlagsSection<ELFT>::writeTo(uint8_t *buf) {
+ memcpy(buf, &flags, sizeof(flags));
}
template <class ELFT>
MipsAbiFlagsSection<ELFT> *MipsAbiFlagsSection<ELFT>::create() {
- Elf_Mips_ABIFlags Flags = {};
- bool Create = false;
+ Elf_Mips_ABIFlags flags = {};
+ bool create = false;
- for (InputSectionBase *Sec : InputSections) {
- if (Sec->Type != SHT_MIPS_ABIFLAGS)
+ for (InputSectionBase *sec : inputSections) {
+ if (sec->type != SHT_MIPS_ABIFLAGS)
continue;
- Sec->markDead();
- Create = true;
+ sec->markDead();
+ create = true;
- std::string Filename = toString(Sec->File);
- const size_t Size = Sec->data().size();
+ std::string filename = toString(sec->file);
+ const size_t size = sec->data().size();
// Older version of BFD (such as the default FreeBSD linker) concatenate
// .MIPS.abiflags instead of merging. To allow for this case (or potential
// zero padding) we ignore everything after the first Elf_Mips_ABIFlags
- if (Size < sizeof(Elf_Mips_ABIFlags)) {
- error(Filename + ": invalid size of .MIPS.abiflags section: got " +
- Twine(Size) + " instead of " + Twine(sizeof(Elf_Mips_ABIFlags)));
+ if (size < sizeof(Elf_Mips_ABIFlags)) {
+ error(filename + ": invalid size of .MIPS.abiflags section: got " +
+ Twine(size) + " instead of " + Twine(sizeof(Elf_Mips_ABIFlags)));
return nullptr;
}
- auto *S = reinterpret_cast<const Elf_Mips_ABIFlags *>(Sec->data().data());
- if (S->version != 0) {
- error(Filename + ": unexpected .MIPS.abiflags version " +
- Twine(S->version));
+ auto *s = reinterpret_cast<const Elf_Mips_ABIFlags *>(sec->data().data());
+ if (s->version != 0) {
+ error(filename + ": unexpected .MIPS.abiflags version " +
+ Twine(s->version));
return nullptr;
}
// LLD checks ISA compatibility in calcMipsEFlags(). Here we just
// select the highest number of ISA/Rev/Ext.
- Flags.isa_level = std::max(Flags.isa_level, S->isa_level);
- Flags.isa_rev = std::max(Flags.isa_rev, S->isa_rev);
- Flags.isa_ext = std::max(Flags.isa_ext, S->isa_ext);
- Flags.gpr_size = std::max(Flags.gpr_size, S->gpr_size);
- Flags.cpr1_size = std::max(Flags.cpr1_size, S->cpr1_size);
- Flags.cpr2_size = std::max(Flags.cpr2_size, S->cpr2_size);
- Flags.ases |= S->ases;
- Flags.flags1 |= S->flags1;
- Flags.flags2 |= S->flags2;
- Flags.fp_abi = elf::getMipsFpAbiFlag(Flags.fp_abi, S->fp_abi, Filename);
+ flags.isa_level = std::max(flags.isa_level, s->isa_level);
+ flags.isa_rev = std::max(flags.isa_rev, s->isa_rev);
+ flags.isa_ext = std::max(flags.isa_ext, s->isa_ext);
+ flags.gpr_size = std::max(flags.gpr_size, s->gpr_size);
+ flags.cpr1_size = std::max(flags.cpr1_size, s->cpr1_size);
+ flags.cpr2_size = std::max(flags.cpr2_size, s->cpr2_size);
+ flags.ases |= s->ases;
+ flags.flags1 |= s->flags1;
+ flags.flags2 |= s->flags2;
+ flags.fp_abi = elf::getMipsFpAbiFlag(flags.fp_abi, s->fp_abi, filename);
};
- if (Create)
- return make<MipsAbiFlagsSection<ELFT>>(Flags);
+ if (create)
+ return make<MipsAbiFlagsSection<ELFT>>(flags);
return nullptr;
}
// .MIPS.options section.
template <class ELFT>
-MipsOptionsSection<ELFT>::MipsOptionsSection(Elf_Mips_RegInfo Reginfo)
+MipsOptionsSection<ELFT>::MipsOptionsSection(Elf_Mips_RegInfo reginfo)
: SyntheticSection(SHF_ALLOC, SHT_MIPS_OPTIONS, 8, ".MIPS.options"),
- Reginfo(Reginfo) {
- this->Entsize = sizeof(Elf_Mips_Options) + sizeof(Elf_Mips_RegInfo);
+ reginfo(reginfo) {
+ this->entsize = sizeof(Elf_Mips_Options) + sizeof(Elf_Mips_RegInfo);
}
-template <class ELFT> void MipsOptionsSection<ELFT>::writeTo(uint8_t *Buf) {
- auto *Options = reinterpret_cast<Elf_Mips_Options *>(Buf);
- Options->kind = ODK_REGINFO;
- Options->size = getSize();
-
- if (!Config->Relocatable)
- Reginfo.ri_gp_value = In.MipsGot->getGp();
- memcpy(Buf + sizeof(Elf_Mips_Options), &Reginfo, sizeof(Reginfo));
+template <class ELFT> void MipsOptionsSection<ELFT>::writeTo(uint8_t *buf) {
+ auto *options = reinterpret_cast<Elf_Mips_Options *>(buf);
+ options->kind = ODK_REGINFO;
+ options->size = getSize();
+
+ if (!config->relocatable)
+ reginfo.ri_gp_value = in.mipsGot->getGp();
+ memcpy(buf + sizeof(Elf_Mips_Options), ®info, sizeof(reginfo));
}
template <class ELFT>
@@ -170,55 +170,55 @@ MipsOptionsSection<ELFT> *MipsOptionsSec
if (!ELFT::Is64Bits)
return nullptr;
- std::vector<InputSectionBase *> Sections;
- for (InputSectionBase *Sec : InputSections)
- if (Sec->Type == SHT_MIPS_OPTIONS)
- Sections.push_back(Sec);
+ std::vector<InputSectionBase *> sections;
+ for (InputSectionBase *sec : inputSections)
+ if (sec->type == SHT_MIPS_OPTIONS)
+ sections.push_back(sec);
- if (Sections.empty())
+ if (sections.empty())
return nullptr;
- Elf_Mips_RegInfo Reginfo = {};
- for (InputSectionBase *Sec : Sections) {
- Sec->markDead();
-
- std::string Filename = toString(Sec->File);
- ArrayRef<uint8_t> D = Sec->data();
-
- while (!D.empty()) {
- if (D.size() < sizeof(Elf_Mips_Options)) {
- error(Filename + ": invalid size of .MIPS.options section");
+ Elf_Mips_RegInfo reginfo = {};
+ for (InputSectionBase *sec : sections) {
+ sec->markDead();
+
+ std::string filename = toString(sec->file);
+ ArrayRef<uint8_t> d = sec->data();
+
+ while (!d.empty()) {
+ if (d.size() < sizeof(Elf_Mips_Options)) {
+ error(filename + ": invalid size of .MIPS.options section");
break;
}
- auto *Opt = reinterpret_cast<const Elf_Mips_Options *>(D.data());
- if (Opt->kind == ODK_REGINFO) {
- Reginfo.ri_gprmask |= Opt->getRegInfo().ri_gprmask;
- Sec->getFile<ELFT>()->MipsGp0 = Opt->getRegInfo().ri_gp_value;
+ auto *opt = reinterpret_cast<const Elf_Mips_Options *>(d.data());
+ if (opt->kind == ODK_REGINFO) {
+ reginfo.ri_gprmask |= opt->getRegInfo().ri_gprmask;
+ sec->getFile<ELFT>()->mipsGp0 = opt->getRegInfo().ri_gp_value;
break;
}
- if (!Opt->size)
- fatal(Filename + ": zero option descriptor size");
- D = D.slice(Opt->size);
+ if (!opt->size)
+ fatal(filename + ": zero option descriptor size");
+ d = d.slice(opt->size);
}
};
- return make<MipsOptionsSection<ELFT>>(Reginfo);
+ return make<MipsOptionsSection<ELFT>>(reginfo);
}
// MIPS .reginfo section.
template <class ELFT>
-MipsReginfoSection<ELFT>::MipsReginfoSection(Elf_Mips_RegInfo Reginfo)
+MipsReginfoSection<ELFT>::MipsReginfoSection(Elf_Mips_RegInfo reginfo)
: SyntheticSection(SHF_ALLOC, SHT_MIPS_REGINFO, 4, ".reginfo"),
- Reginfo(Reginfo) {
- this->Entsize = sizeof(Elf_Mips_RegInfo);
+ reginfo(reginfo) {
+ this->entsize = sizeof(Elf_Mips_RegInfo);
}
-template <class ELFT> void MipsReginfoSection<ELFT>::writeTo(uint8_t *Buf) {
- if (!Config->Relocatable)
- Reginfo.ri_gp_value = In.MipsGot->getGp();
- memcpy(Buf, &Reginfo, sizeof(Reginfo));
+template <class ELFT> void MipsReginfoSection<ELFT>::writeTo(uint8_t *buf) {
+ if (!config->relocatable)
+ reginfo.ri_gp_value = in.mipsGot->getGp();
+ memcpy(buf, ®info, sizeof(reginfo));
}
template <class ELFT>
@@ -227,53 +227,53 @@ MipsReginfoSection<ELFT> *MipsReginfoSec
if (ELFT::Is64Bits)
return nullptr;
- std::vector<InputSectionBase *> Sections;
- for (InputSectionBase *Sec : InputSections)
- if (Sec->Type == SHT_MIPS_REGINFO)
- Sections.push_back(Sec);
+ std::vector<InputSectionBase *> sections;
+ for (InputSectionBase *sec : inputSections)
+ if (sec->type == SHT_MIPS_REGINFO)
+ sections.push_back(sec);
- if (Sections.empty())
+ if (sections.empty())
return nullptr;
- Elf_Mips_RegInfo Reginfo = {};
- for (InputSectionBase *Sec : Sections) {
- Sec->markDead();
+ Elf_Mips_RegInfo reginfo = {};
+ for (InputSectionBase *sec : sections) {
+ sec->markDead();
- if (Sec->data().size() != sizeof(Elf_Mips_RegInfo)) {
- error(toString(Sec->File) + ": invalid size of .reginfo section");
+ if (sec->data().size() != sizeof(Elf_Mips_RegInfo)) {
+ error(toString(sec->file) + ": invalid size of .reginfo section");
return nullptr;
}
- auto *R = reinterpret_cast<const Elf_Mips_RegInfo *>(Sec->data().data());
- Reginfo.ri_gprmask |= R->ri_gprmask;
- Sec->getFile<ELFT>()->MipsGp0 = R->ri_gp_value;
+ auto *r = reinterpret_cast<const Elf_Mips_RegInfo *>(sec->data().data());
+ reginfo.ri_gprmask |= r->ri_gprmask;
+ sec->getFile<ELFT>()->mipsGp0 = r->ri_gp_value;
};
- return make<MipsReginfoSection<ELFT>>(Reginfo);
+ return make<MipsReginfoSection<ELFT>>(reginfo);
}
InputSection *elf::createInterpSection() {
// StringSaver guarantees that the returned string ends with '\0'.
- StringRef S = Saver.save(Config->DynamicLinker);
- ArrayRef<uint8_t> Contents = {(const uint8_t *)S.data(), S.size() + 1};
+ StringRef s = Saver.save(config->dynamicLinker);
+ ArrayRef<uint8_t> contents = {(const uint8_t *)s.data(), s.size() + 1};
- auto *Sec = make<InputSection>(nullptr, SHF_ALLOC, SHT_PROGBITS, 1, Contents,
+ auto *sec = make<InputSection>(nullptr, SHF_ALLOC, SHT_PROGBITS, 1, contents,
".interp");
- Sec->markLive();
- return Sec;
+ sec->markLive();
+ return sec;
}
-Defined *elf::addSyntheticLocal(StringRef Name, uint8_t Type, uint64_t Value,
- uint64_t Size, InputSectionBase &Section) {
- auto *S = make<Defined>(Section.File, Name, STB_LOCAL, STV_DEFAULT, Type,
- Value, Size, &Section);
- if (In.SymTab)
- In.SymTab->addSymbol(S);
- return S;
+Defined *elf::addSyntheticLocal(StringRef name, uint8_t type, uint64_t value,
+ uint64_t size, InputSectionBase §ion) {
+ auto *s = make<Defined>(section.file, name, STB_LOCAL, STV_DEFAULT, type,
+ value, size, §ion);
+ if (in.symTab)
+ in.symTab->addSymbol(s);
+ return s;
}
static size_t getHashSize() {
- switch (Config->BuildId) {
+ switch (config->buildId) {
case BuildIdKind::Fast:
return 8;
case BuildIdKind::Md5:
@@ -282,7 +282,7 @@ static size_t getHashSize() {
case BuildIdKind::Sha1:
return 20;
case BuildIdKind::Hexstring:
- return Config->BuildIdVector.size();
+ return config->buildIdVector.size();
default:
llvm_unreachable("unknown BuildIdKind");
}
@@ -304,45 +304,45 @@ GnuPropertySection::GnuPropertySection()
: SyntheticSection(llvm::ELF::SHF_ALLOC, llvm::ELF::SHT_NOTE, 4,
".note.gnu.property") {}
-void GnuPropertySection::writeTo(uint8_t *Buf) {
- uint32_t FeatureAndType = Config->EMachine == EM_AARCH64
+void GnuPropertySection::writeTo(uint8_t *buf) {
+ uint32_t featureAndType = config->emachine == EM_AARCH64
? GNU_PROPERTY_AARCH64_FEATURE_1_AND
: GNU_PROPERTY_X86_FEATURE_1_AND;
- write32(Buf, 4); // Name size
- write32(Buf + 4, Config->Is64 ? 16 : 12); // Content size
- write32(Buf + 8, NT_GNU_PROPERTY_TYPE_0); // Type
- memcpy(Buf + 12, "GNU", 4); // Name string
- write32(Buf + 16, FeatureAndType); // Feature type
- write32(Buf + 20, 4); // Feature size
- write32(Buf + 24, Config->AndFeatures); // Feature flags
- if (Config->Is64)
- write32(Buf + 28, 0); // Padding
+ write32(buf, 4); // Name size
+ write32(buf + 4, config->is64 ? 16 : 12); // Content size
+ write32(buf + 8, NT_GNU_PROPERTY_TYPE_0); // Type
+ memcpy(buf + 12, "GNU", 4); // Name string
+ write32(buf + 16, featureAndType); // Feature type
+ write32(buf + 20, 4); // Feature size
+ write32(buf + 24, config->andFeatures); // Feature flags
+ if (config->is64)
+ write32(buf + 28, 0); // Padding
}
-size_t GnuPropertySection::getSize() const { return Config->Is64 ? 32 : 28; }
+size_t GnuPropertySection::getSize() const { return config->is64 ? 32 : 28; }
BuildIdSection::BuildIdSection()
: SyntheticSection(SHF_ALLOC, SHT_NOTE, 4, ".note.gnu.build-id"),
- HashSize(getHashSize()) {}
+ hashSize(getHashSize()) {}
-void BuildIdSection::writeTo(uint8_t *Buf) {
- write32(Buf, 4); // Name size
- write32(Buf + 4, HashSize); // Content size
- write32(Buf + 8, NT_GNU_BUILD_ID); // Type
- memcpy(Buf + 12, "GNU", 4); // Name string
- HashBuf = Buf + 16;
+void BuildIdSection::writeTo(uint8_t *buf) {
+ write32(buf, 4); // Name size
+ write32(buf + 4, hashSize); // Content size
+ write32(buf + 8, NT_GNU_BUILD_ID); // Type
+ memcpy(buf + 12, "GNU", 4); // Name string
+ hashBuf = buf + 16;
}
-void BuildIdSection::writeBuildId(ArrayRef<uint8_t> Buf) {
- assert(Buf.size() == HashSize);
- memcpy(HashBuf, Buf.data(), HashSize);
+void BuildIdSection::writeBuildId(ArrayRef<uint8_t> buf) {
+ assert(buf.size() == hashSize);
+ memcpy(hashBuf, buf.data(), hashSize);
}
-BssSection::BssSection(StringRef Name, uint64_t Size, uint32_t Alignment)
- : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_NOBITS, Alignment, Name) {
- this->Bss = true;
- this->Size = Size;
+BssSection::BssSection(StringRef name, uint64_t size, uint32_t alignment)
+ : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_NOBITS, alignment, name) {
+ this->bss = true;
+ this->size = size;
}
EhFrameSection::EhFrameSection()
@@ -352,48 +352,48 @@ EhFrameSection::EhFrameSection()
// CIE records from input object files are uniquified by their contents
// and where their relocations point to.
template <class ELFT, class RelTy>
-CieRecord *EhFrameSection::addCie(EhSectionPiece &Cie, ArrayRef<RelTy> Rels) {
- Symbol *Personality = nullptr;
- unsigned FirstRelI = Cie.FirstRelocation;
- if (FirstRelI != (unsigned)-1)
- Personality =
- &Cie.Sec->template getFile<ELFT>()->getRelocTargetSym(Rels[FirstRelI]);
+CieRecord *EhFrameSection::addCie(EhSectionPiece &cie, ArrayRef<RelTy> rels) {
+ Symbol *personality = nullptr;
+ unsigned firstRelI = cie.firstRelocation;
+ if (firstRelI != (unsigned)-1)
+ personality =
+ &cie.sec->template getFile<ELFT>()->getRelocTargetSym(rels[firstRelI]);
// Search for an existing CIE by CIE contents/relocation target pair.
- CieRecord *&Rec = CieMap[{Cie.data(), Personality}];
+ CieRecord *&rec = cieMap[{cie.data(), personality}];
// If not found, create a new one.
- if (!Rec) {
- Rec = make<CieRecord>();
- Rec->Cie = &Cie;
- CieRecords.push_back(Rec);
+ if (!rec) {
+ rec = make<CieRecord>();
+ rec->cie = &cie;
+ cieRecords.push_back(rec);
}
- return Rec;
+ return rec;
}
// There is one FDE per function. Returns true if a given FDE
// points to a live function.
template <class ELFT, class RelTy>
-bool EhFrameSection::isFdeLive(EhSectionPiece &Fde, ArrayRef<RelTy> Rels) {
- auto *Sec = cast<EhInputSection>(Fde.Sec);
- unsigned FirstRelI = Fde.FirstRelocation;
+bool EhFrameSection::isFdeLive(EhSectionPiece &fde, ArrayRef<RelTy> rels) {
+ auto *sec = cast<EhInputSection>(fde.sec);
+ unsigned firstRelI = fde.firstRelocation;
// An FDE should point to some function because FDEs are to describe
// functions. That's however not always the case due to an issue of
// ld.gold with -r. ld.gold may discard only functions and leave their
// corresponding FDEs, which results in creating bad .eh_frame sections.
// To deal with that, we ignore such FDEs.
- if (FirstRelI == (unsigned)-1)
+ if (firstRelI == (unsigned)-1)
return false;
- const RelTy &Rel = Rels[FirstRelI];
- Symbol &B = Sec->template getFile<ELFT>()->getRelocTargetSym(Rel);
+ const RelTy &rel = rels[firstRelI];
+ Symbol &b = sec->template getFile<ELFT>()->getRelocTargetSym(rel);
// FDEs for garbage-collected or merged-by-ICF sections, or sections in
// another partition, are dead.
- if (auto *D = dyn_cast<Defined>(&B))
- if (SectionBase *Sec = D->Section)
- return Sec->Partition == Partition;
+ if (auto *d = dyn_cast<Defined>(&b))
+ if (SectionBase *sec = d->section)
+ return sec->partition == partition;
return false;
}
@@ -402,73 +402,73 @@ bool EhFrameSection::isFdeLive(EhSection
// a list of FDEs. This function searches an existing CIE or create a new
// one and associates FDEs to the CIE.
template <class ELFT, class RelTy>
-void EhFrameSection::addSectionAux(EhInputSection *Sec, ArrayRef<RelTy> Rels) {
- OffsetToCie.clear();
- for (EhSectionPiece &Piece : Sec->Pieces) {
+void EhFrameSection::addSectionAux(EhInputSection *sec, ArrayRef<RelTy> rels) {
+ offsetToCie.clear();
+ for (EhSectionPiece &piece : sec->pieces) {
// The empty record is the end marker.
- if (Piece.Size == 4)
+ if (piece.size == 4)
return;
- size_t Offset = Piece.InputOff;
- uint32_t ID = read32(Piece.data().data() + 4);
- if (ID == 0) {
- OffsetToCie[Offset] = addCie<ELFT>(Piece, Rels);
+ size_t offset = piece.inputOff;
+ uint32_t id = read32(piece.data().data() + 4);
+ if (id == 0) {
+ offsetToCie[offset] = addCie<ELFT>(piece, rels);
continue;
}
- uint32_t CieOffset = Offset + 4 - ID;
- CieRecord *Rec = OffsetToCie[CieOffset];
- if (!Rec)
- fatal(toString(Sec) + ": invalid CIE reference");
+ uint32_t cieOffset = offset + 4 - id;
+ CieRecord *rec = offsetToCie[cieOffset];
+ if (!rec)
+ fatal(toString(sec) + ": invalid CIE reference");
- if (!isFdeLive<ELFT>(Piece, Rels))
+ if (!isFdeLive<ELFT>(piece, rels))
continue;
- Rec->Fdes.push_back(&Piece);
- NumFdes++;
+ rec->fdes.push_back(&piece);
+ numFdes++;
}
}
-template <class ELFT> void EhFrameSection::addSection(InputSectionBase *C) {
- auto *Sec = cast<EhInputSection>(C);
- Sec->Parent = this;
+template <class ELFT> void EhFrameSection::addSection(InputSectionBase *c) {
+ auto *sec = cast<EhInputSection>(c);
+ sec->parent = this;
- Alignment = std::max(Alignment, Sec->Alignment);
- Sections.push_back(Sec);
+ alignment = std::max(alignment, sec->alignment);
+ sections.push_back(sec);
- for (auto *DS : Sec->DependentSections)
- DependentSections.push_back(DS);
+ for (auto *ds : sec->dependentSections)
+ dependentSections.push_back(ds);
- if (Sec->Pieces.empty())
+ if (sec->pieces.empty())
return;
- if (Sec->AreRelocsRela)
- addSectionAux<ELFT>(Sec, Sec->template relas<ELFT>());
+ if (sec->areRelocsRela)
+ addSectionAux<ELFT>(sec, sec->template relas<ELFT>());
else
- addSectionAux<ELFT>(Sec, Sec->template rels<ELFT>());
+ addSectionAux<ELFT>(sec, sec->template rels<ELFT>());
}
-static void writeCieFde(uint8_t *Buf, ArrayRef<uint8_t> D) {
- memcpy(Buf, D.data(), D.size());
+static void writeCieFde(uint8_t *buf, ArrayRef<uint8_t> d) {
+ memcpy(buf, d.data(), d.size());
- size_t Aligned = alignTo(D.size(), Config->Wordsize);
+ size_t aligned = alignTo(d.size(), config->wordsize);
// Zero-clear trailing padding if it exists.
- memset(Buf + D.size(), 0, Aligned - D.size());
+ memset(buf + d.size(), 0, aligned - d.size());
// Fix the size field. -4 since size does not include the size field itself.
- write32(Buf, Aligned - 4);
+ write32(buf, aligned - 4);
}
void EhFrameSection::finalizeContents() {
- assert(!this->Size); // Not finalized.
- size_t Off = 0;
- for (CieRecord *Rec : CieRecords) {
- Rec->Cie->OutputOff = Off;
- Off += alignTo(Rec->Cie->Size, Config->Wordsize);
-
- for (EhSectionPiece *Fde : Rec->Fdes) {
- Fde->OutputOff = Off;
- Off += alignTo(Fde->Size, Config->Wordsize);
+ assert(!this->size); // Not finalized.
+ size_t off = 0;
+ for (CieRecord *rec : cieRecords) {
+ rec->cie->outputOff = off;
+ off += alignTo(rec->cie->size, config->wordsize);
+
+ for (EhSectionPiece *fde : rec->fdes) {
+ fde->outputOff = off;
+ off += alignTo(fde->size, config->wordsize);
}
}
@@ -476,376 +476,376 @@ void EhFrameSection::finalizeContents()
// Call Frame Information records. glibc unwind-dw2-fde.c
// classify_object_over_fdes expects there is a CIE record length 0 as a
// terminator. Thus we add one unconditionally.
- Off += 4;
+ off += 4;
- this->Size = Off;
+ this->size = off;
}
// Returns data for .eh_frame_hdr. .eh_frame_hdr is a binary search table
// to get an FDE from an address to which FDE is applied. This function
// returns a list of such pairs.
std::vector<EhFrameSection::FdeData> EhFrameSection::getFdeData() const {
- uint8_t *Buf = Out::BufferStart + getParent()->Offset + OutSecOff;
- std::vector<FdeData> Ret;
+ uint8_t *buf = Out::bufferStart + getParent()->offset + outSecOff;
+ std::vector<FdeData> ret;
- uint64_t VA = getPartition().EhFrameHdr->getVA();
- for (CieRecord *Rec : CieRecords) {
- uint8_t Enc = getFdeEncoding(Rec->Cie);
- for (EhSectionPiece *Fde : Rec->Fdes) {
- uint64_t Pc = getFdePc(Buf, Fde->OutputOff, Enc);
- uint64_t FdeVA = getParent()->Addr + Fde->OutputOff;
- if (!isInt<32>(Pc - VA))
- fatal(toString(Fde->Sec) + ": PC offset is too large: 0x" +
- Twine::utohexstr(Pc - VA));
- Ret.push_back({uint32_t(Pc - VA), uint32_t(FdeVA - VA)});
+ uint64_t va = getPartition().ehFrameHdr->getVA();
+ for (CieRecord *rec : cieRecords) {
+ uint8_t enc = getFdeEncoding(rec->cie);
+ for (EhSectionPiece *fde : rec->fdes) {
+ uint64_t pc = getFdePc(buf, fde->outputOff, enc);
+ uint64_t fdeVA = getParent()->addr + fde->outputOff;
+ if (!isInt<32>(pc - va))
+ fatal(toString(fde->sec) + ": PC offset is too large: 0x" +
+ Twine::utohexstr(pc - va));
+ ret.push_back({uint32_t(pc - va), uint32_t(fdeVA - va)});
}
}
// Sort the FDE list by their PC and uniqueify. Usually there is only
// one FDE for a PC (i.e. function), but if ICF merges two functions
// into one, there can be more than one FDEs pointing to the address.
- auto Less = [](const FdeData &A, const FdeData &B) {
- return A.PcRel < B.PcRel;
+ auto less = [](const FdeData &a, const FdeData &b) {
+ return a.pcRel < b.pcRel;
};
- llvm::stable_sort(Ret, Less);
- auto Eq = [](const FdeData &A, const FdeData &B) {
- return A.PcRel == B.PcRel;
+ llvm::stable_sort(ret, less);
+ auto eq = [](const FdeData &a, const FdeData &b) {
+ return a.pcRel == b.pcRel;
};
- Ret.erase(std::unique(Ret.begin(), Ret.end(), Eq), Ret.end());
+ ret.erase(std::unique(ret.begin(), ret.end(), eq), ret.end());
- return Ret;
+ return ret;
}
-static uint64_t readFdeAddr(uint8_t *Buf, int Size) {
- switch (Size) {
+static uint64_t readFdeAddr(uint8_t *buf, int size) {
+ switch (size) {
case DW_EH_PE_udata2:
- return read16(Buf);
+ return read16(buf);
case DW_EH_PE_sdata2:
- return (int16_t)read16(Buf);
+ return (int16_t)read16(buf);
case DW_EH_PE_udata4:
- return read32(Buf);
+ return read32(buf);
case DW_EH_PE_sdata4:
- return (int32_t)read32(Buf);
+ return (int32_t)read32(buf);
case DW_EH_PE_udata8:
case DW_EH_PE_sdata8:
- return read64(Buf);
+ return read64(buf);
case DW_EH_PE_absptr:
- return readUint(Buf);
+ return readUint(buf);
}
fatal("unknown FDE size encoding");
}
// Returns the VA to which a given FDE (on a mmap'ed buffer) is applied to.
// We need it to create .eh_frame_hdr section.
-uint64_t EhFrameSection::getFdePc(uint8_t *Buf, size_t FdeOff,
- uint8_t Enc) const {
+uint64_t EhFrameSection::getFdePc(uint8_t *buf, size_t fdeOff,
+ uint8_t enc) const {
// The starting address to which this FDE applies is
// stored at FDE + 8 byte.
- size_t Off = FdeOff + 8;
- uint64_t Addr = readFdeAddr(Buf + Off, Enc & 0xf);
- if ((Enc & 0x70) == DW_EH_PE_absptr)
- return Addr;
- if ((Enc & 0x70) == DW_EH_PE_pcrel)
- return Addr + getParent()->Addr + Off;
+ size_t off = fdeOff + 8;
+ uint64_t addr = readFdeAddr(buf + off, enc & 0xf);
+ if ((enc & 0x70) == DW_EH_PE_absptr)
+ return addr;
+ if ((enc & 0x70) == DW_EH_PE_pcrel)
+ return addr + getParent()->addr + off;
fatal("unknown FDE size relative encoding");
}
-void EhFrameSection::writeTo(uint8_t *Buf) {
+void EhFrameSection::writeTo(uint8_t *buf) {
// Write CIE and FDE records.
- for (CieRecord *Rec : CieRecords) {
- size_t CieOffset = Rec->Cie->OutputOff;
- writeCieFde(Buf + CieOffset, Rec->Cie->data());
-
- for (EhSectionPiece *Fde : Rec->Fdes) {
- size_t Off = Fde->OutputOff;
- writeCieFde(Buf + Off, Fde->data());
+ for (CieRecord *rec : cieRecords) {
+ size_t cieOffset = rec->cie->outputOff;
+ writeCieFde(buf + cieOffset, rec->cie->data());
+
+ for (EhSectionPiece *fde : rec->fdes) {
+ size_t off = fde->outputOff;
+ writeCieFde(buf + off, fde->data());
// FDE's second word should have the offset to an associated CIE.
// Write it.
- write32(Buf + Off + 4, Off + 4 - CieOffset);
+ write32(buf + off + 4, off + 4 - cieOffset);
}
}
// Apply relocations. .eh_frame section contents are not contiguous
// in the output buffer, but relocateAlloc() still works because
// getOffset() takes care of discontiguous section pieces.
- for (EhInputSection *S : Sections)
- S->relocateAlloc(Buf, nullptr);
+ for (EhInputSection *s : sections)
+ s->relocateAlloc(buf, nullptr);
- if (getPartition().EhFrameHdr && getPartition().EhFrameHdr->getParent())
- getPartition().EhFrameHdr->write();
+ if (getPartition().ehFrameHdr && getPartition().ehFrameHdr->getParent())
+ getPartition().ehFrameHdr->write();
}
GotSection::GotSection()
- : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, Config->Wordsize,
+ : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, config->wordsize,
".got") {
// PPC64 saves the ElfSym::GlobalOffsetTable .TOC. as the first entry in the
// .got. If there are no references to .TOC. in the symbol table,
// ElfSym::GlobalOffsetTable will not be defined and we won't need to save
// .TOC. in the .got. When it is defined, we increase NumEntries by the number
// of entries used to emit ElfSym::GlobalOffsetTable.
- if (ElfSym::GlobalOffsetTable && !Target->GotBaseSymInGotPlt)
- NumEntries += Target->GotHeaderEntriesNum;
+ if (ElfSym::globalOffsetTable && !target->gotBaseSymInGotPlt)
+ numEntries += target->gotHeaderEntriesNum;
}
-void GotSection::addEntry(Symbol &Sym) {
- Sym.GotIndex = NumEntries;
- ++NumEntries;
+void GotSection::addEntry(Symbol &sym) {
+ sym.gotIndex = numEntries;
+ ++numEntries;
}
-bool GotSection::addDynTlsEntry(Symbol &Sym) {
- if (Sym.GlobalDynIndex != -1U)
+bool GotSection::addDynTlsEntry(Symbol &sym) {
+ if (sym.globalDynIndex != -1U)
return false;
- Sym.GlobalDynIndex = NumEntries;
+ sym.globalDynIndex = numEntries;
// Global Dynamic TLS entries take two GOT slots.
- NumEntries += 2;
+ numEntries += 2;
return true;
}
// Reserves TLS entries for a TLS module ID and a TLS block offset.
// In total it takes two GOT slots.
bool GotSection::addTlsIndex() {
- if (TlsIndexOff != uint32_t(-1))
+ if (tlsIndexOff != uint32_t(-1))
return false;
- TlsIndexOff = NumEntries * Config->Wordsize;
- NumEntries += 2;
+ tlsIndexOff = numEntries * config->wordsize;
+ numEntries += 2;
return true;
}
-uint64_t GotSection::getGlobalDynAddr(const Symbol &B) const {
- return this->getVA() + B.GlobalDynIndex * Config->Wordsize;
+uint64_t GotSection::getGlobalDynAddr(const Symbol &b) const {
+ return this->getVA() + b.globalDynIndex * config->wordsize;
}
-uint64_t GotSection::getGlobalDynOffset(const Symbol &B) const {
- return B.GlobalDynIndex * Config->Wordsize;
+uint64_t GotSection::getGlobalDynOffset(const Symbol &b) const {
+ return b.globalDynIndex * config->wordsize;
}
void GotSection::finalizeContents() {
- Size = NumEntries * Config->Wordsize;
+ size = numEntries * config->wordsize;
}
bool GotSection::isNeeded() const {
// We need to emit a GOT even if it's empty if there's a relocation that is
// relative to GOT(such as GOTOFFREL).
- return NumEntries || HasGotOffRel;
+ return numEntries || hasGotOffRel;
}
-void GotSection::writeTo(uint8_t *Buf) {
+void GotSection::writeTo(uint8_t *buf) {
// Buf points to the start of this section's buffer,
// whereas InputSectionBase::relocateAlloc() expects its argument
// to point to the start of the output section.
- Target->writeGotHeader(Buf);
- relocateAlloc(Buf - OutSecOff, Buf - OutSecOff + Size);
+ target->writeGotHeader(buf);
+ relocateAlloc(buf - outSecOff, buf - outSecOff + size);
}
-static uint64_t getMipsPageAddr(uint64_t Addr) {
- return (Addr + 0x8000) & ~0xffff;
+static uint64_t getMipsPageAddr(uint64_t addr) {
+ return (addr + 0x8000) & ~0xffff;
}
-static uint64_t getMipsPageCount(uint64_t Size) {
- return (Size + 0xfffe) / 0xffff + 1;
+static uint64_t getMipsPageCount(uint64_t size) {
+ return (size + 0xfffe) / 0xffff + 1;
}
MipsGotSection::MipsGotSection()
: SyntheticSection(SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL, SHT_PROGBITS, 16,
".got") {}
-void MipsGotSection::addEntry(InputFile &File, Symbol &Sym, int64_t Addend,
- RelExpr Expr) {
- FileGot &G = getGot(File);
- if (Expr == R_MIPS_GOT_LOCAL_PAGE) {
- if (const OutputSection *OS = Sym.getOutputSection())
- G.PagesMap.insert({OS, {}});
+void MipsGotSection::addEntry(InputFile &file, Symbol &sym, int64_t addend,
+ RelExpr expr) {
+ FileGot &g = getGot(file);
+ if (expr == R_MIPS_GOT_LOCAL_PAGE) {
+ if (const OutputSection *os = sym.getOutputSection())
+ g.pagesMap.insert({os, {}});
else
- G.Local16.insert({{nullptr, getMipsPageAddr(Sym.getVA(Addend))}, 0});
- } else if (Sym.isTls())
- G.Tls.insert({&Sym, 0});
- else if (Sym.IsPreemptible && Expr == R_ABS)
- G.Relocs.insert({&Sym, 0});
- else if (Sym.IsPreemptible)
- G.Global.insert({&Sym, 0});
- else if (Expr == R_MIPS_GOT_OFF32)
- G.Local32.insert({{&Sym, Addend}, 0});
+ g.local16.insert({{nullptr, getMipsPageAddr(sym.getVA(addend))}, 0});
+ } else if (sym.isTls())
+ g.tls.insert({&sym, 0});
+ else if (sym.isPreemptible && expr == R_ABS)
+ g.relocs.insert({&sym, 0});
+ else if (sym.isPreemptible)
+ g.global.insert({&sym, 0});
+ else if (expr == R_MIPS_GOT_OFF32)
+ g.local32.insert({{&sym, addend}, 0});
else
- G.Local16.insert({{&Sym, Addend}, 0});
+ g.local16.insert({{&sym, addend}, 0});
}
-void MipsGotSection::addDynTlsEntry(InputFile &File, Symbol &Sym) {
- getGot(File).DynTlsSymbols.insert({&Sym, 0});
+void MipsGotSection::addDynTlsEntry(InputFile &file, Symbol &sym) {
+ getGot(file).dynTlsSymbols.insert({&sym, 0});
}
-void MipsGotSection::addTlsIndex(InputFile &File) {
- getGot(File).DynTlsSymbols.insert({nullptr, 0});
+void MipsGotSection::addTlsIndex(InputFile &file) {
+ getGot(file).dynTlsSymbols.insert({nullptr, 0});
}
size_t MipsGotSection::FileGot::getEntriesNum() const {
- return getPageEntriesNum() + Local16.size() + Global.size() + Relocs.size() +
- Tls.size() + DynTlsSymbols.size() * 2;
+ return getPageEntriesNum() + local16.size() + global.size() + relocs.size() +
+ tls.size() + dynTlsSymbols.size() * 2;
}
size_t MipsGotSection::FileGot::getPageEntriesNum() const {
- size_t Num = 0;
- for (const std::pair<const OutputSection *, FileGot::PageBlock> &P : PagesMap)
- Num += P.second.Count;
- return Num;
+ size_t num = 0;
+ for (const std::pair<const OutputSection *, FileGot::PageBlock> &p : pagesMap)
+ num += p.second.count;
+ return num;
}
size_t MipsGotSection::FileGot::getIndexedEntriesNum() const {
- size_t Count = getPageEntriesNum() + Local16.size() + Global.size();
+ size_t count = getPageEntriesNum() + local16.size() + global.size();
// If there are relocation-only entries in the GOT, TLS entries
// are allocated after them. TLS entries should be addressable
// by 16-bit index so count both reloc-only and TLS entries.
- if (!Tls.empty() || !DynTlsSymbols.empty())
- Count += Relocs.size() + Tls.size() + DynTlsSymbols.size() * 2;
- return Count;
-}
-
-MipsGotSection::FileGot &MipsGotSection::getGot(InputFile &F) {
- if (!F.MipsGotIndex.hasValue()) {
- Gots.emplace_back();
- Gots.back().File = &F;
- F.MipsGotIndex = Gots.size() - 1;
- }
- return Gots[*F.MipsGotIndex];
-}
-
-uint64_t MipsGotSection::getPageEntryOffset(const InputFile *F,
- const Symbol &Sym,
- int64_t Addend) const {
- const FileGot &G = Gots[*F->MipsGotIndex];
- uint64_t Index = 0;
- if (const OutputSection *OutSec = Sym.getOutputSection()) {
- uint64_t SecAddr = getMipsPageAddr(OutSec->Addr);
- uint64_t SymAddr = getMipsPageAddr(Sym.getVA(Addend));
- Index = G.PagesMap.lookup(OutSec).FirstIndex + (SymAddr - SecAddr) / 0xffff;
+ if (!tls.empty() || !dynTlsSymbols.empty())
+ count += relocs.size() + tls.size() + dynTlsSymbols.size() * 2;
+ return count;
+}
+
+MipsGotSection::FileGot &MipsGotSection::getGot(InputFile &f) {
+ if (!f.mipsGotIndex.hasValue()) {
+ gots.emplace_back();
+ gots.back().file = &f;
+ f.mipsGotIndex = gots.size() - 1;
+ }
+ return gots[*f.mipsGotIndex];
+}
+
+uint64_t MipsGotSection::getPageEntryOffset(const InputFile *f,
+ const Symbol &sym,
+ int64_t addend) const {
+ const FileGot &g = gots[*f->mipsGotIndex];
+ uint64_t index = 0;
+ if (const OutputSection *outSec = sym.getOutputSection()) {
+ uint64_t secAddr = getMipsPageAddr(outSec->addr);
+ uint64_t symAddr = getMipsPageAddr(sym.getVA(addend));
+ index = g.pagesMap.lookup(outSec).firstIndex + (symAddr - secAddr) / 0xffff;
} else {
- Index = G.Local16.lookup({nullptr, getMipsPageAddr(Sym.getVA(Addend))});
+ index = g.local16.lookup({nullptr, getMipsPageAddr(sym.getVA(addend))});
}
- return Index * Config->Wordsize;
+ return index * config->wordsize;
}
-uint64_t MipsGotSection::getSymEntryOffset(const InputFile *F, const Symbol &S,
- int64_t Addend) const {
- const FileGot &G = Gots[*F->MipsGotIndex];
- Symbol *Sym = const_cast<Symbol *>(&S);
- if (Sym->isTls())
- return G.Tls.lookup(Sym) * Config->Wordsize;
- if (Sym->IsPreemptible)
- return G.Global.lookup(Sym) * Config->Wordsize;
- return G.Local16.lookup({Sym, Addend}) * Config->Wordsize;
+uint64_t MipsGotSection::getSymEntryOffset(const InputFile *f, const Symbol &s,
+ int64_t addend) const {
+ const FileGot &g = gots[*f->mipsGotIndex];
+ Symbol *sym = const_cast<Symbol *>(&s);
+ if (sym->isTls())
+ return g.tls.lookup(sym) * config->wordsize;
+ if (sym->isPreemptible)
+ return g.global.lookup(sym) * config->wordsize;
+ return g.local16.lookup({sym, addend}) * config->wordsize;
}
-uint64_t MipsGotSection::getTlsIndexOffset(const InputFile *F) const {
- const FileGot &G = Gots[*F->MipsGotIndex];
- return G.DynTlsSymbols.lookup(nullptr) * Config->Wordsize;
+uint64_t MipsGotSection::getTlsIndexOffset(const InputFile *f) const {
+ const FileGot &g = gots[*f->mipsGotIndex];
+ return g.dynTlsSymbols.lookup(nullptr) * config->wordsize;
}
-uint64_t MipsGotSection::getGlobalDynOffset(const InputFile *F,
- const Symbol &S) const {
- const FileGot &G = Gots[*F->MipsGotIndex];
- Symbol *Sym = const_cast<Symbol *>(&S);
- return G.DynTlsSymbols.lookup(Sym) * Config->Wordsize;
+uint64_t MipsGotSection::getGlobalDynOffset(const InputFile *f,
+ const Symbol &s) const {
+ const FileGot &g = gots[*f->mipsGotIndex];
+ Symbol *sym = const_cast<Symbol *>(&s);
+ return g.dynTlsSymbols.lookup(sym) * config->wordsize;
}
const Symbol *MipsGotSection::getFirstGlobalEntry() const {
- if (Gots.empty())
+ if (gots.empty())
return nullptr;
- const FileGot &PrimGot = Gots.front();
- if (!PrimGot.Global.empty())
- return PrimGot.Global.front().first;
- if (!PrimGot.Relocs.empty())
- return PrimGot.Relocs.front().first;
+ const FileGot &primGot = gots.front();
+ if (!primGot.global.empty())
+ return primGot.global.front().first;
+ if (!primGot.relocs.empty())
+ return primGot.relocs.front().first;
return nullptr;
}
unsigned MipsGotSection::getLocalEntriesNum() const {
- if (Gots.empty())
- return HeaderEntriesNum;
- return HeaderEntriesNum + Gots.front().getPageEntriesNum() +
- Gots.front().Local16.size();
-}
-
-bool MipsGotSection::tryMergeGots(FileGot &Dst, FileGot &Src, bool IsPrimary) {
- FileGot Tmp = Dst;
- set_union(Tmp.PagesMap, Src.PagesMap);
- set_union(Tmp.Local16, Src.Local16);
- set_union(Tmp.Global, Src.Global);
- set_union(Tmp.Relocs, Src.Relocs);
- set_union(Tmp.Tls, Src.Tls);
- set_union(Tmp.DynTlsSymbols, Src.DynTlsSymbols);
+ if (gots.empty())
+ return headerEntriesNum;
+ return headerEntriesNum + gots.front().getPageEntriesNum() +
+ gots.front().local16.size();
+}
+
+bool MipsGotSection::tryMergeGots(FileGot &dst, FileGot &src, bool isPrimary) {
+ FileGot tmp = dst;
+ set_union(tmp.pagesMap, src.pagesMap);
+ set_union(tmp.local16, src.local16);
+ set_union(tmp.global, src.global);
+ set_union(tmp.relocs, src.relocs);
+ set_union(tmp.tls, src.tls);
+ set_union(tmp.dynTlsSymbols, src.dynTlsSymbols);
- size_t Count = IsPrimary ? HeaderEntriesNum : 0;
- Count += Tmp.getIndexedEntriesNum();
+ size_t count = isPrimary ? headerEntriesNum : 0;
+ count += tmp.getIndexedEntriesNum();
- if (Count * Config->Wordsize > Config->MipsGotSize)
+ if (count * config->wordsize > config->mipsGotSize)
return false;
- std::swap(Tmp, Dst);
+ std::swap(tmp, dst);
return true;
}
void MipsGotSection::finalizeContents() { updateAllocSize(); }
bool MipsGotSection::updateAllocSize() {
- Size = HeaderEntriesNum * Config->Wordsize;
- for (const FileGot &G : Gots)
- Size += G.getEntriesNum() * Config->Wordsize;
+ size = headerEntriesNum * config->wordsize;
+ for (const FileGot &g : gots)
+ size += g.getEntriesNum() * config->wordsize;
return false;
}
void MipsGotSection::build() {
- if (Gots.empty())
+ if (gots.empty())
return;
- std::vector<FileGot> MergedGots(1);
+ std::vector<FileGot> mergedGots(1);
// For each GOT move non-preemptible symbols from the `Global`
// to `Local16` list. Preemptible symbol might become non-preemptible
// one if, for example, it gets a related copy relocation.
- for (FileGot &Got : Gots) {
- for (auto &P: Got.Global)
- if (!P.first->IsPreemptible)
- Got.Local16.insert({{P.first, 0}, 0});
- Got.Global.remove_if([&](const std::pair<Symbol *, size_t> &P) {
- return !P.first->IsPreemptible;
+ for (FileGot &got : gots) {
+ for (auto &p: got.global)
+ if (!p.first->isPreemptible)
+ got.local16.insert({{p.first, 0}, 0});
+ got.global.remove_if([&](const std::pair<Symbol *, size_t> &p) {
+ return !p.first->isPreemptible;
});
}
// For each GOT remove "reloc-only" entry if there is "global"
// entry for the same symbol. And add local entries which indexed
// using 32-bit value at the end of 16-bit entries.
- for (FileGot &Got : Gots) {
- Got.Relocs.remove_if([&](const std::pair<Symbol *, size_t> &P) {
- return Got.Global.count(P.first);
+ for (FileGot &got : gots) {
+ got.relocs.remove_if([&](const std::pair<Symbol *, size_t> &p) {
+ return got.global.count(p.first);
});
- set_union(Got.Local16, Got.Local32);
- Got.Local32.clear();
+ set_union(got.local16, got.local32);
+ got.local32.clear();
}
// Evaluate number of "reloc-only" entries in the resulting GOT.
// To do that put all unique "reloc-only" and "global" entries
// from all GOTs to the future primary GOT.
- FileGot *PrimGot = &MergedGots.front();
- for (FileGot &Got : Gots) {
- set_union(PrimGot->Relocs, Got.Global);
- set_union(PrimGot->Relocs, Got.Relocs);
- Got.Relocs.clear();
+ FileGot *primGot = &mergedGots.front();
+ for (FileGot &got : gots) {
+ set_union(primGot->relocs, got.global);
+ set_union(primGot->relocs, got.relocs);
+ got.relocs.clear();
}
// Evaluate number of "page" entries in each GOT.
- for (FileGot &Got : Gots) {
- for (std::pair<const OutputSection *, FileGot::PageBlock> &P :
- Got.PagesMap) {
- const OutputSection *OS = P.first;
- uint64_t SecSize = 0;
- for (BaseCommand *Cmd : OS->SectionCommands) {
- if (auto *ISD = dyn_cast<InputSectionDescription>(Cmd))
- for (InputSection *IS : ISD->Sections) {
- uint64_t Off = alignTo(SecSize, IS->Alignment);
- SecSize = Off + IS->getSize();
+ for (FileGot &got : gots) {
+ for (std::pair<const OutputSection *, FileGot::PageBlock> &p :
+ got.pagesMap) {
+ const OutputSection *os = p.first;
+ uint64_t secSize = 0;
+ for (BaseCommand *cmd : os->sectionCommands) {
+ if (auto *isd = dyn_cast<InputSectionDescription>(cmd))
+ for (InputSection *isec : isd->sections) {
+ uint64_t off = alignTo(secSize, isec->alignment);
+ secSize = off + isec->getSize();
}
}
- P.second.Count = getMipsPageCount(SecSize);
+ p.second.count = getMipsPageCount(secSize);
}
}
@@ -854,128 +854,128 @@ void MipsGotSection::build() {
// the primary GOT can be accessed in the most effective way. If it
// is not possible, try to fill the last GOT in the list, and finally
// create a new GOT if both attempts failed.
- for (FileGot &SrcGot : Gots) {
- InputFile *File = SrcGot.File;
- if (tryMergeGots(MergedGots.front(), SrcGot, true)) {
- File->MipsGotIndex = 0;
+ for (FileGot &srcGot : gots) {
+ InputFile *file = srcGot.file;
+ if (tryMergeGots(mergedGots.front(), srcGot, true)) {
+ file->mipsGotIndex = 0;
} else {
// If this is the first time we failed to merge with the primary GOT,
// MergedGots.back() will also be the primary GOT. We must make sure not
// to try to merge again with IsPrimary=false, as otherwise, if the
// inputs are just right, we could allow the primary GOT to become 1 or 2
// words too big due to ignoring the header size.
- if (MergedGots.size() == 1 ||
- !tryMergeGots(MergedGots.back(), SrcGot, false)) {
- MergedGots.emplace_back();
- std::swap(MergedGots.back(), SrcGot);
+ if (mergedGots.size() == 1 ||
+ !tryMergeGots(mergedGots.back(), srcGot, false)) {
+ mergedGots.emplace_back();
+ std::swap(mergedGots.back(), srcGot);
}
- File->MipsGotIndex = MergedGots.size() - 1;
+ file->mipsGotIndex = mergedGots.size() - 1;
}
}
- std::swap(Gots, MergedGots);
+ std::swap(gots, mergedGots);
// Reduce number of "reloc-only" entries in the primary GOT
// by substracting "global" entries exist in the primary GOT.
- PrimGot = &Gots.front();
- PrimGot->Relocs.remove_if([&](const std::pair<Symbol *, size_t> &P) {
- return PrimGot->Global.count(P.first);
+ primGot = &gots.front();
+ primGot->relocs.remove_if([&](const std::pair<Symbol *, size_t> &p) {
+ return primGot->global.count(p.first);
});
// Calculate indexes for each GOT entry.
- size_t Index = HeaderEntriesNum;
- for (FileGot &Got : Gots) {
- Got.StartIndex = &Got == PrimGot ? 0 : Index;
- for (std::pair<const OutputSection *, FileGot::PageBlock> &P :
- Got.PagesMap) {
+ size_t index = headerEntriesNum;
+ for (FileGot &got : gots) {
+ got.startIndex = &got == primGot ? 0 : index;
+ for (std::pair<const OutputSection *, FileGot::PageBlock> &p :
+ got.pagesMap) {
// For each output section referenced by GOT page relocations calculate
// and save into PagesMap an upper bound of MIPS GOT entries required
// to store page addresses of local symbols. We assume the worst case -
// each 64kb page of the output section has at least one GOT relocation
// against it. And take in account the case when the section intersects
// page boundaries.
- P.second.FirstIndex = Index;
- Index += P.second.Count;
+ p.second.firstIndex = index;
+ index += p.second.count;
}
- for (auto &P: Got.Local16)
- P.second = Index++;
- for (auto &P: Got.Global)
- P.second = Index++;
- for (auto &P: Got.Relocs)
- P.second = Index++;
- for (auto &P: Got.Tls)
- P.second = Index++;
- for (auto &P: Got.DynTlsSymbols) {
- P.second = Index;
- Index += 2;
+ for (auto &p: got.local16)
+ p.second = index++;
+ for (auto &p: got.global)
+ p.second = index++;
+ for (auto &p: got.relocs)
+ p.second = index++;
+ for (auto &p: got.tls)
+ p.second = index++;
+ for (auto &p: got.dynTlsSymbols) {
+ p.second = index;
+ index += 2;
}
}
// Update Symbol::GotIndex field to use this
// value later in the `sortMipsSymbols` function.
- for (auto &P : PrimGot->Global)
- P.first->GotIndex = P.second;
- for (auto &P : PrimGot->Relocs)
- P.first->GotIndex = P.second;
+ for (auto &p : primGot->global)
+ p.first->gotIndex = p.second;
+ for (auto &p : primGot->relocs)
+ p.first->gotIndex = p.second;
// Create dynamic relocations.
- for (FileGot &Got : Gots) {
+ for (FileGot &got : gots) {
// Create dynamic relocations for TLS entries.
- for (std::pair<Symbol *, size_t> &P : Got.Tls) {
- Symbol *S = P.first;
- uint64_t Offset = P.second * Config->Wordsize;
- if (S->IsPreemptible)
- Main->RelaDyn->addReloc(Target->TlsGotRel, this, Offset, S);
- }
- for (std::pair<Symbol *, size_t> &P : Got.DynTlsSymbols) {
- Symbol *S = P.first;
- uint64_t Offset = P.second * Config->Wordsize;
- if (S == nullptr) {
- if (!Config->Pic)
+ for (std::pair<Symbol *, size_t> &p : got.tls) {
+ Symbol *s = p.first;
+ uint64_t offset = p.second * config->wordsize;
+ if (s->isPreemptible)
+ mainPart->relaDyn->addReloc(target->tlsGotRel, this, offset, s);
+ }
+ for (std::pair<Symbol *, size_t> &p : got.dynTlsSymbols) {
+ Symbol *s = p.first;
+ uint64_t offset = p.second * config->wordsize;
+ if (s == nullptr) {
+ if (!config->isPic)
continue;
- Main->RelaDyn->addReloc(Target->TlsModuleIndexRel, this, Offset, S);
+ mainPart->relaDyn->addReloc(target->tlsModuleIndexRel, this, offset, s);
} else {
// When building a shared library we still need a dynamic relocation
// for the module index. Therefore only checking for
// S->IsPreemptible is not sufficient (this happens e.g. for
// thread-locals that have been marked as local through a linker script)
- if (!S->IsPreemptible && !Config->Pic)
+ if (!s->isPreemptible && !config->isPic)
continue;
- Main->RelaDyn->addReloc(Target->TlsModuleIndexRel, this, Offset, S);
+ mainPart->relaDyn->addReloc(target->tlsModuleIndexRel, this, offset, s);
// However, we can skip writing the TLS offset reloc for non-preemptible
// symbols since it is known even in shared libraries
- if (!S->IsPreemptible)
+ if (!s->isPreemptible)
continue;
- Offset += Config->Wordsize;
- Main->RelaDyn->addReloc(Target->TlsOffsetRel, this, Offset, S);
+ offset += config->wordsize;
+ mainPart->relaDyn->addReloc(target->tlsOffsetRel, this, offset, s);
}
}
// Do not create dynamic relocations for non-TLS
// entries in the primary GOT.
- if (&Got == PrimGot)
+ if (&got == primGot)
continue;
// Dynamic relocations for "global" entries.
- for (const std::pair<Symbol *, size_t> &P : Got.Global) {
- uint64_t Offset = P.second * Config->Wordsize;
- Main->RelaDyn->addReloc(Target->RelativeRel, this, Offset, P.first);
+ for (const std::pair<Symbol *, size_t> &p : got.global) {
+ uint64_t offset = p.second * config->wordsize;
+ mainPart->relaDyn->addReloc(target->relativeRel, this, offset, p.first);
}
- if (!Config->Pic)
+ if (!config->isPic)
continue;
// Dynamic relocations for "local" entries in case of PIC.
- for (const std::pair<const OutputSection *, FileGot::PageBlock> &L :
- Got.PagesMap) {
- size_t PageCount = L.second.Count;
- for (size_t PI = 0; PI < PageCount; ++PI) {
- uint64_t Offset = (L.second.FirstIndex + PI) * Config->Wordsize;
- Main->RelaDyn->addReloc({Target->RelativeRel, this, Offset, L.first,
- int64_t(PI * 0x10000)});
+ for (const std::pair<const OutputSection *, FileGot::PageBlock> &l :
+ got.pagesMap) {
+ size_t pageCount = l.second.count;
+ for (size_t pi = 0; pi < pageCount; ++pi) {
+ uint64_t offset = (l.second.firstIndex + pi) * config->wordsize;
+ mainPart->relaDyn->addReloc({target->relativeRel, this, offset, l.first,
+ int64_t(pi * 0x10000)});
}
}
- for (const std::pair<GotEntry, size_t> &P : Got.Local16) {
- uint64_t Offset = P.second * Config->Wordsize;
- Main->RelaDyn->addReloc({Target->RelativeRel, this, Offset, true,
- P.first.first, P.first.second});
+ for (const std::pair<GotEntry, size_t> &p : got.local16) {
+ uint64_t offset = p.second * config->wordsize;
+ mainPart->relaDyn->addReloc({target->relativeRel, this, offset, true,
+ p.first.first, p.first.second});
}
}
}
@@ -983,20 +983,20 @@ void MipsGotSection::build() {
bool MipsGotSection::isNeeded() const {
// We add the .got section to the result for dynamic MIPS target because
// its address and properties are mentioned in the .dynamic section.
- return !Config->Relocatable;
+ return !config->relocatable;
}
-uint64_t MipsGotSection::getGp(const InputFile *F) const {
+uint64_t MipsGotSection::getGp(const InputFile *f) const {
// For files without related GOT or files refer a primary GOT
// returns "common" _gp value. For secondary GOTs calculate
// individual _gp values.
- if (!F || !F->MipsGotIndex.hasValue() || *F->MipsGotIndex == 0)
- return ElfSym::MipsGp->getVA(0);
- return getVA() + Gots[*F->MipsGotIndex].StartIndex * Config->Wordsize +
+ if (!f || !f->mipsGotIndex.hasValue() || *f->mipsGotIndex == 0)
+ return ElfSym::mipsGp->getVA(0);
+ return getVA() + gots[*f->mipsGotIndex].startIndex * config->wordsize +
0x7ff0;
}
-void MipsGotSection::writeTo(uint8_t *Buf) {
+void MipsGotSection::writeTo(uint8_t *buf) {
// Set the MSB of the second GOT slot. This is not required by any
// MIPS ABI documentation, though.
//
@@ -1011,48 +1011,48 @@ void MipsGotSection::writeTo(uint8_t *Bu
// we've been doing this for years, it is probably a safe bet to
// keep doing this for now. We really need to revisit this to see
// if we had to do this.
- writeUint(Buf + Config->Wordsize, (uint64_t)1 << (Config->Wordsize * 8 - 1));
- for (const FileGot &G : Gots) {
- auto Write = [&](size_t I, const Symbol *S, int64_t A) {
- uint64_t VA = A;
- if (S)
- VA = S->getVA(A);
- writeUint(Buf + I * Config->Wordsize, VA);
+ writeUint(buf + config->wordsize, (uint64_t)1 << (config->wordsize * 8 - 1));
+ for (const FileGot &g : gots) {
+ auto write = [&](size_t i, const Symbol *s, int64_t a) {
+ uint64_t va = a;
+ if (s)
+ va = s->getVA(a);
+ writeUint(buf + i * config->wordsize, va);
};
// Write 'page address' entries to the local part of the GOT.
- for (const std::pair<const OutputSection *, FileGot::PageBlock> &L :
- G.PagesMap) {
- size_t PageCount = L.second.Count;
- uint64_t FirstPageAddr = getMipsPageAddr(L.first->Addr);
- for (size_t PI = 0; PI < PageCount; ++PI)
- Write(L.second.FirstIndex + PI, nullptr, FirstPageAddr + PI * 0x10000);
+ for (const std::pair<const OutputSection *, FileGot::PageBlock> &l :
+ g.pagesMap) {
+ size_t pageCount = l.second.count;
+ uint64_t firstPageAddr = getMipsPageAddr(l.first->addr);
+ for (size_t pi = 0; pi < pageCount; ++pi)
+ write(l.second.firstIndex + pi, nullptr, firstPageAddr + pi * 0x10000);
}
// Local, global, TLS, reloc-only entries.
// If TLS entry has a corresponding dynamic relocations, leave it
// initialized by zero. Write down adjusted TLS symbol's values otherwise.
// To calculate the adjustments use offsets for thread-local storage.
// https://www.linux-mips.org/wiki/NPTL
- for (const std::pair<GotEntry, size_t> &P : G.Local16)
- Write(P.second, P.first.first, P.first.second);
+ for (const std::pair<GotEntry, size_t> &p : g.local16)
+ write(p.second, p.first.first, p.first.second);
// Write VA to the primary GOT only. For secondary GOTs that
// will be done by REL32 dynamic relocations.
- if (&G == &Gots.front())
- for (const std::pair<const Symbol *, size_t> &P : G.Global)
- Write(P.second, P.first, 0);
- for (const std::pair<Symbol *, size_t> &P : G.Relocs)
- Write(P.second, P.first, 0);
- for (const std::pair<Symbol *, size_t> &P : G.Tls)
- Write(P.second, P.first, P.first->IsPreemptible ? 0 : -0x7000);
- for (const std::pair<Symbol *, size_t> &P : G.DynTlsSymbols) {
- if (P.first == nullptr && !Config->Pic)
- Write(P.second, nullptr, 1);
- else if (P.first && !P.first->IsPreemptible) {
+ if (&g == &gots.front())
+ for (const std::pair<const Symbol *, size_t> &p : g.global)
+ write(p.second, p.first, 0);
+ for (const std::pair<Symbol *, size_t> &p : g.relocs)
+ write(p.second, p.first, 0);
+ for (const std::pair<Symbol *, size_t> &p : g.tls)
+ write(p.second, p.first, p.first->isPreemptible ? 0 : -0x7000);
+ for (const std::pair<Symbol *, size_t> &p : g.dynTlsSymbols) {
+ if (p.first == nullptr && !config->isPic)
+ write(p.second, nullptr, 1);
+ else if (p.first && !p.first->isPreemptible) {
// If we are emitting PIC code with relocations we mustn't write
// anything to the GOT here. When using Elf_Rel relocations the value
// one will be treated as an addend and will cause crashes at runtime
- if (!Config->Pic)
- Write(P.second, nullptr, 1);
- Write(P.second + 1, P.first, -0x8000);
+ if (!config->isPic)
+ write(p.second, nullptr, 1);
+ write(p.second + 1, p.first, -0x8000);
}
}
}
@@ -1063,48 +1063,48 @@ void MipsGotSection::writeTo(uint8_t *Bu
// section. I don't know why we have a BSS style type for the section but it is
// consitent across both 64-bit PowerPC ABIs as well as the 32-bit PowerPC ABI.
GotPltSection::GotPltSection()
- : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, Config->Wordsize,
+ : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, config->wordsize,
".got.plt") {
- if (Config->EMachine == EM_PPC) {
- Name = ".plt";
- } else if (Config->EMachine == EM_PPC64) {
- Type = SHT_NOBITS;
- Name = ".plt";
+ if (config->emachine == EM_PPC) {
+ name = ".plt";
+ } else if (config->emachine == EM_PPC64) {
+ type = SHT_NOBITS;
+ name = ".plt";
}
}
-void GotPltSection::addEntry(Symbol &Sym) {
- assert(Sym.PltIndex == Entries.size());
- Entries.push_back(&Sym);
+void GotPltSection::addEntry(Symbol &sym) {
+ assert(sym.pltIndex == entries.size());
+ entries.push_back(&sym);
}
size_t GotPltSection::getSize() const {
- return (Target->GotPltHeaderEntriesNum + Entries.size()) * Config->Wordsize;
+ return (target->gotPltHeaderEntriesNum + entries.size()) * config->wordsize;
}
-void GotPltSection::writeTo(uint8_t *Buf) {
- Target->writeGotPltHeader(Buf);
- Buf += Target->GotPltHeaderEntriesNum * Config->Wordsize;
- for (const Symbol *B : Entries) {
- Target->writeGotPlt(Buf, *B);
- Buf += Config->Wordsize;
+void GotPltSection::writeTo(uint8_t *buf) {
+ target->writeGotPltHeader(buf);
+ buf += target->gotPltHeaderEntriesNum * config->wordsize;
+ for (const Symbol *b : entries) {
+ target->writeGotPlt(buf, *b);
+ buf += config->wordsize;
}
}
bool GotPltSection::isNeeded() const {
// We need to emit GOTPLT even if it's empty if there's a relocation relative
// to it.
- return !Entries.empty() || HasGotPltOffRel;
+ return !entries.empty() || hasGotPltOffRel;
}
static StringRef getIgotPltName() {
// On ARM the IgotPltSection is part of the GotSection.
- if (Config->EMachine == EM_ARM)
+ if (config->emachine == EM_ARM)
return ".got";
// On PowerPC64 the GotPltSection is renamed to '.plt' so the IgotPltSection
// needs to be named the same.
- if (Config->EMachine == EM_PPC64)
+ if (config->emachine == EM_PPC64)
return ".plt";
return ".got.plt";
@@ -1114,28 +1114,28 @@ static StringRef getIgotPltName() {
// with the IgotPltSection.
IgotPltSection::IgotPltSection()
: SyntheticSection(SHF_ALLOC | SHF_WRITE,
- Config->EMachine == EM_PPC64 ? SHT_NOBITS : SHT_PROGBITS,
- Config->Wordsize, getIgotPltName()) {}
+ config->emachine == EM_PPC64 ? SHT_NOBITS : SHT_PROGBITS,
+ config->wordsize, getIgotPltName()) {}
-void IgotPltSection::addEntry(Symbol &Sym) {
- assert(Sym.PltIndex == Entries.size());
- Entries.push_back(&Sym);
+void IgotPltSection::addEntry(Symbol &sym) {
+ assert(sym.pltIndex == entries.size());
+ entries.push_back(&sym);
}
size_t IgotPltSection::getSize() const {
- return Entries.size() * Config->Wordsize;
+ return entries.size() * config->wordsize;
}
-void IgotPltSection::writeTo(uint8_t *Buf) {
- for (const Symbol *B : Entries) {
- Target->writeIgotPlt(Buf, *B);
- Buf += Config->Wordsize;
+void IgotPltSection::writeTo(uint8_t *buf) {
+ for (const Symbol *b : entries) {
+ target->writeIgotPlt(buf, *b);
+ buf += config->wordsize;
}
}
-StringTableSection::StringTableSection(StringRef Name, bool Dynamic)
- : SyntheticSection(Dynamic ? (uint64_t)SHF_ALLOC : 0, SHT_STRTAB, 1, Name),
- Dynamic(Dynamic) {
+StringTableSection::StringTableSection(StringRef name, bool dynamic)
+ : SyntheticSection(dynamic ? (uint64_t)SHF_ALLOC : 0, SHT_STRTAB, 1, name),
+ dynamic(dynamic) {
// ELF string tables start with a NUL byte.
addString("");
}
@@ -1144,80 +1144,80 @@ StringTableSection::StringTableSection(S
// duplicates. It is optional because the name of global symbols are already
// uniqued and hashing them again has a big cost for a small value: uniquing
// them with some other string that happens to be the same.
-unsigned StringTableSection::addString(StringRef S, bool HashIt) {
- if (HashIt) {
- auto R = StringMap.insert(std::make_pair(S, this->Size));
- if (!R.second)
- return R.first->second;
- }
- unsigned Ret = this->Size;
- this->Size = this->Size + S.size() + 1;
- Strings.push_back(S);
- return Ret;
-}
-
-void StringTableSection::writeTo(uint8_t *Buf) {
- for (StringRef S : Strings) {
- memcpy(Buf, S.data(), S.size());
- Buf[S.size()] = '\0';
- Buf += S.size() + 1;
+unsigned StringTableSection::addString(StringRef s, bool hashIt) {
+ if (hashIt) {
+ auto r = stringMap.insert(std::make_pair(s, this->size));
+ if (!r.second)
+ return r.first->second;
+ }
+ unsigned ret = this->size;
+ this->size = this->size + s.size() + 1;
+ strings.push_back(s);
+ return ret;
+}
+
+void StringTableSection::writeTo(uint8_t *buf) {
+ for (StringRef s : strings) {
+ memcpy(buf, s.data(), s.size());
+ buf[s.size()] = '\0';
+ buf += s.size() + 1;
}
}
// Returns the number of version definition entries. Because the first entry
// is for the version definition itself, it is the number of versioned symbols
// plus one. Note that we don't support multiple versions yet.
-static unsigned getVerDefNum() { return Config->VersionDefinitions.size() + 1; }
+static unsigned getVerDefNum() { return config->versionDefinitions.size() + 1; }
template <class ELFT>
DynamicSection<ELFT>::DynamicSection()
- : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_DYNAMIC, Config->Wordsize,
+ : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_DYNAMIC, config->wordsize,
".dynamic") {
- this->Entsize = ELFT::Is64Bits ? 16 : 8;
+ this->entsize = ELFT::Is64Bits ? 16 : 8;
// .dynamic section is not writable on MIPS and on Fuchsia OS
// which passes -z rodynamic.
// See "Special Section" in Chapter 4 in the following document:
// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
- if (Config->EMachine == EM_MIPS || Config->ZRodynamic)
- this->Flags = SHF_ALLOC;
+ if (config->emachine == EM_MIPS || config->zRodynamic)
+ this->flags = SHF_ALLOC;
}
template <class ELFT>
-void DynamicSection<ELFT>::add(int32_t Tag, std::function<uint64_t()> Fn) {
- Entries.push_back({Tag, Fn});
+void DynamicSection<ELFT>::add(int32_t tag, std::function<uint64_t()> fn) {
+ entries.push_back({tag, fn});
}
template <class ELFT>
-void DynamicSection<ELFT>::addInt(int32_t Tag, uint64_t Val) {
- Entries.push_back({Tag, [=] { return Val; }});
+void DynamicSection<ELFT>::addInt(int32_t tag, uint64_t val) {
+ entries.push_back({tag, [=] { return val; }});
}
template <class ELFT>
-void DynamicSection<ELFT>::addInSec(int32_t Tag, InputSection *Sec) {
- Entries.push_back({Tag, [=] { return Sec->getVA(0); }});
+void DynamicSection<ELFT>::addInSec(int32_t tag, InputSection *sec) {
+ entries.push_back({tag, [=] { return sec->getVA(0); }});
}
template <class ELFT>
-void DynamicSection<ELFT>::addInSecRelative(int32_t Tag, InputSection *Sec) {
- size_t TagOffset = Entries.size() * Entsize;
- Entries.push_back(
- {Tag, [=] { return Sec->getVA(0) - (getVA() + TagOffset); }});
+void DynamicSection<ELFT>::addInSecRelative(int32_t tag, InputSection *sec) {
+ size_t tagOffset = entries.size() * entsize;
+ entries.push_back(
+ {tag, [=] { return sec->getVA(0) - (getVA() + tagOffset); }});
}
template <class ELFT>
-void DynamicSection<ELFT>::addOutSec(int32_t Tag, OutputSection *Sec) {
- Entries.push_back({Tag, [=] { return Sec->Addr; }});
+void DynamicSection<ELFT>::addOutSec(int32_t tag, OutputSection *sec) {
+ entries.push_back({tag, [=] { return sec->addr; }});
}
template <class ELFT>
-void DynamicSection<ELFT>::addSize(int32_t Tag, OutputSection *Sec) {
- Entries.push_back({Tag, [=] { return Sec->Size; }});
+void DynamicSection<ELFT>::addSize(int32_t tag, OutputSection *sec) {
+ entries.push_back({tag, [=] { return sec->size; }});
}
template <class ELFT>
-void DynamicSection<ELFT>::addSym(int32_t Tag, Symbol *Sym) {
- Entries.push_back({Tag, [=] { return Sym->getVA(); }});
+void DynamicSection<ELFT>::addSym(int32_t tag, Symbol *sym) {
+ entries.push_back({tag, [=] { return sym->getVA(); }});
}
// A Linker script may assign the RELA relocation sections to the same
@@ -1225,74 +1225,74 @@ void DynamicSection<ELFT>::addSym(int32_
// Size. Moreover the [DT_JMPREL, DT_JMPREL + DT_PLTRELSZ) is permitted to
// overlap with the [DT_RELA, DT_RELA + DT_RELASZ).
static uint64_t addPltRelSz() {
- size_t Size = In.RelaPlt->getSize();
- if (In.RelaIplt->getParent() == In.RelaPlt->getParent() &&
- In.RelaIplt->Name == In.RelaPlt->Name)
- Size += In.RelaIplt->getSize();
- return Size;
+ size_t size = in.relaPlt->getSize();
+ if (in.relaIplt->getParent() == in.relaPlt->getParent() &&
+ in.relaIplt->name == in.relaPlt->name)
+ size += in.relaIplt->getSize();
+ return size;
}
// Add remaining entries to complete .dynamic contents.
template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {
- elf::Partition &Part = getPartition();
- bool IsMain = Part.Name.empty();
+ elf::Partition &part = getPartition();
+ bool isMain = part.name.empty();
- for (StringRef S : Config->FilterList)
- addInt(DT_FILTER, Part.DynStrTab->addString(S));
- for (StringRef S : Config->AuxiliaryList)
- addInt(DT_AUXILIARY, Part.DynStrTab->addString(S));
-
- if (!Config->Rpath.empty())
- addInt(Config->EnableNewDtags ? DT_RUNPATH : DT_RPATH,
- Part.DynStrTab->addString(Config->Rpath));
-
- for (SharedFile *File : SharedFiles)
- if (File->IsNeeded)
- addInt(DT_NEEDED, Part.DynStrTab->addString(File->SoName));
-
- if (IsMain) {
- if (!Config->SoName.empty())
- addInt(DT_SONAME, Part.DynStrTab->addString(Config->SoName));
+ for (StringRef s : config->filterList)
+ addInt(DT_FILTER, part.dynStrTab->addString(s));
+ for (StringRef s : config->auxiliaryList)
+ addInt(DT_AUXILIARY, part.dynStrTab->addString(s));
+
+ if (!config->rpath.empty())
+ addInt(config->enableNewDtags ? DT_RUNPATH : DT_RPATH,
+ part.dynStrTab->addString(config->rpath));
+
+ for (SharedFile *file : sharedFiles)
+ if (file->isNeeded)
+ addInt(DT_NEEDED, part.dynStrTab->addString(file->soName));
+
+ if (isMain) {
+ if (!config->soName.empty())
+ addInt(DT_SONAME, part.dynStrTab->addString(config->soName));
} else {
- if (!Config->SoName.empty())
- addInt(DT_NEEDED, Part.DynStrTab->addString(Config->SoName));
- addInt(DT_SONAME, Part.DynStrTab->addString(Part.Name));
+ if (!config->soName.empty())
+ addInt(DT_NEEDED, part.dynStrTab->addString(config->soName));
+ addInt(DT_SONAME, part.dynStrTab->addString(part.name));
}
// Set DT_FLAGS and DT_FLAGS_1.
- uint32_t DtFlags = 0;
- uint32_t DtFlags1 = 0;
- if (Config->Bsymbolic)
- DtFlags |= DF_SYMBOLIC;
- if (Config->ZGlobal)
- DtFlags1 |= DF_1_GLOBAL;
- if (Config->ZInitfirst)
- DtFlags1 |= DF_1_INITFIRST;
- if (Config->ZInterpose)
- DtFlags1 |= DF_1_INTERPOSE;
- if (Config->ZNodefaultlib)
- DtFlags1 |= DF_1_NODEFLIB;
- if (Config->ZNodelete)
- DtFlags1 |= DF_1_NODELETE;
- if (Config->ZNodlopen)
- DtFlags1 |= DF_1_NOOPEN;
- if (Config->ZNow) {
- DtFlags |= DF_BIND_NOW;
- DtFlags1 |= DF_1_NOW;
- }
- if (Config->ZOrigin) {
- DtFlags |= DF_ORIGIN;
- DtFlags1 |= DF_1_ORIGIN;
- }
- if (!Config->ZText)
- DtFlags |= DF_TEXTREL;
- if (Config->HasStaticTlsModel)
- DtFlags |= DF_STATIC_TLS;
-
- if (DtFlags)
- addInt(DT_FLAGS, DtFlags);
- if (DtFlags1)
- addInt(DT_FLAGS_1, DtFlags1);
+ uint32_t dtFlags = 0;
+ uint32_t dtFlags1 = 0;
+ if (config->bsymbolic)
+ dtFlags |= DF_SYMBOLIC;
+ if (config->zGlobal)
+ dtFlags1 |= DF_1_GLOBAL;
+ if (config->zInitfirst)
+ dtFlags1 |= DF_1_INITFIRST;
+ if (config->zInterpose)
+ dtFlags1 |= DF_1_INTERPOSE;
+ if (config->zNodefaultlib)
+ dtFlags1 |= DF_1_NODEFLIB;
+ if (config->zNodelete)
+ dtFlags1 |= DF_1_NODELETE;
+ if (config->zNodlopen)
+ dtFlags1 |= DF_1_NOOPEN;
+ if (config->zNow) {
+ dtFlags |= DF_BIND_NOW;
+ dtFlags1 |= DF_1_NOW;
+ }
+ if (config->zOrigin) {
+ dtFlags |= DF_ORIGIN;
+ dtFlags1 |= DF_1_ORIGIN;
+ }
+ if (!config->zText)
+ dtFlags |= DF_TEXTREL;
+ if (config->hasStaticTlsModel)
+ dtFlags |= DF_STATIC_TLS;
+
+ if (dtFlags)
+ addInt(DT_FLAGS, dtFlags);
+ if (dtFlags1)
+ addInt(DT_FLAGS_1, dtFlags1);
// DT_DEBUG is a pointer to debug informaion used by debuggers at runtime. We
// need it for each process, so we don't write it for DSOs. The loader writes
@@ -1302,35 +1302,35 @@ template <class ELFT> void DynamicSectio
// systems (currently only Fuchsia OS) provide other means to give the
// debugger this information. Such systems may choose make .dynamic read-only.
// If the target is such a system (used -z rodynamic) don't write DT_DEBUG.
- if (!Config->Shared && !Config->Relocatable && !Config->ZRodynamic)
+ if (!config->shared && !config->relocatable && !config->zRodynamic)
addInt(DT_DEBUG, 0);
- if (OutputSection *Sec = Part.DynStrTab->getParent())
- this->Link = Sec->SectionIndex;
+ if (OutputSection *sec = part.dynStrTab->getParent())
+ this->link = sec->sectionIndex;
- if (Part.RelaDyn->isNeeded()) {
- addInSec(Part.RelaDyn->DynamicTag, Part.RelaDyn);
- addSize(Part.RelaDyn->SizeDynamicTag, Part.RelaDyn->getParent());
-
- bool IsRela = Config->IsRela;
- addInt(IsRela ? DT_RELAENT : DT_RELENT,
- IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel));
+ if (part.relaDyn->isNeeded()) {
+ addInSec(part.relaDyn->dynamicTag, part.relaDyn);
+ addSize(part.relaDyn->sizeDynamicTag, part.relaDyn->getParent());
+
+ bool isRela = config->isRela;
+ addInt(isRela ? DT_RELAENT : DT_RELENT,
+ isRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel));
// MIPS dynamic loader does not support RELCOUNT tag.
// The problem is in the tight relation between dynamic
// relocations and GOT. So do not emit this tag on MIPS.
- if (Config->EMachine != EM_MIPS) {
- size_t NumRelativeRels = Part.RelaDyn->getRelativeRelocCount();
- if (Config->ZCombreloc && NumRelativeRels)
- addInt(IsRela ? DT_RELACOUNT : DT_RELCOUNT, NumRelativeRels);
+ if (config->emachine != EM_MIPS) {
+ size_t numRelativeRels = part.relaDyn->getRelativeRelocCount();
+ if (config->zCombreloc && numRelativeRels)
+ addInt(isRela ? DT_RELACOUNT : DT_RELCOUNT, numRelativeRels);
}
}
- if (Part.RelrDyn && !Part.RelrDyn->Relocs.empty()) {
- addInSec(Config->UseAndroidRelrTags ? DT_ANDROID_RELR : DT_RELR,
- Part.RelrDyn);
- addSize(Config->UseAndroidRelrTags ? DT_ANDROID_RELRSZ : DT_RELRSZ,
- Part.RelrDyn->getParent());
- addInt(Config->UseAndroidRelrTags ? DT_ANDROID_RELRENT : DT_RELRENT,
+ if (part.relrDyn && !part.relrDyn->relocs.empty()) {
+ addInSec(config->useAndroidRelrTags ? DT_ANDROID_RELR : DT_RELR,
+ part.relrDyn);
+ addSize(config->useAndroidRelrTags ? DT_ANDROID_RELRSZ : DT_RELRSZ,
+ part.relrDyn->getParent());
+ addInt(config->useAndroidRelrTags ? DT_ANDROID_RELRENT : DT_RELRENT,
sizeof(Elf_Relr));
}
// .rel[a].plt section usually consists of two parts, containing plt and
@@ -1339,250 +1339,250 @@ template <class ELFT> void DynamicSectio
// as RelaIplt have. And we still want to emit proper dynamic tags for that
// case, so here we always use RelaPlt as marker for the begining of
// .rel[a].plt section.
- if (IsMain && (In.RelaPlt->isNeeded() || In.RelaIplt->isNeeded())) {
- addInSec(DT_JMPREL, In.RelaPlt);
- Entries.push_back({DT_PLTRELSZ, addPltRelSz});
- switch (Config->EMachine) {
+ if (isMain && (in.relaPlt->isNeeded() || in.relaIplt->isNeeded())) {
+ addInSec(DT_JMPREL, in.relaPlt);
+ entries.push_back({DT_PLTRELSZ, addPltRelSz});
+ switch (config->emachine) {
case EM_MIPS:
- addInSec(DT_MIPS_PLTGOT, In.GotPlt);
+ addInSec(DT_MIPS_PLTGOT, in.gotPlt);
break;
case EM_SPARCV9:
- addInSec(DT_PLTGOT, In.Plt);
+ addInSec(DT_PLTGOT, in.plt);
break;
default:
- addInSec(DT_PLTGOT, In.GotPlt);
+ addInSec(DT_PLTGOT, in.gotPlt);
break;
}
- addInt(DT_PLTREL, Config->IsRela ? DT_RELA : DT_REL);
+ addInt(DT_PLTREL, config->isRela ? DT_RELA : DT_REL);
}
- if (Config->EMachine == EM_AARCH64) {
- if (Config->AndFeatures & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)
+ if (config->emachine == EM_AARCH64) {
+ if (config->andFeatures & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)
addInt(DT_AARCH64_BTI_PLT, 0);
- if (Config->AndFeatures & GNU_PROPERTY_AARCH64_FEATURE_1_PAC)
+ if (config->andFeatures & GNU_PROPERTY_AARCH64_FEATURE_1_PAC)
addInt(DT_AARCH64_PAC_PLT, 0);
}
- addInSec(DT_SYMTAB, Part.DynSymTab);
+ addInSec(DT_SYMTAB, part.dynSymTab);
addInt(DT_SYMENT, sizeof(Elf_Sym));
- addInSec(DT_STRTAB, Part.DynStrTab);
- addInt(DT_STRSZ, Part.DynStrTab->getSize());
- if (!Config->ZText)
+ addInSec(DT_STRTAB, part.dynStrTab);
+ addInt(DT_STRSZ, part.dynStrTab->getSize());
+ if (!config->zText)
addInt(DT_TEXTREL, 0);
- if (Part.GnuHashTab)
- addInSec(DT_GNU_HASH, Part.GnuHashTab);
- if (Part.HashTab)
- addInSec(DT_HASH, Part.HashTab);
-
- if (IsMain) {
- if (Out::PreinitArray) {
- addOutSec(DT_PREINIT_ARRAY, Out::PreinitArray);
- addSize(DT_PREINIT_ARRAYSZ, Out::PreinitArray);
- }
- if (Out::InitArray) {
- addOutSec(DT_INIT_ARRAY, Out::InitArray);
- addSize(DT_INIT_ARRAYSZ, Out::InitArray);
- }
- if (Out::FiniArray) {
- addOutSec(DT_FINI_ARRAY, Out::FiniArray);
- addSize(DT_FINI_ARRAYSZ, Out::FiniArray);
- }
-
- if (Symbol *B = Symtab->find(Config->Init))
- if (B->isDefined())
- addSym(DT_INIT, B);
- if (Symbol *B = Symtab->find(Config->Fini))
- if (B->isDefined())
- addSym(DT_FINI, B);
- }
-
- bool HasVerNeed = SharedFile::VernauxNum != 0;
- if (HasVerNeed || Part.VerDef)
- addInSec(DT_VERSYM, Part.VerSym);
- if (Part.VerDef) {
- addInSec(DT_VERDEF, Part.VerDef);
+ if (part.gnuHashTab)
+ addInSec(DT_GNU_HASH, part.gnuHashTab);
+ if (part.hashTab)
+ addInSec(DT_HASH, part.hashTab);
+
+ if (isMain) {
+ if (Out::preinitArray) {
+ addOutSec(DT_PREINIT_ARRAY, Out::preinitArray);
+ addSize(DT_PREINIT_ARRAYSZ, Out::preinitArray);
+ }
+ if (Out::initArray) {
+ addOutSec(DT_INIT_ARRAY, Out::initArray);
+ addSize(DT_INIT_ARRAYSZ, Out::initArray);
+ }
+ if (Out::finiArray) {
+ addOutSec(DT_FINI_ARRAY, Out::finiArray);
+ addSize(DT_FINI_ARRAYSZ, Out::finiArray);
+ }
+
+ if (Symbol *b = symtab->find(config->init))
+ if (b->isDefined())
+ addSym(DT_INIT, b);
+ if (Symbol *b = symtab->find(config->fini))
+ if (b->isDefined())
+ addSym(DT_FINI, b);
+ }
+
+ bool hasVerNeed = SharedFile::vernauxNum != 0;
+ if (hasVerNeed || part.verDef)
+ addInSec(DT_VERSYM, part.verSym);
+ if (part.verDef) {
+ addInSec(DT_VERDEF, part.verDef);
addInt(DT_VERDEFNUM, getVerDefNum());
}
- if (HasVerNeed) {
- addInSec(DT_VERNEED, Part.VerNeed);
- unsigned NeedNum = 0;
- for (SharedFile *F : SharedFiles)
- if (!F->Vernauxs.empty())
- ++NeedNum;
- addInt(DT_VERNEEDNUM, NeedNum);
+ if (hasVerNeed) {
+ addInSec(DT_VERNEED, part.verNeed);
+ unsigned needNum = 0;
+ for (SharedFile *f : sharedFiles)
+ if (!f->vernauxs.empty())
+ ++needNum;
+ addInt(DT_VERNEEDNUM, needNum);
}
- if (Config->EMachine == EM_MIPS) {
+ if (config->emachine == EM_MIPS) {
addInt(DT_MIPS_RLD_VERSION, 1);
addInt(DT_MIPS_FLAGS, RHF_NOTPOT);
- addInt(DT_MIPS_BASE_ADDRESS, Target->getImageBase());
- addInt(DT_MIPS_SYMTABNO, Part.DynSymTab->getNumSymbols());
+ addInt(DT_MIPS_BASE_ADDRESS, target->getImageBase());
+ addInt(DT_MIPS_SYMTABNO, part.dynSymTab->getNumSymbols());
- add(DT_MIPS_LOCAL_GOTNO, [] { return In.MipsGot->getLocalEntriesNum(); });
+ add(DT_MIPS_LOCAL_GOTNO, [] { return in.mipsGot->getLocalEntriesNum(); });
- if (const Symbol *B = In.MipsGot->getFirstGlobalEntry())
- addInt(DT_MIPS_GOTSYM, B->DynsymIndex);
+ if (const Symbol *b = in.mipsGot->getFirstGlobalEntry())
+ addInt(DT_MIPS_GOTSYM, b->dynsymIndex);
else
- addInt(DT_MIPS_GOTSYM, Part.DynSymTab->getNumSymbols());
- addInSec(DT_PLTGOT, In.MipsGot);
- if (In.MipsRldMap) {
- if (!Config->Pie)
- addInSec(DT_MIPS_RLD_MAP, In.MipsRldMap);
+ addInt(DT_MIPS_GOTSYM, part.dynSymTab->getNumSymbols());
+ addInSec(DT_PLTGOT, in.mipsGot);
+ if (in.mipsRldMap) {
+ if (!config->pie)
+ addInSec(DT_MIPS_RLD_MAP, in.mipsRldMap);
// Store the offset to the .rld_map section
// relative to the address of the tag.
- addInSecRelative(DT_MIPS_RLD_MAP_REL, In.MipsRldMap);
+ addInSecRelative(DT_MIPS_RLD_MAP_REL, in.mipsRldMap);
}
}
// DT_PPC_GOT indicates to glibc Secure PLT is used. If DT_PPC_GOT is absent,
// glibc assumes the old-style BSS PLT layout which we don't support.
- if (Config->EMachine == EM_PPC)
- add(DT_PPC_GOT, [] { return In.Got->getVA(); });
+ if (config->emachine == EM_PPC)
+ add(DT_PPC_GOT, [] { return in.got->getVA(); });
// Glink dynamic tag is required by the V2 abi if the plt section isn't empty.
- if (Config->EMachine == EM_PPC64 && In.Plt->isNeeded()) {
+ if (config->emachine == EM_PPC64 && in.plt->isNeeded()) {
// The Glink tag points to 32 bytes before the first lazy symbol resolution
// stub, which starts directly after the header.
- Entries.push_back({DT_PPC64_GLINK, [=] {
- unsigned Offset = Target->PltHeaderSize - 32;
- return In.Plt->getVA(0) + Offset;
+ entries.push_back({DT_PPC64_GLINK, [=] {
+ unsigned offset = target->pltHeaderSize - 32;
+ return in.plt->getVA(0) + offset;
}});
}
addInt(DT_NULL, 0);
- getParent()->Link = this->Link;
- this->Size = Entries.size() * this->Entsize;
+ getParent()->link = this->link;
+ this->size = entries.size() * this->entsize;
}
-template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) {
- auto *P = reinterpret_cast<Elf_Dyn *>(Buf);
+template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *buf) {
+ auto *p = reinterpret_cast<Elf_Dyn *>(buf);
- for (std::pair<int32_t, std::function<uint64_t()>> &KV : Entries) {
- P->d_tag = KV.first;
- P->d_un.d_val = KV.second();
- ++P;
+ for (std::pair<int32_t, std::function<uint64_t()>> &kv : entries) {
+ p->d_tag = kv.first;
+ p->d_un.d_val = kv.second();
+ ++p;
}
}
uint64_t DynamicReloc::getOffset() const {
- return InputSec->getVA(OffsetInSec);
+ return inputSec->getVA(offsetInSec);
}
int64_t DynamicReloc::computeAddend() const {
- if (UseSymVA)
- return Sym->getVA(Addend);
- if (!OutputSec)
- return Addend;
+ if (useSymVA)
+ return sym->getVA(addend);
+ if (!outputSec)
+ return addend;
// See the comment in the DynamicReloc ctor.
- return getMipsPageAddr(OutputSec->Addr) + Addend;
+ return getMipsPageAddr(outputSec->addr) + addend;
}
-uint32_t DynamicReloc::getSymIndex(SymbolTableBaseSection *SymTab) const {
- if (Sym && !UseSymVA)
- return SymTab->getSymbolIndex(Sym);
+uint32_t DynamicReloc::getSymIndex(SymbolTableBaseSection *symTab) const {
+ if (sym && !useSymVA)
+ return symTab->getSymbolIndex(sym);
return 0;
}
-RelocationBaseSection::RelocationBaseSection(StringRef Name, uint32_t Type,
- int32_t DynamicTag,
- int32_t SizeDynamicTag)
- : SyntheticSection(SHF_ALLOC, Type, Config->Wordsize, Name),
- DynamicTag(DynamicTag), SizeDynamicTag(SizeDynamicTag) {}
-
-void RelocationBaseSection::addReloc(RelType DynType, InputSectionBase *IS,
- uint64_t OffsetInSec, Symbol *Sym) {
- addReloc({DynType, IS, OffsetInSec, false, Sym, 0});
-}
-
-void RelocationBaseSection::addReloc(RelType DynType,
- InputSectionBase *InputSec,
- uint64_t OffsetInSec, Symbol *Sym,
- int64_t Addend, RelExpr Expr,
- RelType Type) {
+RelocationBaseSection::RelocationBaseSection(StringRef name, uint32_t type,
+ int32_t dynamicTag,
+ int32_t sizeDynamicTag)
+ : SyntheticSection(SHF_ALLOC, type, config->wordsize, name),
+ dynamicTag(dynamicTag), sizeDynamicTag(sizeDynamicTag) {}
+
+void RelocationBaseSection::addReloc(RelType dynType, InputSectionBase *isec,
+ uint64_t offsetInSec, Symbol *sym) {
+ addReloc({dynType, isec, offsetInSec, false, sym, 0});
+}
+
+void RelocationBaseSection::addReloc(RelType dynType,
+ InputSectionBase *inputSec,
+ uint64_t offsetInSec, Symbol *sym,
+ int64_t addend, RelExpr expr,
+ RelType type) {
// Write the addends to the relocated address if required. We skip
// it if the written value would be zero.
- if (Config->WriteAddends && (Expr != R_ADDEND || Addend != 0))
- InputSec->Relocations.push_back({Expr, Type, OffsetInSec, Addend, Sym});
- addReloc({DynType, InputSec, OffsetInSec, Expr != R_ADDEND, Sym, Addend});
+ if (config->writeAddends && (expr != R_ADDEND || addend != 0))
+ inputSec->relocations.push_back({expr, type, offsetInSec, addend, sym});
+ addReloc({dynType, inputSec, offsetInSec, expr != R_ADDEND, sym, addend});
}
-void RelocationBaseSection::addReloc(const DynamicReloc &Reloc) {
- if (Reloc.Type == Target->RelativeRel)
- ++NumRelativeRelocs;
- Relocs.push_back(Reloc);
+void RelocationBaseSection::addReloc(const DynamicReloc &reloc) {
+ if (reloc.type == target->relativeRel)
+ ++numRelativeRelocs;
+ relocs.push_back(reloc);
}
void RelocationBaseSection::finalizeContents() {
- SymbolTableBaseSection *SymTab = getPartition().DynSymTab;
+ SymbolTableBaseSection *symTab = getPartition().dynSymTab;
// When linking glibc statically, .rel{,a}.plt contains R_*_IRELATIVE
// relocations due to IFUNC (e.g. strcpy). sh_link will be set to 0 in that
// case.
- if (SymTab && SymTab->getParent())
- getParent()->Link = SymTab->getParent()->SectionIndex;
+ if (symTab && symTab->getParent())
+ getParent()->link = symTab->getParent()->sectionIndex;
else
- getParent()->Link = 0;
+ getParent()->link = 0;
- if (In.RelaPlt == this)
- getParent()->Info = In.GotPlt->getParent()->SectionIndex;
- if (In.RelaIplt == this)
- getParent()->Info = In.IgotPlt->getParent()->SectionIndex;
+ if (in.relaPlt == this)
+ getParent()->info = in.gotPlt->getParent()->sectionIndex;
+ if (in.relaIplt == this)
+ getParent()->info = in.igotPlt->getParent()->sectionIndex;
}
RelrBaseSection::RelrBaseSection()
: SyntheticSection(SHF_ALLOC,
- Config->UseAndroidRelrTags ? SHT_ANDROID_RELR : SHT_RELR,
- Config->Wordsize, ".relr.dyn") {}
+ config->useAndroidRelrTags ? SHT_ANDROID_RELR : SHT_RELR,
+ config->wordsize, ".relr.dyn") {}
template <class ELFT>
-static void encodeDynamicReloc(SymbolTableBaseSection *SymTab,
- typename ELFT::Rela *P,
- const DynamicReloc &Rel) {
- if (Config->IsRela)
- P->r_addend = Rel.computeAddend();
- P->r_offset = Rel.getOffset();
- P->setSymbolAndType(Rel.getSymIndex(SymTab), Rel.Type, Config->IsMips64EL);
+static void encodeDynamicReloc(SymbolTableBaseSection *symTab,
+ typename ELFT::Rela *p,
+ const DynamicReloc &rel) {
+ if (config->isRela)
+ p->r_addend = rel.computeAddend();
+ p->r_offset = rel.getOffset();
+ p->setSymbolAndType(rel.getSymIndex(symTab), rel.type, config->isMips64EL);
}
template <class ELFT>
-RelocationSection<ELFT>::RelocationSection(StringRef Name, bool Sort)
- : RelocationBaseSection(Name, Config->IsRela ? SHT_RELA : SHT_REL,
- Config->IsRela ? DT_RELA : DT_REL,
- Config->IsRela ? DT_RELASZ : DT_RELSZ),
- Sort(Sort) {
- this->Entsize = Config->IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
+RelocationSection<ELFT>::RelocationSection(StringRef name, bool sort)
+ : RelocationBaseSection(name, config->isRela ? SHT_RELA : SHT_REL,
+ config->isRela ? DT_RELA : DT_REL,
+ config->isRela ? DT_RELASZ : DT_RELSZ),
+ sort(sort) {
+ this->entsize = config->isRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
}
-template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) {
- SymbolTableBaseSection *SymTab = getPartition().DynSymTab;
+template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *buf) {
+ SymbolTableBaseSection *symTab = getPartition().dynSymTab;
// Sort by (!IsRelative,SymIndex,r_offset). DT_REL[A]COUNT requires us to
// place R_*_RELATIVE first. SymIndex is to improve locality, while r_offset
// is to make results easier to read.
- if (Sort)
+ if (sort)
llvm::stable_sort(
- Relocs, [&](const DynamicReloc &A, const DynamicReloc &B) {
- return std::make_tuple(A.Type != Target->RelativeRel,
- A.getSymIndex(SymTab), A.getOffset()) <
- std::make_tuple(B.Type != Target->RelativeRel,
- B.getSymIndex(SymTab), B.getOffset());
+ relocs, [&](const DynamicReloc &a, const DynamicReloc &b) {
+ return std::make_tuple(a.type != target->relativeRel,
+ a.getSymIndex(symTab), a.getOffset()) <
+ std::make_tuple(b.type != target->relativeRel,
+ b.getSymIndex(symTab), b.getOffset());
});
- for (const DynamicReloc &Rel : Relocs) {
- encodeDynamicReloc<ELFT>(SymTab, reinterpret_cast<Elf_Rela *>(Buf), Rel);
- Buf += Config->IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
+ for (const DynamicReloc &rel : relocs) {
+ encodeDynamicReloc<ELFT>(symTab, reinterpret_cast<Elf_Rela *>(buf), rel);
+ buf += config->isRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
}
}
template <class ELFT>
AndroidPackedRelocationSection<ELFT>::AndroidPackedRelocationSection(
- StringRef Name)
+ StringRef name)
: RelocationBaseSection(
- Name, Config->IsRela ? SHT_ANDROID_RELA : SHT_ANDROID_REL,
- Config->IsRela ? DT_ANDROID_RELA : DT_ANDROID_REL,
- Config->IsRela ? DT_ANDROID_RELASZ : DT_ANDROID_RELSZ) {
- this->Entsize = 1;
+ name, config->isRela ? SHT_ANDROID_RELA : SHT_ANDROID_REL,
+ config->isRela ? DT_ANDROID_RELA : DT_ANDROID_REL,
+ config->isRela ? DT_ANDROID_RELASZ : DT_ANDROID_RELSZ) {
+ this->entsize = 1;
}
template <class ELFT>
@@ -1632,32 +1632,32 @@ bool AndroidPackedRelocationSection<ELFT
// RELOCATION_GROUPED_BY_ADDEND_FLAG is not set) the r_addend delta for
// this relocation.
- size_t OldSize = RelocData.size();
+ size_t oldSize = relocData.size();
- RelocData = {'A', 'P', 'S', '2'};
- raw_svector_ostream OS(RelocData);
- auto Add = [&](int64_t V) { encodeSLEB128(V, OS); };
+ relocData = {'A', 'P', 'S', '2'};
+ raw_svector_ostream os(relocData);
+ auto add = [&](int64_t v) { encodeSLEB128(v, os); };
// The format header includes the number of relocations and the initial
// offset (we set this to zero because the first relocation group will
// perform the initial adjustment).
- Add(Relocs.size());
- Add(0);
+ add(relocs.size());
+ add(0);
- std::vector<Elf_Rela> Relatives, NonRelatives;
+ std::vector<Elf_Rela> relatives, nonRelatives;
- for (const DynamicReloc &Rel : Relocs) {
- Elf_Rela R;
- encodeDynamicReloc<ELFT>(getPartition().DynSymTab, &R, Rel);
+ for (const DynamicReloc &rel : relocs) {
+ Elf_Rela r;
+ encodeDynamicReloc<ELFT>(getPartition().dynSymTab, &r, rel);
- if (R.getType(Config->IsMips64EL) == Target->RelativeRel)
- Relatives.push_back(R);
+ if (r.getType(config->isMips64EL) == target->relativeRel)
+ relatives.push_back(r);
else
- NonRelatives.push_back(R);
+ nonRelatives.push_back(r);
}
- llvm::sort(Relatives, [](const Elf_Rel &A, const Elf_Rel &B) {
- return A.r_offset < B.r_offset;
+ llvm::sort(relatives, [](const Elf_Rel &a, const Elf_Rel &b) {
+ return a.r_offset < b.r_offset;
});
// Try to find groups of relative relocations which are spaced one word
@@ -1666,108 +1666,108 @@ bool AndroidPackedRelocationSection<ELFT
// encoding, but each group will cost 7 bytes in addition to the offset from
// the previous group, so it is only profitable to do this for groups of
// size 8 or larger.
- std::vector<Elf_Rela> UngroupedRelatives;
- std::vector<std::vector<Elf_Rela>> RelativeGroups;
- for (auto I = Relatives.begin(), E = Relatives.end(); I != E;) {
- std::vector<Elf_Rela> Group;
+ std::vector<Elf_Rela> ungroupedRelatives;
+ std::vector<std::vector<Elf_Rela>> relativeGroups;
+ for (auto i = relatives.begin(), e = relatives.end(); i != e;) {
+ std::vector<Elf_Rela> group;
do {
- Group.push_back(*I++);
- } while (I != E && (I - 1)->r_offset + Config->Wordsize == I->r_offset);
+ group.push_back(*i++);
+ } while (i != e && (i - 1)->r_offset + config->wordsize == i->r_offset);
- if (Group.size() < 8)
- UngroupedRelatives.insert(UngroupedRelatives.end(), Group.begin(),
- Group.end());
+ if (group.size() < 8)
+ ungroupedRelatives.insert(ungroupedRelatives.end(), group.begin(),
+ group.end());
else
- RelativeGroups.emplace_back(std::move(Group));
+ relativeGroups.emplace_back(std::move(group));
}
- unsigned HasAddendIfRela =
- Config->IsRela ? RELOCATION_GROUP_HAS_ADDEND_FLAG : 0;
+ unsigned hasAddendIfRela =
+ config->isRela ? RELOCATION_GROUP_HAS_ADDEND_FLAG : 0;
- uint64_t Offset = 0;
- uint64_t Addend = 0;
+ uint64_t offset = 0;
+ uint64_t addend = 0;
// Emit the run-length encoding for the groups of adjacent relative
// relocations. Each group is represented using two groups in the packed
// format. The first is used to set the current offset to the start of the
// group (and also encodes the first relocation), and the second encodes the
// remaining relocations.
- for (std::vector<Elf_Rela> &G : RelativeGroups) {
+ for (std::vector<Elf_Rela> &g : relativeGroups) {
// The first relocation in the group.
- Add(1);
- Add(RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG |
- RELOCATION_GROUPED_BY_INFO_FLAG | HasAddendIfRela);
- Add(G[0].r_offset - Offset);
- Add(Target->RelativeRel);
- if (Config->IsRela) {
- Add(G[0].r_addend - Addend);
- Addend = G[0].r_addend;
+ add(1);
+ add(RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG |
+ RELOCATION_GROUPED_BY_INFO_FLAG | hasAddendIfRela);
+ add(g[0].r_offset - offset);
+ add(target->relativeRel);
+ if (config->isRela) {
+ add(g[0].r_addend - addend);
+ addend = g[0].r_addend;
}
// The remaining relocations.
- Add(G.size() - 1);
- Add(RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG |
- RELOCATION_GROUPED_BY_INFO_FLAG | HasAddendIfRela);
- Add(Config->Wordsize);
- Add(Target->RelativeRel);
- if (Config->IsRela) {
- for (auto I = G.begin() + 1, E = G.end(); I != E; ++I) {
- Add(I->r_addend - Addend);
- Addend = I->r_addend;
+ add(g.size() - 1);
+ add(RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG |
+ RELOCATION_GROUPED_BY_INFO_FLAG | hasAddendIfRela);
+ add(config->wordsize);
+ add(target->relativeRel);
+ if (config->isRela) {
+ for (auto i = g.begin() + 1, e = g.end(); i != e; ++i) {
+ add(i->r_addend - addend);
+ addend = i->r_addend;
}
}
- Offset = G.back().r_offset;
+ offset = g.back().r_offset;
}
// Now the ungrouped relatives.
- if (!UngroupedRelatives.empty()) {
- Add(UngroupedRelatives.size());
- Add(RELOCATION_GROUPED_BY_INFO_FLAG | HasAddendIfRela);
- Add(Target->RelativeRel);
- for (Elf_Rela &R : UngroupedRelatives) {
- Add(R.r_offset - Offset);
- Offset = R.r_offset;
- if (Config->IsRela) {
- Add(R.r_addend - Addend);
- Addend = R.r_addend;
+ if (!ungroupedRelatives.empty()) {
+ add(ungroupedRelatives.size());
+ add(RELOCATION_GROUPED_BY_INFO_FLAG | hasAddendIfRela);
+ add(target->relativeRel);
+ for (Elf_Rela &r : ungroupedRelatives) {
+ add(r.r_offset - offset);
+ offset = r.r_offset;
+ if (config->isRela) {
+ add(r.r_addend - addend);
+ addend = r.r_addend;
}
}
}
// Finally the non-relative relocations.
- llvm::sort(NonRelatives, [](const Elf_Rela &A, const Elf_Rela &B) {
- return A.r_offset < B.r_offset;
+ llvm::sort(nonRelatives, [](const Elf_Rela &a, const Elf_Rela &b) {
+ return a.r_offset < b.r_offset;
});
- if (!NonRelatives.empty()) {
- Add(NonRelatives.size());
- Add(HasAddendIfRela);
- for (Elf_Rela &R : NonRelatives) {
- Add(R.r_offset - Offset);
- Offset = R.r_offset;
- Add(R.r_info);
- if (Config->IsRela) {
- Add(R.r_addend - Addend);
- Addend = R.r_addend;
+ if (!nonRelatives.empty()) {
+ add(nonRelatives.size());
+ add(hasAddendIfRela);
+ for (Elf_Rela &r : nonRelatives) {
+ add(r.r_offset - offset);
+ offset = r.r_offset;
+ add(r.r_info);
+ if (config->isRela) {
+ add(r.r_addend - addend);
+ addend = r.r_addend;
}
}
}
// Don't allow the section to shrink; otherwise the size of the section can
// oscillate infinitely.
- if (RelocData.size() < OldSize)
- RelocData.append(OldSize - RelocData.size(), 0);
+ if (relocData.size() < oldSize)
+ relocData.append(oldSize - relocData.size(), 0);
// Returns whether the section size changed. We need to keep recomputing both
// section layout and the contents of this section until the size converges
// because changing this section's size can affect section layout, which in
// turn can affect the sizes of the LEB-encoded integers stored in this
// section.
- return RelocData.size() != OldSize;
+ return relocData.size() != oldSize;
}
template <class ELFT> RelrSection<ELFT>::RelrSection() {
- this->Entsize = Config->Wordsize;
+ this->entsize = config->wordsize;
}
template <class ELFT> bool RelrSection<ELFT>::updateAllocSize() {
@@ -1801,90 +1801,90 @@ template <class ELFT> bool RelrSection<E
// even means address, odd means bitmap.
// 2. Just a simple list of addresses is a valid encoding.
- size_t OldSize = RelrRelocs.size();
- RelrRelocs.clear();
+ size_t oldSize = relrRelocs.size();
+ relrRelocs.clear();
// Same as Config->Wordsize but faster because this is a compile-time
// constant.
- const size_t Wordsize = sizeof(typename ELFT::uint);
+ const size_t wordsize = sizeof(typename ELFT::uint);
// Number of bits to use for the relocation offsets bitmap.
// Must be either 63 or 31.
- const size_t NBits = Wordsize * 8 - 1;
+ const size_t nBits = wordsize * 8 - 1;
// Get offsets for all relative relocations and sort them.
- std::vector<uint64_t> Offsets;
- for (const RelativeReloc &Rel : Relocs)
- Offsets.push_back(Rel.getOffset());
- llvm::sort(Offsets);
+ std::vector<uint64_t> offsets;
+ for (const RelativeReloc &rel : relocs)
+ offsets.push_back(rel.getOffset());
+ llvm::sort(offsets);
// For each leading relocation, find following ones that can be folded
// as a bitmap and fold them.
- for (size_t I = 0, E = Offsets.size(); I < E;) {
+ for (size_t i = 0, e = offsets.size(); i < e;) {
// Add a leading relocation.
- RelrRelocs.push_back(Elf_Relr(Offsets[I]));
- uint64_t Base = Offsets[I] + Wordsize;
- ++I;
+ relrRelocs.push_back(Elf_Relr(offsets[i]));
+ uint64_t base = offsets[i] + wordsize;
+ ++i;
// Find foldable relocations to construct bitmaps.
- while (I < E) {
- uint64_t Bitmap = 0;
+ while (i < e) {
+ uint64_t bitmap = 0;
- while (I < E) {
- uint64_t Delta = Offsets[I] - Base;
+ while (i < e) {
+ uint64_t delta = offsets[i] - base;
// If it is too far, it cannot be folded.
- if (Delta >= NBits * Wordsize)
+ if (delta >= nBits * wordsize)
break;
// If it is not a multiple of wordsize away, it cannot be folded.
- if (Delta % Wordsize)
+ if (delta % wordsize)
break;
// Fold it.
- Bitmap |= 1ULL << (Delta / Wordsize);
- ++I;
+ bitmap |= 1ULL << (delta / wordsize);
+ ++i;
}
- if (!Bitmap)
+ if (!bitmap)
break;
- RelrRelocs.push_back(Elf_Relr((Bitmap << 1) | 1));
- Base += NBits * Wordsize;
+ relrRelocs.push_back(Elf_Relr((bitmap << 1) | 1));
+ base += nBits * wordsize;
}
}
- return RelrRelocs.size() != OldSize;
+ return relrRelocs.size() != oldSize;
}
-SymbolTableBaseSection::SymbolTableBaseSection(StringTableSection &StrTabSec)
- : SyntheticSection(StrTabSec.isDynamic() ? (uint64_t)SHF_ALLOC : 0,
- StrTabSec.isDynamic() ? SHT_DYNSYM : SHT_SYMTAB,
- Config->Wordsize,
- StrTabSec.isDynamic() ? ".dynsym" : ".symtab"),
- StrTabSec(StrTabSec) {}
+SymbolTableBaseSection::SymbolTableBaseSection(StringTableSection &strTabSec)
+ : SyntheticSection(strTabSec.isDynamic() ? (uint64_t)SHF_ALLOC : 0,
+ strTabSec.isDynamic() ? SHT_DYNSYM : SHT_SYMTAB,
+ config->wordsize,
+ strTabSec.isDynamic() ? ".dynsym" : ".symtab"),
+ strTabSec(strTabSec) {}
// Orders symbols according to their positions in the GOT,
// in compliance with MIPS ABI rules.
// See "Global Offset Table" in Chapter 5 in the following document
// for detailed description:
// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
-static bool sortMipsSymbols(const SymbolTableEntry &L,
- const SymbolTableEntry &R) {
+static bool sortMipsSymbols(const SymbolTableEntry &l,
+ const SymbolTableEntry &r) {
// Sort entries related to non-local preemptible symbols by GOT indexes.
// All other entries go to the beginning of a dynsym in arbitrary order.
- if (L.Sym->isInGot() && R.Sym->isInGot())
- return L.Sym->GotIndex < R.Sym->GotIndex;
- if (!L.Sym->isInGot() && !R.Sym->isInGot())
+ if (l.sym->isInGot() && r.sym->isInGot())
+ return l.sym->gotIndex < r.sym->gotIndex;
+ if (!l.sym->isInGot() && !r.sym->isInGot())
return false;
- return !L.Sym->isInGot();
+ return !l.sym->isInGot();
}
void SymbolTableBaseSection::finalizeContents() {
- if (OutputSection *Sec = StrTabSec.getParent())
- getParent()->Link = Sec->SectionIndex;
+ if (OutputSection *sec = strTabSec.getParent())
+ getParent()->link = sec->sectionIndex;
- if (this->Type != SHT_DYNSYM) {
+ if (this->type != SHT_DYNSYM) {
sortSymTabSymbols();
return;
}
@@ -1894,21 +1894,21 @@ void SymbolTableBaseSection::finalizeCon
// Section's Info field has the index of the first non-local symbol.
// Because the first symbol entry is a null entry, 1 is the first.
- getParent()->Info = 1;
+ getParent()->info = 1;
- if (getPartition().GnuHashTab) {
+ if (getPartition().gnuHashTab) {
// NB: It also sorts Symbols to meet the GNU hash table requirements.
- getPartition().GnuHashTab->addSymbols(Symbols);
- } else if (Config->EMachine == EM_MIPS) {
- llvm::stable_sort(Symbols, sortMipsSymbols);
+ getPartition().gnuHashTab->addSymbols(symbols);
+ } else if (config->emachine == EM_MIPS) {
+ llvm::stable_sort(symbols, sortMipsSymbols);
}
// Only the main partition's dynsym indexes are stored in the symbols
// themselves. All other partitions use a lookup table.
- if (this == Main->DynSymTab) {
- size_t I = 0;
- for (const SymbolTableEntry &S : Symbols)
- S.Sym->DynsymIndex = ++I;
+ if (this == mainPart->dynSymTab) {
+ size_t i = 0;
+ for (const SymbolTableEntry &s : symbols)
+ s.sym->dynsymIndex = ++i;
}
}
@@ -1921,150 +1921,150 @@ void SymbolTableBaseSection::finalizeCon
// coming from.
void SymbolTableBaseSection::sortSymTabSymbols() {
// Move all local symbols before global symbols.
- auto E = std::stable_partition(
- Symbols.begin(), Symbols.end(), [](const SymbolTableEntry &S) {
- return S.Sym->isLocal() || S.Sym->computeBinding() == STB_LOCAL;
+ auto e = std::stable_partition(
+ symbols.begin(), symbols.end(), [](const SymbolTableEntry &s) {
+ return s.sym->isLocal() || s.sym->computeBinding() == STB_LOCAL;
});
- size_t NumLocals = E - Symbols.begin();
- getParent()->Info = NumLocals + 1;
+ size_t numLocals = e - symbols.begin();
+ getParent()->info = numLocals + 1;
// We want to group the local symbols by file. For that we rebuild the local
// part of the symbols vector. We do not need to care about the STT_FILE
// symbols, they are already naturally placed first in each group. That
// happens because STT_FILE is always the first symbol in the object and hence
// precede all other local symbols we add for a file.
- MapVector<InputFile *, std::vector<SymbolTableEntry>> Arr;
- for (const SymbolTableEntry &S : llvm::make_range(Symbols.begin(), E))
- Arr[S.Sym->File].push_back(S);
+ MapVector<InputFile *, std::vector<SymbolTableEntry>> arr;
+ for (const SymbolTableEntry &s : llvm::make_range(symbols.begin(), e))
+ arr[s.sym->file].push_back(s);
- auto I = Symbols.begin();
- for (std::pair<InputFile *, std::vector<SymbolTableEntry>> &P : Arr)
- for (SymbolTableEntry &Entry : P.second)
- *I++ = Entry;
+ auto i = symbols.begin();
+ for (std::pair<InputFile *, std::vector<SymbolTableEntry>> &p : arr)
+ for (SymbolTableEntry &entry : p.second)
+ *i++ = entry;
}
-void SymbolTableBaseSection::addSymbol(Symbol *B) {
+void SymbolTableBaseSection::addSymbol(Symbol *b) {
// Adding a local symbol to a .dynsym is a bug.
- assert(this->Type != SHT_DYNSYM || !B->isLocal());
+ assert(this->type != SHT_DYNSYM || !b->isLocal());
- bool HashIt = B->isLocal();
- Symbols.push_back({B, StrTabSec.addString(B->getName(), HashIt)});
+ bool hashIt = b->isLocal();
+ symbols.push_back({b, strTabSec.addString(b->getName(), hashIt)});
}
-size_t SymbolTableBaseSection::getSymbolIndex(Symbol *Sym) {
- if (this == Main->DynSymTab)
- return Sym->DynsymIndex;
+size_t SymbolTableBaseSection::getSymbolIndex(Symbol *sym) {
+ if (this == mainPart->dynSymTab)
+ return sym->dynsymIndex;
// Initializes symbol lookup tables lazily. This is used only for -r,
// -emit-relocs and dynsyms in partitions other than the main one.
- llvm::call_once(OnceFlag, [&] {
- SymbolIndexMap.reserve(Symbols.size());
- size_t I = 0;
- for (const SymbolTableEntry &E : Symbols) {
- if (E.Sym->Type == STT_SECTION)
- SectionIndexMap[E.Sym->getOutputSection()] = ++I;
+ llvm::call_once(onceFlag, [&] {
+ symbolIndexMap.reserve(symbols.size());
+ size_t i = 0;
+ for (const SymbolTableEntry &e : symbols) {
+ if (e.sym->type == STT_SECTION)
+ sectionIndexMap[e.sym->getOutputSection()] = ++i;
else
- SymbolIndexMap[E.Sym] = ++I;
+ symbolIndexMap[e.sym] = ++i;
}
});
// Section symbols are mapped based on their output sections
// to maintain their semantics.
- if (Sym->Type == STT_SECTION)
- return SectionIndexMap.lookup(Sym->getOutputSection());
- return SymbolIndexMap.lookup(Sym);
+ if (sym->type == STT_SECTION)
+ return sectionIndexMap.lookup(sym->getOutputSection());
+ return symbolIndexMap.lookup(sym);
}
template <class ELFT>
-SymbolTableSection<ELFT>::SymbolTableSection(StringTableSection &StrTabSec)
- : SymbolTableBaseSection(StrTabSec) {
- this->Entsize = sizeof(Elf_Sym);
+SymbolTableSection<ELFT>::SymbolTableSection(StringTableSection &strTabSec)
+ : SymbolTableBaseSection(strTabSec) {
+ this->entsize = sizeof(Elf_Sym);
}
-static BssSection *getCommonSec(Symbol *Sym) {
- if (!Config->DefineCommon)
- if (auto *D = dyn_cast<Defined>(Sym))
- return dyn_cast_or_null<BssSection>(D->Section);
+static BssSection *getCommonSec(Symbol *sym) {
+ if (!config->defineCommon)
+ if (auto *d = dyn_cast<Defined>(sym))
+ return dyn_cast_or_null<BssSection>(d->section);
return nullptr;
}
-static uint32_t getSymSectionIndex(Symbol *Sym) {
- if (getCommonSec(Sym))
+static uint32_t getSymSectionIndex(Symbol *sym) {
+ if (getCommonSec(sym))
return SHN_COMMON;
- if (!isa<Defined>(Sym) || Sym->NeedsPltAddr)
+ if (!isa<Defined>(sym) || sym->needsPltAddr)
return SHN_UNDEF;
- if (const OutputSection *OS = Sym->getOutputSection())
- return OS->SectionIndex >= SHN_LORESERVE ? (uint32_t)SHN_XINDEX
- : OS->SectionIndex;
+ if (const OutputSection *os = sym->getOutputSection())
+ return os->sectionIndex >= SHN_LORESERVE ? (uint32_t)SHN_XINDEX
+ : os->sectionIndex;
return SHN_ABS;
}
// Write the internal symbol table contents to the output symbol table.
-template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) {
+template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *buf) {
// The first entry is a null entry as per the ELF spec.
- memset(Buf, 0, sizeof(Elf_Sym));
- Buf += sizeof(Elf_Sym);
+ memset(buf, 0, sizeof(Elf_Sym));
+ buf += sizeof(Elf_Sym);
- auto *ESym = reinterpret_cast<Elf_Sym *>(Buf);
+ auto *eSym = reinterpret_cast<Elf_Sym *>(buf);
- for (SymbolTableEntry &Ent : Symbols) {
- Symbol *Sym = Ent.Sym;
- bool IsDefinedHere = Type == SHT_SYMTAB || Sym->Partition == Partition;
+ for (SymbolTableEntry &ent : symbols) {
+ Symbol *sym = ent.sym;
+ bool isDefinedHere = type == SHT_SYMTAB || sym->partition == partition;
// Set st_info and st_other.
- ESym->st_other = 0;
- if (Sym->isLocal()) {
- ESym->setBindingAndType(STB_LOCAL, Sym->Type);
+ eSym->st_other = 0;
+ if (sym->isLocal()) {
+ eSym->setBindingAndType(STB_LOCAL, sym->type);
} else {
- ESym->setBindingAndType(Sym->computeBinding(), Sym->Type);
- ESym->setVisibility(Sym->Visibility);
+ eSym->setBindingAndType(sym->computeBinding(), sym->type);
+ eSym->setVisibility(sym->visibility);
}
// The 3 most significant bits of st_other are used by OpenPOWER ABI.
// See getPPC64GlobalEntryToLocalEntryOffset() for more details.
- if (Config->EMachine == EM_PPC64)
- ESym->st_other |= Sym->StOther & 0xe0;
+ if (config->emachine == EM_PPC64)
+ eSym->st_other |= sym->stOther & 0xe0;
- ESym->st_name = Ent.StrTabOffset;
- if (IsDefinedHere)
- ESym->st_shndx = getSymSectionIndex(Ent.Sym);
+ eSym->st_name = ent.strTabOffset;
+ if (isDefinedHere)
+ eSym->st_shndx = getSymSectionIndex(ent.sym);
else
- ESym->st_shndx = 0;
+ eSym->st_shndx = 0;
// Copy symbol size if it is a defined symbol. st_size is not significant
// for undefined symbols, so whether copying it or not is up to us if that's
// the case. We'll leave it as zero because by not setting a value, we can
// get the exact same outputs for two sets of input files that differ only
// in undefined symbol size in DSOs.
- if (ESym->st_shndx == SHN_UNDEF || !IsDefinedHere)
- ESym->st_size = 0;
+ if (eSym->st_shndx == SHN_UNDEF || !isDefinedHere)
+ eSym->st_size = 0;
else
- ESym->st_size = Sym->getSize();
+ eSym->st_size = sym->getSize();
// st_value is usually an address of a symbol, but that has a
// special meaining for uninstantiated common symbols (this can
// occur if -r is given).
- if (BssSection *CommonSec = getCommonSec(Ent.Sym))
- ESym->st_value = CommonSec->Alignment;
- else if (IsDefinedHere)
- ESym->st_value = Sym->getVA();
+ if (BssSection *commonSec = getCommonSec(ent.sym))
+ eSym->st_value = commonSec->alignment;
+ else if (isDefinedHere)
+ eSym->st_value = sym->getVA();
else
- ESym->st_value = 0;
+ eSym->st_value = 0;
- ++ESym;
+ ++eSym;
}
// On MIPS we need to mark symbol which has a PLT entry and requires
// pointer equality by STO_MIPS_PLT flag. That is necessary to help
// dynamic linker distinguish such symbols and MIPS lazy-binding stubs.
// https://sourceware.org/ml/binutils/2008-07/txt00000.txt
- if (Config->EMachine == EM_MIPS) {
- auto *ESym = reinterpret_cast<Elf_Sym *>(Buf);
+ if (config->emachine == EM_MIPS) {
+ auto *eSym = reinterpret_cast<Elf_Sym *>(buf);
- for (SymbolTableEntry &Ent : Symbols) {
- Symbol *Sym = Ent.Sym;
- if (Sym->isInPlt() && Sym->NeedsPltAddr)
- ESym->st_other |= STO_MIPS_PLT;
+ for (SymbolTableEntry &ent : symbols) {
+ Symbol *sym = ent.sym;
+ if (sym->isInPlt() && sym->needsPltAddr)
+ eSym->st_other |= STO_MIPS_PLT;
if (isMicroMips()) {
// We already set the less-significant bit for symbols
// marked by the `STO_MIPS_MICROMIPS` flag and for microMIPS PLT
@@ -2073,36 +2073,36 @@ template <class ELFT> void SymbolTableSe
// clear that bit for non-dynamic symbol table, so tools
// like `objdump` will be able to deal with a correct
// symbol position.
- if (Sym->isDefined() &&
- ((Sym->StOther & STO_MIPS_MICROMIPS) || Sym->NeedsPltAddr)) {
- if (!StrTabSec.isDynamic())
- ESym->st_value &= ~1;
- ESym->st_other |= STO_MIPS_MICROMIPS;
+ if (sym->isDefined() &&
+ ((sym->stOther & STO_MIPS_MICROMIPS) || sym->needsPltAddr)) {
+ if (!strTabSec.isDynamic())
+ eSym->st_value &= ~1;
+ eSym->st_other |= STO_MIPS_MICROMIPS;
}
}
- if (Config->Relocatable)
- if (auto *D = dyn_cast<Defined>(Sym))
- if (isMipsPIC<ELFT>(D))
- ESym->st_other |= STO_MIPS_PIC;
- ++ESym;
+ if (config->relocatable)
+ if (auto *d = dyn_cast<Defined>(sym))
+ if (isMipsPIC<ELFT>(d))
+ eSym->st_other |= STO_MIPS_PIC;
+ ++eSym;
}
}
}
SymtabShndxSection::SymtabShndxSection()
: SyntheticSection(0, SHT_SYMTAB_SHNDX, 4, ".symtab_shndx") {
- this->Entsize = 4;
+ this->entsize = 4;
}
-void SymtabShndxSection::writeTo(uint8_t *Buf) {
+void SymtabShndxSection::writeTo(uint8_t *buf) {
// We write an array of 32 bit values, where each value has 1:1 association
// with an entry in .symtab. If the corresponding entry contains SHN_XINDEX,
// we need to write actual index, otherwise, we must write SHN_UNDEF(0).
- Buf += 4; // Ignore .symtab[0] entry.
- for (const SymbolTableEntry &Entry : In.SymTab->getSymbols()) {
- if (getSymSectionIndex(Entry.Sym) == SHN_XINDEX)
- write32(Buf, Entry.Sym->getOutputSection()->SectionIndex);
- Buf += 4;
+ buf += 4; // Ignore .symtab[0] entry.
+ for (const SymbolTableEntry &entry : in.symTab->getSymbols()) {
+ if (getSymSectionIndex(entry.sym) == SHN_XINDEX)
+ write32(buf, entry.sym->getOutputSection()->sectionIndex);
+ buf += 4;
}
}
@@ -2112,19 +2112,19 @@ bool SymtabShndxSection::isNeeded() cons
// section. Problem is that we reveal the final section indices a bit too
// late, and we do not know them here. For simplicity, we just always create
// a .symtab_shndx section when the amount of output sections is huge.
- size_t Size = 0;
- for (BaseCommand *Base : Script->SectionCommands)
- if (isa<OutputSection>(Base))
- ++Size;
- return Size >= SHN_LORESERVE;
+ size_t size = 0;
+ for (BaseCommand *base : script->sectionCommands)
+ if (isa<OutputSection>(base))
+ ++size;
+ return size >= SHN_LORESERVE;
}
void SymtabShndxSection::finalizeContents() {
- getParent()->Link = In.SymTab->getParent()->SectionIndex;
+ getParent()->link = in.symTab->getParent()->sectionIndex;
}
size_t SymtabShndxSection::getSize() const {
- return In.SymTab->getNumSymbols() * 4;
+ return in.symTab->getNumSymbols() * 4;
}
// .hash and .gnu.hash sections contain on-disk hash tables that map
@@ -2159,45 +2159,45 @@ size_t SymtabShndxSection::getSize() con
// about .gnu.hash, you want to specify -hash-style=gnu. Otherwise, a
// safe bet is to specify -hash-style=both for backward compatibilty.
GnuHashTableSection::GnuHashTableSection()
- : SyntheticSection(SHF_ALLOC, SHT_GNU_HASH, Config->Wordsize, ".gnu.hash") {
+ : SyntheticSection(SHF_ALLOC, SHT_GNU_HASH, config->wordsize, ".gnu.hash") {
}
void GnuHashTableSection::finalizeContents() {
- if (OutputSection *Sec = getPartition().DynSymTab->getParent())
- getParent()->Link = Sec->SectionIndex;
+ if (OutputSection *sec = getPartition().dynSymTab->getParent())
+ getParent()->link = sec->sectionIndex;
// Computes bloom filter size in word size. We want to allocate 12
// bits for each symbol. It must be a power of two.
- if (Symbols.empty()) {
- MaskWords = 1;
+ if (symbols.empty()) {
+ maskWords = 1;
} else {
- uint64_t NumBits = Symbols.size() * 12;
- MaskWords = NextPowerOf2(NumBits / (Config->Wordsize * 8));
+ uint64_t numBits = symbols.size() * 12;
+ maskWords = NextPowerOf2(numBits / (config->wordsize * 8));
}
- Size = 16; // Header
- Size += Config->Wordsize * MaskWords; // Bloom filter
- Size += NBuckets * 4; // Hash buckets
- Size += Symbols.size() * 4; // Hash values
+ size = 16; // Header
+ size += config->wordsize * maskWords; // Bloom filter
+ size += nBuckets * 4; // Hash buckets
+ size += symbols.size() * 4; // Hash values
}
-void GnuHashTableSection::writeTo(uint8_t *Buf) {
+void GnuHashTableSection::writeTo(uint8_t *buf) {
// The output buffer is not guaranteed to be zero-cleared because we pre-
// fill executable sections with trap instructions. This is a precaution
// for that case, which happens only when -no-rosegment is given.
- memset(Buf, 0, Size);
+ memset(buf, 0, size);
// Write a header.
- write32(Buf, NBuckets);
- write32(Buf + 4, getPartition().DynSymTab->getNumSymbols() - Symbols.size());
- write32(Buf + 8, MaskWords);
- write32(Buf + 12, Shift2);
- Buf += 16;
+ write32(buf, nBuckets);
+ write32(buf + 4, getPartition().dynSymTab->getNumSymbols() - symbols.size());
+ write32(buf + 8, maskWords);
+ write32(buf + 12, Shift2);
+ buf += 16;
// Write a bloom filter and a hash table.
- writeBloomFilter(Buf);
- Buf += Config->Wordsize * MaskWords;
- writeHashTable(Buf);
+ writeBloomFilter(buf);
+ buf += config->wordsize * maskWords;
+ writeHashTable(buf);
}
// This function writes a 2-bit bloom filter. This bloom filter alone
@@ -2207,58 +2207,58 @@ void GnuHashTableSection::writeTo(uint8_
//
// [1] Ulrich Drepper (2011), "How To Write Shared Libraries" (Ver. 4.1.2),
// p.9, https://www.akkadia.org/drepper/dsohowto.pdf
-void GnuHashTableSection::writeBloomFilter(uint8_t *Buf) {
- unsigned C = Config->Is64 ? 64 : 32;
- for (const Entry &Sym : Symbols) {
+void GnuHashTableSection::writeBloomFilter(uint8_t *buf) {
+ unsigned c = config->is64 ? 64 : 32;
+ for (const Entry &sym : symbols) {
// When C = 64, we choose a word with bits [6:...] and set 1 to two bits in
// the word using bits [0:5] and [26:31].
- size_t I = (Sym.Hash / C) & (MaskWords - 1);
- uint64_t Val = readUint(Buf + I * Config->Wordsize);
- Val |= uint64_t(1) << (Sym.Hash % C);
- Val |= uint64_t(1) << ((Sym.Hash >> Shift2) % C);
- writeUint(Buf + I * Config->Wordsize, Val);
+ size_t i = (sym.hash / c) & (maskWords - 1);
+ uint64_t val = readUint(buf + i * config->wordsize);
+ val |= uint64_t(1) << (sym.hash % c);
+ val |= uint64_t(1) << ((sym.hash >> Shift2) % c);
+ writeUint(buf + i * config->wordsize, val);
}
}
-void GnuHashTableSection::writeHashTable(uint8_t *Buf) {
- uint32_t *Buckets = reinterpret_cast<uint32_t *>(Buf);
- uint32_t OldBucket = -1;
- uint32_t *Values = Buckets + NBuckets;
- for (auto I = Symbols.begin(), E = Symbols.end(); I != E; ++I) {
+void GnuHashTableSection::writeHashTable(uint8_t *buf) {
+ uint32_t *buckets = reinterpret_cast<uint32_t *>(buf);
+ uint32_t oldBucket = -1;
+ uint32_t *values = buckets + nBuckets;
+ for (auto i = symbols.begin(), e = symbols.end(); i != e; ++i) {
// Write a hash value. It represents a sequence of chains that share the
// same hash modulo value. The last element of each chain is terminated by
// LSB 1.
- uint32_t Hash = I->Hash;
- bool IsLastInChain = (I + 1) == E || I->BucketIdx != (I + 1)->BucketIdx;
- Hash = IsLastInChain ? Hash | 1 : Hash & ~1;
- write32(Values++, Hash);
+ uint32_t hash = i->hash;
+ bool isLastInChain = (i + 1) == e || i->bucketIdx != (i + 1)->bucketIdx;
+ hash = isLastInChain ? hash | 1 : hash & ~1;
+ write32(values++, hash);
- if (I->BucketIdx == OldBucket)
+ if (i->bucketIdx == oldBucket)
continue;
// Write a hash bucket. Hash buckets contain indices in the following hash
// value table.
- write32(Buckets + I->BucketIdx,
- getPartition().DynSymTab->getSymbolIndex(I->Sym));
- OldBucket = I->BucketIdx;
+ write32(buckets + i->bucketIdx,
+ getPartition().dynSymTab->getSymbolIndex(i->sym));
+ oldBucket = i->bucketIdx;
}
}
-static uint32_t hashGnu(StringRef Name) {
- uint32_t H = 5381;
- for (uint8_t C : Name)
- H = (H << 5) + H + C;
- return H;
+static uint32_t hashGnu(StringRef name) {
+ uint32_t h = 5381;
+ for (uint8_t c : name)
+ h = (h << 5) + h + c;
+ return h;
}
// Add symbols to this symbol hash table. Note that this function
// destructively sort a given vector -- which is needed because
// GNU-style hash table places some sorting requirements.
-void GnuHashTableSection::addSymbols(std::vector<SymbolTableEntry> &V) {
+void GnuHashTableSection::addSymbols(std::vector<SymbolTableEntry> &v) {
// We cannot use 'auto' for Mid because GCC 6.1 cannot deduce
// its type correctly.
- std::vector<SymbolTableEntry>::iterator Mid =
- std::stable_partition(V.begin(), V.end(), [&](const SymbolTableEntry &S) {
- return !S.Sym->isDefined() || S.Sym->Partition != Partition;
+ std::vector<SymbolTableEntry>::iterator mid =
+ std::stable_partition(v.begin(), v.end(), [&](const SymbolTableEntry &s) {
+ return !s.sym->isDefined() || s.sym->partition != partition;
});
// We chose load factor 4 for the on-disk hash table. For each hash
@@ -2270,143 +2270,143 @@ void GnuHashTableSection::addSymbols(std
// Android loader as of 2018 doesn't like a .gnu.hash containing such
// table. If that's the case, we create a hash table with one unused
// dummy slot.
- NBuckets = std::max<size_t>((V.end() - Mid) / 4, 1);
+ nBuckets = std::max<size_t>((v.end() - mid) / 4, 1);
- if (Mid == V.end())
+ if (mid == v.end())
return;
- for (SymbolTableEntry &Ent : llvm::make_range(Mid, V.end())) {
- Symbol *B = Ent.Sym;
- uint32_t Hash = hashGnu(B->getName());
- uint32_t BucketIdx = Hash % NBuckets;
- Symbols.push_back({B, Ent.StrTabOffset, Hash, BucketIdx});
+ for (SymbolTableEntry &ent : llvm::make_range(mid, v.end())) {
+ Symbol *b = ent.sym;
+ uint32_t hash = hashGnu(b->getName());
+ uint32_t bucketIdx = hash % nBuckets;
+ symbols.push_back({b, ent.strTabOffset, hash, bucketIdx});
}
- llvm::stable_sort(Symbols, [](const Entry &L, const Entry &R) {
- return L.BucketIdx < R.BucketIdx;
+ llvm::stable_sort(symbols, [](const Entry &l, const Entry &r) {
+ return l.bucketIdx < r.bucketIdx;
});
- V.erase(Mid, V.end());
- for (const Entry &Ent : Symbols)
- V.push_back({Ent.Sym, Ent.StrTabOffset});
+ v.erase(mid, v.end());
+ for (const Entry &ent : symbols)
+ v.push_back({ent.sym, ent.strTabOffset});
}
HashTableSection::HashTableSection()
: SyntheticSection(SHF_ALLOC, SHT_HASH, 4, ".hash") {
- this->Entsize = 4;
+ this->entsize = 4;
}
void HashTableSection::finalizeContents() {
- SymbolTableBaseSection *SymTab = getPartition().DynSymTab;
+ SymbolTableBaseSection *symTab = getPartition().dynSymTab;
- if (OutputSection *Sec = SymTab->getParent())
- getParent()->Link = Sec->SectionIndex;
+ if (OutputSection *sec = symTab->getParent())
+ getParent()->link = sec->sectionIndex;
- unsigned NumEntries = 2; // nbucket and nchain.
- NumEntries += SymTab->getNumSymbols(); // The chain entries.
+ unsigned numEntries = 2; // nbucket and nchain.
+ numEntries += symTab->getNumSymbols(); // The chain entries.
// Create as many buckets as there are symbols.
- NumEntries += SymTab->getNumSymbols();
- this->Size = NumEntries * 4;
+ numEntries += symTab->getNumSymbols();
+ this->size = numEntries * 4;
}
-void HashTableSection::writeTo(uint8_t *Buf) {
- SymbolTableBaseSection *SymTab = getPartition().DynSymTab;
+void HashTableSection::writeTo(uint8_t *buf) {
+ SymbolTableBaseSection *symTab = getPartition().dynSymTab;
// See comment in GnuHashTableSection::writeTo.
- memset(Buf, 0, Size);
+ memset(buf, 0, size);
- unsigned NumSymbols = SymTab->getNumSymbols();
+ unsigned numSymbols = symTab->getNumSymbols();
- uint32_t *P = reinterpret_cast<uint32_t *>(Buf);
- write32(P++, NumSymbols); // nbucket
- write32(P++, NumSymbols); // nchain
-
- uint32_t *Buckets = P;
- uint32_t *Chains = P + NumSymbols;
-
- for (const SymbolTableEntry &S : SymTab->getSymbols()) {
- Symbol *Sym = S.Sym;
- StringRef Name = Sym->getName();
- unsigned I = Sym->DynsymIndex;
- uint32_t Hash = hashSysV(Name) % NumSymbols;
- Chains[I] = Buckets[Hash];
- write32(Buckets + Hash, I);
+ uint32_t *p = reinterpret_cast<uint32_t *>(buf);
+ write32(p++, numSymbols); // nbucket
+ write32(p++, numSymbols); // nchain
+
+ uint32_t *buckets = p;
+ uint32_t *chains = p + numSymbols;
+
+ for (const SymbolTableEntry &s : symTab->getSymbols()) {
+ Symbol *sym = s.sym;
+ StringRef name = sym->getName();
+ unsigned i = sym->dynsymIndex;
+ uint32_t hash = hashSysV(name) % numSymbols;
+ chains[i] = buckets[hash];
+ write32(buckets + hash, i);
}
}
// On PowerPC64 the lazy symbol resolvers go into the `global linkage table`
// in the .glink section, rather then the typical .plt section.
-PltSection::PltSection(bool IsIplt)
+PltSection::PltSection(bool isIplt)
: SyntheticSection(
SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, 16,
- (Config->EMachine == EM_PPC || Config->EMachine == EM_PPC64)
+ (config->emachine == EM_PPC || config->emachine == EM_PPC64)
? ".glink"
: ".plt"),
- HeaderSize(!IsIplt || Config->ZRetpolineplt ? Target->PltHeaderSize : 0),
- IsIplt(IsIplt) {
+ headerSize(!isIplt || config->zRetpolineplt ? target->pltHeaderSize : 0),
+ isIplt(isIplt) {
// The PLT needs to be writable on SPARC as the dynamic linker will
// modify the instructions in the PLT entries.
- if (Config->EMachine == EM_SPARCV9)
- this->Flags |= SHF_WRITE;
+ if (config->emachine == EM_SPARCV9)
+ this->flags |= SHF_WRITE;
}
-void PltSection::writeTo(uint8_t *Buf) {
- if (Config->EMachine == EM_PPC) {
- writePPC32GlinkSection(Buf, Entries.size());
+void PltSection::writeTo(uint8_t *buf) {
+ if (config->emachine == EM_PPC) {
+ writePPC32GlinkSection(buf, entries.size());
return;
}
// At beginning of PLT or retpoline IPLT, we have code to call the dynamic
// linker to resolve dynsyms at runtime. Write such code.
- if (HeaderSize)
- Target->writePltHeader(Buf);
- size_t Off = HeaderSize;
+ if (headerSize)
+ target->writePltHeader(buf);
+ size_t off = headerSize;
- RelocationBaseSection *RelSec = IsIplt ? In.RelaIplt : In.RelaPlt;
+ RelocationBaseSection *relSec = isIplt ? in.relaIplt : in.relaPlt;
// The IPlt is immediately after the Plt, account for this in RelOff
- size_t PltOff = IsIplt ? In.Plt->getSize() : 0;
+ size_t pltOff = isIplt ? in.plt->getSize() : 0;
- for (size_t I = 0, E = Entries.size(); I != E; ++I) {
- const Symbol *B = Entries[I];
- unsigned RelOff = RelSec->Entsize * I + PltOff;
- uint64_t Got = B->getGotPltVA();
- uint64_t Plt = this->getVA() + Off;
- Target->writePlt(Buf + Off, Got, Plt, B->PltIndex, RelOff);
- Off += Target->PltEntrySize;
+ for (size_t i = 0, e = entries.size(); i != e; ++i) {
+ const Symbol *b = entries[i];
+ unsigned relOff = relSec->entsize * i + pltOff;
+ uint64_t got = b->getGotPltVA();
+ uint64_t plt = this->getVA() + off;
+ target->writePlt(buf + off, got, plt, b->pltIndex, relOff);
+ off += target->pltEntrySize;
}
}
-template <class ELFT> void PltSection::addEntry(Symbol &Sym) {
- Sym.PltIndex = Entries.size();
- Entries.push_back(&Sym);
+template <class ELFT> void PltSection::addEntry(Symbol &sym) {
+ sym.pltIndex = entries.size();
+ entries.push_back(&sym);
}
size_t PltSection::getSize() const {
- return HeaderSize + Entries.size() * Target->PltEntrySize;
+ return headerSize + entries.size() * target->pltEntrySize;
}
// Some architectures such as additional symbols in the PLT section. For
// example ARM uses mapping symbols to aid disassembly
void PltSection::addSymbols() {
// The PLT may have symbols defined for the Header, the IPLT has no header
- if (!IsIplt)
- Target->addPltHeaderSymbols(*this);
+ if (!isIplt)
+ target->addPltHeaderSymbols(*this);
- size_t Off = HeaderSize;
- for (size_t I = 0; I < Entries.size(); ++I) {
- Target->addPltSymbols(*this, Off);
- Off += Target->PltEntrySize;
+ size_t off = headerSize;
+ for (size_t i = 0; i < entries.size(); ++i) {
+ target->addPltSymbols(*this, off);
+ off += target->pltEntrySize;
}
}
// The string hash function for .gdb_index.
-static uint32_t computeGdbHash(StringRef S) {
- uint32_t H = 0;
- for (uint8_t C : S)
- H = H * 67 + toLower(C) - 113;
- return H;
+static uint32_t computeGdbHash(StringRef s) {
+ uint32_t h = 0;
+ for (uint8_t c : s)
+ h = h * 67 + toLower(c) - 113;
+ return h;
}
GdbIndexSection::GdbIndexSection()
@@ -2415,287 +2415,287 @@ GdbIndexSection::GdbIndexSection()
// Returns the desired size of an on-disk hash table for a .gdb_index section.
// There's a tradeoff between size and collision rate. We aim 75% utilization.
size_t GdbIndexSection::computeSymtabSize() const {
- return std::max<size_t>(NextPowerOf2(Symbols.size() * 4 / 3), 1024);
+ return std::max<size_t>(NextPowerOf2(symbols.size() * 4 / 3), 1024);
}
// Compute the output section size.
void GdbIndexSection::initOutputSize() {
- Size = sizeof(GdbIndexHeader) + computeSymtabSize() * 8;
+ size = sizeof(GdbIndexHeader) + computeSymtabSize() * 8;
- for (GdbChunk &Chunk : Chunks)
- Size += Chunk.CompilationUnits.size() * 16 + Chunk.AddressAreas.size() * 20;
+ for (GdbChunk &chunk : chunks)
+ size += chunk.compilationUnits.size() * 16 + chunk.addressAreas.size() * 20;
// Add the constant pool size if exists.
- if (!Symbols.empty()) {
- GdbSymbol &Sym = Symbols.back();
- Size += Sym.NameOff + Sym.Name.size() + 1;
+ if (!symbols.empty()) {
+ GdbSymbol &sym = symbols.back();
+ size += sym.nameOff + sym.name.size() + 1;
}
}
static std::vector<InputSection *> getDebugInfoSections() {
- std::vector<InputSection *> Ret;
- for (InputSectionBase *S : InputSections)
- if (InputSection *IS = dyn_cast<InputSection>(S))
- if (IS->Name == ".debug_info")
- Ret.push_back(IS);
- return Ret;
+ std::vector<InputSection *> ret;
+ for (InputSectionBase *s : inputSections)
+ if (InputSection *isec = dyn_cast<InputSection>(s))
+ if (isec->name == ".debug_info")
+ ret.push_back(isec);
+ return ret;
}
-static std::vector<GdbIndexSection::CuEntry> readCuList(DWARFContext &Dwarf) {
- std::vector<GdbIndexSection::CuEntry> Ret;
- for (std::unique_ptr<DWARFUnit> &Cu : Dwarf.compile_units())
- Ret.push_back({Cu->getOffset(), Cu->getLength() + 4});
- return Ret;
+static std::vector<GdbIndexSection::CuEntry> readCuList(DWARFContext &dwarf) {
+ std::vector<GdbIndexSection::CuEntry> ret;
+ for (std::unique_ptr<DWARFUnit> &cu : dwarf.compile_units())
+ ret.push_back({cu->getOffset(), cu->getLength() + 4});
+ return ret;
}
static std::vector<GdbIndexSection::AddressEntry>
-readAddressAreas(DWARFContext &Dwarf, InputSection *Sec) {
- std::vector<GdbIndexSection::AddressEntry> Ret;
+readAddressAreas(DWARFContext &dwarf, InputSection *sec) {
+ std::vector<GdbIndexSection::AddressEntry> ret;
- uint32_t CuIdx = 0;
- for (std::unique_ptr<DWARFUnit> &Cu : Dwarf.compile_units()) {
- Expected<DWARFAddressRangesVector> Ranges = Cu->collectAddressRanges();
- if (!Ranges) {
- error(toString(Sec) + ": " + toString(Ranges.takeError()));
+ uint32_t cuIdx = 0;
+ for (std::unique_ptr<DWARFUnit> &cu : dwarf.compile_units()) {
+ Expected<DWARFAddressRangesVector> ranges = cu->collectAddressRanges();
+ if (!ranges) {
+ error(toString(sec) + ": " + toString(ranges.takeError()));
return {};
}
- ArrayRef<InputSectionBase *> Sections = Sec->File->getSections();
- for (DWARFAddressRange &R : *Ranges) {
- if (R.SectionIndex == -1ULL)
+ ArrayRef<InputSectionBase *> sections = sec->file->getSections();
+ for (DWARFAddressRange &r : *ranges) {
+ if (r.SectionIndex == -1ULL)
continue;
- InputSectionBase *S = Sections[R.SectionIndex];
- if (!S || S == &InputSection::Discarded || !S->isLive())
+ InputSectionBase *s = sections[r.SectionIndex];
+ if (!s || s == &InputSection::discarded || !s->isLive())
continue;
// Range list with zero size has no effect.
- if (R.LowPC == R.HighPC)
+ if (r.LowPC == r.HighPC)
continue;
- auto *IS = cast<InputSection>(S);
- uint64_t Offset = IS->getOffsetInFile();
- Ret.push_back({IS, R.LowPC - Offset, R.HighPC - Offset, CuIdx});
+ auto *isec = cast<InputSection>(s);
+ uint64_t offset = isec->getOffsetInFile();
+ ret.push_back({isec, r.LowPC - offset, r.HighPC - offset, cuIdx});
}
- ++CuIdx;
+ ++cuIdx;
}
- return Ret;
+ return ret;
}
template <class ELFT>
static std::vector<GdbIndexSection::NameAttrEntry>
-readPubNamesAndTypes(const LLDDwarfObj<ELFT> &Obj,
- const std::vector<GdbIndexSection::CuEntry> &CUs) {
- const DWARFSection &PubNames = Obj.getGnuPubNamesSection();
- const DWARFSection &PubTypes = Obj.getGnuPubTypesSection();
-
- std::vector<GdbIndexSection::NameAttrEntry> Ret;
- for (const DWARFSection *Pub : {&PubNames, &PubTypes}) {
- DWARFDebugPubTable Table(Obj, *Pub, Config->IsLE, true);
- for (const DWARFDebugPubTable::Set &Set : Table.getData()) {
+readPubNamesAndTypes(const LLDDwarfObj<ELFT> &obj,
+ const std::vector<GdbIndexSection::CuEntry> &cUs) {
+ const DWARFSection &pubNames = obj.getGnuPubNamesSection();
+ const DWARFSection &pubTypes = obj.getGnuPubTypesSection();
+
+ std::vector<GdbIndexSection::NameAttrEntry> ret;
+ for (const DWARFSection *pub : {&pubNames, &pubTypes}) {
+ DWARFDebugPubTable table(obj, *pub, config->isLE, true);
+ for (const DWARFDebugPubTable::Set &set : table.getData()) {
// The value written into the constant pool is Kind << 24 | CuIndex. As we
// don't know how many compilation units precede this object to compute
// CuIndex, we compute (Kind << 24 | CuIndexInThisObject) instead, and add
// the number of preceding compilation units later.
- uint32_t I =
- lower_bound(CUs, Set.Offset,
- [](GdbIndexSection::CuEntry CU, uint32_t Offset) {
- return CU.CuOffset < Offset;
+ uint32_t i =
+ lower_bound(cUs, set.Offset,
+ [](GdbIndexSection::CuEntry cu, uint32_t offset) {
+ return cu.cuOffset < offset;
}) -
- CUs.begin();
- for (const DWARFDebugPubTable::Entry &Ent : Set.Entries)
- Ret.push_back({{Ent.Name, computeGdbHash(Ent.Name)},
- (Ent.Descriptor.toBits() << 24) | I});
+ cUs.begin();
+ for (const DWARFDebugPubTable::Entry &ent : set.Entries)
+ ret.push_back({{ent.Name, computeGdbHash(ent.Name)},
+ (ent.Descriptor.toBits() << 24) | i});
}
}
- return Ret;
+ return ret;
}
// Create a list of symbols from a given list of symbol names and types
// by uniquifying them by name.
static std::vector<GdbIndexSection::GdbSymbol>
-createSymbols(ArrayRef<std::vector<GdbIndexSection::NameAttrEntry>> NameAttrs,
- const std::vector<GdbIndexSection::GdbChunk> &Chunks) {
+createSymbols(ArrayRef<std::vector<GdbIndexSection::NameAttrEntry>> nameAttrs,
+ const std::vector<GdbIndexSection::GdbChunk> &chunks) {
using GdbSymbol = GdbIndexSection::GdbSymbol;
using NameAttrEntry = GdbIndexSection::NameAttrEntry;
// For each chunk, compute the number of compilation units preceding it.
- uint32_t CuIdx = 0;
- std::vector<uint32_t> CuIdxs(Chunks.size());
- for (uint32_t I = 0, E = Chunks.size(); I != E; ++I) {
- CuIdxs[I] = CuIdx;
- CuIdx += Chunks[I].CompilationUnits.size();
+ uint32_t cuIdx = 0;
+ std::vector<uint32_t> cuIdxs(chunks.size());
+ for (uint32_t i = 0, e = chunks.size(); i != e; ++i) {
+ cuIdxs[i] = cuIdx;
+ cuIdx += chunks[i].compilationUnits.size();
}
// The number of symbols we will handle in this function is of the order
// of millions for very large executables, so we use multi-threading to
// speed it up.
- size_t NumShards = 32;
- size_t Concurrency = 1;
+ size_t numShards = 32;
+ size_t concurrency = 1;
if (ThreadsEnabled)
- Concurrency =
- std::min<size_t>(PowerOf2Floor(hardware_concurrency()), NumShards);
+ concurrency =
+ std::min<size_t>(PowerOf2Floor(hardware_concurrency()), numShards);
// A sharded map to uniquify symbols by name.
- std::vector<DenseMap<CachedHashStringRef, size_t>> Map(NumShards);
- size_t Shift = 32 - countTrailingZeros(NumShards);
+ std::vector<DenseMap<CachedHashStringRef, size_t>> map(numShards);
+ size_t shift = 32 - countTrailingZeros(numShards);
// Instantiate GdbSymbols while uniqufying them by name.
- std::vector<std::vector<GdbSymbol>> Symbols(NumShards);
- parallelForEachN(0, Concurrency, [&](size_t ThreadId) {
- uint32_t I = 0;
- for (ArrayRef<NameAttrEntry> Entries : NameAttrs) {
- for (const NameAttrEntry &Ent : Entries) {
- size_t ShardId = Ent.Name.hash() >> Shift;
- if ((ShardId & (Concurrency - 1)) != ThreadId)
+ std::vector<std::vector<GdbSymbol>> symbols(numShards);
+ parallelForEachN(0, concurrency, [&](size_t threadId) {
+ uint32_t i = 0;
+ for (ArrayRef<NameAttrEntry> entries : nameAttrs) {
+ for (const NameAttrEntry &ent : entries) {
+ size_t shardId = ent.name.hash() >> shift;
+ if ((shardId & (concurrency - 1)) != threadId)
continue;
- uint32_t V = Ent.CuIndexAndAttrs + CuIdxs[I];
- size_t &Idx = Map[ShardId][Ent.Name];
- if (Idx) {
- Symbols[ShardId][Idx - 1].CuVector.push_back(V);
+ uint32_t v = ent.cuIndexAndAttrs + cuIdxs[i];
+ size_t &idx = map[shardId][ent.name];
+ if (idx) {
+ symbols[shardId][idx - 1].cuVector.push_back(v);
continue;
}
- Idx = Symbols[ShardId].size() + 1;
- Symbols[ShardId].push_back({Ent.Name, {V}, 0, 0});
+ idx = symbols[shardId].size() + 1;
+ symbols[shardId].push_back({ent.name, {v}, 0, 0});
}
- ++I;
+ ++i;
}
});
- size_t NumSymbols = 0;
- for (ArrayRef<GdbSymbol> V : Symbols)
- NumSymbols += V.size();
+ size_t numSymbols = 0;
+ for (ArrayRef<GdbSymbol> v : symbols)
+ numSymbols += v.size();
// The return type is a flattened vector, so we'll copy each vector
// contents to Ret.
- std::vector<GdbSymbol> Ret;
- Ret.reserve(NumSymbols);
- for (std::vector<GdbSymbol> &Vec : Symbols)
- for (GdbSymbol &Sym : Vec)
- Ret.push_back(std::move(Sym));
+ std::vector<GdbSymbol> ret;
+ ret.reserve(numSymbols);
+ for (std::vector<GdbSymbol> &vec : symbols)
+ for (GdbSymbol &sym : vec)
+ ret.push_back(std::move(sym));
// CU vectors and symbol names are adjacent in the output file.
// We can compute their offsets in the output file now.
- size_t Off = 0;
- for (GdbSymbol &Sym : Ret) {
- Sym.CuVectorOff = Off;
- Off += (Sym.CuVector.size() + 1) * 4;
+ size_t off = 0;
+ for (GdbSymbol &sym : ret) {
+ sym.cuVectorOff = off;
+ off += (sym.cuVector.size() + 1) * 4;
}
- for (GdbSymbol &Sym : Ret) {
- Sym.NameOff = Off;
- Off += Sym.Name.size() + 1;
+ for (GdbSymbol &sym : ret) {
+ sym.nameOff = off;
+ off += sym.name.size() + 1;
}
- return Ret;
+ return ret;
}
// Returns a newly-created .gdb_index section.
template <class ELFT> GdbIndexSection *GdbIndexSection::create() {
- std::vector<InputSection *> Sections = getDebugInfoSections();
+ std::vector<InputSection *> sections = getDebugInfoSections();
// .debug_gnu_pub{names,types} are useless in executables.
// They are present in input object files solely for creating
// a .gdb_index. So we can remove them from the output.
- for (InputSectionBase *S : InputSections)
- if (S->Name == ".debug_gnu_pubnames" || S->Name == ".debug_gnu_pubtypes")
- S->markDead();
-
- std::vector<GdbChunk> Chunks(Sections.size());
- std::vector<std::vector<NameAttrEntry>> NameAttrs(Sections.size());
-
- parallelForEachN(0, Sections.size(), [&](size_t I) {
- ObjFile<ELFT> *File = Sections[I]->getFile<ELFT>();
- DWARFContext Dwarf(make_unique<LLDDwarfObj<ELFT>>(File));
-
- Chunks[I].Sec = Sections[I];
- Chunks[I].CompilationUnits = readCuList(Dwarf);
- Chunks[I].AddressAreas = readAddressAreas(Dwarf, Sections[I]);
- NameAttrs[I] = readPubNamesAndTypes<ELFT>(
- static_cast<const LLDDwarfObj<ELFT> &>(Dwarf.getDWARFObj()),
- Chunks[I].CompilationUnits);
+ for (InputSectionBase *s : inputSections)
+ if (s->name == ".debug_gnu_pubnames" || s->name == ".debug_gnu_pubtypes")
+ s->markDead();
+
+ std::vector<GdbChunk> chunks(sections.size());
+ std::vector<std::vector<NameAttrEntry>> nameAttrs(sections.size());
+
+ parallelForEachN(0, sections.size(), [&](size_t i) {
+ ObjFile<ELFT> *file = sections[i]->getFile<ELFT>();
+ DWARFContext dwarf(make_unique<LLDDwarfObj<ELFT>>(file));
+
+ chunks[i].sec = sections[i];
+ chunks[i].compilationUnits = readCuList(dwarf);
+ chunks[i].addressAreas = readAddressAreas(dwarf, sections[i]);
+ nameAttrs[i] = readPubNamesAndTypes<ELFT>(
+ static_cast<const LLDDwarfObj<ELFT> &>(dwarf.getDWARFObj()),
+ chunks[i].compilationUnits);
});
- auto *Ret = make<GdbIndexSection>();
- Ret->Chunks = std::move(Chunks);
- Ret->Symbols = createSymbols(NameAttrs, Ret->Chunks);
- Ret->initOutputSize();
- return Ret;
+ auto *ret = make<GdbIndexSection>();
+ ret->chunks = std::move(chunks);
+ ret->symbols = createSymbols(nameAttrs, ret->chunks);
+ ret->initOutputSize();
+ return ret;
}
-void GdbIndexSection::writeTo(uint8_t *Buf) {
+void GdbIndexSection::writeTo(uint8_t *buf) {
// Write the header.
- auto *Hdr = reinterpret_cast<GdbIndexHeader *>(Buf);
- uint8_t *Start = Buf;
- Hdr->Version = 7;
- Buf += sizeof(*Hdr);
+ auto *hdr = reinterpret_cast<GdbIndexHeader *>(buf);
+ uint8_t *start = buf;
+ hdr->version = 7;
+ buf += sizeof(*hdr);
// Write the CU list.
- Hdr->CuListOff = Buf - Start;
- for (GdbChunk &Chunk : Chunks) {
- for (CuEntry &Cu : Chunk.CompilationUnits) {
- write64le(Buf, Chunk.Sec->OutSecOff + Cu.CuOffset);
- write64le(Buf + 8, Cu.CuLength);
- Buf += 16;
+ hdr->cuListOff = buf - start;
+ for (GdbChunk &chunk : chunks) {
+ for (CuEntry &cu : chunk.compilationUnits) {
+ write64le(buf, chunk.sec->outSecOff + cu.cuOffset);
+ write64le(buf + 8, cu.cuLength);
+ buf += 16;
}
}
// Write the address area.
- Hdr->CuTypesOff = Buf - Start;
- Hdr->AddressAreaOff = Buf - Start;
- uint32_t CuOff = 0;
- for (GdbChunk &Chunk : Chunks) {
- for (AddressEntry &E : Chunk.AddressAreas) {
- uint64_t BaseAddr = E.Section->getVA(0);
- write64le(Buf, BaseAddr + E.LowAddress);
- write64le(Buf + 8, BaseAddr + E.HighAddress);
- write32le(Buf + 16, E.CuIndex + CuOff);
- Buf += 20;
+ hdr->cuTypesOff = buf - start;
+ hdr->addressAreaOff = buf - start;
+ uint32_t cuOff = 0;
+ for (GdbChunk &chunk : chunks) {
+ for (AddressEntry &e : chunk.addressAreas) {
+ uint64_t baseAddr = e.section->getVA(0);
+ write64le(buf, baseAddr + e.lowAddress);
+ write64le(buf + 8, baseAddr + e.highAddress);
+ write32le(buf + 16, e.cuIndex + cuOff);
+ buf += 20;
}
- CuOff += Chunk.CompilationUnits.size();
+ cuOff += chunk.compilationUnits.size();
}
// Write the on-disk open-addressing hash table containing symbols.
- Hdr->SymtabOff = Buf - Start;
- size_t SymtabSize = computeSymtabSize();
- uint32_t Mask = SymtabSize - 1;
+ hdr->symtabOff = buf - start;
+ size_t symtabSize = computeSymtabSize();
+ uint32_t mask = symtabSize - 1;
- for (GdbSymbol &Sym : Symbols) {
- uint32_t H = Sym.Name.hash();
- uint32_t I = H & Mask;
- uint32_t Step = ((H * 17) & Mask) | 1;
+ for (GdbSymbol &sym : symbols) {
+ uint32_t h = sym.name.hash();
+ uint32_t i = h & mask;
+ uint32_t step = ((h * 17) & mask) | 1;
- while (read32le(Buf + I * 8))
- I = (I + Step) & Mask;
+ while (read32le(buf + i * 8))
+ i = (i + step) & mask;
- write32le(Buf + I * 8, Sym.NameOff);
- write32le(Buf + I * 8 + 4, Sym.CuVectorOff);
+ write32le(buf + i * 8, sym.nameOff);
+ write32le(buf + i * 8 + 4, sym.cuVectorOff);
}
- Buf += SymtabSize * 8;
+ buf += symtabSize * 8;
// Write the string pool.
- Hdr->ConstantPoolOff = Buf - Start;
- parallelForEach(Symbols, [&](GdbSymbol &Sym) {
- memcpy(Buf + Sym.NameOff, Sym.Name.data(), Sym.Name.size());
+ hdr->constantPoolOff = buf - start;
+ parallelForEach(symbols, [&](GdbSymbol &sym) {
+ memcpy(buf + sym.nameOff, sym.name.data(), sym.name.size());
});
// Write the CU vectors.
- for (GdbSymbol &Sym : Symbols) {
- write32le(Buf, Sym.CuVector.size());
- Buf += 4;
- for (uint32_t Val : Sym.CuVector) {
- write32le(Buf, Val);
- Buf += 4;
+ for (GdbSymbol &sym : symbols) {
+ write32le(buf, sym.cuVector.size());
+ buf += 4;
+ for (uint32_t val : sym.cuVector) {
+ write32le(buf, val);
+ buf += 4;
}
}
}
-bool GdbIndexSection::isNeeded() const { return !Chunks.empty(); }
+bool GdbIndexSection::isNeeded() const { return !chunks.empty(); }
EhFrameHeader::EhFrameHeader()
: SyntheticSection(SHF_ALLOC, SHT_PROGBITS, 4, ".eh_frame_hdr") {}
-void EhFrameHeader::writeTo(uint8_t *Buf) {
+void EhFrameHeader::writeTo(uint8_t *buf) {
// Unlike most sections, the EhFrameHeader section is written while writing
// another section, namely EhFrameSection, which calls the write() function
// below from its writeTo() function. This is necessary because the contents
@@ -2708,34 +2708,34 @@ void EhFrameHeader::writeTo(uint8_t *Buf
// the starting PC from where FDEs covers, and the FDE's address.
// It is sorted by PC.
void EhFrameHeader::write() {
- uint8_t *Buf = Out::BufferStart + getParent()->Offset + OutSecOff;
+ uint8_t *buf = Out::bufferStart + getParent()->offset + outSecOff;
using FdeData = EhFrameSection::FdeData;
- std::vector<FdeData> Fdes = getPartition().EhFrame->getFdeData();
+ std::vector<FdeData> fdes = getPartition().ehFrame->getFdeData();
- Buf[0] = 1;
- Buf[1] = DW_EH_PE_pcrel | DW_EH_PE_sdata4;
- Buf[2] = DW_EH_PE_udata4;
- Buf[3] = DW_EH_PE_datarel | DW_EH_PE_sdata4;
- write32(Buf + 4,
- getPartition().EhFrame->getParent()->Addr - this->getVA() - 4);
- write32(Buf + 8, Fdes.size());
- Buf += 12;
-
- for (FdeData &Fde : Fdes) {
- write32(Buf, Fde.PcRel);
- write32(Buf + 4, Fde.FdeVARel);
- Buf += 8;
+ buf[0] = 1;
+ buf[1] = DW_EH_PE_pcrel | DW_EH_PE_sdata4;
+ buf[2] = DW_EH_PE_udata4;
+ buf[3] = DW_EH_PE_datarel | DW_EH_PE_sdata4;
+ write32(buf + 4,
+ getPartition().ehFrame->getParent()->addr - this->getVA() - 4);
+ write32(buf + 8, fdes.size());
+ buf += 12;
+
+ for (FdeData &fde : fdes) {
+ write32(buf, fde.pcRel);
+ write32(buf + 4, fde.fdeVARel);
+ buf += 8;
}
}
size_t EhFrameHeader::getSize() const {
// .eh_frame_hdr has a 12 bytes header followed by an array of FDEs.
- return 12 + getPartition().EhFrame->NumFdes * 8;
+ return 12 + getPartition().ehFrame->numFdes * 8;
}
bool EhFrameHeader::isNeeded() const {
- return isLive() && getPartition().EhFrame->isNeeded();
+ return isLive() && getPartition().ehFrame->isNeeded();
}
VersionDefinitionSection::VersionDefinitionSection()
@@ -2743,56 +2743,56 @@ VersionDefinitionSection::VersionDefinit
".gnu.version_d") {}
StringRef VersionDefinitionSection::getFileDefName() {
- if (!getPartition().Name.empty())
- return getPartition().Name;
- if (!Config->SoName.empty())
- return Config->SoName;
- return Config->OutputFile;
+ if (!getPartition().name.empty())
+ return getPartition().name;
+ if (!config->soName.empty())
+ return config->soName;
+ return config->outputFile;
}
void VersionDefinitionSection::finalizeContents() {
- FileDefNameOff = getPartition().DynStrTab->addString(getFileDefName());
- for (VersionDefinition &V : Config->VersionDefinitions)
- VerDefNameOffs.push_back(getPartition().DynStrTab->addString(V.Name));
+ fileDefNameOff = getPartition().dynStrTab->addString(getFileDefName());
+ for (VersionDefinition &v : config->versionDefinitions)
+ verDefNameOffs.push_back(getPartition().dynStrTab->addString(v.name));
- if (OutputSection *Sec = getPartition().DynStrTab->getParent())
- getParent()->Link = Sec->SectionIndex;
+ if (OutputSection *sec = getPartition().dynStrTab->getParent())
+ getParent()->link = sec->sectionIndex;
// sh_info should be set to the number of definitions. This fact is missed in
// documentation, but confirmed by binutils community:
// https://sourceware.org/ml/binutils/2014-11/msg00355.html
- getParent()->Info = getVerDefNum();
+ getParent()->info = getVerDefNum();
}
-void VersionDefinitionSection::writeOne(uint8_t *Buf, uint32_t Index,
- StringRef Name, size_t NameOff) {
- uint16_t Flags = Index == 1 ? VER_FLG_BASE : 0;
+void VersionDefinitionSection::writeOne(uint8_t *buf, uint32_t index,
+ StringRef name, size_t nameOff) {
+ uint16_t flags = index == 1 ? VER_FLG_BASE : 0;
// Write a verdef.
- write16(Buf, 1); // vd_version
- write16(Buf + 2, Flags); // vd_flags
- write16(Buf + 4, Index); // vd_ndx
- write16(Buf + 6, 1); // vd_cnt
- write32(Buf + 8, hashSysV(Name)); // vd_hash
- write32(Buf + 12, 20); // vd_aux
- write32(Buf + 16, 28); // vd_next
+ write16(buf, 1); // vd_version
+ write16(buf + 2, flags); // vd_flags
+ write16(buf + 4, index); // vd_ndx
+ write16(buf + 6, 1); // vd_cnt
+ write32(buf + 8, hashSysV(name)); // vd_hash
+ write32(buf + 12, 20); // vd_aux
+ write32(buf + 16, 28); // vd_next
// Write a veraux.
- write32(Buf + 20, NameOff); // vda_name
- write32(Buf + 24, 0); // vda_next
+ write32(buf + 20, nameOff); // vda_name
+ write32(buf + 24, 0); // vda_next
}
-void VersionDefinitionSection::writeTo(uint8_t *Buf) {
- writeOne(Buf, 1, getFileDefName(), FileDefNameOff);
+void VersionDefinitionSection::writeTo(uint8_t *buf) {
+ writeOne(buf, 1, getFileDefName(), fileDefNameOff);
- auto NameOffIt = VerDefNameOffs.begin();
- for (VersionDefinition &V : Config->VersionDefinitions) {
- Buf += EntrySize;
- writeOne(Buf, V.Id, V.Name, *NameOffIt++);
+ auto nameOffIt = verDefNameOffs.begin();
+ for (VersionDefinition &v : config->versionDefinitions) {
+ buf += EntrySize;
+ writeOne(buf, v.id, v.name, *nameOffIt++);
}
// Need to terminate the last version definition.
- write32(Buf + 16, 0); // vd_next
+ write32(buf + 16, 0); // vd_next
}
size_t VersionDefinitionSection::getSize() const {
@@ -2803,49 +2803,49 @@ size_t VersionDefinitionSection::getSize
VersionTableSection::VersionTableSection()
: SyntheticSection(SHF_ALLOC, SHT_GNU_versym, sizeof(uint16_t),
".gnu.version") {
- this->Entsize = 2;
+ this->entsize = 2;
}
void VersionTableSection::finalizeContents() {
// At the moment of june 2016 GNU docs does not mention that sh_link field
// should be set, but Sun docs do. Also readelf relies on this field.
- getParent()->Link = getPartition().DynSymTab->getParent()->SectionIndex;
+ getParent()->link = getPartition().dynSymTab->getParent()->sectionIndex;
}
size_t VersionTableSection::getSize() const {
- return (getPartition().DynSymTab->getSymbols().size() + 1) * 2;
+ return (getPartition().dynSymTab->getSymbols().size() + 1) * 2;
}
-void VersionTableSection::writeTo(uint8_t *Buf) {
- Buf += 2;
- for (const SymbolTableEntry &S : getPartition().DynSymTab->getSymbols()) {
- write16(Buf, S.Sym->VersionId);
- Buf += 2;
+void VersionTableSection::writeTo(uint8_t *buf) {
+ buf += 2;
+ for (const SymbolTableEntry &s : getPartition().dynSymTab->getSymbols()) {
+ write16(buf, s.sym->versionId);
+ buf += 2;
}
}
bool VersionTableSection::isNeeded() const {
- return getPartition().VerDef || getPartition().VerNeed->isNeeded();
+ return getPartition().verDef || getPartition().verNeed->isNeeded();
}
-void elf::addVerneed(Symbol *SS) {
- auto &File = cast<SharedFile>(*SS->File);
- if (SS->VerdefIndex == VER_NDX_GLOBAL) {
- SS->VersionId = VER_NDX_GLOBAL;
+void elf::addVerneed(Symbol *ss) {
+ auto &file = cast<SharedFile>(*ss->file);
+ if (ss->verdefIndex == VER_NDX_GLOBAL) {
+ ss->versionId = VER_NDX_GLOBAL;
return;
}
- if (File.Vernauxs.empty())
- File.Vernauxs.resize(File.Verdefs.size());
+ if (file.vernauxs.empty())
+ file.vernauxs.resize(file.verdefs.size());
// Select a version identifier for the vernaux data structure, if we haven't
// already allocated one. The verdef identifiers cover the range
// [1..getVerDefNum()]; this causes the vernaux identifiers to start from
// getVerDefNum()+1.
- if (File.Vernauxs[SS->VerdefIndex] == 0)
- File.Vernauxs[SS->VerdefIndex] = ++SharedFile::VernauxNum + getVerDefNum();
+ if (file.vernauxs[ss->verdefIndex] == 0)
+ file.vernauxs[ss->verdefIndex] = ++SharedFile::vernauxNum + getVerDefNum();
- SS->VersionId = File.Vernauxs[SS->VerdefIndex];
+ ss->versionId = file.vernauxs[ss->verdefIndex];
}
template <class ELFT>
@@ -2854,107 +2854,107 @@ VersionNeedSection<ELFT>::VersionNeedSec
".gnu.version_r") {}
template <class ELFT> void VersionNeedSection<ELFT>::finalizeContents() {
- for (SharedFile *F : SharedFiles) {
- if (F->Vernauxs.empty())
+ for (SharedFile *f : sharedFiles) {
+ if (f->vernauxs.empty())
continue;
- Verneeds.emplace_back();
- Verneed &VN = Verneeds.back();
- VN.NameStrTab = getPartition().DynStrTab->addString(F->SoName);
- for (unsigned I = 0; I != F->Vernauxs.size(); ++I) {
- if (F->Vernauxs[I] == 0)
+ verneeds.emplace_back();
+ Verneed &vn = verneeds.back();
+ vn.nameStrTab = getPartition().dynStrTab->addString(f->soName);
+ for (unsigned i = 0; i != f->vernauxs.size(); ++i) {
+ if (f->vernauxs[i] == 0)
continue;
- auto *Verdef =
- reinterpret_cast<const typename ELFT::Verdef *>(F->Verdefs[I]);
- VN.Vernauxs.push_back(
- {Verdef->vd_hash, F->Vernauxs[I],
- getPartition().DynStrTab->addString(F->getStringTable().data() +
- Verdef->getAux()->vda_name)});
+ auto *verdef =
+ reinterpret_cast<const typename ELFT::Verdef *>(f->verdefs[i]);
+ vn.vernauxs.push_back(
+ {verdef->vd_hash, f->vernauxs[i],
+ getPartition().dynStrTab->addString(f->getStringTable().data() +
+ verdef->getAux()->vda_name)});
}
}
- if (OutputSection *Sec = getPartition().DynStrTab->getParent())
- getParent()->Link = Sec->SectionIndex;
- getParent()->Info = Verneeds.size();
+ if (OutputSection *sec = getPartition().dynStrTab->getParent())
+ getParent()->link = sec->sectionIndex;
+ getParent()->info = verneeds.size();
}
-template <class ELFT> void VersionNeedSection<ELFT>::writeTo(uint8_t *Buf) {
+template <class ELFT> void VersionNeedSection<ELFT>::writeTo(uint8_t *buf) {
// The Elf_Verneeds need to appear first, followed by the Elf_Vernauxs.
- auto *Verneed = reinterpret_cast<Elf_Verneed *>(Buf);
- auto *Vernaux = reinterpret_cast<Elf_Vernaux *>(Verneed + Verneeds.size());
+ auto *verneed = reinterpret_cast<Elf_Verneed *>(buf);
+ auto *vernaux = reinterpret_cast<Elf_Vernaux *>(verneed + verneeds.size());
- for (auto &VN : Verneeds) {
+ for (auto &vn : verneeds) {
// Create an Elf_Verneed for this DSO.
- Verneed->vn_version = 1;
- Verneed->vn_cnt = VN.Vernauxs.size();
- Verneed->vn_file = VN.NameStrTab;
- Verneed->vn_aux =
- reinterpret_cast<char *>(Vernaux) - reinterpret_cast<char *>(Verneed);
- Verneed->vn_next = sizeof(Elf_Verneed);
- ++Verneed;
+ verneed->vn_version = 1;
+ verneed->vn_cnt = vn.vernauxs.size();
+ verneed->vn_file = vn.nameStrTab;
+ verneed->vn_aux =
+ reinterpret_cast<char *>(vernaux) - reinterpret_cast<char *>(verneed);
+ verneed->vn_next = sizeof(Elf_Verneed);
+ ++verneed;
// Create the Elf_Vernauxs for this Elf_Verneed.
- for (auto &VNA : VN.Vernauxs) {
- Vernaux->vna_hash = VNA.Hash;
- Vernaux->vna_flags = 0;
- Vernaux->vna_other = VNA.VerneedIndex;
- Vernaux->vna_name = VNA.NameStrTab;
- Vernaux->vna_next = sizeof(Elf_Vernaux);
- ++Vernaux;
+ for (auto &vna : vn.vernauxs) {
+ vernaux->vna_hash = vna.hash;
+ vernaux->vna_flags = 0;
+ vernaux->vna_other = vna.verneedIndex;
+ vernaux->vna_name = vna.nameStrTab;
+ vernaux->vna_next = sizeof(Elf_Vernaux);
+ ++vernaux;
}
- Vernaux[-1].vna_next = 0;
+ vernaux[-1].vna_next = 0;
}
- Verneed[-1].vn_next = 0;
+ verneed[-1].vn_next = 0;
}
template <class ELFT> size_t VersionNeedSection<ELFT>::getSize() const {
- return Verneeds.size() * sizeof(Elf_Verneed) +
- SharedFile::VernauxNum * sizeof(Elf_Vernaux);
+ return verneeds.size() * sizeof(Elf_Verneed) +
+ SharedFile::vernauxNum * sizeof(Elf_Vernaux);
}
template <class ELFT> bool VersionNeedSection<ELFT>::isNeeded() const {
- return SharedFile::VernauxNum != 0;
+ return SharedFile::vernauxNum != 0;
}
-void MergeSyntheticSection::addSection(MergeInputSection *MS) {
- MS->Parent = this;
- Sections.push_back(MS);
- assert(Alignment == MS->Alignment || !(MS->Flags & SHF_STRINGS));
- Alignment = std::max(Alignment, MS->Alignment);
+void MergeSyntheticSection::addSection(MergeInputSection *ms) {
+ ms->parent = this;
+ sections.push_back(ms);
+ assert(alignment == ms->alignment || !(ms->flags & SHF_STRINGS));
+ alignment = std::max(alignment, ms->alignment);
}
-MergeTailSection::MergeTailSection(StringRef Name, uint32_t Type,
- uint64_t Flags, uint32_t Alignment)
- : MergeSyntheticSection(Name, Type, Flags, Alignment),
- Builder(StringTableBuilder::RAW, Alignment) {}
+MergeTailSection::MergeTailSection(StringRef name, uint32_t type,
+ uint64_t flags, uint32_t alignment)
+ : MergeSyntheticSection(name, type, flags, alignment),
+ builder(StringTableBuilder::RAW, alignment) {}
-size_t MergeTailSection::getSize() const { return Builder.getSize(); }
+size_t MergeTailSection::getSize() const { return builder.getSize(); }
-void MergeTailSection::writeTo(uint8_t *Buf) { Builder.write(Buf); }
+void MergeTailSection::writeTo(uint8_t *buf) { builder.write(buf); }
void MergeTailSection::finalizeContents() {
// Add all string pieces to the string table builder to create section
// contents.
- for (MergeInputSection *Sec : Sections)
- for (size_t I = 0, E = Sec->Pieces.size(); I != E; ++I)
- if (Sec->Pieces[I].Live)
- Builder.add(Sec->getData(I));
+ for (MergeInputSection *sec : sections)
+ for (size_t i = 0, e = sec->pieces.size(); i != e; ++i)
+ if (sec->pieces[i].live)
+ builder.add(sec->getData(i));
// Fix the string table content. After this, the contents will never change.
- Builder.finalize();
+ builder.finalize();
// finalize() fixed tail-optimized strings, so we can now get
// offsets of strings. Get an offset for each string and save it
// to a corresponding StringPiece for easy access.
- for (MergeInputSection *Sec : Sections)
- for (size_t I = 0, E = Sec->Pieces.size(); I != E; ++I)
- if (Sec->Pieces[I].Live)
- Sec->Pieces[I].OutputOff = Builder.getOffset(Sec->getData(I));
+ for (MergeInputSection *sec : sections)
+ for (size_t i = 0, e = sec->pieces.size(); i != e; ++i)
+ if (sec->pieces[i].live)
+ sec->pieces[i].outputOff = builder.getOffset(sec->getData(i));
}
-void MergeNoTailSection::writeTo(uint8_t *Buf) {
- for (size_t I = 0; I < NumShards; ++I)
- Shards[I].write(Buf + ShardOffsets[I]);
+void MergeNoTailSection::writeTo(uint8_t *buf) {
+ for (size_t i = 0; i < numShards; ++i)
+ shards[i].write(buf + shardOffsets[i]);
}
// This function is very hot (i.e. it can take several seconds to finish)
@@ -2967,68 +2967,68 @@ void MergeNoTailSection::writeTo(uint8_t
// We do it in parallel.
void MergeNoTailSection::finalizeContents() {
// Initializes string table builders.
- for (size_t I = 0; I < NumShards; ++I)
- Shards.emplace_back(StringTableBuilder::RAW, Alignment);
+ for (size_t i = 0; i < numShards; ++i)
+ shards.emplace_back(StringTableBuilder::RAW, alignment);
// Concurrency level. Must be a power of 2 to avoid expensive modulo
// operations in the following tight loop.
- size_t Concurrency = 1;
+ size_t concurrency = 1;
if (ThreadsEnabled)
- Concurrency =
- std::min<size_t>(PowerOf2Floor(hardware_concurrency()), NumShards);
+ concurrency =
+ std::min<size_t>(PowerOf2Floor(hardware_concurrency()), numShards);
// Add section pieces to the builders.
- parallelForEachN(0, Concurrency, [&](size_t ThreadId) {
- for (MergeInputSection *Sec : Sections) {
- for (size_t I = 0, E = Sec->Pieces.size(); I != E; ++I) {
- if (!Sec->Pieces[I].Live)
+ parallelForEachN(0, concurrency, [&](size_t threadId) {
+ for (MergeInputSection *sec : sections) {
+ for (size_t i = 0, e = sec->pieces.size(); i != e; ++i) {
+ if (!sec->pieces[i].live)
continue;
- size_t ShardId = getShardId(Sec->Pieces[I].Hash);
- if ((ShardId & (Concurrency - 1)) == ThreadId)
- Sec->Pieces[I].OutputOff = Shards[ShardId].add(Sec->getData(I));
+ size_t shardId = getShardId(sec->pieces[i].hash);
+ if ((shardId & (concurrency - 1)) == threadId)
+ sec->pieces[i].outputOff = shards[shardId].add(sec->getData(i));
}
}
});
// Compute an in-section offset for each shard.
- size_t Off = 0;
- for (size_t I = 0; I < NumShards; ++I) {
- Shards[I].finalizeInOrder();
- if (Shards[I].getSize() > 0)
- Off = alignTo(Off, Alignment);
- ShardOffsets[I] = Off;
- Off += Shards[I].getSize();
+ size_t off = 0;
+ for (size_t i = 0; i < numShards; ++i) {
+ shards[i].finalizeInOrder();
+ if (shards[i].getSize() > 0)
+ off = alignTo(off, alignment);
+ shardOffsets[i] = off;
+ off += shards[i].getSize();
}
- Size = Off;
+ size = off;
// So far, section pieces have offsets from beginning of shards, but
// we want offsets from beginning of the whole section. Fix them.
- parallelForEach(Sections, [&](MergeInputSection *Sec) {
- for (size_t I = 0, E = Sec->Pieces.size(); I != E; ++I)
- if (Sec->Pieces[I].Live)
- Sec->Pieces[I].OutputOff +=
- ShardOffsets[getShardId(Sec->Pieces[I].Hash)];
+ parallelForEach(sections, [&](MergeInputSection *sec) {
+ for (size_t i = 0, e = sec->pieces.size(); i != e; ++i)
+ if (sec->pieces[i].live)
+ sec->pieces[i].outputOff +=
+ shardOffsets[getShardId(sec->pieces[i].hash)];
});
}
-static MergeSyntheticSection *createMergeSynthetic(StringRef Name,
- uint32_t Type,
- uint64_t Flags,
- uint32_t Alignment) {
- bool ShouldTailMerge = (Flags & SHF_STRINGS) && Config->Optimize >= 2;
- if (ShouldTailMerge)
- return make<MergeTailSection>(Name, Type, Flags, Alignment);
- return make<MergeNoTailSection>(Name, Type, Flags, Alignment);
+static MergeSyntheticSection *createMergeSynthetic(StringRef name,
+ uint32_t type,
+ uint64_t flags,
+ uint32_t alignment) {
+ bool shouldTailMerge = (flags & SHF_STRINGS) && config->optimize >= 2;
+ if (shouldTailMerge)
+ return make<MergeTailSection>(name, type, flags, alignment);
+ return make<MergeNoTailSection>(name, type, flags, alignment);
}
template <class ELFT> void elf::splitSections() {
// splitIntoPieces needs to be called on each MergeInputSection
// before calling finalizeContents().
- parallelForEach(InputSections, [](InputSectionBase *Sec) {
- if (auto *S = dyn_cast<MergeInputSection>(Sec))
- S->splitIntoPieces();
- else if (auto *Eh = dyn_cast<EhInputSection>(Sec))
- Eh->split<ELFT>();
+ parallelForEach(inputSections, [](InputSectionBase *sec) {
+ if (auto *s = dyn_cast<MergeInputSection>(sec))
+ s->splitIntoPieces();
+ else if (auto *eh = dyn_cast<EhInputSection>(sec))
+ eh->split<ELFT>();
});
}
@@ -3040,22 +3040,22 @@ template <class ELFT> void elf::splitSec
// that it replaces. It then finalizes each synthetic section in order
// to compute an output offset for each piece of each input section.
void elf::mergeSections() {
- std::vector<MergeSyntheticSection *> MergeSections;
- for (InputSectionBase *&S : InputSections) {
- MergeInputSection *MS = dyn_cast<MergeInputSection>(S);
- if (!MS)
+ std::vector<MergeSyntheticSection *> mergeSections;
+ for (InputSectionBase *&s : inputSections) {
+ MergeInputSection *ms = dyn_cast<MergeInputSection>(s);
+ if (!ms)
continue;
// We do not want to handle sections that are not alive, so just remove
// them instead of trying to merge.
- if (!MS->isLive()) {
- S = nullptr;
+ if (!ms->isLive()) {
+ s = nullptr;
continue;
}
- StringRef OutsecName = getOutputSectionName(MS);
+ StringRef outsecName = getOutputSectionName(ms);
- auto I = llvm::find_if(MergeSections, [=](MergeSyntheticSection *Sec) {
+ auto i = llvm::find_if(mergeSections, [=](MergeSyntheticSection *sec) {
// While we could create a single synthetic section for two different
// values of Entsize, it is better to take Entsize into consideration.
//
@@ -3066,55 +3066,55 @@ void elf::mergeSections() {
// section.
//
// SHF_STRINGS section with different alignments should not be merged.
- return Sec->Name == OutsecName && Sec->Flags == MS->Flags &&
- Sec->Entsize == MS->Entsize &&
- (Sec->Alignment == MS->Alignment || !(Sec->Flags & SHF_STRINGS));
+ return sec->name == outsecName && sec->flags == ms->flags &&
+ sec->entsize == ms->entsize &&
+ (sec->alignment == ms->alignment || !(sec->flags & SHF_STRINGS));
});
- if (I == MergeSections.end()) {
- MergeSyntheticSection *Syn =
- createMergeSynthetic(OutsecName, MS->Type, MS->Flags, MS->Alignment);
- MergeSections.push_back(Syn);
- I = std::prev(MergeSections.end());
- S = Syn;
- Syn->Entsize = MS->Entsize;
+ if (i == mergeSections.end()) {
+ MergeSyntheticSection *syn =
+ createMergeSynthetic(outsecName, ms->type, ms->flags, ms->alignment);
+ mergeSections.push_back(syn);
+ i = std::prev(mergeSections.end());
+ s = syn;
+ syn->entsize = ms->entsize;
} else {
- S = nullptr;
+ s = nullptr;
}
- (*I)->addSection(MS);
+ (*i)->addSection(ms);
}
- for (auto *MS : MergeSections)
- MS->finalizeContents();
+ for (auto *ms : mergeSections)
+ ms->finalizeContents();
- std::vector<InputSectionBase *> &V = InputSections;
- V.erase(std::remove(V.begin(), V.end(), nullptr), V.end());
+ std::vector<InputSectionBase *> &v = inputSections;
+ v.erase(std::remove(v.begin(), v.end(), nullptr), v.end());
}
MipsRldMapSection::MipsRldMapSection()
- : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, Config->Wordsize,
+ : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, config->wordsize,
".rld_map") {}
ARMExidxSyntheticSection::ARMExidxSyntheticSection()
: SyntheticSection(SHF_ALLOC | SHF_LINK_ORDER, SHT_ARM_EXIDX,
- Config->Wordsize, ".ARM.exidx") {}
+ config->wordsize, ".ARM.exidx") {}
-static InputSection *findExidxSection(InputSection *IS) {
- for (InputSection *D : IS->DependentSections)
- if (D->Type == SHT_ARM_EXIDX)
- return D;
+static InputSection *findExidxSection(InputSection *isec) {
+ for (InputSection *d : isec->dependentSections)
+ if (d->type == SHT_ARM_EXIDX)
+ return d;
return nullptr;
}
-bool ARMExidxSyntheticSection::addSection(InputSection *IS) {
- if (IS->Type == SHT_ARM_EXIDX) {
- ExidxSections.push_back(IS);
+bool ARMExidxSyntheticSection::addSection(InputSection *isec) {
+ if (isec->type == SHT_ARM_EXIDX) {
+ exidxSections.push_back(isec);
return true;
}
- if ((IS->Flags & SHF_ALLOC) && (IS->Flags & SHF_EXECINSTR) &&
- IS->getSize() > 0) {
- ExecutableSections.push_back(IS);
- if (Empty && findExidxSection(IS))
- Empty = false;
+ if ((isec->flags & SHF_ALLOC) && (isec->flags & SHF_EXECINSTR) &&
+ isec->getSize() > 0) {
+ executableSections.push_back(isec);
+ if (empty && findExidxSection(isec))
+ empty = false;
return false;
}
@@ -3123,9 +3123,9 @@ bool ARMExidxSyntheticSection::addSectio
// and we would have to erase at a late stage relocations from merged entries.
// Given that exception tables are already position independent and a binary
// analyzer could derive the relocations we choose to erase the relocations.
- if (Config->EmitRelocs && IS->Type == SHT_REL)
- if (InputSectionBase *EX = IS->getRelocatedSection())
- if (isa<InputSection>(EX) && EX->Type == SHT_ARM_EXIDX)
+ if (config->emitRelocs && isec->type == SHT_REL)
+ if (InputSectionBase *ex = isec->getRelocatedSection())
+ if (isa<InputSection>(ex) && ex->type == SHT_ARM_EXIDX)
return true;
return false;
@@ -3133,8 +3133,8 @@ bool ARMExidxSyntheticSection::addSectio
// References to .ARM.Extab Sections have bit 31 clear and are not the
// special EXIDX_CANTUNWIND bit-pattern.
-static bool isExtabRef(uint32_t Unwind) {
- return (Unwind & 0x80000000) == 0 && Unwind != 0x1;
+static bool isExtabRef(uint32_t unwind) {
+ return (unwind & 0x80000000) == 0 && unwind != 0x1;
}
// Return true if the .ARM.exidx section Cur can be merged into the .ARM.exidx
@@ -3142,18 +3142,18 @@ static bool isExtabRef(uint32_t Unwind)
// unwinding instructions in Cur are identical to Prev. Linker generated
// EXIDX_CANTUNWIND entries are represented by nullptr as they do not have an
// InputSection.
-static bool isDuplicateArmExidxSec(InputSection *Prev, InputSection *Cur) {
+static bool isDuplicateArmExidxSec(InputSection *prev, InputSection *cur) {
struct ExidxEntry {
- ulittle32_t Fn;
- ulittle32_t Unwind;
+ ulittle32_t fn;
+ ulittle32_t unwind;
};
// Get the last table Entry from the previous .ARM.exidx section. If Prev is
// nullptr then it will be a synthesized EXIDX_CANTUNWIND entry.
- ExidxEntry PrevEntry = {ulittle32_t(0), ulittle32_t(1)};
- if (Prev)
- PrevEntry = Prev->getDataAs<ExidxEntry>().back();
- if (isExtabRef(PrevEntry.Unwind))
+ ExidxEntry prevEntry = {ulittle32_t(0), ulittle32_t(1)};
+ if (prev)
+ prevEntry = prev->getDataAs<ExidxEntry>().back();
+ if (isExtabRef(prevEntry.unwind))
return false;
// We consider the unwind instructions of an .ARM.exidx table entry
@@ -3165,11 +3165,11 @@ static bool isDuplicateArmExidxSec(Input
// are identical is high.
// If Cur is nullptr then this is synthesized EXIDX_CANTUNWIND entry.
- if (Cur == nullptr)
- return PrevEntry.Unwind == 1;
+ if (cur == nullptr)
+ return prevEntry.unwind == 1;
- for (const ExidxEntry Entry : Cur->getDataAs<ExidxEntry>())
- if (isExtabRef(Entry.Unwind) || Entry.Unwind != PrevEntry.Unwind)
+ for (const ExidxEntry entry : cur->getDataAs<ExidxEntry>())
+ if (isExtabRef(entry.unwind) || entry.unwind != prevEntry.unwind)
return false;
// All table entries in this .ARM.exidx Section can be merged into the
@@ -3187,51 +3187,51 @@ void ARMExidxSyntheticSection::finalizeC
// Sort the executable sections that may or may not have associated
// .ARM.exidx sections by order of ascending address. This requires the
// relative positions of InputSections to be known.
- auto CompareByFilePosition = [](const InputSection *A,
- const InputSection *B) {
- OutputSection *AOut = A->getParent();
- OutputSection *BOut = B->getParent();
-
- if (AOut != BOut)
- return AOut->SectionIndex < BOut->SectionIndex;
- return A->OutSecOff < B->OutSecOff;
+ auto compareByFilePosition = [](const InputSection *a,
+ const InputSection *b) {
+ OutputSection *aOut = a->getParent();
+ OutputSection *bOut = b->getParent();
+
+ if (aOut != bOut)
+ return aOut->sectionIndex < bOut->sectionIndex;
+ return a->outSecOff < b->outSecOff;
};
- llvm::stable_sort(ExecutableSections, CompareByFilePosition);
- Sentinel = ExecutableSections.back();
+ llvm::stable_sort(executableSections, compareByFilePosition);
+ sentinel = executableSections.back();
// Optionally merge adjacent duplicate entries.
- if (Config->MergeArmExidx) {
- std::vector<InputSection *> SelectedSections;
- SelectedSections.reserve(ExecutableSections.size());
- SelectedSections.push_back(ExecutableSections[0]);
- size_t Prev = 0;
- for (size_t I = 1; I < ExecutableSections.size(); ++I) {
- InputSection *EX1 = findExidxSection(ExecutableSections[Prev]);
- InputSection *EX2 = findExidxSection(ExecutableSections[I]);
- if (!isDuplicateArmExidxSec(EX1, EX2)) {
- SelectedSections.push_back(ExecutableSections[I]);
- Prev = I;
+ if (config->mergeArmExidx) {
+ std::vector<InputSection *> selectedSections;
+ selectedSections.reserve(executableSections.size());
+ selectedSections.push_back(executableSections[0]);
+ size_t prev = 0;
+ for (size_t i = 1; i < executableSections.size(); ++i) {
+ InputSection *ex1 = findExidxSection(executableSections[prev]);
+ InputSection *ex2 = findExidxSection(executableSections[i]);
+ if (!isDuplicateArmExidxSec(ex1, ex2)) {
+ selectedSections.push_back(executableSections[i]);
+ prev = i;
}
}
- ExecutableSections = std::move(SelectedSections);
+ executableSections = std::move(selectedSections);
}
- size_t Offset = 0;
- Size = 0;
- for (InputSection *IS : ExecutableSections) {
- if (InputSection *D = findExidxSection(IS)) {
- D->OutSecOff = Offset;
- D->Parent = getParent();
- Offset += D->getSize();
+ size_t offset = 0;
+ size = 0;
+ for (InputSection *isec : executableSections) {
+ if (InputSection *d = findExidxSection(isec)) {
+ d->outSecOff = offset;
+ d->parent = getParent();
+ offset += d->getSize();
} else {
- Offset += 8;
+ offset += 8;
}
}
// Size includes Sentinel.
- Size = Offset + 8;
+ size = offset + 8;
}
InputSection *ARMExidxSyntheticSection::getLinkOrderDep() const {
- return ExecutableSections.front();
+ return executableSections.front();
}
// To write the .ARM.exidx table from the ExecutableSections we have three cases
@@ -3243,75 +3243,75 @@ InputSection *ARMExidxSyntheticSection::
// section is to terminate the address range of the previous entry.
// 3.) A trailing EXIDX_CANTUNWIND sentinel section is required at the end of
// the table to terminate the address range of the final entry.
-void ARMExidxSyntheticSection::writeTo(uint8_t *Buf) {
+void ARMExidxSyntheticSection::writeTo(uint8_t *buf) {
- const uint8_t CantUnwindData[8] = {0, 0, 0, 0, // PREL31 to target
+ const uint8_t cantUnwindData[8] = {0, 0, 0, 0, // PREL31 to target
1, 0, 0, 0}; // EXIDX_CANTUNWIND
- uint64_t Offset = 0;
- for (InputSection *IS : ExecutableSections) {
- assert(IS->getParent() != nullptr);
- if (InputSection *D = findExidxSection(IS)) {
- memcpy(Buf + Offset, D->data().data(), D->data().size());
- D->relocateAlloc(Buf, Buf + D->getSize());
- Offset += D->getSize();
+ uint64_t offset = 0;
+ for (InputSection *isec : executableSections) {
+ assert(isec->getParent() != nullptr);
+ if (InputSection *d = findExidxSection(isec)) {
+ memcpy(buf + offset, d->data().data(), d->data().size());
+ d->relocateAlloc(buf, buf + d->getSize());
+ offset += d->getSize();
} else {
// A Linker generated CANTUNWIND section.
- memcpy(Buf + Offset, CantUnwindData, sizeof(CantUnwindData));
- uint64_t S = IS->getVA();
- uint64_t P = getVA() + Offset;
- Target->relocateOne(Buf + Offset, R_ARM_PREL31, S - P);
- Offset += 8;
+ memcpy(buf + offset, cantUnwindData, sizeof(cantUnwindData));
+ uint64_t s = isec->getVA();
+ uint64_t p = getVA() + offset;
+ target->relocateOne(buf + offset, R_ARM_PREL31, s - p);
+ offset += 8;
}
}
// Write Sentinel.
- memcpy(Buf + Offset, CantUnwindData, sizeof(CantUnwindData));
- uint64_t S = Sentinel->getVA(Sentinel->getSize());
- uint64_t P = getVA() + Offset;
- Target->relocateOne(Buf + Offset, R_ARM_PREL31, S - P);
- assert(Size == Offset + 8);
+ memcpy(buf + offset, cantUnwindData, sizeof(cantUnwindData));
+ uint64_t s = sentinel->getVA(sentinel->getSize());
+ uint64_t p = getVA() + offset;
+ target->relocateOne(buf + offset, R_ARM_PREL31, s - p);
+ assert(size == offset + 8);
}
-bool ARMExidxSyntheticSection::classof(const SectionBase *D) {
- return D->kind() == InputSectionBase::Synthetic && D->Type == SHT_ARM_EXIDX;
+bool ARMExidxSyntheticSection::classof(const SectionBase *d) {
+ return d->kind() == InputSectionBase::Synthetic && d->type == SHT_ARM_EXIDX;
}
-ThunkSection::ThunkSection(OutputSection *OS, uint64_t Off)
+ThunkSection::ThunkSection(OutputSection *os, uint64_t off)
: SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS,
- Config->Wordsize, ".text.thunk") {
- this->Parent = OS;
- this->OutSecOff = Off;
+ config->wordsize, ".text.thunk") {
+ this->parent = os;
+ this->outSecOff = off;
}
-void ThunkSection::addThunk(Thunk *T) {
- Thunks.push_back(T);
- T->addSymbols(*this);
+void ThunkSection::addThunk(Thunk *t) {
+ thunks.push_back(t);
+ t->addSymbols(*this);
}
-void ThunkSection::writeTo(uint8_t *Buf) {
- for (Thunk *T : Thunks)
- T->writeTo(Buf + T->Offset);
+void ThunkSection::writeTo(uint8_t *buf) {
+ for (Thunk *t : thunks)
+ t->writeTo(buf + t->offset);
}
InputSection *ThunkSection::getTargetInputSection() const {
- if (Thunks.empty())
+ if (thunks.empty())
return nullptr;
- const Thunk *T = Thunks.front();
- return T->getTargetInputSection();
+ const Thunk *t = thunks.front();
+ return t->getTargetInputSection();
}
bool ThunkSection::assignOffsets() {
- uint64_t Off = 0;
- for (Thunk *T : Thunks) {
- Off = alignTo(Off, T->Alignment);
- T->setOffset(Off);
- uint32_t Size = T->size();
- T->getThunkTargetSym()->Size = Size;
- Off += Size;
- }
- bool Changed = Off != Size;
- Size = Off;
- return Changed;
+ uint64_t off = 0;
+ for (Thunk *t : thunks) {
+ off = alignTo(off, t->alignment);
+ t->setOffset(off);
+ uint32_t size = t->size();
+ t->getThunkTargetSym()->size = size;
+ off += size;
+ }
+ bool changed = off != size;
+ size = off;
+ return changed;
}
PPC32Got2Section::PPC32Got2Section()
@@ -3320,10 +3320,10 @@ PPC32Got2Section::PPC32Got2Section()
bool PPC32Got2Section::isNeeded() const {
// See the comment below. This is not needed if there is no other
// InputSection.
- for (BaseCommand *Base : getParent()->SectionCommands)
- if (auto *ISD = dyn_cast<InputSectionDescription>(Base))
- for (InputSection *IS : ISD->Sections)
- if (IS != this)
+ for (BaseCommand *base : getParent()->sectionCommands)
+ if (auto *isd = dyn_cast<InputSectionDescription>(base))
+ for (InputSection *isec : isd->sections)
+ if (isec != this)
return true;
return false;
}
@@ -3333,14 +3333,14 @@ void PPC32Got2Section::finalizeContents(
// .got2 . This function computes OutSecOff of each .got2 to be used in
// PPC32PltCallStub::writeTo(). The purpose of this empty synthetic section is
// to collect input sections named ".got2".
- uint32_t Offset = 0;
- for (BaseCommand *Base : getParent()->SectionCommands)
- if (auto *ISD = dyn_cast<InputSectionDescription>(Base)) {
- for (InputSection *IS : ISD->Sections) {
- if (IS == this)
+ uint32_t offset = 0;
+ for (BaseCommand *base : getParent()->sectionCommands)
+ if (auto *isd = dyn_cast<InputSectionDescription>(base)) {
+ for (InputSection *isec : isd->sections) {
+ if (isec == this)
continue;
- IS->File->PPC32Got2OutSecOff = Offset;
- Offset += (uint32_t)IS->getSize();
+ isec->file->ppc32Got2OutSecOff = offset;
+ offset += (uint32_t)isec->getSize();
}
}
}
@@ -3351,33 +3351,33 @@ void PPC32Got2Section::finalizeContents(
// allocated and filled in by the dynamic linker.
PPC64LongBranchTargetSection::PPC64LongBranchTargetSection()
: SyntheticSection(SHF_ALLOC | SHF_WRITE,
- Config->Pic ? SHT_NOBITS : SHT_PROGBITS, 8,
+ config->isPic ? SHT_NOBITS : SHT_PROGBITS, 8,
".branch_lt") {}
-void PPC64LongBranchTargetSection::addEntry(Symbol &Sym) {
- assert(Sym.PPC64BranchltIndex == 0xffff);
- Sym.PPC64BranchltIndex = Entries.size();
- Entries.push_back(&Sym);
+void PPC64LongBranchTargetSection::addEntry(Symbol &sym) {
+ assert(sym.ppc64BranchltIndex == 0xffff);
+ sym.ppc64BranchltIndex = entries.size();
+ entries.push_back(&sym);
}
size_t PPC64LongBranchTargetSection::getSize() const {
- return Entries.size() * 8;
+ return entries.size() * 8;
}
-void PPC64LongBranchTargetSection::writeTo(uint8_t *Buf) {
+void PPC64LongBranchTargetSection::writeTo(uint8_t *buf) {
// If linking non-pic we have the final addresses of the targets and they get
// written to the table directly. For pic the dynamic linker will allocate
// the section and fill it it.
- if (Config->Pic)
+ if (config->isPic)
return;
- for (const Symbol *Sym : Entries) {
- assert(Sym->getVA());
+ for (const Symbol *sym : entries) {
+ assert(sym->getVA());
// Need calls to branch to the local entry-point since a long-branch
// must be a local-call.
- write64(Buf,
- Sym->getVA() + getPPC64GlobalEntryToLocalEntryOffset(Sym->StOther));
- Buf += 8;
+ write64(buf,
+ sym->getVA() + getPPC64GlobalEntryToLocalEntryOffset(sym->stOther));
+ buf += 8;
}
}
@@ -3388,85 +3388,85 @@ bool PPC64LongBranchTargetSection::isNee
// only gets set to true once `finalizeSections()` is called after thunk
// creation. Becuase of this, if we don't create any long-branch thunks we end
// up with an empty .branch_lt section in the binary.
- return !Finalized || !Entries.empty();
+ return !finalized || !entries.empty();
}
RISCVSdataSection::RISCVSdataSection()
: SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, 1, ".sdata") {}
bool RISCVSdataSection::isNeeded() const {
- if (!ElfSym::RISCVGlobalPointer)
+ if (!ElfSym::riscvGlobalPointer)
return false;
// __global_pointer$ is defined relative to .sdata . If the section does not
// exist, create a dummy one.
- for (BaseCommand *Base : getParent()->SectionCommands)
- if (auto *ISD = dyn_cast<InputSectionDescription>(Base))
- for (InputSection *IS : ISD->Sections)
- if (IS != this)
+ for (BaseCommand *base : getParent()->sectionCommands)
+ if (auto *isd = dyn_cast<InputSectionDescription>(base))
+ for (InputSection *isec : isd->sections)
+ if (isec != this)
return false;
return true;
}
static uint8_t getAbiVersion() {
// MIPS non-PIC executable gets ABI version 1.
- if (Config->EMachine == EM_MIPS) {
- if (!Config->Pic && !Config->Relocatable &&
- (Config->EFlags & (EF_MIPS_PIC | EF_MIPS_CPIC)) == EF_MIPS_CPIC)
+ if (config->emachine == EM_MIPS) {
+ if (!config->isPic && !config->relocatable &&
+ (config->eflags & (EF_MIPS_PIC | EF_MIPS_CPIC)) == EF_MIPS_CPIC)
return 1;
return 0;
}
- if (Config->EMachine == EM_AMDGPU) {
- uint8_t Ver = ObjectFiles[0]->ABIVersion;
- for (InputFile *File : makeArrayRef(ObjectFiles).slice(1))
- if (File->ABIVersion != Ver)
- error("incompatible ABI version: " + toString(File));
- return Ver;
+ if (config->emachine == EM_AMDGPU) {
+ uint8_t ver = objectFiles[0]->abiVersion;
+ for (InputFile *file : makeArrayRef(objectFiles).slice(1))
+ if (file->abiVersion != ver)
+ error("incompatible ABI version: " + toString(file));
+ return ver;
}
return 0;
}
-template <typename ELFT> void elf::writeEhdr(uint8_t *Buf, Partition &Part) {
+template <typename ELFT> void elf::writeEhdr(uint8_t *buf, Partition &part) {
// For executable segments, the trap instructions are written before writing
// the header. Setting Elf header bytes to zero ensures that any unused bytes
// in header are zero-cleared, instead of having trap instructions.
- memset(Buf, 0, sizeof(typename ELFT::Ehdr));
- memcpy(Buf, "\177ELF", 4);
+ memset(buf, 0, sizeof(typename ELFT::Ehdr));
+ memcpy(buf, "\177ELF", 4);
- auto *EHdr = reinterpret_cast<typename ELFT::Ehdr *>(Buf);
- EHdr->e_ident[EI_CLASS] = Config->Is64 ? ELFCLASS64 : ELFCLASS32;
- EHdr->e_ident[EI_DATA] = Config->IsLE ? ELFDATA2LSB : ELFDATA2MSB;
- EHdr->e_ident[EI_VERSION] = EV_CURRENT;
- EHdr->e_ident[EI_OSABI] = Config->OSABI;
- EHdr->e_ident[EI_ABIVERSION] = getAbiVersion();
- EHdr->e_machine = Config->EMachine;
- EHdr->e_version = EV_CURRENT;
- EHdr->e_flags = Config->EFlags;
- EHdr->e_ehsize = sizeof(typename ELFT::Ehdr);
- EHdr->e_phnum = Part.Phdrs.size();
- EHdr->e_shentsize = sizeof(typename ELFT::Shdr);
-
- if (!Config->Relocatable) {
- EHdr->e_phoff = sizeof(typename ELFT::Ehdr);
- EHdr->e_phentsize = sizeof(typename ELFT::Phdr);
+ auto *eHdr = reinterpret_cast<typename ELFT::Ehdr *>(buf);
+ eHdr->e_ident[EI_CLASS] = config->is64 ? ELFCLASS64 : ELFCLASS32;
+ eHdr->e_ident[EI_DATA] = config->isLE ? ELFDATA2LSB : ELFDATA2MSB;
+ eHdr->e_ident[EI_VERSION] = EV_CURRENT;
+ eHdr->e_ident[EI_OSABI] = config->osabi;
+ eHdr->e_ident[EI_ABIVERSION] = getAbiVersion();
+ eHdr->e_machine = config->emachine;
+ eHdr->e_version = EV_CURRENT;
+ eHdr->e_flags = config->eflags;
+ eHdr->e_ehsize = sizeof(typename ELFT::Ehdr);
+ eHdr->e_phnum = part.phdrs.size();
+ eHdr->e_shentsize = sizeof(typename ELFT::Shdr);
+
+ if (!config->relocatable) {
+ eHdr->e_phoff = sizeof(typename ELFT::Ehdr);
+ eHdr->e_phentsize = sizeof(typename ELFT::Phdr);
}
}
-template <typename ELFT> void elf::writePhdrs(uint8_t *Buf, Partition &Part) {
+template <typename ELFT> void elf::writePhdrs(uint8_t *buf, Partition &part) {
// Write the program header table.
- auto *HBuf = reinterpret_cast<typename ELFT::Phdr *>(Buf);
- for (PhdrEntry *P : Part.Phdrs) {
- HBuf->p_type = P->p_type;
- HBuf->p_flags = P->p_flags;
- HBuf->p_offset = P->p_offset;
- HBuf->p_vaddr = P->p_vaddr;
- HBuf->p_paddr = P->p_paddr;
- HBuf->p_filesz = P->p_filesz;
- HBuf->p_memsz = P->p_memsz;
- HBuf->p_align = P->p_align;
- ++HBuf;
+ auto *hBuf = reinterpret_cast<typename ELFT::Phdr *>(buf);
+ for (PhdrEntry *p : part.phdrs) {
+ hBuf->p_type = p->p_type;
+ hBuf->p_flags = p->p_flags;
+ hBuf->p_offset = p->p_offset;
+ hBuf->p_vaddr = p->p_vaddr;
+ hBuf->p_paddr = p->p_paddr;
+ hBuf->p_filesz = p->p_filesz;
+ hBuf->p_memsz = p->p_memsz;
+ hBuf->p_align = p->p_align;
+ ++hBuf;
}
}
@@ -3480,12 +3480,12 @@ size_t PartitionElfHeaderSection<ELFT>::
}
template <typename ELFT>
-void PartitionElfHeaderSection<ELFT>::writeTo(uint8_t *Buf) {
- writeEhdr<ELFT>(Buf, getPartition());
+void PartitionElfHeaderSection<ELFT>::writeTo(uint8_t *buf) {
+ writeEhdr<ELFT>(buf, getPartition());
// Loadable partitions are always ET_DYN.
- auto *EHdr = reinterpret_cast<typename ELFT::Ehdr *>(Buf);
- EHdr->e_type = ET_DYN;
+ auto *eHdr = reinterpret_cast<typename ELFT::Ehdr *>(buf);
+ eHdr->e_type = ET_DYN;
}
template <typename ELFT>
@@ -3494,45 +3494,45 @@ PartitionProgramHeadersSection<ELFT>::Pa
template <typename ELFT>
size_t PartitionProgramHeadersSection<ELFT>::getSize() const {
- return sizeof(typename ELFT::Phdr) * getPartition().Phdrs.size();
+ return sizeof(typename ELFT::Phdr) * getPartition().phdrs.size();
}
template <typename ELFT>
-void PartitionProgramHeadersSection<ELFT>::writeTo(uint8_t *Buf) {
- writePhdrs<ELFT>(Buf, getPartition());
+void PartitionProgramHeadersSection<ELFT>::writeTo(uint8_t *buf) {
+ writePhdrs<ELFT>(buf, getPartition());
}
PartitionIndexSection::PartitionIndexSection()
: SyntheticSection(SHF_ALLOC, SHT_PROGBITS, 4, ".rodata") {}
size_t PartitionIndexSection::getSize() const {
- return 12 * (Partitions.size() - 1);
+ return 12 * (partitions.size() - 1);
}
void PartitionIndexSection::finalizeContents() {
- for (size_t I = 1; I != Partitions.size(); ++I)
- Partitions[I].NameStrTab = Main->DynStrTab->addString(Partitions[I].Name);
+ for (size_t i = 1; i != partitions.size(); ++i)
+ partitions[i].nameStrTab = mainPart->dynStrTab->addString(partitions[i].name);
}
-void PartitionIndexSection::writeTo(uint8_t *Buf) {
- uint64_t VA = getVA();
- for (size_t I = 1; I != Partitions.size(); ++I) {
- write32(Buf, Main->DynStrTab->getVA() + Partitions[I].NameStrTab - VA);
- write32(Buf + 4, Partitions[I].ElfHeader->getVA() - (VA + 4));
+void PartitionIndexSection::writeTo(uint8_t *buf) {
+ uint64_t va = getVA();
+ for (size_t i = 1; i != partitions.size(); ++i) {
+ write32(buf, mainPart->dynStrTab->getVA() + partitions[i].nameStrTab - va);
+ write32(buf + 4, partitions[i].elfHeader->getVA() - (va + 4));
- SyntheticSection *Next =
- I == Partitions.size() - 1 ? In.PartEnd : Partitions[I + 1].ElfHeader;
- write32(Buf + 8, Next->getVA() - Partitions[I].ElfHeader->getVA());
+ SyntheticSection *next =
+ i == partitions.size() - 1 ? in.partEnd : partitions[i + 1].elfHeader;
+ write32(buf + 8, next->getVA() - partitions[i].elfHeader->getVA());
- VA += 12;
- Buf += 12;
+ va += 12;
+ buf += 12;
}
}
-InStruct elf::In;
+InStruct elf::in;
-std::vector<Partition> elf::Partitions;
-Partition *elf::Main;
+std::vector<Partition> elf::partitions;
+Partition *elf::mainPart;
template GdbIndexSection *GdbIndexSection::create<ELF32LE>();
template GdbIndexSection *GdbIndexSection::create<ELF32BE>();
Modified: lld/trunk/ELF/SyntheticSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.h?rev=365595&r1=365594&r2=365595&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.h (original)
+++ lld/trunk/ELF/SyntheticSections.h Tue Jul 9 22:00:37 2019
@@ -37,15 +37,15 @@ class VersionNeedBaseSection;
class SyntheticSection : public InputSection {
public:
- SyntheticSection(uint64_t Flags, uint32_t Type, uint32_t Alignment,
- StringRef Name)
- : InputSection(nullptr, Flags, Type, Alignment, {}, Name,
+ SyntheticSection(uint64_t flags, uint32_t type, uint32_t alignment,
+ StringRef name)
+ : InputSection(nullptr, flags, type, alignment, {}, name,
InputSectionBase::Synthetic) {
markLive();
}
virtual ~SyntheticSection() = default;
- virtual void writeTo(uint8_t *Buf) = 0;
+ virtual void writeTo(uint8_t *buf) = 0;
virtual size_t getSize() const = 0;
virtual void finalizeContents() {}
// If the section has the SHF_ALLOC flag and the size may be changed if
@@ -53,91 +53,91 @@ public:
virtual bool updateAllocSize() { return false; }
virtual bool isNeeded() const { return true; }
- static bool classof(const SectionBase *D) {
- return D->kind() == InputSectionBase::Synthetic;
+ static bool classof(const SectionBase *d) {
+ return d->kind() == InputSectionBase::Synthetic;
}
};
struct CieRecord {
- EhSectionPiece *Cie = nullptr;
- std::vector<EhSectionPiece *> Fdes;
+ EhSectionPiece *cie = nullptr;
+ std::vector<EhSectionPiece *> fdes;
};
// Section for .eh_frame.
class EhFrameSection final : public SyntheticSection {
public:
EhFrameSection();
- void writeTo(uint8_t *Buf) override;
+ void writeTo(uint8_t *buf) override;
void finalizeContents() override;
- bool isNeeded() const override { return !Sections.empty(); }
- size_t getSize() const override { return Size; }
+ bool isNeeded() const override { return !sections.empty(); }
+ size_t getSize() const override { return size; }
- static bool classof(const SectionBase *D) {
- return SyntheticSection::classof(D) && D->Name == ".eh_frame";
+ static bool classof(const SectionBase *d) {
+ return SyntheticSection::classof(d) && d->name == ".eh_frame";
}
- template <class ELFT> void addSection(InputSectionBase *S);
+ template <class ELFT> void addSection(InputSectionBase *s);
- std::vector<EhInputSection *> Sections;
- size_t NumFdes = 0;
+ std::vector<EhInputSection *> sections;
+ size_t numFdes = 0;
struct FdeData {
- uint32_t PcRel;
- uint32_t FdeVARel;
+ uint32_t pcRel;
+ uint32_t fdeVARel;
};
std::vector<FdeData> getFdeData() const;
- ArrayRef<CieRecord *> getCieRecords() const { return CieRecords; }
+ ArrayRef<CieRecord *> getCieRecords() const { return cieRecords; }
private:
// This is used only when parsing EhInputSection. We keep it here to avoid
// allocating one for each EhInputSection.
- llvm::DenseMap<size_t, CieRecord *> OffsetToCie;
+ llvm::DenseMap<size_t, CieRecord *> offsetToCie;
- uint64_t Size = 0;
+ uint64_t size = 0;
template <class ELFT, class RelTy>
- void addSectionAux(EhInputSection *S, llvm::ArrayRef<RelTy> Rels);
+ void addSectionAux(EhInputSection *s, llvm::ArrayRef<RelTy> rels);
template <class ELFT, class RelTy>
- CieRecord *addCie(EhSectionPiece &Piece, ArrayRef<RelTy> Rels);
+ CieRecord *addCie(EhSectionPiece &piece, ArrayRef<RelTy> rels);
template <class ELFT, class RelTy>
- bool isFdeLive(EhSectionPiece &Piece, ArrayRef<RelTy> Rels);
+ bool isFdeLive(EhSectionPiece &piece, ArrayRef<RelTy> rels);
- uint64_t getFdePc(uint8_t *Buf, size_t Off, uint8_t Enc) const;
+ uint64_t getFdePc(uint8_t *buf, size_t off, uint8_t enc) const;
- std::vector<CieRecord *> CieRecords;
+ std::vector<CieRecord *> cieRecords;
// CIE records are uniquified by their contents and personality functions.
- llvm::DenseMap<std::pair<ArrayRef<uint8_t>, Symbol *>, CieRecord *> CieMap;
+ llvm::DenseMap<std::pair<ArrayRef<uint8_t>, Symbol *>, CieRecord *> cieMap;
};
class GotSection : public SyntheticSection {
public:
GotSection();
- size_t getSize() const override { return Size; }
+ size_t getSize() const override { return size; }
void finalizeContents() override;
bool isNeeded() const override;
- void writeTo(uint8_t *Buf) override;
+ void writeTo(uint8_t *buf) override;
- void addEntry(Symbol &Sym);
- bool addDynTlsEntry(Symbol &Sym);
+ void addEntry(Symbol &sym);
+ bool addDynTlsEntry(Symbol &sym);
bool addTlsIndex();
- uint64_t getGlobalDynAddr(const Symbol &B) const;
- uint64_t getGlobalDynOffset(const Symbol &B) const;
+ uint64_t getGlobalDynAddr(const Symbol &b) const;
+ uint64_t getGlobalDynOffset(const Symbol &b) const;
- uint64_t getTlsIndexVA() { return this->getVA() + TlsIndexOff; }
- uint32_t getTlsIndexOff() const { return TlsIndexOff; }
+ uint64_t getTlsIndexVA() { return this->getVA() + tlsIndexOff; }
+ uint32_t getTlsIndexOff() const { return tlsIndexOff; }
// Flag to force GOT to be in output if we have relocations
// that relies on its address.
- bool HasGotOffRel = false;
+ bool hasGotOffRel = false;
protected:
- size_t NumEntries = 0;
- uint32_t TlsIndexOff = -1;
- uint64_t Size = 0;
+ size_t numEntries = 0;
+ uint32_t tlsIndexOff = -1;
+ uint64_t size = 0;
};
// .note.GNU-stack section.
@@ -145,31 +145,31 @@ class GnuStackSection : public Synthetic
public:
GnuStackSection()
: SyntheticSection(0, llvm::ELF::SHT_PROGBITS, 1, ".note.GNU-stack") {}
- void writeTo(uint8_t *Buf) override {}
+ void writeTo(uint8_t *buf) override {}
size_t getSize() const override { return 0; }
};
class GnuPropertySection : public SyntheticSection {
public:
GnuPropertySection();
- void writeTo(uint8_t *Buf) override;
+ void writeTo(uint8_t *buf) override;
size_t getSize() const override;
};
// .note.gnu.build-id section.
class BuildIdSection : public SyntheticSection {
// First 16 bytes are a header.
- static const unsigned HeaderSize = 16;
+ static const unsigned headerSize = 16;
public:
- const size_t HashSize;
+ const size_t hashSize;
BuildIdSection();
- void writeTo(uint8_t *Buf) override;
- size_t getSize() const override { return HeaderSize + HashSize; }
- void writeBuildId(llvm::ArrayRef<uint8_t> Buf);
+ void writeTo(uint8_t *buf) override;
+ size_t getSize() const override { return headerSize + hashSize; }
+ void writeBuildId(llvm::ArrayRef<uint8_t> buf);
private:
- uint8_t *HashBuf;
+ uint8_t *hashBuf;
};
// BssSection is used to reserve space for copy relocations and common symbols.
@@ -178,22 +178,22 @@ private:
// respectively.
class BssSection final : public SyntheticSection {
public:
- BssSection(StringRef Name, uint64_t Size, uint32_t Alignment);
+ BssSection(StringRef name, uint64_t size, uint32_t alignment);
void writeTo(uint8_t *) override {
llvm_unreachable("unexpected writeTo() call for SHT_NOBITS section");
}
- bool isNeeded() const override { return Size != 0; }
- size_t getSize() const override { return Size; }
+ bool isNeeded() const override { return size != 0; }
+ size_t getSize() const override { return size; }
- static bool classof(const SectionBase *S) { return S->Bss; }
- uint64_t Size;
+ static bool classof(const SectionBase *s) { return s->bss; }
+ uint64_t size;
};
class MipsGotSection final : public SyntheticSection {
public:
MipsGotSection();
- void writeTo(uint8_t *Buf) override;
- size_t getSize() const override { return Size; }
+ void writeTo(uint8_t *buf) override;
+ size_t getSize() const override { return size; }
bool updateAllocSize() override;
void finalizeContents() override;
bool isNeeded() const override;
@@ -202,16 +202,16 @@ public:
// primary and optional multiple secondary GOTs.
void build();
- void addEntry(InputFile &File, Symbol &Sym, int64_t Addend, RelExpr Expr);
- void addDynTlsEntry(InputFile &File, Symbol &Sym);
- void addTlsIndex(InputFile &File);
-
- uint64_t getPageEntryOffset(const InputFile *F, const Symbol &S,
- int64_t Addend) const;
- uint64_t getSymEntryOffset(const InputFile *F, const Symbol &S,
- int64_t Addend) const;
- uint64_t getGlobalDynOffset(const InputFile *F, const Symbol &S) const;
- uint64_t getTlsIndexOffset(const InputFile *F) const;
+ void addEntry(InputFile &file, Symbol &sym, int64_t addend, RelExpr expr);
+ void addDynTlsEntry(InputFile &file, Symbol &sym);
+ void addTlsIndex(InputFile &file);
+
+ uint64_t getPageEntryOffset(const InputFile *f, const Symbol &s,
+ int64_t addend) const;
+ uint64_t getSymEntryOffset(const InputFile *f, const Symbol &s,
+ int64_t addend) const;
+ uint64_t getGlobalDynOffset(const InputFile *f, const Symbol &s) const;
+ uint64_t getTlsIndexOffset(const InputFile *f) const;
// Returns the symbol which corresponds to the first entry of the global part
// of GOT on MIPS platform. It is required to fill up MIPS-specific dynamic
@@ -224,7 +224,7 @@ public:
unsigned getLocalEntriesNum() const;
// Return _gp value for primary GOT (nullptr) or particular input file.
- uint64_t getGp(const InputFile *F = nullptr) const;
+ uint64_t getGp(const InputFile *f = nullptr) const;
private:
// MIPS GOT consists of three parts: local, global and tls. Each part
@@ -314,35 +314,35 @@ private:
// https://dmz-portal.mips.com/wiki/MIPS_Multi_GOT
// Number of "Header" entries.
- static const unsigned HeaderEntriesNum = 2;
+ static const unsigned headerEntriesNum = 2;
- uint64_t Size = 0;
+ uint64_t size = 0;
// Symbol and addend.
using GotEntry = std::pair<Symbol *, int64_t>;
struct FileGot {
- InputFile *File = nullptr;
- size_t StartIndex = 0;
+ InputFile *file = nullptr;
+ size_t startIndex = 0;
struct PageBlock {
- size_t FirstIndex;
- size_t Count;
- PageBlock() : FirstIndex(0), Count(0) {}
+ size_t firstIndex;
+ size_t count;
+ PageBlock() : firstIndex(0), count(0) {}
};
// Map output sections referenced by MIPS GOT relocations
// to the description (index/count) "page" entries allocated
// for this section.
- llvm::SmallMapVector<const OutputSection *, PageBlock, 16> PagesMap;
+ llvm::SmallMapVector<const OutputSection *, PageBlock, 16> pagesMap;
// Maps from Symbol+Addend pair or just Symbol to the GOT entry index.
- llvm::MapVector<GotEntry, size_t> Local16;
- llvm::MapVector<GotEntry, size_t> Local32;
- llvm::MapVector<Symbol *, size_t> Global;
- llvm::MapVector<Symbol *, size_t> Relocs;
- llvm::MapVector<Symbol *, size_t> Tls;
+ llvm::MapVector<GotEntry, size_t> local16;
+ llvm::MapVector<GotEntry, size_t> local32;
+ llvm::MapVector<Symbol *, size_t> global;
+ llvm::MapVector<Symbol *, size_t> relocs;
+ llvm::MapVector<Symbol *, size_t> tls;
// Set of symbols referenced by dynamic TLS relocations.
- llvm::MapVector<Symbol *, size_t> DynTlsSymbols;
+ llvm::MapVector<Symbol *, size_t> dynTlsSymbols;
// Total number of all entries.
size_t getEntriesNum() const;
@@ -355,31 +355,31 @@ private:
// Container of GOT created for each input file.
// After building a final series of GOTs this container
// holds primary and secondary GOT's.
- std::vector<FileGot> Gots;
+ std::vector<FileGot> gots;
// Return (and create if necessary) `FileGot`.
- FileGot &getGot(InputFile &F);
+ FileGot &getGot(InputFile &f);
// Try to merge two GOTs. In case of success the `Dst` contains
// result of merging and the function returns true. In case of
// ovwerflow the `Dst` is unchanged and the function returns false.
- bool tryMergeGots(FileGot & Dst, FileGot & Src, bool IsPrimary);
+ bool tryMergeGots(FileGot & dst, FileGot & src, bool isPrimary);
};
class GotPltSection final : public SyntheticSection {
public:
GotPltSection();
- void addEntry(Symbol &Sym);
+ void addEntry(Symbol &sym);
size_t getSize() const override;
- void writeTo(uint8_t *Buf) override;
+ void writeTo(uint8_t *buf) override;
bool isNeeded() const override;
// Flag to force GotPlt to be in output if we have relocations
// that relies on its address.
- bool HasGotPltOffRel = false;
+ bool hasGotPltOffRel = false;
private:
- std::vector<const Symbol *> Entries;
+ std::vector<const Symbol *> entries;
};
// The IgotPltSection is a Got associated with the PltSection for GNU Ifunc
@@ -389,67 +389,67 @@ private:
class IgotPltSection final : public SyntheticSection {
public:
IgotPltSection();
- void addEntry(Symbol &Sym);
+ void addEntry(Symbol &sym);
size_t getSize() const override;
- void writeTo(uint8_t *Buf) override;
- bool isNeeded() const override { return !Entries.empty(); }
+ void writeTo(uint8_t *buf) override;
+ bool isNeeded() const override { return !entries.empty(); }
private:
- std::vector<const Symbol *> Entries;
+ std::vector<const Symbol *> entries;
};
class StringTableSection final : public SyntheticSection {
public:
- StringTableSection(StringRef Name, bool Dynamic);
- unsigned addString(StringRef S, bool HashIt = true);
- void writeTo(uint8_t *Buf) override;
- size_t getSize() const override { return Size; }
- bool isDynamic() const { return Dynamic; }
+ StringTableSection(StringRef name, bool dynamic);
+ unsigned addString(StringRef s, bool hashIt = true);
+ void writeTo(uint8_t *buf) override;
+ size_t getSize() const override { return size; }
+ bool isDynamic() const { return dynamic; }
private:
- const bool Dynamic;
+ const bool dynamic;
- uint64_t Size = 0;
+ uint64_t size = 0;
- llvm::DenseMap<StringRef, unsigned> StringMap;
- std::vector<StringRef> Strings;
+ llvm::DenseMap<StringRef, unsigned> stringMap;
+ std::vector<StringRef> strings;
};
class DynamicReloc {
public:
- DynamicReloc(RelType Type, const InputSectionBase *InputSec,
- uint64_t OffsetInSec, bool UseSymVA, Symbol *Sym, int64_t Addend)
- : Type(Type), Sym(Sym), InputSec(InputSec), OffsetInSec(OffsetInSec),
- UseSymVA(UseSymVA), Addend(Addend), OutputSec(nullptr) {}
+ DynamicReloc(RelType type, const InputSectionBase *inputSec,
+ uint64_t offsetInSec, bool useSymVA, Symbol *sym, int64_t addend)
+ : type(type), sym(sym), inputSec(inputSec), offsetInSec(offsetInSec),
+ useSymVA(useSymVA), addend(addend), outputSec(nullptr) {}
// This constructor records dynamic relocation settings used by MIPS
// multi-GOT implementation. It's to relocate addresses of 64kb pages
// lie inside the output section.
- DynamicReloc(RelType Type, const InputSectionBase *InputSec,
- uint64_t OffsetInSec, const OutputSection *OutputSec,
- int64_t Addend)
- : Type(Type), Sym(nullptr), InputSec(InputSec), OffsetInSec(OffsetInSec),
- UseSymVA(false), Addend(Addend), OutputSec(OutputSec) {}
+ DynamicReloc(RelType type, const InputSectionBase *inputSec,
+ uint64_t offsetInSec, const OutputSection *outputSec,
+ int64_t addend)
+ : type(type), sym(nullptr), inputSec(inputSec), offsetInSec(offsetInSec),
+ useSymVA(false), addend(addend), outputSec(outputSec) {}
uint64_t getOffset() const;
- uint32_t getSymIndex(SymbolTableBaseSection *SymTab) const;
+ uint32_t getSymIndex(SymbolTableBaseSection *symTab) const;
// Computes the addend of the dynamic relocation. Note that this is not the
// same as the Addend member variable as it also includes the symbol address
// if UseSymVA is true.
int64_t computeAddend() const;
- RelType Type;
+ RelType type;
- Symbol *Sym;
- const InputSectionBase *InputSec = nullptr;
- uint64_t OffsetInSec;
+ Symbol *sym;
+ const InputSectionBase *inputSec = nullptr;
+ uint64_t offsetInSec;
// If this member is true, the dynamic relocation will not be against the
// symbol but will instead be a relative relocation that simply adds the
// load address. This means we need to write the symbol virtual address
// plus the original addend as the final relocation addend.
- bool UseSymVA;
- int64_t Addend;
- const OutputSection *OutputSec;
+ bool useSymVA;
+ int64_t addend;
+ const OutputSection *outputSec;
};
template <class ELFT> class DynamicSection final : public SyntheticSection {
@@ -461,47 +461,47 @@ template <class ELFT> class DynamicSecti
using Elf_Sym = typename ELFT::Sym;
// finalizeContents() fills this vector with the section contents.
- std::vector<std::pair<int32_t, std::function<uint64_t()>>> Entries;
+ std::vector<std::pair<int32_t, std::function<uint64_t()>>> entries;
public:
DynamicSection();
void finalizeContents() override;
- void writeTo(uint8_t *Buf) override;
- size_t getSize() const override { return Size; }
+ void writeTo(uint8_t *buf) override;
+ size_t getSize() const override { return size; }
private:
- void add(int32_t Tag, std::function<uint64_t()> Fn);
- void addInt(int32_t Tag, uint64_t Val);
- void addInSec(int32_t Tag, InputSection *Sec);
- void addInSecRelative(int32_t Tag, InputSection *Sec);
- void addOutSec(int32_t Tag, OutputSection *Sec);
- void addSize(int32_t Tag, OutputSection *Sec);
- void addSym(int32_t Tag, Symbol *Sym);
+ void add(int32_t tag, std::function<uint64_t()> fn);
+ void addInt(int32_t tag, uint64_t val);
+ void addInSec(int32_t tag, InputSection *sec);
+ void addInSecRelative(int32_t tag, InputSection *sec);
+ void addOutSec(int32_t tag, OutputSection *sec);
+ void addSize(int32_t tag, OutputSection *sec);
+ void addSym(int32_t tag, Symbol *sym);
- uint64_t Size = 0;
+ uint64_t size = 0;
};
class RelocationBaseSection : public SyntheticSection {
public:
- RelocationBaseSection(StringRef Name, uint32_t Type, int32_t DynamicTag,
- int32_t SizeDynamicTag);
- void addReloc(RelType DynType, InputSectionBase *IS, uint64_t OffsetInSec,
- Symbol *Sym);
+ RelocationBaseSection(StringRef name, uint32_t type, int32_t dynamicTag,
+ int32_t sizeDynamicTag);
+ void addReloc(RelType dynType, InputSectionBase *isec, uint64_t offsetInSec,
+ Symbol *sym);
// Add a dynamic relocation that might need an addend. This takes care of
// writing the addend to the output section if needed.
- void addReloc(RelType DynType, InputSectionBase *InputSec,
- uint64_t OffsetInSec, Symbol *Sym, int64_t Addend, RelExpr Expr,
- RelType Type);
- void addReloc(const DynamicReloc &Reloc);
- bool isNeeded() const override { return !Relocs.empty(); }
- size_t getSize() const override { return Relocs.size() * this->Entsize; }
- size_t getRelativeRelocCount() const { return NumRelativeRelocs; }
+ void addReloc(RelType dynType, InputSectionBase *inputSec,
+ uint64_t offsetInSec, Symbol *sym, int64_t addend, RelExpr expr,
+ RelType type);
+ void addReloc(const DynamicReloc &reloc);
+ bool isNeeded() const override { return !relocs.empty(); }
+ size_t getSize() const override { return relocs.size() * this->entsize; }
+ size_t getRelativeRelocCount() const { return numRelativeRelocs; }
void finalizeContents() override;
- int32_t DynamicTag, SizeDynamicTag;
- std::vector<DynamicReloc> Relocs;
+ int32_t dynamicTag, sizeDynamicTag;
+ std::vector<DynamicReloc> relocs;
protected:
- size_t NumRelativeRelocs = 0;
+ size_t numRelativeRelocs = 0;
};
template <class ELFT>
@@ -510,11 +510,11 @@ class RelocationSection final : public R
using Elf_Rela = typename ELFT::Rela;
public:
- RelocationSection(StringRef Name, bool Sort);
- void writeTo(uint8_t *Buf) override;
+ RelocationSection(StringRef name, bool sort);
+ void writeTo(uint8_t *buf) override;
private:
- bool Sort;
+ bool sort;
};
template <class ELFT>
@@ -523,30 +523,30 @@ class AndroidPackedRelocationSection fin
using Elf_Rela = typename ELFT::Rela;
public:
- AndroidPackedRelocationSection(StringRef Name);
+ AndroidPackedRelocationSection(StringRef name);
bool updateAllocSize() override;
- size_t getSize() const override { return RelocData.size(); }
- void writeTo(uint8_t *Buf) override {
- memcpy(Buf, RelocData.data(), RelocData.size());
+ size_t getSize() const override { return relocData.size(); }
+ void writeTo(uint8_t *buf) override {
+ memcpy(buf, relocData.data(), relocData.size());
}
private:
- SmallVector<char, 0> RelocData;
+ SmallVector<char, 0> relocData;
};
struct RelativeReloc {
- uint64_t getOffset() const { return InputSec->getVA(OffsetInSec); }
+ uint64_t getOffset() const { return inputSec->getVA(offsetInSec); }
- const InputSectionBase *InputSec;
- uint64_t OffsetInSec;
+ const InputSectionBase *inputSec;
+ uint64_t offsetInSec;
};
class RelrBaseSection : public SyntheticSection {
public:
RelrBaseSection();
- bool isNeeded() const override { return !Relocs.empty(); }
- std::vector<RelativeReloc> Relocs;
+ bool isNeeded() const override { return !relocs.empty(); }
+ std::vector<RelativeReloc> relocs;
};
// RelrSection is used to encode offsets for relative relocations.
@@ -560,41 +560,41 @@ public:
RelrSection();
bool updateAllocSize() override;
- size_t getSize() const override { return RelrRelocs.size() * this->Entsize; }
- void writeTo(uint8_t *Buf) override {
- memcpy(Buf, RelrRelocs.data(), getSize());
+ size_t getSize() const override { return relrRelocs.size() * this->entsize; }
+ void writeTo(uint8_t *buf) override {
+ memcpy(buf, relrRelocs.data(), getSize());
}
private:
- std::vector<Elf_Relr> RelrRelocs;
+ std::vector<Elf_Relr> relrRelocs;
};
struct SymbolTableEntry {
- Symbol *Sym;
- size_t StrTabOffset;
+ Symbol *sym;
+ size_t strTabOffset;
};
class SymbolTableBaseSection : public SyntheticSection {
public:
- SymbolTableBaseSection(StringTableSection &StrTabSec);
+ SymbolTableBaseSection(StringTableSection &strTabSec);
void finalizeContents() override;
- size_t getSize() const override { return getNumSymbols() * Entsize; }
- void addSymbol(Symbol *Sym);
- unsigned getNumSymbols() const { return Symbols.size() + 1; }
- size_t getSymbolIndex(Symbol *Sym);
- ArrayRef<SymbolTableEntry> getSymbols() const { return Symbols; }
+ size_t getSize() const override { return getNumSymbols() * entsize; }
+ void addSymbol(Symbol *sym);
+ unsigned getNumSymbols() const { return symbols.size() + 1; }
+ size_t getSymbolIndex(Symbol *sym);
+ ArrayRef<SymbolTableEntry> getSymbols() const { return symbols; }
protected:
void sortSymTabSymbols();
// A vector of symbols and their string table offsets.
- std::vector<SymbolTableEntry> Symbols;
+ std::vector<SymbolTableEntry> symbols;
- StringTableSection &StrTabSec;
+ StringTableSection &strTabSec;
- llvm::once_flag OnceFlag;
- llvm::DenseMap<Symbol *, size_t> SymbolIndexMap;
- llvm::DenseMap<OutputSection *, size_t> SectionIndexMap;
+ llvm::once_flag onceFlag;
+ llvm::DenseMap<Symbol *, size_t> symbolIndexMap;
+ llvm::DenseMap<OutputSection *, size_t> sectionIndexMap;
};
template <class ELFT>
@@ -602,15 +602,15 @@ class SymbolTableSection final : public
using Elf_Sym = typename ELFT::Sym;
public:
- SymbolTableSection(StringTableSection &StrTabSec);
- void writeTo(uint8_t *Buf) override;
+ SymbolTableSection(StringTableSection &strTabSec);
+ void writeTo(uint8_t *buf) override;
};
class SymtabShndxSection final : public SyntheticSection {
public:
SymtabShndxSection();
- void writeTo(uint8_t *Buf) override;
+ void writeTo(uint8_t *buf) override;
size_t getSize() const override;
bool isNeeded() const override;
void finalizeContents() override;
@@ -622,42 +622,42 @@ class GnuHashTableSection final : public
public:
GnuHashTableSection();
void finalizeContents() override;
- void writeTo(uint8_t *Buf) override;
- size_t getSize() const override { return Size; }
+ void writeTo(uint8_t *buf) override;
+ size_t getSize() const override { return size; }
// Adds symbols to the hash table.
// Sorts the input to satisfy GNU hash section requirements.
- void addSymbols(std::vector<SymbolTableEntry> &Symbols);
+ void addSymbols(std::vector<SymbolTableEntry> &symbols);
private:
// See the comment in writeBloomFilter.
enum { Shift2 = 26 };
- void writeBloomFilter(uint8_t *Buf);
- void writeHashTable(uint8_t *Buf);
+ void writeBloomFilter(uint8_t *buf);
+ void writeHashTable(uint8_t *buf);
struct Entry {
- Symbol *Sym;
- size_t StrTabOffset;
- uint32_t Hash;
- uint32_t BucketIdx;
+ Symbol *sym;
+ size_t strTabOffset;
+ uint32_t hash;
+ uint32_t bucketIdx;
};
- std::vector<Entry> Symbols;
- size_t MaskWords;
- size_t NBuckets = 0;
- size_t Size = 0;
+ std::vector<Entry> symbols;
+ size_t maskWords;
+ size_t nBuckets = 0;
+ size_t size = 0;
};
class HashTableSection final : public SyntheticSection {
public:
HashTableSection();
void finalizeContents() override;
- void writeTo(uint8_t *Buf) override;
- size_t getSize() const override { return Size; }
+ void writeTo(uint8_t *buf) override;
+ size_t getSize() const override { return size; }
private:
- size_t Size = 0;
+ size_t size = 0;
};
// The PltSection is used for both the Plt and Iplt. The former usually has a
@@ -666,66 +666,66 @@ private:
// Target->IRelativeRel.
class PltSection : public SyntheticSection {
public:
- PltSection(bool IsIplt);
- void writeTo(uint8_t *Buf) override;
+ PltSection(bool isIplt);
+ void writeTo(uint8_t *buf) override;
size_t getSize() const override;
- bool isNeeded() const override { return !Entries.empty(); }
+ bool isNeeded() const override { return !entries.empty(); }
void addSymbols();
- template <class ELFT> void addEntry(Symbol &Sym);
+ template <class ELFT> void addEntry(Symbol &sym);
- size_t HeaderSize;
+ size_t headerSize;
private:
- std::vector<const Symbol *> Entries;
- bool IsIplt;
+ std::vector<const Symbol *> entries;
+ bool isIplt;
};
class GdbIndexSection final : public SyntheticSection {
public:
struct AddressEntry {
- InputSection *Section;
- uint64_t LowAddress;
- uint64_t HighAddress;
- uint32_t CuIndex;
+ InputSection *section;
+ uint64_t lowAddress;
+ uint64_t highAddress;
+ uint32_t cuIndex;
};
struct CuEntry {
- uint64_t CuOffset;
- uint64_t CuLength;
+ uint64_t cuOffset;
+ uint64_t cuLength;
};
struct NameAttrEntry {
- llvm::CachedHashStringRef Name;
- uint32_t CuIndexAndAttrs;
+ llvm::CachedHashStringRef name;
+ uint32_t cuIndexAndAttrs;
};
struct GdbChunk {
- InputSection *Sec;
- std::vector<AddressEntry> AddressAreas;
- std::vector<CuEntry> CompilationUnits;
+ InputSection *sec;
+ std::vector<AddressEntry> addressAreas;
+ std::vector<CuEntry> compilationUnits;
};
struct GdbSymbol {
- llvm::CachedHashStringRef Name;
- std::vector<uint32_t> CuVector;
- uint32_t NameOff;
- uint32_t CuVectorOff;
+ llvm::CachedHashStringRef name;
+ std::vector<uint32_t> cuVector;
+ uint32_t nameOff;
+ uint32_t cuVectorOff;
};
GdbIndexSection();
template <typename ELFT> static GdbIndexSection *create();
- void writeTo(uint8_t *Buf) override;
- size_t getSize() const override { return Size; }
+ void writeTo(uint8_t *buf) override;
+ size_t getSize() const override { return size; }
bool isNeeded() const override;
private:
struct GdbIndexHeader {
- llvm::support::ulittle32_t Version;
- llvm::support::ulittle32_t CuListOff;
- llvm::support::ulittle32_t CuTypesOff;
- llvm::support::ulittle32_t AddressAreaOff;
- llvm::support::ulittle32_t SymtabOff;
- llvm::support::ulittle32_t ConstantPoolOff;
+ llvm::support::ulittle32_t version;
+ llvm::support::ulittle32_t cuListOff;
+ llvm::support::ulittle32_t cuTypesOff;
+ llvm::support::ulittle32_t addressAreaOff;
+ llvm::support::ulittle32_t symtabOff;
+ llvm::support::ulittle32_t constantPoolOff;
};
void initOutputSize();
@@ -733,12 +733,12 @@ private:
// Each chunk contains information gathered from debug sections of a
// single object file.
- std::vector<GdbChunk> Chunks;
+ std::vector<GdbChunk> chunks;
// A symbol table for this .gdb_index section.
- std::vector<GdbSymbol> Symbols;
+ std::vector<GdbSymbol> symbols;
- size_t Size;
+ size_t size;
};
// --eh-frame-hdr option tells linker to construct a header for all the
@@ -754,7 +754,7 @@ class EhFrameHeader final : public Synth
public:
EhFrameHeader();
void write();
- void writeTo(uint8_t *Buf) override;
+ void writeTo(uint8_t *buf) override;
size_t getSize() const override;
bool isNeeded() const override;
};
@@ -772,15 +772,15 @@ public:
VersionDefinitionSection();
void finalizeContents() override;
size_t getSize() const override;
- void writeTo(uint8_t *Buf) override;
+ void writeTo(uint8_t *buf) override;
private:
enum { EntrySize = 28 };
- void writeOne(uint8_t *Buf, uint32_t Index, StringRef Name, size_t NameOff);
+ void writeOne(uint8_t *buf, uint32_t index, StringRef name, size_t nameOff);
StringRef getFileDefName();
- unsigned FileDefNameOff;
- std::vector<unsigned> VerDefNameOffs;
+ unsigned fileDefNameOff;
+ std::vector<unsigned> verDefNameOffs;
};
// The .gnu.version section specifies the required version of each symbol in the
@@ -794,7 +794,7 @@ public:
VersionTableSection();
void finalizeContents() override;
size_t getSize() const override;
- void writeTo(uint8_t *Buf) override;
+ void writeTo(uint8_t *buf) override;
bool isNeeded() const override;
};
@@ -809,22 +809,22 @@ class VersionNeedSection final : public
using Elf_Vernaux = typename ELFT::Vernaux;
struct Vernaux {
- uint64_t Hash;
- uint32_t VerneedIndex;
- uint64_t NameStrTab;
+ uint64_t hash;
+ uint32_t verneedIndex;
+ uint64_t nameStrTab;
};
struct Verneed {
- uint64_t NameStrTab;
- std::vector<Vernaux> Vernauxs;
+ uint64_t nameStrTab;
+ std::vector<Vernaux> vernauxs;
};
- std::vector<Verneed> Verneeds;
+ std::vector<Verneed> verneeds;
public:
VersionNeedSection();
void finalizeContents() override;
- void writeTo(uint8_t *Buf) override;
+ void writeTo(uint8_t *buf) override;
size_t getSize() const override;
bool isNeeded() const override;
};
@@ -835,36 +835,36 @@ public:
// attached to regular output sections.
class MergeSyntheticSection : public SyntheticSection {
public:
- void addSection(MergeInputSection *MS);
- std::vector<MergeInputSection *> Sections;
+ void addSection(MergeInputSection *ms);
+ std::vector<MergeInputSection *> sections;
protected:
- MergeSyntheticSection(StringRef Name, uint32_t Type, uint64_t Flags,
- uint32_t Alignment)
- : SyntheticSection(Flags, Type, Alignment, Name) {}
+ MergeSyntheticSection(StringRef name, uint32_t type, uint64_t flags,
+ uint32_t alignment)
+ : SyntheticSection(flags, type, alignment, name) {}
};
class MergeTailSection final : public MergeSyntheticSection {
public:
- MergeTailSection(StringRef Name, uint32_t Type, uint64_t Flags,
- uint32_t Alignment);
+ MergeTailSection(StringRef name, uint32_t type, uint64_t flags,
+ uint32_t alignment);
size_t getSize() const override;
- void writeTo(uint8_t *Buf) override;
+ void writeTo(uint8_t *buf) override;
void finalizeContents() override;
private:
- llvm::StringTableBuilder Builder;
+ llvm::StringTableBuilder builder;
};
class MergeNoTailSection final : public MergeSyntheticSection {
public:
- MergeNoTailSection(StringRef Name, uint32_t Type, uint64_t Flags,
- uint32_t Alignment)
- : MergeSyntheticSection(Name, Type, Flags, Alignment) {}
+ MergeNoTailSection(StringRef name, uint32_t type, uint64_t flags,
+ uint32_t alignment)
+ : MergeSyntheticSection(name, type, flags, alignment) {}
- size_t getSize() const override { return Size; }
- void writeTo(uint8_t *Buf) override;
+ size_t getSize() const override { return size; }
+ void writeTo(uint8_t *buf) override;
void finalizeContents() override;
private:
@@ -873,18 +873,18 @@ private:
// because DenseMap also uses lower bits to determine a bucket ID.
// If we use lower bits, it significantly increases the probability of
// hash collisons.
- size_t getShardId(uint32_t Hash) {
- assert((Hash >> 31) == 0);
- return Hash >> (31 - llvm::countTrailingZeros(NumShards));
+ size_t getShardId(uint32_t hash) {
+ assert((hash >> 31) == 0);
+ return hash >> (31 - llvm::countTrailingZeros(numShards));
}
// Section size
- size_t Size;
+ size_t size;
// String table contents
- constexpr static size_t NumShards = 32;
- std::vector<llvm::StringTableBuilder> Shards;
- size_t ShardOffsets[NumShards];
+ constexpr static size_t numShards = 32;
+ std::vector<llvm::StringTableBuilder> shards;
+ size_t shardOffsets[numShards];
};
// .MIPS.abiflags section.
@@ -895,12 +895,12 @@ class MipsAbiFlagsSection final : public
public:
static MipsAbiFlagsSection *create();
- MipsAbiFlagsSection(Elf_Mips_ABIFlags Flags);
+ MipsAbiFlagsSection(Elf_Mips_ABIFlags flags);
size_t getSize() const override { return sizeof(Elf_Mips_ABIFlags); }
- void writeTo(uint8_t *Buf) override;
+ void writeTo(uint8_t *buf) override;
private:
- Elf_Mips_ABIFlags Flags;
+ Elf_Mips_ABIFlags flags;
};
// .MIPS.options section.
@@ -911,15 +911,15 @@ template <class ELFT> class MipsOptionsS
public:
static MipsOptionsSection *create();
- MipsOptionsSection(Elf_Mips_RegInfo Reginfo);
- void writeTo(uint8_t *Buf) override;
+ MipsOptionsSection(Elf_Mips_RegInfo reginfo);
+ void writeTo(uint8_t *buf) override;
size_t getSize() const override {
return sizeof(Elf_Mips_Options) + sizeof(Elf_Mips_RegInfo);
}
private:
- Elf_Mips_RegInfo Reginfo;
+ Elf_Mips_RegInfo reginfo;
};
// MIPS .reginfo section.
@@ -929,12 +929,12 @@ template <class ELFT> class MipsReginfoS
public:
static MipsReginfoSection *create();
- MipsReginfoSection(Elf_Mips_RegInfo Reginfo);
+ MipsReginfoSection(Elf_Mips_RegInfo reginfo);
size_t getSize() const override { return sizeof(Elf_Mips_RegInfo); }
- void writeTo(uint8_t *Buf) override;
+ void writeTo(uint8_t *buf) override;
private:
- Elf_Mips_RegInfo Reginfo;
+ Elf_Mips_RegInfo reginfo;
};
// This is a MIPS specific section to hold a space within the data segment
@@ -944,8 +944,8 @@ private:
class MipsRldMapSection : public SyntheticSection {
public:
MipsRldMapSection();
- size_t getSize() const override { return Config->Wordsize; }
- void writeTo(uint8_t *Buf) override {}
+ size_t getSize() const override { return config->wordsize; }
+ void writeTo(uint8_t *buf) override {}
};
// Representation of the combined .ARM.Exidx input sections. We process these
@@ -988,38 +988,38 @@ public:
// Add an input section to the ARMExidxSyntheticSection. Returns whether the
// section needs to be removed from the main input section list.
- bool addSection(InputSection *IS);
+ bool addSection(InputSection *isec);
- size_t getSize() const override { return Size; }
- void writeTo(uint8_t *Buf) override;
- bool isNeeded() const override { return !Empty; }
+ size_t getSize() const override { return size; }
+ void writeTo(uint8_t *buf) override;
+ bool isNeeded() const override { return !empty; }
// Sort and remove duplicate entries.
void finalizeContents() override;
InputSection *getLinkOrderDep() const;
- static bool classof(const SectionBase *D);
+ static bool classof(const SectionBase *d);
// Links to the ARMExidxSections so we can transfer the relocations once the
// layout is known.
- std::vector<InputSection *> ExidxSections;
+ std::vector<InputSection *> exidxSections;
private:
- size_t Size;
+ size_t size;
// Empty if ExecutableSections contains no dependent .ARM.exidx sections.
- bool Empty = true;
+ bool empty = true;
// Instead of storing pointers to the .ARM.exidx InputSections from
// InputObjects, we store pointers to the executable sections that need
// .ARM.exidx sections. We can then use the dependentSections of these to
// either find the .ARM.exidx section or know that we need to generate one.
- std::vector<InputSection *> ExecutableSections;
+ std::vector<InputSection *> executableSections;
// The executable InputSection with the highest address to use for the
// sentinel. We store separately from ExecutableSections as merging of
// duplicate entries may mean this InputSection is removed from
// ExecutableSections.
- InputSection *Sentinel = nullptr;
+ InputSection *sentinel = nullptr;
};
// A container for one or more linker generated thunks. Instances of these
@@ -1027,21 +1027,21 @@ private:
class ThunkSection : public SyntheticSection {
public:
// ThunkSection in OS, with desired OutSecOff of Off
- ThunkSection(OutputSection *OS, uint64_t Off);
+ ThunkSection(OutputSection *os, uint64_t off);
// Add a newly created Thunk to this container:
// Thunk is given offset from start of this InputSection
// Thunk defines a symbol in this InputSection that can be used as target
// of a relocation
- void addThunk(Thunk *T);
- size_t getSize() const override { return Size; }
- void writeTo(uint8_t *Buf) override;
+ void addThunk(Thunk *t);
+ size_t getSize() const override { return size; }
+ void writeTo(uint8_t *buf) override;
InputSection *getTargetInputSection() const;
bool assignOffsets();
private:
- std::vector<Thunk *> Thunks;
- size_t Size = 0;
+ std::vector<Thunk *> thunks;
+ size_t size = 0;
};
// Used to compute OutSecOff of .got2 in each object file. This is needed to
@@ -1052,7 +1052,7 @@ public:
size_t getSize() const override { return 0; }
bool isNeeded() const override;
void finalizeContents() override;
- void writeTo(uint8_t *Buf) override {}
+ void writeTo(uint8_t *buf) override {}
};
// This section is used to store the addresses of functions that are called
@@ -1063,15 +1063,15 @@ public:
class PPC64LongBranchTargetSection final : public SyntheticSection {
public:
PPC64LongBranchTargetSection();
- void addEntry(Symbol &Sym);
+ void addEntry(Symbol &sym);
size_t getSize() const override;
- void writeTo(uint8_t *Buf) override;
+ void writeTo(uint8_t *buf) override;
bool isNeeded() const override;
- void finalizeContents() override { Finalized = true; }
+ void finalizeContents() override { finalized = true; }
private:
- std::vector<const Symbol *> Entries;
- bool Finalized = false;
+ std::vector<const Symbol *> entries;
+ bool finalized = false;
};
template <typename ELFT>
@@ -1079,7 +1079,7 @@ class PartitionElfHeaderSection : public
public:
PartitionElfHeaderSection();
size_t getSize() const override;
- void writeTo(uint8_t *Buf) override;
+ void writeTo(uint8_t *buf) override;
};
template <typename ELFT>
@@ -1087,7 +1087,7 @@ class PartitionProgramHeadersSection : p
public:
PartitionProgramHeadersSection();
size_t getSize() const override;
- void writeTo(uint8_t *Buf) override;
+ void writeTo(uint8_t *buf) override;
};
class PartitionIndexSection : public SyntheticSection {
@@ -1095,7 +1095,7 @@ public:
PartitionIndexSection();
size_t getSize() const override;
void finalizeContents() override;
- void writeTo(uint8_t *Buf) override;
+ void writeTo(uint8_t *buf) override;
};
// Create a dummy .sdata for __global_pointer$ if .sdata does not exist.
@@ -1104,7 +1104,7 @@ public:
RISCVSdataSection();
size_t getSize() const override { return 0; }
bool isNeeded() const override;
- void writeTo(uint8_t *Buf) override {}
+ void writeTo(uint8_t *buf) override {}
};
InputSection *createInterpSection();
@@ -1112,75 +1112,75 @@ MergeInputSection *createCommentSection(
template <class ELFT> void splitSections();
void mergeSections();
-template <typename ELFT> void writeEhdr(uint8_t *Buf, Partition &Part);
-template <typename ELFT> void writePhdrs(uint8_t *Buf, Partition &Part);
+template <typename ELFT> void writeEhdr(uint8_t *buf, Partition &part);
+template <typename ELFT> void writePhdrs(uint8_t *buf, Partition &part);
-Defined *addSyntheticLocal(StringRef Name, uint8_t Type, uint64_t Value,
- uint64_t Size, InputSectionBase &Section);
+Defined *addSyntheticLocal(StringRef name, uint8_t type, uint64_t value,
+ uint64_t size, InputSectionBase §ion);
-void addVerneed(Symbol *SS);
+void addVerneed(Symbol *ss);
// Linker generated per-partition sections.
struct Partition {
- StringRef Name;
- uint64_t NameStrTab;
+ StringRef name;
+ uint64_t nameStrTab;
- SyntheticSection *ElfHeader;
- SyntheticSection *ProgramHeaders;
- std::vector<PhdrEntry *> Phdrs;
-
- ARMExidxSyntheticSection *ARMExidx;
- BuildIdSection *BuildId;
- SyntheticSection *Dynamic;
- StringTableSection *DynStrTab;
- SymbolTableBaseSection *DynSymTab;
- EhFrameHeader *EhFrameHdr;
- EhFrameSection *EhFrame;
- GnuHashTableSection *GnuHashTab;
- HashTableSection *HashTab;
- RelocationBaseSection *RelaDyn;
- RelrBaseSection *RelrDyn;
- VersionDefinitionSection *VerDef;
- SyntheticSection *VerNeed;
- VersionTableSection *VerSym;
+ SyntheticSection *elfHeader;
+ SyntheticSection *programHeaders;
+ std::vector<PhdrEntry *> phdrs;
+
+ ARMExidxSyntheticSection *armExidx;
+ BuildIdSection *buildId;
+ SyntheticSection *dynamic;
+ StringTableSection *dynStrTab;
+ SymbolTableBaseSection *dynSymTab;
+ EhFrameHeader *ehFrameHdr;
+ EhFrameSection *ehFrame;
+ GnuHashTableSection *gnuHashTab;
+ HashTableSection *hashTab;
+ RelocationBaseSection *relaDyn;
+ RelrBaseSection *relrDyn;
+ VersionDefinitionSection *verDef;
+ SyntheticSection *verNeed;
+ VersionTableSection *verSym;
- unsigned getNumber() const { return this - &Partitions[0] + 1; }
+ unsigned getNumber() const { return this - &partitions[0] + 1; }
};
-extern Partition *Main;
+extern Partition *mainPart;
inline Partition &SectionBase::getPartition() const {
assert(isLive());
- return Partitions[Partition - 1];
+ return partitions[partition - 1];
}
// Linker generated sections which can be used as inputs and are not specific to
// a partition.
struct InStruct {
- InputSection *ARMAttributes;
- BssSection *Bss;
- BssSection *BssRelRo;
- GotSection *Got;
- GotPltSection *GotPlt;
- IgotPltSection *IgotPlt;
- PPC64LongBranchTargetSection *PPC64LongBranchTarget;
- MipsGotSection *MipsGot;
- MipsRldMapSection *MipsRldMap;
- SyntheticSection *PartEnd;
- SyntheticSection *PartIndex;
- PltSection *Plt;
- PltSection *Iplt;
- PPC32Got2Section *PPC32Got2;
- RISCVSdataSection *RISCVSdata;
- RelocationBaseSection *RelaPlt;
- RelocationBaseSection *RelaIplt;
- StringTableSection *ShStrTab;
- StringTableSection *StrTab;
- SymbolTableBaseSection *SymTab;
- SymtabShndxSection *SymTabShndx;
+ InputSection *armAttributes;
+ BssSection *bss;
+ BssSection *bssRelRo;
+ GotSection *got;
+ GotPltSection *gotPlt;
+ IgotPltSection *igotPlt;
+ PPC64LongBranchTargetSection *ppc64LongBranchTarget;
+ MipsGotSection *mipsGot;
+ MipsRldMapSection *mipsRldMap;
+ SyntheticSection *partEnd;
+ SyntheticSection *partIndex;
+ PltSection *plt;
+ PltSection *iplt;
+ PPC32Got2Section *ppc32Got2;
+ RISCVSdataSection *riscvSdata;
+ RelocationBaseSection *relaPlt;
+ RelocationBaseSection *relaIplt;
+ StringTableSection *shStrTab;
+ StringTableSection *strTab;
+ SymbolTableBaseSection *symTab;
+ SymtabShndxSection *symTabShndx;
};
-extern InStruct In;
+extern InStruct in;
} // namespace elf
} // namespace lld
Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=365595&r1=365594&r2=365595&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Tue Jul 9 22:00:37 2019
@@ -37,17 +37,17 @@ using namespace llvm::ELF;
using namespace lld;
using namespace lld::elf;
-const TargetInfo *elf::Target;
+const TargetInfo *elf::target;
-std::string lld::toString(RelType Type) {
- StringRef S = getELFRelocationTypeName(elf::Config->EMachine, Type);
- if (S == "Unknown")
- return ("Unknown (" + Twine(Type) + ")").str();
- return S;
+std::string lld::toString(RelType type) {
+ StringRef s = getELFRelocationTypeName(elf::config->emachine, type);
+ if (s == "Unknown")
+ return ("Unknown (" + Twine(type) + ")").str();
+ return s;
}
TargetInfo *elf::getTarget() {
- switch (Config->EMachine) {
+ switch (config->emachine) {
case EM_386:
case EM_IAMCU:
return getX86TargetInfo();
@@ -62,7 +62,7 @@ TargetInfo *elf::getTarget() {
case EM_HEXAGON:
return getHexagonTargetInfo();
case EM_MIPS:
- switch (Config->EKind) {
+ switch (config->ekind) {
case ELF32LEKind:
return getMipsTargetInfo<ELF32LE>();
case ELF32BEKind:
@@ -90,29 +90,29 @@ TargetInfo *elf::getTarget() {
llvm_unreachable("unknown target machine");
}
-template <class ELFT> static ErrorPlace getErrPlace(const uint8_t *Loc) {
- for (InputSectionBase *D : InputSections) {
- auto *IS = cast<InputSection>(D);
- if (!IS->getParent())
+template <class ELFT> static ErrorPlace getErrPlace(const uint8_t *loc) {
+ for (InputSectionBase *d : inputSections) {
+ auto *isec = cast<InputSection>(d);
+ if (!isec->getParent())
continue;
- uint8_t *ISLoc = Out::BufferStart + IS->getParent()->Offset + IS->OutSecOff;
- if (ISLoc <= Loc && Loc < ISLoc + IS->getSize())
- return {IS, IS->template getLocation<ELFT>(Loc - ISLoc) + ": "};
+ uint8_t *isecLoc = Out::bufferStart + isec->getParent()->offset + isec->outSecOff;
+ if (isecLoc <= loc && loc < isecLoc + isec->getSize())
+ return {isec, isec->template getLocation<ELFT>(loc - isecLoc) + ": "};
}
return {};
}
-ErrorPlace elf::getErrorPlace(const uint8_t *Loc) {
- switch (Config->EKind) {
+ErrorPlace elf::getErrorPlace(const uint8_t *loc) {
+ switch (config->ekind) {
case ELF32LEKind:
- return getErrPlace<ELF32LE>(Loc);
+ return getErrPlace<ELF32LE>(loc);
case ELF32BEKind:
- return getErrPlace<ELF32BE>(Loc);
+ return getErrPlace<ELF32BE>(loc);
case ELF64LEKind:
- return getErrPlace<ELF64LE>(Loc);
+ return getErrPlace<ELF64LE>(loc);
case ELF64BEKind:
- return getErrPlace<ELF64BE>(Loc);
+ return getErrPlace<ELF64BE>(loc);
default:
llvm_unreachable("unknown ELF type");
}
@@ -120,62 +120,62 @@ ErrorPlace elf::getErrorPlace(const uint
TargetInfo::~TargetInfo() {}
-int64_t TargetInfo::getImplicitAddend(const uint8_t *Buf, RelType Type) const {
+int64_t TargetInfo::getImplicitAddend(const uint8_t *buf, RelType type) const {
return 0;
}
-bool TargetInfo::usesOnlyLowPageBits(RelType Type) const { return false; }
+bool TargetInfo::usesOnlyLowPageBits(RelType type) const { return false; }
-bool TargetInfo::needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
- uint64_t BranchAddr, const Symbol &S) const {
+bool TargetInfo::needsThunk(RelExpr expr, RelType type, const InputFile *file,
+ uint64_t branchAddr, const Symbol &s) const {
return false;
}
-bool TargetInfo::adjustPrologueForCrossSplitStack(uint8_t *Loc, uint8_t *End,
- uint8_t StOther) const {
+bool TargetInfo::adjustPrologueForCrossSplitStack(uint8_t *loc, uint8_t *end,
+ uint8_t stOther) const {
llvm_unreachable("Target doesn't support split stacks.");
}
-bool TargetInfo::inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const {
+bool TargetInfo::inBranchRange(RelType type, uint64_t src, uint64_t dst) const {
return true;
}
-void TargetInfo::writeIgotPlt(uint8_t *Buf, const Symbol &S) const {
- writeGotPlt(Buf, S);
+void TargetInfo::writeIgotPlt(uint8_t *buf, const Symbol &s) const {
+ writeGotPlt(buf, s);
}
-RelExpr TargetInfo::adjustRelaxExpr(RelType Type, const uint8_t *Data,
- RelExpr Expr) const {
- return Expr;
+RelExpr TargetInfo::adjustRelaxExpr(RelType type, const uint8_t *data,
+ RelExpr expr) const {
+ return expr;
}
-void TargetInfo::relaxGot(uint8_t *Loc, RelType Type, uint64_t Val) const {
+void TargetInfo::relaxGot(uint8_t *loc, RelType type, uint64_t val) const {
llvm_unreachable("Should not have claimed to be relaxable");
}
-void TargetInfo::relaxTlsGdToLe(uint8_t *Loc, RelType Type,
- uint64_t Val) const {
+void TargetInfo::relaxTlsGdToLe(uint8_t *loc, RelType type,
+ uint64_t val) const {
llvm_unreachable("Should not have claimed to be relaxable");
}
-void TargetInfo::relaxTlsGdToIe(uint8_t *Loc, RelType Type,
- uint64_t Val) const {
+void TargetInfo::relaxTlsGdToIe(uint8_t *loc, RelType type,
+ uint64_t val) const {
llvm_unreachable("Should not have claimed to be relaxable");
}
-void TargetInfo::relaxTlsIeToLe(uint8_t *Loc, RelType Type,
- uint64_t Val) const {
+void TargetInfo::relaxTlsIeToLe(uint8_t *loc, RelType type,
+ uint64_t val) const {
llvm_unreachable("Should not have claimed to be relaxable");
}
-void TargetInfo::relaxTlsLdToLe(uint8_t *Loc, RelType Type,
- uint64_t Val) const {
+void TargetInfo::relaxTlsLdToLe(uint8_t *loc, RelType type,
+ uint64_t val) const {
llvm_unreachable("Should not have claimed to be relaxable");
}
uint64_t TargetInfo::getImageBase() const {
// Use -image-base if set. Fall back to the target default if not.
- if (Config->ImageBase)
- return *Config->ImageBase;
- return Config->Pic ? 0 : DefaultImageBase;
+ if (config->imageBase)
+ return *config->imageBase;
+ return config->isPic ? 0 : defaultImageBase;
}
Modified: lld/trunk/ELF/Target.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.h?rev=365595&r1=365594&r2=365595&view=diff
==============================================================================
--- lld/trunk/ELF/Target.h (original)
+++ lld/trunk/ELF/Target.h Tue Jul 9 22:00:37 2019
@@ -16,7 +16,7 @@
#include <array>
namespace lld {
-std::string toString(elf::RelType Type);
+std::string toString(elf::RelType type);
namespace elf {
class Defined;
@@ -26,39 +26,39 @@ class Symbol;
class TargetInfo {
public:
virtual uint32_t calcEFlags() const { return 0; }
- virtual RelExpr getRelExpr(RelType Type, const Symbol &S,
- const uint8_t *Loc) const = 0;
- virtual RelType getDynRel(RelType Type) const { return 0; }
- virtual void writeGotPltHeader(uint8_t *Buf) const {}
- virtual void writeGotHeader(uint8_t *Buf) const {}
- virtual void writeGotPlt(uint8_t *Buf, const Symbol &S) const {};
- virtual void writeIgotPlt(uint8_t *Buf, const Symbol &S) const;
- virtual int64_t getImplicitAddend(const uint8_t *Buf, RelType Type) const;
- virtual int getTlsGdRelaxSkip(RelType Type) const { return 1; }
+ virtual RelExpr getRelExpr(RelType type, const Symbol &s,
+ const uint8_t *loc) const = 0;
+ virtual RelType getDynRel(RelType type) const { return 0; }
+ virtual void writeGotPltHeader(uint8_t *buf) const {}
+ virtual void writeGotHeader(uint8_t *buf) const {}
+ virtual void writeGotPlt(uint8_t *buf, const Symbol &s) const {};
+ virtual void writeIgotPlt(uint8_t *buf, const Symbol &s) const;
+ virtual int64_t getImplicitAddend(const uint8_t *buf, RelType type) const;
+ virtual int getTlsGdRelaxSkip(RelType type) const { return 1; }
// If lazy binding is supported, the first entry of the PLT has code
// to call the dynamic linker to resolve PLT entries the first time
// they are called. This function writes that code.
- virtual void writePltHeader(uint8_t *Buf) const {}
+ virtual void writePltHeader(uint8_t *buf) const {}
- virtual void writePlt(uint8_t *Buf, uint64_t GotEntryAddr,
- uint64_t PltEntryAddr, int32_t Index,
- unsigned RelOff) const {}
- virtual void addPltHeaderSymbols(InputSection &IS) const {}
- virtual void addPltSymbols(InputSection &IS, uint64_t Off) const {}
+ virtual void writePlt(uint8_t *buf, uint64_t gotEntryAddr,
+ uint64_t pltEntryAddr, int32_t index,
+ unsigned relOff) const {}
+ virtual void addPltHeaderSymbols(InputSection &isec) const {}
+ virtual void addPltSymbols(InputSection &isec, uint64_t off) const {}
// Returns true if a relocation only uses the low bits of a value such that
// all those bits are in the same page. For example, if the relocation
// only uses the low 12 bits in a system with 4k pages. If this is true, the
// bits will always have the same value at runtime and we don't have to emit
// a dynamic relocation.
- virtual bool usesOnlyLowPageBits(RelType Type) const;
+ virtual bool usesOnlyLowPageBits(RelType type) const;
// Decide whether a Thunk is needed for the relocation from File
// targeting S.
- virtual bool needsThunk(RelExpr Expr, RelType RelocType,
- const InputFile *File, uint64_t BranchAddr,
- const Symbol &S) const;
+ virtual bool needsThunk(RelExpr expr, RelType relocType,
+ const InputFile *file, uint64_t branchAddr,
+ const Symbol &s) const;
// On systems with range extensions we place collections of Thunks at
// regular spacings that enable the majority of branches reach the Thunks.
@@ -70,71 +70,71 @@ public:
// to do the right thing. See https://gcc.gnu.org/wiki/SplitStacks.
// The symbols st_other flags are needed on PowerPC64 for determining the
// offset to the split-stack prologue.
- virtual bool adjustPrologueForCrossSplitStack(uint8_t *Loc, uint8_t *End,
- uint8_t StOther) const;
+ virtual bool adjustPrologueForCrossSplitStack(uint8_t *loc, uint8_t *end,
+ uint8_t stOther) const;
// Return true if we can reach Dst from Src with Relocation RelocType
- virtual bool inBranchRange(RelType Type, uint64_t Src,
- uint64_t Dst) const;
+ virtual bool inBranchRange(RelType type, uint64_t src,
+ uint64_t dst) const;
- virtual void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const = 0;
+ virtual void relocateOne(uint8_t *loc, RelType type, uint64_t val) const = 0;
virtual ~TargetInfo();
- unsigned DefaultCommonPageSize = 4096;
- unsigned DefaultMaxPageSize = 4096;
+ unsigned defaultCommonPageSize = 4096;
+ unsigned defaultMaxPageSize = 4096;
uint64_t getImageBase() const;
// True if _GLOBAL_OFFSET_TABLE_ is relative to .got.plt, false if .got.
- bool GotBaseSymInGotPlt = true;
+ bool gotBaseSymInGotPlt = true;
- RelType CopyRel;
- RelType GotRel;
- RelType NoneRel;
- RelType PltRel;
- RelType RelativeRel;
- RelType IRelativeRel;
- RelType SymbolicRel;
- RelType TlsDescRel;
- RelType TlsGotRel;
- RelType TlsModuleIndexRel;
- RelType TlsOffsetRel;
- unsigned PltEntrySize;
- unsigned PltHeaderSize;
+ RelType copyRel;
+ RelType gotRel;
+ RelType noneRel;
+ RelType pltRel;
+ RelType relativeRel;
+ RelType iRelativeRel;
+ RelType symbolicRel;
+ RelType tlsDescRel;
+ RelType tlsGotRel;
+ RelType tlsModuleIndexRel;
+ RelType tlsOffsetRel;
+ unsigned pltEntrySize;
+ unsigned pltHeaderSize;
// At least on x86_64 positions 1 and 2 are used by the first plt entry
// to support lazy loading.
- unsigned GotPltHeaderEntriesNum = 3;
+ unsigned gotPltHeaderEntriesNum = 3;
// On PPC ELF V2 abi, the first entry in the .got is the .TOC.
- unsigned GotHeaderEntriesNum = 0;
+ unsigned gotHeaderEntriesNum = 0;
- bool NeedsThunks = false;
+ bool needsThunks = false;
// A 4-byte field corresponding to one or more trap instructions, used to pad
// executable OutputSections.
- std::array<uint8_t, 4> TrapInstr;
+ std::array<uint8_t, 4> trapInstr;
// If a target needs to rewrite calls to __morestack to instead call
// __morestack_non_split when a split-stack enabled caller calls a
// non-split-stack callee this will return true. Otherwise returns false.
- bool NeedsMoreStackNonSplit = true;
+ bool needsMoreStackNonSplit = true;
- virtual RelExpr adjustRelaxExpr(RelType Type, const uint8_t *Data,
- RelExpr Expr) const;
- virtual void relaxGot(uint8_t *Loc, RelType Type, uint64_t Val) const;
- virtual void relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const;
- virtual void relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const;
- virtual void relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const;
- virtual void relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const;
+ virtual RelExpr adjustRelaxExpr(RelType type, const uint8_t *data,
+ RelExpr expr) const;
+ virtual void relaxGot(uint8_t *loc, RelType type, uint64_t val) const;
+ virtual void relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const;
+ virtual void relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const;
+ virtual void relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const;
+ virtual void relaxTlsLdToLe(uint8_t *loc, RelType type, uint64_t val) const;
protected:
// On FreeBSD x86_64 the first page cannot be mmaped.
// On Linux that is controled by vm.mmap_min_addr. At least on some x86_64
// installs that is 65536, so the first 15 pages cannot be used.
// Given that, the smallest value that can be used in here is 0x10000.
- uint64_t DefaultImageBase = 0x10000;
+ uint64_t defaultImageBase = 0x10000;
};
TargetInfo *getAArch64TargetInfo();
@@ -152,22 +152,22 @@ TargetInfo *getX86_64TargetInfo();
template <class ELFT> TargetInfo *getMipsTargetInfo();
struct ErrorPlace {
- InputSectionBase *IS;
- std::string Loc;
+ InputSectionBase *isec;
+ std::string loc;
};
// Returns input section and corresponding source string for the given location.
-ErrorPlace getErrorPlace(const uint8_t *Loc);
+ErrorPlace getErrorPlace(const uint8_t *loc);
-static inline std::string getErrorLocation(const uint8_t *Loc) {
- return getErrorPlace(Loc).Loc;
+static inline std::string getErrorLocation(const uint8_t *loc) {
+ return getErrorPlace(loc).loc;
}
-void writePPC32GlinkSection(uint8_t *Buf, size_t NumEntries);
+void writePPC32GlinkSection(uint8_t *buf, size_t numEntries);
-bool tryRelaxPPC64TocIndirection(RelType Type, const Relocation &Rel,
- uint8_t *BufLoc);
-unsigned getPPCDFormOp(unsigned SecondaryOp);
+bool tryRelaxPPC64TocIndirection(RelType type, const Relocation &rel,
+ uint8_t *bufLoc);
+unsigned getPPCDFormOp(unsigned secondaryOp);
// In the PowerPC64 Elf V2 abi a function can have 2 entry points. The first
// is a global entry point (GEP) which typically is used to initialize the TOC
@@ -176,84 +176,84 @@ unsigned getPPCDFormOp(unsigned Secondar
// offset between GEP and LEP is encoded in a function's st_other flags.
// This function will return the offset (in bytes) from the global entry-point
// to the local entry-point.
-unsigned getPPC64GlobalEntryToLocalEntryOffset(uint8_t StOther);
+unsigned getPPC64GlobalEntryToLocalEntryOffset(uint8_t stOther);
// Returns true if a relocation is a small code model relocation that accesses
// the .toc section.
-bool isPPC64SmallCodeModelTocReloc(RelType Type);
+bool isPPC64SmallCodeModelTocReloc(RelType type);
uint64_t getPPC64TocBase();
-uint64_t getAArch64Page(uint64_t Expr);
+uint64_t getAArch64Page(uint64_t expr);
-extern const TargetInfo *Target;
+extern const TargetInfo *target;
TargetInfo *getTarget();
-template <class ELFT> bool isMipsPIC(const Defined *Sym);
+template <class ELFT> bool isMipsPIC(const Defined *sym);
-static inline void reportRangeError(uint8_t *Loc, RelType Type, const Twine &V,
- int64_t Min, uint64_t Max) {
- ErrorPlace ErrPlace = getErrorPlace(Loc);
- StringRef Hint;
- if (ErrPlace.IS && ErrPlace.IS->Name.startswith(".debug"))
- Hint = "; consider recompiling with -fdebug-types-section to reduce size "
+static inline void reportRangeError(uint8_t *loc, RelType type, const Twine &v,
+ int64_t min, uint64_t max) {
+ ErrorPlace errPlace = getErrorPlace(loc);
+ StringRef hint;
+ if (errPlace.isec && errPlace.isec->name.startswith(".debug"))
+ hint = "; consider recompiling with -fdebug-types-section to reduce size "
"of debug sections";
- errorOrWarn(ErrPlace.Loc + "relocation " + lld::toString(Type) +
- " out of range: " + V.str() + " is not in [" + Twine(Min).str() +
- ", " + Twine(Max).str() + "]" + Hint);
+ errorOrWarn(errPlace.loc + "relocation " + lld::toString(type) +
+ " out of range: " + v.str() + " is not in [" + Twine(min).str() +
+ ", " + Twine(max).str() + "]" + hint);
}
// Make sure that V can be represented as an N bit signed integer.
-inline void checkInt(uint8_t *Loc, int64_t V, int N, RelType Type) {
- if (V != llvm::SignExtend64(V, N))
- reportRangeError(Loc, Type, Twine(V), llvm::minIntN(N), llvm::maxIntN(N));
+inline void checkInt(uint8_t *loc, int64_t v, int n, RelType type) {
+ if (v != llvm::SignExtend64(v, n))
+ reportRangeError(loc, type, Twine(v), llvm::minIntN(n), llvm::maxIntN(n));
}
// Make sure that V can be represented as an N bit unsigned integer.
-inline void checkUInt(uint8_t *Loc, uint64_t V, int N, RelType Type) {
- if ((V >> N) != 0)
- reportRangeError(Loc, Type, Twine(V), 0, llvm::maxUIntN(N));
+inline void checkUInt(uint8_t *loc, uint64_t v, int n, RelType type) {
+ if ((v >> n) != 0)
+ reportRangeError(loc, type, Twine(v), 0, llvm::maxUIntN(n));
}
// Make sure that V can be represented as an N bit signed or unsigned integer.
-inline void checkIntUInt(uint8_t *Loc, uint64_t V, int N, RelType Type) {
+inline void checkIntUInt(uint8_t *loc, uint64_t v, int n, RelType type) {
// For the error message we should cast V to a signed integer so that error
// messages show a small negative value rather than an extremely large one
- if (V != (uint64_t)llvm::SignExtend64(V, N) && (V >> N) != 0)
- reportRangeError(Loc, Type, Twine((int64_t)V), llvm::minIntN(N),
- llvm::maxUIntN(N));
+ if (v != (uint64_t)llvm::SignExtend64(v, n) && (v >> n) != 0)
+ reportRangeError(loc, type, Twine((int64_t)v), llvm::minIntN(n),
+ llvm::maxUIntN(n));
}
-inline void checkAlignment(uint8_t *Loc, uint64_t V, int N, RelType Type) {
- if ((V & (N - 1)) != 0)
- error(getErrorLocation(Loc) + "improper alignment for relocation " +
- lld::toString(Type) + ": 0x" + llvm::utohexstr(V) +
- " is not aligned to " + Twine(N) + " bytes");
+inline void checkAlignment(uint8_t *loc, uint64_t v, int n, RelType type) {
+ if ((v & (n - 1)) != 0)
+ error(getErrorLocation(loc) + "improper alignment for relocation " +
+ lld::toString(type) + ": 0x" + llvm::utohexstr(v) +
+ " is not aligned to " + Twine(n) + " bytes");
}
// Endianness-aware read/write.
-inline uint16_t read16(const void *P) {
- return llvm::support::endian::read16(P, Config->Endianness);
+inline uint16_t read16(const void *p) {
+ return llvm::support::endian::read16(p, config->endianness);
}
-inline uint32_t read32(const void *P) {
- return llvm::support::endian::read32(P, Config->Endianness);
+inline uint32_t read32(const void *p) {
+ return llvm::support::endian::read32(p, config->endianness);
}
-inline uint64_t read64(const void *P) {
- return llvm::support::endian::read64(P, Config->Endianness);
+inline uint64_t read64(const void *p) {
+ return llvm::support::endian::read64(p, config->endianness);
}
-inline void write16(void *P, uint16_t V) {
- llvm::support::endian::write16(P, V, Config->Endianness);
+inline void write16(void *p, uint16_t v) {
+ llvm::support::endian::write16(p, v, config->endianness);
}
-inline void write32(void *P, uint32_t V) {
- llvm::support::endian::write32(P, V, Config->Endianness);
+inline void write32(void *p, uint32_t v) {
+ llvm::support::endian::write32(p, v, config->endianness);
}
-inline void write64(void *P, uint64_t V) {
- llvm::support::endian::write64(P, V, Config->Endianness);
+inline void write64(void *p, uint64_t v) {
+ llvm::support::endian::write64(p, v, config->endianness);
}
} // namespace elf
} // namespace lld
Modified: lld/trunk/ELF/Thunks.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Thunks.cpp?rev=365595&r1=365594&r2=365595&view=diff
==============================================================================
--- lld/trunk/ELF/Thunks.cpp (original)
+++ lld/trunk/ELF/Thunks.cpp Tue Jul 9 22:00:37 2019
@@ -49,18 +49,18 @@ namespace {
// AArch64 long range Thunks
class AArch64ABSLongThunk final : public Thunk {
public:
- AArch64ABSLongThunk(Symbol &Dest) : Thunk(Dest) {}
+ AArch64ABSLongThunk(Symbol &dest) : Thunk(dest) {}
uint32_t size() override { return 16; }
- void writeTo(uint8_t *Buf) override;
- void addSymbols(ThunkSection &IS) override;
+ void writeTo(uint8_t *buf) override;
+ void addSymbols(ThunkSection &isec) override;
};
class AArch64ADRPThunk final : public Thunk {
public:
- AArch64ADRPThunk(Symbol &Dest) : Thunk(Dest) {}
+ AArch64ADRPThunk(Symbol &dest) : Thunk(dest) {}
uint32_t size() override { return 12; }
- void writeTo(uint8_t *Buf) override;
- void addSymbols(ThunkSection &IS) override;
+ void writeTo(uint8_t *buf) override;
+ void addSymbols(ThunkSection &isec) override;
};
// Base class for ARM thunks.
@@ -73,19 +73,19 @@ public:
// if the target is in range, otherwise it creates a long thunk.
class ARMThunk : public Thunk {
public:
- ARMThunk(Symbol &Dest) : Thunk(Dest) {}
+ ARMThunk(Symbol &dest) : Thunk(dest) {}
bool getMayUseShortThunk();
uint32_t size() override { return getMayUseShortThunk() ? 4 : sizeLong(); }
- void writeTo(uint8_t *Buf) override;
- bool isCompatibleWith(const InputSection &IS,
- const Relocation &Rel) const override;
+ void writeTo(uint8_t *buf) override;
+ bool isCompatibleWith(const InputSection &isec,
+ const Relocation &rel) const override;
// Returns the size of a long thunk.
virtual uint32_t sizeLong() = 0;
// Writes a long thunk to Buf.
- virtual void writeLong(uint8_t *Buf) = 0;
+ virtual void writeLong(uint8_t *buf) = 0;
private:
// This field tracks whether all previously considered layouts would allow
@@ -94,7 +94,7 @@ private:
// distance to the target. We do this because transitioning from long to short
// can create layout oscillations in certain corner cases which would prevent
// the layout from converging.
- bool MayUseShortThunk = true;
+ bool mayUseShortThunk = true;
};
// Base class for Thumb-2 thunks.
@@ -103,61 +103,61 @@ private:
// which has a range of 16MB.
class ThumbThunk : public Thunk {
public:
- ThumbThunk(Symbol &Dest) : Thunk(Dest) { Alignment = 2; }
+ ThumbThunk(Symbol &dest) : Thunk(dest) { alignment = 2; }
bool getMayUseShortThunk();
uint32_t size() override { return getMayUseShortThunk() ? 4 : sizeLong(); }
- void writeTo(uint8_t *Buf) override;
- bool isCompatibleWith(const InputSection &IS,
- const Relocation &Rel) const override;
+ void writeTo(uint8_t *buf) override;
+ bool isCompatibleWith(const InputSection &isec,
+ const Relocation &rel) const override;
// Returns the size of a long thunk.
virtual uint32_t sizeLong() = 0;
// Writes a long thunk to Buf.
- virtual void writeLong(uint8_t *Buf) = 0;
+ virtual void writeLong(uint8_t *buf) = 0;
private:
// See comment in ARMThunk above.
- bool MayUseShortThunk = true;
+ bool mayUseShortThunk = true;
};
// Specific ARM Thunk implementations. The naming convention is:
// Source State, TargetState, Target Requirement, ABS or PI, Range
class ARMV7ABSLongThunk final : public ARMThunk {
public:
- ARMV7ABSLongThunk(Symbol &Dest) : ARMThunk(Dest) {}
+ ARMV7ABSLongThunk(Symbol &dest) : ARMThunk(dest) {}
uint32_t sizeLong() override { return 12; }
- void writeLong(uint8_t *Buf) override;
- void addSymbols(ThunkSection &IS) override;
+ void writeLong(uint8_t *buf) override;
+ void addSymbols(ThunkSection &isec) override;
};
class ARMV7PILongThunk final : public ARMThunk {
public:
- ARMV7PILongThunk(Symbol &Dest) : ARMThunk(Dest) {}
+ ARMV7PILongThunk(Symbol &dest) : ARMThunk(dest) {}
uint32_t sizeLong() override { return 16; }
- void writeLong(uint8_t *Buf) override;
- void addSymbols(ThunkSection &IS) override;
+ void writeLong(uint8_t *buf) override;
+ void addSymbols(ThunkSection &isec) override;
};
class ThumbV7ABSLongThunk final : public ThumbThunk {
public:
- ThumbV7ABSLongThunk(Symbol &Dest) : ThumbThunk(Dest) {}
+ ThumbV7ABSLongThunk(Symbol &dest) : ThumbThunk(dest) {}
uint32_t sizeLong() override { return 10; }
- void writeLong(uint8_t *Buf) override;
- void addSymbols(ThunkSection &IS) override;
+ void writeLong(uint8_t *buf) override;
+ void addSymbols(ThunkSection &isec) override;
};
class ThumbV7PILongThunk final : public ThumbThunk {
public:
- ThumbV7PILongThunk(Symbol &Dest) : ThumbThunk(Dest) {}
+ ThumbV7PILongThunk(Symbol &dest) : ThumbThunk(dest) {}
uint32_t sizeLong() override { return 12; }
- void writeLong(uint8_t *Buf) override;
- void addSymbols(ThunkSection &IS) override;
+ void writeLong(uint8_t *buf) override;
+ void addSymbols(ThunkSection &isec) override;
};
// Implementations of Thunks for older Arm architectures that do not support
@@ -167,95 +167,95 @@ public:
// can result in a thunk
class ARMV5ABSLongThunk final : public ARMThunk {
public:
- ARMV5ABSLongThunk(Symbol &Dest) : ARMThunk(Dest) {}
+ ARMV5ABSLongThunk(Symbol &dest) : ARMThunk(dest) {}
uint32_t sizeLong() override { return 8; }
- void writeLong(uint8_t *Buf) override;
- void addSymbols(ThunkSection &IS) override;
- bool isCompatibleWith(const InputSection &IS,
- const Relocation &Rel) const override;
+ void writeLong(uint8_t *buf) override;
+ void addSymbols(ThunkSection &isec) override;
+ bool isCompatibleWith(const InputSection &isec,
+ const Relocation &rel) const override;
};
class ARMV5PILongThunk final : public ARMThunk {
public:
- ARMV5PILongThunk(Symbol &Dest) : ARMThunk(Dest) {}
+ ARMV5PILongThunk(Symbol &dest) : ARMThunk(dest) {}
uint32_t sizeLong() override { return 16; }
- void writeLong(uint8_t *Buf) override;
- void addSymbols(ThunkSection &IS) override;
- bool isCompatibleWith(const InputSection &IS,
- const Relocation &Rel) const override;
+ void writeLong(uint8_t *buf) override;
+ void addSymbols(ThunkSection &isec) override;
+ bool isCompatibleWith(const InputSection &isec,
+ const Relocation &rel) const override;
};
// Implementations of Thunks for Arm v6-M. Only Thumb instructions are permitted
class ThumbV6MABSLongThunk final : public ThumbThunk {
public:
- ThumbV6MABSLongThunk(Symbol &Dest) : ThumbThunk(Dest) {}
+ ThumbV6MABSLongThunk(Symbol &dest) : ThumbThunk(dest) {}
uint32_t sizeLong() override { return 12; }
- void writeLong(uint8_t *Buf) override;
- void addSymbols(ThunkSection &IS) override;
+ void writeLong(uint8_t *buf) override;
+ void addSymbols(ThunkSection &isec) override;
};
class ThumbV6MPILongThunk final : public ThumbThunk {
public:
- ThumbV6MPILongThunk(Symbol &Dest) : ThumbThunk(Dest) {}
+ ThumbV6MPILongThunk(Symbol &dest) : ThumbThunk(dest) {}
uint32_t sizeLong() override { return 16; }
- void writeLong(uint8_t *Buf) override;
- void addSymbols(ThunkSection &IS) override;
+ void writeLong(uint8_t *buf) override;
+ void addSymbols(ThunkSection &isec) override;
};
// MIPS LA25 thunk
class MipsThunk final : public Thunk {
public:
- MipsThunk(Symbol &Dest) : Thunk(Dest) {}
+ MipsThunk(Symbol &dest) : Thunk(dest) {}
uint32_t size() override { return 16; }
- void writeTo(uint8_t *Buf) override;
- void addSymbols(ThunkSection &IS) override;
+ void writeTo(uint8_t *buf) override;
+ void addSymbols(ThunkSection &isec) override;
InputSection *getTargetInputSection() const override;
};
// microMIPS R2-R5 LA25 thunk
class MicroMipsThunk final : public Thunk {
public:
- MicroMipsThunk(Symbol &Dest) : Thunk(Dest) {}
+ MicroMipsThunk(Symbol &dest) : Thunk(dest) {}
uint32_t size() override { return 14; }
- void writeTo(uint8_t *Buf) override;
- void addSymbols(ThunkSection &IS) override;
+ void writeTo(uint8_t *buf) override;
+ void addSymbols(ThunkSection &isec) override;
InputSection *getTargetInputSection() const override;
};
// microMIPS R6 LA25 thunk
class MicroMipsR6Thunk final : public Thunk {
public:
- MicroMipsR6Thunk(Symbol &Dest) : Thunk(Dest) {}
+ MicroMipsR6Thunk(Symbol &dest) : Thunk(dest) {}
uint32_t size() override { return 12; }
- void writeTo(uint8_t *Buf) override;
- void addSymbols(ThunkSection &IS) override;
+ void writeTo(uint8_t *buf) override;
+ void addSymbols(ThunkSection &isec) override;
InputSection *getTargetInputSection() const override;
};
class PPC32PltCallStub final : public Thunk {
public:
- PPC32PltCallStub(const InputSection &IS, const Relocation &Rel, Symbol &Dest)
- : Thunk(Dest), Addend(Rel.Type == R_PPC_PLTREL24 ? Rel.Addend : 0),
- File(IS.File) {}
+ PPC32PltCallStub(const InputSection &isec, const Relocation &rel, Symbol &dest)
+ : Thunk(dest), addend(rel.type == R_PPC_PLTREL24 ? rel.addend : 0),
+ file(isec.file) {}
uint32_t size() override { return 16; }
- void writeTo(uint8_t *Buf) override;
- void addSymbols(ThunkSection &IS) override;
- bool isCompatibleWith(const InputSection &IS, const Relocation &Rel) const override;
+ void writeTo(uint8_t *buf) override;
+ void addSymbols(ThunkSection &isec) override;
+ bool isCompatibleWith(const InputSection &isec, const Relocation &rel) const override;
private:
// For R_PPC_PLTREL24, this records the addend, which will be used to decide
// the offsets in the call stub.
- uint32_t Addend;
+ uint32_t addend;
// Records the call site of the call stub.
- const InputFile *File;
+ const InputFile *file;
};
// PPC64 Plt call stubs.
@@ -268,10 +268,10 @@ private:
// 3) Transfering control to the target function through an indirect branch.
class PPC64PltCallStub final : public Thunk {
public:
- PPC64PltCallStub(Symbol &Dest) : Thunk(Dest) {}
+ PPC64PltCallStub(Symbol &dest) : Thunk(dest) {}
uint32_t size() override { return 20; }
- void writeTo(uint8_t *Buf) override;
- void addSymbols(ThunkSection &IS) override;
+ void writeTo(uint8_t *buf) override;
+ void addSymbols(ThunkSection &isec) override;
};
// A bl instruction uses a signed 24 bit offset, with an implicit 4 byte
@@ -285,75 +285,75 @@ public:
class PPC64LongBranchThunk : public Thunk {
public:
uint32_t size() override { return 16; }
- void writeTo(uint8_t *Buf) override;
- void addSymbols(ThunkSection &IS) override;
+ void writeTo(uint8_t *buf) override;
+ void addSymbols(ThunkSection &isec) override;
protected:
- PPC64LongBranchThunk(Symbol &Dest) : Thunk(Dest) {}
+ PPC64LongBranchThunk(Symbol &dest) : Thunk(dest) {}
};
class PPC64PILongBranchThunk final : public PPC64LongBranchThunk {
public:
- PPC64PILongBranchThunk(Symbol &Dest) : PPC64LongBranchThunk(Dest) {
- assert(!Dest.IsPreemptible);
- if (Dest.isInPPC64Branchlt())
+ PPC64PILongBranchThunk(Symbol &dest) : PPC64LongBranchThunk(dest) {
+ assert(!dest.isPreemptible);
+ if (dest.isInPPC64Branchlt())
return;
- In.PPC64LongBranchTarget->addEntry(Dest);
- Main->RelaDyn->addReloc(
- {Target->RelativeRel, In.PPC64LongBranchTarget,
- Dest.getPPC64LongBranchOffset(), true, &Dest,
- getPPC64GlobalEntryToLocalEntryOffset(Dest.StOther)});
+ in.ppc64LongBranchTarget->addEntry(dest);
+ mainPart->relaDyn->addReloc(
+ {target->relativeRel, in.ppc64LongBranchTarget,
+ dest.getPPC64LongBranchOffset(), true, &dest,
+ getPPC64GlobalEntryToLocalEntryOffset(dest.stOther)});
}
};
class PPC64PDLongBranchThunk final : public PPC64LongBranchThunk {
public:
- PPC64PDLongBranchThunk(Symbol &Dest) : PPC64LongBranchThunk(Dest) {
- if (!Dest.isInPPC64Branchlt())
- In.PPC64LongBranchTarget->addEntry(Dest);
+ PPC64PDLongBranchThunk(Symbol &dest) : PPC64LongBranchThunk(dest) {
+ if (!dest.isInPPC64Branchlt())
+ in.ppc64LongBranchTarget->addEntry(dest);
}
};
} // end anonymous namespace
-Defined *Thunk::addSymbol(StringRef Name, uint8_t Type, uint64_t Value,
- InputSectionBase &Section) {
- Defined *D = addSyntheticLocal(Name, Type, Value, /*Size=*/0, Section);
- Syms.push_back(D);
- return D;
+Defined *Thunk::addSymbol(StringRef name, uint8_t type, uint64_t value,
+ InputSectionBase §ion) {
+ Defined *d = addSyntheticLocal(name, type, value, /*Size=*/0, section);
+ syms.push_back(d);
+ return d;
}
-void Thunk::setOffset(uint64_t NewOffset) {
- for (Defined *D : Syms)
- D->Value = D->Value - Offset + NewOffset;
- Offset = NewOffset;
+void Thunk::setOffset(uint64_t newOffset) {
+ for (Defined *d : syms)
+ d->value = d->value - offset + newOffset;
+ offset = newOffset;
}
// AArch64 long range Thunks
-static uint64_t getAArch64ThunkDestVA(const Symbol &S) {
- uint64_t V = S.isInPlt() ? S.getPltVA() : S.getVA();
- return V;
+static uint64_t getAArch64ThunkDestVA(const Symbol &s) {
+ uint64_t v = s.isInPlt() ? s.getPltVA() : s.getVA();
+ return v;
}
-void AArch64ABSLongThunk::writeTo(uint8_t *Buf) {
- const uint8_t Data[] = {
+void AArch64ABSLongThunk::writeTo(uint8_t *buf) {
+ const uint8_t data[] = {
0x50, 0x00, 0x00, 0x58, // ldr x16, L0
0x00, 0x02, 0x1f, 0xd6, // br x16
0x00, 0x00, 0x00, 0x00, // L0: .xword S
0x00, 0x00, 0x00, 0x00,
};
- uint64_t S = getAArch64ThunkDestVA(Destination);
- memcpy(Buf, Data, sizeof(Data));
- Target->relocateOne(Buf + 8, R_AARCH64_ABS64, S);
+ uint64_t s = getAArch64ThunkDestVA(destination);
+ memcpy(buf, data, sizeof(data));
+ target->relocateOne(buf + 8, R_AARCH64_ABS64, s);
}
-void AArch64ABSLongThunk::addSymbols(ThunkSection &IS) {
- addSymbol(Saver.save("__AArch64AbsLongThunk_" + Destination.getName()),
- STT_FUNC, 0, IS);
- addSymbol("$x", STT_NOTYPE, 0, IS);
- addSymbol("$d", STT_NOTYPE, 8, IS);
+void AArch64ABSLongThunk::addSymbols(ThunkSection &isec) {
+ addSymbol(Saver.save("__AArch64AbsLongThunk_" + destination.getName()),
+ STT_FUNC, 0, isec);
+ addSymbol("$x", STT_NOTYPE, 0, isec);
+ addSymbol("$d", STT_NOTYPE, 8, isec);
}
// This Thunk has a maximum range of 4Gb, this is sufficient for all programs
@@ -361,263 +361,263 @@ void AArch64ABSLongThunk::addSymbols(Thu
// clang and gcc do not support the large code model for position independent
// code so it is safe to use this for position independent thunks without
// worrying about the destination being more than 4Gb away.
-void AArch64ADRPThunk::writeTo(uint8_t *Buf) {
- const uint8_t Data[] = {
+void AArch64ADRPThunk::writeTo(uint8_t *buf) {
+ const uint8_t data[] = {
0x10, 0x00, 0x00, 0x90, // adrp x16, Dest R_AARCH64_ADR_PREL_PG_HI21(Dest)
0x10, 0x02, 0x00, 0x91, // add x16, x16, R_AARCH64_ADD_ABS_LO12_NC(Dest)
0x00, 0x02, 0x1f, 0xd6, // br x16
};
- uint64_t S = getAArch64ThunkDestVA(Destination);
- uint64_t P = getThunkTargetSym()->getVA();
- memcpy(Buf, Data, sizeof(Data));
- Target->relocateOne(Buf, R_AARCH64_ADR_PREL_PG_HI21,
- getAArch64Page(S) - getAArch64Page(P));
- Target->relocateOne(Buf + 4, R_AARCH64_ADD_ABS_LO12_NC, S);
+ uint64_t s = getAArch64ThunkDestVA(destination);
+ uint64_t p = getThunkTargetSym()->getVA();
+ memcpy(buf, data, sizeof(data));
+ target->relocateOne(buf, R_AARCH64_ADR_PREL_PG_HI21,
+ getAArch64Page(s) - getAArch64Page(p));
+ target->relocateOne(buf + 4, R_AARCH64_ADD_ABS_LO12_NC, s);
}
-void AArch64ADRPThunk::addSymbols(ThunkSection &IS) {
- addSymbol(Saver.save("__AArch64ADRPThunk_" + Destination.getName()), STT_FUNC,
- 0, IS);
- addSymbol("$x", STT_NOTYPE, 0, IS);
+void AArch64ADRPThunk::addSymbols(ThunkSection &isec) {
+ addSymbol(Saver.save("__AArch64ADRPThunk_" + destination.getName()), STT_FUNC,
+ 0, isec);
+ addSymbol("$x", STT_NOTYPE, 0, isec);
}
// ARM Target Thunks
-static uint64_t getARMThunkDestVA(const Symbol &S) {
- uint64_t V = S.isInPlt() ? S.getPltVA() : S.getVA();
- return SignExtend64<32>(V);
+static uint64_t getARMThunkDestVA(const Symbol &s) {
+ uint64_t v = s.isInPlt() ? s.getPltVA() : s.getVA();
+ return SignExtend64<32>(v);
}
// This function returns true if the target is not Thumb and is within 2^26, and
// it has not previously returned false (see comment for MayUseShortThunk).
bool ARMThunk::getMayUseShortThunk() {
- if (!MayUseShortThunk)
+ if (!mayUseShortThunk)
return false;
- uint64_t S = getARMThunkDestVA(Destination);
- if (S & 1) {
- MayUseShortThunk = false;
+ uint64_t s = getARMThunkDestVA(destination);
+ if (s & 1) {
+ mayUseShortThunk = false;
return false;
}
- uint64_t P = getThunkTargetSym()->getVA();
- int64_t Offset = S - P - 8;
- MayUseShortThunk = llvm::isInt<26>(Offset);
- return MayUseShortThunk;
+ uint64_t p = getThunkTargetSym()->getVA();
+ int64_t offset = s - p - 8;
+ mayUseShortThunk = llvm::isInt<26>(offset);
+ return mayUseShortThunk;
}
-void ARMThunk::writeTo(uint8_t *Buf) {
+void ARMThunk::writeTo(uint8_t *buf) {
if (!getMayUseShortThunk()) {
- writeLong(Buf);
+ writeLong(buf);
return;
}
- uint64_t S = getARMThunkDestVA(Destination);
- uint64_t P = getThunkTargetSym()->getVA();
- int64_t Offset = S - P - 8;
- const uint8_t Data[] = {
+ uint64_t s = getARMThunkDestVA(destination);
+ uint64_t p = getThunkTargetSym()->getVA();
+ int64_t offset = s - p - 8;
+ const uint8_t data[] = {
0x00, 0x00, 0x00, 0xea, // b S
};
- memcpy(Buf, Data, sizeof(Data));
- Target->relocateOne(Buf, R_ARM_JUMP24, Offset);
+ memcpy(buf, data, sizeof(data));
+ target->relocateOne(buf, R_ARM_JUMP24, offset);
}
-bool ARMThunk::isCompatibleWith(const InputSection &IS,
- const Relocation &Rel) const {
+bool ARMThunk::isCompatibleWith(const InputSection &isec,
+ const Relocation &rel) const {
// Thumb branch relocations can't use BLX
- return Rel.Type != R_ARM_THM_JUMP19 && Rel.Type != R_ARM_THM_JUMP24;
+ return rel.type != R_ARM_THM_JUMP19 && rel.type != R_ARM_THM_JUMP24;
}
// This function returns true if the target is Thumb and is within 2^25, and
// it has not previously returned false (see comment for MayUseShortThunk).
bool ThumbThunk::getMayUseShortThunk() {
- if (!MayUseShortThunk)
+ if (!mayUseShortThunk)
return false;
- uint64_t S = getARMThunkDestVA(Destination);
- if ((S & 1) == 0) {
- MayUseShortThunk = false;
+ uint64_t s = getARMThunkDestVA(destination);
+ if ((s & 1) == 0) {
+ mayUseShortThunk = false;
return false;
}
- uint64_t P = getThunkTargetSym()->getVA() & ~1;
- int64_t Offset = S - P - 4;
- MayUseShortThunk = llvm::isInt<25>(Offset);
- return MayUseShortThunk;
+ uint64_t p = getThunkTargetSym()->getVA() & ~1;
+ int64_t offset = s - p - 4;
+ mayUseShortThunk = llvm::isInt<25>(offset);
+ return mayUseShortThunk;
}
-void ThumbThunk::writeTo(uint8_t *Buf) {
+void ThumbThunk::writeTo(uint8_t *buf) {
if (!getMayUseShortThunk()) {
- writeLong(Buf);
+ writeLong(buf);
return;
}
- uint64_t S = getARMThunkDestVA(Destination);
- uint64_t P = getThunkTargetSym()->getVA();
- int64_t Offset = S - P - 4;
- const uint8_t Data[] = {
+ uint64_t s = getARMThunkDestVA(destination);
+ uint64_t p = getThunkTargetSym()->getVA();
+ int64_t offset = s - p - 4;
+ const uint8_t data[] = {
0x00, 0xf0, 0x00, 0xb0, // b.w S
};
- memcpy(Buf, Data, sizeof(Data));
- Target->relocateOne(Buf, R_ARM_THM_JUMP24, Offset);
+ memcpy(buf, data, sizeof(data));
+ target->relocateOne(buf, R_ARM_THM_JUMP24, offset);
}
-bool ThumbThunk::isCompatibleWith(const InputSection &IS,
- const Relocation &Rel) const {
+bool ThumbThunk::isCompatibleWith(const InputSection &isec,
+ const Relocation &rel) const {
// ARM branch relocations can't use BLX
- return Rel.Type != R_ARM_JUMP24 && Rel.Type != R_ARM_PC24 && Rel.Type != R_ARM_PLT32;
+ return rel.type != R_ARM_JUMP24 && rel.type != R_ARM_PC24 && rel.type != R_ARM_PLT32;
}
-void ARMV7ABSLongThunk::writeLong(uint8_t *Buf) {
- const uint8_t Data[] = {
+void ARMV7ABSLongThunk::writeLong(uint8_t *buf) {
+ const uint8_t data[] = {
0x00, 0xc0, 0x00, 0xe3, // movw ip,:lower16:S
0x00, 0xc0, 0x40, 0xe3, // movt ip,:upper16:S
0x1c, 0xff, 0x2f, 0xe1, // bx ip
};
- uint64_t S = getARMThunkDestVA(Destination);
- memcpy(Buf, Data, sizeof(Data));
- Target->relocateOne(Buf, R_ARM_MOVW_ABS_NC, S);
- Target->relocateOne(Buf + 4, R_ARM_MOVT_ABS, S);
+ uint64_t s = getARMThunkDestVA(destination);
+ memcpy(buf, data, sizeof(data));
+ target->relocateOne(buf, R_ARM_MOVW_ABS_NC, s);
+ target->relocateOne(buf + 4, R_ARM_MOVT_ABS, s);
}
-void ARMV7ABSLongThunk::addSymbols(ThunkSection &IS) {
- addSymbol(Saver.save("__ARMv7ABSLongThunk_" + Destination.getName()),
- STT_FUNC, 0, IS);
- addSymbol("$a", STT_NOTYPE, 0, IS);
+void ARMV7ABSLongThunk::addSymbols(ThunkSection &isec) {
+ addSymbol(Saver.save("__ARMv7ABSLongThunk_" + destination.getName()),
+ STT_FUNC, 0, isec);
+ addSymbol("$a", STT_NOTYPE, 0, isec);
}
-void ThumbV7ABSLongThunk::writeLong(uint8_t *Buf) {
- const uint8_t Data[] = {
+void ThumbV7ABSLongThunk::writeLong(uint8_t *buf) {
+ const uint8_t data[] = {
0x40, 0xf2, 0x00, 0x0c, // movw ip, :lower16:S
0xc0, 0xf2, 0x00, 0x0c, // movt ip, :upper16:S
0x60, 0x47, // bx ip
};
- uint64_t S = getARMThunkDestVA(Destination);
- memcpy(Buf, Data, sizeof(Data));
- Target->relocateOne(Buf, R_ARM_THM_MOVW_ABS_NC, S);
- Target->relocateOne(Buf + 4, R_ARM_THM_MOVT_ABS, S);
+ uint64_t s = getARMThunkDestVA(destination);
+ memcpy(buf, data, sizeof(data));
+ target->relocateOne(buf, R_ARM_THM_MOVW_ABS_NC, s);
+ target->relocateOne(buf + 4, R_ARM_THM_MOVT_ABS, s);
}
-void ThumbV7ABSLongThunk::addSymbols(ThunkSection &IS) {
- addSymbol(Saver.save("__Thumbv7ABSLongThunk_" + Destination.getName()),
- STT_FUNC, 1, IS);
- addSymbol("$t", STT_NOTYPE, 0, IS);
+void ThumbV7ABSLongThunk::addSymbols(ThunkSection &isec) {
+ addSymbol(Saver.save("__Thumbv7ABSLongThunk_" + destination.getName()),
+ STT_FUNC, 1, isec);
+ addSymbol("$t", STT_NOTYPE, 0, isec);
}
-void ARMV7PILongThunk::writeLong(uint8_t *Buf) {
- const uint8_t Data[] = {
+void ARMV7PILongThunk::writeLong(uint8_t *buf) {
+ const uint8_t data[] = {
0xf0, 0xcf, 0x0f, 0xe3, // P: movw ip,:lower16:S - (P + (L1-P) + 8)
0x00, 0xc0, 0x40, 0xe3, // movt ip,:upper16:S - (P + (L1-P) + 8)
0x0f, 0xc0, 0x8c, 0xe0, // L1: add ip, ip, pc
0x1c, 0xff, 0x2f, 0xe1, // bx ip
};
- uint64_t S = getARMThunkDestVA(Destination);
- uint64_t P = getThunkTargetSym()->getVA();
- int64_t Offset = S - P - 16;
- memcpy(Buf, Data, sizeof(Data));
- Target->relocateOne(Buf, R_ARM_MOVW_PREL_NC, Offset);
- Target->relocateOne(Buf + 4, R_ARM_MOVT_PREL, Offset);
-}
-
-void ARMV7PILongThunk::addSymbols(ThunkSection &IS) {
- addSymbol(Saver.save("__ARMV7PILongThunk_" + Destination.getName()), STT_FUNC,
- 0, IS);
- addSymbol("$a", STT_NOTYPE, 0, IS);
+ uint64_t s = getARMThunkDestVA(destination);
+ uint64_t p = getThunkTargetSym()->getVA();
+ int64_t offset = s - p - 16;
+ memcpy(buf, data, sizeof(data));
+ target->relocateOne(buf, R_ARM_MOVW_PREL_NC, offset);
+ target->relocateOne(buf + 4, R_ARM_MOVT_PREL, offset);
+}
+
+void ARMV7PILongThunk::addSymbols(ThunkSection &isec) {
+ addSymbol(Saver.save("__ARMV7PILongThunk_" + destination.getName()), STT_FUNC,
+ 0, isec);
+ addSymbol("$a", STT_NOTYPE, 0, isec);
}
-void ThumbV7PILongThunk::writeLong(uint8_t *Buf) {
- const uint8_t Data[] = {
+void ThumbV7PILongThunk::writeLong(uint8_t *buf) {
+ const uint8_t data[] = {
0x4f, 0xf6, 0xf4, 0x7c, // P: movw ip,:lower16:S - (P + (L1-P) + 4)
0xc0, 0xf2, 0x00, 0x0c, // movt ip,:upper16:S - (P + (L1-P) + 4)
0xfc, 0x44, // L1: add ip, pc
0x60, 0x47, // bx ip
};
- uint64_t S = getARMThunkDestVA(Destination);
- uint64_t P = getThunkTargetSym()->getVA() & ~0x1;
- int64_t Offset = S - P - 12;
- memcpy(Buf, Data, sizeof(Data));
- Target->relocateOne(Buf, R_ARM_THM_MOVW_PREL_NC, Offset);
- Target->relocateOne(Buf + 4, R_ARM_THM_MOVT_PREL, Offset);
-}
-
-void ThumbV7PILongThunk::addSymbols(ThunkSection &IS) {
- addSymbol(Saver.save("__ThumbV7PILongThunk_" + Destination.getName()),
- STT_FUNC, 1, IS);
- addSymbol("$t", STT_NOTYPE, 0, IS);
+ uint64_t s = getARMThunkDestVA(destination);
+ uint64_t p = getThunkTargetSym()->getVA() & ~0x1;
+ int64_t offset = s - p - 12;
+ memcpy(buf, data, sizeof(data));
+ target->relocateOne(buf, R_ARM_THM_MOVW_PREL_NC, offset);
+ target->relocateOne(buf + 4, R_ARM_THM_MOVT_PREL, offset);
+}
+
+void ThumbV7PILongThunk::addSymbols(ThunkSection &isec) {
+ addSymbol(Saver.save("__ThumbV7PILongThunk_" + destination.getName()),
+ STT_FUNC, 1, isec);
+ addSymbol("$t", STT_NOTYPE, 0, isec);
}
-void ARMV5ABSLongThunk::writeLong(uint8_t *Buf) {
- const uint8_t Data[] = {
+void ARMV5ABSLongThunk::writeLong(uint8_t *buf) {
+ const uint8_t data[] = {
0x04, 0xf0, 0x1f, 0xe5, // ldr pc, [pc,#-4] ; L1
0x00, 0x00, 0x00, 0x00, // L1: .word S
};
- memcpy(Buf, Data, sizeof(Data));
- Target->relocateOne(Buf + 4, R_ARM_ABS32, getARMThunkDestVA(Destination));
+ memcpy(buf, data, sizeof(data));
+ target->relocateOne(buf + 4, R_ARM_ABS32, getARMThunkDestVA(destination));
}
-void ARMV5ABSLongThunk::addSymbols(ThunkSection &IS) {
- addSymbol(Saver.save("__ARMv5ABSLongThunk_" + Destination.getName()),
- STT_FUNC, 0, IS);
- addSymbol("$a", STT_NOTYPE, 0, IS);
- addSymbol("$d", STT_NOTYPE, 4, IS);
+void ARMV5ABSLongThunk::addSymbols(ThunkSection &isec) {
+ addSymbol(Saver.save("__ARMv5ABSLongThunk_" + destination.getName()),
+ STT_FUNC, 0, isec);
+ addSymbol("$a", STT_NOTYPE, 0, isec);
+ addSymbol("$d", STT_NOTYPE, 4, isec);
}
-bool ARMV5ABSLongThunk::isCompatibleWith(const InputSection &IS,
- const Relocation &Rel) const {
+bool ARMV5ABSLongThunk::isCompatibleWith(const InputSection &isec,
+ const Relocation &rel) const {
// Thumb branch relocations can't use BLX
- return Rel.Type != R_ARM_THM_JUMP19 && Rel.Type != R_ARM_THM_JUMP24;
+ return rel.type != R_ARM_THM_JUMP19 && rel.type != R_ARM_THM_JUMP24;
}
-void ARMV5PILongThunk::writeLong(uint8_t *Buf) {
- const uint8_t Data[] = {
+void ARMV5PILongThunk::writeLong(uint8_t *buf) {
+ const uint8_t data[] = {
0x04, 0xc0, 0x9f, 0xe5, // P: ldr ip, [pc,#4] ; L2
0x0c, 0xc0, 0x8f, 0xe0, // L1: add ip, pc, ip
0x1c, 0xff, 0x2f, 0xe1, // bx ip
0x00, 0x00, 0x00, 0x00, // L2: .word S - (P + (L1 - P) + 8)
};
- uint64_t S = getARMThunkDestVA(Destination);
- uint64_t P = getThunkTargetSym()->getVA() & ~0x1;
- memcpy(Buf, Data, sizeof(Data));
- Target->relocateOne(Buf + 12, R_ARM_REL32, S - P - 12);
+ uint64_t s = getARMThunkDestVA(destination);
+ uint64_t p = getThunkTargetSym()->getVA() & ~0x1;
+ memcpy(buf, data, sizeof(data));
+ target->relocateOne(buf + 12, R_ARM_REL32, s - p - 12);
}
-void ARMV5PILongThunk::addSymbols(ThunkSection &IS) {
- addSymbol(Saver.save("__ARMV5PILongThunk_" + Destination.getName()), STT_FUNC,
- 0, IS);
- addSymbol("$a", STT_NOTYPE, 0, IS);
- addSymbol("$d", STT_NOTYPE, 12, IS);
+void ARMV5PILongThunk::addSymbols(ThunkSection &isec) {
+ addSymbol(Saver.save("__ARMV5PILongThunk_" + destination.getName()), STT_FUNC,
+ 0, isec);
+ addSymbol("$a", STT_NOTYPE, 0, isec);
+ addSymbol("$d", STT_NOTYPE, 12, isec);
}
-bool ARMV5PILongThunk::isCompatibleWith(const InputSection &IS,
- const Relocation &Rel) const {
+bool ARMV5PILongThunk::isCompatibleWith(const InputSection &isec,
+ const Relocation &rel) const {
// Thumb branch relocations can't use BLX
- return Rel.Type != R_ARM_THM_JUMP19 && Rel.Type != R_ARM_THM_JUMP24;
+ return rel.type != R_ARM_THM_JUMP19 && rel.type != R_ARM_THM_JUMP24;
}
-void ThumbV6MABSLongThunk::writeLong(uint8_t *Buf) {
+void ThumbV6MABSLongThunk::writeLong(uint8_t *buf) {
// Most Thumb instructions cannot access the high registers r8 - r15. As the
// only register we can corrupt is r12 we must instead spill a low register
// to the stack to use as a scratch register. We push r1 even though we
// don't need to get some space to use for the return address.
- const uint8_t Data[] = {
+ const uint8_t data[] = {
0x03, 0xb4, // push {r0, r1} ; Obtain scratch registers
0x01, 0x48, // ldr r0, [pc, #4] ; L1
0x01, 0x90, // str r0, [sp, #4] ; SP + 4 = S
0x01, 0xbd, // pop {r0, pc} ; restore r0 and branch to dest
0x00, 0x00, 0x00, 0x00 // L1: .word S
};
- uint64_t S = getARMThunkDestVA(Destination);
- memcpy(Buf, Data, sizeof(Data));
- Target->relocateOne(Buf + 8, R_ARM_ABS32, S);
+ uint64_t s = getARMThunkDestVA(destination);
+ memcpy(buf, data, sizeof(data));
+ target->relocateOne(buf + 8, R_ARM_ABS32, s);
}
-void ThumbV6MABSLongThunk::addSymbols(ThunkSection &IS) {
- addSymbol(Saver.save("__Thumbv6MABSLongThunk_" + Destination.getName()),
- STT_FUNC, 1, IS);
- addSymbol("$t", STT_NOTYPE, 0, IS);
- addSymbol("$d", STT_NOTYPE, 8, IS);
+void ThumbV6MABSLongThunk::addSymbols(ThunkSection &isec) {
+ addSymbol(Saver.save("__Thumbv6MABSLongThunk_" + destination.getName()),
+ STT_FUNC, 1, isec);
+ addSymbol("$t", STT_NOTYPE, 0, isec);
+ addSymbol("$d", STT_NOTYPE, 8, isec);
}
-void ThumbV6MPILongThunk::writeLong(uint8_t *Buf) {
+void ThumbV6MPILongThunk::writeLong(uint8_t *buf) {
// Most Thumb instructions cannot access the high registers r8 - r15. As the
// only register we can corrupt is ip (r12) we must instead spill a low
// register to the stack to use as a scratch register.
- const uint8_t Data[] = {
+ const uint8_t data[] = {
0x01, 0xb4, // P: push {r0} ; Obtain scratch register
0x02, 0x48, // ldr r0, [pc, #8] ; L2
0x84, 0x46, // mov ip, r0 ; high to low register
@@ -626,185 +626,185 @@ void ThumbV6MPILongThunk::writeLong(uint
0xc0, 0x46, // nop ; pad to 4-byte boundary
0x00, 0x00, 0x00, 0x00, // L2: .word S - (P + (L1 - P) + 4)
};
- uint64_t S = getARMThunkDestVA(Destination);
- uint64_t P = getThunkTargetSym()->getVA() & ~0x1;
- memcpy(Buf, Data, sizeof(Data));
- Target->relocateOne(Buf + 12, R_ARM_REL32, S - P - 12);
+ uint64_t s = getARMThunkDestVA(destination);
+ uint64_t p = getThunkTargetSym()->getVA() & ~0x1;
+ memcpy(buf, data, sizeof(data));
+ target->relocateOne(buf + 12, R_ARM_REL32, s - p - 12);
}
-void ThumbV6MPILongThunk::addSymbols(ThunkSection &IS) {
- addSymbol(Saver.save("__Thumbv6MPILongThunk_" + Destination.getName()),
- STT_FUNC, 1, IS);
- addSymbol("$t", STT_NOTYPE, 0, IS);
- addSymbol("$d", STT_NOTYPE, 12, IS);
+void ThumbV6MPILongThunk::addSymbols(ThunkSection &isec) {
+ addSymbol(Saver.save("__Thumbv6MPILongThunk_" + destination.getName()),
+ STT_FUNC, 1, isec);
+ addSymbol("$t", STT_NOTYPE, 0, isec);
+ addSymbol("$d", STT_NOTYPE, 12, isec);
}
// Write MIPS LA25 thunk code to call PIC function from the non-PIC one.
-void MipsThunk::writeTo(uint8_t *Buf) {
- uint64_t S = Destination.getVA();
- write32(Buf, 0x3c190000); // lui $25, %hi(func)
- write32(Buf + 4, 0x08000000 | (S >> 2)); // j func
- write32(Buf + 8, 0x27390000); // addiu $25, $25, %lo(func)
- write32(Buf + 12, 0x00000000); // nop
- Target->relocateOne(Buf, R_MIPS_HI16, S);
- Target->relocateOne(Buf + 8, R_MIPS_LO16, S);
+void MipsThunk::writeTo(uint8_t *buf) {
+ uint64_t s = destination.getVA();
+ write32(buf, 0x3c190000); // lui $25, %hi(func)
+ write32(buf + 4, 0x08000000 | (s >> 2)); // j func
+ write32(buf + 8, 0x27390000); // addiu $25, $25, %lo(func)
+ write32(buf + 12, 0x00000000); // nop
+ target->relocateOne(buf, R_MIPS_HI16, s);
+ target->relocateOne(buf + 8, R_MIPS_LO16, s);
}
-void MipsThunk::addSymbols(ThunkSection &IS) {
- addSymbol(Saver.save("__LA25Thunk_" + Destination.getName()), STT_FUNC, 0,
- IS);
+void MipsThunk::addSymbols(ThunkSection &isec) {
+ addSymbol(Saver.save("__LA25Thunk_" + destination.getName()), STT_FUNC, 0,
+ isec);
}
InputSection *MipsThunk::getTargetInputSection() const {
- auto &DR = cast<Defined>(Destination);
- return dyn_cast<InputSection>(DR.Section);
+ auto &dr = cast<Defined>(destination);
+ return dyn_cast<InputSection>(dr.section);
}
// Write microMIPS R2-R5 LA25 thunk code
// to call PIC function from the non-PIC one.
-void MicroMipsThunk::writeTo(uint8_t *Buf) {
- uint64_t S = Destination.getVA();
- write16(Buf, 0x41b9); // lui $25, %hi(func)
- write16(Buf + 4, 0xd400); // j func
- write16(Buf + 8, 0x3339); // addiu $25, $25, %lo(func)
- write16(Buf + 12, 0x0c00); // nop
- Target->relocateOne(Buf, R_MICROMIPS_HI16, S);
- Target->relocateOne(Buf + 4, R_MICROMIPS_26_S1, S);
- Target->relocateOne(Buf + 8, R_MICROMIPS_LO16, S);
+void MicroMipsThunk::writeTo(uint8_t *buf) {
+ uint64_t s = destination.getVA();
+ write16(buf, 0x41b9); // lui $25, %hi(func)
+ write16(buf + 4, 0xd400); // j func
+ write16(buf + 8, 0x3339); // addiu $25, $25, %lo(func)
+ write16(buf + 12, 0x0c00); // nop
+ target->relocateOne(buf, R_MICROMIPS_HI16, s);
+ target->relocateOne(buf + 4, R_MICROMIPS_26_S1, s);
+ target->relocateOne(buf + 8, R_MICROMIPS_LO16, s);
}
-void MicroMipsThunk::addSymbols(ThunkSection &IS) {
- Defined *D = addSymbol(
- Saver.save("__microLA25Thunk_" + Destination.getName()), STT_FUNC, 0, IS);
- D->StOther |= STO_MIPS_MICROMIPS;
+void MicroMipsThunk::addSymbols(ThunkSection &isec) {
+ Defined *d = addSymbol(
+ Saver.save("__microLA25Thunk_" + destination.getName()), STT_FUNC, 0, isec);
+ d->stOther |= STO_MIPS_MICROMIPS;
}
InputSection *MicroMipsThunk::getTargetInputSection() const {
- auto &DR = cast<Defined>(Destination);
- return dyn_cast<InputSection>(DR.Section);
+ auto &dr = cast<Defined>(destination);
+ return dyn_cast<InputSection>(dr.section);
}
// Write microMIPS R6 LA25 thunk code
// to call PIC function from the non-PIC one.
-void MicroMipsR6Thunk::writeTo(uint8_t *Buf) {
- uint64_t S = Destination.getVA();
- uint64_t P = getThunkTargetSym()->getVA();
- write16(Buf, 0x1320); // lui $25, %hi(func)
- write16(Buf + 4, 0x3339); // addiu $25, $25, %lo(func)
- write16(Buf + 8, 0x9400); // bc func
- Target->relocateOne(Buf, R_MICROMIPS_HI16, S);
- Target->relocateOne(Buf + 4, R_MICROMIPS_LO16, S);
- Target->relocateOne(Buf + 8, R_MICROMIPS_PC26_S1, S - P - 12);
+void MicroMipsR6Thunk::writeTo(uint8_t *buf) {
+ uint64_t s = destination.getVA();
+ uint64_t p = getThunkTargetSym()->getVA();
+ write16(buf, 0x1320); // lui $25, %hi(func)
+ write16(buf + 4, 0x3339); // addiu $25, $25, %lo(func)
+ write16(buf + 8, 0x9400); // bc func
+ target->relocateOne(buf, R_MICROMIPS_HI16, s);
+ target->relocateOne(buf + 4, R_MICROMIPS_LO16, s);
+ target->relocateOne(buf + 8, R_MICROMIPS_PC26_S1, s - p - 12);
}
-void MicroMipsR6Thunk::addSymbols(ThunkSection &IS) {
- Defined *D = addSymbol(
- Saver.save("__microLA25Thunk_" + Destination.getName()), STT_FUNC, 0, IS);
- D->StOther |= STO_MIPS_MICROMIPS;
+void MicroMipsR6Thunk::addSymbols(ThunkSection &isec) {
+ Defined *d = addSymbol(
+ Saver.save("__microLA25Thunk_" + destination.getName()), STT_FUNC, 0, isec);
+ d->stOther |= STO_MIPS_MICROMIPS;
}
InputSection *MicroMipsR6Thunk::getTargetInputSection() const {
- auto &DR = cast<Defined>(Destination);
- return dyn_cast<InputSection>(DR.Section);
+ auto &dr = cast<Defined>(destination);
+ return dyn_cast<InputSection>(dr.section);
}
-void PPC32PltCallStub::writeTo(uint8_t *Buf) {
- if (!Config->Pic) {
- uint64_t VA = Destination.getGotPltVA();
- write32(Buf + 0, 0x3d600000 | (VA + 0x8000) >> 16); // lis r11,ha
- write32(Buf + 4, 0x816b0000 | (uint16_t)VA); // lwz r11,l(r11)
- write32(Buf + 8, 0x7d6903a6); // mtctr r11
- write32(Buf + 12, 0x4e800420); // bctr
+void PPC32PltCallStub::writeTo(uint8_t *buf) {
+ if (!config->isPic) {
+ uint64_t va = destination.getGotPltVA();
+ write32(buf + 0, 0x3d600000 | (va + 0x8000) >> 16); // lis r11,ha
+ write32(buf + 4, 0x816b0000 | (uint16_t)va); // lwz r11,l(r11)
+ write32(buf + 8, 0x7d6903a6); // mtctr r11
+ write32(buf + 12, 0x4e800420); // bctr
return;
}
- uint32_t Offset;
- if (Addend >= 0x8000) {
+ uint32_t offset;
+ if (addend >= 0x8000) {
// The stub loads an address relative to r30 (.got2+Addend). Addend is
// almost always 0x8000. The address of .got2 is different in another object
// file, so a stub cannot be shared.
- Offset = Destination.getGotPltVA() - (In.PPC32Got2->getParent()->getVA() +
- File->PPC32Got2OutSecOff + Addend);
+ offset = destination.getGotPltVA() - (in.ppc32Got2->getParent()->getVA() +
+ file->ppc32Got2OutSecOff + addend);
} else {
// The stub loads an address relative to _GLOBAL_OFFSET_TABLE_ (which is
// currently the address of .got).
- Offset = Destination.getGotPltVA() - In.Got->getVA();
+ offset = destination.getGotPltVA() - in.got->getVA();
}
- uint16_t HA = (Offset + 0x8000) >> 16, L = (uint16_t)Offset;
- if (HA == 0) {
- write32(Buf + 0, 0x817e0000 | L); // lwz r11,l(r30)
- write32(Buf + 4, 0x7d6903a6); // mtctr r11
- write32(Buf + 8, 0x4e800420); // bctr
- write32(Buf + 12, 0x60000000); // nop
+ uint16_t ha = (offset + 0x8000) >> 16, l = (uint16_t)offset;
+ if (ha == 0) {
+ write32(buf + 0, 0x817e0000 | l); // lwz r11,l(r30)
+ write32(buf + 4, 0x7d6903a6); // mtctr r11
+ write32(buf + 8, 0x4e800420); // bctr
+ write32(buf + 12, 0x60000000); // nop
} else {
- write32(Buf + 0, 0x3d7e0000 | HA); // addis r11,r30,ha
- write32(Buf + 4, 0x816b0000 | L); // lwz r11,l(r11)
- write32(Buf + 8, 0x7d6903a6); // mtctr r11
- write32(Buf + 12, 0x4e800420); // bctr
+ write32(buf + 0, 0x3d7e0000 | ha); // addis r11,r30,ha
+ write32(buf + 4, 0x816b0000 | l); // lwz r11,l(r11)
+ write32(buf + 8, 0x7d6903a6); // mtctr r11
+ write32(buf + 12, 0x4e800420); // bctr
}
}
-void PPC32PltCallStub::addSymbols(ThunkSection &IS) {
- std::string Buf;
- raw_string_ostream OS(Buf);
- OS << format_hex_no_prefix(Addend, 8);
- if (!Config->Pic)
- OS << ".plt_call32.";
- else if (Addend >= 0x8000)
- OS << ".got2.plt_pic32.";
+void PPC32PltCallStub::addSymbols(ThunkSection &isec) {
+ std::string buf;
+ raw_string_ostream os(buf);
+ os << format_hex_no_prefix(addend, 8);
+ if (!config->isPic)
+ os << ".plt_call32.";
+ else if (addend >= 0x8000)
+ os << ".got2.plt_pic32.";
else
- OS << ".plt_pic32.";
- OS << Destination.getName();
- addSymbol(Saver.save(OS.str()), STT_FUNC, 0, IS);
+ os << ".plt_pic32.";
+ os << destination.getName();
+ addSymbol(Saver.save(os.str()), STT_FUNC, 0, isec);
}
-bool PPC32PltCallStub::isCompatibleWith(const InputSection &IS,
- const Relocation &Rel) const {
- return !Config->Pic || (IS.File == File && Rel.Addend == Addend);
+bool PPC32PltCallStub::isCompatibleWith(const InputSection &isec,
+ const Relocation &rel) const {
+ return !config->isPic || (isec.file == file && rel.addend == addend);
}
-static void writePPCLoadAndBranch(uint8_t *Buf, int64_t Offset) {
- uint16_t OffHa = (Offset + 0x8000) >> 16;
- uint16_t OffLo = Offset & 0xffff;
+static void writePPCLoadAndBranch(uint8_t *buf, int64_t offset) {
+ uint16_t offHa = (offset + 0x8000) >> 16;
+ uint16_t offLo = offset & 0xffff;
- write32(Buf + 0, 0x3d820000 | OffHa); // addis r12, r2, OffHa
- write32(Buf + 4, 0xe98c0000 | OffLo); // ld r12, OffLo(r12)
- write32(Buf + 8, 0x7d8903a6); // mtctr r12
- write32(Buf + 12, 0x4e800420); // bctr
+ write32(buf + 0, 0x3d820000 | offHa); // addis r12, r2, OffHa
+ write32(buf + 4, 0xe98c0000 | offLo); // ld r12, OffLo(r12)
+ write32(buf + 8, 0x7d8903a6); // mtctr r12
+ write32(buf + 12, 0x4e800420); // bctr
}
-void PPC64PltCallStub::writeTo(uint8_t *Buf) {
- int64_t Offset = Destination.getGotPltVA() - getPPC64TocBase();
+void PPC64PltCallStub::writeTo(uint8_t *buf) {
+ int64_t offset = destination.getGotPltVA() - getPPC64TocBase();
// Save the TOC pointer to the save-slot reserved in the call frame.
- write32(Buf + 0, 0xf8410018); // std r2,24(r1)
- writePPCLoadAndBranch(Buf + 4, Offset);
+ write32(buf + 0, 0xf8410018); // std r2,24(r1)
+ writePPCLoadAndBranch(buf + 4, offset);
}
-void PPC64PltCallStub::addSymbols(ThunkSection &IS) {
- Defined *S = addSymbol(Saver.save("__plt_" + Destination.getName()), STT_FUNC,
- 0, IS);
- S->NeedsTocRestore = true;
+void PPC64PltCallStub::addSymbols(ThunkSection &isec) {
+ Defined *s = addSymbol(Saver.save("__plt_" + destination.getName()), STT_FUNC,
+ 0, isec);
+ s->needsTocRestore = true;
}
-void PPC64LongBranchThunk::writeTo(uint8_t *Buf) {
- int64_t Offset = Destination.getPPC64LongBranchTableVA() - getPPC64TocBase();
- writePPCLoadAndBranch(Buf, Offset);
+void PPC64LongBranchThunk::writeTo(uint8_t *buf) {
+ int64_t offset = destination.getPPC64LongBranchTableVA() - getPPC64TocBase();
+ writePPCLoadAndBranch(buf, offset);
}
-void PPC64LongBranchThunk::addSymbols(ThunkSection &IS) {
- addSymbol(Saver.save("__long_branch_" + Destination.getName()), STT_FUNC, 0,
- IS);
+void PPC64LongBranchThunk::addSymbols(ThunkSection &isec) {
+ addSymbol(Saver.save("__long_branch_" + destination.getName()), STT_FUNC, 0,
+ isec);
}
-Thunk::Thunk(Symbol &D) : Destination(D), Offset(0) {}
+Thunk::Thunk(Symbol &d) : destination(d), offset(0) {}
Thunk::~Thunk() = default;
-static Thunk *addThunkAArch64(RelType Type, Symbol &S) {
- if (Type != R_AARCH64_CALL26 && Type != R_AARCH64_JUMP26)
+static Thunk *addThunkAArch64(RelType type, Symbol &s) {
+ if (type != R_AARCH64_CALL26 && type != R_AARCH64_JUMP26)
fatal("unrecognized relocation type");
- if (Config->PicThunk)
- return make<AArch64ADRPThunk>(S);
- return make<AArch64ABSLongThunk>(S);
+ if (config->picThunk)
+ return make<AArch64ADRPThunk>(s);
+ return make<AArch64ABSLongThunk>(s);
}
// Creates a thunk for Thumb-ARM interworking.
@@ -812,18 +812,18 @@ static Thunk *addThunkAArch64(RelType Ty
// - MOVT and MOVW instructions cannot be used
// - Only Thumb relocation that can generate a Thunk is a BL, this can always
// be transformed into a BLX
-static Thunk *addThunkPreArmv7(RelType Reloc, Symbol &S) {
- switch (Reloc) {
+static Thunk *addThunkPreArmv7(RelType reloc, Symbol &s) {
+ switch (reloc) {
case R_ARM_PC24:
case R_ARM_PLT32:
case R_ARM_JUMP24:
case R_ARM_CALL:
case R_ARM_THM_CALL:
- if (Config->PicThunk)
- return make<ARMV5PILongThunk>(S);
- return make<ARMV5ABSLongThunk>(S);
+ if (config->picThunk)
+ return make<ARMV5PILongThunk>(s);
+ return make<ARMV5ABSLongThunk>(s);
}
- fatal("relocation " + toString(Reloc) + " to " + toString(S) +
+ fatal("relocation " + toString(reloc) + " to " + toString(s) +
" not supported for Armv5 or Armv6 targets");
}
@@ -832,21 +832,21 @@ static Thunk *addThunkPreArmv7(RelType R
// - MOVT and MOVW instructions cannot be used.
// - Only a limited number of instructions can access registers r8 and above
// - No interworking support is needed (all Thumb).
-static Thunk *addThunkV6M(RelType Reloc, Symbol &S) {
- switch (Reloc) {
+static Thunk *addThunkV6M(RelType reloc, Symbol &s) {
+ switch (reloc) {
case R_ARM_THM_JUMP19:
case R_ARM_THM_JUMP24:
case R_ARM_THM_CALL:
- if (Config->Pic)
- return make<ThumbV6MPILongThunk>(S);
- return make<ThumbV6MABSLongThunk>(S);
+ if (config->isPic)
+ return make<ThumbV6MPILongThunk>(s);
+ return make<ThumbV6MABSLongThunk>(s);
}
- fatal("relocation " + toString(Reloc) + " to " + toString(S) +
+ fatal("relocation " + toString(reloc) + " to " + toString(s) +
" not supported for Armv6-M targets");
}
// Creates a thunk for Thumb-ARM interworking or branch range extension.
-static Thunk *addThunkArm(RelType Reloc, Symbol &S) {
+static Thunk *addThunkArm(RelType reloc, Symbol &s) {
// Decide which Thunk is needed based on:
// Available instruction set
// - An Arm Thunk can only be used if Arm state is available.
@@ -863,72 +863,72 @@ static Thunk *addThunkArm(RelType Reloc,
// can use in Thunks. The flags below are set by reading the BuildAttributes
// of the input objects. InputFiles.cpp contains the mapping from ARM
// architecture to flag.
- if (!Config->ARMHasMovtMovw) {
- if (!Config->ARMJ1J2BranchEncoding)
- return addThunkPreArmv7(Reloc, S);
- return addThunkV6M(Reloc, S);
+ if (!config->armHasMovtMovw) {
+ if (!config->armJ1J2BranchEncoding)
+ return addThunkPreArmv7(reloc, s);
+ return addThunkV6M(reloc, s);
}
- switch (Reloc) {
+ switch (reloc) {
case R_ARM_PC24:
case R_ARM_PLT32:
case R_ARM_JUMP24:
case R_ARM_CALL:
- if (Config->PicThunk)
- return make<ARMV7PILongThunk>(S);
- return make<ARMV7ABSLongThunk>(S);
+ if (config->picThunk)
+ return make<ARMV7PILongThunk>(s);
+ return make<ARMV7ABSLongThunk>(s);
case R_ARM_THM_JUMP19:
case R_ARM_THM_JUMP24:
case R_ARM_THM_CALL:
- if (Config->PicThunk)
- return make<ThumbV7PILongThunk>(S);
- return make<ThumbV7ABSLongThunk>(S);
+ if (config->picThunk)
+ return make<ThumbV7PILongThunk>(s);
+ return make<ThumbV7ABSLongThunk>(s);
}
fatal("unrecognized relocation type");
}
-static Thunk *addThunkMips(RelType Type, Symbol &S) {
- if ((S.StOther & STO_MIPS_MICROMIPS) && isMipsR6())
- return make<MicroMipsR6Thunk>(S);
- if (S.StOther & STO_MIPS_MICROMIPS)
- return make<MicroMipsThunk>(S);
- return make<MipsThunk>(S);
+static Thunk *addThunkMips(RelType type, Symbol &s) {
+ if ((s.stOther & STO_MIPS_MICROMIPS) && isMipsR6())
+ return make<MicroMipsR6Thunk>(s);
+ if (s.stOther & STO_MIPS_MICROMIPS)
+ return make<MicroMipsThunk>(s);
+ return make<MipsThunk>(s);
}
-static Thunk *addThunkPPC32(const InputSection &IS, const Relocation &Rel, Symbol &S) {
- assert((Rel.Type == R_PPC_REL24 || Rel.Type == R_PPC_PLTREL24) &&
+static Thunk *addThunkPPC32(const InputSection &isec, const Relocation &rel, Symbol &s) {
+ assert((rel.type == R_PPC_REL24 || rel.type == R_PPC_PLTREL24) &&
"unexpected relocation type for thunk");
- return make<PPC32PltCallStub>(IS, Rel, S);
+ return make<PPC32PltCallStub>(isec, rel, s);
}
-static Thunk *addThunkPPC64(RelType Type, Symbol &S) {
- assert(Type == R_PPC64_REL24 && "unexpected relocation type for thunk");
- if (S.isInPlt())
- return make<PPC64PltCallStub>(S);
+static Thunk *addThunkPPC64(RelType type, Symbol &s) {
+ assert(type == R_PPC64_REL24 && "unexpected relocation type for thunk");
+ if (s.isInPlt())
+ return make<PPC64PltCallStub>(s);
- if (Config->PicThunk)
- return make<PPC64PILongBranchThunk>(S);
+ if (config->picThunk)
+ return make<PPC64PILongBranchThunk>(s);
- return make<PPC64PDLongBranchThunk>(S);
+ return make<PPC64PDLongBranchThunk>(s);
}
-Thunk *addThunk(const InputSection &IS, Relocation &Rel) {
- Symbol &S = *Rel.Sym;
+Thunk *addThunk(const InputSection &isec, Relocation &rel) {
+ Symbol &s = *rel.sym;
- if (Config->EMachine == EM_AARCH64)
- return addThunkAArch64(Rel.Type, S);
+ if (config->emachine == EM_AARCH64)
+ return addThunkAArch64(rel.type, s);
- if (Config->EMachine == EM_ARM)
- return addThunkArm(Rel.Type, S);
+ if (config->emachine == EM_ARM)
+ return addThunkArm(rel.type, s);
- if (Config->EMachine == EM_MIPS)
- return addThunkMips(Rel.Type, S);
+ if (config->emachine == EM_MIPS)
+ return addThunkMips(rel.type, s);
- if (Config->EMachine == EM_PPC)
- return addThunkPPC32(IS, Rel, S);
+ if (config->emachine == EM_PPC)
+ return addThunkPPC32(isec, rel, s);
- if (Config->EMachine == EM_PPC64)
- return addThunkPPC64(Rel.Type, S);
+ if (config->emachine == EM_PPC64)
+ return addThunkPPC64(rel.type, s);
llvm_unreachable("add Thunk only supported for ARM, Mips and PowerPC");
}
Modified: lld/trunk/ELF/Thunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Thunks.h?rev=365595&r1=365594&r2=365595&view=diff
==============================================================================
--- lld/trunk/ELF/Thunks.h (original)
+++ lld/trunk/ELF/Thunks.h Tue Jul 9 22:00:37 2019
@@ -27,20 +27,20 @@ class ThunkSection;
// Thunks are assigned to synthetic ThunkSections
class Thunk {
public:
- Thunk(Symbol &Destination);
+ Thunk(Symbol &destination);
virtual ~Thunk();
virtual uint32_t size() = 0;
- virtual void writeTo(uint8_t *Buf) = 0;
+ virtual void writeTo(uint8_t *buf) = 0;
// All Thunks must define at least one symbol, known as the thunk target
// symbol, so that we can redirect relocations to it. The thunk may define
// additional symbols, but these are never targets for relocations.
- virtual void addSymbols(ThunkSection &IS) = 0;
+ virtual void addSymbols(ThunkSection &isec) = 0;
- void setOffset(uint64_t Offset);
- Defined *addSymbol(StringRef Name, uint8_t Type, uint64_t Value,
- InputSectionBase &Section);
+ void setOffset(uint64_t offset);
+ Defined *addSymbol(StringRef name, uint8_t type, uint64_t value,
+ InputSectionBase §ion);
// Some Thunks must be placed immediately before their Target as they elide
// a branch and fall through to the first Symbol in the Target.
@@ -53,19 +53,19 @@ public:
return true;
}
- Defined *getThunkTargetSym() const { return Syms[0]; }
+ Defined *getThunkTargetSym() const { return syms[0]; }
// The alignment requirement for this Thunk, defaults to the size of the
// typical code section alignment.
- Symbol &Destination;
- llvm::SmallVector<Defined *, 3> Syms;
- uint64_t Offset = 0;
- uint32_t Alignment = 4;
+ Symbol &destination;
+ llvm::SmallVector<Defined *, 3> syms;
+ uint64_t offset = 0;
+ uint32_t alignment = 4;
};
// For a Relocation to symbol S create a Thunk to be added to a synthetic
// ThunkSection.
-Thunk *addThunk(const InputSection &IS, Relocation &Rel);
+Thunk *addThunk(const InputSection &isec, Relocation &rel);
} // namespace elf
} // namespace lld
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=365595&r1=365594&r2=365595&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Tue Jul 9 22:00:37 2019
@@ -42,7 +42,7 @@ namespace {
// The writer writes a SymbolTable result to a file.
template <class ELFT> class Writer {
public:
- Writer() : Buffer(errorHandler().OutputBuffer) {}
+ Writer() : buffer(errorHandler().OutputBuffer) {}
using Elf_Shdr = typename ELFT::Shdr;
using Elf_Ehdr = typename ELFT::Ehdr;
using Elf_Phdr = typename ELFT::Phdr;
@@ -52,7 +52,7 @@ public:
private:
void copyLocalSymbols();
void addSectionSymbols();
- void forEachRelSec(llvm::function_ref<void(InputSectionBase &)> Fn);
+ void forEachRelSec(llvm::function_ref<void(InputSectionBase &)> fn);
void sortSections();
void resolveShfLinkOrder();
void finalizeAddressDependentContent();
@@ -61,13 +61,13 @@ private:
void checkExecuteOnly();
void setReservedSymbolSections();
- std::vector<PhdrEntry *> createPhdrs(Partition &Part);
- void removeEmptyPTLoad(std::vector<PhdrEntry *> &PhdrEntry);
- void addPhdrForSection(Partition &Part, unsigned ShType, unsigned PType,
- unsigned PFlags);
+ std::vector<PhdrEntry *> createPhdrs(Partition &part);
+ void removeEmptyPTLoad(std::vector<PhdrEntry *> &phdrEntry);
+ void addPhdrForSection(Partition &part, unsigned shType, unsigned pType,
+ unsigned pFlags);
void assignFileOffsets();
void assignFileOffsetsBinary();
- void setPhdrs(Partition &Part);
+ void setPhdrs(Partition &part);
void checkSections();
void fixSectionAlignments();
void openFile();
@@ -77,34 +77,34 @@ private:
void writeSectionsBinary();
void writeBuildId();
- std::unique_ptr<FileOutputBuffer> &Buffer;
+ std::unique_ptr<FileOutputBuffer> &buffer;
void addRelIpltSymbols();
void addStartEndSymbols();
- void addStartStopSymbols(OutputSection *Sec);
+ void addStartStopSymbols(OutputSection *sec);
- uint64_t FileSize;
- uint64_t SectionHeaderOff;
+ uint64_t fileSize;
+ uint64_t sectionHeaderOff;
};
} // anonymous namespace
-static bool isSectionPrefix(StringRef Prefix, StringRef Name) {
- return Name.startswith(Prefix) || Name == Prefix.drop_back();
+static bool isSectionPrefix(StringRef prefix, StringRef name) {
+ return name.startswith(prefix) || name == prefix.drop_back();
}
-StringRef elf::getOutputSectionName(const InputSectionBase *S) {
- if (Config->Relocatable)
- return S->Name;
+StringRef elf::getOutputSectionName(const InputSectionBase *s) {
+ if (config->relocatable)
+ return s->name;
// This is for --emit-relocs. If .text.foo is emitted as .text.bar, we want
// to emit .rela.text.foo as .rela.text.bar for consistency (this is not
// technically required, but not doing it is odd). This code guarantees that.
- if (auto *IS = dyn_cast<InputSection>(S)) {
- if (InputSectionBase *Rel = IS->getRelocatedSection()) {
- OutputSection *Out = Rel->getOutputSection();
- if (S->Type == SHT_RELA)
- return Saver.save(".rela" + Out->Name);
- return Saver.save(".rel" + Out->Name);
+ if (auto *isec = dyn_cast<InputSection>(s)) {
+ if (InputSectionBase *rel = isec->getRelocatedSection()) {
+ OutputSection *out = rel->getOutputSection();
+ if (s->type == SHT_RELA)
+ return Saver.save(".rela" + out->name);
+ return Saver.save(".rel" + out->name);
}
}
@@ -114,130 +114,130 @@ StringRef elf::getOutputSectionName(cons
// When enabled, this allows identifying the hot code region (.text.hot) in
// the final binary which can be selectively mapped to huge pages or mlocked,
// for instance.
- if (Config->ZKeepTextSectionPrefix)
- for (StringRef V :
+ if (config->zKeepTextSectionPrefix)
+ for (StringRef v :
{".text.hot.", ".text.unlikely.", ".text.startup.", ".text.exit."})
- if (isSectionPrefix(V, S->Name))
- return V.drop_back();
+ if (isSectionPrefix(v, s->name))
+ return v.drop_back();
- for (StringRef V :
+ for (StringRef v :
{".text.", ".rodata.", ".data.rel.ro.", ".data.", ".bss.rel.ro.",
".bss.", ".init_array.", ".fini_array.", ".ctors.", ".dtors.", ".tbss.",
".gcc_except_table.", ".tdata.", ".ARM.exidx.", ".ARM.extab."})
- if (isSectionPrefix(V, S->Name))
- return V.drop_back();
+ if (isSectionPrefix(v, s->name))
+ return v.drop_back();
// CommonSection is identified as "COMMON" in linker scripts.
// By default, it should go to .bss section.
- if (S->Name == "COMMON")
+ if (s->name == "COMMON")
return ".bss";
- return S->Name;
+ return s->name;
}
static bool needsInterpSection() {
- return !SharedFiles.empty() && !Config->DynamicLinker.empty() &&
- Script->needsInterpSection();
+ return !sharedFiles.empty() && !config->dynamicLinker.empty() &&
+ script->needsInterpSection();
}
template <class ELFT> void elf::writeResult() { Writer<ELFT>().run(); }
template <class ELFT>
-void Writer<ELFT>::removeEmptyPTLoad(std::vector<PhdrEntry *> &Phdrs) {
- llvm::erase_if(Phdrs, [&](const PhdrEntry *P) {
- if (P->p_type != PT_LOAD)
+void Writer<ELFT>::removeEmptyPTLoad(std::vector<PhdrEntry *> &phdrs) {
+ llvm::erase_if(phdrs, [&](const PhdrEntry *p) {
+ if (p->p_type != PT_LOAD)
return false;
- if (!P->FirstSec)
+ if (!p->firstSec)
return true;
- uint64_t Size = P->LastSec->Addr + P->LastSec->Size - P->FirstSec->Addr;
- return Size == 0;
+ uint64_t size = p->lastSec->addr + p->lastSec->size - p->firstSec->addr;
+ return size == 0;
});
}
template <class ELFT> static void copySectionsIntoPartitions() {
- std::vector<InputSectionBase *> NewSections;
- for (unsigned Part = 2; Part != Partitions.size() + 1; ++Part) {
- for (InputSectionBase *S : InputSections) {
- if (!(S->Flags & SHF_ALLOC) || !S->isLive())
+ std::vector<InputSectionBase *> newSections;
+ for (unsigned part = 2; part != partitions.size() + 1; ++part) {
+ for (InputSectionBase *s : inputSections) {
+ if (!(s->flags & SHF_ALLOC) || !s->isLive())
continue;
- InputSectionBase *Copy;
- if (S->Type == SHT_NOTE)
- Copy = make<InputSection>(cast<InputSection>(*S));
- else if (auto *ES = dyn_cast<EhInputSection>(S))
- Copy = make<EhInputSection>(*ES);
+ InputSectionBase *copy;
+ if (s->type == SHT_NOTE)
+ copy = make<InputSection>(cast<InputSection>(*s));
+ else if (auto *es = dyn_cast<EhInputSection>(s))
+ copy = make<EhInputSection>(*es);
else
continue;
- Copy->Partition = Part;
- NewSections.push_back(Copy);
+ copy->partition = part;
+ newSections.push_back(copy);
}
}
- InputSections.insert(InputSections.end(), NewSections.begin(),
- NewSections.end());
+ inputSections.insert(inputSections.end(), newSections.begin(),
+ newSections.end());
}
template <class ELFT> static void combineEhSections() {
- for (InputSectionBase *&S : InputSections) {
+ for (InputSectionBase *&s : inputSections) {
// Ignore dead sections and the partition end marker (.part.end),
// whose partition number is out of bounds.
- if (!S->isLive() || S->Partition == 255)
+ if (!s->isLive() || s->partition == 255)
continue;
- Partition &Part = S->getPartition();
- if (auto *ES = dyn_cast<EhInputSection>(S)) {
- Part.EhFrame->addSection<ELFT>(ES);
- S = nullptr;
- } else if (S->kind() == SectionBase::Regular && Part.ARMExidx &&
- Part.ARMExidx->addSection(cast<InputSection>(S))) {
- S = nullptr;
+ Partition &part = s->getPartition();
+ if (auto *es = dyn_cast<EhInputSection>(s)) {
+ part.ehFrame->addSection<ELFT>(es);
+ s = nullptr;
+ } else if (s->kind() == SectionBase::Regular && part.armExidx &&
+ part.armExidx->addSection(cast<InputSection>(s))) {
+ s = nullptr;
}
}
- std::vector<InputSectionBase *> &V = InputSections;
- V.erase(std::remove(V.begin(), V.end(), nullptr), V.end());
+ std::vector<InputSectionBase *> &v = inputSections;
+ v.erase(std::remove(v.begin(), v.end(), nullptr), v.end());
}
-static Defined *addOptionalRegular(StringRef Name, SectionBase *Sec,
- uint64_t Val, uint8_t StOther = STV_HIDDEN,
- uint8_t Binding = STB_GLOBAL) {
- Symbol *S = Symtab->find(Name);
- if (!S || S->isDefined())
+static Defined *addOptionalRegular(StringRef name, SectionBase *sec,
+ uint64_t val, uint8_t stOther = STV_HIDDEN,
+ uint8_t binding = STB_GLOBAL) {
+ Symbol *s = symtab->find(name);
+ if (!s || s->isDefined())
return nullptr;
- S->resolve(Defined{/*File=*/nullptr, Name, Binding, StOther, STT_NOTYPE, Val,
- /*Size=*/0, Sec});
- return cast<Defined>(S);
+ s->resolve(Defined{/*File=*/nullptr, name, binding, stOther, STT_NOTYPE, val,
+ /*Size=*/0, sec});
+ return cast<Defined>(s);
}
-static Defined *addAbsolute(StringRef Name) {
- Symbol *Sym = Symtab->addSymbol(Defined{nullptr, Name, STB_GLOBAL, STV_HIDDEN,
+static Defined *addAbsolute(StringRef name) {
+ Symbol *sym = symtab->addSymbol(Defined{nullptr, name, STB_GLOBAL, STV_HIDDEN,
STT_NOTYPE, 0, 0, nullptr});
- return cast<Defined>(Sym);
+ return cast<Defined>(sym);
}
// The linker is expected to define some symbols depending on
// the linking result. This function defines such symbols.
void elf::addReservedSymbols() {
- if (Config->EMachine == EM_MIPS) {
+ if (config->emachine == EM_MIPS) {
// Define _gp for MIPS. st_value of _gp symbol will be updated by Writer
// so that it points to an absolute address which by default is relative
// to GOT. Default offset is 0x7ff0.
// See "Global Data Symbols" in Chapter 6 in the following document:
// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
- ElfSym::MipsGp = addAbsolute("_gp");
+ ElfSym::mipsGp = addAbsolute("_gp");
// On MIPS O32 ABI, _gp_disp is a magic symbol designates offset between
// start of function and 'gp' pointer into GOT.
- if (Symtab->find("_gp_disp"))
- ElfSym::MipsGpDisp = addAbsolute("_gp_disp");
+ if (symtab->find("_gp_disp"))
+ ElfSym::mipsGpDisp = addAbsolute("_gp_disp");
// The __gnu_local_gp is a magic symbol equal to the current value of 'gp'
// pointer. This symbol is used in the code generated by .cpload pseudo-op
// in case of using -mno-shared option.
// https://sourceware.org/ml/binutils/2004-12/msg00094.html
- if (Symtab->find("__gnu_local_gp"))
- ElfSym::MipsLocalGp = addAbsolute("__gnu_local_gp");
- } else if (Config->EMachine == EM_PPC) {
+ if (symtab->find("__gnu_local_gp"))
+ ElfSym::mipsLocalGp = addAbsolute("__gnu_local_gp");
+ } else if (config->emachine == EM_PPC) {
// glibc *crt1.o has a undefined reference to _SDA_BASE_. Since we don't
// support Small Data Area, define it arbitrarily as 0.
addOptionalRegular("_SDA_BASE_", nullptr, 0, STV_HIDDEN);
@@ -251,62 +251,62 @@ void elf::addReservedSymbols() {
// the .got section.
// We do not allow _GLOBAL_OFFSET_TABLE_ to be defined by input objects as the
// correctness of some relocations depends on its value.
- StringRef GotSymName =
- (Config->EMachine == EM_PPC64) ? ".TOC." : "_GLOBAL_OFFSET_TABLE_";
+ StringRef gotSymName =
+ (config->emachine == EM_PPC64) ? ".TOC." : "_GLOBAL_OFFSET_TABLE_";
- if (Symbol *S = Symtab->find(GotSymName)) {
- if (S->isDefined()) {
- error(toString(S->File) + " cannot redefine linker defined symbol '" +
- GotSymName + "'");
+ if (Symbol *s = symtab->find(gotSymName)) {
+ if (s->isDefined()) {
+ error(toString(s->file) + " cannot redefine linker defined symbol '" +
+ gotSymName + "'");
return;
}
- uint64_t GotOff = 0;
- if (Config->EMachine == EM_PPC64)
- GotOff = 0x8000;
-
- S->resolve(Defined{/*File=*/nullptr, GotSymName, STB_GLOBAL, STV_HIDDEN,
- STT_NOTYPE, GotOff, /*Size=*/0, Out::ElfHeader});
- ElfSym::GlobalOffsetTable = cast<Defined>(S);
+ uint64_t gotOff = 0;
+ if (config->emachine == EM_PPC64)
+ gotOff = 0x8000;
+
+ s->resolve(Defined{/*File=*/nullptr, gotSymName, STB_GLOBAL, STV_HIDDEN,
+ STT_NOTYPE, gotOff, /*Size=*/0, Out::elfHeader});
+ ElfSym::globalOffsetTable = cast<Defined>(s);
}
// __ehdr_start is the location of ELF file headers. Note that we define
// this symbol unconditionally even when using a linker script, which
// differs from the behavior implemented by GNU linker which only define
// this symbol if ELF headers are in the memory mapped segment.
- addOptionalRegular("__ehdr_start", Out::ElfHeader, 0, STV_HIDDEN);
+ addOptionalRegular("__ehdr_start", Out::elfHeader, 0, STV_HIDDEN);
// __executable_start is not documented, but the expectation of at
// least the Android libc is that it points to the ELF header.
- addOptionalRegular("__executable_start", Out::ElfHeader, 0, STV_HIDDEN);
+ addOptionalRegular("__executable_start", Out::elfHeader, 0, STV_HIDDEN);
// __dso_handle symbol is passed to cxa_finalize as a marker to identify
// each DSO. The address of the symbol doesn't matter as long as they are
// different in different DSOs, so we chose the start address of the DSO.
- addOptionalRegular("__dso_handle", Out::ElfHeader, 0, STV_HIDDEN);
+ addOptionalRegular("__dso_handle", Out::elfHeader, 0, STV_HIDDEN);
// If linker script do layout we do not need to create any standart symbols.
- if (Script->HasSectionsCommand)
+ if (script->hasSectionsCommand)
return;
- auto Add = [](StringRef S, int64_t Pos) {
- return addOptionalRegular(S, Out::ElfHeader, Pos, STV_DEFAULT);
+ auto add = [](StringRef s, int64_t pos) {
+ return addOptionalRegular(s, Out::elfHeader, pos, STV_DEFAULT);
};
- ElfSym::Bss = Add("__bss_start", 0);
- ElfSym::End1 = Add("end", -1);
- ElfSym::End2 = Add("_end", -1);
- ElfSym::Etext1 = Add("etext", -1);
- ElfSym::Etext2 = Add("_etext", -1);
- ElfSym::Edata1 = Add("edata", -1);
- ElfSym::Edata2 = Add("_edata", -1);
+ ElfSym::bss = add("__bss_start", 0);
+ ElfSym::end1 = add("end", -1);
+ ElfSym::end2 = add("_end", -1);
+ ElfSym::etext1 = add("etext", -1);
+ ElfSym::etext2 = add("_etext", -1);
+ ElfSym::edata1 = add("edata", -1);
+ ElfSym::edata2 = add("_edata", -1);
}
-static OutputSection *findSection(StringRef Name, unsigned Partition = 1) {
- for (BaseCommand *Base : Script->SectionCommands)
- if (auto *Sec = dyn_cast<OutputSection>(Base))
- if (Sec->Name == Name && Sec->Partition == Partition)
- return Sec;
+static OutputSection *findSection(StringRef name, unsigned partition = 1) {
+ for (BaseCommand *base : script->sectionCommands)
+ if (auto *sec = dyn_cast<OutputSection>(base))
+ if (sec->name == name && sec->partition == partition)
+ return sec;
return nullptr;
}
@@ -314,195 +314,195 @@ static OutputSection *findSection(String
template <class ELFT> static void createSyntheticSections() {
// Initialize all pointers with NULL. This is needed because
// you can call lld::elf::main more than once as a library.
- memset(&Out::First, 0, sizeof(Out));
+ memset(&Out::first, 0, sizeof(Out));
- auto Add = [](InputSectionBase *Sec) { InputSections.push_back(Sec); };
+ auto add = [](InputSectionBase *sec) { inputSections.push_back(sec); };
- In.ShStrTab = make<StringTableSection>(".shstrtab", false);
+ in.shStrTab = make<StringTableSection>(".shstrtab", false);
- Out::ProgramHeaders = make<OutputSection>("", 0, SHF_ALLOC);
- Out::ProgramHeaders->Alignment = Config->Wordsize;
+ Out::programHeaders = make<OutputSection>("", 0, SHF_ALLOC);
+ Out::programHeaders->alignment = config->wordsize;
- if (Config->Strip != StripPolicy::All) {
- In.StrTab = make<StringTableSection>(".strtab", false);
- In.SymTab = make<SymbolTableSection<ELFT>>(*In.StrTab);
- In.SymTabShndx = make<SymtabShndxSection>();
+ if (config->strip != StripPolicy::All) {
+ in.strTab = make<StringTableSection>(".strtab", false);
+ in.symTab = make<SymbolTableSection<ELFT>>(*in.strTab);
+ in.symTabShndx = make<SymtabShndxSection>();
}
- In.Bss = make<BssSection>(".bss", 0, 1);
- Add(In.Bss);
+ in.bss = make<BssSection>(".bss", 0, 1);
+ add(in.bss);
// If there is a SECTIONS command and a .data.rel.ro section name use name
// .data.rel.ro.bss so that we match in the .data.rel.ro output section.
// This makes sure our relro is contiguous.
- bool HasDataRelRo =
- Script->HasSectionsCommand && findSection(".data.rel.ro", 0);
- In.BssRelRo =
- make<BssSection>(HasDataRelRo ? ".data.rel.ro.bss" : ".bss.rel.ro", 0, 1);
- Add(In.BssRelRo);
+ bool hasDataRelRo =
+ script->hasSectionsCommand && findSection(".data.rel.ro", 0);
+ in.bssRelRo =
+ make<BssSection>(hasDataRelRo ? ".data.rel.ro.bss" : ".bss.rel.ro", 0, 1);
+ add(in.bssRelRo);
// Add MIPS-specific sections.
- if (Config->EMachine == EM_MIPS) {
- if (!Config->Shared && Config->HasDynSymTab) {
- In.MipsRldMap = make<MipsRldMapSection>();
- Add(In.MipsRldMap);
- }
- if (auto *Sec = MipsAbiFlagsSection<ELFT>::create())
- Add(Sec);
- if (auto *Sec = MipsOptionsSection<ELFT>::create())
- Add(Sec);
- if (auto *Sec = MipsReginfoSection<ELFT>::create())
- Add(Sec);
- }
-
- for (Partition &Part : Partitions) {
- auto Add = [&](InputSectionBase *Sec) {
- Sec->Partition = Part.getNumber();
- InputSections.push_back(Sec);
+ if (config->emachine == EM_MIPS) {
+ if (!config->shared && config->hasDynSymTab) {
+ in.mipsRldMap = make<MipsRldMapSection>();
+ add(in.mipsRldMap);
+ }
+ if (auto *sec = MipsAbiFlagsSection<ELFT>::create())
+ add(sec);
+ if (auto *sec = MipsOptionsSection<ELFT>::create())
+ add(sec);
+ if (auto *sec = MipsReginfoSection<ELFT>::create())
+ add(sec);
+ }
+
+ for (Partition &part : partitions) {
+ auto add = [&](InputSectionBase *sec) {
+ sec->partition = part.getNumber();
+ inputSections.push_back(sec);
};
- if (!Part.Name.empty()) {
- Part.ElfHeader = make<PartitionElfHeaderSection<ELFT>>();
- Part.ElfHeader->Name = Part.Name;
- Add(Part.ElfHeader);
-
- Part.ProgramHeaders = make<PartitionProgramHeadersSection<ELFT>>();
- Add(Part.ProgramHeaders);
- }
-
- if (Config->BuildId != BuildIdKind::None) {
- Part.BuildId = make<BuildIdSection>();
- Add(Part.BuildId);
- }
-
- Part.DynStrTab = make<StringTableSection>(".dynstr", true);
- Part.DynSymTab = make<SymbolTableSection<ELFT>>(*Part.DynStrTab);
- Part.Dynamic = make<DynamicSection<ELFT>>();
- if (Config->AndroidPackDynRelocs) {
- Part.RelaDyn = make<AndroidPackedRelocationSection<ELFT>>(
- Config->IsRela ? ".rela.dyn" : ".rel.dyn");
+ if (!part.name.empty()) {
+ part.elfHeader = make<PartitionElfHeaderSection<ELFT>>();
+ part.elfHeader->name = part.name;
+ add(part.elfHeader);
+
+ part.programHeaders = make<PartitionProgramHeadersSection<ELFT>>();
+ add(part.programHeaders);
+ }
+
+ if (config->buildId != BuildIdKind::None) {
+ part.buildId = make<BuildIdSection>();
+ add(part.buildId);
+ }
+
+ part.dynStrTab = make<StringTableSection>(".dynstr", true);
+ part.dynSymTab = make<SymbolTableSection<ELFT>>(*part.dynStrTab);
+ part.dynamic = make<DynamicSection<ELFT>>();
+ if (config->androidPackDynRelocs) {
+ part.relaDyn = make<AndroidPackedRelocationSection<ELFT>>(
+ config->isRela ? ".rela.dyn" : ".rel.dyn");
} else {
- Part.RelaDyn = make<RelocationSection<ELFT>>(
- Config->IsRela ? ".rela.dyn" : ".rel.dyn", Config->ZCombreloc);
+ part.relaDyn = make<RelocationSection<ELFT>>(
+ config->isRela ? ".rela.dyn" : ".rel.dyn", config->zCombreloc);
}
if (needsInterpSection())
- Add(createInterpSection());
+ add(createInterpSection());
- if (Config->HasDynSymTab) {
- Part.DynSymTab = make<SymbolTableSection<ELFT>>(*Part.DynStrTab);
- Add(Part.DynSymTab);
-
- Part.VerSym = make<VersionTableSection>();
- Add(Part.VerSym);
-
- if (!Config->VersionDefinitions.empty()) {
- Part.VerDef = make<VersionDefinitionSection>();
- Add(Part.VerDef);
+ if (config->hasDynSymTab) {
+ part.dynSymTab = make<SymbolTableSection<ELFT>>(*part.dynStrTab);
+ add(part.dynSymTab);
+
+ part.verSym = make<VersionTableSection>();
+ add(part.verSym);
+
+ if (!config->versionDefinitions.empty()) {
+ part.verDef = make<VersionDefinitionSection>();
+ add(part.verDef);
}
- Part.VerNeed = make<VersionNeedSection<ELFT>>();
- Add(Part.VerNeed);
+ part.verNeed = make<VersionNeedSection<ELFT>>();
+ add(part.verNeed);
- if (Config->GnuHash) {
- Part.GnuHashTab = make<GnuHashTableSection>();
- Add(Part.GnuHashTab);
+ if (config->gnuHash) {
+ part.gnuHashTab = make<GnuHashTableSection>();
+ add(part.gnuHashTab);
}
- if (Config->SysvHash) {
- Part.HashTab = make<HashTableSection>();
- Add(Part.HashTab);
+ if (config->sysvHash) {
+ part.hashTab = make<HashTableSection>();
+ add(part.hashTab);
}
- Add(Part.Dynamic);
- Add(Part.DynStrTab);
- Add(Part.RelaDyn);
+ add(part.dynamic);
+ add(part.dynStrTab);
+ add(part.relaDyn);
}
- if (Config->RelrPackDynRelocs) {
- Part.RelrDyn = make<RelrSection<ELFT>>();
- Add(Part.RelrDyn);
+ if (config->relrPackDynRelocs) {
+ part.relrDyn = make<RelrSection<ELFT>>();
+ add(part.relrDyn);
}
- if (!Config->Relocatable) {
- if (Config->EhFrameHdr) {
- Part.EhFrameHdr = make<EhFrameHeader>();
- Add(Part.EhFrameHdr);
+ if (!config->relocatable) {
+ if (config->ehFrameHdr) {
+ part.ehFrameHdr = make<EhFrameHeader>();
+ add(part.ehFrameHdr);
}
- Part.EhFrame = make<EhFrameSection>();
- Add(Part.EhFrame);
+ part.ehFrame = make<EhFrameSection>();
+ add(part.ehFrame);
}
- if (Config->EMachine == EM_ARM && !Config->Relocatable) {
+ if (config->emachine == EM_ARM && !config->relocatable) {
// The ARMExidxsyntheticsection replaces all the individual .ARM.exidx
// InputSections.
- Part.ARMExidx = make<ARMExidxSyntheticSection>();
- Add(Part.ARMExidx);
+ part.armExidx = make<ARMExidxSyntheticSection>();
+ add(part.armExidx);
}
}
- if (Partitions.size() != 1) {
+ if (partitions.size() != 1) {
// Create the partition end marker. This needs to be in partition number 255
// so that it is sorted after all other partitions. It also has other
// special handling (see createPhdrs() and combineEhSections()).
- In.PartEnd = make<BssSection>(".part.end", Config->MaxPageSize, 1);
- In.PartEnd->Partition = 255;
- Add(In.PartEnd);
-
- In.PartIndex = make<PartitionIndexSection>();
- addOptionalRegular("__part_index_begin", In.PartIndex, 0);
- addOptionalRegular("__part_index_end", In.PartIndex,
- In.PartIndex->getSize());
- Add(In.PartIndex);
+ in.partEnd = make<BssSection>(".part.end", config->maxPageSize, 1);
+ in.partEnd->partition = 255;
+ add(in.partEnd);
+
+ in.partIndex = make<PartitionIndexSection>();
+ addOptionalRegular("__part_index_begin", in.partIndex, 0);
+ addOptionalRegular("__part_index_end", in.partIndex,
+ in.partIndex->getSize());
+ add(in.partIndex);
}
// Add .got. MIPS' .got is so different from the other archs,
// it has its own class.
- if (Config->EMachine == EM_MIPS) {
- In.MipsGot = make<MipsGotSection>();
- Add(In.MipsGot);
+ if (config->emachine == EM_MIPS) {
+ in.mipsGot = make<MipsGotSection>();
+ add(in.mipsGot);
} else {
- In.Got = make<GotSection>();
- Add(In.Got);
+ in.got = make<GotSection>();
+ add(in.got);
}
- if (Config->EMachine == EM_PPC) {
- In.PPC32Got2 = make<PPC32Got2Section>();
- Add(In.PPC32Got2);
+ if (config->emachine == EM_PPC) {
+ in.ppc32Got2 = make<PPC32Got2Section>();
+ add(in.ppc32Got2);
}
- if (Config->EMachine == EM_PPC64) {
- In.PPC64LongBranchTarget = make<PPC64LongBranchTargetSection>();
- Add(In.PPC64LongBranchTarget);
+ if (config->emachine == EM_PPC64) {
+ in.ppc64LongBranchTarget = make<PPC64LongBranchTargetSection>();
+ add(in.ppc64LongBranchTarget);
}
- if (Config->EMachine == EM_RISCV) {
- In.RISCVSdata = make<RISCVSdataSection>();
- Add(In.RISCVSdata);
+ if (config->emachine == EM_RISCV) {
+ in.riscvSdata = make<RISCVSdataSection>();
+ add(in.riscvSdata);
}
- In.GotPlt = make<GotPltSection>();
- Add(In.GotPlt);
- In.IgotPlt = make<IgotPltSection>();
- Add(In.IgotPlt);
+ in.gotPlt = make<GotPltSection>();
+ add(in.gotPlt);
+ in.igotPlt = make<IgotPltSection>();
+ add(in.igotPlt);
// _GLOBAL_OFFSET_TABLE_ is defined relative to either .got.plt or .got. Treat
// it as a relocation and ensure the referenced section is created.
- if (ElfSym::GlobalOffsetTable && Config->EMachine != EM_MIPS) {
- if (Target->GotBaseSymInGotPlt)
- In.GotPlt->HasGotPltOffRel = true;
+ if (ElfSym::globalOffsetTable && config->emachine != EM_MIPS) {
+ if (target->gotBaseSymInGotPlt)
+ in.gotPlt->hasGotPltOffRel = true;
else
- In.Got->HasGotOffRel = true;
+ in.got->hasGotOffRel = true;
}
- if (Config->GdbIndex)
- Add(GdbIndexSection::create<ELFT>());
+ if (config->gdbIndex)
+ add(GdbIndexSection::create<ELFT>());
// We always need to add rel[a].plt to output if it has entries.
// Even for static linking it can contain R_[*]_IRELATIVE relocations.
- In.RelaPlt = make<RelocationSection<ELFT>>(
- Config->IsRela ? ".rela.plt" : ".rel.plt", false /*Sort*/);
- Add(In.RelaPlt);
+ in.relaPlt = make<RelocationSection<ELFT>>(
+ config->isRela ? ".rela.plt" : ".rel.plt", false /*Sort*/);
+ add(in.relaPlt);
// The RelaIplt immediately follows .rel.plt (.rel.dyn for ARM) to ensure
// that the IRelative relocations are processed last by the dynamic loader.
@@ -510,36 +510,36 @@ template <class ELFT> static void create
// packing is enabled because that would cause a section type mismatch.
// However, because the Android dynamic loader reads .rel.plt after .rel.dyn,
// we can get the desired behaviour by placing the iplt section in .rel.plt.
- In.RelaIplt = make<RelocationSection<ELFT>>(
- (Config->EMachine == EM_ARM && !Config->AndroidPackDynRelocs)
+ in.relaIplt = make<RelocationSection<ELFT>>(
+ (config->emachine == EM_ARM && !config->androidPackDynRelocs)
? ".rel.dyn"
- : In.RelaPlt->Name,
+ : in.relaPlt->name,
false /*Sort*/);
- Add(In.RelaIplt);
+ add(in.relaIplt);
- In.Plt = make<PltSection>(false);
- Add(In.Plt);
- In.Iplt = make<PltSection>(true);
- Add(In.Iplt);
+ in.plt = make<PltSection>(false);
+ add(in.plt);
+ in.iplt = make<PltSection>(true);
+ add(in.iplt);
- if (Config->AndFeatures)
- Add(make<GnuPropertySection>());
+ if (config->andFeatures)
+ add(make<GnuPropertySection>());
// .note.GNU-stack is always added when we are creating a re-linkable
// object file. Other linkers are using the presence of this marker
// section to control the executable-ness of the stack area, but that
// is irrelevant these days. Stack area should always be non-executable
// by default. So we emit this section unconditionally.
- if (Config->Relocatable)
- Add(make<GnuStackSection>());
+ if (config->relocatable)
+ add(make<GnuStackSection>());
- if (In.SymTab)
- Add(In.SymTab);
- if (In.SymTabShndx)
- Add(In.SymTabShndx);
- Add(In.ShStrTab);
- if (In.StrTab)
- Add(In.StrTab);
+ if (in.symTab)
+ add(in.symTab);
+ if (in.symTabShndx)
+ add(in.symTabShndx);
+ add(in.shStrTab);
+ if (in.strTab)
+ add(in.strTab);
}
// The main function of the writer.
@@ -555,22 +555,22 @@ template <class ELFT> void Writer<ELFT>:
// Some input sections that are used for exception handling need to be moved
// into synthetic sections. Do that now so that they aren't assigned to
// output sections in the usual way.
- if (!Config->Relocatable)
+ if (!config->relocatable)
combineEhSections<ELFT>();
// We want to process linker script commands. When SECTIONS command
// is given we let it create sections.
- Script->processSectionCommands();
+ script->processSectionCommands();
// Linker scripts controls how input sections are assigned to output sections.
// Input sections that were not handled by scripts are called "orphans", and
// they are assigned to output sections by the default rule. Process that.
- Script->addOrphanSections();
+ script->addOrphanSections();
- if (Config->Discard != DiscardPolicy::All)
+ if (config->discard != DiscardPolicy::All)
copyLocalSymbols();
- if (Config->CopyRelocs)
+ if (config->copyRelocs)
addSectionSymbols();
// Now that we have a complete set of output sections. This function
@@ -582,35 +582,35 @@ template <class ELFT> void Writer<ELFT>:
if (errorCount())
return;
- Script->assignAddresses();
+ script->assignAddresses();
// If -compressed-debug-sections is specified, we need to compress
// .debug_* sections. Do it right now because it changes the size of
// output sections.
- for (OutputSection *Sec : OutputSections)
- Sec->maybeCompress<ELFT>();
+ for (OutputSection *sec : outputSections)
+ sec->maybeCompress<ELFT>();
- Script->allocateHeaders(Main->Phdrs);
+ script->allocateHeaders(mainPart->phdrs);
// Remove empty PT_LOAD to avoid causing the dynamic linker to try to mmap a
// 0 sized region. This has to be done late since only after assignAddresses
// we know the size of the sections.
- for (Partition &Part : Partitions)
- removeEmptyPTLoad(Part.Phdrs);
+ for (Partition &part : partitions)
+ removeEmptyPTLoad(part.phdrs);
- if (!Config->OFormatBinary)
+ if (!config->oFormatBinary)
assignFileOffsets();
else
assignFileOffsetsBinary();
- for (Partition &Part : Partitions)
- setPhdrs(Part);
+ for (Partition &part : partitions)
+ setPhdrs(part);
- if (Config->Relocatable)
- for (OutputSection *Sec : OutputSections)
- Sec->Addr = 0;
+ if (config->relocatable)
+ for (OutputSection *sec : outputSections)
+ sec->addr = 0;
- if (Config->CheckSections)
+ if (config->checkSections)
checkSections();
// It does not make sense try to open the file if we have error already.
@@ -621,7 +621,7 @@ template <class ELFT> void Writer<ELFT>:
if (errorCount())
return;
- if (!Config->OFormatBinary) {
+ if (!config->oFormatBinary) {
writeTrapInstr();
writeHeader();
writeSections();
@@ -641,20 +641,20 @@ template <class ELFT> void Writer<ELFT>:
if (errorCount())
return;
- if (auto E = Buffer->commit())
- error("failed to write to the output file: " + toString(std::move(E)));
+ if (auto e = buffer->commit())
+ error("failed to write to the output file: " + toString(std::move(e)));
}
-static bool shouldKeepInSymtab(const Defined &Sym) {
- if (Sym.isSection())
+static bool shouldKeepInSymtab(const Defined &sym) {
+ if (sym.isSection())
return false;
- if (Config->Discard == DiscardPolicy::None)
+ if (config->discard == DiscardPolicy::None)
return true;
// If -emit-reloc is given, all symbols including local ones need to be
// copied because they may be referenced by relocations.
- if (Config->EmitRelocs)
+ if (config->emitRelocs)
return true;
// In ELF assembly .L symbols are normally discarded by the assembler.
@@ -662,62 +662,62 @@ static bool shouldKeepInSymtab(const Def
// * --discard-locals is used.
// * The symbol is in a SHF_MERGE section, which is normally the reason for
// the assembler keeping the .L symbol.
- StringRef Name = Sym.getName();
- bool IsLocal = Name.startswith(".L") || Name.empty();
- if (!IsLocal)
+ StringRef name = sym.getName();
+ bool isLocal = name.startswith(".L") || name.empty();
+ if (!isLocal)
return true;
- if (Config->Discard == DiscardPolicy::Locals)
+ if (config->discard == DiscardPolicy::Locals)
return false;
- SectionBase *Sec = Sym.Section;
- return !Sec || !(Sec->Flags & SHF_MERGE);
+ SectionBase *sec = sym.section;
+ return !sec || !(sec->flags & SHF_MERGE);
}
-static bool includeInSymtab(const Symbol &B) {
- if (!B.isLocal() && !B.IsUsedInRegularObj)
+static bool includeInSymtab(const Symbol &b) {
+ if (!b.isLocal() && !b.isUsedInRegularObj)
return false;
- if (auto *D = dyn_cast<Defined>(&B)) {
+ if (auto *d = dyn_cast<Defined>(&b)) {
// Always include absolute symbols.
- SectionBase *Sec = D->Section;
- if (!Sec)
+ SectionBase *sec = d->section;
+ if (!sec)
return true;
- Sec = Sec->Repl;
+ sec = sec->repl;
// Exclude symbols pointing to garbage-collected sections.
- if (isa<InputSectionBase>(Sec) && !Sec->isLive())
+ if (isa<InputSectionBase>(sec) && !sec->isLive())
return false;
- if (auto *S = dyn_cast<MergeInputSection>(Sec))
- if (!S->getSectionPiece(D->Value)->Live)
+ if (auto *s = dyn_cast<MergeInputSection>(sec))
+ if (!s->getSectionPiece(d->value)->live)
return false;
return true;
}
- return B.Used;
+ return b.used;
}
// Local symbols are not in the linker's symbol table. This function scans
// each object file's symbol table to copy local symbols to the output.
template <class ELFT> void Writer<ELFT>::copyLocalSymbols() {
- if (!In.SymTab)
+ if (!in.symTab)
return;
- for (InputFile *File : ObjectFiles) {
- ObjFile<ELFT> *F = cast<ObjFile<ELFT>>(File);
- for (Symbol *B : F->getLocalSymbols()) {
- if (!B->isLocal())
- fatal(toString(F) +
+ for (InputFile *file : objectFiles) {
+ ObjFile<ELFT> *f = cast<ObjFile<ELFT>>(file);
+ for (Symbol *b : f->getLocalSymbols()) {
+ if (!b->isLocal())
+ fatal(toString(f) +
": broken object: getLocalSymbols returns a non-local symbol");
- auto *DR = dyn_cast<Defined>(B);
+ auto *dr = dyn_cast<Defined>(b);
// No reason to keep local undefined symbol in symtab.
- if (!DR)
+ if (!dr)
continue;
- if (!includeInSymtab(*B))
+ if (!includeInSymtab(*b))
continue;
- if (!shouldKeepInSymtab(*DR))
+ if (!shouldKeepInSymtab(*dr))
continue;
- In.SymTab->addSymbol(B);
+ in.symTab->addSymbol(b);
}
}
}
@@ -727,33 +727,33 @@ template <class ELFT> void Writer<ELFT>:
// referring to a section (that happens if the section is a synthetic one), we
// don't create a section symbol for that section.
template <class ELFT> void Writer<ELFT>::addSectionSymbols() {
- for (BaseCommand *Base : Script->SectionCommands) {
- auto *Sec = dyn_cast<OutputSection>(Base);
- if (!Sec)
+ for (BaseCommand *base : script->sectionCommands) {
+ auto *sec = dyn_cast<OutputSection>(base);
+ if (!sec)
continue;
- auto I = llvm::find_if(Sec->SectionCommands, [](BaseCommand *Base) {
- if (auto *ISD = dyn_cast<InputSectionDescription>(Base))
- return !ISD->Sections.empty();
+ auto i = llvm::find_if(sec->sectionCommands, [](BaseCommand *base) {
+ if (auto *isd = dyn_cast<InputSectionDescription>(base))
+ return !isd->sections.empty();
return false;
});
- if (I == Sec->SectionCommands.end())
+ if (i == sec->sectionCommands.end())
continue;
- InputSection *IS = cast<InputSectionDescription>(*I)->Sections[0];
+ InputSection *isec = cast<InputSectionDescription>(*i)->sections[0];
// Relocations are not using REL[A] section symbols.
- if (IS->Type == SHT_REL || IS->Type == SHT_RELA)
+ if (isec->type == SHT_REL || isec->type == SHT_RELA)
continue;
// Unlike other synthetic sections, mergeable output sections contain data
// copied from input sections, and there may be a relocation pointing to its
// contents if -r or -emit-reloc are given.
- if (isa<SyntheticSection>(IS) && !(IS->Flags & SHF_MERGE))
+ if (isa<SyntheticSection>(isec) && !(isec->flags & SHF_MERGE))
continue;
- auto *Sym =
- make<Defined>(IS->File, "", STB_LOCAL, /*StOther=*/0, STT_SECTION,
- /*Value=*/0, /*Size=*/0, IS);
- In.SymTab->addSymbol(Sym);
+ auto *sym =
+ make<Defined>(isec->file, "", STB_LOCAL, /*StOther=*/0, STT_SECTION,
+ /*Value=*/0, /*Size=*/0, isec);
+ in.symTab->addSymbol(sym);
}
}
@@ -763,25 +763,25 @@ template <class ELFT> void Writer<ELFT>:
//
// This function returns true if a section needs to be put into a
// PT_GNU_RELRO segment.
-static bool isRelroSection(const OutputSection *Sec) {
- if (!Config->ZRelro)
+static bool isRelroSection(const OutputSection *sec) {
+ if (!config->zRelro)
return false;
- uint64_t Flags = Sec->Flags;
+ uint64_t flags = sec->flags;
// Non-allocatable or non-writable sections don't need RELRO because
// they are not writable or not even mapped to memory in the first place.
// RELRO is for sections that are essentially read-only but need to
// be writable only at process startup to allow dynamic linker to
// apply relocations.
- if (!(Flags & SHF_ALLOC) || !(Flags & SHF_WRITE))
+ if (!(flags & SHF_ALLOC) || !(flags & SHF_WRITE))
return false;
// Once initialized, TLS data segments are used as data templates
// for a thread-local storage. For each new thread, runtime
// allocates memory for a TLS and copy templates there. No thread
// are supposed to use templates directly. Thus, it can be in RELRO.
- if (Flags & SHF_TLS)
+ if (flags & SHF_TLS)
return true;
// .init_array, .preinit_array and .fini_array contain pointers to
@@ -790,15 +790,15 @@ static bool isRelroSection(const OutputS
// to change at runtime. But if you are an attacker, you could do
// interesting things by manipulating pointers in .fini_array, for
// example. So they are put into RELRO.
- uint32_t Type = Sec->Type;
- if (Type == SHT_INIT_ARRAY || Type == SHT_FINI_ARRAY ||
- Type == SHT_PREINIT_ARRAY)
+ uint32_t type = sec->type;
+ if (type == SHT_INIT_ARRAY || type == SHT_FINI_ARRAY ||
+ type == SHT_PREINIT_ARRAY)
return true;
// .got contains pointers to external symbols. They are resolved by
// the dynamic linker when a module is loaded into memory, and after
// that they are not expected to change. So, it can be in RELRO.
- if (In.Got && Sec == In.Got->getParent())
+ if (in.got && sec == in.got->getParent())
return true;
// .toc is a GOT-ish section for PowerPC64. Their contents are accessed
@@ -806,30 +806,30 @@ static bool isRelroSection(const OutputS
// for accessing .got as well, .got and .toc need to be close enough in the
// virtual address space. Usually, .toc comes just after .got. Since we place
// .got into RELRO, .toc needs to be placed into RELRO too.
- if (Sec->Name.equals(".toc"))
+ if (sec->name.equals(".toc"))
return true;
// .got.plt contains pointers to external function symbols. They are
// by default resolved lazily, so we usually cannot put it into RELRO.
// However, if "-z now" is given, the lazy symbol resolution is
// disabled, which enables us to put it into RELRO.
- if (Sec == In.GotPlt->getParent())
- return Config->ZNow;
+ if (sec == in.gotPlt->getParent())
+ return config->zNow;
// .dynamic section contains data for the dynamic linker, and
// there's no need to write to it at runtime, so it's better to put
// it into RELRO.
- if (Sec->Name == ".dynamic")
+ if (sec->name == ".dynamic")
return true;
// Sections with some special names are put into RELRO. This is a
// bit unfortunate because section names shouldn't be significant in
// ELF in spirit. But in reality many linker features depend on
// magic section names.
- StringRef S = Sec->Name;
- return S == ".data.rel.ro" || S == ".bss.rel.ro" || S == ".ctors" ||
- S == ".dtors" || S == ".jcr" || S == ".eh_frame" ||
- S == ".openbsd.randomdata";
+ StringRef s = sec->name;
+ return s == ".data.rel.ro" || s == ".bss.rel.ro" || s == ".ctors" ||
+ s == ".dtors" || s == ".jcr" || s == ".eh_frame" ||
+ s == ".openbsd.randomdata";
}
// We compute a rank for each section. The rank indicates where the
@@ -863,41 +863,41 @@ enum RankFlags {
RF_MIPS_NOT_GOT = 1 << 0
};
-static unsigned getSectionRank(const OutputSection *Sec) {
- unsigned Rank = Sec->Partition * RF_PARTITION;
+static unsigned getSectionRank(const OutputSection *sec) {
+ unsigned rank = sec->partition * RF_PARTITION;
// We want to put section specified by -T option first, so we
// can start assigning VA starting from them later.
- if (Config->SectionStartMap.count(Sec->Name))
- return Rank;
- Rank |= RF_NOT_ADDR_SET;
+ if (config->sectionStartMap.count(sec->name))
+ return rank;
+ rank |= RF_NOT_ADDR_SET;
// Allocatable sections go first to reduce the total PT_LOAD size and
// so debug info doesn't change addresses in actual code.
- if (!(Sec->Flags & SHF_ALLOC))
- return Rank | RF_NOT_ALLOC;
+ if (!(sec->flags & SHF_ALLOC))
+ return rank | RF_NOT_ALLOC;
- if (Sec->Type == SHT_LLVM_PART_EHDR)
- return Rank;
- Rank |= RF_NOT_PART_EHDR;
-
- if (Sec->Type == SHT_LLVM_PART_PHDR)
- return Rank;
- Rank |= RF_NOT_PART_PHDR;
+ if (sec->type == SHT_LLVM_PART_EHDR)
+ return rank;
+ rank |= RF_NOT_PART_EHDR;
+
+ if (sec->type == SHT_LLVM_PART_PHDR)
+ return rank;
+ rank |= RF_NOT_PART_PHDR;
// Put .interp first because some loaders want to see that section
// on the first page of the executable file when loaded into memory.
- if (Sec->Name == ".interp")
- return Rank;
- Rank |= RF_NOT_INTERP;
+ if (sec->name == ".interp")
+ return rank;
+ rank |= RF_NOT_INTERP;
// Put .note sections (which make up one PT_NOTE) at the beginning so that
// they are likely to be included in a core file even if core file size is
// limited. In particular, we want a .note.gnu.build-id and a .note.tag to be
// included in a core to match core files with executables.
- if (Sec->Type == SHT_NOTE)
- return Rank;
- Rank |= RF_NOT_NOTE;
+ if (sec->type == SHT_NOTE)
+ return rank;
+ rank |= RF_NOT_NOTE;
// Sort sections based on their access permission in the following
// order: R, RX, RWX, RW. This order is based on the following
@@ -910,22 +910,22 @@ static unsigned getSectionRank(const Out
// between .text and .data.
// * Writable sections come last, such that .bss lands at the very
// end of the last PT_LOAD.
- bool IsExec = Sec->Flags & SHF_EXECINSTR;
- bool IsWrite = Sec->Flags & SHF_WRITE;
+ bool isExec = sec->flags & SHF_EXECINSTR;
+ bool isWrite = sec->flags & SHF_WRITE;
- if (IsExec) {
- if (IsWrite)
- Rank |= RF_EXEC_WRITE;
+ if (isExec) {
+ if (isWrite)
+ rank |= RF_EXEC_WRITE;
else
- Rank |= RF_EXEC;
- } else if (IsWrite) {
- Rank |= RF_WRITE;
- } else if (Sec->Type == SHT_PROGBITS) {
+ rank |= RF_EXEC;
+ } else if (isWrite) {
+ rank |= RF_WRITE;
+ } else if (sec->type == SHT_PROGBITS) {
// Make non-executable and non-writable PROGBITS sections (e.g .rodata
// .eh_frame) closer to .text. They likely contain PC or GOT relative
// relocations and there could be relocation overflow if other huge sections
// (.dynstr .dynsym) were placed in between.
- Rank |= RF_RODATA;
+ rank |= RF_RODATA;
}
// Place RelRo sections first. After considering SHT_NOBITS below, the
@@ -933,8 +933,8 @@ static unsigned getSectionRank(const Out
// where | marks where page alignment happens. An alternative ordering is
// PT_LOAD(.data | PT_GNU_RELRO( .data.rel.ro .bss.rel.ro) | .bss), but it may
// waste more bytes due to 2 alignment places.
- if (!isRelroSection(Sec))
- Rank |= RF_NOT_RELRO;
+ if (!isRelroSection(sec))
+ rank |= RF_NOT_RELRO;
// If we got here we know that both A and B are in the same PT_LOAD.
@@ -942,73 +942,73 @@ static unsigned getSectionRank(const Out
// PT_LOAD, so stick TLS sections directly before the other RelRo R/W
// sections. Since p_filesz can be less than p_memsz, place NOBITS sections
// after PROGBITS.
- if (!(Sec->Flags & SHF_TLS))
- Rank |= RF_NOT_TLS;
+ if (!(sec->flags & SHF_TLS))
+ rank |= RF_NOT_TLS;
// Within TLS sections, or within other RelRo sections, or within non-RelRo
// sections, place non-NOBITS sections first.
- if (Sec->Type == SHT_NOBITS)
- Rank |= RF_BSS;
+ if (sec->type == SHT_NOBITS)
+ rank |= RF_BSS;
// Some architectures have additional ordering restrictions for sections
// within the same PT_LOAD.
- if (Config->EMachine == EM_PPC64) {
+ if (config->emachine == EM_PPC64) {
// PPC64 has a number of special SHT_PROGBITS+SHF_ALLOC+SHF_WRITE sections
// that we would like to make sure appear is a specific order to maximize
// their coverage by a single signed 16-bit offset from the TOC base
// pointer. Conversely, the special .tocbss section should be first among
// all SHT_NOBITS sections. This will put it next to the loaded special
// PPC64 sections (and, thus, within reach of the TOC base pointer).
- StringRef Name = Sec->Name;
- if (Name != ".tocbss")
- Rank |= RF_PPC_NOT_TOCBSS;
+ StringRef name = sec->name;
+ if (name != ".tocbss")
+ rank |= RF_PPC_NOT_TOCBSS;
- if (Name == ".toc1")
- Rank |= RF_PPC_TOCL;
+ if (name == ".toc1")
+ rank |= RF_PPC_TOCL;
- if (Name == ".toc")
- Rank |= RF_PPC_TOC;
+ if (name == ".toc")
+ rank |= RF_PPC_TOC;
- if (Name == ".got")
- Rank |= RF_PPC_GOT;
+ if (name == ".got")
+ rank |= RF_PPC_GOT;
- if (Name == ".branch_lt")
- Rank |= RF_PPC_BRANCH_LT;
+ if (name == ".branch_lt")
+ rank |= RF_PPC_BRANCH_LT;
}
- if (Config->EMachine == EM_MIPS) {
+ if (config->emachine == EM_MIPS) {
// All sections with SHF_MIPS_GPREL flag should be grouped together
// because data in these sections is addressable with a gp relative address.
- if (Sec->Flags & SHF_MIPS_GPREL)
- Rank |= RF_MIPS_GPREL;
+ if (sec->flags & SHF_MIPS_GPREL)
+ rank |= RF_MIPS_GPREL;
- if (Sec->Name != ".got")
- Rank |= RF_MIPS_NOT_GOT;
+ if (sec->name != ".got")
+ rank |= RF_MIPS_NOT_GOT;
}
- return Rank;
+ return rank;
}
-static bool compareSections(const BaseCommand *ACmd, const BaseCommand *BCmd) {
- const OutputSection *A = cast<OutputSection>(ACmd);
- const OutputSection *B = cast<OutputSection>(BCmd);
+static bool compareSections(const BaseCommand *aCmd, const BaseCommand *bCmd) {
+ const OutputSection *a = cast<OutputSection>(aCmd);
+ const OutputSection *b = cast<OutputSection>(bCmd);
- if (A->SortRank != B->SortRank)
- return A->SortRank < B->SortRank;
+ if (a->sortRank != b->sortRank)
+ return a->sortRank < b->sortRank;
- if (!(A->SortRank & RF_NOT_ADDR_SET))
- return Config->SectionStartMap.lookup(A->Name) <
- Config->SectionStartMap.lookup(B->Name);
+ if (!(a->sortRank & RF_NOT_ADDR_SET))
+ return config->sectionStartMap.lookup(a->name) <
+ config->sectionStartMap.lookup(b->name);
return false;
}
-void PhdrEntry::add(OutputSection *Sec) {
- LastSec = Sec;
- if (!FirstSec)
- FirstSec = Sec;
- p_align = std::max(p_align, Sec->Alignment);
+void PhdrEntry::add(OutputSection *sec) {
+ lastSec = sec;
+ if (!firstSec)
+ firstSec = sec;
+ p_align = std::max(p_align, sec->alignment);
if (p_type == PT_LOAD)
- Sec->PtLoad = this;
+ sec->ptLoad = this;
}
// The beginning and the ending of .rel[a].plt section are marked
@@ -1018,39 +1018,39 @@ void PhdrEntry::add(OutputSection *Sec)
// need these symbols, since IRELATIVE relocs are resolved through GOT
// and PLT. For details, see http://www.airs.com/blog/archives/403.
template <class ELFT> void Writer<ELFT>::addRelIpltSymbols() {
- if (Config->Relocatable || needsInterpSection())
+ if (config->relocatable || needsInterpSection())
return;
// By default, __rela_iplt_{start,end} belong to a dummy section 0
// because .rela.plt might be empty and thus removed from output.
// We'll override Out::ElfHeader with In.RelaIplt later when we are
// sure that .rela.plt exists in output.
- ElfSym::RelaIpltStart = addOptionalRegular(
- Config->IsRela ? "__rela_iplt_start" : "__rel_iplt_start",
- Out::ElfHeader, 0, STV_HIDDEN, STB_WEAK);
-
- ElfSym::RelaIpltEnd = addOptionalRegular(
- Config->IsRela ? "__rela_iplt_end" : "__rel_iplt_end",
- Out::ElfHeader, 0, STV_HIDDEN, STB_WEAK);
+ ElfSym::relaIpltStart = addOptionalRegular(
+ config->isRela ? "__rela_iplt_start" : "__rel_iplt_start",
+ Out::elfHeader, 0, STV_HIDDEN, STB_WEAK);
+
+ ElfSym::relaIpltEnd = addOptionalRegular(
+ config->isRela ? "__rela_iplt_end" : "__rel_iplt_end",
+ Out::elfHeader, 0, STV_HIDDEN, STB_WEAK);
}
template <class ELFT>
void Writer<ELFT>::forEachRelSec(
- llvm::function_ref<void(InputSectionBase &)> Fn) {
+ llvm::function_ref<void(InputSectionBase &)> fn) {
// Scan all relocations. Each relocation goes through a series
// of tests to determine if it needs special treatment, such as
// creating GOT, PLT, copy relocations, etc.
// Note that relocations for non-alloc sections are directly
// processed by InputSection::relocateNonAlloc.
- for (InputSectionBase *IS : InputSections)
- if (IS->isLive() && isa<InputSection>(IS) && (IS->Flags & SHF_ALLOC))
- Fn(*IS);
- for (Partition &Part : Partitions) {
- for (EhInputSection *ES : Part.EhFrame->Sections)
- Fn(*ES);
- if (Part.ARMExidx && Part.ARMExidx->isLive())
- for (InputSection *Ex : Part.ARMExidx->ExidxSections)
- Fn(*Ex);
+ for (InputSectionBase *isec : inputSections)
+ if (isec->isLive() && isa<InputSection>(isec) && (isec->flags & SHF_ALLOC))
+ fn(*isec);
+ for (Partition &part : partitions) {
+ for (EhInputSection *es : part.ehFrame->sections)
+ fn(*es);
+ if (part.armExidx && part.armExidx->isLive())
+ for (InputSection *ex : part.armExidx->exidxSections)
+ fn(*ex);
}
}
@@ -1060,78 +1060,78 @@ void Writer<ELFT>::forEachRelSec(
// time any references to these symbols are processed and is equivalent to
// defining these symbols explicitly in the linker script.
template <class ELFT> void Writer<ELFT>::setReservedSymbolSections() {
- if (ElfSym::GlobalOffsetTable) {
+ if (ElfSym::globalOffsetTable) {
// The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention usually
// to the start of the .got or .got.plt section.
- InputSection *GotSection = In.GotPlt;
- if (!Target->GotBaseSymInGotPlt)
- GotSection = In.MipsGot ? cast<InputSection>(In.MipsGot)
- : cast<InputSection>(In.Got);
- ElfSym::GlobalOffsetTable->Section = GotSection;
+ InputSection *gotSection = in.gotPlt;
+ if (!target->gotBaseSymInGotPlt)
+ gotSection = in.mipsGot ? cast<InputSection>(in.mipsGot)
+ : cast<InputSection>(in.got);
+ ElfSym::globalOffsetTable->section = gotSection;
}
// .rela_iplt_{start,end} mark the start and the end of .rela.plt section.
- if (ElfSym::RelaIpltStart && In.RelaIplt->isNeeded()) {
- ElfSym::RelaIpltStart->Section = In.RelaIplt;
- ElfSym::RelaIpltEnd->Section = In.RelaIplt;
- ElfSym::RelaIpltEnd->Value = In.RelaIplt->getSize();
+ if (ElfSym::relaIpltStart && in.relaIplt->isNeeded()) {
+ ElfSym::relaIpltStart->section = in.relaIplt;
+ ElfSym::relaIpltEnd->section = in.relaIplt;
+ ElfSym::relaIpltEnd->value = in.relaIplt->getSize();
}
- PhdrEntry *Last = nullptr;
- PhdrEntry *LastRO = nullptr;
-
- for (Partition &Part : Partitions) {
- for (PhdrEntry *P : Part.Phdrs) {
- if (P->p_type != PT_LOAD)
+ PhdrEntry *last = nullptr;
+ PhdrEntry *lastRO = nullptr;
+
+ for (Partition &part : partitions) {
+ for (PhdrEntry *p : part.phdrs) {
+ if (p->p_type != PT_LOAD)
continue;
- Last = P;
- if (!(P->p_flags & PF_W))
- LastRO = P;
+ last = p;
+ if (!(p->p_flags & PF_W))
+ lastRO = p;
}
}
- if (LastRO) {
+ if (lastRO) {
// _etext is the first location after the last read-only loadable segment.
- if (ElfSym::Etext1)
- ElfSym::Etext1->Section = LastRO->LastSec;
- if (ElfSym::Etext2)
- ElfSym::Etext2->Section = LastRO->LastSec;
+ if (ElfSym::etext1)
+ ElfSym::etext1->section = lastRO->lastSec;
+ if (ElfSym::etext2)
+ ElfSym::etext2->section = lastRO->lastSec;
}
- if (Last) {
+ if (last) {
// _edata points to the end of the last mapped initialized section.
- OutputSection *Edata = nullptr;
- for (OutputSection *OS : OutputSections) {
- if (OS->Type != SHT_NOBITS)
- Edata = OS;
- if (OS == Last->LastSec)
+ OutputSection *edata = nullptr;
+ for (OutputSection *os : outputSections) {
+ if (os->type != SHT_NOBITS)
+ edata = os;
+ if (os == last->lastSec)
break;
}
- if (ElfSym::Edata1)
- ElfSym::Edata1->Section = Edata;
- if (ElfSym::Edata2)
- ElfSym::Edata2->Section = Edata;
+ if (ElfSym::edata1)
+ ElfSym::edata1->section = edata;
+ if (ElfSym::edata2)
+ ElfSym::edata2->section = edata;
// _end is the first location after the uninitialized data region.
- if (ElfSym::End1)
- ElfSym::End1->Section = Last->LastSec;
- if (ElfSym::End2)
- ElfSym::End2->Section = Last->LastSec;
+ if (ElfSym::end1)
+ ElfSym::end1->section = last->lastSec;
+ if (ElfSym::end2)
+ ElfSym::end2->section = last->lastSec;
}
- if (ElfSym::Bss)
- ElfSym::Bss->Section = findSection(".bss");
+ if (ElfSym::bss)
+ ElfSym::bss->section = findSection(".bss");
// Setup MIPS _gp_disp/__gnu_local_gp symbols which should
// be equal to the _gp symbol's value.
- if (ElfSym::MipsGp) {
+ if (ElfSym::mipsGp) {
// Find GP-relative section with the lowest address
// and use this address to calculate default _gp value.
- for (OutputSection *OS : OutputSections) {
- if (OS->Flags & SHF_MIPS_GPREL) {
- ElfSym::MipsGp->Section = OS;
- ElfSym::MipsGp->Value = 0x7ff0;
+ for (OutputSection *os : outputSections) {
+ if (os->flags & SHF_MIPS_GPREL) {
+ ElfSym::mipsGp->section = os;
+ ElfSym::mipsGp->value = 0x7ff0;
break;
}
}
@@ -1142,13 +1142,13 @@ template <class ELFT> void Writer<ELFT>:
// The more branches in getSectionRank that match, the more similar they are.
// Since each branch corresponds to a bit flag, we can just use
// countLeadingZeros.
-static int getRankProximityAux(OutputSection *A, OutputSection *B) {
- return countLeadingZeros(A->SortRank ^ B->SortRank);
+static int getRankProximityAux(OutputSection *a, OutputSection *b) {
+ return countLeadingZeros(a->sortRank ^ b->sortRank);
}
-static int getRankProximity(OutputSection *A, BaseCommand *B) {
- auto *Sec = dyn_cast<OutputSection>(B);
- return (Sec && Sec->HasInputSections) ? getRankProximityAux(A, Sec) : -1;
+static int getRankProximity(OutputSection *a, BaseCommand *b) {
+ auto *sec = dyn_cast<OutputSection>(b);
+ return (sec && sec->hasInputSections) ? getRankProximityAux(a, sec) : -1;
}
// When placing orphan sections, we want to place them after symbol assignments
@@ -1165,9 +1165,9 @@ static int getRankProximity(OutputSectio
// /* The RW PT_LOAD starts here*/
// rw_sec : { *(rw_sec) }
// would mean that the RW PT_LOAD would become unaligned.
-static bool shouldSkip(BaseCommand *Cmd) {
- if (auto *Assign = dyn_cast<SymbolAssignment>(Cmd))
- return Assign->Name != ".";
+static bool shouldSkip(BaseCommand *cmd) {
+ if (auto *assign = dyn_cast<SymbolAssignment>(cmd))
+ return assign->name != ".";
return false;
}
@@ -1175,132 +1175,132 @@ static bool shouldSkip(BaseCommand *Cmd)
// characteristics with their neighbors as possible. For example, if
// both are rw, or both are tls.
static std::vector<BaseCommand *>::iterator
-findOrphanPos(std::vector<BaseCommand *>::iterator B,
- std::vector<BaseCommand *>::iterator E) {
- OutputSection *Sec = cast<OutputSection>(*E);
+findOrphanPos(std::vector<BaseCommand *>::iterator b,
+ std::vector<BaseCommand *>::iterator e) {
+ OutputSection *sec = cast<OutputSection>(*e);
// Find the first element that has as close a rank as possible.
- auto I = std::max_element(B, E, [=](BaseCommand *A, BaseCommand *B) {
- return getRankProximity(Sec, A) < getRankProximity(Sec, B);
+ auto i = std::max_element(b, e, [=](BaseCommand *a, BaseCommand *b) {
+ return getRankProximity(sec, a) < getRankProximity(sec, b);
});
- if (I == E)
- return E;
+ if (i == e)
+ return e;
// Consider all existing sections with the same proximity.
- int Proximity = getRankProximity(Sec, *I);
- for (; I != E; ++I) {
- auto *CurSec = dyn_cast<OutputSection>(*I);
- if (!CurSec || !CurSec->HasInputSections)
+ int proximity = getRankProximity(sec, *i);
+ for (; i != e; ++i) {
+ auto *curSec = dyn_cast<OutputSection>(*i);
+ if (!curSec || !curSec->hasInputSections)
continue;
- if (getRankProximity(Sec, CurSec) != Proximity ||
- Sec->SortRank < CurSec->SortRank)
+ if (getRankProximity(sec, curSec) != proximity ||
+ sec->sortRank < curSec->sortRank)
break;
}
- auto IsOutputSecWithInputSections = [](BaseCommand *Cmd) {
- auto *OS = dyn_cast<OutputSection>(Cmd);
- return OS && OS->HasInputSections;
+ auto isOutputSecWithInputSections = [](BaseCommand *cmd) {
+ auto *os = dyn_cast<OutputSection>(cmd);
+ return os && os->hasInputSections;
};
- auto J = std::find_if(llvm::make_reverse_iterator(I),
- llvm::make_reverse_iterator(B),
- IsOutputSecWithInputSections);
- I = J.base();
+ auto j = std::find_if(llvm::make_reverse_iterator(i),
+ llvm::make_reverse_iterator(b),
+ isOutputSecWithInputSections);
+ i = j.base();
// As a special case, if the orphan section is the last section, put
// it at the very end, past any other commands.
// This matches bfd's behavior and is convenient when the linker script fully
// specifies the start of the file, but doesn't care about the end (the non
// alloc sections for example).
- auto NextSec = std::find_if(I, E, IsOutputSecWithInputSections);
- if (NextSec == E)
- return E;
-
- while (I != E && shouldSkip(*I))
- ++I;
- return I;
+ auto nextSec = std::find_if(i, e, isOutputSecWithInputSections);
+ if (nextSec == e)
+ return e;
+
+ while (i != e && shouldSkip(*i))
+ ++i;
+ return i;
}
// Builds section order for handling --symbol-ordering-file.
static DenseMap<const InputSectionBase *, int> buildSectionOrder() {
- DenseMap<const InputSectionBase *, int> SectionOrder;
+ DenseMap<const InputSectionBase *, int> sectionOrder;
// Use the rarely used option -call-graph-ordering-file to sort sections.
- if (!Config->CallGraphProfile.empty())
+ if (!config->callGraphProfile.empty())
return computeCallGraphProfileOrder();
- if (Config->SymbolOrderingFile.empty())
- return SectionOrder;
+ if (config->symbolOrderingFile.empty())
+ return sectionOrder;
struct SymbolOrderEntry {
- int Priority;
- bool Present;
+ int priority;
+ bool present;
};
// Build a map from symbols to their priorities. Symbols that didn't
// appear in the symbol ordering file have the lowest priority 0.
// All explicitly mentioned symbols have negative (higher) priorities.
- DenseMap<StringRef, SymbolOrderEntry> SymbolOrder;
- int Priority = -Config->SymbolOrderingFile.size();
- for (StringRef S : Config->SymbolOrderingFile)
- SymbolOrder.insert({S, {Priority++, false}});
+ DenseMap<StringRef, SymbolOrderEntry> symbolOrder;
+ int priority = -config->symbolOrderingFile.size();
+ for (StringRef s : config->symbolOrderingFile)
+ symbolOrder.insert({s, {priority++, false}});
// Build a map from sections to their priorities.
- auto AddSym = [&](Symbol &Sym) {
- auto It = SymbolOrder.find(Sym.getName());
- if (It == SymbolOrder.end())
+ auto addSym = [&](Symbol &sym) {
+ auto it = symbolOrder.find(sym.getName());
+ if (it == symbolOrder.end())
return;
- SymbolOrderEntry &Ent = It->second;
- Ent.Present = true;
+ SymbolOrderEntry &ent = it->second;
+ ent.present = true;
- maybeWarnUnorderableSymbol(&Sym);
+ maybeWarnUnorderableSymbol(&sym);
- if (auto *D = dyn_cast<Defined>(&Sym)) {
- if (auto *Sec = dyn_cast_or_null<InputSectionBase>(D->Section)) {
- int &Priority = SectionOrder[cast<InputSectionBase>(Sec->Repl)];
- Priority = std::min(Priority, Ent.Priority);
+ if (auto *d = dyn_cast<Defined>(&sym)) {
+ if (auto *sec = dyn_cast_or_null<InputSectionBase>(d->section)) {
+ int &priority = sectionOrder[cast<InputSectionBase>(sec->repl)];
+ priority = std::min(priority, ent.priority);
}
}
};
// We want both global and local symbols. We get the global ones from the
// symbol table and iterate the object files for the local ones.
- Symtab->forEachSymbol([&](Symbol *Sym) {
- if (!Sym->isLazy())
- AddSym(*Sym);
+ symtab->forEachSymbol([&](Symbol *sym) {
+ if (!sym->isLazy())
+ addSym(*sym);
});
- for (InputFile *File : ObjectFiles)
- for (Symbol *Sym : File->getSymbols())
- if (Sym->isLocal())
- AddSym(*Sym);
-
- if (Config->WarnSymbolOrdering)
- for (auto OrderEntry : SymbolOrder)
- if (!OrderEntry.second.Present)
- warn("symbol ordering file: no such symbol: " + OrderEntry.first);
+ for (InputFile *file : objectFiles)
+ for (Symbol *sym : file->getSymbols())
+ if (sym->isLocal())
+ addSym(*sym);
+
+ if (config->warnSymbolOrdering)
+ for (auto orderEntry : symbolOrder)
+ if (!orderEntry.second.present)
+ warn("symbol ordering file: no such symbol: " + orderEntry.first);
- return SectionOrder;
+ return sectionOrder;
}
// Sorts the sections in ISD according to the provided section order.
static void
-sortISDBySectionOrder(InputSectionDescription *ISD,
- const DenseMap<const InputSectionBase *, int> &Order) {
- std::vector<InputSection *> UnorderedSections;
- std::vector<std::pair<InputSection *, int>> OrderedSections;
- uint64_t UnorderedSize = 0;
-
- for (InputSection *IS : ISD->Sections) {
- auto I = Order.find(IS);
- if (I == Order.end()) {
- UnorderedSections.push_back(IS);
- UnorderedSize += IS->getSize();
+sortISDBySectionOrder(InputSectionDescription *isd,
+ const DenseMap<const InputSectionBase *, int> &order) {
+ std::vector<InputSection *> unorderedSections;
+ std::vector<std::pair<InputSection *, int>> orderedSections;
+ uint64_t unorderedSize = 0;
+
+ for (InputSection *isec : isd->sections) {
+ auto i = order.find(isec);
+ if (i == order.end()) {
+ unorderedSections.push_back(isec);
+ unorderedSize += isec->getSize();
continue;
}
- OrderedSections.push_back({IS, I->second});
+ orderedSections.push_back({isec, i->second});
}
- llvm::sort(OrderedSections, [&](std::pair<InputSection *, int> A,
- std::pair<InputSection *, int> B) {
- return A.second < B.second;
+ llvm::sort(orderedSections, [&](std::pair<InputSection *, int> a,
+ std::pair<InputSection *, int> b) {
+ return a.second < b.second;
});
// Find an insertion point for the ordered section list in the unordered
@@ -1330,46 +1330,46 @@ sortISDBySectionOrder(InputSectionDescri
// of the second block of cold code can call the hot code without a thunk. So
// we effectively double the amount of code that could potentially call into
// the hot code without a thunk.
- size_t InsPt = 0;
- if (Target->getThunkSectionSpacing() && !OrderedSections.empty()) {
- uint64_t UnorderedPos = 0;
- for (; InsPt != UnorderedSections.size(); ++InsPt) {
- UnorderedPos += UnorderedSections[InsPt]->getSize();
- if (UnorderedPos > UnorderedSize / 2)
+ size_t insPt = 0;
+ if (target->getThunkSectionSpacing() && !orderedSections.empty()) {
+ uint64_t unorderedPos = 0;
+ for (; insPt != unorderedSections.size(); ++insPt) {
+ unorderedPos += unorderedSections[insPt]->getSize();
+ if (unorderedPos > unorderedSize / 2)
break;
}
}
- ISD->Sections.clear();
- for (InputSection *IS : makeArrayRef(UnorderedSections).slice(0, InsPt))
- ISD->Sections.push_back(IS);
- for (std::pair<InputSection *, int> P : OrderedSections)
- ISD->Sections.push_back(P.first);
- for (InputSection *IS : makeArrayRef(UnorderedSections).slice(InsPt))
- ISD->Sections.push_back(IS);
+ isd->sections.clear();
+ for (InputSection *isec : makeArrayRef(unorderedSections).slice(0, insPt))
+ isd->sections.push_back(isec);
+ for (std::pair<InputSection *, int> p : orderedSections)
+ isd->sections.push_back(p.first);
+ for (InputSection *isec : makeArrayRef(unorderedSections).slice(insPt))
+ isd->sections.push_back(isec);
}
-static void sortSection(OutputSection *Sec,
- const DenseMap<const InputSectionBase *, int> &Order) {
- StringRef Name = Sec->Name;
+static void sortSection(OutputSection *sec,
+ const DenseMap<const InputSectionBase *, int> &order) {
+ StringRef name = sec->name;
// Sort input sections by section name suffixes for
// __attribute__((init_priority(N))).
- if (Name == ".init_array" || Name == ".fini_array") {
- if (!Script->HasSectionsCommand)
- Sec->sortInitFini();
+ if (name == ".init_array" || name == ".fini_array") {
+ if (!script->hasSectionsCommand)
+ sec->sortInitFini();
return;
}
// Sort input sections by the special rule for .ctors and .dtors.
- if (Name == ".ctors" || Name == ".dtors") {
- if (!Script->HasSectionsCommand)
- Sec->sortCtorsDtors();
+ if (name == ".ctors" || name == ".dtors") {
+ if (!script->hasSectionsCommand)
+ sec->sortCtorsDtors();
return;
}
// Never sort these.
- if (Name == ".init" || Name == ".fini")
+ if (name == ".init" || name == ".fini")
return;
// .toc is allocated just after .got and is accessed using GOT-relative
@@ -1377,67 +1377,67 @@ static void sortSection(OutputSection *S
// addressable range of [.got, .got + 0xFFFC] for GOT-relative relocations.
// To reduce the risk of relocation overflow, .toc contents are sorted so that
// sections having smaller relocation offsets are at beginning of .toc
- if (Config->EMachine == EM_PPC64 && Name == ".toc") {
- if (Script->HasSectionsCommand)
+ if (config->emachine == EM_PPC64 && name == ".toc") {
+ if (script->hasSectionsCommand)
return;
- assert(Sec->SectionCommands.size() == 1);
- auto *ISD = cast<InputSectionDescription>(Sec->SectionCommands[0]);
- llvm::stable_sort(ISD->Sections,
- [](const InputSection *A, const InputSection *B) -> bool {
- return A->File->PPC64SmallCodeModelTocRelocs &&
- !B->File->PPC64SmallCodeModelTocRelocs;
+ assert(sec->sectionCommands.size() == 1);
+ auto *isd = cast<InputSectionDescription>(sec->sectionCommands[0]);
+ llvm::stable_sort(isd->sections,
+ [](const InputSection *a, const InputSection *b) -> bool {
+ return a->file->ppc64SmallCodeModelTocRelocs &&
+ !b->file->ppc64SmallCodeModelTocRelocs;
});
return;
}
// Sort input sections by priority using the list provided
// by --symbol-ordering-file.
- if (!Order.empty())
- for (BaseCommand *B : Sec->SectionCommands)
- if (auto *ISD = dyn_cast<InputSectionDescription>(B))
- sortISDBySectionOrder(ISD, Order);
+ if (!order.empty())
+ for (BaseCommand *b : sec->sectionCommands)
+ if (auto *isd = dyn_cast<InputSectionDescription>(b))
+ sortISDBySectionOrder(isd, order);
}
// If no layout was provided by linker script, we want to apply default
// sorting for special input sections. This also handles --symbol-ordering-file.
template <class ELFT> void Writer<ELFT>::sortInputSections() {
// Build the order once since it is expensive.
- DenseMap<const InputSectionBase *, int> Order = buildSectionOrder();
- for (BaseCommand *Base : Script->SectionCommands)
- if (auto *Sec = dyn_cast<OutputSection>(Base))
- sortSection(Sec, Order);
+ DenseMap<const InputSectionBase *, int> order = buildSectionOrder();
+ for (BaseCommand *base : script->sectionCommands)
+ if (auto *sec = dyn_cast<OutputSection>(base))
+ sortSection(sec, order);
}
template <class ELFT> void Writer<ELFT>::sortSections() {
- Script->adjustSectionsBeforeSorting();
+ script->adjustSectionsBeforeSorting();
// Don't sort if using -r. It is not necessary and we want to preserve the
// relative order for SHF_LINK_ORDER sections.
- if (Config->Relocatable)
+ if (config->relocatable)
return;
sortInputSections();
- for (BaseCommand *Base : Script->SectionCommands) {
- auto *OS = dyn_cast<OutputSection>(Base);
- if (!OS)
+ for (BaseCommand *base : script->sectionCommands) {
+ auto *os = dyn_cast<OutputSection>(base);
+ if (!os)
continue;
- OS->SortRank = getSectionRank(OS);
+ os->sortRank = getSectionRank(os);
// We want to assign rude approximation values to OutSecOff fields
// to know the relative order of the input sections. We use it for
// sorting SHF_LINK_ORDER sections. See resolveShfLinkOrder().
- uint64_t I = 0;
- for (InputSection *Sec : getInputSections(OS))
- Sec->OutSecOff = I++;
+ uint64_t i = 0;
+ for (InputSection *sec : getInputSections(os))
+ sec->outSecOff = i++;
}
- if (!Script->HasSectionsCommand) {
+ if (!script->hasSectionsCommand) {
// We know that all the OutputSections are contiguous in this case.
- auto IsSection = [](BaseCommand *Base) { return isa<OutputSection>(Base); };
+ auto isSection = [](BaseCommand *base) { return isa<OutputSection>(base); };
std::stable_sort(
- llvm::find_if(Script->SectionCommands, IsSection),
- llvm::find_if(llvm::reverse(Script->SectionCommands), IsSection).base(),
+ llvm::find_if(script->sectionCommands, isSection),
+ llvm::find_if(llvm::reverse(script->sectionCommands), isSection).base(),
compareSections);
return;
}
@@ -1481,84 +1481,84 @@ template <class ELFT> void Writer<ELFT>:
// after another commands. For the details, look at shouldSkip
// function.
- auto I = Script->SectionCommands.begin();
- auto E = Script->SectionCommands.end();
- auto NonScriptI = std::find_if(I, E, [](BaseCommand *Base) {
- if (auto *Sec = dyn_cast<OutputSection>(Base))
- return Sec->SectionIndex == UINT32_MAX;
+ auto i = script->sectionCommands.begin();
+ auto e = script->sectionCommands.end();
+ auto nonScriptI = std::find_if(i, e, [](BaseCommand *base) {
+ if (auto *sec = dyn_cast<OutputSection>(base))
+ return sec->sectionIndex == UINT32_MAX;
return false;
});
// Sort the orphan sections.
- std::stable_sort(NonScriptI, E, compareSections);
+ std::stable_sort(nonScriptI, e, compareSections);
// As a horrible special case, skip the first . assignment if it is before any
// section. We do this because it is common to set a load address by starting
// the script with ". = 0xabcd" and the expectation is that every section is
// after that.
- auto FirstSectionOrDotAssignment =
- std::find_if(I, E, [](BaseCommand *Cmd) { return !shouldSkip(Cmd); });
- if (FirstSectionOrDotAssignment != E &&
- isa<SymbolAssignment>(**FirstSectionOrDotAssignment))
- ++FirstSectionOrDotAssignment;
- I = FirstSectionOrDotAssignment;
-
- while (NonScriptI != E) {
- auto Pos = findOrphanPos(I, NonScriptI);
- OutputSection *Orphan = cast<OutputSection>(*NonScriptI);
+ auto firstSectionOrDotAssignment =
+ std::find_if(i, e, [](BaseCommand *cmd) { return !shouldSkip(cmd); });
+ if (firstSectionOrDotAssignment != e &&
+ isa<SymbolAssignment>(**firstSectionOrDotAssignment))
+ ++firstSectionOrDotAssignment;
+ i = firstSectionOrDotAssignment;
+
+ while (nonScriptI != e) {
+ auto pos = findOrphanPos(i, nonScriptI);
+ OutputSection *orphan = cast<OutputSection>(*nonScriptI);
// As an optimization, find all sections with the same sort rank
// and insert them with one rotate.
- unsigned Rank = Orphan->SortRank;
- auto End = std::find_if(NonScriptI + 1, E, [=](BaseCommand *Cmd) {
- return cast<OutputSection>(Cmd)->SortRank != Rank;
+ unsigned rank = orphan->sortRank;
+ auto end = std::find_if(nonScriptI + 1, e, [=](BaseCommand *cmd) {
+ return cast<OutputSection>(cmd)->sortRank != rank;
});
- std::rotate(Pos, NonScriptI, End);
- NonScriptI = End;
+ std::rotate(pos, nonScriptI, end);
+ nonScriptI = end;
}
- Script->adjustSectionsAfterSorting();
+ script->adjustSectionsAfterSorting();
}
-static bool compareByFilePosition(InputSection *A, InputSection *B) {
- InputSection *LA = A->getLinkOrderDep();
- InputSection *LB = B->getLinkOrderDep();
- OutputSection *AOut = LA->getParent();
- OutputSection *BOut = LB->getParent();
+static bool compareByFilePosition(InputSection *a, InputSection *b) {
+ InputSection *la = a->getLinkOrderDep();
+ InputSection *lb = b->getLinkOrderDep();
+ OutputSection *aOut = la->getParent();
+ OutputSection *bOut = lb->getParent();
- if (AOut != BOut)
- return AOut->SectionIndex < BOut->SectionIndex;
- return LA->OutSecOff < LB->OutSecOff;
+ if (aOut != bOut)
+ return aOut->sectionIndex < bOut->sectionIndex;
+ return la->outSecOff < lb->outSecOff;
}
template <class ELFT> void Writer<ELFT>::resolveShfLinkOrder() {
- for (OutputSection *Sec : OutputSections) {
- if (!(Sec->Flags & SHF_LINK_ORDER))
+ for (OutputSection *sec : outputSections) {
+ if (!(sec->flags & SHF_LINK_ORDER))
continue;
// Link order may be distributed across several InputSectionDescriptions
// but sort must consider them all at once.
- std::vector<InputSection **> ScriptSections;
- std::vector<InputSection *> Sections;
- for (BaseCommand *Base : Sec->SectionCommands) {
- if (auto *ISD = dyn_cast<InputSectionDescription>(Base)) {
- for (InputSection *&IS : ISD->Sections) {
- ScriptSections.push_back(&IS);
- Sections.push_back(IS);
+ std::vector<InputSection **> scriptSections;
+ std::vector<InputSection *> sections;
+ for (BaseCommand *base : sec->sectionCommands) {
+ if (auto *isd = dyn_cast<InputSectionDescription>(base)) {
+ for (InputSection *&isec : isd->sections) {
+ scriptSections.push_back(&isec);
+ sections.push_back(isec);
}
}
}
// The ARM.exidx section use SHF_LINK_ORDER, but we have consolidated
// this processing inside the ARMExidxsyntheticsection::finalizeContents().
- if (!Config->Relocatable && Config->EMachine == EM_ARM &&
- Sec->Type == SHT_ARM_EXIDX)
+ if (!config->relocatable && config->emachine == EM_ARM &&
+ sec->type == SHT_ARM_EXIDX)
continue;
- llvm::stable_sort(Sections, compareByFilePosition);
+ llvm::stable_sort(sections, compareByFilePosition);
- for (int I = 0, N = Sections.size(); I < N; ++I)
- *ScriptSections[I] = Sections[I];
+ for (int i = 0, n = sections.size(); i < n; ++i)
+ *scriptSections[i] = sections[i];
}
}
@@ -1567,41 +1567,41 @@ template <class ELFT> void Writer<ELFT>:
// addresses we must converge to a fixed point. We do that here. See the comment
// in Writer<ELFT>::finalizeSections().
template <class ELFT> void Writer<ELFT>::finalizeAddressDependentContent() {
- ThunkCreator TC;
- AArch64Err843419Patcher A64P;
+ ThunkCreator tc;
+ AArch64Err843419Patcher a64p;
// For some targets, like x86, this loop iterates only once.
for (;;) {
- bool Changed = false;
+ bool changed = false;
- Script->assignAddresses();
+ script->assignAddresses();
- if (Target->NeedsThunks)
- Changed |= TC.createThunks(OutputSections);
+ if (target->needsThunks)
+ changed |= tc.createThunks(outputSections);
- if (Config->FixCortexA53Errata843419) {
- if (Changed)
- Script->assignAddresses();
- Changed |= A64P.createFixes();
+ if (config->fixCortexA53Errata843419) {
+ if (changed)
+ script->assignAddresses();
+ changed |= a64p.createFixes();
}
- if (In.MipsGot)
- In.MipsGot->updateAllocSize();
+ if (in.mipsGot)
+ in.mipsGot->updateAllocSize();
- for (Partition &Part : Partitions) {
- Changed |= Part.RelaDyn->updateAllocSize();
- if (Part.RelrDyn)
- Changed |= Part.RelrDyn->updateAllocSize();
+ for (Partition &part : partitions) {
+ changed |= part.relaDyn->updateAllocSize();
+ if (part.relrDyn)
+ changed |= part.relrDyn->updateAllocSize();
}
- if (!Changed)
+ if (!changed)
return;
}
}
-static void finalizeSynthetic(SyntheticSection *Sec) {
- if (Sec && Sec->isNeeded() && Sec->getParent())
- Sec->finalizeContents();
+static void finalizeSynthetic(SyntheticSection *sec) {
+ if (sec && sec->isNeeded() && sec->getParent())
+ sec->finalizeContents();
}
// In order to allow users to manipulate linker-synthesized sections,
@@ -1620,90 +1620,90 @@ static void removeUnusedSyntheticSection
// All input synthetic sections that can be empty are placed after
// all regular ones. We iterate over them all and exit at first
// non-synthetic.
- for (InputSectionBase *S : llvm::reverse(InputSections)) {
- SyntheticSection *SS = dyn_cast<SyntheticSection>(S);
- if (!SS)
+ for (InputSectionBase *s : llvm::reverse(inputSections)) {
+ SyntheticSection *ss = dyn_cast<SyntheticSection>(s);
+ if (!ss)
return;
- OutputSection *OS = SS->getParent();
- if (!OS || SS->isNeeded())
+ OutputSection *os = ss->getParent();
+ if (!os || ss->isNeeded())
continue;
// If we reach here, then SS is an unused synthetic section and we want to
// remove it from corresponding input section description of output section.
- for (BaseCommand *B : OS->SectionCommands)
- if (auto *ISD = dyn_cast<InputSectionDescription>(B))
- llvm::erase_if(ISD->Sections,
- [=](InputSection *IS) { return IS == SS; });
+ for (BaseCommand *b : os->sectionCommands)
+ if (auto *isd = dyn_cast<InputSectionDescription>(b))
+ llvm::erase_if(isd->sections,
+ [=](InputSection *isec) { return isec == ss; });
}
}
// Returns true if a symbol can be replaced at load-time by a symbol
// with the same name defined in other ELF executable or DSO.
-static bool computeIsPreemptible(const Symbol &B) {
- assert(!B.isLocal());
+static bool computeIsPreemptible(const Symbol &b) {
+ assert(!b.isLocal());
// Only symbols that appear in dynsym can be preempted.
- if (!B.includeInDynsym())
+ if (!b.includeInDynsym())
return false;
// Only default visibility symbols can be preempted.
- if (B.Visibility != STV_DEFAULT)
+ if (b.visibility != STV_DEFAULT)
return false;
// At this point copy relocations have not been created yet, so any
// symbol that is not defined locally is preemptible.
- if (!B.isDefined())
+ if (!b.isDefined())
return true;
// If we have a dynamic list it specifies which local symbols are preemptible.
- if (Config->HasDynamicList)
+ if (config->hasDynamicList)
return false;
- if (!Config->Shared)
+ if (!config->shared)
return false;
// -Bsymbolic means that definitions are not preempted.
- if (Config->Bsymbolic || (Config->BsymbolicFunctions && B.isFunc()))
+ if (config->bsymbolic || (config->bsymbolicFunctions && b.isFunc()))
return false;
return true;
}
// Create output section objects and add them to OutputSections.
template <class ELFT> void Writer<ELFT>::finalizeSections() {
- Out::PreinitArray = findSection(".preinit_array");
- Out::InitArray = findSection(".init_array");
- Out::FiniArray = findSection(".fini_array");
+ Out::preinitArray = findSection(".preinit_array");
+ Out::initArray = findSection(".init_array");
+ Out::finiArray = findSection(".fini_array");
// The linker needs to define SECNAME_start, SECNAME_end and SECNAME_stop
// symbols for sections, so that the runtime can get the start and end
// addresses of each section by section name. Add such symbols.
- if (!Config->Relocatable) {
+ if (!config->relocatable) {
addStartEndSymbols();
- for (BaseCommand *Base : Script->SectionCommands)
- if (auto *Sec = dyn_cast<OutputSection>(Base))
- addStartStopSymbols(Sec);
+ for (BaseCommand *base : script->sectionCommands)
+ if (auto *sec = dyn_cast<OutputSection>(base))
+ addStartStopSymbols(sec);
}
// Add _DYNAMIC symbol. Unlike GNU gold, our _DYNAMIC symbol has no type.
// It should be okay as no one seems to care about the type.
// Even the author of gold doesn't remember why gold behaves that way.
// https://sourceware.org/ml/binutils/2002-03/msg00360.html
- if (Main->Dynamic->Parent)
- Symtab->addSymbol(Defined{/*File=*/nullptr, "_DYNAMIC", STB_WEAK,
+ if (mainPart->dynamic->parent)
+ symtab->addSymbol(Defined{/*File=*/nullptr, "_DYNAMIC", STB_WEAK,
STV_HIDDEN, STT_NOTYPE,
- /*Value=*/0, /*Size=*/0, Main->Dynamic});
+ /*Value=*/0, /*Size=*/0, mainPart->dynamic});
// Define __rel[a]_iplt_{start,end} symbols if needed.
addRelIpltSymbols();
// RISC-V's gp can address +/- 2 KiB, set it to .sdata + 0x800 if not defined.
// This symbol should only be defined in an executable.
- if (Config->EMachine == EM_RISCV && !Config->Shared)
- ElfSym::RISCVGlobalPointer =
+ if (config->emachine == EM_RISCV && !config->shared)
+ ElfSym::riscvGlobalPointer =
addOptionalRegular("__global_pointer$", findSection(".sdata"), 0x800,
STV_DEFAULT, STB_GLOBAL);
- if (Config->EMachine == EM_X86_64) {
+ if (config->emachine == EM_X86_64) {
// On targets that support TLSDESC, _TLS_MODULE_BASE_ is defined in such a
// way that:
//
@@ -1715,41 +1715,41 @@ template <class ELFT> void Writer<ELFT>:
// 2) is special cased in @tpoff computation. To satisfy 1), we define it as
// an absolute symbol of zero. This is different from GNU linkers which
// define _TLS_MODULE_BASE_ relative to the first TLS section.
- Symbol *S = Symtab->find("_TLS_MODULE_BASE_");
- if (S && S->isUndefined()) {
- S->resolve(Defined{/*File=*/nullptr, S->getName(), STB_GLOBAL, STV_HIDDEN,
+ Symbol *s = symtab->find("_TLS_MODULE_BASE_");
+ if (s && s->isUndefined()) {
+ s->resolve(Defined{/*File=*/nullptr, s->getName(), STB_GLOBAL, STV_HIDDEN,
STT_TLS, /*Value=*/0, 0,
/*Section=*/nullptr});
- ElfSym::TlsModuleBase = cast<Defined>(S);
+ ElfSym::tlsModuleBase = cast<Defined>(s);
}
}
// This responsible for splitting up .eh_frame section into
// pieces. The relocation scan uses those pieces, so this has to be
// earlier.
- for (Partition &Part : Partitions)
- finalizeSynthetic(Part.EhFrame);
+ for (Partition &part : partitions)
+ finalizeSynthetic(part.ehFrame);
- Symtab->forEachSymbol([](Symbol *S) {
- if (!S->IsPreemptible)
- S->IsPreemptible = computeIsPreemptible(*S);
+ symtab->forEachSymbol([](Symbol *s) {
+ if (!s->isPreemptible)
+ s->isPreemptible = computeIsPreemptible(*s);
});
// Scan relocations. This must be done after every symbol is declared so that
// we can correctly decide if a dynamic relocation is needed.
- if (!Config->Relocatable) {
+ if (!config->relocatable) {
forEachRelSec(scanRelocations<ELFT>);
reportUndefinedSymbols<ELFT>();
}
addIRelativeRelocs();
- if (In.Plt && In.Plt->isNeeded())
- In.Plt->addSymbols();
- if (In.Iplt && In.Iplt->isNeeded())
- In.Iplt->addSymbols();
+ if (in.plt && in.plt->isNeeded())
+ in.plt->addSymbols();
+ if (in.iplt && in.iplt->isNeeded())
+ in.iplt->addSymbols();
- if (!Config->AllowShlibUndefined) {
+ if (!config->allowShlibUndefined) {
// Error on undefined symbols in a shared object, if all of its DT_NEEDED
// entires are seen. These cases would otherwise lead to runtime errors
// reported by the dynamic linker.
@@ -1757,53 +1757,53 @@ template <class ELFT> void Writer<ELFT>:
// ld.bfd traces all DT_NEEDED to emulate the logic of the dynamic linker to
// catch more cases. That is too much for us. Our approach resembles the one
// used in ld.gold, achieves a good balance to be useful but not too smart.
- for (SharedFile *File : SharedFiles)
- File->AllNeededIsKnown =
- llvm::all_of(File->DtNeeded, [&](StringRef Needed) {
- return Symtab->SoNames.count(Needed);
+ for (SharedFile *file : sharedFiles)
+ file->allNeededIsKnown =
+ llvm::all_of(file->dtNeeded, [&](StringRef needed) {
+ return symtab->soNames.count(needed);
});
- Symtab->forEachSymbol([](Symbol *Sym) {
- if (Sym->isUndefined() && !Sym->isWeak())
- if (auto *F = dyn_cast_or_null<SharedFile>(Sym->File))
- if (F->AllNeededIsKnown)
- error(toString(F) + ": undefined reference to " + toString(*Sym));
+ symtab->forEachSymbol([](Symbol *sym) {
+ if (sym->isUndefined() && !sym->isWeak())
+ if (auto *f = dyn_cast_or_null<SharedFile>(sym->file))
+ if (f->allNeededIsKnown)
+ error(toString(f) + ": undefined reference to " + toString(*sym));
});
}
// Now that we have defined all possible global symbols including linker-
// synthesized ones. Visit all symbols to give the finishing touches.
- Symtab->forEachSymbol([](Symbol *Sym) {
- if (!includeInSymtab(*Sym))
+ symtab->forEachSymbol([](Symbol *sym) {
+ if (!includeInSymtab(*sym))
return;
- if (In.SymTab)
- In.SymTab->addSymbol(Sym);
+ if (in.symTab)
+ in.symTab->addSymbol(sym);
- if (Sym->includeInDynsym()) {
- Partitions[Sym->Partition - 1].DynSymTab->addSymbol(Sym);
- if (auto *File = dyn_cast_or_null<SharedFile>(Sym->File))
- if (File->IsNeeded && !Sym->isUndefined())
- addVerneed(Sym);
+ if (sym->includeInDynsym()) {
+ partitions[sym->partition - 1].dynSymTab->addSymbol(sym);
+ if (auto *file = dyn_cast_or_null<SharedFile>(sym->file))
+ if (file->isNeeded && !sym->isUndefined())
+ addVerneed(sym);
}
});
// We also need to scan the dynamic relocation tables of the other partitions
// and add any referenced symbols to the partition's dynsym.
- for (Partition &Part : MutableArrayRef<Partition>(Partitions).slice(1)) {
- DenseSet<Symbol *> Syms;
- for (const SymbolTableEntry &E : Part.DynSymTab->getSymbols())
- Syms.insert(E.Sym);
- for (DynamicReloc &Reloc : Part.RelaDyn->Relocs)
- if (Reloc.Sym && !Reloc.UseSymVA && Syms.insert(Reloc.Sym).second)
- Part.DynSymTab->addSymbol(Reloc.Sym);
+ for (Partition &part : MutableArrayRef<Partition>(partitions).slice(1)) {
+ DenseSet<Symbol *> syms;
+ for (const SymbolTableEntry &e : part.dynSymTab->getSymbols())
+ syms.insert(e.sym);
+ for (DynamicReloc &reloc : part.relaDyn->relocs)
+ if (reloc.sym && !reloc.useSymVA && syms.insert(reloc.sym).second)
+ part.dynSymTab->addSymbol(reloc.sym);
}
// Do not proceed if there was an undefined symbol.
if (errorCount())
return;
- if (In.MipsGot)
- In.MipsGot->build();
+ if (in.mipsGot)
+ in.mipsGot->build();
removeUnusedSyntheticSections();
@@ -1811,95 +1811,95 @@ template <class ELFT> void Writer<ELFT>:
// Now that we have the final list, create a list of all the
// OutputSections for convenience.
- for (BaseCommand *Base : Script->SectionCommands)
- if (auto *Sec = dyn_cast<OutputSection>(Base))
- OutputSections.push_back(Sec);
+ for (BaseCommand *base : script->sectionCommands)
+ if (auto *sec = dyn_cast<OutputSection>(base))
+ outputSections.push_back(sec);
// Prefer command line supplied address over other constraints.
- for (OutputSection *Sec : OutputSections) {
- auto I = Config->SectionStartMap.find(Sec->Name);
- if (I != Config->SectionStartMap.end())
- Sec->AddrExpr = [=] { return I->second; };
+ for (OutputSection *sec : outputSections) {
+ auto i = config->sectionStartMap.find(sec->name);
+ if (i != config->sectionStartMap.end())
+ sec->addrExpr = [=] { return i->second; };
}
// This is a bit of a hack. A value of 0 means undef, so we set it
// to 1 to make __ehdr_start defined. The section number is not
// particularly relevant.
- Out::ElfHeader->SectionIndex = 1;
+ Out::elfHeader->sectionIndex = 1;
- for (size_t I = 0, E = OutputSections.size(); I != E; ++I) {
- OutputSection *Sec = OutputSections[I];
- Sec->SectionIndex = I + 1;
- Sec->ShName = In.ShStrTab->addString(Sec->Name);
+ for (size_t i = 0, e = outputSections.size(); i != e; ++i) {
+ OutputSection *sec = outputSections[i];
+ sec->sectionIndex = i + 1;
+ sec->shName = in.shStrTab->addString(sec->name);
}
// Binary and relocatable output does not have PHDRS.
// The headers have to be created before finalize as that can influence the
// image base and the dynamic section on mips includes the image base.
- if (!Config->Relocatable && !Config->OFormatBinary) {
- for (Partition &Part : Partitions) {
- Part.Phdrs = Script->hasPhdrsCommands() ? Script->createPhdrs()
- : createPhdrs(Part);
- if (Config->EMachine == EM_ARM) {
+ if (!config->relocatable && !config->oFormatBinary) {
+ for (Partition &part : partitions) {
+ part.phdrs = script->hasPhdrsCommands() ? script->createPhdrs()
+ : createPhdrs(part);
+ if (config->emachine == EM_ARM) {
// PT_ARM_EXIDX is the ARM EHABI equivalent of PT_GNU_EH_FRAME
- addPhdrForSection(Part, SHT_ARM_EXIDX, PT_ARM_EXIDX, PF_R);
+ addPhdrForSection(part, SHT_ARM_EXIDX, PT_ARM_EXIDX, PF_R);
}
- if (Config->EMachine == EM_MIPS) {
+ if (config->emachine == EM_MIPS) {
// Add separate segments for MIPS-specific sections.
- addPhdrForSection(Part, SHT_MIPS_REGINFO, PT_MIPS_REGINFO, PF_R);
- addPhdrForSection(Part, SHT_MIPS_OPTIONS, PT_MIPS_OPTIONS, PF_R);
- addPhdrForSection(Part, SHT_MIPS_ABIFLAGS, PT_MIPS_ABIFLAGS, PF_R);
+ addPhdrForSection(part, SHT_MIPS_REGINFO, PT_MIPS_REGINFO, PF_R);
+ addPhdrForSection(part, SHT_MIPS_OPTIONS, PT_MIPS_OPTIONS, PF_R);
+ addPhdrForSection(part, SHT_MIPS_ABIFLAGS, PT_MIPS_ABIFLAGS, PF_R);
}
}
- Out::ProgramHeaders->Size = sizeof(Elf_Phdr) * Main->Phdrs.size();
+ Out::programHeaders->size = sizeof(Elf_Phdr) * mainPart->phdrs.size();
// Find the TLS segment. This happens before the section layout loop so that
// Android relocation packing can look up TLS symbol addresses. We only need
// to care about the main partition here because all TLS symbols were moved
// to the main partition (see MarkLive.cpp).
- for (PhdrEntry *P : Main->Phdrs)
- if (P->p_type == PT_TLS)
- Out::TlsPhdr = P;
+ for (PhdrEntry *p : mainPart->phdrs)
+ if (p->p_type == PT_TLS)
+ Out::tlsPhdr = p;
}
// Some symbols are defined in term of program headers. Now that we
// have the headers, we can find out which sections they point to.
setReservedSymbolSections();
- finalizeSynthetic(In.Bss);
- finalizeSynthetic(In.BssRelRo);
- finalizeSynthetic(In.SymTabShndx);
- finalizeSynthetic(In.ShStrTab);
- finalizeSynthetic(In.StrTab);
- finalizeSynthetic(In.Got);
- finalizeSynthetic(In.MipsGot);
- finalizeSynthetic(In.IgotPlt);
- finalizeSynthetic(In.GotPlt);
- finalizeSynthetic(In.RelaIplt);
- finalizeSynthetic(In.RelaPlt);
- finalizeSynthetic(In.Plt);
- finalizeSynthetic(In.Iplt);
- finalizeSynthetic(In.PPC32Got2);
- finalizeSynthetic(In.RISCVSdata);
- finalizeSynthetic(In.PartIndex);
+ finalizeSynthetic(in.bss);
+ finalizeSynthetic(in.bssRelRo);
+ finalizeSynthetic(in.symTabShndx);
+ finalizeSynthetic(in.shStrTab);
+ finalizeSynthetic(in.strTab);
+ finalizeSynthetic(in.got);
+ finalizeSynthetic(in.mipsGot);
+ finalizeSynthetic(in.igotPlt);
+ finalizeSynthetic(in.gotPlt);
+ finalizeSynthetic(in.relaIplt);
+ finalizeSynthetic(in.relaPlt);
+ finalizeSynthetic(in.plt);
+ finalizeSynthetic(in.iplt);
+ finalizeSynthetic(in.ppc32Got2);
+ finalizeSynthetic(in.riscvSdata);
+ finalizeSynthetic(in.partIndex);
// Dynamic section must be the last one in this list and dynamic
// symbol table section (DynSymTab) must be the first one.
- for (Partition &Part : Partitions) {
- finalizeSynthetic(Part.ARMExidx);
- finalizeSynthetic(Part.DynSymTab);
- finalizeSynthetic(Part.GnuHashTab);
- finalizeSynthetic(Part.HashTab);
- finalizeSynthetic(Part.VerDef);
- finalizeSynthetic(Part.RelaDyn);
- finalizeSynthetic(Part.RelrDyn);
- finalizeSynthetic(Part.EhFrameHdr);
- finalizeSynthetic(Part.VerSym);
- finalizeSynthetic(Part.VerNeed);
- finalizeSynthetic(Part.Dynamic);
+ for (Partition &part : partitions) {
+ finalizeSynthetic(part.armExidx);
+ finalizeSynthetic(part.dynSymTab);
+ finalizeSynthetic(part.gnuHashTab);
+ finalizeSynthetic(part.hashTab);
+ finalizeSynthetic(part.verDef);
+ finalizeSynthetic(part.relaDyn);
+ finalizeSynthetic(part.relrDyn);
+ finalizeSynthetic(part.ehFrameHdr);
+ finalizeSynthetic(part.verSym);
+ finalizeSynthetic(part.verNeed);
+ finalizeSynthetic(part.dynamic);
}
- if (!Script->HasSectionsCommand && !Config->Relocatable)
+ if (!script->hasSectionsCommand && !config->relocatable)
fixSectionAlignments();
// SHFLinkOrder processing must be processed after relative section placements are
@@ -1930,28 +1930,28 @@ template <class ELFT> void Writer<ELFT>:
finalizeAddressDependentContent();
// finalizeAddressDependentContent may have added local symbols to the static symbol table.
- finalizeSynthetic(In.SymTab);
- finalizeSynthetic(In.PPC64LongBranchTarget);
+ finalizeSynthetic(in.symTab);
+ finalizeSynthetic(in.ppc64LongBranchTarget);
// Fill other section headers. The dynamic table is finalized
// at the end because some tags like RELSZ depend on result
// of finalizing other sections.
- for (OutputSection *Sec : OutputSections)
- Sec->finalize();
+ for (OutputSection *sec : outputSections)
+ sec->finalize();
}
// Ensure data sections are not mixed with executable sections when
// -execute-only is used. -execute-only is a feature to make pages executable
// but not readable, and the feature is currently supported only on AArch64.
template <class ELFT> void Writer<ELFT>::checkExecuteOnly() {
- if (!Config->ExecuteOnly)
+ if (!config->executeOnly)
return;
- for (OutputSection *OS : OutputSections)
- if (OS->Flags & SHF_EXECINSTR)
- for (InputSection *IS : getInputSections(OS))
- if (!(IS->Flags & SHF_EXECINSTR))
- error("cannot place " + toString(IS) + " into " + toString(OS->Name) +
+ for (OutputSection *os : outputSections)
+ if (os->flags & SHF_EXECINSTR)
+ for (InputSection *isec : getInputSections(os))
+ if (!(isec->flags & SHF_EXECINSTR))
+ error("cannot place " + toString(isec) + " into " + toString(os->name) +
": -execute-only does not support intermingling data and code");
}
@@ -1976,24 +1976,24 @@ template <class ELFT> void Writer<ELFT>:
// case, use the image base address as a last resort.
OutputSection *Default = findSection(".text");
if (!Default)
- Default = Out::ElfHeader;
+ Default = Out::elfHeader;
- auto Define = [=](StringRef Start, StringRef End, OutputSection *OS) {
- if (OS) {
- addOptionalRegular(Start, OS, 0);
- addOptionalRegular(End, OS, -1);
+ auto define = [=](StringRef start, StringRef end, OutputSection *os) {
+ if (os) {
+ addOptionalRegular(start, os, 0);
+ addOptionalRegular(end, os, -1);
} else {
- addOptionalRegular(Start, Default, 0);
- addOptionalRegular(End, Default, 0);
+ addOptionalRegular(start, Default, 0);
+ addOptionalRegular(end, Default, 0);
}
};
- Define("__preinit_array_start", "__preinit_array_end", Out::PreinitArray);
- Define("__init_array_start", "__init_array_end", Out::InitArray);
- Define("__fini_array_start", "__fini_array_end", Out::FiniArray);
+ define("__preinit_array_start", "__preinit_array_end", Out::preinitArray);
+ define("__init_array_start", "__init_array_end", Out::initArray);
+ define("__fini_array_start", "__fini_array_end", Out::finiArray);
- if (OutputSection *Sec = findSection(".ARM.exidx"))
- Define("__exidx_start", "__exidx_end", Sec);
+ if (OutputSection *sec = findSection(".ARM.exidx"))
+ define("__exidx_start", "__exidx_end", sec);
}
// If a section name is valid as a C identifier (which is rare because of
@@ -2002,22 +2002,22 @@ template <class ELFT> void Writer<ELFT>:
// respectively. This is not requested by the ELF standard, but GNU ld and
// gold provide the feature, and used by many programs.
template <class ELFT>
-void Writer<ELFT>::addStartStopSymbols(OutputSection *Sec) {
- StringRef S = Sec->Name;
- if (!isValidCIdentifier(S))
+void Writer<ELFT>::addStartStopSymbols(OutputSection *sec) {
+ StringRef s = sec->name;
+ if (!isValidCIdentifier(s))
return;
- addOptionalRegular(Saver.save("__start_" + S), Sec, 0, STV_PROTECTED);
- addOptionalRegular(Saver.save("__stop_" + S), Sec, -1, STV_PROTECTED);
+ addOptionalRegular(Saver.save("__start_" + s), sec, 0, STV_PROTECTED);
+ addOptionalRegular(Saver.save("__stop_" + s), sec, -1, STV_PROTECTED);
}
-static bool needsPtLoad(OutputSection *Sec) {
- if (!(Sec->Flags & SHF_ALLOC) || Sec->Noload)
+static bool needsPtLoad(OutputSection *sec) {
+ if (!(sec->flags & SHF_ALLOC) || sec->noload)
return false;
// Don't allocate VA space for TLS NOBITS sections. The PT_TLS PHDR is
// responsible for allocating space for them, not the PT_LOAD that
// contains the TLS initialization image.
- if ((Sec->Flags & SHF_TLS) && Sec->Type == SHT_NOBITS)
+ if ((sec->flags & SHF_TLS) && sec->type == SHT_NOBITS)
return false;
return true;
}
@@ -2026,79 +2026,79 @@ static bool needsPtLoad(OutputSection *S
// linker scripts are designed for creating two PT_LOADs only, one RX and one
// RW. This means that there is no alignment in the RO to RX transition and we
// cannot create a PT_LOAD there.
-static uint64_t computeFlags(uint64_t Flags) {
- if (Config->Omagic)
+static uint64_t computeFlags(uint64_t flags) {
+ if (config->omagic)
return PF_R | PF_W | PF_X;
- if (Config->ExecuteOnly && (Flags & PF_X))
- return Flags & ~PF_R;
- if (Config->SingleRoRx && !(Flags & PF_W))
- return Flags | PF_X;
- return Flags;
+ if (config->executeOnly && (flags & PF_X))
+ return flags & ~PF_R;
+ if (config->singleRoRx && !(flags & PF_W))
+ return flags | PF_X;
+ return flags;
}
// Decide which program headers to create and which sections to include in each
// one.
template <class ELFT>
-std::vector<PhdrEntry *> Writer<ELFT>::createPhdrs(Partition &Part) {
- std::vector<PhdrEntry *> Ret;
- auto AddHdr = [&](unsigned Type, unsigned Flags) -> PhdrEntry * {
- Ret.push_back(make<PhdrEntry>(Type, Flags));
- return Ret.back();
+std::vector<PhdrEntry *> Writer<ELFT>::createPhdrs(Partition &part) {
+ std::vector<PhdrEntry *> ret;
+ auto addHdr = [&](unsigned type, unsigned flags) -> PhdrEntry * {
+ ret.push_back(make<PhdrEntry>(type, flags));
+ return ret.back();
};
- unsigned PartNo = Part.getNumber();
- bool IsMain = PartNo == 1;
+ unsigned partNo = part.getNumber();
+ bool isMain = partNo == 1;
// The first phdr entry is PT_PHDR which describes the program header itself.
- if (IsMain)
- AddHdr(PT_PHDR, PF_R)->add(Out::ProgramHeaders);
+ if (isMain)
+ addHdr(PT_PHDR, PF_R)->add(Out::programHeaders);
else
- AddHdr(PT_PHDR, PF_R)->add(Part.ProgramHeaders->getParent());
+ addHdr(PT_PHDR, PF_R)->add(part.programHeaders->getParent());
// PT_INTERP must be the second entry if exists.
- if (OutputSection *Cmd = findSection(".interp", PartNo))
- AddHdr(PT_INTERP, Cmd->getPhdrFlags())->add(Cmd);
+ if (OutputSection *cmd = findSection(".interp", partNo))
+ addHdr(PT_INTERP, cmd->getPhdrFlags())->add(cmd);
// Add the first PT_LOAD segment for regular output sections.
- uint64_t Flags = computeFlags(PF_R);
- PhdrEntry *Load = nullptr;
+ uint64_t flags = computeFlags(PF_R);
+ PhdrEntry *load = nullptr;
// Add the headers. We will remove them if they don't fit.
// In the other partitions the headers are ordinary sections, so they don't
// need to be added here.
- if (IsMain) {
- Load = AddHdr(PT_LOAD, Flags);
- Load->add(Out::ElfHeader);
- Load->add(Out::ProgramHeaders);
+ if (isMain) {
+ load = addHdr(PT_LOAD, flags);
+ load->add(Out::elfHeader);
+ load->add(Out::programHeaders);
}
// PT_GNU_RELRO includes all sections that should be marked as
// read-only by dynamic linker after proccessing relocations.
// Current dynamic loaders only support one PT_GNU_RELRO PHDR, give
// an error message if more than one PT_GNU_RELRO PHDR is required.
- PhdrEntry *RelRo = make<PhdrEntry>(PT_GNU_RELRO, PF_R);
- bool InRelroPhdr = false;
- OutputSection *RelroEnd = nullptr;
- for (OutputSection *Sec : OutputSections) {
- if (Sec->Partition != PartNo || !needsPtLoad(Sec))
+ PhdrEntry *relRo = make<PhdrEntry>(PT_GNU_RELRO, PF_R);
+ bool inRelroPhdr = false;
+ OutputSection *relroEnd = nullptr;
+ for (OutputSection *sec : outputSections) {
+ if (sec->partition != partNo || !needsPtLoad(sec))
continue;
- if (isRelroSection(Sec)) {
- InRelroPhdr = true;
- if (!RelroEnd)
- RelRo->add(Sec);
+ if (isRelroSection(sec)) {
+ inRelroPhdr = true;
+ if (!relroEnd)
+ relRo->add(sec);
else
- error("section: " + Sec->Name + " is not contiguous with other relro" +
+ error("section: " + sec->name + " is not contiguous with other relro" +
" sections");
- } else if (InRelroPhdr) {
- InRelroPhdr = false;
- RelroEnd = Sec;
+ } else if (inRelroPhdr) {
+ inRelroPhdr = false;
+ relroEnd = sec;
}
}
- for (OutputSection *Sec : OutputSections) {
- if (!(Sec->Flags & SHF_ALLOC))
+ for (OutputSection *sec : outputSections) {
+ if (!(sec->flags & SHF_ALLOC))
break;
- if (!needsPtLoad(Sec))
+ if (!needsPtLoad(sec))
continue;
// Normally, sections in partitions other than the current partition are
@@ -2107,9 +2107,9 @@ std::vector<PhdrEntry *> Writer<ELFT>::c
// partition so that a segment is created for it in the main partition,
// which will cause the dynamic loader to reserve space for the other
// partitions.
- if (Sec->Partition != PartNo) {
- if (IsMain && Sec->Partition == 255)
- AddHdr(PT_LOAD, computeFlags(Sec->getPhdrFlags()))->add(Sec);
+ if (sec->partition != partNo) {
+ if (isMain && sec->partition == 255)
+ addHdr(PT_LOAD, computeFlags(sec->getPhdrFlags()))->add(sec);
continue;
}
@@ -2120,127 +2120,127 @@ std::vector<PhdrEntry *> Writer<ELFT>::c
// region using AT or AT> linker script command, respectively. At the same
// time, we don't want to create a separate load segment for the headers,
// even if the first output section has an AT or AT> attribute.
- uint64_t NewFlags = computeFlags(Sec->getPhdrFlags());
- if (!Load ||
- ((Sec->LMAExpr ||
- (Sec->LMARegion && (Sec->LMARegion != Load->FirstSec->LMARegion))) &&
- Load->LastSec != Out::ProgramHeaders) ||
- Sec->MemRegion != Load->FirstSec->MemRegion || Flags != NewFlags ||
- Sec == RelroEnd) {
- Load = AddHdr(PT_LOAD, NewFlags);
- Flags = NewFlags;
+ uint64_t newFlags = computeFlags(sec->getPhdrFlags());
+ if (!load ||
+ ((sec->lmaExpr ||
+ (sec->lmaRegion && (sec->lmaRegion != load->firstSec->lmaRegion))) &&
+ load->lastSec != Out::programHeaders) ||
+ sec->memRegion != load->firstSec->memRegion || flags != newFlags ||
+ sec == relroEnd) {
+ load = addHdr(PT_LOAD, newFlags);
+ flags = newFlags;
}
- Load->add(Sec);
+ load->add(sec);
}
// Add a TLS segment if any.
- PhdrEntry *TlsHdr = make<PhdrEntry>(PT_TLS, PF_R);
- for (OutputSection *Sec : OutputSections)
- if (Sec->Partition == PartNo && Sec->Flags & SHF_TLS)
- TlsHdr->add(Sec);
- if (TlsHdr->FirstSec)
- Ret.push_back(TlsHdr);
+ PhdrEntry *tlsHdr = make<PhdrEntry>(PT_TLS, PF_R);
+ for (OutputSection *sec : outputSections)
+ if (sec->partition == partNo && sec->flags & SHF_TLS)
+ tlsHdr->add(sec);
+ if (tlsHdr->firstSec)
+ ret.push_back(tlsHdr);
// Add an entry for .dynamic.
- if (OutputSection *Sec = Part.Dynamic->getParent())
- AddHdr(PT_DYNAMIC, Sec->getPhdrFlags())->add(Sec);
+ if (OutputSection *sec = part.dynamic->getParent())
+ addHdr(PT_DYNAMIC, sec->getPhdrFlags())->add(sec);
- if (RelRo->FirstSec)
- Ret.push_back(RelRo);
+ if (relRo->firstSec)
+ ret.push_back(relRo);
// PT_GNU_EH_FRAME is a special section pointing on .eh_frame_hdr.
- if (Part.EhFrame->isNeeded() && Part.EhFrameHdr &&
- Part.EhFrame->getParent() && Part.EhFrameHdr->getParent())
- AddHdr(PT_GNU_EH_FRAME, Part.EhFrameHdr->getParent()->getPhdrFlags())
- ->add(Part.EhFrameHdr->getParent());
+ if (part.ehFrame->isNeeded() && part.ehFrameHdr &&
+ part.ehFrame->getParent() && part.ehFrameHdr->getParent())
+ addHdr(PT_GNU_EH_FRAME, part.ehFrameHdr->getParent()->getPhdrFlags())
+ ->add(part.ehFrameHdr->getParent());
// PT_OPENBSD_RANDOMIZE is an OpenBSD-specific feature. That makes
// the dynamic linker fill the segment with random data.
- if (OutputSection *Cmd = findSection(".openbsd.randomdata", PartNo))
- AddHdr(PT_OPENBSD_RANDOMIZE, Cmd->getPhdrFlags())->add(Cmd);
+ if (OutputSection *cmd = findSection(".openbsd.randomdata", partNo))
+ addHdr(PT_OPENBSD_RANDOMIZE, cmd->getPhdrFlags())->add(cmd);
// PT_GNU_STACK is a special section to tell the loader to make the
// pages for the stack non-executable. If you really want an executable
// stack, you can pass -z execstack, but that's not recommended for
// security reasons.
- unsigned Perm = PF_R | PF_W;
- if (Config->ZExecstack)
- Perm |= PF_X;
- AddHdr(PT_GNU_STACK, Perm)->p_memsz = Config->ZStackSize;
+ unsigned perm = PF_R | PF_W;
+ if (config->zExecstack)
+ perm |= PF_X;
+ addHdr(PT_GNU_STACK, perm)->p_memsz = config->zStackSize;
// PT_OPENBSD_WXNEEDED is a OpenBSD-specific header to mark the executable
// is expected to perform W^X violations, such as calling mprotect(2) or
// mmap(2) with PROT_WRITE | PROT_EXEC, which is prohibited by default on
// OpenBSD.
- if (Config->ZWxneeded)
- AddHdr(PT_OPENBSD_WXNEEDED, PF_X);
+ if (config->zWxneeded)
+ addHdr(PT_OPENBSD_WXNEEDED, PF_X);
// Create one PT_NOTE per a group of contiguous SHT_NOTE sections with the
// same alignment.
- PhdrEntry *Note = nullptr;
- for (OutputSection *Sec : OutputSections) {
- if (Sec->Partition != PartNo)
+ PhdrEntry *note = nullptr;
+ for (OutputSection *sec : outputSections) {
+ if (sec->partition != partNo)
continue;
- if (Sec->Type == SHT_NOTE && (Sec->Flags & SHF_ALLOC)) {
- if (!Note || Sec->LMAExpr || Note->LastSec->Alignment != Sec->Alignment)
- Note = AddHdr(PT_NOTE, PF_R);
- Note->add(Sec);
+ if (sec->type == SHT_NOTE && (sec->flags & SHF_ALLOC)) {
+ if (!note || sec->lmaExpr || note->lastSec->alignment != sec->alignment)
+ note = addHdr(PT_NOTE, PF_R);
+ note->add(sec);
} else {
- Note = nullptr;
+ note = nullptr;
}
}
- return Ret;
+ return ret;
}
template <class ELFT>
-void Writer<ELFT>::addPhdrForSection(Partition &Part, unsigned ShType,
- unsigned PType, unsigned PFlags) {
- unsigned PartNo = Part.getNumber();
- auto I = llvm::find_if(OutputSections, [=](OutputSection *Cmd) {
- return Cmd->Partition == PartNo && Cmd->Type == ShType;
+void Writer<ELFT>::addPhdrForSection(Partition &part, unsigned shType,
+ unsigned pType, unsigned pFlags) {
+ unsigned partNo = part.getNumber();
+ auto i = llvm::find_if(outputSections, [=](OutputSection *cmd) {
+ return cmd->partition == partNo && cmd->type == shType;
});
- if (I == OutputSections.end())
+ if (i == outputSections.end())
return;
- PhdrEntry *Entry = make<PhdrEntry>(PType, PFlags);
- Entry->add(*I);
- Part.Phdrs.push_back(Entry);
+ PhdrEntry *entry = make<PhdrEntry>(pType, pFlags);
+ entry->add(*i);
+ part.phdrs.push_back(entry);
}
// The first section of each PT_LOAD, the first section in PT_GNU_RELRO and the
// first section after PT_GNU_RELRO have to be page aligned so that the dynamic
// linker can set the permissions.
template <class ELFT> void Writer<ELFT>::fixSectionAlignments() {
- auto PageAlign = [](OutputSection *Cmd) {
- if (Cmd && !Cmd->AddrExpr)
- Cmd->AddrExpr = [=] {
- return alignTo(Script->getDot(), Config->MaxPageSize);
+ auto pageAlign = [](OutputSection *cmd) {
+ if (cmd && !cmd->addrExpr)
+ cmd->addrExpr = [=] {
+ return alignTo(script->getDot(), config->maxPageSize);
};
};
- for (Partition &Part : Partitions) {
- for (const PhdrEntry *P : Part.Phdrs)
- if (P->p_type == PT_LOAD && P->FirstSec)
- PageAlign(P->FirstSec);
+ for (Partition &part : partitions) {
+ for (const PhdrEntry *p : part.phdrs)
+ if (p->p_type == PT_LOAD && p->firstSec)
+ pageAlign(p->firstSec);
- for (const PhdrEntry *P : Part.Phdrs) {
- if (P->p_type != PT_GNU_RELRO)
+ for (const PhdrEntry *p : part.phdrs) {
+ if (p->p_type != PT_GNU_RELRO)
continue;
- if (P->FirstSec)
- PageAlign(P->FirstSec);
+ if (p->firstSec)
+ pageAlign(p->firstSec);
// Find the first section after PT_GNU_RELRO. If it is in a PT_LOAD we
// have to align it to a page.
- auto End = OutputSections.end();
- auto I = llvm::find(OutputSections, P->LastSec);
- if (I == End || (I + 1) == End)
+ auto end = outputSections.end();
+ auto i = llvm::find(outputSections, p->lastSec);
+ if (i == end || (i + 1) == end)
continue;
- OutputSection *Cmd = (*(I + 1));
- if (needsPtLoad(Cmd))
- PageAlign(Cmd);
+ OutputSection *cmd = (*(i + 1));
+ if (needsPtLoad(cmd))
+ pageAlign(cmd);
}
}
}
@@ -2248,78 +2248,78 @@ template <class ELFT> void Writer<ELFT>:
// Compute an in-file position for a given section. The file offset must be the
// same with its virtual address modulo the page size, so that the loader can
// load executables without any address adjustment.
-static uint64_t computeFileOffset(OutputSection *OS, uint64_t Off) {
+static uint64_t computeFileOffset(OutputSection *os, uint64_t off) {
// File offsets are not significant for .bss sections. By convention, we keep
// section offsets monotonically increasing rather than setting to zero.
- if (OS->Type == SHT_NOBITS)
- return Off;
+ if (os->type == SHT_NOBITS)
+ return off;
// If the section is not in a PT_LOAD, we just have to align it.
- if (!OS->PtLoad)
- return alignTo(Off, OS->Alignment);
+ if (!os->ptLoad)
+ return alignTo(off, os->alignment);
// The first section in a PT_LOAD has to have congruent offset and address
// module the page size.
- OutputSection *First = OS->PtLoad->FirstSec;
- if (OS == First) {
- uint64_t Alignment = std::max<uint64_t>(OS->Alignment, Config->MaxPageSize);
- return alignTo(Off, Alignment, OS->Addr);
+ OutputSection *first = os->ptLoad->firstSec;
+ if (os == first) {
+ uint64_t alignment = std::max<uint64_t>(os->alignment, config->maxPageSize);
+ return alignTo(off, alignment, os->addr);
}
// If two sections share the same PT_LOAD the file offset is calculated
// using this formula: Off2 = Off1 + (VA2 - VA1).
- return First->Offset + OS->Addr - First->Addr;
+ return first->offset + os->addr - first->addr;
}
// Set an in-file position to a given section and returns the end position of
// the section.
-static uint64_t setFileOffset(OutputSection *OS, uint64_t Off) {
- Off = computeFileOffset(OS, Off);
- OS->Offset = Off;
-
- if (OS->Type == SHT_NOBITS)
- return Off;
- return Off + OS->Size;
+static uint64_t setFileOffset(OutputSection *os, uint64_t off) {
+ off = computeFileOffset(os, off);
+ os->offset = off;
+
+ if (os->type == SHT_NOBITS)
+ return off;
+ return off + os->size;
}
template <class ELFT> void Writer<ELFT>::assignFileOffsetsBinary() {
- uint64_t Off = 0;
- for (OutputSection *Sec : OutputSections)
- if (Sec->Flags & SHF_ALLOC)
- Off = setFileOffset(Sec, Off);
- FileSize = alignTo(Off, Config->Wordsize);
+ uint64_t off = 0;
+ for (OutputSection *sec : outputSections)
+ if (sec->flags & SHF_ALLOC)
+ off = setFileOffset(sec, off);
+ fileSize = alignTo(off, config->wordsize);
}
-static std::string rangeToString(uint64_t Addr, uint64_t Len) {
- return "[0x" + utohexstr(Addr) + ", 0x" + utohexstr(Addr + Len - 1) + "]";
+static std::string rangeToString(uint64_t addr, uint64_t len) {
+ return "[0x" + utohexstr(addr) + ", 0x" + utohexstr(addr + len - 1) + "]";
}
// Assign file offsets to output sections.
template <class ELFT> void Writer<ELFT>::assignFileOffsets() {
- uint64_t Off = 0;
- Off = setFileOffset(Out::ElfHeader, Off);
- Off = setFileOffset(Out::ProgramHeaders, Off);
-
- PhdrEntry *LastRX = nullptr;
- for (Partition &Part : Partitions)
- for (PhdrEntry *P : Part.Phdrs)
- if (P->p_type == PT_LOAD && (P->p_flags & PF_X))
- LastRX = P;
-
- for (OutputSection *Sec : OutputSections) {
- Off = setFileOffset(Sec, Off);
- if (Script->HasSectionsCommand)
+ uint64_t off = 0;
+ off = setFileOffset(Out::elfHeader, off);
+ off = setFileOffset(Out::programHeaders, off);
+
+ PhdrEntry *lastRX = nullptr;
+ for (Partition &part : partitions)
+ for (PhdrEntry *p : part.phdrs)
+ if (p->p_type == PT_LOAD && (p->p_flags & PF_X))
+ lastRX = p;
+
+ for (OutputSection *sec : outputSections) {
+ off = setFileOffset(sec, off);
+ if (script->hasSectionsCommand)
continue;
// If this is a last section of the last executable segment and that
// segment is the last loadable segment, align the offset of the
// following section to avoid loading non-segments parts of the file.
- if (LastRX && LastRX->LastSec == Sec)
- Off = alignTo(Off, Config->CommonPageSize);
+ if (lastRX && lastRX->lastSec == sec)
+ off = alignTo(off, config->commonPageSize);
}
- SectionHeaderOff = alignTo(Off, Config->Wordsize);
- FileSize = SectionHeaderOff + (OutputSections.size() + 1) * sizeof(Elf_Shdr);
+ sectionHeaderOff = alignTo(off, config->wordsize);
+ fileSize = sectionHeaderOff + (outputSections.size() + 1) * sizeof(Elf_Shdr);
// Our logic assumes that sections have rising VA within the same segment.
// With use of linker scripts it is possible to violate this rule and get file
@@ -2330,49 +2330,49 @@ template <class ELFT> void Writer<ELFT>:
// backwards, so we have to allow doing that to support linking them. We
// perform non-critical checks for overlaps in checkSectionOverlap(), but here
// we want to prevent file size overflows because it would crash the linker.
- for (OutputSection *Sec : OutputSections) {
- if (Sec->Type == SHT_NOBITS)
+ for (OutputSection *sec : outputSections) {
+ if (sec->type == SHT_NOBITS)
continue;
- if ((Sec->Offset > FileSize) || (Sec->Offset + Sec->Size > FileSize))
- error("unable to place section " + Sec->Name + " at file offset " +
- rangeToString(Sec->Offset, Sec->Size) +
+ if ((sec->offset > fileSize) || (sec->offset + sec->size > fileSize))
+ error("unable to place section " + sec->name + " at file offset " +
+ rangeToString(sec->offset, sec->size) +
"; check your linker script for overflows");
}
}
// Finalize the program headers. We call this function after we assign
// file offsets and VAs to all sections.
-template <class ELFT> void Writer<ELFT>::setPhdrs(Partition &Part) {
- for (PhdrEntry *P : Part.Phdrs) {
- OutputSection *First = P->FirstSec;
- OutputSection *Last = P->LastSec;
-
- if (First) {
- P->p_filesz = Last->Offset - First->Offset;
- if (Last->Type != SHT_NOBITS)
- P->p_filesz += Last->Size;
-
- P->p_memsz = Last->Addr + Last->Size - First->Addr;
- P->p_offset = First->Offset;
- P->p_vaddr = First->Addr;
+template <class ELFT> void Writer<ELFT>::setPhdrs(Partition &part) {
+ for (PhdrEntry *p : part.phdrs) {
+ OutputSection *first = p->firstSec;
+ OutputSection *last = p->lastSec;
+
+ if (first) {
+ p->p_filesz = last->offset - first->offset;
+ if (last->type != SHT_NOBITS)
+ p->p_filesz += last->size;
+
+ p->p_memsz = last->addr + last->size - first->addr;
+ p->p_offset = first->offset;
+ p->p_vaddr = first->addr;
// File offsets in partitions other than the main partition are relative
// to the offset of the ELF headers. Perform that adjustment now.
- if (Part.ElfHeader)
- P->p_offset -= Part.ElfHeader->getParent()->Offset;
+ if (part.elfHeader)
+ p->p_offset -= part.elfHeader->getParent()->offset;
- if (!P->HasLMA)
- P->p_paddr = First->getLMA();
+ if (!p->hasLMA)
+ p->p_paddr = first->getLMA();
}
- if (P->p_type == PT_LOAD) {
- P->p_align = std::max<uint64_t>(P->p_align, Config->MaxPageSize);
- } else if (P->p_type == PT_GNU_RELRO) {
- P->p_align = 1;
+ if (p->p_type == PT_LOAD) {
+ p->p_align = std::max<uint64_t>(p->p_align, config->maxPageSize);
+ } else if (p->p_type == PT_GNU_RELRO) {
+ p->p_align = 1;
// The glibc dynamic loader rounds the size down, so we need to round up
// to protect the last page. This is a no-op on FreeBSD which always
// rounds up.
- P->p_memsz = alignTo(P->p_memsz, Config->CommonPageSize);
+ p->p_memsz = alignTo(p->p_memsz, config->commonPageSize);
}
}
}
@@ -2380,37 +2380,37 @@ template <class ELFT> void Writer<ELFT>:
// A helper struct for checkSectionOverlap.
namespace {
struct SectionOffset {
- OutputSection *Sec;
- uint64_t Offset;
+ OutputSection *sec;
+ uint64_t offset;
};
} // namespace
// Check whether sections overlap for a specific address range (file offsets,
// load and virtual adresses).
-static void checkOverlap(StringRef Name, std::vector<SectionOffset> &Sections,
- bool IsVirtualAddr) {
- llvm::sort(Sections, [=](const SectionOffset &A, const SectionOffset &B) {
- return A.Offset < B.Offset;
+static void checkOverlap(StringRef name, std::vector<SectionOffset> §ions,
+ bool isVirtualAddr) {
+ llvm::sort(sections, [=](const SectionOffset &a, const SectionOffset &b) {
+ return a.offset < b.offset;
});
// Finding overlap is easy given a vector is sorted by start position.
// If an element starts before the end of the previous element, they overlap.
- for (size_t I = 1, End = Sections.size(); I < End; ++I) {
- SectionOffset A = Sections[I - 1];
- SectionOffset B = Sections[I];
- if (B.Offset >= A.Offset + A.Sec->Size)
+ for (size_t i = 1, end = sections.size(); i < end; ++i) {
+ SectionOffset a = sections[i - 1];
+ SectionOffset b = sections[i];
+ if (b.offset >= a.offset + a.sec->size)
continue;
// If both sections are in OVERLAY we allow the overlapping of virtual
// addresses, because it is what OVERLAY was designed for.
- if (IsVirtualAddr && A.Sec->InOverlay && B.Sec->InOverlay)
+ if (isVirtualAddr && a.sec->inOverlay && b.sec->inOverlay)
continue;
- errorOrWarn("section " + A.Sec->Name + " " + Name +
- " range overlaps with " + B.Sec->Name + "\n>>> " + A.Sec->Name +
- " range is " + rangeToString(A.Offset, A.Sec->Size) + "\n>>> " +
- B.Sec->Name + " range is " +
- rangeToString(B.Offset, B.Sec->Size));
+ errorOrWarn("section " + a.sec->name + " " + name +
+ " range overlaps with " + b.sec->name + "\n>>> " + a.sec->name +
+ " range is " + rangeToString(a.offset, a.sec->size) + "\n>>> " +
+ b.sec->name + " range is " +
+ rangeToString(b.offset, b.sec->size));
}
}
@@ -2421,11 +2421,11 @@ static void checkOverlap(StringRef Name,
// ranges and the virtual address ranges don't overlap
template <class ELFT> void Writer<ELFT>::checkSections() {
// First, check that section's VAs fit in available address space for target.
- for (OutputSection *OS : OutputSections)
- if ((OS->Addr + OS->Size < OS->Addr) ||
- (!ELFT::Is64Bits && OS->Addr + OS->Size > UINT32_MAX))
- errorOrWarn("section " + OS->Name + " at 0x" + utohexstr(OS->Addr) +
- " of size 0x" + utohexstr(OS->Size) +
+ for (OutputSection *os : outputSections)
+ if ((os->addr + os->size < os->addr) ||
+ (!ELFT::Is64Bits && os->addr + os->size > UINT32_MAX))
+ errorOrWarn("section " + os->name + " at 0x" + utohexstr(os->addr) +
+ " of size 0x" + utohexstr(os->size) +
" exceeds available address space");
// Check for overlapping file offsets. In this case we need to skip any
@@ -2433,17 +2433,17 @@ template <class ELFT> void Writer<ELFT>:
// the file so Sec->Offset + Sec->Size can overlap with others. If --oformat
// binary is specified only add SHF_ALLOC sections are added to the output
// file so we skip any non-allocated sections in that case.
- std::vector<SectionOffset> FileOffs;
- for (OutputSection *Sec : OutputSections)
- if (Sec->Size > 0 && Sec->Type != SHT_NOBITS &&
- (!Config->OFormatBinary || (Sec->Flags & SHF_ALLOC)))
- FileOffs.push_back({Sec, Sec->Offset});
- checkOverlap("file", FileOffs, false);
+ std::vector<SectionOffset> fileOffs;
+ for (OutputSection *sec : outputSections)
+ if (sec->size > 0 && sec->type != SHT_NOBITS &&
+ (!config->oFormatBinary || (sec->flags & SHF_ALLOC)))
+ fileOffs.push_back({sec, sec->offset});
+ checkOverlap("file", fileOffs, false);
// When linking with -r there is no need to check for overlapping virtual/load
// addresses since those addresses will only be assigned when the final
// executable/shared object is created.
- if (Config->Relocatable)
+ if (config->relocatable)
return;
// Checking for overlapping virtual and load addresses only needs to take
@@ -2451,20 +2451,20 @@ template <class ELFT> void Writer<ELFT>:
// Furthermore, we also need to skip SHF_TLS sections since these will be
// mapped to other addresses at runtime and can therefore have overlapping
// ranges in the file.
- std::vector<SectionOffset> VMAs;
- for (OutputSection *Sec : OutputSections)
- if (Sec->Size > 0 && (Sec->Flags & SHF_ALLOC) && !(Sec->Flags & SHF_TLS))
- VMAs.push_back({Sec, Sec->Addr});
- checkOverlap("virtual address", VMAs, true);
+ std::vector<SectionOffset> vmas;
+ for (OutputSection *sec : outputSections)
+ if (sec->size > 0 && (sec->flags & SHF_ALLOC) && !(sec->flags & SHF_TLS))
+ vmas.push_back({sec, sec->addr});
+ checkOverlap("virtual address", vmas, true);
// Finally, check that the load addresses don't overlap. This will usually be
// the same as the virtual addresses but can be different when using a linker
// script with AT().
- std::vector<SectionOffset> LMAs;
- for (OutputSection *Sec : OutputSections)
- if (Sec->Size > 0 && (Sec->Flags & SHF_ALLOC) && !(Sec->Flags & SHF_TLS))
- LMAs.push_back({Sec, Sec->getLMA()});
- checkOverlap("load address", LMAs, false);
+ std::vector<SectionOffset> lmas;
+ for (OutputSection *sec : outputSections)
+ if (sec->size > 0 && (sec->flags & SHF_ALLOC) && !(sec->flags & SHF_TLS))
+ lmas.push_back({sec, sec->getLMA()});
+ checkOverlap("load address", lmas, false);
}
// The entry point address is chosen in the following ways.
@@ -2477,45 +2477,45 @@ template <class ELFT> void Writer<ELFT>:
// 6. the address 0.
static uint64_t getEntryAddr() {
// Case 1, 2 or 3
- if (Symbol *B = Symtab->find(Config->Entry))
- return B->getVA();
+ if (Symbol *b = symtab->find(config->entry))
+ return b->getVA();
// Case 4
- uint64_t Addr;
- if (to_integer(Config->Entry, Addr))
- return Addr;
+ uint64_t addr;
+ if (to_integer(config->entry, addr))
+ return addr;
// Case 5
- if (OutputSection *Sec = findSection(".text")) {
- if (Config->WarnMissingEntry)
- warn("cannot find entry symbol " + Config->Entry + "; defaulting to 0x" +
- utohexstr(Sec->Addr));
- return Sec->Addr;
+ if (OutputSection *sec = findSection(".text")) {
+ if (config->warnMissingEntry)
+ warn("cannot find entry symbol " + config->entry + "; defaulting to 0x" +
+ utohexstr(sec->addr));
+ return sec->addr;
}
// Case 6
- if (Config->WarnMissingEntry)
- warn("cannot find entry symbol " + Config->Entry +
+ if (config->warnMissingEntry)
+ warn("cannot find entry symbol " + config->entry +
"; not setting start address");
return 0;
}
static uint16_t getELFType() {
- if (Config->Pic)
+ if (config->isPic)
return ET_DYN;
- if (Config->Relocatable)
+ if (config->relocatable)
return ET_REL;
return ET_EXEC;
}
template <class ELFT> void Writer<ELFT>::writeHeader() {
- writeEhdr<ELFT>(Out::BufferStart, *Main);
- writePhdrs<ELFT>(Out::BufferStart + sizeof(Elf_Ehdr), *Main);
+ writeEhdr<ELFT>(Out::bufferStart, *mainPart);
+ writePhdrs<ELFT>(Out::bufferStart + sizeof(Elf_Ehdr), *mainPart);
- auto *EHdr = reinterpret_cast<Elf_Ehdr *>(Out::BufferStart);
- EHdr->e_type = getELFType();
- EHdr->e_entry = getEntryAddr();
- EHdr->e_shoff = SectionHeaderOff;
+ auto *eHdr = reinterpret_cast<Elf_Ehdr *>(Out::bufferStart);
+ eHdr->e_type = getELFType();
+ eHdr->e_entry = getEntryAddr();
+ eHdr->e_shoff = sectionHeaderOff;
// Write the section header table.
//
@@ -2526,58 +2526,58 @@ template <class ELFT> void Writer<ELFT>:
// the value. The sentinel values and fields are:
// e_shnum = 0, SHdrs[0].sh_size = number of sections.
// e_shstrndx = SHN_XINDEX, SHdrs[0].sh_link = .shstrtab section index.
- auto *SHdrs = reinterpret_cast<Elf_Shdr *>(Out::BufferStart + EHdr->e_shoff);
- size_t Num = OutputSections.size() + 1;
- if (Num >= SHN_LORESERVE)
- SHdrs->sh_size = Num;
+ auto *sHdrs = reinterpret_cast<Elf_Shdr *>(Out::bufferStart + eHdr->e_shoff);
+ size_t num = outputSections.size() + 1;
+ if (num >= SHN_LORESERVE)
+ sHdrs->sh_size = num;
else
- EHdr->e_shnum = Num;
+ eHdr->e_shnum = num;
- uint32_t StrTabIndex = In.ShStrTab->getParent()->SectionIndex;
- if (StrTabIndex >= SHN_LORESERVE) {
- SHdrs->sh_link = StrTabIndex;
- EHdr->e_shstrndx = SHN_XINDEX;
+ uint32_t strTabIndex = in.shStrTab->getParent()->sectionIndex;
+ if (strTabIndex >= SHN_LORESERVE) {
+ sHdrs->sh_link = strTabIndex;
+ eHdr->e_shstrndx = SHN_XINDEX;
} else {
- EHdr->e_shstrndx = StrTabIndex;
+ eHdr->e_shstrndx = strTabIndex;
}
- for (OutputSection *Sec : OutputSections)
- Sec->writeHeaderTo<ELFT>(++SHdrs);
+ for (OutputSection *sec : outputSections)
+ sec->writeHeaderTo<ELFT>(++sHdrs);
}
// Open a result file.
template <class ELFT> void Writer<ELFT>::openFile() {
- uint64_t MaxSize = Config->Is64 ? INT64_MAX : UINT32_MAX;
- if (FileSize != size_t(FileSize) || MaxSize < FileSize) {
- error("output file too large: " + Twine(FileSize) + " bytes");
+ uint64_t maxSize = config->is64 ? INT64_MAX : UINT32_MAX;
+ if (fileSize != size_t(fileSize) || maxSize < fileSize) {
+ error("output file too large: " + Twine(fileSize) + " bytes");
return;
}
- unlinkAsync(Config->OutputFile);
- unsigned Flags = 0;
- if (!Config->Relocatable)
- Flags = FileOutputBuffer::F_executable;
- Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
- FileOutputBuffer::create(Config->OutputFile, FileSize, Flags);
+ unlinkAsync(config->outputFile);
+ unsigned flags = 0;
+ if (!config->relocatable)
+ flags = FileOutputBuffer::F_executable;
+ Expected<std::unique_ptr<FileOutputBuffer>> bufferOrErr =
+ FileOutputBuffer::create(config->outputFile, fileSize, flags);
- if (!BufferOrErr) {
- error("failed to open " + Config->OutputFile + ": " +
- llvm::toString(BufferOrErr.takeError()));
+ if (!bufferOrErr) {
+ error("failed to open " + config->outputFile + ": " +
+ llvm::toString(bufferOrErr.takeError()));
return;
}
- Buffer = std::move(*BufferOrErr);
- Out::BufferStart = Buffer->getBufferStart();
+ buffer = std::move(*bufferOrErr);
+ Out::bufferStart = buffer->getBufferStart();
}
template <class ELFT> void Writer<ELFT>::writeSectionsBinary() {
- for (OutputSection *Sec : OutputSections)
- if (Sec->Flags & SHF_ALLOC)
- Sec->writeTo<ELFT>(Out::BufferStart + Sec->Offset);
+ for (OutputSection *sec : outputSections)
+ if (sec->flags & SHF_ALLOC)
+ sec->writeTo<ELFT>(Out::bufferStart + sec->offset);
}
-static void fillTrap(uint8_t *I, uint8_t *End) {
- for (; I + 4 <= End; I += 4)
- memcpy(I, &Target->TrapInstr, 4);
+static void fillTrap(uint8_t *i, uint8_t *end) {
+ for (; i + 4 <= end; i += 4)
+ memcpy(i, &target->trapInstr, 4);
}
// Fill the last page of executable segments with trap instructions
@@ -2587,29 +2587,29 @@ static void fillTrap(uint8_t *I, uint8_t
// We'll leave other pages in segments as-is because the rest will be
// overwritten by output sections.
template <class ELFT> void Writer<ELFT>::writeTrapInstr() {
- if (Script->HasSectionsCommand)
+ if (script->hasSectionsCommand)
return;
- for (Partition &Part : Partitions) {
+ for (Partition &part : partitions) {
// Fill the last page.
- for (PhdrEntry *P : Part.Phdrs)
- if (P->p_type == PT_LOAD && (P->p_flags & PF_X))
- fillTrap(Out::BufferStart + alignDown(P->FirstSec->Offset + P->p_filesz,
- Config->CommonPageSize),
- Out::BufferStart + alignTo(P->FirstSec->Offset + P->p_filesz,
- Config->CommonPageSize));
+ for (PhdrEntry *p : part.phdrs)
+ if (p->p_type == PT_LOAD && (p->p_flags & PF_X))
+ fillTrap(Out::bufferStart + alignDown(p->firstSec->offset + p->p_filesz,
+ config->commonPageSize),
+ Out::bufferStart + alignTo(p->firstSec->offset + p->p_filesz,
+ config->commonPageSize));
// Round up the file size of the last segment to the page boundary iff it is
// an executable segment to ensure that other tools don't accidentally
// trim the instruction padding (e.g. when stripping the file).
- PhdrEntry *Last = nullptr;
- for (PhdrEntry *P : Part.Phdrs)
- if (P->p_type == PT_LOAD)
- Last = P;
-
- if (Last && (Last->p_flags & PF_X))
- Last->p_memsz = Last->p_filesz =
- alignTo(Last->p_filesz, Config->CommonPageSize);
+ PhdrEntry *last = nullptr;
+ for (PhdrEntry *p : part.phdrs)
+ if (p->p_type == PT_LOAD)
+ last = p;
+
+ if (last && (last->p_flags & PF_X))
+ last->p_memsz = last->p_filesz =
+ alignTo(last->p_filesz, config->commonPageSize);
}
}
@@ -2618,26 +2618,26 @@ template <class ELFT> void Writer<ELFT>:
// In -r or -emit-relocs mode, write the relocation sections first as in
// ELf_Rel targets we might find out that we need to modify the relocated
// section while doing it.
- for (OutputSection *Sec : OutputSections)
- if (Sec->Type == SHT_REL || Sec->Type == SHT_RELA)
- Sec->writeTo<ELFT>(Out::BufferStart + Sec->Offset);
-
- for (OutputSection *Sec : OutputSections)
- if (Sec->Type != SHT_REL && Sec->Type != SHT_RELA)
- Sec->writeTo<ELFT>(Out::BufferStart + Sec->Offset);
+ for (OutputSection *sec : outputSections)
+ if (sec->type == SHT_REL || sec->type == SHT_RELA)
+ sec->writeTo<ELFT>(Out::bufferStart + sec->offset);
+
+ for (OutputSection *sec : outputSections)
+ if (sec->type != SHT_REL && sec->type != SHT_RELA)
+ sec->writeTo<ELFT>(Out::bufferStart + sec->offset);
}
// Split one uint8 array into small pieces of uint8 arrays.
-static std::vector<ArrayRef<uint8_t>> split(ArrayRef<uint8_t> Arr,
- size_t ChunkSize) {
- std::vector<ArrayRef<uint8_t>> Ret;
- while (Arr.size() > ChunkSize) {
- Ret.push_back(Arr.take_front(ChunkSize));
- Arr = Arr.drop_front(ChunkSize);
- }
- if (!Arr.empty())
- Ret.push_back(Arr);
- return Ret;
+static std::vector<ArrayRef<uint8_t>> split(ArrayRef<uint8_t> arr,
+ size_t chunkSize) {
+ std::vector<ArrayRef<uint8_t>> ret;
+ while (arr.size() > chunkSize) {
+ ret.push_back(arr.take_front(chunkSize));
+ arr = arr.drop_front(chunkSize);
+ }
+ if (!arr.empty())
+ ret.push_back(arr);
+ return ret;
}
// Computes a hash value of Data using a given hash function.
@@ -2645,61 +2645,61 @@ static std::vector<ArrayRef<uint8_t>> sp
// chunks, compute a hash for each chunk, and then compute a hash value
// of the hash values.
static void
-computeHash(llvm::MutableArrayRef<uint8_t> HashBuf,
- llvm::ArrayRef<uint8_t> Data,
- std::function<void(uint8_t *Dest, ArrayRef<uint8_t> Arr)> HashFn) {
- std::vector<ArrayRef<uint8_t>> Chunks = split(Data, 1024 * 1024);
- std::vector<uint8_t> Hashes(Chunks.size() * HashBuf.size());
+computeHash(llvm::MutableArrayRef<uint8_t> hashBuf,
+ llvm::ArrayRef<uint8_t> data,
+ std::function<void(uint8_t *dest, ArrayRef<uint8_t> arr)> hashFn) {
+ std::vector<ArrayRef<uint8_t>> chunks = split(data, 1024 * 1024);
+ std::vector<uint8_t> hashes(chunks.size() * hashBuf.size());
// Compute hash values.
- parallelForEachN(0, Chunks.size(), [&](size_t I) {
- HashFn(Hashes.data() + I * HashBuf.size(), Chunks[I]);
+ parallelForEachN(0, chunks.size(), [&](size_t i) {
+ hashFn(hashes.data() + i * hashBuf.size(), chunks[i]);
});
// Write to the final output buffer.
- HashFn(HashBuf.data(), Hashes);
+ hashFn(hashBuf.data(), hashes);
}
template <class ELFT> void Writer<ELFT>::writeBuildId() {
- if (!Main->BuildId || !Main->BuildId->getParent())
+ if (!mainPart->buildId || !mainPart->buildId->getParent())
return;
- if (Config->BuildId == BuildIdKind::Hexstring) {
- for (Partition &Part : Partitions)
- Part.BuildId->writeBuildId(Config->BuildIdVector);
+ if (config->buildId == BuildIdKind::Hexstring) {
+ for (Partition &part : partitions)
+ part.buildId->writeBuildId(config->buildIdVector);
return;
}
// Compute a hash of all sections of the output file.
- size_t HashSize = Main->BuildId->HashSize;
- std::vector<uint8_t> BuildId(HashSize);
- llvm::ArrayRef<uint8_t> Buf{Out::BufferStart, size_t(FileSize)};
+ size_t hashSize = mainPart->buildId->hashSize;
+ std::vector<uint8_t> buildId(hashSize);
+ llvm::ArrayRef<uint8_t> buf{Out::bufferStart, size_t(fileSize)};
- switch (Config->BuildId) {
+ switch (config->buildId) {
case BuildIdKind::Fast:
- computeHash(BuildId, Buf, [](uint8_t *Dest, ArrayRef<uint8_t> Arr) {
- write64le(Dest, xxHash64(Arr));
+ computeHash(buildId, buf, [](uint8_t *dest, ArrayRef<uint8_t> arr) {
+ write64le(dest, xxHash64(arr));
});
break;
case BuildIdKind::Md5:
- computeHash(BuildId, Buf, [&](uint8_t *Dest, ArrayRef<uint8_t> Arr) {
- memcpy(Dest, MD5::hash(Arr).data(), HashSize);
+ computeHash(buildId, buf, [&](uint8_t *dest, ArrayRef<uint8_t> arr) {
+ memcpy(dest, MD5::hash(arr).data(), hashSize);
});
break;
case BuildIdKind::Sha1:
- computeHash(BuildId, Buf, [&](uint8_t *Dest, ArrayRef<uint8_t> Arr) {
- memcpy(Dest, SHA1::hash(Arr).data(), HashSize);
+ computeHash(buildId, buf, [&](uint8_t *dest, ArrayRef<uint8_t> arr) {
+ memcpy(dest, SHA1::hash(arr).data(), hashSize);
});
break;
case BuildIdKind::Uuid:
- if (auto EC = llvm::getRandomBytes(BuildId.data(), HashSize))
- error("entropy source failure: " + EC.message());
+ if (auto ec = llvm::getRandomBytes(buildId.data(), hashSize))
+ error("entropy source failure: " + ec.message());
break;
default:
llvm_unreachable("unknown BuildIdKind");
}
- for (Partition &Part : Partitions)
- Part.BuildId->writeBuildId(BuildId);
+ for (Partition &part : partitions)
+ part.buildId->writeBuildId(buildId);
}
template void elf::writeResult<ELF32LE>();
Modified: lld/trunk/ELF/Writer.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.h?rev=365595&r1=365594&r2=365595&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.h (original)
+++ lld/trunk/ELF/Writer.h Tue Jul 9 22:00:37 2019
@@ -25,8 +25,8 @@ template <class ELFT> void writeResult()
// Each contains type, access flags and range of output sections that will be
// placed in it.
struct PhdrEntry {
- PhdrEntry(unsigned Type, unsigned Flags) : p_type(Type), p_flags(Flags) {}
- void add(OutputSection *Sec);
+ PhdrEntry(unsigned type, unsigned flags) : p_type(type), p_flags(flags) {}
+ void add(OutputSection *sec);
uint64_t p_paddr = 0;
uint64_t p_vaddr = 0;
@@ -37,22 +37,22 @@ struct PhdrEntry {
uint32_t p_type = 0;
uint32_t p_flags = 0;
- OutputSection *FirstSec = nullptr;
- OutputSection *LastSec = nullptr;
- bool HasLMA = false;
+ OutputSection *firstSec = nullptr;
+ OutputSection *lastSec = nullptr;
+ bool hasLMA = false;
- uint64_t LMAOffset = 0;
+ uint64_t lmaOffset = 0;
};
void addReservedSymbols();
-llvm::StringRef getOutputSectionName(const InputSectionBase *S);
+llvm::StringRef getOutputSectionName(const InputSectionBase *s);
template <class ELFT> uint32_t calcMipsEFlags();
-uint8_t getMipsFpAbiFlag(uint8_t OldFlag, uint8_t NewFlag,
- llvm::StringRef FileName);
+uint8_t getMipsFpAbiFlag(uint8_t oldFlag, uint8_t newFlag,
+ llvm::StringRef fileName);
-bool isMipsN32Abi(const InputFile *F);
+bool isMipsN32Abi(const InputFile *f);
bool isMicroMips();
bool isMipsR6();
} // namespace elf
More information about the llvm-commits
mailing list