53  memset(&ElfHeader, 0, 
sizeof(ElfHeader));
 
   69  ElfHeader.e_ehsize = 
sizeof(
typename ELFT::Ehdr);
 
   70  ElfHeader.e_phentsize = 
sizeof(
typename ELFT::Phdr);
 
   71  ElfHeader.e_shentsize = 
sizeof(
typename ELFT::Shdr);
 
 
   75template <
class ELFT> 
struct OutputSection {
 
   76  using Elf_Shdr = 
typename ELFT::Shdr;
 
   87template <
class T, 
class ELFT>
 
   88struct ContentSection : 
public OutputSection<ELFT> {
 
   90  ContentSection() { this->NoBits = 
false; }
 
   95class ELFStringTableBuilder : 
public StringTableBuilder {
 
   97  ELFStringTableBuilder() : StringTableBuilder(StringTableBuilder::
ELF) {}
 
  100template <
class ELFT> 
class ELFSymbolTableBuilder {
 
  102  using Elf_Sym = 
typename ELFT::Sym;
 
  104  ELFSymbolTableBuilder() { Symbols.push_back({}); }
 
  106  void add(
size_t StNameOffset, uint64_t StSize, uint8_t StBind, uint8_t StType,
 
  107           uint8_t StOther, uint16_t StShndx) {
 
  109    S.st_name = StNameOffset;
 
  111    S.st_info = (StBind << 4) | (StType & 0xf);
 
  112    S.st_other = StOther;
 
  113    S.st_shndx = StShndx;
 
  114    Symbols.push_back(S);
 
  117  size_t getSize()
 const { 
return Symbols.size() * 
sizeof(Elf_Sym); }
 
  119  void write(uint8_t *Buf)
 const {
 
  120    memcpy(Buf, Symbols.data(), 
sizeof(Elf_Sym) * Symbols.size());
 
  127template <
class ELFT> 
class ELFDynamicTableBuilder {
 
  129  using Elf_Dyn = 
typename ELFT::Dyn;
 
  131  size_t addAddr(uint64_t 
Tag, uint64_t Addr) {
 
  134    Entry.d_un.d_ptr = Addr;
 
  135    Entries.push_back(Entry);
 
  136    return Entries.size() - 1;
 
  139  void modifyAddr(
size_t Index, uint64_t Addr) {
 
  140    Entries[
Index].d_un.d_ptr = Addr;
 
  143  size_t addValue(uint64_t 
Tag, uint64_t 
Value) {
 
  147    Entries.push_back(Entry);
 
  148    return Entries.size() - 1;
 
  151  void modifyValue(
size_t Index, uint64_t 
Value) {
 
  157    return (Entries.size() + 1) * 
sizeof(Elf_Dyn);
 
  160  void write(uint8_t *Buf)
 const {
 
  161    memcpy(Buf, Entries.data(), 
sizeof(Elf_Dyn) * Entries.size());
 
  163    memset(Buf + 
sizeof(Elf_Dyn) * Entries.size(), 0, 
sizeof(Elf_Dyn));
 
  170template <
class ELFT> 
class ELFStubBuilder {
 
  172  using Elf_Ehdr = 
typename ELFT::Ehdr;
 
  173  using Elf_Shdr = 
typename ELFT::Shdr;
 
  174  using Elf_Phdr = 
typename ELFT::Phdr;
 
  175  using Elf_Sym = 
typename ELFT::Sym;
 
  176  using Elf_Addr = 
typename ELFT::Addr;
 
  177  using Elf_Dyn = 
typename ELFT::Dyn;
 
  179  ELFStubBuilder(
const ELFStubBuilder &) = 
delete;
 
  180  ELFStubBuilder(ELFStubBuilder &&) = 
default;
 
  182  explicit ELFStubBuilder(
const IFSStub &Stub) {
 
  183    DynSym.Name = 
".dynsym";
 
  184    DynSym.Align = 
sizeof(Elf_Addr);
 
  185    DynStr.Name = 
".dynstr";
 
  187    DynTab.Name = 
".dynamic";
 
  188    DynTab.Align = 
sizeof(Elf_Addr);
 
  189    ShStrTab.Name = 
".shstrtab";
 
  193    for (
const IFSSymbol &Sym : Stub.Symbols)
 
  194      DynStr.Content.add(Sym.Name);
 
  195    for (
const std::string &
Lib : Stub.NeededLibs)
 
  196      DynStr.Content.add(
Lib);
 
  198      DynStr.Content.add(*Stub.SoName);
 
  200    std::vector<OutputSection<ELFT> *> Sections = {&DynSym, &DynStr, &DynTab,
 
  202    const OutputSection<ELFT> *LastSection = Sections.back();
 
  205    for (OutputSection<ELFT> *Sec : Sections) {
 
  206      Sec->Index = 
Index++;
 
  207      ShStrTab.Content.add(Sec->Name);
 
  209    ShStrTab.Content.finalize();
 
  210    ShStrTab.Size = ShStrTab.Content.getSize();
 
  211    DynStr.Content.finalize();
 
  212    DynStr.Size = DynStr.Content.getSize();
 
  215    for (
const IFSSymbol &Sym : Stub.Symbols) {
 
  220      uint16_t Shndx = Sym.Undefined ? 
SHN_UNDEF : 1;
 
  221      uint64_t 
Size = Sym.Size.value_or(0);
 
  222      DynSym.Content.add(DynStr.Content.getOffset(Sym.Name), 
Size, Bind,
 
  225    DynSym.Size = DynSym.Content.getSize();
 
  228    size_t DynSymIndex = DynTab.Content.addAddr(DT_SYMTAB, 0);
 
  229    size_t DynStrIndex = DynTab.Content.addAddr(DT_STRTAB, 0);
 
  230    DynTab.Content.addValue(DT_STRSZ, DynSym.Size);
 
  231    for (
const std::string &
Lib : Stub.NeededLibs)
 
  232      DynTab.Content.addValue(DT_NEEDED, DynStr.Content.getOffset(
Lib));
 
  234      DynTab.Content.addValue(DT_SONAME,
 
  235                              DynStr.Content.getOffset(*Stub.SoName));
 
  236    DynTab.Size = DynTab.Content.getSize();
 
  238    uint64_t CurrentOffset = 
sizeof(Elf_Ehdr);
 
  239    for (OutputSection<ELFT> *Sec : Sections) {
 
  240      Sec->Offset = 
alignTo(CurrentOffset, Sec->Align);
 
  241      Sec->Addr = Sec->Offset;
 
  242      CurrentOffset = Sec->Offset + Sec->Size;
 
  245    DynTab.Content.modifyAddr(DynSymIndex, DynSym.Addr);
 
  246    DynTab.Content.modifyAddr(DynStrIndex, DynStr.Addr);
 
  250    fillDynTabShdr(DynTab);
 
  251    fillStrTabShdr(ShStrTab);
 
  255    ElfHeader.e_shstrndx = ShStrTab.Index;
 
  256    ElfHeader.e_shnum = LastSection->Index + 1;
 
  258        alignTo(LastSection->Offset + LastSection->Size, 
sizeof(Elf_Addr));
 
  262    return ElfHeader.e_shoff + ElfHeader.e_shnum * 
sizeof(Elf_Shdr);
 
  267    DynSym.Content.write(
Data + DynSym.Shdr.sh_offset);
 
  268    DynStr.Content.write(
Data + DynStr.Shdr.sh_offset);
 
  269    DynTab.Content.write(
Data + DynTab.Shdr.sh_offset);
 
  270    ShStrTab.Content.write(
Data + ShStrTab.Shdr.sh_offset);
 
  271    writeShdr(
Data, DynSym);
 
  272    writeShdr(
Data, DynStr);
 
  273    writeShdr(
Data, DynTab);
 
  274    writeShdr(
Data, ShStrTab);
 
  279  ContentSection<ELFStringTableBuilder, ELFT> DynStr;
 
  280  ContentSection<ELFStringTableBuilder, ELFT> ShStrTab;
 
  281  ContentSection<ELFSymbolTableBuilder<ELFT>, ELFT> DynSym;
 
  282  ContentSection<ELFDynamicTableBuilder<ELFT>, ELFT> DynTab;
 
  288  void fillStrTabShdr(ContentSection<ELFStringTableBuilder, ELFT> &StrTab,
 
  289                      uint32_t ShFlags = 0)
 const {
 
  291    StrTab.Shdr.sh_flags = ShFlags;
 
  292    StrTab.Shdr.sh_addr = StrTab.Addr;
 
  293    StrTab.Shdr.sh_offset = StrTab.Offset;
 
  294    StrTab.Shdr.sh_info = 0;
 
  295    StrTab.Shdr.sh_size = StrTab.Size;
 
  296    StrTab.Shdr.sh_name = ShStrTab.Content.getOffset(StrTab.Name);
 
  297    StrTab.Shdr.sh_addralign = StrTab.Align;
 
  298    StrTab.Shdr.sh_entsize = 0;
 
  299    StrTab.Shdr.sh_link = 0;
 
  301  void fillSymTabShdr(ContentSection<ELFSymbolTableBuilder<ELFT>, ELFT> &SymTab,
 
  302                      uint32_t ShType)
 const {
 
  303    SymTab.Shdr.sh_type = ShType;
 
  305    SymTab.Shdr.sh_addr = SymTab.Addr;
 
  306    SymTab.Shdr.sh_offset = SymTab.Offset;
 
  310    SymTab.Shdr.sh_info = 1;
 
  311    SymTab.Shdr.sh_size = SymTab.Size;
 
  312    SymTab.Shdr.sh_name = this->ShStrTab.Content.getOffset(SymTab.Name);
 
  313    SymTab.Shdr.sh_addralign = SymTab.Align;
 
  314    SymTab.Shdr.sh_entsize = 
sizeof(Elf_Sym);
 
  315    SymTab.Shdr.sh_link = this->DynStr.Index;
 
  318      ContentSection<ELFDynamicTableBuilder<ELFT>, ELFT> &DynTab)
 const {
 
  321    DynTab.Shdr.sh_addr = DynTab.Addr;
 
  322    DynTab.Shdr.sh_offset = DynTab.Offset;
 
  323    DynTab.Shdr.sh_info = 0;
 
  324    DynTab.Shdr.sh_size = DynTab.Size;
 
  325    DynTab.Shdr.sh_name = this->ShStrTab.Content.getOffset(DynTab.Name);
 
  326    DynTab.Shdr.sh_addralign = DynTab.Align;
 
  327    DynTab.Shdr.sh_entsize = 
sizeof(Elf_Dyn);
 
  328    DynTab.Shdr.sh_link = this->DynStr.Index;
 
  330  uint64_t shdrOffset(
const OutputSection<ELFT> &Sec)
 const {
 
  331    return ElfHeader.e_shoff + Sec.Index * 
sizeof(Elf_Shdr);
 
  334  void writeShdr(uint8_t *
Data, 
const OutputSection<ELFT> &Sec)
 const {
 
  346Error appendToError(
Error Err, StringRef After) {
 
  348  raw_string_ostream Stream(Message);
 
  350  Stream << 
" " << After;
 
  355template <
class ELFT> 
class DynSym {
 
  356  using Elf_Shdr_Range = 
typename ELFT::ShdrRange;
 
  357  using Elf_Shdr = 
typename ELFT::Shdr;
 
  360  static Expected<DynSym> create(
const ELFFile<ELFT> &ElfFile,
 
  361                                 const DynamicEntries &DynEnt) {
 
  362    Expected<Elf_Shdr_Range> Shdrs = ElfFile.sections();
 
  364      return Shdrs.takeError();
 
  365    return DynSym(ElfFile, DynEnt, *Shdrs);
 
  368  Expected<const uint8_t *> getDynSym() {
 
  370      return ElfFile.base() + DynSymHdr->sh_offset;
 
  371    return getDynamicData(DynEnt.DynSymAddr, 
"dynamic symbol table");
 
  374  Expected<StringRef> getDynStr() {
 
  376      return ElfFile.getStringTableForSymtab(*DynSymHdr, Shdrs);
 
  377    Expected<const uint8_t *> DataOrErr = getDynamicData(
 
  378        DynEnt.StrTabAddr, 
"dynamic string table", DynEnt.StrSize);
 
  381    return StringRef(
reinterpret_cast<const char *
>(*DataOrErr),
 
  386  DynSym(
const ELFFile<ELFT> &ElfFile, 
const DynamicEntries &DynEnt,
 
  387         Elf_Shdr_Range Shdrs)
 
  388      : ElfFile(ElfFile), DynEnt(DynEnt), Shdrs(Shdrs),
 
  389        DynSymHdr(findDynSymHdr()) {}
 
  391  const Elf_Shdr *findDynSymHdr() {
 
  392    for (
const Elf_Shdr &Sec : Shdrs)
 
  401  Expected<const uint8_t *> getDynamicData(uint64_t EntAddr, StringRef Name,
 
  403    Expected<const uint8_t *> SecPtr = ElfFile.toMappedAddr(EntAddr);
 
  405      return appendToError(
 
  407          (
"when locating " + Name + 
" section contents").str());
 
  408    Expected<const uint8_t *> SecEndPtr = ElfFile.toMappedAddr(EntAddr + 
Size);
 
  410      return appendToError(
 
  412          (
"when locating " + Name + 
" section contents").str());
 
  416  const ELFFile<ELFT> &ElfFile;
 
  417  const DynamicEntries &DynEnt;
 
  418  Elf_Shdr_Range Shdrs;
 
  419  const Elf_Shdr *DynSymHdr;
 
  430  size_t StrEnd = Str.find(
'\0', 
Offset);
 
  433        "String overran bounds of string table (no null terminator)");
 
  436  size_t StrLen = StrEnd - 
Offset;
 
  437  return Str.substr(
Offset, StrLen);
 
 
  448                             typename ELFT::DynRange DynTable) {
 
  449  if (DynTable.empty())
 
  453  bool FoundDynStr = 
false;
 
  454  bool FoundDynStrSz = 
false;
 
  455  bool FoundDynSym = 
false;
 
  456  for (
auto &Entry : DynTable) {
 
  457    switch (Entry.d_tag) {
 
  466      Dyn.
StrSize = Entry.d_un.d_val;
 
  467      FoundDynStrSz = 
true;
 
  477      Dyn.
ElfHash = Entry.d_un.d_ptr;
 
  480      Dyn.
GnuHash = Entry.d_un.d_ptr;
 
  486        "Couldn't locate dynamic string table (no DT_STRTAB entry)");
 
  488  if (!FoundDynStrSz) {
 
  490        "Couldn't determine dynamic string table size (no DT_STRSZ entry)");
 
  494        "Couldn't locate dynamic symbol table (no DT_SYMTAB entry)");
 
  498                             "DT_SONAME string offset (0x%016" PRIx64
 
  499                             ") outside of dynamic string table",
 
  505                               "DT_NEEDED string offset (0x%016" PRIx64
 
  506                               ") outside of dynamic string table",
 
 
  521                              const typename ELFT::Sym &RawSym) {
 
  522  IFSSymbol TargetSym{std::string(SymName)};
 
  523  uint8_t Binding = RawSym.getBinding();
 
  525    TargetSym.
Weak = 
true;
 
  527    TargetSym.
Weak = 
false;
 
  529  TargetSym.
Undefined = RawSym.isUndefined();
 
  535    TargetSym.
Size = RawSym.st_size;
 
 
  548                             const typename ELFT::SymRange DynSym,
 
  551  for (
auto RawSym : DynSym.drop_front(1)) {
 
  553    uint8_t Binding = RawSym.getBinding();
 
  557    uint8_t Visibility = RawSym.getVisibility();
 
  566    TargetStub.
Symbols.push_back(std::move(Sym));
 
 
  577  using Elf_Dyn_Range = 
typename ELFT::DynRange;
 
  578  using Elf_Sym_Range = 
typename ELFT::SymRange;
 
  579  using Elf_Sym = 
typename ELFT::Sym;
 
  580  std::unique_ptr<IFSStub> DestStub = std::make_unique<IFSStub>();
 
  591    return std::move(Err);
 
  603  DestStub->Target.Arch = 
static_cast<IFSArch>(ElfFile.
getHeader().e_machine);
 
  604  DestStub->Target.BitWidth =
 
  606  DestStub->Target.Endianness =
 
  608  DestStub->Target.ObjectFormat = 
"ELF";
 
  615      return appendToError(NameOrErr.
takeError(), 
"when reading DT_SONAME");
 
  617    DestStub->SoName = std::string(*NameOrErr);
 
  625      return appendToError(LibNameOrErr.
takeError(), 
"when reading DT_NEEDED");
 
  627    DestStub->NeededLibs.push_back(std::string(*LibNameOrErr));
 
  638      return appendToError(DynSymPtr.
takeError(),
 
  639                           "when locating .dynsym section contents");
 
  641        reinterpret_cast<const Elf_Sym *
>(*DynSymPtr), *SymCount);
 
  644      return appendToError(std::move(SymReadError),
 
  645                           "when reading dynamic symbols");
 
  648  return std::move(DestStub);
 
 
  659  ELFStubBuilder<ELFT> Builder{Stub};
 
  661  std::vector<uint8_t> Buf(Builder.getSize());
 
  662  Builder.write(Buf.data());
 
  665    if (
ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrError =
 
  669      if ((*BufOrError)->getBufferSize() == Builder.getSize() &&
 
  670          !
memcmp((*BufOrError)->getBufferStart(), Buf.data(),
 
  681                                 " when trying to open `" + FilePath +
 
  685  std::unique_ptr<FileOutputBuffer> FileBuf = std::move(*BufOrError);
 
  686  memcpy(FileBuf->getBufferStart(), Buf.data(), Buf.size());
 
  688  return FileBuf->commit();
 
 
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
 
This supports reading and writing of elf dynamic shared objects.
 
This file defines an internal representation of an InterFace Stub.
 
static cl::opt< bool > WriteIfChanged("write-if-changed", cl::desc("Only write output if it changed"))
 
Merge contiguous icmps into a memcmp
 
Function const char TargetMachine * Machine
 
static unsigned getSize(unsigned Kind)
 
Represents either an error or a value T.
 
Lightweight error class with error context and mandatory checking.
 
static ErrorSuccess success()
Create a success value.
 
Tagged union holding either a T or a Error.
 
Error takeError()
Take ownership of the stored error.
 
reference get()
Returns a reference to the stored T value.
 
static LLVM_ABI Expected< std::unique_ptr< FileOutputBuffer > > create(StringRef FilePath, size_t Size, unsigned Flags=0)
Factory method to create an OutputBuffer object which manages a read/write buffer of the specified si...
 
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
 
StringRef - Represent a constant reference to a string, i.e.
 
static constexpr size_t npos
 
const Elf_Ehdr & getHeader() const
 
Expected< uint64_t > getDynSymtabSize() const
This function determines the number of dynamic symbols.
 
Expected< Elf_Dyn_Range > dynamicEntries() const
 
const ELFFile< ELFT > & getELFFile() const
 
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
 
static const char ElfMagic[]
 
static Error writeELFBinaryToFile(StringRef FilePath, const IFSStub &Stub, bool WriteIfChanged)
This function opens a file for writing and then writes a binary ELF stub to the file.
 
LLVM_ABI Expected< std::unique_ptr< IFSStub > > readELFFile(MemoryBufferRef Buf)
Attempt to read a binary ELF file from a MemoryBuffer.
 
LLVM_ABI Error writeBinaryStub(StringRef FilePath, const IFSStub &Stub, bool WriteIfChanged=false)
Attempt to write a binary ELF stub.
 
LLVM_ABI uint8_t convertIFSSymbolTypeToELF(IFSSymbolType SymbolType)
This function convert symbol type from IFS enum to ELF format Currently, STT_NOTYPE,...
 
static Expected< std::unique_ptr< IFSStub > > buildStub(const ELFObjectFile< ELFT > &ElfObj)
Returns a new IFSStub with all members populated from an ELFObjectFile.
 
static Error populateSymbols(IFSStub &TargetStub, const typename ELFT::SymRange DynSym, StringRef DynStr)
This function populates an IFSStub with symbols using information read from an ELF binary.
 
static void initELFHeader(typename ELFT::Ehdr &ElfHeader, uint16_t Machine)
This initializes an ELF file header with information specific to a binary dynamic shared object.
 
LLVM_ABI IFSBitWidthType convertELFBitWidthToIFS(uint8_t BitWidth)
This function extracts ELF bit width from e_ident[EI_CLASS] of an ELF file Currently,...
 
LLVM_ABI IFSEndiannessType convertELFEndiannessToIFS(uint8_t Endianness)
This function extracts ELF endianness from e_ident[EI_DATA] of an ELF file Currently,...
 
static Error populateDynamic(DynamicEntries &Dyn, typename ELFT::DynRange DynTable)
This function populates a DynamicEntries struct using an ELFT::DynRange.
 
static IFSSymbol createELFSym(StringRef SymName, const typename ELFT::Sym &RawSym)
This function creates an IFSSymbol and populates all members using information from a binary ELFT::Sy...
 
LLVM_ABI IFSSymbolType convertELFSymbolTypeToIFS(uint8_t SymbolType)
This function extracts symbol type from a symbol's st_info member and maps it to an IFSSymbolType enu...
 
static Expected< StringRef > terminatedSubstr(StringRef Str, size_t Offset)
This function behaves similarly to StringRef::substr(), but attempts to terminate the returned String...
 
LLVM_ABI Expected< std::unique_ptr< Binary > > createBinary(MemoryBufferRef Source, LLVMContext *Context=nullptr, bool InitContent=true)
Create a Binary from Source, autodetecting the file type.
 
This is an optimization pass for GlobalISel generic memory operations.
 
FunctionAddr VTableAddr Value
 
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
 
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
 
LLVM_ABI Error write(MCStreamer &Out, ArrayRef< std::string > Inputs, OnCuIndexOverflow OverflowOptValue)
 
static Error createError(const Twine &Err)
 
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
 
FunctionAddr VTableAddr uintptr_t uintptr_t Data
 
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
 
ArrayRef(const T &OneElt) -> ArrayRef< T >
 
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
 
void consumeError(Error Err)
Consume a Error without doing anything.
 
This struct is a compact representation of a valid (non-zero power of two) alignment.
 
std::optional< uint64_t > ElfHash
 
std::vector< uint64_t > NeededLibNames
 
std::optional< uint64_t > GnuHash
 
std::optional< uint64_t > SONameOffset
 
std::vector< IFSSymbol > Symbols
 
std::optional< uint64_t > Size
 
std::optional< IFSEndiannessType > Endianness
 
std::optional< IFSBitWidthType > BitWidth
 
std::optional< IFSArch > Arch