[ELF] Create Attribute class associated with Input files.

The attribute class holds positional attributes for Input files specified on the
command line for the Gnu flavor.

llvm-svn: 205392
This commit is contained in:
Shankar Easwaran 2014-04-02 03:57:39 +00:00
parent a00abba152
commit 086f8a6ef5
3 changed files with 43 additions and 26 deletions

View File

@ -28,12 +28,30 @@ namespace lld {
/// \brief Represents a ELF File
class ELFFileNode : public FileNode {
public:
ELFFileNode(ELFLinkingContext &ctx, StringRef path, int64_t ordinal = -1,
bool isWholeArchive = false, bool asNeeded = false,
bool dashlPrefix = false)
/// \brief The attributes class provides a way for a input file to look into
/// all the positional attributes that were specified in the command line.
/// There are few positional operators and the number of arguments to the
/// ELFFileNode class keeps growing. This achieves code to be clean as well.
class Attributes {
public:
Attributes()
: _isWholeArchive(false), _asNeeded(false), _isDashlPrefix(false) {}
void setWholeArchive(bool isWholeArchive) {
_isWholeArchive = isWholeArchive;
}
void setAsNeeded(bool asNeeded) { _asNeeded = asNeeded; }
void setDashlPrefix(bool isDashlPrefix) { _isDashlPrefix = isDashlPrefix; }
public:
bool _isWholeArchive;
bool _asNeeded;
bool _isDashlPrefix;
};
ELFFileNode(ELFLinkingContext &ctx, StringRef path, int64_t ordinal,
Attributes &attributes)
: FileNode(path, ordinal), _elfLinkingContext(ctx),
_isWholeArchive(isWholeArchive), _asNeeded(asNeeded),
_isDashlPrefix(dashlPrefix) {}
_attributes(attributes) {}
ErrorOr<StringRef> getPath(const LinkingContext &ctx) const override;
@ -50,9 +68,9 @@ public:
<< "Attributes : "
<< "\n"
<< " - wholeArchive : "
<< ((_isWholeArchive) ? "true" : "false") << "\n"
<< " - asNeeded : " << ((_asNeeded) ? "true" : "false")
<< "\n";
<< ((_attributes._isWholeArchive) ? "true" : "false") << "\n"
<< " - asNeeded : "
<< ((_attributes._asNeeded) ? "true" : "false") << "\n";
return true;
}
@ -66,7 +84,8 @@ public:
/// reset the next file index to 0 only if the node is an archive library or
/// a shared library
void resetNextIndex() override {
if ((!_isWholeArchive && (_files[0]->kind() == File::kindArchiveLibrary)) ||
if ((!_attributes._isWholeArchive &&
(_files[0]->kind() == File::kindArchiveLibrary)) ||
(_files[0]->kind() == File::kindSharedLibrary)) {
_nextFileIndex = 0;
}
@ -86,10 +105,8 @@ public:
private:
llvm::BumpPtrAllocator _alloc;
const ELFLinkingContext &_elfLinkingContext;
bool _isWholeArchive;
bool _asNeeded;
bool _isDashlPrefix;
std::unique_ptr<const ArchiveLibraryFile> _archiveFile;
const Attributes _attributes;
};
/// \brief Parse GNU Linker scripts.

View File

@ -143,14 +143,14 @@ static bool parseDefsymOption(StringRef opt, StringRef &sym, uint64_t &addr) {
}
llvm::ErrorOr<StringRef> ELFFileNode::getPath(const LinkingContext &) const {
if (!_isDashlPrefix)
if (!_attributes._isDashlPrefix)
return _path;
return _elfLinkingContext.searchLibrary(_path);
}
std::string ELFFileNode::errStr(error_code errc) {
if (errc == llvm::errc::no_such_file_or_directory) {
if (_isDashlPrefix)
if (_attributes._isDashlPrefix)
return (Twine("Unable to find library -l") + _path).str();
return (Twine("Unable to find file ") + _path).str();
}
@ -268,12 +268,10 @@ bool GnuLdDriver::parse(int argc, const char *argv[],
std::unique_ptr<InputGraph> inputGraph(new InputGraph());
std::stack<Group *> groupStack;
// Positional options for an Input File
bool isWholeArchive = false;
bool asNeeded = false;
bool _outputOptionSet = false;
ELFFileNode::Attributes attributes;
int index = 0;
bool _outputOptionSet = false;
// Ignore unknown arguments.
for (auto it = parsedArgs->filtered_begin(OPT_UNKNOWN),
@ -403,19 +401,19 @@ bool GnuLdDriver::parse(int argc, const char *argv[],
break;
case OPT_no_whole_archive:
isWholeArchive = false;
attributes.setWholeArchive(false);
break;
case OPT_whole_archive:
isWholeArchive = true;
attributes.setWholeArchive(true);
break;
case OPT_as_needed:
asNeeded = true;
attributes.setAsNeeded(true);
break;
case OPT_no_as_needed:
asNeeded = false;
attributes.setAsNeeded(false);
break;
case OPT_defsym: {
@ -453,6 +451,7 @@ bool GnuLdDriver::parse(int argc, const char *argv[],
case OPT_INPUT:
case OPT_l: {
bool isDashlPrefix = (inputArg->getOption().getID() == OPT_l);
attributes.setDashlPrefix(isDashlPrefix);
bool isELFFileNode = true;
StringRef userPath = inputArg->getValue();
std::string resolvedInputPath = userPath;
@ -481,8 +480,7 @@ bool GnuLdDriver::parse(int argc, const char *argv[],
isELFFileNode = false;
FileNode *inputNode = nullptr;
if (isELFFileNode)
inputNode = new ELFFileNode(*ctx, userPath, index++, isWholeArchive,
asNeeded, isDashlPrefix);
inputNode = new ELFFileNode(*ctx, userPath, index++, attributes);
else {
inputNode = new ELFGNULdScript(*ctx, resolvedInputPath, index++);
ec = inputNode->parse(*ctx, diagnostics);

View File

@ -25,7 +25,7 @@ error_code ELFFileNode::parse(const LinkingContext &ctx,
if (ctx.logInputFiles())
diagnostics << *filePath << "\n";
if (_isWholeArchive) {
if (_attributes._isWholeArchive) {
std::vector<std::unique_ptr<File>> parsedFiles;
error_code ec = ctx.registry().parseFile(_buffer, parsedFiles);
if (ec)
@ -75,6 +75,7 @@ error_code GNULdScript::parse(const LinkingContext &ctx,
error_code ELFGNULdScript::parse(const LinkingContext &ctx,
raw_ostream &diagnostics) {
int64_t index = 0;
ELFFileNode::Attributes attributes;
if (error_code ec = GNULdScript::parse(ctx, diagnostics))
return ec;
for (const auto &c : _linkerScript->_commands) {
@ -82,9 +83,10 @@ error_code ELFGNULdScript::parse(const LinkingContext &ctx,
std::unique_ptr<Group> groupStart(new Group(index++));
for (auto &path : group->getPaths()) {
// TODO : Propagate Set WholeArchive/dashlPrefix
attributes.setAsNeeded(path._asNeeded);
auto inputNode = new ELFFileNode(
_elfLinkingContext, _elfLinkingContext.allocateString(path._path),
index++, false, path._asNeeded, false);
index++, attributes);
std::unique_ptr<InputElement> inputFile(inputNode);
cast<Group>(groupStart.get())->addFile(
std::move(inputFile));