uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsAddress( const DWARFUnit *U, const uint16_t Attr, uint64_t FailValue) const { DWARFFormValue FormValue; if (!getAttributeValue(U, Attr, FormValue)) return FailValue; Optional<uint64_t> Result = FormValue.getAsAddress(U); return Result.hasValue() ? Result.getValue() : FailValue; }
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); } } }