Go to the documentation of this file.
9 #ifndef LLVM_LIB_OBJCOPY_ELF_ELFOBJECT_H
10 #define LLVM_LIB_OBJCOPY_ELF_ELFOBJECT_H
36 class OwnedDataSection;
37 class StringTableSection;
38 class SymbolTableSection;
39 class RelocationSection;
40 class DynamicRelocationSection;
41 class GnuDebugLinkSection;
43 class SectionIndexSection;
44 class CompressedSection;
45 class DecompressedSection;
62 size_t size()
const {
return Sections.
size(); }
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;
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;
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;
439 struct SectionCompare {
464 std::set<const SectionBase *, SectionCompare>
Sections;
493 bool AllowBrokenLinks,
505 std::vector<uint8_t> Data;
653 std::vector<uint32_t> Indexes;
660 Indexes.push_back(
Index);
664 Indexes.reserve(NumSymbols);
665 Size = NumSymbols * 4;
674 Name =
".symtab_shndx";
685 void assignIndices();
714 bool AllowBrokenLinks,
762 template <
class SymTabType>
764 void setSymTab(SymTabType *SymTab) {
Symbols = SymTab; }
780 std::vector<Relocation> Relocations;
789 bool AllowBrokenLinks,
830 bool AllowBrokenLinks,
874 bool AllowBrokenLinks,
913 std::unique_ptr<Object>
Obj;
927 uint8_t NewSymbolVisibility;
932 : MemBuf(MB), NewSymbolVisibility(NewSymbolVisibility) {}
938 const std::vector<IHexRecord> &Records;
940 void addDataSections();
956 size_t EhdrOffset = 0;
959 void setParentSegment(
Segment &Child);
963 Error readSectionHeaders();
964 Error readSections(
bool EnsureSymtab);
965 Error findEhdrOffset();
977 uint8_t NewSymbolVisibility;
981 : MemBuf(MB), NewSymbolVisibility(NewSymbolVisibility) {}
995 template <
typename... Ts>
996 Error parseError(
size_t LineNo,
char const *Fmt,
const Ts &...Vals)
const {
1014 :
Bin(
B), ExtractPartition(ExtractPartition) {}
1019 using SecPtr = std::unique_ptr<SectionBase>;
1020 using SegPtr = std::unique_ptr<Segment>;
1022 std::vector<SecPtr> Sections;
1023 std::vector<SegPtr> Segments;
1024 std::vector<SecPtr> RemovedSections;
1027 static bool sectionIsAlloc(
const SectionBase &Sec) {
1065 decltype(§ionIsAlloc)>>
1075 find_if(Sections, [&](
const SecPtr &Sec) {
return Sec->Name ==
Name; });
1076 return SecIt == Sections.end() ? nullptr : SecIt->get();
1087 auto Sec = std::make_unique<T>(std::forward<Ts>(
Args)...);
1088 auto Ptr = Sec.get();
1091 Ptr->Index = Sections.size();
1096 Segments.emplace_back(std::make_unique<Segment>(
Data));
1097 return *Segments.back();
1108 #endif // LLVM_LIB_OBJCOPY_ELF_ELFOBJECT_H
virtual Expected< std::unique_ptr< Object > > create(bool EnsureSymtab) const =0
BinaryWriter(Object &Obj, raw_ostream &Out)
void addRelocation(Relocation Rel)
IHexSectionWriterBase(WritableMemoryBuffer &Buf)
OwnedDataSection(StringRef SecName, ArrayRef< uint8_t > Data)
virtual Error removeSymbols(function_ref< bool(const Symbol &)> ToRemove)
@ SYMBOL_HEXAGON_SCOMMON_4
Error finalize() override
This is an optimization pass for GlobalISel generic memory operations.
uint16_t getShndx() const
Error updateSection(StringRef Name, ArrayRef< uint8_t > Data)
ELFSectionWriter(WritableMemoryBuffer &Buf)
SectionTableRef(ArrayRef< std::unique_ptr< SectionBase >> Secs)
ELFReader(Binary *B, Optional< StringRef > ExtractPartition)
void replaceSectionReferences(const DenseMap< SectionBase *, SectionBase * > &FromTo) override
ELFWriter(Object &Obj, raw_ostream &Out, bool WSH, bool OnlyKeepDebug)
const SectionBase * getSection() const
Error initialize(SectionTableRef SecTable) override
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
RelocationSection(const Object &O)
Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove) override
ReachingDefAnalysis InstSet & ToRemove
Expected< SectionBase * > getSection(uint32_t Index, Twine ErrMsg)
void markSymbols() override
bool isRelocatable() const
Error removeSymbols(function_ref< bool(const Symbol &)> ToRemove)
static size_t getLength(size_t DataSize)
CompressedSection(const SectionBase &Sec, DebugCompressionType CompressionType)
The instances of the Type class are immutable: once they are created, they are never changed.
Specialization of filter_iterator_base for forward iteration only.
IHexReader(MemoryBuffer *MB)
const_iterator end(StringRef path)
Get end iterator over path.
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove) override
virtual ~SectionWriter()=default
const SectionIndexSection * getShndxTable() const
SectionIndexSection * SectionIndexTable
ArrayRef< uint8_t > Contents
BinaryReader(MemoryBuffer *MB, const uint8_t NewSymbolVisibility)
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
uint32_t findIndex(StringRef Name) const
Error visit(const Section &Sec) override
Tagged union holding either a T or a Error.
Writer(Object &O, raw_ostream &Out)
IHexELFBuilder(const std::vector< IHexRecord > &Records)
uint64_t getDecompressedAlign() const
Error replaceSections(const DenseMap< SectionBase *, SectionBase * > &FromTo)
This interface provides simple read-only access to a block of memory, and provides simple methods for...
virtual Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove)
virtual bool hasContents() const
T & addSection(Ts &&...Args)
uint64_t getBufferOffset() const
Expected< T * > getSectionOfType(uint32_t Index, Twine IndexErrMsg, Twine TypeErrMsg)
iterator_range< filter_iterator< pointee_iterator< std::vector< SecPtr >::const_iterator >, decltype(§ionIsAlloc)> > allocSections() const
Segment & addSegment(ArrayRef< uint8_t > Data)
virtual ~SectionBase()=default
Error accept(SectionVisitor &Visitor) const override
std::vector< std::unique_ptr< Symbol > > Symbols
static bool classof(const SectionBase *S)
ArrayRef< uint8_t > Contents
Error initialize(SectionTableRef SecTable) override
SectionBase * findSection(StringRef Name)
SectionWriter(WritableMemoryBuffer &Buf)
Error addNewSymbolTable()
StringTableSection * SymbolNames
void addSymbol(Twine Name, uint8_t Bind, uint8_t Type, SectionBase *DefinedIn, uint64_t Value, uint8_t Visibility, uint16_t Shndx, uint64_t SymbolSize)
Error createFileError(const Twine &F, Error E)
Concatenate a source file path and/or name with an Error.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static bool classof(const SectionBase *S)
Error visit(const SymbolTableSection &Sec) override
@ SYMBOL_HEXAGON_SCOMMON_2
virtual ~SectionVisitor()=default
StringTableSection * SectionNames
static bool classof(const SectionBase *S)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Error visit(Section &Sec) override
DynamicSymbolTableSection(ArrayRef< uint8_t > Data)
static bool classof(const SectionBase *S)
This class implements an extremely fast bulk output stream that can only output to a stream.
void appendHexData(StringRef HexData)
BinarySectionWriter(WritableMemoryBuffer &Buf)
const SectionBase * getStrTab() const
void setShndxTable(SectionIndexSection *ShndxTable)
Error removeSymbols(function_ref< bool(const Symbol &)> ToRemove) override
Expected< std::unique_ptr< Object > > build()
This struct is a compact representation of a valid (non-zero power of two) alignment.
virtual Error accept(SectionVisitor &Visitor) const =0
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
Section(ArrayRef< uint8_t > Data)
virtual ~ELFSectionWriter()
bool hasContents() const override
virtual ~MutableSectionVisitor()=default
static uint8_t getChecksum(StringRef S)
DecompressedSection(const CompressedSection &Sec)
void addMember(SectionBase *Sec)
virtual StringRef getBufferIdentifier() const
Return an identifier for this buffer, typically the filename it was read from.
std::string str() const
Return the twine contents as a std::string.
void writeSection(const SectionBase *Sec, ArrayRef< uint8_t > Data)
Error accept(SectionVisitor &) const override
An efficient, type-erasing, non-owning reference to a callable.
virtual ~BinarySectionWriter()
SectionBase * SecToApplyRel
ArrayRef< uint8_t > getContents() const
StringRef getNamePrefix() const
GroupSection(ArrayRef< uint8_t > Data)
Error finalize() override
Error accept(SectionVisitor &) const override
virtual ~SectionIndexSection()
Error finalize() override
Expected< std::unique_ptr< Object > > create(bool EnsureSymtab) const override
virtual Error initialize(SectionTableRef SecTable)
virtual void replaceSectionReferences(const DenseMap< SectionBase *, SectionBase * > &)
std::unique_ptr< WritableMemoryBuffer > Buf
void addSection(const SectionBase *Sec)
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
OwnedDataSection(const Twine &SecName, uint64_t SecAddr, uint64_t SecFlags, uint64_t SecOff)
DynamicRelocationSection(ArrayRef< uint8_t > Data)
Expected< std::unique_ptr< Object > > create(bool EnsureSymtab) const override
virtual void markSymbols()
static bool classof(const SectionBase *S)
static bool classof(const SectionBase *S)
Expected< std::unique_ptr< Object > > create(bool EnsureSymtab) const override
GnuDebugLinkSection(StringRef File, uint32_t PrecomputedCRC)
virtual Error visit(const Section &Sec)=0
iterator_range< pointee_iterator< WrappedIteratorT > > make_pointee_range(RangeT &&Range)
WritableMemoryBuffer & Out
StringTableSection * addStrTab()
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Segment(ArrayRef< uint8_t > Data)
SymbolTableSection * addSymTab(StringTableSection *StrTab)
BinaryELFBuilder(MemoryBuffer *MB, uint8_t NewSymbolVisibility)
Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove) override
print Print MemDeps of function
Error accept(SectionVisitor &Visitor) const override
pointee_iterator< const std::unique_ptr< SectionBase > * > iterator
uint64_t getDecompressedSize() const
Error accept(SectionVisitor &Visitor) const override
Segment ProgramHdrSegment
void reserve(size_t NumSymbols)
support::ulittle32_t Word
void addString(StringRef Name)
void setSymTab(const SymbolTableSection *SymTabSec)
ConstRange< Segment > segments() const
DynamicSection(ArrayRef< uint8_t > Data)
static bool classof(const SectionBase *S)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
StringRef - Represent a constant reference to a string, i.e.
Error build(bool EnsureSymtab)
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
void setSymbol(Symbol *S)
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...
#define MAKE_SEC_WRITER_FRIEND
ELFBuilder(const ELFObjectFile< ELFT > &ElfObj, Object &Obj, Optional< StringRef > ExtractPartition)
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
void markSymbols() override
Error accept(SectionVisitor &Visitor) const override
void updateSymbols(function_ref< void(Symbol &)> Callable)
Error visit(const StringTableSection &Sec) override
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
SectionTableRef sections() const
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Error accept(SectionVisitor &Sec) const override
Error removeSections(bool AllowBrokenLinks, std::function< bool(const SectionBase &)> ToRemove)
Lightweight error class with error context and mandatory checking.
void writeData(uint8_t Type, uint16_t Addr, ArrayRef< uint8_t > Data) override
Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove) override
Error initialize(SectionTableRef SecTable) override
virtual Error finalize()=0
const SectionBase * firstSection() const
Error accept(SectionVisitor &Visitor) const override
Error removeSymbols(function_ref< bool(const Symbol &)> ToRemove) override
RelocSectionWithSymtabBase()=default
virtual void writeData(uint8_t Type, uint16_t Addr, ArrayRef< uint8_t > Data)
std::set< const SectionBase *, SectionCompare > Sections
Utility for building string tables with deduplicated suffixes.
void setSymTab(SymbolTableSection *SymTab)
Error visit(const SymbolTableSection &Sec) override
void setFlagWord(ELF::Elf32_Word W)
Error accept(SectionVisitor &Visitor) const override
static bool classof(const SectionBase *S)
void setSection(SectionBase *Sec)
std::unique_ptr< Symbol > SymPtr
void replaceSectionReferences(const DenseMap< SectionBase *, SectionBase * > &FromTo) override
static size_t getLineLength(size_t DataSize)
static bool classof(const SectionBase *S)
size_t size() const
size - Get the array size.
bool hasContents() const override
A range adaptor for a pair of iterators.
Expected< const Symbol * > getSymbolByIndex(uint32_t Index) const
std::unique_ptr< Object > Obj
const Object & getObject() const
Error accept(SectionVisitor &Visitor) const override
SymbolShndxType ShndxType
static Expected< IHexRecord > parse(StringRef Line)
Error removeSymbols(function_ref< bool(const Symbol &)> ToRemove) override
SymbolTableSection * SymbolTable
virtual Error visit(Section &Sec)=0
ArrayRef< uint8_t > OriginalData
An iterator type that allows iterating over the pointees via some other iterator.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove) override
SectionTableRef removedSections()
This class is an extension of MemoryBuffer, which allows copy-on-write access to the underlying conte...
Error initialize(SectionTableRef SecTable) override
SectionIndexSection * SectionIndexTable
const auto & getUpdatedSections() const
IHexSectionWriter(WritableMemoryBuffer &Buf)
static IHexLineData getLine(uint8_t Type, uint16_t Addr, ArrayRef< uint8_t > Data)
Error accept(SectionVisitor &Visitor) const override
Expected< std::unique_ptr< Object > > build()
void addIndex(uint32_t Index)
LLVM Value Representation.
OwnedDataSection(SectionBase &S, ArrayRef< uint8_t > Data)
@ SYMBOL_HEXAGON_SCOMMON_8
void replaceSectionReferences(const DenseMap< SectionBase *, SectionBase * > &FromTo) override
Error visit(const Section &Sec) final
IHexWriter(Object &Obj, raw_ostream &Out)
void removeSection(const SectionBase *Sec)