1//===-- LVCodeViewVisitor.cpp ---------------------------------------------===// 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 7//===----------------------------------------------------------------------===// 9// This implements the LVCodeViewVisitor class. 11//===----------------------------------------------------------------------===// 40#define DEBUG_TYPE "CodeViewUtilities" 46// Dealing with a MSVC generated PDB, we encountered a type index with the 47// value of: 0x0280xxxx where xxxx=0000. 49// There is some documentation about type indices: 50// https://llvm.org/docs/PDB/TpiStream.html 52// A type index is a 32-bit integer that uniquely identifies a type inside 53// of an object file’s .debug$T section or a PDB file’s TPI or IPI stream. 54// The value of the type index for the first type record from the TPI stream 55// is given by the TypeIndexBegin member of the TPI Stream Header although 56// in practice this value is always equal to 0x1000 (4096). 58// Any type index with a high bit set is considered to come from the IPI 59// stream, although this appears to be more of a hack, and LLVM does not 60// generate type indices of this nature. They can, however, be observed in 61// Microsoft PDBs occasionally, so one should be prepared to handle them. 62// Note that having the high bit set is not a necessary condition to 63// determine whether a type index comes from the IPI stream, it is only 74#define CV_TYPE(enum, val) {#enum, enum}, 75#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" 78// Return the type name pointed by the type index. It uses the kind to query 79// the associated name for the record type. 86auto GetName = [&](
autoRecord) {
95if (RK == TypeRecordKind::Class || RK == TypeRecordKind::Struct)
97elseif (RK == TypeRecordKind::Union)
99elseif (RK == TypeRecordKind::Enum)
105}
// namespace logicalview 109#define DEBUG_TYPE "CodeViewDataVisitor" 112namespacelogicalview {
114// Keeps the type indexes with line information. 122// Logical elements associated to their CodeView Type Index. 123usingRecordEntry = std::pair<TypeLeafKind, LVElement *>;
124usingRecordTable = std::map<TypeIndex, RecordEntry>;
125 RecordTable RecordFromTypes;
126 RecordTable RecordFromIds;
128usingNameTable = std::map<StringRef, TypeIndex>;
129 NameTable NameFromTypes;
130 NameTable NameFromIds;
133 LVTypeRecords(
LVShared *Shared) : Shared(Shared) {}
142classLVForwardReferences {
143// Forward reference and its definitions (Name as key). 144usingForwardEntry = std::pair<TypeIndex, TypeIndex>;
145usingForwardTypeNames = std::map<StringRef, ForwardEntry>;
146 ForwardTypeNames ForwardTypesNames;
148// Forward reference and its definition (TypeIndex as key). 149usingForwardType = std::map<TypeIndex, TypeIndex>;
150 ForwardType ForwardTypes;
152// Forward types and its references. 154 ForwardTypes.emplace(TIForward, TIReference);
158if (ForwardTypesNames.find(
Name) == ForwardTypesNames.end()) {
159 ForwardTypesNames.emplace(
160 std::piecewise_construct, std::forward_as_tuple(
Name),
163// Update a recorded definition with its reference. 164 ForwardTypesNames[
Name].first = TIForward;
165 add(TIForward, ForwardTypesNames[
Name].second);
169// Update a previously recorded forward reference with its definition. 171auto It = ForwardTypesNames.find(
Name);
172if (It != ForwardTypesNames.end()) {
173// Update the recorded forward reference with its definition. 174 It->second.second = TIReference;
175 add(It->second.first, TIReference);
177// We have not seen the forward reference. Insert the definition. 178 ForwardTypesNames.emplace(
179 std::piecewise_construct, std::forward_as_tuple(
Name),
185 LVForwardReferences() =
default;
188// We are expecting for the forward references to be first. But that 189// is not always the case. A name must be recorded regardless of the 190// order in which the forward reference appears. 191 (IsForwardRef) ? add(
Name, TI) : update(
Name, TI);
195auto It = ForwardTypes.find(TIForward);
200auto It = ForwardTypesNames.find(
Name);
201return It != ForwardTypesNames.end() ? It->second.second
205// If the given TI corresponds to a reference, return the reference. 206// Otherwise return the given TI. 213// Namespace deduction. 214classLVNamespaceDeduction {
217usingNames = std::map<StringRef, LVScope *>;
218 Names NamespaceNames;
220usingLookupSet = std::set<StringRef>;
221 LookupSet DeducedScopes;
222 LookupSet UnresolvedScopes;
223 LookupSet IdentifiedNamespaces;
226if (NamespaceNames.find(
Name) == NamespaceNames.end())
227 NamespaceNames.emplace(
Name, Namespace);
231 LVNamespaceDeduction(
LVShared *Shared) : Shared(Shared) {}
238// Find the logical namespace for the 'Name' component. 240auto It = NamespaceNames.find(
Name);
241LVScope *Namespace = It != NamespaceNames.end() ? It->second :
nullptr;
245// For the given lexical components, return a tuple with the first entry 246// being the outermost namespace and the second entry being the first 249if (Components.empty())
252 LVStringRefs::size_type FirstNamespace = 0;
253 LVStringRefs::size_type FirstNonNamespace;
254for (LVStringRefs::size_type Index = 0; Index < Components.size();
256 FirstNonNamespace = Index;
257 LookupSet::iterator Iter = IdentifiedNamespaces.find(Components[Index]);
258if (Iter == IdentifiedNamespaces.end())
259// The component is not a namespace name. 262return std::make_tuple(FirstNamespace, FirstNonNamespace);
267classLVStringRecords {
268usingStringEntry = std::tuple<uint32_t, std::string, LVScopeCompileUnit *>;
269usingStringIds = std::map<TypeIndex, StringEntry>;
273 LVStringRecords() =
default;
277if (Strings.find(TI) == Strings.end())
279 std::piecewise_construct, std::forward_as_tuple(TI),
280 std::forward_as_tuple(++Index, std::string(
String),
nullptr));
284 StringIds::iterator Iter = Strings.find(TI);
285return Iter != Strings.end() ? std::get<1>(Iter->second) :
StringRef{};
289 StringIds::iterator Iter = Strings.find(TI);
290return Iter != Strings.end() ? std::get<0>(Iter->second) : 0;
293// Move strings representing the filenames to the compile unit. 302// The following data keeps forward information, type records, names for 303// namespace deduction, strings records, line records. 304// It is shared by the type visitor, symbol visitor and logical visitor and 305// it is independent from the CodeViewReader. 315// In order to determine which types and/or symbols records should be handled 316// by the reader, we record record kinds seen by the type and symbol visitors. 317// At the end of the scopes creation, the '--internal=tag' option will allow 318// to print the unique record ids collected. 327}
// namespace logicalview 333 (StreamIdx ==
StreamTPI) ? RecordFromTypes : RecordFromIds;
334Target.emplace(std::piecewise_construct, std::forward_as_tuple(TI),
335 std::forward_as_tuple(
Kind, Element));
339 NameTable &
Target = (StreamIdx ==
StreamTPI) ? NameFromTypes : NameFromIds;
345 (StreamIdx ==
StreamTPI) ? RecordFromTypes : RecordFromIds;
348 RecordTable::iterator Iter =
Target.find(TI);
350 Element = Iter->second.second;
351if (Element || !Create)
354// Create the logical element if not found. 358 Element->setOffsetFromTypeIndex();
359Target[TI].second = Element;
366 NameTable &
Target = (StreamIdx ==
StreamTPI) ? NameFromTypes : NameFromIds;
371void LVStringRecords::addFilenames() {
372for (StringIds::const_reference Entry : Strings) {
381for (StringIds::reference Entry : Strings)
382if (!std::get<2>(
Entry.second))
390 DeducedScopes.insert(InnerComponent);
391if (OuterComponent.
size())
392 UnresolvedScopes.insert(OuterComponent);
395void LVNamespaceDeduction::init() {
396// We have 2 sets of names: 397// - deduced scopes (class, structure, union and enum) and 398// - unresolved scopes, that can represent namespaces or any deduced. 399// Before creating the namespaces, we have to traverse the unresolved 400// and remove any references to already deduced scopes. 402for (
constStringRef &Unresolved : UnresolvedScopes) {
404for (
constStringRef &Component : Components) {
405 LookupSet::iterator Iter = DeducedScopes.find(Component);
406if (Iter == DeducedScopes.end())
407 IdentifiedNamespaces.insert(Component);
412autoPrint = [&](LookupSet &Container,
constchar *Title) {
423Print(DeducedScopes,
"Deducted Scopes");
424Print(UnresolvedScopes,
"Unresolved Scopes");
425Print(IdentifiedNamespaces,
"Namespaces");
431for (
constStringRef &Component : Components)
435if (Components.empty())
438// Update the namespaces relationship. 441for (
constStringRef &Component : Components) {
442// Check if we have seen the namespace. 443 Namespace =
find(Component);
445// We have identified namespaces that are generated by MSVC. Mark them 446// as 'system' so they will be excluded from the logical view. 447 Namespace = Shared->
Reader->createScopeNamespace();
448 Namespace->
setTag(dwarf::DW_TAG_namespace);
452add(Component, Namespace);
463 LookupSet::iterator Iter = IdentifiedNamespaces.find(Component);
464return Iter == IdentifiedNamespaces.end();
468 {
dbgs() <<
formatv(
"ScopedName: '{0}'\n", ScopedName.
str().c_str()); });
470returnget(Components);
474#define DEBUG_TYPE "CodeViewTypeVisitor" 476//===----------------------------------------------------------------------===// 477// TypeRecord traversal. 478//===----------------------------------------------------------------------===// 498// The collected type records, will be use to create the logical elements 499// during the symbols traversal when a type is referenced. 500 CurrentTypeIndex = TI;
532// LF_BUILDINFO (TPI)/(IPI) 534// All the args are references into the TPI/IPI stream. 539 printTypeIndex(
"ArgType", Arg,
StreamIPI);
542// Only add the strings that hold information about filenames. They will be 543// used to complete the line/file information for the logical elements. 544// There are other strings holding information about namespaces. 549 TI = Args.getArgs()[BuildInfoRecord::BuildInfoArg::CurrentDirectory];
554// Get the compile unit name. 555 TI = Args.getArgs()[BuildInfoRecord::BuildInfoArg::SourceFile];
564// LF_CLASS, LF_STRUCTURE, LF_INTERFACE (TPI) 567 printTypeIndex(
"TypeIndex", CurrentTypeIndex,
StreamTPI);
572// Collect class name for scope deduction. 577// Collect class name for contained scopes deduction. 585 printTypeIndex(
"TypeIndex", CurrentTypeIndex,
StreamTPI);
586 printTypeIndex(
"FieldListType",
Enum.getFieldList(),
StreamTPI);
590// Collect enum name for scope deduction. 595// LF_FUNC_ID (TPI)/(IPI) 598 printTypeIndex(
"TypeIndex", CurrentTypeIndex,
StreamTPI);
599 printTypeIndex(
"Type", Func.getFunctionType(),
StreamTPI);
600 printTypeIndex(
"Parent", Func.getParentScope(),
StreamTPI);
604// Collect function name for scope deduction. 612 printTypeIndex(
"TypeIndex", CurrentTypeIndex,
StreamTPI);
618// Collect procedure information as they can be referenced by typedefs. 623// LF_STRING_ID (TPI)/(IPI) 625// No additional references are needed. 633// LF_UDT_SRC_LINE (TPI)/(IPI) 636// UDT and SourceFile are references into the TPI/IPI stream. 658// Collect union name for scope deduction. 663// Collect class name for contained scopes deduction. 669#define DEBUG_TYPE "CodeViewSymbolVisitor" 671//===----------------------------------------------------------------------===// 672// SymbolRecord traversal. 673//===----------------------------------------------------------------------===// 678 Reader->printRelocatedField(
Label, CoffSection, RelocOffset,
Offset,
699return Reader->CVStringTable;
702void LVSymbolVisitor::printLocalVariableAddrRange(
712void LVSymbolVisitor::printLocalVariableAddrGap(
716 W.
printHex(
"GapStartOffset", Gap.GapStartOffset);
742// We have an unsupported Symbol or Type Record. 743// W.printEnum("Kind ignored", unsigned(Kind), getSymbolTypeNames()); 748// Offset carried by the traversal routines when dealing with streams. 750 IsCompileUnit =
false;
798if (
options().getGeneralCollectRanges()) {
799// Record converted segment::offset addressing for this scope. 804 Scope->addObject(LowPC, HighPC);
815 printTypeIndex(
"Type",
Local.Type);
821 Symbol->setName(
Local.Name);
822// From the MS_Symbol_Type.pdf documentation (S_BPREL32): 823// This symbol specifies symbols that are allocated on the stack for a 824// procedure. For C and C++, these include the actual function parameters 825// and the local non-static variables of functions. 826// However, the offset for 'this' comes as a negative value. 828// Symbol was created as 'variable'; determine its real kind. 829 Symbol->resetIsVariable();
831if (
Local.Name ==
"this") {
832 Symbol->setIsParameter();
833 Symbol->setIsArtificial();
835// Determine symbol kind. 836bool(
Local.Offset > 0) ? Symbol->setIsParameter()
837 : Symbol->setIsVariable();
840// Update correct debug information tag. 841if (Symbol->getIsParameter())
842 Symbol->setTag(dwarf::DW_TAG_formal_parameter);
845if (Element && Element->getIsScoped()) {
846// We have a local type. Find its parent function. 847LVScope *Parent = Symbol->getFunctionParent();
848// The element representing the type has been already finalized. If 849// the type is an aggregate type, its members have been already added. 850// As the type is local, its level will be changed. 852// FIXME: Currently the algorithm used to scope lambda functions is 853// incorrect. Before we allocate the type at this scope, check if is 854// already allocated in other scope. 860 Symbol->setType(Element);
870 printTypeIndex(
"Type",
Local.Type);
876 Symbol->setName(
Local.Name);
878// Symbol was created as 'variable'; determine its real kind. 879 Symbol->resetIsVariable();
881// Check for the 'this' symbol. 882if (
Local.Name ==
"this") {
883 Symbol->setIsArtificial();
884 Symbol->setIsParameter();
886// Determine symbol kind. 887 determineSymbolKind(Symbol,
Local.Register);
890// Update correct debug information tag. 891if (Symbol->getIsParameter())
892 Symbol->setTag(dwarf::DW_TAG_formal_parameter);
895if (Element && Element->getIsScoped()) {
896// We have a local type. Find its parent function. 897LVScope *Parent = Symbol->getFunctionParent();
898// The element representing the type has been already finalized. If 899// the type is an aggregate type, its members have been already added. 900// As the type is local, its level will be changed. 902// FIXME: Currently the algorithm used to scope lambda functions is 903// incorrect. Before we allocate the type at this scope, check if is 904// already allocated in other scope. 910 Symbol->setType(Element);
941// MSVC generates the following sequence for a CodeView module: 942// S_OBJNAME --> Set 'CurrentObjectName'. 943// S_COMPILE2 --> Set the compile unit name using 'CurrentObjectName'. 945// S_BUILDINFO --> Extract the source name. 947// Clang generates the following sequence for a CodeView module: 948// S_COMPILE2 --> Set the compile unit name to empty string. 950// S_BUILDINFO --> Extract the source name. 952// For both toolchains, update the compile unit name from S_BUILDINFO. 954// The name of the CU, was extracted from the 'BuildInfo' subsection. 956 Scope->setName(CurrentObjectName);
957if (
options().getAttributeProducer())
958 Scope->setProducer(Compile2.
Version);
961// The line records in CodeView are recorded per Module ID. Update 962// the relationship between the current CU and the Module ID. 965// Updated the collected strings with their associated compile unit. 969// Clear any previous ObjectName. 970 CurrentObjectName =
"";
986// MSVC generates the following sequence for a CodeView module: 987// S_OBJNAME --> Set 'CurrentObjectName'. 988// S_COMPILE3 --> Set the compile unit name using 'CurrentObjectName'. 990// S_BUILDINFO --> Extract the source name. 992// Clang generates the following sequence for a CodeView module: 993// S_COMPILE3 --> Set the compile unit name to empty string. 995// S_BUILDINFO --> Extract the source name. 997// For both toolchains, update the compile unit name from S_BUILDINFO. 999// The name of the CU, was extracted from the 'BuildInfo' subsection. 1001 Scope->setName(CurrentObjectName);
1002if (
options().getAttributeProducer())
1003 Scope->setProducer(Compile3.
Version);
1006// The line records in CodeView are recorded per Module ID. Update 1007// the relationship between the current CU and the Module ID. 1010// Updated the collected strings with their associated compile unit. 1014// Clear any previous ObjectName. 1015 CurrentObjectName =
"";
1019// S_CONSTANT, S_MANCONSTANT 1023 printTypeIndex(
"Type",
Constant.Type);
1031 Symbol->resetIncludeInPrint();
1037// S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE 1041// DefRanges don't have types, just registers and code offsets. 1049if (
LVSymbol *Symbol = LocalSymbol) {
1050 Symbol->setHasCodeViewLocation();
1051 LocalSymbol =
nullptr;
1053// Add location debug location. Operands: [Offset, 0]. 1058 Symbol->addLocation(Attr, 0, 0, 0, 0);
1059 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1});
1065// S_DEFRANGE_FRAMEPOINTER_REL 1068// DefRanges don't have types, just registers and code offsets. 1074 printLocalVariableAddrRange(DefRangeFramePointerRel.
Range,
1076 printLocalVariableAddrGap(DefRangeFramePointerRel.
Gaps);
1079// We are expecting the following sequence: 1080// 128 | S_LOCAL [size = 20] `ParamBar` 1082// 148 | S_DEFRANGE_FRAMEPOINTER_REL [size = 16] 1083if (
LVSymbol *Symbol = LocalSymbol) {
1084 Symbol->setHasCodeViewLocation();
1085 LocalSymbol =
nullptr;
1087// Add location debug location. Operands: [Offset, 0]. 1097 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1});
1103// S_DEFRANGE_REGISTER_REL 1106// DefRanges don't have types, just registers and code offsets. 1116 printLocalVariableAddrRange(DefRangeRegisterRel.
Range,
1118 printLocalVariableAddrGap(DefRangeRegisterRel.
Gaps);
1121if (
LVSymbol *Symbol = LocalSymbol) {
1122 Symbol->setHasCodeViewLocation();
1123 LocalSymbol =
nullptr;
1125// Add location debug location. Operands: [Register, Offset]. 1136 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1, Operand2});
1142// S_DEFRANGE_REGISTER 1145// DefRanges don't have types, just registers and code offsets. 1153 printLocalVariableAddrRange(DefRangeRegister.
Range,
1155 printLocalVariableAddrGap(DefRangeRegister.
Gaps);
1158if (
LVSymbol *Symbol = LocalSymbol) {
1159 Symbol->setHasCodeViewLocation();
1160 LocalSymbol =
nullptr;
1162// Add location debug location. Operands: [Register, 0]. 1171 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1});
1177// S_DEFRANGE_SUBFIELD_REGISTER 1180// DefRanges don't have types, just registers and code offsets. 1190 printLocalVariableAddrRange(DefRangeSubfieldRegister.
Range,
1192 printLocalVariableAddrGap(DefRangeSubfieldRegister.
Gaps);
1195if (
LVSymbol *Symbol = LocalSymbol) {
1196 Symbol->setHasCodeViewLocation();
1197 LocalSymbol =
nullptr;
1199// Add location debug location. Operands: [Register, 0]. 1209 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1});
1215// S_DEFRANGE_SUBFIELD 1218// DefRanges don't have types, just registers and code offsets. 1225auto ExpectedProgram = Strings.getString(DefRangeSubfield.
Program);
1226if (!ExpectedProgram) {
1228return llvm::make_error<CodeViewError>(
1229"String table offset outside of bounds of String Table!");
1234 printLocalVariableAddrRange(DefRangeSubfield.
Range,
1236 printLocalVariableAddrGap(DefRangeSubfield.
Gaps);
1239if (
LVSymbol *Symbol = LocalSymbol) {
1240 Symbol->setHasCodeViewLocation();
1241 LocalSymbol =
nullptr;
1243// Add location debug location. Operands: [Program, 0]. 1252 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1,
/*Operand2=*/0});
1261// DefRanges don't have types, just registers and code offsets. 1268auto ExpectedProgram = Strings.getString(DefRange.
Program);
1269if (!ExpectedProgram) {
1271return llvm::make_error<CodeViewError>(
1272"String table offset outside of bounds of String Table!");
1277 printLocalVariableAddrGap(DefRange.
Gaps);
1280if (
LVSymbol *Symbol = LocalSymbol) {
1281 Symbol->setHasCodeViewLocation();
1282 LocalSymbol =
nullptr;
1284// Add location debug location. Operands: [Program, 0]. 1293 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1,
/*Operand2=*/0});
1303// S_FRAMEPROC contains extra information for the function described 1304// by any of the previous generated records: 1305// S_GPROC32, S_LPROC32, S_LPROC32_ID, S_GPROC32_ID. 1307// The generated sequence is: 1311// Collect additional inline flags for the current scope function. 1313if (FrameProcedureOptions::MarkedInline ==
1314 (Flags & FrameProcedureOptions::MarkedInline))
1316if (FrameProcedureOptions::Inlined ==
1317 (Flags & FrameProcedureOptions::Inlined))
1320// To determine the symbol kind for any symbol declared in that function, 1321// we can access the S_FRAMEPROC for the parent scope function. It contains 1322// information about the local fp and param fp registers and compare with 1323// the register in the S_REGREL32 to get a match. 1332// S_GDATA32, S_LDATA32, S_LMANDATA, S_GMANDATA 1335 printTypeIndex(
"Type",
Data.Type);
1345 Symbol->setName(
Data.Name);
1348// The MSVC generates local data as initialization for aggregates. It 1349// contains the address for an initialization function. 1350// The symbols contains the '$initializer$' pattern. Allow them only if 1351// the '--internal=system' option is given. 1352// 0 | S_LDATA32 `Struct$initializer$` 1353// type = 0x1040 (void ()*) 1355 Symbol->resetIncludeInPrint();
1360// The variable is already at different scope. In order to reflect 1361// the correct parent, move it to the namespace. 1362if (Symbol->getParentScope()->removeElement(Symbol))
1367if (
Record.kind() == SymbolKind::S_GDATA32)
1368 Symbol->setIsExternal();
1380LVScope *AbstractFunction = Reader->createScopeFunction();
1381 AbstractFunction->setIsSubprogram();
1382 AbstractFunction->
setTag(dwarf::DW_TAG_subprogram);
1384 AbstractFunction->setIsInlinedAbstract();
1388// 'Inlinee' is a Type ID. 1391 CVFunctionType,
InlineSite.Inlinee, AbstractFunction))
1395// For inlined functions set the linkage name to be the same as 1396// the name. It used to find their lines and ranges. 1398 InlinedFunction->setName(
Name);
1399 InlinedFunction->setLinkageName(
Name);
1401// Process annotation bytes to calculate code and line offsets. 1403 AbstractFunction, InlinedFunction,
InlineSite))
1413 printTypeIndex(
"Type",
Local.Type);
1419 Symbol->setName(
Local.Name);
1421// Symbol was created as 'variable'; determine its real kind. 1422 Symbol->resetIsVariable();
1424// Be sure the 'this' symbol is marked as 'compiler generated'. 1425if (
bool(
Local.Flags & LocalSymFlags::IsCompilerGenerated) ||
1426Local.Name ==
"this") {
1427 Symbol->setIsArtificial();
1428 Symbol->setIsParameter();
1430bool(
Local.Flags & LocalSymFlags::IsParameter) ? Symbol->setIsParameter()
1431 : Symbol->setIsVariable();
1434// Update correct debug information tag. 1435if (Symbol->getIsParameter())
1436 Symbol->setTag(dwarf::DW_TAG_formal_parameter);
1439if (Element && Element->getIsScoped()) {
1440// We have a local type. Find its parent function. 1441LVScope *Parent = Symbol->getFunctionParent();
1442// The element representing the type has been already finalized. If 1443// the type is an aggregate type, its members have been already added. 1444// As the type is local, its level will be changed. 1448 Symbol->setType(Element);
1450// The CodeView records (S_DEFFRAME_*) describing debug location for 1451// this symbol, do not have any direct reference to it. Those records 1452// are emitted after this symbol. Record the current symbol. 1453 LocalSymbol = Symbol;
1466 CurrentObjectName = ObjName.
Name;
1470// S_GPROC32, S_LPROC32, S_LPROC32_ID, S_GPROC32_ID 1473return llvm::make_error<CodeViewError>(
"Visiting a ProcSym while inside " 1476 InFunctionScope =
true;
1486// Clang and Microsoft generated different debug information records: 1487// For functions definitions: 1488// Clang: S_GPROC32 -> LF_FUNC_ID -> LF_PROCEDURE 1489// Microsoft: S_GPROC32 -> LF_PROCEDURE 1491// For member function definition: 1492// Clang: S_GPROC32 -> LF_MFUNC_ID -> LF_MFUNCTION 1493// Microsoft: S_GPROC32 -> LF_MFUNCTION 1494// In order to support both sequences, if we found LF_FUNCTION_ID, just 1495// get the TypeIndex for LF_PROCEDURE. 1497// For the given test case, we have the sequence: 1498// namespace NSP_local { 1499// void foo_local() { 1503// 0x1000 | LF_STRING_ID String: NSP_local 1504// 0x1002 | LF_PROCEDURE 1505// return type = 0x0003 (void), # args = 0, param list = 0x1001 1506// calling conv = cdecl, options = None 1507// 0x1003 | LF_FUNC_ID 1508// name = foo_local, type = 0x1002, parent scope = 0x1000 1509// 0 | S_GPROC32_ID `NSP_local::foo_local` 1510// type = `0x1003 (foo_local)` 1511// 0x1004 | LF_STRING_ID String: suite 1512// 0x1005 | LF_STRING_ID String: suite_local.cpp 1514// The LF_STRING_ID can hold different information: 1515// 0x1000 - The enclosing namespace. 1516// 0x1004 - The compile unit directory name. 1517// 0x1005 - The compile unit name. 1519// Before deducting its scope, we need to evaluate its type and create any 1520// associated namespaces. 1527// The line table can be accessed using the linkage name. 1532if (
options().getGeneralCollectRanges()) {
1533// Record converted segment::offset addressing for this scope. 1540// If the scope is a function, add it to the public names. 1541if ((
options().getAttributePublics() ||
options().getPrintAnyLine()) &&
1555// We have to detect the correct stream, using the lexical parent 1556// name, as there is not other obvious way to get the stream. 1557// Normal function: LF_FUNC_ID (TPI)/(IPI) 1558// LF_PROCEDURE (TPI) 1559// Lambda function: LF_MFUNCTION (TPI) 1560// Member function: LF_MFUNC_ID (TPI)/(IPI) 1566 std::optional<CVType> CVFunctionType;
1567auto GetRecordType = [&]() ->
bool {
1568 CVFunctionType = Ids.
tryGetType(TIFunctionType);
1574if (CVFunctionType->kind() == LF_FUNC_ID)
1578return (CVFunctionType->kind() == LF_MFUNC_ID);
1581// We can have a LF_FUNC_ID, LF_PROCEDURE or LF_MFUNCTION. 1582if (!GetRecordType()) {
1583 CVFunctionType = Types.
tryGetType(TIFunctionType);
1585return llvm::make_error<CodeViewError>(
"Invalid type index");
1589 *CVFunctionType, TIFunctionType,
Function))
1593if (
Record.kind() == SymbolKind::S_GPROC32 ||
1594Record.kind() == SymbolKind::S_GPROC32_ID)
1597// We don't have a way to see if the symbol is compiler generated. Use 1598// the linkage name, to detect `scalar deleting destructor' functions. 1600if (DemangledSymbol.find(
"scalar deleting dtor") != std::string::npos) {
1603// Clang generates global ctor and dtor names containing the substrings: 1604// 'dynamic initializer for' and 'dynamic atexit destructor for'. 1605if (DemangledSymbol.find(
"dynamic atexit destructor for") !=
1617 InFunctionScope =
false;
1624return llvm::make_error<CodeViewError>(
"Visiting a Thunk32Sym while inside " 1627 InFunctionScope =
true;
1643 printTypeIndex(
"Type",
UDT.Type);
1649if (
Type->getParentScope()->removeElement(
Type))
1655// We have to determine if the typedef is a real C/C++ definition or is 1656// the S_UDT record that describe all the user defined types. 1657// 0 | S_UDT `Name` original type = 0x1009 1658// 0x1009 | LF_STRUCTURE `Name` 1659// Ignore type definitions for RTTI types: 1660// _s__RTTIBaseClassArray, _s__RTTIBaseClassDescriptor, 1661// _s__RTTICompleteObjectLocator, _s__RTTIClassHierarchyDescriptor. 1663Type->resetIncludeInPrint();
1666if (
UDT.Name == RecordName)
1667Type->resetIncludeInPrint();
1686 W.
printHex(
"BaseOffset", JumpTable.BaseOffset);
1687 W.
printNumber(
"BaseSegment", JumpTable.BaseSegment);
1690 W.
printHex(
"BranchOffset", JumpTable.BranchOffset);
1691 W.
printHex(
"TableOffset", JumpTable.TableOffset);
1692 W.
printNumber(
"BranchSegment", JumpTable.BranchSegment);
1693 W.
printNumber(
"TableSegment", JumpTable.TableSegment);
1694 W.
printNumber(
"EntriesCount", JumpTable.EntriesCount);
1699// S_CALLERS, S_CALLEES, S_INLINEES 1703switch (
Caller.getKind()) {
1704 case SymbolRecordKind::CallerSym:
1705 FieldName =
"Callee";
1707 case SymbolRecordKind::CalleeSym:
1708 FieldName =
"Caller";
1710 case SymbolRecordKind::InlineesSym:
1711 FieldName =
"Inlinee";
1714 return llvm::make_error<CodeViewError>(
1715"Unknown CV Record type for a CallerSym object!");
1718 printTypeIndex(FieldName, FuncID);
1725#define DEBUG_TYPE "CodeViewLogicalVisitor" 1727//===----------------------------------------------------------------------===// 1729//===----------------------------------------------------------------------===// 1732 : Reader(Reader), W(W), Input(Input) {
1733// The LogicalVisitor connects the CodeViewReader with the visitors that 1734// traverse the types, symbols, etc. Do any initialization that is needed. 1735 Shared = std::make_shared<LVShared>(Reader,
this);
1741 StreamIdx ==
StreamTPI ? types() : ids());
1805TypeIndex ParameterType = Indices[Index];
1824if (Element->getIsFinalized())
1826 Element->setIsFinalized();
1835LVType *PrevSubrange =
nullptr;
1838// As the logical view is modeled on DWARF, for each dimension we have to 1839// create a DW_TAG_subrange_type, with dimension size. 1840// The subrange type can be: unsigned __int32 or unsigned __int64. 1843Subrange->setTag(dwarf::DW_TAG_subrange_type);
1853if (int64_t Count =
Subrange->getCount())
1858// Preserve the original TypeIndex; it would be updated in the case of: 1859// - The array type contains qualifiers. 1860// - In multidimensional arrays, the last LF_ARRAY entry contains the type. 1863// For each dimension in the array, there is a LF_ARRAY entry. The last 1864// entry contains the array type, which can be a LF_MODIFIER in the case 1865// of the type being modified by a qualifier (const, etc). 1868while (CVEntry.
kind() == LF_ARRAY) {
1869// Create the subrange information, required by the logical view. Once 1870// the array has been processed, the dimension sizes will updated, as 1871// the sizes are a progression. For instance: 1873// int Array[2]; Sizes: 8 Dim: 8 / 4 -> [2] 1874// int Array[2][3]; Sizes: 24, 12 Dim: 24 / 12 -> [2] 1875// Dim: 12 / 4 -> [3] 1876// int Array[2][3][4]; sizes: 96, 48, 16 Dim: 96 / 48 -> [2] 1877// Dim: 48 / 16 -> [3] 1878// Dim: 16 / 4 -> [4] 1879 AddSubrangeType(AR);
1880 TIArrayType = TIElementType;
1882// The current ElementType can be a modifier, in which case we need to 1883// get the type being modified. 1884// If TypeIndex is not a simple type, check if we have a qualified type. 1886CVType CVElementType =
Types.getType(TIElementType);
1887if (CVElementType.
kind() == LF_MODIFIER) {
1889 Shared->TypeRecords.find(
StreamTPI, TIElementType);
1893// Get the TypeIndex of the type that the LF_MODIFIER modifies. 1897// Ends the traversal, as we have reached a simple type (int, char, etc). 1901// Read next dimension linked entry, if any. 1902 CVEntry =
Types.getType(TIElementType);
1904const_cast<CVType &
>(CVEntry), AR)) {
1909// NOTE: The typeindex has a value of: 0x0280.0000 1914 TIArrayType = Shared->ForwardReferences.remap(TIArrayType);
1918// In the case of an aggregate type (class, struct, union, interface), 1919// get the aggregate size. As the original record is pointing to its 1920// reference, we have to update it. 1946// LF_BUILDINFO (TPI)/(IPI) 1958// The given 'Element' refers to the current compilation unit. 1959// All the args are references into the TPI/IPI stream. 1963// There are cases where LF_BUILDINFO fields are empty. 1970// LF_CLASS, LF_STRUCTURE, LF_INTERFACE (TPI) 1981if (
Class.hasUniqueName())
1986if (Element->getIsFinalized())
1988 Element->setIsFinalized();
1994 Scope->setName(
Class.getName());
1995if (
Class.hasUniqueName())
1996 Scope->setLinkageName(
Class.getUniqueName());
1998if (
Class.isNested()) {
1999 Scope->setIsNested();
2000 createParents(
Class.getName(), Scope);
2003if (
Class.isScoped())
2004 Scope->setIsScoped();
2006// Nested types will be added to their parents at creation. The forward 2007// references are only processed to finish the referenced element creation. 2009if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
Class.getName()))
2018TypeIndex ForwardType = Shared->ForwardReferences.find(
Class.getName());
2024const_cast<CVType &
>(CVReference), ReferenceRecord))
2031// Pass down the TypeIndex 'TI' for the aggregate containing the field list. 2056if (Scope->getIsFinalized())
2058 Scope->setIsFinalized();
2060// Set the name, as in the case of nested, it would determine the relation 2061// to any potential parent, via the LF_NESTTYPE record. 2062 Scope->setName(
Enum.getName());
2063if (
Enum.hasUniqueName())
2064 Scope->setLinkageName(
Enum.getUniqueName());
2068if (
Enum.isNested()) {
2069 Scope->setIsNested();
2070 createParents(
Enum.getName(), Scope);
2073if (
Enum.isScoped()) {
2074 Scope->setIsScoped();
2075 Scope->setIsEnumClass();
2078// Nested types will be added to their parents at creation. 2079if (!(
Enum.isNested() ||
Enum.isScoped())) {
2080if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
Enum.getName()))
2097// LF_FIELDLIST (TPI) 2106if (
Error Err = visitFieldListMemberStream(TI, Element,
FieldList.Data))
2112// LF_FUNC_ID (TPI)/(IPI) 2115// ParentScope and FunctionType are references into the TPI stream. 2124// The TypeIndex (LF_PROCEDURE) returned by 'getFunctionType' is the 2125// function propotype, we need to use the function definition. 2127// For inlined functions, the inlined instance has been already processed 2128// (all its information is contained in the Symbols section). 2129// 'Element' points to the created 'abstract' (out-of-line) function. 2130// Use the parent scope information to allocate it to the correct scope. 2132TypeIndex TIParent = Func.getParentScope();
2133if (FunctionDcl->getIsInlinedAbstract()) {
2134 FunctionDcl->setName(Func.getName());
2145TypeIndex TIFunctionType = Func.getFunctionType();
2146CVType CVFunctionType =
Types.getType(TIFunctionType);
2151 FunctionDcl->setIsFinalized();
2167// LF_MFUNC_ID (TPI)/(IPI) 2170// ClassType and FunctionType are references into the TPI stream. 2180if (FunctionDcl->getIsInlinedAbstract()) {
2181// For inlined functions, the inlined instance has been already processed 2182// (all its information is contained in the Symbols section). 2183// 'Element' points to the created 'abstract' (out-of-line) function. 2184// Use the parent scope information to allocate it to the correct scope. 2186 Shared->TypeRecords.find(
StreamTPI, Id.getClassType())))
2187Class->addElement(FunctionDcl);
2190TypeIndex TIFunctionType = Id.getFunctionType();
2198// LF_MFUNCTION (TPI) 2216 MemberFunction->setIsFinalized();
2218 MemberFunction->setOffset(TI.
getIndex());
2219 MemberFunction->setOffsetFromTypeIndex();
2221if (ProcessArgumentList) {
2222 ProcessArgumentList =
false;
2224if (!MemberFunction->getIsStatic()) {
2226// When creating the 'this' pointer, check if it points to a reference. 2229 createParameter(ThisPointer,
StringRef(), MemberFunction);
2230This->setIsArtificial();
2233// Create formal parameters. 2245// LF_METHODLIST (TPI) 2257 Method.
Name = OverloadedMethodName;
2274// Create the modified type, which will be attached to the type(s) that 2275// contains the modifiers. 2278// At this point the types recording the qualifiers do not have a 2279// scope parent. They must be assigned to the current compile unit. 2282// The incoming element does not have a defined kind. Use the given 2283// modifiers to complete its type. A type can have more than one modifier; 2284// in that case, we have to create an extra type to have the other modifier. 2289bool SeenModifier =
false;
2291if (Mods &
uint16_t(ModifierOptions::Const)) {
2293 LastLink->
setTag(dwarf::DW_TAG_const_type);
2294 LastLink->setIsConst();
2297if (Mods &
uint16_t(ModifierOptions::Volatile)) {
2305 LastLink->
setTag(dwarf::DW_TAG_volatile_type);
2306 LastLink->setIsVolatile();
2307 LastLink->
setName(
"volatile");
2309if (Mods &
uint16_t(ModifierOptions::Unaligned)) {
2318 LastLink->setIsUnaligned();
2319 LastLink->
setName(
"unaligned");
2322 LastLink->
setType(ModifiedType);
2341if (
Ptr.isPointerToMember()) {
2348// Find the pointed-to type. 2353 Pointee =
Ptr.isPointerToMember()
2354 ? Shared->TypeRecords.find(
StreamTPI,
Ptr.getReferentType())
2357// At this point the types recording the qualifiers do not have a 2358// scope parent. They must be assigned to the current compile unit. 2361// Order for the different modifiers: 2362// <restrict> <pointer, Reference, ValueReference> <const, volatile> 2363// Const and volatile already processed. 2364bool SeenModifier =
false;
2369if (
Ptr.isRestrict()) {
2372Restrict->setTag(dwarf::DW_TAG_restrict_type);
2379if (Mode == PointerMode::LValueReference) {
2381LVType *LReference = Reader->createType();
2382 LReference->setIsModifier();
2383 LastLink->
setType(LReference);
2384 LastLink = LReference;
2387 LastLink->
setTag(dwarf::DW_TAG_reference_type);
2388 LastLink->setIsReference();
2391if (Mode == PointerMode::RValueReference) {
2393LVType *RReference = Reader->createType();
2394 RReference->setIsModifier();
2395 LastLink->
setType(RReference);
2396 LastLink = RReference;
2399 LastLink->
setTag(dwarf::DW_TAG_rvalue_reference_type);
2400 LastLink->setIsRvalueReference();
2404// When creating the pointer, check if it points to a reference. 2409// LF_PROCEDURE (TPI) 2420// There is no need to traverse the argument list, as the CodeView format 2421// declares the parameters as a 'S_LOCAL' symbol tagged as parameter. 2422// Only process parameters when dealing with inline functions. 2426if (ProcessArgumentList) {
2427 ProcessArgumentList =
false;
2428// Create formal parameters. 2449if (
Union.hasUniqueName())
2458if (Scope->getIsFinalized())
2460 Scope->setIsFinalized();
2462 Scope->setName(
Union.getName());
2463if (
Union.hasUniqueName())
2464 Scope->setLinkageName(
Union.getUniqueName());
2466if (
Union.isNested()) {
2467 Scope->setIsNested();
2468 createParents(
Union.getName(), Scope);
2470if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
Union.getName()))
2476if (!
Union.getFieldList().isNoneType()) {
2478// Pass down the TypeIndex 'TI' for the aggregate containing the field list. 2487// LF_TYPESERVER2 (TPI) 2528// LF_SUBSTR_LIST (TPI)/(IPI) 2532// All the indices are references into the TPI/IPI stream. 2546// LF_STRING_ID (TPI)/(IPI) 2549// All args are references into the TPI/IPI stream. 2556if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
2557String.getString(),
/*CheckScope=*/false)) {
2558// The function is already at different scope. In order to reflect 2559// the correct parent, move it to the namespace. 2561 Scope->removeElement(Element);
2568// LF_UDT_SRC_LINE (TPI)/(IPI) 2572// All args are references into the TPI/IPI stream. 2582// LF_UDT_MOD_SRC_LINE (TPI)/(IPI) 2586// All args are references into the TPI/IPI stream. 2613// LF_ENDPRECOMP (TPI) 2631// LF_BCLASS, LF_BINTERFACE 2647 Symbol->setAccessibilityCode(
Base.getAccess());
2666// Create the data member. 2687Enum.getValue().toString(
Value, 16,
true,
true);
2725if (NestedType && NestedType->getIsNested()) {
2726// 'Element' is an aggregate type that may contains this nested type 2727// definition. Used their scoped names, to decide on their relationship. 2731if (NestedTypeName.
size() && RecordName.
size()) {
2733 std::tie(OuterComponent, std::ignore) =
2735// We have an already created nested type. Add it to the current scope 2736// and update all its children if any. 2737if (OuterComponent.
size() && OuterComponent == RecordName) {
2738if (!NestedType->getIsScopedAlready()) {
2739 Scope->addElement(NestedType);
2740 NestedType->setIsScopedAlready();
2743Typedef->resetIncludeInPrint();
2759// If virtual, then read the vftable offset. 2766// All the LF_ONEMETHOD objects share the same type description. 2767// We have to create a scope object for each one and get the required 2768// information from the LF_MFUNCTION object. 2769 ProcessArgumentList =
true;
2771 MemberFunction->setIsFinalized();
2774 MemberFunction->setName(Method.
getName());
2775 MemberFunction->setAccessibilityCode(Method.
getAccess());
2778if (
Kind == MethodKind::Static)
2779 MemberFunction->setIsStatic();
2780 MemberFunction->setVirtualityCode(
Kind);
2783if (MethodOptions::CompilerGenerated ==
2784 (Flags & MethodOptions::CompilerGenerated))
2785 MemberFunction->setIsArtificial();
2793 ProcessArgumentList =
false;
2810// Record the overloaded method name, which will be used during the 2811// traversal of the method list. 2813 OverloadedMethodName = Method.
getName();
2832// Create the data member. 2850// LF_VBCLASS, LF_IVBCLASS 2868 Symbol->setAccessibilityCode(
Base.getAccess());
2869 Symbol->setVirtualityCode(MethodKind::Virtual);
2887#define MEMBER_RECORD(EnumName, EnumVal, Name) \ 2890 visitKnownMember<Name##Record>(Record, Callbacks, TI, Element)) \ 2894#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \ 2895 MEMBER_RECORD(EnumVal, EnumVal, AliasName) 2896#define TYPE_RECORD(EnumName, EnumVal, Name) 2897#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) 2898#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" 2914#define TYPE_RECORD(EnumName, EnumVal, Name) \ 2916 if (Error Err = visitKnownRecord<Name##Record>(Record, TI, Element)) \ 2920#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \ 2921 TYPE_RECORD(EnumVal, EnumVal, AliasName) 2922#define MEMBER_RECORD(EnumName, EnumVal, Name) 2923#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) 2924#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" 2930// Customized version of 'FieldListVisitHelper'. 2931Error LVLogicalVisitor::visitFieldListMemberStream(
2940while (!Reader.empty()) {
2941if (
Error Err = Reader.readEnum(Leaf))
2954// The CodeView specifications does not treat S_COMPILE2 and S_COMPILE3 2955// as symbols that open a scope. The CodeView reader, treat them in a 2956// similar way as DWARF. As there is no a symbole S_END to close the 2957// compile unit, we need to check for the next compile unit. 2959if (!ScopeStack.empty())
2961 InCompileUnitScope =
true;
2985if (
options().getAttributeBase())
2992case TypeLeafKind::LF_ENUMERATE:
2996case TypeLeafKind::LF_MODIFIER:
3000case TypeLeafKind::LF_POINTER:
3008case TypeLeafKind::LF_BCLASS:
3009case TypeLeafKind::LF_IVBCLASS:
3010case TypeLeafKind::LF_VBCLASS:
3015case TypeLeafKind::LF_MEMBER:
3016case TypeLeafKind::LF_STMEMBER:
3023case TypeLeafKind::LF_ARRAY:
3027case TypeLeafKind::LF_CLASS:
3032case TypeLeafKind::LF_ENUM:
3036case TypeLeafKind::LF_METHOD:
3037case TypeLeafKind::LF_ONEMETHOD:
3038case TypeLeafKind::LF_PROCEDURE:
3043case TypeLeafKind::LF_STRUCTURE:
3048case TypeLeafKind::LF_UNION:
3054// If '--internal=tag' and '--print=warning' are specified in the command 3055// line, we record and print each seen 'TypeLeafKind'. 3067case SymbolKind::S_UDT:
3073case SymbolKind::S_CONSTANT:
3079case SymbolKind::S_BPREL32:
3080case SymbolKind::S_REGREL32:
3081case SymbolKind::S_GDATA32:
3082case SymbolKind::S_LDATA32:
3083case SymbolKind::S_LOCAL:
3084// During the symbol traversal more information is available to 3085// determine if the symbol is a parameter or a variable. At this 3086// stage mark it as variable. 3093case SymbolKind::S_BLOCK32:
3098case SymbolKind::S_COMPILE2:
3099case SymbolKind::S_COMPILE3:
3104case SymbolKind::S_INLINESITE:
3105case SymbolKind::S_INLINESITE2:
3110case SymbolKind::S_LPROC32:
3111case SymbolKind::S_GPROC32:
3112case SymbolKind::S_LPROC32_ID:
3113case SymbolKind::S_GPROC32_ID:
3114case SymbolKind::S_SEPCODE:
3115case SymbolKind::S_THUNK32:
3121// If '--internal=tag' and '--print=warning' are specified in the command 3122// line, we record and print each seen 'SymbolKind'. 3131// We are dealing with a base type or pointer to a base type, which are 3132// not included explicitly in the CodeView format. 3135 Element->setIsFinalized();
3140// We are dealing with a pointer to a base type. 3145 Element->setOffsetFromTypeIndex();
3156 Element->setOffsetFromTypeIndex();
3170 Symbol->setName(
Name);
3176if (CVMemberType.
kind() == LF_BITFIELD) {
3191LVSymbol *Parameter = Reader->createSymbol();
3193 Parameter->setIsParameter();
3194 Parameter->
setTag(dwarf::DW_TAG_formal_parameter);
3214returnstatic_cast<LVType *
>(Element);
3230returnstatic_cast<LVType *
>(Element);
3242// For the given test case: 3244// struct S { enum E { ... }; }; 3248// type=0x1004 (S::E), flags = none 3249// 0x1004 | LF_ENUM `S::E` 3250// options: has unique name | is nested 3251// 0x1009 | LF_STRUCTURE `S` 3252// options: contains nested class 3254// When the local 'V' is processed, its type 'E' is created. But There is 3255// no direct reference to its parent 'S'. We use the scoped name for 'E', 3256// to create its parents. 3258// The input scoped name must have at least parent and nested names. 3259// Drop the last element name, as it corresponds to the nested type. 3261if (Components.size() < 2)
3263 Components.pop_back();
3265 LVStringRefs::size_type FirstNamespace;
3266 LVStringRefs::size_type FirstAggregate;
3267 std::tie(FirstNamespace, FirstAggregate) =
3268 Shared->NamespaceDeduction.find(Components);
3271 W.
printString(
"First Namespace", Components[FirstNamespace]);
3272 W.
printString(
"First NonNamespace", Components[FirstAggregate]);
3275// Create any referenced namespaces. 3276if (FirstNamespace < FirstAggregate) {
3277 Shared->NamespaceDeduction.get(
3279 Components.begin() + FirstAggregate));
3282// Traverse the enclosing scopes (aggregates) and create them. In the 3283// case of nested empty aggregates, MSVC does not emit a full record 3284// description. It emits only the reference record. 3288LVStringRefs(Components.begin(), Components.begin() + FirstAggregate));
3290// This traversal is executed at least once. 3291for (LVStringRefs::size_type Index = FirstAggregate;
3294 Components.begin() + Index + 1),
3296 TIAggregate = Shared->ForwardReferences.remap(
3297 Shared->TypeRecords.find(
StreamTPI, AggregateName));
3304// Workaround for cases where LF_NESTTYPE is missing for nested templates. 3305// If we manage to get parent information from the scoped name, we can add 3306// the nested type without relying on the LF_NESTTYPE. 3307if (Aggregate && !Element->getIsScopedAlready()) {
3309 Element->setIsScopedAlready();
3316 TI = Shared->ForwardReferences.remap(TI);
3319LVElement *Element = Shared->TypeRecords.find(StreamIdx, TI);
3323// If the name ends with "*", create 2 logical types: a pointer and a 3324// pointee type. TypeIndex is composed of a SympleTypeMode byte followed 3325// by a SimpleTypeKind byte. The logical pointer will be identified by 3326// the full TypeIndex value and the pointee by the SimpleTypeKind. 3327return (TypeName.back() ==
'*') ? createPointerType(TI, TypeName)
3328 : createBaseType(TI, TypeName);
3335// The element has been finalized. 3336if (Element->getIsFinalized())
3339// Add the element in case of a given parent. 3343// Check for a composite type. 3350 Element->setIsFinalized();
3355// Traverse the collected LF_UDT_SRC_LINE records and add the source line 3356// information to the logical elements. 3357for (
constTypeIndex &Entry : Shared->LineRecords) {
3370// The TypeIndex returned by 'getUDT()' must point to an already 3371// created logical element. If no logical element is found, it means 3372// the LF_UDT_SRC_LINE is associated with a system TypeIndex. 3373if (
LVElement *Element = Shared->TypeRecords.find(
3377 Shared->StringRecords.findIndex(
Line.getSourceFile()));
3384// Create namespaces. 3385 Shared->NamespaceDeduction.init();
3391if (!
options().getInternalTag())
3396auto NewLine = [&]() {
3409 Shared->TypeKinds.clear();
3415 Shared->SymbolKinds.clear();
3423// Get the parent scope to update the address ranges of the nested 3424// scope representing the inlined function. 3429 ParentLowPC = (*
Locations->begin())->getLowerAddress();
3432// For the given inlinesite, get the initial line number and its 3433// source filename. Update the logical scope representing it. 3436 LVInlineeInfo::iterator Iter = InlineeInfo.find(
InlineSite.Inlinee);
3437if (Iter != InlineeInfo.end()) {
3438 LineNumber = Iter->second.first;
3441// TODO: This part needs additional work in order to set properly the 3442// correct filename in order to detect changes between filenames. 3443// AbstractFunction->setFilename(Filename); 3447dbgs() <<
"inlineSiteAnnotation\n" 3448 <<
"Abstract: " << AbstractFunction->
getName() <<
"\n" 3449 <<
"Inlined: " << InlinedFunction->
getName() <<
"\n" 3450 <<
"Parent: " << Parent->
getName() <<
"\n" 3451 <<
"Low PC: " <<
hexValue(ParentLowPC) <<
"\n";
3454// Get the source lines if requested by command line option. 3455if (!
options().getPrintLines())
3458// Limitation: Currently we don't track changes in the FileOffset. The 3459// side effects are the caller that it is unable to differentiate the 3460// source filename for the inlined code. 3462 int32_t LineOffset = LineNumber;
3466auto UpdateCodeOffset = [&](
uint32_t Delta) {
3473auto UpdateLineOffset = [&](int32_t Delta) {
3474 LineOffset += Delta;
3476char Sign = Delta > 0 ?
'+' :
'-';
3477dbgs() <<
formatv(
" line {0} ({1}{2})", LineOffset, Sign,
3481auto UpdateFileOffset = [&](int32_t
Offset) {
3487auto CreateLine = [&]() {
3488// Create the logical line record. 3491Line->setLineNumber(LineOffset);
3492// TODO: This part needs additional work in order to set properly the 3493// correct filename in order to detect changes between filenames. 3494// Line->setFilename(Filename); 3498bool SeenLowAddress =
false;
3499bool SeenHighAddress =
false;
3509// Use the opcode to interpret the integer values. 3510switch (Annot.OpCode) {
3511case BinaryAnnotationsOpCode::ChangeCodeOffset:
3512case BinaryAnnotationsOpCode::CodeOffset:
3513case BinaryAnnotationsOpCode::ChangeCodeLength:
3514 UpdateCodeOffset(Annot.U1);
3516if (Annot.OpCode == BinaryAnnotationsOpCode::ChangeCodeOffset) {
3519 SeenLowAddress =
true;
3522if (Annot.OpCode == BinaryAnnotationsOpCode::ChangeCodeLength) {
3524 SeenHighAddress =
true;
3527case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset:
3528 UpdateCodeOffset(Annot.U2);
3531case BinaryAnnotationsOpCode::ChangeLineOffset:
3532case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset:
3533 UpdateCodeOffset(Annot.U1);
3534 UpdateLineOffset(Annot.S1);
3537 BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset)
3540case BinaryAnnotationsOpCode::ChangeFile:
3541 UpdateFileOffset(Annot.U1);
3547if (SeenLowAddress && SeenHighAddress) {
3548 SeenLowAddress =
false;
3549 SeenHighAddress =
false;
3550 InlinedFunction->
addObject(LowPC, HighPC);
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
AMDGPU Lower Kernel Arguments
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
An implementation of BinaryStream which holds its entire data set in a single contiguous buffer.
Provides read only access to a subclass of BinaryStream.
This is an important base class in LLVM.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
StringRef getName() const
virtual void printString(StringRef Value)
void indent(int Levels=1)
void unindent(int Levels=1)
void printEnum(StringRef Label, T Value, ArrayRef< EnumEntry< TEnum > > EnumValues)
virtual raw_ostream & getOStream()
virtual raw_ostream & startLine()
virtual void printNumber(StringRef Label, char Value)
void printHex(StringRef Label, T Value)
void printFlags(StringRef Label, T Value, ArrayRef< EnumEntry< TFlag > > Flags, TFlag EnumMask1={}, TFlag EnumMask2={}, TFlag EnumMask3={}, ArrayRef< FlagEntry > ExtraFlags={})
virtual void printBoolean(StringRef Label, bool Value)
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMapEntry - This is used to represent one value that is inserted into a StringMap.
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
constexpr size_t size() const
size - Get the string size.
Target - Wrapper for Target specific information.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
Value(Type *Ty, unsigned scid)
void setName(const Twine &Name)
Change the name of the value.
TypeIndex getElementType() const
TypeIndex getIndexType() const
StringRef getName() const
uint8_t getBitSize() const
TypeIndex getType() const
uint8_t getBitOffset() const
ArrayRef< TypeIndex > getArgs() const
uint8_t getLanguage() const
uint32_t getFlags() const
CompileSym3Flags getFlags() const
SourceLanguage getLanguage() const
Represents a read-only view of a CodeView string table.
DefRangeFramePointerRelHeader Hdr
LocalVariableAddrRange Range
uint32_t getRelocationOffset() const
std::vector< LocalVariableAddrGap > Gaps
DefRangeRegisterRelHeader Hdr
bool hasSpilledUDTMember() const
uint32_t getRelocationOffset() const
uint16_t offsetInParent() const
std::vector< LocalVariableAddrGap > Gaps
LocalVariableAddrRange Range
uint32_t getRelocationOffset() const
std::vector< LocalVariableAddrGap > Gaps
LocalVariableAddrRange Range
DefRangeRegisterHeader Hdr
LocalVariableAddrRange Range
uint32_t getRelocationOffset() const
std::vector< LocalVariableAddrGap > Gaps
DefRangeSubfieldRegisterHeader Hdr
std::vector< LocalVariableAddrGap > Gaps
LocalVariableAddrRange Range
uint32_t getRelocationOffset() const
std::vector< LocalVariableAddrGap > Gaps
uint32_t getRelocationOffset() const
LocalVariableAddrRange Range
uint32_t getSignature() const
RegisterId getLocalFramePtrReg(CPUType CPU) const
Extract the register this frame uses to refer to local variables.
RegisterId getParamFramePtrReg(CPUType CPU) const
Extract the register this frame uses to refer to parameters.
FrameProcedureOptions Flags
Provides amortized O(1) random access to a CodeView type stream.
std::optional< CVType > tryGetType(TypeIndex Index)
CVType getType(TypeIndex Index) override
StringRef getTypeName(TypeIndex Index) override
LF_INDEX - Used to chain two large LF_FIELDLIST or LF_METHODLIST records together.
TypeIndex getContinuationIndex() const
TypeIndex getReturnType() const
int32_t getThisPointerAdjustment() const
TypeIndex getArgumentList() const
uint16_t getParameterCount() const
TypeIndex getThisType() const
TypeIndex getClassType() const
std::vector< OneMethodRecord > Methods
int32_t getVFTableOffset() const
TypeIndex getType() const
bool isIntroducingVirtual() const
MemberAccess getAccess() const
MethodKind getMethodKind() const
StringRef getName() const
For method overload sets. LF_METHOD.
StringRef getName() const
uint16_t getNumOverloads() const
TypeIndex getMethodList() const
uint32_t getSignature() const
StringRef getPrecompFilePath() const
uint32_t getTypesCount() const
uint32_t getStartTypeIndex() const
uint32_t getRelocationOffset() const
TypeIndex getReturnType() const
TypeIndex getArgumentList() const
uint16_t getParameterCount() const
TypeIndex getFieldList() const
static Error deserializeAs(CVType &CVT, T &Record)
static TypeIndex fromArrayIndex(uint32_t Index)
SimpleTypeKind getSimpleKind() const
void setIndex(uint32_t I)
static const uint32_t FirstNonSimpleIndex
static StringRef simpleTypeName(TypeIndex TI)
uint32_t getIndex() const
StringRef getName() const
const GUID & getGuid() const
void addCallbackToPipeline(TypeVisitorCallbacks &Callbacks)
virtual Error visitUnknownMember(CVMemberRecord &Record)
virtual Error visitMemberEnd(CVMemberRecord &Record)
virtual Error visitMemberBegin(CVMemberRecord &Record)
TypeIndex getSourceFile() const
uint16_t getModule() const
uint32_t getLineNumber() const
uint32_t getLineNumber() const
TypeIndex getSourceFile() const
TypeIndex getType() const
uint32_t getVFPtrOffset() const
TypeIndex getOverriddenVTable() const
ArrayRef< StringRef > getMethodNames() const
StringRef getName() const
TypeIndex getCompleteClass() const
uint32_t getEntryCount() const
Stores all information relating to a compile unit, be it in its original instance in the object file ...
void addInlineeLines(LVScope *Scope, LVLines &Lines)
LVAddress getSymbolTableAddress(StringRef Name)
LVAddress linearAddress(uint16_t Segment, uint32_t Offset, LVAddress Addendum=0)
void addToSymbolTable(StringRef Name, LVScope *Function, LVSectionIndex SectionIndex=0)
void addModule(LVScope *Scope)
void getLinkageName(const llvm::object::coff_section *CoffSection, uint32_t RelocOffset, uint32_t Offset, StringRef *RelocSym)
static StringRef getSymbolKindName(SymbolKind Kind)
virtual void setCount(int64_t Value)
virtual void setBitSize(uint32_t Size)
virtual void updateLevel(LVScope *Parent, bool Moved=false)
virtual int64_t getCount() const
void setInlineCode(uint32_t Code)
virtual void setReference(LVElement *Element)
void setName(StringRef ElementName) override
StringRef getName() const override
void setType(LVElement *Element=nullptr)
void setFilenameIndex(size_t Index)
Error visitKnownRecord(CVType &Record, ArgListRecord &Args, TypeIndex TI, LVElement *Element)
void printRecords(raw_ostream &OS) const
void stopProcessArgumentList()
void printTypeEnd(CVType &Record)
Error visitMemberRecord(CVMemberRecord &Record, TypeVisitorCallbacks &Callbacks, TypeIndex TI, LVElement *Element)
Error visitKnownMember(CVMemberRecord &Record, BaseClassRecord &Base, TypeIndex TI, LVElement *Element)
void printMemberEnd(CVMemberRecord &Record)
void setCompileUnitName(std::string Name)
LVElement * CurrentElement
Error inlineSiteAnnotation(LVScope *AbstractFunction, LVScope *InlinedFunction, InlineSiteSym &InlineSite)
LVLogicalVisitor(LVCodeViewReader *Reader, ScopedPrinter &W, llvm::pdb::InputFile &Input)
void printTypeIndex(StringRef FieldName, TypeIndex TI, uint32_t StreamIdx)
Error visitUnknownMember(CVMemberRecord &Record, TypeIndex TI)
void pushScope(LVScope *Scope)
Error visitUnknownType(CVType &Record, TypeIndex TI)
void startProcessArgumentList()
void addElement(LVScope *Scope, bool IsCompileUnit)
void printTypeBegin(CVType &Record, TypeIndex TI, LVElement *Element, uint32_t StreamIdx)
LVElement * getElement(uint32_t StreamIdx, TypeIndex TI, LVScope *Parent=nullptr)
LVScope * getReaderScope() const
void printMemberBegin(CVMemberRecord &Record, TypeIndex TI, LVElement *Element, uint32_t StreamIdx)
Error finishVisitation(CVType &Record, TypeIndex TI, LVElement *Element)
LVElement * createElement(TypeLeafKind Kind)
LVScope * getParentScope() const
void setOffset(LVOffset DieOffset)
LVOffset getOffset() const
void setLineNumber(uint32_t Number)
void setTag(dwarf::Tag Tag)
codeview::CPUType getCompileUnitCPUType()
void setCompileUnitCPUType(codeview::CPUType Type)
virtual bool isSystemEntry(LVElement *Element, StringRef Name={}) const
LVScopeCompileUnit * getCompileUnit() const
void setCompileUnit(LVScope *Scope)
void addPublicName(LVScope *Scope, LVAddress LowPC, LVAddress HighPC)
void addElement(LVElement *Element)
void addObject(LVLocation *Location)
const LVLocations * getRanges() const
void getLinkageName(uint32_t RelocOffset, uint32_t Offset, StringRef *RelocSym=nullptr)
void printRelocatedField(StringRef Label, uint32_t RelocOffset, uint32_t Offset, StringRef *RelocSym=nullptr)
DebugStringTableSubsectionRef getStringTable() override
StringRef getFileNameForFileOffset(uint32_t FileOffset) override
Error visitSymbolEnd(CVSymbol &Record) override
Error visitKnownRecord(CVSymbol &Record, BlockSym &Block) override
Error visitSymbolBegin(CVSymbol &Record) override
Error visitUnknownSymbol(CVSymbol &Record) override
Action to take on unknown symbols. By default, they are ignored.
Error visitMemberEnd(CVMemberRecord &Record) override
Error visitUnknownMember(CVMemberRecord &Record) override
Error visitTypeBegin(CVType &Record) override
Paired begin/end actions for all types.
Error visitMemberBegin(CVMemberRecord &Record) override
Error visitKnownRecord(CVType &Record, BuildInfoRecord &Args) override
Error visitUnknownType(CVType &Record) override
Action to take on unknown types. By default, they are ignored.
This class implements an extremely fast bulk output stream that can only output to a stream.
constexpr char TypeName[]
Key for Kernel::Arg::Metadata::mTypeName.
PointerMode
Equivalent to CV_ptrmode_e.
MethodKind
Part of member attribute flags. (CV_methodprop_e)
CPUType
These values correspond to the CV_CPU_TYPE_e enumeration, and are documented here: https://msdn....
ArrayRef< EnumEntry< uint16_t > > getJumpTableEntrySizeNames()
bool symbolEndsScope(SymbolKind Kind)
Return true if this ssymbol ends a scope.
MethodOptions
Equivalent to CV_fldattr_t bitfield.
ArrayRef< EnumEntry< SymbolKind > > getSymbolTypeNames()
MemberAccess
Source-level access specifier. (CV_access_e)
bool symbolOpensScope(SymbolKind Kind)
Return true if this symbol opens a scope.
TypeLeafKind
Duplicate copy of the above enum, but using the official CV names.
ArrayRef< EnumEntry< uint16_t > > getLocalFlagNames()
ArrayRef< EnumEntry< uint16_t > > getRegisterNames(CPUType Cpu)
bool isAggregate(CVType CVT)
Given an arbitrary codeview type, determine if it is an LF_STRUCTURE, LF_CLASS, LF_INTERFACE,...
ArrayRef< EnumEntry< uint8_t > > getProcSymFlagNames()
TypeRecordKind
Distinguishes individual records in .debug$T or .debug$P section or PDB type stream.
SymbolKind
Duplicate copy of the above enum, but using the official CV names.
uint64_t getSizeInBytesForTypeRecord(CVType CVT)
Given an arbitrary codeview type, return the type's size in the case of aggregate (LF_STRUCTURE,...
ArrayRef< EnumEntry< unsigned > > getCPUTypeNames()
ArrayRef< EnumEntry< SourceLanguage > > getSourceLanguageNames()
uint64_t getSizeInBytesForTypeIndex(TypeIndex TI)
Given an arbitrary codeview type index, determine its size.
TypeIndex getModifiedType(const CVType &CVT)
Given a CVType which is assumed to be an LF_MODIFIER, return the TypeIndex of the type that the LF_MO...
ArrayRef< EnumEntry< uint32_t > > getCompileSym3FlagNames()
void printTypeIndex(ScopedPrinter &Printer, StringRef FieldName, TypeIndex TI, TypeCollection &Types)
@ DW_INL_declared_inlined
constexpr Tag DW_TAG_unaligned
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
FormattedNumber hexValue(uint64_t N, unsigned Width=HEX_WIDTH, bool Upper=false)
static TypeIndex getTrueType(TypeIndex &TI)
std::vector< StringRef > LVStringRefs
static StringRef getRecordName(LazyRandomTypeCollection &Types, TypeIndex TI)
std::vector< TypeIndex > LVLineRecords
LVStringRefs getAllLexicalComponents(StringRef Name)
std::string transformPath(StringRef Path)
LVLexicalComponent getInnerComponent(StringRef Name)
static const EnumEntry< TypeLeafKind > LeafTypeNames[]
std::set< SymbolKind > LVSymbolKinds
std::set< TypeLeafKind > LVTypeKinds
std::string getScopedName(const LVStringRefs &Components, StringRef BaseName={})
std::tuple< LVStringRefs::size_type, LVStringRefs::size_type > LVLexicalIndex
std::string formatTypeLeafKind(codeview::TypeLeafKind K)
Print(const T &, const DataFlowGraph &) -> Print< T >
This is an optimization pass for GlobalISel generic memory operations.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
std::tuple< uint64_t, uint32_t > InlineSite
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
StringRef getTypeName()
We provide a function which tries to compute the (demangled) name of a type statically.
@ Mod
The access may modify the value stored in memory.
support::detail::RepeatAdapter< T > fmt_repeat(T &&Item, size_t Count)
support::detail::AlignAdapter< T > fmt_align(T &&Item, AlignStyle Where, size_t Amount, char Fill=' ')
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
void consumeError(Error Err)
Consume a Error without doing anything.
std::string demangle(std::string_view MangledName)
Attempt to demangle a string using different demangling schemes.
ulittle16_t MayHaveNoName
little32_t BasePointerOffset
ulittle16_t MayHaveNoName
ulittle32_t OffsetInParent
MethodOptions getFlags() const
Get the flags that are not included in access control or method properties.
LVShared(LVCodeViewReader *Reader, LVLogicalVisitor *Visitor)
LVLineRecords LineRecords
LVTypeRecords TypeRecords
LVCodeViewReader * Reader
LVLogicalVisitor * Visitor
LVNamespaceDeduction NamespaceDeduction
LVSymbolKinds SymbolKinds
LVStringRecords StringRecords
LVForwardReferences ForwardReferences