Skip to content
This repository was archived by the owner on Mar 22, 2019. It is now read-only.

Commit a1b6d0d

Browse files
committed
Merge remote-tracking branch 'origin/amd-common' into remove-promote-change-addr-space
2 parents 2163057 + 4c8a374 commit a1b6d0d

File tree

98 files changed

+2692
-1987
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

98 files changed

+2692
-1987
lines changed

COFF/Config.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ struct Configuration {
8989
bool Debug = false;
9090
bool WriteSymtab = true;
9191
unsigned DebugTypes = static_cast<unsigned>(DebugType::None);
92-
StringRef PDBPath;
92+
llvm::SmallString<128> PDBPath;
9393

9494
// Symbols in this set are considered as live by the garbage collector.
9595
std::set<SymbolBody *> GCRoot;

COFF/Driver.cpp

Lines changed: 114 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "llvm/ADT/Optional.h"
2020
#include "llvm/ADT/StringSwitch.h"
2121
#include "llvm/LibDriver/LibDriver.h"
22+
#include "llvm/Object/ArchiveWriter.h"
2223
#include "llvm/Option/Arg.h"
2324
#include "llvm/Option/ArgList.h"
2425
#include "llvm/Option/Option.h"
@@ -136,9 +137,6 @@ void LinkerDriver::enqueuePath(StringRef Path) {
136137
fatal(MBOrErr.second, "could not open " + PathStr);
137138
Driver->addBuffer(std::move(MBOrErr.first));
138139
});
139-
140-
if (Config->OutputFile == "")
141-
Config->OutputFile = getOutputPath(Path);
142140
}
143141

144142
void LinkerDriver::addArchiveBuffer(MemoryBufferRef MB, StringRef SymName,
@@ -417,71 +415,130 @@ static std::string getMapFile(const opt::InputArgList &Args) {
417415
return (OutFile.substr(0, OutFile.rfind('.')) + ".map").str();
418416
}
419417

420-
// Returns true if a given file is a LLVM bitcode file. If it is a
421-
// static library, this function returns true if all files in the
422-
// archive are bitcode files.
423-
static bool isBitcodeFile(StringRef Path) {
424-
using namespace sys::fs;
418+
std::vector<MemoryBufferRef> getArchiveMembers(Archive *File) {
419+
std::vector<MemoryBufferRef> V;
420+
Error Err = Error::success();
421+
for (const ErrorOr<Archive::Child> &COrErr : File->children(Err)) {
422+
Archive::Child C =
423+
check(COrErr,
424+
File->getFileName() + ": could not get the child of the archive");
425+
MemoryBufferRef MBRef =
426+
check(C.getMemoryBufferRef(),
427+
File->getFileName() +
428+
": could not get the buffer for a child of the archive");
429+
V.push_back(MBRef);
430+
}
431+
if (Err)
432+
fatal(File->getFileName() +
433+
": Archive::children failed: " + toString(std::move(Err)));
434+
return V;
435+
}
436+
437+
// A helper function for filterBitcodeFiles.
438+
static bool needsRebuilding(MemoryBufferRef MB) {
439+
// The MSVC linker doesn't support thin archives, so if it's a thin
440+
// archive, we always need to rebuild it.
441+
std::unique_ptr<Archive> File =
442+
check(Archive::create(MB), "Failed to read " + MB.getBufferIdentifier());
443+
if (File->isThin())
444+
return true;
445+
446+
// Returns true if the archive contains at least one bitcode file.
447+
for (MemoryBufferRef Member : getArchiveMembers(File.get()))
448+
if (identify_magic(Member.getBuffer()) == file_magic::bitcode)
449+
return true;
450+
return false;
451+
}
425452

453+
// Opens a given path as an archive file and removes bitcode files
454+
// from them if exists. This function is to appease the MSVC linker as
455+
// their linker doesn't like archive files containing non-native
456+
// object files.
457+
//
458+
// If a given archive doesn't contain bitcode files, the archive path
459+
// is returned as-is. Otherwise, a new temporary file is created and
460+
// its path is returned.
461+
static Optional<std::string>
462+
filterBitcodeFiles(StringRef Path, std::vector<std::string> &TemporaryFiles) {
426463
std::unique_ptr<MemoryBuffer> MB = check(
427464
MemoryBuffer::getFile(Path, -1, false, true), "could not open " + Path);
428-
file_magic Magic = identify_magic(MB->getBuffer());
465+
MemoryBufferRef MBRef = MB->getMemBufferRef();
466+
file_magic Magic = identify_magic(MBRef.getBuffer());
429467

430468
if (Magic == file_magic::bitcode)
431-
return true;
469+
return None;
470+
if (Magic != file_magic::archive)
471+
return Path.str();
472+
if (!needsRebuilding(MBRef))
473+
return Path.str();
432474

433-
if (Magic == file_magic::archive) {
434-
std::unique_ptr<Archive> File =
435-
check(Archive::create(MB->getMemBufferRef()));
436-
437-
Error Err = Error::success();
438-
for (const ErrorOr<Archive::Child> &COrErr : File->children(Err)) {
439-
if (Err)
440-
return false;
441-
Archive::Child C = check(COrErr);
442-
MemoryBufferRef MBRef = check(C.getMemoryBufferRef());
443-
if (identify_magic(MBRef.getBuffer()) != file_magic::bitcode)
444-
return false;
445-
}
446-
if (Err)
447-
return false;
448-
return true;
449-
}
475+
std::unique_ptr<Archive> File =
476+
check(Archive::create(MBRef),
477+
MBRef.getBufferIdentifier() + ": failed to parse archive");
450478

451-
return false;
479+
std::vector<NewArchiveMember> New;
480+
for (MemoryBufferRef Member : getArchiveMembers(File.get()))
481+
if (identify_magic(Member.getBuffer()) != file_magic::bitcode)
482+
New.emplace_back(Member);
483+
484+
if (New.empty())
485+
return None;
486+
487+
log("Creating a temporary archive for " + Path + " to remove bitcode files");
488+
489+
SmallString<128> S;
490+
if (auto EC = sys::fs::createTemporaryFile("lld-" + sys::path::stem(Path),
491+
".lib", S))
492+
fatal(EC, "cannot create a temporary file");
493+
std::string Temp = S.str();
494+
TemporaryFiles.push_back(Temp);
495+
496+
std::pair<StringRef, std::error_code> Ret =
497+
llvm::writeArchive(Temp, New, /*WriteSymtab=*/true, Archive::Kind::K_GNU,
498+
/*Deterministics=*/true,
499+
/*Thin=*/false);
500+
if (Ret.second)
501+
error("failed to create a new archive " + S.str() + ": " + Ret.first);
502+
return Temp;
452503
}
453504

454505
// Create response file contents and invoke the MSVC linker.
455506
void LinkerDriver::invokeMSVC(opt::InputArgList &Args) {
456507
std::string Rsp = "/nologo ";
508+
std::vector<std::string> Temps;
457509

458510
for (auto *Arg : Args) {
459511
switch (Arg->getOption().getID()) {
460512
case OPT_linkrepro:
461513
case OPT_lldmap:
462514
case OPT_lldmap_file:
515+
case OPT_lldsavetemps:
463516
case OPT_msvclto:
464517
// LLD-specific options are stripped.
465518
break;
466519
case OPT_opt:
467520
if (!StringRef(Arg->getValue()).startswith("lld"))
468521
Rsp += toString(Arg) + " ";
469522
break;
470-
case OPT_INPUT:
471-
// Bitcode files are stripped as they've been compiled to
472-
// native object files.
473-
if (Optional<StringRef> Path = doFindFile(Arg->getValue()))
474-
if (isBitcodeFile(*Path))
475-
break;
523+
case OPT_INPUT: {
524+
if (Optional<StringRef> Path = doFindFile(Arg->getValue())) {
525+
if (Optional<std::string> S = filterBitcodeFiles(*Path, Temps))
526+
Rsp += quote(*S) + " ";
527+
continue;
528+
}
476529
Rsp += quote(Arg->getValue()) + " ";
477530
break;
531+
}
478532
default:
479533
Rsp += toString(Arg) + " ";
480534
}
481535
}
482536

483537
std::vector<StringRef> ObjectFiles = Symtab.compileBitcodeFiles();
484538
runMSVCLinker(Rsp, ObjectFiles);
539+
540+
for (StringRef Path : Temps)
541+
sys::fs::remove(Path);
485542
}
486543

487544
void LinkerDriver::enqueueTask(std::function<void()> Task) {
@@ -517,6 +574,13 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
517574
// Parse command line options.
518575
opt::InputArgList Args = Parser.parseLINK(ArgsArr.slice(1));
519576

577+
// Parse and evaluate -mllvm options.
578+
std::vector<const char *> V;
579+
V.push_back("lld-link (LLVM option parsing)");
580+
for (auto *Arg : Args.filtered(OPT_mllvm))
581+
V.push_back(Arg->getValue());
582+
cl::ParseCommandLineOptions(V.size(), V.data());
583+
520584
// Handle /help
521585
if (Args.hasArg(OPT_help)) {
522586
printHelp(ArgsArr[0]);
@@ -827,6 +891,22 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
827891
}
828892
}
829893

894+
// Set default image name if neither /out or /def set it.
895+
if (Config->OutputFile.empty()) {
896+
Config->OutputFile =
897+
getOutputPath((*Args.filtered_begin(OPT_INPUT))->getValue());
898+
}
899+
900+
// Put the PDB next to the image if no /pdb flag was passed.
901+
if (Config->Debug && Config->PDBPath.empty()) {
902+
Config->PDBPath = Config->OutputFile;
903+
sys::path::replace_extension(Config->PDBPath, ".pdb");
904+
}
905+
906+
// Disable PDB generation if the user requested it.
907+
if (Args.hasArg(OPT_nopdb))
908+
Config->PDBPath = "";
909+
830910
// Set default image base if /base is not given.
831911
if (Config->ImageBase == uint64_t(-1))
832912
Config->ImageBase = getDefaultImageBase();

COFF/Error.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg);
2828
LLVM_ATTRIBUTE_NORETURN void fatal(std::error_code EC, const Twine &Prefix);
2929
LLVM_ATTRIBUTE_NORETURN void fatal(llvm::Error &Err, const Twine &Prefix);
3030

31-
template <class T> T check(ErrorOr<T> &&V, const Twine &Prefix) {
31+
template <class T> T check(ErrorOr<T> V, const Twine &Prefix) {
3232
if (auto EC = V.getError())
3333
fatal(EC, Prefix);
3434
return std::move(*V);

COFF/InputFiles.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -339,18 +339,16 @@ void ImportFile::parse() {
339339
}
340340

341341
void BitcodeFile::parse() {
342-
Obj = check(lto::InputFile::create(
343-
MemoryBufferRef(MB.getBuffer(), Saver.save(MB.getBufferIdentifier()))));
342+
Obj = check(lto::InputFile::create(MemoryBufferRef(
343+
MB.getBuffer(), Saver.save(ParentName + MB.getBufferIdentifier()))));
344344
for (const lto::InputFile::Symbol &ObjSym : Obj->symbols()) {
345345
StringRef SymName = Saver.save(ObjSym.getName());
346-
auto Flags = ObjSym.getFlags();
347346
Symbol *Sym;
348-
if (Flags & object::BasicSymbolRef::SF_Undefined) {
347+
if (ObjSym.isUndefined()) {
349348
Sym = Symtab->addUndefined(SymName, this, false);
350-
} else if (Flags & object::BasicSymbolRef::SF_Common) {
349+
} else if (ObjSym.isCommon()) {
351350
Sym = Symtab->addCommon(this, SymName, ObjSym.getCommonSize());
352-
} else if ((Flags & object::BasicSymbolRef::SF_Weak) &&
353-
(Flags & object::BasicSymbolRef::SF_Indirect)) {
351+
} else if (ObjSym.isWeak() && ObjSym.isIndirect()) {
354352
// Weak external.
355353
Sym = Symtab->addUndefined(SymName, this, true);
356354
std::string Fallback = ObjSym.getCOFFWeakExternalFallback();

COFF/LTO.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,7 @@ void BitcodeCompiler::add(BitcodeFile &F) {
105105
// flags an undefined in IR with a definition in ASM as prevailing.
106106
// Once IRObjectFile is fixed to report only one symbol this hack can
107107
// be removed.
108-
R.Prevailing =
109-
!(ObjSym.getFlags() & object::BasicSymbolRef::SF_Undefined) &&
110-
B->getFile() == &F;
108+
R.Prevailing = !ObjSym.isUndefined() && B->getFile() == &F;
111109
R.VisibleToRegularObj = Sym->IsUsedInRegularObj;
112110
if (R.Prevailing)
113111
undefine(Sym);

COFF/ModuleDef.cpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -163,17 +163,25 @@ class Parser {
163163
case KwHeapsize:
164164
parseNumbers(&Config->HeapReserve, &Config->HeapCommit);
165165
return;
166-
case KwLibrary:
167-
parseName(&Config->OutputFile, &Config->ImageBase);
168-
if (!StringRef(Config->OutputFile).endswith_lower(".dll"))
169-
Config->OutputFile += ".dll";
170-
return;
171166
case KwStacksize:
172167
parseNumbers(&Config->StackReserve, &Config->StackCommit);
173168
return;
174-
case KwName:
175-
parseName(&Config->OutputFile, &Config->ImageBase);
169+
case KwLibrary:
170+
case KwName: {
171+
bool IsDll = Tok.K == KwLibrary; // Check before parseName.
172+
std::string Name;
173+
parseName(&Name, &Config->ImageBase);
174+
175+
// Append the appropriate file extension if not already present.
176+
StringRef Ext = IsDll ? ".dll" : ".exe";
177+
if (!StringRef(Name).endswith_lower(Ext))
178+
Name += Ext;
179+
180+
// Set the output file, but don't override /out if it was already passed.
181+
if (Config->OutputFile.empty())
182+
Config->OutputFile = Name;
176183
return;
184+
}
177185
case KwVersion:
178186
parseVersion(&Config->MajorImageVersion, &Config->MinorImageVersion);
179187
return;

COFF/Options.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ def help : F<"help">;
9393
def help_q : Flag<["/?", "-?"], "">, Alias<help>;
9494

9595
// LLD extensions
96+
def nopdb : F<"nopdb">, HelpText<"Disable PDB generation for DWARF users">;
9697
def nosymtab : F<"nosymtab">;
9798
def msvclto : F<"msvclto">;
9899

0 commit comments

Comments
 (0)