Skip to content

Commit

Permalink
[LLD] [COFF] Add support for a new, mingw specific embedded directive…
Browse files Browse the repository at this point in the history
… -exclude-symbols:

This is an entirely new embedded directive - extending the GNU ld
command line option --exclude-symbols to be usable in embedded
directives too.

(GNU ld.bfd also got support for the same new directive, currently in
the latest git version, after the 2.39 branch.)

This works as an inverse to the regular embedded dllexport directives,
for cases when autoexport of all eligible symbols is performed.

Differential Revision: https://reviews.llvm.org/D130120
  • Loading branch information
mstorsjo committed Aug 11, 2022
1 parent d1da646 commit 5d513ef
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 4 deletions.
10 changes: 9 additions & 1 deletion lld/COFF/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,14 @@ void LinkerDriver::parseDirectives(InputFile *file) {
for (StringRef inc : directives.includes)
addUndefined(inc);

// Handle /exclude-symbols: in bulk.
for (StringRef e : directives.excludes) {
SmallVector<StringRef, 2> vec;
e.split(vec, ',');
for (StringRef sym : vec)
excludedSymbols.insert(mangle(sym));
}

// https://docs.microsoft.com/en-us/cpp/preprocessor/comment-c-cpp?view=msvc-160
for (auto *arg : directives.args) {
switch (arg->getOption().getID()) {
Expand Down Expand Up @@ -1309,7 +1317,7 @@ void LinkerDriver::maybeExportMinGWSymbols(const opt::InputArgList &args) {
return;
}

AutoExporter exporter;
AutoExporter exporter(excludedSymbols);

for (auto *arg : args.filtered(OPT_wholearchive_file))
if (Optional<StringRef> path = doFindFile(arg->getValue()))
Expand Down
2 changes: 2 additions & 0 deletions lld/COFF/Driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ extern COFFOptTable optTable;
struct ParsedDirectives {
std::vector<StringRef> exports;
std::vector<StringRef> includes;
std::vector<StringRef> excludes;
llvm::opt::InputArgList args;
};

Expand Down Expand Up @@ -159,6 +160,7 @@ class LinkerDriver {
std::vector<MemoryBufferRef> resources;

llvm::DenseSet<StringRef> directivesExports;
llvm::DenseSet<StringRef> excludedSymbols;

COFFLinkerContext &ctx;

Expand Down
3 changes: 3 additions & 0 deletions lld/COFF/DriverUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -899,6 +899,9 @@ ParsedDirectives ArgParser::parseDirectives(StringRef s) {
else if (tok.startswith_insensitive("/include:") ||
tok.startswith_insensitive("-include:"))
result.includes.push_back(tok.substr(strlen("/include:")));
else if (tok.startswith_insensitive("/exclude-symbols:") ||
tok.startswith_insensitive("-exclude-symbols:"))
result.excludes.push_back(tok.substr(strlen("/exclude-symbols:")));
else {
// Copy substrings that are not valid C strings. The tokenizer may have
// already copied quoted arguments for us, so those do not need to be
Expand Down
6 changes: 4 additions & 2 deletions lld/COFF/MinGW.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ using namespace llvm::COFF;
using namespace lld;
using namespace lld::coff;

AutoExporter::AutoExporter() {
AutoExporter::AutoExporter(
const llvm::DenseSet<StringRef> &manualExcludeSymbols)
: manualExcludeSymbols(manualExcludeSymbols) {
excludeLibs = {
"libgcc",
"libgcc_s",
Expand Down Expand Up @@ -135,7 +137,7 @@ bool AutoExporter::shouldExport(const COFFLinkerContext &ctx,
// disallow import symbols.
if (!isa<DefinedRegular>(sym) && !isa<DefinedCommon>(sym))
return false;
if (excludeSymbols.count(sym->getName()))
if (excludeSymbols.count(sym->getName()) || manualExcludeSymbols.count(sym->getName()))
return false;

for (StringRef prefix : excludeSymbolPrefixes.keys())
Expand Down
5 changes: 4 additions & 1 deletion lld/COFF/MinGW.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "Symbols.h"
#include "lld/Common/LLVM.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Option/ArgList.h"
#include <vector>
Expand All @@ -24,7 +25,7 @@ class COFFLinkerContext;
// symbols for MinGW.
class AutoExporter {
public:
AutoExporter();
AutoExporter(const llvm::DenseSet<StringRef> &manualExcludeSymbols);

void addWholeArchive(StringRef path);
void addExcludedSymbol(StringRef symbol);
Expand All @@ -35,6 +36,8 @@ class AutoExporter {
llvm::StringSet<> excludeLibs;
llvm::StringSet<> excludeObjects;

const llvm::DenseSet<StringRef> &manualExcludeSymbols;

bool shouldExport(const COFFLinkerContext &ctx, Defined *sym) const;
};

Expand Down
3 changes: 3 additions & 0 deletions lld/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ MinGW Improvements
* The ``--exclude-symbols`` option is now supported.
(`D130118 <https://reviews.llvm.org/D130118>`_)

* Support for an entirely new object file directive, ``-exclude-symbols:``,
has been implemented. (`D130120 <https://reviews.llvm.org/D130120>`_)

MachO Improvements
------------------

Expand Down
24 changes: 24 additions & 0 deletions lld/test/COFF/exclude-symbols-embedded.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// REQUIRES: x86
// RUN: llvm-mc -filetype=obj -triple=i686-win32-gnu %s -o %t.o

// RUN: lld-link -lldmingw -dll -out:%t.dll %t.o -noentry
// RUN: llvm-readobj --coff-exports %t.dll | FileCheck --implicit-check-not=Name: %s

// CHECK: Name:
// CHECK: Name: sym1

.global _sym1
_sym1:
ret

.global _sym2
_sym2:
ret

.global _sym3
_sym3:
ret

.section .drectve,"yn"
.ascii " -exclude-symbols:sym2,unknownsym"
.ascii " -exclude-symbols:unkonwnsym,sym3"

0 comments on commit 5d513ef

Please sign in to comment.