llvm/llvm/lib/ObjCopy/ELF/ELFObject.cpp

//===- ELFObject.cpp ------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "ELFObject.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/MC/MCELFExtras.h"
#include "llvm/MC/MCTargetOptions.h"
#include "llvm/Object/ELF.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Support/Compression.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileOutputBuffer.h"
#include "llvm/Support/Path.h"
#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <iterator>
#include <unordered_set>
#include <utility>
#include <vector>

usingnamespacellvm;
usingnamespacellvm::ELF;
usingnamespacellvm::objcopy::elf;
usingnamespacellvm::object;
usingnamespacellvm::support;

template <class ELFT> void ELFWriter<ELFT>::writePhdr(const Segment &Seg) {}

Error SectionBase::removeSectionReferences(
    bool, function_ref<bool(const SectionBase *)>) {}

Error SectionBase::removeSymbols(function_ref<bool(const Symbol &)>) {}

Error SectionBase::initialize(SectionTableRef) {}
void SectionBase::finalize() {}
void SectionBase::markSymbols() {}
void SectionBase::replaceSectionReferences(
    const DenseMap<SectionBase *, SectionBase *> &) {}
void SectionBase::onRemove() {}

template <class ELFT> void ELFWriter<ELFT>::writeShdr(const SectionBase &Sec) {}

template <class ELFT> Error ELFSectionSizer<ELFT>::visit(Section &) {}

template <class ELFT> Error ELFSectionSizer<ELFT>::visit(OwnedDataSection &) {}

template <class ELFT> Error ELFSectionSizer<ELFT>::visit(StringTableSection &) {}

template <class ELFT>
Error ELFSectionSizer<ELFT>::visit(DynamicRelocationSection &) {}

template <class ELFT>
Error ELFSectionSizer<ELFT>::visit(SymbolTableSection &Sec) {}

template <bool Is64>
static SmallVector<char, 0> encodeCrel(ArrayRef<Relocation> Relocations) {}

template <class ELFT>
Error ELFSectionSizer<ELFT>::visit(RelocationSection &Sec) {}

template <class ELFT>
Error ELFSectionSizer<ELFT>::visit(GnuDebugLinkSection &) {}

template <class ELFT> Error ELFSectionSizer<ELFT>::visit(GroupSection &Sec) {}

template <class ELFT>
Error ELFSectionSizer<ELFT>::visit(SectionIndexSection &) {}

template <class ELFT> Error ELFSectionSizer<ELFT>::visit(CompressedSection &) {}

template <class ELFT>
Error ELFSectionSizer<ELFT>::visit(DecompressedSection &) {}

Error BinarySectionWriter::visit(const SectionIndexSection &Sec) {}

Error BinarySectionWriter::visit(const SymbolTableSection &Sec) {}

Error BinarySectionWriter::visit(const RelocationSection &Sec) {}

Error BinarySectionWriter::visit(const GnuDebugLinkSection &Sec) {}

Error BinarySectionWriter::visit(const GroupSection &Sec) {}

Error SectionWriter::visit(const Section &Sec) {}

static bool addressOverflows32bit(uint64_t Addr) {}

template <class T> static T checkedGetHex(StringRef S) {}

// Fills exactly Len bytes of buffer with hexadecimal characters
// representing value 'X'
template <class T, class Iterator>
static Iterator toHexStr(T X, Iterator It, size_t Len) {}

uint8_t IHexRecord::getChecksum(StringRef S) {}

IHexLineData IHexRecord::getLine(uint8_t Type, uint16_t Addr,
                                 ArrayRef<uint8_t> Data) {}

static Error checkRecord(const IHexRecord &R) {}

// Checks that IHEX line contains valid characters.
// This allows converting hexadecimal data to integers
// without extra verification.
static Error checkChars(StringRef Line) {}

Expected<IHexRecord> IHexRecord::parse(StringRef Line) {}

static uint64_t sectionPhysicalAddr(const SectionBase *Sec) {}

void IHexSectionWriterBase::writeSection(const SectionBase *Sec,
                                         ArrayRef<uint8_t> Data) {}

uint64_t IHexSectionWriterBase::writeSegmentAddr(uint64_t Addr) {}

uint64_t IHexSectionWriterBase::writeBaseAddr(uint64_t Addr) {}

void IHexSectionWriterBase::writeData(uint8_t, uint16_t,
                                      ArrayRef<uint8_t> Data) {}

Error IHexSectionWriterBase::visit(const Section &Sec) {}

Error IHexSectionWriterBase::visit(const OwnedDataSection &Sec) {}

Error IHexSectionWriterBase::visit(const StringTableSection &Sec) {}

Error IHexSectionWriterBase::visit(const DynamicRelocationSection &Sec) {}

void IHexSectionWriter::writeData(uint8_t Type, uint16_t Addr,
                                  ArrayRef<uint8_t> Data) {}

Error IHexSectionWriter::visit(const StringTableSection &Sec) {}

Error Section::accept(SectionVisitor &Visitor) const {}

Error Section::accept(MutableSectionVisitor &Visitor) {}

void Section::restoreSymTabLink(SymbolTableSection &SymTab) {}

Error SectionWriter::visit(const OwnedDataSection &Sec) {}

template <class ELFT>
Error ELFSectionWriter<ELFT>::visit(const DecompressedSection &Sec) {}

Error BinarySectionWriter::visit(const DecompressedSection &Sec) {}

Error DecompressedSection::accept(SectionVisitor &Visitor) const {}

Error DecompressedSection::accept(MutableSectionVisitor &Visitor) {}

Error OwnedDataSection::accept(SectionVisitor &Visitor) const {}

Error OwnedDataSection::accept(MutableSectionVisitor &Visitor) {}

void OwnedDataSection::appendHexData(StringRef HexData) {}

Error BinarySectionWriter::visit(const CompressedSection &Sec) {}

template <class ELFT>
Error ELFSectionWriter<ELFT>::visit(const CompressedSection &Sec) {}

CompressedSection::CompressedSection(const SectionBase &Sec,
                                     DebugCompressionType CompressionType,
                                     bool Is64Bits)
    :{}

CompressedSection::CompressedSection(ArrayRef<uint8_t> CompressedData,
                                     uint32_t ChType, uint64_t DecompressedSize,
                                     uint64_t DecompressedAlign)
    :{}

Error CompressedSection::accept(SectionVisitor &Visitor) const {}

Error CompressedSection::accept(MutableSectionVisitor &Visitor) {}

void StringTableSection::addString(StringRef Name) {}

uint32_t StringTableSection::findIndex(StringRef Name) const {}

void StringTableSection::prepareForLayout() {}

Error SectionWriter::visit(const StringTableSection &Sec) {}

Error StringTableSection::accept(SectionVisitor &Visitor) const {}

Error StringTableSection::accept(MutableSectionVisitor &Visitor) {}

template <class ELFT>
Error ELFSectionWriter<ELFT>::visit(const SectionIndexSection &Sec) {}

Error SectionIndexSection::initialize(SectionTableRef SecTable) {}

void SectionIndexSection::finalize() {}

Error SectionIndexSection::accept(SectionVisitor &Visitor) const {}

Error SectionIndexSection::accept(MutableSectionVisitor &Visitor) {}

static bool isValidReservedSectionIndex(uint16_t Index, uint16_t Machine) {}

// Large indexes force us to clarify exactly what this function should do. This
// function should return the value that will appear in st_shndx when written
// out.
uint16_t Symbol::getShndx() const {}

bool Symbol::isCommon() const {}

void SymbolTableSection::assignIndices() {}

void SymbolTableSection::addSymbol(Twine Name, uint8_t Bind, uint8_t Type,
                                   SectionBase *DefinedIn, uint64_t Value,
                                   uint8_t Visibility, uint16_t Shndx,
                                   uint64_t SymbolSize) {}

Error SymbolTableSection::removeSectionReferences(
    bool AllowBrokenLinks, function_ref<bool(const SectionBase *)> ToRemove) {}

void SymbolTableSection::updateSymbols(function_ref<void(Symbol &)> Callable) {}

Error SymbolTableSection::removeSymbols(
    function_ref<bool(const Symbol &)> ToRemove) {}

void SymbolTableSection::replaceSectionReferences(
    const DenseMap<SectionBase *, SectionBase *> &FromTo) {}

Error SymbolTableSection::initialize(SectionTableRef SecTable) {}

void SymbolTableSection::finalize() {}

void SymbolTableSection::prepareForLayout() {}

void SymbolTableSection::fillShndxTable() {}

Expected<const Symbol *>
SymbolTableSection::getSymbolByIndex(uint32_t Index) const {}

Expected<Symbol *> SymbolTableSection::getSymbolByIndex(uint32_t Index) {}

template <class ELFT>
Error ELFSectionWriter<ELFT>::visit(const SymbolTableSection &Sec) {}

Error SymbolTableSection::accept(SectionVisitor &Visitor) const {}

Error SymbolTableSection::accept(MutableSectionVisitor &Visitor) {}

StringRef RelocationSectionBase::getNamePrefix() const {}

Error RelocationSection::removeSectionReferences(
    bool AllowBrokenLinks, function_ref<bool(const SectionBase *)> ToRemove) {}

template <class SymTabType>
Error RelocSectionWithSymtabBase<SymTabType>::initialize(
    SectionTableRef SecTable) {}

template <class SymTabType>
void RelocSectionWithSymtabBase<SymTabType>::finalize() {}

template <class ELFT>
static void setAddend(Elf_Rel_Impl<ELFT, false> &, uint64_t) {}

template <class ELFT>
static void setAddend(Elf_Rel_Impl<ELFT, true> &Rela, uint64_t Addend) {}

template <class RelRange, class T>
static void writeRel(const RelRange &Relocations, T *Buf, bool IsMips64EL) {}

template <class ELFT>
Error ELFSectionWriter<ELFT>::visit(const RelocationSection &Sec) {}

Error RelocationSection::accept(SectionVisitor &Visitor) const {}

Error RelocationSection::accept(MutableSectionVisitor &Visitor) {}

Error RelocationSection::removeSymbols(
    function_ref<bool(const Symbol &)> ToRemove) {}

void RelocationSection::markSymbols() {}

void RelocationSection::replaceSectionReferences(
    const DenseMap<SectionBase *, SectionBase *> &FromTo) {}

Error SectionWriter::visit(const DynamicRelocationSection &Sec) {}

Error DynamicRelocationSection::accept(SectionVisitor &Visitor) const {}

Error DynamicRelocationSection::accept(MutableSectionVisitor &Visitor) {}

Error DynamicRelocationSection::removeSectionReferences(
    bool AllowBrokenLinks, function_ref<bool(const SectionBase *)> ToRemove) {}

Error Section::removeSectionReferences(
    bool AllowBrokenDependency,
    function_ref<bool(const SectionBase *)> ToRemove) {}

void GroupSection::finalize() {}

Error GroupSection::removeSectionReferences(
    bool AllowBrokenLinks, function_ref<bool(const SectionBase *)> ToRemove) {}

Error GroupSection::removeSymbols(function_ref<bool(const Symbol &)> ToRemove) {}

void GroupSection::markSymbols() {}

void GroupSection::replaceSectionReferences(
    const DenseMap<SectionBase *, SectionBase *> &FromTo) {}

void GroupSection::onRemove() {}

Error Section::initialize(SectionTableRef SecTable) {}

void Section::finalize() {}

void GnuDebugLinkSection::init(StringRef File) {}

GnuDebugLinkSection::GnuDebugLinkSection(StringRef File,
                                         uint32_t PrecomputedCRC)
    :{}

template <class ELFT>
Error ELFSectionWriter<ELFT>::visit(const GnuDebugLinkSection &Sec) {}

Error GnuDebugLinkSection::accept(SectionVisitor &Visitor) const {}

Error GnuDebugLinkSection::accept(MutableSectionVisitor &Visitor) {}

template <class ELFT>
Error ELFSectionWriter<ELFT>::visit(const GroupSection &Sec) {}

Error GroupSection::accept(SectionVisitor &Visitor) const {}

Error GroupSection::accept(MutableSectionVisitor &Visitor) {}

// Returns true IFF a section is wholly inside the range of a segment
static bool sectionWithinSegment(const SectionBase &Sec, const Segment &Seg) {}

// Returns true IFF a segment's original offset is inside of another segment's
// range.
static bool segmentOverlapsSegment(const Segment &Child,
                                   const Segment &Parent) {}

static bool compareSegmentsByOffset(const Segment *A, const Segment *B) {}

void BasicELFBuilder::initFileHeader() {}

void BasicELFBuilder::initHeaderSegment() {}

StringTableSection *BasicELFBuilder::addStrTab() {}

SymbolTableSection *BasicELFBuilder::addSymTab(StringTableSection *StrTab) {}

Error BasicELFBuilder::initSections() {}

void BinaryELFBuilder::addData(SymbolTableSection *SymTab) {}

Expected<std::unique_ptr<Object>> BinaryELFBuilder::build() {}

// Adds sections from IHEX data file. Data should have been
// fully validated by this time.
void IHexELFBuilder::addDataSections() {}

Expected<std::unique_ptr<Object>> IHexELFBuilder::build() {}

template <class ELFT>
ELFBuilder<ELFT>::ELFBuilder(const ELFObjectFile<ELFT> &ElfObj, Object &Obj,
                             std::optional<StringRef> ExtractPartition)
    :{}

template <class ELFT> void ELFBuilder<ELFT>::setParentSegment(Segment &Child) {}

template <class ELFT> Error ELFBuilder<ELFT>::findEhdrOffset() {}

template <class ELFT>
Error ELFBuilder<ELFT>::readProgramHeaders(const ELFFile<ELFT> &HeadersFile) {}

template <class ELFT>
Error ELFBuilder<ELFT>::initGroupSection(GroupSection *GroupSec) {}

template <class ELFT>
Error ELFBuilder<ELFT>::initSymbolTable(SymbolTableSection *SymTab) {}

template <class ELFT>
static void getAddend(uint64_t &, const Elf_Rel_Impl<ELFT, false> &) {}

template <class ELFT>
static void getAddend(uint64_t &ToSet, const Elf_Rel_Impl<ELFT, true> &Rela) {}

template <class T>
static Error initRelocations(RelocationSection *Relocs, T RelRange) {}

Expected<SectionBase *> SectionTableRef::getSection(uint32_t Index,
                                                    Twine ErrMsg) {}

template <class T>
Expected<T *> SectionTableRef::getSectionOfType(uint32_t Index,
                                                Twine IndexErrMsg,
                                                Twine TypeErrMsg) {}

template <class ELFT>
Expected<SectionBase &> ELFBuilder<ELFT>::makeSection(const Elf_Shdr &Shdr) {}

template <class ELFT> Error ELFBuilder<ELFT>::readSectionHeaders() {}

template <class ELFT> Error ELFBuilder<ELFT>::readSections(bool EnsureSymtab) {}

template <class ELFT> Error ELFBuilder<ELFT>::build(bool EnsureSymtab) {}

Writer::~Writer() = default;

Reader::~Reader() = default;

Expected<std::unique_ptr<Object>>
BinaryReader::create(bool /*EnsureSymtab*/) const {}

Expected<std::vector<IHexRecord>> IHexReader::parse() const {}

Expected<std::unique_ptr<Object>>
IHexReader::create(bool /*EnsureSymtab*/) const {}

Expected<std::unique_ptr<Object>> ELFReader::create(bool EnsureSymtab) const {}

template <class ELFT> void ELFWriter<ELFT>::writeEhdr() {}

template <class ELFT> void ELFWriter<ELFT>::writePhdrs() {}

template <class ELFT> void ELFWriter<ELFT>::writeShdrs() {}

template <class ELFT> Error ELFWriter<ELFT>::writeSectionData() {}

template <class ELFT> void ELFWriter<ELFT>::writeSegmentData() {}

template <class ELFT>
ELFWriter<ELFT>::ELFWriter(Object &Obj, raw_ostream &Buf, bool WSH,
                           bool OnlyKeepDebug)
    :{}

Error Object::updateSection(StringRef Name, ArrayRef<uint8_t> Data) {}

Error Object::removeSections(
    bool AllowBrokenLinks, std::function<bool(const SectionBase &)> ToRemove) {}

Error Object::replaceSections(
    const DenseMap<SectionBase *, SectionBase *> &FromTo) {}

Error Object::removeSymbols(function_ref<bool(const Symbol &)> ToRemove) {}

Error Object::addNewSymbolTable() {}

// Orders segments such that if x = y->ParentSegment then y comes before x.
static void orderSegments(std::vector<Segment *> &Segments) {}

// This function finds a consistent layout for a list of segments starting from
// an Offset. It assumes that Segments have been sorted by orderSegments and
// returns an Offset one past the end of the last segment.
static uint64_t layoutSegments(std::vector<Segment *> &Segments,
                               uint64_t Offset) {}

// This function finds a consistent layout for a list of sections. It assumes
// that the ->ParentSegment of each section has already been laid out. The
// supplied starting Offset is used for the starting offset of any section that
// does not have a ParentSegment. It returns either the offset given if all
// sections had a ParentSegment or an offset one past the last section if there
// was a section that didn't have a ParentSegment.
template <class Range>
static uint64_t layoutSections(Range Sections, uint64_t Offset) {}

// Rewrite sh_offset after some sections are changed to SHT_NOBITS and thus
// occupy no space in the file.
static uint64_t layoutSectionsForOnlyKeepDebug(Object &Obj, uint64_t Off) {}

// Rewrite p_offset and p_filesz of non-PT_PHDR segments after sh_offset values
// have been updated.
static uint64_t layoutSegmentsForOnlyKeepDebug(std::vector<Segment *> &Segments,
                                               uint64_t HdrEnd) {}

template <class ELFT> void ELFWriter<ELFT>::initEhdrSegment() {}

template <class ELFT> void ELFWriter<ELFT>::assignOffsets() {}

template <class ELFT> size_t ELFWriter<ELFT>::totalSize() const {}

template <class ELFT> Error ELFWriter<ELFT>::write() {}

static Error removeUnneededSections(Object &Obj) {}

template <class ELFT> Error ELFWriter<ELFT>::finalize() {}

Error BinaryWriter::write() {}

Error BinaryWriter::finalize() {}

Error ASCIIHexWriter::checkSection(const SectionBase &S) const {}

Error ASCIIHexWriter::finalize() {}

uint64_t IHexWriter::writeEntryPointRecord(uint8_t *Buf) {}

uint64_t IHexWriter::writeEndOfFileRecord(uint8_t *Buf) {}

Expected<size_t>
IHexWriter::getTotalSize(WritableMemoryBuffer &EmptyBuffer) const {}

Error IHexWriter::write() {}

Error SRECSectionWriterBase::visit(const StringTableSection &Sec) {}

Error SRECSectionWriterBase::visit(const Section &Sec) {}

Error SRECSectionWriterBase::visit(const OwnedDataSection &Sec) {}

Error SRECSectionWriterBase::visit(const DynamicRelocationSection &Sec) {}

void SRECSectionWriter::writeRecord(SRecord &Record, uint64_t Off) {}

void SRECSectionWriterBase::writeRecords(uint32_t Entry) {}

void SRECSectionWriterBase::writeSection(const SectionBase &S,
                                         ArrayRef<uint8_t> Data) {}

Error SRECSectionWriter::visit(const StringTableSection &Sec) {}

SRecLineData SRecord::toString() const {}

uint8_t SRecord::getChecksum() const {}

size_t SRecord::getSize() const {}

uint8_t SRecord::getAddressSize() const {}

uint8_t SRecord::getCount() const {}

uint8_t SRecord::getType(uint32_t Address) {}

SRecord SRecord::getHeader(StringRef FileName) {}

size_t SRECWriter::writeHeader(uint8_t *Buf) {}

size_t SRECWriter::writeTerminator(uint8_t *Buf, uint8_t Type) {}

Expected<size_t>
SRECWriter::getTotalSize(WritableMemoryBuffer &EmptyBuffer) const {}

Error SRECWriter::write() {}

namespace llvm {
namespace objcopy {
namespace elf {

template class ELFBuilder<ELF64LE>;
template class ELFBuilder<ELF64BE>;
template class ELFBuilder<ELF32LE>;
template class ELFBuilder<ELF32BE>;

template class ELFWriter<ELF64LE>;
template class ELFWriter<ELF64BE>;
template class ELFWriter<ELF32LE>;
template class ELFWriter<ELF32BE>;

} // end namespace elf
} // end namespace objcopy
} // end namespace llvm