//===- ELFObjHandler.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 "llvm/InterfaceStub/ELFObjHandler.h" #include "llvm/InterfaceStub/IFSStub.h" #include "llvm/MC/StringTableBuilder.h" #include "llvm/Object/Binary.h" #include "llvm/Object/ELFObjectFile.h" #include "llvm/Object/ELFTypes.h" #include "llvm/Support/Errc.h" #include "llvm/Support/Error.h" #include "llvm/Support/FileOutputBuffer.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/MemoryBuffer.h" #include <optional> ELFObjectFile; usingnamespacellvm; usingnamespacellvm::object; usingnamespacellvm::ELF; namespace llvm { namespace ifs { // Simple struct to hold relevant .dynamic entries. struct DynamicEntries { … }; /// This initializes an ELF file header with information specific to a binary /// dynamic shared object. /// Offsets, indexes, links, etc. for section and program headers are just /// zero-initialized as they will be updated elsewhere. /// /// @param ElfHeader Target ELFT::Ehdr to populate. /// @param Machine Target architecture (e_machine from ELF specifications). template <class ELFT> static void initELFHeader(typename ELFT::Ehdr &ElfHeader, uint16_t Machine) { … } namespace { template <class ELFT> struct OutputSection { … }; template <class T, class ELFT> struct ContentSection : public OutputSection<ELFT> { … }; // This class just wraps StringTableBuilder for the purpose of adding a // default constructor. class ELFStringTableBuilder : public StringTableBuilder { … }; template <class ELFT> class ELFSymbolTableBuilder { … }; template <class ELFT> class ELFDynamicTableBuilder { … }; template <class ELFT> class ELFStubBuilder { … }; /// This function takes an error, and appends a string of text to the end of /// that error. Since "appending" to an Error isn't supported behavior of an /// Error, this function technically creates a new error with the combined /// message and consumes the old error. /// /// @param Err Source error. /// @param After Text to append at the end of Err's error message. Error appendToError(Error Err, StringRef After) { … } template <class ELFT> class DynSym { … }; } // end anonymous namespace /// This function behaves similarly to StringRef::substr(), but attempts to /// terminate the returned StringRef at the first null terminator. If no null /// terminator is found, an error is returned. /// /// @param Str Source string to create a substring from. /// @param Offset The start index of the desired substring. static Expected<StringRef> terminatedSubstr(StringRef Str, size_t Offset) { … } /// This function populates a DynamicEntries struct using an ELFT::DynRange. /// After populating the struct, the members are validated with /// some basic correctness checks. /// /// @param Dyn Target DynamicEntries struct to populate. /// @param DynTable Source dynamic table. template <class ELFT> static Error populateDynamic(DynamicEntries &Dyn, typename ELFT::DynRange DynTable) { … } /// This function creates an IFSSymbol and populates all members using /// information from a binary ELFT::Sym. /// /// @param SymName The desired name of the IFSSymbol. /// @param RawSym ELFT::Sym to extract symbol information from. template <class ELFT> static IFSSymbol createELFSym(StringRef SymName, const typename ELFT::Sym &RawSym) { … } /// This function populates an IFSStub with symbols using information read /// from an ELF binary. /// /// @param TargetStub IFSStub to add symbols to. /// @param DynSym Range of dynamic symbols to add to TargetStub. /// @param DynStr StringRef to the dynamic string table. template <class ELFT> static Error populateSymbols(IFSStub &TargetStub, const typename ELFT::SymRange DynSym, StringRef DynStr) { … } /// Returns a new IFSStub with all members populated from an ELFObjectFile. /// @param ElfObj Source ELFObjectFile. template <class ELFT> static Expected<std::unique_ptr<IFSStub>> buildStub(const ELFObjectFile<ELFT> &ElfObj) { … } /// This function opens a file for writing and then writes a binary ELF stub to /// the file. /// /// @param FilePath File path for writing the ELF binary. /// @param Stub Source InterFace Stub to generate a binary ELF stub from. template <class ELFT> static Error writeELFBinaryToFile(StringRef FilePath, const IFSStub &Stub, bool WriteIfChanged) { … } Expected<std::unique_ptr<IFSStub>> readELFFile(MemoryBufferRef Buf) { … } // This function wraps the ELFT writeELFBinaryToFile() so writeBinaryStub() // can be called without having to use ELFType templates directly. Error writeBinaryStub(StringRef FilePath, const IFSStub &Stub, bool WriteIfChanged) { … } } // end namespace ifs } // end namespace llvm