summaryrefslogtreecommitdiff
path: root/lld/lib/Core/NativeReader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/lib/Core/NativeReader.cpp')
-rw-r--r--lld/lib/Core/NativeReader.cpp839
1 files changed, 0 insertions, 839 deletions
diff --git a/lld/lib/Core/NativeReader.cpp b/lld/lib/Core/NativeReader.cpp
deleted file mode 100644
index 29086148ebc6..000000000000
--- a/lld/lib/Core/NativeReader.cpp
+++ /dev/null
@@ -1,839 +0,0 @@
-//===- Core/NativeReader.cpp - reads native object file ------------------===//
-//
-// 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 "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/MemoryBuffer.h"
-
-#include <vector>
-#include <memory>
-
-namespace lld {
-
-// forward reference
-class NativeFile;
-
-//
-// An object of this class is instantied for each NativeDefinedAtomIvarsV1
-// struct in the NCS_DefinedAtomsV1 chunk.
-//
-class NativeDefinedAtomV1 : public DefinedAtom {
-public:
- NativeDefinedAtomV1(const NativeFile& f,
- const NativeDefinedAtomIvarsV1* ivarData)
- : _file(&f), _ivarData(ivarData) { }
-
- virtual const class File& file() const;
-
- virtual uint64_t ordinal() const;
-
- virtual StringRef name() const;
-
- virtual uint64_t size() const {
- return _ivarData->contentSize;
- }
-
- virtual DefinedAtom::Scope scope() const {
- return (DefinedAtom::Scope)(attributes().scope);
- }
-
- virtual DefinedAtom::Interposable interposable() const {
- return (DefinedAtom::Interposable)(attributes().interposable);
- }
-
- virtual DefinedAtom::Merge merge() const {
- return (DefinedAtom::Merge)(attributes().merge);
- }
-
- virtual DefinedAtom::ContentType contentType() const {
- const NativeAtomAttributesV1& attr = attributes();
- return (DefinedAtom::ContentType)(attr.contentType);
- }
-
- virtual DefinedAtom::Alignment alignment() const {
- return DefinedAtom::Alignment(attributes().align2, attributes().alignModulus);
- }
-
- virtual DefinedAtom::SectionChoice sectionChoice() const {
- return (DefinedAtom::SectionChoice)(attributes().sectionChoice);
- }
-
- virtual StringRef customSectionName() const;
-
- virtual DefinedAtom::DeadStripKind deadStrip() const {
- return (DefinedAtom::DeadStripKind)(attributes().deadStrip);
- }
-
- virtual DefinedAtom::ContentPermissions permissions() const {
- return (DefinedAtom::ContentPermissions)(attributes().permissions);
- }
-
- virtual bool isThumb() const {
- return false; //(attributes().thumb != 0);
- }
-
- virtual bool isAlias() const {
- return (attributes().alias != 0);
- }
-
- virtual ArrayRef<uint8_t> rawContent() const;
-
- virtual reference_iterator begin() const;
-
- virtual reference_iterator end() const;
-
- virtual const Reference* derefIterator(const void*) const;
-
- virtual void incrementIterator(const void*& it) const;
-
-private:
- const NativeAtomAttributesV1& attributes() const;
-
- const NativeFile* _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 NativeFile& f,
- const NativeUndefinedAtomIvarsV1* ivarData)
- : _file(&f), _ivarData(ivarData) { }
-
- virtual const File& file() const;
- virtual StringRef name() const;
-
- virtual CanBeNull canBeNull() const {
- return (CanBeNull)(_ivarData->flags & 0x3);
- }
-
-
-private:
- const NativeFile* _file;
- const NativeUndefinedAtomIvarsV1* _ivarData;
-};
-
-
-//
-// An object of this class is instantied for each NativeUndefinedAtomIvarsV1
-// struct in the NCS_SharedLibraryAtomsV1 chunk.
-//
-class NativeSharedLibraryAtomV1 : public SharedLibraryAtom {
-public:
- NativeSharedLibraryAtomV1(const NativeFile& f,
- const NativeSharedLibraryAtomIvarsV1* ivarData)
- : _file(&f), _ivarData(ivarData) { }
-
- virtual const File& file() const;
- virtual StringRef name() const;
- virtual StringRef loadName() const;
-
- virtual bool canBeNullAtRuntime() const {
- return (_ivarData->flags & 0x1);
- }
-
-private:
- const NativeFile* _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 NativeFile& f,
- const NativeAbsoluteAtomIvarsV1* ivarData)
- : _file(&f), _ivarData(ivarData) { }
-
- virtual const File& file() const;
- virtual StringRef name() const;
-
- virtual uint64_t value() const {
- return _ivarData->value;
- }
-
-private:
- const NativeFile* _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 NativeFile& f,
- const NativeReferenceIvarsV1* ivarData)
- : _file(&f), _ivarData(ivarData) { }
-
- virtual uint64_t offsetInAtom() const {
- return _ivarData->offsetInAtom;
- }
-
- virtual Kind kind() const {
- return _ivarData->kind;
- }
-
- virtual void setKind(Kind);
- virtual const Atom* target() const;
- virtual Addend addend() const;
- virtual void setTarget(const Atom* newAtom);
- virtual void setAddend(Addend a);
-
-private:
- // Used in rare cases when Reference is modified,
- // since ivar data is mapped read-only.
- void cloneIvarData() {
- // TODO: do nothing on second call
- NativeReferenceIvarsV1* niv = reinterpret_cast<NativeReferenceIvarsV1*>
- (operator new(sizeof(NativeReferenceIvarsV1),
- std::nothrow));
- memcpy(niv, _ivarData, sizeof(NativeReferenceIvarsV1));
- }
-
- const NativeFile* _file;
- const NativeReferenceIvarsV1* _ivarData;
-};
-
-
-
-//
-// lld::File object for native llvm object file
-//
-class NativeFile : public File {
-public:
-
- /// Instantiates a File object from a native object file. Ownership
- /// of the MemoryBuffer is transfered to the resulting File object.
- static error_code make(std::unique_ptr<llvm::MemoryBuffer> mb,
- StringRef path,
- std::unique_ptr<File> &result) {
- const uint8_t* const base =
- reinterpret_cast<const uint8_t*>(mb->getBufferStart());
- 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, 16) != 0 )
- return make_error_code(native_reader_error::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(native_reader_error::file_too_short);
-
- // instantiate NativeFile object and add values to it as found
- std::unique_ptr<NativeFile> file(new NativeFile(std::move(mb), path));
-
- // process each chunk
- for(uint32_t i=0; i < header->chunkCount; ++i) {
- error_code ec;
- const NativeChunk* chunk = &chunks[i];
- // sanity check chunk is within file
- if ( chunk->fileOffset > fileSize )
- return make_error_code(native_reader_error::file_malformed);
- if ( (chunk->fileOffset + chunk->fileSize) > fileSize)
- return make_error_code(native_reader_error::file_malformed);
- // process chunk, based on signature
- switch ( chunk->signature ) {
- case NCS_DefinedAtomsV1:
- ec = file->processDefinedAtomsV1(base, chunk);
- break;
- case NCS_AttributesArrayV1:
- ec = file->processAttributesV1(base, chunk);
- break;
- case NCS_UndefinedAtomsV1:
- ec = file->processUndefinedAtomsV1(base, chunk);
- break;
- case NCS_SharedLibraryAtomsV1:
- ec = file->processSharedLibraryAtomsV1(base, chunk);
- break;
- case NCS_AbsoluteAtomsV1:
- ec = file->processAbsoluteAtomsV1(base, chunk);
- break;
- case NCS_ReferencesArrayV1:
- ec = file->processReferencesV1(base, chunk);
- break;
- case NCS_TargetsTable:
- ec = file->processTargetsTable(base, chunk);
- break;
- case NCS_AddendsTable:
- ec = file->processAddendsTable(base, chunk);
- break;
- case NCS_Content:
- ec = file->processContent(base, chunk);
- break;
- case NCS_Strings:
- ec = file->processStrings(base, chunk);
- break;
- default:
- return make_error_code(native_reader_error::unknown_chunk_type);
- }
- if ( ec ) {
- return ec;
- }
- // TO DO: validate enough chunks were used
- }
-
- result.reset(file.release());
- return make_error_code(native_reader_error::success);
- }
-
- virtual ~NativeFile() {
- // _buffer is automatically deleted because of OwningPtr<>
-
- // 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 _definedAtoms._arrayStart;
- delete _undefinedAtoms._arrayStart;
- delete _sharedLibraryAtoms._arrayStart;
- delete _absoluteAtoms._arrayStart;
- delete _references.arrayStart;
- delete _targetsTable;
- }
-
- virtual const atom_collection<DefinedAtom>& defined() const {
- return _definedAtoms;
- }
- virtual const atom_collection<UndefinedAtom>& undefined() const {
- return _undefinedAtoms;
- }
- virtual const atom_collection<SharedLibraryAtom>& sharedLibrary() const {
- return _sharedLibraryAtoms;
- }
- virtual const atom_collection<AbsoluteAtom>& absolute() const {
- return _absoluteAtoms;
- }
-
- virtual void addAtom(const Atom&) {
- assert(0 && "cannot add atoms to native .o files");
- }
-
-private:
- friend class NativeDefinedAtomV1;
- friend class NativeUndefinedAtomV1;
- friend class NativeSharedLibraryAtomV1;
- friend class NativeAbsoluteAtomV1;
- friend class NativeReferenceV1;
-
- // instantiate array of DefinedAtoms from v1 ivar data in file
- error_code processDefinedAtomsV1(const uint8_t *base,
- const NativeChunk *chunk) {
- const size_t atomSize = sizeof(NativeDefinedAtomV1);
- size_t atomsArraySize = chunk->elementCount * atomSize;
- uint8_t* atomsStart = reinterpret_cast<uint8_t*>
- (operator new(atomsArraySize, std::nothrow));
- if (atomsStart == nullptr)
- return make_error_code(native_reader_error::memory_error);
- const size_t ivarElementSize = chunk->fileSize
- / chunk->elementCount;
- if ( ivarElementSize != sizeof(NativeDefinedAtomIvarsV1) )
- return make_error_code(native_reader_error::file_malformed);
- uint8_t* atomsEnd = atomsStart + atomsArraySize;
- const NativeDefinedAtomIvarsV1* ivarData =
- reinterpret_cast<const NativeDefinedAtomIvarsV1*>
- (base + chunk->fileOffset);
- for(uint8_t* s = atomsStart; s != atomsEnd; s += atomSize) {
- NativeDefinedAtomV1* atomAllocSpace =
- reinterpret_cast<NativeDefinedAtomV1*>(s);
- new (atomAllocSpace) NativeDefinedAtomV1(*this, ivarData);
- ++ivarData;
- }
- this->_definedAtoms._arrayStart = atomsStart;
- this->_definedAtoms._arrayEnd = atomsEnd;
- this->_definedAtoms._elementSize = atomSize;
- this->_definedAtoms._elementCount = chunk->elementCount;
- return make_error_code(native_reader_error::success);
- }
-
- // set up pointers to attributes array
- error_code processAttributesV1(const uint8_t *base,
- const NativeChunk *chunk) {
- this->_attributes = base + chunk->fileOffset;
- this->_attributesMaxOffset = chunk->fileSize;
- return make_error_code(native_reader_error::success);
- }
-
- // instantiate array of UndefinedAtoms from v1 ivar data in file
- error_code processUndefinedAtomsV1(const uint8_t *base,
- const NativeChunk *chunk) {
- const size_t atomSize = sizeof(NativeUndefinedAtomV1);
- size_t atomsArraySize = chunk->elementCount * atomSize;
- uint8_t* atomsStart = reinterpret_cast<uint8_t*>
- (operator new(atomsArraySize, std::nothrow));
- if (atomsStart == nullptr)
- return make_error_code(native_reader_error::memory_error);
- const size_t ivarElementSize = chunk->fileSize
- / chunk->elementCount;
- if ( ivarElementSize != sizeof(NativeUndefinedAtomIvarsV1) )
- return make_error_code(native_reader_error::file_malformed);
- uint8_t* atomsEnd = atomsStart + atomsArraySize;
- const NativeUndefinedAtomIvarsV1* ivarData =
- reinterpret_cast<const NativeUndefinedAtomIvarsV1*>
- (base + chunk->fileOffset);
- for(uint8_t* s = atomsStart; s != atomsEnd; s += atomSize) {
- NativeUndefinedAtomV1* atomAllocSpace =
- reinterpret_cast<NativeUndefinedAtomV1*>(s);
- new (atomAllocSpace) NativeUndefinedAtomV1(*this, ivarData);
- ++ivarData;
- }
- this->_undefinedAtoms._arrayStart = atomsStart;
- this->_undefinedAtoms._arrayEnd = atomsEnd;
- this->_undefinedAtoms._elementSize = atomSize;
- this->_undefinedAtoms._elementCount = chunk->elementCount;
- return make_error_code(native_reader_error::success);
- }
-
-
- // instantiate array of ShareLibraryAtoms from v1 ivar data in file
- error_code processSharedLibraryAtomsV1(const uint8_t *base,
- const NativeChunk *chunk) {
- const size_t atomSize = sizeof(NativeSharedLibraryAtomV1);
- size_t atomsArraySize = chunk->elementCount * atomSize;
- uint8_t* atomsStart = reinterpret_cast<uint8_t*>
- (operator new(atomsArraySize, std::nothrow));
- if (atomsStart == nullptr)
- return make_error_code(native_reader_error::memory_error);
- const size_t ivarElementSize = chunk->fileSize
- / chunk->elementCount;
- if ( ivarElementSize != sizeof(NativeSharedLibraryAtomIvarsV1) )
- return make_error_code(native_reader_error::file_malformed);
- uint8_t* atomsEnd = atomsStart + atomsArraySize;
- const NativeSharedLibraryAtomIvarsV1* ivarData =
- reinterpret_cast<const NativeSharedLibraryAtomIvarsV1*>
- (base + chunk->fileOffset);
- for(uint8_t* s = atomsStart; s != atomsEnd; s += atomSize) {
- NativeSharedLibraryAtomV1* atomAllocSpace =
- reinterpret_cast<NativeSharedLibraryAtomV1*>(s);
- new (atomAllocSpace) NativeSharedLibraryAtomV1(*this, ivarData);
- ++ivarData;
- }
- this->_sharedLibraryAtoms._arrayStart = atomsStart;
- this->_sharedLibraryAtoms._arrayEnd = atomsEnd;
- this->_sharedLibraryAtoms._elementSize = atomSize;
- this->_sharedLibraryAtoms._elementCount = chunk->elementCount;
- return make_error_code(native_reader_error::success);
- }
-
-
- // instantiate array of AbsoluteAtoms from v1 ivar data in file
- error_code processAbsoluteAtomsV1(const uint8_t *base,
- const NativeChunk *chunk) {
- const size_t atomSize = sizeof(NativeAbsoluteAtomV1);
- size_t atomsArraySize = chunk->elementCount * atomSize;
- uint8_t* atomsStart = reinterpret_cast<uint8_t*>
- (operator new(atomsArraySize, std::nothrow));
- if (atomsStart == nullptr)
- return make_error_code(native_reader_error::memory_error);
- const size_t ivarElementSize = chunk->fileSize
- / chunk->elementCount;
- if ( ivarElementSize != sizeof(NativeAbsoluteAtomIvarsV1) )
- return make_error_code(native_reader_error::file_malformed);
- uint8_t* atomsEnd = atomsStart + atomsArraySize;
- const NativeAbsoluteAtomIvarsV1* ivarData =
- reinterpret_cast<const NativeAbsoluteAtomIvarsV1*>
- (base + chunk->fileOffset);
- for(uint8_t* s = atomsStart; s != atomsEnd; s += atomSize) {
- NativeAbsoluteAtomV1* atomAllocSpace =
- reinterpret_cast<NativeAbsoluteAtomV1*>(s);
- new (atomAllocSpace) NativeAbsoluteAtomV1(*this, ivarData);
- ++ivarData;
- }
- this->_absoluteAtoms._arrayStart = atomsStart;
- this->_absoluteAtoms._arrayEnd = atomsEnd;
- this->_absoluteAtoms._elementSize = atomSize;
- this->_absoluteAtoms._elementCount = chunk->elementCount;
- return make_error_code(native_reader_error::success);
- }
-
-
-
-
- // instantiate array of Referemces from v1 ivar data in file
- error_code processReferencesV1(const uint8_t *base,
- const NativeChunk *chunk) {
- if ( chunk->elementCount == 0 )
- return make_error_code(native_reader_error::success);
- const size_t refSize = sizeof(NativeReferenceV1);
- size_t refsArraySize = chunk->elementCount * refSize;
- uint8_t* refsStart = reinterpret_cast<uint8_t*>
- (operator new(refsArraySize, std::nothrow));
- if (refsStart == nullptr)
- return make_error_code(native_reader_error::memory_error);
- const size_t ivarElementSize = chunk->fileSize
- / chunk->elementCount;
- if ( ivarElementSize != sizeof(NativeReferenceIvarsV1) )
- return make_error_code(native_reader_error::file_malformed);
- uint8_t* refsEnd = refsStart + refsArraySize;
- const NativeReferenceIvarsV1* ivarData =
- reinterpret_cast<const NativeReferenceIvarsV1*>
- (base + chunk->fileOffset);
- for(uint8_t* s = refsStart; s != refsEnd; s += refSize) {
- NativeReferenceV1* atomAllocSpace =
- reinterpret_cast<NativeReferenceV1*>(s);
- new (atomAllocSpace) NativeReferenceV1(*this, ivarData);
- ++ivarData;
- }
- this->_references.arrayStart = refsStart;
- this->_references.arrayEnd = refsEnd;
- this->_references.elementSize = refSize;
- this->_references.elementCount = chunk->elementCount;
- return make_error_code(native_reader_error::success);
- }
-
- // set up pointers to target table
- 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._elementCount ) {
- const uint8_t* p = _definedAtoms._arrayStart
- + index * _definedAtoms._elementSize;
- this->_targetsTable[i] = reinterpret_cast<const DefinedAtom*>(p);
- continue;
- }
- const uint32_t undefIndex = index - _definedAtoms._elementCount;
- if ( undefIndex < _undefinedAtoms._elementCount ) {
- const uint8_t* p = _undefinedAtoms._arrayStart
- + undefIndex * _undefinedAtoms._elementSize;
- this->_targetsTable[i] = reinterpret_cast<const UndefinedAtom*>(p);
- continue;
- }
- const uint32_t slIndex = index - _definedAtoms._elementCount
- - _undefinedAtoms._elementCount;
- if ( slIndex < _sharedLibraryAtoms._elementCount ) {
- const uint8_t* p = _sharedLibraryAtoms._arrayStart
- + slIndex * _sharedLibraryAtoms._elementSize;
- this->_targetsTable[i] = reinterpret_cast<const SharedLibraryAtom*>(p);
- continue;
- }
- const uint32_t abIndex = index - _definedAtoms._elementCount
- - _undefinedAtoms._elementCount
- - _sharedLibraryAtoms._elementCount;
- if ( abIndex < _absoluteAtoms._elementCount ) {
- const uint8_t* p = _absoluteAtoms._arrayStart
- + slIndex * _absoluteAtoms._elementSize;
- this->_targetsTable[i] = reinterpret_cast<const AbsoluteAtom*>(p);
- continue;
- }
- return make_error_code(native_reader_error::file_malformed);
- }
- return make_error_code(native_reader_error::success);
- }
-
-
- // set up pointers to addend pool in file
- error_code processAddendsTable(const uint8_t *base,
- const NativeChunk *chunk) {
- this->_addends = reinterpret_cast<const Reference::Addend*>
- (base + chunk->fileOffset);
- this->_addendsMaxIndex = chunk->elementCount;
- return make_error_code(native_reader_error::success);
- }
-
- // set up pointers to string pool in file
- error_code processStrings(const uint8_t *base,
- const NativeChunk *chunk) {
- this->_strings = reinterpret_cast<const char*>(base + chunk->fileOffset);
- this->_stringsMaxOffset = chunk->fileSize;
- return make_error_code(native_reader_error::success);
- }
-
- // set up pointers to content area in file
- error_code processContent(const uint8_t *base,
- const NativeChunk *chunk) {
- this->_contentStart = base + chunk->fileOffset;
- this->_contentEnd = base + chunk->fileOffset + chunk->fileSize;
- return make_error_code(native_reader_error::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 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 {
- assert(index < _references.elementCount);
- const uint8_t* p = _references.arrayStart + index * _references.elementSize;
- return reinterpret_cast<const NativeReferenceV1*>(p);
- }
-
- const Atom* target(uint16_t index) const {
- if ( index == NativeReferenceIvarsV1::noTarget )
- return nullptr;
- assert(index < _targetsTableCount);
- return _targetsTable[index];
- }
-
- void setTarget(uint16_t index, const Atom* newAtom) const {
- assert(index != NativeReferenceIvarsV1::noTarget);
- assert(index > _targetsTableCount);
- _targetsTable[index] = newAtom;
- }
-
-
-
- // private constructor, only called by make()
- NativeFile(std::unique_ptr<llvm::MemoryBuffer> mb, StringRef path) :
- File(path),
- _buffer(std::move(mb)), // NativeFile 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*>
- (_buffer->getBufferStart());
- }
-
- template <typename T>
- class AtomArray : public File::atom_collection<T> {
- public:
- AtomArray() : _arrayStart(nullptr), _arrayEnd(nullptr),
- _elementSize(0), _elementCount(0) { }
-
- virtual atom_iterator<T> begin() const {
- return atom_iterator<T>(*this, reinterpret_cast<const void*>(_arrayStart));
- }
- virtual atom_iterator<T> end() const{
- return atom_iterator<T>(*this, reinterpret_cast<const void*>(_arrayEnd));
- }
- virtual const T* deref(const void* it) const {
- return reinterpret_cast<const T*>(it);
- }
- virtual void next(const void*& it) const {
- const uint8_t* p = reinterpret_cast<const uint8_t*>(it);
- p += _elementSize;
- it = reinterpret_cast<const void*>(p);
- }
- const uint8_t* _arrayStart;
- const uint8_t* _arrayEnd;
- uint32_t _elementSize;
- uint32_t _elementCount;
- };
-
- 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<llvm::MemoryBuffer> _buffer;
- const NativeFileHeader* _header;
- AtomArray<DefinedAtom> _definedAtoms;
- AtomArray<UndefinedAtom> _undefinedAtoms;
- AtomArray<SharedLibraryAtom> _sharedLibraryAtoms;
- AtomArray<AbsoluteAtom> _absoluteAtoms;
- const uint8_t* _attributes;
- uint32_t _attributesMaxOffset;
- IvarArray _references;
- 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;
-};
-
-
-inline const class File& NativeDefinedAtomV1::file() const {
- return *_file;
-}
-
-inline uint64_t NativeDefinedAtomV1:: ordinal() const {
- const uint8_t* p = reinterpret_cast<const uint8_t*>(_ivarData);
- return p - _file->_definedAtoms._arrayStart;
-}
-
-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 ( this->contentType() == DefinedAtom::typeZeroFill )
- 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 class File& NativeUndefinedAtomV1::file() const {
- return *_file;
-}
-
-inline StringRef NativeUndefinedAtomV1::name() const {
- return _file->string(_ivarData->nameOffset);
-}
-
-
-
-
-inline const class 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 class File& NativeAbsoluteAtomV1::file() const {
- return *_file;
-}
-
-inline StringRef NativeAbsoluteAtomV1::name() const {
- return _file->string(_ivarData->nameOffset);
-}
-
-
-inline const Atom* NativeReferenceV1::target() const {
- return _file->target(_ivarData->targetIndex);
-}
-
-inline Reference::Addend NativeReferenceV1::addend() const {
- return _file->addend(_ivarData->addendIndex);
-}
-
-inline void NativeReferenceV1::setKind(Kind k) {
- this->cloneIvarData();
- const_cast<NativeReferenceIvarsV1*>(_ivarData)->kind = k;
-}
-
-inline void NativeReferenceV1::setTarget(const Atom* newAtom) {
- return _file->setTarget(_ivarData->targetIndex, newAtom);
-}
-
-inline void NativeReferenceV1::setAddend(Addend a) {
- assert(0 && "setAddend() not supported");
-}
-
-
-//
-// Instantiate an lld::File from the given native object file buffer
-//
-error_code parseNativeObjectFile(std::unique_ptr<llvm::MemoryBuffer> mb,
- StringRef path,
- std::unique_ptr<File> &result) {
- return NativeFile::make(std::move(mb), path, result);
-}
-
-
-
-//
-// Instantiate an lld::File from the given native object file path
-//
-error_code parseNativeObjectFileOrSTDIN(StringRef path,
- std::unique_ptr<File>& result) {
- OwningPtr<llvm::MemoryBuffer> mb;
- error_code ec = llvm::MemoryBuffer::getFileOrSTDIN(path, mb);
- if ( ec )
- return ec;
-
- return parseNativeObjectFile( std::unique_ptr<llvm::MemoryBuffer>(mb.take())
- , path
- , result);
-}
-
-} // namespace lld