9#ifndef LLVM_LIB_OBJCOPY_ELF_ELFOBJECT_H
10#define LLVM_LIB_OBJCOPY_ELF_ELFOBJECT_H
36class OwnedDataSection;
37class StringTableSection;
38class SymbolTableSection;
39class RelocationSection;
40class DynamicRelocationSection;
41class GnuDebugLinkSection;
43class SectionIndexSection;
44class CompressedSection;
45class DecompressedSection;
62 size_t size()
const {
return Sections.
size(); }
131 using Elf_Word =
typename ELFT::Word;
132 using Elf_Rel =
typename ELFT::Rel;
133 using Elf_Rela =
typename ELFT::Rela;
134 using Elf_Sym =
typename ELFT::Sym;
151 using Elf_Rel =
typename ELFT::Rel;
152 using Elf_Rela =
typename ELFT::Rela;
153 using Elf_Sym =
typename ELFT::Sym;
154 using Elf_Word =
typename ELFT::Word;
155 using Elf_Xword =
typename ELFT::Xword;
171#define MAKE_SEC_WRITER_FRIEND \
172 friend class SectionWriter; \
173 friend class IHexSectionWriterBase; \
174 friend class IHexSectionWriter; \
175 template <class ELFT> friend class ELFSectionWriter; \
176 template <class ELFT> friend class ELFSectionSizer;
208 return DataSize * 2 + 11;
310 std::unique_ptr<WritableMemoryBuffer>
Buf;
323 using Elf_Addr =
typename ELFT::Addr;
324 using Elf_Shdr =
typename ELFT::Shdr;
325 using Elf_Phdr =
typename ELFT::Phdr;
326 using Elf_Ehdr =
typename ELFT::Ehdr;
328 void initEhdrSegment();
331 void writePhdr(
const Segment &Seg);
336 Error writeSectionData();
337 void writeSegmentData();
339 void assignOffsets();
341 std::unique_ptr<ELFSectionWriter<ELFT>> SecWriter;
343 size_t totalSize()
const;
360 std::unique_ptr<BinarySectionWriter> SecWriter;
372 struct SectionCompare {
376 std::set<const SectionBase *, SectionCompare> Sections;
377 size_t TotalSize = 0;
441 struct SectionCompare {
466 std::set<const SectionBase *, SectionCompare>
Sections;
488 bool HasSymTabLink =
false;
496 bool AllowBrokenLinks,
509 std::vector<uint8_t> Data;
660 std::vector<uint32_t> Indexes;
667 Indexes.push_back(
Index);
671 Indexes.reserve(NumSymbols);
672 Size = NumSymbols * 4;
681 Name =
".symtab_shndx";
692 void assignIndices();
723 bool AllowBrokenLinks,
771template <
class SymTabType>
773 void setSymTab(SymTabType *SymTab) {
Symbols = SymTab; }
789 std::vector<Relocation> Relocations;
798 bool AllowBrokenLinks,
839 bool AllowBrokenLinks,
883 bool AllowBrokenLinks,
922 std::unique_ptr<Object>
Obj;
936 uint8_t NewSymbolVisibility;
941 : MemBuf(MB), NewSymbolVisibility(NewSymbolVisibility) {}
947 const std::vector<IHexRecord> &Records;
949 void addDataSections();
959 using Elf_Addr =
typename ELFT::Addr;
960 using Elf_Shdr =
typename ELFT::Shdr;
961 using Elf_Word =
typename ELFT::Word;
965 size_t EhdrOffset = 0;
966 std::optional<StringRef> ExtractPartition;
968 void setParentSegment(
Segment &Child);
972 Error readSectionHeaders();
973 Error readSections(
bool EnsureSymtab);
974 Error findEhdrOffset();
979 std::optional<StringRef> ExtractPartition);
986 uint8_t NewSymbolVisibility;
990 : MemBuf(MB), NewSymbolVisibility(NewSymbolVisibility) {}
1004 template <
typename... Ts>
1005 Error parseError(
size_t LineNo,
char const *Fmt,
const Ts &...Vals)
const {
1007 return parseError(LineNo, std::move(
E));
1018 std::optional<StringRef> ExtractPartition;
1023 :
Bin(
B), ExtractPartition(ExtractPartition) {}
1028 using SecPtr = std::unique_ptr<SectionBase>;
1029 using SegPtr = std::unique_ptr<Segment>;
1031 std::vector<SecPtr> Sections;
1032 std::vector<SegPtr> Segments;
1033 std::vector<SecPtr> RemovedSections;
1036 static bool sectionIsAlloc(
const SectionBase &Sec) {
1075 decltype(§ionIsAlloc)>>
1085 find_if(Sections, [&](
const SecPtr &Sec) {
return Sec->Name ==
Name; });
1086 return SecIt == Sections.end() ? nullptr : SecIt->get();
1097 auto Sec = std::make_unique<T>(std::forward<Ts>(Args)...);
1098 auto Ptr = Sec.get();
1100 Sections.emplace_back(std::move(Sec));
1101 Ptr->Index = Sections.size();
1106 Segments.emplace_back(std::make_unique<Segment>(
Data));
1107 return *Segments.back();
ReachingDefAnalysis InstSet & ToRemove
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define MAKE_SEC_WRITER_FRIEND
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
Lightweight error class with error context and mandatory checking.
Tagged union holding either a T or a Error.
This interface provides simple read-only access to a block of memory, and provides simple methods for...
virtual StringRef getBufferIdentifier() const
Return an identifier for this buffer, typically the filename it was read from.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
Utility for building string tables with deduplicated suffixes.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
std::string str() const
Return the twine contents as a std::string.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
This class is an extension of MemoryBuffer, which allows copy-on-write access to the underlying conte...
Specialization of filter_iterator_base for forward iteration only.
An efficient, type-erasing, non-owning reference to a callable.
A range adaptor for a pair of iterators.
StringTableSection * addStrTab()
SymbolTableSection * addSymTab(StringTableSection *StrTab)
std::unique_ptr< Object > Obj
BinaryELFBuilder(MemoryBuffer *MB, uint8_t NewSymbolVisibility)
Expected< std::unique_ptr< Object > > build()
BinaryReader(MemoryBuffer *MB, const uint8_t NewSymbolVisibility)
Expected< std::unique_ptr< Object > > create(bool EnsureSymtab) const override
virtual ~BinarySectionWriter()
Error visit(const SymbolTableSection &Sec) override
BinarySectionWriter(WritableMemoryBuffer &Buf)
BinaryWriter(Object &Obj, raw_ostream &Out)
Error finalize() override
Error accept(SectionVisitor &Visitor) const override
uint64_t getDecompressedSize() const
uint64_t getChType() const
uint64_t getDecompressedAlign() const
static bool classof(const SectionBase *S)
Error accept(SectionVisitor &Visitor) const override
DecompressedSection(const CompressedSection &Sec)
Error accept(SectionVisitor &) const override
DynamicRelocationSection(ArrayRef< uint8_t > Data)
static bool classof(const SectionBase *S)
Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove) override
DynamicSection(ArrayRef< uint8_t > Data)
static bool classof(const SectionBase *S)
static bool classof(const SectionBase *S)
DynamicSymbolTableSection(ArrayRef< uint8_t > Data)
Error build(bool EnsureSymtab)
ELFReader(Binary *B, std::optional< StringRef > ExtractPartition)
Expected< std::unique_ptr< Object > > create(bool EnsureSymtab) const override
Error visit(Section &Sec) override
ELFSectionWriter(WritableMemoryBuffer &Buf)
Error visit(const SymbolTableSection &Sec) override
virtual ~ELFSectionWriter()
Error finalize() override
Error accept(SectionVisitor &Visitor) const override
GroupSection(ArrayRef< uint8_t > Data)
void setSymTab(const SymbolTableSection *SymTabSec)
void setSymbol(Symbol *S)
void replaceSectionReferences(const DenseMap< SectionBase *, SectionBase * > &FromTo) override
Error accept(SectionVisitor &) const override
static bool classof(const SectionBase *S)
void markSymbols() override
ArrayRef< uint8_t > Contents
void addMember(SectionBase *Sec)
Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove) override
void setFlagWord(ELF::Elf32_Word W)
Error removeSymbols(function_ref< bool(const Symbol &)> ToRemove) override
IHexELFBuilder(const std::vector< IHexRecord > &Records)
Expected< std::unique_ptr< Object > > build()
IHexReader(MemoryBuffer *MB)
Expected< std::unique_ptr< Object > > create(bool EnsureSymtab) const override
uint64_t getBufferOffset() const
IHexSectionWriterBase(WritableMemoryBuffer &Buf)
void writeSection(const SectionBase *Sec, ArrayRef< uint8_t > Data)
Error visit(const Section &Sec) final
virtual void writeData(uint8_t Type, uint16_t Addr, ArrayRef< uint8_t > Data)
IHexSectionWriter(WritableMemoryBuffer &Buf)
void writeData(uint8_t Type, uint16_t Addr, ArrayRef< uint8_t > Data) override
Error visit(const StringTableSection &Sec) override
Error finalize() override
IHexWriter(Object &Obj, raw_ostream &Out)
virtual Error visit(OwnedDataSection &Sec)=0
virtual Error visit(SymbolTableSection &Sec)=0
virtual Error visit(DecompressedSection &Sec)=0
virtual Error visit(StringTableSection &Sec)=0
virtual Error visit(GnuDebugLinkSection &Sec)=0
virtual ~MutableSectionVisitor()=default
virtual Error visit(SectionIndexSection &Sec)=0
virtual Error visit(DynamicRelocationSection &Sec)=0
virtual Error visit(Section &Sec)=0
virtual Error visit(GroupSection &Sec)=0
virtual Error visit(CompressedSection &Sec)=0
virtual Error visit(RelocationSection &Sec)=0
SectionTableRef sections() const
StringTableSection * SectionNames
SectionTableRef removedSections()
bool isRelocatable() const
iterator_range< filter_iterator< pointee_iterator< std::vector< SecPtr >::const_iterator >, decltype(§ionIsAlloc)> > allocSections() const
Error updateSection(StringRef Name, ArrayRef< uint8_t > Data)
SectionIndexSection * SectionIndexTable
Error removeSymbols(function_ref< bool(const Symbol &)> ToRemove)
T & addSection(Ts &&...Args)
Error removeSections(bool AllowBrokenLinks, std::function< bool(const SectionBase &)> ToRemove)
Segment & addSegment(ArrayRef< uint8_t > Data)
ConstRange< Segment > segments() const
SymbolTableSection * SymbolTable
Segment ProgramHdrSegment
const auto & getUpdatedSections() const
SectionBase * findSection(StringRef Name)
Error addNewSymbolTable()
Error replaceSections(const DenseMap< SectionBase *, SectionBase * > &FromTo)
void appendHexData(StringRef HexData)
OwnedDataSection(const Twine &SecName, uint64_t SecAddr, uint64_t SecFlags, uint64_t SecOff)
Error accept(SectionVisitor &Sec) const override
OwnedDataSection(StringRef SecName, ArrayRef< uint8_t > Data)
OwnedDataSection(SectionBase &S, ArrayRef< uint8_t > Data)
bool hasContents() const override
virtual Expected< std::unique_ptr< Object > > create(bool EnsureSymtab) const =0
RelocSectionWithSymtabBase()=default
Error initialize(SectionTableRef SecTable) override
const SectionBase * getSection() const
SectionBase * SecToApplyRel
StringRef getNamePrefix() const
void setSection(SectionBase *Sec)
static bool classof(const SectionBase *S)
void addRelocation(Relocation Rel)
void markSymbols() override
const Object & getObject() const
Error accept(SectionVisitor &Visitor) const override
RelocationSection(const Object &O)
Error removeSymbols(function_ref< bool(const Symbol &)> ToRemove) override
void replaceSectionReferences(const DenseMap< SectionBase *, SectionBase * > &FromTo) override
static bool classof(const SectionBase *S)
Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove) override
virtual void markSymbols()
ArrayRef< uint8_t > OriginalData
virtual Error initialize(SectionTableRef SecTable)
virtual Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove)
virtual void restoreSymTabLink(SymbolTableSection &)
virtual void replaceSectionReferences(const DenseMap< SectionBase *, SectionBase * > &)
virtual Error accept(MutableSectionVisitor &Visitor)=0
virtual ~SectionBase()=default
virtual bool hasContents() const
SectionBase(const SectionBase &)=default
virtual Error removeSymbols(function_ref< bool(const Symbol &)> ToRemove)
virtual Error accept(SectionVisitor &Visitor) const =0
void addIndex(uint32_t Index)
virtual ~SectionIndexSection()
void setSymTab(SymbolTableSection *SymTab)
Error accept(SectionVisitor &Visitor) const override
void reserve(size_t NumSymbols)
Error initialize(SectionTableRef SecTable) override
pointee_iterator< const std::unique_ptr< SectionBase > * > iterator
Expected< T * > getSectionOfType(uint32_t Index, Twine IndexErrMsg, Twine TypeErrMsg)
SectionTableRef(ArrayRef< std::unique_ptr< SectionBase > > Secs)
SectionTableRef(const SectionTableRef &)=default
Expected< SectionBase * > getSection(uint32_t Index, Twine ErrMsg)
virtual Error visit(const CompressedSection &Sec)=0
virtual Error visit(const Section &Sec)=0
virtual Error visit(const DecompressedSection &Sec)=0
virtual ~SectionVisitor()=default
virtual Error visit(const GroupSection &Sec)=0
virtual Error visit(const SymbolTableSection &Sec)=0
virtual Error visit(const RelocationSection &Sec)=0
virtual Error visit(const SectionIndexSection &Sec)=0
virtual Error visit(const DynamicRelocationSection &Sec)=0
virtual Error visit(const GnuDebugLinkSection &Sec)=0
virtual Error visit(const StringTableSection &Sec)=0
virtual Error visit(const OwnedDataSection &Sec)=0
Error visit(const GroupSection &Sec) override=0
Error visit(const RelocationSection &Sec) override=0
Error visit(const SectionIndexSection &Sec) override=0
Error visit(const CompressedSection &Sec) override=0
Error visit(const Section &Sec) override
Error visit(const GnuDebugLinkSection &Sec) override=0
Error visit(const SymbolTableSection &Sec) override=0
WritableMemoryBuffer & Out
Error visit(const DecompressedSection &Sec) override=0
virtual ~SectionWriter()=default
SectionWriter(WritableMemoryBuffer &Buf)
Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove) override
Error initialize(SectionTableRef SecTable) override
Section(ArrayRef< uint8_t > Data)
void restoreSymTabLink(SymbolTableSection &SymTab) override
bool hasContents() const override
Error accept(SectionVisitor &Visitor) const override
void addSection(const SectionBase *Sec)
Segment(ArrayRef< uint8_t > Data)
ArrayRef< uint8_t > Contents
void removeSection(const SectionBase *Sec)
const SectionBase * firstSection() const
ArrayRef< uint8_t > getContents() const
std::set< const SectionBase *, SectionCompare > Sections
void addString(StringRef Name)
static bool classof(const SectionBase *S)
uint32_t findIndex(StringRef Name) const
Error accept(SectionVisitor &Visitor) const override
const SectionBase * getStrTab() const
Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove) override
const SectionIndexSection * getShndxTable() const
std::vector< std::unique_ptr< Symbol > > Symbols
SectionIndexSection * SectionIndexTable
Error accept(SectionVisitor &Visitor) const override
void addSymbol(Twine Name, uint8_t Bind, uint8_t Type, SectionBase *DefinedIn, uint64_t Value, uint8_t Visibility, uint16_t Shndx, uint64_t SymbolSize)
void updateSymbols(function_ref< void(Symbol &)> Callable)
static bool classof(const SectionBase *S)
bool indicesChanged() const
Expected< const Symbol * > getSymbolByIndex(uint32_t Index) const
Error removeSymbols(function_ref< bool(const Symbol &)> ToRemove) override
Error initialize(SectionTableRef SecTable) override
void replaceSectionReferences(const DenseMap< SectionBase *, SectionBase * > &FromTo) override
std::unique_ptr< Symbol > SymPtr
void setShndxTable(SectionIndexSection *ShndxTable)
StringTableSection * SymbolNames
virtual Error finalize()=0
std::unique_ptr< WritableMemoryBuffer > Buf
Writer(Object &O, raw_ostream &Out)
This class implements an extremely fast bulk output stream that can only output to a stream.
@ SYMBOL_HEXAGON_SCOMMON_8
@ SYMBOL_HEXAGON_SCOMMON_4
@ SYMBOL_HEXAGON_SCOMMON_2
This is an optimization pass for GlobalISel generic memory operations.
Error createFileError(const Twine &F, Error E)
Concatenate a source file path and/or name with an Error.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
iterator_range< pointee_iterator< WrappedIteratorT > > make_pointee_range(RangeT &&Range)
iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)
Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Implement std::hash so that hash_code can be used in STL containers.
This struct is a compact representation of a valid (non-zero power of two) alignment.
static IHexLineData getLine(uint8_t Type, uint16_t Addr, ArrayRef< uint8_t > Data)
static uint8_t getChecksum(StringRef S)
static size_t getLength(size_t DataSize)
static size_t getLineLength(size_t DataSize)
uint16_t getShndx() const
SymbolShndxType ShndxType
An iterator type that allows iterating over the pointees via some other iterator.