summaryrefslogtreecommitdiff
path: root/gnu/llvm
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2022-10-07 15:04:53 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2022-10-07 15:04:53 +0000
commitd84b2f71567c468b7f2769f79a0af1327195910f (patch)
treeb6fad20e138e250832697afebcdb3a36fc9231f3 /gnu/llvm
parentc7304b2b8d4c6bb3e2222fa3795e3ffd2c0eb2f3 (diff)
In the linkers, collect objects in section "openbsd.mutable" and place
them into a page-aligned region in the bss, with the right markers for kernel/ld.so to identify the region and skip making it immutable. While here, fix readelf/objdump versions to show all of this. ok miod kettenis
Diffstat (limited to 'gnu/llvm')
-rw-r--r--gnu/llvm/lld/ELF/ScriptParser.cpp373
-rw-r--r--gnu/llvm/lld/ELF/Writer.cpp8
-rw-r--r--gnu/llvm/llvm/include/llvm/BinaryFormat/ELF.h409
3 files changed, 533 insertions, 257 deletions
diff --git a/gnu/llvm/lld/ELF/ScriptParser.cpp b/gnu/llvm/lld/ELF/ScriptParser.cpp
index fd8de3b54bd..a9b96e3c361 100644
--- a/gnu/llvm/lld/ELF/ScriptParser.cpp
+++ b/gnu/llvm/lld/ELF/ScriptParser.cpp
@@ -29,7 +29,10 @@
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/ScopedPrinter.h"
+#include "llvm/Support/TimeProfiler.h"
#include <cassert>
#include <limits>
#include <vector>
@@ -37,9 +40,9 @@
using namespace llvm;
using namespace llvm::ELF;
using namespace llvm::support::endian;
+using namespace lld;
+using namespace lld::elf;
-namespace lld {
-namespace elf {
namespace {
class ScriptParser final : ScriptLexer {
public:
@@ -74,6 +77,7 @@ private:
void readOutput();
void readOutputArch();
void readOutputFormat();
+ void readOverwriteSections();
void readPhdrs();
void readRegionAlias();
void readSearchDir();
@@ -91,11 +95,15 @@ private:
OutputSection *readOutputSectionDescription(StringRef outSec);
std::vector<BaseCommand *> readOverlay();
std::vector<StringRef> readOutputSectionPhdrs();
+ std::pair<uint64_t, uint64_t> readInputSectionFlags();
InputSectionDescription *readInputSectionDescription(StringRef tok);
StringMatcher readFilePatterns();
std::vector<SectionPattern> readInputSectionsList();
- InputSectionDescription *readInputSectionRules(StringRef filePattern);
+ InputSectionDescription *readInputSectionRules(StringRef filePattern,
+ uint64_t withFlags,
+ uint64_t withoutFlags);
unsigned readPhdrType();
+ SortSectionPolicy peekSortKind();
SortSectionPolicy readSortKind();
SymbolAssignment *readProvideHidden(bool provide, bool hidden);
SymbolAssignment *readAssignment(StringRef tok);
@@ -104,7 +112,7 @@ private:
Expr readConstant();
Expr getPageSize();
- uint64_t readMemoryAssignment(StringRef, StringRef, StringRef);
+ Expr readMemoryAssignment(StringRef, StringRef, StringRef);
std::pair<uint32_t, uint32_t> readMemoryAttributes();
Expr combine(StringRef op, Expr l, Expr r);
@@ -171,7 +179,6 @@ static ExprValue bitOr(ExprValue a, ExprValue b) {
}
void ScriptParser::readDynamicList() {
- config->hasDynamicList = true;
expect("{");
std::vector<SymbolVersion> locals;
std::vector<SymbolVersion> globals;
@@ -245,6 +252,8 @@ void ScriptParser::readLinkerScript() {
readOutputArch();
} else if (tok == "OUTPUT_FORMAT") {
readOutputFormat();
+ } else if (tok == "OVERWRITE_SECTIONS") {
+ readOverwriteSections();
} else if (tok == "PHDRS") {
readPhdrs();
} else if (tok == "REGION_ALIAS") {
@@ -279,29 +288,48 @@ void ScriptParser::addFile(StringRef s) {
if (isUnderSysroot && s.startswith("/")) {
SmallString<128> pathData;
StringRef path = (config->sysroot + s).toStringRef(pathData);
- if (sys::fs::exists(path)) {
+ if (sys::fs::exists(path))
driver->addFile(saver.save(path), /*withLOption=*/false);
- return;
- }
+ else
+ setError("cannot find " + s + " inside " + config->sysroot);
+ return;
}
if (s.startswith("/")) {
+ // Case 1: s is an absolute path. Just open it.
driver->addFile(s, /*withLOption=*/false);
} else if (s.startswith("=")) {
+ // Case 2: relative to the sysroot.
if (config->sysroot.empty())
driver->addFile(s.substr(1), /*withLOption=*/false);
else
driver->addFile(saver.save(config->sysroot + "/" + s.substr(1)),
/*withLOption=*/false);
} else if (s.startswith("-l")) {
+ // Case 3: search in the list of library paths.
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);
- else
- setError("unable to find " + s);
+ // Case 4: s is a relative path. Search in the directory of the script file.
+ std::string filename = std::string(getCurrentMB().getBufferIdentifier());
+ StringRef directory = sys::path::parent_path(filename);
+ if (!directory.empty()) {
+ SmallString<0> path(directory);
+ sys::path::append(path, s);
+ if (sys::fs::exists(path)) {
+ driver->addFile(path, /*withLOption=*/false);
+ return;
+ }
+ }
+ // Then search in the current working directory.
+ if (sys::fs::exists(s)) {
+ driver->addFile(s, /*withLOption=*/false);
+ } else {
+ // Finally, search in the list of library paths.
+ if (Optional<std::string> path = findFromSearchPaths(s))
+ driver->addFile(saver.save(*path), /*withLOption=*/true);
+ else
+ setError("unable to find " + s);
+ }
}
}
@@ -388,7 +416,9 @@ static std::pair<ELFKind, uint16_t> parseBfdName(StringRef s) {
.Case("elf32-x86-64", {ELF32LEKind, EM_X86_64})
.Case("elf64-aarch64", {ELF64LEKind, EM_AARCH64})
.Case("elf64-littleaarch64", {ELF64LEKind, EM_AARCH64})
+ .Case("elf64-bigaarch64", {ELF64BEKind, EM_AARCH64})
.Case("elf32-powerpc", {ELF32BEKind, EM_PPC})
+ .Case("elf32-powerpcle", {ELF32LEKind, EM_PPC})
.Case("elf64-powerpc", {ELF64BEKind, EM_PPC64})
.Case("elf64-powerpcle", {ELF64LEKind, EM_PPC64})
.Case("elf64-x86-64", {ELF64LEKind, EM_X86_64})
@@ -400,32 +430,41 @@ static std::pair<ELFKind, uint16_t> parseBfdName(StringRef s) {
.Case("elf64-tradlittlemips", {ELF64LEKind, EM_MIPS})
.Case("elf32-littleriscv", {ELF32LEKind, EM_RISCV})
.Case("elf64-littleriscv", {ELF64LEKind, EM_RISCV})
+ .Case("elf64-sparc", {ELF64BEKind, EM_SPARCV9})
+ .Case("elf32-msp430", {ELF32LEKind, EM_MSP430})
.Default({ELFNoneKind, EM_NONE});
}
-// Parse OUTPUT_FORMAT(bfdname) or OUTPUT_FORMAT(bfdname, big, little).
-// Currently we ignore big and little parameters.
+// Parse OUTPUT_FORMAT(bfdname) or OUTPUT_FORMAT(default, big, little). Choose
+// big if -EB is specified, little if -EL is specified, or default if neither is
+// specified.
void ScriptParser::readOutputFormat() {
expect("(");
- StringRef name = unquote(next());
- StringRef s = name;
+ StringRef s;
+ config->bfdname = unquote(next());
+ if (!consume(")")) {
+ expect(",");
+ s = unquote(next());
+ if (config->optEB)
+ config->bfdname = s;
+ expect(",");
+ s = unquote(next());
+ if (config->optEL)
+ config->bfdname = s;
+ consume(")");
+ }
+ s = config->bfdname;
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);
+ setError("unknown output format name: " + config->bfdname);
if (s == "elf32-ntradlittlemips" || s == "elf32-ntradbigmips")
config->mipsN32Abi = true;
-
- if (consume(")"))
- return;
- expect(",");
- skip();
- expect(",");
- skip();
- expect(")");
+ if (config->emachine == EM_MSP430)
+ config->osabi = ELFOSABI_STANDALONE;
}
void ScriptParser::readPhdrs() {
@@ -518,14 +557,13 @@ std::vector<BaseCommand *> ScriptParser::readOverlay() {
return v;
}
-void ScriptParser::readSections() {
- 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;
+void ScriptParser::readOverwriteSections() {
+ expect("{");
+ while (!errorCount() && !consume("}"))
+ script->overwriteSections.push_back(readOutputSectionDescription(next()));
+}
+void ScriptParser::readSections() {
expect("{");
std::vector<BaseCommand *> v;
while (!errorCount() && !consume("}")) {
@@ -544,22 +582,26 @@ void ScriptParser::readSections() {
else
v.push_back(readOutputSectionDescription(tok));
}
+ script->sectionCommands.insert(script->sectionCommands.end(), v.begin(),
+ v.end());
- if (!atEOF() && consume("INSERT")) {
- std::vector<BaseCommand *> *dest = nullptr;
- if (consume("AFTER"))
- dest = &script->insertAfterCommands[next()];
- else if (consume("BEFORE"))
- dest = &script->insertBeforeCommands[next()];
- else
- setError("expected AFTER/BEFORE, but got '" + next() + "'");
- if (dest)
- dest->insert(dest->end(), v.begin(), v.end());
+ if (atEOF() || !consume("INSERT")) {
+ script->hasSectionsCommand = true;
return;
}
- script->sectionCommands.insert(script->sectionCommands.end(), v.begin(),
- v.end());
+ bool isAfter = false;
+ if (consume("AFTER"))
+ isAfter = true;
+ else if (!consume("BEFORE"))
+ setError("expected AFTER/BEFORE, but got '" + next() + "'");
+ StringRef where = next();
+ std::vector<StringRef> names;
+ for (BaseCommand *cmd : v)
+ if (auto *os = dyn_cast<OutputSection>(cmd))
+ names.push_back(os->name);
+ if (!names.empty())
+ script->insertCommands.push_back({std::move(names), isAfter, where});
}
void ScriptParser::readTarget() {
@@ -593,22 +635,27 @@ static int precedence(StringRef op) {
}
StringMatcher ScriptParser::readFilePatterns() {
- std::vector<StringRef> v;
+ StringMatcher Matcher;
+
while (!errorCount() && !consume(")"))
- v.push_back(next());
- return StringMatcher(v);
+ Matcher.addPattern(SingleStringMatcher(next()));
+ return Matcher;
+}
+
+SortSectionPolicy ScriptParser::peekSortKind() {
+ return StringSwitch<SortSectionPolicy>(peek())
+ .Cases("SORT", "SORT_BY_NAME", SortSectionPolicy::Name)
+ .Case("SORT_BY_ALIGNMENT", SortSectionPolicy::Alignment)
+ .Case("SORT_BY_INIT_PRIORITY", SortSectionPolicy::Priority)
+ .Case("SORT_NONE", SortSectionPolicy::None)
+ .Default(SortSectionPolicy::Default);
}
SortSectionPolicy ScriptParser::readSortKind() {
- if (consume("SORT") || consume("SORT_BY_NAME"))
- return SortSectionPolicy::Name;
- if (consume("SORT_BY_ALIGNMENT"))
- return SortSectionPolicy::Alignment;
- if (consume("SORT_BY_INIT_PRIORITY"))
- return SortSectionPolicy::Priority;
- if (consume("SORT_NONE"))
- return SortSectionPolicy::None;
- return SortSectionPolicy::Default;
+ SortSectionPolicy ret = peekSortKind();
+ if (ret != SortSectionPolicy::Default)
+ skip();
+ return ret;
}
// Reads SECTIONS command contents in the following form:
@@ -633,12 +680,16 @@ std::vector<SectionPattern> ScriptParser::readInputSectionsList() {
excludeFilePat = readFilePatterns();
}
- std::vector<StringRef> v;
- while (!errorCount() && peek() != ")" && peek() != "EXCLUDE_FILE")
- v.push_back(unquote(next()));
+ StringMatcher SectionMatcher;
+ // Break if the next token is ), EXCLUDE_FILE, or SORT*.
+ while (!errorCount() && peek() != ")" && peek() != "EXCLUDE_FILE" &&
+ peekSortKind() == SortSectionPolicy::Default)
+ SectionMatcher.addPattern(unquote(next()));
- if (!v.empty())
- ret.push_back({std::move(excludeFilePat), StringMatcher(v)});
+ if (!SectionMatcher.empty())
+ ret.push_back({std::move(excludeFilePat), std::move(SectionMatcher)});
+ else if (excludeFilePat.empty())
+ break;
else
setError("section pattern is expected");
}
@@ -657,8 +708,10 @@ std::vector<SectionPattern> ScriptParser::readInputSectionsList() {
//
// <section-list> is parsed by readInputSectionsList().
InputSectionDescription *
-ScriptParser::readInputSectionRules(StringRef filePattern) {
- auto *cmd = make<InputSectionDescription>(filePattern);
+ScriptParser::readInputSectionRules(StringRef filePattern, uint64_t withFlags,
+ uint64_t withoutFlags) {
+ auto *cmd =
+ make<InputSectionDescription>(filePattern, withFlags, withoutFlags);
expect("(");
while (!errorCount() && !consume(")")) {
@@ -694,15 +747,23 @@ InputSectionDescription *
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
+ uint64_t withFlags = 0;
+ uint64_t withoutFlags = 0;
if (tok == "KEEP") {
expect("(");
- StringRef filePattern = next();
- InputSectionDescription *cmd = readInputSectionRules(filePattern);
+ if (consume("INPUT_SECTION_FLAGS"))
+ std::tie(withFlags, withoutFlags) = readInputSectionFlags();
+ InputSectionDescription *cmd =
+ readInputSectionRules(next(), withFlags, withoutFlags);
expect(")");
script->keptSections.push_back(cmd);
return cmd;
}
- return readInputSectionRules(tok);
+ if (tok == "INPUT_SECTION_FLAGS") {
+ std::tie(withFlags, withoutFlags) = readInputSectionFlags();
+ tok = next();
+ }
+ return readInputSectionRules(tok, withFlags, withoutFlags);
}
void ScriptParser::readSort() {
@@ -737,6 +798,7 @@ bool ScriptParser::readSectionDirective(OutputSection *cmd, StringRef tok1, Stri
expect("(");
if (consume("NOLOAD")) {
cmd->noload = true;
+ cmd->type = SHT_NOBITS;
} else {
skip(); // This is "COPY", "INFO" or "OVERLAY".
cmd->nonAlloc = true;
@@ -781,9 +843,14 @@ OutputSection *ScriptParser::readOverlaySectionDescription() {
script->createOutputSection(next(), getCurrentLocation());
cmd->inOverlay = true;
expect("{");
- while (!errorCount() && !consume("}"))
- cmd->sectionCommands.push_back(readInputSectionRules(next()));
- cmd->phdrs = readOutputSectionPhdrs();
+ while (!errorCount() && !consume("}")) {
+ uint64_t withFlags = 0;
+ uint64_t withoutFlags = 0;
+ if (consume("INPUT_SECTION_FLAGS"))
+ std::tie(withFlags, withoutFlags) = readInputSectionFlags();
+ cmd->sectionCommands.push_back(
+ readInputSectionRules(next(), withFlags, withoutFlags));
+ }
return cmd;
}
@@ -828,9 +895,9 @@ OutputSection *ScriptParser::readOutputSectionDescription(StringRef outSec) {
// 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
- expect("(");
+ if (peek() != "(")
+ setError("( expected, but got " + peek());
cmd->filler = readFill();
- expect(")");
} else if (tok == "SORT") {
readSort();
} else if (tok == "INCLUDE") {
@@ -841,18 +908,21 @@ OutputSection *ScriptParser::readOutputSectionDescription(StringRef outSec) {
// 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.
+ // FIXME: GNU ld permits INPUT_SECTION_FLAGS to be used here. We do not
+ // handle this case here as it will already have been matched by the
+ // case above.
auto *isd = make<InputSectionDescription>(tok);
- isd->sectionPatterns.push_back({{}, StringMatcher({"*"})});
+ isd->sectionPatterns.push_back({{}, StringMatcher("*")});
cmd->sectionCommands.push_back(isd);
}
}
if (consume(">"))
- cmd->memoryRegionName = next();
+ cmd->memoryRegionName = std::string(next());
if (consume("AT")) {
expect(">");
- cmd->lmaRegionName = next();
+ cmd->lmaRegionName = std::string(next());
}
if (cmd->lmaExpr && !cmd->lmaRegionName.empty())
@@ -882,8 +952,11 @@ OutputSection *ScriptParser::readOutputSectionDescription(StringRef outSec) {
// When reading a hexstring, ld.bfd handles it as a blob of arbitrary
// 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.
+// Also, we require that expressions with operators must be wrapped into
+// round brackets. We did it to resolve the ambiguity when parsing scripts like:
+// SECTIONS { .foo : { ... } =120+3 /DISCARD/ : { ... } }
std::array<uint8_t, 4> ScriptParser::readFill() {
- uint64_t value = readExpr()().val;
+ uint64_t value = readPrimary()().val;
if (value > UINT32_MAX)
setError("filler expression result does not fit 32-bit: 0x" +
Twine::utohexstr(value));
@@ -928,6 +1001,7 @@ SymbolAssignment *ScriptParser::readAssignment(StringRef tok) {
}
SymbolAssignment *ScriptParser::readSymbolAssignment(StringRef name) {
+ name = unquote(name);
StringRef op = next();
assert(op == "=" || op == "+=");
Expr e = readExpr();
@@ -1057,24 +1131,24 @@ Expr ScriptParser::readConstant() {
static Optional<uint64_t> parseInt(StringRef tok) {
// Hexadecimal
uint64_t val;
- if (tok.startswith_lower("0x")) {
+ if (tok.startswith_insensitive("0x")) {
if (!to_integer(tok.substr(2), val, 16))
return None;
return val;
}
- if (tok.endswith_lower("H")) {
+ if (tok.endswith_insensitive("H")) {
if (!to_integer(tok.drop_back(), val, 16))
return None;
return val;
}
// Decimal
- if (tok.endswith_lower("K")) {
+ if (tok.endswith_insensitive("K")) {
if (!to_integer(tok.drop_back(), val, 10))
return None;
return val * 1024;
}
- if (tok.endswith_lower("M")) {
+ if (tok.endswith_insensitive("M")) {
if (!to_integer(tok.drop_back(), val, 10))
return None;
return val * 1024 * 1024;
@@ -1102,6 +1176,63 @@ ByteCommand *ScriptParser::readByteCommand(StringRef tok) {
return make<ByteCommand>(e, size, commandString);
}
+static llvm::Optional<uint64_t> parseFlag(StringRef tok) {
+ if (llvm::Optional<uint64_t> asInt = parseInt(tok))
+ return asInt;
+#define CASE_ENT(enum) #enum, ELF::enum
+ return StringSwitch<llvm::Optional<uint64_t>>(tok)
+ .Case(CASE_ENT(SHF_WRITE))
+ .Case(CASE_ENT(SHF_ALLOC))
+ .Case(CASE_ENT(SHF_EXECINSTR))
+ .Case(CASE_ENT(SHF_MERGE))
+ .Case(CASE_ENT(SHF_STRINGS))
+ .Case(CASE_ENT(SHF_INFO_LINK))
+ .Case(CASE_ENT(SHF_LINK_ORDER))
+ .Case(CASE_ENT(SHF_OS_NONCONFORMING))
+ .Case(CASE_ENT(SHF_GROUP))
+ .Case(CASE_ENT(SHF_TLS))
+ .Case(CASE_ENT(SHF_COMPRESSED))
+ .Case(CASE_ENT(SHF_EXCLUDE))
+ .Case(CASE_ENT(SHF_ARM_PURECODE))
+ .Default(None);
+#undef CASE_ENT
+}
+
+// Reads the '(' <flags> ')' list of section flags in
+// INPUT_SECTION_FLAGS '(' <flags> ')' in the
+// following form:
+// <flags> ::= <flag>
+// | <flags> & flag
+// <flag> ::= Recognized Flag Name, or Integer value of flag.
+// If the first character of <flag> is a ! then this means without flag,
+// otherwise with flag.
+// Example: SHF_EXECINSTR & !SHF_WRITE means with flag SHF_EXECINSTR and
+// without flag SHF_WRITE.
+std::pair<uint64_t, uint64_t> ScriptParser::readInputSectionFlags() {
+ uint64_t withFlags = 0;
+ uint64_t withoutFlags = 0;
+ expect("(");
+ while (!errorCount()) {
+ StringRef tok = unquote(next());
+ bool without = tok.consume_front("!");
+ if (llvm::Optional<uint64_t> flag = parseFlag(tok)) {
+ if (without)
+ withoutFlags |= *flag;
+ else
+ withFlags |= *flag;
+ } else {
+ setError("unrecognised flag: " + tok);
+ }
+ if (consume(")"))
+ break;
+ if (!consume("&")) {
+ next();
+ setError("expected & or )");
+ }
+ }
+ return std::make_pair(withFlags, withoutFlags);
+}
+
StringRef ScriptParser::readParenLiteral() {
expect("(");
bool orig = inExpr;
@@ -1117,6 +1248,13 @@ static void checkIfExists(OutputSection *cmd, StringRef location) {
error(location + ": undefined section " + cmd->name);
}
+static bool isValidSymbolName(StringRef s) {
+ auto valid = [](char c) {
+ return isAlnum(c) || c == '$' || c == '.' || c == '_';
+ };
+ return !s.empty() && !isDigit(s[0]) && llvm::all_of(s, valid);
+}
+
Expr ScriptParser::readPrimary() {
if (peek() == "(")
return readParenExpr();
@@ -1213,8 +1351,11 @@ Expr ScriptParser::readPrimary() {
return [=] { return alignTo(script->getDot(), e().getValue()); };
}
if (tok == "DEFINED") {
- StringRef name = readParenLiteral();
- return [=] { return symtab->find(name) ? 1 : 0; };
+ StringRef name = unquote(readParenLiteral());
+ return [=] {
+ Symbol *b = symtab->find(name);
+ return (b && b->isDefined()) ? 1 : 0;
+ };
}
if (tok == "LENGTH") {
StringRef name = readParenLiteral();
@@ -1222,7 +1363,7 @@ Expr ScriptParser::readPrimary() {
setError("memory region not defined: " + name);
return [] { return 0; };
}
- return [=] { return script->memoryRegions[name]->length; };
+ return script->memoryRegions[name]->length;
}
if (tok == "LOADADDR") {
StringRef name = readParenLiteral();
@@ -1233,6 +1374,15 @@ Expr ScriptParser::readPrimary() {
return cmd->getLMA();
};
}
+ if (tok == "LOG2CEIL") {
+ expect("(");
+ Expr a = readExpr();
+ expect(")");
+ return [=] {
+ // LOG2CEIL(0) is defined to be 0.
+ return llvm::Log2_64_Ceil(std::max(a().getValue(), UINT64_C(1)));
+ };
+ }
if (tok == "MAX" || tok == "MIN") {
expect("(");
Expr a = readExpr();
@@ -1249,7 +1399,7 @@ Expr ScriptParser::readPrimary() {
setError("memory region not defined: " + name);
return [] { return 0; };
}
- return [=] { return script->memoryRegions[name]->origin; };
+ return script->memoryRegions[name]->origin;
}
if (tok == "SEGMENT_START") {
expect("(");
@@ -1268,7 +1418,7 @@ Expr ScriptParser::readPrimary() {
return [=] { return cmd->size; };
}
if (tok == "SIZEOF_HEADERS")
- return [=] { return getHeaderSize(); };
+ return [=] { return elf::getHeaderSize(); };
// Tok is the dot.
if (tok == ".")
@@ -1279,7 +1429,8 @@ Expr ScriptParser::readPrimary() {
return [=] { return *val; };
// Tok is a symbol name.
- if (!isValidCIdentifier(tok))
+ tok = unquote(tok);
+ if (!isValidSymbolName(tok))
setError("malformed number: " + tok);
script->referencedSymbols.push_back(tok);
return [=] { return script->getSymbolValue(tok, location); };
@@ -1327,6 +1478,7 @@ unsigned ScriptParser::readPhdrType() {
.Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME)
.Case("PT_GNU_STACK", PT_GNU_STACK)
.Case("PT_GNU_RELRO", PT_GNU_RELRO)
+ .Case("PT_OPENBSD_MUTABLE", PT_OPENBSD_MUTABLE)
.Case("PT_OPENBSD_RANDOMIZE", PT_OPENBSD_RANDOMIZE)
.Case("PT_OPENBSD_WXNEEDED", PT_OPENBSD_WXNEEDED)
.Case("PT_OPENBSD_BOOTDATA", PT_OPENBSD_BOOTDATA)
@@ -1345,9 +1497,9 @@ void ScriptParser::readAnonymousDeclaration() {
std::vector<SymbolVersion> globals;
std::tie(locals, globals) = readSymbols();
for (const SymbolVersion &pat : locals)
- config->versionDefinitions[VER_NDX_LOCAL].patterns.push_back(pat);
+ config->versionDefinitions[VER_NDX_LOCAL].localPatterns.push_back(pat);
for (const SymbolVersion &pat : globals)
- config->versionDefinitions[VER_NDX_GLOBAL].patterns.push_back(pat);
+ config->versionDefinitions[VER_NDX_GLOBAL].nonLocalPatterns.push_back(pat);
expect(";");
}
@@ -1359,13 +1511,12 @@ void ScriptParser::readVersionDeclaration(StringRef verStr) {
std::vector<SymbolVersion> locals;
std::vector<SymbolVersion> globals;
std::tie(locals, globals) = readSymbols();
- for (const SymbolVersion &pat : locals)
- config->versionDefinitions[VER_NDX_LOCAL].patterns.push_back(pat);
// Create a new version definition and add that to the global symbols.
VersionDefinition ver;
ver.name = verStr;
- ver.patterns = globals;
+ ver.nonLocalPatterns = std::move(globals);
+ ver.localPatterns = std::move(locals);
ver.id = config->versionDefinitions.size();
config->versionDefinitions.push_back(ver);
@@ -1374,12 +1525,11 @@ void ScriptParser::readVersionDeclaration(StringRef verStr) {
// as a parent. This version hierarchy is, probably against your
// instinct, purely for hint; the runtime doesn't care about it
// at all. In LLD, we simply ignore it.
- if (peek() != ";")
- skip();
- expect(";");
+ if (next() != ";")
+ expect(";");
}
-static bool hasWildcard(StringRef s) {
+bool elf::hasWildcard(StringRef s) {
return s.find_first_of("?*[") != StringRef::npos;
}
@@ -1440,14 +1590,14 @@ std::vector<SymbolVersion> ScriptParser::readVersionExtern() {
return ret;
}
-uint64_t ScriptParser::readMemoryAssignment(StringRef s1, StringRef s2,
- StringRef s3) {
+Expr 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;
+ return [] { return 0; };
}
expect("=");
- return readExpr()().getValue();
+ return readExpr();
}
// Parse the MEMORY command as specified in:
@@ -1471,9 +1621,9 @@ void ScriptParser::readMemory() {
}
expect(":");
- uint64_t origin = readMemoryAssignment("ORIGIN", "org", "o");
+ Expr origin = readMemoryAssignment("ORIGIN", "org", "o");
expect(",");
- uint64_t length = readMemoryAssignment("LENGTH", "len", "l");
+ Expr length = readMemoryAssignment("LENGTH", "len", "l");
// Add the memory region to the region map.
MemoryRegion *mr = make<MemoryRegion>(tok, origin, length, flags, negFlags);
@@ -1511,19 +1661,24 @@ std::pair<uint32_t, uint32_t> ScriptParser::readMemoryAttributes() {
return {flags, negFlags};
}
-void readLinkerScript(MemoryBufferRef mb) {
+void elf::readLinkerScript(MemoryBufferRef mb) {
+ llvm::TimeTraceScope timeScope("Read linker script",
+ mb.getBufferIdentifier());
ScriptParser(mb).readLinkerScript();
}
-void readVersionScript(MemoryBufferRef mb) {
+void elf::readVersionScript(MemoryBufferRef mb) {
+ llvm::TimeTraceScope timeScope("Read version script",
+ mb.getBufferIdentifier());
ScriptParser(mb).readVersionScript();
}
-void readDynamicList(MemoryBufferRef mb) { ScriptParser(mb).readDynamicList(); }
+void elf::readDynamicList(MemoryBufferRef mb) {
+ llvm::TimeTraceScope timeScope("Read dynamic list", mb.getBufferIdentifier());
+ ScriptParser(mb).readDynamicList();
+}
-void readDefsym(StringRef name, MemoryBufferRef mb) {
+void elf::readDefsym(StringRef name, MemoryBufferRef mb) {
+ llvm::TimeTraceScope timeScope("Read defsym input", name);
ScriptParser(mb).readDefsym(name);
}
-
-} // namespace elf
-} // namespace lld
diff --git a/gnu/llvm/lld/ELF/Writer.cpp b/gnu/llvm/lld/ELF/Writer.cpp
index 9e6692b3709..8b5e4e294e8 100644
--- a/gnu/llvm/lld/ELF/Writer.cpp
+++ b/gnu/llvm/lld/ELF/Writer.cpp
@@ -146,7 +146,7 @@ StringRef elf::getOutputSectionName(const InputSectionBase *s) {
{".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.",
- ".openbsd.randomdata."})
+ ".openbsd.randomdata.", ".openbsd.mutable." })
if (isSectionPrefix(v, s->name))
return v.drop_back();
@@ -2470,6 +2470,12 @@ std::vector<PhdrEntry *> Writer<ELFT>::createPhdrs(Partition &part) {
addHdr(PT_GNU_EH_FRAME, part.ehFrameHdr->getParent()->getPhdrFlags())
->add(part.ehFrameHdr->getParent());
+ // PT_OPENBSD_MUTABLE is an OpenBSD-specific feature. That makes
+ // the dynamic linker fill the segment with zero data, like bss, but
+ // it can be treated differently.
+ if (OutputSection *cmd = findSection(".openbsd.mutable", partNo))
+ addHdr(PT_OPENBSD_MUTABLE, cmd->getPhdrFlags())->add(cmd);
+
// 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))
diff --git a/gnu/llvm/llvm/include/llvm/BinaryFormat/ELF.h b/gnu/llvm/llvm/include/llvm/BinaryFormat/ELF.h
index caab91da9c8..fa4139b88c2 100644
--- a/gnu/llvm/llvm/include/llvm/BinaryFormat/ELF.h
+++ b/gnu/llvm/llvm/include/llvm/BinaryFormat/ELF.h
@@ -19,8 +19,10 @@
#ifndef LLVM_BINARYFORMAT_ELF_H
#define LLVM_BINARYFORMAT_ELF_H
+#include "llvm/ADT/StringRef.h"
#include <cstdint>
#include <cstring>
+#include <string>
namespace llvm {
namespace ELF {
@@ -107,13 +109,17 @@ struct Elf64_Ehdr {
unsigned char getDataEncoding() const { return e_ident[EI_DATA]; }
};
-// File types
+// File types.
+// See current registered ELF types at:
+// http://www.sco.com/developers/gabi/latest/ch4.eheader.html
enum {
ET_NONE = 0, // No file type
ET_REL = 1, // Relocatable file
ET_EXEC = 2, // Executable file
ET_DYN = 3, // Shared object file
ET_CORE = 4, // Core file
+ ET_LOOS = 0xfe00, // Beginning of operating system-specific codes
+ ET_HIOS = 0xfeff, // Operating system-specific
ET_LOPROC = 0xff00, // Beginning of processor-specific codes
ET_HIPROC = 0xffff // Processor-specific
};
@@ -277,6 +283,7 @@ enum {
EM_STM8 = 186, // STMicroeletronics STM8 8-bit microcontroller
EM_TILE64 = 187, // Tilera TILE64 multicore architecture family
EM_TILEPRO = 188, // Tilera TILEPro multicore architecture family
+ EM_MICROBLAZE = 189, // Xilinx MicroBlaze 32-bit RISC soft processor core
EM_CUDA = 190, // NVIDIA CUDA architecture
EM_TILEGX = 191, // Tilera TILE-Gx multicore architecture family
EM_CLOUDSHIELD = 192, // CloudShield architecture family
@@ -311,6 +318,8 @@ enum {
EM_RISCV = 243, // RISC-V
EM_LANAI = 244, // Lanai 32-bit processor
EM_BPF = 247, // Linux kernel bpf virtual machine
+ EM_VE = 251, // NEC SX-Aurora VE
+ EM_CSKY = 252, // C-SKY 32-bit processor
};
// Object file classes.
@@ -358,6 +367,15 @@ enum {
ELFOSABI_LAST_ARCH = 255 // Last Architecture-specific OS ABI
};
+// AMDGPU OS ABI Version identification.
+enum {
+ // ELFABIVERSION_AMDGPU_HSA_V1 does not exist because OS ABI identification
+ // was never defined for V1.
+ ELFABIVERSION_AMDGPU_HSA_V2 = 0,
+ ELFABIVERSION_AMDGPU_HSA_V3 = 1,
+ ELFABIVERSION_AMDGPU_HSA_V4 = 2
+};
+
#define ELF_RELOC(name, value) name = value,
// X86_64 relocations.
@@ -393,12 +411,6 @@ static inline int64_t decodePPC64LocalEntryOffset(unsigned Other) {
unsigned Val = (Other & STO_PPC64_LOCAL_MASK) >> STO_PPC64_LOCAL_BIT;
return ((1 << Val) >> 2) << 2;
}
-static inline unsigned encodePPC64LocalEntryOffset(int64_t Offset) {
- unsigned Val =
- (Offset >= 4 * 4 ? (Offset >= 8 * 4 ? (Offset >= 16 * 4 ? 6 : 5) : 4)
- : (Offset >= 2 * 4 ? 3 : (Offset >= 1 * 4 ? 2 : 0)));
- return Val << STO_PPC64_LOCAL_BIT;
-}
// ELF Relocation types for PPC64
enum {
@@ -410,6 +422,12 @@ enum {
#include "ELFRelocs/AArch64.def"
};
+// Special values for the st_other field in the symbol table entry for AArch64.
+enum {
+ // Symbol may follow different calling convention than base PCS.
+ STO_AARCH64_VARIANT_PCS = 0x80
+};
+
// ARM Specific e_flags
enum : unsigned {
EF_ARM_SOFT_FLOAT = 0x00000200U, // Legacy pre EABI_VER5
@@ -470,7 +488,12 @@ enum : unsigned {
EF_AVR_ARCH_XMEGA4 = 104,
EF_AVR_ARCH_XMEGA5 = 105,
EF_AVR_ARCH_XMEGA6 = 106,
- EF_AVR_ARCH_XMEGA7 = 107
+ EF_AVR_ARCH_XMEGA7 = 107,
+
+ EF_AVR_ARCH_MASK = 0x7f, // EF_AVR_ARCH_xxx selection mask
+
+ EF_AVR_LINKRELAX_PREPARED = 0x80, // The file is prepared for linker
+ // relaxation to be applied
};
// ELF Relocation types for AVR
@@ -573,15 +596,18 @@ enum {
// Hexagon-specific e_flags
enum {
// Object processor version flags, bits[11:0]
- EF_HEXAGON_MACH_V2 = 0x00000001, // Hexagon V2
- EF_HEXAGON_MACH_V3 = 0x00000002, // Hexagon V3
- EF_HEXAGON_MACH_V4 = 0x00000003, // Hexagon V4
- EF_HEXAGON_MACH_V5 = 0x00000004, // Hexagon V5
- EF_HEXAGON_MACH_V55 = 0x00000005, // Hexagon V55
- EF_HEXAGON_MACH_V60 = 0x00000060, // Hexagon V60
- EF_HEXAGON_MACH_V62 = 0x00000062, // Hexagon V62
- EF_HEXAGON_MACH_V65 = 0x00000065, // Hexagon V65
- EF_HEXAGON_MACH_V66 = 0x00000066, // Hexagon V66
+ EF_HEXAGON_MACH_V2 = 0x00000001, // Hexagon V2
+ EF_HEXAGON_MACH_V3 = 0x00000002, // Hexagon V3
+ EF_HEXAGON_MACH_V4 = 0x00000003, // Hexagon V4
+ EF_HEXAGON_MACH_V5 = 0x00000004, // Hexagon V5
+ EF_HEXAGON_MACH_V55 = 0x00000005, // Hexagon V55
+ EF_HEXAGON_MACH_V60 = 0x00000060, // Hexagon V60
+ EF_HEXAGON_MACH_V62 = 0x00000062, // Hexagon V62
+ EF_HEXAGON_MACH_V65 = 0x00000065, // Hexagon V65
+ EF_HEXAGON_MACH_V66 = 0x00000066, // Hexagon V66
+ EF_HEXAGON_MACH_V67 = 0x00000067, // Hexagon V67
+ EF_HEXAGON_MACH_V67T = 0x00008067, // Hexagon V67T
+ EF_HEXAGON_MACH_V68 = 0x00000068, // Hexagon V68
// Highest ISA version flags
EF_HEXAGON_ISA_MACH = 0x00000000, // Same as specified in bits[11:0]
@@ -595,6 +621,8 @@ enum {
EF_HEXAGON_ISA_V62 = 0x00000062, // Hexagon V62 ISA
EF_HEXAGON_ISA_V65 = 0x00000065, // Hexagon V65 ISA
EF_HEXAGON_ISA_V66 = 0x00000066, // Hexagon V66 ISA
+ EF_HEXAGON_ISA_V67 = 0x00000067, // Hexagon V67 ISA
+ EF_HEXAGON_ISA_V68 = 0x00000068, // Hexagon V68 ISA
};
// Hexagon-specific section indexes for common small data
@@ -682,47 +710,96 @@ enum : unsigned {
EF_AMDGPU_MACH_R600_LAST = EF_AMDGPU_MACH_R600_TURKS,
// AMDGCN-based processors.
-
- // AMDGCN GFX6.
- EF_AMDGPU_MACH_AMDGCN_GFX600 = 0x020,
- EF_AMDGPU_MACH_AMDGCN_GFX601 = 0x021,
- // AMDGCN GFX7.
- EF_AMDGPU_MACH_AMDGCN_GFX700 = 0x022,
- EF_AMDGPU_MACH_AMDGCN_GFX701 = 0x023,
- EF_AMDGPU_MACH_AMDGCN_GFX702 = 0x024,
- EF_AMDGPU_MACH_AMDGCN_GFX703 = 0x025,
- EF_AMDGPU_MACH_AMDGCN_GFX704 = 0x026,
- // AMDGCN GFX8.
- EF_AMDGPU_MACH_AMDGCN_GFX801 = 0x028,
- EF_AMDGPU_MACH_AMDGCN_GFX802 = 0x029,
- EF_AMDGPU_MACH_AMDGCN_GFX803 = 0x02a,
- EF_AMDGPU_MACH_AMDGCN_GFX810 = 0x02b,
- // AMDGCN GFX9.
- EF_AMDGPU_MACH_AMDGCN_GFX900 = 0x02c,
- EF_AMDGPU_MACH_AMDGCN_GFX902 = 0x02d,
- EF_AMDGPU_MACH_AMDGCN_GFX904 = 0x02e,
- EF_AMDGPU_MACH_AMDGCN_GFX906 = 0x02f,
- EF_AMDGPU_MACH_AMDGCN_GFX908 = 0x030,
- EF_AMDGPU_MACH_AMDGCN_GFX909 = 0x031,
- // AMDGCN GFX10.
- EF_AMDGPU_MACH_AMDGCN_GFX1010 = 0x033,
- EF_AMDGPU_MACH_AMDGCN_GFX1011 = 0x034,
- EF_AMDGPU_MACH_AMDGCN_GFX1012 = 0x035,
-
- // Reserved for AMDGCN-based processors.
- EF_AMDGPU_MACH_AMDGCN_RESERVED0 = 0x027,
- EF_AMDGPU_MACH_AMDGCN_RESERVED1 = 0x032,
+ EF_AMDGPU_MACH_AMDGCN_GFX600 = 0x020,
+ EF_AMDGPU_MACH_AMDGCN_GFX601 = 0x021,
+ EF_AMDGPU_MACH_AMDGCN_GFX700 = 0x022,
+ EF_AMDGPU_MACH_AMDGCN_GFX701 = 0x023,
+ EF_AMDGPU_MACH_AMDGCN_GFX702 = 0x024,
+ EF_AMDGPU_MACH_AMDGCN_GFX703 = 0x025,
+ EF_AMDGPU_MACH_AMDGCN_GFX704 = 0x026,
+ EF_AMDGPU_MACH_AMDGCN_RESERVED_0X27 = 0x027,
+ EF_AMDGPU_MACH_AMDGCN_GFX801 = 0x028,
+ EF_AMDGPU_MACH_AMDGCN_GFX802 = 0x029,
+ EF_AMDGPU_MACH_AMDGCN_GFX803 = 0x02a,
+ EF_AMDGPU_MACH_AMDGCN_GFX810 = 0x02b,
+ EF_AMDGPU_MACH_AMDGCN_GFX900 = 0x02c,
+ EF_AMDGPU_MACH_AMDGCN_GFX902 = 0x02d,
+ EF_AMDGPU_MACH_AMDGCN_GFX904 = 0x02e,
+ EF_AMDGPU_MACH_AMDGCN_GFX906 = 0x02f,
+ EF_AMDGPU_MACH_AMDGCN_GFX908 = 0x030,
+ EF_AMDGPU_MACH_AMDGCN_GFX909 = 0x031,
+ EF_AMDGPU_MACH_AMDGCN_GFX90C = 0x032,
+ EF_AMDGPU_MACH_AMDGCN_GFX1010 = 0x033,
+ EF_AMDGPU_MACH_AMDGCN_GFX1011 = 0x034,
+ EF_AMDGPU_MACH_AMDGCN_GFX1012 = 0x035,
+ EF_AMDGPU_MACH_AMDGCN_GFX1030 = 0x036,
+ EF_AMDGPU_MACH_AMDGCN_GFX1031 = 0x037,
+ EF_AMDGPU_MACH_AMDGCN_GFX1032 = 0x038,
+ EF_AMDGPU_MACH_AMDGCN_GFX1033 = 0x039,
+ EF_AMDGPU_MACH_AMDGCN_GFX602 = 0x03a,
+ EF_AMDGPU_MACH_AMDGCN_GFX705 = 0x03b,
+ EF_AMDGPU_MACH_AMDGCN_GFX805 = 0x03c,
+ EF_AMDGPU_MACH_AMDGCN_GFX1035 = 0x03d,
+ EF_AMDGPU_MACH_AMDGCN_GFX1034 = 0x03e,
+ EF_AMDGPU_MACH_AMDGCN_GFX90A = 0x03f,
+ EF_AMDGPU_MACH_AMDGCN_RESERVED_0X40 = 0x040,
+ EF_AMDGPU_MACH_AMDGCN_RESERVED_0X41 = 0x041,
+ EF_AMDGPU_MACH_AMDGCN_GFX1013 = 0x042,
+ EF_AMDGPU_MACH_AMDGCN_RESERVED_0X43 = 0x043,
+ EF_AMDGPU_MACH_AMDGCN_RESERVED_0X44 = 0x044,
+ EF_AMDGPU_MACH_AMDGCN_RESERVED_0X45 = 0x045,
// First/last AMDGCN-based processors.
EF_AMDGPU_MACH_AMDGCN_FIRST = EF_AMDGPU_MACH_AMDGCN_GFX600,
- EF_AMDGPU_MACH_AMDGCN_LAST = EF_AMDGPU_MACH_AMDGCN_GFX1012,
+ EF_AMDGPU_MACH_AMDGCN_LAST = EF_AMDGPU_MACH_AMDGCN_RESERVED_0X45,
+
+ // Indicates if the "xnack" target feature is enabled for all code contained
+ // in the object.
+ //
+ // Only valid for ELFOSABI_AMDGPU_HSA and ELFABIVERSION_AMDGPU_HSA_V2.
+ EF_AMDGPU_FEATURE_XNACK_V2 = 0x01,
+ // Indicates if the trap handler is enabled for all code contained
+ // in the object.
+ //
+ // Only valid for ELFOSABI_AMDGPU_HSA and ELFABIVERSION_AMDGPU_HSA_V2.
+ EF_AMDGPU_FEATURE_TRAP_HANDLER_V2 = 0x02,
// Indicates if the "xnack" target feature is enabled for all code contained
// in the object.
- EF_AMDGPU_XNACK = 0x100,
- // Indicates if the "sram-ecc" target feature is enabled for all code
+ //
+ // Only valid for ELFOSABI_AMDGPU_HSA and ELFABIVERSION_AMDGPU_HSA_V3.
+ EF_AMDGPU_FEATURE_XNACK_V3 = 0x100,
+ // Indicates if the "sramecc" target feature is enabled for all code
// contained in the object.
- EF_AMDGPU_SRAM_ECC = 0x200,
+ //
+ // Only valid for ELFOSABI_AMDGPU_HSA and ELFABIVERSION_AMDGPU_HSA_V3.
+ EF_AMDGPU_FEATURE_SRAMECC_V3 = 0x200,
+
+ // XNACK selection mask for EF_AMDGPU_FEATURE_XNACK_* values.
+ //
+ // Only valid for ELFOSABI_AMDGPU_HSA and ELFABIVERSION_AMDGPU_HSA_V4.
+ EF_AMDGPU_FEATURE_XNACK_V4 = 0x300,
+ // XNACK is not supported.
+ EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4 = 0x000,
+ // XNACK is any/default/unspecified.
+ EF_AMDGPU_FEATURE_XNACK_ANY_V4 = 0x100,
+ // XNACK is off.
+ EF_AMDGPU_FEATURE_XNACK_OFF_V4 = 0x200,
+ // XNACK is on.
+ EF_AMDGPU_FEATURE_XNACK_ON_V4 = 0x300,
+
+ // SRAMECC selection mask for EF_AMDGPU_FEATURE_SRAMECC_* values.
+ //
+ // Only valid for ELFOSABI_AMDGPU_HSA and ELFABIVERSION_AMDGPU_HSA_V4.
+ EF_AMDGPU_FEATURE_SRAMECC_V4 = 0xc00,
+ // SRAMECC is not supported.
+ EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4 = 0x000,
+ // SRAMECC is any/default/unspecified.
+ EF_AMDGPU_FEATURE_SRAMECC_ANY_V4 = 0x400,
+ // SRAMECC is off.
+ EF_AMDGPU_FEATURE_SRAMECC_OFF_V4 = 0x800,
+ // SRAMECC is on.
+ EF_AMDGPU_FEATURE_SRAMECC_ON_V4 = 0xc00,
};
// ELF Relocation types for AMDGPU
@@ -735,6 +812,11 @@ enum {
#include "ELFRelocs/BPF.def"
};
+// ELF Relocation types for M68k
+enum {
+#include "ELFRelocs/M68k.def"
+};
+
// MSP430 specific e_flags
enum : unsigned {
EF_MSP430_MACH_MSP430x11 = 11,
@@ -767,6 +849,17 @@ enum {
#include "ELFRelocs/MSP430.def"
};
+// ELF Relocation type for VE.
+enum {
+#include "ELFRelocs/VE.def"
+};
+
+
+// ELF Relocation types for CSKY
+enum {
+#include "ELFRelocs/CSKY.def"
+};
+
#undef ELF_RELOC
// Section header.
@@ -813,50 +906,52 @@ enum {
// Section types.
enum : unsigned {
- SHT_NULL = 0, // No associated section (inactive entry).
- SHT_PROGBITS = 1, // Program-defined contents.
- SHT_SYMTAB = 2, // Symbol table.
- SHT_STRTAB = 3, // String table.
- SHT_RELA = 4, // Relocation entries; explicit addends.
- SHT_HASH = 5, // Symbol hash table.
- SHT_DYNAMIC = 6, // Information for dynamic linking.
- SHT_NOTE = 7, // Information about the file.
- SHT_NOBITS = 8, // Data occupies no space in the file.
- SHT_REL = 9, // Relocation entries; no explicit addends.
- SHT_SHLIB = 10, // Reserved.
- SHT_DYNSYM = 11, // Symbol table.
- SHT_INIT_ARRAY = 14, // Pointers to initialization functions.
- SHT_FINI_ARRAY = 15, // Pointers to termination functions.
- SHT_PREINIT_ARRAY = 16, // Pointers to pre-init functions.
- SHT_GROUP = 17, // Section group.
- SHT_SYMTAB_SHNDX = 18, // Indices for SHN_XINDEX entries.
+ SHT_NULL = 0, // No associated section (inactive entry).
+ SHT_PROGBITS = 1, // Program-defined contents.
+ SHT_SYMTAB = 2, // Symbol table.
+ SHT_STRTAB = 3, // String table.
+ SHT_RELA = 4, // Relocation entries; explicit addends.
+ SHT_HASH = 5, // Symbol hash table.
+ SHT_DYNAMIC = 6, // Information for dynamic linking.
+ SHT_NOTE = 7, // Information about the file.
+ SHT_NOBITS = 8, // Data occupies no space in the file.
+ SHT_REL = 9, // Relocation entries; no explicit addends.
+ SHT_SHLIB = 10, // Reserved.
+ SHT_DYNSYM = 11, // Symbol table.
+ SHT_INIT_ARRAY = 14, // Pointers to initialization functions.
+ SHT_FINI_ARRAY = 15, // Pointers to termination functions.
+ SHT_PREINIT_ARRAY = 16, // Pointers to pre-init functions.
+ SHT_GROUP = 17, // Section group.
+ SHT_SYMTAB_SHNDX = 18, // Indices for SHN_XINDEX entries.
// Experimental support for SHT_RELR sections. For details, see proposal
// at https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg
- SHT_RELR = 19, // Relocation entries; only offsets.
- SHT_LOOS = 0x60000000, // Lowest operating system-specific type.
+ SHT_RELR = 19, // Relocation entries; only offsets.
+ SHT_LOOS = 0x60000000, // Lowest operating system-specific type.
// Android packed relocation section types.
// https://android.googlesource.com/platform/bionic/+/6f12bfece5dcc01325e0abba56a46b1bcf991c69/tools/relocation_packer/src/elf_file.cc#37
SHT_ANDROID_REL = 0x60000001,
SHT_ANDROID_RELA = 0x60000002,
SHT_LLVM_ODRTAB = 0x6fff4c00, // LLVM ODR table.
SHT_LLVM_LINKER_OPTIONS = 0x6fff4c01, // LLVM Linker Options.
- SHT_LLVM_CALL_GRAPH_PROFILE = 0x6fff4c02, // LLVM Call Graph Profile.
SHT_LLVM_ADDRSIG = 0x6fff4c03, // List of address-significant symbols
// for safe ICF.
- SHT_LLVM_DEPENDENT_LIBRARIES = 0x6fff4c04, // LLVM Dependent Library Specifiers.
- SHT_LLVM_SYMPART = 0x6fff4c05, // Symbol partition specification.
- SHT_LLVM_PART_EHDR = 0x6fff4c06, // ELF header for loadable partition.
- SHT_LLVM_PART_PHDR = 0x6fff4c07, // Phdrs for loadable partition.
+ SHT_LLVM_DEPENDENT_LIBRARIES =
+ 0x6fff4c04, // LLVM Dependent Library Specifiers.
+ SHT_LLVM_SYMPART = 0x6fff4c05, // Symbol partition specification.
+ SHT_LLVM_PART_EHDR = 0x6fff4c06, // ELF header for loadable partition.
+ SHT_LLVM_PART_PHDR = 0x6fff4c07, // Phdrs for loadable partition.
+ SHT_LLVM_BB_ADDR_MAP = 0x6fff4c08, // LLVM Basic Block Address Map.
+ SHT_LLVM_CALL_GRAPH_PROFILE = 0x6fff4c09, // LLVM Call Graph Profile.
// Android's experimental support for SHT_RELR sections.
// https://android.googlesource.com/platform/bionic/+/b7feec74547f84559a1467aca02708ff61346d2a/libc/include/elf.h#512
- SHT_ANDROID_RELR = 0x6fffff00, // Relocation entries; only offsets.
- SHT_GNU_ATTRIBUTES = 0x6ffffff5, // Object attributes.
- SHT_GNU_HASH = 0x6ffffff6, // GNU-style hash table.
- SHT_GNU_verdef = 0x6ffffffd, // GNU version definitions.
- SHT_GNU_verneed = 0x6ffffffe, // GNU version references.
- SHT_GNU_versym = 0x6fffffff, // GNU symbol versions table.
- SHT_HIOS = 0x6fffffff, // Highest operating system-specific type.
- SHT_LOPROC = 0x70000000, // Lowest processor arch-specific type.
+ SHT_ANDROID_RELR = 0x6fffff00, // Relocation entries; only offsets.
+ SHT_GNU_ATTRIBUTES = 0x6ffffff5, // Object attributes.
+ SHT_GNU_HASH = 0x6ffffff6, // GNU-style hash table.
+ SHT_GNU_verdef = 0x6ffffffd, // GNU version definitions.
+ SHT_GNU_verneed = 0x6ffffffe, // GNU version references.
+ SHT_GNU_versym = 0x6fffffff, // GNU symbol versions table.
+ SHT_HIOS = 0x6fffffff, // Highest operating system-specific type.
+ SHT_LOPROC = 0x70000000, // Lowest processor arch-specific type.
// Fixme: All this is duplicated in MCSectionELF. Why??
// Exception Index table
SHT_ARM_EXIDX = 0x70000001U,
@@ -866,20 +961,22 @@ enum : unsigned {
SHT_ARM_ATTRIBUTES = 0x70000003U,
SHT_ARM_DEBUGOVERLAY = 0x70000004U,
SHT_ARM_OVERLAYSECTION = 0x70000005U,
- SHT_HEX_ORDERED = 0x70000000, // Link editor is to sort the entries in
- // this section based on their sizes
- SHT_X86_64_UNWIND = 0x70000001, // Unwind information
+ SHT_HEX_ORDERED = 0x70000000, // Link editor is to sort the entries in
+ // this section based on their sizes
+ SHT_X86_64_UNWIND = 0x70000001, // Unwind information
- SHT_MIPS_REGINFO = 0x70000006, // Register usage information
- SHT_MIPS_OPTIONS = 0x7000000d, // General options
- SHT_MIPS_DWARF = 0x7000001e, // DWARF debugging section.
- SHT_MIPS_ABIFLAGS = 0x7000002a, // ABI information.
+ SHT_MIPS_REGINFO = 0x70000006, // Register usage information
+ SHT_MIPS_OPTIONS = 0x7000000d, // General options
+ SHT_MIPS_DWARF = 0x7000001e, // DWARF debugging section.
+ SHT_MIPS_ABIFLAGS = 0x7000002a, // ABI information.
SHT_MSP430_ATTRIBUTES = 0x70000003U,
- SHT_HIPROC = 0x7fffffff, // Highest processor arch-specific type.
- SHT_LOUSER = 0x80000000, // Lowest type reserved for applications.
- SHT_HIUSER = 0xffffffff // Highest type reserved for applications.
+ SHT_RISCV_ATTRIBUTES = 0x70000003U,
+
+ SHT_HIPROC = 0x7fffffff, // Highest processor arch-specific type.
+ SHT_LOUSER = 0x80000000, // Lowest type reserved for applications.
+ SHT_HIUSER = 0xffffffff // Highest type reserved for applications.
};
// Section flags.
@@ -918,6 +1015,9 @@ enum : unsigned {
// Identifies a section containing compressed data.
SHF_COMPRESSED = 0x800U,
+ // This section should not be garbage collected by the linker.
+ SHF_GNU_RETAIN = 0x200000,
+
// This section is excluded from the final executable or shared library.
SHF_EXCLUDE = 0x80000000U,
@@ -1203,6 +1303,7 @@ enum {
PT_GNU_RELRO = 0x6474e552, // Read-only after relocation.
PT_GNU_PROPERTY = 0x6474e553, // .note.gnu.property notes sections.
+ PT_OPENBSD_MUTABLE = 0x65a3dbe5, // Like bss, but not immutable.
PT_OPENBSD_RANDOMIZE = 0x65a3dbe6, // Fill with random data.
PT_OPENBSD_WXNEEDED = 0x65a3dbe7, // Program does W^X violations.
PT_OPENBSD_BOOTDATA = 0x65a41be6, // Section for boot arguments.
@@ -1290,7 +1391,8 @@ enum {
DF_1_NORELOC = 0x00400000,
DF_1_SYMINTPOSE = 0x00800000, // Object has individual interposers.
DF_1_GLOBAUDIT = 0x01000000, // Global auditing required.
- DF_1_SINGLETON = 0x02000000 // Singleton symbols are used.
+ DF_1_SINGLETON = 0x02000000, // Singleton symbols are used.
+ DF_1_PIE = 0x08000000, // Object is a position-independent executable.
};
// DT_MIPS_FLAGS values.
@@ -1335,21 +1437,9 @@ enum {
// ElfXX_VerNeed structure version (GNU versioning)
enum { VER_NEED_NONE = 0, VER_NEED_CURRENT = 1 };
-// SHT_NOTE section types
-enum {
- NT_FREEBSD_THRMISC = 7,
- NT_FREEBSD_PROCSTAT_PROC = 8,
- NT_FREEBSD_PROCSTAT_FILES = 9,
- NT_FREEBSD_PROCSTAT_VMMAP = 10,
- NT_FREEBSD_PROCSTAT_GROUPS = 11,
- NT_FREEBSD_PROCSTAT_UMASK = 12,
- NT_FREEBSD_PROCSTAT_RLIMIT = 13,
- NT_FREEBSD_PROCSTAT_OSREL = 14,
- NT_FREEBSD_PROCSTAT_PSSTRINGS = 15,
- NT_FREEBSD_PROCSTAT_AUXV = 16,
-};
+// SHT_NOTE section types.
-// Generic note types
+// Generic note types.
enum : unsigned {
NT_VERSION = 1,
NT_ARCH = 2,
@@ -1357,7 +1447,7 @@ enum : unsigned {
NT_GNU_BUILD_ATTRIBUTE_FUNC = 0x101,
};
-// Core note types
+// Core note types.
enum : unsigned {
NT_PRSTATUS = 1,
NT_FPREGSET = 2,
@@ -1422,7 +1512,7 @@ enum {
NT_LLVM_HWASAN_GLOBALS = 3,
};
-// GNU note types
+// GNU note types.
enum {
NT_GNU_ABI_TAG = 1,
NT_GNU_HWCAP = 2,
@@ -1437,10 +1527,14 @@ enum : unsigned {
GNU_PROPERTY_NO_COPY_ON_PROTECTED = 2,
GNU_PROPERTY_AARCH64_FEATURE_1_AND = 0xc0000000,
GNU_PROPERTY_X86_FEATURE_1_AND = 0xc0000002,
- GNU_PROPERTY_X86_ISA_1_NEEDED = 0xc0008000,
- GNU_PROPERTY_X86_FEATURE_2_NEEDED = 0xc0008001,
- GNU_PROPERTY_X86_ISA_1_USED = 0xc0010000,
- GNU_PROPERTY_X86_FEATURE_2_USED = 0xc0010001,
+
+ GNU_PROPERTY_X86_UINT32_OR_LO = 0xc0008000,
+ GNU_PROPERTY_X86_FEATURE_2_NEEDED = GNU_PROPERTY_X86_UINT32_OR_LO + 1,
+ GNU_PROPERTY_X86_ISA_1_NEEDED = GNU_PROPERTY_X86_UINT32_OR_LO + 2,
+
+ GNU_PROPERTY_X86_UINT32_OR_AND_LO = 0xc0010000,
+ GNU_PROPERTY_X86_FEATURE_2_USED = GNU_PROPERTY_X86_UINT32_OR_AND_LO + 1,
+ GNU_PROPERTY_X86_ISA_1_USED = GNU_PROPERTY_X86_UINT32_OR_AND_LO + 2,
};
// aarch64 processor feature bits.
@@ -1454,31 +1548,6 @@ enum : unsigned {
GNU_PROPERTY_X86_FEATURE_1_IBT = 1 << 0,
GNU_PROPERTY_X86_FEATURE_1_SHSTK = 1 << 1,
- GNU_PROPERTY_X86_ISA_1_CMOV = 1 << 0,
- GNU_PROPERTY_X86_ISA_1_SSE = 1 << 1,
- GNU_PROPERTY_X86_ISA_1_SSE2 = 1 << 2,
- GNU_PROPERTY_X86_ISA_1_SSE3 = 1 << 3,
- GNU_PROPERTY_X86_ISA_1_SSSE3 = 1 << 4,
- GNU_PROPERTY_X86_ISA_1_SSE4_1 = 1 << 5,
- GNU_PROPERTY_X86_ISA_1_SSE4_2 = 1 << 6,
- GNU_PROPERTY_X86_ISA_1_AVX = 1 << 7,
- GNU_PROPERTY_X86_ISA_1_AVX2 = 1 << 8,
- GNU_PROPERTY_X86_ISA_1_FMA = 1 << 9,
- GNU_PROPERTY_X86_ISA_1_AVX512F = 1 << 10,
- GNU_PROPERTY_X86_ISA_1_AVX512CD = 1 << 11,
- GNU_PROPERTY_X86_ISA_1_AVX512ER = 1 << 12,
- GNU_PROPERTY_X86_ISA_1_AVX512PF = 1 << 13,
- GNU_PROPERTY_X86_ISA_1_AVX512VL = 1 << 14,
- GNU_PROPERTY_X86_ISA_1_AVX512DQ = 1 << 15,
- GNU_PROPERTY_X86_ISA_1_AVX512BW = 1 << 16,
- GNU_PROPERTY_X86_ISA_1_AVX512_4FMAPS = 1 << 17,
- GNU_PROPERTY_X86_ISA_1_AVX512_4VNNIW = 1 << 18,
- GNU_PROPERTY_X86_ISA_1_AVX512_BITALG = 1 << 19,
- GNU_PROPERTY_X86_ISA_1_AVX512_IFMA = 1 << 20,
- GNU_PROPERTY_X86_ISA_1_AVX512_VBMI = 1 << 21,
- GNU_PROPERTY_X86_ISA_1_AVX512_VBMI2 = 1 << 22,
- GNU_PROPERTY_X86_ISA_1_AVX512_VNNI = 1 << 23,
-
GNU_PROPERTY_X86_FEATURE_2_X86 = 1 << 0,
GNU_PROPERTY_X86_FEATURE_2_X87 = 1 << 1,
GNU_PROPERTY_X86_FEATURE_2_MMX = 1 << 2,
@@ -1489,6 +1558,43 @@ enum : unsigned {
GNU_PROPERTY_X86_FEATURE_2_XSAVE = 1 << 7,
GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT = 1 << 8,
GNU_PROPERTY_X86_FEATURE_2_XSAVEC = 1 << 9,
+
+ GNU_PROPERTY_X86_ISA_1_BASELINE = 1 << 0,
+ GNU_PROPERTY_X86_ISA_1_V2 = 1 << 1,
+ GNU_PROPERTY_X86_ISA_1_V3 = 1 << 2,
+ GNU_PROPERTY_X86_ISA_1_V4 = 1 << 3,
+};
+
+// FreeBSD note types.
+enum {
+ NT_FREEBSD_ABI_TAG = 1,
+ NT_FREEBSD_NOINIT_TAG = 2,
+ NT_FREEBSD_ARCH_TAG = 3,
+ NT_FREEBSD_FEATURE_CTL = 4,
+};
+
+// NT_FREEBSD_FEATURE_CTL values (see FreeBSD's sys/sys/elf_common.h).
+enum {
+ NT_FREEBSD_FCTL_ASLR_DISABLE = 0x00000001,
+ NT_FREEBSD_FCTL_PROTMAX_DISABLE = 0x00000002,
+ NT_FREEBSD_FCTL_STKGAP_DISABLE = 0x00000004,
+ NT_FREEBSD_FCTL_WXNEEDED = 0x00000008,
+ NT_FREEBSD_FCTL_LA48 = 0x00000010,
+ NT_FREEBSD_FCTL_ASG_DISABLE = 0x00000020,
+};
+
+// FreeBSD core note types.
+enum {
+ NT_FREEBSD_THRMISC = 7,
+ NT_FREEBSD_PROCSTAT_PROC = 8,
+ NT_FREEBSD_PROCSTAT_FILES = 9,
+ NT_FREEBSD_PROCSTAT_VMMAP = 10,
+ NT_FREEBSD_PROCSTAT_GROUPS = 11,
+ NT_FREEBSD_PROCSTAT_UMASK = 12,
+ NT_FREEBSD_PROCSTAT_RLIMIT = 13,
+ NT_FREEBSD_PROCSTAT_OSREL = 14,
+ NT_FREEBSD_PROCSTAT_PSSTRINGS = 15,
+ NT_FREEBSD_PROCSTAT_AUXV = 16,
};
// AMDGPU-specific section indices.
@@ -1496,15 +1602,18 @@ enum {
SHN_AMDGPU_LDS = 0xff00, // Variable in LDS; symbol encoded like SHN_COMMON
};
-// AMD specific notes. (Code Object V2)
+// AMD vendor specific notes. (Code Object V2)
enum {
- // Note types with values between 0 and 9 (inclusive) are reserved.
- NT_AMD_AMDGPU_HSA_METADATA = 10,
- NT_AMD_AMDGPU_ISA = 11,
- NT_AMD_AMDGPU_PAL_METADATA = 12
+ NT_AMD_HSA_CODE_OBJECT_VERSION = 1,
+ NT_AMD_HSA_HSAIL = 2,
+ NT_AMD_HSA_ISA_VERSION = 3,
+ // Note types with values between 4 and 9 (inclusive) are reserved.
+ NT_AMD_HSA_METADATA = 10,
+ NT_AMD_HSA_ISA_NAME = 11,
+ NT_AMD_PAL_METADATA = 12
};
-// AMDGPU specific notes. (Code Object V3)
+// AMDGPU vendor specific notes. (Code Object V3)
enum {
// Note types with values between 0 and 31 (inclusive) are reserved.
NT_AMDGPU_METADATA = 32
@@ -1545,14 +1654,14 @@ struct Elf64_Chdr {
Elf64_Xword ch_addralign;
};
-// Node header for ELF32.
+// Note header for ELF32.
struct Elf32_Nhdr {
Elf32_Word n_namesz;
Elf32_Word n_descsz;
Elf32_Word n_type;
};
-// Node header for ELF64.
+// Note header for ELF64.
struct Elf64_Nhdr {
Elf64_Word n_namesz;
Elf64_Word n_descsz;
@@ -1568,6 +1677,12 @@ enum {
ELFCOMPRESS_HIPROC = 0x7fffffff // End of processor-specific.
};
+/// Convert an architecture name into ELF's e_machine value.
+uint16_t convertArchNameToEMachine(StringRef Arch);
+
+/// Convert an ELF's e_machine value into an architecture name.
+StringRef convertEMachineToArchName(uint16_t EMachine);
+
} // end namespace ELF
} // end namespace llvm