Commit Graph

30 Commits

Author SHA1 Message Date
Rui Ueyama a5f0f758d3 COFF: Move markLive() from Writer.cpp to its own file.
Conceptually, garbage collection is not part of Writer,
so move the function out of the file.

llvm-svn: 248099
2015-09-19 21:36:28 +00:00
Rafael Espindola beee25e484 Make these headers as being c++.
llvm-svn: 245050
2015-08-14 14:12:54 +00:00
Rafael Espindola b835ae8e4a Port the error functions from ELF to COFF.
This has a few advantages

* Less C++ code (about 300 lines less).
* Less machine code (about 14 KB of text on a linux x86_64 build).
* It is more debugger friendly. Just set a breakpoint on the exit function and
  you get the complete lld stack trace of when the error was found.
* It is a more robust API. The errors are handled early and we don't get a
  std::error_code hot potato being passed around.
* In most cases the error function in a better position to print diagnostics
  (it has more context).

llvm-svn: 244215
2015-08-06 14:58:50 +00:00
Rui Ueyama cb8474edae COFF, ELF2: Pass output file path implicitly using Config global variable.
Various parameters are passed implicitly using Config global variable
already. Output file path is no different from others, so there was no
special reason to handle that differnetly.

This patch changes the signature of writeResult(SymbolTable *, StringRef)
to writeResult(SymbolTable *).

llvm-svn: 244180
2015-08-05 23:51:50 +00:00
Rui Ueyama 685c41cd39 COFF: Simplify Writer interface by hiding Writer class.
llvm-svn: 244175
2015-08-05 23:43:53 +00:00
Rui Ueyama 67fcd1a0c7 COFF: Fix bad #includes.
Writer.h is intended to be included only by Writer.cpp and Driver.cpp.
Use of the header in other files are bad.

llvm-svn: 244106
2015-08-05 19:51:28 +00:00
Rui Ueyama a8eed749a2 COFF: Write import library symbols to a symbol table.
Previously no __imp_ symbols nor dllimport thunk functions were
written to a symbol table.

llvm-svn: 243350
2015-07-27 23:40:20 +00:00
Rui Ueyama 3afd5bfd7b COFF: Handle base relocation as a tuple of relocation type and RVA. NFC.
On x64 and x86, we use only one base relocation type, so we handled
base relocations just as a list of RVAs. That doesn't work well for
ARM becuase we have to handle two types of base relocations on ARM.
This patch changes the type of base relocation from uint32_t to
{reltype, uint32_t} to make it easy to port this code to ARM.

llvm-svn: 243197
2015-07-25 01:44:32 +00:00
Rui Ueyama cd3f99b6c5 COFF: Implement Safe SEH support for x86.
An object file compatible with Safe SEH contains a .sxdata section.
The section contains a list of symbol table indices, each of which
is an exception handler function. A safe SEH-enabled executable
contains a list of exception handler RVAs. So, what the linker has
to do to support Safe SEH is basically to read the .sxdata section,
interpret the contents as a list of symbol indices, unique-fy and
sort their RVAs, and then emit that list to .rdata. This patch
implements that feature.

llvm-svn: 243182
2015-07-24 23:51:14 +00:00
Rui Ueyama e59a530a6c COFF: Split createSymbolAndSymbolTable to small functions. NFC.
llvm-svn: 242066
2015-07-13 20:56:31 +00:00
Rui Ueyama 1b53ec796a COFF: Remove Writer::Is64 and use Config::is64 instead. NFC.
llvm-svn: 241819
2015-07-09 16:40:39 +00:00
David Majnemer 2c345a337c COFF: Emit a symbol table if /debug is specified
Providing a symbol table in the executable is quite useful when
debugging a fully-linked executable without having to reconstruct one
from DWARF.

Differential Revision: http://reviews.llvm.org/D11023

llvm-svn: 241689
2015-07-08 16:37:50 +00:00
Rui Ueyama 11863b4ae1 COFF: Support x86 file header and relocations.
llvm-svn: 241657
2015-07-08 01:45:29 +00:00
Rui Ueyama 88e0f9206b COFF: Fix a bug of __imp_ symbol.
The change I made in r240620 was not correct. If a symbol foo is
defined, and if you use __imp_foo, __imp_foo symbol is automatically
defined as a pointer (not just an alias) to foo.

Now that we need to create a chunk for automatically-created symbols.
I defined LocalImportChunk class for them.

llvm-svn: 240622
2015-06-25 03:31:47 +00:00
Rui Ueyama 49560c7a10 COFF: Move code for ICF from Writer.cpp to ICF.cpp.
llvm-svn: 240590
2015-06-24 20:40:03 +00:00
Rui Ueyama ddf71fc370 COFF: Initial implementation of Identical COMDAT Folding.
Identical COMDAT Folding (ICF) is an optimization to reduce binary
size by merging COMDAT sections that contain the same metadata,
actual data and relocations. MSVC link.exe and many other linkers
have this feature. LLD achieves on per with MSVC in terms produced
binary size with this patch.

This technique is pretty effective. For example, LLD's size is
reduced from 64MB to 54MB by enaling this optimization.

The algorithm implemented in this patch is extremely inefficient.
It puts all COMDAT sections into a set to identify duplicates.
Time to self-link with/without ICF are 3.3 and 320 seconds,
respectively. So this option roughly makes LLD 100x slower.
But it's okay as I wanted to achieve correctness first.
LLD is still able to link itself with this optimization.
I'm going to make it more efficient in followup patches.

Note that this optimization is *not* entirely safe. C/C++ require
different functions have different addresses. If your program
relies on that property, your program wouldn't work with ICF.
However, it's not going to be an issue on Windows because MSVC
link.exe turns ICF on by default. As long as your program works
with default settings (or not passing /opt:noicf), your program
would work with LLD too.

llvm-svn: 240519
2015-06-24 04:36:52 +00:00
Rui Ueyama a77336bd5d COFF: Support delay-load import tables.
DLLs are usually resolved at process startup, but you can
delay-load them by passing /delayload option to the linker.

If a /delayload is specified, the linker has to create data
which is similar to regular import table.
One notable difference is that the pointers in a delay-load
import table are originally pointing to thunks that resolves
themselves. Each thunk loads a DLL, resolve its name, and then
overwrites the pointer with the result so that subsequent
function calls directly call a desired function. The linker
has to emit thunks.

llvm-svn: 240250
2015-06-21 22:31:52 +00:00
Rui Ueyama 4d769c3a57 COFF: Support exception table.
.pdata section contains a list of triplets of function start address,
function end address and its unwind information. Linkers have to
sort section contents by function start address and set the section
address to the file header (so that runtime is able to find it and
do binary search.)

This change seems to resolve all but one remaining test failures in
check{,-clang,-lld} when building the entire stuff with clang-cl and
lld-link.

llvm-svn: 240231
2015-06-21 04:00:54 +00:00
Rui Ueyama 97dff9ee3a COFF: Support creating DLLs.
DLL files are in the same format as executables but they have export tables.
The format of the export table is described in PE/COFF spec section 5.3.

A new class, EdataContents, takes care of creating chunks for export tables.
What we need to do is to parse command line flags for dllexports, and then
instantiate the class to create chunks. For the writer, export table chunks
are opaque data -- it just add chunks to .edata section.

llvm-svn: 239869
2015-06-17 00:16:33 +00:00
Rui Ueyama bc2cc7d0b8 COFF: Fix .reloc section attributes.
llvm-svn: 239738
2015-06-15 18:03:47 +00:00
Rui Ueyama 588e832d0a COFF: Support base relocations.
PE/COFF executables/DLLs usually contain data which is called
base relocations. Base relocations are a list of addresses that
need to be fixed by the loader if load-time relocation is needed.

Base relocations are in .reloc section.

We emit one base relocation entry for each IMAGE_REL_AMD64_ADDR64
relocation.

In order to save disk space, base relocations are grouped by page.
Each group is called a block. A block starts with a 32-bit page
address followed by 16-bit offsets in the page. That is more
efficient representation of addresses than just an array of 32-bit
addresses.

llvm-svn: 239710
2015-06-15 01:23:58 +00:00
Davide Italiano d106ab263a [COFF] Spell the namespace correctly.
llvm-svn: 239641
2015-06-12 21:37:55 +00:00
Rui Ueyama 4b22fa7437 COFF: Move Windows-specific code from Chunk.{cpp,h} to DLL.{cpp,h}.
llvm-svn: 239239
2015-06-07 01:15:04 +00:00
Rui Ueyama cc608e4f35 COFF: Rename writeHeader -> writeHeaderTo.
Chunk has writeTo function which takes uint8_t *Buf.
writeHeaderTo feels more consistent with that because this member
function also takes uint8_t *Buf.

llvm-svn: 239236
2015-06-06 23:19:38 +00:00
Rui Ueyama c6ea057d7f COFF: Move .idata constructor from Writer to Chunk.
Previously, half of the constructor for .idata contents was in Chunks.cpp
and the rest was in Writer.cpp. This patch moves the latter to Chunks.cpp.
Now IdataContents class manages everything for .idata section.

llvm-svn: 239230
2015-06-06 22:46:15 +00:00
Rui Ueyama eb262ce4b6 COFF: /include'd symbols must be preserved.
Not only entry point symbol but also symbols specified by /include
option must be preserved, as they will never be dead-stripped.

http://reviews.llvm.org/D10220

llvm-svn: 239005
2015-06-04 02:12:16 +00:00
Rui Ueyama bda72a4af4 COFF: Change OutputSections' type from vector<unique_ptr<T>> to vector<T*>.
This is mainly for readability. OutputSection objects are still owned
by the writer using SpecificBumpPtrAllocator.

llvm-svn: 238936
2015-06-03 16:44:00 +00:00
Rui Ueyama e00d651071 Use initializer instead of memset to zero out.
llvm-svn: 238662
2015-05-30 19:28:58 +00:00
Rui Ueyama bfb4aa1791 COFF: Support long section name.
Section names were truncated to 8 bytes because the section table's
name field is 8 byte long. This patch creates the string table to
store long names.

llvm-svn: 238661
2015-05-30 19:09:50 +00:00
Rui Ueyama 411c636081 COFF: Add a new PE/COFF port.
This is an initial patch for a section-based COFF linker.

The patch has 2300 lines of code including comments and blank lines.
Before diving into details, you want to start from reading README
because it should give you an overview of the design.

All important things are written in the README file, so I write
summary here.

- The linker is already able to self-link on Windows.

- It's significantly faster than the existing implementation.
  The existing one takes 5 seconds to link LLD on my machine,
  while the new one only takes 1.2 seconds, even though the new
  one is not multi-threaded yet. (And a proof-of-concept multi-
  threaded version was able to link it in 0.5 seconds.)

- It uses much less memory (250MB vs. 2GB virtual memory space
  to self-host).

- IMHO the new code is much simpler and easier to read than
  the existing PE/COFF port.

http://reviews.llvm.org/D10036

llvm-svn: 238458
2015-05-28 19:09:30 +00:00