void ObjectLoadListener::extractLocalLocations( const DWARFUnit *CU, const DWARFDebugInfoEntryMinimal *DebugEntry, std::vector<uint64_t> &Offsets) { if (DebugEntry->isNULL()) return; if (DebugEntry->getTag() == dwarf::DW_TAG_formal_parameter || DebugEntry->getTag() == dwarf::DW_TAG_variable) { uint64_t Offset; // Extract offset for each local found DWARFFormValue FormValue; if (DebugEntry->getAttributeValue(CU, dwarf::DW_AT_location, FormValue)) { Optional<ArrayRef<uint8_t>> FormValues = FormValue.getAsBlock(); Offset = FormValues->back(); } Offsets.push_back(Offset); } const DWARFDebugInfoEntryMinimal *Child = DebugEntry->getFirstChild(); // Extract info for DebugEntry's child and its child's siblings. while (Child) { extractLocalLocations(CU, Child, Offsets); Child = Child->getSibling(); } }
void ObjectLoadListener::getDebugInfoForLocals( DWARFContextInMemory &DwarfContext, uint64_t Addr, uint64_t Size) { for (const auto &CU : DwarfContext.compile_units()) { const DWARFDebugInfoEntryMinimal *UnitDIE = CU->getUnitDIE(false); const DWARFDebugInfoEntryMinimal *SubprogramDIE = getSubprogramDIE(UnitDIE); ICorDebugInfo::RegNum FrameBaseRegister = ICorDebugInfo::REGNUM_COUNT; DWARFFormValue FormValue; // Find the frame_base register value if (SubprogramDIE->getAttributeValue(CU.get(), dwarf::DW_AT_frame_base, FormValue)) { Optional<ArrayRef<uint8_t>> FormValues = FormValue.getAsBlock(); FrameBaseRegister = mapDwarfRegisterToRegNum(FormValues->back()); } if (SubprogramDIE->getAttributeValue(CU.get(), dwarf::DW_AT_low_pc, FormValue)) { Optional<uint64_t> FormAddress = FormValue.getAsAddress(CU.get()); // If the Form address doesn't match the address for the function passed // do not collect debug for locals since they do not go with the current // function being processed if (FormAddress.getValue() != Addr) { return; } } std::vector<uint64_t> Offsets; extractLocalLocations(CU.get(), SubprogramDIE, Offsets); // Allocate the array of NativeVarInfo objects that will be sent to the EE ICorDebugInfo::NativeVarInfo *LocalVars; unsigned SizeOfArray = Offsets.size() * sizeof(ICorDebugInfo::NativeVarInfo); if (SizeOfArray > 0) { LocalVars = (ICorDebugInfo::NativeVarInfo *)Context->JitInfo->allocateArray( SizeOfArray); unsigned CurrentDebugEntry = 0; for (auto &Offset : Offsets) { LocalVars[CurrentDebugEntry].startOffset = Addr; LocalVars[CurrentDebugEntry].endOffset = Addr + Size; LocalVars[CurrentDebugEntry].varNumber = CurrentDebugEntry; // Assume all locals are on the stack ICorDebugInfo::VarLoc VarLoc; VarLoc.vlType = ICorDebugInfo::VLT_STK; VarLoc.vlStk.vlsBaseReg = FrameBaseRegister; VarLoc.vlStk.vlsOffset = Offset; LocalVars[CurrentDebugEntry].loc = VarLoc; CurrentDebugEntry++; } CORINFO_METHOD_INFO *MethodInfo = Context->MethodInfo; CORINFO_METHOD_HANDLE MethodHandle = MethodInfo->ftn; Context->JitInfo->setVars(MethodHandle, Offsets.size(), LocalVars); } } }