Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:21

0001 //===- MachOYAML.h - Mach-O YAMLIO implementation ---------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 ///
0009 /// \file
0010 /// This file declares classes for handling the YAML representation
0011 /// of Mach-O.
0012 ///
0013 //===----------------------------------------------------------------------===//
0014 
0015 #ifndef LLVM_OBJECTYAML_MACHOYAML_H
0016 #define LLVM_OBJECTYAML_MACHOYAML_H
0017 
0018 #include "llvm/ADT/StringRef.h"
0019 #include "llvm/BinaryFormat/MachO.h"
0020 #include "llvm/ObjectYAML/DWARFYAML.h"
0021 #include "llvm/ObjectYAML/YAML.h"
0022 #include "llvm/Support/YAMLTraits.h"
0023 #include <cstdint>
0024 #include <optional>
0025 #include <string>
0026 #include <vector>
0027 
0028 namespace llvm {
0029 namespace MachOYAML {
0030 
0031 struct Relocation {
0032   // Offset in the section to what is being relocated.
0033   llvm::yaml::Hex32 address;
0034   // Symbol index if r_extern == 1 else section index.
0035   uint32_t symbolnum;
0036   bool is_pcrel;
0037   // Real length = 2 ^ length.
0038   uint8_t length;
0039   bool is_extern;
0040   uint8_t type;
0041   bool is_scattered;
0042   int32_t value;
0043 };
0044 
0045 struct Section {
0046   char sectname[16];
0047   char segname[16];
0048   llvm::yaml::Hex64 addr;
0049   uint64_t size;
0050   llvm::yaml::Hex32 offset;
0051   uint32_t align;
0052   llvm::yaml::Hex32 reloff;
0053   uint32_t nreloc;
0054   llvm::yaml::Hex32 flags;
0055   llvm::yaml::Hex32 reserved1;
0056   llvm::yaml::Hex32 reserved2;
0057   llvm::yaml::Hex32 reserved3;
0058   std::optional<llvm::yaml::BinaryRef> content;
0059   std::vector<Relocation> relocations;
0060 };
0061 
0062 struct FileHeader {
0063   llvm::yaml::Hex32 magic;
0064   llvm::yaml::Hex32 cputype;
0065   llvm::yaml::Hex32 cpusubtype;
0066   llvm::yaml::Hex32 filetype;
0067   uint32_t ncmds;
0068   uint32_t sizeofcmds;
0069   llvm::yaml::Hex32 flags;
0070   llvm::yaml::Hex32 reserved;
0071 };
0072 
0073 struct LoadCommand {
0074   virtual ~LoadCommand();
0075 
0076   llvm::MachO::macho_load_command Data;
0077   std::vector<Section> Sections;
0078   std::vector<MachO::build_tool_version> Tools;
0079   std::vector<llvm::yaml::Hex8> PayloadBytes;
0080   std::string Content;
0081   uint64_t ZeroPadBytes;
0082 };
0083 
0084 struct NListEntry {
0085   uint32_t n_strx;
0086   llvm::yaml::Hex8 n_type;
0087   uint8_t n_sect;
0088   uint16_t n_desc;
0089   uint64_t n_value;
0090 };
0091 
0092 struct RebaseOpcode {
0093   MachO::RebaseOpcode Opcode;
0094   uint8_t Imm;
0095   std::vector<yaml::Hex64> ExtraData;
0096 };
0097 
0098 struct BindOpcode {
0099   MachO::BindOpcode Opcode;
0100   uint8_t Imm;
0101   std::vector<yaml::Hex64> ULEBExtraData;
0102   std::vector<int64_t> SLEBExtraData;
0103   StringRef Symbol;
0104 };
0105 
0106 struct ExportEntry {
0107   uint64_t TerminalSize = 0;
0108   uint64_t NodeOffset = 0;
0109   std::string Name;
0110   llvm::yaml::Hex64 Flags = 0;
0111   llvm::yaml::Hex64 Address = 0;
0112   llvm::yaml::Hex64 Other = 0;
0113   std::string ImportName;
0114   std::vector<MachOYAML::ExportEntry> Children;
0115 };
0116 
0117 struct DataInCodeEntry {
0118   llvm::yaml::Hex32 Offset;
0119   uint16_t Length;
0120   llvm::yaml::Hex16 Kind;
0121 };
0122 
0123 struct LinkEditData {
0124   std::vector<MachOYAML::RebaseOpcode> RebaseOpcodes;
0125   std::vector<MachOYAML::BindOpcode> BindOpcodes;
0126   std::vector<MachOYAML::BindOpcode> WeakBindOpcodes;
0127   std::vector<MachOYAML::BindOpcode> LazyBindOpcodes;
0128   MachOYAML::ExportEntry ExportTrie;
0129   std::vector<NListEntry> NameList;
0130   std::vector<StringRef> StringTable;
0131   std::vector<yaml::Hex32> IndirectSymbols;
0132   std::vector<yaml::Hex64> FunctionStarts;
0133   std::vector<DataInCodeEntry> DataInCode;
0134   std::vector<yaml::Hex8> ChainedFixups;
0135 
0136   bool isEmpty() const;
0137 };
0138 
0139 struct Object {
0140   bool IsLittleEndian;
0141   FileHeader Header;
0142   std::vector<LoadCommand> LoadCommands;
0143   std::vector<Section> Sections;
0144   LinkEditData LinkEdit;
0145   std::optional<llvm::yaml::BinaryRef> RawLinkEditSegment;
0146   DWARFYAML::Data DWARF;
0147 };
0148 
0149 struct FatHeader {
0150   llvm::yaml::Hex32 magic;
0151   uint32_t nfat_arch;
0152 };
0153 
0154 struct FatArch {
0155   llvm::yaml::Hex32 cputype;
0156   llvm::yaml::Hex32 cpusubtype;
0157   llvm::yaml::Hex64 offset;
0158   uint64_t size;
0159   uint32_t align;
0160   llvm::yaml::Hex32 reserved;
0161 };
0162 
0163 struct UniversalBinary {
0164   FatHeader Header;
0165   std::vector<FatArch> FatArchs;
0166   std::vector<Object> Slices;
0167 };
0168 
0169 } // end namespace MachOYAML
0170 } // end namespace llvm
0171 
0172 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::LoadCommand)
0173 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::Relocation)
0174 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::Section)
0175 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::RebaseOpcode)
0176 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::BindOpcode)
0177 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::ExportEntry)
0178 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::NListEntry)
0179 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::Object)
0180 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::FatArch)
0181 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::DataInCodeEntry)
0182 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachO::build_tool_version)
0183 
0184 namespace llvm {
0185 
0186 class raw_ostream;
0187 
0188 namespace yaml {
0189 
0190 template <> struct MappingTraits<MachOYAML::FileHeader> {
0191   static void mapping(IO &IO, MachOYAML::FileHeader &FileHeader);
0192 };
0193 
0194 template <> struct MappingTraits<MachOYAML::Object> {
0195   static void mapping(IO &IO, MachOYAML::Object &Object);
0196 };
0197 
0198 template <> struct MappingTraits<MachOYAML::FatHeader> {
0199   static void mapping(IO &IO, MachOYAML::FatHeader &FatHeader);
0200 };
0201 
0202 template <> struct MappingTraits<MachOYAML::FatArch> {
0203   static void mapping(IO &IO, MachOYAML::FatArch &FatArch);
0204 };
0205 
0206 template <> struct MappingTraits<MachOYAML::UniversalBinary> {
0207   static void mapping(IO &IO, MachOYAML::UniversalBinary &UniversalBinary);
0208 };
0209 
0210 template <> struct MappingTraits<MachOYAML::LoadCommand> {
0211   static void mapping(IO &IO, MachOYAML::LoadCommand &LoadCommand);
0212 };
0213 
0214 template <> struct MappingTraits<MachOYAML::LinkEditData> {
0215   static void mapping(IO &IO, MachOYAML::LinkEditData &LinkEditData);
0216 };
0217 
0218 template <> struct MappingTraits<MachOYAML::RebaseOpcode> {
0219   static void mapping(IO &IO, MachOYAML::RebaseOpcode &RebaseOpcode);
0220 };
0221 
0222 template <> struct MappingTraits<MachOYAML::BindOpcode> {
0223   static void mapping(IO &IO, MachOYAML::BindOpcode &BindOpcode);
0224 };
0225 
0226 template <> struct MappingTraits<MachOYAML::ExportEntry> {
0227   static void mapping(IO &IO, MachOYAML::ExportEntry &ExportEntry);
0228 };
0229 
0230 template <> struct MappingTraits<MachOYAML::Relocation> {
0231   static void mapping(IO &IO, MachOYAML::Relocation &R);
0232 };
0233 
0234 template <> struct MappingTraits<MachOYAML::Section> {
0235   static void mapping(IO &IO, MachOYAML::Section &Section);
0236   static std::string validate(IO &io, MachOYAML::Section &Section);
0237 };
0238 
0239 template <> struct MappingTraits<MachOYAML::NListEntry> {
0240   static void mapping(IO &IO, MachOYAML::NListEntry &NListEntry);
0241 };
0242 
0243 template <> struct MappingTraits<MachO::build_tool_version> {
0244   static void mapping(IO &IO, MachO::build_tool_version &tool);
0245 };
0246 
0247 template <> struct MappingTraits<MachOYAML::DataInCodeEntry> {
0248   static void mapping(IO &IO, MachOYAML::DataInCodeEntry &DataInCodeEntry);
0249 };
0250 
0251 #define HANDLE_LOAD_COMMAND(LCName, LCValue, LCStruct)                         \
0252   io.enumCase(value, #LCName, MachO::LCName);
0253 
0254 template <> struct ScalarEnumerationTraits<MachO::LoadCommandType> {
0255   static void enumeration(IO &io, MachO::LoadCommandType &value) {
0256 #include "llvm/BinaryFormat/MachO.def"
0257     io.enumFallback<Hex32>(value);
0258   }
0259 };
0260 
0261 #define ENUM_CASE(Enum) io.enumCase(value, #Enum, MachO::Enum);
0262 
0263 template <> struct ScalarEnumerationTraits<MachO::RebaseOpcode> {
0264   static void enumeration(IO &io, MachO::RebaseOpcode &value) {
0265     ENUM_CASE(REBASE_OPCODE_DONE)
0266     ENUM_CASE(REBASE_OPCODE_SET_TYPE_IMM)
0267     ENUM_CASE(REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB)
0268     ENUM_CASE(REBASE_OPCODE_ADD_ADDR_ULEB)
0269     ENUM_CASE(REBASE_OPCODE_ADD_ADDR_IMM_SCALED)
0270     ENUM_CASE(REBASE_OPCODE_DO_REBASE_IMM_TIMES)
0271     ENUM_CASE(REBASE_OPCODE_DO_REBASE_ULEB_TIMES)
0272     ENUM_CASE(REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB)
0273     ENUM_CASE(REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB)
0274     io.enumFallback<Hex8>(value);
0275   }
0276 };
0277 
0278 template <> struct ScalarEnumerationTraits<MachO::BindOpcode> {
0279   static void enumeration(IO &io, MachO::BindOpcode &value) {
0280     ENUM_CASE(BIND_OPCODE_DONE)
0281     ENUM_CASE(BIND_OPCODE_SET_DYLIB_ORDINAL_IMM)
0282     ENUM_CASE(BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB)
0283     ENUM_CASE(BIND_OPCODE_SET_DYLIB_SPECIAL_IMM)
0284     ENUM_CASE(BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM)
0285     ENUM_CASE(BIND_OPCODE_SET_TYPE_IMM)
0286     ENUM_CASE(BIND_OPCODE_SET_ADDEND_SLEB)
0287     ENUM_CASE(BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB)
0288     ENUM_CASE(BIND_OPCODE_ADD_ADDR_ULEB)
0289     ENUM_CASE(BIND_OPCODE_DO_BIND)
0290     ENUM_CASE(BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB)
0291     ENUM_CASE(BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED)
0292     ENUM_CASE(BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB)
0293     io.enumFallback<Hex8>(value);
0294   }
0295 };
0296 
0297 // This trait is used for 16-byte chars in Mach structures used for strings
0298 using char_16 = char[16];
0299 
0300 template <> struct ScalarTraits<char_16> {
0301   static void output(const char_16 &Val, void *, raw_ostream &Out);
0302   static StringRef input(StringRef Scalar, void *, char_16 &Val);
0303   static QuotingType mustQuote(StringRef S);
0304 };
0305 
0306 // This trait is used for UUIDs. It reads and writes them matching otool's
0307 // formatting style.
0308 using uuid_t = raw_ostream::uuid_t;
0309 
0310 template <> struct ScalarTraits<uuid_t> {
0311   static void output(const uuid_t &Val, void *, raw_ostream &Out);
0312   static StringRef input(StringRef Scalar, void *, uuid_t &Val);
0313   static QuotingType mustQuote(StringRef S);
0314 };
0315 
0316 // Load Command struct mapping traits
0317 
0318 #define LOAD_COMMAND_STRUCT(LCStruct)                                          \
0319   template <> struct MappingTraits<MachO::LCStruct> {                          \
0320     static void mapping(IO &IO, MachO::LCStruct &LoadCommand);                 \
0321   };
0322 
0323 #include "llvm/BinaryFormat/MachO.def"
0324 
0325 // Extra structures used by load commands
0326 template <> struct MappingTraits<MachO::dylib> {
0327   static void mapping(IO &IO, MachO::dylib &LoadCommand);
0328 };
0329 
0330 template <> struct MappingTraits<MachO::fvmlib> {
0331   static void mapping(IO &IO, MachO::fvmlib &LoadCommand);
0332 };
0333 
0334 template <> struct MappingTraits<MachO::section> {
0335   static void mapping(IO &IO, MachO::section &LoadCommand);
0336 };
0337 
0338 template <> struct MappingTraits<MachO::section_64> {
0339   static void mapping(IO &IO, MachO::section_64 &LoadCommand);
0340 };
0341 
0342 } // end namespace yaml
0343 
0344 } // end namespace llvm
0345 
0346 #endif // LLVM_OBJECTYAML_MACHOYAML_H