[LLD] [COFF] Fix automatic export of symbols from LTO objects
Differential Revision: https://reviews.llvm.org/D101569
This commit is contained in:
parent
27c3db32c0
commit
33b71ec9c6
|
|
@ -32,12 +32,15 @@ namespace coff {
|
|||
SectionChunk::SectionChunk(ObjFile *f, const coff_section *h)
|
||||
: Chunk(SectionKind), file(f), header(h), repl(this) {
|
||||
// Initialize relocs.
|
||||
setRelocs(file->getCOFFObj()->getRelocations(header));
|
||||
if (file)
|
||||
setRelocs(file->getCOFFObj()->getRelocations(header));
|
||||
|
||||
// Initialize sectionName.
|
||||
StringRef sectionName;
|
||||
if (Expected<StringRef> e = file->getCOFFObj()->getSectionName(header))
|
||||
sectionName = *e;
|
||||
if (file) {
|
||||
if (Expected<StringRef> e = file->getCOFFObj()->getSectionName(header))
|
||||
sectionName = *e;
|
||||
}
|
||||
sectionNameData = sectionName.data();
|
||||
sectionNameSize = sectionName.size();
|
||||
|
||||
|
|
@ -49,7 +52,10 @@ SectionChunk::SectionChunk(ObjFile *f, const coff_section *h)
|
|||
// enabled, treat non-comdat sections as roots. Generally optimized object
|
||||
// files will be built with -ffunction-sections or /Gy, so most things worth
|
||||
// stripping will be in a comdat.
|
||||
live = !config->doGC || !isCOMDAT();
|
||||
if (config)
|
||||
live = !config->doGC || !isCOMDAT();
|
||||
else
|
||||
live = true;
|
||||
}
|
||||
|
||||
// SectionChunk is one of the most frequently allocated classes, so it is
|
||||
|
|
|
|||
|
|
@ -1220,6 +1220,7 @@ void LinkerDriver::maybeExportMinGWSymbols(const opt::InputArgList &args) {
|
|||
if (Chunk *c = def->getChunk())
|
||||
if (!(c->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE))
|
||||
e.data = true;
|
||||
s->isUsedInRegularObj = true;
|
||||
config->exports.push_back(e);
|
||||
});
|
||||
}
|
||||
|
|
@ -2117,6 +2118,13 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
|
|||
if (errorCount())
|
||||
return;
|
||||
|
||||
config->hadExplicitExports = !config->exports.empty();
|
||||
if (config->mingw) {
|
||||
// In MinGW, all symbols are automatically exported if no symbols
|
||||
// are chosen to be exported.
|
||||
maybeExportMinGWSymbols(args);
|
||||
}
|
||||
|
||||
// Do LTO by compiling bitcode input files to a set of native COFF files then
|
||||
// link those files (unless -thinlto-index-only was given, in which case we
|
||||
// resolve symbols and write indices, but don't generate native code or link).
|
||||
|
|
@ -2141,12 +2149,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
|
|||
if (errorCount())
|
||||
return;
|
||||
|
||||
config->hadExplicitExports = !config->exports.empty();
|
||||
if (config->mingw) {
|
||||
// In MinGW, all symbols are automatically exported if no symbols
|
||||
// are chosen to be exported.
|
||||
maybeExportMinGWSymbols(args);
|
||||
|
||||
// Make sure the crtend.o object is the last object file. This object
|
||||
// file can contain terminating section chunks that need to be placed
|
||||
// last. GNU ld processes files and static libraries explicitly in the
|
||||
|
|
|
|||
|
|
@ -1042,6 +1042,21 @@ BitcodeFile::BitcodeFile(MemoryBufferRef mb, StringRef archiveName,
|
|||
|
||||
BitcodeFile::~BitcodeFile() = default;
|
||||
|
||||
namespace {
|
||||
// Convenience class for initializing a coff_section with specific flags.
|
||||
class FakeSection {
|
||||
public:
|
||||
FakeSection(int c) { section.Characteristics = c; }
|
||||
|
||||
coff_section section;
|
||||
};
|
||||
|
||||
FakeSection ltoTextSection(IMAGE_SCN_MEM_EXECUTE);
|
||||
FakeSection ltoDataSection(IMAGE_SCN_CNT_INITIALIZED_DATA);
|
||||
SectionChunk ltoTextSectionChunk(nullptr, <oTextSection.section);
|
||||
SectionChunk ltoDataSectionChunk(nullptr, <oDataSection.section);
|
||||
} // namespace
|
||||
|
||||
void BitcodeFile::parse() {
|
||||
std::vector<std::pair<Symbol *, bool>> comdat(obj->getComdatTable().size());
|
||||
for (size_t i = 0; i != obj->getComdatTable().size(); ++i)
|
||||
|
|
@ -1052,6 +1067,11 @@ void BitcodeFile::parse() {
|
|||
StringRef symName = saver.save(objSym.getName());
|
||||
int comdatIndex = objSym.getComdatIndex();
|
||||
Symbol *sym;
|
||||
SectionChunk *fakeSC = nullptr;
|
||||
if (objSym.isExecutable())
|
||||
fakeSC = <oTextSectionChunk;
|
||||
else
|
||||
fakeSC = <oDataSectionChunk;
|
||||
if (objSym.isUndefined()) {
|
||||
sym = symtab->addUndefined(symName, this, false);
|
||||
} else if (objSym.isCommon()) {
|
||||
|
|
@ -1066,11 +1086,11 @@ void BitcodeFile::parse() {
|
|||
if (symName == obj->getComdatTable()[comdatIndex])
|
||||
sym = comdat[comdatIndex].first;
|
||||
else if (comdat[comdatIndex].second)
|
||||
sym = symtab->addRegular(this, symName);
|
||||
sym = symtab->addRegular(this, symName, nullptr, fakeSC);
|
||||
else
|
||||
sym = symtab->addUndefined(symName, this, false);
|
||||
} else {
|
||||
sym = symtab->addRegular(this, symName);
|
||||
sym = symtab->addRegular(this, symName, nullptr, fakeSC);
|
||||
}
|
||||
symbols.push_back(sym);
|
||||
if (objSym.isUsed())
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
; REQUIRES: x86
|
||||
|
||||
; RUN: llvm-as %s -o %t.bc
|
||||
|
||||
; RUN: lld-link -lldmingw -dll -out:%t.dll %t.bc -noentry -output-def:%t.def
|
||||
; RUN: llvm-readobj --coff-exports %t.dll | grep Name: | FileCheck %s
|
||||
; RUN: cat %t.def | FileCheck --check-prefix=IMPLIB %s
|
||||
|
||||
; CHECK: Name: MyExtData
|
||||
; CHECK: Name: MyLibFunc
|
||||
|
||||
; IMPLIB: MyExtData @1 DATA
|
||||
; IMPLIB: MyLibFunc @2{{$}}
|
||||
|
||||
target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-w64-windows-gnu"
|
||||
|
||||
@MyExtData = dso_local global i32 42, align 4
|
||||
|
||||
define dso_local void @MyLibFunc() {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
Loading…
Reference in New Issue