summaryrefslogtreecommitdiffstats
path: root/llvm/lib/DebugInfo/CodeView/RecordName.cpp
diff options
context:
space:
mode:
authorAlexandre Ganea <alexandre.ganea@ubisoft.com>2018-04-09 20:17:56 +0000
committerAlexandre Ganea <alexandre.ganea@ubisoft.com>2018-04-09 20:17:56 +0000
commitd9e96741c464f35722bbbb4d11bb7fa7c6f4fb21 (patch)
tree450fa7f2b11c3954d3beb58f6d587468428b5f8b /llvm/lib/DebugInfo/CodeView/RecordName.cpp
parent69a2e18b4aeafad0e30091fb5f9c191e6d1c2df4 (diff)
downloadbcm5719-llvm-d9e96741c464f35722bbbb4d11bb7fa7c6f4fb21.tar.gz
bcm5719-llvm-d9e96741c464f35722bbbb4d11bb7fa7c6f4fb21.zip
[Debuginfo][COFF] Minimal serialization support for precompiled types records
This change adds support for the LF_PRECOMP and LF_ENDPRECOMP records required to read/write Microsoft precompiled types .objs. See https://en.wikipedia.org/wiki/Precompiled_header#Microsoft_Visual_C_and_C++ This also adds handling for the .debug$P section, which is actually a .debug$T section in disguise, found only in precompiled .objs. Differential Revision: https://reviews.llvm.org/D45283 llvm-svn: 329613
Diffstat (limited to 'llvm/lib/DebugInfo/CodeView/RecordName.cpp')
-rw-r--r--llvm/lib/DebugInfo/CodeView/RecordName.cpp656
1 files changed, 333 insertions, 323 deletions
diff --git a/llvm/lib/DebugInfo/CodeView/RecordName.cpp b/llvm/lib/DebugInfo/CodeView/RecordName.cpp
index e6fd7cd3d28..d18d346e86a 100644
--- a/llvm/lib/DebugInfo/CodeView/RecordName.cpp
+++ b/llvm/lib/DebugInfo/CodeView/RecordName.cpp
@@ -1,323 +1,333 @@
-//===- RecordName.cpp ----------------------------------------- *- C++ --*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/RecordName.h"
-
-#include "llvm/ADT/SmallString.h"
-#include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h"
-#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
-#include "llvm/DebugInfo/CodeView/SymbolRecordMapping.h"
-#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
-#include "llvm/Support/FormatVariadic.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-
-namespace {
-class TypeNameComputer : public TypeVisitorCallbacks {
- /// The type collection. Used to calculate names of nested types.
- TypeCollection &Types;
- TypeIndex CurrentTypeIndex = TypeIndex::None();
-
- /// Name of the current type. Only valid before visitTypeEnd.
- SmallString<256> Name;
-
-public:
- explicit TypeNameComputer(TypeCollection &Types) : Types(Types) {}
-
- StringRef name() const { return Name; }
-
- /// Paired begin/end actions for all types. Receives all record data,
- /// including the fixed-length record prefix.
- Error visitTypeBegin(CVType &Record) override;
- Error visitTypeBegin(CVType &Record, TypeIndex Index) override;
- Error visitTypeEnd(CVType &Record) override;
-
-#define TYPE_RECORD(EnumName, EnumVal, Name) \
- Error visitKnownRecord(CVType &CVR, Name##Record &Record) override;
-#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#define MEMBER_RECORD(EnumName, EnumVal, Name)
-#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
-};
-} // namespace
-
-Error TypeNameComputer::visitTypeBegin(CVType &Record) {
- llvm_unreachable("Must call visitTypeBegin with a TypeIndex!");
- return Error::success();
-}
-
-Error TypeNameComputer::visitTypeBegin(CVType &Record, TypeIndex Index) {
- // Reset Name to the empty string. If the visitor sets it, we know it.
- Name = "";
- CurrentTypeIndex = Index;
- return Error::success();
-}
-
-Error TypeNameComputer::visitTypeEnd(CVType &CVR) { return Error::success(); }
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR,
- FieldListRecord &FieldList) {
- Name = "<field list>";
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
- StringIdRecord &String) {
- Name = String.getString();
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR, ArgListRecord &Args) {
- auto Indices = Args.getIndices();
- uint32_t Size = Indices.size();
- Name = "(";
- for (uint32_t I = 0; I < Size; ++I) {
- assert(Indices[I] < CurrentTypeIndex);
-
- Name.append(Types.getTypeName(Indices[I]));
- if (I + 1 != Size)
- Name.append(", ");
- }
- Name.push_back(')');
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR,
- StringListRecord &Strings) {
- auto Indices = Strings.getIndices();
- uint32_t Size = Indices.size();
- Name = "\"";
- for (uint32_t I = 0; I < Size; ++I) {
- Name.append(Types.getTypeName(Indices[I]));
- if (I + 1 != Size)
- Name.append("\" \"");
- }
- Name.push_back('\"');
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR, ClassRecord &Class) {
- Name = Class.getName();
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR, UnionRecord &Union) {
- Name = Union.getName();
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR, EnumRecord &Enum) {
- Name = Enum.getName();
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR, ArrayRecord &AT) {
- Name = AT.getName();
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR, VFTableRecord &VFT) {
- Name = VFT.getName();
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR, MemberFuncIdRecord &Id) {
- Name = Id.getName();
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR, ProcedureRecord &Proc) {
- StringRef Ret = Types.getTypeName(Proc.getReturnType());
- StringRef Params = Types.getTypeName(Proc.getArgumentList());
- Name = formatv("{0} {1}", Ret, Params).sstr<256>();
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR,
- MemberFunctionRecord &MF) {
- StringRef Ret = Types.getTypeName(MF.getReturnType());
- StringRef Class = Types.getTypeName(MF.getClassType());
- StringRef Params = Types.getTypeName(MF.getArgumentList());
- Name = formatv("{0} {1}::{2}", Ret, Class, Params).sstr<256>();
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR, FuncIdRecord &Func) {
- Name = Func.getName();
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR, TypeServer2Record &TS) {
- Name = TS.getName();
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR, PointerRecord &Ptr) {
-
- if (Ptr.isPointerToMember()) {
- const MemberPointerInfo &MI = Ptr.getMemberInfo();
-
- StringRef Pointee = Types.getTypeName(Ptr.getReferentType());
- StringRef Class = Types.getTypeName(MI.getContainingType());
- Name = formatv("{0} {1}::*", Pointee, Class);
- } else {
- Name.append(Types.getTypeName(Ptr.getReferentType()));
-
- if (Ptr.getMode() == PointerMode::LValueReference)
- Name.append("&");
- else if (Ptr.getMode() == PointerMode::RValueReference)
- Name.append("&&");
- else if (Ptr.getMode() == PointerMode::Pointer)
- Name.append("*");
-
- // Qualifiers in pointer records apply to the pointer, not the pointee, so
- // they go on the right.
- if (Ptr.isConst())
- Name.append(" const");
- if (Ptr.isVolatile())
- Name.append(" volatile");
- if (Ptr.isUnaligned())
- Name.append(" __unaligned");
- if (Ptr.isRestrict())
- Name.append(" __restrict");
- }
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR, ModifierRecord &Mod) {
- uint16_t Mods = static_cast<uint16_t>(Mod.getModifiers());
-
- if (Mods & uint16_t(ModifierOptions::Const))
- Name.append("const ");
- if (Mods & uint16_t(ModifierOptions::Volatile))
- Name.append("volatile ");
- if (Mods & uint16_t(ModifierOptions::Unaligned))
- Name.append("__unaligned ");
- Name.append(Types.getTypeName(Mod.getModifiedType()));
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR,
- VFTableShapeRecord &Shape) {
- Name = formatv("<vftable {0} methods>", Shape.getEntryCount());
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(
- CVType &CVR, UdtModSourceLineRecord &ModSourceLine) {
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR,
- UdtSourceLineRecord &SourceLine) {
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR, BitFieldRecord &BF) {
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR,
- MethodOverloadListRecord &Overloads) {
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR, BuildInfoRecord &BI) {
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR, LabelRecord &R) {
- return Error::success();
-}
-
-std::string llvm::codeview::computeTypeName(TypeCollection &Types,
- TypeIndex Index) {
- TypeNameComputer Computer(Types);
- CVType Record = Types.getType(Index);
- if (auto EC = visitTypeRecord(Record, Index, Computer)) {
- consumeError(std::move(EC));
- return "<unknown UDT>";
- }
- return Computer.name();
-}
-
-static int getSymbolNameOffset(CVSymbol Sym) {
- switch (Sym.kind()) {
- // See ProcSym
- case SymbolKind::S_GPROC32:
- case SymbolKind::S_LPROC32:
- case SymbolKind::S_GPROC32_ID:
- case SymbolKind::S_LPROC32_ID:
- case SymbolKind::S_LPROC32_DPC:
- case SymbolKind::S_LPROC32_DPC_ID:
- return 35;
- // See Thunk32Sym
- case SymbolKind::S_THUNK32:
- return 21;
- // See SectionSym
- case SymbolKind::S_SECTION:
- return 16;
- // See CoffGroupSym
- case SymbolKind::S_COFFGROUP:
- return 14;
- // See PublicSym32, FileStaticSym, RegRelativeSym, DataSym, ThreadLocalDataSym
- case SymbolKind::S_PUB32:
- case SymbolKind::S_FILESTATIC:
- case SymbolKind::S_REGREL32:
- case SymbolKind::S_GDATA32:
- case SymbolKind::S_LDATA32:
- case SymbolKind::S_LMANDATA:
- case SymbolKind::S_GMANDATA:
- case SymbolKind::S_LTHREAD32:
- case SymbolKind::S_GTHREAD32:
- return 10;
- // See RegisterSym and LocalSym
- case SymbolKind::S_REGISTER:
- case SymbolKind::S_LOCAL:
- return 6;
- // See BlockSym
- case SymbolKind::S_BLOCK32:
- return 18;
- // See LabelSym
- case SymbolKind::S_LABEL32:
- return 7;
- // See ObjNameSym, ExportSym, and UDTSym
- case SymbolKind::S_OBJNAME:
- case SymbolKind::S_EXPORT:
- case SymbolKind::S_UDT:
- return 4;
- // See BPRelativeSym
- case SymbolKind::S_BPREL32:
- return 8;
- default:
- return -1;
- }
-}
-
-StringRef llvm::codeview::getSymbolName(CVSymbol Sym) {
- if (Sym.kind() == SymbolKind::S_CONSTANT) {
- // S_CONSTANT is preceded by an APSInt, which has a variable length. So we
- // have to do a full deserialization.
- BinaryStreamReader Reader(Sym.content(), llvm::support::little);
- // The container doesn't matter for single records.
- SymbolRecordMapping Mapping(Reader, CodeViewContainer::ObjectFile);
- ConstantSym Const(SymbolKind::S_CONSTANT);
- cantFail(Mapping.visitSymbolBegin(Sym));
- cantFail(Mapping.visitKnownRecord(Sym, Const));
- cantFail(Mapping.visitSymbolEnd(Sym));
- return Const.Name;
- }
-
- int Offset = getSymbolNameOffset(Sym);
- if (Offset == -1)
- return StringRef();
-
- StringRef StringData = toStringRef(Sym.content()).drop_front(Offset);
- return StringData.split('\0').first;
-}
+//===- RecordName.cpp ----------------------------------------- *- C++ --*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/RecordName.h"
+
+#include "llvm/ADT/SmallString.h"
+#include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h"
+#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecordMapping.h"
+#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
+#include "llvm/Support/FormatVariadic.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+namespace {
+class TypeNameComputer : public TypeVisitorCallbacks {
+ /// The type collection. Used to calculate names of nested types.
+ TypeCollection &Types;
+ TypeIndex CurrentTypeIndex = TypeIndex::None();
+
+ /// Name of the current type. Only valid before visitTypeEnd.
+ SmallString<256> Name;
+
+public:
+ explicit TypeNameComputer(TypeCollection &Types) : Types(Types) {}
+
+ StringRef name() const { return Name; }
+
+ /// Paired begin/end actions for all types. Receives all record data,
+ /// including the fixed-length record prefix.
+ Error visitTypeBegin(CVType &Record) override;
+ Error visitTypeBegin(CVType &Record, TypeIndex Index) override;
+ Error visitTypeEnd(CVType &Record) override;
+
+#define TYPE_RECORD(EnumName, EnumVal, Name) \
+ Error visitKnownRecord(CVType &CVR, Name##Record &Record) override;
+#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#define MEMBER_RECORD(EnumName, EnumVal, Name)
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
+};
+} // namespace
+
+Error TypeNameComputer::visitTypeBegin(CVType &Record) {
+ llvm_unreachable("Must call visitTypeBegin with a TypeIndex!");
+ return Error::success();
+}
+
+Error TypeNameComputer::visitTypeBegin(CVType &Record, TypeIndex Index) {
+ // Reset Name to the empty string. If the visitor sets it, we know it.
+ Name = "";
+ CurrentTypeIndex = Index;
+ return Error::success();
+}
+
+Error TypeNameComputer::visitTypeEnd(CVType &CVR) { return Error::success(); }
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR,
+ FieldListRecord &FieldList) {
+ Name = "<field list>";
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
+ StringIdRecord &String) {
+ Name = String.getString();
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR, ArgListRecord &Args) {
+ auto Indices = Args.getIndices();
+ uint32_t Size = Indices.size();
+ Name = "(";
+ for (uint32_t I = 0; I < Size; ++I) {
+ assert(Indices[I] < CurrentTypeIndex);
+
+ Name.append(Types.getTypeName(Indices[I]));
+ if (I + 1 != Size)
+ Name.append(", ");
+ }
+ Name.push_back(')');
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR,
+ StringListRecord &Strings) {
+ auto Indices = Strings.getIndices();
+ uint32_t Size = Indices.size();
+ Name = "\"";
+ for (uint32_t I = 0; I < Size; ++I) {
+ Name.append(Types.getTypeName(Indices[I]));
+ if (I + 1 != Size)
+ Name.append("\" \"");
+ }
+ Name.push_back('\"');
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR, ClassRecord &Class) {
+ Name = Class.getName();
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR, UnionRecord &Union) {
+ Name = Union.getName();
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR, EnumRecord &Enum) {
+ Name = Enum.getName();
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR, ArrayRecord &AT) {
+ Name = AT.getName();
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR, VFTableRecord &VFT) {
+ Name = VFT.getName();
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR, MemberFuncIdRecord &Id) {
+ Name = Id.getName();
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR, ProcedureRecord &Proc) {
+ StringRef Ret = Types.getTypeName(Proc.getReturnType());
+ StringRef Params = Types.getTypeName(Proc.getArgumentList());
+ Name = formatv("{0} {1}", Ret, Params).sstr<256>();
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR,
+ MemberFunctionRecord &MF) {
+ StringRef Ret = Types.getTypeName(MF.getReturnType());
+ StringRef Class = Types.getTypeName(MF.getClassType());
+ StringRef Params = Types.getTypeName(MF.getArgumentList());
+ Name = formatv("{0} {1}::{2}", Ret, Class, Params).sstr<256>();
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR, FuncIdRecord &Func) {
+ Name = Func.getName();
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR, TypeServer2Record &TS) {
+ Name = TS.getName();
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR, PointerRecord &Ptr) {
+
+ if (Ptr.isPointerToMember()) {
+ const MemberPointerInfo &MI = Ptr.getMemberInfo();
+
+ StringRef Pointee = Types.getTypeName(Ptr.getReferentType());
+ StringRef Class = Types.getTypeName(MI.getContainingType());
+ Name = formatv("{0} {1}::*", Pointee, Class);
+ } else {
+ Name.append(Types.getTypeName(Ptr.getReferentType()));
+
+ if (Ptr.getMode() == PointerMode::LValueReference)
+ Name.append("&");
+ else if (Ptr.getMode() == PointerMode::RValueReference)
+ Name.append("&&");
+ else if (Ptr.getMode() == PointerMode::Pointer)
+ Name.append("*");
+
+ // Qualifiers in pointer records apply to the pointer, not the pointee, so
+ // they go on the right.
+ if (Ptr.isConst())
+ Name.append(" const");
+ if (Ptr.isVolatile())
+ Name.append(" volatile");
+ if (Ptr.isUnaligned())
+ Name.append(" __unaligned");
+ if (Ptr.isRestrict())
+ Name.append(" __restrict");
+ }
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR, ModifierRecord &Mod) {
+ uint16_t Mods = static_cast<uint16_t>(Mod.getModifiers());
+
+ if (Mods & uint16_t(ModifierOptions::Const))
+ Name.append("const ");
+ if (Mods & uint16_t(ModifierOptions::Volatile))
+ Name.append("volatile ");
+ if (Mods & uint16_t(ModifierOptions::Unaligned))
+ Name.append("__unaligned ");
+ Name.append(Types.getTypeName(Mod.getModifiedType()));
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR,
+ VFTableShapeRecord &Shape) {
+ Name = formatv("<vftable {0} methods>", Shape.getEntryCount());
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(
+ CVType &CVR, UdtModSourceLineRecord &ModSourceLine) {
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR,
+ UdtSourceLineRecord &SourceLine) {
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR, BitFieldRecord &BF) {
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR,
+ MethodOverloadListRecord &Overloads) {
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR, BuildInfoRecord &BI) {
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR, LabelRecord &R) {
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR,
+ PrecompRecord &Precomp) {
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR,
+ EndPrecompRecord &EndPrecomp) {
+ return Error::success();
+}
+
+std::string llvm::codeview::computeTypeName(TypeCollection &Types,
+ TypeIndex Index) {
+ TypeNameComputer Computer(Types);
+ CVType Record = Types.getType(Index);
+ if (auto EC = visitTypeRecord(Record, Index, Computer)) {
+ consumeError(std::move(EC));
+ return "<unknown UDT>";
+ }
+ return Computer.name();
+}
+
+static int getSymbolNameOffset(CVSymbol Sym) {
+ switch (Sym.kind()) {
+ // See ProcSym
+ case SymbolKind::S_GPROC32:
+ case SymbolKind::S_LPROC32:
+ case SymbolKind::S_GPROC32_ID:
+ case SymbolKind::S_LPROC32_ID:
+ case SymbolKind::S_LPROC32_DPC:
+ case SymbolKind::S_LPROC32_DPC_ID:
+ return 35;
+ // See Thunk32Sym
+ case SymbolKind::S_THUNK32:
+ return 21;
+ // See SectionSym
+ case SymbolKind::S_SECTION:
+ return 16;
+ // See CoffGroupSym
+ case SymbolKind::S_COFFGROUP:
+ return 14;
+ // See PublicSym32, FileStaticSym, RegRelativeSym, DataSym, ThreadLocalDataSym
+ case SymbolKind::S_PUB32:
+ case SymbolKind::S_FILESTATIC:
+ case SymbolKind::S_REGREL32:
+ case SymbolKind::S_GDATA32:
+ case SymbolKind::S_LDATA32:
+ case SymbolKind::S_LMANDATA:
+ case SymbolKind::S_GMANDATA:
+ case SymbolKind::S_LTHREAD32:
+ case SymbolKind::S_GTHREAD32:
+ return 10;
+ // See RegisterSym and LocalSym
+ case SymbolKind::S_REGISTER:
+ case SymbolKind::S_LOCAL:
+ return 6;
+ // See BlockSym
+ case SymbolKind::S_BLOCK32:
+ return 18;
+ // See LabelSym
+ case SymbolKind::S_LABEL32:
+ return 7;
+ // See ObjNameSym, ExportSym, and UDTSym
+ case SymbolKind::S_OBJNAME:
+ case SymbolKind::S_EXPORT:
+ case SymbolKind::S_UDT:
+ return 4;
+ // See BPRelativeSym
+ case SymbolKind::S_BPREL32:
+ return 8;
+ default:
+ return -1;
+ }
+}
+
+StringRef llvm::codeview::getSymbolName(CVSymbol Sym) {
+ if (Sym.kind() == SymbolKind::S_CONSTANT) {
+ // S_CONSTANT is preceded by an APSInt, which has a variable length. So we
+ // have to do a full deserialization.
+ BinaryStreamReader Reader(Sym.content(), llvm::support::little);
+ // The container doesn't matter for single records.
+ SymbolRecordMapping Mapping(Reader, CodeViewContainer::ObjectFile);
+ ConstantSym Const(SymbolKind::S_CONSTANT);
+ cantFail(Mapping.visitSymbolBegin(Sym));
+ cantFail(Mapping.visitKnownRecord(Sym, Const));
+ cantFail(Mapping.visitSymbolEnd(Sym));
+ return Const.Name;
+ }
+
+ int Offset = getSymbolNameOffset(Sym);
+ if (Offset == -1)
+ return StringRef();
+
+ StringRef StringData = toStringRef(Sym.content()).drop_front(Offset);
+ return StringData.split('\0').first;
+}
OpenPOWER on IntegriCloud