GsymCreator.h revision 360784
1//===- GsymCreator.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_GSYMCREATOR_H 10#define LLVM_DEBUGINFO_GSYM_GSYMCREATOR_H 11 12#include <functional> 13#include <memory> 14#include <mutex> 15#include <string> 16#include <thread> 17 18#include "llvm/ADT/ArrayRef.h" 19#include "llvm/DebugInfo/GSYM/FileEntry.h" 20#include "llvm/DebugInfo/GSYM/FunctionInfo.h" 21#include "llvm/DebugInfo/GSYM/Range.h" 22#include "llvm/MC/StringTableBuilder.h" 23#include "llvm/Support/Endian.h" 24#include "llvm/Support/Error.h" 25#include "llvm/Support/Path.h" 26 27namespace llvm { 28 29namespace gsym { 30class FileWriter; 31 32/// GsymCreator is used to emit GSYM data to a stand alone file or section 33/// within a file. 34/// 35/// The GsymCreator is designed to be used in 3 stages: 36/// - Create FunctionInfo objects and add them 37/// - Finalize the GsymCreator object 38/// - Save to file or section 39/// 40/// The first stage involves creating FunctionInfo objects from another source 41/// of information like compiler debug info metadata, DWARF or Breakpad files. 42/// Any strings in the FunctionInfo or contained information, like InlineInfo 43/// or LineTable objects, should get the string table offsets by calling 44/// GsymCreator::insertString(...). Any file indexes that are needed should be 45/// obtained by calling GsymCreator::insertFile(...). All of the function calls 46/// in GsymCreator are thread safe. This allows multiple threads to create and 47/// add FunctionInfo objects while parsing debug information. 48/// 49/// Once all of the FunctionInfo objects have been added, the 50/// GsymCreator::finalize(...) must be called prior to saving. This function 51/// will sort the FunctionInfo objects, finalize the string table, and do any 52/// other passes on the information needed to prepare the information to be 53/// saved. 54/// 55/// Once the object has been finalized, it can be saved to a file or section. 56/// 57/// ENCODING 58/// 59/// GSYM files are designed to be memory mapped into a process as shared, read 60/// only data, and used as is. 61/// 62/// The GSYM file format when in a stand alone file consists of: 63/// - Header 64/// - Address Table 65/// - Function Info Offsets 66/// - File Table 67/// - String Table 68/// - Function Info Data 69/// 70/// HEADER 71/// 72/// The header is fully described in "llvm/DebugInfo/GSYM/Header.h". 73/// 74/// ADDRESS TABLE 75/// 76/// The address table immediately follows the header in the file and consists 77/// of Header.NumAddresses address offsets. These offsets are sorted and can be 78/// binary searched for efficient lookups. Addresses in the address table are 79/// stored as offsets from a 64 bit base address found in Header.BaseAddress. 80/// This allows the address table to contain 8, 16, or 32 offsets. This allows 81/// the address table to not require full 64 bit addresses for each address. 82/// The resulting GSYM size is smaller and causes fewer pages to be touched 83/// during address lookups when the address table is smaller. The size of the 84/// address offsets in the address table is specified in the header in 85/// Header.AddrOffSize. The first offset in the address table is aligned to 86/// Header.AddrOffSize alignment to ensure efficient access when loaded into 87/// memory. 88/// 89/// FUNCTION INFO OFFSETS TABLE 90/// 91/// The function info offsets table immediately follows the address table and 92/// consists of Header.NumAddresses 32 bit file offsets: one for each address 93/// in the address table. This data is aligned to a 4 byte boundary. The 94/// offsets in this table are the relative offsets from the start offset of the 95/// GSYM header and point to the function info data for each address in the 96/// address table. Keeping this data separate from the address table helps to 97/// reduce the number of pages that are touched when address lookups occur on a 98/// GSYM file. 99/// 100/// FILE TABLE 101/// 102/// The file table immediately follows the function info offsets table. The 103/// encoding of the FileTable is: 104/// 105/// struct FileTable { 106/// uint32_t Count; 107/// FileEntry Files[]; 108/// }; 109/// 110/// The file table starts with a 32 bit count of the number of files that are 111/// used in all of the function info, followed by that number of FileEntry 112/// structures. The file table is aligned to a 4 byte boundary, Each file in 113/// the file table is represented with a FileEntry structure. 114/// See "llvm/DebugInfo/GSYM/FileEntry.h" for details. 115/// 116/// STRING TABLE 117/// 118/// The string table follows the file table in stand alone GSYM files and 119/// contains all strings for everything contained in the GSYM file. Any string 120/// data should be added to the string table and any references to strings 121/// inside GSYM information must be stored as 32 bit string table offsets into 122/// this string table. The string table always starts with an empty string at 123/// offset zero and is followed by any strings needed by the GSYM information. 124/// The start of the string table is not aligned to any boundary. 125/// 126/// FUNCTION INFO DATA 127/// 128/// The function info data is the payload that contains information about the 129/// address that is being looked up. It contains all of the encoded 130/// FunctionInfo objects. Each encoded FunctionInfo's data is pointed to by an 131/// entry in the Function Info Offsets Table. For details on the exact encoding 132/// of FunctionInfo objects, see "llvm/DebugInfo/GSYM/FunctionInfo.h". 133class GsymCreator { 134 // Private member variables require Mutex protections 135 mutable std::recursive_mutex Mutex; 136 std::vector<FunctionInfo> Funcs; 137 StringTableBuilder StrTab; 138 DenseMap<llvm::gsym::FileEntry, uint32_t> FileEntryToIndex; 139 std::vector<llvm::gsym::FileEntry> Files; 140 std::vector<uint8_t> UUID; 141 bool Finalized = false; 142 143public: 144 145 GsymCreator(); 146 147 /// Save a GSYM file to a stand alone file. 148 /// 149 /// \param Path The file path to save the GSYM file to. 150 /// \param ByteOrder The endianness to use when saving the file. 151 /// \returns An error object that indicates success or failure of the save. 152 llvm::Error save(StringRef Path, llvm::support::endianness ByteOrder) const; 153 154 /// Encode a GSYM into the file writer stream at the current position. 155 /// 156 /// \param O The stream to save the binary data to 157 /// \returns An error object that indicates success or failure of the save. 158 llvm::Error encode(FileWriter &O) const; 159 160 /// Insert a string into the GSYM string table. 161 /// 162 /// All strings used by GSYM files must be uniqued by adding them to this 163 /// string pool and using the returned offset for any string values. 164 /// 165 /// \param S The string to insert into the string table. 166 /// \returns The unique 32 bit offset into the string table. 167 uint32_t insertString(StringRef S); 168 169 /// Insert a file into this GSYM creator. 170 /// 171 /// Inserts a file by adding a FileEntry into the "Files" member variable if 172 /// the file has not already been added. The file path is split into 173 /// directory and filename which are both added to the string table. This 174 /// allows paths to be stored efficiently by reusing the directories that are 175 /// common between multiple files. 176 /// 177 /// \param Path The path to the file to insert. 178 /// \param Style The path style for the "Path" parameter. 179 /// \returns The unique file index for the inserted file. 180 uint32_t insertFile(StringRef Path, 181 sys::path::Style Style = sys::path::Style::native); 182 183 /// Add a function info to this GSYM creator. 184 /// 185 /// All information in the FunctionInfo object must use the 186 /// GsymCreator::insertString(...) function when creating string table 187 /// offsets for names and other strings. 188 /// 189 /// \param FI The function info object to emplace into our functions list. 190 void addFunctionInfo(FunctionInfo &&FI); 191 192 /// Finalize the data in the GSYM creator prior to saving the data out. 193 /// 194 /// Finalize must be called after all FunctionInfo objects have been added 195 /// and before GsymCreator::save() is called. 196 /// 197 /// \param OS Output stream to report duplicate function infos, overlapping 198 /// function infos, and function infos that were merged or removed. 199 /// \returns An error object that indicates success or failure of the 200 /// finalize. 201 llvm::Error finalize(llvm::raw_ostream &OS); 202 203 /// Set the UUID value. 204 /// 205 /// \param UUIDBytes The new UUID bytes. 206 void setUUID(llvm::ArrayRef<uint8_t> UUIDBytes) { 207 UUID.assign(UUIDBytes.begin(), UUIDBytes.end()); 208 } 209 210 /// Thread safe iteration over all function infos. 211 /// 212 /// \param Callback A callback function that will get called with each 213 /// FunctionInfo. If the callback returns false, stop iterating. 214 void forEachFunctionInfo( 215 std::function<bool(FunctionInfo &)> const &Callback); 216 217 /// Thread safe const iteration over all function infos. 218 /// 219 /// \param Callback A callback function that will get called with each 220 /// FunctionInfo. If the callback returns false, stop iterating. 221 void forEachFunctionInfo( 222 std::function<bool(const FunctionInfo &)> const &Callback) const; 223 224}; 225 226} // namespace gsym 227} // namespace llvm 228 229#endif // #ifndef LLVM_DEBUGINFO_GSYM_GSYMCREATOR_H 230