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
4 changes: 0 additions & 4 deletions include/eld/Config/GeneralOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -599,9 +599,6 @@ class GeneralOptions {
const DynListType &getDynList() const { return DynList; }
DynListType &getDynList() { return DynList; }

const DynListType &getVersionScripts() const { return VersionScripts; }
DynListType &getVersionScripts() { return VersionScripts; }

// ---- remap input file names ---- //
const RemapInputsType &getRemapInputs() const { return RemapInputs; }
RemapInputsType &getRemapInputs() { return RemapInputs; }
Expand Down Expand Up @@ -1354,7 +1351,6 @@ class GeneralOptions {
UndefSymListType UndefSymList; // -u
UndefSymListType ExportDynSymList; // --export-dynamic-symbol
DynListType DynList; // --dynamic-list files
DynListType VersionScripts; // --version-script files
DynListType ExternList; // --extern-list files
RemapInputsType RemapInputs; // --remap-inputs entries
std::string Filter;
Expand Down
14 changes: 0 additions & 14 deletions include/eld/Core/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -607,19 +607,6 @@ class Module {
return VersionScripts;
}

// Tracks VersionScript objects parsed from a VERSION{} block embedded
// directly inside a -T linker script, as opposed to a standalone
// --version-script= file. These still need their nodes registered via
// ObjectLinker::parseVersionScript(), just not re-parsed from scratch.
void addLinkerScriptVersionScript(const VersionScript *VerScr) {
LinkerScriptVersionScripts.push_back(VerScr);
}

const llvm::SmallVectorImpl<const VersionScript *> &
getLinkerScriptVersionScripts() const {
return LinkerScriptVersionScripts;
}

bool isLinkStateBeforeLayout() const {
return getState() == LinkState::BeforeLayout;
}
Expand Down Expand Up @@ -732,7 +719,6 @@ class Module {
DynamicListFileToScriptSymbolsMap;
llvm::StringSet<> OutputSectDescNameSet;
llvm::SmallVector<const VersionScript *> VersionScripts;
llvm::SmallVector<const VersionScript *> LinkerScriptVersionScripts;
llvm::DenseMap<Fragment *, uint64_t> FragmentPaddingValues;
PluginManager PM;
NamePool SymbolNamePool;
Expand Down
10 changes: 9 additions & 1 deletion include/eld/Input/LinkerScriptFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ class ScriptFile;

class LinkerScriptFile : public InputFile {
public:
LinkerScriptFile(Input *I, DiagnosticEngine *DiagEngine);
LinkerScriptFile(Input *I, DiagnosticEngine *DiagEngine,
ScriptFile::Kind ScriptKind = ScriptFile::LDScript);

/// Casting support.
static bool classof(const InputFile *I) {
Expand Down Expand Up @@ -58,9 +59,16 @@ class LinkerScriptFile : public InputFile {

ScriptFile *getScript() const { return Script; }

ScriptFile::Kind getScriptKind() const { return ScriptKind; }

bool isVersionScript() const {
return ScriptKind == ScriptFile::VersionScript;
}

private:
ScriptFile *Script = nullptr;
std::vector<Node *> Nodes;
ScriptFile::Kind ScriptKind = ScriptFile::LDScript;
bool Parsed = false;
bool EarlyActivated = false;
bool FullyActivated = false;
Expand Down
2 changes: 2 additions & 0 deletions include/eld/Object/ObjectLinker.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ class ObjectLinker {

bool parseVersionScript();

bool readVersionScriptFile(InputFile *I);

/// linkable - check the linkability of current LinkerConfig
/// Check list:
/// - check the Attributes are not violate the constaint
Expand Down
8 changes: 5 additions & 3 deletions lib/Core/Linker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -268,9 +268,11 @@ bool Linker::activateInputs(std::vector<InputAction *> &Actions) {
}
if (!Action->activate(IR->getInputBuilder()))
return false;
if (!ObjLinker->readAndActivateLinkerScript(
llvm::dyn_cast<eld::ScriptAction>(Action)->getLinkerScriptFile(),
ScriptFile::ScriptActivationKind::Early)) {
auto *SA = llvm::dyn_cast<eld::ScriptAction>(Action);
if (SA->kind() != eld::ScriptFile::VersionScript &&
!ObjLinker->readAndActivateLinkerScript(
SA->getLinkerScriptFile(),
ScriptFile::ScriptActivationKind::Early)) {
ThisModule->setFailure(true);
return false;
}
Expand Down
6 changes: 4 additions & 2 deletions lib/Input/LinkerScriptFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@

using namespace eld;

LinkerScriptFile::LinkerScriptFile(Input *I, DiagnosticEngine *DiagEngine)
: InputFile(I, DiagEngine, InputFile::GNULinkerScriptKind) {
LinkerScriptFile::LinkerScriptFile(Input *I, DiagnosticEngine *DiagEngine,
ScriptFile::Kind ScriptKind)
: InputFile(I, DiagEngine, InputFile::GNULinkerScriptKind),
ScriptKind(ScriptKind) {
if (I->getSize())
Contents = I->getFileContents();
}
Expand Down
13 changes: 7 additions & 6 deletions lib/LinkerWrapper/GnuLdDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -886,12 +886,6 @@ bool GnuLdDriver::processOptions(llvm::opt::InputArgList &Args) {
if (Config.options().getDynList().size())
Config.options().setDynamicList();

// --version-script
for (auto *Arg : Args.filtered(T::version_script))
Config.options().getVersionScripts().emplace(Arg->getValue());
if (Config.options().getVersionScripts().size())
Config.options().setVersionScript();

// --extern-list
for (auto *Arg : Args.filtered(T::extern_list))
Config.options().getExternList().emplace(Arg->getValue());
Expand Down Expand Up @@ -1367,6 +1361,13 @@ bool GnuLdDriver::createInputActions(llvm::opt::InputArgList &Args,
++input_num;
} break;

case T::version_script: {
actions.push_back(eld::make<eld::ScriptAction>(
arg->getValue(), eld::ScriptFile::VersionScript, Config,
Config.getPrinter()));
Config.options().setVersionScript();
} break;

case T::R: {
Config.options().getScriptList().push_back(arg->getValue());
actions.push_back(eld::make<eld::JustSymbolsAction>(
Expand Down
22 changes: 17 additions & 5 deletions lib/Object/GroupReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,25 @@ bool GroupReader::readGroup(InputBuilder::InputIteratorT &CurNode,
if (!Input->resolvePath(PConfig))
return false;

if (Input->getInputFile() &&
Input->getInputFile()->getKind() == InputFile::GNULinkerScriptKind) {
auto *LSFile =
llvm::dyn_cast<eld::LinkerScriptFile>(Input->getInputFile());
if (LSFile->isVersionScript()) {
if (!MObjLinker->readVersionScriptFile(LSFile))
return false;
++CurNode;
continue;
}
}
if (!MObjLinker->readAndProcessInput(Input, IsPostLtoPhase))
return false;

if (Input->getInputFile()->getKind() == InputFile::GNULinkerScriptKind) {
if (!MObjLinker->readInputs(
llvm::dyn_cast<eld::LinkerScriptFile>(Input->getInputFile())
->getNodes()))
if (Input->getInputFile() &&
Input->getInputFile()->getKind() == InputFile::GNULinkerScriptKind) {
auto *LSFile =
llvm::dyn_cast<eld::LinkerScriptFile>(Input->getInputFile());
if (!LSFile->isVersionScript() &&
!MObjLinker->readInputs(LSFile->getNodes()))
return false;
}

Expand Down
24 changes: 24 additions & 0 deletions lib/Object/LibReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "eld/Config/LinkerConfig.h"
#include "eld/Input/Input.h"
#include "eld/Input/InputTree.h"
#include "eld/Input/LinkerScriptFile.h"
#include "eld/Object/ObjectLinker.h"
#include "eld/Support/MemoryArea.h"
#include "eld/Support/RegisterTimer.h"
Expand Down Expand Up @@ -83,6 +84,29 @@ bool LibReader::readLib(InputBuilder::InputIteratorT &CurNode,
if (!Input->resolvePath(Config))
return false;

if (Input->getInputFile() &&
Input->getInputFile()->getKind() == InputFile::GNULinkerScriptKind) {
auto *LSFile = llvm::cast<eld::LinkerScriptFile>(Input->getInputFile());
if (LSFile->isVersionScript()) {
if (!MObjLinker->readVersionScriptFile(LSFile))
return false;
++CurNode;
continue;
}
}

if (Input->getInputFile() &&
Input->getInputFile()->getKind() == InputFile::GNULinkerScriptKind) {
auto *LSFile = llvm::cast<eld::LinkerScriptFile>(Input->getInputFile());
if (!MObjLinker->readAndProcessInput(Input, IsPostLtoPhase))
return false;
if (!LSFile->isVersionScript() &&
!MObjLinker->readInputs(LSFile->getNodes()))
return false;
++CurNode;
continue;
}

if (IsThin)
MemberNames.push_back(Input->getResolvedPath().getFullPath());
else
Expand Down
104 changes: 54 additions & 50 deletions lib/Object/ObjectLinker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,9 @@ bool ObjectLinker::readAndActivateLinkerScript(
return false;
}

if (S->getVersionScript() && kind == ScriptFile::ScriptActivationKind::Full)
ThisModule->addVersionScript(S->getVersionScript());

if (kind == ScriptFile::ScriptActivationKind::Early)
linkerScriptFile->setEarlyActivated();
else
Expand All @@ -268,6 +271,33 @@ bool ObjectLinker::readAndActivateLinkerScript(
return true;
}

bool ObjectLinker::readVersionScriptFile(InputFile *Input) {
auto *LSFile = llvm::cast<eld::LinkerScriptFile>(Input);
assert(LSFile->isVersionScript() && "Expected version script input");

if (LSFile->isParsed())
return true;

LayoutInfo *layoutInfo = ThisModule->getLayoutInfo();
addInputFileToTar(Input, eld::MappingFile::VersionScript);
if (layoutInfo) {
const eld::Input *I = Input->getInput();
layoutInfo->recordVersionScript(I->wasRemapped() ? I->getOriginalFileName()
: I->getFileName());
}

ScriptFile VSReader(ScriptFile::VersionScript, *ThisModule, *LSFile,
ThisModule->getIRBuilder()->getInputBuilder());
if (!getScriptReader()->readScript(ThisConfig, VSReader))
return false;

LSFile->setParsed();
Input->setToSkip();
if (VSReader.getVersionScript())
ThisModule->addVersionScript(VSReader.getVersionScript());
return true;
}

bool ObjectLinker::readInputs(const std::vector<Node *> &InputVector) {
typedef std::vector<Node *>::const_iterator Iter;

Expand All @@ -278,18 +308,20 @@ bool ObjectLinker::readInputs(const std::vector<Node *> &InputVector) {
eld::RegisterTimer T("Read Start Group and End Group",
"Read all Input files",
ThisConfig.options().printTimingStats());
getGroupReader()->readGroup(Begin,
ThisModule->getIRBuilder()->getInputBuilder(),
ThisConfig, MPostLtoPhase);
if (!getGroupReader()->readGroup(
Begin, ThisModule->getIRBuilder()->getInputBuilder(), ThisConfig,
MPostLtoPhase))
return false;
continue;
}

if ((*Begin)->kind() == Node::LibStart) {
eld::RegisterTimer T("Read Start Lib and End Lib", "Read all Input files",
ThisConfig.options().printTimingStats());
getLibReader()->readLib(Begin,
ThisModule->getIRBuilder()->getInputBuilder(),
ThisConfig, MPostLtoPhase);
if (!getLibReader()->readLib(
Begin, ThisModule->getIRBuilder()->getInputBuilder(), ThisConfig,
MPostLtoPhase))
return false;
continue;
}

Expand All @@ -304,13 +336,23 @@ bool ObjectLinker::readInputs(const std::vector<Node *> &InputVector) {
ThisModule->setFailure(true);
return false;
}
if (Input->getInputFile() &&
Input->getInputFile()->getKind() == InputFile::GNULinkerScriptKind) {
auto *LSFile =
llvm::dyn_cast<eld::LinkerScriptFile>(Input->getInputFile());
if (LSFile->isVersionScript()) {
if (!readVersionScriptFile(LSFile))
return false;
continue;
}
}
if (!readAndProcessInput(Input, MPostLtoPhase))
return false;
if (Input->getInputFile()->getKind() == InputFile::GNULinkerScriptKind) {
// Read inputs that the script contains.
if (!readInputs(
llvm::dyn_cast<eld::LinkerScriptFile>(Input->getInputFile())
->getNodes()))
if (Input->getInputFile() &&
Input->getInputFile()->getKind() == InputFile::GNULinkerScriptKind) {
auto *LSFile =
llvm::dyn_cast<eld::LinkerScriptFile>(Input->getInputFile());
if (!LSFile->isVersionScript() && !readInputs(LSFile->getNodes()))
return false;
}
} // end of for
Expand Down Expand Up @@ -352,49 +394,11 @@ bool ObjectLinker::normalize() {
// FIXME: We should maybe parse version script after reading LTO-generated
// object files.
bool ObjectLinker::parseVersionScript() {
if (ThisConfig.options().hasVersionScript()) {
LayoutInfo *layoutInfo = ThisModule->getLayoutInfo();
for (const auto &List : ThisConfig.options().getVersionScripts()) {
Input *VersionScriptInput =
eld::make<Input>(List, ThisConfig.getDiagEngine(), Input::Script);
if (!VersionScriptInput->resolvePath(ThisConfig))
return false;
// Create an Input file and set the input file to be of kind DynamicList
InputFile *VersionScriptInputFile =
InputFile::create(VersionScriptInput, InputFile::GNULinkerScriptKind,
ThisConfig.getDiagEngine());
addInputFileToTar(VersionScriptInputFile,
eld::MappingFile::VersionScript);
VersionScriptInput->setInputFile(VersionScriptInputFile);
// Record the dynamic list script in the Map file.
if (layoutInfo)
layoutInfo->recordVersionScript(List);
// Read the dynamic List file
ScriptFile VersionScriptReader(
ScriptFile::VersionScript, *ThisModule,
*(llvm::dyn_cast<eld::LinkerScriptFile>(VersionScriptInputFile)),
ThisModule->getIRBuilder()->getInputBuilder());
bool SuccessFullInParse =
getScriptReader()->readScript(ThisConfig, VersionScriptReader);
if (!SuccessFullInParse)
return false;
ThisModule->addVersionScript(VersionScriptReader.getVersionScript());
if (!registerVersionScriptNodes(VersionScriptReader.getVersionScript(),
VersionScriptInput->decoratedPath()))
return false;
}
}

// VersionScript objects parsed from a VERSION{} block embedded directly
// inside a -T linker script (recorded by readLinkerScript(), which runs
// before the target backend is guaranteed to exist). Process them here,
// where registerVersionScriptNodes() can safely touch the backend.
for (const VersionScript *VS : ThisModule->getLinkerScriptVersionScripts()) {
for (const VersionScript *VS : ThisModule->getVersionScripts()) {
if (!registerVersionScriptNodes(
VS, VS->getInputFile()->getInput()->decoratedPath()))
return false;
}

assignVersionNodesToSymbols();
return true;
}
Expand Down
6 changes: 4 additions & 2 deletions lib/Script/ScriptAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
//===----------------------------------------------------------------------===//
#include "eld/Script/ScriptAction.h"
#include "eld/Config/LinkerConfig.h"
#include "eld/Input/InputBuilder.h"
#include "eld/Input/LinkerScriptFile.h"
#include "eld/Input/SearchDirs.h"
#include "eld/Support/MsgHandling.h"
Expand Down Expand Up @@ -59,7 +60,7 @@ bool ScriptAction::activate(InputBuilder &PBuilder) {
Path = Res->native();
}
setFileName(Path);
InputFileAction::activate(PBuilder);
I = PBuilder.createInputNode(Name);

// Resolve the path so that the appropriate file has been read and the memory
// area created for it.
Expand All @@ -68,7 +69,8 @@ bool ScriptAction::activate(InputBuilder &PBuilder) {

// Create an InputFile and set the Input back.
LinkerScriptFile *LSFile =
make<eld::LinkerScriptFile>(I, ThisConfig.getDiagEngine());
make<eld::LinkerScriptFile>(I, ThisConfig.getDiagEngine(),
ScriptFileKind);
I->setInputFile(LSFile);

return true;
Expand Down
6 changes: 0 additions & 6 deletions lib/Script/ScriptFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,12 +170,6 @@ eld::Expected<void> ScriptFile::activate(Module &CurModule,
ELDEXP_RETURN_DIAGENTRY_IF_ERROR(Sym->activate());
}

// A -T script may embed its own VERSION{} block. Record it now so
// parseVersionScript() can register its nodes later, once the target
// backend is guaranteed to be initialized, which is not yet the case here.
if (getVersionScript())
CurModule.addLinkerScriptVersionScript(getVersionScript());

return eld::Expected<void>();
}

Expand Down
Loading