summaryrefslogtreecommitdiffstats
path: root/lld/ELF/ScriptParser.cpp
diff options
context:
space:
mode:
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