Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 20 additions & 9 deletions include/eld/Object/OutputSectionEntry.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,17 +98,28 @@ class OutputSectionEntry {

void append(RuleContainer *PInput) { Inputs.push_back(PInput); }

const SymbolAssignments &sectionsEndAssignments() const {
return SectionEndAssignments;
const SymbolAssignments &getPostOutputSectionAssignments() const {
return postOutputSectionAssignments;
}
SymbolAssignments &getPostOutputSectionAssignments() {
return postOutputSectionAssignments;
}
SymbolAssignments &sectionEndAssignments() { return SectionEndAssignments; }

sym_iterator sectionendsymBegin() { return SectionEndAssignments.begin(); }
sym_iterator sectionendsymEnd() { return SectionEndAssignments.end(); }
sym_iterator postOutputSectionAssignmentsBegin() {
return postOutputSectionAssignments.begin();
}
sym_iterator postOutputSectionAssignmentsEnd() {
return postOutputSectionAssignments.end();
}

void movePostOutputSectionAssignments(OutputSectionEntry *Out) {
postOutputSectionAssignments = Out->getPostOutputSectionAssignments();
Out->getPostOutputSectionAssignments().clear();
}

void moveSectionAssignments(OutputSectionEntry *Out) {
SectionEndAssignments = Out->sectionEndAssignments();
Out->sectionEndAssignments().clear();
template <typename Func> void forEachPostOutputSectionAssignment(Func F) {
for (auto *A : postOutputSectionAssignments)
F(A);
}

// A section may be part of multiple segments, this only returns the
Expand Down Expand Up @@ -221,7 +232,7 @@ class OutputSectionEntry {
size_t Order;
bool IsDiscard;
InputList Inputs;
SymbolAssignments SectionEndAssignments;
SymbolAssignments postOutputSectionAssignments;
RuleContainer *FirstNonEmptyRule;
RuleContainer *LastRule;
std::vector<BranchIsland *> BranchIslands;
Expand Down
17 changes: 8 additions & 9 deletions include/eld/Script/Assignment.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,11 @@ class ELFSection;
class Assignment : public ScriptCommand {
public:
enum Level {
BEFORE_SECTIONS, // Assignments before SECTIONS command
AFTER_SECTIONS, // Assignments after SECTIONS command
INPUT_SECTION, // related to an input section
SECTIONS_END
BeforeSections, // Assignments before any SECTIONS command
AfterInputSectDesc, // Assignments inside output section body (with input
// rules)
AfterOutputSection, // Assignments between output sections inside SECTIONS
AfterSections // Assignments after SECTIONS command
};

enum Type { DEFAULT, HIDDEN, PROVIDE, PROVIDE_HIDDEN, FILL, ASSERT, PRINT };
Expand All @@ -47,8 +48,6 @@ class Assignment : public ScriptCommand {
Assignment(Level AssignmentLevel, Type AssignmentType, std::string Symbol,
Expression *ScriptExpression);



Level level() const { return AssignmentLevel; }

void setLevel(enum Level AssignmentLevel) {
Expand Down Expand Up @@ -93,12 +92,12 @@ class Assignment : public ScriptCommand {

/// Query functions on Assignment Kinds.
bool isOutsideSections() const {
return AssignmentLevel == BEFORE_SECTIONS ||
AssignmentLevel == AFTER_SECTIONS;
return AssignmentLevel == BeforeSections ||
AssignmentLevel == AfterSections;
}

bool isInsideOutputSection() const {
return AssignmentLevel == INPUT_SECTION;
return AssignmentLevel == AfterInputSectDesc;
}

bool isHidden() const { return ThisType == HIDDEN; }
Expand Down
4 changes: 2 additions & 2 deletions include/eld/Target/GNULDBackend.h
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@ class GNULDBackend {

void evaluateAssignments(OutputSectionEntry *output);

void evaluateAssignmentsAtEndOfOutputSection(OutputSectionEntry *output);
void evaluatePostOutputSectionAssignments(OutputSectionEntry *output);

// Print padding between end and start fragments of adjacent rules
std::vector<PaddingT>
Expand Down Expand Up @@ -962,7 +962,7 @@ class GNULDBackend {

// Evaluate defsym assignments and script assignments that appear outside
// sections.
void evaluateScriptAssignments(bool evaluateAsserts = true);
void evaluateBeforeSectionsAssignments(bool evaluateAsserts = true);

bool isRelROSection(const ELFSection *sect) const;

Expand Down
11 changes: 4 additions & 7 deletions lib/LayoutMap/TextLayoutPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1303,7 +1303,8 @@ void TextLayoutPrinter::printMapFile(eld::Module &Module) {

for (const auto *X : (Script.getScriptCommands())) {
if (const Assignment *A = llvm::dyn_cast<Assignment>(X))
printAssignment(*A, Module, UseColor);
if (A->level() == Assignment::Level::BeforeSections)
printAssignment(*A, Module, UseColor);
}

printLayout(Module);
Expand Down Expand Up @@ -1405,12 +1406,8 @@ void TextLayoutPrinter::printLayout(eld::Module &Module) {
}
}

// Evaluate all assignments at the end of the output section.
for (OutputSectionEntry::sym_iterator It = (*Out)->sectionendsymBegin(),
Ie = (*Out)->sectionendsymEnd();
It != Ie; ++It) {
printAssignment(**It, Module, UseColor);
}
(*Out)->forEachPostOutputSectionAssignment(
[&](Assignment *A) { printAssignment(*A, Module, UseColor); });
}
}

Expand Down
12 changes: 5 additions & 7 deletions lib/LayoutMap/YamlLayoutPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -383,20 +383,18 @@ eld::YamlLayoutPrinter::buildYaml(eld::Module &Module,
}
Result.OutputSections.emplace_back(
std::make_shared<eld::LDYAML::OutputSection>(std::move(Value)));
for (OutputSectionEntry::sym_iterator It = I->sectionendsymBegin(),
Ie = I->sectionendsymEnd();
It != Ie; ++It) {
I->forEachPostOutputSectionAssignment([&](Assignment *A) {
eld::LDYAML::Assignment Assignment;
Assignment.Name = (*It)->name();
Assignment.Value = (*It)->value();
Assignment.Name = A->name();
Assignment.Value = A->value();
{
raw_string_ostream Stream(Assignment.Text);
(*It)->getExpression()->dump(Stream);
A->getExpression()->dump(Stream);
Stream.flush();
}
Result.OutputSections.emplace_back(
std::make_shared<eld::LDYAML::Assignment>(std::move(Assignment)));
}
});
}
Module::const_obj_iterator Obj, ObjEnd = Module.objEnd();
for (Obj = Module.objBegin(); Obj != ObjEnd; ++Obj) {
Expand Down
8 changes: 4 additions & 4 deletions lib/LinkerWrapper/LinkerScript.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -471,10 +471,11 @@ bool plugin::Script::Assignment::isGlobal() const {
return m_Assignment->isOutsideSections();
}

// FIXME: This should return true when the assignment level
// is SECTIONS_END or OUTSIDE_SECTIONS.
bool plugin::Script::Assignment::isOutsideOutputSection() const {
return false;
auto Level = m_Assignment->level();
return Level == eld::Assignment::BeforeSections ||
Level == eld::Assignment::AfterSections ||
Level == eld::Assignment::AfterOutputSection;
}

bool plugin::Script::Assignment::isInsideOutputSection() const {
Expand Down Expand Up @@ -658,7 +659,6 @@ eld::ScriptCommand *plugin::Script::Output::getCommand() const {
return m_Output;
}


//
// OUTPUT_ARCH
//
Expand Down
36 changes: 17 additions & 19 deletions lib/Script/Assignment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ Assignment::Assignment(Level AssignmentLevel, Type AssignmentType,
ExpressionValue(0), Name(Symbol), ExpressionToEvaluate(ScriptExpression),
ThisSymbol(nullptr) {}



void Assignment::dump(llvm::raw_ostream &Outs) const {
bool CloseParen = true;
switch (type()) {
Expand Down Expand Up @@ -75,16 +73,16 @@ void Assignment::dump(llvm::raw_ostream &Outs) const {

void Assignment::trace(llvm::raw_ostream &Outs) const {
switch (AssignmentLevel) {
case BEFORE_SECTIONS:
case BeforeSections:
Outs << "BEFORE_SECTIONS >> ";
break;
case AFTER_SECTIONS:
case AfterSections:
Outs << "AFTER_SECTIONS >> ";
break;
case INPUT_SECTION:
case AfterInputSectDesc:
Outs << " INSIDE_OUTPUT_SECTION >> ";
break;
case SECTIONS_END:
case AfterOutputSection:
Outs << " OUTPUT_SECTION(EPILOGUE) >> ";
break;
}
Expand All @@ -99,22 +97,22 @@ void Assignment::dumpMap(llvm::raw_ostream &Ostream, bool Color,
bool UseNewLine, bool WithValues,
bool AddIndent) const {
switch (AssignmentLevel) {
case BEFORE_SECTIONS:
case AFTER_SECTIONS: {
case BeforeSections:
case AfterSections: {
if (Color)
Ostream.changeColor(llvm::raw_ostream::GREEN);
break;
}

case INPUT_SECTION: {
case AfterInputSectDesc: {
if (Color)
Ostream.changeColor(llvm::raw_ostream::YELLOW);
if (AddIndent)
Ostream << "\t";
break;
}

case SECTIONS_END: {
case AfterOutputSection: {
if (Color)
Ostream.changeColor(llvm::raw_ostream::MAGENTA);
break;
Expand Down Expand Up @@ -176,22 +174,22 @@ eld::Expected<void> Assignment::activate(Module &CurModule) {
ExpressionToEvaluate->setContext(getContext());

switch (AssignmentLevel) {
case BEFORE_SECTIONS:
case AFTER_SECTIONS:
case BeforeSections:
break;

case INPUT_SECTION: {
OutputSectionEntry::reference In = Script.sectionMap().back()->back();
In->symAssignments().push_back(this);
case AfterSections:
case AfterOutputSection: {
SectionMap::reference Out = Script.sectionMap().back();
Out->getPostOutputSectionAssignments().push_back(this);
break;
}

case SECTIONS_END: {
SectionMap::reference Out = Script.sectionMap().back();
Out->sectionEndAssignments().push_back(this);
case AfterInputSectDesc: {
OutputSectionEntry::reference In = Script.sectionMap().back()->back();
In->symAssignments().push_back(this);
break;
}
} // end of switch
}
return eld::Expected<void>();
}

Expand Down
22 changes: 9 additions & 13 deletions lib/Script/ScriptFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -311,30 +311,26 @@ void ScriptFile::addAssignment(const std::string &SymbolName,
if (ScriptStateInsideOutputSection) {
assert(!Sections->empty());
NewAssignment =
make<Assignment>(Assignment::INPUT_SECTION, AssignmentType,
make<Assignment>(Assignment::AfterInputSectDesc, AssignmentType,
SymbolName, ScriptExpression);
NewAssignment->setInputFileInContext(getContext());
NewAssignment->setParent(getParent());
OutputSectionDescription->pushBack(NewAssignment);
} else {
NewAssignment =
make<Assignment>(Assignment::Level::SECTIONS_END, AssignmentType,
make<Assignment>(Assignment::AfterOutputSection, AssignmentType,
SymbolName, ScriptExpression);
NewAssignment->setInputFileInContext(getContext());
NewAssignment->setParent(getParent());
Sections->pushBack(NewAssignment);
}
} else {
// Assignments encountered when not inside SECTIONS are either BEFORE or
// AFTER SECTIONS. Mark as AFTER if we've already seen a SECTIONS block
// in this script file or any previously processed script.
// Global state is sufficient: it is set during parsing when any
// SECTIONS block is entered.
Assignment::Level Lvl = ThisModule.getScript().linkerScriptHasSectionsCommand()
? Assignment::AFTER_SECTIONS
: Assignment::BEFORE_SECTIONS;
NewAssignment = make<Assignment>(Lvl, AssignmentType, SymbolName,
ScriptExpression);
Assignment::Level Lvl =
ThisModule.getScript().linkerScriptHasSectionsCommand()
? Assignment::AfterSections
: Assignment::BeforeSections;
NewAssignment =
make<Assignment>(Lvl, AssignmentType, SymbolName, ScriptExpression);
NewAssignment->setInputFileInContext(getContext());
NewAssignment->setParent(getParent());
LinkerScriptCommandQueue.push_back(NewAssignment);
Expand All @@ -349,7 +345,7 @@ bool ScriptFile::linkerScriptHasSectionsCommand() const {
void ScriptFile::enterSectionsCmd() {
LinkerScriptHasSectionsCommand = true;
// Also mark global script state so other scripts parsed later
// can correctly mark AFTER_SECTIONS assignments.
// can correctly set the level of assignments.
ThisModule.getScript().setHasSectionsCmd();
ScriptStateInSectionsCommmand = true;
auto *Cmd = make<SectionsCmd>();
Expand Down
9 changes: 2 additions & 7 deletions lib/Script/SectionsCmd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ using namespace eld;
//===----------------------------------------------------------------------===//
SectionsCmd::SectionsCmd() : ScriptCommand(ScriptCommand::SECTIONS) {}



void SectionsCmd::dump(llvm::raw_ostream &Outs) const {
Outs << "SECTIONS\n{\n";

Expand Down Expand Up @@ -103,12 +101,9 @@ eld::Expected<void> SectionsCmd::activate(Module &CurModule) {
break;
}
}
// The assignment may be the last set too.
if (!Assignments.empty()) {
iterator Assign, AssignEnd = Assignments.end();
for (Assign = Assignments.begin(); Assign != AssignEnd; ++Assign) {
llvm::cast<Assignment>(*Assign)->setLevel(Assignment::SECTIONS_END);
eld::Expected<void> E = (*Assign)->activate(CurModule);
for (auto *Assign : Assignments) {
eld::Expected<void> E = Assign->activate(CurModule);
ELDEXP_RETURN_DIAGENTRY_IF_ERROR(E);
}
Assignments.clear();
Expand Down
6 changes: 3 additions & 3 deletions lib/Target/CreateProgramHeaders.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ bool GNULDBackend::createProgramHdrs() {
{
eld::RegisterTimer T("Evaluate Script Assignments", "Establish Layout",
m_Module.getConfig().options().printTimingStats());
evaluateScriptAssignments(/*evaluateAsserts=*/false);
evaluateBeforeSectionsAssignments(/*evaluateAsserts=*/false);
}
};

Expand Down Expand Up @@ -321,7 +321,7 @@ bool GNULDBackend::createProgramHdrs() {
if (curIsDebugSection || (*out)->isDiscard()) {
cur->setAddr(dotSymbol->value());
evaluateAssignments(*out);
evaluateAssignmentsAtEndOfOutputSection(*out);
evaluatePostOutputSectionAssignments(*out);
cur->setWanted(cur->wantedInOutput() || cur->size());
++out;
cur->setAddr(0);
Expand Down Expand Up @@ -585,7 +585,7 @@ bool GNULDBackend::createProgramHdrs() {
}

// Evaluate Assignments at end of output section.
evaluateAssignmentsAtEndOfOutputSection(*out);
evaluatePostOutputSectionAssignments(*out);
cur->setWanted(cur->wantedInOutput() || cur->size());

if (!config().getDiagEngine()->diagnose()) {
Expand Down
6 changes: 3 additions & 3 deletions lib/Target/CreateScriptProgramHeaders.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ bool GNULDBackend::createScriptProgramHdrs() {
{
eld::RegisterTimer T("Evaluate Script Assignments", "Establish Layout",
m_Module.getConfig().options().printTimingStats());
evaluateScriptAssignments(/*evaluateAsserts=*/false);
evaluateBeforeSectionsAssignments(/*evaluateAsserts=*/false);
}
};

Expand Down Expand Up @@ -203,7 +203,7 @@ bool GNULDBackend::createScriptProgramHdrs() {
if (curIsDebugSection || (*out)->isDiscard()) {
cur->setAddr(dotSymbol->value());
evaluateAssignments(*out);
evaluateAssignmentsAtEndOfOutputSection(*out);
evaluatePostOutputSectionAssignments(*out);
cur->setAddr(0);
cur->setPaddr(0);
++out;
Expand Down Expand Up @@ -329,7 +329,7 @@ bool GNULDBackend::createScriptProgramHdrs() {
}

// Evaluate Assignments at the end of the output section.
evaluateAssignmentsAtEndOfOutputSection(*out);
evaluatePostOutputSectionAssignments(*out);
cur->setWanted(cur->wantedInOutput() || cur->size());
if (!config().getDiagEngine()->diagnose()) {
return false;
Expand Down
Loading
Loading