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 friend class SRECSectionWriter; \
176 friend class SRECSectionWriterBase; \
177 friend class SRECSizeCalculator; \
178 template <class ELFT> friend class ELFSectionWriter; \
179 template <class ELFT> friend class ELFSectionSizer;
211 return DataSize * 2 + 11;
313 std::unique_ptr<WritableMemoryBuffer>
Buf;
326 using Elf_Addr =
typename ELFT::Addr;
327 using Elf_Shdr =
typename ELFT::Shdr;
328 using Elf_Phdr =
typename ELFT::Phdr;
329 using Elf_Ehdr =
typename ELFT::Ehdr;
331 void initEhdrSegment();
334 void writePhdr(
const Segment &Seg);
339 Error writeSectionData();
340 void writeSegmentData();
342 void assignOffsets();
344 std::unique_ptr<ELFSectionWriter<ELFT>> SecWriter;
346 size_t totalSize()
const;
365 std::unique_ptr<BinarySectionWriter> SecWriter;
560 struct SectionCompare {
585 std::set<const SectionBase *, SectionCompare>
Sections;
607 bool HasSymTabLink =
false;
615 bool AllowBrokenLinks,
628 std::vector<uint8_t> Data;
632 : Data(
std::begin(Data),
std::end(Data)) {
779 std::vector<uint32_t> Indexes;
786 Indexes.push_back(
Index);
790 Indexes.reserve(NumSymbols);
791 Size = NumSymbols * 4;
800 Name =
".symtab_shndx";
811 void assignIndices();
842 bool AllowBrokenLinks,
891template <
class SymTabType>
893 void setSymTab(SymTabType *SymTab) {
Symbols = SymTab; }
909 std::vector<Relocation> Relocations;
918 bool AllowBrokenLinks,
962 bool AllowBrokenLinks,
1010 bool AllowBrokenLinks,
1068 : MemBuf(MB), NewSymbolVisibility(NewSymbolVisibility) {}
1074 const std::vector<IHexRecord> &Records;
1076 void addDataSections();
1086 using Elf_Addr =
typename ELFT::Addr;
1087 using Elf_Shdr =
typename ELFT::Shdr;
1088 using Elf_Word =
typename ELFT::Word;
1092 size_t EhdrOffset = 0;
1093 std::optional<StringRef> ExtractPartition;
1095 void setParentSegment(
Segment &Child);
1099 Error readSectionHeaders();
1100 Error readSections(
bool EnsureSymtab);
1101 Error findEhdrOffset();
1106 std::optional<StringRef> ExtractPartition);
1117 : MemBuf(MB), NewSymbolVisibility(NewSymbolVisibility) {}
1126 return LineNo == -1U
1131 template <
typename... Ts>
1132 Error parseError(
size_t LineNo,
char const *Fmt,
const Ts &...Vals)
const {
1134 return parseError(LineNo, std::move(
E));
1145 std::optional<StringRef> ExtractPartition;
1150 :
Bin(
B), ExtractPartition(ExtractPartition) {}
1155 using SecPtr = std::unique_ptr<SectionBase>;
1156 using SegPtr = std::unique_ptr<Segment>;
1158 std::vector<SecPtr> Sections;
1159 std::vector<SegPtr> Segments;
1160 std::vector<SecPtr> RemovedSections;
1163 static bool sectionIsAlloc(
const SectionBase &Sec) {
1202 decltype(§ionIsAlloc)>>
1212 find_if(Sections, [&](
const SecPtr &Sec) {
return Sec->Name ==
Name; });
1213 return SecIt == Sections.end() ? nullptr : SecIt->get();
1225 auto Sec = std::make_unique<T>(std::forward<Ts>(Args)...);
1226 auto Ptr = Sec.get();
1228 Sections.emplace_back(std::move(Sec));
1229 Ptr->Index = Sections.size();
1234 Segments.emplace_back(std::make_unique<Segment>(
Data));
1235 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.
Error checkSection(const SectionBase &S) const
ASCIIHexWriter(Object &Obj, raw_ostream &OS, StringRef OutputFile)
Error finalize() override
std::vector< const SectionBase * > Sections
virtual Expected< size_t > getTotalSize(WritableMemoryBuffer &EmptyBuffer) const =0
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)
Error finalize() override
BinaryWriter(Object &Obj, raw_ostream &Out, const CommonConfig &Config)
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)
ConstRange< SectionBase > members() const
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
IHexWriter(Object &Obj, raw_ostream &Out, StringRef OutputFile)
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
Error compressOrDecompressSections(const CommonConfig &Config)
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 markSymbols() override
const Object & getObject() const
void addRelocation(const Relocation &Rel)
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
uint64_t getBufferOffset() const
std::vector< SRecord > Records
virtual void writeRecord(SRecord &Record, uint64_t Off)=0
void writeSection(const SectionBase &S, ArrayRef< uint8_t > Data)
Error visit(const Section &S) override
void writeRecords(uint32_t Entry)
SRECSectionWriterBase(WritableMemoryBuffer &Buf, uint64_t StartOffset)
Error visit(const StringTableSection &Sec) override
void writeRecord(SRecord &Record, uint64_t Off) override
SRECSectionWriter(WritableMemoryBuffer &Buf, uint64_t Offset)
SRECSizeCalculator(WritableMemoryBuffer &EmptyBuffer, uint64_t Offset)
void writeRecord(SRecord &Record, uint64_t Off) override
SRECWriter(Object &Obj, raw_ostream &OS, StringRef OutputFile)
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)
Represents a GOFF physical record.
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.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
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)
uint8_t getAddressSize() const
static SRecord getHeader(StringRef FileName)
uint8_t getChecksum() const
SRecLineData toString() const
static uint8_t getType(uint32_t Address)
uint16_t getShndx() const
SymbolShndxType ShndxType
An iterator type that allows iterating over the pointees via some other iterator.