diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:01:25 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:01:25 +0000 |
| commit | d8e91e46262bc44006913e6796843909f1ac7bcd (patch) | |
| tree | 7d0c143d9b38190e0fa0180805389da22cd834c5 /lib/CodeGen/AsmPrinter/DwarfUnit.cpp | |
| parent | b7eb8e35e481a74962664b63dfb09483b200209a (diff) | |
Notes
Diffstat (limited to 'lib/CodeGen/AsmPrinter/DwarfUnit.cpp')
| -rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfUnit.cpp | 194 |
1 files changed, 52 insertions, 142 deletions
diff --git a/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index 600f4a78fda0..80b365f1aa43 100644 --- a/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -234,15 +234,23 @@ void DwarfUnit::addSInt(DIELoc &Die, Optional<dwarf::Form> Form, void DwarfUnit::addString(DIE &Die, dwarf::Attribute Attribute, StringRef String) { + if (CUNode->isDebugDirectivesOnly()) + return; + if (DD->useInlineStrings()) { Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_string, new (DIEValueAllocator) DIEInlineString(String, DIEValueAllocator)); return; } - auto StringPoolEntry = DU->getStringPool().getEntry(*Asm, String); dwarf::Form IxForm = isDwoUnit() ? dwarf::DW_FORM_GNU_str_index : dwarf::DW_FORM_strp; + + auto StringPoolEntry = + useSegmentedStringOffsetsTable() || IxForm == dwarf::DW_FORM_GNU_str_index + ? DU->getStringPool().getIndexedEntry(*Asm, String) + : DU->getStringPool().getEntry(*Asm, String); + // For DWARF v5 and beyond, use the smallest strx? form possible. if (useSegmentedStringOffsetsTable()) { IxForm = dwarf::DW_FORM_strx1; @@ -307,14 +315,21 @@ unsigned DwarfTypeUnit::getOrCreateSourceID(const DIFile *File) { } void DwarfUnit::addOpAddress(DIELoc &Die, const MCSymbol *Sym) { - if (!DD->useSplitDwarf()) { - addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_addr); - addLabel(Die, dwarf::DW_FORM_udata, Sym); - } else { + if (DD->getDwarfVersion() >= 5) { + addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_addrx); + addUInt(Die, dwarf::DW_FORM_addrx, DD->getAddressPool().getIndex(Sym)); + return; + } + + if (DD->useSplitDwarf()) { addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_addr_index); addUInt(Die, dwarf::DW_FORM_GNU_addr_index, DD->getAddressPool().getIndex(Sym)); + return; } + + addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_addr); + addLabel(Die, dwarf::DW_FORM_udata, Sym); } void DwarfUnit::addLabelDelta(DIE &Die, dwarf::Attribute Attribute, @@ -401,6 +416,12 @@ void DwarfUnit::addSourceLine(DIE &Die, const DISubprogram *SP) { addSourceLine(Die, SP->getLine(), SP->getFile()); } +void DwarfUnit::addSourceLine(DIE &Die, const DILabel *L) { + assert(L); + + addSourceLine(Die, L->getLine(), L->getFile()); +} + void DwarfUnit::addSourceLine(DIE &Die, const DIType *Ty) { assert(Ty); @@ -413,138 +434,6 @@ void DwarfUnit::addSourceLine(DIE &Die, const DIObjCProperty *Ty) { addSourceLine(Die, Ty->getLine(), Ty->getFile()); } -/* Byref variables, in Blocks, are declared by the programmer as "SomeType - VarName;", but the compiler creates a __Block_byref_x_VarName struct, and - gives the variable VarName either the struct, or a pointer to the struct, as - its type. This is necessary for various behind-the-scenes things the - compiler needs to do with by-reference variables in Blocks. - - However, as far as the original *programmer* is concerned, the variable - should still have type 'SomeType', as originally declared. - - The function getBlockByrefType dives into the __Block_byref_x_VarName - struct to find the original type of the variable, which is then assigned to - the variable's Debug Information Entry as its real type. So far, so good. - However now the debugger will expect the variable VarName to have the type - SomeType. So we need the location attribute for the variable to be an - expression that explains to the debugger how to navigate through the - pointers and struct to find the actual variable of type SomeType. - - The following function does just that. We start by getting - the "normal" location for the variable. This will be the location - of either the struct __Block_byref_x_VarName or the pointer to the - struct __Block_byref_x_VarName. - - The struct will look something like: - - struct __Block_byref_x_VarName { - ... <various fields> - struct __Block_byref_x_VarName *forwarding; - ... <various other fields> - SomeType VarName; - ... <maybe more fields> - }; - - If we are given the struct directly (as our starting point) we - need to tell the debugger to: - - 1). Add the offset of the forwarding field. - - 2). Follow that pointer to get the real __Block_byref_x_VarName - struct to use (the real one may have been copied onto the heap). - - 3). Add the offset for the field VarName, to find the actual variable. - - If we started with a pointer to the struct, then we need to - dereference that pointer first, before the other steps. - Translating this into DWARF ops, we will need to append the following - to the current location description for the variable: - - DW_OP_deref -- optional, if we start with a pointer - DW_OP_plus_uconst <forward_fld_offset> - DW_OP_deref - DW_OP_plus_uconst <varName_fld_offset> - - That is what this function does. */ - -void DwarfUnit::addBlockByrefAddress(const DbgVariable &DV, DIE &Die, - dwarf::Attribute Attribute, - const MachineLocation &Location) { - const DIType *Ty = DV.getType(); - const DIType *TmpTy = Ty; - uint16_t Tag = Ty->getTag(); - bool isPointer = false; - - StringRef varName = DV.getName(); - - if (Tag == dwarf::DW_TAG_pointer_type) { - auto *DTy = cast<DIDerivedType>(Ty); - TmpTy = resolve(DTy->getBaseType()); - isPointer = true; - } - - // Find the __forwarding field and the variable field in the __Block_byref - // struct. - DINodeArray Fields = cast<DICompositeType>(TmpTy)->getElements(); - const DIDerivedType *varField = nullptr; - const DIDerivedType *forwardingField = nullptr; - - for (unsigned i = 0, N = Fields.size(); i < N; ++i) { - auto *DT = cast<DIDerivedType>(Fields[i]); - StringRef fieldName = DT->getName(); - if (fieldName == "__forwarding") - forwardingField = DT; - else if (fieldName == varName) - varField = DT; - } - - // Get the offsets for the forwarding field and the variable field. - unsigned forwardingFieldOffset = forwardingField->getOffsetInBits() >> 3; - unsigned varFieldOffset = varField->getOffsetInBits() >> 2; - - // Decode the original location, and use that as the start of the byref - // variable's location. - DIELoc *Loc = new (DIEValueAllocator) DIELoc; - DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); - if (Location.isIndirect()) - DwarfExpr.setMemoryLocationKind(); - - SmallVector<uint64_t, 6> Ops; - // If we started with a pointer to the __Block_byref... struct, then - // the first thing we need to do is dereference the pointer (DW_OP_deref). - if (isPointer) - Ops.push_back(dwarf::DW_OP_deref); - - // Next add the offset for the '__forwarding' field: - // DW_OP_plus_uconst ForwardingFieldOffset. Note there's no point in - // adding the offset if it's 0. - if (forwardingFieldOffset > 0) { - Ops.push_back(dwarf::DW_OP_plus_uconst); - Ops.push_back(forwardingFieldOffset); - } - - // Now dereference the __forwarding field to get to the real __Block_byref - // struct: DW_OP_deref. - Ops.push_back(dwarf::DW_OP_deref); - - // Now that we've got the real __Block_byref... struct, add the offset - // for the variable's field to get to the location of the actual variable: - // DW_OP_plus_uconst varFieldOffset. Again, don't add if it's 0. - if (varFieldOffset > 0) { - Ops.push_back(dwarf::DW_OP_plus_uconst); - Ops.push_back(varFieldOffset); - } - - DIExpressionCursor Cursor(Ops); - const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo(); - if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg())) - return; - DwarfExpr.addExpression(std::move(Cursor)); - - // Now attach the location information to the DIE. - addBlock(Die, Attribute, DwarfExpr.finalize()); -} - /// Return true if type encoding is unsigned. static bool isUnsignedDIType(DwarfDebug *DD, const DIType *Ty) { if (auto *CTy = dyn_cast<DICompositeType>(Ty)) { @@ -787,7 +676,7 @@ void DwarfUnit::updateAcceleratorTables(const DIScope *Context, IsImplementation = CT->getRuntimeLang() == 0 || CT->isObjcClassComplete(); } unsigned Flags = IsImplementation ? dwarf::DW_FLAG_type_implementation : 0; - DD->addAccelType(Ty->getName(), TyDIE, Flags); + DD->addAccelType(*CUNode, Ty->getName(), TyDIE, Flags); if (!Context || isa<DICompileUnit>(Context) || isa<DIFile>(Context) || isa<DINamespace>(Context)) @@ -851,6 +740,11 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DIBasicType *BTy) { uint64_t Size = BTy->getSizeInBits() >> 3; addUInt(Buffer, dwarf::DW_AT_byte_size, None, Size); + + if (BTy->isBigEndian()) + addUInt(Buffer, dwarf::DW_AT_endianity, None, dwarf::DW_END_big); + else if (BTy->isLittleEndian()) + addUInt(Buffer, dwarf::DW_AT_endianity, None, dwarf::DW_END_little); } void DwarfUnit::constructTypeDIE(DIE &Buffer, const DIDerivedType *DTy) { @@ -1155,7 +1049,7 @@ DIE *DwarfUnit::getOrCreateNameSpace(const DINamespace *NS) { addString(NDie, dwarf::DW_AT_name, NS->getName()); else Name = "(anonymous namespace)"; - DD->addAccelNamespace(Name, NDie); + DD->addAccelNamespace(*CUNode, Name, NDie); addGlobalName(Name, NDie, NS->getScope()); if (NS->getExportSymbols()) addFlag(NDie, dwarf::DW_AT_export_symbols); @@ -1404,7 +1298,7 @@ DIE *DwarfUnit::getIndexTyDie() { addUInt(*IndexTyDie, dwarf::DW_AT_byte_size, None, sizeof(int64_t)); addUInt(*IndexTyDie, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, dwarf::DW_ATE_unsigned); - DD->addAccelType(Name, *IndexTyDie, /*Flags*/ 0); + DD->addAccelType(*CUNode, Name, *IndexTyDie, /*Flags*/ 0); return IndexTyDie; } @@ -1467,7 +1361,7 @@ void DwarfUnit::constructEnumTypeDIE(DIE &Buffer, const DICompositeType *CTy) { if (DTy) { if (DD->getDwarfVersion() >= 3) addType(Buffer, DTy); - if (DD->getDwarfVersion() >= 4 && (CTy->getFlags() & DINode::FlagFixedEnum)) + if (DD->getDwarfVersion() >= 4 && (CTy->getFlags() & DINode::FlagEnumClass)) addFlag(Buffer, dwarf::DW_AT_enum_class); } @@ -1659,7 +1553,14 @@ DIE *DwarfUnit::getOrCreateStaticMemberDIE(const DIDerivedType *DT) { void DwarfUnit::emitCommonHeader(bool UseOffsets, dwarf::UnitType UT) { // Emit size of content not including length itself Asm->OutStreamer->AddComment("Length of Unit"); - Asm->emitInt32(getHeaderSize() + getUnitDie().getSize()); + if (!DD->useSectionsAsReferences()) { + StringRef Prefix = isDwoUnit() ? "debug_info_dwo_" : "debug_info_"; + MCSymbol *BeginLabel = Asm->createTempSymbol(Prefix + "start"); + EndLabel = Asm->createTempSymbol(Prefix + "end"); + Asm->EmitLabelDifference(EndLabel, BeginLabel, 4); + Asm->OutStreamer->EmitLabel(BeginLabel); + } else + Asm->emitInt32(getHeaderSize() + getUnitDie().getSize()); Asm->OutStreamer->AddComment("DWARF version number"); unsigned Version = DD->getDwarfVersion(); @@ -1761,3 +1662,12 @@ void DwarfUnit::addRnglistsBase() { DU->getRnglistsTableBaseSym(), TLOF.getDwarfRnglistsSection()->getBeginSymbol()); } + +void DwarfUnit::addLoclistsBase() { + assert(DD->getDwarfVersion() >= 5 && + "DW_AT_loclists_base requires DWARF version 5 or later"); + const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); + addSectionLabel(getUnitDie(), dwarf::DW_AT_loclists_base, + DU->getLoclistsTableBaseSym(), + TLOF.getDwarfLoclistsSection()->getBeginSymbol()); +} |
