The MinGW driver has separate options for OS and subsystem version.
Having this available in lld-link allows the MinGW driver to both match
GNU ld better and simplifies the code for merging two (potentially
mismatching) arguments into one.
Differential Revision: https://reviews.llvm.org/D88802
Parse the components as decimal, instead of decuding the base from
the string. This avoids ambiguity if the second number contains leading
zeros, which previously were parsed as indicating an octal number.
MS link.exe doesn't support hexadecimal numbers in the version numbers,
neither in /version nor in /subsystem.
Differential Revision: https://reviews.llvm.org/D88801
Otherwise an ArgumentParser is constructed for every directive section,
and that involves copying the entire table of options into a vector.
There is no need for this, just have one option table.
This generalizes the main Windows command line tokenizer to be able to
produce StringRef substrings as well as freshly copied C strings. The
implementation is still shared with the normal tokenizer, which is
important, because we have unit tests for that.
.drective sections can be very long. They can potentially list up to
every symbol in the object file by name. It is worth avoiding these
string copies.
This saves a lot of memory when linking chrome.dll with PGO
instrumentation:
BEFORE AFTER % IMP
peak memory: 6657.76MB 4983.54MB -25%
real: 4m30.875s 2m26.250s -46%
The time improvement may not be real, my machine was noisy while running
this, but that the peak memory usage improvement should be real.
This change may also help apps that heavily use dllexport annotations,
because those also use linker directives in object files. Apps that do
not use many directives are unlikely to be affected.
Reviewed By: thakis
Differential Revision: https://reviews.llvm.org/D79262
This speeds up linking chrome.dll with PGO instrumentation by 13%
(154271ms -> 134033ms).
LLVM's Option library is very slow. In particular, it allocates at least
one large-ish heap object (Arg) for every argument. When PGO
instrumentation is enabled, all the __profd_* symbols are added to the
@llvm.used list, which compiles down to these /INCLUDE: directives. This
means we have O(#symbols) directives to parse in the section, so we end
up allocating an Arg for every function symbol in the object file. This
is unnecessary.
To address the issue and speed up the link, extend the fast path that we
already have for /EXPORT:, which has similar scaling issues.
I promise that I took a hard look at optimizing the Option library, but
its data structures are very general and would need a lot of cleanup. We
have accumulated lots of optional features (option groups, aliases,
multiple values) over the years, and these are now properties of every
parsed argument, when the vast majority of arguments do not use these
features.
Reviewed By: thakis
Differential Revision: https://reviews.llvm.org/D78845
This is how it should've been and brings it more in line with
std::string_view. There should be no functional change here.
This is mostly mechanical from a custom clang-tidy check, with a lot of
manual fixups. It uncovers a lot of minor inefficiencies.
This doesn't actually modify StringRef yet, I'll do that in a follow-up.
Remove the lld::enableColors function, as it just obscures which
stream it's affecting, and replace with explicit calls to the stream's
enable_colors.
Also, assign the stderrOS and stdoutOS globals first in link function,
just to ensure nothing might use them.
(Either change individually fixes the issue of using the old
stream, but both together seems best.)
Follow-up to b11386f9be.
Differential Revision: https://reviews.llvm.org/D70492
This change is for those who use lld as a library. Context:
https://reviews.llvm.org/D70287
This patch adds a new parmeter to lld::*::link() so that we can pass
an raw_ostream object representing stdout. Previously, lld::*::link()
took only an stderr object.
Justification for making stdoutOS and stderrOS mandatory: I wanted to
make link() functions to take stdout and stderr in that order.
However, if we change the function signature from
bool link(ArrayRef<const char *> args, bool canExitEarly,
raw_ostream &stderrOS = llvm::errs());
to
bool link(ArrayRef<const char *> args, bool canExitEarly,
raw_ostream &stdoutOS = llvm::outs(),
raw_ostream &stderrOS = llvm::errs());
, then the meaning of existing code that passes stderrOS silently
changes (stderrOS would be interpreted as stdoutOS). So, I chose to
make existing code not to compile, so that developers can fix their
code.
Differential Revision: https://reviews.llvm.org/D70292
This is useful for enforcing that builds are independent of the
environment; it can be used when all system library paths are added
via /libpath: already. It's similar ot cl.exe's /X flag.
Since it should also affect %LINK% (the other caller of
`Process::GetEnv` in lld/COFF), the early-option-parsing needs
to move around a bit. The options are:
- Add a manual loop over the argv ArrayRef and look for "/lldignoreenv".
This repeats the name of the flag in both Options.td and in
DriverUtils.cpp.
- Add yet another table.ParseArgs() call just for /lldignoreenv before
adding %LINK%.
- Use the existing early ParseArgs() that's there for --rsp-quoting and use
it for /lldignoreenv for %LINK% as well. This means --rsp-quoting
and /lldignoreenv can't be passed via %LINK%.
I went with the third approach.
Differential Revision: https://reviews.llvm.org/D67456
llvm-svn: 371852
In mingw environments, resources are normally compiled to resource
object files directly, instead of letting the linker convert them to
COFF format.
Since some time, GCC supports the notion of a default manifest object.
When invoking the linker, GCC looks for the default manifest object
file, and if found in the expected path, it is added to linker commands.
The default manifest is one that indicates support for the latest known
versions of windows, to implicitly unlock the modern behaviours of certain
APIs.
Not all mingw/gcc distributions include this file, but e.g. in msys2,
the default manifest object is distributed in a separate package (which
can be but might not always be installed).
This means that even if user projects only use one single resource
object file, the linker can end up with two resource object files,
and thus needs to support merging them.
The default manifest has a language id of zero, and GNU ld has got
logic for dropping a manifest with a zero language id, if there's
another manifest present with a nonzero language id. If there are
multiple manifests with a nonzero language id, the merging process
errors out.
Differential Revision: https://reviews.llvm.org/D66825
llvm-svn: 370974
Extend WindowsResourceParser to support using a ResourceSectionRef for
loading resources from an object file.
Only allow merging resource object files in mingw mode; keep the
existing error on multiple resource objects in link mode.
If there only is one resource object file and no .res resources,
don't parse and recreate the .rsrc section, but just link it in without
inspecting it. This allows users to produce any .rsrc section (outside
of what the parser supports), just like before. (I don't have a specific
need for this, but it reduces the risk of this new feature.)
Separate out the .rsrc section chunks in InputFiles.cpp, and only include
them in the list of section chunks to link if we've determined that there
only was one single resource object. (We need to keep other chunks from
those object files, as they can legitimately contain other sections as
well, in addition to .rsrc section chunks.)
Differential Revision: https://reviews.llvm.org/D66824
llvm-svn: 370436
1. raw_ostream supports ANSI colors so that you can write messages to
the termina with colors. Previously, in order to change and reset
color, you had to call `changeColor` and `resetColor` functions,
respectively.
So, if you print out "error: " in red, for example, you had to do
something like this:
OS.changeColor(raw_ostream::RED);
OS << "error: ";
OS.resetColor();
With this patch, you can write the same code as follows:
OS << raw_ostream::RED << "error: " << raw_ostream::RESET;
2. Add a boolean flag to raw_ostream so that you can disable colored
output. If you disable colors, changeColor, operator<<(Color),
resetColor and other color-related functions have no effect.
Most LLVM tools automatically prints out messages using colors, and
you can disable it by passing a flag such as `--disable-colors`.
This new flag makes it easy to write code that works that way.
Differential Revision: https://reviews.llvm.org/D65564
llvm-svn: 367649
This patch does the same thing as r365595 to other subdirectories,
which completes the naming style change for the entire lld directory.
With this, the naming style conversion is complete for lld.
Differential Revision: https://reviews.llvm.org/D64473
llvm-svn: 365730
Since OPT_UNKNOWN args never have any values and consist only of
spelling (and are never aliased), this doesn't make any difference in
practice, but it's more consistent with Arg's guidance to use
getAsString() for diagnostics, and it matches what clang does.
Also tweak two tests to use an unknown option that contains '=' for
additional coverage while here. (The new tests pass fine with the old
code too though.)
llvm-svn: 365200
Users are exepcted to pass all .res files to the linker, which then
merges all the resource in all .res files into a tree structure and then
converts the final tree structure to a .obj file with .rsrc$01 and
.rsrc$02 sections and then links that.
If the user instead passes several .obj files containing such resources,
the correct thing to do would be to have custom code to merge the trees
in the resource sections instead of doing normal section merging -- but
link.exe rejects if multiple resource obj files are passed in with
LNK4078, so let lld-link do that too instead of silently writing broken
.rsrc sections in that case.
The only real way to run into this is if users manually convert .res
files to .obj files by running cvtres and then handing the resulting
.obj files to lld-link instead, which in practice likely never happens.
(lld-link is slightly stricter than link.exe now: If link.exe is passed
one .obj file created by cvtres, and a .res file, for some reason it
just emits a warning instead of an error and outputs strange looking
data. lld-link now errors out on mixed input like this.)
One way users could accidentally run into this is the following
scenario: If a .res file is passed to lib.exe, then lib.exe calls
cvtres.exe on the .res file before putting it in the output .lib.
(llvm-lib currently doesn't do this.)
link.exe's /wholearchive seems to only add obj files referenced from the
static library index, but lld-link current really adds all files in the
archive. So if lld-link /wholearchive is used with .lib files produced
by lib.exe and .res files were among the files handed to lib.exe, we
previously silently produced invalid output, but now we error out.
link.exe's /wholearchive semantics on the other hand mean that it
wouldn't load the resource object files from the .lib file at all.
Since this scenario is probably still an unlikely corner case,
the difference in behavior here seems fine -- and lld-link might have to
change to use link.exe's /wholearchive semantics in the future anyways.
Vaguely related to PR42180.
Differential Revision: https://reviews.llvm.org/D63109
llvm-svn: 363078
For lld, pass in Config->Timestamp (which is set based on lld's
/timestamp: and /Brepro flags). Since the writeWindowsResourceCOFF()
data is only used in-memory by LLD and the obj's timestamp isn't used
for anything in the output, this doesn't change behavior.
For llvm-cvtres, add an optional /timestamp: parameter, and use the
current behavior of calling time() if the parameter is not passed in.
This doesn't really change observable behavior (unless someone passes
/timestamp: to llvm-cvtres, which wasn't possible before), but it
removes the last unqualified call to time() from llvm/lib, which seems
like a good thing.
Differential Revision: https://reviews.llvm.org/D63116
llvm-svn: 363050
And share some code with lld-link.
While here, also add a FIXME about PR42180 and merge r360150 to llvm-lib.
Differential Revision: https://reviews.llvm.org/D63021
llvm-svn: 363016
Summary:
When handling exports from the command line or from .def files, the
linker does a "fuzzy" string lookup to allow finding mangled symbols.
However, when the symbol is re-exported under a new name, the linker has
to transfer the decorations from the exported symbol over to the new
name. This is implemented by taking the mangled symbol that was found in
the object and replacing the original symbol name with the export name.
Before this patch, LLD implemented the fuzzy search by adding an
undefined symbol with the unmangled name, and then during symbol
resolution, checking if similar mangled symbols had been added after the
last round of symbol resolution. If so, LLD makes the original symbol a
weak alias of the mangled symbol. Later, to get the original symbol
name, LLD would look through the weak alias and forward it on to the
import library writer, which copies the symbol decorations. This
approach doesn't work when bar is itself a weak alias, as is the case in
asan. It's especially bad when the aliasee of bar contains the string
"bar", consider "bar_default". In this case, we would end up exporting
the symbol "foo_default" when we should've exported just "foo".
To fix this, don't look through weak aliases to find the mangled name.
Save the mangled name earlier during fuzzy symbol lookup.
Fixes PR42074
Reviewers: mstorsjo, ruiu
Subscribers: thakis, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D62984
llvm-svn: 362849
OptTable treats arguments starting with / that aren't a known option
as filenames. This means lld-link's and clang-cl's typo correction for
unknown flags didn't do spell checking for misspelled options that start
with /.
I first tried changing OptTable, but that got pretty messy, see PR41787
comments 2 and 3.
Instead, let lld-link's and clang's (including clang-cl's) "file not
found" diagnostic check if a non-existent file looks like it could be a
mis-spelled option, and if so add a "did you mean" suggestion to the
"file not found" diagnostic.
While here, make formatting of a few diagnostics a bit more
self-consistent.
Fixes PR41787.
Differential Revision: https://reviews.llvm.org/D62276
llvm-svn: 361518
For lld-link, unknown '/'-style flags are treated as filenames on POSIX
systems, so only '-'-style flags get typo correction for now. This
matches clang-cl.
PR37006.
Differential Revision: https://reviews.llvm.org/D61443
llvm-svn: 360145
As a side benefit, lld-link now reports more than one duplicate resource
entry before exiting with an error even if the new flag is not passed.
llvm-svn: 359829
Reduces the error message from:
lld-link: error: failed to parse .res file: duplicate resource: type STRINGTABLE (ID 6)/name ID 3/language 1033, in test1.res and in test2.res
To:
lld-link: error: duplicate resource: type STRINGTABLE (ID 6)/name ID 3/language 1033, in test1.res and in test2.res
Make sure every error message emitted by cvtres contains the name of at
least one ".res" file, so that removing the "failed to parse .res file"
string doesn't lose information.
Differential Revision: https://reviews.llvm.org/D61388
llvm-svn: 359749
r191276 added this to old LLD, but it never made it to new LLD -- except
that the flag was in Options.td, so it was silently ignored. I figured
it should be easy to implement, so I did that instead of removing the
flags from Options.td.
I then discovered that link.exe also supports comma-separated lists of
'cd' and 'net', which made the parsing code a bit annoying.
The Alias technique in Options.td is to get nice help output.
Differential Revision: https://reviews.llvm.org/D61067
llvm-svn: 359192
When mismatched #pragma detect_mismatch declarations occur, now print the conflicting OBJs.
lld-link: error: /failifmismatch: mismatch detected for 'TEST':
>>> test.obj has value 1
>>> test2.obj has value 2
Fixes PR38579
Differential Revision: https://reviews.llvm.org/D58910
llvm-svn: 355543
to reflect the new license.
We understand that people may be surprised that we're moving the header
entirely to discuss the new license. We checked this carefully with the
Foundation's lawyer and we believe this is the correct approach.
Essentially, all code in the project is now made available by the LLVM
project under our new license, so you will see that the license headers
include that license only. Some of our contributors have contributed
code under our old license, and accordingly, we have retained a copy of
our old license notice in the top-level files in each project and
repository.
llvm-svn: 351636
Summary: Before, OptTable::PrintHelp append "[options] <inputs>" to its parameter `Help`. It is more flexible to change its semantic to `Usage` and let user customize the usage line.
Reviewers: rupprecht, ruiu, espindola
Reviewed By: rupprecht
Subscribers: emaste, sbc100, arichardson, aheejin, llvm-commits
Differential Revision: https://reviews.llvm.org/D53054
llvm-svn: 344099
This was useful for LTO bringup in lld-link while lld couldn't write PDBs. Now
that it can, this should no longer be needed. Hopefully the flag is obscure
enough and recent enough, that nobody uses it – but if somebody should use it,
they should be able to just stop passing it and things should continue to work.
https://reviews.llvm.org/D50139
llvm-svn: 338615
This simplifies some code which had StringRefs to begin with, and
makes other code more complicated which had const char* to begin
with.
In the end, I think this makes for a more idiomatic and platform
agnostic API. Not all platforms launch process with null terminated
c-string arrays for the environment pointer and argv, but the api
was designed that way because it allowed easy pass-through for
posix-based platforms. There's a little additional overhead now
since on posix based platforms we'll be takign StringRefs which
were constructed from null terminated strings and then copying
them to null terminate them again, but from a readability and
usability standpoint of the API user, I think this API signature
is strictly better.
llvm-svn: 334518
This is most useful when using lld-link on a non-Win host (but it might become
useful on Windows too if lld also grows a fansi-escape-codes flag).
Also make the help for --color-diagnostic mention the valid values in ELF and
wasm, and print the flag name with two dashes in diags, since the one-dash form
is seen as a list of many one-letter flags in some contexts.
https://reviews.llvm.org/D46693
llvm-svn: 332012
GNU ld has got a number of different flags for adjusting how to
behave around stdcall functions. The --kill-at flag strips the
trailing sdcall suffix from exported functions (which otherwise
is included by default in MinGW setups).
This also strips it from the corresponding import library though.
That makes it hard to link to such an import library from code
that calls the functions - but this matches what GNU ld does with
this flag. Therefore, this flag is probably not sensibly used
together with import libraries, but probably mostly when creating
some sort of plugin, or if creating the import library separately
with dlltool.
Differential Revision: https://reviews.llvm.org/D44292
llvm-svn: 327561
This makes the output of some flag names in warning messages consistent with
the output of /? and the output of flags in most other diagnostics.
https://reviews.llvm.org/D44307
llvm-svn: 327261
Summary:
This protects calls to longjmp from transferring control to arbitrary
program points. Instead, longjmp calls are limited to the set of
registered setjmp return addresses.
This also implements /guard:nolongjmp to allow users to link in object
files that call setjmp that weren't compiled with /guard:cf. In this
case, the linker will approximate the set of address taken functions,
but it will leave longjmp unprotected.
I used the following program to test, compiling it with different -guard
flags:
$ cl -c t.c -guard:cf
$ lld-link t.obj -guard:cf
#include <setjmp.h>
#include <stdio.h>
jmp_buf buf;
void g() {
printf("before longjmp\n");
fflush(stdout);
longjmp(buf, 1);
}
void f() {
if (setjmp(buf)) {
printf("setjmp returned non-zero\n");
return;
}
g();
}
int main() {
f();
printf("hello world\n");
}
In particular, the program aborts when the code is compiled *without*
-guard:cf and linked with -guard:cf. That indicates that longjmps are
protected.
Reviewers: ruiu, inglorion, amccarth
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D43217
llvm-svn: 325047
Summary:
This patch adds some initial support for Windows control flow guard. At
the end of the day, the linker needs to synthesize a table of RVAs very
similar to the structured exception handler table (/safeseh).
Both /safeseh and /guard:cf take sections of symbol table indices
(.sxdata and .gfids$y) and turn them into RVA tables referenced by the
load config struct in the CRT through special symbols.
Reviewers: ruiu, amccarth
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D42592
llvm-svn: 324306
The compiler could not find the conversion from
unique_ptr<WritableMemoryBuffer> to unique_ptr<MemoryBuffer>. This will
hopefully help it along.
llvm-svn: 322365
Patch by Takuto Ikuta.
This patch reduces lld link time of chromium's blink_core.dll in
component build.
Total size of input argument in .directives become nearly 300MB in the
build and almost all its content are /EXPORT.
To reduce time of parsing too many /EXPORT option in the build, I
introduce fastpath for /EXPORT in ArgParser::parseDirectives.
On my desktop machine, 4 times stats of the link time are like below.
Improved around 20%.
This patch
TotalSeconds : 8.6217627
TotalSeconds : 8.5402175
TotalSeconds : 8.6855853
TotalSeconds : 8.3624441
Ave : 8.5525024
master
TotalSeconds : 10.9975031
TotalSeconds : 11.3409428
TotalSeconds : 10.6332897
TotalSeconds : 10.7650687
Ave : 10.934201075
llvm-svn: 322117