[lld] Introduce registry and Reference kind tuple
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
2013-12-20 05:58:00 +08:00
|
|
|
//===- lib/ReaderWriter/FileArchive.cpp -----------------------------------===//
|
2013-12-06 12:43:01 +08:00
|
|
|
//
|
|
|
|
// The LLVM Linker
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
[lld] Introduce registry and Reference kind tuple
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
2013-12-20 05:58:00 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
2013-12-06 12:43:01 +08:00
|
|
|
|
[lld] Introduce registry and Reference kind tuple
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
2013-12-20 05:58:00 +08:00
|
|
|
#include "lld/Core/ArchiveLibraryFile.h"
|
|
|
|
#include "lld/Core/LLVM.h"
|
2014-12-14 15:57:35 +08:00
|
|
|
#include "lld/Core/LinkingContext.h"
|
2015-03-04 06:19:46 +08:00
|
|
|
#include "lld/Core/Parallel.h"
|
2013-12-06 12:43:01 +08:00
|
|
|
#include "llvm/ADT/Hashing.h"
|
[lld] Introduce registry and Reference kind tuple
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
2013-12-20 05:58:00 +08:00
|
|
|
#include "llvm/ADT/StringRef.h"
|
2013-12-06 12:43:01 +08:00
|
|
|
#include "llvm/Object/Archive.h"
|
[lld] Introduce registry and Reference kind tuple
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
2013-12-20 05:58:00 +08:00
|
|
|
#include "llvm/Object/ObjectFile.h"
|
|
|
|
#include "llvm/Support/Debug.h"
|
|
|
|
#include "llvm/Support/Format.h"
|
2013-12-06 12:43:01 +08:00
|
|
|
#include "llvm/Support/MemoryBuffer.h"
|
2014-03-14 00:20:38 +08:00
|
|
|
#include <memory>
|
2015-01-17 06:44:50 +08:00
|
|
|
#include <mutex>
|
[lld] Introduce registry and Reference kind tuple
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
2013-12-20 05:58:00 +08:00
|
|
|
#include <set>
|
2014-03-12 23:55:13 +08:00
|
|
|
#include <unordered_map>
|
[lld] Introduce registry and Reference kind tuple
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
2013-12-20 05:58:00 +08:00
|
|
|
|
|
|
|
using llvm::object::Archive;
|
|
|
|
using llvm::object::ObjectFile;
|
|
|
|
using llvm::object::SymbolRef;
|
|
|
|
using llvm::object::symbol_iterator;
|
|
|
|
using llvm::object::object_error;
|
2013-12-06 12:43:01 +08:00
|
|
|
|
|
|
|
namespace lld {
|
|
|
|
|
[lld] Introduce registry and Reference kind tuple
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
2013-12-20 05:58:00 +08:00
|
|
|
namespace {
|
2013-12-06 12:43:01 +08:00
|
|
|
|
[lld] Introduce registry and Reference kind tuple
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
2013-12-20 05:58:00 +08:00
|
|
|
/// \brief The FileArchive class represents an Archive Library file
|
|
|
|
class FileArchive : public lld::ArchiveLibraryFile {
|
|
|
|
public:
|
2014-12-12 18:27:33 +08:00
|
|
|
FileArchive(std::unique_ptr<MemoryBuffer> mb, const Registry ®,
|
Separate file parsing from File's constructors.
This is a second patch for InputGraph cleanup.
Sorry about the size of the patch, but what I did in this
patch is basically moving code from constructor to a new
method, parse(), so the amount of new code is small.
This has no change in functionality.
We've discussed the issue that we have too many classes
to represent a concept of "file". We have File subclasses
that represent files read from disk. In addition to that,
we have bunch of InputElement subclasses (that are part
of InputGraph) that represent command line arguments for
input file names. InputElement is a wrapper for File.
InputElement has parseFile method. The method instantiates
a File. The File's constructor reads a file from disk and
parses that.
Because parseFile method is called from multiple worker
threads, file parsing is processed in parallel. In other
words, one reason why we needed the wrapper classes is
because a File would start reading a file as soon as it
is instantiated.
So, the reason why we have too many classes here is at
least partly because of the design flaw of File class.
Just like threads in a good threading library, we need
to separate instantiation from "start" method, so that
we can instantiate File objects when we need them (which
should be very fast because it involves only one mmap()
and no real file IO) and use them directly instead of
the wrapper classes. Later, we call parse() on each
file in parallel to let them do actual file IO.
In this design, we can eliminate a reason to have the
wrapper classes.
In order to minimize the size of the patch, I didn't go so
far as to replace the wrapper classes with File classes.
The wrapper classes are still there.
In this patch, we call parse() immediately after
instantiating a File, so this really has no change in
functionality. Eventually the call of parse() should be
moved to Driver::link(). That'll be done in another patch.
llvm-svn: 224102
2014-12-12 15:31:09 +08:00
|
|
|
StringRef path, bool logLoading)
|
2014-12-12 18:27:33 +08:00
|
|
|
: ArchiveLibraryFile(path), _mb(std::shared_ptr<MemoryBuffer>(mb.release())),
|
|
|
|
_registry(reg), _logLoading(logLoading) {}
|
2014-06-04 17:09:06 +08:00
|
|
|
|
[lld] Introduce registry and Reference kind tuple
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
2013-12-20 05:58:00 +08:00
|
|
|
/// \brief Check if any member of the archive contains an Atom with the
|
|
|
|
/// specified name and return the File object for that member, or nullptr.
|
2015-03-04 12:36:46 +08:00
|
|
|
File *find(StringRef name, bool dataSymbolOnly) override {
|
[lld] Introduce registry and Reference kind tuple
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
2013-12-20 05:58:00 +08:00
|
|
|
auto member = _symbolMemberMap.find(name);
|
2013-12-20 15:48:29 +08:00
|
|
|
if (member == _symbolMemberMap.end())
|
2013-12-06 12:43:01 +08:00
|
|
|
return nullptr;
|
[lld] Introduce registry and Reference kind tuple
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
2013-12-20 05:58:00 +08:00
|
|
|
Archive::child_iterator ci = member->second;
|
|
|
|
|
2013-12-20 15:48:29 +08:00
|
|
|
// Don't return a member already returned
|
[lld] Introduce registry and Reference kind tuple
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
2013-12-20 05:58:00 +08:00
|
|
|
const char *memberStart = ci->getBuffer().data();
|
2013-12-20 15:48:29 +08:00
|
|
|
if (_membersInstantiated.count(memberStart))
|
2013-12-06 12:43:01 +08:00
|
|
|
return nullptr;
|
2015-03-04 10:12:55 +08:00
|
|
|
if (dataSymbolOnly && !isDataSymbol(ci, name))
|
2014-09-06 06:06:07 +08:00
|
|
|
return nullptr;
|
[lld] Introduce registry and Reference kind tuple
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
2013-12-20 05:58:00 +08:00
|
|
|
|
2014-09-12 04:42:01 +08:00
|
|
|
_membersInstantiated.insert(memberStart);
|
2015-01-17 06:44:50 +08:00
|
|
|
|
|
|
|
// Check if a file is preloaded.
|
|
|
|
{
|
|
|
|
std::lock_guard<std::mutex> lock(_mutex);
|
|
|
|
auto it = _preloaded.find(memberStart);
|
|
|
|
if (it != _preloaded.end()) {
|
2015-03-04 12:36:46 +08:00
|
|
|
std::unique_ptr<Future<File *>> &p = it->second;
|
|
|
|
Future<File *> *future = p.get();
|
2015-03-04 06:19:46 +08:00
|
|
|
return future->get();
|
2015-01-17 06:44:50 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-12 04:42:01 +08:00
|
|
|
std::unique_ptr<File> result;
|
2015-03-04 10:12:55 +08:00
|
|
|
if (instantiateMember(ci, result))
|
[lld] Introduce registry and Reference kind tuple
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
2013-12-20 05:58:00 +08:00
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
// give up the pointer so that this object no longer manages it
|
2014-09-12 04:42:01 +08:00
|
|
|
return result.release();
|
2013-12-06 12:43:01 +08:00
|
|
|
}
|
|
|
|
|
2015-01-17 06:44:50 +08:00
|
|
|
// Instantiate a member file containing a given symbol name.
|
|
|
|
void preload(TaskGroup &group, StringRef name) override {
|
|
|
|
auto member = _symbolMemberMap.find(name);
|
|
|
|
if (member == _symbolMemberMap.end())
|
|
|
|
return;
|
|
|
|
Archive::child_iterator ci = member->second;
|
|
|
|
|
|
|
|
// Do nothing if a member is already instantiated.
|
|
|
|
const char *memberStart = ci->getBuffer().data();
|
|
|
|
if (_membersInstantiated.count(memberStart))
|
|
|
|
return;
|
|
|
|
|
|
|
|
std::lock_guard<std::mutex> lock(_mutex);
|
|
|
|
if (_preloaded.find(memberStart) != _preloaded.end())
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Instantiate the member
|
2015-03-04 12:36:46 +08:00
|
|
|
auto *future = new Future<File *>();
|
|
|
|
_preloaded[memberStart] = std::unique_ptr<Future<File *>>(future);
|
2015-01-17 06:44:50 +08:00
|
|
|
|
|
|
|
group.spawn([=] {
|
|
|
|
std::unique_ptr<File> result;
|
2015-03-04 10:12:55 +08:00
|
|
|
std::error_code ec = instantiateMember(ci, result);
|
2015-03-04 06:19:46 +08:00
|
|
|
future->set(ec ? nullptr : result.release());
|
2015-01-17 06:44:50 +08:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
[lld] Introduce registry and Reference kind tuple
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
2013-12-20 05:58:00 +08:00
|
|
|
/// \brief parse each member
|
2014-06-12 22:53:47 +08:00
|
|
|
std::error_code
|
2015-01-15 12:34:31 +08:00
|
|
|
parseAllMembers(std::vector<std::unique_ptr<File>> &result) override {
|
|
|
|
if (std::error_code ec = parse())
|
|
|
|
return ec;
|
2014-01-22 00:09:55 +08:00
|
|
|
for (auto mf = _archive->child_begin(), me = _archive->child_end();
|
2013-12-20 15:48:29 +08:00
|
|
|
mf != me; ++mf) {
|
2014-09-12 04:42:01 +08:00
|
|
|
std::unique_ptr<File> file;
|
2015-03-04 10:12:55 +08:00
|
|
|
if (std::error_code ec = instantiateMember(mf, file))
|
[lld] Introduce registry and Reference kind tuple
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
2013-12-20 05:58:00 +08:00
|
|
|
return ec;
|
2014-09-12 04:42:01 +08:00
|
|
|
result.push_back(std::move(file));
|
[lld] Introduce registry and Reference kind tuple
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
2013-12-20 05:58:00 +08:00
|
|
|
}
|
2014-06-12 22:53:47 +08:00
|
|
|
return std::error_code();
|
[lld] Introduce registry and Reference kind tuple
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
2013-12-20 05:58:00 +08:00
|
|
|
}
|
2013-12-06 12:43:01 +08:00
|
|
|
|
2014-03-07 05:14:04 +08:00
|
|
|
const atom_collection<DefinedAtom> &defined() const override {
|
[lld] Introduce registry and Reference kind tuple
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
2013-12-20 05:58:00 +08:00
|
|
|
return _definedAtoms;
|
|
|
|
}
|
2013-12-06 12:43:01 +08:00
|
|
|
|
2014-03-07 05:14:04 +08:00
|
|
|
const atom_collection<UndefinedAtom> &undefined() const override {
|
[lld] Introduce registry and Reference kind tuple
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
2013-12-20 05:58:00 +08:00
|
|
|
return _undefinedAtoms;
|
|
|
|
}
|
|
|
|
|
2014-03-07 05:14:04 +08:00
|
|
|
const atom_collection<SharedLibraryAtom> &sharedLibrary() const override {
|
[lld] Introduce registry and Reference kind tuple
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
2013-12-20 05:58:00 +08:00
|
|
|
return _sharedLibraryAtoms;
|
|
|
|
}
|
|
|
|
|
2014-03-07 05:14:04 +08:00
|
|
|
const atom_collection<AbsoluteAtom> &absolute() const override {
|
[lld] Introduce registry and Reference kind tuple
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
2013-12-20 05:58:00 +08:00
|
|
|
return _absoluteAtoms;
|
|
|
|
}
|
2013-12-06 12:43:01 +08:00
|
|
|
|
2014-05-14 13:31:54 +08:00
|
|
|
/// Returns a set of all defined symbols in the archive.
|
2015-01-17 06:44:50 +08:00
|
|
|
std::set<StringRef> getDefinedSymbols() override {
|
|
|
|
parse();
|
2014-05-14 13:31:54 +08:00
|
|
|
std::set<StringRef> ret;
|
|
|
|
for (const auto &e : _symbolMemberMap)
|
|
|
|
ret.insert(e.first);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2014-12-15 15:14:32 +08:00
|
|
|
protected:
|
|
|
|
std::error_code doParse() override {
|
|
|
|
// Make Archive object which will be owned by FileArchive object.
|
|
|
|
std::error_code ec;
|
|
|
|
_archive.reset(new Archive(_mb->getMemBufferRef(), ec));
|
|
|
|
if (ec)
|
|
|
|
return ec;
|
|
|
|
if ((ec = buildTableOfContents()))
|
|
|
|
return ec;
|
|
|
|
return std::error_code();
|
|
|
|
}
|
|
|
|
|
2014-09-12 04:42:01 +08:00
|
|
|
private:
|
2014-06-12 22:53:47 +08:00
|
|
|
std::error_code
|
2015-03-04 10:12:55 +08:00
|
|
|
instantiateMember(Archive::child_iterator member,
|
2014-09-12 04:42:01 +08:00
|
|
|
std::unique_ptr<File> &result) const {
|
2015-03-04 10:12:55 +08:00
|
|
|
ErrorOr<llvm::MemoryBufferRef> mbOrErr = member->getMemoryBufferRef();
|
2014-06-17 00:09:08 +08:00
|
|
|
if (std::error_code ec = mbOrErr.getError())
|
2013-12-06 12:43:01 +08:00
|
|
|
return ec;
|
2014-08-20 02:44:51 +08:00
|
|
|
llvm::MemoryBufferRef mb = mbOrErr.get();
|
2014-11-08 04:52:38 +08:00
|
|
|
std::string memberPath = (_archive->getFileName() + "("
|
|
|
|
+ mb.getBufferIdentifier() + ")").str();
|
|
|
|
|
[lld] Introduce registry and Reference kind tuple
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
2013-12-20 05:58:00 +08:00
|
|
|
if (_logLoading)
|
2014-11-08 04:52:38 +08:00
|
|
|
llvm::errs() << memberPath << "\n";
|
2014-08-20 02:44:51 +08:00
|
|
|
|
2014-11-08 04:52:38 +08:00
|
|
|
std::unique_ptr<MemoryBuffer> memberMB(MemoryBuffer::getMemBuffer(
|
2015-02-06 06:51:36 +08:00
|
|
|
mb.getBuffer(), mb.getBufferIdentifier(), false));
|
2014-08-20 02:44:51 +08:00
|
|
|
|
2014-09-12 04:42:01 +08:00
|
|
|
std::vector<std::unique_ptr<File>> files;
|
2015-01-15 12:34:31 +08:00
|
|
|
if (std::error_code ec = _registry.loadFile(std::move(memberMB), files))
|
|
|
|
return ec;
|
2014-09-12 04:42:01 +08:00
|
|
|
assert(files.size() == 1);
|
|
|
|
result = std::move(files[0]);
|
2015-01-15 12:34:31 +08:00
|
|
|
if (std::error_code ec = result->parse())
|
|
|
|
return ec;
|
2015-02-06 06:51:36 +08:00
|
|
|
result->setArchivePath(_archive->getFileName());
|
2014-11-08 04:52:38 +08:00
|
|
|
|
2014-12-12 18:27:33 +08:00
|
|
|
// The memory buffer is co-owned by the archive file and the children,
|
|
|
|
// so that the bufffer is deallocated when all the members are destructed.
|
|
|
|
result->setSharedMemoryBuffer(_mb);
|
2014-06-12 22:53:47 +08:00
|
|
|
return std::error_code();
|
2013-12-06 12:43:01 +08:00
|
|
|
}
|
|
|
|
|
2014-09-06 06:06:07 +08:00
|
|
|
// Parses the given memory buffer as an object file, and returns true
|
2014-06-04 17:00:55 +08:00
|
|
|
// code if the given symbol is a data symbol. If the symbol is not a data
|
2014-09-06 06:06:07 +08:00
|
|
|
// symbol or does not exist, returns false.
|
2015-03-04 10:12:55 +08:00
|
|
|
bool isDataSymbol(Archive::child_iterator member, StringRef symbol) const {
|
|
|
|
ErrorOr<llvm::MemoryBufferRef> buf = member->getMemoryBufferRef();
|
2014-09-06 06:06:07 +08:00
|
|
|
if (buf.getError())
|
|
|
|
return false;
|
|
|
|
std::unique_ptr<MemoryBuffer> mb(MemoryBuffer::getMemBuffer(
|
|
|
|
buf.get().getBuffer(), buf.get().getBufferIdentifier(), false));
|
|
|
|
|
2014-08-20 02:44:51 +08:00
|
|
|
auto objOrErr(ObjectFile::createObjectFile(mb->getMemBufferRef()));
|
2014-09-06 06:06:07 +08:00
|
|
|
if (objOrErr.getError())
|
|
|
|
return false;
|
2014-07-31 11:17:04 +08:00
|
|
|
std::unique_ptr<ObjectFile> obj = std::move(objOrErr.get());
|
2015-03-04 10:09:22 +08:00
|
|
|
|
|
|
|
for (SymbolRef sym : obj->symbols()) {
|
|
|
|
// Skip until we find the symbol.
|
|
|
|
StringRef name;
|
|
|
|
if (sym.getName(name))
|
2014-09-06 06:06:07 +08:00
|
|
|
return false;
|
2015-03-04 10:09:22 +08:00
|
|
|
if (name != symbol)
|
2013-12-20 15:48:29 +08:00
|
|
|
continue;
|
2015-03-04 10:09:22 +08:00
|
|
|
uint32_t flags = sym.getFlags();
|
|
|
|
if (flags <= SymbolRef::SF_Undefined)
|
2013-12-20 15:48:29 +08:00
|
|
|
continue;
|
2013-12-06 12:43:01 +08:00
|
|
|
|
2015-03-04 10:09:22 +08:00
|
|
|
// Returns true if it's a data symbol.
|
|
|
|
SymbolRef::Type type;
|
|
|
|
if (sym.getType(type))
|
2014-09-06 06:06:07 +08:00
|
|
|
return false;
|
2015-03-04 10:09:22 +08:00
|
|
|
if (type == SymbolRef::ST_Data)
|
2014-09-06 06:06:07 +08:00
|
|
|
return true;
|
[lld] Introduce registry and Reference kind tuple
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
2013-12-20 05:58:00 +08:00
|
|
|
}
|
2014-09-06 06:06:07 +08:00
|
|
|
return false;
|
[lld] Introduce registry and Reference kind tuple
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
2013-12-20 05:58:00 +08:00
|
|
|
}
|
2013-12-06 12:43:01 +08:00
|
|
|
|
2015-03-04 09:26:32 +08:00
|
|
|
std::error_code buildTableOfContents() {
|
|
|
|
DEBUG_WITH_TYPE("FileArchive", llvm::dbgs()
|
|
|
|
<< "Table of contents for archive '"
|
|
|
|
<< _archive->getFileName() << "':\n");
|
2015-03-04 10:09:22 +08:00
|
|
|
for (const Archive::Symbol &sym : _archive->symbols()) {
|
|
|
|
StringRef name = sym.getName();
|
|
|
|
ErrorOr<Archive::child_iterator> memberOrErr = sym.getMember();
|
2015-03-04 09:26:32 +08:00
|
|
|
if (std::error_code ec = memberOrErr.getError())
|
|
|
|
return ec;
|
|
|
|
Archive::child_iterator member = memberOrErr.get();
|
|
|
|
DEBUG_WITH_TYPE(
|
|
|
|
"FileArchive",
|
|
|
|
llvm::dbgs() << llvm::format("0x%08llX ", member->getBuffer().data())
|
|
|
|
<< "'" << name << "'\n");
|
|
|
|
_symbolMemberMap[name] = member;
|
|
|
|
}
|
|
|
|
return std::error_code();
|
|
|
|
}
|
|
|
|
|
2013-12-20 15:48:29 +08:00
|
|
|
typedef std::unordered_map<StringRef, Archive::child_iterator> MemberMap;
|
|
|
|
typedef std::set<const char *> InstantiatedSet;
|
|
|
|
|
2014-12-12 18:27:33 +08:00
|
|
|
std::shared_ptr<MemoryBuffer> _mb;
|
2013-12-20 15:48:29 +08:00
|
|
|
const Registry &_registry;
|
|
|
|
std::unique_ptr<Archive> _archive;
|
2015-03-04 12:36:46 +08:00
|
|
|
MemberMap _symbolMemberMap;
|
|
|
|
InstantiatedSet _membersInstantiated;
|
2013-12-20 15:48:29 +08:00
|
|
|
atom_collection_vector<DefinedAtom> _definedAtoms;
|
|
|
|
atom_collection_vector<UndefinedAtom> _undefinedAtoms;
|
[lld] Introduce registry and Reference kind tuple
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
2013-12-20 05:58:00 +08:00
|
|
|
atom_collection_vector<SharedLibraryAtom> _sharedLibraryAtoms;
|
2013-12-20 15:48:29 +08:00
|
|
|
atom_collection_vector<AbsoluteAtom> _absoluteAtoms;
|
|
|
|
bool _logLoading;
|
2015-03-04 12:36:46 +08:00
|
|
|
std::vector<std::unique_ptr<MemoryBuffer>> _memberBuffers;
|
|
|
|
std::map<const char *, std::unique_ptr<Future<File *>>> _preloaded;
|
|
|
|
std::mutex _mutex;
|
2014-06-04 17:09:06 +08:00
|
|
|
};
|
[lld] Introduce registry and Reference kind tuple
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
2013-12-20 05:58:00 +08:00
|
|
|
|
|
|
|
class ArchiveReader : public Reader {
|
|
|
|
public:
|
2013-12-20 15:48:29 +08:00
|
|
|
ArchiveReader(bool logLoading) : _logLoading(logLoading) {}
|
|
|
|
|
2015-04-04 10:44:36 +08:00
|
|
|
bool canParse(file_magic magic, const MemoryBuffer &) const override {
|
|
|
|
return magic == llvm::sys::fs::file_magic::archive;
|
[lld] Introduce registry and Reference kind tuple
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
2013-12-20 05:58:00 +08:00
|
|
|
}
|
2013-12-20 15:48:29 +08:00
|
|
|
|
2014-06-12 22:53:47 +08:00
|
|
|
std::error_code
|
2015-01-15 12:34:31 +08:00
|
|
|
loadFile(std::unique_ptr<MemoryBuffer> mb, const Registry ®,
|
|
|
|
std::vector<std::unique_ptr<File>> &result) const override {
|
2014-12-12 18:27:33 +08:00
|
|
|
StringRef path = mb->getBufferIdentifier();
|
2013-12-20 15:48:29 +08:00
|
|
|
std::unique_ptr<FileArchive> file(
|
2014-12-12 18:27:33 +08:00
|
|
|
new FileArchive(std::move(mb), reg, path, _logLoading));
|
[lld] Introduce registry and Reference kind tuple
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
2013-12-20 05:58:00 +08:00
|
|
|
result.push_back(std::move(file));
|
2014-06-12 22:53:47 +08:00
|
|
|
return std::error_code();
|
2013-12-06 12:43:01 +08:00
|
|
|
}
|
2013-12-20 15:48:29 +08:00
|
|
|
|
[lld] Introduce registry and Reference kind tuple
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
2013-12-20 05:58:00 +08:00
|
|
|
private:
|
2013-12-20 15:48:29 +08:00
|
|
|
bool _logLoading;
|
[lld] Introduce registry and Reference kind tuple
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
2013-12-20 05:58:00 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
} // anonymous namespace
|
|
|
|
|
|
|
|
void Registry::addSupportArchives(bool logLoading) {
|
|
|
|
add(std::unique_ptr<Reader>(new ArchiveReader(logLoading)));
|
2013-12-06 12:43:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
} // end namespace lld
|