[PECOFF] Add files appear in .drectve to input graph

-- so that command line options to specify new input files, such as
/defaultlib:foo, is handled properly. Such options were ignored before
this patch.

llvm-svn: 192342
This commit is contained in:
Rui Ueyama 2013-10-10 05:39:43 +00:00
parent 5fb5bd3373
commit 9f3a77a9f4
3 changed files with 78 additions and 41 deletions

View File

@ -208,7 +208,7 @@ StringRef getDefaultEntrySymbolName(PECOFFLinkingContext &context) {
// there's an error in the options.
std::unique_ptr<llvm::opt::InputArgList>
parseArgs(int argc, const char *argv[], raw_ostream &diagnostics,
bool isDirective) {
bool isReadingDirectiveSection) {
// Parse command line options using WinLinkOptions.td
std::unique_ptr<llvm::opt::InputArgList> parsedArgs;
WinLinkOptTable table;
@ -229,7 +229,7 @@ parseArgs(int argc, const char *argv[], raw_ostream &diagnostics,
for (auto it = parsedArgs->filtered_begin(OPT_UNKNOWN),
ie = parsedArgs->filtered_end(); it != ie; ++it) {
StringRef arg = (*it)->getAsString(*parsedArgs);
if (isDirective && arg.startswith("-?"))
if (isReadingDirectiveSection && arg.startswith("-?"))
continue;
diagnostics << "warning: ignoring unknown argument: " << arg << "\n";
}
@ -262,19 +262,18 @@ bool WinLinkDriver::linkPECOFF(int argc, const char *argv[],
return link(context, diagnostics);
}
bool WinLinkDriver::parse(int argc, const char *argv[], PECOFFLinkingContext &ctx,
raw_ostream &diagnostics, bool isDirective) {
bool
WinLinkDriver::parse(int argc, const char *argv[], PECOFFLinkingContext &ctx,
raw_ostream &diagnostics, bool isReadingDirectiveSection) {
std::map<StringRef, StringRef> failIfMismatchMap;
// Parse the options.
std::unique_ptr<llvm::opt::InputArgList> parsedArgs = parseArgs(
argc, argv, diagnostics, isDirective);
argc, argv, diagnostics, isReadingDirectiveSection);
if (!parsedArgs)
return false;
if (!ctx.hasInputGraph())
ctx.setInputGraph(std::unique_ptr<InputGraph>(new InputGraph()));
InputGraph &inputGraph = ctx.inputGraph();
// The list of input files.
std::vector<std::unique_ptr<InputElement> > inputElements;
// Handle /help
if (parsedArgs->getLastArg(OPT_help)) {
@ -461,8 +460,7 @@ bool WinLinkDriver::parse(int argc, const char *argv[], PECOFFLinkingContext &ct
break;
case OPT_INPUT:
// Add an input file.
inputGraph.addInputElement(std::unique_ptr<InputElement>(
inputElements.push_back(std::unique_ptr<InputElement>(
new PECOFFFileNode(ctx, inputArg->getValue())));
break;
@ -513,7 +511,7 @@ bool WinLinkDriver::parse(int argc, const char *argv[], PECOFFLinkingContext &ct
// but useful for us to test lld on Unix.
if (llvm::opt::Arg *dashdash = parsedArgs->getLastArg(OPT_DASH_DASH)) {
for (const StringRef value : dashdash->getValues())
inputGraph.addInputElement(
inputElements.push_back(
std::unique_ptr<InputElement>(new PECOFFFileNode(ctx, value)));
}
@ -523,10 +521,10 @@ bool WinLinkDriver::parse(int argc, const char *argv[], PECOFFLinkingContext &ct
for (const StringRef defaultLibPath : defaultLibs)
if (ctx.getNoDefaultLibs().find(defaultLibPath) ==
ctx.getNoDefaultLibs().end())
inputGraph.addInputElement(std::unique_ptr<InputElement>(
inputElements.push_back(std::unique_ptr<InputElement>(
new PECOFFLibraryNode(ctx, defaultLibPath)));
if (!inputGraph.size()) {
if (inputElements.size() == 0 && !isReadingDirectiveSection) {
diagnostics << "No input files\n";
return false;
}
@ -536,11 +534,25 @@ bool WinLinkDriver::parse(int argc, const char *argv[], PECOFFLinkingContext &ct
// with ".exe".
if (ctx.outputPath().empty()) {
SmallString<128> firstInputFilePath =
*dyn_cast<FileNode>(&inputGraph[0])->getPath(ctx);
*dyn_cast<FileNode>(&*inputElements[0])->getPath(ctx);
llvm::sys::path::replace_extension(firstInputFilePath, ".exe");
ctx.setOutputPath(ctx.allocateString(firstInputFilePath.str()));
}
// If the core linker already started, we need to explicitly call parse() for
// each input element, because the pass to parse input files in Driver::link
// has already done.
if (isReadingDirectiveSection)
for (auto &e : inputElements)
if (error_code ec = e->parse(ctx, diagnostics))
return ec;
// Add the input files to the input graph.
if (!ctx.hasInputGraph())
ctx.setInputGraph(std::unique_ptr<InputGraph>(new InputGraph()));
for (auto &e : inputElements)
ctx.inputGraph().addInputElement(std::move(e));
// Validate the combination of options used.
return ctx.validate(diagnostics);
}

View File

@ -5,16 +5,22 @@ header:
sections:
- Name: .text
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
Alignment: 4
SectionData: B82A000000C3
- Name: .data
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
Alignment: 4
SectionData: ""
Alignment: 16
SectionData: 558BEC56FF15000000008B0D000000008B3103F0FF150000000003C65E5DC3
Relocations:
- VirtualAddress: 6
SymbolName: __imp__fn
Type: IMAGE_REL_I386_DIR32
- VirtualAddress: 12
SymbolName: __imp__var
Type: IMAGE_REL_I386_DIR32
- VirtualAddress: 22
SymbolName: __imp___name_with_underscore
Type: IMAGE_REL_I386_DIR32
- Name: .drectve
Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
Alignment: 2147483648
SectionData: 2f73756273797374656d3a636f6e736f6c652c34322e313935202d3f666f6f00
SectionData: 2f64656661756c746c69623a766172732e6c6962202f73756273797374656d3a636f6e736f6c652c34322e313935202d3f666f6f00
symbols:
- Name: .text
Value: 0
@ -23,27 +29,37 @@ symbols:
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
NumberOfAuxSymbols: 1
AuxiliaryData: 060000000000000000000000000000000000
- Name: .data
AuxiliaryData: 1F000000030000008C7450D6000000000000
- Name: __imp__fn
Value: 0
SectionNumber: 0
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
- Name: __imp___name_with_underscore
Value: 0
SectionNumber: 0
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
- Name: _main
Value: 0
SectionNumber: 1
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
- Name: __imp__var
Value: 0
SectionNumber: 0
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
- Name: .drectve
Value: 0
SectionNumber: 2
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
NumberOfAuxSymbols: 1
AuxiliaryData: 000000000000000000000000000000000000
- Name: _start
Value: 0
SectionNumber: 1
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
- Name: .drectve
Value: 0
SectionNumber: 3
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
NumberOfAuxSymbols: 1
AuxiliaryData: 0D0000000000000000000000000000000000
...

View File

@ -1,15 +1,24 @@
# Test if the linker can properly parse the .drectve section contents.
# "drectve.obj" contains "/subsystem:console,42.195 -?foo" in its .drectve
# section.
# "drectve.obj" contains "/defaultlib:vars /subsystem:console,42.195 -?foo"
# in its .drectve section.
# RUN: yaml2obj %p/Inputs/drectve.obj.yaml > %t.obj
#
# RUN: lld -flavor link /out:%t.exe /entry:start -- %t.obj >& %t.log
# RUN: lld -flavor link /out:%t.exe /entry:main /opt:noref /libpath:%p/Inputs \
# RUN: -- %t.obj >& %t.log
#
# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=HEADER %s
# RUN: llvm-objdump -p %t.exe | FileCheck -check-prefix=IMPORT %s
# RUN: echo >> %t.log
# RUN: FileCheck -check-prefix=ERROR %s < %t.log
HEADER: MajorOperatingSystemVersion: 42
HEADER: MinorOperatingSystemVersion: 195
IMPORT: DLL Name: vars.dll
IMPORT-NEXT: Hint/Ord Name
IMPORT-NEXT: 0 _name_with_underscore
IMPORT-NEXT: 1 fn
IMPORT-NEXT: 1
ERROR-NOT: foo