aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2015-04-10 21:23:51 +0000
committerRui Ueyama <ruiu@google.com>2015-04-10 21:23:51 +0000
commitff05d4477f4d108502e2f9c3db95d95ff2c2617b (patch)
treefbf8d42b0c9b2f91c910b874733f81a3e8f4c44d /lib
parent80ad8619b16779eec744f779065ef09b99e9bf37 (diff)
Remove the Native file format.
The Native file format was designed to be the fastest on-memory or on-disk file format for object files. The problem is that no one is working on that. No LLVM tools can produce object files in the Native, thus the feature of supporting the format is useless in the linker. This patch removes the Native file support. We can add it back if we really want it in future. git-svn-id: https://llvm.org/svn/llvm-project/lld/trunk@234641 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Core/Error.cpp33
-rw-r--r--lib/Core/TODO.txt18
-rw-r--r--lib/Driver/CoreDriver.cpp1
-rw-r--r--lib/Driver/DarwinLdDriver.cpp1
-rw-r--r--lib/Driver/GnuLdDriver.cpp4
-rw-r--r--lib/Driver/GnuLdOptions.td2
-rw-r--r--lib/Driver/WinLinkDriver.cpp1
-rw-r--r--lib/ReaderWriter/CMakeLists.txt1
-rw-r--r--lib/ReaderWriter/ELF/ELFLinkingContext.cpp3
-rw-r--r--lib/ReaderWriter/Native/CMakeLists.txt7
-rw-r--r--lib/ReaderWriter/Native/NativeFileFormat.h258
-rw-r--r--lib/ReaderWriter/Native/ReaderNative.cpp881
-rw-r--r--lib/ReaderWriter/Native/WriterNative.cpp566
-rw-r--r--lib/ReaderWriter/PECOFF/ReaderCOFF.cpp9
-rw-r--r--lib/ReaderWriter/PECOFF/ReaderImportHeader.cpp2
15 files changed, 6 insertions, 1781 deletions
diff --git a/lib/Core/Error.cpp b/lib/Core/Error.cpp
index 24809c386..e1734283f 100644
--- a/lib/Core/Error.cpp
+++ b/lib/Core/Error.cpp
@@ -16,39 +16,6 @@
using namespace lld;
-class _NativeReaderErrorCategory : public std::error_category {
-public:
- const char* name() const LLVM_NOEXCEPT override {
- return "lld.native.reader";
- }
-
- std::string message(int ev) const override {
- switch (static_cast<NativeReaderError>(ev)) {
- case NativeReaderError::success:
- return "Success";
- case NativeReaderError::unknown_file_format:
- return "Unknown file format";
- case NativeReaderError::file_too_short:
- return "file truncated";
- case NativeReaderError::file_malformed:
- return "file malformed";
- case NativeReaderError::memory_error:
- return "out of memory";
- case NativeReaderError::unknown_chunk_type:
- return "unknown chunk type";
- case NativeReaderError::conflicting_target_machine:
- return "conflicting target machine";
- }
- llvm_unreachable("An enumerator of NativeReaderError does not have a "
- "message defined.");
- }
-};
-
-const std::error_category &lld::native_reader_category() {
- static _NativeReaderErrorCategory o;
- return o;
-}
-
class _YamlReaderErrorCategory : public std::error_category {
public:
const char* name() const LLVM_NOEXCEPT override {
diff --git a/lib/Core/TODO.txt b/lib/Core/TODO.txt
deleted file mode 100644
index 196a3e02c..000000000
--- a/lib/Core/TODO.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-lib/Core
-~~~~~~~~
-
-* Add endianness support to the native reader and writer.
-
-* The NativeReader has lots of similar code for converting arrays of ivar
- data in mapped memory into arrays of objects. The commonality can be
- factored out, maybe templatized.
-
-* The NativeFileFormat.h is old school C structs and constants. We scope
- things better by defining constants used with a struct inside the struct
- declaration.
-
-* The native reader and writer currently just blast in memory enumeration
- values (e.g. DefinedAtom::Scope) into a byte in the disk format. To support
- future changes to the enumerations, there should be a translation layer
- to map disk values to in-memory values.
-
diff --git a/lib/Driver/CoreDriver.cpp b/lib/Driver/CoreDriver.cpp
index b8adee557..825475ba8 100644
--- a/lib/Driver/CoreDriver.cpp
+++ b/lib/Driver/CoreDriver.cpp
@@ -77,7 +77,6 @@ bool CoreDriver::link(int argc, const char *argv[], raw_ostream &diagnostics) {
CoreLinkingContext ctx;
// Register possible input file parsers.
- ctx.registry().addSupportNativeObjects();
ctx.registry().addSupportYamlFiles();
ctx.registry().addKindTable(Reference::KindNamespace::testing,
Reference::KindArch::all, coreKindStrings);
diff --git a/lib/Driver/DarwinLdDriver.cpp b/lib/Driver/DarwinLdDriver.cpp
index 62afac8ab..992f8adc8 100644
--- a/lib/Driver/DarwinLdDriver.cpp
+++ b/lib/Driver/DarwinLdDriver.cpp
@@ -544,7 +544,6 @@ bool DarwinLdDriver::parse(int argc, const char *argv[],
if (!ctx.doNothing()) {
ctx.registry().addSupportMachOObjects(ctx);
ctx.registry().addSupportArchives(ctx.logInputFiles());
- ctx.registry().addSupportNativeObjects();
ctx.registry().addSupportYamlFiles();
}
diff --git a/lib/Driver/GnuLdDriver.cpp b/lib/Driver/GnuLdDriver.cpp
index 7a1f674ec..7f8d2473a 100644
--- a/lib/Driver/GnuLdDriver.cpp
+++ b/lib/Driver/GnuLdDriver.cpp
@@ -645,7 +645,6 @@ bool GnuLdDriver::parse(int argc, const char *argv[],
ctx->registry().addSupportELFObjects(*ctx);
ctx->registry().addSupportArchives(ctx->logInputFiles());
ctx->registry().addSupportYamlFiles();
- ctx->registry().addSupportNativeObjects();
if (ctx->allowLinkWithDynamicLibraries())
ctx->registry().addSupportELFDynamicSharedObjects(*ctx);
@@ -752,9 +751,6 @@ bool GnuLdDriver::parse(int argc, const char *argv[],
case LinkingContext::OutputFileType::YAML:
ctx->setOutputPath("-");
break;
- case LinkingContext::OutputFileType::Native:
- ctx->setOutputPath("a.native");
- break;
default:
ctx->setOutputPath("a.out");
break;
diff --git a/lib/Driver/GnuLdOptions.td b/lib/Driver/GnuLdOptions.td
index 6cd26fa31..b8b3fb694 100644
--- a/lib/Driver/GnuLdOptions.td
+++ b/lib/Driver/GnuLdOptions.td
@@ -313,7 +313,7 @@ def stats : Flag<["--"], "stats">,
def grp_extns : OptionGroup<"opts">,
HelpText<"Extensions">;
def output_filetype: Separate<["--"], "output-filetype">,
- HelpText<"Specify what type of output file that lld creates, YAML/Native">,
+ HelpText<"Specify yaml to create an output in YAML format">,
Group<grp_extns>;
def alias_output_filetype: Joined<["--"], "output-filetype=">,
Alias<output_filetype>;
diff --git a/lib/Driver/WinLinkDriver.cpp b/lib/Driver/WinLinkDriver.cpp
index 6ee7a5a00..7bc26bb24 100644
--- a/lib/Driver/WinLinkDriver.cpp
+++ b/lib/Driver/WinLinkDriver.cpp
@@ -862,7 +862,6 @@ bool WinLinkDriver::linkPECOFF(int argc, const char **argv, raw_ostream &diag) {
ctx.registry().addSupportCOFFObjects(ctx);
ctx.registry().addSupportCOFFImportLibraries(ctx);
ctx.registry().addSupportArchives(ctx.logInputFiles());
- ctx.registry().addSupportNativeObjects();
ctx.registry().addSupportYamlFiles();
std::vector<const char *> newargv = processLinkEnv(ctx, argc, argv);
diff --git a/lib/ReaderWriter/CMakeLists.txt b/lib/ReaderWriter/CMakeLists.txt
index 1fd19eb73..0f5df9490 100644
--- a/lib/ReaderWriter/CMakeLists.txt
+++ b/lib/ReaderWriter/CMakeLists.txt
@@ -1,6 +1,5 @@
add_subdirectory(ELF)
add_subdirectory(MachO)
-add_subdirectory(Native)
add_subdirectory(PECOFF)
add_subdirectory(YAML)
diff --git a/lib/ReaderWriter/ELF/ELFLinkingContext.cpp b/lib/ReaderWriter/ELF/ELFLinkingContext.cpp
index 040a412d4..5e734b2f8 100644
--- a/lib/ReaderWriter/ELF/ELFLinkingContext.cpp
+++ b/lib/ReaderWriter/ELF/ELFLinkingContext.cpp
@@ -75,9 +75,6 @@ bool ELFLinkingContext::validateImpl(raw_ostream &diagnostics) {
case LinkingContext::OutputFileType::YAML:
_writer = createWriterYAML(*this);
break;
- case LinkingContext::OutputFileType::Native:
- llvm_unreachable("Unimplemented");
- break;
default:
_writer = createWriterELF(*this);
break;
diff --git a/lib/ReaderWriter/Native/CMakeLists.txt b/lib/ReaderWriter/Native/CMakeLists.txt
deleted file mode 100644
index e15f3d60e..000000000
--- a/lib/ReaderWriter/Native/CMakeLists.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-add_llvm_library(lldNative
- ReaderNative.cpp
- WriterNative.cpp
- LINK_LIBS
- lldCore
- LLVMSupport
- )
diff --git a/lib/ReaderWriter/Native/NativeFileFormat.h b/lib/ReaderWriter/Native/NativeFileFormat.h
deleted file mode 100644
index dec893baa..000000000
--- a/lib/ReaderWriter/Native/NativeFileFormat.h
+++ /dev/null
@@ -1,258 +0,0 @@
-//===- lib/ReaderWriter/Native/NativeFileFormat.h -------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_READER_WRITER_NATIVE_NATIVE_FILE_FORMAT_H
-#define LLD_READER_WRITER_NATIVE_NATIVE_FILE_FORMAT_H
-
-#include "llvm/Support/DataTypes.h"
-#include <cstdint>
-
-namespace lld {
-
-//
-// Overview:
-//
-// The number one design goal of this file format is enable the linker to
-// read object files into in-memory Atom objects extremely quickly.
-// The second design goal is to enable future modifications to the
-// Atom attribute model.
-//
-// The llvm native object file format is not like traditional object file
-// formats (e.g. ELF, COFF, mach-o). There is no symbol table and no
-// sections. Instead the file is essentially an array of archived Atoms.
-// It is *not* serialized Atoms which would require deserialization into
-// in memory objects. Instead it is an array of read-only info about each
-// Atom. The NativeReader bulk creates in-memory Atoms which just have
-// an ivar which points to the read-only info for that Atom. No additional
-// processing is done to construct the in-memory Atoms. All Atom attribute
-// getter methods are virtual calls which dig up the info they need from the
-// ivar data.
-//
-// To support the gradual evolution of Atom attributes, the Atom read-only
-// data is versioned. The NativeReader chooses which in-memory Atom class
-// to use based on the version. What this means is that if new attributes
-// are added (or changed) in the Atom model, a new native atom class and
-// read-only atom info struct needs to be defined. Then, all the existing
-// native reader atom classes need to be modified to do their best effort
-// to map their old style read-only data to the new Atom model. At some point
-// some classes to support old versions may be dropped.
-//
-//
-// Details:
-//
-// The native object file format consists of a header that specifies the
-// endianness of the file and the architecture along with a list of "chunks"
-// in the file. A Chunk is simply a tagged range of the file. There is
-// one chunk for the array of atom infos. There is another chunk for the
-// string pool, and another for the content pool.
-//
-// It turns out there most atoms have very similar sets of attributes, only
-// the name and content attribute vary. To exploit this fact to reduce the file
-// size, the atom read-only info contains just the name and content info plus
-// a reference to which attribute set it uses. The attribute sets are stored
-// in another chunk.
-//
-
-
-//
-// An entry in the NativeFileHeader that describes one chunk of the file.
-//
-struct NativeChunk {
- uint32_t signature;
- uint32_t fileOffset;
- uint32_t fileSize;
- uint32_t elementCount;
-};
-
-
-//
-// The header in a native object file
-//
-struct NativeFileHeader {
- uint8_t magic[16];
- uint32_t endian;
- uint32_t architecture;
- uint32_t fileSize;
- uint32_t chunkCount;
- // NativeChunk chunks[]
-};
-
-//
-// Possible values for NativeChunk.signature field
-//
-enum NativeChunkSignatures {
- NCS_DefinedAtomsV1 = 1,
- NCS_AttributesArrayV1 = 2,
- NCS_AbsoluteAttributesV1 = 12,
- NCS_UndefinedAtomsV1 = 3,
- NCS_SharedLibraryAtomsV1 = 4,
- NCS_AbsoluteAtomsV1 = 5,
- NCS_Strings = 6,
- NCS_ReferencesArrayV1 = 7,
- NCS_ReferencesArrayV2 = 8,
- NCS_TargetsTable = 9,
- NCS_AddendsTable = 10,
- NCS_Content = 11,
-};
-
-//
-// The 16-bytes at the start of a native object file
-//
-#define NATIVE_FILE_HEADER_MAGIC "llvm nat obj v1 "
-
-//
-// Possible values for the NativeFileHeader.endian field
-//
-enum {
- NFH_BigEndian = 0x42696745,
- NFH_LittleEndian = 0x4574696c
-};
-
-
-//
-// Possible values for the NativeFileHeader.architecture field
-//
-enum {
- NFA_x86 = 1,
- NFA_x86_64 = 2,
- NFA_armv6 = 3,
- NFA_armv7 = 4,
-};
-
-
-//
-// The NCS_DefinedAtomsV1 chunk contains an array of these structs
-//
-struct NativeDefinedAtomIvarsV1 {
- uint32_t nameOffset;
- uint32_t attributesOffset;
- uint32_t referencesStartIndex;
- uint32_t referencesCount;
- uint32_t contentOffset;
- uint32_t contentSize;
- uint64_t sectionSize;
-};
-
-
-//
-// The NCS_AttributesArrayV1 chunk contains an array of these structs
-//
-struct NativeAtomAttributesV1 {
- uint32_t sectionNameOffset;
- uint16_t align;
- uint16_t alignModulus;
- uint8_t scope;
- uint8_t interposable;
- uint8_t merge;
- uint8_t contentType;
- uint8_t sectionChoice;
- uint8_t deadStrip;
- uint8_t dynamicExport;
- uint8_t permissions;
- uint8_t alias;
- uint8_t codeModel;
-};
-
-
-
-//
-// The NCS_UndefinedAtomsV1 chunk contains an array of these structs
-//
-struct NativeUndefinedAtomIvarsV1 {
- uint32_t nameOffset;
- uint32_t flags;
- uint32_t fallbackNameOffset;
-};
-
-
-//
-// The NCS_SharedLibraryAtomsV1 chunk contains an array of these structs
-//
-struct NativeSharedLibraryAtomIvarsV1 {
- uint64_t size;
- uint32_t nameOffset;
- uint32_t loadNameOffset;
- uint32_t type;
- uint32_t flags;
-};
-
-
-
-//
-// The NCS_AbsoluteAtomsV1 chunk contains an array of these structs
-//
-struct NativeAbsoluteAtomIvarsV1 {
- uint32_t nameOffset;
- uint32_t attributesOffset;
- uint32_t reserved;
- uint64_t value;
-};
-
-
-
-//
-// The NCS_ReferencesArrayV1 chunk contains an array of these structs
-//
-struct NativeReferenceIvarsV1 {
- enum {
- noTarget = UINT16_MAX
- };
- uint32_t offsetInAtom;
- uint16_t kindValue;
- uint8_t kindNamespace;
- uint8_t kindArch;
- uint16_t targetIndex;
- uint16_t addendIndex;
-};
-
-
-//
-// The NCS_ReferencesArrayV2 chunk contains an array of these structs
-//
-struct NativeReferenceIvarsV2 {
- enum : unsigned {
- noTarget = UINT32_MAX
- };
- uint64_t offsetInAtom;
- int64_t addend;
- uint16_t kindValue;
- uint8_t kindNamespace;
- uint8_t kindArch;
- uint32_t targetIndex;
- uint32_t tag;
-};
-
-
-//
-// The NCS_TargetsTable chunk contains an array of uint32_t entries.
-// The C++ class Reference has a target() method that returns a
-// pointer to another Atom. We can't have pointers in object files,
-// so instead NativeReferenceIvarsV1 contains an index to the target.
-// The index is into this NCS_TargetsTable of uint32_t entries.
-// The values in this table are the index of the (target) atom in this file.
-// For DefinedAtoms the value is from 0 to NCS_DefinedAtomsV1.elementCount.
-// For UndefinedAtoms the value is from NCS_DefinedAtomsV1.elementCount to
-// NCS_DefinedAtomsV1.elementCount+NCS_UndefinedAtomsV1.elementCount.
-//
-
-
-//
-// The NCS_AddendsTable chunk contains an array of int64_t entries.
-// If we allocated space for addends directly in NativeReferenceIvarsV1
-// it would double the size of that struct. But since addends are rare,
-// we instead just keep a pool of addends and have NativeReferenceIvarsV1
-// (if it needs an addend) just store the index (into the pool) of the
-// addend it needs.
-//
-
-
-
-} // namespace lld
-
-#endif // LLD_READER_WRITER_NATIVE_NATIVE_FILE_FORMAT_H
diff --git a/lib/ReaderWriter/Native/ReaderNative.cpp b/lib/ReaderWriter/Native/ReaderNative.cpp
deleted file mode 100644
index 2e4089277..000000000
--- a/lib/ReaderWriter/Native/ReaderNative.cpp
+++ /dev/null
@@ -1,881 +0,0 @@
-//===- lib/ReaderWriter/Native/ReaderNative.cpp ---------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "NativeFileFormat.h"
-#include "lld/Core/Atom.h"
-#include "lld/Core/Error.h"
-#include "lld/Core/File.h"
-#include "lld/Core/Reader.h"
-#include "lld/Core/Simple.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/raw_ostream.h"
-#include <memory>
-#include <vector>
-
-namespace lld {
-namespace native {
-
-// forward reference
-class File;
-
-//
-// An object of this class is instantied for each NativeDefinedAtomIvarsV1
-// struct in the NCS_DefinedAtomsV1 chunk.
-//
-class NativeDefinedAtomV1 : public DefinedAtom {
-public:
- NativeDefinedAtomV1(const File& f,
- const NativeDefinedAtomIvarsV1* ivarData)
- : _file(&f), _ivarData(ivarData) { }
-
- const lld::File& file() const override;
-
- uint64_t ordinal() const override;
-
- StringRef name() const override;
-
- uint64_t size() const override { return _ivarData->contentSize; }
-
- uint64_t sectionSize() const override { return _ivarData->sectionSize; }
-
- DefinedAtom::Scope scope() const override {
- return (DefinedAtom::Scope)(attributes().scope);
- }
-
- DefinedAtom::Interposable interposable() const override {
- return (DefinedAtom::Interposable)(attributes().interposable);
- }
-
- DefinedAtom::Merge merge() const override {
- return (DefinedAtom::Merge)(attributes().merge);
- }
-
- DefinedAtom::ContentType contentType() const override {
- const NativeAtomAttributesV1& attr = attributes();
- return (DefinedAtom::ContentType)(attr.contentType);
- }
-
- DefinedAtom::Alignment alignment() const override {
- return DefinedAtom::Alignment(attributes().align,
- attributes().alignModulus);
- }
-
- DefinedAtom::SectionChoice sectionChoice() const override {
- return (DefinedAtom::SectionChoice)(attributes().sectionChoice);
- }
-
- StringRef customSectionName() const override;
-
- DefinedAtom::DeadStripKind deadStrip() const override {
- return (DefinedAtom::DeadStripKind)(attributes().deadStrip);
- }
-
- DynamicExport dynamicExport() const override {
- return (DynamicExport)attributes().dynamicExport;
- }
-
- DefinedAtom::CodeModel codeModel() const override {
- return DefinedAtom::CodeModel(attributes().codeModel);
- }
-
- DefinedAtom::ContentPermissions permissions() const override {
- return (DefinedAtom::ContentPermissions)(attributes().permissions);
- }
-
- ArrayRef<uint8_t> rawContent() const override;
-
- reference_iterator begin() const override;
-
- reference_iterator end() const override;
-
- const Reference* derefIterator(const void*) const override;
-
- void incrementIterator(const void*& it) const override;
-
-private:
- const NativeAtomAttributesV1& attributes() const;
-
- const File *_file;
- const NativeDefinedAtomIvarsV1 *_ivarData;
-};
-
-
-
-//
-// An object of this class is instantied for each NativeUndefinedAtomIvarsV1
-// struct in the NCS_UndefinedAtomsV1 chunk.
-//
-class NativeUndefinedAtomV1 : public UndefinedAtom {
-public:
- NativeUndefinedAtomV1(const File& f,
- const NativeUndefinedAtomIvarsV1* ivarData)
- : _file(&f), _ivarData(ivarData) { }
-
- const lld::File& file() const override;
- StringRef name() const override;
-
- CanBeNull canBeNull() const override {
- return (CanBeNull)(_ivarData->flags & 0x3);
- }
-
- const UndefinedAtom *fallback() const override;
-
-private:
- const File *_file;
- const NativeUndefinedAtomIvarsV1 *_ivarData;
- mutable std::unique_ptr<const SimpleUndefinedAtom> _fallback;
-};
-
-
-//
-// An object of this class is instantied for each NativeUndefinedAtomIvarsV1
-// struct in the NCS_SharedLibraryAtomsV1 chunk.
-//
-class NativeSharedLibraryAtomV1 : public SharedLibraryAtom {
-public:
- NativeSharedLibraryAtomV1(const File& f,
- const NativeSharedLibraryAtomIvarsV1* ivarData)
- : _file(&f), _ivarData(ivarData) { }
-
- const lld::File& file() const override;
- StringRef name() const override;
- StringRef loadName() const override;
-
- bool canBeNullAtRuntime() const override {
- return (_ivarData->flags & 0x1);
- }
-
- Type type() const override {
- return (Type)_ivarData->type;
- }
-
- uint64_t size() const override {
- return _ivarData->size;
- }
-
-private:
- const File *_file;
- const NativeSharedLibraryAtomIvarsV1 *_ivarData;
-};
-
-
-//
-// An object of this class is instantied for each NativeAbsoluteAtomIvarsV1
-// struct in the NCS_AbsoluteAtomsV1 chunk.
-//
-class NativeAbsoluteAtomV1 : public AbsoluteAtom {
-public:
- NativeAbsoluteAtomV1(const File& f,
- const NativeAbsoluteAtomIvarsV1* ivarData)
- : _file(&f), _ivarData(ivarData) { }
-
- const lld::File& file() const override;
- StringRef name() const override;
- Scope scope() const override {
- const NativeAtomAttributesV1& attr = absAttributes();
- return (Scope)(attr.scope);
- }
- uint64_t value() const override {
- return _ivarData->value;
- }
-
-private:
- const NativeAtomAttributesV1& absAttributes() const;
- const File *_file;
- const NativeAbsoluteAtomIvarsV1 *_ivarData;
-};
-
-
-//
-// An object of this class is instantied for each NativeReferenceIvarsV1
-// struct in the NCS_ReferencesArrayV1 chunk.
-//
-class NativeReferenceV1 : public Reference {
-public:
- NativeReferenceV1(const File &f, const NativeReferenceIvarsV1 *ivarData)
- : Reference((KindNamespace)ivarData->kindNamespace,
- (KindArch)ivarData->kindArch, ivarData->kindValue),
- _file(&f), _ivarData(ivarData) {}
-
- uint64_t offsetInAtom() const override {
- return _ivarData->offsetInAtom;
- }
-
- const Atom* target() const override;
- Addend addend() const override;
- void setTarget(const Atom* newAtom) override;
- void setAddend(Addend a) override;
-
-private:
- const File *_file;
- const NativeReferenceIvarsV1 *_ivarData;
-};
-
-
-//
-// An object of this class is instantied for each NativeReferenceIvarsV1
-// struct in the NCS_ReferencesArrayV1 chunk.
-//
-class NativeReferenceV2 : public Reference {
-public:
- NativeReferenceV2(const File &f, const NativeReferenceIvarsV2 *ivarData)
- : Reference((KindNamespace)ivarData->kindNamespace,
- (KindArch)ivarData->kindArch, ivarData->kindValue),
- _file(&f), _ivarData(ivarData) {}
-
- uint64_t offsetInAtom() const override {
- return _ivarData->offsetInAtom;
- }
-
- const Atom* target() const override;
- Addend addend() const override;
- void setTarget(const Atom* newAtom) override;
- void setAddend(Addend a) override;
- uint32_t tag() const override;
-
-private:
- const File *_file;
- const NativeReferenceIvarsV2 *_ivarData;
-};
-
-
-//
-// lld::File object for native llvm object file
-//
-class File : public lld::File {
-public:
- File(std::unique_ptr<MemoryBuffer> mb)
- : lld::File(mb->getBufferIdentifier(), kindObject),
- _mb(std::move(mb)), // Reader now takes ownership of buffer
- _header(nullptr), _targetsTable(nullptr), _targetsTableCount(0),
- _strings(nullptr), _stringsMaxOffset(0), _addends(nullptr),
- _addendsMaxIndex(0), _contentStart(nullptr), _contentEnd(nullptr) {
- _header =
- reinterpret_cast<const NativeFileHeader *>(_mb->getBufferStart());
- }
-
- /// Parses a File object from a native object file.
- std::error_code doParse() override {
- const uint8_t *const base =
- reinterpret_cast<const uint8_t *>(_mb->getBufferStart());
- StringRef path(_mb->getBufferIdentifier());
- const NativeFileHeader *const header =
- reinterpret_cast<const NativeFileHeader *>(base);
- const NativeChunk *const chunks =
- reinterpret_cast<const NativeChunk *>(base + sizeof(NativeFileHeader));
- // make sure magic matches
- if (memcmp(header->magic, NATIVE_FILE_HEADER_MAGIC,
- sizeof(header->magic)) != 0)
- return make_error_code(NativeReaderError::unknown_file_format);
-
- // make sure mapped file contains all needed data
- const size_t fileSize = _mb->getBufferSize();
- if (header->fileSize > fileSize)
- return make_error_code(NativeReaderError::file_too_short);
-
- DEBUG_WITH_TYPE("ReaderNative",
- llvm::dbgs() << " Native File Header:" << " fileSize="
- << header->fileSize << " chunkCount="
- << header->chunkCount << "\n");
-
- // process each chunk
- for (uint32_t i = 0; i < header->chunkCount; ++i) {
- std::error_code ec;
- const NativeChunk* chunk = &chunks[i];
- // sanity check chunk is within file
- if ( chunk->fileOffset > fileSize )
- return make_error_code(NativeReaderError::file_malformed);
- if ( (chunk->fileOffset + chunk->fileSize) > fileSize)
- return make_error_code(NativeReaderError::file_malformed);
- // process chunk, based on signature
- switch ( chunk->signature ) {
- case NCS_DefinedAtomsV1:
- ec = processDefinedAtomsV1(base, chunk);
- break;
- case NCS_AttributesArrayV1:
- ec = processAttributesV1(base, chunk);
- break;
- case NCS_UndefinedAtomsV1:
- ec = processUndefinedAtomsV1(base, chunk);
- break;
- case NCS_SharedLibraryAtomsV1:
- ec = processSharedLibraryAtomsV1(base, chunk);
- break;
- case NCS_AbsoluteAtomsV1:
- ec = processAbsoluteAtomsV1(base, chunk);
- break;
- case NCS_AbsoluteAttributesV1:
- ec = processAbsoluteAttributesV1(base, chunk);
- break;
- case NCS_ReferencesArrayV1:
- ec = processReferencesV1(base, chunk);
- break;
- case NCS_ReferencesArrayV2:
- ec = processReferencesV2(base, chunk);
- break;
- case NCS_TargetsTable:
- ec = processTargetsTable(base, chunk);
- break;
- case NCS_AddendsTable:
- ec = processAddendsTable(base, chunk);
- break;
- case NCS_Content:
- ec = processContent(base, chunk);
- break;
- case NCS_Strings:
- ec = processStrings(base, chunk);
- break;
- default:
- return make_error_code(NativeReaderError::unknown_chunk_type);
- }
- if ( ec ) {
- return ec;
- }
- }
- // TO DO: validate enough chunks were used
-
- DEBUG_WITH_TYPE("ReaderNative", {
- llvm::dbgs() << " ReaderNative DefinedAtoms:\n";
- for (const DefinedAtom *a : defined()) {
- llvm::dbgs() << llvm::format(" 0x%09lX", a)
- << ", name=" << a->name()
- << ", size=" << a->size() << "\n";
- for (const Reference *r : *a) {
- llvm::dbgs() << " offset="
- << llvm::format("0x%03X", r->offsetInAtom())
- << ", kind=" << r->kindValue()
- << ", target=" << r->target() << "\n";
- }
- }
- });
- return make_error_code(NativeReaderError::success);
- }
-
- virtual ~File() {
- // _mb is automatically deleted because of std::unique_ptr<>
-
- // All other ivar pointers are pointers into the MemoryBuffer, except
- // the _definedAtoms array which was allocated to contain an array
- // of Atom objects. The atoms have empty destructors, so it is ok
- // to just delete the memory.
- delete _referencesV1.arrayStart;
- delete _referencesV2.arrayStart;
- delete [] _targetsTable;
- }
-
- const AtomVector<DefinedAtom> &defined() const override {
- return _definedAtoms;
- }
- const AtomVector<UndefinedAtom> &undefined() const override {
- return _undefinedAtoms;
- }
- const AtomVector<SharedLibraryAtom> &sharedLibrary() const override {
- return _sharedLibraryAtoms;
- }
- const AtomVector<AbsoluteAtom> &absolute() const override {
- return _absoluteAtoms;
- }
-
-private:
- friend NativeDefinedAtomV1;
- friend NativeUndefinedAtomV1;
- friend NativeSharedLibraryAtomV1;
- friend NativeAbsoluteAtomV1;
- friend NativeReferenceV1;
- friend NativeReferenceV2;
- template <typename T> class AtomArray;
-
- // instantiate array of BASeT from IvarsT data in file
- template <typename BaseT, typename AtomT, typename IvarsT>
- std::error_code processAtoms(AtomVector<BaseT> &result, const uint8_t *base,
- const NativeChunk *chunk) {
- std::vector<const BaseT *> vec(chunk->elementCount);
- const size_t ivarElementSize = chunk->fileSize / chunk->elementCount;
- if (ivarElementSize != sizeof(IvarsT))
- return make_error_code(NativeReaderError::file_malformed);
- auto *ivar = reinterpret_cast<const IvarsT *>(base + chunk->fileOffset);
- for (size_t i = 0; i < chunk->elementCount; ++i)
- vec[i] = new (_alloc) AtomT(*this, ivar++);
- result = std::move(vec);
- return make_error_code(NativeReaderError::success);
- }
-
- // instantiate array of DefinedAtoms from v1 ivar data in file
- std::error_code processDefinedAtomsV1(const uint8_t *base,
- const NativeChunk *chunk) {
- return processAtoms<DefinedAtom, NativeDefinedAtomV1,
- NativeDefinedAtomIvarsV1>(this->_definedAtoms, base,
- chunk);
- }
-
- // set up pointers to attributes array
- std::error_code processAttributesV1(const uint8_t *base,
- const NativeChunk *chunk) {
- this->_attributes = base + chunk->fileOffset;
- this->_attributesMaxOffset = chunk->fileSize;
- DEBUG_WITH_TYPE("ReaderNative", llvm::dbgs()
- << " chunk AttributesV1: "
- << " count=" << chunk->elementCount
- << " chunkSize=" << chunk->fileSize
- << "\n");
- return make_error_code(NativeReaderError::success);
- }
-
- // set up pointers to attributes array
- std::error_code processAbsoluteAttributesV1(const uint8_t *base,
- const NativeChunk *chunk) {
- this->_absAttributes = base + chunk->fileOffset;
- this->_absAbsoluteMaxOffset = chunk->fileSize;
- DEBUG_WITH_TYPE("ReaderNative", llvm::dbgs()
- << " chunk AbsoluteAttributesV1: "
- << " count=" << chunk->elementCount
- << " chunkSize=" << chunk->fileSize
- << "\n");
- return make_error_code(NativeReaderError::success);
- }
-
- // instantiate array of UndefinedAtoms from v1 ivar data in file
- std::error_code processUndefinedAtomsV1(const uint8_t *base,
- const NativeChunk *chunk) {
- return processAtoms<UndefinedAtom, NativeUndefinedAtomV1,
- NativeUndefinedAtomIvarsV1>(this->_undefinedAtoms, base,
- chunk);
- }
-
-
- // instantiate array of ShareLibraryAtoms from v1 ivar data in file
- std::error_code processSharedLibraryAtomsV1(const uint8_t *base,
- const NativeChunk *chunk) {
- return processAtoms<SharedLibraryAtom, NativeSharedLibraryAtomV1,
- NativeSharedLibraryAtomIvarsV1>(
- this->_sharedLibraryAtoms, base, chunk);
- }
-
-
- // instantiate array of AbsoluteAtoms from v1 ivar data in file
- std::error_code processAbsoluteAtomsV1(const uint8_t *base,
- const NativeChunk *chunk) {
- return processAtoms<AbsoluteAtom, NativeAbsoluteAtomV1,
- NativeAbsoluteAtomIvarsV1>(this->_absoluteAtoms, base,
- chunk);
- }
-
- template <class T, class U>
- std::error_code
- processReferences(const uint8_t *base, const NativeChunk *chunk,
- uint8_t *&refsStart, uint8_t *&refsEnd) const {
- if (chunk->elementCount == 0)
- return make_error_code(NativeReaderError::success);
- size_t refsArraySize = chunk->elementCount * sizeof(T);
- refsStart = reinterpret_cast<uint8_t *>(
- operator new(refsArraySize, std::nothrow));
- if (refsStart == nullptr)
- return make_error_code(NativeReaderError::memory_error);
- const size_t ivarElementSize = chunk->fileSize / chunk->elementCount;
- if (ivarElementSize != sizeof(U))
- return make_error_code(NativeReaderError::file_malformed);
- refsEnd = refsStart + refsArraySize;
- const U* ivarData = reinterpret_cast<const U *>(base + chunk->fileOffset);
- for (uint8_t *s = refsStart; s != refsEnd; s += sizeof(T), ++ivarData) {
- T *atomAllocSpace = reinterpret_cast<T *>(s);
- new (atomAllocSpace) T(*this, ivarData);
- }
- return make_error_code(NativeReaderError::success);
- }
-
- // instantiate array of References from v1 ivar data in file
- std::error_code processReferencesV1(const uint8_t *base,
- const NativeChunk *chunk) {
- uint8_t *refsStart, *refsEnd;
- if (std::error_code ec =
- processReferences<NativeReferenceV1, NativeReferenceIvarsV1>(
- base, chunk, refsStart, refsEnd))
- return ec;
- this->_referencesV1.arrayStart = refsStart;
- this->_referencesV1.arrayEnd = refsEnd;
- this->_referencesV1.elementSize = sizeof(NativeReferenceV1);
- this->_referencesV1.elementCount = chunk->elementCount;
- DEBUG_WITH_TYPE("ReaderNative", {
- llvm::dbgs() << " chunk ReferencesV1: "
- << " count=" << chunk->elementCount
- << " chunkSize=" << chunk->fileSize << "\n";
- });
- return make_error_code(NativeReaderError::success);
- }
-
- // instantiate array of References from v2 ivar data in file
- std::error_code processReferencesV2(const uint8_t *base,
- const NativeChunk *chunk) {
- uint8_t *refsStart, *refsEnd;
- if (std::error_code ec =
- processReferences<NativeReferenceV2, NativeReferenceIvarsV2>(
- base, chunk, refsStart, refsEnd))
- return ec;
- this->_referencesV2.arrayStart = refsStart;
- this->_referencesV2.arrayEnd = refsEnd;
- this->_referencesV2.elementSize = sizeof(NativeReferenceV2);
- this->_referencesV2.elementCount = chunk->elementCount;
- DEBUG_WITH_TYPE("ReaderNative", {
- llvm::dbgs() << " chunk ReferencesV2: "
- << " count=" << chunk->elementCount
- << " chunkSize=" << chunk->fileSize << "\n";
- });
- return make_error_code(NativeReaderError::success);
- }
-
- // set up pointers to target table
- std::error_code processTargetsTable(const uint8_t *base,
- const NativeChunk *chunk) {
- const uint32_t* targetIndexes = reinterpret_cast<const uint32_t*>
- (base + chunk->fileOffset);
- this->_targetsTableCount = chunk->elementCount;
- this->_targetsTable = new const Atom*[chunk->elementCount];
- for (uint32_t i=0; i < chunk->elementCount; ++i) {
- const uint32_t index = targetIndexes[i];
- if (index < _definedAtoms.size()) {
- this->_targetsTable[i] = _definedAtoms[index];
- continue;
- }
- const uint32_t undefIndex = index - _definedAtoms.size();
- if (undefIndex < _undefinedAtoms.size()) {
- this->_targetsTable[i] = _undefinedAtoms[index];
- continue;
- }
- const uint32_t slIndex = undefIndex - _undefinedAtoms.size();
- if (slIndex < _sharedLibraryAtoms.size()) {
- this->_targetsTable[i] = _sharedLibraryAtoms[slIndex];
- continue;
- }
- const uint32_t abIndex = slIndex - _sharedLibraryAtoms.size();
- if (abIndex < _absoluteAtoms.size()) {
- this->_targetsTable[i] = _absoluteAtoms[abIndex];
- continue;
- }
- return make_error_code(NativeReaderError::file_malformed);
- }
- DEBUG_WITH_TYPE("ReaderNative", llvm::dbgs()
- << " chunk Targets Table: "
- << " count=" << chunk->elementCount
- << " chunkSize=" << chunk->fileSize
- << "\n");
- return make_error_code(NativeReaderError::success);
- }
-
-
- // set up pointers to addend pool in file
- std::error_code processAddendsTable(const uint8_t *base,
- const NativeChunk *chunk) {
- this->_addends = reinterpret_cast<const Reference::Addend*>
- (base + chunk->fileOffset);
- this->_addendsMaxIndex = chunk->elementCount;
- DEBUG_WITH_TYPE("ReaderNative", llvm::dbgs()
- << " chunk Addends: "
- << " count=" << chunk->elementCount
- << " chunkSize=" << chunk->fileSize
- << "\n");
- return make_error_code(NativeReaderError::success);
- }
-
- // set up pointers to string pool in file
- std::error_code processStrings(const uint8_t *base,
- const NativeChunk *chunk) {
- this->_strings = reinterpret_cast<const char*>(base + chunk->fileOffset);
- this->_stringsMaxOffset = chunk->fileSize;
- DEBUG_WITH_TYPE("ReaderNative", llvm::dbgs()
- << " chunk Strings: "
- << " chunkSize=" << chunk->fileSize
- << "\n");
- return make_error_code(NativeReaderError::success);
- }
-
- // set up pointers to content area in file
- std::error_code processContent(const uint8_t *base,
- const NativeChunk *chunk) {
- this->_contentStart = base + chunk->fileOffset;
- this->_contentEnd = base + chunk->fileOffset + chunk->fileSize;
- DEBUG_WITH_TYPE("ReaderNative", llvm::dbgs()
- << " chunk content: "
- << " chunkSize=" << chunk->fileSize
- << "\n");
- return make_error_code(NativeReaderError::success);
- }
-
- StringRef string(uint32_t offset) const {
- assert(offset < _stringsMaxOffset);
- return StringRef(&_strings[offset]);
- }
-
- Reference::Addend addend(uint32_t index) const {
- if ( index == 0 )
- return 0; // addend index zero is used to mean "no addend"
- assert(index <= _addendsMaxIndex);
- return _addends[index-1]; // one-based indexing
- }
-
- const NativeAtomAttributesV1& attribute(uint32_t off) const {
- assert(off < _attributesMaxOffset);
- return *reinterpret_cast<const NativeAtomAttributesV1*>(_attributes + off);
- }
-
- const NativeAtomAttributesV1& absAttribute(uint32_t off) const {
- assert(off < _absAbsoluteMaxOffset);
- return *reinterpret_cast<const NativeAtomAttributesV1*>(_absAttributes + off);
- }
-
- const uint8_t* content(uint32_t offset, uint32_t size) const {
- const uint8_t* result = _contentStart + offset;
- assert((result+size) <= _contentEnd);
- return result;
- }
-
- const Reference* referenceByIndex(uintptr_t index) const {
- if (index < _referencesV1.elementCount) {
- return reinterpret_cast<const NativeReferenceV1*>(
- _referencesV1.arrayStart + index * _referencesV1.elementSize);
- }
- assert(index < _referencesV2.elementCount);
- return reinterpret_cast<const NativeReferenceV2*>(
- _referencesV2.arrayStart + index * _referencesV2.elementSize);
- }
-
- const Atom* targetV1(uint16_t index) const {
- if ( index == NativeReferenceIvarsV1::noTarget )
- return nullptr;
- assert(index < _targetsTableCount);
- return _targetsTable[index];
- }
-
- void setTargetV1(uint16_t index, const Atom* newAtom) const {
- assert(index != NativeReferenceIvarsV1::noTarget);
- assert(index > _targetsTableCount);
- _targetsTable[index] = newAtom;
- }
-
- const Atom* targetV2(uint32_t index) const {
- if (index == NativeReferenceIvarsV2::noTarget)
- return nullptr;
- assert(index < _targetsTableCount);
- return _targetsTable[index];
- }
-
- void setTargetV2(uint32_t index, const Atom* newAtom) const {
- assert(index != NativeReferenceIvarsV2::noTarget);
- assert(index > _targetsTableCount);
- _targetsTable[index] = newAtom;
- }
-
- struct IvarArray {
- IvarArray() :
- arrayStart(nullptr),
- arrayEnd(nullptr),
- elementSize(0),
- elementCount(0) { }
-
- const uint8_t* arrayStart;
- const uint8_t* arrayEnd;
- uint32_t elementSize;
- uint32_t elementCount;
- };
-
- std::unique_ptr<MemoryBuffer> _mb;
- const NativeFileHeader* _header;
- AtomVector<DefinedAtom> _definedAtoms;
- AtomVector<UndefinedAtom> _undefinedAtoms;
- AtomVector<SharedLibraryAtom> _sharedLibraryAtoms;
- AtomVector<AbsoluteAtom> _absoluteAtoms;
- const uint8_t* _absAttributes;
- uint32_t _absAbsoluteMaxOffset;
- const uint8_t* _attributes;
- uint32_t _attributesMaxOffset;
- IvarArray _referencesV1;
- IvarArray _referencesV2;
- const Atom** _targetsTable;
- uint32_t _targetsTableCount;
- const char* _strings;
- uint32_t _stringsMaxOffset;
- const Reference::Addend* _addends;
- uint32_t _addendsMaxIndex;
- const uint8_t *_contentStart;
- const uint8_t *_contentEnd;
- llvm::BumpPtrAllocator _alloc;
-};
-
-inline const lld::File &NativeDefinedAtomV1::file() const {
- return *_file;
-}
-
-inline uint64_t NativeDefinedAtomV1::ordinal() const {
- const uint8_t* p = reinterpret_cast<const uint8_t*>(_ivarData);
- auto *start = reinterpret_cast<const NativeDefinedAtomV1 *>(
- _file->_definedAtoms[0]);
- const uint8_t *startp = reinterpret_cast<const uint8_t *>(start->_ivarData);
- return p - startp;
-}
-
-inline StringRef NativeDefinedAtomV1::name() const {
- return _file->string(_ivarData->nameOffset);
-}
-
-inline const NativeAtomAttributesV1& NativeDefinedAtomV1::attributes() const {
- return _file->attribute(_ivarData->attributesOffset);
-}
-
-inline ArrayRef<uint8_t> NativeDefinedAtomV1::rawContent() const {
- if (!occupiesDiskSpace())
- return ArrayRef<uint8_t>();
- const uint8_t* p = _file->content(_ivarData->contentOffset,
- _ivarData->contentSize);
- return ArrayRef<uint8_t>(p, _ivarData->contentSize);
-}
-
-inline StringRef NativeDefinedAtomV1::customSectionName() const {
- uint32_t offset = attributes().sectionNameOffset;
- return _file->string(offset);
-}
-
-DefinedAtom::reference_iterator NativeDefinedAtomV1::begin() const {
- uintptr_t index = _ivarData->referencesStartIndex;
- const void* it = reinterpret_cast<const void*>(index);
- return reference_iterator(*this, it);
-}
-
-DefinedAtom::reference_iterator NativeDefinedAtomV1::end() const {
- uintptr_t index = _ivarData->referencesStartIndex+_ivarData->referencesCount;
- const void* it = reinterpret_cast<const void*>(index);
- return reference_iterator(*this, it);
-}
-
-const Reference* NativeDefinedAtomV1::derefIterator(const void* it) const {
- uintptr_t index = reinterpret_cast<uintptr_t>(it);
- return _file->referenceByIndex(index);
-}
-
-void NativeDefinedAtomV1::incrementIterator(const void*& it) const {
- uintptr_t index = reinterpret_cast<uintptr_t>(it);
- ++index;
- it = reinterpret_cast<const void*>(index);
-}
-
-inline const lld::File& NativeUndefinedAtomV1::file() const {
- return *_file;
-}
-
-inline StringRef NativeUndefinedAtomV1::name() const {
- return _file->string(_ivarData->nameOffset);
-}
-
-inline const UndefinedAtom *NativeUndefinedAtomV1::fallback() const {
- if (!_ivarData->fallbackNameOffset)
- return nullptr;
- if (!_fallback)
- _fallback.reset(new SimpleUndefinedAtom(
- *_file, _file->string(_ivarData->fallbackNameOffset)));
- return _fallback.get();
-}
-
-inline const lld::File& NativeSharedLibraryAtomV1::file() const {
- return *_file;
-}
-
-inline StringRef NativeSharedLibraryAtomV1::name() const {
- return _file->string(_ivarData->nameOffset);
-}
-
-inline StringRef NativeSharedLibraryAtomV1::loadName() const {
- return _file->string(_ivarData->loadNameOffset);
-}
-
-
-
-inline const lld::File& NativeAbsoluteAtomV1::file() const {
- return *_file;
-}
-
-inline StringRef NativeAbsoluteAtomV1::name() const {
- return _file->string(_ivarData->nameOffset);
-}
-
-inline const NativeAtomAttributesV1& NativeAbsoluteAtomV1::absAttributes() const {
- return _file->absAttribute(_ivarData->attributesOffset);
-}
-
-inline const Atom* NativeReferenceV1::target() const {
- return _file->targetV1(_ivarData->targetIndex);
-}
-
-inline Reference::Addend NativeReferenceV1::addend() const {
- return _file->addend(_ivarData->addendIndex);
-}
-
-inline void NativeReferenceV1::setTarget(const Atom* newAtom) {
- return _file->setTargetV1(_ivarData->targetIndex, newAtom);
-}
-
-inline void NativeReferenceV1::setAddend(Addend a) {
- // Do nothing if addend value is not being changed.
- if (addend() == a)
- return;
- llvm_unreachable("setAddend() not supported");
-}
-
-inline const Atom* NativeReferenceV2::target() const {
- return _file->targetV2(_ivarData->targetIndex);
-}
-
-inline Reference::Addend NativeReferenceV2::addend() const {
- return _ivarData->addend;
-}
-
-inline void NativeReferenceV2::setTarget(const Atom* newAtom) {
- return _file->setTargetV2(_ivarData->targetIndex, newAtom);
-}
-
-inline void NativeReferenceV2::setAddend(Addend a) {
- // Do nothing if addend value is not being changed.
- if (addend() == a)
- return;
- llvm_unreachable("setAddend() not supported");
-}
-
-uint32_t NativeReferenceV2::tag() const { return _ivarData->tag; }
-
-} // end namespace native
-
-namespace {
-
-class NativeReader : public Reader {
-public:
- bool canParse(file_magic magic, const MemoryBuffer &mb) const override {
- const NativeFileHeader *const header =
- reinterpret_cast<const NativeFileHeader *>(mb.getBufferStart());
- return (memcmp(header->magic, NATIVE_FILE_HEADER_MAGIC,
- sizeof(header->magic)) == 0);
- }
-
- virtual std::error_code
- loadFile(std::unique_ptr<MemoryBuffer> mb, const class Registry &,
- std::vector<std::unique_ptr<File>> &result) const override {
- auto *file = new lld::native::File(std::move(mb));
- result.push_back(std::unique_ptr<File>(file));
- return std::error_code();
- }
-};
-
-}
-
-void Registry::addSupportNativeObjects() {
- add(std::unique_ptr<Reader>(new NativeReader()));
-}
-
-} // end namespace lld
diff --git a/lib/ReaderWriter/Native/WriterNative.cpp b/lib/ReaderWriter/Native/WriterNative.cpp
deleted file mode 100644
index dbaeea2f2..000000000
--- a/lib/ReaderWriter/Native/WriterNative.cpp
+++ /dev/null
@@ -1,566 +0,0 @@
-//===- lib/ReaderWriter/Native/WriterNative.cpp ---------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "NativeFileFormat.h"
-#include "lld/Core/File.h"
-#include "lld/Core/LinkingContext.h"
-#include "lld/Core/Writer.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/raw_ostream.h"
-#include <cstdint>
-#include <set>
-#include <system_error>
-#include <vector>
-
-namespace lld {
-namespace native {
-
-///
-/// Class for writing native object files.
-///
-class Writer : public lld::Writer {
-public:
- std::error_code writeFile(const lld::File &file, StringRef outPath) override {
- // reserve first byte for unnamed atoms
- _stringPool.push_back('\0');
- // visit all atoms
- for ( const DefinedAtom *defAtom : file.defined() ) {
- this->addIVarsForDefinedAtom(*defAtom);
- // We are trying to process all atoms, but the defined() iterator does not
- // return group children. So, when a group parent is found, we need to
- // handle each child atom.
- if (defAtom->isGroupParent()) {
- for (const Reference *r : *defAtom) {
- if (r->kindNamespace() != lld::Reference::KindNamespace::all)
- continue;
- if (r->kindValue() == lld::Reference::kindGroupChild) {
- const DefinedAtom *target = dyn_cast<DefinedAtom>(r->target());
- assert(target && "Internal Error: kindGroupChild references need "
- "to be associated with Defined Atoms only");
- this->addIVarsForDefinedAtom(*target);
- }
- }
- }
- }
- for ( const UndefinedAtom *undefAtom : file.undefined() ) {
- this->addIVarsForUndefinedAtom(*undefAtom);
- }
- for ( const SharedLibraryAtom *shlibAtom : file.sharedLibrary() ) {
- this->addIVarsForSharedLibraryAtom(*shlibAtom);
- }
- for ( const AbsoluteAtom *absAtom : file.absolute() ) {
- this->addIVarsForAbsoluteAtom(*absAtom);
- }
-
- maybeConvertReferencesToV1();
-
- // construct file header based on atom information accumulated
- this->makeHeader();
-
- std::error_code ec;
- llvm::raw_fd_ostream out(outPath, ec, llvm::sys::fs::F_None);
- if (ec)
- return ec;
-
- this->write(out);
-
- return std::error_code();
- }
-
- virtual ~Writer() {
- }
-
-private:
-
- // write the lld::File in native format to the specified stream
- void write(raw_ostream &out) {
- assert(out.tell() == 0);
- out.write((char*)_headerBuffer, _headerBufferSize);
-
- writeChunk(out, _definedAtomIvars, NCS_DefinedAtomsV1);
- writeChunk(out, _attributes, NCS_AttributesArrayV1);
- writeChunk(out, _undefinedAtomIvars, NCS_UndefinedAtomsV1);
- writeChunk(out, _sharedLibraryAtomIvars, NCS_SharedLibraryAtomsV1);
- writeChunk(out, _absoluteAtomIvars, NCS_AbsoluteAtomsV1);
- writeChunk(out, _absAttributes, NCS_AbsoluteAttributesV1);
- writeChunk(out, _stringPool, NCS_Strings);
- writeChunk(out, _referencesV1, NCS_ReferencesArrayV1);
- writeChunk(out, _referencesV2, NCS_ReferencesArrayV2);
-
- if (!_targetsTableIndex.empty()) {
- assert(out.tell() == findChunk(NCS_TargetsTable).fileOffset);
- writeTargetTable(out);
- }
-
- if (!_addendsTableIndex.empty()) {
- assert(out.tell() == findChunk(NCS_AddendsTable).fileOffset);
- writeAddendTable(out);
- }
-
- writeChunk(out, _contentPool, NCS_Content);
- }
-
- template<class T>
- void writeChunk(raw_ostream &out, std::vector<T> &vector, uint32_t signature) {
- if (vector.empty())
- return;
- assert(out.tell() == findChunk(signature).fileOffset);
- out.write((char*)&vector[0], vector.size() * sizeof(T));
- }
-
- void addIVarsForDefinedAtom(const DefinedAtom& atom) {
- _definedAtomIndex[&atom] = _definedAtomIvars.size();
- NativeDefinedAtomIvarsV1 ivar;
- unsigned refsCount;
- ivar.nameOffset = getNameOffset(atom);
- ivar.attributesOffset = getAttributeOffset(atom);
- ivar.referencesStartIndex = getReferencesIndex(atom, refsCount);
- ivar.referencesCount = refsCount;
- ivar.contentOffset = getContentOffset(atom);
- ivar.contentSize = atom.size();
- ivar.sectionSize = atom.sectionSize();
- _definedAtomIvars.push_back(ivar);
- }
-
- void addIVarsForUndefinedAtom(const UndefinedAtom& atom) {
- _undefinedAtomIndex[&atom] = _undefinedAtomIvars.size();
- NativeUndefinedAtomIvarsV1 ivar;
- ivar.nameOffset = getNameOffset(atom);
- ivar.flags = (atom.canBeNull() & 0x03);
- ivar.fallbackNameOffset = 0;
- if (atom.fallback())
- ivar.fallbackNameOffset = getNameOffset(*atom.fallback());
- _undefinedAtomIvars.push_back(ivar);
- }
-
- void addIVarsForSharedLibraryAtom(const SharedLibraryAtom& atom) {
- _sharedLibraryAtomIndex[&atom] = _sharedLibraryAtomIvars.size();
- NativeSharedLibraryAtomIvarsV1 ivar;
- ivar.size = atom.size();
- ivar.nameOffset = getNameOffset(atom);
- ivar.loadNameOffset = getSharedLibraryNameOffset(atom.loadName());
- ivar.type = (uint32_t)atom.type();
- ivar.flags = atom.canBeNullAtRuntime();
- _sharedLibraryAtomIvars.push_back(ivar);
- }
-
- void addIVarsForAbsoluteAtom(const AbsoluteAtom& atom) {
- _absoluteAtomIndex[&atom] = _absoluteAtomIvars.size();
- NativeAbsoluteAtomIvarsV1 ivar;
- ivar.nameOffset = getNameOffset(atom);
- ivar.attributesOffset = getAttributeOffset(atom);
- ivar.reserved = 0;
- ivar.value = atom.value();
- _absoluteAtomIvars.push_back(ivar);
- }
-
- void convertReferencesToV1() {
- for (const NativeReferenceIvarsV2 &v2 : _referencesV2) {
- NativeReferenceIvarsV1 v1;
- v1.offsetInAtom = v2.offsetInAtom;
- v1.kindNamespace = v2.kindNamespace;
- v1.kindArch = v2.kindArch;
- v1.kindValue = v2.kindValue;
- v1.targetIndex = (v2.targetIndex == NativeReferenceIvarsV2::noTarget) ?
- (uint16_t)NativeReferenceIvarsV1::noTarget : v2.targetIndex;
- v1.addendIndex = this->getAddendIndex(v2.addend);
- _referencesV1.push_back(v1);
- }
- _referencesV2.clear();
- }
-
- bool canConvertReferenceToV1(const NativeReferenceIvarsV2 &ref) {
- bool validOffset = (ref.offsetInAtom == NativeReferenceIvarsV2::noTarget) ||
- ref.offsetInAtom < NativeReferenceIvarsV1::noTarget;
- return validOffset && ref.targetIndex < UINT16_MAX;
- }
-
- // Convert vector of NativeReferenceIvarsV2 to NativeReferenceIvarsV1 if
- // possible.
- void maybeConvertReferencesToV1() {
- std::set<int64_t> addends;
- for (const NativeReferenceIvarsV2 &ref : _referencesV2) {
- if (!canConvertReferenceToV1(ref))
- return;
- addends.insert(ref.addend);
- if (addends.size() >= UINT16_MAX)
- return;
- }
- convertReferencesToV1();
- }
-
- // fill out native file header and chunk directory
- void makeHeader() {
- const bool hasDefines = !_definedAtomIvars.empty();
- const bool hasUndefines = !_undefinedAtomIvars.empty();
- const bool hasSharedLibraries = !_sharedLibraryAtomIvars.empty();
- const bool hasAbsolutes = !_absoluteAtomIvars.empty();
- const bool hasReferencesV1 = !_referencesV1.empty();
- const bool hasReferencesV2 = !_referencesV2.empty();
- const bool hasTargetsTable = !_targetsTableIndex.empty();
- const bool hasAddendTable = !_addendsTableIndex.empty();
- const bool hasContent = !_contentPool.empty();
-
- int chunkCount = 1; // always have string pool chunk
- if ( hasDefines ) chunkCount += 2;
- if ( hasUndefines ) ++chunkCount;
- if ( hasSharedLibraries ) ++chunkCount;
- if ( hasAbsolutes ) chunkCount += 2;
- if ( hasReferencesV1 ) ++chunkCount;
- if ( hasReferencesV2 ) ++chunkCount;
- if ( hasTargetsTable ) ++chunkCount;
- if ( hasAddendTable ) ++chunkCount;
- if ( hasContent ) ++chunkCount;
-
- _headerBufferSize = sizeof(NativeFileHeader)
- + chunkCount*sizeof(NativeChunk);
- _headerBuffer = reinterpret_cast<NativeFileHeader*>
- (operator new(_headerBufferSize, std::nothrow));
- NativeChunk *chunks =
- reinterpret_cast<NativeChunk*>(reinterpret_cast<char*>(_headerBuffer)
- + sizeof(NativeFileHeader));
- memcpy(_headerBuffer->magic, NATIVE_FILE_HEADER_MAGIC,
- sizeof(_headerBuffer->magic));
- _headerBuffer->endian = NFH_LittleEndian;
- _headerBuffer->architecture = 0;
- _headerBuffer->fileSize = 0;
- _headerBuffer->chunkCount = chunkCount;
-
- // create chunk for defined atom ivar array
- int nextIndex = 0;
- uint32_t nextFileOffset = _headerBufferSize;
- if (hasDefines) {
- fillChunkHeader(chunks[nextIndex++], nextFileOffset, _definedAtomIvars,
- NCS_DefinedAtomsV1);
-
- // create chunk for attributes
- fillChunkHeader(chunks[nextIndex++], nextFileOffset, _attributes,
- NCS_AttributesArrayV1);
- }
-
- // create chunk for undefined atom array
- if (hasUndefines)
- fillChunkHeader(chunks[nextIndex++], nextFileOffset, _undefinedAtomIvars,
- NCS_UndefinedAtomsV1);
-
- // create chunk for shared library atom array
- if (hasSharedLibraries)
- fillChunkHeader(chunks[nextIndex++], nextFileOffset,
- _sharedLibraryAtomIvars, NCS_SharedLibraryAtomsV1);
-
- // create chunk for shared library atom array
- if (hasAbsolutes) {
- fillChunkHeader(chunks[nextIndex++], nextFileOffset, _absoluteAtomIvars,
- NCS_AbsoluteAtomsV1);
-
- // create chunk for attributes
- fillChunkHeader(chunks[nextIndex++], nextFileOffset, _absAttributes,
- NCS_AbsoluteAttributesV1);
- }
-
- // create chunk for symbol strings
- // pad end of string pool to 4-bytes
- while ((_stringPool.size() % 4) != 0)
- _stringPool.push_back('\0');
- fillChunkHeader(chunks[nextIndex++], nextFileOffset, _stringPool,
- NCS_Strings);
-
- // create chunk for referencesV2
- if (hasReferencesV1)
- fillChunkHeader(chunks[nextIndex++], nextFileOffset, _referencesV1,
- NCS_ReferencesArrayV1);
-
- // create chunk for referencesV2
- if (hasReferencesV2)
- fillChunkHeader(chunks[nextIndex++], nextFileOffset, _referencesV2,
- NCS_ReferencesArrayV2);
-
- // create chunk for target table
- if (hasTargetsTable) {
- NativeChunk& cht = chunks[nextIndex++];
- cht.signature = NCS_TargetsTable;
- cht.fileOffset = nextFileOffset;
- cht.fileSize = _targetsTableIndex.size() * sizeof(uint32_t);
- cht.elementCount = _targetsTableIndex.size();
- nextFileOffset = cht.fileOffset + cht.fileSize;
- }
-
- // create chunk for addend table
- if (hasAddendTable) {
- NativeChunk& chad = chunks[nextIndex++];
- chad.signature = NCS_AddendsTable;
- chad.fileOffset = nextFileOffset;
- chad.fileSize = _addendsTableIndex.size() * sizeof(Reference::Addend);
- chad.elementCount = _addendsTableIndex.size();
- nextFileOffset = chad.fileOffset + chad.fileSize;
- }
-
- // create chunk for content
- if (hasContent)
- fillChunkHeader(chunks[nextIndex++], nextFileOffset, _contentPool,
- NCS_Content);
-
- _headerBuffer->fileSize = nextFileOffset;
- }
-
- template<class T>
- void fillChunkHeader(NativeChunk &chunk, uint32_t &nextFileOffset,
- const std::vector<T> &data, uint32_t signature) {
- chunk.signature = signature;
- chunk.fileOffset = nextFileOffset;
- chunk.fileSize = data.size() * sizeof(T);
- chunk.elementCount = data.size();
- nextFileOffset = chunk.fileOffset + chunk.fileSize;
- }
-
- // scan header to find particular chunk
- NativeChunk& findChunk(uint32_t signature) {
- const uint32_t chunkCount = _headerBuffer->chunkCount;
- NativeChunk* chunks =
- reinterpret_cast<NativeChunk*>(reinterpret_cast<char*>(_headerBuffer)
- + sizeof(NativeFileHeader));
- for (uint32_t i=0; i < chunkCount; ++i) {
- if ( chunks[i].signature == signature )
- return chunks[i];
- }
- llvm_unreachable("findChunk() signature not found");
- }
-
- // append atom name to string pool and return offset
- uint32_t getNameOffset(const Atom& atom) {
- return this->getNameOffset(atom.name());
- }
-
- // check if name is already in pool or append and return offset
- uint32_t getSharedLibraryNameOffset(StringRef name) {
- assert(!name.empty());
- // look to see if this library name was used by another atom
- for (auto &it : _sharedLibraryNames)
- if (name.equals(it.first))
- return it.second;
- // first use of this library name
- uint32_t result = this->getNameOffset(name);
- _sharedLibraryNames.push_back(std::make_pair(name, result));
- return result;
- }
-
- // append atom name to string pool and return offset
- uint32_t getNameOffset(StringRef name) {
- if ( name.empty() )
- return 0;
- uint32_t result = _stringPool.size();
- _stringPool.insert(_stringPool.end(), name.begin(), name.end());
- _stringPool.push_back(0);
- return result;
- }
-
- // append atom cotent to content pool and return offset
- uint32_t getContentOffset(const DefinedAtom& atom) {
- if (!atom.occupiesDiskSpace())
- return 0;
- uint32_t result = _contentPool.size();
- ArrayRef<uint8_t> cont = atom.rawContent();
- _contentPool.insert(_contentPool.end(), cont.begin(), cont.end());
- return result;
- }
-
- // reuse existing attributes entry or create a new one and return offet
- uint32_t getAttributeOffset(const DefinedAtom& atom) {
- NativeAtomAttributesV1 attrs = computeAttributesV1(atom);
- return getOrPushAttribute(_attributes, attrs);
- }
-
- uint32_t getAttributeOffset(const AbsoluteAtom& atom) {
- NativeAtomAttributesV1 attrs = computeAbsoluteAttributes(atom);
- return getOrPushAttribute(_absAttributes, attrs);
- }
-
- uint32_t getOrPushAttribute(std::vector<NativeAtomAttributesV1> &dest,
- const NativeAtomAttributesV1 &attrs) {
- for (size_t i = 0, e = dest.size(); i < e; ++i) {
- if (!memcmp(&dest[i], &attrs, sizeof(attrs))) {
- // found that this set of attributes already used, so re-use
- return i * sizeof(attrs);
- }
- }
- // append new attribute set to end
- uint32_t result = dest.size() * sizeof(attrs);
- dest.push_back(attrs);
- return result;
- }
-
- uint32_t sectionNameOffset(const DefinedAtom& atom) {
- // if section based on content, then no custom section name available
- if (atom.sectionChoice() == DefinedAtom::sectionBasedOnContent)
- return 0;
- StringRef name = atom.customSectionName();
- assert(!name.empty());
- // look to see if this section name was used by another atom
- for (auto &it : _sectionNames)
- if (name.equals(it.first))
- return it.second;
- // first use of this section name
- uint32_t result = this->getNameOffset(name);
- _sectionNames.push_back(std::make_pair(name, result));
- return result;
- }
-
- NativeAtomAttributesV1 computeAttributesV1(const DefinedAtom& atom) {
- NativeAtomAttributesV1 attrs;
- attrs.sectionNameOffset = sectionNameOffset(atom);
- attrs.align = atom.alignment().value;
- attrs.alignModulus = atom.alignment().modulus;
- attrs.scope = atom.scope();
- attrs.interposable = atom.interposable();
- attrs.merge = atom.merge();
- attrs.contentType = atom.contentType();
- attrs.sectionChoice = atom.sectionChoice();
- attrs.deadStrip = atom.deadStrip();
- attrs.dynamicExport = atom.dynamicExport();
- attrs.codeModel = atom.codeModel();
- attrs.permissions = atom.permissions();
- return attrs;
- }
-
- NativeAtomAttributesV1 computeAbsoluteAttributes(const AbsoluteAtom& atom) {
- NativeAtomAttributesV1 attrs;
- attrs.scope = atom.scope();
- return attrs;
- }
-
- // add references for this atom in a contiguous block in NCS_ReferencesArrayV2
- uint32_t getReferencesIndex(const DefinedAtom& atom, unsigned& refsCount) {
- size_t startRefSize = _referencesV2.size();
- uint32_t result = startRefSize;
- for (const Reference *ref : atom) {
- NativeReferenceIvarsV2 nref;
- nref.offsetInAtom = ref->offsetInAtom();
- nref.kindNamespace = (uint8_t)ref->kindNamespace();
- nref.kindArch = (uint8_t)ref->kindArch();
- nref.kindValue = ref->kindValue();
- nref.targetIndex = this->getTargetIndex(ref->target());
- nref.addend = ref->addend();
- nref.tag = ref->tag();
- _referencesV2.push_back(nref);
- }
- refsCount = _referencesV2.size() - startRefSize;
- return (refsCount == 0) ? 0 : result;
- }
-
- uint32_t getTargetIndex(const Atom* target) {
- if ( target == nullptr )
- return NativeReferenceIvarsV2::noTarget;
- TargetToIndex::const_iterator pos = _targetsTableIndex.find(target);
- if ( pos != _targetsTableIndex.end() ) {
- return pos->second;
- }
- uint32_t result = _targetsTableIndex.size();
- _targetsTableIndex[target] = result;
- return result;
- }
-
- void writeTargetTable(raw_ostream &out) {
- // Build table of target indexes
- uint32_t maxTargetIndex = _targetsTableIndex.size();
- assert(maxTargetIndex > 0);
- std::vector<uint32_t> targetIndexes(maxTargetIndex);
- for (auto &it : _targetsTableIndex) {
- const Atom* atom = it.first;
- uint32_t targetIndex = it.second;
- assert(targetIndex < maxTargetIndex);
-
- TargetToIndex::iterator pos = _definedAtomIndex.find(atom);
- if (pos != _definedAtomIndex.end()) {
- targetIndexes[targetIndex] = pos->second;
- continue;
- }
- uint32_t base = _definedAtomIvars.size();
-
- pos = _undefinedAtomIndex.find(atom);
- if (pos != _undefinedAtomIndex.end()) {
- targetIndexes[targetIndex] = pos->second + base;
- continue;
- }
- base += _undefinedAtomIndex.size();
-
- pos = _sharedLibraryAtomIndex.find(atom);
- if (pos != _sharedLibraryAtomIndex.end()) {
- targetIndexes[targetIndex] = pos->second + base;
- continue;
- }
- base += _sharedLibraryAtomIndex.size();
-
- pos = _absoluteAtomIndex.find(atom);
- assert(pos != _absoluteAtomIndex.end());
- targetIndexes[targetIndex] = pos->second + base;
- }
- // write table
- out.write((char*)&targetIndexes[0], maxTargetIndex * sizeof(uint32_t));
- }
-
- uint32_t getAddendIndex(Reference::Addend addend) {
- if ( addend == 0 )
- return 0; // addend index zero is used to mean "no addend"
- AddendToIndex::const_iterator pos = _addendsTableIndex.find(addend);
- if ( pos != _addendsTableIndex.end() ) {
- return pos->second;
- }
- uint32_t result = _addendsTableIndex.size() + 1; // one-based index
- _addendsTableIndex[addend] = result;
- return result;
- }
-
- void writeAddendTable(raw_ostream &out) {
- // Build table of addends
- uint32_t maxAddendIndex = _addendsTableIndex.size();
- std::vector<Reference::Addend> addends(maxAddendIndex);
- for (auto &it : _addendsTableIndex) {
- Reference::Addend addend = it.first;
- uint32_t index = it.second;
- assert(index <= maxAddendIndex);
- addends[index-1] = addend;
- }
- // write table
- out.write((char*)&addends[0], maxAddendIndex*sizeof(Reference::Addend));
- }
-
- typedef std::vector<std::pair<StringRef, uint32_t>> NameToOffsetVector;
-
- typedef llvm::DenseMap<const Atom*, uint32_t> TargetToIndex;
- typedef llvm::DenseMap<Reference::Addend, uint32_t> AddendToIndex;
-
- NativeFileHeader* _headerBuffer;
- size_t _headerBufferSize;
- std::vector<char> _stringPool;
- std::vector<uint8_t> _contentPool;
- std::vector<NativeDefinedAtomIvarsV1> _definedAtomIvars;
- std::vector<NativeAtomAttributesV1> _attributes;
- std::vector<NativeAtomAttributesV1> _absAttributes;
- std::vector<NativeUndefinedAtomIvarsV1> _undefinedAtomIvars;
- std::vector<NativeSharedLibraryAtomIvarsV1> _sharedLibraryAtomIvars;
- std::vector<NativeAbsoluteAtomIvarsV1> _absoluteAtomIvars;
- std::vector<NativeReferenceIvarsV1> _referencesV1;
- std::vector<NativeReferenceIvarsV2> _referencesV2;
- TargetToIndex _targetsTableIndex;
- TargetToIndex _definedAtomIndex;
- TargetToIndex _undefinedAtomIndex;
- TargetToIndex _sharedLibraryAtomIndex;
- TargetToIndex _absoluteAtomIndex;
- AddendToIndex _addendsTableIndex;
- NameToOffsetVector _sectionNames;
- NameToOffsetVector _sharedLibraryNames;
-};
-} // end namespace native
-
-std::unique_ptr<Writer> createWriterNative() {
- return std::unique_ptr<Writer>(new native::Writer());
-}
-} // end namespace lld
diff --git a/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp b/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
index da822dc36..f7c9c7e8e 100644
--- a/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
+++ b/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
@@ -312,11 +312,10 @@ std::error_code FileCOFF::doParse() {
if (getMachineType() != llvm::COFF::IMAGE_FILE_MACHINE_UNKNOWN &&
getMachineType() != _ctx.getMachineType()) {
- llvm::errs() << "module machine type '"
- << getMachineName(getMachineType())
- << "' conflicts with target machine type '"
- << getMachineName(_ctx.getMachineType()) << "'\n";
- return NativeReaderError::conflicting_target_machine;
+ return make_dynamic_error_code(Twine("module machine type '") +
+ getMachineName(getMachineType()) +
+ "' conflicts with target machine type '" +
+ getMachineName(_ctx.getMachineType()) + "'");
}
if (std::error_code ec = getReferenceArch(_referenceArch))
diff --git a/lib/ReaderWriter/PECOFF/ReaderImportHeader.cpp b/lib/ReaderWriter/PECOFF/ReaderImportHeader.cpp
index e88ed057e..7ae3096ac 100644
--- a/lib/ReaderWriter/PECOFF/ReaderImportHeader.cpp
+++ b/lib/ReaderWriter/PECOFF/ReaderImportHeader.cpp
@@ -257,7 +257,7 @@ public:
// Check if the total size is valid.
if (std::size_t(end - buf) != sizeof(COFF::ImportHeader) + dataSize)
- return make_error_code(NativeReaderError::unknown_file_format);
+ return make_dynamic_error_code(StringRef("Broken import library"));
uint16_t hint = read16le(buf + offsetof(COFF::ImportHeader, OrdinalHint));
StringRef symbolName(buf + sizeof(COFF::ImportHeader));