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; }
status_t ArchitectureX8664::InitRegisterRules(CfaContext& context) const { status_t error = Architecture::InitRegisterRules(context); if (error != B_OK) return error; // set up rule for RIP register context.RegisterRule(fToDwarfRegisterMap->MapRegisterIndex( X86_64_REGISTER_RIP))->SetToLocationOffset(0); return B_OK; }