Ticket #7761: return_values.patch
File return_values.patch, 17.5 KB (added by , 11 years ago) |
---|
-
src/apps/debugger/Jamfile
diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile index 44c56d0..c2aaa66 100644
a b Application Debugger : 124 124 125 125 # ids 126 126 FunctionID.cpp 127 FunctionParameterID.cpp 127 128 LocalVariableID.cpp 128 129 ObjectID.cpp 129 FunctionParameterID.cpp130 ReturnValueID.cpp 130 131 131 132 # jobs 132 133 GetCPUStateJob.cpp -
src/apps/debugger/arch/Architecture.h
diff --git a/src/apps/debugger/arch/Architecture.h b/src/apps/debugger/arch/Architecture.h index 38409d0..748e9dc 100644
a b class StackTrace; 30 30 class Statement; 31 31 class Team; 32 32 class TeamMemory; 33 class ValueLocation; 33 34 34 35 35 36 enum { … … public: 118 119 int32& _maxBytesPerRegister, 119 120 uint8& _watchpointCapabilityFlags) = 0; 120 121 122 virtual status_t GetReturnAddressLocation( 123 StackFrame* frame, target_size_t valueSize, 124 ValueLocation*& _location) = 0; 125 121 126 122 127 protected: 123 128 TeamMemory* fTeamMemory; -
src/apps/debugger/arch/InstructionInfo.cpp
diff --git a/src/apps/debugger/arch/InstructionInfo.cpp b/src/apps/debugger/arch/InstructionInfo.cpp index 03afae4..1a48c70 100644
a b 9 9 InstructionInfo::InstructionInfo() 10 10 : 11 11 fAddress(0), 12 fTargetAddress(0), 12 13 fSize(0), 13 14 fType(INSTRUCTION_TYPE_OTHER), 14 15 fBreakpointAllowed(false), … … InstructionInfo::InstructionInfo() 17 18 } 18 19 19 20 20 InstructionInfo::InstructionInfo(target_addr_t address, target_size_t size, 21 InstructionInfo::InstructionInfo(target_addr_t address, 22 target_addr_t targetAddress, target_size_t size, 21 23 instruction_type type, bool breakpointAllowed, 22 24 const BString& disassembledLine) 23 25 : 24 26 fAddress(address), 27 fTargetAddress(targetAddress), 25 28 fSize(size), 26 29 fType(type), 27 30 fBreakpointAllowed(breakpointAllowed), … … InstructionInfo::InstructionInfo(target_addr_t address, target_size_t size, 31 34 32 35 33 36 bool 34 InstructionInfo::SetTo(target_addr_t address, target_ size_t size,35 instruction_type type, bool breakpointAllowed,37 InstructionInfo::SetTo(target_addr_t address, target_addr_t targetAddress, 38 target_size_t size, instruction_type type, bool breakpointAllowed, 36 39 const BString& disassembledLine) 37 40 { 38 41 fAddress = address; 42 fTargetAddress = targetAddress; 39 43 fSize = size; 40 44 fType = type; 41 45 fBreakpointAllowed = breakpointAllowed; -
src/apps/debugger/arch/InstructionInfo.h
diff --git a/src/apps/debugger/arch/InstructionInfo.h b/src/apps/debugger/arch/InstructionInfo.h index 36c2fa2..f130080 100644
a b class InstructionInfo { 20 20 public: 21 21 InstructionInfo(); 22 22 InstructionInfo(target_addr_t address, 23 target_addr_t targetAddress, 23 24 target_size_t size, instruction_type type, 24 25 bool breakpointAllowed, 25 26 const BString& disassembledLine); 26 27 27 bool SetTo(target_addr_t address, target_size_t size, 28 bool SetTo(target_addr_t address, 29 target_addr_t targetAddress, 30 target_size_t size, 28 31 instruction_type type, 29 32 bool breakpointAllowed, 30 33 const BString& disassembledLine); 31 34 32 35 target_addr_t Address() const { return fAddress; } 36 target_addr_t TargetAddress() const 37 { return fTargetAddress; } 33 38 target_size_t Size() const { return fSize; } 34 39 instruction_type Type() const { return fType; } 35 40 bool IsBreakpointAllowed() const … … public: 40 45 41 46 private: 42 47 target_addr_t fAddress; 48 target_addr_t fTargetAddress; 43 49 target_size_t fSize; 44 50 instruction_type fType; 45 51 bool fBreakpointAllowed; -
src/apps/debugger/arch/x86/ArchitectureX86.cpp
diff --git a/src/apps/debugger/arch/x86/ArchitectureX86.cpp b/src/apps/debugger/arch/x86/ArchitectureX86.cpp index dd19a90..80aec92 100644
a b 23 23 #include "StackFrame.h" 24 24 #include "Statement.h" 25 25 #include "TeamMemory.h" 26 #include "ValueLocation.h" 26 27 #include "X86AssemblyLanguage.h" 27 28 28 29 #include "disasm/DisassemblerX86.h" … … status_t 579 580 ArchitectureX86::GetInstructionInfo(target_addr_t address, 580 581 InstructionInfo& _info) 581 582 { 582 // read the code 583 // read the code - maximum x86{-64} instruction size = 15 bytes 583 584 uint8 buffer[16]; 584 // TODO: What's the maximum instruction size?585 585 ssize_t bytesRead = fTeamMemory->ReadMemory(address, buffer, 586 586 sizeof(buffer)); 587 587 if (bytesRead < 0) … … ArchitectureX86::GetInstructionInfo(target_addr_t address, 596 596 // disassemble the instruction 597 597 BString line; 598 598 target_addr_t instructionAddress; 599 target_addr_t targetAddress = 0; 599 600 target_size_t instructionSize; 600 601 bool breakpointAllowed; 601 602 error = disassembler.GetNextInstruction(line, instructionAddress, … … ArchitectureX86::GetInstructionInfo(target_addr_t address, 607 608 if (buffer[0] == 0xff && (buffer[1] & 0x34) == 0x10) { 608 609 // absolute call with r/m32 609 610 instructionType = INSTRUCTION_TYPE_SUBROUTINE_CALL; 611 // TODO: retrieve target address (might be in a register) 610 612 } else if (buffer[0] == 0xe8 && instructionSize == 5) { 611 613 // relative call with rel32 -- don't categorize the call with 0 as 612 614 // subroutine call, since it is only used to get the address of the GOT 613 615 if (buffer[1] != 0 || buffer[2] != 0 || buffer[3] != 0 614 616 || buffer[4] != 0) { 615 617 instructionType = INSTRUCTION_TYPE_SUBROUTINE_CALL; 618 int32 offset; 619 memcpy(&offset, &buffer[1], 4); 620 targetAddress = instructionAddress + instructionSize + offset; 616 621 } 617 622 } 618 623 619 if (!_info.SetTo(instructionAddress, instructionSize, instructionType,620 breakpointAllowed, line)) {624 if (!_info.SetTo(instructionAddress, targetAddress, instructionSize, 625 instructionType, breakpointAllowed, line)) { 621 626 return B_NO_MEMORY; 622 627 } 623 628 … … ArchitectureX86::GetWatchpointDebugCapabilities(int32& _maxRegisterCount, 643 648 } 644 649 645 650 651 status_t 652 ArchitectureX86::GetReturnAddressLocation(StackFrame* frame, 653 target_size_t valueSize, ValueLocation*& _location) 654 { 655 ValueLocation* location = new(std::nothrow) ValueLocation( 656 IsBigEndian()); 657 if (location == NULL) 658 return B_NO_MEMORY; 659 BReference<ValueLocation> locationReference(location, 660 true); 661 662 if (valueSize <= 4) { 663 ValuePieceLocation piece; 664 piece.SetSize(valueSize); 665 piece.SetToRegister(X86_REGISTER_EAX); 666 if (!location->AddPiece(piece)) 667 return B_NO_MEMORY; 668 } else if (valueSize <= 8) { 669 ValuePieceLocation piece; 670 piece.SetSize(4); 671 piece.SetToRegister(X86_REGISTER_EAX); 672 if (!location->AddPiece(piece)) 673 return B_NO_MEMORY; 674 piece.SetToRegister(X86_REGISTER_EDX); 675 piece.SetSize(valueSize - 4); 676 if (!location->AddPiece(piece)) 677 return B_NO_MEMORY; 678 } else { 679 ValuePieceLocation piece; 680 piece.SetToMemory(frame->GetCpuState()->StackPointer()); 681 piece.SetSize(valueSize); 682 if (!location->AddPiece(piece)) 683 return B_NO_MEMORY; 684 } 685 686 _location = locationReference.Detach(); 687 return B_OK; 688 } 689 690 646 691 void 647 692 ArchitectureX86::_AddRegister(int32 index, const char* name, 648 693 uint32 bitSize, uint32 valueType, register_type type, bool calleePreserved) -
src/apps/debugger/arch/x86/ArchitectureX86.h
diff --git a/src/apps/debugger/arch/x86/ArchitectureX86.h b/src/apps/debugger/arch/x86/ArchitectureX86.h index 48e849c..1549f9b 100644
a b public: 66 66 int32& _maxBytesPerRegister, 67 67 uint8& _watchpointCapabilityFlags); 68 68 69 virtual status_t GetReturnAddressLocation( 70 StackFrame* frame, target_size_t valueSize, 71 ValueLocation*& _location); 72 73 69 74 private: 70 75 struct ToDwarfRegisterMap; 71 76 struct FromDwarfRegisterMap; -
src/apps/debugger/arch/x86_64/ArchitectureX8664.cpp
diff --git a/src/apps/debugger/arch/x86_64/ArchitectureX8664.cpp b/src/apps/debugger/arch/x86_64/ArchitectureX8664.cpp index 2152562..acf2f93 100644
a b ArchitectureX8664::GetInstructionInfo(target_addr_t address, 487 487 // disassemble the instruction 488 488 BString line; 489 489 target_addr_t instructionAddress; 490 target_addr_t targetAddress = 0; 490 491 target_size_t instructionSize; 491 492 bool breakpointAllowed; 492 493 error = disassembler.GetNextInstruction(line, instructionAddress, … … ArchitectureX8664::GetInstructionInfo(target_addr_t address, 508 509 } 509 510 } 510 511 511 if (!_info.SetTo(instructionAddress, instructionSize, instructionType,512 breakpointAllowed, line)) {512 if (!_info.SetTo(instructionAddress, targetAddress, instructionSize, 513 instructionType, breakpointAllowed, line)) { 513 514 return B_NO_MEMORY; 514 515 } 515 516 … … ArchitectureX8664::GetWatchpointDebugCapabilities(int32& _maxRegisterCount, 534 535 } 535 536 536 537 538 status_t 539 ArchitectureX8664::GetReturnAddressLocation(StackFrame* frame, 540 target_size_t valueSize, ValueLocation*& _location) { 541 return B_NOT_SUPPORTED; 542 } 543 544 537 545 void 538 546 ArchitectureX8664::_AddRegister(int32 index, const char* name, 539 547 uint32 bitSize, uint32 valueType, register_type type, bool calleePreserved) -
src/apps/debugger/arch/x86_64/ArchitectureX8664.h
diff --git a/src/apps/debugger/arch/x86_64/ArchitectureX8664.h b/src/apps/debugger/arch/x86_64/ArchitectureX8664.h index ec81448..f61b8f3 100644
a b public: 67 67 int32& _maxBytesPerRegister, 68 68 uint8& _watchpointCapabilityFlags); 69 69 70 virtual status_t GetReturnAddressLocation( 71 StackFrame* frame, target_size_t valueSize, 72 ValueLocation*& _location); 73 70 74 private: 71 75 struct ToDwarfRegisterMap; 72 76 struct FromDwarfRegisterMap; -
src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp
diff --git a/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp b/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp index c6aa3ca..d8942ff 100644
a b 41 41 #include "FunctionID.h" 42 42 #include "FunctionInstance.h" 43 43 #include "GlobalTypeLookup.h" 44 #include "Image.h" 45 #include "ImageDebugInfo.h" 44 46 #include "InstructionInfo.h" 45 47 #include "LocatableFile.h" 46 48 #include "Register.h" … … 56 58 #include "TypeLookupConstraints.h" 57 59 #include "UnsupportedLanguage.h" 58 60 #include "Variable.h" 61 #include "ValueLocation.h" 59 62 60 63 61 64 namespace { … … DwarfImageDebugInfo::CreateFrame(Image* image, 672 675 // call to see if we need to potentially retrieve a return value 673 676 // as well 674 677 if (instructionPointer > functionInstance->Address() - fRelocationDelta) { 675 _CreateReturnValue(functionInstance, function, frame,678 _CreateReturnValue(functionInstance, image, function, frame, 676 679 *stackFrameDebugInfo, instructionPointer); 677 680 } 678 681 } … … DwarfImageDebugInfo::_CreateLocalVariables(CompilationUnit* unit, 1085 1088 1086 1089 status_t 1087 1090 DwarfImageDebugInfo::_CreateReturnValue(FunctionInstance* functionInstance, 1088 DwarfFunctionDebugInfo* function, StackFrame* frame,1091 Image* image, DwarfFunctionDebugInfo* function, StackFrame* frame, 1089 1092 DwarfStackFrameDebugInfo& factory, target_addr_t instructionPointer) 1090 1093 { 1091 1094 DisassembledCode* sourceCode = NULL; … … DwarfImageDebugInfo::_CreateReturnValue(FunctionInstance* functionInstance, 1111 1114 previousStatementAddress); 1112 1115 if (statement == NULL) 1113 1116 return B_BAD_VALUE; 1117 previousStatementAddress = statement->CoveringAddressRange().Start() - 1; 1118 statement = sourceCode->StatementAtAddress( 1119 previousStatementAddress); 1120 if (statement == NULL) 1121 return B_BAD_VALUE; 1114 1122 1115 1123 TargetAddressRange range = statement->CoveringAddressRange(); 1116 1124 InstructionInfo info; 1117 1125 if (fArchitecture->GetInstructionInfo(range.Start(), info) == B_OK 1118 1126 && info.Type() == INSTRUCTION_TYPE_SUBROUTINE_CALL) { 1119 // TODO: determine where the previous instruction actually jumps to, 1120 // retrieve that function (could potentially be in another image), 1121 // and use its return type to retrieve the return value (will need 1122 // architecture support since function return value passing convention 1123 // is arch-dependent). 1127 target_addr_t targetAddress = info.TargetAddress(); 1128 if (targetAddress == 0) 1129 return B_BAD_VALUE; 1130 1131 if (image->ContainsAddress(targetAddress)) { 1132 FunctionInstance* targetFunction; 1133 if (targetAddress >= fPLTSectionStart && targetAddress < fPLTSectionEnd) { 1134 // TODO: resolve actual target address in the PIC case 1135 // and adjust targetAddress accordingly 1136 } 1137 ImageDebugInfo* imageInfo = image->GetImageDebugInfo(); 1138 targetFunction = imageInfo->FunctionAtAddress(targetAddress); 1139 if (targetFunction != NULL) { 1140 DwarfFunctionDebugInfo* targetInfo = 1141 dynamic_cast<DwarfFunctionDebugInfo*>( 1142 targetFunction->GetFunctionDebugInfo()); 1143 if (targetInfo != NULL) { 1144 DIESubprogram* subProgram = targetInfo->SubprogramEntry(); 1145 DIEType* returnType = subProgram->ReturnType(); 1146 if (returnType == NULL) { 1147 // function doesn't return a value, we're done. 1148 return B_OK; 1149 } 1150 1151 ValueLocation* location; 1152 result = fArchitecture->GetReturnAddressLocation(frame, 1153 returnType->ByteSize()->constant, location); 1154 if (result != B_OK) 1155 return result; 1156 BReference<ValueLocation> locationReference(location, 1157 true); 1158 Variable* variable = NULL; 1159 BReference<FunctionID> idReference( 1160 targetFunction->GetFunctionID(), true); 1161 result = factory.CreateReturnValue(idReference, 1162 returnType, location, variable); 1163 if (result != B_OK) 1164 return result; 1165 BReference<Variable> variableReference(variable, true); 1166 if (!frame->AddLocalVariable(variable)) 1167 return B_NO_MEMORY; 1168 } 1169 } 1170 } 1124 1171 } 1125 1172 1126 1173 return B_OK; -
src/apps/debugger/debug_info/DwarfImageDebugInfo.h
diff --git a/src/apps/debugger/debug_info/DwarfImageDebugInfo.h b/src/apps/debugger/debug_info/DwarfImageDebugInfo.h index c03370f..4c9b0c1 100644
a b private: 104 104 const EntryListWrapper& blockEntries); 105 105 106 106 status_t _CreateReturnValue(FunctionInstance* instance, 107 Image* image, 107 108 DwarfFunctionDebugInfo* info, 108 109 StackFrame* frame, 109 110 DwarfStackFrameDebugInfo& factory, -
src/apps/debugger/debug_info/DwarfStackFrameDebugInfo.cpp
diff --git a/src/apps/debugger/debug_info/DwarfStackFrameDebugInfo.cpp b/src/apps/debugger/debug_info/DwarfStackFrameDebugInfo.cpp index 99853ae..42cef63 100644
a b 1 1 /* 2 * Copyright 2012, Rene Gollent, rene@gollent.com. 2 3 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. 3 4 * Distributed under the terms of the MIT License. 4 5 */ … … 23 24 #include "LocalVariableID.h" 24 25 #include "Register.h" 25 26 #include "RegisterMap.h" 27 #include "ReturnValueID.h" 26 28 #include "StringUtils.h" 27 29 #include "Tracing.h" 28 30 #include "ValueLocation.h" … … private: 117 119 }; 118 120 119 121 122 // #pragma mark - DwarfReturnValueID 123 124 125 struct DwarfStackFrameDebugInfo::DwarfReturnValueID 126 : public ReturnValueID { 127 128 DwarfReturnValueID(FunctionID* functionID) 129 : 130 fFunctionID(functionID), 131 fName("(returned)") 132 { 133 fFunctionID->AcquireReference(); 134 } 135 136 virtual ~DwarfReturnValueID() 137 { 138 fFunctionID->ReleaseReference(); 139 } 140 141 virtual bool operator==(const ObjectID& other) const 142 { 143 const DwarfReturnValueID* returnValueID 144 = dynamic_cast<const DwarfReturnValueID*>(&other); 145 return returnValueID != NULL 146 && *fFunctionID == *returnValueID->fFunctionID 147 && fName == returnValueID->fName; 148 } 149 150 protected: 151 virtual uint32 ComputeHashValue() const 152 { 153 uint32 hash = fFunctionID->HashValue(); 154 return hash * 25 + StringUtils::HashValue(fName); 155 } 156 157 private: 158 FunctionID* fFunctionID; 159 const BString fName; 160 }; 161 162 120 163 // #pragma mark - DwarfStackFrameDebugInfo 121 164 122 165 … … DwarfStackFrameDebugInfo::CreateLocalVariable(FunctionID* functionID, 235 278 236 279 237 280 status_t 281 DwarfStackFrameDebugInfo::CreateReturnValue(FunctionID* functionID, 282 DIEType* returnType, ValueLocation* location, Variable*& _variable) 283 { 284 if (returnType == NULL) 285 return B_BAD_VALUE; 286 287 // create the type 288 DwarfType* type; 289 status_t error = fTypeFactory->CreateType(returnType, type); 290 if (error != B_OK) 291 return error; 292 BReference<DwarfType> typeReference(type, true); 293 294 DwarfReturnValueID* id = new(std::nothrow) DwarfReturnValueID( 295 functionID); 296 if (id == NULL) 297 return B_NO_MEMORY; 298 299 BString name; 300 name.SetToFormat("%s returned", functionID->FunctionName().String()); 301 302 Variable* variable = new(std::nothrow) Variable(id, name, 303 type, location); 304 if (variable == NULL) 305 return B_NO_MEMORY; 306 307 _variable = variable; 308 309 return B_OK; 310 } 311 312 313 status_t 238 314 DwarfStackFrameDebugInfo::_CreateVariable(ObjectID* id, const BString& name, 239 315 DIEType* typeEntry, LocationDescription* locationDescription, 240 316 Variable*& _variable) -
src/apps/debugger/debug_info/DwarfStackFrameDebugInfo.h
diff --git a/src/apps/debugger/debug_info/DwarfStackFrameDebugInfo.h b/src/apps/debugger/debug_info/DwarfStackFrameDebugInfo.h index e55d0d2..3e69130 100644
a b 1 1 /* 2 * Copyright 2012, Rene Gollent, rene@gollent.com. 2 3 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. 3 4 * Distributed under the terms of the MIT License. 4 5 */ … … public: 56 57 DIEVariable* variableEntry, 57 58 Variable*& _variable); 58 59 // returns reference 60 status_t CreateReturnValue(FunctionID* functionID, 61 DIEType* returnType, 62 ValueLocation* location, 63 Variable*& _variable); 64 // returns reference 59 65 60 66 private: 61 67 struct DwarfFunctionParameterID; 62 68 struct DwarfLocalVariableID; 69 struct DwarfReturnValueID; 63 70 64 71 private: 65 72 status_t _CreateVariable(ObjectID* id,