COFF supports a feature similar to ELF's section groups. This
patch implements it.
In ELF, section groups are identified by their names, and they are
treated somewhat differently from regular symbols. In COFF, the
feature is realized in a more straightforward way. A section can
have an annotation saying "if Nth section is linked, link this
section too."
I added a new reference type, kindAssociate. If a target atom is
coalesced away, the referring atom is removed by Resolver, so that
they are treated as a group.
Differential Revision: http://reviews.llvm.org/D4028
llvm-svn: 211106
COFF supports a feature similar to ELF's section groups. This
patch implements it.
In ELF, section groups are identified by their names, and they are
treated somewhat differently from regular symbols. In COFF, the
feature is realized in a more straightforward way. A section can
have an annotation saying "if Nth section is linked, link this
section too."
Implementing such feature is easy. We can add a reference from a
target atom to an original atom, so that if the target is linked,
the original atom is also linked. If not linked, both will be
dead-stripped. So they are treated as a group.
I added a new reference type, kindAssociate. It does nothing except
preventing referenced atoms from being dead-stripped.
No change to the Resolver is needed.
Reviewers: Bigcheese, shankarke, atanasyan
Subscribers: llvm-commits
Differential Revision: http://reviews.llvm.org/D3946
llvm-svn: 210240
isAlias always returns false and no one is using it. It was
originally added Atom to query if an atom is an alias for another
atom, assuming that alias atoms are different from normal atoms.
We now support atom aliasing, but the way that's implemented is
in a different way than what isAlias assumed. An alias atom is
just a regular defined atom with no content, and it has a layout-
before edge to alias-to atom so that they are layed out at the
same location in the result. So this is dead code, and it doesn't
make much sense to keep it.
llvm-svn: 207884
The main changes are in:
include/lld/Core/Reference.h
include/lld/ReaderWriter/Reader.h
Everything else is details to support the main change.
1) Registration based Readers
Previously, lld had a tangled interdependency with all the Readers. It would
have been impossible to make a streamlined linker (say for a JIT) which
just supported one file format and one architecture (no yaml, no archives, etc).
The old model also required a LinkingContext to read an object file, which
would have made .o inspection tools awkward.
The new model is that there is a global Registry object. You programmatically
register the Readers you want with the registry object. Whenever you need to
read/parse a file, you ask the registry to do it, and the registry tries each
registered reader.
For ease of use with the existing lld code base, there is one Registry
object inside the LinkingContext object.
2) Changing kind value to be a tuple
Beside Readers, the registry also keeps track of the mapping for Reference
Kind values to and from strings. Along with that, this patch also fixes
an ambiguity with the previous Reference::Kind values. The problem was that
we wanted to reuse existing relocation type values as Reference::Kind values.
But then how can the YAML write know how to convert a value to a string? The
fix is to change the 32-bit Reference::Kind into a tuple with an 8-bit namespace
(e.g. ELF, COFFF, etc), an 8-bit architecture (e.g. x86_64, PowerPC, etc), and
a 16-bit value. This tuple system allows conversion to and from strings with
no ambiguities.
llvm-svn: 197727
DLLNameAtom is an atom whose content is a string. IdataAtom is not going to
be the only place we need such atom, so I want to generalize it.
llvm-svn: 197137
I'm planning to create a new pass for the DLL export table, and I want to use
the class both from IdataPass and the new pass, EdataPass. So move the class to
a common place.
llvm-svn: 197132
This patch is to basically move the functionality to construct Data Directory
from IdataPass to WriterPECOFF.
Data Directory is a part of the PE/COFF header and contains the addresses of
the import tables.
We used to represent the link from Data Directory to the import tables as
relocation references. The idea behind it is that, because relocation
references are processed by the Writer, we wouldn't have to do anything special
to fill the addresses of the import tables. I thought that the addresses would
be set "automatically".
But it turned out that that design made the pass and the writer rather
complicated. In order to make relocation references between Data Directory to
the import tables, these data structures needed to be represented as Atom.
However, because Data Directory is not a section content but a part of the
PE/COFF header, it did not fit well as an Atom. So we ended up having
complicated code both in IdataPass and the writer.
This patch simplifies it.
One side effect of this patch is that we now have ".idata.a", ".idata.d" and
"idata.t" sections for the import address table, the import directory table,
and the import lookup table. The writer looks for the sections by name to find
the start addresses of the sections. We probably should have a better way to
find a specific atom from the core linking result, but currently using the
section name seems to be the easiest way to do that. The Windows loader do not
care about the import table's section layout.
llvm-svn: 197016
This patch won't change the output because the layout of linker internal
atoms is forced by layout-{before,after} references. Ordinals of the linker
internal atoms are not currently used. (That's why it's working even if there
are atoms having the same ordinals.)
llvm-svn: 195610
Change the attribute from sectionBasedOnContent to sectionCustomRequired
because its the right attribute for atoms read from COFF files to have.
COFF atoms should basically be emitted to the section having the same name
as input. Permissions/attributes should not affect that.
There's no functionality change because the writer doesn't yet use the
section name. The writer will be modified in a following patch, so that atoms
are written to its customSectionName()'s section.
llvm-svn: 195595
The data directory in the PE/COFF header consisted of list of data directory
atoms. This patch changes it -- now there's only one data directory entry that
contains former data directories. That's easier to handle in the writer as well
as to write to/read from YAML/Native files. The main purpose of this refactoring
is to enable RoundTrip tests for PE/COFF.
There's no functionality change.
llvm-svn: 193854
We should dead-strip atoms only if they are created for COMDAT symbols. If we
remove non-COMDAT atoms from a binary, it will no longer be guaranteed that
the binary will work correctly.
In COFF, you can manipulate the order of section contents in the resulting
binary by section name. For example, if you have four sections
.data$unique_prefix_{a,b,c,d}, it's guaranteed that the contents of A, B, C,
and D will be consecutive in the resulting .data section in that order.
Thus, you can access B's and C's contents by incrementing a pointer pointing
to A until it reached to D. That's why we cannot dead-strip B or C even if
no one is directly referencing to them.
Some object files in the standard library actually use that technique.
llvm-svn: 193017
Summary:
This patch changes WriterPECOFF to actually write down the address instead of ignoring it.
Also, it changes the order of adding the BaseReloc chunk as otherwise the address wasn't set yet.
I think a better way of doing it would be to change DataDirectoryAtom to create a Reference
instead of using a number, and to change IdataPass accordingly, but I'm not sure how to do that.
Reviewers: ruiu
Reviewed By: ruiu
CC: llvm-commits
Differential Revision: http://llvm-reviews.chandlerc.com/D1743
llvm-svn: 191220
Alignment(1) does not mean that the atom should be aligned on a 1 byte
boundary but on a 2^1 boundary. So, atoms without any specific alignment
requirements should have Alignment(0).
llvm-svn: 190723
The COMDAT section is a section with a special attribute to tell the linker
whether the symbols in the section are allowed to be merged or not. This patch
add a function to interpret the COMDAT data and set "merge" attribute to the
atoms accordingly.
LLD supports multiple policies to merge atoms; atoms can be merged by name or
by content. COFF supports them, and in addition to that, it supports
choose-the-largest-atom policy, which LLD currently does not support. I simply
mapped it to merge-by-name attribute for now, but we eventually have to support
that policy in the core linker.
llvm-svn: 188025
The aim of this patch is to reduce the dependency from COFFDefinedAtom
to COFF structs defined in llvm/Object/COFF.h. Currently many attributes
of the atom are computed in the atom. That provide a simple interface but
does not work well in some cases.
There are some cases that the same type atom is created from different
parts of a COFF file. One example is the BSS atom, which can be created
from the defined symbol in the .bss section or from the undefined symbol.
Computing attributes from different sources in the atom complicates the
code. We should compute it outside the atom.
In the next patch, I'll move more code from Atoms.h to ReaderCOFF.cpp.
llvm-svn: 187681
A instance of the class always represents a BSS atom, so we don't need
to look at the symbol or the section to retrieve its attributes.
llvm-svn: 187643
The BSS atom is similar to the regular defined atom, but it's different
in the sense that it does not have contents. Until now we assumed all the
defined atoms have its contents. That did not fit well to the BSS atom.
llvm-svn: 187453
This patch removes hacky mangle() function, which strips all decorations
uncondtitionally. LLD now interprets Import Name/Type field in the import
library properly as described in the Microsoft PE/COFF Spec.
llvm-svn: 187388
This patch adds a new pass, IdataPass, to transform shared atom references
to real references and to construct the .idata section data. With this patch
lld can produce a working Hello World program by linking it against
kernel32.dll and user32.dll.
Reviewers: Bigcheese
CC: llvm-commits
Differential Revision: http://llvm-reviews.chandlerc.com/D1096
llvm-svn: 186071
A hint is an index of the export pointer table in a DLL, at which
PE/COFF loader starts looking for a symbol name. The import library
comes with hints and symbol pairs, and as long as hints are in sync
with the actual symbol table in DLL, the symbols will be resolved
quickly. So, we shouldn't ignore hints but propagate them to an output.
llvm-svn: 185516
In order to support linking against DLL, the linker needs to create defined
atoms for jump tables and etc. Because such atoms are not read from a file,
they lack some information such as an ordinal. With this patch, COFFDefinedAtom
is split into two classes; one is the base class of all COFF defined atoms, and
another is a concrete class for atoms read from file. More classes inheriting
COFFBaseDefinedAtom will be added for jump tables and etc.
llvm-svn: 185195