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

View File

@ -5,16 +5,22 @@ header:
sections: sections:
- Name: .text - Name: .text
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
Alignment: 4 Alignment: 16
SectionData: B82A000000C3 SectionData: 558BEC56FF15000000008B0D000000008B3103F0FF150000000003C65E5DC3
- Name: .data Relocations:
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] - VirtualAddress: 6
Alignment: 4 SymbolName: __imp__fn
SectionData: "" 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 - Name: .drectve
Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
Alignment: 2147483648 Alignment: 2147483648
SectionData: 2f73756273797374656d3a636f6e736f6c652c34322e313935202d3f666f6f00 SectionData: 2f64656661756c746c69623a766172732e6c6962202f73756273797374656d3a636f6e736f6c652c34322e313935202d3f666f6f00
symbols: symbols:
- Name: .text - Name: .text
Value: 0 Value: 0
@ -23,27 +29,37 @@ symbols:
ComplexType: IMAGE_SYM_DTYPE_NULL ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC StorageClass: IMAGE_SYM_CLASS_STATIC
NumberOfAuxSymbols: 1 NumberOfAuxSymbols: 1
AuxiliaryData: 060000000000000000000000000000000000 AuxiliaryData: 1F000000030000008C7450D6000000000000
- Name: .data - 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 Value: 0
SectionNumber: 2 SectionNumber: 2
SimpleType: IMAGE_SYM_TYPE_NULL SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC StorageClass: IMAGE_SYM_CLASS_STATIC
NumberOfAuxSymbols: 1 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 AuxiliaryData: 0D0000000000000000000000000000000000
... ...

View File

@ -1,15 +1,24 @@
# Test if the linker can properly parse the .drectve section contents. # Test if the linker can properly parse the .drectve section contents.
# "drectve.obj" contains "/subsystem:console,42.195 -?foo" in its .drectve # "drectve.obj" contains "/defaultlib:vars /subsystem:console,42.195 -?foo"
# section. # in its .drectve section.
# RUN: yaml2obj %p/Inputs/drectve.obj.yaml > %t.obj # 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-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: echo >> %t.log
# RUN: FileCheck -check-prefix=ERROR %s < %t.log # RUN: FileCheck -check-prefix=ERROR %s < %t.log
HEADER: MajorOperatingSystemVersion: 42 HEADER: MajorOperatingSystemVersion: 42
HEADER: MinorOperatingSystemVersion: 195 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 ERROR-NOT: foo