diff options
author | Rui Ueyama <ruiu@google.com> | 2013-06-28 19:08:57 +0000 |
---|---|---|
committer | Rui Ueyama <ruiu@google.com> | 2013-06-28 19:08:57 +0000 |
commit | e5fdfdc07bbdb1cd9abf2506db9cb97ae3ed8e23 (patch) | |
tree | cd11a3fba8bb3aedcbfe9d9eb5ecea61b03c69ba /lld/lib | |
parent | 0673464a9296638e4fc497769aabf0149ab1e665 (diff) | |
download | bcm5719-llvm-e5fdfdc07bbdb1cd9abf2506db9cb97ae3ed8e23.tar.gz bcm5719-llvm-e5fdfdc07bbdb1cd9abf2506db9cb97ae3ed8e23.zip |
[PECOFF][Writer] Define COFFBaseDefinedAtom as the base class of COFF defined atoms.
In order to support linking against DLL, the linker needs to create defined
atoms for jump tables and etc. Because such atoms are not read from a file,
they lack some information such as an ordinal. With this patch, COFFDefinedAtom
is split into two classes; one is the base class of all COFF defined atoms, and
another is a concrete class for atoms read from file. More classes inheriting
COFFBaseDefinedAtom will be added for jump tables and etc.
llvm-svn: 185195
Diffstat (limited to 'lld/lib')
-rw-r--r-- | lld/lib/ReaderWriter/PECOFF/Atoms.h | 163 |
1 files changed, 110 insertions, 53 deletions
diff --git a/lld/lib/ReaderWriter/PECOFF/Atoms.h b/lld/lib/ReaderWriter/PECOFF/Atoms.h index 42a6bfd2983..12affa9881f 100644 --- a/lld/lib/ReaderWriter/PECOFF/Atoms.h +++ b/lld/lib/ReaderWriter/PECOFF/Atoms.h @@ -95,26 +95,99 @@ private: StringRef _name; }; -class COFFDefinedAtom : public DefinedAtom { +/// The base class of all COFF defined atoms. A derived class of +/// COFFBaseDefinedAtom may represent atoms read from a file or atoms created +/// by the linker. An example of the latter case is the jump table for symbols +/// in a DLL. +class COFFBaseDefinedAtom : public DefinedAtom { public: - COFFDefinedAtom(const File &f, StringRef n, const coff_symbol *symb, - const coff_section *sec, ArrayRef<uint8_t> d, - StringRef sectionName, uint64_t ordinal) - : _owningFile(f), _name(n), _symbol(symb), _section(sec), _data(d), - _sectionName(sectionName), _ordinal(ordinal) {} - - virtual const File &file() const { return _owningFile; } + enum class Kind { + File, Internal + }; + virtual const File &file() const { return _file; } virtual StringRef name() const { return _name; } + virtual uint64_t size() const { return _dataref.size(); } + virtual Interposable interposable() const { return interposeNo; } + virtual Merge merge() const { return mergeNo; } + virtual Alignment alignment() const { return Alignment(1); } + virtual SectionChoice sectionChoice() const { return sectionBasedOnContent; } + virtual StringRef customSectionName() const { return ""; } + virtual SectionPosition sectionPosition() const { return sectionPositionAny; } + virtual DeadStripKind deadStrip() const { return deadStripNormal; } + virtual bool isAlias() const { return false; } + virtual ArrayRef<uint8_t> rawContent() const { return _dataref; } - virtual uint64_t ordinal() const { return _ordinal; } + Kind getKind() const { return _kind; } + void setKind(Kind kind) { _kind = kind; } + + void addReference(std::unique_ptr<COFFReference> reference) { + _references.push_back(std::move(reference)); + } + + virtual reference_iterator begin() const { + return reference_iterator(*this, reinterpret_cast<const void *>(0)); + } + + virtual reference_iterator end() const { + return reference_iterator( + *this, reinterpret_cast<const void *>(_references.size())); + } + +protected: + COFFBaseDefinedAtom(const File &file, StringRef name) + : _file(file), _name(name), _kind(Kind::Internal) {} + + COFFBaseDefinedAtom(const File &file, StringRef name, ArrayRef<uint8_t> data) + : _file(file), _name(name), _dataref(data), _kind(Kind::Internal) {} + + COFFBaseDefinedAtom(const File &file, StringRef name, + std::vector<uint8_t> *data) + : _file(file), _name(name), _dataref(*data), + _data(std::unique_ptr<std::vector<uint8_t>>(data)), + _kind(Kind::Internal) {} + + void setRawContent(std::vector<uint8_t> *data) { + _dataref = *data; + _data = std::unique_ptr<std::vector<uint8_t>>(data); + } + +private: + virtual const Reference *derefIterator(const void *iter) const { + size_t index = reinterpret_cast<size_t>(iter); + return _references[index].get(); + } - virtual uint64_t size() const { return _data.size(); } + virtual void incrementIterator(const void *&iter) const { + size_t index = reinterpret_cast<size_t>(iter); + iter = reinterpret_cast<const void *>(index + 1); + } + + const File &_file; + StringRef _name; + ArrayRef<uint8_t> _dataref; + std::unique_ptr<std::vector<uint8_t>> _data; + Kind _kind; + std::vector<std::unique_ptr<COFFReference>> _references; +}; + +/// A COFFDefinedAtom represents an atom read from a file. +class COFFDefinedAtom : public COFFBaseDefinedAtom { +public: + COFFDefinedAtom(const File &file, StringRef name, const coff_symbol *symbol, + const coff_section *section, ArrayRef<uint8_t> data, + StringRef sectionName, uint64_t ordinal) + : COFFBaseDefinedAtom(file, name, data), _symbol(symbol), + _section(section), _sectionName(sectionName), _ordinal(ordinal) { + setKind(Kind::File); + } + virtual uint64_t ordinal() const { return _ordinal; } uint64_t originalOffset() const { return _symbol->Value; } + virtual StringRef getSectionName() const { return _sectionName; } - void addReference(std::unique_ptr<COFFReference> reference) { - _references.push_back(std::move(reference)); + static bool classof(const COFFBaseDefinedAtom *atom) { + return atom->getKind() == Kind::File; } virtual Scope scope() const { @@ -129,10 +202,6 @@ public: llvm_unreachable("Unknown scope!"); } - virtual Interposable interposable() const { return interposeNo; } - - virtual Merge merge() const { return mergeNo; } - virtual ContentType contentType() const { if (_section->Characteristics & llvm::COFF::IMAGE_SCN_CNT_CODE) return typeCode; @@ -144,16 +213,6 @@ public: return typeUnknown; } - virtual Alignment alignment() const { return Alignment(1); } - - virtual SectionChoice sectionChoice() const { return sectionBasedOnContent; } - - virtual StringRef customSectionName() const { return ""; } - - virtual SectionPosition sectionPosition() const { return sectionPositionAny; } - - virtual DeadStripKind deadStrip() const { return deadStripNormal; } - virtual ContentPermissions permissions() const { if (_section->Characteristics & llvm::COFF::IMAGE_SCN_MEM_READ && _section->Characteristics & llvm::COFF::IMAGE_SCN_MEM_WRITE) @@ -166,40 +225,38 @@ public: return perm___; } - virtual bool isAlias() const { return false; } +private: + const coff_symbol *_symbol; + const coff_section *_section; + StringRef _sectionName; + std::vector<std::unique_ptr<COFFReference>> _references; + uint64_t _ordinal; +}; - virtual StringRef getSectionName() const { return _sectionName; } +class COFFSharedLibraryAtom : public SharedLibraryAtom { +public: + enum class Kind { + DATA, FUNC + }; - virtual ArrayRef<uint8_t> rawContent() const { return _data; } + virtual const File &file() const { return _file; } + virtual StringRef name() const { return _symbolName; } + virtual StringRef loadName() const { return _loadName; } + virtual bool canBeNullAtRuntime() const { return false; } - virtual reference_iterator begin() const { - return reference_iterator(*this, reinterpret_cast<const void *>(0)); - } + Kind getKind() const { return _kind; } - virtual reference_iterator end() const { - return reference_iterator( - *this, reinterpret_cast<const void *>(_references.size())); +protected: + COFFSharedLibraryAtom(const File &file, StringRef symbolName, + StringRef loadName, Kind kind) + : _file(file), _symbolName(symbolName), _loadName(loadName), _kind(kind) { } private: - virtual const Reference *derefIterator(const void *iter) const { - size_t index = reinterpret_cast<size_t>(iter); - return _references[index].get(); - } - - virtual void incrementIterator(const void *&iter) const { - size_t index = reinterpret_cast<size_t>(iter); - iter = reinterpret_cast<const void *>(index + 1); - } - - const File &_owningFile; - StringRef _name; - const coff_symbol *_symbol; - const coff_section *_section; - std::vector<std::unique_ptr<COFFReference> > _references; - ArrayRef<uint8_t> _data; - StringRef _sectionName; - uint64_t _ordinal; + const File &_file; + StringRef _symbolName; + StringRef _loadName; + Kind _kind; }; //===----------------------------------------------------------------------===// |