[lld] r244743 - [LinkerScript] Process program header in PHDRS command
Denis Protivensky via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 12 05:31:36 PDT 2015
Author: denis-protivensky
Date: Wed Aug 12 07:31:35 2015
New Revision: 244743
URL: http://llvm.org/viewvc/llvm-project?rev=244743&view=rev
Log:
[LinkerScript] Process program header in PHDRS command
Add PT_PHDR segment depending on its availability in linker script's
PHDRS command, fallback if no linker script is given.
Handle FILEHDR, PHDRS and FLAGS attributes of program header.
Differential Revision: http://reviews.llvm.org/D11589
Added:
lld/trunk/test/elf/linkerscript/phdrs-extra-program.test
lld/trunk/test/elf/linkerscript/phdrs-has-program.test
lld/trunk/test/elf/linkerscript/phdrs-misplaced-program.test
lld/trunk/test/elf/linkerscript/phdrs-no-program.test
lld/trunk/test/elf/linkerscript/phdrs-program-flags.test
lld/trunk/test/elf/linkerscript/phdrs-program-good-phdrs.test
lld/trunk/test/elf/linkerscript/phdrs-program-no-phdrs.test
lld/trunk/test/elf/linkerscript/phdrs-program-wrong-phdrs.test
Modified:
lld/trunk/include/lld/Core/Error.h
lld/trunk/include/lld/ReaderWriter/LinkerScript.h
lld/trunk/lib/Core/Error.cpp
lld/trunk/lib/Driver/GnuLdDriver.cpp
lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.cpp
lld/trunk/lib/ReaderWriter/ELF/TargetLayout.cpp
lld/trunk/lib/ReaderWriter/LinkerScript.cpp
lld/trunk/test/elf/linkerscript/phdrs-invalid.test
Modified: lld/trunk/include/lld/Core/Error.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Error.h?rev=244743&r1=244742&r2=244743&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/Error.h (original)
+++ lld/trunk/include/lld/Core/Error.h Wed Aug 12 07:31:35 2015
@@ -38,6 +38,9 @@ enum class LinkerScriptReaderError {
unknown_symbol_in_expr,
unrecognized_function_in_expr,
unknown_phdr_ids,
+ extra_program_phdr,
+ misplaced_program_phdr,
+ program_phdr_wrong_phdrs,
};
inline std::error_code make_error_code(LinkerScriptReaderError e) {
Modified: lld/trunk/include/lld/ReaderWriter/LinkerScript.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/LinkerScript.h?rev=244743&r1=244742&r2=244743&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/LinkerScript.h (original)
+++ lld/trunk/include/lld/ReaderWriter/LinkerScript.h Wed Aug 12 07:31:35 2015
@@ -79,7 +79,9 @@ public:
kw_entry,
kw_exclude_file,
kw_extern,
+ kw_filehdr,
kw_fill,
+ kw_flags,
kw_group,
kw_hidden,
kw_input,
@@ -818,6 +820,8 @@ public:
StringRef name() const { return _name; }
uint64_t type() const { return _type; }
+ bool hasFileHdr() const { return _includeFileHdr; }
+ bool hasPHDRs() const { return _includePHDRs; }
uint64_t flags() const { return _flags; }
bool isNone() const;
@@ -1284,7 +1288,7 @@ public:
/// Prepare our data structures according to the linker scripts currently in
/// our control (control given via addLinkerScript()). Called once all linker
/// scripts have been parsed.
- void perform();
+ std::error_code perform();
/// Answer if we have layout commands (section mapping rules). If we don't,
/// the output file writer can assume there is no linker script special rule
@@ -1326,12 +1330,14 @@ public:
/// has been performed (by calling evalExpr() for all expressions).
uint64_t getLinkerScriptExprValue(StringRef name) const;
+ /// Check if there are custom headers available.
+ bool hasPHDRs() const;
+
/// Retrieve all the headers the given output section is assigned to.
- /// Error is returned if the output section is assigned to headers with
- /// missing declarations.
- std::error_code
- getPHDRsForOutputSection(StringRef name,
- std::vector<const PHDR *> &phdrs) const;
+ std::vector<const PHDR *> getPHDRsForOutputSection(StringRef name) const;
+
+ /// Retrieve program header if available.
+ const PHDR *getProgramPHDR() const;
void dump() const;
@@ -1374,9 +1380,14 @@ private:
bool localCompare(int order, const SectionKey &lhs,
const SectionKey &rhs) const;
+ /// Convert the PHDRS command into map of names to headers.
+ /// Determine program header during processing.
+ std::error_code collectPHDRs(const PHDRS *ph,
+ llvm::StringMap<const PHDR *> &phdrs);
+
/// Build map that matches output section names to segments they should be
/// put into.
- std::error_code buildSectionToPHDR();
+ std::error_code buildSectionToPHDR(llvm::StringMap<const PHDR *> &phdrs);
/// Our goal with all linearizeAST overloaded functions is to
/// traverse the linker script AST while putting nodes in a vector and
@@ -1433,8 +1444,6 @@ private:
void linearizeAST(const InputSectionsCmd *inputSections);
void linearizeAST(const InputSection *inputSection);
- void perform(const LinkerScript *ls);
-
std::vector<std::unique_ptr<Parser>> _scripts;
std::vector<const Command *> _layoutCommands;
std::unordered_multimap<std::string, int> _memberToLayoutOrder;
@@ -1444,8 +1453,8 @@ private:
llvm::DenseSet<int> _deliveredExprs;
mutable llvm::StringSet<> _definedSymbols;
- bool _parsedPHDRS;
llvm::StringMap<llvm::SmallVector<const PHDR *, 2>> _sectionToPHDR;
+ const PHDR *_programPHDR;
Expression::SymbolTableTy _symbolTable;
};
Modified: lld/trunk/lib/Core/Error.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/Error.cpp?rev=244743&r1=244742&r2=244743&view=diff
==============================================================================
--- lld/trunk/lib/Core/Error.cpp (original)
+++ lld/trunk/lib/Core/Error.cpp Wed Aug 12 07:31:35 2015
@@ -58,6 +58,12 @@ public:
"expression";
case LinkerScriptReaderError::unknown_phdr_ids:
return "Unknown header identifiers (missing in PHDRS command) are used";
+ case LinkerScriptReaderError::extra_program_phdr:
+ return "Extra program header is found";
+ case LinkerScriptReaderError::misplaced_program_phdr:
+ return "Program header must precede load segments";
+ case LinkerScriptReaderError::program_phdr_wrong_phdrs:
+ return "Program header has invalid PHDRS attribute";
}
llvm_unreachable("An enumerator of LinkerScriptReaderError does not have a "
"message defined.");
Modified: lld/trunk/lib/Driver/GnuLdDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/GnuLdDriver.cpp?rev=244743&r1=244742&r2=244743&view=diff
==============================================================================
--- lld/trunk/lib/Driver/GnuLdDriver.cpp (original)
+++ lld/trunk/lib/Driver/GnuLdDriver.cpp Wed Aug 12 07:31:35 2015
@@ -748,7 +748,10 @@ bool GnuLdDriver::parse(llvm::ArrayRef<c
return false;
// Perform linker script semantic actions
- ctx->linkerScriptSema().perform();
+ if (auto ec = ctx->linkerScriptSema().perform()) {
+ diag << "Error in the linker script's semantics: " << ec.message() << "\n";
+ return false;
+ }
context.swap(ctx);
return true;
Modified: lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.cpp?rev=244743&r1=244742&r2=244743&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.cpp Wed Aug 12 07:31:35 2015
@@ -423,7 +423,7 @@ template <class ELFT> int64_t Segment<EL
}
template <class ELFT> void Segment<ELFT>::setSegmentFlags(uint64_t flags) {
- assert(!_segmentFlags && !_flags && "Flags has already been set");
+ assert(!_segmentFlags && "Segment flags have already been set");
_segmentFlags = true;
_flags = flags;
_atomflags = toAtomPermsSegment(flags);
Modified: lld/trunk/lib/ReaderWriter/ELF/TargetLayout.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/TargetLayout.cpp?rev=244743&r1=244742&r2=244743&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/TargetLayout.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/TargetLayout.cpp Wed Aug 12 07:31:35 2015
@@ -330,12 +330,7 @@ template <class ELFT> void TargetLayout<
template <class ELFT>
std::vector<const script::PHDR *>
TargetLayout<ELFT>::getCustomSegments(const OutputSection<ELFT> *sec) const {
- std::vector<const script::PHDR *> phdrs;
- if (_linkerScriptSema.getPHDRsForOutputSection(sec->name(), phdrs)) {
- llvm::report_fatal_error(
- "Linker script has wrong segments set for output sections");
- }
- return phdrs;
+ return _linkerScriptSema.getPHDRsForOutputSection(sec->name());
}
template <class ELFT>
@@ -466,11 +461,36 @@ template <class ELFT> void TargetLayout<
}
}
}
- if (_ctx.isDynamic() && !_ctx.isDynamicLibrary()) {
+
+ // Default values if no linker script is available
+ bool hasProgramSegment = _ctx.isDynamic() && !_ctx.isDynamicLibrary();
+ bool hasElfHeader = true;
+ bool hasProgramHeader = true;
+ uint64_t segmentFlags = 0;
+
+ // Check if linker script has PHDRS and program segment defined
+ if (_linkerScriptSema.hasPHDRs()) {
+ if (auto p = _linkerScriptSema.getProgramPHDR()) {
+ hasProgramSegment = true;
+ hasElfHeader = p->hasFileHdr();
+ hasProgramHeader = p->hasPHDRs();
+ segmentFlags = p->flags();
+ } else {
+ hasProgramSegment = false;
+ hasElfHeader = false;
+ hasProgramHeader = false;
+ }
+ }
+
+ if (hasProgramSegment) {
Segment<ELFT> *segment = new (_allocator) ProgramHeaderSegment<ELFT>(_ctx);
_segments.push_back(segment);
- segment->append(_elfHeader);
- segment->append(_programHeader);
+ if (segmentFlags)
+ segment->setSegmentFlags(segmentFlags);
+ if (hasElfHeader)
+ segment->append(_elfHeader);
+ if (hasProgramHeader)
+ segment->append(_programHeader);
}
}
Modified: lld/trunk/lib/ReaderWriter/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/LinkerScript.cpp?rev=244743&r1=244742&r2=244743&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/LinkerScript.cpp (original)
+++ lld/trunk/lib/ReaderWriter/LinkerScript.cpp Wed Aug 12 07:31:35 2015
@@ -68,7 +68,9 @@ void Token::dump(raw_ostream &os) const
CASE(kw_entry)
CASE(kw_exclude_file)
CASE(kw_extern)
+ CASE(kw_filehdr)
CASE(kw_fill)
+ CASE(kw_flags)
CASE(kw_group)
CASE(kw_hidden)
CASE(kw_input)
@@ -476,7 +478,9 @@ void Lexer::lex(Token &tok) {
.Case("ENTRY", Token::kw_entry)
.Case("EXCLUDE_FILE", Token::kw_exclude_file)
.Case("EXTERN", Token::kw_extern)
+ .Case("FILEHDR", Token::kw_filehdr)
.Case("FILL", Token::kw_fill)
+ .Case("FLAGS", Token::kw_flags)
.Case("GROUP", Token::kw_group)
.Case("HIDDEN", Token::kw_hidden)
.Case("INPUT", Token::kw_input)
@@ -2126,26 +2130,57 @@ const PHDR *Parser::parsePHDR() {
}
uint64_t flags = 0;
+ const Expression *flagsExpr = nullptr;
+ bool includeFileHdr = false;
+ bool includePHDRs = false;
- if (_tok._kind == Token::identifier && _tok._range == "FLAGS") {
- consumeToken();
- if (!expectAndConsume(Token::l_paren, "Expected ("))
- return nullptr;
- const Expression *flagsExpr = parseExpression();
- if (!flagsExpr)
- return nullptr;
- auto f = flagsExpr->evalExpr();
- if (!f)
- return nullptr;
- flags = *f;
- if (!expectAndConsume(Token::r_paren, "Expected )"))
+ while (_tok._kind != Token::semicolon) {
+ switch (_tok._kind) {
+ case Token::kw_filehdr:
+ if (includeFileHdr) {
+ error(_tok, "Duplicate FILEHDR attribute");
+ return nullptr;
+ }
+ includeFileHdr = true;
+ consumeToken();
+ break;
+ case Token::kw_phdrs:
+ if (includePHDRs) {
+ error(_tok, "Duplicate PHDRS attribute");
+ return nullptr;
+ }
+ includePHDRs = true;
+ consumeToken();
+ break;
+ case Token::kw_flags: {
+ if (flagsExpr) {
+ error(_tok, "Duplicate FLAGS attribute");
+ return nullptr;
+ }
+ consumeToken();
+ if (!expectAndConsume(Token::l_paren, "Expected ("))
+ return nullptr;
+ flagsExpr = parseExpression();
+ if (!flagsExpr)
+ return nullptr;
+ auto f = flagsExpr->evalExpr();
+ if (!f)
+ return nullptr;
+ flags = *f;
+ if (!expectAndConsume(Token::r_paren, "Expected )"))
+ return nullptr;
+ } break;
+ default:
+ error(_tok, "Unexpected token");
return nullptr;
+ }
}
if (!expectAndConsume(Token::semicolon, "Expected ;"))
return nullptr;
- return new (getAllocator()) PHDR(name, type, false, false, nullptr, flags);
+ return new (getAllocator())
+ PHDR(name, type, includeFileHdr, includePHDRs, nullptr, flags);
}
PHDRS *Parser::parsePHDRS() {
@@ -2360,11 +2395,22 @@ Extern *Parser::parseExtern() {
}
// Sema member functions
-Sema::Sema() : _parsedPHDRS(false) {}
+Sema::Sema() : _programPHDR(nullptr) {}
-void Sema::perform() {
- for (auto &parser : _scripts)
- perform(parser->get());
+std::error_code Sema::perform() {
+ llvm::StringMap<const PHDR *> phdrs;
+
+ for (auto &parser : _scripts) {
+ for (const Command *c : parser->get()->_commands) {
+ if (const auto *sec = dyn_cast<Sections>(c)) {
+ linearizeAST(sec);
+ } else if (const auto *ph = dyn_cast<PHDRS>(c)) {
+ if (auto ec = collectPHDRs(ph, phdrs))
+ return ec;
+ }
+ }
+ }
+ return buildSectionToPHDR(phdrs);
}
bool Sema::less(const SectionKey &lhs, const SectionKey &rhs) const {
@@ -2469,18 +2515,15 @@ uint64_t Sema::getLinkerScriptExprValue(
return it->second;
}
-std::error_code
-Sema::getPHDRsForOutputSection(StringRef name,
- std::vector<const PHDR *> &phdrs) const {
- // Cache results if not done yet.
- if (auto ec = const_cast<Sema *>(this)->buildSectionToPHDR())
- return ec;
+bool Sema::hasPHDRs() const { return !_sectionToPHDR.empty(); }
+std::vector<const PHDR *> Sema::getPHDRsForOutputSection(StringRef name) const {
auto vec = _sectionToPHDR.lookup(name);
- std::copy(std::begin(vec), std::end(vec), std::back_inserter(phdrs));
- return std::error_code();
+ return std::vector<const PHDR *>(std::begin(vec), std::end(vec));
}
+const PHDR *Sema::getProgramPHDR() const { return _programPHDR; }
+
void Sema::dump() const {
raw_ostream &os = llvm::outs();
os << "Linker script semantics dump\n";
@@ -2717,25 +2760,35 @@ bool Sema::localCompare(int order, const
return false;
}
-std::error_code Sema::buildSectionToPHDR() {
- if (_parsedPHDRS)
- return std::error_code();
- _parsedPHDRS = true;
-
- // No scripts - nothing to do.
- if (_scripts.empty() || _layoutCommands.empty())
- return std::error_code();
-
- // Collect all header declarations.
- llvm::StringMap<const PHDR *> phdrs;
- for (auto &parser : _scripts) {
- for (auto *cmd : parser->get()->_commands) {
- if (auto *ph = dyn_cast<PHDRS>(cmd)) {
- for (auto *p : *ph)
- phdrs[p->name()] = p;
- }
+std::error_code Sema::collectPHDRs(const PHDRS *ph,
+ llvm::StringMap<const PHDR *> &phdrs) {
+ bool loadFound = false;
+ for (auto *p : *ph) {
+ phdrs[p->name()] = p;
+
+ switch (p->type()) {
+ case llvm::ELF::PT_PHDR:
+ if (_programPHDR != nullptr)
+ return LinkerScriptReaderError::extra_program_phdr;
+ if (loadFound)
+ return LinkerScriptReaderError::misplaced_program_phdr;
+ if (!p->hasPHDRs())
+ return LinkerScriptReaderError::program_phdr_wrong_phdrs;
+ _programPHDR = p;
+ break;
+ case llvm::ELF::PT_LOAD:
+ // Program header, if available, should have program header table
+ // mapped in the first loadable segment.
+ if (!loadFound && _programPHDR && !p->hasPHDRs())
+ return LinkerScriptReaderError::program_phdr_wrong_phdrs;
+ loadFound = true;
+ break;
}
}
+ return std::error_code();
+}
+
+std::error_code Sema::buildSectionToPHDR(llvm::StringMap<const PHDR *> &phdrs) {
const bool noPhdrs = phdrs.empty();
// Add NONE header to the map provided there's no user-defined
@@ -2838,12 +2891,5 @@ void Sema::linearizeAST(const Sections *
}
}
-void Sema::perform(const LinkerScript *ls) {
- for (const Command *c : ls->_commands) {
- if (const Sections *sec = dyn_cast<Sections>(c))
- linearizeAST(sec);
- }
-}
-
} // End namespace script
} // end namespace lld
Added: lld/trunk/test/elf/linkerscript/phdrs-extra-program.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/linkerscript/phdrs-extra-program.test?rev=244743&view=auto
==============================================================================
--- lld/trunk/test/elf/linkerscript/phdrs-extra-program.test (added)
+++ lld/trunk/test/elf/linkerscript/phdrs-extra-program.test Wed Aug 12 07:31:35 2015
@@ -0,0 +1,27 @@
+/*
+Test extra program header generates error.
+
+RUN: yaml2obj -format=elf %p/Inputs/simple.o.yaml -o=%t.o
+
+RUN: not lld -flavor gnu -target x86_64 -T %s %t.o -static -o %t1 &> %t1-error
+RUN: FileCheck -check-prefix EXTRA-PROGRAM-PHDR %s < %t1-error
+*/
+
+ENTRY(_start)
+
+PHDRS
+{
+ header PT_PHDR PHDRS;
+ header2 PT_PHDR PHDRS;
+ text PT_LOAD;
+}
+
+SECTIONS
+{
+ .text : { *(.text) } :NONE
+ .data : { *(.data) }
+}
+
+/*
+EXTRA-PROGRAM-PHDR: Extra program header is found
+*/
Added: lld/trunk/test/elf/linkerscript/phdrs-has-program.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/linkerscript/phdrs-has-program.test?rev=244743&view=auto
==============================================================================
--- lld/trunk/test/elf/linkerscript/phdrs-has-program.test (added)
+++ lld/trunk/test/elf/linkerscript/phdrs-has-program.test Wed Aug 12 07:31:35 2015
@@ -0,0 +1,33 @@
+/*
+Test when program segment is set it's generated.
+
+RUN: yaml2obj -format=elf %p/Inputs/simple.o.yaml -o=%t.o
+
+RUN: lld -flavor gnu -target x86_64 -T %s %t.o -static -o %t1
+RUN: llvm-readobj -program-headers %t1 | FileCheck -check-prefix PROGRAM-PHDR %s
+*/
+
+ENTRY(_start)
+
+PHDRS
+{
+ header PT_PHDR FILEHDR PHDRS;
+ text PT_LOAD PHDRS;
+}
+
+SECTIONS
+{
+ .text : { *(.text) } :text
+ .data : { *(.data) }
+}
+
+/*
+PROGRAM-PHDR: ProgramHeader {
+PROGRAM-PHDR: Type: PT_PHDR (0x6)
+PROGRAM-PHDR: VirtualAddress: 0x400040
+PROGRAM-PHDR: Flags [ (0x5)
+PROGRAM-PHDR: PF_R (0x4)
+PROGRAM-PHDR: PF_X (0x1)
+PROGRAM-PHDR: ]
+PROGRAM-PHDR: }
+*/
Modified: lld/trunk/test/elf/linkerscript/phdrs-invalid.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/linkerscript/phdrs-invalid.test?rev=244743&r1=244742&r2=244743&view=diff
==============================================================================
--- lld/trunk/test/elf/linkerscript/phdrs-invalid.test (original)
+++ lld/trunk/test/elf/linkerscript/phdrs-invalid.test Wed Aug 12 07:31:35 2015
@@ -41,7 +41,7 @@ Test undefined header used when no PHDRS
RUN: not lld -flavor gnu -target x86_64 -T %p/phdrs/undef-no-phdrs.script %t.o -static -o %t1 &> %t1-error
RUN: FileCheck -check-prefix UNDEF-NO-PHDRS %s < %t1-error
-UNDEF-NO-PHDRS: Linker script has wrong segments set for output sections
+UNDEF-NO-PHDRS: Unknown header identifiers (missing in PHDRS command) are used
*/
/*
@@ -50,7 +50,7 @@ Test undefined header used when PHDRS is
RUN: not lld -flavor gnu -target x86_64 -T %p/phdrs/undef-empty-phdrs.script %t.o -static -o %t2 &> %t2-error
RUN: FileCheck -check-prefix UNDEF-EMPTY-PHDRS %s < %t2-error
-UNDEF-EMPTY-PHDRS: Linker script has wrong segments set for output sections
+UNDEF-EMPTY-PHDRS: Unknown header identifiers (missing in PHDRS command) are used
*/
/*
@@ -59,5 +59,5 @@ Test undefined header used when PHDRS co
RUN: not lld -flavor gnu -target x86_64 -T %p/phdrs/undef-id-phdrs.script %t.o -static -o %t3 &> %t3-error
RUN: FileCheck -check-prefix UNDEF-ID-PHDRS %s < %t3-error
-UNDEF-ID-PHDRS: Linker script has wrong segments set for output sections
+UNDEF-ID-PHDRS: Unknown header identifiers (missing in PHDRS command) are used
*/
Added: lld/trunk/test/elf/linkerscript/phdrs-misplaced-program.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/linkerscript/phdrs-misplaced-program.test?rev=244743&view=auto
==============================================================================
--- lld/trunk/test/elf/linkerscript/phdrs-misplaced-program.test (added)
+++ lld/trunk/test/elf/linkerscript/phdrs-misplaced-program.test Wed Aug 12 07:31:35 2015
@@ -0,0 +1,26 @@
+/*
+Test misplaced program header generates error.
+
+RUN: yaml2obj -format=elf %p/Inputs/simple.o.yaml -o=%t.o
+
+RUN: not lld -flavor gnu -target x86_64 -T %s %t.o -static -o %t1 &> %t1-error
+RUN: FileCheck -check-prefix MISPLACED-PROGRAM-PHDR %s < %t1-error
+*/
+
+ENTRY(_start)
+
+PHDRS
+{
+ text PT_LOAD;
+ header PT_PHDR PHDRS;
+}
+
+SECTIONS
+{
+ .text : { *(.text) } :NONE
+ .data : { *(.data) }
+}
+
+/*
+MISPLACED-PROGRAM-PHDR: Program header must precede load segments
+*/
Added: lld/trunk/test/elf/linkerscript/phdrs-no-program.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/linkerscript/phdrs-no-program.test?rev=244743&view=auto
==============================================================================
--- lld/trunk/test/elf/linkerscript/phdrs-no-program.test (added)
+++ lld/trunk/test/elf/linkerscript/phdrs-no-program.test Wed Aug 12 07:31:35 2015
@@ -0,0 +1,25 @@
+/*
+Test when no program segment set it's not generated.
+
+RUN: yaml2obj -format=elf %p/Inputs/simple.o.yaml -o=%t.o
+
+RUN: lld -flavor gnu -target x86_64 -T %s %t.o -static -o %t1
+RUN: llvm-readobj -program-headers %t1 | FileCheck -check-prefix PROGRAM-PHDR %s
+*/
+
+ENTRY(_start)
+
+PHDRS
+{
+ text PT_LOAD;
+}
+
+SECTIONS
+{
+ .text : { *(.text) } :text
+ .data : { *(.data) }
+}
+
+/*
+PROGRAM-PHDR-NOT: Type: PT_PHDR (0x6)
+*/
Added: lld/trunk/test/elf/linkerscript/phdrs-program-flags.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/linkerscript/phdrs-program-flags.test?rev=244743&view=auto
==============================================================================
--- lld/trunk/test/elf/linkerscript/phdrs-program-flags.test (added)
+++ lld/trunk/test/elf/linkerscript/phdrs-program-flags.test Wed Aug 12 07:31:35 2015
@@ -0,0 +1,33 @@
+/*
+Test when program segment contains only FLAGS attribute.
+
+RUN: yaml2obj -format=elf %p/Inputs/simple.o.yaml -o=%t.o
+
+RUN: lld -flavor gnu -target x86_64 -T %s %t.o -static -o %t1
+RUN: llvm-readobj -program-headers %t1 | FileCheck -check-prefix PROGRAM-FLAGS-PHDR %s
+*/
+
+ENTRY(_start)
+
+PHDRS
+{
+ header PT_PHDR PHDRS FLAGS(0x7);
+ text PT_LOAD FILEHDR PHDRS;
+}
+
+SECTIONS
+{
+ .text : { *(.text) } :text
+ .data : { *(.data) }
+}
+
+/*
+PROGRAM-FLAGS-PHDR: ProgramHeader {
+PROGRAM-FLAGS-PHDR: Type: PT_PHDR (0x6)
+PROGRAM-FLAGS-PHDR: Flags [ (0x7)
+PROGRAM-FLAGS-PHDR: PF_R (0x4)
+PROGRAM-FLAGS-PHDR: PF_W (0x2)
+PROGRAM-FLAGS-PHDR: PF_X (0x1)
+PROGRAM-FLAGS-PHDR: ]
+PROGRAM-FLAGS-PHDR: }
+*/
Added: lld/trunk/test/elf/linkerscript/phdrs-program-good-phdrs.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/linkerscript/phdrs-program-good-phdrs.test?rev=244743&view=auto
==============================================================================
--- lld/trunk/test/elf/linkerscript/phdrs-program-good-phdrs.test (added)
+++ lld/trunk/test/elf/linkerscript/phdrs-program-good-phdrs.test Wed Aug 12 07:31:35 2015
@@ -0,0 +1,34 @@
+/*
+Test when program segment contains only PHDRS attribute.
+
+RUN: yaml2obj -format=elf %p/Inputs/simple.o.yaml -o=%t.o
+
+RUN: lld -flavor gnu -target x86_64 -T %s %t.o -static -o %t1
+RUN: llvm-readobj -program-headers %t1 | FileCheck -check-prefix PROGRAM-PHDRS-PHDR %s
+*/
+
+ENTRY(_start)
+
+PHDRS
+{
+ header PT_PHDR PHDRS;
+ text PT_LOAD PHDRS;
+}
+
+SECTIONS
+{
+ .text : { *(.text) } :text
+ .data : { *(.data) }
+}
+
+/*
+PROGRAM-PHDRS-PHDR: ProgramHeader {
+PROGRAM-PHDRS-PHDR: Type: PT_PHDR (0x6)
+PROGRAM-PHDRS-PHDR: VirtualAddress: 0x400040
+PROGRAM-PHDRS-PHDR: MemSize: 168
+PROGRAM-PHDRS-PHDR: Flags [ (0x5)
+PROGRAM-PHDRS-PHDR: PF_R (0x4)
+PROGRAM-PHDRS-PHDR: PF_X (0x1)
+PROGRAM-PHDRS-PHDR: ]
+PROGRAM-PHDRS-PHDR: }
+*/
Added: lld/trunk/test/elf/linkerscript/phdrs-program-no-phdrs.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/linkerscript/phdrs-program-no-phdrs.test?rev=244743&view=auto
==============================================================================
--- lld/trunk/test/elf/linkerscript/phdrs-program-no-phdrs.test (added)
+++ lld/trunk/test/elf/linkerscript/phdrs-program-no-phdrs.test Wed Aug 12 07:31:35 2015
@@ -0,0 +1,26 @@
+/*
+Test when program segment doesn't contain PHDRS attribute.
+
+RUN: yaml2obj -format=elf %p/Inputs/simple.o.yaml -o=%t.o
+
+RUN: not lld -flavor gnu -target x86_64 -T %s %t.o -static -o %t1 &> %t1-error
+RUN: FileCheck -check-prefix PROGRAM-PHDR-NO-PHDRS %s < %t1-error
+*/
+
+ENTRY(_start)
+
+PHDRS
+{
+ header PT_PHDR;
+ text PT_LOAD;
+}
+
+SECTIONS
+{
+ .text : { *(.text) } :text
+ .data : { *(.data) }
+}
+
+/*
+PROGRAM-PHDR-NO-PHDRS: Program header has invalid PHDRS attribute
+*/
Added: lld/trunk/test/elf/linkerscript/phdrs-program-wrong-phdrs.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/linkerscript/phdrs-program-wrong-phdrs.test?rev=244743&view=auto
==============================================================================
--- lld/trunk/test/elf/linkerscript/phdrs-program-wrong-phdrs.test (added)
+++ lld/trunk/test/elf/linkerscript/phdrs-program-wrong-phdrs.test Wed Aug 12 07:31:35 2015
@@ -0,0 +1,26 @@
+/*
+Test when program segment contains PHDRS attribute not mapped to load segment.
+
+RUN: yaml2obj -format=elf %p/Inputs/simple.o.yaml -o=%t.o
+
+RUN: not lld -flavor gnu -target x86_64 -T %s %t.o -static -o %t1 &> %t1-error
+RUN: FileCheck -check-prefix PROGRAM-PHDR-WRONG-PHDRS %s < %t1-error
+*/
+
+ENTRY(_start)
+
+PHDRS
+{
+ header PT_PHDR PHDRS;
+ text PT_LOAD;
+}
+
+SECTIONS
+{
+ .text : { *(.text) } :text
+ .data : { *(.data) }
+}
+
+/*
+PROGRAM-PHDR-WRONG-PHDRS: Program header has invalid PHDRS attribute
+*/
More information about the llvm-commits
mailing list