summaryrefslogtreecommitdiffstats
path: root/lld/ELF/ScriptParser.cpp
diff options
context:
space:
mode:
authorGeorge Rimar <grimar@accesssoftek.com>2017-10-25 14:50:51 +0000
committerGeorge Rimar <grimar@accesssoftek.com>2017-10-25 14:50:51 +0000
commitf22ec9ddf61a1328f77f039c786cab5d79397ffb (patch)
treebf21a61a859f577e7c4c864153254efca67ef5c4 /lld/ELF/ScriptParser.cpp
parenta3436bb21a26799610005f1956ec0e6ce36789b0 (diff)
downloadbcm5719-llvm-f22ec9ddf61a1328f77f039c786cab5d79397ffb.tar.gz
bcm5719-llvm-f22ec9ddf61a1328f77f039c786cab5d79397ffb.zip
[ELF] - Linkerscript: fix issue with SUBALIGN.
This is PR34886. SUBALIGN command currently triggers failture if result expression is zero. Patch fixes the issue, treating zero as 1, what is consistent with other places and ELF spec it seems. Patch also adds "is power of 2" check for this and other expressions returning alignment. Differential revision: https://reviews.llvm.org/D38846 llvm-svn: 316580
Diffstat (limited to 'lld/ELF/ScriptParser.cpp')
-rw-r--r--lld/ELF/ScriptParser.cpp28
1 files changed, 20 insertions, 8 deletions
diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp
index 5582ce672fb..903be2f503c 100644
--- a/lld/ELF/ScriptParser.cpp
+++ b/lld/ELF/ScriptParser.cpp
@@ -642,6 +642,17 @@ void ScriptParser::readSectionAddressType(OutputSection *Cmd) {
}
}
+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");
+ return (uint64_t)1; // Return a dummy value.
+ }
+ return Alignment;
+ };
+}
+
OutputSection *ScriptParser::readOutputSectionDescription(StringRef OutSec) {
OutputSection *Cmd =
Script->createOutputSection(OutSec, getCurrentLocation());
@@ -650,12 +661,13 @@ OutputSection *ScriptParser::readOutputSectionDescription(StringRef OutSec) {
readSectionAddressType(Cmd);
expect(":");
+ std::string Location = getCurrentLocation();
if (consume("AT"))
Cmd->LMAExpr = readParenExpr();
if (consume("ALIGN"))
- Cmd->AlignExpr = readParenExpr();
+ Cmd->AlignExpr = checkAlignment(readParenExpr(), Location);
if (consume("SUBALIGN"))
- Cmd->SubalignExpr = readParenExpr();
+ Cmd->SubalignExpr = checkAlignment(readParenExpr(), Location);
// Parse constraints.
if (consume("ONLY_IF_RO"))
@@ -959,16 +971,16 @@ Expr ScriptParser::readPrimary() {
if (Tok == "ALIGN") {
expect("(");
Expr E = readExpr();
- if (consume(")"))
- return [=] {
- return alignTo(Script->getDot(), std::max((uint64_t)1, E().getValue()));
- };
+ if (consume(")")) {
+ E = checkAlignment(E, Location);
+ return [=] { return alignTo(Script->getDot(), E().getValue()); };
+ }
expect(",");
- Expr E2 = readExpr();
+ Expr E2 = checkAlignment(readExpr(), Location);
expect(")");
return [=] {
ExprValue V = E();
- V.Alignment = std::max((uint64_t)1, E2().getValue());
+ V.Alignment = E2().getValue();
return V;
};
}
OpenPOWER on IntegriCloud