Import prebuilt clang toolchain for linux.
diff --git a/linux-x64/clang/include/llvm/Object/Archive.h b/linux-x64/clang/include/llvm/Object/Archive.h
new file mode 100644
index 0000000..5a1512b
--- /dev/null
+++ b/linux-x64/clang/include/llvm/Object/Archive.h
@@ -0,0 +1,289 @@
+//===- Archive.h - ar archive file format -----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the ar archive file format class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_ARCHIVE_H
+#define LLVM_OBJECT_ARCHIVE_H
+
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/Object/Binary.h"
+#include "llvm/Support/Chrono.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace llvm {
+namespace object {
+
+class Archive;
+
+class ArchiveMemberHeader {
+public:
+ friend class Archive;
+
+ ArchiveMemberHeader(Archive const *Parent, const char *RawHeaderPtr,
+ uint64_t Size, Error *Err);
+ // ArchiveMemberHeader() = default;
+
+ /// Get the name without looking up long names.
+ Expected<StringRef> getRawName() const;
+
+ /// Get the name looking up long names.
+ Expected<StringRef> getName(uint64_t Size) const;
+
+ /// Members are not larger than 4GB.
+ Expected<uint32_t> getSize() const;
+
+ Expected<sys::fs::perms> getAccessMode() const;
+ Expected<sys::TimePoint<std::chrono::seconds>> getLastModified() const;
+
+ StringRef getRawLastModified() const {
+ return StringRef(ArMemHdr->LastModified,
+ sizeof(ArMemHdr->LastModified)).rtrim(' ');
+ }
+
+ Expected<unsigned> getUID() const;
+ Expected<unsigned> getGID() const;
+
+ // This returns the size of the private struct ArMemHdrType
+ uint64_t getSizeOf() const {
+ return sizeof(ArMemHdrType);
+ }
+
+private:
+ struct ArMemHdrType {
+ char Name[16];
+ char LastModified[12];
+ char UID[6];
+ char GID[6];
+ char AccessMode[8];
+ char Size[10]; ///< Size of data, not including header or padding.
+ char Terminator[2];
+ };
+ Archive const *Parent;
+ ArMemHdrType const *ArMemHdr;
+};
+
+class Archive : public Binary {
+ virtual void anchor();
+
+public:
+ class Child {
+ friend Archive;
+ friend ArchiveMemberHeader;
+
+ const Archive *Parent;
+ ArchiveMemberHeader Header;
+ /// \brief Includes header but not padding byte.
+ StringRef Data;
+ /// \brief Offset from Data to the start of the file.
+ uint16_t StartOfFile;
+
+ Expected<bool> isThinMember() const;
+
+ public:
+ Child(const Archive *Parent, const char *Start, Error *Err);
+ Child(const Archive *Parent, StringRef Data, uint16_t StartOfFile);
+
+ bool operator ==(const Child &other) const {
+ assert(!Parent || !other.Parent || Parent == other.Parent);
+ return Data.begin() == other.Data.begin();
+ }
+
+ const Archive *getParent() const { return Parent; }
+ Expected<Child> getNext() const;
+
+ Expected<StringRef> getName() const;
+ Expected<std::string> getFullName() const;
+ Expected<StringRef> getRawName() const { return Header.getRawName(); }
+
+ Expected<sys::TimePoint<std::chrono::seconds>> getLastModified() const {
+ return Header.getLastModified();
+ }
+
+ StringRef getRawLastModified() const {
+ return Header.getRawLastModified();
+ }
+
+ Expected<unsigned> getUID() const { return Header.getUID(); }
+ Expected<unsigned> getGID() const { return Header.getGID(); }
+
+ Expected<sys::fs::perms> getAccessMode() const {
+ return Header.getAccessMode();
+ }
+
+ /// \return the size of the archive member without the header or padding.
+ Expected<uint64_t> getSize() const;
+ /// \return the size in the archive header for this member.
+ Expected<uint64_t> getRawSize() const;
+
+ Expected<StringRef> getBuffer() const;
+ uint64_t getChildOffset() const;
+
+ Expected<MemoryBufferRef> getMemoryBufferRef() const;
+
+ Expected<std::unique_ptr<Binary>>
+ getAsBinary(LLVMContext *Context = nullptr) const;
+ };
+
+ class child_iterator {
+ Child C;
+ Error *E = nullptr;
+
+ public:
+ child_iterator() : C(Child(nullptr, nullptr, nullptr)) {}
+ child_iterator(const Child &C, Error *E) : C(C), E(E) {}
+
+ const Child *operator->() const { return &C; }
+ const Child &operator*() const { return C; }
+
+ bool operator==(const child_iterator &other) const {
+ // Ignore errors here: If an error occurred during increment then getNext
+ // will have been set to child_end(), and the following comparison should
+ // do the right thing.
+ return C == other.C;
+ }
+
+ bool operator!=(const child_iterator &other) const {
+ return !(*this == other);
+ }
+
+ // Code in loops with child_iterators must check for errors on each loop
+ // iteration. And if there is an error break out of the loop.
+ child_iterator &operator++() { // Preincrement
+ assert(E && "Can't increment iterator with no Error attached");
+ ErrorAsOutParameter ErrAsOutParam(E);
+ if (auto ChildOrErr = C.getNext())
+ C = *ChildOrErr;
+ else {
+ C = C.getParent()->child_end().C;
+ *E = ChildOrErr.takeError();
+ E = nullptr;
+ }
+ return *this;
+ }
+ };
+
+ class Symbol {
+ const Archive *Parent;
+ uint32_t SymbolIndex;
+ uint32_t StringIndex; // Extra index to the string.
+
+ public:
+ Symbol(const Archive *p, uint32_t symi, uint32_t stri)
+ : Parent(p)
+ , SymbolIndex(symi)
+ , StringIndex(stri) {}
+
+ bool operator ==(const Symbol &other) const {
+ return (Parent == other.Parent) && (SymbolIndex == other.SymbolIndex);
+ }
+
+ StringRef getName() const;
+ Expected<Child> getMember() const;
+ Symbol getNext() const;
+ };
+
+ class symbol_iterator {
+ Symbol symbol;
+
+ public:
+ symbol_iterator(const Symbol &s) : symbol(s) {}
+
+ const Symbol *operator->() const { return &symbol; }
+ const Symbol &operator*() const { return symbol; }
+
+ bool operator==(const symbol_iterator &other) const {
+ return symbol == other.symbol;
+ }
+
+ bool operator!=(const symbol_iterator &other) const {
+ return !(*this == other);
+ }
+
+ symbol_iterator& operator++() { // Preincrement
+ symbol = symbol.getNext();
+ return *this;
+ }
+ };
+
+ Archive(MemoryBufferRef Source, Error &Err);
+ static Expected<std::unique_ptr<Archive>> create(MemoryBufferRef Source);
+
+ enum Kind {
+ K_GNU,
+ K_GNU64,
+ K_BSD,
+ K_DARWIN,
+ K_DARWIN64,
+ K_COFF
+ };
+
+ Kind kind() const { return (Kind)Format; }
+ bool isThin() const { return IsThin; }
+
+ child_iterator child_begin(Error &Err, bool SkipInternal = true) const;
+ child_iterator child_end() const;
+ iterator_range<child_iterator> children(Error &Err,
+ bool SkipInternal = true) const {
+ return make_range(child_begin(Err, SkipInternal), child_end());
+ }
+
+ symbol_iterator symbol_begin() const;
+ symbol_iterator symbol_end() const;
+ iterator_range<symbol_iterator> symbols() const {
+ return make_range(symbol_begin(), symbol_end());
+ }
+
+ // Cast methods.
+ static bool classof(Binary const *v) {
+ return v->isArchive();
+ }
+
+ // check if a symbol is in the archive
+ Expected<Optional<Child>> findSym(StringRef name) const;
+
+ bool isEmpty() const;
+ bool hasSymbolTable() const;
+ StringRef getSymbolTable() const { return SymbolTable; }
+ StringRef getStringTable() const { return StringTable; }
+ uint32_t getNumberOfSymbols() const;
+
+ std::vector<std::unique_ptr<MemoryBuffer>> takeThinBuffers() {
+ return std::move(ThinBuffers);
+ }
+
+private:
+ StringRef SymbolTable;
+ StringRef StringTable;
+
+ StringRef FirstRegularData;
+ uint16_t FirstRegularStartOfFile = -1;
+ void setFirstRegular(const Child &C);
+
+ unsigned Format : 3;
+ unsigned IsThin : 1;
+ mutable std::vector<std::unique_ptr<MemoryBuffer>> ThinBuffers;
+};
+
+} // end namespace object
+} // end namespace llvm
+
+#endif // LLVM_OBJECT_ARCHIVE_H
diff --git a/linux-x64/clang/include/llvm/Object/ArchiveWriter.h b/linux-x64/clang/include/llvm/Object/ArchiveWriter.h
new file mode 100644
index 0000000..495b943
--- /dev/null
+++ b/linux-x64/clang/include/llvm/Object/ArchiveWriter.h
@@ -0,0 +1,47 @@
+//===- ArchiveWriter.h - ar archive file format writer ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Declares the writeArchive function for writing an archive file.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_ARCHIVEWRITER_H
+#define LLVM_OBJECT_ARCHIVEWRITER_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Object/Archive.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/FileSystem.h"
+
+namespace llvm {
+
+struct NewArchiveMember {
+ std::unique_ptr<MemoryBuffer> Buf;
+ StringRef MemberName;
+ sys::TimePoint<std::chrono::seconds> ModTime;
+ unsigned UID = 0, GID = 0, Perms = 0644;
+
+ bool IsNew = false;
+ NewArchiveMember() = default;
+ NewArchiveMember(MemoryBufferRef BufRef);
+
+ static Expected<NewArchiveMember>
+ getOldMember(const object::Archive::Child &OldMember, bool Deterministic);
+
+ static Expected<NewArchiveMember> getFile(StringRef FileName,
+ bool Deterministic);
+};
+
+Error writeArchive(StringRef ArcName, ArrayRef<NewArchiveMember> NewMembers,
+ bool WriteSymtab, object::Archive::Kind Kind,
+ bool Deterministic, bool Thin,
+ std::unique_ptr<MemoryBuffer> OldArchiveBuf = nullptr);
+}
+
+#endif
diff --git a/linux-x64/clang/include/llvm/Object/Binary.h b/linux-x64/clang/include/llvm/Object/Binary.h
new file mode 100644
index 0000000..5e93691
--- /dev/null
+++ b/linux-x64/clang/include/llvm/Object/Binary.h
@@ -0,0 +1,219 @@
+//===- Binary.h - A generic binary file -------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the Binary class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_BINARY_H
+#define LLVM_OBJECT_BINARY_H
+
+#include "llvm/ADT/Triple.h"
+#include "llvm/Object/Error.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include <algorithm>
+#include <memory>
+#include <utility>
+
+namespace llvm {
+
+class LLVMContext;
+class StringRef;
+
+namespace object {
+
+class Binary {
+private:
+ unsigned int TypeID;
+
+protected:
+ MemoryBufferRef Data;
+
+ Binary(unsigned int Type, MemoryBufferRef Source);
+
+ enum {
+ ID_Archive,
+ ID_MachOUniversalBinary,
+ ID_COFFImportFile,
+ ID_IR, // LLVM IR
+
+ ID_WinRes, // Windows resource (.res) file.
+
+ // Object and children.
+ ID_StartObjects,
+ ID_COFF,
+
+ ID_ELF32L, // ELF 32-bit, little endian
+ ID_ELF32B, // ELF 32-bit, big endian
+ ID_ELF64L, // ELF 64-bit, little endian
+ ID_ELF64B, // ELF 64-bit, big endian
+
+ ID_MachO32L, // MachO 32-bit, little endian
+ ID_MachO32B, // MachO 32-bit, big endian
+ ID_MachO64L, // MachO 64-bit, little endian
+ ID_MachO64B, // MachO 64-bit, big endian
+
+ ID_Wasm,
+
+ ID_EndObjects
+ };
+
+ static inline unsigned int getELFType(bool isLE, bool is64Bits) {
+ if (isLE)
+ return is64Bits ? ID_ELF64L : ID_ELF32L;
+ else
+ return is64Bits ? ID_ELF64B : ID_ELF32B;
+ }
+
+ static unsigned int getMachOType(bool isLE, bool is64Bits) {
+ if (isLE)
+ return is64Bits ? ID_MachO64L : ID_MachO32L;
+ else
+ return is64Bits ? ID_MachO64B : ID_MachO32B;
+ }
+
+public:
+ Binary() = delete;
+ Binary(const Binary &other) = delete;
+ virtual ~Binary();
+
+ StringRef getData() const;
+ StringRef getFileName() const;
+ MemoryBufferRef getMemoryBufferRef() const;
+
+ // Cast methods.
+ unsigned int getType() const { return TypeID; }
+
+ // Convenience methods
+ bool isObject() const {
+ return TypeID > ID_StartObjects && TypeID < ID_EndObjects;
+ }
+
+ bool isSymbolic() const { return isIR() || isObject() || isCOFFImportFile(); }
+
+ bool isArchive() const {
+ return TypeID == ID_Archive;
+ }
+
+ bool isMachOUniversalBinary() const {
+ return TypeID == ID_MachOUniversalBinary;
+ }
+
+ bool isELF() const {
+ return TypeID >= ID_ELF32L && TypeID <= ID_ELF64B;
+ }
+
+ bool isMachO() const {
+ return TypeID >= ID_MachO32L && TypeID <= ID_MachO64B;
+ }
+
+ bool isCOFF() const {
+ return TypeID == ID_COFF;
+ }
+
+ bool isWasm() const { return TypeID == ID_Wasm; }
+
+ bool isCOFFImportFile() const {
+ return TypeID == ID_COFFImportFile;
+ }
+
+ bool isIR() const {
+ return TypeID == ID_IR;
+ }
+
+ bool isLittleEndian() const {
+ return !(TypeID == ID_ELF32B || TypeID == ID_ELF64B ||
+ TypeID == ID_MachO32B || TypeID == ID_MachO64B);
+ }
+
+ bool isWinRes() const { return TypeID == ID_WinRes; }
+
+ Triple::ObjectFormatType getTripleObjectFormat() const {
+ if (isCOFF())
+ return Triple::COFF;
+ if (isMachO())
+ return Triple::MachO;
+ if (isELF())
+ return Triple::ELF;
+ return Triple::UnknownObjectFormat;
+ }
+
+ static std::error_code checkOffset(MemoryBufferRef M, uintptr_t Addr,
+ const uint64_t Size) {
+ if (Addr + Size < Addr || Addr + Size < Size ||
+ Addr + Size > uintptr_t(M.getBufferEnd()) ||
+ Addr < uintptr_t(M.getBufferStart())) {
+ return object_error::unexpected_eof;
+ }
+ return std::error_code();
+ }
+};
+
+/// @brief Create a Binary from Source, autodetecting the file type.
+///
+/// @param Source The data to create the Binary from.
+Expected<std::unique_ptr<Binary>> createBinary(MemoryBufferRef Source,
+ LLVMContext *Context = nullptr);
+
+template <typename T> class OwningBinary {
+ std::unique_ptr<T> Bin;
+ std::unique_ptr<MemoryBuffer> Buf;
+
+public:
+ OwningBinary();
+ OwningBinary(std::unique_ptr<T> Bin, std::unique_ptr<MemoryBuffer> Buf);
+ OwningBinary(OwningBinary<T>&& Other);
+ OwningBinary<T> &operator=(OwningBinary<T> &&Other);
+
+ std::pair<std::unique_ptr<T>, std::unique_ptr<MemoryBuffer>> takeBinary();
+
+ T* getBinary();
+ const T* getBinary() const;
+};
+
+template <typename T>
+OwningBinary<T>::OwningBinary(std::unique_ptr<T> Bin,
+ std::unique_ptr<MemoryBuffer> Buf)
+ : Bin(std::move(Bin)), Buf(std::move(Buf)) {}
+
+template <typename T> OwningBinary<T>::OwningBinary() = default;
+
+template <typename T>
+OwningBinary<T>::OwningBinary(OwningBinary &&Other)
+ : Bin(std::move(Other.Bin)), Buf(std::move(Other.Buf)) {}
+
+template <typename T>
+OwningBinary<T> &OwningBinary<T>::operator=(OwningBinary &&Other) {
+ Bin = std::move(Other.Bin);
+ Buf = std::move(Other.Buf);
+ return *this;
+}
+
+template <typename T>
+std::pair<std::unique_ptr<T>, std::unique_ptr<MemoryBuffer>>
+OwningBinary<T>::takeBinary() {
+ return std::make_pair(std::move(Bin), std::move(Buf));
+}
+
+template <typename T> T* OwningBinary<T>::getBinary() {
+ return Bin.get();
+}
+
+template <typename T> const T* OwningBinary<T>::getBinary() const {
+ return Bin.get();
+}
+
+Expected<OwningBinary<Binary>> createBinary(StringRef Path);
+
+} // end namespace object
+
+} // end namespace llvm
+
+#endif // LLVM_OBJECT_BINARY_H
diff --git a/linux-x64/clang/include/llvm/Object/COFF.h b/linux-x64/clang/include/llvm/Object/COFF.h
new file mode 100644
index 0000000..9190149
--- /dev/null
+++ b/linux-x64/clang/include/llvm/Object/COFF.h
@@ -0,0 +1,1226 @@
+//===- COFF.h - COFF object file implementation -----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the COFFObjectFile class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_COFF_H
+#define LLVM_OBJECT_COFF_H
+
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/BinaryFormat/COFF.h"
+#include "llvm/MC/SubtargetFeature.h"
+#include "llvm/Object/Binary.h"
+#include "llvm/Object/CVDebugRecord.h"
+#include "llvm/Object/Error.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/BinaryByteStream.h"
+#include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <system_error>
+
+namespace llvm {
+
+template <typename T> class ArrayRef;
+
+namespace object {
+
+class BaseRelocRef;
+class DelayImportDirectoryEntryRef;
+class ExportDirectoryEntryRef;
+class ImportDirectoryEntryRef;
+class ImportedSymbolRef;
+class ResourceSectionRef;
+
+using import_directory_iterator = content_iterator<ImportDirectoryEntryRef>;
+using delay_import_directory_iterator =
+ content_iterator<DelayImportDirectoryEntryRef>;
+using export_directory_iterator = content_iterator<ExportDirectoryEntryRef>;
+using imported_symbol_iterator = content_iterator<ImportedSymbolRef>;
+using base_reloc_iterator = content_iterator<BaseRelocRef>;
+
+/// The DOS compatible header at the front of all PE/COFF executables.
+struct dos_header {
+ char Magic[2];
+ support::ulittle16_t UsedBytesInTheLastPage;
+ support::ulittle16_t FileSizeInPages;
+ support::ulittle16_t NumberOfRelocationItems;
+ support::ulittle16_t HeaderSizeInParagraphs;
+ support::ulittle16_t MinimumExtraParagraphs;
+ support::ulittle16_t MaximumExtraParagraphs;
+ support::ulittle16_t InitialRelativeSS;
+ support::ulittle16_t InitialSP;
+ support::ulittle16_t Checksum;
+ support::ulittle16_t InitialIP;
+ support::ulittle16_t InitialRelativeCS;
+ support::ulittle16_t AddressOfRelocationTable;
+ support::ulittle16_t OverlayNumber;
+ support::ulittle16_t Reserved[4];
+ support::ulittle16_t OEMid;
+ support::ulittle16_t OEMinfo;
+ support::ulittle16_t Reserved2[10];
+ support::ulittle32_t AddressOfNewExeHeader;
+};
+
+struct coff_file_header {
+ support::ulittle16_t Machine;
+ support::ulittle16_t NumberOfSections;
+ support::ulittle32_t TimeDateStamp;
+ support::ulittle32_t PointerToSymbolTable;
+ support::ulittle32_t NumberOfSymbols;
+ support::ulittle16_t SizeOfOptionalHeader;
+ support::ulittle16_t Characteristics;
+
+ bool isImportLibrary() const { return NumberOfSections == 0xffff; }
+};
+
+struct coff_bigobj_file_header {
+ support::ulittle16_t Sig1;
+ support::ulittle16_t Sig2;
+ support::ulittle16_t Version;
+ support::ulittle16_t Machine;
+ support::ulittle32_t TimeDateStamp;
+ uint8_t UUID[16];
+ support::ulittle32_t unused1;
+ support::ulittle32_t unused2;
+ support::ulittle32_t unused3;
+ support::ulittle32_t unused4;
+ support::ulittle32_t NumberOfSections;
+ support::ulittle32_t PointerToSymbolTable;
+ support::ulittle32_t NumberOfSymbols;
+};
+
+/// The 32-bit PE header that follows the COFF header.
+struct pe32_header {
+ support::ulittle16_t Magic;
+ uint8_t MajorLinkerVersion;
+ uint8_t MinorLinkerVersion;
+ support::ulittle32_t SizeOfCode;
+ support::ulittle32_t SizeOfInitializedData;
+ support::ulittle32_t SizeOfUninitializedData;
+ support::ulittle32_t AddressOfEntryPoint;
+ support::ulittle32_t BaseOfCode;
+ support::ulittle32_t BaseOfData;
+ support::ulittle32_t ImageBase;
+ support::ulittle32_t SectionAlignment;
+ support::ulittle32_t FileAlignment;
+ support::ulittle16_t MajorOperatingSystemVersion;
+ support::ulittle16_t MinorOperatingSystemVersion;
+ support::ulittle16_t MajorImageVersion;
+ support::ulittle16_t MinorImageVersion;
+ support::ulittle16_t MajorSubsystemVersion;
+ support::ulittle16_t MinorSubsystemVersion;
+ support::ulittle32_t Win32VersionValue;
+ support::ulittle32_t SizeOfImage;
+ support::ulittle32_t SizeOfHeaders;
+ support::ulittle32_t CheckSum;
+ support::ulittle16_t Subsystem;
+ // FIXME: This should be DllCharacteristics.
+ support::ulittle16_t DLLCharacteristics;
+ support::ulittle32_t SizeOfStackReserve;
+ support::ulittle32_t SizeOfStackCommit;
+ support::ulittle32_t SizeOfHeapReserve;
+ support::ulittle32_t SizeOfHeapCommit;
+ support::ulittle32_t LoaderFlags;
+ // FIXME: This should be NumberOfRvaAndSizes.
+ support::ulittle32_t NumberOfRvaAndSize;
+};
+
+/// The 64-bit PE header that follows the COFF header.
+struct pe32plus_header {
+ support::ulittle16_t Magic;
+ uint8_t MajorLinkerVersion;
+ uint8_t MinorLinkerVersion;
+ support::ulittle32_t SizeOfCode;
+ support::ulittle32_t SizeOfInitializedData;
+ support::ulittle32_t SizeOfUninitializedData;
+ support::ulittle32_t AddressOfEntryPoint;
+ support::ulittle32_t BaseOfCode;
+ support::ulittle64_t ImageBase;
+ support::ulittle32_t SectionAlignment;
+ support::ulittle32_t FileAlignment;
+ support::ulittle16_t MajorOperatingSystemVersion;
+ support::ulittle16_t MinorOperatingSystemVersion;
+ support::ulittle16_t MajorImageVersion;
+ support::ulittle16_t MinorImageVersion;
+ support::ulittle16_t MajorSubsystemVersion;
+ support::ulittle16_t MinorSubsystemVersion;
+ support::ulittle32_t Win32VersionValue;
+ support::ulittle32_t SizeOfImage;
+ support::ulittle32_t SizeOfHeaders;
+ support::ulittle32_t CheckSum;
+ support::ulittle16_t Subsystem;
+ support::ulittle16_t DLLCharacteristics;
+ support::ulittle64_t SizeOfStackReserve;
+ support::ulittle64_t SizeOfStackCommit;
+ support::ulittle64_t SizeOfHeapReserve;
+ support::ulittle64_t SizeOfHeapCommit;
+ support::ulittle32_t LoaderFlags;
+ support::ulittle32_t NumberOfRvaAndSize;
+};
+
+struct data_directory {
+ support::ulittle32_t RelativeVirtualAddress;
+ support::ulittle32_t Size;
+};
+
+struct debug_directory {
+ support::ulittle32_t Characteristics;
+ support::ulittle32_t TimeDateStamp;
+ support::ulittle16_t MajorVersion;
+ support::ulittle16_t MinorVersion;
+ support::ulittle32_t Type;
+ support::ulittle32_t SizeOfData;
+ support::ulittle32_t AddressOfRawData;
+ support::ulittle32_t PointerToRawData;
+};
+
+template <typename IntTy>
+struct import_lookup_table_entry {
+ IntTy Data;
+
+ bool isOrdinal() const { return Data < 0; }
+
+ uint16_t getOrdinal() const {
+ assert(isOrdinal() && "ILT entry is not an ordinal!");
+ return Data & 0xFFFF;
+ }
+
+ uint32_t getHintNameRVA() const {
+ assert(!isOrdinal() && "ILT entry is not a Hint/Name RVA!");
+ return Data & 0xFFFFFFFF;
+ }
+};
+
+using import_lookup_table_entry32 =
+ import_lookup_table_entry<support::little32_t>;
+using import_lookup_table_entry64 =
+ import_lookup_table_entry<support::little64_t>;
+
+struct delay_import_directory_table_entry {
+ // dumpbin reports this field as "Characteristics" instead of "Attributes".
+ support::ulittle32_t Attributes;
+ support::ulittle32_t Name;
+ support::ulittle32_t ModuleHandle;
+ support::ulittle32_t DelayImportAddressTable;
+ support::ulittle32_t DelayImportNameTable;
+ support::ulittle32_t BoundDelayImportTable;
+ support::ulittle32_t UnloadDelayImportTable;
+ support::ulittle32_t TimeStamp;
+};
+
+struct export_directory_table_entry {
+ support::ulittle32_t ExportFlags;
+ support::ulittle32_t TimeDateStamp;
+ support::ulittle16_t MajorVersion;
+ support::ulittle16_t MinorVersion;
+ support::ulittle32_t NameRVA;
+ support::ulittle32_t OrdinalBase;
+ support::ulittle32_t AddressTableEntries;
+ support::ulittle32_t NumberOfNamePointers;
+ support::ulittle32_t ExportAddressTableRVA;
+ support::ulittle32_t NamePointerRVA;
+ support::ulittle32_t OrdinalTableRVA;
+};
+
+union export_address_table_entry {
+ support::ulittle32_t ExportRVA;
+ support::ulittle32_t ForwarderRVA;
+};
+
+using export_name_pointer_table_entry = support::ulittle32_t;
+using export_ordinal_table_entry = support::ulittle16_t;
+
+struct StringTableOffset {
+ support::ulittle32_t Zeroes;
+ support::ulittle32_t Offset;
+};
+
+template <typename SectionNumberType>
+struct coff_symbol {
+ union {
+ char ShortName[COFF::NameSize];
+ StringTableOffset Offset;
+ } Name;
+
+ support::ulittle32_t Value;
+ SectionNumberType SectionNumber;
+
+ support::ulittle16_t Type;
+
+ uint8_t StorageClass;
+ uint8_t NumberOfAuxSymbols;
+};
+
+using coff_symbol16 = coff_symbol<support::ulittle16_t>;
+using coff_symbol32 = coff_symbol<support::ulittle32_t>;
+
+// Contains only common parts of coff_symbol16 and coff_symbol32.
+struct coff_symbol_generic {
+ union {
+ char ShortName[COFF::NameSize];
+ StringTableOffset Offset;
+ } Name;
+ support::ulittle32_t Value;
+};
+
+struct coff_aux_section_definition;
+
+class COFFSymbolRef {
+public:
+ COFFSymbolRef() = default;
+ COFFSymbolRef(const coff_symbol16 *CS) : CS16(CS) {}
+ COFFSymbolRef(const coff_symbol32 *CS) : CS32(CS) {}
+
+ const void *getRawPtr() const {
+ return CS16 ? static_cast<const void *>(CS16) : CS32;
+ }
+
+ const coff_symbol_generic *getGeneric() const {
+ if (CS16)
+ return reinterpret_cast<const coff_symbol_generic *>(CS16);
+ return reinterpret_cast<const coff_symbol_generic *>(CS32);
+ }
+
+ friend bool operator<(COFFSymbolRef A, COFFSymbolRef B) {
+ return A.getRawPtr() < B.getRawPtr();
+ }
+
+ bool isBigObj() const {
+ if (CS16)
+ return false;
+ if (CS32)
+ return true;
+ llvm_unreachable("COFFSymbolRef points to nothing!");
+ }
+
+ const char *getShortName() const {
+ return CS16 ? CS16->Name.ShortName : CS32->Name.ShortName;
+ }
+
+ const StringTableOffset &getStringTableOffset() const {
+ assert(isSet() && "COFFSymbolRef points to nothing!");
+ return CS16 ? CS16->Name.Offset : CS32->Name.Offset;
+ }
+
+ uint32_t getValue() const { return CS16 ? CS16->Value : CS32->Value; }
+
+ int32_t getSectionNumber() const {
+ assert(isSet() && "COFFSymbolRef points to nothing!");
+ if (CS16) {
+ // Reserved sections are returned as negative numbers.
+ if (CS16->SectionNumber <= COFF::MaxNumberOfSections16)
+ return CS16->SectionNumber;
+ return static_cast<int16_t>(CS16->SectionNumber);
+ }
+ return static_cast<int32_t>(CS32->SectionNumber);
+ }
+
+ uint16_t getType() const {
+ assert(isSet() && "COFFSymbolRef points to nothing!");
+ return CS16 ? CS16->Type : CS32->Type;
+ }
+
+ uint8_t getStorageClass() const {
+ assert(isSet() && "COFFSymbolRef points to nothing!");
+ return CS16 ? CS16->StorageClass : CS32->StorageClass;
+ }
+
+ uint8_t getNumberOfAuxSymbols() const {
+ assert(isSet() && "COFFSymbolRef points to nothing!");
+ return CS16 ? CS16->NumberOfAuxSymbols : CS32->NumberOfAuxSymbols;
+ }
+
+ uint8_t getBaseType() const { return getType() & 0x0F; }
+
+ uint8_t getComplexType() const {
+ return (getType() & 0xF0) >> COFF::SCT_COMPLEX_TYPE_SHIFT;
+ }
+
+ template <typename T> const T *getAux() const {
+ return CS16 ? reinterpret_cast<const T *>(CS16 + 1)
+ : reinterpret_cast<const T *>(CS32 + 1);
+ }
+
+ const coff_aux_section_definition *getSectionDefinition() const {
+ if (!getNumberOfAuxSymbols() ||
+ getStorageClass() != COFF::IMAGE_SYM_CLASS_STATIC)
+ return nullptr;
+ return getAux<coff_aux_section_definition>();
+ }
+
+ bool isAbsolute() const {
+ return getSectionNumber() == -1;
+ }
+
+ bool isExternal() const {
+ return getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL;
+ }
+
+ bool isCommon() const {
+ return isExternal() && getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED &&
+ getValue() != 0;
+ }
+
+ bool isUndefined() const {
+ return isExternal() && getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED &&
+ getValue() == 0;
+ }
+
+ bool isWeakExternal() const {
+ return getStorageClass() == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL;
+ }
+
+ bool isFunctionDefinition() const {
+ return isExternal() && getBaseType() == COFF::IMAGE_SYM_TYPE_NULL &&
+ getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION &&
+ !COFF::isReservedSectionNumber(getSectionNumber());
+ }
+
+ bool isFunctionLineInfo() const {
+ return getStorageClass() == COFF::IMAGE_SYM_CLASS_FUNCTION;
+ }
+
+ bool isAnyUndefined() const {
+ return isUndefined() || isWeakExternal();
+ }
+
+ bool isFileRecord() const {
+ return getStorageClass() == COFF::IMAGE_SYM_CLASS_FILE;
+ }
+
+ bool isSection() const {
+ return getStorageClass() == COFF::IMAGE_SYM_CLASS_SECTION;
+ }
+
+ bool isSectionDefinition() const {
+ // C++/CLI creates external ABS symbols for non-const appdomain globals.
+ // These are also followed by an auxiliary section definition.
+ bool isAppdomainGlobal =
+ getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
+ getSectionNumber() == COFF::IMAGE_SYM_ABSOLUTE;
+ bool isOrdinarySection = getStorageClass() == COFF::IMAGE_SYM_CLASS_STATIC;
+ if (!getNumberOfAuxSymbols())
+ return false;
+ return isAppdomainGlobal || isOrdinarySection;
+ }
+
+ bool isCLRToken() const {
+ return getStorageClass() == COFF::IMAGE_SYM_CLASS_CLR_TOKEN;
+ }
+
+private:
+ bool isSet() const { return CS16 || CS32; }
+
+ const coff_symbol16 *CS16 = nullptr;
+ const coff_symbol32 *CS32 = nullptr;
+};
+
+struct coff_section {
+ char Name[COFF::NameSize];
+ support::ulittle32_t VirtualSize;
+ support::ulittle32_t VirtualAddress;
+ support::ulittle32_t SizeOfRawData;
+ support::ulittle32_t PointerToRawData;
+ support::ulittle32_t PointerToRelocations;
+ support::ulittle32_t PointerToLinenumbers;
+ support::ulittle16_t NumberOfRelocations;
+ support::ulittle16_t NumberOfLinenumbers;
+ support::ulittle32_t Characteristics;
+
+ // Returns true if the actual number of relocations is stored in
+ // VirtualAddress field of the first relocation table entry.
+ bool hasExtendedRelocations() const {
+ return (Characteristics & COFF::IMAGE_SCN_LNK_NRELOC_OVFL) &&
+ NumberOfRelocations == UINT16_MAX;
+ }
+
+ uint32_t getAlignment() const {
+ // The IMAGE_SCN_TYPE_NO_PAD bit is a legacy way of getting to
+ // IMAGE_SCN_ALIGN_1BYTES.
+ if (Characteristics & COFF::IMAGE_SCN_TYPE_NO_PAD)
+ return 1;
+
+ // Bit [20:24] contains section alignment. Both 0 and 1 mean alignment 1.
+ uint32_t Shift = (Characteristics >> 20) & 0xF;
+ if (Shift > 0)
+ return 1U << (Shift - 1);
+ return 1;
+ }
+};
+
+struct coff_relocation {
+ support::ulittle32_t VirtualAddress;
+ support::ulittle32_t SymbolTableIndex;
+ support::ulittle16_t Type;
+};
+
+struct coff_aux_function_definition {
+ support::ulittle32_t TagIndex;
+ support::ulittle32_t TotalSize;
+ support::ulittle32_t PointerToLinenumber;
+ support::ulittle32_t PointerToNextFunction;
+ char Unused1[2];
+};
+
+static_assert(sizeof(coff_aux_function_definition) == 18,
+ "auxiliary entry must be 18 bytes");
+
+struct coff_aux_bf_and_ef_symbol {
+ char Unused1[4];
+ support::ulittle16_t Linenumber;
+ char Unused2[6];
+ support::ulittle32_t PointerToNextFunction;
+ char Unused3[2];
+};
+
+static_assert(sizeof(coff_aux_bf_and_ef_symbol) == 18,
+ "auxiliary entry must be 18 bytes");
+
+struct coff_aux_weak_external {
+ support::ulittle32_t TagIndex;
+ support::ulittle32_t Characteristics;
+ char Unused1[10];
+};
+
+static_assert(sizeof(coff_aux_weak_external) == 18,
+ "auxiliary entry must be 18 bytes");
+
+struct coff_aux_section_definition {
+ support::ulittle32_t Length;
+ support::ulittle16_t NumberOfRelocations;
+ support::ulittle16_t NumberOfLinenumbers;
+ support::ulittle32_t CheckSum;
+ support::ulittle16_t NumberLowPart;
+ uint8_t Selection;
+ uint8_t Unused;
+ support::ulittle16_t NumberHighPart;
+ int32_t getNumber(bool IsBigObj) const {
+ uint32_t Number = static_cast<uint32_t>(NumberLowPart);
+ if (IsBigObj)
+ Number |= static_cast<uint32_t>(NumberHighPart) << 16;
+ return static_cast<int32_t>(Number);
+ }
+};
+
+static_assert(sizeof(coff_aux_section_definition) == 18,
+ "auxiliary entry must be 18 bytes");
+
+struct coff_aux_clr_token {
+ uint8_t AuxType;
+ uint8_t Reserved;
+ support::ulittle32_t SymbolTableIndex;
+ char MBZ[12];
+};
+
+static_assert(sizeof(coff_aux_clr_token) == 18,
+ "auxiliary entry must be 18 bytes");
+
+struct coff_import_header {
+ support::ulittle16_t Sig1;
+ support::ulittle16_t Sig2;
+ support::ulittle16_t Version;
+ support::ulittle16_t Machine;
+ support::ulittle32_t TimeDateStamp;
+ support::ulittle32_t SizeOfData;
+ support::ulittle16_t OrdinalHint;
+ support::ulittle16_t TypeInfo;
+
+ int getType() const { return TypeInfo & 0x3; }
+ int getNameType() const { return (TypeInfo >> 2) & 0x7; }
+};
+
+struct coff_import_directory_table_entry {
+ support::ulittle32_t ImportLookupTableRVA;
+ support::ulittle32_t TimeDateStamp;
+ support::ulittle32_t ForwarderChain;
+ support::ulittle32_t NameRVA;
+ support::ulittle32_t ImportAddressTableRVA;
+
+ bool isNull() const {
+ return ImportLookupTableRVA == 0 && TimeDateStamp == 0 &&
+ ForwarderChain == 0 && NameRVA == 0 && ImportAddressTableRVA == 0;
+ }
+};
+
+template <typename IntTy>
+struct coff_tls_directory {
+ IntTy StartAddressOfRawData;
+ IntTy EndAddressOfRawData;
+ IntTy AddressOfIndex;
+ IntTy AddressOfCallBacks;
+ support::ulittle32_t SizeOfZeroFill;
+ support::ulittle32_t Characteristics;
+
+ uint32_t getAlignment() const {
+ // Bit [20:24] contains section alignment.
+ uint32_t Shift = (Characteristics & 0x00F00000) >> 20;
+ if (Shift > 0)
+ return 1U << (Shift - 1);
+ return 0;
+ }
+};
+
+using coff_tls_directory32 = coff_tls_directory<support::little32_t>;
+using coff_tls_directory64 = coff_tls_directory<support::little64_t>;
+
+/// Bits in control flow guard flags as we understand them.
+enum class coff_guard_flags : uint32_t {
+ CFInstrumented = 0x00000100,
+ HasFidTable = 0x00000400,
+ ProtectDelayLoadIAT = 0x00001000,
+ DelayLoadIATSection = 0x00002000, // Delay load in separate section
+ HasLongJmpTable = 0x00010000,
+ FidTableHasFlags = 0x10000000, // Indicates that fid tables are 5 bytes
+};
+
+struct coff_load_config_code_integrity {
+ support::ulittle16_t Flags;
+ support::ulittle16_t Catalog;
+ support::ulittle32_t CatalogOffset;
+ support::ulittle32_t Reserved;
+};
+
+/// 32-bit load config (IMAGE_LOAD_CONFIG_DIRECTORY32)
+struct coff_load_configuration32 {
+ support::ulittle32_t Size;
+ support::ulittle32_t TimeDateStamp;
+ support::ulittle16_t MajorVersion;
+ support::ulittle16_t MinorVersion;
+ support::ulittle32_t GlobalFlagsClear;
+ support::ulittle32_t GlobalFlagsSet;
+ support::ulittle32_t CriticalSectionDefaultTimeout;
+ support::ulittle32_t DeCommitFreeBlockThreshold;
+ support::ulittle32_t DeCommitTotalFreeThreshold;
+ support::ulittle32_t LockPrefixTable;
+ support::ulittle32_t MaximumAllocationSize;
+ support::ulittle32_t VirtualMemoryThreshold;
+ support::ulittle32_t ProcessAffinityMask;
+ support::ulittle32_t ProcessHeapFlags;
+ support::ulittle16_t CSDVersion;
+ support::ulittle16_t DependentLoadFlags;
+ support::ulittle32_t EditList;
+ support::ulittle32_t SecurityCookie;
+ support::ulittle32_t SEHandlerTable;
+ support::ulittle32_t SEHandlerCount;
+
+ // Added in MSVC 2015 for /guard:cf.
+ support::ulittle32_t GuardCFCheckFunction;
+ support::ulittle32_t GuardCFCheckDispatch;
+ support::ulittle32_t GuardCFFunctionTable;
+ support::ulittle32_t GuardCFFunctionCount;
+ support::ulittle32_t GuardFlags; // coff_guard_flags
+
+ // Added in MSVC 2017
+ coff_load_config_code_integrity CodeIntegrity;
+ support::ulittle32_t GuardAddressTakenIatEntryTable;
+ support::ulittle32_t GuardAddressTakenIatEntryCount;
+ support::ulittle32_t GuardLongJumpTargetTable;
+ support::ulittle32_t GuardLongJumpTargetCount;
+ support::ulittle32_t DynamicValueRelocTable;
+ support::ulittle32_t CHPEMetadataPointer;
+ support::ulittle32_t GuardRFFailureRoutine;
+ support::ulittle32_t GuardRFFailureRoutineFunctionPointer;
+ support::ulittle32_t DynamicValueRelocTableOffset;
+ support::ulittle16_t DynamicValueRelocTableSection;
+ support::ulittle16_t Reserved2;
+ support::ulittle32_t GuardRFVerifyStackPointerFunctionPointer;
+ support::ulittle32_t HotPatchTableOffset;
+};
+
+/// 64-bit load config (IMAGE_LOAD_CONFIG_DIRECTORY64)
+struct coff_load_configuration64 {
+ support::ulittle32_t Size;
+ support::ulittle32_t TimeDateStamp;
+ support::ulittle16_t MajorVersion;
+ support::ulittle16_t MinorVersion;
+ support::ulittle32_t GlobalFlagsClear;
+ support::ulittle32_t GlobalFlagsSet;
+ support::ulittle32_t CriticalSectionDefaultTimeout;
+ support::ulittle64_t DeCommitFreeBlockThreshold;
+ support::ulittle64_t DeCommitTotalFreeThreshold;
+ support::ulittle64_t LockPrefixTable;
+ support::ulittle64_t MaximumAllocationSize;
+ support::ulittle64_t VirtualMemoryThreshold;
+ support::ulittle64_t ProcessAffinityMask;
+ support::ulittle32_t ProcessHeapFlags;
+ support::ulittle16_t CSDVersion;
+ support::ulittle16_t DependentLoadFlags;
+ support::ulittle64_t EditList;
+ support::ulittle64_t SecurityCookie;
+ support::ulittle64_t SEHandlerTable;
+ support::ulittle64_t SEHandlerCount;
+
+ // Added in MSVC 2015 for /guard:cf.
+ support::ulittle64_t GuardCFCheckFunction;
+ support::ulittle64_t GuardCFCheckDispatch;
+ support::ulittle64_t GuardCFFunctionTable;
+ support::ulittle64_t GuardCFFunctionCount;
+ support::ulittle32_t GuardFlags;
+
+ // Added in MSVC 2017
+ coff_load_config_code_integrity CodeIntegrity;
+ support::ulittle64_t GuardAddressTakenIatEntryTable;
+ support::ulittle64_t GuardAddressTakenIatEntryCount;
+ support::ulittle64_t GuardLongJumpTargetTable;
+ support::ulittle64_t GuardLongJumpTargetCount;
+ support::ulittle64_t DynamicValueRelocTable;
+ support::ulittle64_t CHPEMetadataPointer;
+ support::ulittle64_t GuardRFFailureRoutine;
+ support::ulittle64_t GuardRFFailureRoutineFunctionPointer;
+ support::ulittle32_t DynamicValueRelocTableOffset;
+ support::ulittle16_t DynamicValueRelocTableSection;
+ support::ulittle16_t Reserved2;
+ support::ulittle64_t GuardRFVerifyStackPointerFunctionPointer;
+ support::ulittle32_t HotPatchTableOffset;
+};
+
+struct coff_runtime_function_x64 {
+ support::ulittle32_t BeginAddress;
+ support::ulittle32_t EndAddress;
+ support::ulittle32_t UnwindInformation;
+};
+
+struct coff_base_reloc_block_header {
+ support::ulittle32_t PageRVA;
+ support::ulittle32_t BlockSize;
+};
+
+struct coff_base_reloc_block_entry {
+ support::ulittle16_t Data;
+
+ int getType() const { return Data >> 12; }
+ int getOffset() const { return Data & ((1 << 12) - 1); }
+};
+
+struct coff_resource_dir_entry {
+ union {
+ support::ulittle32_t NameOffset;
+ support::ulittle32_t ID;
+ uint32_t getNameOffset() const {
+ return maskTrailingOnes<uint32_t>(31) & NameOffset;
+ }
+ // Even though the PE/COFF spec doesn't mention this, the high bit of a name
+ // offset is set.
+ void setNameOffset(uint32_t Offset) { NameOffset = Offset | (1 << 31); }
+ } Identifier;
+ union {
+ support::ulittle32_t DataEntryOffset;
+ support::ulittle32_t SubdirOffset;
+
+ bool isSubDir() const { return SubdirOffset >> 31; }
+ uint32_t value() const {
+ return maskTrailingOnes<uint32_t>(31) & SubdirOffset;
+ }
+
+ } Offset;
+};
+
+struct coff_resource_data_entry {
+ support::ulittle32_t DataRVA;
+ support::ulittle32_t DataSize;
+ support::ulittle32_t Codepage;
+ support::ulittle32_t Reserved;
+};
+
+struct coff_resource_dir_table {
+ support::ulittle32_t Characteristics;
+ support::ulittle32_t TimeDateStamp;
+ support::ulittle16_t MajorVersion;
+ support::ulittle16_t MinorVersion;
+ support::ulittle16_t NumberOfNameEntries;
+ support::ulittle16_t NumberOfIDEntries;
+};
+
+struct debug_h_header {
+ support::ulittle32_t Magic;
+ support::ulittle16_t Version;
+ support::ulittle16_t HashAlgorithm;
+};
+
+class COFFObjectFile : public ObjectFile {
+private:
+ friend class ImportDirectoryEntryRef;
+ friend class ExportDirectoryEntryRef;
+ const coff_file_header *COFFHeader;
+ const coff_bigobj_file_header *COFFBigObjHeader;
+ const pe32_header *PE32Header;
+ const pe32plus_header *PE32PlusHeader;
+ const data_directory *DataDirectory;
+ const coff_section *SectionTable;
+ const coff_symbol16 *SymbolTable16;
+ const coff_symbol32 *SymbolTable32;
+ const char *StringTable;
+ uint32_t StringTableSize;
+ const coff_import_directory_table_entry *ImportDirectory;
+ const delay_import_directory_table_entry *DelayImportDirectory;
+ uint32_t NumberOfDelayImportDirectory;
+ const export_directory_table_entry *ExportDirectory;
+ const coff_base_reloc_block_header *BaseRelocHeader;
+ const coff_base_reloc_block_header *BaseRelocEnd;
+ const debug_directory *DebugDirectoryBegin;
+ const debug_directory *DebugDirectoryEnd;
+ // Either coff_load_configuration32 or coff_load_configuration64.
+ const void *LoadConfig = nullptr;
+
+ std::error_code getString(uint32_t offset, StringRef &Res) const;
+
+ template <typename coff_symbol_type>
+ const coff_symbol_type *toSymb(DataRefImpl Symb) const;
+ const coff_section *toSec(DataRefImpl Sec) const;
+ const coff_relocation *toRel(DataRefImpl Rel) const;
+
+ std::error_code initSymbolTablePtr();
+ std::error_code initImportTablePtr();
+ std::error_code initDelayImportTablePtr();
+ std::error_code initExportTablePtr();
+ std::error_code initBaseRelocPtr();
+ std::error_code initDebugDirectoryPtr();
+ std::error_code initLoadConfigPtr();
+
+public:
+ uintptr_t getSymbolTable() const {
+ if (SymbolTable16)
+ return reinterpret_cast<uintptr_t>(SymbolTable16);
+ if (SymbolTable32)
+ return reinterpret_cast<uintptr_t>(SymbolTable32);
+ return uintptr_t(0);
+ }
+
+ uint16_t getMachine() const {
+ if (COFFHeader)
+ return COFFHeader->Machine;
+ if (COFFBigObjHeader)
+ return COFFBigObjHeader->Machine;
+ llvm_unreachable("no COFF header!");
+ }
+
+ uint16_t getSizeOfOptionalHeader() const {
+ if (COFFHeader)
+ return COFFHeader->isImportLibrary() ? 0
+ : COFFHeader->SizeOfOptionalHeader;
+ // bigobj doesn't have this field.
+ if (COFFBigObjHeader)
+ return 0;
+ llvm_unreachable("no COFF header!");
+ }
+
+ uint16_t getCharacteristics() const {
+ if (COFFHeader)
+ return COFFHeader->isImportLibrary() ? 0 : COFFHeader->Characteristics;
+ // bigobj doesn't have characteristics to speak of,
+ // editbin will silently lie to you if you attempt to set any.
+ if (COFFBigObjHeader)
+ return 0;
+ llvm_unreachable("no COFF header!");
+ }
+
+ uint32_t getTimeDateStamp() const {
+ if (COFFHeader)
+ return COFFHeader->TimeDateStamp;
+ if (COFFBigObjHeader)
+ return COFFBigObjHeader->TimeDateStamp;
+ llvm_unreachable("no COFF header!");
+ }
+
+ uint32_t getNumberOfSections() const {
+ if (COFFHeader)
+ return COFFHeader->isImportLibrary() ? 0 : COFFHeader->NumberOfSections;
+ if (COFFBigObjHeader)
+ return COFFBigObjHeader->NumberOfSections;
+ llvm_unreachable("no COFF header!");
+ }
+
+ uint32_t getPointerToSymbolTable() const {
+ if (COFFHeader)
+ return COFFHeader->isImportLibrary() ? 0
+ : COFFHeader->PointerToSymbolTable;
+ if (COFFBigObjHeader)
+ return COFFBigObjHeader->PointerToSymbolTable;
+ llvm_unreachable("no COFF header!");
+ }
+
+ uint32_t getRawNumberOfSymbols() const {
+ if (COFFHeader)
+ return COFFHeader->isImportLibrary() ? 0 : COFFHeader->NumberOfSymbols;
+ if (COFFBigObjHeader)
+ return COFFBigObjHeader->NumberOfSymbols;
+ llvm_unreachable("no COFF header!");
+ }
+
+ uint32_t getNumberOfSymbols() const {
+ if (!SymbolTable16 && !SymbolTable32)
+ return 0;
+ return getRawNumberOfSymbols();
+ }
+
+ const coff_load_configuration32 *getLoadConfig32() const {
+ assert(!is64());
+ return reinterpret_cast<const coff_load_configuration32 *>(LoadConfig);
+ }
+
+ const coff_load_configuration64 *getLoadConfig64() const {
+ assert(is64());
+ return reinterpret_cast<const coff_load_configuration64 *>(LoadConfig);
+ }
+
+protected:
+ void moveSymbolNext(DataRefImpl &Symb) const override;
+ Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
+ Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
+ uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
+ uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
+ uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
+ uint32_t getSymbolFlags(DataRefImpl Symb) const override;
+ Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
+ Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
+ void moveSectionNext(DataRefImpl &Sec) const override;
+ std::error_code getSectionName(DataRefImpl Sec,
+ StringRef &Res) const override;
+ uint64_t getSectionAddress(DataRefImpl Sec) const override;
+ uint64_t getSectionIndex(DataRefImpl Sec) const override;
+ uint64_t getSectionSize(DataRefImpl Sec) const override;
+ std::error_code getSectionContents(DataRefImpl Sec,
+ StringRef &Res) const override;
+ uint64_t getSectionAlignment(DataRefImpl Sec) const override;
+ bool isSectionCompressed(DataRefImpl Sec) const override;
+ bool isSectionText(DataRefImpl Sec) const override;
+ bool isSectionData(DataRefImpl Sec) const override;
+ bool isSectionBSS(DataRefImpl Sec) const override;
+ bool isSectionVirtual(DataRefImpl Sec) const override;
+ relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
+ relocation_iterator section_rel_end(DataRefImpl Sec) const override;
+
+ void moveRelocationNext(DataRefImpl &Rel) const override;
+ uint64_t getRelocationOffset(DataRefImpl Rel) const override;
+ symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
+ uint64_t getRelocationType(DataRefImpl Rel) const override;
+ void getRelocationTypeName(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const override;
+
+public:
+ COFFObjectFile(MemoryBufferRef Object, std::error_code &EC);
+
+ basic_symbol_iterator symbol_begin() const override;
+ basic_symbol_iterator symbol_end() const override;
+ section_iterator section_begin() const override;
+ section_iterator section_end() const override;
+
+ const coff_section *getCOFFSection(const SectionRef &Section) const;
+ COFFSymbolRef getCOFFSymbol(const DataRefImpl &Ref) const;
+ COFFSymbolRef getCOFFSymbol(const SymbolRef &Symbol) const;
+ const coff_relocation *getCOFFRelocation(const RelocationRef &Reloc) const;
+ unsigned getSectionID(SectionRef Sec) const;
+ unsigned getSymbolSectionID(SymbolRef Sym) const;
+
+ uint8_t getBytesInAddress() const override;
+ StringRef getFileFormatName() const override;
+ Triple::ArchType getArch() const override;
+ SubtargetFeatures getFeatures() const override { return SubtargetFeatures(); }
+
+ import_directory_iterator import_directory_begin() const;
+ import_directory_iterator import_directory_end() const;
+ delay_import_directory_iterator delay_import_directory_begin() const;
+ delay_import_directory_iterator delay_import_directory_end() const;
+ export_directory_iterator export_directory_begin() const;
+ export_directory_iterator export_directory_end() const;
+ base_reloc_iterator base_reloc_begin() const;
+ base_reloc_iterator base_reloc_end() const;
+ const debug_directory *debug_directory_begin() const {
+ return DebugDirectoryBegin;
+ }
+ const debug_directory *debug_directory_end() const {
+ return DebugDirectoryEnd;
+ }
+
+ iterator_range<import_directory_iterator> import_directories() const;
+ iterator_range<delay_import_directory_iterator>
+ delay_import_directories() const;
+ iterator_range<export_directory_iterator> export_directories() const;
+ iterator_range<base_reloc_iterator> base_relocs() const;
+ iterator_range<const debug_directory *> debug_directories() const {
+ return make_range(debug_directory_begin(), debug_directory_end());
+ }
+
+ const dos_header *getDOSHeader() const {
+ if (!PE32Header && !PE32PlusHeader)
+ return nullptr;
+ return reinterpret_cast<const dos_header *>(base());
+ }
+ std::error_code getPE32Header(const pe32_header *&Res) const;
+ std::error_code getPE32PlusHeader(const pe32plus_header *&Res) const;
+ std::error_code getDataDirectory(uint32_t index,
+ const data_directory *&Res) const;
+ std::error_code getSection(int32_t index, const coff_section *&Res) const;
+
+ template <typename coff_symbol_type>
+ std::error_code getSymbol(uint32_t Index,
+ const coff_symbol_type *&Res) const {
+ if (Index >= getNumberOfSymbols())
+ return object_error::parse_failed;
+
+ Res = reinterpret_cast<coff_symbol_type *>(getSymbolTable()) + Index;
+ return std::error_code();
+ }
+ Expected<COFFSymbolRef> getSymbol(uint32_t index) const {
+ if (SymbolTable16) {
+ const coff_symbol16 *Symb = nullptr;
+ if (std::error_code EC = getSymbol(index, Symb))
+ return errorCodeToError(EC);
+ return COFFSymbolRef(Symb);
+ }
+ if (SymbolTable32) {
+ const coff_symbol32 *Symb = nullptr;
+ if (std::error_code EC = getSymbol(index, Symb))
+ return errorCodeToError(EC);
+ return COFFSymbolRef(Symb);
+ }
+ return errorCodeToError(object_error::parse_failed);
+ }
+
+ template <typename T>
+ std::error_code getAuxSymbol(uint32_t index, const T *&Res) const {
+ Expected<COFFSymbolRef> S = getSymbol(index);
+ if (Error E = S.takeError())
+ return errorToErrorCode(std::move(E));
+ Res = reinterpret_cast<const T *>(S->getRawPtr());
+ return std::error_code();
+ }
+
+ std::error_code getSymbolName(COFFSymbolRef Symbol, StringRef &Res) const;
+ std::error_code getSymbolName(const coff_symbol_generic *Symbol,
+ StringRef &Res) const;
+
+ ArrayRef<uint8_t> getSymbolAuxData(COFFSymbolRef Symbol) const;
+
+ size_t getSymbolTableEntrySize() const {
+ if (COFFHeader)
+ return sizeof(coff_symbol16);
+ if (COFFBigObjHeader)
+ return sizeof(coff_symbol32);
+ llvm_unreachable("null symbol table pointer!");
+ }
+
+ iterator_range<const coff_relocation *>
+ getRelocations(const coff_section *Sec) const;
+
+ std::error_code getSectionName(const coff_section *Sec, StringRef &Res) const;
+ uint64_t getSectionSize(const coff_section *Sec) const;
+ std::error_code getSectionContents(const coff_section *Sec,
+ ArrayRef<uint8_t> &Res) const;
+
+ uint64_t getImageBase() const;
+ std::error_code getVaPtr(uint64_t VA, uintptr_t &Res) const;
+ std::error_code getRvaPtr(uint32_t Rva, uintptr_t &Res) const;
+
+ /// Given an RVA base and size, returns a valid array of bytes or an error
+ /// code if the RVA and size is not contained completely within a valid
+ /// section.
+ std::error_code getRvaAndSizeAsBytes(uint32_t RVA, uint32_t Size,
+ ArrayRef<uint8_t> &Contents) const;
+
+ std::error_code getHintName(uint32_t Rva, uint16_t &Hint,
+ StringRef &Name) const;
+
+ /// Get PDB information out of a codeview debug directory entry.
+ std::error_code getDebugPDBInfo(const debug_directory *DebugDir,
+ const codeview::DebugInfo *&Info,
+ StringRef &PDBFileName) const;
+
+ /// Get PDB information from an executable. If the information is not present,
+ /// Info will be set to nullptr and PDBFileName will be empty. An error is
+ /// returned only on corrupt object files. Convenience accessor that can be
+ /// used if the debug directory is not already handy.
+ std::error_code getDebugPDBInfo(const codeview::DebugInfo *&Info,
+ StringRef &PDBFileName) const;
+
+ bool isRelocatableObject() const override;
+ bool is64() const { return PE32PlusHeader; }
+
+ static bool classof(const Binary *v) { return v->isCOFF(); }
+};
+
+// The iterator for the import directory table.
+class ImportDirectoryEntryRef {
+public:
+ ImportDirectoryEntryRef() = default;
+ ImportDirectoryEntryRef(const coff_import_directory_table_entry *Table,
+ uint32_t I, const COFFObjectFile *Owner)
+ : ImportTable(Table), Index(I), OwningObject(Owner) {}
+
+ bool operator==(const ImportDirectoryEntryRef &Other) const;
+ void moveNext();
+
+ imported_symbol_iterator imported_symbol_begin() const;
+ imported_symbol_iterator imported_symbol_end() const;
+ iterator_range<imported_symbol_iterator> imported_symbols() const;
+
+ imported_symbol_iterator lookup_table_begin() const;
+ imported_symbol_iterator lookup_table_end() const;
+ iterator_range<imported_symbol_iterator> lookup_table_symbols() const;
+
+ std::error_code getName(StringRef &Result) const;
+ std::error_code getImportLookupTableRVA(uint32_t &Result) const;
+ std::error_code getImportAddressTableRVA(uint32_t &Result) const;
+
+ std::error_code
+ getImportTableEntry(const coff_import_directory_table_entry *&Result) const;
+
+private:
+ const coff_import_directory_table_entry *ImportTable;
+ uint32_t Index;
+ const COFFObjectFile *OwningObject = nullptr;
+};
+
+class DelayImportDirectoryEntryRef {
+public:
+ DelayImportDirectoryEntryRef() = default;
+ DelayImportDirectoryEntryRef(const delay_import_directory_table_entry *T,
+ uint32_t I, const COFFObjectFile *Owner)
+ : Table(T), Index(I), OwningObject(Owner) {}
+
+ bool operator==(const DelayImportDirectoryEntryRef &Other) const;
+ void moveNext();
+
+ imported_symbol_iterator imported_symbol_begin() const;
+ imported_symbol_iterator imported_symbol_end() const;
+ iterator_range<imported_symbol_iterator> imported_symbols() const;
+
+ std::error_code getName(StringRef &Result) const;
+ std::error_code getDelayImportTable(
+ const delay_import_directory_table_entry *&Result) const;
+ std::error_code getImportAddress(int AddrIndex, uint64_t &Result) const;
+
+private:
+ const delay_import_directory_table_entry *Table;
+ uint32_t Index;
+ const COFFObjectFile *OwningObject = nullptr;
+};
+
+// The iterator for the export directory table entry.
+class ExportDirectoryEntryRef {
+public:
+ ExportDirectoryEntryRef() = default;
+ ExportDirectoryEntryRef(const export_directory_table_entry *Table, uint32_t I,
+ const COFFObjectFile *Owner)
+ : ExportTable(Table), Index(I), OwningObject(Owner) {}
+
+ bool operator==(const ExportDirectoryEntryRef &Other) const;
+ void moveNext();
+
+ std::error_code getDllName(StringRef &Result) const;
+ std::error_code getOrdinalBase(uint32_t &Result) const;
+ std::error_code getOrdinal(uint32_t &Result) const;
+ std::error_code getExportRVA(uint32_t &Result) const;
+ std::error_code getSymbolName(StringRef &Result) const;
+
+ std::error_code isForwarder(bool &Result) const;
+ std::error_code getForwardTo(StringRef &Result) const;
+
+private:
+ const export_directory_table_entry *ExportTable;
+ uint32_t Index;
+ const COFFObjectFile *OwningObject = nullptr;
+};
+
+class ImportedSymbolRef {
+public:
+ ImportedSymbolRef() = default;
+ ImportedSymbolRef(const import_lookup_table_entry32 *Entry, uint32_t I,
+ const COFFObjectFile *Owner)
+ : Entry32(Entry), Entry64(nullptr), Index(I), OwningObject(Owner) {}
+ ImportedSymbolRef(const import_lookup_table_entry64 *Entry, uint32_t I,
+ const COFFObjectFile *Owner)
+ : Entry32(nullptr), Entry64(Entry), Index(I), OwningObject(Owner) {}
+
+ bool operator==(const ImportedSymbolRef &Other) const;
+ void moveNext();
+
+ std::error_code getSymbolName(StringRef &Result) const;
+ std::error_code isOrdinal(bool &Result) const;
+ std::error_code getOrdinal(uint16_t &Result) const;
+ std::error_code getHintNameRVA(uint32_t &Result) const;
+
+private:
+ const import_lookup_table_entry32 *Entry32;
+ const import_lookup_table_entry64 *Entry64;
+ uint32_t Index;
+ const COFFObjectFile *OwningObject = nullptr;
+};
+
+class BaseRelocRef {
+public:
+ BaseRelocRef() = default;
+ BaseRelocRef(const coff_base_reloc_block_header *Header,
+ const COFFObjectFile *Owner)
+ : Header(Header), Index(0) {}
+
+ bool operator==(const BaseRelocRef &Other) const;
+ void moveNext();
+
+ std::error_code getType(uint8_t &Type) const;
+ std::error_code getRVA(uint32_t &Result) const;
+
+private:
+ const coff_base_reloc_block_header *Header;
+ uint32_t Index;
+};
+
+class ResourceSectionRef {
+public:
+ ResourceSectionRef() = default;
+ explicit ResourceSectionRef(StringRef Ref) : BBS(Ref, support::little) {}
+
+ Expected<ArrayRef<UTF16>>
+ getEntryNameString(const coff_resource_dir_entry &Entry);
+ Expected<const coff_resource_dir_table &>
+ getEntrySubDir(const coff_resource_dir_entry &Entry);
+ Expected<const coff_resource_dir_table &> getBaseTable();
+
+private:
+ BinaryByteStream BBS;
+
+ Expected<const coff_resource_dir_table &> getTableAtOffset(uint32_t Offset);
+ Expected<ArrayRef<UTF16>> getDirStringAtOffset(uint32_t Offset);
+};
+
+// Corresponds to `_FPO_DATA` structure in the PE/COFF spec.
+struct FpoData {
+ support::ulittle32_t Offset; // ulOffStart: Offset 1st byte of function code
+ support::ulittle32_t Size; // cbProcSize: # bytes in function
+ support::ulittle32_t NumLocals; // cdwLocals: # bytes in locals/4
+ support::ulittle16_t NumParams; // cdwParams: # bytes in params/4
+ support::ulittle16_t Attributes;
+
+ // cbProlog: # bytes in prolog
+ int getPrologSize() const { return Attributes & 0xF; }
+
+ // cbRegs: # regs saved
+ int getNumSavedRegs() const { return (Attributes >> 8) & 0x7; }
+
+ // fHasSEH: true if seh is func
+ bool hasSEH() const { return (Attributes >> 9) & 1; }
+
+ // fUseBP: true if EBP has been allocated
+ bool useBP() const { return (Attributes >> 10) & 1; }
+
+ // cbFrame: frame pointer
+ int getFP() const { return Attributes >> 14; }
+};
+
+} // end namespace object
+
+} // end namespace llvm
+
+#endif // LLVM_OBJECT_COFF_H
diff --git a/linux-x64/clang/include/llvm/Object/COFFImportFile.h b/linux-x64/clang/include/llvm/Object/COFFImportFile.h
new file mode 100644
index 0000000..7ca416f
--- /dev/null
+++ b/linux-x64/clang/include/llvm/Object/COFFImportFile.h
@@ -0,0 +1,107 @@
+//===- COFFImportFile.h - COFF short import file implementation -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// COFF short import file is a special kind of file which contains
+// only symbol names for DLL-exported symbols. This class implements
+// exporting of Symbols to create libraries and a SymbolicFile
+// interface for the file type.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_COFF_IMPORT_FILE_H
+#define LLVM_OBJECT_COFF_IMPORT_FILE_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Object/COFF.h"
+#include "llvm/Object/IRObjectFile.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Object/SymbolicFile.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+namespace object {
+
+class COFFImportFile : public SymbolicFile {
+public:
+ COFFImportFile(MemoryBufferRef Source)
+ : SymbolicFile(ID_COFFImportFile, Source) {}
+
+ static bool classof(Binary const *V) { return V->isCOFFImportFile(); }
+
+ void moveSymbolNext(DataRefImpl &Symb) const override { ++Symb.p; }
+
+ std::error_code printSymbolName(raw_ostream &OS,
+ DataRefImpl Symb) const override {
+ if (Symb.p == 0)
+ OS << "__imp_";
+ OS << StringRef(Data.getBufferStart() + sizeof(coff_import_header));
+ return std::error_code();
+ }
+
+ uint32_t getSymbolFlags(DataRefImpl Symb) const override {
+ return SymbolRef::SF_Global;
+ }
+
+ basic_symbol_iterator symbol_begin() const override {
+ return BasicSymbolRef(DataRefImpl(), this);
+ }
+
+ basic_symbol_iterator symbol_end() const override {
+ DataRefImpl Symb;
+ Symb.p = isData() ? 1 : 2;
+ return BasicSymbolRef(Symb, this);
+ }
+
+ const coff_import_header *getCOFFImportHeader() const {
+ return reinterpret_cast<const object::coff_import_header *>(
+ Data.getBufferStart());
+ }
+
+private:
+ bool isData() const {
+ return getCOFFImportHeader()->getType() == COFF::IMPORT_DATA;
+ }
+};
+
+struct COFFShortExport {
+ std::string Name;
+ std::string ExtName;
+ std::string SymbolName;
+
+ uint16_t Ordinal = 0;
+ bool Noname = false;
+ bool Data = false;
+ bool Private = false;
+ bool Constant = false;
+
+ bool isWeak() {
+ return ExtName.size() && ExtName != Name;
+ }
+
+ friend bool operator==(const COFFShortExport &L, const COFFShortExport &R) {
+ return L.Name == R.Name && L.ExtName == R.ExtName &&
+ L.Ordinal == R.Ordinal && L.Noname == R.Noname &&
+ L.Data == R.Data && L.Private == R.Private;
+ }
+
+ friend bool operator!=(const COFFShortExport &L, const COFFShortExport &R) {
+ return !(L == R);
+ }
+};
+
+Error writeImportLibrary(StringRef ImportName, StringRef Path,
+ ArrayRef<COFFShortExport> Exports,
+ COFF::MachineTypes Machine, bool MakeWeakAliases,
+ bool MinGW);
+
+} // namespace object
+} // namespace llvm
+
+#endif
diff --git a/linux-x64/clang/include/llvm/Object/COFFModuleDefinition.h b/linux-x64/clang/include/llvm/Object/COFFModuleDefinition.h
new file mode 100644
index 0000000..be139a2
--- /dev/null
+++ b/linux-x64/clang/include/llvm/Object/COFFModuleDefinition.h
@@ -0,0 +1,53 @@
+//===--- COFFModuleDefinition.h ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Windows-specific.
+// A parser for the module-definition file (.def file).
+// Parsed results are directly written to Config global variable.
+//
+// The format of module-definition files are described in this document:
+// https://msdn.microsoft.com/en-us/library/28d6s79h.aspx
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_COFF_MODULE_DEFINITION_H
+#define LLVM_OBJECT_COFF_MODULE_DEFINITION_H
+
+#include "llvm/Object/COFF.h"
+#include "llvm/Object/COFFImportFile.h"
+
+namespace llvm {
+namespace object {
+
+struct COFFModuleDefinition {
+ std::vector<COFFShortExport> Exports;
+ std::string OutputFile;
+ std::string ImportName;
+ uint64_t ImageBase = 0;
+ uint64_t StackReserve = 0;
+ uint64_t StackCommit = 0;
+ uint64_t HeapReserve = 0;
+ uint64_t HeapCommit = 0;
+ uint32_t MajorImageVersion = 0;
+ uint32_t MinorImageVersion = 0;
+ uint32_t MajorOSVersion = 0;
+ uint32_t MinorOSVersion = 0;
+};
+
+// mingw and wine def files do not mangle _ for x86 which
+// is a consequence of legacy binutils' dlltool functionality.
+// This MingwDef flag should be removed once mingw stops this pratice.
+Expected<COFFModuleDefinition>
+parseCOFFModuleDefinition(MemoryBufferRef MB, COFF::MachineTypes Machine,
+ bool MingwDef = false);
+
+} // End namespace object.
+} // End namespace llvm.
+
+#endif
diff --git a/linux-x64/clang/include/llvm/Object/CVDebugRecord.h b/linux-x64/clang/include/llvm/Object/CVDebugRecord.h
new file mode 100644
index 0000000..faad72c
--- /dev/null
+++ b/linux-x64/clang/include/llvm/Object/CVDebugRecord.h
@@ -0,0 +1,55 @@
+//===- CVDebugRecord.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_CVDEBUGRECORD_H
+#define LLVM_OBJECT_CVDEBUGRECORD_H
+
+#include "llvm/Support/Endian.h"
+
+namespace llvm {
+namespace OMF {
+struct Signature {
+ enum ID : uint32_t {
+ PDB70 = 0x53445352, // RSDS
+ PDB20 = 0x3031424e, // NB10
+ CV50 = 0x3131424e, // NB11
+ CV41 = 0x3930424e, // NB09
+ };
+
+ support::ulittle32_t CVSignature;
+ support::ulittle32_t Offset;
+};
+}
+
+namespace codeview {
+struct PDB70DebugInfo {
+ support::ulittle32_t CVSignature;
+ uint8_t Signature[16];
+ support::ulittle32_t Age;
+ // char PDBFileName[];
+};
+
+struct PDB20DebugInfo {
+ support::ulittle32_t CVSignature;
+ support::ulittle32_t Offset;
+ support::ulittle32_t Signature;
+ support::ulittle32_t Age;
+ // char PDBFileName[];
+};
+
+union DebugInfo {
+ struct OMF::Signature Signature;
+ struct PDB20DebugInfo PDB20;
+ struct PDB70DebugInfo PDB70;
+};
+}
+}
+
+#endif
+
diff --git a/linux-x64/clang/include/llvm/Object/Decompressor.h b/linux-x64/clang/include/llvm/Object/Decompressor.h
new file mode 100644
index 0000000..c8e888d
--- /dev/null
+++ b/linux-x64/clang/include/llvm/Object/Decompressor.h
@@ -0,0 +1,67 @@
+//===-- Decompressor.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===/
+
+#ifndef LLVM_OBJECT_DECOMPRESSOR_H
+#define LLVM_OBJECT_DECOMPRESSOR_H
+
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Object/ObjectFile.h"
+
+namespace llvm {
+namespace object {
+
+/// @brief Decompressor helps to handle decompression of compressed sections.
+class Decompressor {
+public:
+ /// @brief Create decompressor object.
+ /// @param Name Section name.
+ /// @param Data Section content.
+ /// @param IsLE Flag determines if Data is in little endian form.
+ /// @param Is64Bit Flag determines if object is 64 bit.
+ static Expected<Decompressor> create(StringRef Name, StringRef Data,
+ bool IsLE, bool Is64Bit);
+
+ /// @brief Resize the buffer and uncompress section data into it.
+ /// @param Out Destination buffer.
+ template <class T> Error resizeAndDecompress(T &Out) {
+ Out.resize(DecompressedSize);
+ return decompress({Out.data(), (size_t)DecompressedSize});
+ }
+
+ /// @brief Uncompress section data to raw buffer provided.
+ /// @param Buffer Destination buffer.
+ Error decompress(MutableArrayRef<char> Buffer);
+
+ /// @brief Return memory buffer size required for decompression.
+ uint64_t getDecompressedSize() { return DecompressedSize; }
+
+ /// @brief Return true if section is compressed, including gnu-styled case.
+ static bool isCompressed(const object::SectionRef &Section);
+
+ /// @brief Return true if section is a ELF compressed one.
+ static bool isCompressedELFSection(uint64_t Flags, StringRef Name);
+
+ /// @brief Return true if section name matches gnu style compressed one.
+ static bool isGnuStyle(StringRef Name);
+
+private:
+ Decompressor(StringRef Data);
+
+ Error consumeCompressedGnuHeader();
+ Error consumeCompressedZLibHeader(bool Is64Bit, bool IsLittleEndian);
+
+ StringRef SectionData;
+ uint64_t DecompressedSize;
+};
+
+} // end namespace object
+} // end namespace llvm
+
+#endif // LLVM_OBJECT_DECOMPRESSOR_H
diff --git a/linux-x64/clang/include/llvm/Object/ELF.h b/linux-x64/clang/include/llvm/Object/ELF.h
new file mode 100644
index 0000000..46504e7
--- /dev/null
+++ b/linux-x64/clang/include/llvm/Object/ELF.h
@@ -0,0 +1,611 @@
+//===- ELF.h - ELF object file implementation -------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the ELFFile template class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_ELF_H
+#define LLVM_OBJECT_ELF_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/ELF.h"
+#include "llvm/Object/ELFTypes.h"
+#include "llvm/Object/Error.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <limits>
+#include <utility>
+
+namespace llvm {
+namespace object {
+
+StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type);
+StringRef getELFSectionTypeName(uint32_t Machine, uint32_t Type);
+
+// Subclasses of ELFFile may need this for template instantiation
+inline std::pair<unsigned char, unsigned char>
+getElfArchType(StringRef Object) {
+ if (Object.size() < ELF::EI_NIDENT)
+ return std::make_pair((uint8_t)ELF::ELFCLASSNONE,
+ (uint8_t)ELF::ELFDATANONE);
+ return std::make_pair((uint8_t)Object[ELF::EI_CLASS],
+ (uint8_t)Object[ELF::EI_DATA]);
+}
+
+static inline Error createError(StringRef Err) {
+ return make_error<StringError>(Err, object_error::parse_failed);
+}
+
+template <class ELFT>
+class ELFFile {
+public:
+ LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
+ using uintX_t = typename ELFT::uint;
+ using Elf_Ehdr = typename ELFT::Ehdr;
+ using Elf_Shdr = typename ELFT::Shdr;
+ using Elf_Sym = typename ELFT::Sym;
+ using Elf_Dyn = typename ELFT::Dyn;
+ using Elf_Phdr = typename ELFT::Phdr;
+ using Elf_Rel = typename ELFT::Rel;
+ using Elf_Rela = typename ELFT::Rela;
+ using Elf_Verdef = typename ELFT::Verdef;
+ using Elf_Verdaux = typename ELFT::Verdaux;
+ using Elf_Verneed = typename ELFT::Verneed;
+ using Elf_Vernaux = typename ELFT::Vernaux;
+ using Elf_Versym = typename ELFT::Versym;
+ using Elf_Hash = typename ELFT::Hash;
+ using Elf_GnuHash = typename ELFT::GnuHash;
+ using Elf_Nhdr = typename ELFT::Nhdr;
+ using Elf_Note = typename ELFT::Note;
+ using Elf_Note_Iterator = typename ELFT::NoteIterator;
+ using Elf_Dyn_Range = typename ELFT::DynRange;
+ using Elf_Shdr_Range = typename ELFT::ShdrRange;
+ using Elf_Sym_Range = typename ELFT::SymRange;
+ using Elf_Rel_Range = typename ELFT::RelRange;
+ using Elf_Rela_Range = typename ELFT::RelaRange;
+ using Elf_Phdr_Range = typename ELFT::PhdrRange;
+
+ const uint8_t *base() const {
+ return reinterpret_cast<const uint8_t *>(Buf.data());
+ }
+
+ size_t getBufSize() const { return Buf.size(); }
+
+private:
+ StringRef Buf;
+
+ ELFFile(StringRef Object);
+
+public:
+ const Elf_Ehdr *getHeader() const {
+ return reinterpret_cast<const Elf_Ehdr *>(base());
+ }
+
+ template <typename T>
+ Expected<const T *> getEntry(uint32_t Section, uint32_t Entry) const;
+ template <typename T>
+ Expected<const T *> getEntry(const Elf_Shdr *Section, uint32_t Entry) const;
+
+ Expected<StringRef> getStringTable(const Elf_Shdr *Section) const;
+ Expected<StringRef> getStringTableForSymtab(const Elf_Shdr &Section) const;
+ Expected<StringRef> getStringTableForSymtab(const Elf_Shdr &Section,
+ Elf_Shdr_Range Sections) const;
+
+ Expected<ArrayRef<Elf_Word>> getSHNDXTable(const Elf_Shdr &Section) const;
+ Expected<ArrayRef<Elf_Word>> getSHNDXTable(const Elf_Shdr &Section,
+ Elf_Shdr_Range Sections) const;
+
+ StringRef getRelocationTypeName(uint32_t Type) const;
+ void getRelocationTypeName(uint32_t Type,
+ SmallVectorImpl<char> &Result) const;
+
+ /// \brief Get the symbol for a given relocation.
+ Expected<const Elf_Sym *> getRelocationSymbol(const Elf_Rel *Rel,
+ const Elf_Shdr *SymTab) const;
+
+ static Expected<ELFFile> create(StringRef Object);
+
+ bool isMipsELF64() const {
+ return getHeader()->e_machine == ELF::EM_MIPS &&
+ getHeader()->getFileClass() == ELF::ELFCLASS64;
+ }
+
+ bool isMips64EL() const {
+ return isMipsELF64() &&
+ getHeader()->getDataEncoding() == ELF::ELFDATA2LSB;
+ }
+
+ Expected<Elf_Shdr_Range> sections() const;
+
+ Expected<Elf_Sym_Range> symbols(const Elf_Shdr *Sec) const {
+ if (!Sec)
+ return makeArrayRef<Elf_Sym>(nullptr, nullptr);
+ return getSectionContentsAsArray<Elf_Sym>(Sec);
+ }
+
+ Expected<Elf_Rela_Range> relas(const Elf_Shdr *Sec) const {
+ return getSectionContentsAsArray<Elf_Rela>(Sec);
+ }
+
+ Expected<Elf_Rel_Range> rels(const Elf_Shdr *Sec) const {
+ return getSectionContentsAsArray<Elf_Rel>(Sec);
+ }
+
+ Expected<std::vector<Elf_Rela>> android_relas(const Elf_Shdr *Sec) const;
+
+ /// \brief Iterate over program header table.
+ Expected<Elf_Phdr_Range> program_headers() const {
+ if (getHeader()->e_phnum && getHeader()->e_phentsize != sizeof(Elf_Phdr))
+ return createError("invalid e_phentsize");
+ if (getHeader()->e_phoff +
+ (getHeader()->e_phnum * getHeader()->e_phentsize) >
+ getBufSize())
+ return createError("program headers longer than binary");
+ auto *Begin =
+ reinterpret_cast<const Elf_Phdr *>(base() + getHeader()->e_phoff);
+ return makeArrayRef(Begin, Begin + getHeader()->e_phnum);
+ }
+
+ /// Get an iterator over notes in a program header.
+ ///
+ /// The program header must be of type \c PT_NOTE.
+ ///
+ /// \param Phdr the program header to iterate over.
+ /// \param Err [out] an error to support fallible iteration, which should
+ /// be checked after iteration ends.
+ Elf_Note_Iterator notes_begin(const Elf_Phdr &Phdr, Error &Err) const {
+ if (Phdr.p_type != ELF::PT_NOTE) {
+ Err = createError("attempt to iterate notes of non-note program header");
+ return Elf_Note_Iterator(Err);
+ }
+ if (Phdr.p_offset + Phdr.p_filesz > getBufSize()) {
+ Err = createError("invalid program header offset/size");
+ return Elf_Note_Iterator(Err);
+ }
+ return Elf_Note_Iterator(base() + Phdr.p_offset, Phdr.p_filesz, Err);
+ }
+
+ /// Get an iterator over notes in a section.
+ ///
+ /// The section must be of type \c SHT_NOTE.
+ ///
+ /// \param Shdr the section to iterate over.
+ /// \param Err [out] an error to support fallible iteration, which should
+ /// be checked after iteration ends.
+ Elf_Note_Iterator notes_begin(const Elf_Shdr &Shdr, Error &Err) const {
+ if (Shdr.sh_type != ELF::SHT_NOTE) {
+ Err = createError("attempt to iterate notes of non-note section");
+ return Elf_Note_Iterator(Err);
+ }
+ if (Shdr.sh_offset + Shdr.sh_size > getBufSize()) {
+ Err = createError("invalid section offset/size");
+ return Elf_Note_Iterator(Err);
+ }
+ return Elf_Note_Iterator(base() + Shdr.sh_offset, Shdr.sh_size, Err);
+ }
+
+ /// Get the end iterator for notes.
+ Elf_Note_Iterator notes_end() const {
+ return Elf_Note_Iterator();
+ }
+
+ /// Get an iterator range over notes of a program header.
+ ///
+ /// The program header must be of type \c PT_NOTE.
+ ///
+ /// \param Phdr the program header to iterate over.
+ /// \param Err [out] an error to support fallible iteration, which should
+ /// be checked after iteration ends.
+ iterator_range<Elf_Note_Iterator> notes(const Elf_Phdr &Phdr,
+ Error &Err) const {
+ return make_range(notes_begin(Phdr, Err), notes_end());
+ }
+
+ /// Get an iterator range over notes of a section.
+ ///
+ /// The section must be of type \c SHT_NOTE.
+ ///
+ /// \param Shdr the section to iterate over.
+ /// \param Err [out] an error to support fallible iteration, which should
+ /// be checked after iteration ends.
+ iterator_range<Elf_Note_Iterator> notes(const Elf_Shdr &Shdr,
+ Error &Err) const {
+ return make_range(notes_begin(Shdr, Err), notes_end());
+ }
+
+ Expected<StringRef> getSectionStringTable(Elf_Shdr_Range Sections) const;
+ Expected<uint32_t> getSectionIndex(const Elf_Sym *Sym, Elf_Sym_Range Syms,
+ ArrayRef<Elf_Word> ShndxTable) const;
+ Expected<const Elf_Shdr *> getSection(const Elf_Sym *Sym,
+ const Elf_Shdr *SymTab,
+ ArrayRef<Elf_Word> ShndxTable) const;
+ Expected<const Elf_Shdr *> getSection(const Elf_Sym *Sym,
+ Elf_Sym_Range Symtab,
+ ArrayRef<Elf_Word> ShndxTable) const;
+ Expected<const Elf_Shdr *> getSection(uint32_t Index) const;
+
+ Expected<const Elf_Sym *> getSymbol(const Elf_Shdr *Sec,
+ uint32_t Index) const;
+
+ Expected<StringRef> getSectionName(const Elf_Shdr *Section) const;
+ Expected<StringRef> getSectionName(const Elf_Shdr *Section,
+ StringRef DotShstrtab) const;
+ template <typename T>
+ Expected<ArrayRef<T>> getSectionContentsAsArray(const Elf_Shdr *Sec) const;
+ Expected<ArrayRef<uint8_t>> getSectionContents(const Elf_Shdr *Sec) const;
+};
+
+using ELF32LEFile = ELFFile<ELF32LE>;
+using ELF64LEFile = ELFFile<ELF64LE>;
+using ELF32BEFile = ELFFile<ELF32BE>;
+using ELF64BEFile = ELFFile<ELF64BE>;
+
+template <class ELFT>
+inline Expected<const typename ELFT::Shdr *>
+getSection(typename ELFT::ShdrRange Sections, uint32_t Index) {
+ if (Index >= Sections.size())
+ return createError("invalid section index");
+ return &Sections[Index];
+}
+
+template <class ELFT>
+inline Expected<uint32_t>
+getExtendedSymbolTableIndex(const typename ELFT::Sym *Sym,
+ const typename ELFT::Sym *FirstSym,
+ ArrayRef<typename ELFT::Word> ShndxTable) {
+ assert(Sym->st_shndx == ELF::SHN_XINDEX);
+ unsigned Index = Sym - FirstSym;
+ if (Index >= ShndxTable.size())
+ return createError("index past the end of the symbol table");
+
+ // The size of the table was checked in getSHNDXTable.
+ return ShndxTable[Index];
+}
+
+template <class ELFT>
+Expected<uint32_t>
+ELFFile<ELFT>::getSectionIndex(const Elf_Sym *Sym, Elf_Sym_Range Syms,
+ ArrayRef<Elf_Word> ShndxTable) const {
+ uint32_t Index = Sym->st_shndx;
+ if (Index == ELF::SHN_XINDEX) {
+ auto ErrorOrIndex = getExtendedSymbolTableIndex<ELFT>(
+ Sym, Syms.begin(), ShndxTable);
+ if (!ErrorOrIndex)
+ return ErrorOrIndex.takeError();
+ return *ErrorOrIndex;
+ }
+ if (Index == ELF::SHN_UNDEF || Index >= ELF::SHN_LORESERVE)
+ return 0;
+ return Index;
+}
+
+template <class ELFT>
+Expected<const typename ELFT::Shdr *>
+ELFFile<ELFT>::getSection(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
+ ArrayRef<Elf_Word> ShndxTable) const {
+ auto SymsOrErr = symbols(SymTab);
+ if (!SymsOrErr)
+ return SymsOrErr.takeError();
+ return getSection(Sym, *SymsOrErr, ShndxTable);
+}
+
+template <class ELFT>
+Expected<const typename ELFT::Shdr *>
+ELFFile<ELFT>::getSection(const Elf_Sym *Sym, Elf_Sym_Range Symbols,
+ ArrayRef<Elf_Word> ShndxTable) const {
+ auto IndexOrErr = getSectionIndex(Sym, Symbols, ShndxTable);
+ if (!IndexOrErr)
+ return IndexOrErr.takeError();
+ uint32_t Index = *IndexOrErr;
+ if (Index == 0)
+ return nullptr;
+ return getSection(Index);
+}
+
+template <class ELFT>
+inline Expected<const typename ELFT::Sym *>
+getSymbol(typename ELFT::SymRange Symbols, uint32_t Index) {
+ if (Index >= Symbols.size())
+ return createError("invalid symbol index");
+ return &Symbols[Index];
+}
+
+template <class ELFT>
+Expected<const typename ELFT::Sym *>
+ELFFile<ELFT>::getSymbol(const Elf_Shdr *Sec, uint32_t Index) const {
+ auto SymtabOrErr = symbols(Sec);
+ if (!SymtabOrErr)
+ return SymtabOrErr.takeError();
+ return object::getSymbol<ELFT>(*SymtabOrErr, Index);
+}
+
+template <class ELFT>
+template <typename T>
+Expected<ArrayRef<T>>
+ELFFile<ELFT>::getSectionContentsAsArray(const Elf_Shdr *Sec) const {
+ if (Sec->sh_entsize != sizeof(T) && sizeof(T) != 1)
+ return createError("invalid sh_entsize");
+
+ uintX_t Offset = Sec->sh_offset;
+ uintX_t Size = Sec->sh_size;
+
+ if (Size % sizeof(T))
+ return createError("size is not a multiple of sh_entsize");
+ if ((std::numeric_limits<uintX_t>::max() - Offset < Size) ||
+ Offset + Size > Buf.size())
+ return createError("invalid section offset");
+
+ if (Offset % alignof(T))
+ return createError("unaligned data");
+
+ const T *Start = reinterpret_cast<const T *>(base() + Offset);
+ return makeArrayRef(Start, Size / sizeof(T));
+}
+
+template <class ELFT>
+Expected<ArrayRef<uint8_t>>
+ELFFile<ELFT>::getSectionContents(const Elf_Shdr *Sec) const {
+ return getSectionContentsAsArray<uint8_t>(Sec);
+}
+
+template <class ELFT>
+StringRef ELFFile<ELFT>::getRelocationTypeName(uint32_t Type) const {
+ return getELFRelocationTypeName(getHeader()->e_machine, Type);
+}
+
+template <class ELFT>
+void ELFFile<ELFT>::getRelocationTypeName(uint32_t Type,
+ SmallVectorImpl<char> &Result) const {
+ if (!isMipsELF64()) {
+ StringRef Name = getRelocationTypeName(Type);
+ Result.append(Name.begin(), Name.end());
+ } else {
+ // The Mips N64 ABI allows up to three operations to be specified per
+ // relocation record. Unfortunately there's no easy way to test for the
+ // presence of N64 ELFs as they have no special flag that identifies them
+ // as being N64. We can safely assume at the moment that all Mips
+ // ELFCLASS64 ELFs are N64. New Mips64 ABIs should provide enough
+ // information to disambiguate between old vs new ABIs.
+ uint8_t Type1 = (Type >> 0) & 0xFF;
+ uint8_t Type2 = (Type >> 8) & 0xFF;
+ uint8_t Type3 = (Type >> 16) & 0xFF;
+
+ // Concat all three relocation type names.
+ StringRef Name = getRelocationTypeName(Type1);
+ Result.append(Name.begin(), Name.end());
+
+ Name = getRelocationTypeName(Type2);
+ Result.append(1, '/');
+ Result.append(Name.begin(), Name.end());
+
+ Name = getRelocationTypeName(Type3);
+ Result.append(1, '/');
+ Result.append(Name.begin(), Name.end());
+ }
+}
+
+template <class ELFT>
+Expected<const typename ELFT::Sym *>
+ELFFile<ELFT>::getRelocationSymbol(const Elf_Rel *Rel,
+ const Elf_Shdr *SymTab) const {
+ uint32_t Index = Rel->getSymbol(isMips64EL());
+ if (Index == 0)
+ return nullptr;
+ return getEntry<Elf_Sym>(SymTab, Index);
+}
+
+template <class ELFT>
+Expected<StringRef>
+ELFFile<ELFT>::getSectionStringTable(Elf_Shdr_Range Sections) const {
+ uint32_t Index = getHeader()->e_shstrndx;
+ if (Index == ELF::SHN_XINDEX)
+ Index = Sections[0].sh_link;
+
+ if (!Index) // no section string table.
+ return "";
+ if (Index >= Sections.size())
+ return createError("invalid section index");
+ return getStringTable(&Sections[Index]);
+}
+
+template <class ELFT> ELFFile<ELFT>::ELFFile(StringRef Object) : Buf(Object) {}
+
+template <class ELFT>
+Expected<ELFFile<ELFT>> ELFFile<ELFT>::create(StringRef Object) {
+ if (sizeof(Elf_Ehdr) > Object.size())
+ return createError("Invalid buffer");
+ return ELFFile(Object);
+}
+
+template <class ELFT>
+Expected<typename ELFT::ShdrRange> ELFFile<ELFT>::sections() const {
+ const uintX_t SectionTableOffset = getHeader()->e_shoff;
+ if (SectionTableOffset == 0)
+ return ArrayRef<Elf_Shdr>();
+
+ if (getHeader()->e_shentsize != sizeof(Elf_Shdr))
+ return createError(
+ "invalid section header entry size (e_shentsize) in ELF header");
+
+ const uint64_t FileSize = Buf.size();
+
+ if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize)
+ return createError("section header table goes past the end of the file");
+
+ // Invalid address alignment of section headers
+ if (SectionTableOffset & (alignof(Elf_Shdr) - 1))
+ return createError("invalid alignment of section headers");
+
+ const Elf_Shdr *First =
+ reinterpret_cast<const Elf_Shdr *>(base() + SectionTableOffset);
+
+ uintX_t NumSections = getHeader()->e_shnum;
+ if (NumSections == 0)
+ NumSections = First->sh_size;
+
+ if (NumSections > UINT64_MAX / sizeof(Elf_Shdr))
+ return createError("section table goes past the end of file");
+
+ const uint64_t SectionTableSize = NumSections * sizeof(Elf_Shdr);
+
+ // Section table goes past end of file!
+ if (SectionTableOffset + SectionTableSize > FileSize)
+ return createError("section table goes past the end of file");
+
+ return makeArrayRef(First, NumSections);
+}
+
+template <class ELFT>
+template <typename T>
+Expected<const T *> ELFFile<ELFT>::getEntry(uint32_t Section,
+ uint32_t Entry) const {
+ auto SecOrErr = getSection(Section);
+ if (!SecOrErr)
+ return SecOrErr.takeError();
+ return getEntry<T>(*SecOrErr, Entry);
+}
+
+template <class ELFT>
+template <typename T>
+Expected<const T *> ELFFile<ELFT>::getEntry(const Elf_Shdr *Section,
+ uint32_t Entry) const {
+ if (sizeof(T) != Section->sh_entsize)
+ return createError("invalid sh_entsize");
+ size_t Pos = Section->sh_offset + Entry * sizeof(T);
+ if (Pos + sizeof(T) > Buf.size())
+ return createError("invalid section offset");
+ return reinterpret_cast<const T *>(base() + Pos);
+}
+
+template <class ELFT>
+Expected<const typename ELFT::Shdr *>
+ELFFile<ELFT>::getSection(uint32_t Index) const {
+ auto TableOrErr = sections();
+ if (!TableOrErr)
+ return TableOrErr.takeError();
+ return object::getSection<ELFT>(*TableOrErr, Index);
+}
+
+template <class ELFT>
+Expected<StringRef>
+ELFFile<ELFT>::getStringTable(const Elf_Shdr *Section) const {
+ if (Section->sh_type != ELF::SHT_STRTAB)
+ return createError("invalid sh_type for string table, expected SHT_STRTAB");
+ auto V = getSectionContentsAsArray<char>(Section);
+ if (!V)
+ return V.takeError();
+ ArrayRef<char> Data = *V;
+ if (Data.empty())
+ return createError("empty string table");
+ if (Data.back() != '\0')
+ return createError("string table non-null terminated");
+ return StringRef(Data.begin(), Data.size());
+}
+
+template <class ELFT>
+Expected<ArrayRef<typename ELFT::Word>>
+ELFFile<ELFT>::getSHNDXTable(const Elf_Shdr &Section) const {
+ auto SectionsOrErr = sections();
+ if (!SectionsOrErr)
+ return SectionsOrErr.takeError();
+ return getSHNDXTable(Section, *SectionsOrErr);
+}
+
+template <class ELFT>
+Expected<ArrayRef<typename ELFT::Word>>
+ELFFile<ELFT>::getSHNDXTable(const Elf_Shdr &Section,
+ Elf_Shdr_Range Sections) const {
+ assert(Section.sh_type == ELF::SHT_SYMTAB_SHNDX);
+ auto VOrErr = getSectionContentsAsArray<Elf_Word>(&Section);
+ if (!VOrErr)
+ return VOrErr.takeError();
+ ArrayRef<Elf_Word> V = *VOrErr;
+ auto SymTableOrErr = object::getSection<ELFT>(Sections, Section.sh_link);
+ if (!SymTableOrErr)
+ return SymTableOrErr.takeError();
+ const Elf_Shdr &SymTable = **SymTableOrErr;
+ if (SymTable.sh_type != ELF::SHT_SYMTAB &&
+ SymTable.sh_type != ELF::SHT_DYNSYM)
+ return createError("invalid sh_type");
+ if (V.size() != (SymTable.sh_size / sizeof(Elf_Sym)))
+ return createError("invalid section contents size");
+ return V;
+}
+
+template <class ELFT>
+Expected<StringRef>
+ELFFile<ELFT>::getStringTableForSymtab(const Elf_Shdr &Sec) const {
+ auto SectionsOrErr = sections();
+ if (!SectionsOrErr)
+ return SectionsOrErr.takeError();
+ return getStringTableForSymtab(Sec, *SectionsOrErr);
+}
+
+template <class ELFT>
+Expected<StringRef>
+ELFFile<ELFT>::getStringTableForSymtab(const Elf_Shdr &Sec,
+ Elf_Shdr_Range Sections) const {
+
+ if (Sec.sh_type != ELF::SHT_SYMTAB && Sec.sh_type != ELF::SHT_DYNSYM)
+ return createError(
+ "invalid sh_type for symbol table, expected SHT_SYMTAB or SHT_DYNSYM");
+ auto SectionOrErr = object::getSection<ELFT>(Sections, Sec.sh_link);
+ if (!SectionOrErr)
+ return SectionOrErr.takeError();
+ return getStringTable(*SectionOrErr);
+}
+
+template <class ELFT>
+Expected<StringRef>
+ELFFile<ELFT>::getSectionName(const Elf_Shdr *Section) const {
+ auto SectionsOrErr = sections();
+ if (!SectionsOrErr)
+ return SectionsOrErr.takeError();
+ auto Table = getSectionStringTable(*SectionsOrErr);
+ if (!Table)
+ return Table.takeError();
+ return getSectionName(Section, *Table);
+}
+
+template <class ELFT>
+Expected<StringRef> ELFFile<ELFT>::getSectionName(const Elf_Shdr *Section,
+ StringRef DotShstrtab) const {
+ uint32_t Offset = Section->sh_name;
+ if (Offset == 0)
+ return StringRef();
+ if (Offset >= DotShstrtab.size())
+ return createError("invalid string offset");
+ return StringRef(DotShstrtab.data() + Offset);
+}
+
+/// This function returns the hash value for a symbol in the .dynsym section
+/// Name of the API remains consistent as specified in the libelf
+/// REF : http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#hash
+inline unsigned hashSysV(StringRef SymbolName) {
+ unsigned h = 0, g;
+ for (char C : SymbolName) {
+ h = (h << 4) + C;
+ g = h & 0xf0000000L;
+ if (g != 0)
+ h ^= g >> 24;
+ h &= ~g;
+ }
+ return h;
+}
+
+} // end namespace object
+} // end namespace llvm
+
+#endif // LLVM_OBJECT_ELF_H
diff --git a/linux-x64/clang/include/llvm/Object/ELFObjectFile.h b/linux-x64/clang/include/llvm/Object/ELFObjectFile.h
new file mode 100644
index 0000000..4d00103
--- /dev/null
+++ b/linux-x64/clang/include/llvm/Object/ELFObjectFile.h
@@ -0,0 +1,1122 @@
+//===- ELFObjectFile.h - ELF object file implementation ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the ELFObjectFile template class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_ELFOBJECTFILE_H
+#define LLVM_OBJECT_ELFOBJECTFILE_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/BinaryFormat/ELF.h"
+#include "llvm/MC/SubtargetFeature.h"
+#include "llvm/Object/Binary.h"
+#include "llvm/Object/ELF.h"
+#include "llvm/Object/ELFTypes.h"
+#include "llvm/Object/Error.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Object/SymbolicFile.h"
+#include "llvm/Support/ARMAttributeParser.h"
+#include "llvm/Support/ARMBuildAttributes.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include <cassert>
+#include <cstdint>
+#include <system_error>
+
+namespace llvm {
+namespace object {
+
+class elf_symbol_iterator;
+
+class ELFObjectFileBase : public ObjectFile {
+ friend class ELFRelocationRef;
+ friend class ELFSectionRef;
+ friend class ELFSymbolRef;
+
+protected:
+ ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source);
+
+ virtual uint16_t getEMachine() const = 0;
+ virtual uint64_t getSymbolSize(DataRefImpl Symb) const = 0;
+ virtual uint8_t getSymbolOther(DataRefImpl Symb) const = 0;
+ virtual uint8_t getSymbolELFType(DataRefImpl Symb) const = 0;
+
+ virtual uint32_t getSectionType(DataRefImpl Sec) const = 0;
+ virtual uint64_t getSectionFlags(DataRefImpl Sec) const = 0;
+ virtual uint64_t getSectionOffset(DataRefImpl Sec) const = 0;
+
+ virtual Expected<int64_t> getRelocationAddend(DataRefImpl Rel) const = 0;
+
+public:
+ using elf_symbol_iterator_range = iterator_range<elf_symbol_iterator>;
+
+ virtual elf_symbol_iterator_range getDynamicSymbolIterators() const = 0;
+
+ /// Returns platform-specific object flags, if any.
+ virtual unsigned getPlatformFlags() const = 0;
+
+ elf_symbol_iterator_range symbols() const;
+
+ static bool classof(const Binary *v) { return v->isELF(); }
+
+ SubtargetFeatures getFeatures() const override;
+
+ SubtargetFeatures getMIPSFeatures() const;
+
+ SubtargetFeatures getARMFeatures() const;
+
+ SubtargetFeatures getRISCVFeatures() const;
+
+ void setARMSubArch(Triple &TheTriple) const override;
+};
+
+class ELFSectionRef : public SectionRef {
+public:
+ ELFSectionRef(const SectionRef &B) : SectionRef(B) {
+ assert(isa<ELFObjectFileBase>(SectionRef::getObject()));
+ }
+
+ const ELFObjectFileBase *getObject() const {
+ return cast<ELFObjectFileBase>(SectionRef::getObject());
+ }
+
+ uint32_t getType() const {
+ return getObject()->getSectionType(getRawDataRefImpl());
+ }
+
+ uint64_t getFlags() const {
+ return getObject()->getSectionFlags(getRawDataRefImpl());
+ }
+
+ uint64_t getOffset() const {
+ return getObject()->getSectionOffset(getRawDataRefImpl());
+ }
+};
+
+class elf_section_iterator : public section_iterator {
+public:
+ elf_section_iterator(const section_iterator &B) : section_iterator(B) {
+ assert(isa<ELFObjectFileBase>(B->getObject()));
+ }
+
+ const ELFSectionRef *operator->() const {
+ return static_cast<const ELFSectionRef *>(section_iterator::operator->());
+ }
+
+ const ELFSectionRef &operator*() const {
+ return static_cast<const ELFSectionRef &>(section_iterator::operator*());
+ }
+};
+
+class ELFSymbolRef : public SymbolRef {
+public:
+ ELFSymbolRef(const SymbolRef &B) : SymbolRef(B) {
+ assert(isa<ELFObjectFileBase>(SymbolRef::getObject()));
+ }
+
+ const ELFObjectFileBase *getObject() const {
+ return cast<ELFObjectFileBase>(BasicSymbolRef::getObject());
+ }
+
+ uint64_t getSize() const {
+ return getObject()->getSymbolSize(getRawDataRefImpl());
+ }
+
+ uint8_t getOther() const {
+ return getObject()->getSymbolOther(getRawDataRefImpl());
+ }
+
+ uint8_t getELFType() const {
+ return getObject()->getSymbolELFType(getRawDataRefImpl());
+ }
+};
+
+class elf_symbol_iterator : public symbol_iterator {
+public:
+ elf_symbol_iterator(const basic_symbol_iterator &B)
+ : symbol_iterator(SymbolRef(B->getRawDataRefImpl(),
+ cast<ELFObjectFileBase>(B->getObject()))) {}
+
+ const ELFSymbolRef *operator->() const {
+ return static_cast<const ELFSymbolRef *>(symbol_iterator::operator->());
+ }
+
+ const ELFSymbolRef &operator*() const {
+ return static_cast<const ELFSymbolRef &>(symbol_iterator::operator*());
+ }
+};
+
+class ELFRelocationRef : public RelocationRef {
+public:
+ ELFRelocationRef(const RelocationRef &B) : RelocationRef(B) {
+ assert(isa<ELFObjectFileBase>(RelocationRef::getObject()));
+ }
+
+ const ELFObjectFileBase *getObject() const {
+ return cast<ELFObjectFileBase>(RelocationRef::getObject());
+ }
+
+ Expected<int64_t> getAddend() const {
+ return getObject()->getRelocationAddend(getRawDataRefImpl());
+ }
+};
+
+class elf_relocation_iterator : public relocation_iterator {
+public:
+ elf_relocation_iterator(const relocation_iterator &B)
+ : relocation_iterator(RelocationRef(
+ B->getRawDataRefImpl(), cast<ELFObjectFileBase>(B->getObject()))) {}
+
+ const ELFRelocationRef *operator->() const {
+ return static_cast<const ELFRelocationRef *>(
+ relocation_iterator::operator->());
+ }
+
+ const ELFRelocationRef &operator*() const {
+ return static_cast<const ELFRelocationRef &>(
+ relocation_iterator::operator*());
+ }
+};
+
+inline ELFObjectFileBase::elf_symbol_iterator_range
+ELFObjectFileBase::symbols() const {
+ return elf_symbol_iterator_range(symbol_begin(), symbol_end());
+}
+
+template <class ELFT> class ELFObjectFile : public ELFObjectFileBase {
+ uint16_t getEMachine() const override;
+ uint64_t getSymbolSize(DataRefImpl Sym) const override;
+
+public:
+ LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
+
+ using uintX_t = typename ELFT::uint;
+
+ using Elf_Sym = typename ELFT::Sym;
+ using Elf_Shdr = typename ELFT::Shdr;
+ using Elf_Ehdr = typename ELFT::Ehdr;
+ using Elf_Rel = typename ELFT::Rel;
+ using Elf_Rela = typename ELFT::Rela;
+ using Elf_Dyn = typename ELFT::Dyn;
+
+private:
+ ELFObjectFile(MemoryBufferRef Object, ELFFile<ELFT> EF,
+ const Elf_Shdr *DotDynSymSec, const Elf_Shdr *DotSymtabSec,
+ ArrayRef<Elf_Word> ShndxTable);
+
+protected:
+ ELFFile<ELFT> EF;
+
+ const Elf_Shdr *DotDynSymSec = nullptr; // Dynamic symbol table section.
+ const Elf_Shdr *DotSymtabSec = nullptr; // Symbol table section.
+ ArrayRef<Elf_Word> ShndxTable;
+
+ void moveSymbolNext(DataRefImpl &Symb) const override;
+ Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
+ Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
+ uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
+ uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
+ uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
+ uint32_t getSymbolFlags(DataRefImpl Symb) const override;
+ uint8_t getSymbolOther(DataRefImpl Symb) const override;
+ uint8_t getSymbolELFType(DataRefImpl Symb) const override;
+ Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
+ Expected<section_iterator> getSymbolSection(const Elf_Sym *Symb,
+ const Elf_Shdr *SymTab) const;
+ Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
+
+ void moveSectionNext(DataRefImpl &Sec) const override;
+ std::error_code getSectionName(DataRefImpl Sec,
+ StringRef &Res) const override;
+ uint64_t getSectionAddress(DataRefImpl Sec) const override;
+ uint64_t getSectionIndex(DataRefImpl Sec) const override;
+ uint64_t getSectionSize(DataRefImpl Sec) const override;
+ std::error_code getSectionContents(DataRefImpl Sec,
+ StringRef &Res) const override;
+ uint64_t getSectionAlignment(DataRefImpl Sec) const override;
+ bool isSectionCompressed(DataRefImpl Sec) const override;
+ bool isSectionText(DataRefImpl Sec) const override;
+ bool isSectionData(DataRefImpl Sec) const override;
+ bool isSectionBSS(DataRefImpl Sec) const override;
+ bool isSectionVirtual(DataRefImpl Sec) const override;
+ relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
+ relocation_iterator section_rel_end(DataRefImpl Sec) const override;
+ section_iterator getRelocatedSection(DataRefImpl Sec) const override;
+
+ void moveRelocationNext(DataRefImpl &Rel) const override;
+ uint64_t getRelocationOffset(DataRefImpl Rel) const override;
+ symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
+ uint64_t getRelocationType(DataRefImpl Rel) const override;
+ void getRelocationTypeName(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const override;
+
+ uint32_t getSectionType(DataRefImpl Sec) const override;
+ uint64_t getSectionFlags(DataRefImpl Sec) const override;
+ uint64_t getSectionOffset(DataRefImpl Sec) const override;
+ StringRef getRelocationTypeName(uint32_t Type) const;
+
+ /// \brief Get the relocation section that contains \a Rel.
+ const Elf_Shdr *getRelSection(DataRefImpl Rel) const {
+ auto RelSecOrErr = EF.getSection(Rel.d.a);
+ if (!RelSecOrErr)
+ report_fatal_error(errorToErrorCode(RelSecOrErr.takeError()).message());
+ return *RelSecOrErr;
+ }
+
+ DataRefImpl toDRI(const Elf_Shdr *SymTable, unsigned SymbolNum) const {
+ DataRefImpl DRI;
+ if (!SymTable) {
+ DRI.d.a = 0;
+ DRI.d.b = 0;
+ return DRI;
+ }
+ assert(SymTable->sh_type == ELF::SHT_SYMTAB ||
+ SymTable->sh_type == ELF::SHT_DYNSYM);
+
+ auto SectionsOrErr = EF.sections();
+ if (!SectionsOrErr) {
+ DRI.d.a = 0;
+ DRI.d.b = 0;
+ return DRI;
+ }
+ uintptr_t SHT = reinterpret_cast<uintptr_t>((*SectionsOrErr).begin());
+ unsigned SymTableIndex =
+ (reinterpret_cast<uintptr_t>(SymTable) - SHT) / sizeof(Elf_Shdr);
+
+ DRI.d.a = SymTableIndex;
+ DRI.d.b = SymbolNum;
+ return DRI;
+ }
+
+ const Elf_Shdr *toELFShdrIter(DataRefImpl Sec) const {
+ return reinterpret_cast<const Elf_Shdr *>(Sec.p);
+ }
+
+ DataRefImpl toDRI(const Elf_Shdr *Sec) const {
+ DataRefImpl DRI;
+ DRI.p = reinterpret_cast<uintptr_t>(Sec);
+ return DRI;
+ }
+
+ DataRefImpl toDRI(const Elf_Dyn *Dyn) const {
+ DataRefImpl DRI;
+ DRI.p = reinterpret_cast<uintptr_t>(Dyn);
+ return DRI;
+ }
+
+ bool isExportedToOtherDSO(const Elf_Sym *ESym) const {
+ unsigned char Binding = ESym->getBinding();
+ unsigned char Visibility = ESym->getVisibility();
+
+ // A symbol is exported if its binding is either GLOBAL or WEAK, and its
+ // visibility is either DEFAULT or PROTECTED. All other symbols are not
+ // exported.
+ return ((Binding == ELF::STB_GLOBAL || Binding == ELF::STB_WEAK) &&
+ (Visibility == ELF::STV_DEFAULT ||
+ Visibility == ELF::STV_PROTECTED));
+ }
+
+ // This flag is used for classof, to distinguish ELFObjectFile from
+ // its subclass. If more subclasses will be created, this flag will
+ // have to become an enum.
+ bool isDyldELFObject;
+
+public:
+ ELFObjectFile(ELFObjectFile<ELFT> &&Other);
+ static Expected<ELFObjectFile<ELFT>> create(MemoryBufferRef Object);
+
+ const Elf_Rel *getRel(DataRefImpl Rel) const;
+ const Elf_Rela *getRela(DataRefImpl Rela) const;
+
+ const Elf_Sym *getSymbol(DataRefImpl Sym) const {
+ auto Ret = EF.template getEntry<Elf_Sym>(Sym.d.a, Sym.d.b);
+ if (!Ret)
+ report_fatal_error(errorToErrorCode(Ret.takeError()).message());
+ return *Ret;
+ }
+
+ const Elf_Shdr *getSection(DataRefImpl Sec) const {
+ return reinterpret_cast<const Elf_Shdr *>(Sec.p);
+ }
+
+ basic_symbol_iterator symbol_begin() const override;
+ basic_symbol_iterator symbol_end() const override;
+
+ elf_symbol_iterator dynamic_symbol_begin() const;
+ elf_symbol_iterator dynamic_symbol_end() const;
+
+ section_iterator section_begin() const override;
+ section_iterator section_end() const override;
+
+ Expected<int64_t> getRelocationAddend(DataRefImpl Rel) const override;
+
+ uint8_t getBytesInAddress() const override;
+ StringRef getFileFormatName() const override;
+ Triple::ArchType getArch() const override;
+
+ unsigned getPlatformFlags() const override { return EF.getHeader()->e_flags; }
+
+ std::error_code getBuildAttributes(ARMAttributeParser &Attributes) const override {
+ auto SectionsOrErr = EF.sections();
+ if (!SectionsOrErr)
+ return errorToErrorCode(SectionsOrErr.takeError());
+
+ for (const Elf_Shdr &Sec : *SectionsOrErr) {
+ if (Sec.sh_type == ELF::SHT_ARM_ATTRIBUTES) {
+ auto ErrorOrContents = EF.getSectionContents(&Sec);
+ if (!ErrorOrContents)
+ return errorToErrorCode(ErrorOrContents.takeError());
+
+ auto Contents = ErrorOrContents.get();
+ if (Contents[0] != ARMBuildAttrs::Format_Version || Contents.size() == 1)
+ return std::error_code();
+
+ Attributes.Parse(Contents, ELFT::TargetEndianness == support::little);
+ break;
+ }
+ }
+ return std::error_code();
+ }
+
+ const ELFFile<ELFT> *getELFFile() const { return &EF; }
+
+ bool isDyldType() const { return isDyldELFObject; }
+ static bool classof(const Binary *v) {
+ return v->getType() == getELFType(ELFT::TargetEndianness == support::little,
+ ELFT::Is64Bits);
+ }
+
+ elf_symbol_iterator_range getDynamicSymbolIterators() const override;
+
+ bool isRelocatableObject() const override;
+};
+
+using ELF32LEObjectFile = ELFObjectFile<ELF32LE>;
+using ELF64LEObjectFile = ELFObjectFile<ELF64LE>;
+using ELF32BEObjectFile = ELFObjectFile<ELF32BE>;
+using ELF64BEObjectFile = ELFObjectFile<ELF64BE>;
+
+template <class ELFT>
+void ELFObjectFile<ELFT>::moveSymbolNext(DataRefImpl &Sym) const {
+ ++Sym.d.b;
+}
+
+template <class ELFT>
+Expected<StringRef> ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Sym) const {
+ const Elf_Sym *ESym = getSymbol(Sym);
+ auto SymTabOrErr = EF.getSection(Sym.d.a);
+ if (!SymTabOrErr)
+ return SymTabOrErr.takeError();
+ const Elf_Shdr *SymTableSec = *SymTabOrErr;
+ auto StrTabOrErr = EF.getSection(SymTableSec->sh_link);
+ if (!StrTabOrErr)
+ return StrTabOrErr.takeError();
+ const Elf_Shdr *StringTableSec = *StrTabOrErr;
+ auto SymStrTabOrErr = EF.getStringTable(StringTableSec);
+ if (!SymStrTabOrErr)
+ return SymStrTabOrErr.takeError();
+ return ESym->getName(*SymStrTabOrErr);
+}
+
+template <class ELFT>
+uint64_t ELFObjectFile<ELFT>::getSectionFlags(DataRefImpl Sec) const {
+ return getSection(Sec)->sh_flags;
+}
+
+template <class ELFT>
+uint32_t ELFObjectFile<ELFT>::getSectionType(DataRefImpl Sec) const {
+ return getSection(Sec)->sh_type;
+}
+
+template <class ELFT>
+uint64_t ELFObjectFile<ELFT>::getSectionOffset(DataRefImpl Sec) const {
+ return getSection(Sec)->sh_offset;
+}
+
+template <class ELFT>
+uint64_t ELFObjectFile<ELFT>::getSymbolValueImpl(DataRefImpl Symb) const {
+ const Elf_Sym *ESym = getSymbol(Symb);
+ uint64_t Ret = ESym->st_value;
+ if (ESym->st_shndx == ELF::SHN_ABS)
+ return Ret;
+
+ const Elf_Ehdr *Header = EF.getHeader();
+ // Clear the ARM/Thumb or microMIPS indicator flag.
+ if ((Header->e_machine == ELF::EM_ARM || Header->e_machine == ELF::EM_MIPS) &&
+ ESym->getType() == ELF::STT_FUNC)
+ Ret &= ~1;
+
+ return Ret;
+}
+
+template <class ELFT>
+Expected<uint64_t>
+ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb) const {
+ uint64_t Result = getSymbolValue(Symb);
+ const Elf_Sym *ESym = getSymbol(Symb);
+ switch (ESym->st_shndx) {
+ case ELF::SHN_COMMON:
+ case ELF::SHN_UNDEF:
+ case ELF::SHN_ABS:
+ return Result;
+ }
+
+ const Elf_Ehdr *Header = EF.getHeader();
+ auto SymTabOrErr = EF.getSection(Symb.d.a);
+ if (!SymTabOrErr)
+ return SymTabOrErr.takeError();
+ const Elf_Shdr *SymTab = *SymTabOrErr;
+
+ if (Header->e_type == ELF::ET_REL) {
+ auto SectionOrErr = EF.getSection(ESym, SymTab, ShndxTable);
+ if (!SectionOrErr)
+ return SectionOrErr.takeError();
+ const Elf_Shdr *Section = *SectionOrErr;
+ if (Section)
+ Result += Section->sh_addr;
+ }
+
+ return Result;
+}
+
+template <class ELFT>
+uint32_t ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb) const {
+ const Elf_Sym *Sym = getSymbol(Symb);
+ if (Sym->st_shndx == ELF::SHN_COMMON)
+ return Sym->st_value;
+ return 0;
+}
+
+template <class ELFT>
+uint16_t ELFObjectFile<ELFT>::getEMachine() const {
+ return EF.getHeader()->e_machine;
+}
+
+template <class ELFT>
+uint64_t ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Sym) const {
+ return getSymbol(Sym)->st_size;
+}
+
+template <class ELFT>
+uint64_t ELFObjectFile<ELFT>::getCommonSymbolSizeImpl(DataRefImpl Symb) const {
+ return getSymbol(Symb)->st_size;
+}
+
+template <class ELFT>
+uint8_t ELFObjectFile<ELFT>::getSymbolOther(DataRefImpl Symb) const {
+ return getSymbol(Symb)->st_other;
+}
+
+template <class ELFT>
+uint8_t ELFObjectFile<ELFT>::getSymbolELFType(DataRefImpl Symb) const {
+ return getSymbol(Symb)->getType();
+}
+
+template <class ELFT>
+Expected<SymbolRef::Type>
+ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb) const {
+ const Elf_Sym *ESym = getSymbol(Symb);
+
+ switch (ESym->getType()) {
+ case ELF::STT_NOTYPE:
+ return SymbolRef::ST_Unknown;
+ case ELF::STT_SECTION:
+ return SymbolRef::ST_Debug;
+ case ELF::STT_FILE:
+ return SymbolRef::ST_File;
+ case ELF::STT_FUNC:
+ return SymbolRef::ST_Function;
+ case ELF::STT_OBJECT:
+ case ELF::STT_COMMON:
+ case ELF::STT_TLS:
+ return SymbolRef::ST_Data;
+ default:
+ return SymbolRef::ST_Other;
+ }
+}
+
+template <class ELFT>
+uint32_t ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Sym) const {
+ const Elf_Sym *ESym = getSymbol(Sym);
+
+ uint32_t Result = SymbolRef::SF_None;
+
+ if (ESym->getBinding() != ELF::STB_LOCAL)
+ Result |= SymbolRef::SF_Global;
+
+ if (ESym->getBinding() == ELF::STB_WEAK)
+ Result |= SymbolRef::SF_Weak;
+
+ if (ESym->st_shndx == ELF::SHN_ABS)
+ Result |= SymbolRef::SF_Absolute;
+
+ if (ESym->getType() == ELF::STT_FILE || ESym->getType() == ELF::STT_SECTION)
+ Result |= SymbolRef::SF_FormatSpecific;
+
+ auto DotSymtabSecSyms = EF.symbols(DotSymtabSec);
+ if (DotSymtabSecSyms && ESym == (*DotSymtabSecSyms).begin())
+ Result |= SymbolRef::SF_FormatSpecific;
+ auto DotDynSymSecSyms = EF.symbols(DotDynSymSec);
+ if (DotDynSymSecSyms && ESym == (*DotDynSymSecSyms).begin())
+ Result |= SymbolRef::SF_FormatSpecific;
+
+ if (EF.getHeader()->e_machine == ELF::EM_ARM) {
+ if (Expected<StringRef> NameOrErr = getSymbolName(Sym)) {
+ StringRef Name = *NameOrErr;
+ if (Name.startswith("$d") || Name.startswith("$t") ||
+ Name.startswith("$a"))
+ Result |= SymbolRef::SF_FormatSpecific;
+ } else {
+ // TODO: Actually report errors helpfully.
+ consumeError(NameOrErr.takeError());
+ }
+ if (ESym->getType() == ELF::STT_FUNC && (ESym->st_value & 1) == 1)
+ Result |= SymbolRef::SF_Thumb;
+ }
+
+ if (ESym->st_shndx == ELF::SHN_UNDEF)
+ Result |= SymbolRef::SF_Undefined;
+
+ if (ESym->getType() == ELF::STT_COMMON || ESym->st_shndx == ELF::SHN_COMMON)
+ Result |= SymbolRef::SF_Common;
+
+ if (isExportedToOtherDSO(ESym))
+ Result |= SymbolRef::SF_Exported;
+
+ if (ESym->getVisibility() == ELF::STV_HIDDEN)
+ Result |= SymbolRef::SF_Hidden;
+
+ return Result;
+}
+
+template <class ELFT>
+Expected<section_iterator>
+ELFObjectFile<ELFT>::getSymbolSection(const Elf_Sym *ESym,
+ const Elf_Shdr *SymTab) const {
+ auto ESecOrErr = EF.getSection(ESym, SymTab, ShndxTable);
+ if (!ESecOrErr)
+ return ESecOrErr.takeError();
+
+ const Elf_Shdr *ESec = *ESecOrErr;
+ if (!ESec)
+ return section_end();
+
+ DataRefImpl Sec;
+ Sec.p = reinterpret_cast<intptr_t>(ESec);
+ return section_iterator(SectionRef(Sec, this));
+}
+
+template <class ELFT>
+Expected<section_iterator>
+ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb) const {
+ const Elf_Sym *Sym = getSymbol(Symb);
+ auto SymTabOrErr = EF.getSection(Symb.d.a);
+ if (!SymTabOrErr)
+ return SymTabOrErr.takeError();
+ const Elf_Shdr *SymTab = *SymTabOrErr;
+ return getSymbolSection(Sym, SymTab);
+}
+
+template <class ELFT>
+void ELFObjectFile<ELFT>::moveSectionNext(DataRefImpl &Sec) const {
+ const Elf_Shdr *ESec = getSection(Sec);
+ Sec = toDRI(++ESec);
+}
+
+template <class ELFT>
+std::error_code ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec,
+ StringRef &Result) const {
+ auto Name = EF.getSectionName(&*getSection(Sec));
+ if (!Name)
+ return errorToErrorCode(Name.takeError());
+ Result = *Name;
+ return std::error_code();
+}
+
+template <class ELFT>
+uint64_t ELFObjectFile<ELFT>::getSectionAddress(DataRefImpl Sec) const {
+ return getSection(Sec)->sh_addr;
+}
+
+template <class ELFT>
+uint64_t ELFObjectFile<ELFT>::getSectionIndex(DataRefImpl Sec) const {
+ auto SectionsOrErr = EF.sections();
+ handleAllErrors(std::move(SectionsOrErr.takeError()),
+ [](const ErrorInfoBase &) {
+ llvm_unreachable("unable to get section index");
+ });
+ const Elf_Shdr *First = SectionsOrErr->begin();
+ return getSection(Sec) - First;
+}
+
+template <class ELFT>
+uint64_t ELFObjectFile<ELFT>::getSectionSize(DataRefImpl Sec) const {
+ return getSection(Sec)->sh_size;
+}
+
+template <class ELFT>
+std::error_code
+ELFObjectFile<ELFT>::getSectionContents(DataRefImpl Sec,
+ StringRef &Result) const {
+ const Elf_Shdr *EShdr = getSection(Sec);
+ if (std::error_code EC =
+ checkOffset(getMemoryBufferRef(),
+ (uintptr_t)base() + EShdr->sh_offset, EShdr->sh_size))
+ return EC;
+ Result = StringRef((const char *)base() + EShdr->sh_offset, EShdr->sh_size);
+ return std::error_code();
+}
+
+template <class ELFT>
+uint64_t ELFObjectFile<ELFT>::getSectionAlignment(DataRefImpl Sec) const {
+ return getSection(Sec)->sh_addralign;
+}
+
+template <class ELFT>
+bool ELFObjectFile<ELFT>::isSectionCompressed(DataRefImpl Sec) const {
+ return getSection(Sec)->sh_flags & ELF::SHF_COMPRESSED;
+}
+
+template <class ELFT>
+bool ELFObjectFile<ELFT>::isSectionText(DataRefImpl Sec) const {
+ return getSection(Sec)->sh_flags & ELF::SHF_EXECINSTR;
+}
+
+template <class ELFT>
+bool ELFObjectFile<ELFT>::isSectionData(DataRefImpl Sec) const {
+ const Elf_Shdr *EShdr = getSection(Sec);
+ return EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) &&
+ EShdr->sh_type == ELF::SHT_PROGBITS;
+}
+
+template <class ELFT>
+bool ELFObjectFile<ELFT>::isSectionBSS(DataRefImpl Sec) const {
+ const Elf_Shdr *EShdr = getSection(Sec);
+ return EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) &&
+ EShdr->sh_type == ELF::SHT_NOBITS;
+}
+
+template <class ELFT>
+bool ELFObjectFile<ELFT>::isSectionVirtual(DataRefImpl Sec) const {
+ return getSection(Sec)->sh_type == ELF::SHT_NOBITS;
+}
+
+template <class ELFT>
+relocation_iterator
+ELFObjectFile<ELFT>::section_rel_begin(DataRefImpl Sec) const {
+ DataRefImpl RelData;
+ auto SectionsOrErr = EF.sections();
+ if (!SectionsOrErr)
+ return relocation_iterator(RelocationRef());
+ uintptr_t SHT = reinterpret_cast<uintptr_t>((*SectionsOrErr).begin());
+ RelData.d.a = (Sec.p - SHT) / EF.getHeader()->e_shentsize;
+ RelData.d.b = 0;
+ return relocation_iterator(RelocationRef(RelData, this));
+}
+
+template <class ELFT>
+relocation_iterator
+ELFObjectFile<ELFT>::section_rel_end(DataRefImpl Sec) const {
+ const Elf_Shdr *S = reinterpret_cast<const Elf_Shdr *>(Sec.p);
+ relocation_iterator Begin = section_rel_begin(Sec);
+ if (S->sh_type != ELF::SHT_RELA && S->sh_type != ELF::SHT_REL)
+ return Begin;
+ DataRefImpl RelData = Begin->getRawDataRefImpl();
+ const Elf_Shdr *RelSec = getRelSection(RelData);
+
+ // Error check sh_link here so that getRelocationSymbol can just use it.
+ auto SymSecOrErr = EF.getSection(RelSec->sh_link);
+ if (!SymSecOrErr)
+ report_fatal_error(errorToErrorCode(SymSecOrErr.takeError()).message());
+
+ RelData.d.b += S->sh_size / S->sh_entsize;
+ return relocation_iterator(RelocationRef(RelData, this));
+}
+
+template <class ELFT>
+section_iterator
+ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const {
+ if (EF.getHeader()->e_type != ELF::ET_REL)
+ return section_end();
+
+ const Elf_Shdr *EShdr = getSection(Sec);
+ uintX_t Type = EShdr->sh_type;
+ if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA)
+ return section_end();
+
+ auto R = EF.getSection(EShdr->sh_info);
+ if (!R)
+ report_fatal_error(errorToErrorCode(R.takeError()).message());
+ return section_iterator(SectionRef(toDRI(*R), this));
+}
+
+// Relocations
+template <class ELFT>
+void ELFObjectFile<ELFT>::moveRelocationNext(DataRefImpl &Rel) const {
+ ++Rel.d.b;
+}
+
+template <class ELFT>
+symbol_iterator
+ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const {
+ uint32_t symbolIdx;
+ const Elf_Shdr *sec = getRelSection(Rel);
+ if (sec->sh_type == ELF::SHT_REL)
+ symbolIdx = getRel(Rel)->getSymbol(EF.isMips64EL());
+ else
+ symbolIdx = getRela(Rel)->getSymbol(EF.isMips64EL());
+ if (!symbolIdx)
+ return symbol_end();
+
+ // FIXME: error check symbolIdx
+ DataRefImpl SymbolData;
+ SymbolData.d.a = sec->sh_link;
+ SymbolData.d.b = symbolIdx;
+ return symbol_iterator(SymbolRef(SymbolData, this));
+}
+
+template <class ELFT>
+uint64_t ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel) const {
+ assert(EF.getHeader()->e_type == ELF::ET_REL &&
+ "Only relocatable object files have relocation offsets");
+ const Elf_Shdr *sec = getRelSection(Rel);
+ if (sec->sh_type == ELF::SHT_REL)
+ return getRel(Rel)->r_offset;
+
+ return getRela(Rel)->r_offset;
+}
+
+template <class ELFT>
+uint64_t ELFObjectFile<ELFT>::getRelocationType(DataRefImpl Rel) const {
+ const Elf_Shdr *sec = getRelSection(Rel);
+ if (sec->sh_type == ELF::SHT_REL)
+ return getRel(Rel)->getType(EF.isMips64EL());
+ else
+ return getRela(Rel)->getType(EF.isMips64EL());
+}
+
+template <class ELFT>
+StringRef ELFObjectFile<ELFT>::getRelocationTypeName(uint32_t Type) const {
+ return getELFRelocationTypeName(EF.getHeader()->e_machine, Type);
+}
+
+template <class ELFT>
+void ELFObjectFile<ELFT>::getRelocationTypeName(
+ DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
+ uint32_t type = getRelocationType(Rel);
+ EF.getRelocationTypeName(type, Result);
+}
+
+template <class ELFT>
+Expected<int64_t>
+ELFObjectFile<ELFT>::getRelocationAddend(DataRefImpl Rel) const {
+ if (getRelSection(Rel)->sh_type != ELF::SHT_RELA)
+ return createError("Section is not SHT_RELA");
+ return (int64_t)getRela(Rel)->r_addend;
+}
+
+template <class ELFT>
+const typename ELFObjectFile<ELFT>::Elf_Rel *
+ELFObjectFile<ELFT>::getRel(DataRefImpl Rel) const {
+ assert(getRelSection(Rel)->sh_type == ELF::SHT_REL);
+ auto Ret = EF.template getEntry<Elf_Rel>(Rel.d.a, Rel.d.b);
+ if (!Ret)
+ report_fatal_error(errorToErrorCode(Ret.takeError()).message());
+ return *Ret;
+}
+
+template <class ELFT>
+const typename ELFObjectFile<ELFT>::Elf_Rela *
+ELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const {
+ assert(getRelSection(Rela)->sh_type == ELF::SHT_RELA);
+ auto Ret = EF.template getEntry<Elf_Rela>(Rela.d.a, Rela.d.b);
+ if (!Ret)
+ report_fatal_error(errorToErrorCode(Ret.takeError()).message());
+ return *Ret;
+}
+
+template <class ELFT>
+Expected<ELFObjectFile<ELFT>>
+ELFObjectFile<ELFT>::create(MemoryBufferRef Object) {
+ auto EFOrErr = ELFFile<ELFT>::create(Object.getBuffer());
+ if (Error E = EFOrErr.takeError())
+ return std::move(E);
+ auto EF = std::move(*EFOrErr);
+
+ auto SectionsOrErr = EF.sections();
+ if (!SectionsOrErr)
+ return SectionsOrErr.takeError();
+
+ const Elf_Shdr *DotDynSymSec = nullptr;
+ const Elf_Shdr *DotSymtabSec = nullptr;
+ ArrayRef<Elf_Word> ShndxTable;
+ for (const Elf_Shdr &Sec : *SectionsOrErr) {
+ switch (Sec.sh_type) {
+ case ELF::SHT_DYNSYM: {
+ if (DotDynSymSec)
+ return createError("More than one dynamic symbol table!");
+ DotDynSymSec = &Sec;
+ break;
+ }
+ case ELF::SHT_SYMTAB: {
+ if (DotSymtabSec)
+ return createError("More than one static symbol table!");
+ DotSymtabSec = &Sec;
+ break;
+ }
+ case ELF::SHT_SYMTAB_SHNDX: {
+ auto TableOrErr = EF.getSHNDXTable(Sec);
+ if (!TableOrErr)
+ return TableOrErr.takeError();
+ ShndxTable = *TableOrErr;
+ break;
+ }
+ }
+ }
+ return ELFObjectFile<ELFT>(Object, EF, DotDynSymSec, DotSymtabSec,
+ ShndxTable);
+}
+
+template <class ELFT>
+ELFObjectFile<ELFT>::ELFObjectFile(MemoryBufferRef Object, ELFFile<ELFT> EF,
+ const Elf_Shdr *DotDynSymSec,
+ const Elf_Shdr *DotSymtabSec,
+ ArrayRef<Elf_Word> ShndxTable)
+ : ELFObjectFileBase(
+ getELFType(ELFT::TargetEndianness == support::little, ELFT::Is64Bits),
+ Object),
+ EF(EF), DotDynSymSec(DotDynSymSec), DotSymtabSec(DotSymtabSec),
+ ShndxTable(ShndxTable) {}
+
+template <class ELFT>
+ELFObjectFile<ELFT>::ELFObjectFile(ELFObjectFile<ELFT> &&Other)
+ : ELFObjectFile(Other.Data, Other.EF, Other.DotDynSymSec,
+ Other.DotSymtabSec, Other.ShndxTable) {}
+
+template <class ELFT>
+basic_symbol_iterator ELFObjectFile<ELFT>::symbol_begin() const {
+ DataRefImpl Sym = toDRI(DotSymtabSec, 0);
+ return basic_symbol_iterator(SymbolRef(Sym, this));
+}
+
+template <class ELFT>
+basic_symbol_iterator ELFObjectFile<ELFT>::symbol_end() const {
+ const Elf_Shdr *SymTab = DotSymtabSec;
+ if (!SymTab)
+ return symbol_begin();
+ DataRefImpl Sym = toDRI(SymTab, SymTab->sh_size / sizeof(Elf_Sym));
+ return basic_symbol_iterator(SymbolRef(Sym, this));
+}
+
+template <class ELFT>
+elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_begin() const {
+ DataRefImpl Sym = toDRI(DotDynSymSec, 0);
+ return symbol_iterator(SymbolRef(Sym, this));
+}
+
+template <class ELFT>
+elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_end() const {
+ const Elf_Shdr *SymTab = DotDynSymSec;
+ if (!SymTab)
+ return dynamic_symbol_begin();
+ DataRefImpl Sym = toDRI(SymTab, SymTab->sh_size / sizeof(Elf_Sym));
+ return basic_symbol_iterator(SymbolRef(Sym, this));
+}
+
+template <class ELFT>
+section_iterator ELFObjectFile<ELFT>::section_begin() const {
+ auto SectionsOrErr = EF.sections();
+ if (!SectionsOrErr)
+ return section_iterator(SectionRef());
+ return section_iterator(SectionRef(toDRI((*SectionsOrErr).begin()), this));
+}
+
+template <class ELFT>
+section_iterator ELFObjectFile<ELFT>::section_end() const {
+ auto SectionsOrErr = EF.sections();
+ if (!SectionsOrErr)
+ return section_iterator(SectionRef());
+ return section_iterator(SectionRef(toDRI((*SectionsOrErr).end()), this));
+}
+
+template <class ELFT>
+uint8_t ELFObjectFile<ELFT>::getBytesInAddress() const {
+ return ELFT::Is64Bits ? 8 : 4;
+}
+
+template <class ELFT>
+StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
+ bool IsLittleEndian = ELFT::TargetEndianness == support::little;
+ switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) {
+ case ELF::ELFCLASS32:
+ switch (EF.getHeader()->e_machine) {
+ case ELF::EM_386:
+ return "ELF32-i386";
+ case ELF::EM_IAMCU:
+ return "ELF32-iamcu";
+ case ELF::EM_X86_64:
+ return "ELF32-x86-64";
+ case ELF::EM_ARM:
+ return (IsLittleEndian ? "ELF32-arm-little" : "ELF32-arm-big");
+ case ELF::EM_AVR:
+ return "ELF32-avr";
+ case ELF::EM_HEXAGON:
+ return "ELF32-hexagon";
+ case ELF::EM_LANAI:
+ return "ELF32-lanai";
+ case ELF::EM_MIPS:
+ return "ELF32-mips";
+ case ELF::EM_PPC:
+ return "ELF32-ppc";
+ case ELF::EM_RISCV:
+ return "ELF32-riscv";
+ case ELF::EM_SPARC:
+ case ELF::EM_SPARC32PLUS:
+ return "ELF32-sparc";
+ case ELF::EM_WEBASSEMBLY:
+ return "ELF32-wasm";
+ case ELF::EM_AMDGPU:
+ return "ELF32-amdgpu";
+ default:
+ return "ELF32-unknown";
+ }
+ case ELF::ELFCLASS64:
+ switch (EF.getHeader()->e_machine) {
+ case ELF::EM_386:
+ return "ELF64-i386";
+ case ELF::EM_X86_64:
+ return "ELF64-x86-64";
+ case ELF::EM_AARCH64:
+ return (IsLittleEndian ? "ELF64-aarch64-little" : "ELF64-aarch64-big");
+ case ELF::EM_PPC64:
+ return "ELF64-ppc64";
+ case ELF::EM_RISCV:
+ return "ELF64-riscv";
+ case ELF::EM_S390:
+ return "ELF64-s390";
+ case ELF::EM_SPARCV9:
+ return "ELF64-sparc";
+ case ELF::EM_MIPS:
+ return "ELF64-mips";
+ case ELF::EM_WEBASSEMBLY:
+ return "ELF64-wasm";
+ case ELF::EM_AMDGPU:
+ return "ELF64-amdgpu";
+ case ELF::EM_BPF:
+ return "ELF64-BPF";
+ default:
+ return "ELF64-unknown";
+ }
+ default:
+ // FIXME: Proper error handling.
+ report_fatal_error("Invalid ELFCLASS!");
+ }
+}
+
+template <class ELFT> Triple::ArchType ELFObjectFile<ELFT>::getArch() const {
+ bool IsLittleEndian = ELFT::TargetEndianness == support::little;
+ switch (EF.getHeader()->e_machine) {
+ case ELF::EM_386:
+ case ELF::EM_IAMCU:
+ return Triple::x86;
+ case ELF::EM_X86_64:
+ return Triple::x86_64;
+ case ELF::EM_AARCH64:
+ return IsLittleEndian ? Triple::aarch64 : Triple::aarch64_be;
+ case ELF::EM_ARM:
+ return Triple::arm;
+ case ELF::EM_AVR:
+ return Triple::avr;
+ case ELF::EM_HEXAGON:
+ return Triple::hexagon;
+ case ELF::EM_LANAI:
+ return Triple::lanai;
+ case ELF::EM_MIPS:
+ switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) {
+ case ELF::ELFCLASS32:
+ return IsLittleEndian ? Triple::mipsel : Triple::mips;
+ case ELF::ELFCLASS64:
+ return IsLittleEndian ? Triple::mips64el : Triple::mips64;
+ default:
+ report_fatal_error("Invalid ELFCLASS!");
+ }
+ case ELF::EM_PPC:
+ return Triple::ppc;
+ case ELF::EM_PPC64:
+ return IsLittleEndian ? Triple::ppc64le : Triple::ppc64;
+ case ELF::EM_RISCV:
+ switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) {
+ case ELF::ELFCLASS32:
+ return Triple::riscv32;
+ case ELF::ELFCLASS64:
+ return Triple::riscv64;
+ default:
+ report_fatal_error("Invalid ELFCLASS!");
+ }
+ case ELF::EM_S390:
+ return Triple::systemz;
+
+ case ELF::EM_SPARC:
+ case ELF::EM_SPARC32PLUS:
+ return IsLittleEndian ? Triple::sparcel : Triple::sparc;
+ case ELF::EM_SPARCV9:
+ return Triple::sparcv9;
+ case ELF::EM_WEBASSEMBLY:
+ switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) {
+ case ELF::ELFCLASS32: return Triple::wasm32;
+ case ELF::ELFCLASS64: return Triple::wasm64;
+ default: return Triple::UnknownArch;
+ }
+
+ case ELF::EM_AMDGPU: {
+ if (!IsLittleEndian)
+ return Triple::UnknownArch;
+
+ unsigned MACH = EF.getHeader()->e_flags & ELF::EF_AMDGPU_MACH;
+ if (MACH >= ELF::EF_AMDGPU_MACH_R600_FIRST &&
+ MACH <= ELF::EF_AMDGPU_MACH_R600_LAST)
+ return Triple::r600;
+ if (MACH >= ELF::EF_AMDGPU_MACH_AMDGCN_FIRST &&
+ MACH <= ELF::EF_AMDGPU_MACH_AMDGCN_LAST)
+ return Triple::amdgcn;
+
+ return Triple::UnknownArch;
+ }
+
+ case ELF::EM_BPF:
+ return IsLittleEndian ? Triple::bpfel : Triple::bpfeb;
+
+ default:
+ return Triple::UnknownArch;
+ }
+}
+
+template <class ELFT>
+ELFObjectFileBase::elf_symbol_iterator_range
+ELFObjectFile<ELFT>::getDynamicSymbolIterators() const {
+ return make_range(dynamic_symbol_begin(), dynamic_symbol_end());
+}
+
+template <class ELFT> bool ELFObjectFile<ELFT>::isRelocatableObject() const {
+ return EF.getHeader()->e_type == ELF::ET_REL;
+}
+
+} // end namespace object
+} // end namespace llvm
+
+#endif // LLVM_OBJECT_ELFOBJECTFILE_H
diff --git a/linux-x64/clang/include/llvm/Object/ELFTypes.h b/linux-x64/clang/include/llvm/Object/ELFTypes.h
new file mode 100644
index 0000000..260ca96
--- /dev/null
+++ b/linux-x64/clang/include/llvm/Object/ELFTypes.h
@@ -0,0 +1,740 @@
+//===- ELFTypes.h - Endian specific types for ELF ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_ELFTYPES_H
+#define LLVM_OBJECT_ELFTYPES_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/ELF.h"
+#include "llvm/Object/Error.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <cassert>
+#include <cstdint>
+#include <cstring>
+#include <type_traits>
+
+namespace llvm {
+namespace object {
+
+using support::endianness;
+
+template <class ELFT> struct Elf_Ehdr_Impl;
+template <class ELFT> struct Elf_Shdr_Impl;
+template <class ELFT> struct Elf_Sym_Impl;
+template <class ELFT> struct Elf_Dyn_Impl;
+template <class ELFT> struct Elf_Phdr_Impl;
+template <class ELFT, bool isRela> struct Elf_Rel_Impl;
+template <class ELFT> struct Elf_Verdef_Impl;
+template <class ELFT> struct Elf_Verdaux_Impl;
+template <class ELFT> struct Elf_Verneed_Impl;
+template <class ELFT> struct Elf_Vernaux_Impl;
+template <class ELFT> struct Elf_Versym_Impl;
+template <class ELFT> struct Elf_Hash_Impl;
+template <class ELFT> struct Elf_GnuHash_Impl;
+template <class ELFT> struct Elf_Chdr_Impl;
+template <class ELFT> struct Elf_Nhdr_Impl;
+template <class ELFT> class Elf_Note_Impl;
+template <class ELFT> class Elf_Note_Iterator_Impl;
+
+template <endianness E, bool Is64> struct ELFType {
+private:
+ template <typename Ty>
+ using packed = support::detail::packed_endian_specific_integral<Ty, E, 1>;
+
+public:
+ static const endianness TargetEndianness = E;
+ static const bool Is64Bits = Is64;
+
+ using uint = typename std::conditional<Is64, uint64_t, uint32_t>::type;
+ using Ehdr = Elf_Ehdr_Impl<ELFType<E, Is64>>;
+ using Shdr = Elf_Shdr_Impl<ELFType<E, Is64>>;
+ using Sym = Elf_Sym_Impl<ELFType<E, Is64>>;
+ using Dyn = Elf_Dyn_Impl<ELFType<E, Is64>>;
+ using Phdr = Elf_Phdr_Impl<ELFType<E, Is64>>;
+ using Rel = Elf_Rel_Impl<ELFType<E, Is64>, false>;
+ using Rela = Elf_Rel_Impl<ELFType<E, Is64>, true>;
+ using Verdef = Elf_Verdef_Impl<ELFType<E, Is64>>;
+ using Verdaux = Elf_Verdaux_Impl<ELFType<E, Is64>>;
+ using Verneed = Elf_Verneed_Impl<ELFType<E, Is64>>;
+ using Vernaux = Elf_Vernaux_Impl<ELFType<E, Is64>>;
+ using Versym = Elf_Versym_Impl<ELFType<E, Is64>>;
+ using Hash = Elf_Hash_Impl<ELFType<E, Is64>>;
+ using GnuHash = Elf_GnuHash_Impl<ELFType<E, Is64>>;
+ using Chdr = Elf_Chdr_Impl<ELFType<E, Is64>>;
+ using Nhdr = Elf_Nhdr_Impl<ELFType<E, Is64>>;
+ using Note = Elf_Note_Impl<ELFType<E, Is64>>;
+ using NoteIterator = Elf_Note_Iterator_Impl<ELFType<E, Is64>>;
+ using DynRange = ArrayRef<Dyn>;
+ using ShdrRange = ArrayRef<Shdr>;
+ using SymRange = ArrayRef<Sym>;
+ using RelRange = ArrayRef<Rel>;
+ using RelaRange = ArrayRef<Rela>;
+ using PhdrRange = ArrayRef<Phdr>;
+
+ using Half = packed<uint16_t>;
+ using Word = packed<uint32_t>;
+ using Sword = packed<int32_t>;
+ using Xword = packed<uint64_t>;
+ using Sxword = packed<int64_t>;
+ using Addr = packed<uint>;
+ using Off = packed<uint>;
+};
+
+using ELF32LE = ELFType<support::little, false>;
+using ELF32BE = ELFType<support::big, false>;
+using ELF64LE = ELFType<support::little, true>;
+using ELF64BE = ELFType<support::big, true>;
+
+// Use an alignment of 2 for the typedefs since that is the worst case for
+// ELF files in archives.
+
+// I really don't like doing this, but the alternative is copypasta.
+#define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) \
+ using Elf_Addr = typename ELFT::Addr; \
+ using Elf_Off = typename ELFT::Off; \
+ using Elf_Half = typename ELFT::Half; \
+ using Elf_Word = typename ELFT::Word; \
+ using Elf_Sword = typename ELFT::Sword; \
+ using Elf_Xword = typename ELFT::Xword; \
+ using Elf_Sxword = typename ELFT::Sxword;
+
+#define LLVM_ELF_COMMA ,
+#define LLVM_ELF_IMPORT_TYPES(E, W) \
+ LLVM_ELF_IMPORT_TYPES_ELFT(ELFType<E LLVM_ELF_COMMA W>)
+
+// Section header.
+template <class ELFT> struct Elf_Shdr_Base;
+
+template <endianness TargetEndianness>
+struct Elf_Shdr_Base<ELFType<TargetEndianness, false>> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
+ Elf_Word sh_name; // Section name (index into string table)
+ Elf_Word sh_type; // Section type (SHT_*)
+ Elf_Word sh_flags; // Section flags (SHF_*)
+ Elf_Addr sh_addr; // Address where section is to be loaded
+ Elf_Off sh_offset; // File offset of section data, in bytes
+ Elf_Word sh_size; // Size of section, in bytes
+ Elf_Word sh_link; // Section type-specific header table index link
+ Elf_Word sh_info; // Section type-specific extra information
+ Elf_Word sh_addralign; // Section address alignment
+ Elf_Word sh_entsize; // Size of records contained within the section
+};
+
+template <endianness TargetEndianness>
+struct Elf_Shdr_Base<ELFType<TargetEndianness, true>> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
+ Elf_Word sh_name; // Section name (index into string table)
+ Elf_Word sh_type; // Section type (SHT_*)
+ Elf_Xword sh_flags; // Section flags (SHF_*)
+ Elf_Addr sh_addr; // Address where section is to be loaded
+ Elf_Off sh_offset; // File offset of section data, in bytes
+ Elf_Xword sh_size; // Size of section, in bytes
+ Elf_Word sh_link; // Section type-specific header table index link
+ Elf_Word sh_info; // Section type-specific extra information
+ Elf_Xword sh_addralign; // Section address alignment
+ Elf_Xword sh_entsize; // Size of records contained within the section
+};
+
+template <class ELFT>
+struct Elf_Shdr_Impl : Elf_Shdr_Base<ELFT> {
+ using Elf_Shdr_Base<ELFT>::sh_entsize;
+ using Elf_Shdr_Base<ELFT>::sh_size;
+
+ /// @brief Get the number of entities this section contains if it has any.
+ unsigned getEntityCount() const {
+ if (sh_entsize == 0)
+ return 0;
+ return sh_size / sh_entsize;
+ }
+};
+
+template <class ELFT> struct Elf_Sym_Base;
+
+template <endianness TargetEndianness>
+struct Elf_Sym_Base<ELFType<TargetEndianness, false>> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
+ Elf_Word st_name; // Symbol name (index into string table)
+ Elf_Addr st_value; // Value or address associated with the symbol
+ Elf_Word st_size; // Size of the symbol
+ unsigned char st_info; // Symbol's type and binding attributes
+ unsigned char st_other; // Must be zero; reserved
+ Elf_Half st_shndx; // Which section (header table index) it's defined in
+};
+
+template <endianness TargetEndianness>
+struct Elf_Sym_Base<ELFType<TargetEndianness, true>> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
+ Elf_Word st_name; // Symbol name (index into string table)
+ unsigned char st_info; // Symbol's type and binding attributes
+ unsigned char st_other; // Must be zero; reserved
+ Elf_Half st_shndx; // Which section (header table index) it's defined in
+ Elf_Addr st_value; // Value or address associated with the symbol
+ Elf_Xword st_size; // Size of the symbol
+};
+
+template <class ELFT>
+struct Elf_Sym_Impl : Elf_Sym_Base<ELFT> {
+ using Elf_Sym_Base<ELFT>::st_info;
+ using Elf_Sym_Base<ELFT>::st_shndx;
+ using Elf_Sym_Base<ELFT>::st_other;
+ using Elf_Sym_Base<ELFT>::st_value;
+
+ // These accessors and mutators correspond to the ELF32_ST_BIND,
+ // ELF32_ST_TYPE, and ELF32_ST_INFO macros defined in the ELF specification:
+ unsigned char getBinding() const { return st_info >> 4; }
+ unsigned char getType() const { return st_info & 0x0f; }
+ uint64_t getValue() const { return st_value; }
+ void setBinding(unsigned char b) { setBindingAndType(b, getType()); }
+ void setType(unsigned char t) { setBindingAndType(getBinding(), t); }
+
+ void setBindingAndType(unsigned char b, unsigned char t) {
+ st_info = (b << 4) + (t & 0x0f);
+ }
+
+ /// Access to the STV_xxx flag stored in the first two bits of st_other.
+ /// STV_DEFAULT: 0
+ /// STV_INTERNAL: 1
+ /// STV_HIDDEN: 2
+ /// STV_PROTECTED: 3
+ unsigned char getVisibility() const { return st_other & 0x3; }
+ void setVisibility(unsigned char v) {
+ assert(v < 4 && "Invalid value for visibility");
+ st_other = (st_other & ~0x3) | v;
+ }
+
+ bool isAbsolute() const { return st_shndx == ELF::SHN_ABS; }
+
+ bool isCommon() const {
+ return getType() == ELF::STT_COMMON || st_shndx == ELF::SHN_COMMON;
+ }
+
+ bool isDefined() const { return !isUndefined(); }
+
+ bool isProcessorSpecific() const {
+ return st_shndx >= ELF::SHN_LOPROC && st_shndx <= ELF::SHN_HIPROC;
+ }
+
+ bool isOSSpecific() const {
+ return st_shndx >= ELF::SHN_LOOS && st_shndx <= ELF::SHN_HIOS;
+ }
+
+ bool isReserved() const {
+ // ELF::SHN_HIRESERVE is 0xffff so st_shndx <= ELF::SHN_HIRESERVE is always
+ // true and some compilers warn about it.
+ return st_shndx >= ELF::SHN_LORESERVE;
+ }
+
+ bool isUndefined() const { return st_shndx == ELF::SHN_UNDEF; }
+
+ bool isExternal() const {
+ return getBinding() != ELF::STB_LOCAL;
+ }
+
+ Expected<StringRef> getName(StringRef StrTab) const;
+};
+
+template <class ELFT>
+Expected<StringRef> Elf_Sym_Impl<ELFT>::getName(StringRef StrTab) const {
+ uint32_t Offset = this->st_name;
+ if (Offset >= StrTab.size())
+ return errorCodeToError(object_error::parse_failed);
+ return StringRef(StrTab.data() + Offset);
+}
+
+/// Elf_Versym: This is the structure of entries in the SHT_GNU_versym section
+/// (.gnu.version). This structure is identical for ELF32 and ELF64.
+template <class ELFT>
+struct Elf_Versym_Impl {
+ LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
+ Elf_Half vs_index; // Version index with flags (e.g. VERSYM_HIDDEN)
+};
+
+/// Elf_Verdef: This is the structure of entries in the SHT_GNU_verdef section
+/// (.gnu.version_d). This structure is identical for ELF32 and ELF64.
+template <class ELFT>
+struct Elf_Verdef_Impl {
+ LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
+ using Elf_Verdaux = Elf_Verdaux_Impl<ELFT>;
+ Elf_Half vd_version; // Version of this structure (e.g. VER_DEF_CURRENT)
+ Elf_Half vd_flags; // Bitwise flags (VER_DEF_*)
+ Elf_Half vd_ndx; // Version index, used in .gnu.version entries
+ Elf_Half vd_cnt; // Number of Verdaux entries
+ Elf_Word vd_hash; // Hash of name
+ Elf_Word vd_aux; // Offset to the first Verdaux entry (in bytes)
+ Elf_Word vd_next; // Offset to the next Verdef entry (in bytes)
+
+ /// Get the first Verdaux entry for this Verdef.
+ const Elf_Verdaux *getAux() const {
+ return reinterpret_cast<const Elf_Verdaux *>((const char *)this + vd_aux);
+ }
+};
+
+/// Elf_Verdaux: This is the structure of auxiliary data in the SHT_GNU_verdef
+/// section (.gnu.version_d). This structure is identical for ELF32 and ELF64.
+template <class ELFT>
+struct Elf_Verdaux_Impl {
+ LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
+ Elf_Word vda_name; // Version name (offset in string table)
+ Elf_Word vda_next; // Offset to next Verdaux entry (in bytes)
+};
+
+/// Elf_Verneed: This is the structure of entries in the SHT_GNU_verneed
+/// section (.gnu.version_r). This structure is identical for ELF32 and ELF64.
+template <class ELFT>
+struct Elf_Verneed_Impl {
+ LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
+ Elf_Half vn_version; // Version of this structure (e.g. VER_NEED_CURRENT)
+ Elf_Half vn_cnt; // Number of associated Vernaux entries
+ Elf_Word vn_file; // Library name (string table offset)
+ Elf_Word vn_aux; // Offset to first Vernaux entry (in bytes)
+ Elf_Word vn_next; // Offset to next Verneed entry (in bytes)
+};
+
+/// Elf_Vernaux: This is the structure of auxiliary data in SHT_GNU_verneed
+/// section (.gnu.version_r). This structure is identical for ELF32 and ELF64.
+template <class ELFT>
+struct Elf_Vernaux_Impl {
+ LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
+ Elf_Word vna_hash; // Hash of dependency name
+ Elf_Half vna_flags; // Bitwise Flags (VER_FLAG_*)
+ Elf_Half vna_other; // Version index, used in .gnu.version entries
+ Elf_Word vna_name; // Dependency name
+ Elf_Word vna_next; // Offset to next Vernaux entry (in bytes)
+};
+
+/// Elf_Dyn_Base: This structure matches the form of entries in the dynamic
+/// table section (.dynamic) look like.
+template <class ELFT> struct Elf_Dyn_Base;
+
+template <endianness TargetEndianness>
+struct Elf_Dyn_Base<ELFType<TargetEndianness, false>> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
+ Elf_Sword d_tag;
+ union {
+ Elf_Word d_val;
+ Elf_Addr d_ptr;
+ } d_un;
+};
+
+template <endianness TargetEndianness>
+struct Elf_Dyn_Base<ELFType<TargetEndianness, true>> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
+ Elf_Sxword d_tag;
+ union {
+ Elf_Xword d_val;
+ Elf_Addr d_ptr;
+ } d_un;
+};
+
+/// Elf_Dyn_Impl: This inherits from Elf_Dyn_Base, adding getters.
+template <class ELFT>
+struct Elf_Dyn_Impl : Elf_Dyn_Base<ELFT> {
+ using Elf_Dyn_Base<ELFT>::d_tag;
+ using Elf_Dyn_Base<ELFT>::d_un;
+ using intX_t = typename std::conditional<ELFT::Is64Bits,
+ int64_t, int32_t>::type;
+ using uintX_t = typename std::conditional<ELFT::Is64Bits,
+ uint64_t, uint32_t>::type;
+ intX_t getTag() const { return d_tag; }
+ uintX_t getVal() const { return d_un.d_val; }
+ uintX_t getPtr() const { return d_un.d_ptr; }
+};
+
+template <endianness TargetEndianness>
+struct Elf_Rel_Impl<ELFType<TargetEndianness, false>, false> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
+ static const bool IsRela = false;
+ Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
+ Elf_Word r_info; // Symbol table index and type of relocation to apply
+
+ uint32_t getRInfo(bool isMips64EL) const {
+ assert(!isMips64EL);
+ return r_info;
+ }
+ void setRInfo(uint32_t R, bool IsMips64EL) {
+ assert(!IsMips64EL);
+ r_info = R;
+ }
+
+ // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE,
+ // and ELF32_R_INFO macros defined in the ELF specification:
+ uint32_t getSymbol(bool isMips64EL) const {
+ return this->getRInfo(isMips64EL) >> 8;
+ }
+ unsigned char getType(bool isMips64EL) const {
+ return (unsigned char)(this->getRInfo(isMips64EL) & 0x0ff);
+ }
+ void setSymbol(uint32_t s, bool IsMips64EL) {
+ setSymbolAndType(s, getType(IsMips64EL), IsMips64EL);
+ }
+ void setType(unsigned char t, bool IsMips64EL) {
+ setSymbolAndType(getSymbol(IsMips64EL), t, IsMips64EL);
+ }
+ void setSymbolAndType(uint32_t s, unsigned char t, bool IsMips64EL) {
+ this->setRInfo((s << 8) + t, IsMips64EL);
+ }
+};
+
+template <endianness TargetEndianness>
+struct Elf_Rel_Impl<ELFType<TargetEndianness, false>, true>
+ : public Elf_Rel_Impl<ELFType<TargetEndianness, false>, false> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
+ static const bool IsRela = true;
+ Elf_Sword r_addend; // Compute value for relocatable field by adding this
+};
+
+template <endianness TargetEndianness>
+struct Elf_Rel_Impl<ELFType<TargetEndianness, true>, false> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
+ static const bool IsRela = false;
+ Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
+ Elf_Xword r_info; // Symbol table index and type of relocation to apply
+
+ uint64_t getRInfo(bool isMips64EL) const {
+ uint64_t t = r_info;
+ if (!isMips64EL)
+ return t;
+ // Mips64 little endian has a "special" encoding of r_info. Instead of one
+ // 64 bit little endian number, it is a little endian 32 bit number followed
+ // by a 32 bit big endian number.
+ return (t << 32) | ((t >> 8) & 0xff000000) | ((t >> 24) & 0x00ff0000) |
+ ((t >> 40) & 0x0000ff00) | ((t >> 56) & 0x000000ff);
+ }
+
+ void setRInfo(uint64_t R, bool IsMips64EL) {
+ if (IsMips64EL)
+ r_info = (R >> 32) | ((R & 0xff000000) << 8) | ((R & 0x00ff0000) << 24) |
+ ((R & 0x0000ff00) << 40) | ((R & 0x000000ff) << 56);
+ else
+ r_info = R;
+ }
+
+ // These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE,
+ // and ELF64_R_INFO macros defined in the ELF specification:
+ uint32_t getSymbol(bool isMips64EL) const {
+ return (uint32_t)(this->getRInfo(isMips64EL) >> 32);
+ }
+ uint32_t getType(bool isMips64EL) const {
+ return (uint32_t)(this->getRInfo(isMips64EL) & 0xffffffffL);
+ }
+ void setSymbol(uint32_t s, bool IsMips64EL) {
+ setSymbolAndType(s, getType(IsMips64EL), IsMips64EL);
+ }
+ void setType(uint32_t t, bool IsMips64EL) {
+ setSymbolAndType(getSymbol(IsMips64EL), t, IsMips64EL);
+ }
+ void setSymbolAndType(uint32_t s, uint32_t t, bool IsMips64EL) {
+ this->setRInfo(((uint64_t)s << 32) + (t & 0xffffffffL), IsMips64EL);
+ }
+};
+
+template <endianness TargetEndianness>
+struct Elf_Rel_Impl<ELFType<TargetEndianness, true>, true>
+ : public Elf_Rel_Impl<ELFType<TargetEndianness, true>, false> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
+ static const bool IsRela = true;
+ Elf_Sxword r_addend; // Compute value for relocatable field by adding this.
+};
+
+template <class ELFT>
+struct Elf_Ehdr_Impl {
+ LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
+ unsigned char e_ident[ELF::EI_NIDENT]; // ELF Identification bytes
+ Elf_Half e_type; // Type of file (see ET_*)
+ Elf_Half e_machine; // Required architecture for this file (see EM_*)
+ Elf_Word e_version; // Must be equal to 1
+ Elf_Addr e_entry; // Address to jump to in order to start program
+ Elf_Off e_phoff; // Program header table's file offset, in bytes
+ Elf_Off e_shoff; // Section header table's file offset, in bytes
+ Elf_Word e_flags; // Processor-specific flags
+ Elf_Half e_ehsize; // Size of ELF header, in bytes
+ Elf_Half e_phentsize; // Size of an entry in the program header table
+ Elf_Half e_phnum; // Number of entries in the program header table
+ Elf_Half e_shentsize; // Size of an entry in the section header table
+ Elf_Half e_shnum; // Number of entries in the section header table
+ Elf_Half e_shstrndx; // Section header table index of section name
+ // string table
+
+ bool checkMagic() const {
+ return (memcmp(e_ident, ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0;
+ }
+
+ unsigned char getFileClass() const { return e_ident[ELF::EI_CLASS]; }
+ unsigned char getDataEncoding() const { return e_ident[ELF::EI_DATA]; }
+};
+
+template <endianness TargetEndianness>
+struct Elf_Phdr_Impl<ELFType<TargetEndianness, false>> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
+ Elf_Word p_type; // Type of segment
+ Elf_Off p_offset; // FileOffset where segment is located, in bytes
+ Elf_Addr p_vaddr; // Virtual Address of beginning of segment
+ Elf_Addr p_paddr; // Physical address of beginning of segment (OS-specific)
+ Elf_Word p_filesz; // Num. of bytes in file image of segment (may be zero)
+ Elf_Word p_memsz; // Num. of bytes in mem image of segment (may be zero)
+ Elf_Word p_flags; // Segment flags
+ Elf_Word p_align; // Segment alignment constraint
+};
+
+template <endianness TargetEndianness>
+struct Elf_Phdr_Impl<ELFType<TargetEndianness, true>> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
+ Elf_Word p_type; // Type of segment
+ Elf_Word p_flags; // Segment flags
+ Elf_Off p_offset; // FileOffset where segment is located, in bytes
+ Elf_Addr p_vaddr; // Virtual Address of beginning of segment
+ Elf_Addr p_paddr; // Physical address of beginning of segment (OS-specific)
+ Elf_Xword p_filesz; // Num. of bytes in file image of segment (may be zero)
+ Elf_Xword p_memsz; // Num. of bytes in mem image of segment (may be zero)
+ Elf_Xword p_align; // Segment alignment constraint
+};
+
+// ELFT needed for endianness.
+template <class ELFT>
+struct Elf_Hash_Impl {
+ LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
+ Elf_Word nbucket;
+ Elf_Word nchain;
+
+ ArrayRef<Elf_Word> buckets() const {
+ return ArrayRef<Elf_Word>(&nbucket + 2, &nbucket + 2 + nbucket);
+ }
+
+ ArrayRef<Elf_Word> chains() const {
+ return ArrayRef<Elf_Word>(&nbucket + 2 + nbucket,
+ &nbucket + 2 + nbucket + nchain);
+ }
+};
+
+// .gnu.hash section
+template <class ELFT>
+struct Elf_GnuHash_Impl {
+ LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
+ Elf_Word nbuckets;
+ Elf_Word symndx;
+ Elf_Word maskwords;
+ Elf_Word shift2;
+
+ ArrayRef<Elf_Off> filter() const {
+ return ArrayRef<Elf_Off>(reinterpret_cast<const Elf_Off *>(&shift2 + 1),
+ maskwords);
+ }
+
+ ArrayRef<Elf_Word> buckets() const {
+ return ArrayRef<Elf_Word>(
+ reinterpret_cast<const Elf_Word *>(filter().end()), nbuckets);
+ }
+
+ ArrayRef<Elf_Word> values(unsigned DynamicSymCount) const {
+ return ArrayRef<Elf_Word>(buckets().end(), DynamicSymCount - symndx);
+ }
+};
+
+// Compressed section headers.
+// http://www.sco.com/developers/gabi/latest/ch4.sheader.html#compression_header
+template <endianness TargetEndianness>
+struct Elf_Chdr_Impl<ELFType<TargetEndianness, false>> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
+ Elf_Word ch_type;
+ Elf_Word ch_size;
+ Elf_Word ch_addralign;
+};
+
+template <endianness TargetEndianness>
+struct Elf_Chdr_Impl<ELFType<TargetEndianness, true>> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
+ Elf_Word ch_type;
+ Elf_Word ch_reserved;
+ Elf_Xword ch_size;
+ Elf_Xword ch_addralign;
+};
+
+/// Note header
+template <class ELFT>
+struct Elf_Nhdr_Impl {
+ LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
+ Elf_Word n_namesz;
+ Elf_Word n_descsz;
+ Elf_Word n_type;
+
+ /// The alignment of the name and descriptor.
+ ///
+ /// Implementations differ from the specification here: in practice all
+ /// variants align both the name and descriptor to 4-bytes.
+ static const unsigned int Align = 4;
+
+ /// Get the size of the note, including name, descriptor, and padding.
+ size_t getSize() const {
+ return sizeof(*this) + alignTo<Align>(n_namesz) + alignTo<Align>(n_descsz);
+ }
+};
+
+/// An ELF note.
+///
+/// Wraps a note header, providing methods for accessing the name and
+/// descriptor safely.
+template <class ELFT>
+class Elf_Note_Impl {
+ LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
+
+ const Elf_Nhdr_Impl<ELFT> &Nhdr;
+
+ template <class NoteIteratorELFT> friend class Elf_Note_Iterator_Impl;
+
+ Elf_Note_Impl(const Elf_Nhdr_Impl<ELFT> &Nhdr) : Nhdr(Nhdr) {}
+
+public:
+ /// Get the note's name, excluding the terminating null byte.
+ StringRef getName() const {
+ if (!Nhdr.n_namesz)
+ return StringRef();
+ return StringRef(reinterpret_cast<const char *>(&Nhdr) + sizeof(Nhdr),
+ Nhdr.n_namesz - 1);
+ }
+
+ /// Get the note's descriptor.
+ ArrayRef<Elf_Word> getDesc() const {
+ if (!Nhdr.n_descsz)
+ return ArrayRef<Elf_Word>();
+ return ArrayRef<Elf_Word>(
+ reinterpret_cast<const Elf_Word *>(
+ reinterpret_cast<const uint8_t *>(&Nhdr) + sizeof(Nhdr) +
+ alignTo<Elf_Nhdr_Impl<ELFT>::Align>(Nhdr.n_namesz)),
+ Nhdr.n_descsz);
+ }
+
+ /// Get the note's type.
+ Elf_Word getType() const { return Nhdr.n_type; }
+};
+
+template <class ELFT>
+class Elf_Note_Iterator_Impl
+ : std::iterator<std::forward_iterator_tag, Elf_Note_Impl<ELFT>> {
+ // Nhdr being a nullptr marks the end of iteration.
+ const Elf_Nhdr_Impl<ELFT> *Nhdr = nullptr;
+ size_t RemainingSize = 0u;
+ Error *Err = nullptr;
+
+ template <class ELFFileELFT> friend class ELFFile;
+
+ // Stop iteration and indicate an overflow.
+ void stopWithOverflowError() {
+ Nhdr = nullptr;
+ *Err = make_error<StringError>("ELF note overflows container",
+ object_error::parse_failed);
+ }
+
+ // Advance Nhdr by NoteSize bytes, starting from NhdrPos.
+ //
+ // Assumes NoteSize <= RemainingSize. Ensures Nhdr->getSize() <= RemainingSize
+ // upon returning. Handles stopping iteration when reaching the end of the
+ // container, either cleanly or with an overflow error.
+ void advanceNhdr(const uint8_t *NhdrPos, size_t NoteSize) {
+ RemainingSize -= NoteSize;
+ if (RemainingSize == 0u)
+ Nhdr = nullptr;
+ else if (sizeof(*Nhdr) > RemainingSize)
+ stopWithOverflowError();
+ else {
+ Nhdr = reinterpret_cast<const Elf_Nhdr_Impl<ELFT> *>(NhdrPos + NoteSize);
+ if (Nhdr->getSize() > RemainingSize)
+ stopWithOverflowError();
+ }
+ }
+
+ Elf_Note_Iterator_Impl() {}
+ explicit Elf_Note_Iterator_Impl(Error &Err) : Err(&Err) {}
+ Elf_Note_Iterator_Impl(const uint8_t *Start, size_t Size, Error &Err)
+ : RemainingSize(Size), Err(&Err) {
+ assert(Start && "ELF note iterator starting at NULL");
+ advanceNhdr(Start, 0u);
+ }
+
+public:
+ Elf_Note_Iterator_Impl &operator++() {
+ assert(Nhdr && "incremented ELF note end iterator");
+ const uint8_t *NhdrPos = reinterpret_cast<const uint8_t *>(Nhdr);
+ size_t NoteSize = Nhdr->getSize();
+ advanceNhdr(NhdrPos, NoteSize);
+ return *this;
+ }
+ bool operator==(Elf_Note_Iterator_Impl Other) const {
+ return Nhdr == Other.Nhdr;
+ }
+ bool operator!=(Elf_Note_Iterator_Impl Other) const {
+ return !(*this == Other);
+ }
+ Elf_Note_Impl<ELFT> operator*() const {
+ assert(Nhdr && "dereferenced ELF note end iterator");
+ return Elf_Note_Impl<ELFT>(*Nhdr);
+ }
+};
+
+// MIPS .reginfo section
+template <class ELFT>
+struct Elf_Mips_RegInfo;
+
+template <support::endianness TargetEndianness>
+struct Elf_Mips_RegInfo<ELFType<TargetEndianness, false>> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
+ Elf_Word ri_gprmask; // bit-mask of used general registers
+ Elf_Word ri_cprmask[4]; // bit-mask of used co-processor registers
+ Elf_Addr ri_gp_value; // gp register value
+};
+
+template <support::endianness TargetEndianness>
+struct Elf_Mips_RegInfo<ELFType<TargetEndianness, true>> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
+ Elf_Word ri_gprmask; // bit-mask of used general registers
+ Elf_Word ri_pad; // unused padding field
+ Elf_Word ri_cprmask[4]; // bit-mask of used co-processor registers
+ Elf_Addr ri_gp_value; // gp register value
+};
+
+// .MIPS.options section
+template <class ELFT> struct Elf_Mips_Options {
+ LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
+ uint8_t kind; // Determines interpretation of variable part of descriptor
+ uint8_t size; // Byte size of descriptor, including this header
+ Elf_Half section; // Section header index of section affected,
+ // or 0 for global options
+ Elf_Word info; // Kind-specific information
+
+ Elf_Mips_RegInfo<ELFT> &getRegInfo() {
+ assert(kind == ELF::ODK_REGINFO);
+ return *reinterpret_cast<Elf_Mips_RegInfo<ELFT> *>(
+ (uint8_t *)this + sizeof(Elf_Mips_Options));
+ }
+ const Elf_Mips_RegInfo<ELFT> &getRegInfo() const {
+ return const_cast<Elf_Mips_Options *>(this)->getRegInfo();
+ }
+};
+
+// .MIPS.abiflags section content
+template <class ELFT> struct Elf_Mips_ABIFlags {
+ LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
+ Elf_Half version; // Version of the structure
+ uint8_t isa_level; // ISA level: 1-5, 32, and 64
+ uint8_t isa_rev; // ISA revision (0 for MIPS I - MIPS V)
+ uint8_t gpr_size; // General purpose registers size
+ uint8_t cpr1_size; // Co-processor 1 registers size
+ uint8_t cpr2_size; // Co-processor 2 registers size
+ uint8_t fp_abi; // Floating-point ABI flag
+ Elf_Word isa_ext; // Processor-specific extension
+ Elf_Word ases; // ASEs flags
+ Elf_Word flags1; // General flags
+ Elf_Word flags2; // General flags
+};
+
+} // end namespace object.
+} // end namespace llvm.
+
+#endif // LLVM_OBJECT_ELFTYPES_H
diff --git a/linux-x64/clang/include/llvm/Object/Error.h b/linux-x64/clang/include/llvm/Object/Error.h
new file mode 100644
index 0000000..eb93833
--- /dev/null
+++ b/linux-x64/clang/include/llvm/Object/Error.h
@@ -0,0 +1,92 @@
+//===- Error.h - system_error extensions for Object -------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This declares a new error_category for the Object library.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_ERROR_H
+#define LLVM_OBJECT_ERROR_H
+
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/Error.h"
+#include <system_error>
+
+namespace llvm {
+namespace object {
+
+class Binary;
+
+const std::error_category &object_category();
+
+enum class object_error {
+ // Error code 0 is absent. Use std::error_code() instead.
+ arch_not_found = 1,
+ invalid_file_type,
+ parse_failed,
+ unexpected_eof,
+ string_table_non_null_end,
+ invalid_section_index,
+ bitcode_section_not_found,
+ invalid_symbol_index,
+};
+
+inline std::error_code make_error_code(object_error e) {
+ return std::error_code(static_cast<int>(e), object_category());
+}
+
+/// Base class for all errors indicating malformed binary files.
+///
+/// Having a subclass for all malformed binary files allows archive-walking
+/// code to skip malformed files without having to understand every possible
+/// way that a binary file might be malformed.
+///
+/// Currently inherits from ECError for easy interoperability with
+/// std::error_code, but this will be removed in the future.
+class BinaryError : public ErrorInfo<BinaryError, ECError> {
+public:
+ static char ID;
+ BinaryError() {
+ // Default to parse_failed, can be overridden with setErrorCode.
+ setErrorCode(make_error_code(object_error::parse_failed));
+ }
+};
+
+/// Generic binary error.
+///
+/// For errors that don't require their own specific sub-error (most errors)
+/// this class can be used to describe the error via a string message.
+class GenericBinaryError : public ErrorInfo<GenericBinaryError, BinaryError> {
+public:
+ static char ID;
+ GenericBinaryError(Twine Msg);
+ GenericBinaryError(Twine Msg, object_error ECOverride);
+ const std::string &getMessage() const { return Msg; }
+ void log(raw_ostream &OS) const override;
+private:
+ std::string Msg;
+};
+
+/// isNotObjectErrorInvalidFileType() is used when looping through the children
+/// of an archive after calling getAsBinary() on the child and it returns an
+/// llvm::Error. In the cases we want to loop through the children and ignore the
+/// non-objects in the archive this is used to test the error to see if an
+/// error() function needs to called on the llvm::Error.
+Error isNotObjectErrorInvalidFileType(llvm::Error Err);
+
+} // end namespace object.
+
+} // end namespace llvm.
+
+namespace std {
+template <>
+struct is_error_code_enum<llvm::object::object_error> : std::true_type {};
+}
+
+#endif
diff --git a/linux-x64/clang/include/llvm/Object/IRObjectFile.h b/linux-x64/clang/include/llvm/Object/IRObjectFile.h
new file mode 100644
index 0000000..6c271b1
--- /dev/null
+++ b/linux-x64/clang/include/llvm/Object/IRObjectFile.h
@@ -0,0 +1,82 @@
+//===- IRObjectFile.h - LLVM IR object file implementation ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the IRObjectFile template class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_IROBJECTFILE_H
+#define LLVM_OBJECT_IROBJECTFILE_H
+
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/Object/IRSymtab.h"
+#include "llvm/Object/ModuleSymbolTable.h"
+#include "llvm/Object/SymbolicFile.h"
+
+namespace llvm {
+class BitcodeModule;
+class Mangler;
+class Module;
+class GlobalValue;
+class Triple;
+
+namespace object {
+class ObjectFile;
+
+class IRObjectFile : public SymbolicFile {
+ std::vector<std::unique_ptr<Module>> Mods;
+ ModuleSymbolTable SymTab;
+ IRObjectFile(MemoryBufferRef Object,
+ std::vector<std::unique_ptr<Module>> Mods);
+
+public:
+ ~IRObjectFile() override;
+ void moveSymbolNext(DataRefImpl &Symb) const override;
+ std::error_code printSymbolName(raw_ostream &OS,
+ DataRefImpl Symb) const override;
+ uint32_t getSymbolFlags(DataRefImpl Symb) const override;
+ basic_symbol_iterator symbol_begin() const override;
+ basic_symbol_iterator symbol_end() const override;
+
+ StringRef getTargetTriple() const;
+
+ static bool classof(const Binary *v) {
+ return v->isIR();
+ }
+
+ /// \brief Finds and returns bitcode embedded in the given object file, or an
+ /// error code if not found.
+ static Expected<MemoryBufferRef> findBitcodeInObject(const ObjectFile &Obj);
+
+ /// \brief Finds and returns bitcode in the given memory buffer (which may
+ /// be either a bitcode file or a native object file with embedded bitcode),
+ /// or an error code if not found.
+ static Expected<MemoryBufferRef>
+ findBitcodeInMemBuffer(MemoryBufferRef Object);
+
+ static Expected<std::unique_ptr<IRObjectFile>> create(MemoryBufferRef Object,
+ LLVMContext &Context);
+};
+
+/// The contents of a bitcode file and its irsymtab. Any underlying data
+/// for the irsymtab are owned by Symtab and Strtab.
+struct IRSymtabFile {
+ std::vector<BitcodeModule> Mods;
+ SmallVector<char, 0> Symtab, Strtab;
+ irsymtab::Reader TheReader;
+};
+
+/// Reads a bitcode file, creating its irsymtab if necessary.
+Expected<IRSymtabFile> readIRSymtab(MemoryBufferRef MBRef);
+
+}
+
+}
+
+#endif
diff --git a/linux-x64/clang/include/llvm/Object/IRSymtab.h b/linux-x64/clang/include/llvm/Object/IRSymtab.h
new file mode 100644
index 0000000..5f6a024
--- /dev/null
+++ b/linux-x64/clang/include/llvm/Object/IRSymtab.h
@@ -0,0 +1,358 @@
+//===- IRSymtab.h - data definitions for IR symbol tables -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains data definitions and a reader and builder for a symbol
+// table for LLVM IR. Its purpose is to allow linkers and other consumers of
+// bitcode files to efficiently read the symbol table for symbol resolution
+// purposes without needing to construct a module in memory.
+//
+// As with most object files the symbol table has two parts: the symbol table
+// itself and a string table which is referenced by the symbol table.
+//
+// A symbol table corresponds to a single bitcode file, which may consist of
+// multiple modules, so symbol tables may likewise contain symbols for multiple
+// modules.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_IRSYMTAB_H
+#define LLVM_OBJECT_IRSYMTAB_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/IR/GlobalValue.h"
+#include "llvm/Object/SymbolicFile.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <cassert>
+#include <cstdint>
+#include <vector>
+
+namespace llvm {
+
+struct BitcodeFileContents;
+class StringTableBuilder;
+
+namespace irsymtab {
+
+namespace storage {
+
+// The data structures in this namespace define the low-level serialization
+// format. Clients that just want to read a symbol table should use the
+// irsymtab::Reader class.
+
+using Word = support::ulittle32_t;
+
+/// A reference to a string in the string table.
+struct Str {
+ Word Offset, Size;
+
+ StringRef get(StringRef Strtab) const {
+ return {Strtab.data() + Offset, Size};
+ }
+};
+
+/// A reference to a range of objects in the symbol table.
+template <typename T> struct Range {
+ Word Offset, Size;
+
+ ArrayRef<T> get(StringRef Symtab) const {
+ return {reinterpret_cast<const T *>(Symtab.data() + Offset), Size};
+ }
+};
+
+/// Describes the range of a particular module's symbols within the symbol
+/// table.
+struct Module {
+ Word Begin, End;
+
+ /// The index of the first Uncommon for this Module.
+ Word UncBegin;
+};
+
+/// This is equivalent to an IR comdat.
+struct Comdat {
+ Str Name;
+};
+
+/// Contains the information needed by linkers for symbol resolution, as well as
+/// by the LTO implementation itself.
+struct Symbol {
+ /// The mangled symbol name.
+ Str Name;
+
+ /// The unmangled symbol name, or the empty string if this is not an IR
+ /// symbol.
+ Str IRName;
+
+ /// The index into Header::Comdats, or -1 if not a comdat member.
+ Word ComdatIndex;
+
+ Word Flags;
+ enum FlagBits {
+ FB_visibility, // 2 bits
+ FB_has_uncommon = FB_visibility + 2,
+ FB_undefined,
+ FB_weak,
+ FB_common,
+ FB_indirect,
+ FB_used,
+ FB_tls,
+ FB_may_omit,
+ FB_global,
+ FB_format_specific,
+ FB_unnamed_addr,
+ FB_executable,
+ };
+};
+
+/// This data structure contains rarely used symbol fields and is optionally
+/// referenced by a Symbol.
+struct Uncommon {
+ Word CommonSize, CommonAlign;
+
+ /// COFF-specific: the name of the symbol that a weak external resolves to
+ /// if not defined.
+ Str COFFWeakExternFallbackName;
+
+ /// Specified section name, if any.
+ Str SectionName;
+};
+
+struct Header {
+ /// Version number of the symtab format. This number should be incremented
+ /// when the format changes, but it does not need to be incremented if a
+ /// change to LLVM would cause it to create a different symbol table.
+ Word Version;
+ enum { kCurrentVersion = 1 };
+
+ /// The producer's version string (LLVM_VERSION_STRING " " LLVM_REVISION).
+ /// Consumers should rebuild the symbol table from IR if the producer's
+ /// version does not match the consumer's version due to potential differences
+ /// in symbol table format, symbol enumeration order and so on.
+ Str Producer;
+
+ Range<Module> Modules;
+ Range<Comdat> Comdats;
+ Range<Symbol> Symbols;
+ Range<Uncommon> Uncommons;
+
+ Str TargetTriple, SourceFileName;
+
+ /// COFF-specific: linker directives.
+ Str COFFLinkerOpts;
+};
+
+} // end namespace storage
+
+/// Fills in Symtab and StrtabBuilder with a valid symbol and string table for
+/// Mods.
+Error build(ArrayRef<Module *> Mods, SmallVector<char, 0> &Symtab,
+ StringTableBuilder &StrtabBuilder, BumpPtrAllocator &Alloc);
+
+/// This represents a symbol that has been read from a storage::Symbol and
+/// possibly a storage::Uncommon.
+struct Symbol {
+ // Copied from storage::Symbol.
+ StringRef Name, IRName;
+ int ComdatIndex;
+ uint32_t Flags;
+
+ // Copied from storage::Uncommon.
+ uint32_t CommonSize, CommonAlign;
+ StringRef COFFWeakExternFallbackName;
+ StringRef SectionName;
+
+ /// Returns the mangled symbol name.
+ StringRef getName() const { return Name; }
+
+ /// Returns the unmangled symbol name, or the empty string if this is not an
+ /// IR symbol.
+ StringRef getIRName() const { return IRName; }
+
+ /// Returns the index into the comdat table (see Reader::getComdatTable()), or
+ /// -1 if not a comdat member.
+ int getComdatIndex() const { return ComdatIndex; }
+
+ using S = storage::Symbol;
+
+ GlobalValue::VisibilityTypes getVisibility() const {
+ return GlobalValue::VisibilityTypes((Flags >> S::FB_visibility) & 3);
+ }
+
+ bool isUndefined() const { return (Flags >> S::FB_undefined) & 1; }
+ bool isWeak() const { return (Flags >> S::FB_weak) & 1; }
+ bool isCommon() const { return (Flags >> S::FB_common) & 1; }
+ bool isIndirect() const { return (Flags >> S::FB_indirect) & 1; }
+ bool isUsed() const { return (Flags >> S::FB_used) & 1; }
+ bool isTLS() const { return (Flags >> S::FB_tls) & 1; }
+
+ bool canBeOmittedFromSymbolTable() const {
+ return (Flags >> S::FB_may_omit) & 1;
+ }
+
+ bool isGlobal() const { return (Flags >> S::FB_global) & 1; }
+ bool isFormatSpecific() const { return (Flags >> S::FB_format_specific) & 1; }
+ bool isUnnamedAddr() const { return (Flags >> S::FB_unnamed_addr) & 1; }
+ bool isExecutable() const { return (Flags >> S::FB_executable) & 1; }
+
+ uint64_t getCommonSize() const {
+ assert(isCommon());
+ return CommonSize;
+ }
+
+ uint32_t getCommonAlignment() const {
+ assert(isCommon());
+ return CommonAlign;
+ }
+
+ /// COFF-specific: for weak externals, returns the name of the symbol that is
+ /// used as a fallback if the weak external remains undefined.
+ StringRef getCOFFWeakExternalFallback() const {
+ assert(isWeak() && isIndirect());
+ return COFFWeakExternFallbackName;
+ }
+
+ StringRef getSectionName() const { return SectionName; }
+};
+
+/// This class can be used to read a Symtab and Strtab produced by
+/// irsymtab::build.
+class Reader {
+ StringRef Symtab, Strtab;
+
+ ArrayRef<storage::Module> Modules;
+ ArrayRef<storage::Comdat> Comdats;
+ ArrayRef<storage::Symbol> Symbols;
+ ArrayRef<storage::Uncommon> Uncommons;
+
+ StringRef str(storage::Str S) const { return S.get(Strtab); }
+
+ template <typename T> ArrayRef<T> range(storage::Range<T> R) const {
+ return R.get(Symtab);
+ }
+
+ const storage::Header &header() const {
+ return *reinterpret_cast<const storage::Header *>(Symtab.data());
+ }
+
+public:
+ class SymbolRef;
+
+ Reader() = default;
+ Reader(StringRef Symtab, StringRef Strtab) : Symtab(Symtab), Strtab(Strtab) {
+ Modules = range(header().Modules);
+ Comdats = range(header().Comdats);
+ Symbols = range(header().Symbols);
+ Uncommons = range(header().Uncommons);
+ }
+
+ using symbol_range = iterator_range<object::content_iterator<SymbolRef>>;
+
+ /// Returns the symbol table for the entire bitcode file.
+ /// The symbols enumerated by this method are ephemeral, but they can be
+ /// copied into an irsymtab::Symbol object.
+ symbol_range symbols() const;
+
+ size_t getNumModules() const { return Modules.size(); }
+
+ /// Returns a slice of the symbol table for the I'th module in the file.
+ /// The symbols enumerated by this method are ephemeral, but they can be
+ /// copied into an irsymtab::Symbol object.
+ symbol_range module_symbols(unsigned I) const;
+
+ StringRef getTargetTriple() const { return str(header().TargetTriple); }
+
+ /// Returns the source file path specified at compile time.
+ StringRef getSourceFileName() const { return str(header().SourceFileName); }
+
+ /// Returns a table with all the comdats used by this file.
+ std::vector<StringRef> getComdatTable() const {
+ std::vector<StringRef> ComdatTable;
+ ComdatTable.reserve(Comdats.size());
+ for (auto C : Comdats)
+ ComdatTable.push_back(str(C.Name));
+ return ComdatTable;
+ }
+
+ /// COFF-specific: returns linker options specified in the input file.
+ StringRef getCOFFLinkerOpts() const { return str(header().COFFLinkerOpts); }
+};
+
+/// Ephemeral symbols produced by Reader::symbols() and
+/// Reader::module_symbols().
+class Reader::SymbolRef : public Symbol {
+ const storage::Symbol *SymI, *SymE;
+ const storage::Uncommon *UncI;
+ const Reader *R;
+
+ void read() {
+ if (SymI == SymE)
+ return;
+
+ Name = R->str(SymI->Name);
+ IRName = R->str(SymI->IRName);
+ ComdatIndex = SymI->ComdatIndex;
+ Flags = SymI->Flags;
+
+ if (Flags & (1 << storage::Symbol::FB_has_uncommon)) {
+ CommonSize = UncI->CommonSize;
+ CommonAlign = UncI->CommonAlign;
+ COFFWeakExternFallbackName = R->str(UncI->COFFWeakExternFallbackName);
+ SectionName = R->str(UncI->SectionName);
+ } else
+ // Reset this field so it can be queried unconditionally for all symbols.
+ SectionName = "";
+ }
+
+public:
+ SymbolRef(const storage::Symbol *SymI, const storage::Symbol *SymE,
+ const storage::Uncommon *UncI, const Reader *R)
+ : SymI(SymI), SymE(SymE), UncI(UncI), R(R) {
+ read();
+ }
+
+ void moveNext() {
+ ++SymI;
+ if (Flags & (1 << storage::Symbol::FB_has_uncommon))
+ ++UncI;
+ read();
+ }
+
+ bool operator==(const SymbolRef &Other) const { return SymI == Other.SymI; }
+};
+
+inline Reader::symbol_range Reader::symbols() const {
+ return {SymbolRef(Symbols.begin(), Symbols.end(), Uncommons.begin(), this),
+ SymbolRef(Symbols.end(), Symbols.end(), nullptr, this)};
+}
+
+inline Reader::symbol_range Reader::module_symbols(unsigned I) const {
+ const storage::Module &M = Modules[I];
+ const storage::Symbol *MBegin = Symbols.begin() + M.Begin,
+ *MEnd = Symbols.begin() + M.End;
+ return {SymbolRef(MBegin, MEnd, Uncommons.begin() + M.UncBegin, this),
+ SymbolRef(MEnd, MEnd, nullptr, this)};
+}
+
+/// The contents of the irsymtab in a bitcode file. Any underlying data for the
+/// irsymtab are owned by Symtab and Strtab.
+struct FileContents {
+ SmallVector<char, 0> Symtab, Strtab;
+ Reader TheReader;
+};
+
+/// Reads the contents of a bitcode file, creating its irsymtab if necessary.
+Expected<FileContents> readBitcode(const BitcodeFileContents &BFC);
+
+} // end namespace irsymtab
+} // end namespace llvm
+
+#endif // LLVM_OBJECT_IRSYMTAB_H
diff --git a/linux-x64/clang/include/llvm/Object/MachO.h b/linux-x64/clang/include/llvm/Object/MachO.h
new file mode 100644
index 0000000..bfd3462
--- /dev/null
+++ b/linux-x64/clang/include/llvm/Object/MachO.h
@@ -0,0 +1,737 @@
+//===- MachO.h - MachO object file implementation ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the MachOObjectFile class, which implement the ObjectFile
+// interface for MachO files.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_MACHO_H
+#define LLVM_OBJECT_MACHO_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/BinaryFormat/MachO.h"
+#include "llvm/MC/SubtargetFeature.h"
+#include "llvm/Object/Binary.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Object/SymbolicFile.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <system_error>
+
+namespace llvm {
+namespace object {
+
+/// DiceRef - This is a value type class that represents a single
+/// data in code entry in the table in a Mach-O object file.
+class DiceRef {
+ DataRefImpl DicePimpl;
+ const ObjectFile *OwningObject = nullptr;
+
+public:
+ DiceRef() = default;
+ DiceRef(DataRefImpl DiceP, const ObjectFile *Owner);
+
+ bool operator==(const DiceRef &Other) const;
+ bool operator<(const DiceRef &Other) const;
+
+ void moveNext();
+
+ std::error_code getOffset(uint32_t &Result) const;
+ std::error_code getLength(uint16_t &Result) const;
+ std::error_code getKind(uint16_t &Result) const;
+
+ DataRefImpl getRawDataRefImpl() const;
+ const ObjectFile *getObjectFile() const;
+};
+using dice_iterator = content_iterator<DiceRef>;
+
+/// ExportEntry encapsulates the current-state-of-the-walk used when doing a
+/// non-recursive walk of the trie data structure. This allows you to iterate
+/// across all exported symbols using:
+/// Error Err;
+/// for (const llvm::object::ExportEntry &AnExport : Obj->exports(&Err)) {
+/// }
+/// if (Err) { report error ...
+class ExportEntry {
+public:
+ ExportEntry(Error *Err, const MachOObjectFile *O, ArrayRef<uint8_t> Trie);
+
+ StringRef name() const;
+ uint64_t flags() const;
+ uint64_t address() const;
+ uint64_t other() const;
+ StringRef otherName() const;
+ uint32_t nodeOffset() const;
+
+ bool operator==(const ExportEntry &) const;
+
+ void moveNext();
+
+private:
+ friend class MachOObjectFile;
+
+ void moveToFirst();
+ void moveToEnd();
+ uint64_t readULEB128(const uint8_t *&p, const char **error);
+ void pushDownUntilBottom();
+ void pushNode(uint64_t Offset);
+
+ // Represents a node in the mach-o exports trie.
+ struct NodeState {
+ NodeState(const uint8_t *Ptr);
+
+ const uint8_t *Start;
+ const uint8_t *Current;
+ uint64_t Flags = 0;
+ uint64_t Address = 0;
+ uint64_t Other = 0;
+ const char *ImportName = nullptr;
+ unsigned ChildCount = 0;
+ unsigned NextChildIndex = 0;
+ unsigned ParentStringLength = 0;
+ bool IsExportNode = false;
+ };
+ using NodeList = SmallVector<NodeState, 16>;
+ using node_iterator = NodeList::const_iterator;
+
+ Error *E;
+ const MachOObjectFile *O;
+ ArrayRef<uint8_t> Trie;
+ SmallString<256> CumulativeString;
+ NodeList Stack;
+ bool Done = false;
+
+ iterator_range<node_iterator> nodes() const {
+ return make_range(Stack.begin(), Stack.end());
+ }
+};
+using export_iterator = content_iterator<ExportEntry>;
+
+// Segment info so SegIndex/SegOffset pairs in a Mach-O Bind or Rebase entry
+// can be checked and translated. Only the SegIndex/SegOffset pairs from
+// checked entries are to be used with the segmentName(), sectionName() and
+// address() methods below.
+class BindRebaseSegInfo {
+public:
+ BindRebaseSegInfo(const MachOObjectFile *Obj);
+
+ // Used to check a Mach-O Bind or Rebase entry for errors when iterating.
+ const char *checkSegAndOffset(int32_t SegIndex, uint64_t SegOffset,
+ bool endInvalid);
+ const char *checkCountAndSkip(uint32_t Count, uint32_t Skip,
+ uint8_t PointerSize, int32_t SegIndex,
+ uint64_t SegOffset);
+ // Used with valid SegIndex/SegOffset values from checked entries.
+ StringRef segmentName(int32_t SegIndex);
+ StringRef sectionName(int32_t SegIndex, uint64_t SegOffset);
+ uint64_t address(uint32_t SegIndex, uint64_t SegOffset);
+
+private:
+ struct SectionInfo {
+ uint64_t Address;
+ uint64_t Size;
+ StringRef SectionName;
+ StringRef SegmentName;
+ uint64_t OffsetInSegment;
+ uint64_t SegmentStartAddress;
+ int32_t SegmentIndex;
+ };
+ const SectionInfo &findSection(int32_t SegIndex, uint64_t SegOffset);
+
+ SmallVector<SectionInfo, 32> Sections;
+ int32_t MaxSegIndex;
+};
+
+/// MachORebaseEntry encapsulates the current state in the decompression of
+/// rebasing opcodes. This allows you to iterate through the compressed table of
+/// rebasing using:
+/// Error Err;
+/// for (const llvm::object::MachORebaseEntry &Entry : Obj->rebaseTable(&Err)) {
+/// }
+/// if (Err) { report error ...
+class MachORebaseEntry {
+public:
+ MachORebaseEntry(Error *Err, const MachOObjectFile *O,
+ ArrayRef<uint8_t> opcodes, bool is64Bit);
+
+ int32_t segmentIndex() const;
+ uint64_t segmentOffset() const;
+ StringRef typeName() const;
+ StringRef segmentName() const;
+ StringRef sectionName() const;
+ uint64_t address() const;
+
+ bool operator==(const MachORebaseEntry &) const;
+
+ void moveNext();
+
+private:
+ friend class MachOObjectFile;
+
+ void moveToFirst();
+ void moveToEnd();
+ uint64_t readULEB128(const char **error);
+
+ Error *E;
+ const MachOObjectFile *O;
+ ArrayRef<uint8_t> Opcodes;
+ const uint8_t *Ptr;
+ uint64_t SegmentOffset = 0;
+ int32_t SegmentIndex = -1;
+ uint64_t RemainingLoopCount = 0;
+ uint64_t AdvanceAmount = 0;
+ uint8_t RebaseType = 0;
+ uint8_t PointerSize;
+ bool Done = false;
+};
+using rebase_iterator = content_iterator<MachORebaseEntry>;
+
+/// MachOBindEntry encapsulates the current state in the decompression of
+/// binding opcodes. This allows you to iterate through the compressed table of
+/// bindings using:
+/// Error Err;
+/// for (const llvm::object::MachOBindEntry &Entry : Obj->bindTable(&Err)) {
+/// }
+/// if (Err) { report error ...
+class MachOBindEntry {
+public:
+ enum class Kind { Regular, Lazy, Weak };
+
+ MachOBindEntry(Error *Err, const MachOObjectFile *O,
+ ArrayRef<uint8_t> Opcodes, bool is64Bit, MachOBindEntry::Kind);
+
+ int32_t segmentIndex() const;
+ uint64_t segmentOffset() const;
+ StringRef typeName() const;
+ StringRef symbolName() const;
+ uint32_t flags() const;
+ int64_t addend() const;
+ int ordinal() const;
+
+ StringRef segmentName() const;
+ StringRef sectionName() const;
+ uint64_t address() const;
+
+ bool operator==(const MachOBindEntry &) const;
+
+ void moveNext();
+
+private:
+ friend class MachOObjectFile;
+
+ void moveToFirst();
+ void moveToEnd();
+ uint64_t readULEB128(const char **error);
+ int64_t readSLEB128(const char **error);
+
+ Error *E;
+ const MachOObjectFile *O;
+ ArrayRef<uint8_t> Opcodes;
+ const uint8_t *Ptr;
+ uint64_t SegmentOffset = 0;
+ int32_t SegmentIndex = -1;
+ StringRef SymbolName;
+ bool LibraryOrdinalSet = false;
+ int Ordinal = 0;
+ uint32_t Flags = 0;
+ int64_t Addend = 0;
+ uint64_t RemainingLoopCount = 0;
+ uint64_t AdvanceAmount = 0;
+ uint8_t BindType = 0;
+ uint8_t PointerSize;
+ Kind TableKind;
+ bool Done = false;
+};
+using bind_iterator = content_iterator<MachOBindEntry>;
+
+class MachOObjectFile : public ObjectFile {
+public:
+ struct LoadCommandInfo {
+ const char *Ptr; // Where in memory the load command is.
+ MachO::load_command C; // The command itself.
+ };
+ using LoadCommandList = SmallVector<LoadCommandInfo, 4>;
+ using load_command_iterator = LoadCommandList::const_iterator;
+
+ static Expected<std::unique_ptr<MachOObjectFile>>
+ create(MemoryBufferRef Object, bool IsLittleEndian, bool Is64Bits,
+ uint32_t UniversalCputype = 0, uint32_t UniversalIndex = 0);
+
+ void moveSymbolNext(DataRefImpl &Symb) const override;
+
+ uint64_t getNValue(DataRefImpl Sym) const;
+ Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
+
+ // MachO specific.
+ Error checkSymbolTable() const;
+
+ std::error_code getIndirectName(DataRefImpl Symb, StringRef &Res) const;
+ unsigned getSectionType(SectionRef Sec) const;
+
+ Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
+ uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
+ uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
+ Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
+ uint32_t getSymbolFlags(DataRefImpl Symb) const override;
+ Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
+ unsigned getSymbolSectionID(SymbolRef Symb) const;
+ unsigned getSectionID(SectionRef Sec) const;
+
+ void moveSectionNext(DataRefImpl &Sec) const override;
+ std::error_code getSectionName(DataRefImpl Sec,
+ StringRef &Res) const override;
+ uint64_t getSectionAddress(DataRefImpl Sec) const override;
+ uint64_t getSectionIndex(DataRefImpl Sec) const override;
+ uint64_t getSectionSize(DataRefImpl Sec) const override;
+ std::error_code getSectionContents(DataRefImpl Sec,
+ StringRef &Res) const override;
+ uint64_t getSectionAlignment(DataRefImpl Sec) const override;
+ bool isSectionCompressed(DataRefImpl Sec) const override;
+ bool isSectionText(DataRefImpl Sec) const override;
+ bool isSectionData(DataRefImpl Sec) const override;
+ bool isSectionBSS(DataRefImpl Sec) const override;
+ bool isSectionVirtual(DataRefImpl Sec) const override;
+ bool isSectionBitcode(DataRefImpl Sec) const override;
+
+ /// When dsymutil generates the companion file, it strips all unnecessary
+ /// sections (e.g. everything in the _TEXT segment) by omitting their body
+ /// and setting the offset in their corresponding load command to zero.
+ ///
+ /// While the load command itself is valid, reading the section corresponds
+ /// to reading the number of bytes specified in the load command, starting
+ /// from offset 0 (i.e. the Mach-O header at the beginning of the file).
+ bool isSectionStripped(DataRefImpl Sec) const override;
+
+ relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
+ relocation_iterator section_rel_end(DataRefImpl Sec) const override;
+
+ relocation_iterator extrel_begin() const;
+ relocation_iterator extrel_end() const;
+ iterator_range<relocation_iterator> external_relocations() const {
+ return make_range(extrel_begin(), extrel_end());
+ }
+
+ relocation_iterator locrel_begin() const;
+ relocation_iterator locrel_end() const;
+
+ void moveRelocationNext(DataRefImpl &Rel) const override;
+ uint64_t getRelocationOffset(DataRefImpl Rel) const override;
+ symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
+ section_iterator getRelocationSection(DataRefImpl Rel) const;
+ uint64_t getRelocationType(DataRefImpl Rel) const override;
+ void getRelocationTypeName(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const override;
+ uint8_t getRelocationLength(DataRefImpl Rel) const;
+
+ // MachO specific.
+ std::error_code getLibraryShortNameByIndex(unsigned Index, StringRef &) const;
+ uint32_t getLibraryCount() const;
+
+ section_iterator getRelocationRelocatedSection(relocation_iterator Rel) const;
+
+ // TODO: Would be useful to have an iterator based version
+ // of the load command interface too.
+
+ basic_symbol_iterator symbol_begin() const override;
+ basic_symbol_iterator symbol_end() const override;
+
+ // MachO specific.
+ basic_symbol_iterator getSymbolByIndex(unsigned Index) const;
+ uint64_t getSymbolIndex(DataRefImpl Symb) const;
+
+ section_iterator section_begin() const override;
+ section_iterator section_end() const override;
+
+ uint8_t getBytesInAddress() const override;
+
+ StringRef getFileFormatName() const override;
+ Triple::ArchType getArch() const override;
+ SubtargetFeatures getFeatures() const override { return SubtargetFeatures(); }
+ Triple getArchTriple(const char **McpuDefault = nullptr) const;
+
+ relocation_iterator section_rel_begin(unsigned Index) const;
+ relocation_iterator section_rel_end(unsigned Index) const;
+
+ dice_iterator begin_dices() const;
+ dice_iterator end_dices() const;
+
+ load_command_iterator begin_load_commands() const;
+ load_command_iterator end_load_commands() const;
+ iterator_range<load_command_iterator> load_commands() const;
+
+ /// For use iterating over all exported symbols.
+ iterator_range<export_iterator> exports(Error &Err) const;
+
+ /// For use examining a trie not in a MachOObjectFile.
+ static iterator_range<export_iterator> exports(Error &Err,
+ ArrayRef<uint8_t> Trie,
+ const MachOObjectFile *O =
+ nullptr);
+
+ /// For use iterating over all rebase table entries.
+ iterator_range<rebase_iterator> rebaseTable(Error &Err);
+
+ /// For use examining rebase opcodes in a MachOObjectFile.
+ static iterator_range<rebase_iterator> rebaseTable(Error &Err,
+ MachOObjectFile *O,
+ ArrayRef<uint8_t> Opcodes,
+ bool is64);
+
+ /// For use iterating over all bind table entries.
+ iterator_range<bind_iterator> bindTable(Error &Err);
+
+ /// For use iterating over all lazy bind table entries.
+ iterator_range<bind_iterator> lazyBindTable(Error &Err);
+
+ /// For use iterating over all weak bind table entries.
+ iterator_range<bind_iterator> weakBindTable(Error &Err);
+
+ /// For use examining bind opcodes in a MachOObjectFile.
+ static iterator_range<bind_iterator> bindTable(Error &Err,
+ MachOObjectFile *O,
+ ArrayRef<uint8_t> Opcodes,
+ bool is64,
+ MachOBindEntry::Kind);
+
+ /// For use with a SegIndex,SegOffset pair in MachOBindEntry::moveNext() to
+ /// validate a MachOBindEntry.
+ const char *BindEntryCheckSegAndOffset(int32_t SegIndex, uint64_t SegOffset,
+ bool endInvalid) const {
+ return BindRebaseSectionTable->checkSegAndOffset(SegIndex, SegOffset,
+ endInvalid);
+ }
+ /// For use in MachOBindEntry::moveNext() to validate a MachOBindEntry for
+ /// the BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB opcode.
+ const char *BindEntryCheckCountAndSkip(uint32_t Count, uint32_t Skip,
+ uint8_t PointerSize, int32_t SegIndex,
+ uint64_t SegOffset) const {
+ return BindRebaseSectionTable->checkCountAndSkip(Count, Skip, PointerSize,
+ SegIndex, SegOffset);
+ }
+
+ /// For use with a SegIndex,SegOffset pair in MachORebaseEntry::moveNext() to
+ /// validate a MachORebaseEntry.
+ const char *RebaseEntryCheckSegAndOffset(int32_t SegIndex, uint64_t SegOffset,
+ bool endInvalid) const {
+ return BindRebaseSectionTable->checkSegAndOffset(SegIndex, SegOffset,
+ endInvalid);
+ }
+ /// For use in MachORebaseEntry::moveNext() to validate a MachORebaseEntry for
+ /// the REBASE_OPCODE_DO_*_TIMES* opcodes.
+ const char *RebaseEntryCheckCountAndSkip(uint32_t Count, uint32_t Skip,
+ uint8_t PointerSize, int32_t SegIndex,
+ uint64_t SegOffset) const {
+ return BindRebaseSectionTable->checkCountAndSkip(Count, Skip, PointerSize,
+ SegIndex, SegOffset);
+ }
+
+ /// For use with the SegIndex of a checked Mach-O Bind or Rebase entry to
+ /// get the segment name.
+ StringRef BindRebaseSegmentName(int32_t SegIndex) const {
+ return BindRebaseSectionTable->segmentName(SegIndex);
+ }
+
+ /// For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or
+ /// Rebase entry to get the section name.
+ StringRef BindRebaseSectionName(uint32_t SegIndex, uint64_t SegOffset) const {
+ return BindRebaseSectionTable->sectionName(SegIndex, SegOffset);
+ }
+
+ /// For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or
+ /// Rebase entry to get the address.
+ uint64_t BindRebaseAddress(uint32_t SegIndex, uint64_t SegOffset) const {
+ return BindRebaseSectionTable->address(SegIndex, SegOffset);
+ }
+
+ // In a MachO file, sections have a segment name. This is used in the .o
+ // files. They have a single segment, but this field specifies which segment
+ // a section should be put in the final object.
+ StringRef getSectionFinalSegmentName(DataRefImpl Sec) const;
+
+ // Names are stored as 16 bytes. These returns the raw 16 bytes without
+ // interpreting them as a C string.
+ ArrayRef<char> getSectionRawName(DataRefImpl Sec) const;
+ ArrayRef<char> getSectionRawFinalSegmentName(DataRefImpl Sec) const;
+
+ // MachO specific Info about relocations.
+ bool isRelocationScattered(const MachO::any_relocation_info &RE) const;
+ unsigned getPlainRelocationSymbolNum(
+ const MachO::any_relocation_info &RE) const;
+ bool getPlainRelocationExternal(const MachO::any_relocation_info &RE) const;
+ bool getScatteredRelocationScattered(
+ const MachO::any_relocation_info &RE) const;
+ uint32_t getScatteredRelocationValue(
+ const MachO::any_relocation_info &RE) const;
+ uint32_t getScatteredRelocationType(
+ const MachO::any_relocation_info &RE) const;
+ unsigned getAnyRelocationAddress(const MachO::any_relocation_info &RE) const;
+ unsigned getAnyRelocationPCRel(const MachO::any_relocation_info &RE) const;
+ unsigned getAnyRelocationLength(const MachO::any_relocation_info &RE) const;
+ unsigned getAnyRelocationType(const MachO::any_relocation_info &RE) const;
+ SectionRef getAnyRelocationSection(const MachO::any_relocation_info &RE) const;
+
+ // MachO specific structures.
+ MachO::section getSection(DataRefImpl DRI) const;
+ MachO::section_64 getSection64(DataRefImpl DRI) const;
+ MachO::section getSection(const LoadCommandInfo &L, unsigned Index) const;
+ MachO::section_64 getSection64(const LoadCommandInfo &L,unsigned Index) const;
+ MachO::nlist getSymbolTableEntry(DataRefImpl DRI) const;
+ MachO::nlist_64 getSymbol64TableEntry(DataRefImpl DRI) const;
+
+ MachO::linkedit_data_command
+ getLinkeditDataLoadCommand(const LoadCommandInfo &L) const;
+ MachO::segment_command
+ getSegmentLoadCommand(const LoadCommandInfo &L) const;
+ MachO::segment_command_64
+ getSegment64LoadCommand(const LoadCommandInfo &L) const;
+ MachO::linker_option_command
+ getLinkerOptionLoadCommand(const LoadCommandInfo &L) const;
+ MachO::version_min_command
+ getVersionMinLoadCommand(const LoadCommandInfo &L) const;
+ MachO::note_command
+ getNoteLoadCommand(const LoadCommandInfo &L) const;
+ MachO::build_version_command
+ getBuildVersionLoadCommand(const LoadCommandInfo &L) const;
+ MachO::build_tool_version
+ getBuildToolVersion(unsigned index) const;
+ MachO::dylib_command
+ getDylibIDLoadCommand(const LoadCommandInfo &L) const;
+ MachO::dyld_info_command
+ getDyldInfoLoadCommand(const LoadCommandInfo &L) const;
+ MachO::dylinker_command
+ getDylinkerCommand(const LoadCommandInfo &L) const;
+ MachO::uuid_command
+ getUuidCommand(const LoadCommandInfo &L) const;
+ MachO::rpath_command
+ getRpathCommand(const LoadCommandInfo &L) const;
+ MachO::source_version_command
+ getSourceVersionCommand(const LoadCommandInfo &L) const;
+ MachO::entry_point_command
+ getEntryPointCommand(const LoadCommandInfo &L) const;
+ MachO::encryption_info_command
+ getEncryptionInfoCommand(const LoadCommandInfo &L) const;
+ MachO::encryption_info_command_64
+ getEncryptionInfoCommand64(const LoadCommandInfo &L) const;
+ MachO::sub_framework_command
+ getSubFrameworkCommand(const LoadCommandInfo &L) const;
+ MachO::sub_umbrella_command
+ getSubUmbrellaCommand(const LoadCommandInfo &L) const;
+ MachO::sub_library_command
+ getSubLibraryCommand(const LoadCommandInfo &L) const;
+ MachO::sub_client_command
+ getSubClientCommand(const LoadCommandInfo &L) const;
+ MachO::routines_command
+ getRoutinesCommand(const LoadCommandInfo &L) const;
+ MachO::routines_command_64
+ getRoutinesCommand64(const LoadCommandInfo &L) const;
+ MachO::thread_command
+ getThreadCommand(const LoadCommandInfo &L) const;
+
+ MachO::any_relocation_info getRelocation(DataRefImpl Rel) const;
+ MachO::data_in_code_entry getDice(DataRefImpl Rel) const;
+ const MachO::mach_header &getHeader() const;
+ const MachO::mach_header_64 &getHeader64() const;
+ uint32_t
+ getIndirectSymbolTableEntry(const MachO::dysymtab_command &DLC,
+ unsigned Index) const;
+ MachO::data_in_code_entry getDataInCodeTableEntry(uint32_t DataOffset,
+ unsigned Index) const;
+ MachO::symtab_command getSymtabLoadCommand() const;
+ MachO::dysymtab_command getDysymtabLoadCommand() const;
+ MachO::linkedit_data_command getDataInCodeLoadCommand() const;
+ MachO::linkedit_data_command getLinkOptHintsLoadCommand() const;
+ ArrayRef<uint8_t> getDyldInfoRebaseOpcodes() const;
+ ArrayRef<uint8_t> getDyldInfoBindOpcodes() const;
+ ArrayRef<uint8_t> getDyldInfoWeakBindOpcodes() const;
+ ArrayRef<uint8_t> getDyldInfoLazyBindOpcodes() const;
+ ArrayRef<uint8_t> getDyldInfoExportsTrie() const;
+ ArrayRef<uint8_t> getUuid() const;
+
+ StringRef getStringTableData() const;
+ bool is64Bit() const;
+ void ReadULEB128s(uint64_t Index, SmallVectorImpl<uint64_t> &Out) const;
+
+ static StringRef guessLibraryShortName(StringRef Name, bool &isFramework,
+ StringRef &Suffix);
+
+ static Triple::ArchType getArch(uint32_t CPUType);
+ static Triple getArchTriple(uint32_t CPUType, uint32_t CPUSubType,
+ const char **McpuDefault = nullptr,
+ const char **ArchFlag = nullptr);
+ static bool isValidArch(StringRef ArchFlag);
+ static Triple getHostArch();
+
+ bool isRelocatableObject() const override;
+
+ StringRef mapDebugSectionName(StringRef Name) const override;
+
+ bool hasPageZeroSegment() const { return HasPageZeroSegment; }
+
+ static bool classof(const Binary *v) {
+ return v->isMachO();
+ }
+
+ static uint32_t
+ getVersionMinMajor(MachO::version_min_command &C, bool SDK) {
+ uint32_t VersionOrSDK = (SDK) ? C.sdk : C.version;
+ return (VersionOrSDK >> 16) & 0xffff;
+ }
+
+ static uint32_t
+ getVersionMinMinor(MachO::version_min_command &C, bool SDK) {
+ uint32_t VersionOrSDK = (SDK) ? C.sdk : C.version;
+ return (VersionOrSDK >> 8) & 0xff;
+ }
+
+ static uint32_t
+ getVersionMinUpdate(MachO::version_min_command &C, bool SDK) {
+ uint32_t VersionOrSDK = (SDK) ? C.sdk : C.version;
+ return VersionOrSDK & 0xff;
+ }
+
+ static std::string getBuildPlatform(uint32_t platform) {
+ switch (platform) {
+ case MachO::PLATFORM_MACOS: return "macos";
+ case MachO::PLATFORM_IOS: return "ios";
+ case MachO::PLATFORM_TVOS: return "tvos";
+ case MachO::PLATFORM_WATCHOS: return "watchos";
+ case MachO::PLATFORM_BRIDGEOS: return "bridgeos";
+ default:
+ std::string ret;
+ raw_string_ostream ss(ret);
+ ss << format_hex(platform, 8, true);
+ return ss.str();
+ }
+ }
+
+ static std::string getBuildTool(uint32_t tools) {
+ switch (tools) {
+ case MachO::TOOL_CLANG: return "clang";
+ case MachO::TOOL_SWIFT: return "swift";
+ case MachO::TOOL_LD: return "ld";
+ default:
+ std::string ret;
+ raw_string_ostream ss(ret);
+ ss << format_hex(tools, 8, true);
+ return ss.str();
+ }
+ }
+
+ static std::string getVersionString(uint32_t version) {
+ uint32_t major = (version >> 16) & 0xffff;
+ uint32_t minor = (version >> 8) & 0xff;
+ uint32_t update = version & 0xff;
+
+ SmallString<32> Version;
+ Version = utostr(major) + "." + utostr(minor);
+ if (update != 0)
+ Version += "." + utostr(update);
+ return Version.str();
+ }
+
+private:
+ MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian, bool Is64Bits,
+ Error &Err, uint32_t UniversalCputype = 0,
+ uint32_t UniversalIndex = 0);
+
+ uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
+
+ union {
+ MachO::mach_header_64 Header64;
+ MachO::mach_header Header;
+ };
+ using SectionList = SmallVector<const char*, 1>;
+ SectionList Sections;
+ using LibraryList = SmallVector<const char*, 1>;
+ LibraryList Libraries;
+ LoadCommandList LoadCommands;
+ using LibraryShortName = SmallVector<StringRef, 1>;
+ using BuildToolList = SmallVector<const char*, 1>;
+ BuildToolList BuildTools;
+ mutable LibraryShortName LibrariesShortNames;
+ std::unique_ptr<BindRebaseSegInfo> BindRebaseSectionTable;
+ const char *SymtabLoadCmd = nullptr;
+ const char *DysymtabLoadCmd = nullptr;
+ const char *DataInCodeLoadCmd = nullptr;
+ const char *LinkOptHintsLoadCmd = nullptr;
+ const char *DyldInfoLoadCmd = nullptr;
+ const char *UuidLoadCmd = nullptr;
+ bool HasPageZeroSegment = false;
+};
+
+/// DiceRef
+inline DiceRef::DiceRef(DataRefImpl DiceP, const ObjectFile *Owner)
+ : DicePimpl(DiceP) , OwningObject(Owner) {}
+
+inline bool DiceRef::operator==(const DiceRef &Other) const {
+ return DicePimpl == Other.DicePimpl;
+}
+
+inline bool DiceRef::operator<(const DiceRef &Other) const {
+ return DicePimpl < Other.DicePimpl;
+}
+
+inline void DiceRef::moveNext() {
+ const MachO::data_in_code_entry *P =
+ reinterpret_cast<const MachO::data_in_code_entry *>(DicePimpl.p);
+ DicePimpl.p = reinterpret_cast<uintptr_t>(P + 1);
+}
+
+// Since a Mach-O data in code reference, a DiceRef, can only be created when
+// the OwningObject ObjectFile is a MachOObjectFile a static_cast<> is used for
+// the methods that get the values of the fields of the reference.
+
+inline std::error_code DiceRef::getOffset(uint32_t &Result) const {
+ const MachOObjectFile *MachOOF =
+ static_cast<const MachOObjectFile *>(OwningObject);
+ MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl);
+ Result = Dice.offset;
+ return std::error_code();
+}
+
+inline std::error_code DiceRef::getLength(uint16_t &Result) const {
+ const MachOObjectFile *MachOOF =
+ static_cast<const MachOObjectFile *>(OwningObject);
+ MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl);
+ Result = Dice.length;
+ return std::error_code();
+}
+
+inline std::error_code DiceRef::getKind(uint16_t &Result) const {
+ const MachOObjectFile *MachOOF =
+ static_cast<const MachOObjectFile *>(OwningObject);
+ MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl);
+ Result = Dice.kind;
+ return std::error_code();
+}
+
+inline DataRefImpl DiceRef::getRawDataRefImpl() const {
+ return DicePimpl;
+}
+
+inline const ObjectFile *DiceRef::getObjectFile() const {
+ return OwningObject;
+}
+
+} // end namespace object
+} // end namespace llvm
+
+#endif // LLVM_OBJECT_MACHO_H
diff --git a/linux-x64/clang/include/llvm/Object/MachOUniversal.h b/linux-x64/clang/include/llvm/Object/MachOUniversal.h
new file mode 100644
index 0000000..72837d0
--- /dev/null
+++ b/linux-x64/clang/include/llvm/Object/MachOUniversal.h
@@ -0,0 +1,168 @@
+//===- MachOUniversal.h - Mach-O universal binaries -------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares Mach-O fat/universal binaries.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_MACHOUNIVERSAL_H
+#define LLVM_OBJECT_MACHOUNIVERSAL_H
+
+#include "llvm/ADT/Triple.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/BinaryFormat/MachO.h"
+#include "llvm/Object/Archive.h"
+#include "llvm/Object/Binary.h"
+#include "llvm/Object/MachO.h"
+
+namespace llvm {
+class StringRef;
+
+namespace object {
+
+class MachOUniversalBinary : public Binary {
+ virtual void anchor();
+
+ uint32_t Magic;
+ uint32_t NumberOfObjects;
+public:
+ class ObjectForArch {
+ const MachOUniversalBinary *Parent;
+ /// \brief Index of object in the universal binary.
+ uint32_t Index;
+ /// \brief Descriptor of the object.
+ MachO::fat_arch Header;
+ MachO::fat_arch_64 Header64;
+
+ public:
+ ObjectForArch(const MachOUniversalBinary *Parent, uint32_t Index);
+
+ void clear() {
+ Parent = nullptr;
+ Index = 0;
+ }
+
+ bool operator==(const ObjectForArch &Other) const {
+ return (Parent == Other.Parent) && (Index == Other.Index);
+ }
+
+ ObjectForArch getNext() const { return ObjectForArch(Parent, Index + 1); }
+ uint32_t getCPUType() const {
+ if (Parent->getMagic() == MachO::FAT_MAGIC)
+ return Header.cputype;
+ else // Parent->getMagic() == MachO::FAT_MAGIC_64
+ return Header64.cputype;
+ }
+ uint32_t getCPUSubType() const {
+ if (Parent->getMagic() == MachO::FAT_MAGIC)
+ return Header.cpusubtype;
+ else // Parent->getMagic() == MachO::FAT_MAGIC_64
+ return Header64.cpusubtype;
+ }
+ uint32_t getOffset() const {
+ if (Parent->getMagic() == MachO::FAT_MAGIC)
+ return Header.offset;
+ else // Parent->getMagic() == MachO::FAT_MAGIC_64
+ return Header64.offset;
+ }
+ uint32_t getSize() const {
+ if (Parent->getMagic() == MachO::FAT_MAGIC)
+ return Header.size;
+ else // Parent->getMagic() == MachO::FAT_MAGIC_64
+ return Header64.size;
+ }
+ uint32_t getAlign() const {
+ if (Parent->getMagic() == MachO::FAT_MAGIC)
+ return Header.align;
+ else // Parent->getMagic() == MachO::FAT_MAGIC_64
+ return Header64.align;
+ }
+ uint32_t getReserved() const {
+ if (Parent->getMagic() == MachO::FAT_MAGIC)
+ return 0;
+ else // Parent->getMagic() == MachO::FAT_MAGIC_64
+ return Header64.reserved;
+ }
+ std::string getArchFlagName() const {
+ const char *McpuDefault, *ArchFlag;
+ if (Parent->getMagic() == MachO::FAT_MAGIC) {
+ Triple T =
+ MachOObjectFile::getArchTriple(Header.cputype, Header.cpusubtype,
+ &McpuDefault, &ArchFlag);
+ } else { // Parent->getMagic() == MachO::FAT_MAGIC_64
+ Triple T =
+ MachOObjectFile::getArchTriple(Header64.cputype,
+ Header64.cpusubtype,
+ &McpuDefault, &ArchFlag);
+ }
+ if (ArchFlag) {
+ std::string ArchFlagName(ArchFlag);
+ return ArchFlagName;
+ } else {
+ std::string ArchFlagName("");
+ return ArchFlagName;
+ }
+ }
+
+ Expected<std::unique_ptr<MachOObjectFile>> getAsObjectFile() const;
+
+ Expected<std::unique_ptr<Archive>> getAsArchive() const;
+ };
+
+ class object_iterator {
+ ObjectForArch Obj;
+ public:
+ object_iterator(const ObjectForArch &Obj) : Obj(Obj) {}
+ const ObjectForArch *operator->() const { return &Obj; }
+ const ObjectForArch &operator*() const { return Obj; }
+
+ bool operator==(const object_iterator &Other) const {
+ return Obj == Other.Obj;
+ }
+ bool operator!=(const object_iterator &Other) const {
+ return !(*this == Other);
+ }
+
+ object_iterator& operator++() { // Preincrement
+ Obj = Obj.getNext();
+ return *this;
+ }
+ };
+
+ MachOUniversalBinary(MemoryBufferRef Souce, Error &Err);
+ static Expected<std::unique_ptr<MachOUniversalBinary>>
+ create(MemoryBufferRef Source);
+
+ object_iterator begin_objects() const {
+ return ObjectForArch(this, 0);
+ }
+ object_iterator end_objects() const {
+ return ObjectForArch(nullptr, 0);
+ }
+
+ iterator_range<object_iterator> objects() const {
+ return make_range(begin_objects(), end_objects());
+ }
+
+ uint32_t getMagic() const { return Magic; }
+ uint32_t getNumberOfObjects() const { return NumberOfObjects; }
+
+ // Cast methods.
+ static bool classof(Binary const *V) {
+ return V->isMachOUniversalBinary();
+ }
+
+ Expected<std::unique_ptr<MachOObjectFile>>
+ getObjectForArch(StringRef ArchName) const;
+};
+
+}
+}
+
+#endif
diff --git a/linux-x64/clang/include/llvm/Object/ModuleSymbolTable.h b/linux-x64/clang/include/llvm/Object/ModuleSymbolTable.h
new file mode 100644
index 0000000..9e93228
--- /dev/null
+++ b/linux-x64/clang/include/llvm/Object/ModuleSymbolTable.h
@@ -0,0 +1,64 @@
+//===- ModuleSymbolTable.h - symbol table for in-memory IR ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class represents a symbol table built from in-memory IR. It provides
+// access to GlobalValues and should only be used if such access is required
+// (e.g. in the LTO implementation).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_MODULESYMBOLTABLE_H
+#define LLVM_OBJECT_MODULESYMBOLTABLE_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/IR/Mangler.h"
+#include "llvm/Object/SymbolicFile.h"
+#include "llvm/Support/Allocator.h"
+#include <cstdint>
+#include <string>
+#include <utility>
+#include <vector>
+
+namespace llvm {
+
+class GlobalValue;
+
+class ModuleSymbolTable {
+public:
+ using AsmSymbol = std::pair<std::string, uint32_t>;
+ using Symbol = PointerUnion<GlobalValue *, AsmSymbol *>;
+
+private:
+ Module *FirstMod = nullptr;
+
+ SpecificBumpPtrAllocator<AsmSymbol> AsmSymbols;
+ std::vector<Symbol> SymTab;
+ Mangler Mang;
+
+public:
+ ArrayRef<Symbol> symbols() const { return SymTab; }
+ void addModule(Module *M);
+
+ void printSymbolName(raw_ostream &OS, Symbol S) const;
+ uint32_t getSymbolFlags(Symbol S) const;
+
+ /// Parse inline ASM and collect the symbols that are defined or referenced in
+ /// the current module.
+ ///
+ /// For each found symbol, call \p AsmSymbol with the name of the symbol found
+ /// and the associated flags.
+ static void CollectAsmSymbols(
+ const Module &M,
+ function_ref<void(StringRef, object::BasicSymbolRef::Flags)> AsmSymbol);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_OBJECT_MODULESYMBOLTABLE_H
diff --git a/linux-x64/clang/include/llvm/Object/ObjectFile.h b/linux-x64/clang/include/llvm/Object/ObjectFile.h
new file mode 100644
index 0000000..9c4ae94
--- /dev/null
+++ b/linux-x64/clang/include/llvm/Object/ObjectFile.h
@@ -0,0 +1,507 @@
+//===- ObjectFile.h - File format independent object file -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares a file format independent ObjectFile class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_OBJECTFILE_H
+#define LLVM_OBJECT_OBJECTFILE_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/BinaryFormat/Magic.h"
+#include "llvm/MC/SubtargetFeature.h"
+#include "llvm/Object/Binary.h"
+#include "llvm/Object/Error.h"
+#include "llvm/Object/SymbolicFile.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include <cassert>
+#include <cstdint>
+#include <memory>
+#include <system_error>
+
+namespace llvm {
+
+class ARMAttributeParser;
+
+namespace object {
+
+class COFFObjectFile;
+class MachOObjectFile;
+class ObjectFile;
+class SectionRef;
+class SymbolRef;
+class symbol_iterator;
+class WasmObjectFile;
+
+using section_iterator = content_iterator<SectionRef>;
+
+/// This is a value type class that represents a single relocation in the list
+/// of relocations in the object file.
+class RelocationRef {
+ DataRefImpl RelocationPimpl;
+ const ObjectFile *OwningObject = nullptr;
+
+public:
+ RelocationRef() = default;
+ RelocationRef(DataRefImpl RelocationP, const ObjectFile *Owner);
+
+ bool operator==(const RelocationRef &Other) const;
+
+ void moveNext();
+
+ uint64_t getOffset() const;
+ symbol_iterator getSymbol() const;
+ uint64_t getType() const;
+
+ /// @brief Get a string that represents the type of this relocation.
+ ///
+ /// This is for display purposes only.
+ void getTypeName(SmallVectorImpl<char> &Result) const;
+
+ DataRefImpl getRawDataRefImpl() const;
+ const ObjectFile *getObject() const;
+};
+
+using relocation_iterator = content_iterator<RelocationRef>;
+
+/// This is a value type class that represents a single section in the list of
+/// sections in the object file.
+class SectionRef {
+ friend class SymbolRef;
+
+ DataRefImpl SectionPimpl;
+ const ObjectFile *OwningObject = nullptr;
+
+public:
+ SectionRef() = default;
+ SectionRef(DataRefImpl SectionP, const ObjectFile *Owner);
+
+ bool operator==(const SectionRef &Other) const;
+ bool operator!=(const SectionRef &Other) const;
+ bool operator<(const SectionRef &Other) const;
+
+ void moveNext();
+
+ std::error_code getName(StringRef &Result) const;
+ uint64_t getAddress() const;
+ uint64_t getIndex() const;
+ uint64_t getSize() const;
+ std::error_code getContents(StringRef &Result) const;
+
+ /// @brief Get the alignment of this section as the actual value (not log 2).
+ uint64_t getAlignment() const;
+
+ bool isCompressed() const;
+ bool isText() const;
+ bool isData() const;
+ bool isBSS() const;
+ bool isVirtual() const;
+ bool isBitcode() const;
+ bool isStripped() const;
+
+ bool containsSymbol(SymbolRef S) const;
+
+ relocation_iterator relocation_begin() const;
+ relocation_iterator relocation_end() const;
+ iterator_range<relocation_iterator> relocations() const {
+ return make_range(relocation_begin(), relocation_end());
+ }
+ section_iterator getRelocatedSection() const;
+
+ DataRefImpl getRawDataRefImpl() const;
+ const ObjectFile *getObject() const;
+};
+
+/// This is a value type class that represents a single symbol in the list of
+/// symbols in the object file.
+class SymbolRef : public BasicSymbolRef {
+ friend class SectionRef;
+
+public:
+ enum Type {
+ ST_Unknown, // Type not specified
+ ST_Data,
+ ST_Debug,
+ ST_File,
+ ST_Function,
+ ST_Other
+ };
+
+ SymbolRef() = default;
+ SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner);
+ SymbolRef(const BasicSymbolRef &B) : BasicSymbolRef(B) {
+ assert(isa<ObjectFile>(BasicSymbolRef::getObject()));
+ }
+
+ Expected<StringRef> getName() const;
+ /// Returns the symbol virtual address (i.e. address at which it will be
+ /// mapped).
+ Expected<uint64_t> getAddress() const;
+
+ /// Return the value of the symbol depending on the object this can be an
+ /// offset or a virtual address.
+ uint64_t getValue() const;
+
+ /// @brief Get the alignment of this symbol as the actual value (not log 2).
+ uint32_t getAlignment() const;
+ uint64_t getCommonSize() const;
+ Expected<SymbolRef::Type> getType() const;
+
+ /// @brief Get section this symbol is defined in reference to. Result is
+ /// end_sections() if it is undefined or is an absolute symbol.
+ Expected<section_iterator> getSection() const;
+
+ const ObjectFile *getObject() const;
+};
+
+class symbol_iterator : public basic_symbol_iterator {
+public:
+ symbol_iterator(SymbolRef Sym) : basic_symbol_iterator(Sym) {}
+ symbol_iterator(const basic_symbol_iterator &B)
+ : basic_symbol_iterator(SymbolRef(B->getRawDataRefImpl(),
+ cast<ObjectFile>(B->getObject()))) {}
+
+ const SymbolRef *operator->() const {
+ const BasicSymbolRef &P = basic_symbol_iterator::operator *();
+ return static_cast<const SymbolRef*>(&P);
+ }
+
+ const SymbolRef &operator*() const {
+ const BasicSymbolRef &P = basic_symbol_iterator::operator *();
+ return static_cast<const SymbolRef&>(P);
+ }
+};
+
+/// This class is the base class for all object file types. Concrete instances
+/// of this object are created by createObjectFile, which figures out which type
+/// to create.
+class ObjectFile : public SymbolicFile {
+ virtual void anchor();
+
+protected:
+ ObjectFile(unsigned int Type, MemoryBufferRef Source);
+
+ const uint8_t *base() const {
+ return reinterpret_cast<const uint8_t *>(Data.getBufferStart());
+ }
+
+ // These functions are for SymbolRef to call internally. The main goal of
+ // this is to allow SymbolRef::SymbolPimpl to point directly to the symbol
+ // entry in the memory mapped object file. SymbolPimpl cannot contain any
+ // virtual functions because then it could not point into the memory mapped
+ // file.
+ //
+ // Implementations assume that the DataRefImpl is valid and has not been
+ // modified externally. It's UB otherwise.
+ friend class SymbolRef;
+
+ virtual Expected<StringRef> getSymbolName(DataRefImpl Symb) const = 0;
+ std::error_code printSymbolName(raw_ostream &OS,
+ DataRefImpl Symb) const override;
+ virtual Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const = 0;
+ virtual uint64_t getSymbolValueImpl(DataRefImpl Symb) const = 0;
+ virtual uint32_t getSymbolAlignment(DataRefImpl Symb) const;
+ virtual uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const = 0;
+ virtual Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const = 0;
+ virtual Expected<section_iterator>
+ getSymbolSection(DataRefImpl Symb) const = 0;
+
+ // Same as above for SectionRef.
+ friend class SectionRef;
+
+ virtual void moveSectionNext(DataRefImpl &Sec) const = 0;
+ virtual std::error_code getSectionName(DataRefImpl Sec,
+ StringRef &Res) const = 0;
+ virtual uint64_t getSectionAddress(DataRefImpl Sec) const = 0;
+ virtual uint64_t getSectionIndex(DataRefImpl Sec) const = 0;
+ virtual uint64_t getSectionSize(DataRefImpl Sec) const = 0;
+ virtual std::error_code getSectionContents(DataRefImpl Sec,
+ StringRef &Res) const = 0;
+ virtual uint64_t getSectionAlignment(DataRefImpl Sec) const = 0;
+ virtual bool isSectionCompressed(DataRefImpl Sec) const = 0;
+ virtual bool isSectionText(DataRefImpl Sec) const = 0;
+ virtual bool isSectionData(DataRefImpl Sec) const = 0;
+ virtual bool isSectionBSS(DataRefImpl Sec) const = 0;
+ // A section is 'virtual' if its contents aren't present in the object image.
+ virtual bool isSectionVirtual(DataRefImpl Sec) const = 0;
+ virtual bool isSectionBitcode(DataRefImpl Sec) const;
+ virtual bool isSectionStripped(DataRefImpl Sec) const;
+ virtual relocation_iterator section_rel_begin(DataRefImpl Sec) const = 0;
+ virtual relocation_iterator section_rel_end(DataRefImpl Sec) const = 0;
+ virtual section_iterator getRelocatedSection(DataRefImpl Sec) const;
+
+ // Same as above for RelocationRef.
+ friend class RelocationRef;
+ virtual void moveRelocationNext(DataRefImpl &Rel) const = 0;
+ virtual uint64_t getRelocationOffset(DataRefImpl Rel) const = 0;
+ virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const = 0;
+ virtual uint64_t getRelocationType(DataRefImpl Rel) const = 0;
+ virtual void getRelocationTypeName(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const = 0;
+
+ uint64_t getSymbolValue(DataRefImpl Symb) const;
+
+public:
+ ObjectFile() = delete;
+ ObjectFile(const ObjectFile &other) = delete;
+
+ uint64_t getCommonSymbolSize(DataRefImpl Symb) const {
+ assert(getSymbolFlags(Symb) & SymbolRef::SF_Common);
+ return getCommonSymbolSizeImpl(Symb);
+ }
+
+ using symbol_iterator_range = iterator_range<symbol_iterator>;
+ symbol_iterator_range symbols() const {
+ return symbol_iterator_range(symbol_begin(), symbol_end());
+ }
+
+ virtual section_iterator section_begin() const = 0;
+ virtual section_iterator section_end() const = 0;
+
+ using section_iterator_range = iterator_range<section_iterator>;
+ section_iterator_range sections() const {
+ return section_iterator_range(section_begin(), section_end());
+ }
+
+ /// @brief The number of bytes used to represent an address in this object
+ /// file format.
+ virtual uint8_t getBytesInAddress() const = 0;
+
+ virtual StringRef getFileFormatName() const = 0;
+ virtual Triple::ArchType getArch() const = 0;
+ virtual SubtargetFeatures getFeatures() const = 0;
+ virtual void setARMSubArch(Triple &TheTriple) const { }
+
+ /// @brief Create a triple from the data in this object file.
+ Triple makeTriple() const;
+
+ virtual std::error_code
+ getBuildAttributes(ARMAttributeParser &Attributes) const {
+ return std::error_code();
+ }
+
+ /// Maps a debug section name to a standard DWARF section name.
+ virtual StringRef mapDebugSectionName(StringRef Name) const { return Name; }
+
+ /// True if this is a relocatable object (.o/.obj).
+ virtual bool isRelocatableObject() const = 0;
+
+ /// @returns Pointer to ObjectFile subclass to handle this type of object.
+ /// @param ObjectPath The path to the object file. ObjectPath.isObject must
+ /// return true.
+ /// @brief Create ObjectFile from path.
+ static Expected<OwningBinary<ObjectFile>>
+ createObjectFile(StringRef ObjectPath);
+
+ static Expected<std::unique_ptr<ObjectFile>>
+ createObjectFile(MemoryBufferRef Object, llvm::file_magic Type);
+ static Expected<std::unique_ptr<ObjectFile>>
+ createObjectFile(MemoryBufferRef Object) {
+ return createObjectFile(Object, llvm::file_magic::unknown);
+ }
+
+ static bool classof(const Binary *v) {
+ return v->isObject();
+ }
+
+ static Expected<std::unique_ptr<COFFObjectFile>>
+ createCOFFObjectFile(MemoryBufferRef Object);
+
+ static Expected<std::unique_ptr<ObjectFile>>
+ createELFObjectFile(MemoryBufferRef Object);
+
+ static Expected<std::unique_ptr<MachOObjectFile>>
+ createMachOObjectFile(MemoryBufferRef Object,
+ uint32_t UniversalCputype = 0,
+ uint32_t UniversalIndex = 0);
+
+ static Expected<std::unique_ptr<WasmObjectFile>>
+ createWasmObjectFile(MemoryBufferRef Object);
+};
+
+// Inline function definitions.
+inline SymbolRef::SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner)
+ : BasicSymbolRef(SymbolP, Owner) {}
+
+inline Expected<StringRef> SymbolRef::getName() const {
+ return getObject()->getSymbolName(getRawDataRefImpl());
+}
+
+inline Expected<uint64_t> SymbolRef::getAddress() const {
+ return getObject()->getSymbolAddress(getRawDataRefImpl());
+}
+
+inline uint64_t SymbolRef::getValue() const {
+ return getObject()->getSymbolValue(getRawDataRefImpl());
+}
+
+inline uint32_t SymbolRef::getAlignment() const {
+ return getObject()->getSymbolAlignment(getRawDataRefImpl());
+}
+
+inline uint64_t SymbolRef::getCommonSize() const {
+ return getObject()->getCommonSymbolSize(getRawDataRefImpl());
+}
+
+inline Expected<section_iterator> SymbolRef::getSection() const {
+ return getObject()->getSymbolSection(getRawDataRefImpl());
+}
+
+inline Expected<SymbolRef::Type> SymbolRef::getType() const {
+ return getObject()->getSymbolType(getRawDataRefImpl());
+}
+
+inline const ObjectFile *SymbolRef::getObject() const {
+ const SymbolicFile *O = BasicSymbolRef::getObject();
+ return cast<ObjectFile>(O);
+}
+
+/// SectionRef
+inline SectionRef::SectionRef(DataRefImpl SectionP,
+ const ObjectFile *Owner)
+ : SectionPimpl(SectionP)
+ , OwningObject(Owner) {}
+
+inline bool SectionRef::operator==(const SectionRef &Other) const {
+ return SectionPimpl == Other.SectionPimpl;
+}
+
+inline bool SectionRef::operator!=(const SectionRef &Other) const {
+ return SectionPimpl != Other.SectionPimpl;
+}
+
+inline bool SectionRef::operator<(const SectionRef &Other) const {
+ return SectionPimpl < Other.SectionPimpl;
+}
+
+inline void SectionRef::moveNext() {
+ return OwningObject->moveSectionNext(SectionPimpl);
+}
+
+inline std::error_code SectionRef::getName(StringRef &Result) const {
+ return OwningObject->getSectionName(SectionPimpl, Result);
+}
+
+inline uint64_t SectionRef::getAddress() const {
+ return OwningObject->getSectionAddress(SectionPimpl);
+}
+
+inline uint64_t SectionRef::getIndex() const {
+ return OwningObject->getSectionIndex(SectionPimpl);
+}
+
+inline uint64_t SectionRef::getSize() const {
+ return OwningObject->getSectionSize(SectionPimpl);
+}
+
+inline std::error_code SectionRef::getContents(StringRef &Result) const {
+ return OwningObject->getSectionContents(SectionPimpl, Result);
+}
+
+inline uint64_t SectionRef::getAlignment() const {
+ return OwningObject->getSectionAlignment(SectionPimpl);
+}
+
+inline bool SectionRef::isCompressed() const {
+ return OwningObject->isSectionCompressed(SectionPimpl);
+}
+
+inline bool SectionRef::isText() const {
+ return OwningObject->isSectionText(SectionPimpl);
+}
+
+inline bool SectionRef::isData() const {
+ return OwningObject->isSectionData(SectionPimpl);
+}
+
+inline bool SectionRef::isBSS() const {
+ return OwningObject->isSectionBSS(SectionPimpl);
+}
+
+inline bool SectionRef::isVirtual() const {
+ return OwningObject->isSectionVirtual(SectionPimpl);
+}
+
+inline bool SectionRef::isBitcode() const {
+ return OwningObject->isSectionBitcode(SectionPimpl);
+}
+
+inline bool SectionRef::isStripped() const {
+ return OwningObject->isSectionStripped(SectionPimpl);
+}
+
+inline relocation_iterator SectionRef::relocation_begin() const {
+ return OwningObject->section_rel_begin(SectionPimpl);
+}
+
+inline relocation_iterator SectionRef::relocation_end() const {
+ return OwningObject->section_rel_end(SectionPimpl);
+}
+
+inline section_iterator SectionRef::getRelocatedSection() const {
+ return OwningObject->getRelocatedSection(SectionPimpl);
+}
+
+inline DataRefImpl SectionRef::getRawDataRefImpl() const {
+ return SectionPimpl;
+}
+
+inline const ObjectFile *SectionRef::getObject() const {
+ return OwningObject;
+}
+
+/// RelocationRef
+inline RelocationRef::RelocationRef(DataRefImpl RelocationP,
+ const ObjectFile *Owner)
+ : RelocationPimpl(RelocationP)
+ , OwningObject(Owner) {}
+
+inline bool RelocationRef::operator==(const RelocationRef &Other) const {
+ return RelocationPimpl == Other.RelocationPimpl;
+}
+
+inline void RelocationRef::moveNext() {
+ return OwningObject->moveRelocationNext(RelocationPimpl);
+}
+
+inline uint64_t RelocationRef::getOffset() const {
+ return OwningObject->getRelocationOffset(RelocationPimpl);
+}
+
+inline symbol_iterator RelocationRef::getSymbol() const {
+ return OwningObject->getRelocationSymbol(RelocationPimpl);
+}
+
+inline uint64_t RelocationRef::getType() const {
+ return OwningObject->getRelocationType(RelocationPimpl);
+}
+
+inline void RelocationRef::getTypeName(SmallVectorImpl<char> &Result) const {
+ return OwningObject->getRelocationTypeName(RelocationPimpl, Result);
+}
+
+inline DataRefImpl RelocationRef::getRawDataRefImpl() const {
+ return RelocationPimpl;
+}
+
+inline const ObjectFile *RelocationRef::getObject() const {
+ return OwningObject;
+}
+
+} // end namespace object
+
+} // end namespace llvm
+
+#endif // LLVM_OBJECT_OBJECTFILE_H
diff --git a/linux-x64/clang/include/llvm/Object/RelocVisitor.h b/linux-x64/clang/include/llvm/Object/RelocVisitor.h
new file mode 100644
index 0000000..2d0e938
--- /dev/null
+++ b/linux-x64/clang/include/llvm/Object/RelocVisitor.h
@@ -0,0 +1,324 @@
+//===- RelocVisitor.h - Visitor for object file relocations -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides a wrapper around all the different types of relocations
+// in different file formats, such that a client can handle them in a unified
+// manner by only implementing a minimal number of functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_RELOCVISITOR_H
+#define LLVM_OBJECT_RELOCVISITOR_H
+
+#include "llvm/ADT/Triple.h"
+#include "llvm/BinaryFormat/ELF.h"
+#include "llvm/BinaryFormat/MachO.h"
+#include "llvm/Object/COFF.h"
+#include "llvm/Object/ELFObjectFile.h"
+#include "llvm/Object/MachO.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <cstdint>
+#include <system_error>
+
+namespace llvm {
+namespace object {
+
+/// @brief Base class for object file relocation visitors.
+class RelocVisitor {
+public:
+ explicit RelocVisitor(const ObjectFile &Obj) : ObjToVisit(Obj) {}
+
+ // TODO: Should handle multiple applied relocations via either passing in the
+ // previously computed value or just count paired relocations as a single
+ // visit.
+ uint64_t visit(uint32_t Rel, RelocationRef R, uint64_t Value = 0) {
+ if (isa<ELFObjectFileBase>(ObjToVisit))
+ return visitELF(Rel, R, Value);
+ if (isa<COFFObjectFile>(ObjToVisit))
+ return visitCOFF(Rel, R, Value);
+ if (isa<MachOObjectFile>(ObjToVisit))
+ return visitMachO(Rel, R, Value);
+
+ HasError = true;
+ return 0;
+ }
+
+ bool error() { return HasError; }
+
+private:
+ const ObjectFile &ObjToVisit;
+ bool HasError = false;
+
+ uint64_t visitELF(uint32_t Rel, RelocationRef R, uint64_t Value) {
+ if (ObjToVisit.getBytesInAddress() == 8) { // 64-bit object file
+ switch (ObjToVisit.getArch()) {
+ case Triple::x86_64:
+ return visitX86_64(Rel, R, Value);
+ case Triple::aarch64:
+ case Triple::aarch64_be:
+ return visitAarch64(Rel, R, Value);
+ case Triple::bpfel:
+ case Triple::bpfeb:
+ return visitBpf(Rel, R, Value);
+ case Triple::mips64el:
+ case Triple::mips64:
+ return visitMips64(Rel, R, Value);
+ case Triple::ppc64le:
+ case Triple::ppc64:
+ return visitPPC64(Rel, R, Value);
+ case Triple::systemz:
+ return visitSystemz(Rel, R, Value);
+ case Triple::sparcv9:
+ return visitSparc64(Rel, R, Value);
+ case Triple::amdgcn:
+ return visitAmdgpu(Rel, R, Value);
+ default:
+ HasError = true;
+ return 0;
+ }
+ }
+
+ // 32-bit object file
+ assert(ObjToVisit.getBytesInAddress() == 4 &&
+ "Invalid word size in object file");
+
+ switch (ObjToVisit.getArch()) {
+ case Triple::x86:
+ return visitX86(Rel, R, Value);
+ case Triple::ppc:
+ return visitPPC32(Rel, R, Value);
+ case Triple::arm:
+ case Triple::armeb:
+ return visitARM(Rel, R, Value);
+ case Triple::lanai:
+ return visitLanai(Rel, R, Value);
+ case Triple::mipsel:
+ case Triple::mips:
+ return visitMips32(Rel, R, Value);
+ case Triple::sparc:
+ return visitSparc32(Rel, R, Value);
+ case Triple::hexagon:
+ return visitHexagon(Rel, R, Value);
+ default:
+ HasError = true;
+ return 0;
+ }
+ }
+
+ int64_t getELFAddend(RelocationRef R) {
+ Expected<int64_t> AddendOrErr = ELFRelocationRef(R).getAddend();
+ handleAllErrors(AddendOrErr.takeError(), [](const ErrorInfoBase &EI) {
+ report_fatal_error(EI.message());
+ });
+ return *AddendOrErr;
+ }
+
+ uint64_t visitX86_64(uint32_t Rel, RelocationRef R, uint64_t Value) {
+ switch (Rel) {
+ case ELF::R_X86_64_NONE:
+ return 0;
+ case ELF::R_X86_64_64:
+ return Value + getELFAddend(R);
+ case ELF::R_X86_64_PC32:
+ return Value + getELFAddend(R) - R.getOffset();
+ case ELF::R_X86_64_32:
+ case ELF::R_X86_64_32S:
+ return (Value + getELFAddend(R)) & 0xFFFFFFFF;
+ }
+ HasError = true;
+ return 0;
+ }
+
+ uint64_t visitAarch64(uint32_t Rel, RelocationRef R, uint64_t Value) {
+ switch (Rel) {
+ case ELF::R_AARCH64_ABS32: {
+ int64_t Res = Value + getELFAddend(R);
+ if (Res < INT32_MIN || Res > UINT32_MAX)
+ HasError = true;
+ return static_cast<uint32_t>(Res);
+ }
+ case ELF::R_AARCH64_ABS64:
+ return Value + getELFAddend(R);
+ }
+ HasError = true;
+ return 0;
+ }
+
+ uint64_t visitBpf(uint32_t Rel, RelocationRef R, uint64_t Value) {
+ switch (Rel) {
+ case ELF::R_BPF_64_32:
+ return Value & 0xFFFFFFFF;
+ case ELF::R_BPF_64_64:
+ return Value;
+ }
+ HasError = true;
+ return 0;
+ }
+
+ uint64_t visitMips64(uint32_t Rel, RelocationRef R, uint64_t Value) {
+ switch (Rel) {
+ case ELF::R_MIPS_32:
+ return (Value + getELFAddend(R)) & 0xFFFFFFFF;
+ case ELF::R_MIPS_64:
+ return Value + getELFAddend(R);
+ case ELF::R_MIPS_TLS_DTPREL64:
+ return Value + getELFAddend(R) - 0x8000;
+ }
+ HasError = true;
+ return 0;
+ }
+
+ uint64_t visitPPC64(uint32_t Rel, RelocationRef R, uint64_t Value) {
+ switch (Rel) {
+ case ELF::R_PPC64_ADDR32:
+ return (Value + getELFAddend(R)) & 0xFFFFFFFF;
+ case ELF::R_PPC64_ADDR64:
+ return Value + getELFAddend(R);
+ }
+ HasError = true;
+ return 0;
+ }
+
+ uint64_t visitSystemz(uint32_t Rel, RelocationRef R, uint64_t Value) {
+ switch (Rel) {
+ case ELF::R_390_32: {
+ int64_t Res = Value + getELFAddend(R);
+ if (Res < INT32_MIN || Res > UINT32_MAX)
+ HasError = true;
+ return static_cast<uint32_t>(Res);
+ }
+ case ELF::R_390_64:
+ return Value + getELFAddend(R);
+ }
+ HasError = true;
+ return 0;
+ }
+
+ uint64_t visitSparc64(uint32_t Rel, RelocationRef R, uint64_t Value) {
+ switch (Rel) {
+ case ELF::R_SPARC_32:
+ case ELF::R_SPARC_64:
+ case ELF::R_SPARC_UA32:
+ case ELF::R_SPARC_UA64:
+ return Value + getELFAddend(R);
+ }
+ HasError = true;
+ return 0;
+ }
+
+ uint64_t visitAmdgpu(uint32_t Rel, RelocationRef R, uint64_t Value) {
+ switch (Rel) {
+ case ELF::R_AMDGPU_ABS32:
+ case ELF::R_AMDGPU_ABS64:
+ return Value + getELFAddend(R);
+ }
+ HasError = true;
+ return 0;
+ }
+
+ uint64_t visitX86(uint32_t Rel, RelocationRef R, uint64_t Value) {
+ switch (Rel) {
+ case ELF::R_386_NONE:
+ return 0;
+ case ELF::R_386_32:
+ return Value;
+ case ELF::R_386_PC32:
+ return Value - R.getOffset();
+ }
+ HasError = true;
+ return 0;
+ }
+
+ uint64_t visitPPC32(uint32_t Rel, RelocationRef R, uint64_t Value) {
+ if (Rel == ELF::R_PPC_ADDR32)
+ return (Value + getELFAddend(R)) & 0xFFFFFFFF;
+ HasError = true;
+ return 0;
+ }
+
+ uint64_t visitARM(uint32_t Rel, RelocationRef R, uint64_t Value) {
+ if (Rel == ELF::R_ARM_ABS32) {
+ if ((int64_t)Value < INT32_MIN || (int64_t)Value > UINT32_MAX)
+ HasError = true;
+ return static_cast<uint32_t>(Value);
+ }
+ HasError = true;
+ return 0;
+ }
+
+ uint64_t visitLanai(uint32_t Rel, RelocationRef R, uint64_t Value) {
+ if (Rel == ELF::R_LANAI_32)
+ return (Value + getELFAddend(R)) & 0xFFFFFFFF;
+ HasError = true;
+ return 0;
+ }
+
+ uint64_t visitMips32(uint32_t Rel, RelocationRef R, uint64_t Value) {
+ // FIXME: Take in account implicit addends to get correct results.
+ if (Rel == ELF::R_MIPS_32)
+ return Value & 0xFFFFFFFF;
+ if (Rel == ELF::R_MIPS_TLS_DTPREL32)
+ return Value & 0xFFFFFFFF;
+ HasError = true;
+ return 0;
+ }
+
+ uint64_t visitSparc32(uint32_t Rel, RelocationRef R, uint64_t Value) {
+ if (Rel == ELF::R_SPARC_32 || Rel == ELF::R_SPARC_UA32)
+ return Value + getELFAddend(R);
+ HasError = true;
+ return 0;
+ }
+
+ uint64_t visitHexagon(uint32_t Rel, RelocationRef R, uint64_t Value) {
+ if (Rel == ELF::R_HEX_32)
+ return Value + getELFAddend(R);
+ HasError = true;
+ return 0;
+ }
+
+ uint64_t visitCOFF(uint32_t Rel, RelocationRef R, uint64_t Value) {
+ switch (ObjToVisit.getArch()) {
+ case Triple::x86:
+ switch (Rel) {
+ case COFF::IMAGE_REL_I386_SECREL:
+ case COFF::IMAGE_REL_I386_DIR32:
+ return static_cast<uint32_t>(Value);
+ }
+ break;
+ case Triple::x86_64:
+ switch (Rel) {
+ case COFF::IMAGE_REL_AMD64_SECREL:
+ return static_cast<uint32_t>(Value);
+ case COFF::IMAGE_REL_AMD64_ADDR64:
+ return Value;
+ }
+ break;
+ default:
+ break;
+ }
+ HasError = true;
+ return 0;
+ }
+
+ uint64_t visitMachO(uint32_t Rel, RelocationRef R, uint64_t Value) {
+ if (ObjToVisit.getArch() == Triple::x86_64 &&
+ Rel == MachO::X86_64_RELOC_UNSIGNED)
+ return Value;
+ HasError = true;
+ return 0;
+ }
+};
+
+} // end namespace object
+} // end namespace llvm
+
+#endif // LLVM_OBJECT_RELOCVISITOR_H
diff --git a/linux-x64/clang/include/llvm/Object/StackMapParser.h b/linux-x64/clang/include/llvm/Object/StackMapParser.h
new file mode 100644
index 0000000..557db5a
--- /dev/null
+++ b/linux-x64/clang/include/llvm/Object/StackMapParser.h
@@ -0,0 +1,439 @@
+//===- StackMapParser.h - StackMap Parsing Support --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_STACKMAPPARSER_H
+#define LLVM_CODEGEN_STACKMAPPARSER_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/Support/Endian.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <vector>
+
+namespace llvm {
+
+template <support::endianness Endianness>
+class StackMapV2Parser {
+public:
+ template <typename AccessorT>
+ class AccessorIterator {
+ public:
+ AccessorIterator(AccessorT A) : A(A) {}
+
+ AccessorIterator& operator++() { A = A.next(); return *this; }
+ AccessorIterator operator++(int) {
+ auto tmp = *this;
+ ++*this;
+ return tmp;
+ }
+
+ bool operator==(const AccessorIterator &Other) {
+ return A.P == Other.A.P;
+ }
+
+ bool operator!=(const AccessorIterator &Other) { return !(*this == Other); }
+
+ AccessorT& operator*() { return A; }
+ AccessorT* operator->() { return &A; }
+
+ private:
+ AccessorT A;
+ };
+
+ /// Accessor for function records.
+ class FunctionAccessor {
+ friend class StackMapV2Parser;
+
+ public:
+ /// Get the function address.
+ uint64_t getFunctionAddress() const {
+ return read<uint64_t>(P);
+ }
+
+ /// Get the function's stack size.
+ uint64_t getStackSize() const {
+ return read<uint64_t>(P + sizeof(uint64_t));
+ }
+
+ /// Get the number of callsite records.
+ uint64_t getRecordCount() const {
+ return read<uint64_t>(P + (2 * sizeof(uint64_t)));
+ }
+
+ private:
+ FunctionAccessor(const uint8_t *P) : P(P) {}
+
+ const static int FunctionAccessorSize = 3 * sizeof(uint64_t);
+
+ FunctionAccessor next() const {
+ return FunctionAccessor(P + FunctionAccessorSize);
+ }
+
+ const uint8_t *P;
+ };
+
+ /// Accessor for constants.
+ class ConstantAccessor {
+ friend class StackMapV2Parser;
+
+ public:
+ /// Return the value of this constant.
+ uint64_t getValue() const { return read<uint64_t>(P); }
+
+ private:
+ ConstantAccessor(const uint8_t *P) : P(P) {}
+
+ const static int ConstantAccessorSize = sizeof(uint64_t);
+
+ ConstantAccessor next() const {
+ return ConstantAccessor(P + ConstantAccessorSize);
+ }
+
+ const uint8_t *P;
+ };
+
+ enum class LocationKind : uint8_t {
+ Register = 1, Direct = 2, Indirect = 3, Constant = 4, ConstantIndex = 5
+ };
+
+ /// Accessor for location records.
+ class LocationAccessor {
+ friend class StackMapV2Parser;
+ friend class RecordAccessor;
+
+ public:
+ /// Get the Kind for this location.
+ LocationKind getKind() const {
+ return LocationKind(P[KindOffset]);
+ }
+
+ /// Get the Dwarf register number for this location.
+ uint16_t getDwarfRegNum() const {
+ return read<uint16_t>(P + DwarfRegNumOffset);
+ }
+
+ /// Get the small-constant for this location. (Kind must be Constant).
+ uint32_t getSmallConstant() const {
+ assert(getKind() == LocationKind::Constant && "Not a small constant.");
+ return read<uint32_t>(P + SmallConstantOffset);
+ }
+
+ /// Get the constant-index for this location. (Kind must be ConstantIndex).
+ uint32_t getConstantIndex() const {
+ assert(getKind() == LocationKind::ConstantIndex &&
+ "Not a constant-index.");
+ return read<uint32_t>(P + SmallConstantOffset);
+ }
+
+ /// Get the offset for this location. (Kind must be Direct or Indirect).
+ int32_t getOffset() const {
+ assert((getKind() == LocationKind::Direct ||
+ getKind() == LocationKind::Indirect) &&
+ "Not direct or indirect.");
+ return read<int32_t>(P + SmallConstantOffset);
+ }
+
+ private:
+ LocationAccessor(const uint8_t *P) : P(P) {}
+
+ LocationAccessor next() const {
+ return LocationAccessor(P + LocationAccessorSize);
+ }
+
+ static const int KindOffset = 0;
+ static const int DwarfRegNumOffset = KindOffset + sizeof(uint16_t);
+ static const int SmallConstantOffset = DwarfRegNumOffset + sizeof(uint16_t);
+ static const int LocationAccessorSize = sizeof(uint64_t);
+
+ const uint8_t *P;
+ };
+
+ /// Accessor for stackmap live-out fields.
+ class LiveOutAccessor {
+ friend class StackMapV2Parser;
+ friend class RecordAccessor;
+
+ public:
+ /// Get the Dwarf register number for this live-out.
+ uint16_t getDwarfRegNum() const {
+ return read<uint16_t>(P + DwarfRegNumOffset);
+ }
+
+ /// Get the size in bytes of live [sub]register.
+ unsigned getSizeInBytes() const {
+ return read<uint8_t>(P + SizeOffset);
+ }
+
+ private:
+ LiveOutAccessor(const uint8_t *P) : P(P) {}
+
+ LiveOutAccessor next() const {
+ return LiveOutAccessor(P + LiveOutAccessorSize);
+ }
+
+ static const int DwarfRegNumOffset = 0;
+ static const int SizeOffset =
+ DwarfRegNumOffset + sizeof(uint16_t) + sizeof(uint8_t);
+ static const int LiveOutAccessorSize = sizeof(uint32_t);
+
+ const uint8_t *P;
+ };
+
+ /// Accessor for stackmap records.
+ class RecordAccessor {
+ friend class StackMapV2Parser;
+
+ public:
+ using location_iterator = AccessorIterator<LocationAccessor>;
+ using liveout_iterator = AccessorIterator<LiveOutAccessor>;
+
+ /// Get the patchpoint/stackmap ID for this record.
+ uint64_t getID() const {
+ return read<uint64_t>(P + PatchpointIDOffset);
+ }
+
+ /// Get the instruction offset (from the start of the containing function)
+ /// for this record.
+ uint32_t getInstructionOffset() const {
+ return read<uint32_t>(P + InstructionOffsetOffset);
+ }
+
+ /// Get the number of locations contained in this record.
+ uint16_t getNumLocations() const {
+ return read<uint16_t>(P + NumLocationsOffset);
+ }
+
+ /// Get the location with the given index.
+ LocationAccessor getLocation(unsigned LocationIndex) const {
+ unsigned LocationOffset =
+ LocationListOffset + LocationIndex * LocationSize;
+ return LocationAccessor(P + LocationOffset);
+ }
+
+ /// Begin iterator for locations.
+ location_iterator location_begin() const {
+ return location_iterator(getLocation(0));
+ }
+
+ /// End iterator for locations.
+ location_iterator location_end() const {
+ return location_iterator(getLocation(getNumLocations()));
+ }
+
+ /// Iterator range for locations.
+ iterator_range<location_iterator> locations() const {
+ return make_range(location_begin(), location_end());
+ }
+
+ /// Get the number of liveouts contained in this record.
+ uint16_t getNumLiveOuts() const {
+ return read<uint16_t>(P + getNumLiveOutsOffset());
+ }
+
+ /// Get the live-out with the given index.
+ LiveOutAccessor getLiveOut(unsigned LiveOutIndex) const {
+ unsigned LiveOutOffset =
+ getNumLiveOutsOffset() + sizeof(uint16_t) + LiveOutIndex * LiveOutSize;
+ return LiveOutAccessor(P + LiveOutOffset);
+ }
+
+ /// Begin iterator for live-outs.
+ liveout_iterator liveouts_begin() const {
+ return liveout_iterator(getLiveOut(0));
+ }
+
+ /// End iterator for live-outs.
+ liveout_iterator liveouts_end() const {
+ return liveout_iterator(getLiveOut(getNumLiveOuts()));
+ }
+
+ /// Iterator range for live-outs.
+ iterator_range<liveout_iterator> liveouts() const {
+ return make_range(liveouts_begin(), liveouts_end());
+ }
+
+ private:
+ RecordAccessor(const uint8_t *P) : P(P) {}
+
+ unsigned getNumLiveOutsOffset() const {
+ return LocationListOffset + LocationSize * getNumLocations() +
+ sizeof(uint16_t);
+ }
+
+ unsigned getSizeInBytes() const {
+ unsigned RecordSize =
+ getNumLiveOutsOffset() + sizeof(uint16_t) + getNumLiveOuts() * LiveOutSize;
+ return (RecordSize + 7) & ~0x7;
+ }
+
+ RecordAccessor next() const {
+ return RecordAccessor(P + getSizeInBytes());
+ }
+
+ static const unsigned PatchpointIDOffset = 0;
+ static const unsigned InstructionOffsetOffset =
+ PatchpointIDOffset + sizeof(uint64_t);
+ static const unsigned NumLocationsOffset =
+ InstructionOffsetOffset + sizeof(uint32_t) + sizeof(uint16_t);
+ static const unsigned LocationListOffset =
+ NumLocationsOffset + sizeof(uint16_t);
+ static const unsigned LocationSize = sizeof(uint64_t);
+ static const unsigned LiveOutSize = sizeof(uint32_t);
+
+ const uint8_t *P;
+ };
+
+ /// Construct a parser for a version-2 stackmap. StackMap data will be read
+ /// from the given array.
+ StackMapV2Parser(ArrayRef<uint8_t> StackMapSection)
+ : StackMapSection(StackMapSection) {
+ ConstantsListOffset = FunctionListOffset + getNumFunctions() * FunctionSize;
+
+ assert(StackMapSection[0] == 2 &&
+ "StackMapV2Parser can only parse version 2 stackmaps");
+
+ unsigned CurrentRecordOffset =
+ ConstantsListOffset + getNumConstants() * ConstantSize;
+
+ for (unsigned I = 0, E = getNumRecords(); I != E; ++I) {
+ StackMapRecordOffsets.push_back(CurrentRecordOffset);
+ CurrentRecordOffset +=
+ RecordAccessor(&StackMapSection[CurrentRecordOffset]).getSizeInBytes();
+ }
+ }
+
+ using function_iterator = AccessorIterator<FunctionAccessor>;
+ using constant_iterator = AccessorIterator<ConstantAccessor>;
+ using record_iterator = AccessorIterator<RecordAccessor>;
+
+ /// Get the version number of this stackmap. (Always returns 2).
+ unsigned getVersion() const { return 2; }
+
+ /// Get the number of functions in the stack map.
+ uint32_t getNumFunctions() const {
+ return read<uint32_t>(&StackMapSection[NumFunctionsOffset]);
+ }
+
+ /// Get the number of large constants in the stack map.
+ uint32_t getNumConstants() const {
+ return read<uint32_t>(&StackMapSection[NumConstantsOffset]);
+ }
+
+ /// Get the number of stackmap records in the stackmap.
+ uint32_t getNumRecords() const {
+ return read<uint32_t>(&StackMapSection[NumRecordsOffset]);
+ }
+
+ /// Return an FunctionAccessor for the given function index.
+ FunctionAccessor getFunction(unsigned FunctionIndex) const {
+ return FunctionAccessor(StackMapSection.data() +
+ getFunctionOffset(FunctionIndex));
+ }
+
+ /// Begin iterator for functions.
+ function_iterator functions_begin() const {
+ return function_iterator(getFunction(0));
+ }
+
+ /// End iterator for functions.
+ function_iterator functions_end() const {
+ return function_iterator(
+ FunctionAccessor(StackMapSection.data() +
+ getFunctionOffset(getNumFunctions())));
+ }
+
+ /// Iterator range for functions.
+ iterator_range<function_iterator> functions() const {
+ return make_range(functions_begin(), functions_end());
+ }
+
+ /// Return the large constant at the given index.
+ ConstantAccessor getConstant(unsigned ConstantIndex) const {
+ return ConstantAccessor(StackMapSection.data() +
+ getConstantOffset(ConstantIndex));
+ }
+
+ /// Begin iterator for constants.
+ constant_iterator constants_begin() const {
+ return constant_iterator(getConstant(0));
+ }
+
+ /// End iterator for constants.
+ constant_iterator constants_end() const {
+ return constant_iterator(
+ ConstantAccessor(StackMapSection.data() +
+ getConstantOffset(getNumConstants())));
+ }
+
+ /// Iterator range for constants.
+ iterator_range<constant_iterator> constants() const {
+ return make_range(constants_begin(), constants_end());
+ }
+
+ /// Return a RecordAccessor for the given record index.
+ RecordAccessor getRecord(unsigned RecordIndex) const {
+ std::size_t RecordOffset = StackMapRecordOffsets[RecordIndex];
+ return RecordAccessor(StackMapSection.data() + RecordOffset);
+ }
+
+ /// Begin iterator for records.
+ record_iterator records_begin() const {
+ if (getNumRecords() == 0)
+ return record_iterator(RecordAccessor(nullptr));
+ return record_iterator(getRecord(0));
+ }
+
+ /// End iterator for records.
+ record_iterator records_end() const {
+ // Records need to be handled specially, since we cache the start addresses
+ // for them: We can't just compute the 1-past-the-end address, we have to
+ // look at the last record and use the 'next' method.
+ if (getNumRecords() == 0)
+ return record_iterator(RecordAccessor(nullptr));
+ return record_iterator(getRecord(getNumRecords() - 1).next());
+ }
+
+ /// Iterator range for records.
+ iterator_range<record_iterator> records() const {
+ return make_range(records_begin(), records_end());
+ }
+
+private:
+ template <typename T>
+ static T read(const uint8_t *P) {
+ return support::endian::read<T, Endianness, 1>(P);
+ }
+
+ static const unsigned HeaderOffset = 0;
+ static const unsigned NumFunctionsOffset = HeaderOffset + sizeof(uint32_t);
+ static const unsigned NumConstantsOffset = NumFunctionsOffset + sizeof(uint32_t);
+ static const unsigned NumRecordsOffset = NumConstantsOffset + sizeof(uint32_t);
+ static const unsigned FunctionListOffset = NumRecordsOffset + sizeof(uint32_t);
+
+ static const unsigned FunctionSize = 3 * sizeof(uint64_t);
+ static const unsigned ConstantSize = sizeof(uint64_t);
+
+ std::size_t getFunctionOffset(unsigned FunctionIndex) const {
+ return FunctionListOffset + FunctionIndex * FunctionSize;
+ }
+
+ std::size_t getConstantOffset(unsigned ConstantIndex) const {
+ return ConstantsListOffset + ConstantIndex * ConstantSize;
+ }
+
+ ArrayRef<uint8_t> StackMapSection;
+ unsigned ConstantsListOffset;
+ std::vector<unsigned> StackMapRecordOffsets;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_CODEGEN_STACKMAPPARSER_H
diff --git a/linux-x64/clang/include/llvm/Object/SymbolSize.h b/linux-x64/clang/include/llvm/Object/SymbolSize.h
new file mode 100644
index 0000000..1a1dc87
--- /dev/null
+++ b/linux-x64/clang/include/llvm/Object/SymbolSize.h
@@ -0,0 +1,34 @@
+//===- SymbolSize.h ---------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_SYMBOLSIZE_H
+#define LLVM_OBJECT_SYMBOLSIZE_H
+
+#include "llvm/Object/ObjectFile.h"
+
+namespace llvm {
+namespace object {
+
+struct SymEntry {
+ symbol_iterator I;
+ uint64_t Address;
+ unsigned Number;
+ unsigned SectionID;
+};
+
+int compareAddress(const SymEntry *A, const SymEntry *B);
+
+std::vector<std::pair<SymbolRef, uint64_t>>
+computeSymbolSizes(const ObjectFile &O);
+
+}
+} // namespace llvm
+
+#endif
diff --git a/linux-x64/clang/include/llvm/Object/SymbolicFile.h b/linux-x64/clang/include/llvm/Object/SymbolicFile.h
new file mode 100644
index 0000000..5b9549b
--- /dev/null
+++ b/linux-x64/clang/include/llvm/Object/SymbolicFile.h
@@ -0,0 +1,216 @@
+//===- SymbolicFile.h - Interface that only provides symbols ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the SymbolicFile interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_SYMBOLICFILE_H
+#define LLVM_OBJECT_SYMBOLICFILE_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/BinaryFormat/Magic.h"
+#include "llvm/Object/Binary.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include <cinttypes>
+#include <cstdint>
+#include <cstring>
+#include <iterator>
+#include <memory>
+#include <system_error>
+
+namespace llvm {
+namespace object {
+
+union DataRefImpl {
+ // This entire union should probably be a
+ // char[max(8, sizeof(uintptr_t))] and require the impl to cast.
+ struct {
+ uint32_t a, b;
+ } d;
+ uintptr_t p;
+
+ DataRefImpl() { std::memset(this, 0, sizeof(DataRefImpl)); }
+};
+
+template <typename OStream>
+OStream& operator<<(OStream &OS, const DataRefImpl &D) {
+ OS << "(" << format("0x%08" PRIxPTR, D.p) << " (" << format("0x%08x", D.d.a)
+ << ", " << format("0x%08x", D.d.b) << "))";
+ return OS;
+}
+
+inline bool operator==(const DataRefImpl &a, const DataRefImpl &b) {
+ // Check bitwise identical. This is the only legal way to compare a union w/o
+ // knowing which member is in use.
+ return std::memcmp(&a, &b, sizeof(DataRefImpl)) == 0;
+}
+
+inline bool operator!=(const DataRefImpl &a, const DataRefImpl &b) {
+ return !operator==(a, b);
+}
+
+inline bool operator<(const DataRefImpl &a, const DataRefImpl &b) {
+ // Check bitwise identical. This is the only legal way to compare a union w/o
+ // knowing which member is in use.
+ return std::memcmp(&a, &b, sizeof(DataRefImpl)) < 0;
+}
+
+template <class content_type>
+class content_iterator
+ : public std::iterator<std::forward_iterator_tag, content_type> {
+ content_type Current;
+
+public:
+ content_iterator(content_type symb) : Current(std::move(symb)) {}
+
+ const content_type *operator->() const { return &Current; }
+
+ const content_type &operator*() const { return Current; }
+
+ bool operator==(const content_iterator &other) const {
+ return Current == other.Current;
+ }
+
+ bool operator!=(const content_iterator &other) const {
+ return !(*this == other);
+ }
+
+ content_iterator &operator++() { // preincrement
+ Current.moveNext();
+ return *this;
+ }
+};
+
+class SymbolicFile;
+
+/// This is a value type class that represents a single symbol in the list of
+/// symbols in the object file.
+class BasicSymbolRef {
+ DataRefImpl SymbolPimpl;
+ const SymbolicFile *OwningObject = nullptr;
+
+public:
+ enum Flags : unsigned {
+ SF_None = 0,
+ SF_Undefined = 1U << 0, // Symbol is defined in another object file
+ SF_Global = 1U << 1, // Global symbol
+ SF_Weak = 1U << 2, // Weak symbol
+ SF_Absolute = 1U << 3, // Absolute symbol
+ SF_Common = 1U << 4, // Symbol has common linkage
+ SF_Indirect = 1U << 5, // Symbol is an alias to another symbol
+ SF_Exported = 1U << 6, // Symbol is visible to other DSOs
+ SF_FormatSpecific = 1U << 7, // Specific to the object file format
+ // (e.g. section symbols)
+ SF_Thumb = 1U << 8, // Thumb symbol in a 32-bit ARM binary
+ SF_Hidden = 1U << 9, // Symbol has hidden visibility
+ SF_Const = 1U << 10, // Symbol value is constant
+ SF_Executable = 1U << 11, // Symbol points to an executable section
+ // (IR only)
+ };
+
+ BasicSymbolRef() = default;
+ BasicSymbolRef(DataRefImpl SymbolP, const SymbolicFile *Owner);
+
+ bool operator==(const BasicSymbolRef &Other) const;
+ bool operator<(const BasicSymbolRef &Other) const;
+
+ void moveNext();
+
+ std::error_code printName(raw_ostream &OS) const;
+
+ /// Get symbol flags (bitwise OR of SymbolRef::Flags)
+ uint32_t getFlags() const;
+
+ DataRefImpl getRawDataRefImpl() const;
+ const SymbolicFile *getObject() const;
+};
+
+using basic_symbol_iterator = content_iterator<BasicSymbolRef>;
+
+class SymbolicFile : public Binary {
+public:
+ SymbolicFile(unsigned int Type, MemoryBufferRef Source);
+ ~SymbolicFile() override;
+
+ // virtual interface.
+ virtual void moveSymbolNext(DataRefImpl &Symb) const = 0;
+
+ virtual std::error_code printSymbolName(raw_ostream &OS,
+ DataRefImpl Symb) const = 0;
+
+ virtual uint32_t getSymbolFlags(DataRefImpl Symb) const = 0;
+
+ virtual basic_symbol_iterator symbol_begin() const = 0;
+
+ virtual basic_symbol_iterator symbol_end() const = 0;
+
+ // convenience wrappers.
+ using basic_symbol_iterator_range = iterator_range<basic_symbol_iterator>;
+ basic_symbol_iterator_range symbols() const {
+ return basic_symbol_iterator_range(symbol_begin(), symbol_end());
+ }
+
+ // construction aux.
+ static Expected<std::unique_ptr<SymbolicFile>>
+ createSymbolicFile(MemoryBufferRef Object, llvm::file_magic Type,
+ LLVMContext *Context);
+
+ static Expected<std::unique_ptr<SymbolicFile>>
+ createSymbolicFile(MemoryBufferRef Object) {
+ return createSymbolicFile(Object, llvm::file_magic::unknown, nullptr);
+ }
+ static Expected<OwningBinary<SymbolicFile>>
+ createSymbolicFile(StringRef ObjectPath);
+
+ static bool classof(const Binary *v) {
+ return v->isSymbolic();
+ }
+};
+
+inline BasicSymbolRef::BasicSymbolRef(DataRefImpl SymbolP,
+ const SymbolicFile *Owner)
+ : SymbolPimpl(SymbolP), OwningObject(Owner) {}
+
+inline bool BasicSymbolRef::operator==(const BasicSymbolRef &Other) const {
+ return SymbolPimpl == Other.SymbolPimpl;
+}
+
+inline bool BasicSymbolRef::operator<(const BasicSymbolRef &Other) const {
+ return SymbolPimpl < Other.SymbolPimpl;
+}
+
+inline void BasicSymbolRef::moveNext() {
+ return OwningObject->moveSymbolNext(SymbolPimpl);
+}
+
+inline std::error_code BasicSymbolRef::printName(raw_ostream &OS) const {
+ return OwningObject->printSymbolName(OS, SymbolPimpl);
+}
+
+inline uint32_t BasicSymbolRef::getFlags() const {
+ return OwningObject->getSymbolFlags(SymbolPimpl);
+}
+
+inline DataRefImpl BasicSymbolRef::getRawDataRefImpl() const {
+ return SymbolPimpl;
+}
+
+inline const SymbolicFile *BasicSymbolRef::getObject() const {
+ return OwningObject;
+}
+
+} // end namespace object
+} // end namespace llvm
+
+#endif // LLVM_OBJECT_SYMBOLICFILE_H
diff --git a/linux-x64/clang/include/llvm/Object/Wasm.h b/linux-x64/clang/include/llvm/Object/Wasm.h
new file mode 100644
index 0000000..d49acf3
--- /dev/null
+++ b/linux-x64/clang/include/llvm/Object/Wasm.h
@@ -0,0 +1,278 @@
+//===- WasmObjectFile.h - Wasm object file implementation -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the WasmObjectFile class, which implements the ObjectFile
+// interface for Wasm files.
+//
+// See: https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_WASM_H
+#define LLVM_OBJECT_WASM_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/BinaryFormat/Wasm.h"
+#include "llvm/Object/Binary.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include <cstddef>
+#include <cstdint>
+#include <vector>
+
+namespace llvm {
+namespace object {
+
+class WasmSymbol {
+public:
+ WasmSymbol(const wasm::WasmSymbolInfo &Info,
+ const wasm::WasmSignature *FunctionType,
+ const wasm::WasmGlobalType *GlobalType)
+ : Info(Info), FunctionType(FunctionType), GlobalType(GlobalType) {}
+
+ const wasm::WasmSymbolInfo &Info;
+ const wasm::WasmSignature *FunctionType;
+ const wasm::WasmGlobalType *GlobalType;
+
+ bool isTypeFunction() const {
+ return Info.Kind == wasm::WASM_SYMBOL_TYPE_FUNCTION;
+ }
+
+ bool isTypeData() const { return Info.Kind == wasm::WASM_SYMBOL_TYPE_DATA; }
+
+ bool isTypeGlobal() const {
+ return Info.Kind == wasm::WASM_SYMBOL_TYPE_GLOBAL;
+ }
+
+ bool isDefined() const { return !isUndefined(); }
+
+ bool isUndefined() const {
+ return (Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) != 0;
+ }
+
+ bool isBindingWeak() const {
+ return getBinding() == wasm::WASM_SYMBOL_BINDING_WEAK;
+ }
+
+ bool isBindingGlobal() const {
+ return getBinding() == wasm::WASM_SYMBOL_BINDING_GLOBAL;
+ }
+
+ bool isBindingLocal() const {
+ return getBinding() == wasm::WASM_SYMBOL_BINDING_LOCAL;
+ }
+
+ unsigned getBinding() const {
+ return Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK;
+ }
+
+ bool isHidden() const {
+ return getVisibility() == wasm::WASM_SYMBOL_VISIBILITY_HIDDEN;
+ }
+
+ unsigned getVisibility() const {
+ return Info.Flags & wasm::WASM_SYMBOL_VISIBILITY_MASK;
+ }
+
+ void print(raw_ostream &Out) const {
+ Out << "Name=" << Info.Name << ", Kind=" << Info.Kind
+ << ", Flags=" << Info.Flags;
+ if (!isTypeData()) {
+ Out << ", ElemIndex=" << Info.ElementIndex;
+ } else if (isDefined()) {
+ Out << ", Segment=" << Info.DataRef.Segment;
+ Out << ", Offset=" << Info.DataRef.Offset;
+ Out << ", Size=" << Info.DataRef.Size;
+ }
+ }
+
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+ LLVM_DUMP_METHOD void dump() const { print(dbgs()); }
+#endif
+};
+
+struct WasmSection {
+ WasmSection() = default;
+
+ uint32_t Type = 0; // Section type (See below)
+ uint32_t Offset = 0; // Offset with in the file
+ StringRef Name; // Section name (User-defined sections only)
+ ArrayRef<uint8_t> Content; // Section content
+ std::vector<wasm::WasmRelocation> Relocations; // Relocations for this section
+};
+
+struct WasmSegment {
+ uint32_t SectionOffset;
+ wasm::WasmDataSegment Data;
+};
+
+class WasmObjectFile : public ObjectFile {
+
+public:
+ WasmObjectFile(MemoryBufferRef Object, Error &Err);
+
+ const wasm::WasmObjectHeader &getHeader() const;
+ const WasmSymbol &getWasmSymbol(const DataRefImpl &Symb) const;
+ const WasmSymbol &getWasmSymbol(const SymbolRef &Symbol) const;
+ const WasmSection &getWasmSection(const SectionRef &Section) const;
+ const wasm::WasmRelocation &getWasmRelocation(const RelocationRef& Ref) const;
+
+ static bool classof(const Binary *v) { return v->isWasm(); }
+
+ ArrayRef<wasm::WasmSignature> types() const { return Signatures; }
+ ArrayRef<uint32_t> functionTypes() const { return FunctionTypes; }
+ ArrayRef<wasm::WasmImport> imports() const { return Imports; }
+ ArrayRef<wasm::WasmTable> tables() const { return Tables; }
+ ArrayRef<wasm::WasmLimits> memories() const { return Memories; }
+ ArrayRef<wasm::WasmGlobal> globals() const { return Globals; }
+ ArrayRef<wasm::WasmExport> exports() const { return Exports; }
+ ArrayRef<WasmSymbol> syms() const { return Symbols; }
+ const wasm::WasmLinkingData& linkingData() const { return LinkingData; }
+ uint32_t getNumberOfSymbols() const { return Symbols.size(); }
+ ArrayRef<wasm::WasmElemSegment> elements() const { return ElemSegments; }
+ ArrayRef<WasmSegment> dataSegments() const { return DataSegments; }
+ ArrayRef<wasm::WasmFunction> functions() const { return Functions; }
+ ArrayRef<wasm::WasmFunctionName> debugNames() const { return DebugNames; }
+ uint32_t startFunction() const { return StartFunction; }
+ uint32_t getNumImportedGlobals() const { return NumImportedGlobals; }
+ uint32_t getNumImportedFunctions() const { return NumImportedFunctions; }
+
+ void moveSymbolNext(DataRefImpl &Symb) const override;
+
+ uint32_t getSymbolFlags(DataRefImpl Symb) const override;
+
+ basic_symbol_iterator symbol_begin() const override;
+
+ basic_symbol_iterator symbol_end() const override;
+ Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
+
+ Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
+ uint64_t getWasmSymbolValue(const WasmSymbol& Sym) const;
+ uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
+ uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
+ uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
+ Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
+ Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
+
+ // Overrides from SectionRef.
+ void moveSectionNext(DataRefImpl &Sec) const override;
+ std::error_code getSectionName(DataRefImpl Sec,
+ StringRef &Res) const override;
+ uint64_t getSectionAddress(DataRefImpl Sec) const override;
+ uint64_t getSectionIndex(DataRefImpl Sec) const override;
+ uint64_t getSectionSize(DataRefImpl Sec) const override;
+ std::error_code getSectionContents(DataRefImpl Sec,
+ StringRef &Res) const override;
+ uint64_t getSectionAlignment(DataRefImpl Sec) const override;
+ bool isSectionCompressed(DataRefImpl Sec) const override;
+ bool isSectionText(DataRefImpl Sec) const override;
+ bool isSectionData(DataRefImpl Sec) const override;
+ bool isSectionBSS(DataRefImpl Sec) const override;
+ bool isSectionVirtual(DataRefImpl Sec) const override;
+ bool isSectionBitcode(DataRefImpl Sec) const override;
+ relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
+ relocation_iterator section_rel_end(DataRefImpl Sec) const override;
+
+ // Overrides from RelocationRef.
+ void moveRelocationNext(DataRefImpl &Rel) const override;
+ uint64_t getRelocationOffset(DataRefImpl Rel) const override;
+ symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
+ uint64_t getRelocationType(DataRefImpl Rel) const override;
+ void getRelocationTypeName(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const override;
+
+ section_iterator section_begin() const override;
+ section_iterator section_end() const override;
+ uint8_t getBytesInAddress() const override;
+ StringRef getFileFormatName() const override;
+ Triple::ArchType getArch() const override;
+ SubtargetFeatures getFeatures() const override;
+ bool isRelocatableObject() const override;
+
+private:
+ bool isValidFunctionIndex(uint32_t Index) const;
+ bool isDefinedFunctionIndex(uint32_t Index) const;
+ bool isValidGlobalIndex(uint32_t Index) const;
+ bool isDefinedGlobalIndex(uint32_t Index) const;
+ bool isValidFunctionSymbol(uint32_t Index) const;
+ bool isValidGlobalSymbol(uint32_t Index) const;
+ bool isValidDataSymbol(uint32_t Index) const;
+ wasm::WasmFunction &getDefinedFunction(uint32_t Index);
+ wasm::WasmGlobal &getDefinedGlobal(uint32_t Index);
+
+ const WasmSection &getWasmSection(DataRefImpl Ref) const;
+ const wasm::WasmRelocation &getWasmRelocation(DataRefImpl Ref) const;
+
+ WasmSection* findCustomSectionByName(StringRef Name);
+ WasmSection* findSectionByType(uint32_t Type);
+
+ const uint8_t *getPtr(size_t Offset) const;
+ Error parseSection(WasmSection &Sec);
+ Error parseCustomSection(WasmSection &Sec, const uint8_t *Ptr,
+ const uint8_t *End);
+
+ // Standard section types
+ Error parseTypeSection(const uint8_t *Ptr, const uint8_t *End);
+ Error parseImportSection(const uint8_t *Ptr, const uint8_t *End);
+ Error parseFunctionSection(const uint8_t *Ptr, const uint8_t *End);
+ Error parseTableSection(const uint8_t *Ptr, const uint8_t *End);
+ Error parseMemorySection(const uint8_t *Ptr, const uint8_t *End);
+ Error parseGlobalSection(const uint8_t *Ptr, const uint8_t *End);
+ Error parseExportSection(const uint8_t *Ptr, const uint8_t *End);
+ Error parseStartSection(const uint8_t *Ptr, const uint8_t *End);
+ Error parseElemSection(const uint8_t *Ptr, const uint8_t *End);
+ Error parseCodeSection(const uint8_t *Ptr, const uint8_t *End);
+ Error parseDataSection(const uint8_t *Ptr, const uint8_t *End);
+
+ // Custom section types
+ Error parseNameSection(const uint8_t *Ptr, const uint8_t *End);
+ Error parseLinkingSection(const uint8_t *Ptr, const uint8_t *End);
+ Error parseLinkingSectionSymtab(const uint8_t *&Ptr, const uint8_t *End);
+ Error parseLinkingSectionComdat(const uint8_t *&Ptr, const uint8_t *End);
+ Error parseRelocSection(StringRef Name, const uint8_t *Ptr,
+ const uint8_t *End);
+
+ wasm::WasmObjectHeader Header;
+ std::vector<WasmSection> Sections;
+ std::vector<wasm::WasmSignature> Signatures;
+ std::vector<uint32_t> FunctionTypes;
+ std::vector<wasm::WasmTable> Tables;
+ std::vector<wasm::WasmLimits> Memories;
+ std::vector<wasm::WasmGlobal> Globals;
+ std::vector<wasm::WasmImport> Imports;
+ std::vector<wasm::WasmExport> Exports;
+ std::vector<wasm::WasmElemSegment> ElemSegments;
+ std::vector<WasmSegment> DataSegments;
+ std::vector<wasm::WasmFunction> Functions;
+ std::vector<WasmSymbol> Symbols;
+ std::vector<wasm::WasmFunctionName> DebugNames;
+ uint32_t StartFunction = -1;
+ bool HasLinkingSection = false;
+ wasm::WasmLinkingData LinkingData;
+ uint32_t NumImportedGlobals = 0;
+ uint32_t NumImportedFunctions = 0;
+ uint32_t CodeSection = 0;
+ uint32_t DataSection = 0;
+ uint32_t GlobalSection = 0;
+};
+
+} // end namespace object
+
+inline raw_ostream &operator<<(raw_ostream &OS,
+ const object::WasmSymbol &Sym) {
+ Sym.print(OS);
+ return OS;
+}
+
+} // end namespace llvm
+
+#endif // LLVM_OBJECT_WASM_H
diff --git a/linux-x64/clang/include/llvm/Object/WasmTraits.h b/linux-x64/clang/include/llvm/Object/WasmTraits.h
new file mode 100644
index 0000000..ebcd00b
--- /dev/null
+++ b/linux-x64/clang/include/llvm/Object/WasmTraits.h
@@ -0,0 +1,63 @@
+//===- WasmTraits.h - DenseMap traits for the Wasm structures ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides llvm::DenseMapInfo traits for the Wasm structures.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_WASMTRAITS_H
+#define LLVM_OBJECT_WASMTRAITS_H
+
+#include "llvm/ADT/Hashing.h"
+#include "llvm/BinaryFormat/Wasm.h"
+
+namespace llvm {
+
+template <typename T> struct DenseMapInfo;
+
+// Traits for using WasmSignature in a DenseMap.
+template <> struct DenseMapInfo<wasm::WasmSignature> {
+ static wasm::WasmSignature getEmptyKey() {
+ return wasm::WasmSignature{{}, 1};
+ }
+ static wasm::WasmSignature getTombstoneKey() {
+ return wasm::WasmSignature{{}, 2};
+ }
+ static unsigned getHashValue(const wasm::WasmSignature &Sig) {
+ unsigned H = hash_value(Sig.ReturnType);
+ for (int32_t Param : Sig.ParamTypes)
+ H = hash_combine(H, Param);
+ return H;
+ }
+ static bool isEqual(const wasm::WasmSignature &LHS,
+ const wasm::WasmSignature &RHS) {
+ return LHS == RHS;
+ }
+};
+
+// Traits for using WasmGlobalType in a DenseMap
+template <> struct DenseMapInfo<wasm::WasmGlobalType> {
+ static wasm::WasmGlobalType getEmptyKey() {
+ return wasm::WasmGlobalType{1, true};
+ }
+ static wasm::WasmGlobalType getTombstoneKey() {
+ return wasm::WasmGlobalType{2, true};
+ }
+ static unsigned getHashValue(const wasm::WasmGlobalType &GlobalType) {
+ return hash_combine(GlobalType.Type, GlobalType.Mutable);
+ }
+ static bool isEqual(const wasm::WasmGlobalType &LHS,
+ const wasm::WasmGlobalType &RHS) {
+ return LHS == RHS;
+ }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_OBJECT_WASMTRAITS_H
diff --git a/linux-x64/clang/include/llvm/Object/WindowsResource.h b/linux-x64/clang/include/llvm/Object/WindowsResource.h
new file mode 100644
index 0000000..a077c82
--- /dev/null
+++ b/linux-x64/clang/include/llvm/Object/WindowsResource.h
@@ -0,0 +1,227 @@
+//===-- WindowsResource.h ---------------------------------------*- C++-*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===---------------------------------------------------------------------===//
+//
+// This file declares the .res file class. .res files are intermediate
+// products of the typical resource-compilation process on Windows. This
+// process is as follows:
+//
+// .rc file(s) ---(rc.exe)---> .res file(s) ---(cvtres.exe)---> COFF file
+//
+// .rc files are human-readable scripts that list all resources a program uses.
+//
+// They are compiled into .res files, which are a list of the resources in
+// binary form.
+//
+// Finally the data stored in the .res is compiled into a COFF file, where it
+// is organized in a directory tree structure for optimized access by the
+// program during runtime.
+//
+// Ref: msdn.microsoft.com/en-us/library/windows/desktop/ms648007(v=vs.85).aspx
+//
+//===---------------------------------------------------------------------===//
+
+#ifndef LLVM_INCLUDE_LLVM_OBJECT_RESFILE_H
+#define LLVM_INCLUDE_LLVM_OBJECT_RESFILE_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/BinaryFormat/COFF.h"
+#include "llvm/Object/Binary.h"
+#include "llvm/Object/Error.h"
+#include "llvm/Support/BinaryByteStream.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/ScopedPrinter.h"
+
+#include <map>
+
+namespace llvm {
+namespace object {
+
+class WindowsResource;
+
+const size_t WIN_RES_MAGIC_SIZE = 16;
+const size_t WIN_RES_NULL_ENTRY_SIZE = 16;
+const uint32_t WIN_RES_HEADER_ALIGNMENT = 4;
+const uint32_t WIN_RES_DATA_ALIGNMENT = 4;
+const uint16_t WIN_RES_PURE_MOVEABLE = 0x0030;
+
+struct WinResHeaderPrefix {
+ support::ulittle32_t DataSize;
+ support::ulittle32_t HeaderSize;
+};
+
+// Type and Name may each either be an integer ID or a string. This struct is
+// only used in the case where they are both IDs.
+struct WinResIDs {
+ uint16_t TypeFlag;
+ support::ulittle16_t TypeID;
+ uint16_t NameFlag;
+ support::ulittle16_t NameID;
+
+ void setType(uint16_t ID) {
+ TypeFlag = 0xffff;
+ TypeID = ID;
+ }
+
+ void setName(uint16_t ID) {
+ NameFlag = 0xffff;
+ NameID = ID;
+ }
+};
+
+struct WinResHeaderSuffix {
+ support::ulittle32_t DataVersion;
+ support::ulittle16_t MemoryFlags;
+ support::ulittle16_t Language;
+ support::ulittle32_t Version;
+ support::ulittle32_t Characteristics;
+};
+
+class EmptyResError : public GenericBinaryError {
+public:
+ EmptyResError(Twine Msg, object_error ECOverride)
+ : GenericBinaryError(Msg, ECOverride) {}
+};
+
+class ResourceEntryRef {
+public:
+ Error moveNext(bool &End);
+ bool checkTypeString() const { return IsStringType; }
+ ArrayRef<UTF16> getTypeString() const { return Type; }
+ uint16_t getTypeID() const { return TypeID; }
+ bool checkNameString() const { return IsStringName; }
+ ArrayRef<UTF16> getNameString() const { return Name; }
+ uint16_t getNameID() const { return NameID; }
+ uint16_t getDataVersion() const { return Suffix->DataVersion; }
+ uint16_t getLanguage() const { return Suffix->Language; }
+ uint16_t getMemoryFlags() const { return Suffix->MemoryFlags; }
+ uint16_t getMajorVersion() const { return Suffix->Version >> 16; }
+ uint16_t getMinorVersion() const { return Suffix->Version; }
+ uint32_t getCharacteristics() const { return Suffix->Characteristics; }
+ ArrayRef<uint8_t> getData() const { return Data; }
+
+private:
+ friend class WindowsResource;
+
+ ResourceEntryRef(BinaryStreamRef Ref, const WindowsResource *Owner);
+ Error loadNext();
+
+ static Expected<ResourceEntryRef> create(BinaryStreamRef Ref,
+ const WindowsResource *Owner);
+
+ BinaryStreamReader Reader;
+ bool IsStringType;
+ ArrayRef<UTF16> Type;
+ uint16_t TypeID;
+ bool IsStringName;
+ ArrayRef<UTF16> Name;
+ uint16_t NameID;
+ const WinResHeaderSuffix *Suffix = nullptr;
+ ArrayRef<uint8_t> Data;
+};
+
+class WindowsResource : public Binary {
+public:
+ Expected<ResourceEntryRef> getHeadEntry();
+
+ static bool classof(const Binary *V) { return V->isWinRes(); }
+
+ static Expected<std::unique_ptr<WindowsResource>>
+ createWindowsResource(MemoryBufferRef Source);
+
+private:
+ friend class ResourceEntryRef;
+
+ WindowsResource(MemoryBufferRef Source);
+
+ BinaryByteStream BBS;
+};
+
+class WindowsResourceParser {
+public:
+ class TreeNode;
+ WindowsResourceParser();
+ Error parse(WindowsResource *WR);
+ void printTree(raw_ostream &OS) const;
+ const TreeNode &getTree() const { return Root; }
+ const ArrayRef<std::vector<uint8_t>> getData() const { return Data; }
+ const ArrayRef<std::vector<UTF16>> getStringTable() const {
+ return StringTable;
+ }
+
+ class TreeNode {
+ public:
+ template <typename T>
+ using Children = std::map<T, std::unique_ptr<TreeNode>>;
+
+ void print(ScopedPrinter &Writer, StringRef Name) const;
+ uint32_t getTreeSize() const;
+ uint32_t getStringIndex() const { return StringIndex; }
+ uint32_t getDataIndex() const { return DataIndex; }
+ uint16_t getMajorVersion() const { return MajorVersion; }
+ uint16_t getMinorVersion() const { return MinorVersion; }
+ uint32_t getCharacteristics() const { return Characteristics; }
+ bool checkIsDataNode() const { return IsDataNode; }
+ const Children<uint32_t> &getIDChildren() const { return IDChildren; }
+ const Children<std::string> &getStringChildren() const {
+ return StringChildren;
+ }
+
+ private:
+ friend class WindowsResourceParser;
+
+ static uint32_t StringCount;
+ static uint32_t DataCount;
+
+ static std::unique_ptr<TreeNode> createStringNode();
+ static std::unique_ptr<TreeNode> createIDNode();
+ static std::unique_ptr<TreeNode> createDataNode(uint16_t MajorVersion,
+ uint16_t MinorVersion,
+ uint32_t Characteristics);
+
+ explicit TreeNode(bool IsStringNode);
+ TreeNode(uint16_t MajorVersion, uint16_t MinorVersion,
+ uint32_t Characteristics);
+
+ void addEntry(const ResourceEntryRef &Entry, bool &IsNewTypeString,
+ bool &IsNewNameString);
+ TreeNode &addTypeNode(const ResourceEntryRef &Entry, bool &IsNewTypeString);
+ TreeNode &addNameNode(const ResourceEntryRef &Entry, bool &IsNewNameString);
+ TreeNode &addLanguageNode(const ResourceEntryRef &Entry);
+ TreeNode &addChild(uint32_t ID, bool IsDataNode = false,
+ uint16_t MajorVersion = 0, uint16_t MinorVersion = 0,
+ uint32_t Characteristics = 0);
+ TreeNode &addChild(ArrayRef<UTF16> NameRef, bool &IsNewString);
+
+ bool IsDataNode = false;
+ uint32_t StringIndex;
+ uint32_t DataIndex;
+ Children<uint32_t> IDChildren;
+ Children<std::string> StringChildren;
+ uint16_t MajorVersion = 0;
+ uint16_t MinorVersion = 0;
+ uint32_t Characteristics = 0;
+ };
+
+private:
+ TreeNode Root;
+ std::vector<std::vector<uint8_t>> Data;
+ std::vector<std::vector<UTF16>> StringTable;
+};
+
+Expected<std::unique_ptr<MemoryBuffer>>
+writeWindowsResourceCOFF(llvm::COFF::MachineTypes MachineType,
+ const WindowsResourceParser &Parser);
+
+} // namespace object
+} // namespace llvm
+
+#endif