1 //===- Header.h -------------------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_DEBUGINFO_GSYM_HEADER_H 10 #define LLVM_DEBUGINFO_GSYM_HEADER_H 11 12 #include "llvm/Support/Compiler.h" 13 #include "llvm/Support/Error.h" 14 15 #include <cstddef> 16 #include <cstdint> 17 18 namespace llvm { 19 class raw_ostream; 20 class DataExtractor; 21 22 namespace gsym { 23 class FileWriter; 24 25 constexpr uint32_t GSYM_MAGIC = 0x4753594d; // 'GSYM' 26 constexpr uint32_t GSYM_CIGAM = 0x4d595347; // 'MYSG' 27 constexpr uint32_t GSYM_VERSION = 1; 28 constexpr size_t GSYM_MAX_UUID_SIZE = 20; 29 30 /// The GSYM header. 31 /// 32 /// The GSYM header is found at the start of a stand alone GSYM file, or as 33 /// the first bytes in a section when GSYM is contained in a section of an 34 /// executable file (ELF, mach-o, COFF). 35 /// 36 /// The structure is encoded exactly as it appears in the structure definition 37 /// with no gaps between members. Alignment should not change from system to 38 /// system as the members were laid out so that they shouldn't align 39 /// differently on different architectures. 40 /// 41 /// When endianness of the system loading a GSYM file matches, the file can 42 /// be mmap'ed in and a pointer to the header can be cast to the first bytes 43 /// of the file (stand alone GSYM file) or section data (GSYM in a section). 44 /// When endianness is swapped, the Header::decode() function should be used to 45 /// decode the header. 46 struct Header { 47 /// The magic bytes should be set to GSYM_MAGIC. This helps detect if a file 48 /// is a GSYM file by scanning the first 4 bytes of a file or section. 49 /// This value might appear byte swapped 50 uint32_t Magic; 51 /// The version can number determines how the header is decoded and how each 52 /// InfoType in FunctionInfo is encoded/decoded. As version numbers increase, 53 /// "Magic" and "Version" members should always appear at offset zero and 4 54 /// respectively to ensure clients figure out if they can parse the format. 55 uint16_t Version; 56 /// The size in bytes of each address offset in the address offsets table. 57 uint8_t AddrOffSize; 58 /// The size in bytes of the UUID encoded in the "UUID" member. 59 uint8_t UUIDSize; 60 /// The 64 bit base address that all address offsets in the address offsets 61 /// table are relative to. Storing a full 64 bit address allows our address 62 /// offsets table to be smaller on disk. 63 uint64_t BaseAddress; 64 /// The number of addresses stored in the address offsets table. 65 uint32_t NumAddresses; 66 /// The file relative offset of the start of the string table for strings 67 /// contained in the GSYM file. If the GSYM in contained in a stand alone 68 /// file this will be the file offset of the start of the string table. If 69 /// the GSYM is contained in a section within an executable file, this can 70 /// be the offset of the first string used in the GSYM file and can possibly 71 /// span one or more executable string tables. This allows the strings to 72 /// share string tables in an ELF or mach-o file. 73 uint32_t StrtabOffset; 74 /// The size in bytes of the string table. For a stand alone GSYM file, this 75 /// will be the exact size in bytes of the string table. When the GSYM data 76 /// is in a section within an executable file, this size can span one or more 77 /// sections that contains strings. This allows any strings that are already 78 /// stored in the executable file to be re-used, and any extra strings could 79 /// be added to another string table and the string table offset and size 80 /// can be set to span all needed string tables. 81 uint32_t StrtabSize; 82 /// The UUID of the original executable file. This is stored to allow 83 /// matching a GSYM file to an executable file when symbolication is 84 /// required. Only the first "UUIDSize" bytes of the UUID are valid. Any 85 /// bytes in the UUID value that appear after the first UUIDSize bytes should 86 /// be set to zero. 87 uint8_t UUID[GSYM_MAX_UUID_SIZE]; 88 89 /// Check if a header is valid and return an error if anything is wrong. 90 /// 91 /// This function can be used prior to encoding a header to ensure it is 92 /// valid, or after decoding a header to ensure it is valid and supported. 93 /// 94 /// Check a correctly byte swapped header for errors: 95 /// - check magic value 96 /// - check that version number is supported 97 /// - check that the address offset size is supported 98 /// - check that the UUID size is valid 99 /// 100 /// \returns An error if anything is wrong in the header, or Error::success() 101 /// if there are no errors. 102 LLVM_ABI llvm::Error checkForError() const; 103 104 /// Decode an object from a binary data stream. 105 /// 106 /// \param Data The binary stream to read the data from. This object must 107 /// have the data for the object starting at offset zero. The data 108 /// can contain more data than needed. 109 /// 110 /// \returns A Header or an error describing the issue that was 111 /// encountered during decoding. 112 LLVM_ABI static llvm::Expected<Header> decode(DataExtractor &Data); 113 114 /// Encode this object into FileWriter stream. 115 /// 116 /// \param O The binary stream to write the data to at the current file 117 /// position. 118 /// 119 /// \returns An error object that indicates success or failure of the 120 /// encoding process. 121 LLVM_ABI llvm::Error encode(FileWriter &O) const; 122 }; 123 124 LLVM_ABI bool operator==(const Header &LHS, const Header &RHS); 125 LLVM_ABI raw_ostream &operator<<(raw_ostream &OS, const llvm::gsym::Header &H); 126 127 } // namespace gsym 128 } // namespace llvm 129 130 #endif // LLVM_DEBUGINFO_GSYM_HEADER_H 131