diff options
Diffstat (limited to 'include/llvm/BinaryFormat')
-rw-r--r-- | include/llvm/BinaryFormat/COFF.h | 19 | ||||
-rw-r--r-- | include/llvm/BinaryFormat/Dwarf.def | 54 | ||||
-rw-r--r-- | include/llvm/BinaryFormat/Dwarf.h | 115 | ||||
-rw-r--r-- | include/llvm/BinaryFormat/DynamicTags.def | 216 | ||||
-rw-r--r-- | include/llvm/BinaryFormat/ELF.h | 355 | ||||
-rw-r--r-- | include/llvm/BinaryFormat/ELFRelocs/PowerPC64.def | 14 | ||||
-rw-r--r-- | include/llvm/BinaryFormat/ELFRelocs/WebAssembly.def | 8 | ||||
-rw-r--r-- | include/llvm/BinaryFormat/MachO.h | 4 | ||||
-rw-r--r-- | include/llvm/BinaryFormat/Magic.h | 7 | ||||
-rw-r--r-- | include/llvm/BinaryFormat/Wasm.h | 154 | ||||
-rw-r--r-- | include/llvm/BinaryFormat/WasmRelocs.def | 2 |
11 files changed, 664 insertions, 284 deletions
diff --git a/include/llvm/BinaryFormat/COFF.h b/include/llvm/BinaryFormat/COFF.h index a55c544dfe90..7b973c03cc80 100644 --- a/include/llvm/BinaryFormat/COFF.h +++ b/include/llvm/BinaryFormat/COFF.h @@ -110,6 +110,9 @@ enum MachineTypes : unsigned { IMAGE_FILE_MACHINE_POWERPC = 0x1F0, IMAGE_FILE_MACHINE_POWERPCFP = 0x1F1, IMAGE_FILE_MACHINE_R4000 = 0x166, + IMAGE_FILE_MACHINE_RISCV32 = 0x5032, + IMAGE_FILE_MACHINE_RISCV64 = 0x5064, + IMAGE_FILE_MACHINE_RISCV128 = 0x5128, IMAGE_FILE_MACHINE_SH3 = 0x1A2, IMAGE_FILE_MACHINE_SH3DSP = 0x1A3, IMAGE_FILE_MACHINE_SH4 = 0x1A6, @@ -460,7 +463,7 @@ union Auxiliary { AuxiliarySectionDefinition SectionDefinition; }; -/// @brief The Import Directory Table. +/// The Import Directory Table. /// /// There is a single array of these and one entry per imported DLL. struct ImportDirectoryTableEntry { @@ -471,7 +474,7 @@ struct ImportDirectoryTableEntry { uint32_t ImportAddressTableRVA; }; -/// @brief The PE32 Import Lookup Table. +/// The PE32 Import Lookup Table. /// /// There is an array of these for each imported DLL. It represents either /// the ordinal to import from the target DLL, or a name to lookup and import @@ -482,32 +485,32 @@ struct ImportDirectoryTableEntry { struct ImportLookupTableEntry32 { uint32_t data; - /// @brief Is this entry specified by ordinal, or name? + /// Is this entry specified by ordinal, or name? bool isOrdinal() const { return data & 0x80000000; } - /// @brief Get the ordinal value of this entry. isOrdinal must be true. + /// Get the ordinal value of this entry. isOrdinal must be true. uint16_t getOrdinal() const { assert(isOrdinal() && "ILT entry is not an ordinal!"); return data & 0xFFFF; } - /// @brief Set the ordinal value and set isOrdinal to true. + /// Set the ordinal value and set isOrdinal to true. void setOrdinal(uint16_t o) { data = o; data |= 0x80000000; } - /// @brief Get the Hint/Name entry RVA. isOrdinal must be false. + /// Get the Hint/Name entry RVA. isOrdinal must be false. uint32_t getHintNameRVA() const { assert(!isOrdinal() && "ILT entry is not a Hint/Name RVA!"); return data; } - /// @brief Set the Hint/Name entry RVA and set isOrdinal to false. + /// Set the Hint/Name entry RVA and set isOrdinal to false. void setHintNameRVA(uint32_t rva) { data = rva; } }; -/// @brief The DOS compatible header at the front of all PEs. +/// The DOS compatible header at the front of all PEs. struct DOSHeader { uint16_t Magic; uint16_t UsedBytesInTheLastPage; diff --git a/include/llvm/BinaryFormat/Dwarf.def b/include/llvm/BinaryFormat/Dwarf.def index 3ade3ea0d338..57e259615d0c 100644 --- a/include/llvm/BinaryFormat/Dwarf.def +++ b/include/llvm/BinaryFormat/Dwarf.def @@ -12,15 +12,15 @@ //===----------------------------------------------------------------------===// // TODO: Add other DW-based macros. -#if !(defined HANDLE_DW_TAG || defined HANDLE_DW_AT || \ - defined HANDLE_DW_FORM || defined HANDLE_DW_OP || \ - defined HANDLE_DW_LANG || defined HANDLE_DW_ATE || \ - defined HANDLE_DW_VIRTUALITY || defined HANDLE_DW_DEFAULTED || \ - defined HANDLE_DW_CC || defined HANDLE_DW_LNS || \ - defined HANDLE_DW_LNE || defined HANDLE_DW_LNCT || \ - defined HANDLE_DW_MACRO || defined HANDLE_DW_RLE || \ - defined HANDLE_DW_CFA || defined HANDLE_DW_APPLE_PROPERTY || \ - defined HANDLE_DW_UT || defined HANDLE_DWARF_SECTION) +#if !( \ + defined HANDLE_DW_TAG || defined HANDLE_DW_AT || defined HANDLE_DW_FORM || \ + defined HANDLE_DW_OP || defined HANDLE_DW_LANG || defined HANDLE_DW_ATE || \ + defined HANDLE_DW_VIRTUALITY || defined HANDLE_DW_DEFAULTED || \ + defined HANDLE_DW_CC || defined HANDLE_DW_LNS || defined HANDLE_DW_LNE || \ + defined HANDLE_DW_LNCT || defined HANDLE_DW_MACRO || \ + defined HANDLE_DW_RLE || defined HANDLE_DW_CFA || \ + defined HANDLE_DW_APPLE_PROPERTY || defined HANDLE_DW_UT || \ + defined HANDLE_DWARF_SECTION || defined HANDLE_DW_IDX) #error "Missing macro definition of HANDLE_DW*" #endif @@ -96,6 +96,10 @@ #define HANDLE_DWARF_SECTION(ENUM_NAME, ELF_NAME, CMDLINE_NAME) #endif +#ifndef HANDLE_DW_IDX +#define HANDLE_DW_IDX(ID, NAME) +#endif + HANDLE_DW_TAG(0x0000, null, 2, DWARF) HANDLE_DW_TAG(0x0001, array_type, 2, DWARF) HANDLE_DW_TAG(0x0002, class_type, 2, DWARF) @@ -704,6 +708,7 @@ HANDLE_DW_CC(0x03, nocall) HANDLE_DW_CC(0x04, pass_by_reference) HANDLE_DW_CC(0x05, pass_by_value) // Vendor extensions: +HANDLE_DW_CC(0x40, GNU_renesas_sh) HANDLE_DW_CC(0x41, GNU_borland_fastcall_i386) HANDLE_DW_CC(0xb0, BORLAND_safecall) HANDLE_DW_CC(0xb1, BORLAND_stdcall) @@ -713,6 +718,22 @@ HANDLE_DW_CC(0xb4, BORLAND_msreturn) HANDLE_DW_CC(0xb5, BORLAND_thiscall) HANDLE_DW_CC(0xb6, BORLAND_fastcall) HANDLE_DW_CC(0xc0, LLVM_vectorcall) +HANDLE_DW_CC(0xc1, LLVM_Win64) +HANDLE_DW_CC(0xc2, LLVM_X86_64SysV) +HANDLE_DW_CC(0xc3, LLVM_AAPCS) +HANDLE_DW_CC(0xc4, LLVM_AAPCS_VFP) +HANDLE_DW_CC(0xc5, LLVM_IntelOclBicc) +HANDLE_DW_CC(0xc6, LLVM_SpirFunction) +HANDLE_DW_CC(0xc7, LLVM_OpenCLKernel) +HANDLE_DW_CC(0xc8, LLVM_Swift) +HANDLE_DW_CC(0xc9, LLVM_PreserveMost) +HANDLE_DW_CC(0xca, LLVM_PreserveAll) +HANDLE_DW_CC(0xcb, LLVM_X86RegCall) +// From GCC source code (include/dwarf2.h): This DW_CC_ value is not currently +// generated by any toolchain. It is used internally to GDB to indicate OpenCL C +// functions that have been compiled with the IBM XL C for OpenCL compiler and use +// a non-platform calling convention for passing OpenCL C vector types. +HANDLE_DW_CC(0xff, GDB_IBM_OpenCL) // Line Number Extended Opcode Encodings HANDLE_DW_LNE(0x01, end_sequence) @@ -743,6 +764,9 @@ HANDLE_DW_LNCT(0x02, directory_index) HANDLE_DW_LNCT(0x03, timestamp) HANDLE_DW_LNCT(0x04, size) HANDLE_DW_LNCT(0x05, MD5) +// A vendor extension until http://dwarfstd.org/ShowIssue.php?issue=180201.1 is +// accepted and incorporated into the next DWARF standard. +HANDLE_DW_LNCT(0x2001, LLVM_source) // DWARF v5 Macro information. HANDLE_DW_MACRO(0x01, define) @@ -836,14 +860,17 @@ HANDLE_DWARF_SECTION(DebugAranges, ".debug_aranges", "debug-aranges") HANDLE_DWARF_SECTION(DebugInfo, ".debug_info", "debug-info") HANDLE_DWARF_SECTION(DebugTypes, ".debug_types", "debug-types") HANDLE_DWARF_SECTION(DebugLine, ".debug_line", "debug-line") +HANDLE_DWARF_SECTION(DebugLineStr, ".debug_line_str", "debug-line-str") HANDLE_DWARF_SECTION(DebugLoc, ".debug_loc", "debug-loc") HANDLE_DWARF_SECTION(DebugFrame, ".debug_frame", "debug-frame") HANDLE_DWARF_SECTION(DebugMacro, ".debug_macro", "debug-macro") -HANDLE_DWARF_SECTION(DebugRanges, ".debug_ranges", "debug-ranges") +HANDLE_DWARF_SECTION(DebugNames, ".debug_names", "debug-names") HANDLE_DWARF_SECTION(DebugPubnames, ".debug_pubnames", "debug-pubnames") HANDLE_DWARF_SECTION(DebugPubtypes, ".debug_pubtypes", "debug-pubtypes") HANDLE_DWARF_SECTION(DebugGnuPubnames, ".debug_gnu_pubnames", "debug-gnu-pubnames") HANDLE_DWARF_SECTION(DebugGnuPubtypes, ".debug_gnu_pubtypes", "debug-gnu-pubtypes") +HANDLE_DWARF_SECTION(DebugRanges, ".debug_ranges", "debug-ranges") +HANDLE_DWARF_SECTION(DebugRnglists, ".debug_rnglists", "debug-rnglists") HANDLE_DWARF_SECTION(DebugStr, ".debug_str", "debug-str") HANDLE_DWARF_SECTION(DebugStrOffsets, ".debug_str_offsets", "debug-str-offsets") HANDLE_DWARF_SECTION(DebugCUIndex, ".debug_cu_index", "debug-cu-index") @@ -855,6 +882,12 @@ HANDLE_DWARF_SECTION(AppleNamespaces, ".apple_namespaces", "apple-namespaces") HANDLE_DWARF_SECTION(AppleObjC, ".apple_objc", "apple-objc") HANDLE_DWARF_SECTION(GdbIndex, ".gdb_index", "gdb-index") +HANDLE_DW_IDX(0x01, compile_unit) +HANDLE_DW_IDX(0x02, type_unit) +HANDLE_DW_IDX(0x03, die_offset) +HANDLE_DW_IDX(0x04, parent) +HANDLE_DW_IDX(0x05, type_hash) + #undef HANDLE_DW_TAG #undef HANDLE_DW_AT @@ -874,3 +907,4 @@ HANDLE_DWARF_SECTION(GdbIndex, ".gdb_index", "gdb-index") #undef HANDLE_DW_APPLE_PROPERTY #undef HANDLE_DW_UT #undef HANDLE_DWARF_SECTION +#undef HANDLE_DW_IDX diff --git a/include/llvm/BinaryFormat/Dwarf.h b/include/llvm/BinaryFormat/Dwarf.h index a0e5367b412c..9036f405eaea 100644 --- a/include/llvm/BinaryFormat/Dwarf.h +++ b/include/llvm/BinaryFormat/Dwarf.h @@ -20,8 +20,12 @@ #ifndef LLVM_BINARYFORMAT_DWARF_H #define LLVM_BINARYFORMAT_DWARF_H +#include "llvm/ADT/Optional.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/FormatVariadicDetails.h" namespace llvm { class StringRef; @@ -57,6 +61,9 @@ enum LLVMConstants : uint32_t { DWARF_VENDOR_MIPS = 6 }; +/// Constants that define the DWARF format as 32 or 64 bit. +enum DwarfFormat : uint8_t { DWARF32, DWARF64 }; + /// Special ID values that distinguish a CIE from a FDE in DWARF CFI. /// Not inside an enum because a 64-bit value is needed. /// @{ @@ -125,7 +132,7 @@ enum LocationAtom { DW_OP_LLVM_fragment = 0x1000 ///< Only used in LLVM metadata. }; -enum TypeKind { +enum TypeKind : uint8_t { #define HANDLE_DW_ATE(ID, NAME, VERSION, VENDOR) DW_ATE_##NAME = ID, #include "llvm/BinaryFormat/Dwarf.def" DW_ATE_lo_user = 0x80, @@ -325,6 +332,13 @@ enum UnitType : unsigned char { DW_UT_hi_user = 0xff }; +enum Index { +#define HANDLE_DW_IDX(ID, NAME) DW_IDX_##NAME = ID, +#include "llvm/BinaryFormat/Dwarf.def" + DW_IDX_lo_user = 0x2000, + DW_IDX_hi_user = 0x3fff +}; + inline bool isUnitType(uint8_t UnitType) { switch (UnitType) { case DW_UT_compile: @@ -354,13 +368,16 @@ inline bool isUnitType(dwarf::Tag T) { // Constants for the DWARF v5 Accelerator Table Proposal enum AcceleratorTable { // Data layout descriptors. - DW_ATOM_null = 0u, // Marker as the end of a list of atoms. + DW_ATOM_null = 0u, /// Marker as the end of a list of atoms. DW_ATOM_die_offset = 1u, // DIE offset in the debug_info section. DW_ATOM_cu_offset = 2u, // Offset of the compile unit header that contains the // item in question. DW_ATOM_die_tag = 3u, // A tag entry. DW_ATOM_type_flags = 4u, // Set of flags for a type. + DW_ATOM_type_type_flags = 5u, // Dsymutil type extension. + DW_ATOM_qual_name_hash = 6u, // Dsymutil qualified hash extension. + // DW_ATOM_type_flags values. // Always set for C++, only set for ObjC if this is the @implementation for a @@ -390,8 +407,8 @@ enum GDBIndexEntryLinkage { GIEL_EXTERNAL, GIEL_STATIC }; /// \defgroup DwarfConstantsDumping Dwarf constants dumping functions /// /// All these functions map their argument's value back to the -/// corresponding enumerator name or return nullptr if the value isn't -/// known. +/// corresponding enumerator name or return an empty StringRef if the value +/// isn't known. /// /// @{ StringRef TagString(unsigned Tag); @@ -410,16 +427,17 @@ StringRef CaseString(unsigned Case); StringRef ConventionString(unsigned Convention); StringRef InlineCodeString(unsigned Code); StringRef ArrayOrderString(unsigned Order); -StringRef DiscriminantString(unsigned Discriminant); StringRef LNStandardString(unsigned Standard); StringRef LNExtendedString(unsigned Encoding); StringRef MacinfoString(unsigned Encoding); +StringRef RangeListEncodingString(unsigned Encoding); StringRef CallFrameString(unsigned Encoding); StringRef ApplePropertyString(unsigned); StringRef UnitTypeString(unsigned); StringRef AtomTypeString(unsigned Atom); StringRef GDBIndexEntryKindString(GDBIndexEntryKind Kind); StringRef GDBIndexEntryLinkageString(GDBIndexEntryLinkage Linkage); +StringRef IndexString(unsigned Idx); /// @} /// \defgroup DwarfConstantsParsing Dwarf constants parsing functions @@ -471,6 +489,49 @@ unsigned AttributeEncodingVendor(TypeKind E); unsigned LanguageVendor(SourceLanguage L); /// @} +/// A helper struct providing information about the byte size of DW_FORM +/// values that vary in size depending on the DWARF version, address byte +/// size, or DWARF32/DWARF64. +struct FormParams { + uint16_t Version; + uint8_t AddrSize; + DwarfFormat Format; + + /// The definition of the size of form DW_FORM_ref_addr depends on the + /// version. In DWARF v2 it's the size of an address; after that, it's the + /// size of a reference. + uint8_t getRefAddrByteSize() const { + if (Version == 2) + return AddrSize; + return getDwarfOffsetByteSize(); + } + + /// The size of a reference is determined by the DWARF 32/64-bit format. + uint8_t getDwarfOffsetByteSize() const { + switch (Format) { + case DwarfFormat::DWARF32: + return 4; + case DwarfFormat::DWARF64: + return 8; + } + llvm_unreachable("Invalid Format value"); + } + + explicit operator bool() const { return Version && AddrSize; } +}; + +/// Get the fixed byte size for a given form. +/// +/// If the form has a fixed byte size, then an Optional with a value will be +/// returned. If the form is always encoded using a variable length storage +/// format (ULEB or SLEB numbers or blocks) then None will be returned. +/// +/// \param Form DWARF form to get the fixed byte size for. +/// \param Params DWARF parameters to help interpret forms. +/// \returns Optional<uint8_t> value with the fixed byte size or None if +/// \p Form doesn't have a fixed byte size. +Optional<uint8_t> getFixedFormByteSize(dwarf::Form Form, FormParams Params); + /// Tells whether the specified form is defined in the specified version, /// or is an extension if extensions are allowed. bool isValidFormForVersion(Form F, unsigned Version, bool ExtensionsOk = true); @@ -479,6 +540,10 @@ bool isValidFormForVersion(Form F, unsigned Version, bool ExtensionsOk = true); /// for attribute Attr. StringRef AttributeValueString(uint16_t Attr, unsigned Val); +/// Returns the symbolic string representing Val when used as a value +/// for atom Atom. +StringRef AtomValueString(uint16_t Atom, unsigned Val); + /// Describes an entry of the various gnu_pub* debug sections. /// /// The gnu_pub* kind looks like: @@ -514,14 +579,46 @@ private: }; }; -/// Constants that define the DWARF format as 32 or 64 bit. -enum DwarfFormat : uint8_t { DWARF32, DWARF64 }; +template <typename Enum> struct EnumTraits : public std::false_type {}; + +template <> struct EnumTraits<Attribute> : public std::true_type { + static constexpr char Type[3] = "AT"; + static constexpr StringRef (*StringFn)(unsigned) = &AttributeString; +}; -/// The Bernstein hash function used by the accelerator tables. -uint32_t djbHash(StringRef Buffer); +template <> struct EnumTraits<Form> : public std::true_type { + static constexpr char Type[5] = "FORM"; + static constexpr StringRef (*StringFn)(unsigned) = &FormEncodingString; +}; + +template <> struct EnumTraits<Index> : public std::true_type { + static constexpr char Type[4] = "IDX"; + static constexpr StringRef (*StringFn)(unsigned) = &IndexString; +}; +template <> struct EnumTraits<Tag> : public std::true_type { + static constexpr char Type[4] = "TAG"; + static constexpr StringRef (*StringFn)(unsigned) = &TagString; +}; } // End of namespace dwarf +/// Dwarf constants format_provider +/// +/// Specialization of the format_provider template for dwarf enums. Unlike the +/// dumping functions above, these format unknown enumerator values as +/// DW_TYPE_unknown_1234 (e.g. DW_TAG_unknown_ffff). +template <typename Enum> +struct format_provider< + Enum, typename std::enable_if<dwarf::EnumTraits<Enum>::value>::type> { + static void format(const Enum &E, raw_ostream &OS, StringRef Style) { + StringRef Str = dwarf::EnumTraits<Enum>::StringFn(E); + if (Str.empty()) { + OS << "DW_" << dwarf::EnumTraits<Enum>::Type << "_unknown_" + << llvm::format("%x", E); + } else + OS << Str; + } +}; } // End of namespace llvm #endif diff --git a/include/llvm/BinaryFormat/DynamicTags.def b/include/llvm/BinaryFormat/DynamicTags.def new file mode 100644 index 000000000000..2e15cc30fca7 --- /dev/null +++ b/include/llvm/BinaryFormat/DynamicTags.def @@ -0,0 +1,216 @@ +#ifndef DYNAMIC_TAG +#error "DYNAMIC_TAG must be defined" +#endif + +// Add separate macros for the architecture specific tags and the markers +// such as DT_HIOS, etc. to allow using this file to in other contexts. +// For example we can use it to generate a stringification switch statement. + +#ifndef HEXAGON_DYNAMIC_TAG +#define HEXAGON_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value) +#define HEXAGON_DYNAMIC_TAG_DEFINED +#endif + +#ifndef MIPS_DYNAMIC_TAG +#define MIPS_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value) +#define MIPS_DYNAMIC_TAG_DEFINED +#endif + +#ifndef PPC64_DYNAMIC_TAG +#define PPC64_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value) +#define PPC64_DYNAMIC_TAG_DEFINED +#endif + +#ifndef DYNAMIC_TAG_MARKER +#define DYNAMIC_TAG_MARKER(name, value) DYNAMIC_TAG(name, value) +#define DYNAMIC_TAG_MARKER_DEFINED +#endif + +DYNAMIC_TAG(NULL, 0) // Marks end of dynamic array. +DYNAMIC_TAG(NEEDED, 1) // String table offset of needed library. +DYNAMIC_TAG(PLTRELSZ, 2) // Size of relocation entries in PLT. +DYNAMIC_TAG(PLTGOT, 3) // Address associated with linkage table. +DYNAMIC_TAG(HASH, 4) // Address of symbolic hash table. +DYNAMIC_TAG(STRTAB, 5) // Address of dynamic string table. +DYNAMIC_TAG(SYMTAB, 6) // Address of dynamic symbol table. +DYNAMIC_TAG(RELA, 7) // Address of relocation table (Rela entries). +DYNAMIC_TAG(RELASZ, 8) // Size of Rela relocation table. +DYNAMIC_TAG(RELAENT, 9) // Size of a Rela relocation entry. +DYNAMIC_TAG(STRSZ, 10) // Total size of the string table. +DYNAMIC_TAG(SYMENT, 11) // Size of a symbol table entry. +DYNAMIC_TAG(INIT, 12) // Address of initialization function. +DYNAMIC_TAG(FINI, 13) // Address of termination function. +DYNAMIC_TAG(SONAME, 14) // String table offset of a shared objects name. +DYNAMIC_TAG(RPATH, 15) // String table offset of library search path. +DYNAMIC_TAG(SYMBOLIC, 16) // Changes symbol resolution algorithm. +DYNAMIC_TAG(REL, 17) // Address of relocation table (Rel entries). +DYNAMIC_TAG(RELSZ, 18) // Size of Rel relocation table. +DYNAMIC_TAG(RELENT, 19) // Size of a Rel relocation entry. +DYNAMIC_TAG(PLTREL, 20) // Type of relocation entry used for linking. +DYNAMIC_TAG(DEBUG, 21) // Reserved for debugger. +DYNAMIC_TAG(TEXTREL, 22) // Relocations exist for non-writable segments. +DYNAMIC_TAG(JMPREL, 23) // Address of relocations associated with PLT. +DYNAMIC_TAG(BIND_NOW, 24) // Process all relocations before execution. +DYNAMIC_TAG(INIT_ARRAY, 25) // Pointer to array of initialization functions. +DYNAMIC_TAG(FINI_ARRAY, 26) // Pointer to array of termination functions. +DYNAMIC_TAG(INIT_ARRAYSZ, 27) // Size of DT_INIT_ARRAY. +DYNAMIC_TAG(FINI_ARRAYSZ, 28) // Size of DT_FINI_ARRAY. +DYNAMIC_TAG(RUNPATH, 29) // String table offset of lib search path. +DYNAMIC_TAG(FLAGS, 30) // Flags. +DYNAMIC_TAG_MARKER(ENCODING, 32) // Values from here to DT_LOOS follow the rules + // for the interpretation of the d_un union. + +DYNAMIC_TAG(PREINIT_ARRAY, 32) // Pointer to array of preinit functions. +DYNAMIC_TAG(PREINIT_ARRAYSZ, 33) // Size of the DT_PREINIT_ARRAY array. + +DYNAMIC_TAG(SYMTAB_SHNDX, 34) // Address of the SHT_SYMTAB_SHNDX section. + +// Experimental support for SHT_RELR sections. For details, see proposal +// at https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg +DYNAMIC_TAG(RELRSZ, 35) // Size of Relr relocation table. +DYNAMIC_TAG(RELR, 36) // Address of relocation table (Relr entries). +DYNAMIC_TAG(RELRENT, 37) // Size of a Relr relocation entry. + +DYNAMIC_TAG_MARKER(LOOS, 0x60000000) // Start of environment specific tags. +DYNAMIC_TAG_MARKER(HIOS, 0x6FFFFFFF) // End of environment specific tags. +DYNAMIC_TAG_MARKER(LOPROC, 0x70000000) // Start of processor specific tags. +DYNAMIC_TAG_MARKER(HIPROC, 0x7FFFFFFF) // End of processor specific tags. + +// Android packed relocation section tags. +// https://android.googlesource.com/platform/bionic/+/6f12bfece5dcc01325e0abba56a46b1bcf991c69/tools/relocation_packer/src/elf_file.cc#31 +DYNAMIC_TAG(ANDROID_REL, 0x6000000F) +DYNAMIC_TAG(ANDROID_RELSZ, 0x60000010) +DYNAMIC_TAG(ANDROID_RELA, 0x60000011) +DYNAMIC_TAG(ANDROID_RELASZ, 0x60000012) + +// Android's experimental support for SHT_RELR sections. +// https://android.googlesource.com/platform/bionic/+/b7feec74547f84559a1467aca02708ff61346d2a/libc/include/elf.h#253 +DYNAMIC_TAG(ANDROID_RELR, 0x6FFFE000) // Address of relocation table (Relr entries). +DYNAMIC_TAG(ANDROID_RELRSZ, 0x6FFFE001) // Size of Relr relocation table. +DYNAMIC_TAG(ANDROID_RELRENT, 0x6FFFE003) // Size of a Relr relocation entry. + +DYNAMIC_TAG(GNU_HASH, 0x6FFFFEF5) // Reference to the GNU hash table. +DYNAMIC_TAG(TLSDESC_PLT, 0x6FFFFEF6) // Location of PLT entry for TLS + // descriptor resolver calls. +DYNAMIC_TAG(TLSDESC_GOT, 0x6FFFFEF7) // Location of GOT entry used by TLS + // descriptor resolver PLT entry. +DYNAMIC_TAG(RELACOUNT, 0x6FFFFFF9) // ELF32_Rela count. +DYNAMIC_TAG(RELCOUNT, 0x6FFFFFFA) // ELF32_Rel count. + +DYNAMIC_TAG(FLAGS_1, 0X6FFFFFFB) // Flags_1. + +DYNAMIC_TAG(VERSYM, 0x6FFFFFF0) // The address of .gnu.version section. +DYNAMIC_TAG(VERDEF, 0X6FFFFFFC) // The address of the version definition + // table. +DYNAMIC_TAG(VERDEFNUM, 0X6FFFFFFD) // The number of entries in DT_VERDEF. +DYNAMIC_TAG(VERNEED, 0X6FFFFFFE) // The address of the version dependency + // table. +DYNAMIC_TAG(VERNEEDNUM, 0X6FFFFFFF) // The number of entries in DT_VERNEED. + +// Hexagon specific dynamic table entries +HEXAGON_DYNAMIC_TAG(HEXAGON_SYMSZ, 0x70000000) +HEXAGON_DYNAMIC_TAG(HEXAGON_VER, 0x70000001) +HEXAGON_DYNAMIC_TAG(HEXAGON_PLT, 0x70000002) + +// Mips specific dynamic table entry tags. + +MIPS_DYNAMIC_TAG(MIPS_RLD_VERSION, 0x70000001) // 32 bit version number for + // runtime linker interface. +MIPS_DYNAMIC_TAG(MIPS_TIME_STAMP, 0x70000002) // Time stamp. +MIPS_DYNAMIC_TAG(MIPS_ICHECKSUM, 0x70000003) // Checksum of external strings + // and common sizes. +MIPS_DYNAMIC_TAG(MIPS_IVERSION, 0x70000004) // Index of version string + // in string table. +MIPS_DYNAMIC_TAG(MIPS_FLAGS, 0x70000005) // 32 bits of flags. +MIPS_DYNAMIC_TAG(MIPS_BASE_ADDRESS, 0x70000006) // Base address of the segment. +MIPS_DYNAMIC_TAG(MIPS_MSYM, 0x70000007) // Address of .msym section. +MIPS_DYNAMIC_TAG(MIPS_CONFLICT, 0x70000008) // Address of .conflict section. +MIPS_DYNAMIC_TAG(MIPS_LIBLIST, 0x70000009) // Address of .liblist section. +MIPS_DYNAMIC_TAG(MIPS_LOCAL_GOTNO, 0x7000000a) // Number of local global offset + // table entries. +MIPS_DYNAMIC_TAG(MIPS_CONFLICTNO, 0x7000000b) // Number of entries + // in the .conflict section. +MIPS_DYNAMIC_TAG(MIPS_LIBLISTNO, 0x70000010) // Number of entries + // in the .liblist section. +MIPS_DYNAMIC_TAG(MIPS_SYMTABNO, 0x70000011) // Number of entries + // in the .dynsym section. +MIPS_DYNAMIC_TAG(MIPS_UNREFEXTNO, 0x70000012) // Index of first external dynamic + // symbol not referenced locally. +MIPS_DYNAMIC_TAG(MIPS_GOTSYM, 0x70000013) // Index of first dynamic symbol + // in global offset table. +MIPS_DYNAMIC_TAG(MIPS_HIPAGENO, 0x70000014) // Number of page table entries + // in global offset table. +MIPS_DYNAMIC_TAG(MIPS_RLD_MAP, 0x70000016) // Address of run time loader map + // used for debugging. +MIPS_DYNAMIC_TAG(MIPS_DELTA_CLASS, 0x70000017) // Delta C++ class definition. +MIPS_DYNAMIC_TAG(MIPS_DELTA_CLASS_NO, 0x70000018) // Number of entries + // in DT_MIPS_DELTA_CLASS. +MIPS_DYNAMIC_TAG(MIPS_DELTA_INSTANCE, 0x70000019) // Delta C++ class instances. +MIPS_DYNAMIC_TAG(MIPS_DELTA_INSTANCE_NO, 0x7000001A) // Number of entries + // in DT_MIPS_DELTA_INSTANCE. +MIPS_DYNAMIC_TAG(MIPS_DELTA_RELOC, 0x7000001B) // Delta relocations. +MIPS_DYNAMIC_TAG(MIPS_DELTA_RELOC_NO, 0x7000001C) // Number of entries + // in DT_MIPS_DELTA_RELOC. +MIPS_DYNAMIC_TAG(MIPS_DELTA_SYM, 0x7000001D) // Delta symbols that Delta + // relocations refer to. +MIPS_DYNAMIC_TAG(MIPS_DELTA_SYM_NO, 0x7000001E) // Number of entries + // in DT_MIPS_DELTA_SYM. +MIPS_DYNAMIC_TAG(MIPS_DELTA_CLASSSYM, 0x70000020) // Delta symbols that hold + // class declarations. +MIPS_DYNAMIC_TAG(MIPS_DELTA_CLASSSYM_NO, 0x70000021) // Number of entries + // in DT_MIPS_DELTA_CLASSSYM. + +MIPS_DYNAMIC_TAG(MIPS_CXX_FLAGS, 0x70000022) // Flags indicating information + // about C++ flavor. +MIPS_DYNAMIC_TAG(MIPS_PIXIE_INIT, 0x70000023) // Pixie information. +MIPS_DYNAMIC_TAG(MIPS_SYMBOL_LIB, 0x70000024) // Address of .MIPS.symlib +MIPS_DYNAMIC_TAG(MIPS_LOCALPAGE_GOTIDX, 0x70000025) // The GOT index of the first PTE + // for a segment +MIPS_DYNAMIC_TAG(MIPS_LOCAL_GOTIDX, 0x70000026) // The GOT index of the first PTE + // for a local symbol +MIPS_DYNAMIC_TAG(MIPS_HIDDEN_GOTIDX, 0x70000027) // The GOT index of the first PTE + // for a hidden symbol +MIPS_DYNAMIC_TAG(MIPS_PROTECTED_GOTIDX, 0x70000028) // The GOT index of the first PTE + // for a protected symbol +MIPS_DYNAMIC_TAG(MIPS_OPTIONS, 0x70000029) // Address of `.MIPS.options'. +MIPS_DYNAMIC_TAG(MIPS_INTERFACE, 0x7000002A) // Address of `.interface'. +MIPS_DYNAMIC_TAG(MIPS_DYNSTR_ALIGN, 0x7000002B) // Unknown. +MIPS_DYNAMIC_TAG(MIPS_INTERFACE_SIZE, 0x7000002C) // Size of the .interface section. +MIPS_DYNAMIC_TAG(MIPS_RLD_TEXT_RESOLVE_ADDR, 0x7000002D) // Size of rld_text_resolve + // function stored in the GOT. +MIPS_DYNAMIC_TAG(MIPS_PERF_SUFFIX, 0x7000002E) // Default suffix of DSO to be added + // by rld on dlopen() calls. +MIPS_DYNAMIC_TAG(MIPS_COMPACT_SIZE, 0x7000002F) // Size of compact relocation + // section (O32). +MIPS_DYNAMIC_TAG(MIPS_GP_VALUE, 0x70000030) // GP value for auxiliary GOTs. +MIPS_DYNAMIC_TAG(MIPS_AUX_DYNAMIC, 0x70000031) // Address of auxiliary .dynamic. +MIPS_DYNAMIC_TAG(MIPS_PLTGOT, 0x70000032) // Address of the base of the PLTGOT. +MIPS_DYNAMIC_TAG(MIPS_RWPLT, 0x70000034) // Points to the base + // of a writable PLT. +MIPS_DYNAMIC_TAG(MIPS_RLD_MAP_REL, 0x70000035) // Relative offset of run time loader + // map, used for debugging. + +// PPC64 specific dynamic table entries. +PPC64_DYNAMIC_TAG(PPC64_GLINK, 0x70000000) // Address of 32 bytes before the + // first glink lazy resolver stub. + +// Sun machine-independent extensions. +DYNAMIC_TAG(AUXILIARY, 0x7FFFFFFD) // Shared object to load before self +DYNAMIC_TAG(FILTER, 0x7FFFFFFF) // Shared object to get values from + + +#ifdef DYNAMIC_TAG_MARKER_DEFINED +#undef DYNAMIC_TAG_MARKER +#endif +#ifdef MIPS_DYNAMIC_TAG_DEFINED +#undef MIPS_DYNAMIC_TAG +#undef MIPS_DYNAMIC_TAG_DEFINED +#endif +#ifdef HEXAGON_DYNAMIC_TAG_DEFINED +#undef HEXAGON_DYNAMIC_TAG +#undef HEXAGON_DYNAMIC_TAG_DEFINED +#endif +#ifdef PPC64_DYNAMIC_TAG_DEFINED +#undef PPC64_DYNAMIC_TAG +#undef PPC64_DYNAMIC_TAG_DEFINED +#endif diff --git a/include/llvm/BinaryFormat/ELF.h b/include/llvm/BinaryFormat/ELF.h index c902972d93bd..0f3f1939ce68 100644 --- a/include/llvm/BinaryFormat/ELF.h +++ b/include/llvm/BinaryFormat/ELF.h @@ -312,11 +312,6 @@ enum { EM_RISCV = 243, // RISC-V EM_LANAI = 244, // Lanai 32-bit processor EM_BPF = 247, // Linux kernel bpf virtual machine - - // A request has been made to the maintainer of the official registry for - // such numbers for an official value for WebAssembly. As soon as one is - // allocated, this enum will be updated to use it. - EM_WEBASSEMBLY = 0x4157, // WebAssembly architecture }; // Object file classes. @@ -644,18 +639,78 @@ enum { #include "ELFRelocs/Sparc.def" }; -// ELF Relocation types for WebAssembly -enum { -#include "ELFRelocs/WebAssembly.def" -}; - // AMDGPU specific e_flags. enum : unsigned { - // AMDGPU machine architectures. - EF_AMDGPU_ARCH_NONE = 0x00000000, // None/unknown. - EF_AMDGPU_ARCH_R600 = 0x00000001, // AMD HD2XXX-HD6XXX GPUs. - EF_AMDGPU_ARCH_GCN = 0x00000002, // AMD GCN GFX6+ GPUs. - EF_AMDGPU_ARCH = 0x0000000f // EF_AMDGPU_ARCH_XXX selection mask. + // Processor selection mask for EF_AMDGPU_MACH_* values. + EF_AMDGPU_MACH = 0x0ff, + + // Not specified processor. + EF_AMDGPU_MACH_NONE = 0x000, + + // R600-based processors. + + // Radeon HD 2000/3000 Series (R600). + EF_AMDGPU_MACH_R600_R600 = 0x001, + EF_AMDGPU_MACH_R600_R630 = 0x002, + EF_AMDGPU_MACH_R600_RS880 = 0x003, + EF_AMDGPU_MACH_R600_RV670 = 0x004, + // Radeon HD 4000 Series (R700). + EF_AMDGPU_MACH_R600_RV710 = 0x005, + EF_AMDGPU_MACH_R600_RV730 = 0x006, + EF_AMDGPU_MACH_R600_RV770 = 0x007, + // Radeon HD 5000 Series (Evergreen). + EF_AMDGPU_MACH_R600_CEDAR = 0x008, + EF_AMDGPU_MACH_R600_CYPRESS = 0x009, + EF_AMDGPU_MACH_R600_JUNIPER = 0x00a, + EF_AMDGPU_MACH_R600_REDWOOD = 0x00b, + EF_AMDGPU_MACH_R600_SUMO = 0x00c, + // Radeon HD 6000 Series (Northern Islands). + EF_AMDGPU_MACH_R600_BARTS = 0x00d, + EF_AMDGPU_MACH_R600_CAICOS = 0x00e, + EF_AMDGPU_MACH_R600_CAYMAN = 0x00f, + EF_AMDGPU_MACH_R600_TURKS = 0x010, + + // Reserved for R600-based processors. + EF_AMDGPU_MACH_R600_RESERVED_FIRST = 0x011, + EF_AMDGPU_MACH_R600_RESERVED_LAST = 0x01f, + + // First/last R600-based processors. + EF_AMDGPU_MACH_R600_FIRST = EF_AMDGPU_MACH_R600_R600, + EF_AMDGPU_MACH_R600_LAST = EF_AMDGPU_MACH_R600_TURKS, + + // AMDGCN-based processors. + + // AMDGCN GFX6. + EF_AMDGPU_MACH_AMDGCN_GFX600 = 0x020, + EF_AMDGPU_MACH_AMDGCN_GFX601 = 0x021, + // AMDGCN GFX7. + EF_AMDGPU_MACH_AMDGCN_GFX700 = 0x022, + EF_AMDGPU_MACH_AMDGCN_GFX701 = 0x023, + EF_AMDGPU_MACH_AMDGCN_GFX702 = 0x024, + EF_AMDGPU_MACH_AMDGCN_GFX703 = 0x025, + EF_AMDGPU_MACH_AMDGCN_GFX704 = 0x026, + // AMDGCN GFX8. + EF_AMDGPU_MACH_AMDGCN_GFX801 = 0x028, + EF_AMDGPU_MACH_AMDGCN_GFX802 = 0x029, + EF_AMDGPU_MACH_AMDGCN_GFX803 = 0x02a, + EF_AMDGPU_MACH_AMDGCN_GFX810 = 0x02b, + // AMDGCN GFX9. + EF_AMDGPU_MACH_AMDGCN_GFX900 = 0x02c, + EF_AMDGPU_MACH_AMDGCN_GFX902 = 0x02d, + EF_AMDGPU_MACH_AMDGCN_GFX904 = 0x02e, + EF_AMDGPU_MACH_AMDGCN_GFX906 = 0x02f, + + // Reserved for AMDGCN-based processors. + EF_AMDGPU_MACH_AMDGCN_RESERVED0 = 0x027, + EF_AMDGPU_MACH_AMDGCN_RESERVED1 = 0x030, + + // First/last AMDGCN-based processors. + EF_AMDGPU_MACH_AMDGCN_FIRST = EF_AMDGPU_MACH_AMDGCN_GFX600, + EF_AMDGPU_MACH_AMDGCN_LAST = EF_AMDGPU_MACH_AMDGCN_GFX906, + + // Indicates if the xnack target feature is enabled for all code contained in + // the object. + EF_AMDGPU_XNACK = 0x100, }; // ELF Relocation types for AMDGPU @@ -714,36 +769,46 @@ enum { // Section types. enum : unsigned { - SHT_NULL = 0, // No associated section (inactive entry). - SHT_PROGBITS = 1, // Program-defined contents. - SHT_SYMTAB = 2, // Symbol table. - SHT_STRTAB = 3, // String table. - SHT_RELA = 4, // Relocation entries; explicit addends. - SHT_HASH = 5, // Symbol hash table. - SHT_DYNAMIC = 6, // Information for dynamic linking. - SHT_NOTE = 7, // Information about the file. - SHT_NOBITS = 8, // Data occupies no space in the file. - SHT_REL = 9, // Relocation entries; no explicit addends. - SHT_SHLIB = 10, // Reserved. - SHT_DYNSYM = 11, // Symbol table. - SHT_INIT_ARRAY = 14, // Pointers to initialization functions. - SHT_FINI_ARRAY = 15, // Pointers to termination functions. - SHT_PREINIT_ARRAY = 16, // Pointers to pre-init functions. - SHT_GROUP = 17, // Section group. - SHT_SYMTAB_SHNDX = 18, // Indices for SHN_XINDEX entries. - SHT_LOOS = 0x60000000, // Lowest operating system-specific type. + SHT_NULL = 0, // No associated section (inactive entry). + SHT_PROGBITS = 1, // Program-defined contents. + SHT_SYMTAB = 2, // Symbol table. + SHT_STRTAB = 3, // String table. + SHT_RELA = 4, // Relocation entries; explicit addends. + SHT_HASH = 5, // Symbol hash table. + SHT_DYNAMIC = 6, // Information for dynamic linking. + SHT_NOTE = 7, // Information about the file. + SHT_NOBITS = 8, // Data occupies no space in the file. + SHT_REL = 9, // Relocation entries; no explicit addends. + SHT_SHLIB = 10, // Reserved. + SHT_DYNSYM = 11, // Symbol table. + SHT_INIT_ARRAY = 14, // Pointers to initialization functions. + SHT_FINI_ARRAY = 15, // Pointers to termination functions. + SHT_PREINIT_ARRAY = 16, // Pointers to pre-init functions. + SHT_GROUP = 17, // Section group. + SHT_SYMTAB_SHNDX = 18, // Indices for SHN_XINDEX entries. + // Experimental support for SHT_RELR sections. For details, see proposal + // at https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg + SHT_RELR = 19, // Relocation entries; only offsets. + SHT_LOOS = 0x60000000, // Lowest operating system-specific type. // Android packed relocation section types. // https://android.googlesource.com/platform/bionic/+/6f12bfece5dcc01325e0abba56a46b1bcf991c69/tools/relocation_packer/src/elf_file.cc#37 SHT_ANDROID_REL = 0x60000001, SHT_ANDROID_RELA = 0x60000002, - SHT_LLVM_ODRTAB = 0x6fff4c00, // LLVM ODR table. - SHT_GNU_ATTRIBUTES = 0x6ffffff5, // Object attributes. - SHT_GNU_HASH = 0x6ffffff6, // GNU-style hash table. - SHT_GNU_verdef = 0x6ffffffd, // GNU version definitions. - SHT_GNU_verneed = 0x6ffffffe, // GNU version references. - SHT_GNU_versym = 0x6fffffff, // GNU symbol versions table. - SHT_HIOS = 0x6fffffff, // Highest operating system-specific type. - SHT_LOPROC = 0x70000000, // Lowest processor arch-specific type. + SHT_LLVM_ODRTAB = 0x6fff4c00, // LLVM ODR table. + SHT_LLVM_LINKER_OPTIONS = 0x6fff4c01, // LLVM Linker Options. + SHT_LLVM_CALL_GRAPH_PROFILE = 0x6fff4c02, // LLVM Call Graph Profile. + SHT_LLVM_ADDRSIG = 0x6fff4c03, // List of address-significant symbols + // for safe ICF. + // Android's experimental support for SHT_RELR sections. + // https://android.googlesource.com/platform/bionic/+/b7feec74547f84559a1467aca02708ff61346d2a/libc/include/elf.h#512 + SHT_ANDROID_RELR = 0x6fffff00, // Relocation entries; only offsets. + SHT_GNU_ATTRIBUTES = 0x6ffffff5, // Object attributes. + SHT_GNU_HASH = 0x6ffffff6, // GNU-style hash table. + SHT_GNU_verdef = 0x6ffffffd, // GNU version definitions. + SHT_GNU_verneed = 0x6ffffffe, // GNU version references. + SHT_GNU_versym = 0x6fffffff, // GNU symbol versions table. + SHT_HIOS = 0x6fffffff, // Highest operating system-specific type. + SHT_LOPROC = 0x70000000, // Lowest processor arch-specific type. // Fixme: All this is duplicated in MCSectionELF. Why?? // Exception Index table SHT_ARM_EXIDX = 0x70000001U, @@ -753,18 +818,18 @@ enum : unsigned { SHT_ARM_ATTRIBUTES = 0x70000003U, SHT_ARM_DEBUGOVERLAY = 0x70000004U, SHT_ARM_OVERLAYSECTION = 0x70000005U, - SHT_HEX_ORDERED = 0x70000000, // Link editor is to sort the entries in - // this section based on their sizes - SHT_X86_64_UNWIND = 0x70000001, // Unwind information + SHT_HEX_ORDERED = 0x70000000, // Link editor is to sort the entries in + // this section based on their sizes + SHT_X86_64_UNWIND = 0x70000001, // Unwind information - SHT_MIPS_REGINFO = 0x70000006, // Register usage information - SHT_MIPS_OPTIONS = 0x7000000d, // General options - SHT_MIPS_DWARF = 0x7000001e, // DWARF debugging section. - SHT_MIPS_ABIFLAGS = 0x7000002a, // ABI information. + SHT_MIPS_REGINFO = 0x70000006, // Register usage information + SHT_MIPS_OPTIONS = 0x7000000d, // General options + SHT_MIPS_DWARF = 0x7000001e, // DWARF debugging section. + SHT_MIPS_ABIFLAGS = 0x7000002a, // ABI information. - SHT_HIPROC = 0x7fffffff, // Highest processor arch-specific type. - SHT_LOUSER = 0x80000000, // Lowest type reserved for applications. - SHT_HIUSER = 0xffffffff // Highest type reserved for applications. + SHT_HIPROC = 0x7fffffff, // Highest processor arch-specific type. + SHT_LOUSER = 0x80000000, // Lowest type reserved for applications. + SHT_HIUSER = 0xffffffff // Highest type reserved for applications. }; // Section flags. @@ -1000,6 +1065,9 @@ struct Elf32_Rela { } }; +// Relocation entry without explicit addend or info (relative relocations only). +typedef Elf32_Word Elf32_Relr; // offset/bitmap for relative relocations + // Relocation entry, without explicit addend. struct Elf64_Rel { Elf64_Addr r_offset; // Location (file byte offset, or program virtual addr). @@ -1033,6 +1101,9 @@ struct Elf64_Rela { } }; +// Relocation entry without explicit addend or info (relative relocations only). +typedef Elf64_Xword Elf64_Relr; // offset/bitmap for relative relocations + // Program header for ELF32. struct Elf32_Phdr { Elf32_Word p_type; // Type of segment @@ -1096,9 +1167,6 @@ enum { PT_MIPS_RTPROC = 0x70000001, // Runtime procedure table. PT_MIPS_OPTIONS = 0x70000002, // Options segment. PT_MIPS_ABIFLAGS = 0x70000003, // Abiflags segment. - - // WebAssembly program header types. - PT_WEBASSEMBLY_FUNCTIONS = PT_LOPROC + 0, // Function definitions. }; // Segment flag bits. @@ -1130,154 +1198,9 @@ struct Elf64_Dyn { // Dynamic table entry tags. enum { - DT_NULL = 0, // Marks end of dynamic array. - DT_NEEDED = 1, // String table offset of needed library. - DT_PLTRELSZ = 2, // Size of relocation entries in PLT. - DT_PLTGOT = 3, // Address associated with linkage table. - DT_HASH = 4, // Address of symbolic hash table. - DT_STRTAB = 5, // Address of dynamic string table. - DT_SYMTAB = 6, // Address of dynamic symbol table. - DT_RELA = 7, // Address of relocation table (Rela entries). - DT_RELASZ = 8, // Size of Rela relocation table. - DT_RELAENT = 9, // Size of a Rela relocation entry. - DT_STRSZ = 10, // Total size of the string table. - DT_SYMENT = 11, // Size of a symbol table entry. - DT_INIT = 12, // Address of initialization function. - DT_FINI = 13, // Address of termination function. - DT_SONAME = 14, // String table offset of a shared objects name. - DT_RPATH = 15, // String table offset of library search path. - DT_SYMBOLIC = 16, // Changes symbol resolution algorithm. - DT_REL = 17, // Address of relocation table (Rel entries). - DT_RELSZ = 18, // Size of Rel relocation table. - DT_RELENT = 19, // Size of a Rel relocation entry. - DT_PLTREL = 20, // Type of relocation entry used for linking. - DT_DEBUG = 21, // Reserved for debugger. - DT_TEXTREL = 22, // Relocations exist for non-writable segments. - DT_JMPREL = 23, // Address of relocations associated with PLT. - DT_BIND_NOW = 24, // Process all relocations before execution. - DT_INIT_ARRAY = 25, // Pointer to array of initialization functions. - DT_FINI_ARRAY = 26, // Pointer to array of termination functions. - DT_INIT_ARRAYSZ = 27, // Size of DT_INIT_ARRAY. - DT_FINI_ARRAYSZ = 28, // Size of DT_FINI_ARRAY. - DT_RUNPATH = 29, // String table offset of lib search path. - DT_FLAGS = 30, // Flags. - DT_ENCODING = 32, // Values from here to DT_LOOS follow the rules - // for the interpretation of the d_un union. - - DT_PREINIT_ARRAY = 32, // Pointer to array of preinit functions. - DT_PREINIT_ARRAYSZ = 33, // Size of the DT_PREINIT_ARRAY array. - - DT_LOOS = 0x60000000, // Start of environment specific tags. - DT_HIOS = 0x6FFFFFFF, // End of environment specific tags. - DT_LOPROC = 0x70000000, // Start of processor specific tags. - DT_HIPROC = 0x7FFFFFFF, // End of processor specific tags. - - // Android packed relocation section tags. - // https://android.googlesource.com/platform/bionic/+/6f12bfece5dcc01325e0abba56a46b1bcf991c69/tools/relocation_packer/src/elf_file.cc#31 - DT_ANDROID_REL = 0x6000000F, - DT_ANDROID_RELSZ = 0x60000010, - DT_ANDROID_RELA = 0x60000011, - DT_ANDROID_RELASZ = 0x60000012, - - DT_GNU_HASH = 0x6FFFFEF5, // Reference to the GNU hash table. - DT_TLSDESC_PLT = - 0x6FFFFEF6, // Location of PLT entry for TLS descriptor resolver calls. - DT_TLSDESC_GOT = 0x6FFFFEF7, // Location of GOT entry used by TLS descriptor - // resolver PLT entry. - DT_RELACOUNT = 0x6FFFFFF9, // ELF32_Rela count. - DT_RELCOUNT = 0x6FFFFFFA, // ELF32_Rel count. - - DT_FLAGS_1 = 0X6FFFFFFB, // Flags_1. - DT_VERSYM = 0x6FFFFFF0, // The address of .gnu.version section. - DT_VERDEF = 0X6FFFFFFC, // The address of the version definition table. - DT_VERDEFNUM = 0X6FFFFFFD, // The number of entries in DT_VERDEF. - DT_VERNEED = 0X6FFFFFFE, // The address of the version Dependency table. - DT_VERNEEDNUM = 0X6FFFFFFF, // The number of entries in DT_VERNEED. - - // Hexagon specific dynamic table entries - DT_HEXAGON_SYMSZ = 0x70000000, - DT_HEXAGON_VER = 0x70000001, - DT_HEXAGON_PLT = 0x70000002, - - // Mips specific dynamic table entry tags. - DT_MIPS_RLD_VERSION = 0x70000001, // 32 bit version number for runtime - // linker interface. - DT_MIPS_TIME_STAMP = 0x70000002, // Time stamp. - DT_MIPS_ICHECKSUM = 0x70000003, // Checksum of external strings - // and common sizes. - DT_MIPS_IVERSION = 0x70000004, // Index of version string - // in string table. - DT_MIPS_FLAGS = 0x70000005, // 32 bits of flags. - DT_MIPS_BASE_ADDRESS = 0x70000006, // Base address of the segment. - DT_MIPS_MSYM = 0x70000007, // Address of .msym section. - DT_MIPS_CONFLICT = 0x70000008, // Address of .conflict section. - DT_MIPS_LIBLIST = 0x70000009, // Address of .liblist section. - DT_MIPS_LOCAL_GOTNO = 0x7000000a, // Number of local global offset - // table entries. - DT_MIPS_CONFLICTNO = 0x7000000b, // Number of entries - // in the .conflict section. - DT_MIPS_LIBLISTNO = 0x70000010, // Number of entries - // in the .liblist section. - DT_MIPS_SYMTABNO = 0x70000011, // Number of entries - // in the .dynsym section. - DT_MIPS_UNREFEXTNO = 0x70000012, // Index of first external dynamic symbol - // not referenced locally. - DT_MIPS_GOTSYM = 0x70000013, // Index of first dynamic symbol - // in global offset table. - DT_MIPS_HIPAGENO = 0x70000014, // Number of page table entries - // in global offset table. - DT_MIPS_RLD_MAP = 0x70000016, // Address of run time loader map, - // used for debugging. - DT_MIPS_DELTA_CLASS = 0x70000017, // Delta C++ class definition. - DT_MIPS_DELTA_CLASS_NO = 0x70000018, // Number of entries - // in DT_MIPS_DELTA_CLASS. - DT_MIPS_DELTA_INSTANCE = 0x70000019, // Delta C++ class instances. - DT_MIPS_DELTA_INSTANCE_NO = 0x7000001A, // Number of entries - // in DT_MIPS_DELTA_INSTANCE. - DT_MIPS_DELTA_RELOC = 0x7000001B, // Delta relocations. - DT_MIPS_DELTA_RELOC_NO = 0x7000001C, // Number of entries - // in DT_MIPS_DELTA_RELOC. - DT_MIPS_DELTA_SYM = 0x7000001D, // Delta symbols that Delta - // relocations refer to. - DT_MIPS_DELTA_SYM_NO = 0x7000001E, // Number of entries - // in DT_MIPS_DELTA_SYM. - DT_MIPS_DELTA_CLASSSYM = 0x70000020, // Delta symbols that hold - // class declarations. - DT_MIPS_DELTA_CLASSSYM_NO = 0x70000021, // Number of entries - // in DT_MIPS_DELTA_CLASSSYM. - DT_MIPS_CXX_FLAGS = 0x70000022, // Flags indicating information - // about C++ flavor. - DT_MIPS_PIXIE_INIT = 0x70000023, // Pixie information. - DT_MIPS_SYMBOL_LIB = 0x70000024, // Address of .MIPS.symlib - DT_MIPS_LOCALPAGE_GOTIDX = 0x70000025, // The GOT index of the first PTE - // for a segment - DT_MIPS_LOCAL_GOTIDX = 0x70000026, // The GOT index of the first PTE - // for a local symbol - DT_MIPS_HIDDEN_GOTIDX = 0x70000027, // The GOT index of the first PTE - // for a hidden symbol - DT_MIPS_PROTECTED_GOTIDX = 0x70000028, // The GOT index of the first PTE - // for a protected symbol - DT_MIPS_OPTIONS = 0x70000029, // Address of `.MIPS.options'. - DT_MIPS_INTERFACE = 0x7000002A, // Address of `.interface'. - DT_MIPS_DYNSTR_ALIGN = 0x7000002B, // Unknown. - DT_MIPS_INTERFACE_SIZE = 0x7000002C, // Size of the .interface section. - DT_MIPS_RLD_TEXT_RESOLVE_ADDR = 0x7000002D, // Size of rld_text_resolve - // function stored in the GOT. - DT_MIPS_PERF_SUFFIX = 0x7000002E, // Default suffix of DSO to be added - // by rld on dlopen() calls. - DT_MIPS_COMPACT_SIZE = 0x7000002F, // Size of compact relocation - // section (O32). - DT_MIPS_GP_VALUE = 0x70000030, // GP value for auxiliary GOTs. - DT_MIPS_AUX_DYNAMIC = 0x70000031, // Address of auxiliary .dynamic. - DT_MIPS_PLTGOT = 0x70000032, // Address of the base of the PLTGOT. - DT_MIPS_RWPLT = 0x70000034, // Points to the base - // of a writable PLT. - DT_MIPS_RLD_MAP_REL = 0x70000035, // Relative offset of run time loader - // map, used for debugging. - - // Sun machine-independent extensions. - DT_AUXILIARY = 0x7FFFFFFD, // Shared object to load before self - DT_FILTER = 0x7FFFFFFF // Shared object to get values from +#define DYNAMIC_TAG(name, value) DT_##name = value, +#include "DynamicTags.def" +#undef DYNAMIC_TAG }; // DT_FLAGS values. @@ -1380,6 +1303,20 @@ enum { NT_GNU_HWCAP = 2, NT_GNU_BUILD_ID = 3, NT_GNU_GOLD_VERSION = 4, + NT_GNU_PROPERTY_TYPE_0 = 5, +}; + +// Property types used in GNU_PROPERTY_TYPE_0 notes. +enum : unsigned { + GNU_PROPERTY_STACK_SIZE = 1, + GNU_PROPERTY_NO_COPY_ON_PROTECTED = 2, + GNU_PROPERTY_X86_FEATURE_1_AND = 0xc0000002 +}; + +// CET properties +enum { + GNU_PROPERTY_X86_FEATURE_1_IBT = 1 << 0, + GNU_PROPERTY_X86_FEATURE_1_SHSTK = 1 << 1 }; // AMDGPU specific notes. @@ -1423,6 +1360,20 @@ struct Elf64_Chdr { Elf64_Xword ch_addralign; }; +// Node header for ELF32. +struct Elf32_Nhdr { + Elf32_Word n_namesz; + Elf32_Word n_descsz; + Elf32_Word n_type; +}; + +// Node header for ELF64. +struct Elf64_Nhdr { + Elf64_Word n_namesz; + Elf64_Word n_descsz; + Elf64_Word n_type; +}; + // Legal values for ch_type field of compressed section header. enum { ELFCOMPRESS_ZLIB = 1, // ZLIB/DEFLATE algorithm. diff --git a/include/llvm/BinaryFormat/ELFRelocs/PowerPC64.def b/include/llvm/BinaryFormat/ELFRelocs/PowerPC64.def index 3a47c5a07574..8c5b482f0511 100644 --- a/include/llvm/BinaryFormat/ELFRelocs/PowerPC64.def +++ b/include/llvm/BinaryFormat/ELFRelocs/PowerPC64.def @@ -89,6 +89,13 @@ #undef R_PPC64_DTPREL16_HIGHESTA #undef R_PPC64_TLSGD #undef R_PPC64_TLSLD +#undef R_PPC64_ADDR16_HIGH +#undef R_PPC64_ADDR16_HIGHA +#undef R_PPC64_TPREL16_HIGH +#undef R_PPC64_TPREL16_HIGHA +#undef R_PPC64_DTPREL16_HIGH +#undef R_PPC64_DTPREL16_HIGHA +#undef R_PPC64_IRELATIVE #undef R_PPC64_REL16 #undef R_PPC64_REL16_LO #undef R_PPC64_REL16_HI @@ -175,6 +182,13 @@ ELF_RELOC(R_PPC64_DTPREL16_HIGHEST, 105) ELF_RELOC(R_PPC64_DTPREL16_HIGHESTA, 106) ELF_RELOC(R_PPC64_TLSGD, 107) ELF_RELOC(R_PPC64_TLSLD, 108) +ELF_RELOC(R_PPC64_ADDR16_HIGH, 110) +ELF_RELOC(R_PPC64_ADDR16_HIGHA, 111) +ELF_RELOC(R_PPC64_TPREL16_HIGH, 112) +ELF_RELOC(R_PPC64_TPREL16_HIGHA, 113) +ELF_RELOC(R_PPC64_DTPREL16_HIGH, 114) +ELF_RELOC(R_PPC64_DTPREL16_HIGHA, 115) +ELF_RELOC(R_PPC64_IRELATIVE, 248) ELF_RELOC(R_PPC64_REL16, 249) ELF_RELOC(R_PPC64_REL16_LO, 250) ELF_RELOC(R_PPC64_REL16_HI, 251) diff --git a/include/llvm/BinaryFormat/ELFRelocs/WebAssembly.def b/include/llvm/BinaryFormat/ELFRelocs/WebAssembly.def deleted file mode 100644 index 9a34349efb96..000000000000 --- a/include/llvm/BinaryFormat/ELFRelocs/WebAssembly.def +++ /dev/null @@ -1,8 +0,0 @@ - -#ifndef ELF_RELOC -#error "ELF_RELOC must be defined" -#endif - -ELF_RELOC(R_WEBASSEMBLY_NONE, 0) -ELF_RELOC(R_WEBASSEMBLY_DATA, 1) -ELF_RELOC(R_WEBASSEMBLY_FUNCTION, 2) diff --git a/include/llvm/BinaryFormat/MachO.h b/include/llvm/BinaryFormat/MachO.h index 060fbe162ad2..c5294c76ebf7 100644 --- a/include/llvm/BinaryFormat/MachO.h +++ b/include/llvm/BinaryFormat/MachO.h @@ -1973,9 +1973,11 @@ const uint32_t PPC_THREAD_STATE_COUNT = // Define a union of all load command structs #define LOAD_COMMAND_STRUCT(LCStruct) LCStruct LCStruct##_data; -union macho_load_command { +LLVM_PACKED_START +union alignas(4) macho_load_command { #include "llvm/BinaryFormat/MachO.def" }; +LLVM_PACKED_END } // end namespace MachO } // end namespace llvm diff --git a/include/llvm/BinaryFormat/Magic.h b/include/llvm/BinaryFormat/Magic.h index c0e23db5e1ae..04801f810be3 100644 --- a/include/llvm/BinaryFormat/Magic.h +++ b/include/llvm/BinaryFormat/Magic.h @@ -45,7 +45,8 @@ struct file_magic { coff_import_library, ///< COFF import library pecoff_executable, ///< PECOFF executable file windows_resource, ///< Windows compiled resource file (.res) - wasm_object ///< WebAssembly Object file + wasm_object, ///< WebAssembly Object file + pdb, ///< Windows PDB debug info file }; bool is_object() const { return V != unknown; } @@ -58,10 +59,10 @@ private: Impl V = unknown; }; -/// @brief Identify the type of a binary file based on how magical it is. +/// Identify the type of a binary file based on how magical it is. file_magic identify_magic(StringRef magic); -/// @brief Get and identify \a path's type based on its content. +/// Get and identify \a path's type based on its content. /// /// @param path Input path. /// @param result Set to the type of file, or file_magic::unknown. diff --git a/include/llvm/BinaryFormat/Wasm.h b/include/llvm/BinaryFormat/Wasm.h index 57a0b441821b..fa5448dacec4 100644 --- a/include/llvm/BinaryFormat/Wasm.h +++ b/include/llvm/BinaryFormat/Wasm.h @@ -24,6 +24,8 @@ namespace wasm { const char WasmMagic[] = {'\0', 'a', 's', 'm'}; // Wasm binary format version const uint32_t WasmVersion = 0x1; +// Wasm linking metadata version +const uint32_t WasmMetadataVersion = 0x1; // Wasm uses a 64k page size const uint32_t WasmPageSize = 65536; @@ -33,24 +35,24 @@ struct WasmObjectHeader { }; struct WasmSignature { - std::vector<int32_t> ParamTypes; - int32_t ReturnType; + std::vector<uint8_t> ParamTypes; + uint8_t ReturnType; }; struct WasmExport { StringRef Name; - uint32_t Kind; + uint8_t Kind; uint32_t Index; }; struct WasmLimits { - uint32_t Flags; + uint8_t Flags; uint32_t Initial; uint32_t Maximum; }; struct WasmTable { - int32_t ElemType; + uint8_t ElemType; WasmLimits Limits; }; @@ -65,43 +67,55 @@ struct WasmInitExpr { } Value; }; -struct WasmGlobal { - int32_t Type; +struct WasmGlobalType { + uint8_t Type; bool Mutable; +}; + +struct WasmGlobal { + uint32_t Index; + WasmGlobalType Type; WasmInitExpr InitExpr; + StringRef SymbolName; // from the "linking" section }; struct WasmImport { StringRef Module; StringRef Field; - uint32_t Kind; + uint8_t Kind; union { uint32_t SigIndex; - WasmGlobal Global; + WasmGlobalType Global; WasmTable Table; WasmLimits Memory; }; }; struct WasmLocalDecl { - int32_t Type; + uint8_t Type; uint32_t Count; }; struct WasmFunction { + uint32_t Index; std::vector<WasmLocalDecl> Locals; ArrayRef<uint8_t> Body; uint32_t CodeSectionOffset; uint32_t Size; + uint32_t CodeOffset; // start of Locals and Body + StringRef SymbolName; // from the "linking" section + StringRef DebugName; // from the "name" section + uint32_t Comdat; // from the "comdat info" section }; struct WasmDataSegment { uint32_t MemoryIndex; WasmInitExpr Offset; ArrayRef<uint8_t> Content; - StringRef Name; + StringRef Name; // from the "segment info" section uint32_t Alignment; uint32_t Flags; + uint32_t Comdat; // from the "comdat info" section }; struct WasmElemSegment { @@ -110,21 +124,50 @@ struct WasmElemSegment { std::vector<uint32_t> Functions; }; +// Represents the location of a Wasm data symbol within a WasmDataSegment, as +// the index of the segment, and the offset and size within the segment. +struct WasmDataReference { + uint32_t Segment; + uint32_t Offset; + uint32_t Size; +}; + struct WasmRelocation { - uint32_t Type; // The type of the relocation. - uint32_t Index; // Index into function to global index space. + uint8_t Type; // The type of the relocation. + uint32_t Index; // Index into either symbol or type index space. uint64_t Offset; // Offset from the start of the section. int64_t Addend; // A value to add to the symbol. }; struct WasmInitFunc { uint32_t Priority; - uint32_t FunctionIndex; + uint32_t Symbol; +}; + +struct WasmSymbolInfo { + StringRef Name; + uint8_t Kind; + uint32_t Flags; + StringRef Module; // For undefined symbols the module name of the import + union { + // For function or global symbols, the index in function or global index + // space. + uint32_t ElementIndex; + // For a data symbols, the address of the data relative to segment. + WasmDataReference DataRef; + }; +}; + +struct WasmFunctionName { + uint32_t Index; + StringRef Name; }; struct WasmLinkingData { - uint32_t DataSize; + uint32_t Version; std::vector<WasmInitFunc> InitFunctions; + std::vector<StringRef> Comdats; + std::vector<WasmSymbolInfo> SymbolTable; }; enum : unsigned { @@ -143,14 +186,15 @@ enum : unsigned { }; // Type immediate encodings used in various contexts. -enum { - WASM_TYPE_I32 = -0x01, - WASM_TYPE_I64 = -0x02, - WASM_TYPE_F32 = -0x03, - WASM_TYPE_F64 = -0x04, - WASM_TYPE_ANYFUNC = -0x10, - WASM_TYPE_FUNC = -0x20, - WASM_TYPE_NORESULT = -0x40, // for blocks with no result values +enum : unsigned { + WASM_TYPE_I32 = 0x7F, + WASM_TYPE_I64 = 0x7E, + WASM_TYPE_F32 = 0x7D, + WASM_TYPE_F64 = 0x7C, + WASM_TYPE_ANYFUNC = 0x70, + WASM_TYPE_EXCEPT_REF = 0x68, + WASM_TYPE_FUNC = 0x60, + WASM_TYPE_NORESULT = 0x40, // for blocks with no result values }; // Kinds of externals (for imports and exports). @@ -172,11 +216,6 @@ enum : unsigned { }; enum : unsigned { - WASM_NAMES_FUNCTION = 0x1, - WASM_NAMES_LOCAL = 0x2, -}; - -enum : unsigned { WASM_LIMITS_FLAG_HAS_MAX = 0x1, }; @@ -186,24 +225,46 @@ enum class ValType { I64 = WASM_TYPE_I64, F32 = WASM_TYPE_F32, F64 = WASM_TYPE_F64, + EXCEPT_REF = WASM_TYPE_EXCEPT_REF, +}; + +// Kind codes used in the custom "name" section +enum : unsigned { + WASM_NAMES_FUNCTION = 0x1, + WASM_NAMES_LOCAL = 0x2, }; -// Linking metadata kinds. +// Kind codes used in the custom "linking" section enum : unsigned { - WASM_SYMBOL_INFO = 0x2, - WASM_DATA_SIZE = 0x3, WASM_SEGMENT_INFO = 0x5, WASM_INIT_FUNCS = 0x6, + WASM_COMDAT_INFO = 0x7, + WASM_SYMBOL_TABLE = 0x8, +}; + +// Kind codes used in the custom "linking" section in the WASM_COMDAT_INFO +enum : unsigned { + WASM_COMDAT_DATA = 0x0, + WASM_COMDAT_FUNCTION = 0x1, +}; + +// Kind codes used in the custom "linking" section in the WASM_SYMBOL_TABLE +enum WasmSymbolType : unsigned { + WASM_SYMBOL_TYPE_FUNCTION = 0x0, + WASM_SYMBOL_TYPE_DATA = 0x1, + WASM_SYMBOL_TYPE_GLOBAL = 0x2, + WASM_SYMBOL_TYPE_SECTION = 0x3, }; const unsigned WASM_SYMBOL_BINDING_MASK = 0x3; -const unsigned WASM_SYMBOL_VISIBILITY_MASK = 0x4; +const unsigned WASM_SYMBOL_VISIBILITY_MASK = 0xc; const unsigned WASM_SYMBOL_BINDING_GLOBAL = 0x0; const unsigned WASM_SYMBOL_BINDING_WEAK = 0x1; const unsigned WASM_SYMBOL_BINDING_LOCAL = 0x2; const unsigned WASM_SYMBOL_VISIBILITY_DEFAULT = 0x0; const unsigned WASM_SYMBOL_VISIBILITY_HIDDEN = 0x4; +const unsigned WASM_SYMBOL_UNDEFINED = 0x10; #define WASM_RELOC(name, value) name = value, @@ -213,18 +274,25 @@ enum : unsigned { #undef WASM_RELOC -struct Global { - ValType Type; - bool Mutable; +// Useful comparison operators +inline bool operator==(const WasmSignature &LHS, const WasmSignature &RHS) { + return LHS.ReturnType == RHS.ReturnType && LHS.ParamTypes == RHS.ParamTypes; +} - // The initial value for this global is either the value of an imported - // global, in which case InitialModule and InitialName specify the global - // import, or a value, in which case InitialModule is empty and InitialValue - // holds the value. - StringRef InitialModule; - StringRef InitialName; - uint64_t InitialValue; -}; +inline bool operator!=(const WasmSignature &LHS, const WasmSignature &RHS) { + return !(LHS == RHS); +} + +inline bool operator==(const WasmGlobalType &LHS, const WasmGlobalType &RHS) { + return LHS.Type == RHS.Type && LHS.Mutable == RHS.Mutable; +} + +inline bool operator!=(const WasmGlobalType &LHS, const WasmGlobalType &RHS) { + return !(LHS == RHS); +} + +std::string toString(wasm::WasmSymbolType type); +std::string relocTypetoString(uint32_t type); } // end namespace wasm } // end namespace llvm diff --git a/include/llvm/BinaryFormat/WasmRelocs.def b/include/llvm/BinaryFormat/WasmRelocs.def index d6f0e42b33bf..8ffd51e483f3 100644 --- a/include/llvm/BinaryFormat/WasmRelocs.def +++ b/include/llvm/BinaryFormat/WasmRelocs.def @@ -11,3 +11,5 @@ WASM_RELOC(R_WEBASSEMBLY_MEMORY_ADDR_SLEB, 4) WASM_RELOC(R_WEBASSEMBLY_MEMORY_ADDR_I32, 5) WASM_RELOC(R_WEBASSEMBLY_TYPE_INDEX_LEB, 6) WASM_RELOC(R_WEBASSEMBLY_GLOBAL_INDEX_LEB, 7) +WASM_RELOC(R_WEBASSEMBLY_FUNCTION_OFFSET_I32, 8) +WASM_RELOC(R_WEBASSEMBLY_SECTION_OFFSET_I32, 9) |