status_t Architecture::InitRegisterRules(CfaContext& context) const { // Init the initial register rules. The DWARF 3 specs on the // matter: "The default rule for all columns before // interpretation of the initial instructions is the undefined // rule. However, an ABI authoring body or a compilation system // authoring body may specify an alternate default value for any // or all columns." // GCC's assumes the "same value" rule for all callee preserved // registers. We set them respectively. // the stack pointer is initialized to // CFA offset 0 by default. const Register* registers = Registers(); RegisterMap* toDwarf = NULL; status_t result = GetDwarfRegisterMaps(&toDwarf, NULL); if (result != B_OK) return result; BReference<RegisterMap> toDwarfMapReference(toDwarf, true); for (int32 i = 0; i < CountRegisters(); i++) { int32 dwarfReg = toDwarf->MapRegisterIndex(i); if (dwarfReg < 0 || dwarfReg > CountRegisters() - 1) continue; // TODO: on CPUs that have a return address register // a default rule should be set up to use that to // extract the instruction pointer switch (registers[i].Type()) { case REGISTER_TYPE_STACK_POINTER: { context.RegisterRule(dwarfReg)->SetToValueOffset(0); break; } default: { context.RegisterRule(dwarfReg)->SetToSameValue(); break; } } } return result; }
Registers TwoOperandOperate::GetDstRegs() const { return Registers(1, dstReg); }
Registers getRegisters(CIDebugRegisters *regs, unsigned flags, std::string *errorMessage) { enum { bufSize= 128 }; WCHAR buf[bufSize]; ULONG registerCount = 0; HRESULT hr = regs->GetNumberRegisters(®isterCount); if (FAILED(hr)) { *errorMessage = msgDebugEngineComFailed("GetNumberRegisters", hr); return Registers(); } ULONG pseudoRegisterCount = 0; if (flags & IncludePseudoRegisters) { hr = regs->GetNumberPseudoRegisters(&pseudoRegisterCount); if (FAILED(hr)) { *errorMessage = msgDebugEngineComFailed("GetNumberPseudoRegisters", hr); return Registers(); } } Registers rc; rc.reserve(registerCount + pseudoRegisterCount); // Standard registers DEBUG_REGISTER_DESCRIPTION description; DEBUG_VALUE value; for (ULONG r = 0; r < registerCount; ++r) { hr = regs->GetDescriptionWide(r, buf, bufSize, NULL, &description); if (FAILED(hr)) { *errorMessage = msgDebugEngineComFailed("GetDescription", hr); return Registers(); } hr = regs->GetValue(r, &value); if (FAILED(hr)) { *errorMessage = msgDebugEngineComFailed("GetValue", hr); return Registers(); } const bool isSubRegister = (description.Flags & DEBUG_REGISTER_SUB_REGISTER); if (!isSubRegister || (flags & IncludeSubRegisters)) { Register reg; reg.name = buf; reg.description = registerDescription(description); reg.subRegister = isSubRegister; reg.value = value; rc.push_back(reg); } } // Pseudo for (ULONG r = 0; r < pseudoRegisterCount; ++r) { ULONG type; hr = regs->GetPseudoDescriptionWide(r, buf, bufSize, NULL, NULL, &type); if (FAILED(hr)) continue; // Fails for some pseudo registers hr = regs->GetValue(r, &value); if (FAILED(hr)) continue; // Fails for some pseudo registers Register reg; reg.pseudoRegister = true; reg.name = buf; reg.description = valueType(type); reg.value = value; rc.push_back(reg); } return rc; }