Path: blob/main/contrib/llvm-project/llvm/lib/DebugInfo/GSYM/Header.cpp
35266 views
//===- Header.cpp -----------------------------------------------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "llvm/DebugInfo/GSYM/Header.h"9#include "llvm/DebugInfo/GSYM/FileWriter.h"10#include "llvm/Support/DataExtractor.h"11#include "llvm/Support/Format.h"12#include "llvm/Support/raw_ostream.h"1314#define HEX8(v) llvm::format_hex(v, 4)15#define HEX16(v) llvm::format_hex(v, 6)16#define HEX32(v) llvm::format_hex(v, 10)17#define HEX64(v) llvm::format_hex(v, 18)1819using namespace llvm;20using namespace gsym;2122raw_ostream &llvm::gsym::operator<<(raw_ostream &OS, const Header &H) {23OS << "Header:\n";24OS << " Magic = " << HEX32(H.Magic) << "\n";25OS << " Version = " << HEX16(H.Version) << '\n';26OS << " AddrOffSize = " << HEX8(H.AddrOffSize) << '\n';27OS << " UUIDSize = " << HEX8(H.UUIDSize) << '\n';28OS << " BaseAddress = " << HEX64(H.BaseAddress) << '\n';29OS << " NumAddresses = " << HEX32(H.NumAddresses) << '\n';30OS << " StrtabOffset = " << HEX32(H.StrtabOffset) << '\n';31OS << " StrtabSize = " << HEX32(H.StrtabSize) << '\n';32OS << " UUID = ";33for (uint8_t I = 0; I < H.UUIDSize; ++I)34OS << format_hex_no_prefix(H.UUID[I], 2);35OS << '\n';36return OS;37}3839/// Check the header and detect any errors.40llvm::Error Header::checkForError() const {41if (Magic != GSYM_MAGIC)42return createStringError(std::errc::invalid_argument,43"invalid GSYM magic 0x%8.8x", Magic);44if (Version != GSYM_VERSION)45return createStringError(std::errc::invalid_argument,46"unsupported GSYM version %u", Version);47switch (AddrOffSize) {48case 1: break;49case 2: break;50case 4: break;51case 8: break;52default:53return createStringError(std::errc::invalid_argument,54"invalid address offset size %u",55AddrOffSize);56}57if (UUIDSize > GSYM_MAX_UUID_SIZE)58return createStringError(std::errc::invalid_argument,59"invalid UUID size %u", UUIDSize);60return Error::success();61}6263llvm::Expected<Header> Header::decode(DataExtractor &Data) {64uint64_t Offset = 0;65// The header is stored as a single blob of data that has a fixed byte size.66if (!Data.isValidOffsetForDataOfSize(Offset, sizeof(Header)))67return createStringError(std::errc::invalid_argument,68"not enough data for a gsym::Header");69Header H;70H.Magic = Data.getU32(&Offset);71H.Version = Data.getU16(&Offset);72H.AddrOffSize = Data.getU8(&Offset);73H.UUIDSize = Data.getU8(&Offset);74H.BaseAddress = Data.getU64(&Offset);75H.NumAddresses = Data.getU32(&Offset);76H.StrtabOffset = Data.getU32(&Offset);77H.StrtabSize = Data.getU32(&Offset);78Data.getU8(&Offset, H.UUID, GSYM_MAX_UUID_SIZE);79if (llvm::Error Err = H.checkForError())80return std::move(Err);81return H;82}8384llvm::Error Header::encode(FileWriter &O) const {85// Users must verify the Header is valid prior to calling this funtion.86if (llvm::Error Err = checkForError())87return Err;88O.writeU32(Magic);89O.writeU16(Version);90O.writeU8(AddrOffSize);91O.writeU8(UUIDSize);92O.writeU64(BaseAddress);93O.writeU32(NumAddresses);94O.writeU32(StrtabOffset);95O.writeU32(StrtabSize);96O.writeData(llvm::ArrayRef<uint8_t>(UUID));97return Error::success();98}99100bool llvm::gsym::operator==(const Header &LHS, const Header &RHS) {101return LHS.Magic == RHS.Magic && LHS.Version == RHS.Version &&102LHS.AddrOffSize == RHS.AddrOffSize && LHS.UUIDSize == RHS.UUIDSize &&103LHS.BaseAddress == RHS.BaseAddress &&104LHS.NumAddresses == RHS.NumAddresses &&105LHS.StrtabOffset == RHS.StrtabOffset &&106LHS.StrtabSize == RHS.StrtabSize &&107memcmp(LHS.UUID, RHS.UUID, LHS.UUIDSize) == 0;108}109110111