[ELF] Fix -nostdlib option.

Only search library directories explicitly specified
on the command line. Library directories specified in linker
scripts (including linker scripts specified on the command
line) are ignored.

llvm-svn: 228375
This commit is contained in:
Shankar Easwaran
2015-02-06 04:15:00 +00:00
parent a786077253
commit e315edd747
4 changed files with 27 additions and 5 deletions

View File

@@ -303,6 +303,10 @@ public:
_scripts.push_back(std::move(script));
}
/// \brief nostdlib support.
bool nostdlib() const { return _nostdlib; }
void setNoStdLib(bool nostdlib) { _nostdlib = nostdlib; }
private:
ELFLinkingContext() LLVM_DELETED_FUNCTION;
@@ -328,6 +332,7 @@ protected:
bool _mergeRODataToTextSegment;
bool _demangle;
bool _alignSegments;
bool _nostdlib;
llvm::Optional<uint64_t> _maxPageSize;
OutputMagic _outputMagic;

View File

@@ -293,7 +293,8 @@ GnuLdDriver::evalLinkerScript(ELFLinkingContext &ctx,
ctx.getNodes().push_back(llvm::make_unique<GroupEnd>(groupSize));
}
if (auto *searchDir = dyn_cast<script::SearchDir>(c))
ctx.addSearchPath(searchDir->getSearchPath());
if (!ctx.nostdlib())
ctx.addSearchPath(searchDir->getSearchPath());
if (auto *entry = dyn_cast<script::Entry>(c))
ctx.setEntrySymbolName(entry->getEntryName());
if (auto *output = dyn_cast<script::Output>(c))
@@ -386,6 +387,8 @@ bool GnuLdDriver::parse(int argc, const char *argv[],
bool _outputOptionSet = false;
bool hasNoStdLib = false;
// Ignore unknown arguments.
for (auto unknownArg : parsedArgs->filtered(OPT_UNKNOWN))
diag << "warning: ignoring unknown argument: "
@@ -400,9 +403,12 @@ bool GnuLdDriver::parse(int argc, const char *argv[],
ctx->addSearchPath(libDir->getValue());
// Add the default search directory specific to the target.
if (!parsedArgs->hasArg(OPT_nostdlib))
if (!(hasNoStdLib = parsedArgs->hasArg(OPT_nostdlib)))
ctx->addDefaultSearchDirs(baseTriple);
// -nostdlib support.
ctx->setNoStdLib(hasNoStdLib);
// Handle --demangle option(For compatibility)
if (parsedArgs->getLastArg(OPT_demangle))
ctx->setDemangleSymbols(true);

View File

@@ -61,8 +61,8 @@ ELFLinkingContext::ELFLinkingContext(
_mergeCommonStrings(false), _useShlibUndefines(true),
_dynamicLinkerArg(false), _noAllowDynamicLibraries(false),
_mergeRODataToTextSegment(true), _demangle(true), _alignSegments(true),
_outputMagic(OutputMagic::DEFAULT), _initFunction("_init"),
_finiFunction("_fini"), _sysrootPath("") {}
_nostdlib(false), _outputMagic(OutputMagic::DEFAULT),
_initFunction("_init"), _finiFunction("_fini"), _sysrootPath("") {}
void ELFLinkingContext::addPasses(PassManager &pm) {
pm.add(std::unique_ptr<Pass>(new elf::OrderPass()));

View File

@@ -29,9 +29,12 @@ protected:
class LinkerScriptTest : public testing::Test {
protected:
void parse(StringRef script) {
virtual void SetUp() {
llvm::Triple triple(llvm::sys::getDefaultTargetTriple());
_ctx = std::move(GnuLdDriver::createELFLinkingContext(triple));
}
void parse(StringRef script) {
std::unique_ptr<MemoryBuffer> mb = MemoryBuffer::getMemBuffer(
script, "foo.so");
std::string s;
@@ -214,3 +217,11 @@ TEST_F(LinkerScriptTest, Output) {
parse("OUTPUT(\"/path/to/output\")");
EXPECT_EQ("/path/to/output", _ctx->outputPath());
}
// Test that search paths are ignored when nostdlib is set.
TEST_F(LinkerScriptTest, IgnoreSearchDirNoStdLib) {
_ctx->setNoStdLib(true);
parse("SEARCH_DIR(\"/foo/bar\")");
std::vector<StringRef> paths = _ctx->getSearchPaths();
EXPECT_EQ((size_t)0, paths.size());
}