Implement support for detecting if a given target address is in a Procedure
Linkage Table section. Use that additional information to skip PLT entries while stepping. Fixes #6974. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39823 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2009, Ingo Weinhold, [email protected].
|
* Copyright 2009, Ingo Weinhold, [email protected].
|
||||||
|
* Copyright 2010, Rene Gollent, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -589,6 +590,33 @@ ThreadHandler::_HandleSingleStepStep(CpuState* cpuState)
|
|||||||
if (fStepStatement->ContainsAddress(cpuState->InstructionPointer())) {
|
if (fStepStatement->ContainsAddress(cpuState->InstructionPointer())) {
|
||||||
_SingleStepThread(cpuState->InstructionPointer());
|
_SingleStepThread(cpuState->InstructionPointer());
|
||||||
return true;
|
return true;
|
||||||
|
} else {
|
||||||
|
StackTrace* stackTrace = fThread->GetStackTrace();
|
||||||
|
Reference<StackTrace> stackTraceReference(stackTrace);
|
||||||
|
|
||||||
|
if (stackTrace == NULL && cpuState != NULL) {
|
||||||
|
if (fDebuggerInterface->GetArchitecture()->CreateStackTrace(
|
||||||
|
fThread->GetTeam(), this, cpuState, stackTrace) == B_OK) {
|
||||||
|
stackTraceReference.SetTo(stackTrace, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stackTrace != NULL) {
|
||||||
|
StackFrame *frame = stackTrace->FrameAt(0);
|
||||||
|
Image* image = frame->GetImage();
|
||||||
|
ImageDebugInfo* info = NULL;
|
||||||
|
if (GetImageDebugInfo(image, info) != B_OK)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Reference<ImageDebugInfo>(info, true);
|
||||||
|
|
||||||
|
if (info->GetAddressSectionType(
|
||||||
|
cpuState->InstructionPointer())
|
||||||
|
== ADDRESS_SECTION_TYPE_PLT) {
|
||||||
|
_SingleStepThread(cpuState->InstructionPointer());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,6 +86,13 @@ DebuggerImageDebugInfo::GetType(GlobalTypeCache* cache,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AddressSectionType
|
||||||
|
DebuggerImageDebugInfo::GetAddressSectionType(target_addr_t address)
|
||||||
|
{
|
||||||
|
return ADDRESS_SECTION_TYPE_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
DebuggerImageDebugInfo::CreateFrame(Image* image,
|
DebuggerImageDebugInfo::CreateFrame(Image* image,
|
||||||
FunctionInstance* functionInstance, CpuState* cpuState,
|
FunctionInstance* functionInstance, CpuState* cpuState,
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ public:
|
|||||||
BObjectList<FunctionDebugInfo>& functions);
|
BObjectList<FunctionDebugInfo>& functions);
|
||||||
virtual status_t GetType(GlobalTypeCache* cache,
|
virtual status_t GetType(GlobalTypeCache* cache,
|
||||||
const BString& name, Type*& _type);
|
const BString& name, Type*& _type);
|
||||||
|
virtual AddressSectionType GetAddressSectionType(target_addr_t address);
|
||||||
virtual status_t CreateFrame(Image* image,
|
virtual status_t CreateFrame(Image* image,
|
||||||
FunctionInstance* functionInstance,
|
FunctionInstance* functionInstance,
|
||||||
CpuState* cpuState,
|
CpuState* cpuState,
|
||||||
|
|||||||
@@ -429,6 +429,30 @@ DwarfImageDebugInfo::GetType(GlobalTypeCache* cache,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AddressSectionType
|
||||||
|
DwarfImageDebugInfo::GetAddressSectionType(target_addr_t address)
|
||||||
|
{
|
||||||
|
address -= fRelocationDelta;
|
||||||
|
ElfFile* file = fFile->GetElfFile();
|
||||||
|
|
||||||
|
ElfSection* section = file->GetSection(".text");
|
||||||
|
if (section != NULL && address >= section->LoadAddress()
|
||||||
|
&& address < section->LoadAddress() + section->Size()) {
|
||||||
|
file->PutSection(section);
|
||||||
|
return ADDRESS_SECTION_TYPE_FUNCTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
section = file->GetSection(".plt");
|
||||||
|
if (section != NULL && address >= section->LoadAddress()
|
||||||
|
&& address < section->LoadAddress() + section->Size()) {
|
||||||
|
file->PutSection(section);
|
||||||
|
return ADDRESS_SECTION_TYPE_PLT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ADDRESS_SECTION_TYPE_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
DwarfImageDebugInfo::CreateFrame(Image* image,
|
DwarfImageDebugInfo::CreateFrame(Image* image,
|
||||||
FunctionInstance* functionInstance, CpuState* cpuState,
|
FunctionInstance* functionInstance, CpuState* cpuState,
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||||
|
* Copyright 2010, Rene Gollent, rene@gollent.com.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
#ifndef DWARF_IMAGE_DEBUG_INFO_H
|
#ifndef DWARF_IMAGE_DEBUG_INFO_H
|
||||||
@@ -10,6 +11,7 @@
|
|||||||
|
|
||||||
#include <util/OpenHashTable.h>
|
#include <util/OpenHashTable.h>
|
||||||
|
|
||||||
|
#include "AddressSectionTypes.h"
|
||||||
#include "ImageInfo.h"
|
#include "ImageInfo.h"
|
||||||
#include "SpecificImageDebugInfo.h"
|
#include "SpecificImageDebugInfo.h"
|
||||||
#include "Type.h"
|
#include "Type.h"
|
||||||
@@ -50,6 +52,9 @@ public:
|
|||||||
BObjectList<FunctionDebugInfo>& functions);
|
BObjectList<FunctionDebugInfo>& functions);
|
||||||
virtual status_t GetType(GlobalTypeCache* cache,
|
virtual status_t GetType(GlobalTypeCache* cache,
|
||||||
const BString& name, Type*& _type);
|
const BString& name, Type*& _type);
|
||||||
|
|
||||||
|
virtual AddressSectionType GetAddressSectionType(target_addr_t address);
|
||||||
|
|
||||||
virtual status_t CreateFrame(Image* image,
|
virtual status_t CreateFrame(Image* image,
|
||||||
FunctionInstance* functionInstance,
|
FunctionInstance* functionInstance,
|
||||||
CpuState* cpuState,
|
CpuState* cpuState,
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||||
|
* Copyright 2010, Rene Gollent, rene@gollent.com.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -90,6 +91,21 @@ ImageDebugInfo::GetType(GlobalTypeCache* cache, const BString& name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AddressSectionType
|
||||||
|
ImageDebugInfo::GetAddressSectionType(target_addr_t address) const
|
||||||
|
{
|
||||||
|
AddressSectionType type = ADDRESS_SECTION_TYPE_UNKNOWN;
|
||||||
|
for (int32 i = 0; SpecificImageDebugInfo* specificInfo
|
||||||
|
= fSpecificInfos.ItemAt(i); i++) {
|
||||||
|
type = specificInfo->GetAddressSectionType(address);
|
||||||
|
if (type != ADDRESS_SECTION_TYPE_UNKNOWN)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int32
|
int32
|
||||||
ImageDebugInfo::CountFunctions() const
|
ImageDebugInfo::CountFunctions() const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||||
|
* Copyright 2010, Rene Gollent, rene@gollent.com.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
#ifndef IMAGE_DEBUG_INFO_H
|
#ifndef IMAGE_DEBUG_INFO_H
|
||||||
@@ -11,6 +12,7 @@
|
|||||||
#include <ObjectList.h>
|
#include <ObjectList.h>
|
||||||
#include <Referenceable.h>
|
#include <Referenceable.h>
|
||||||
|
|
||||||
|
#include "AddressSectionTypes.h"
|
||||||
#include "ImageInfo.h"
|
#include "ImageInfo.h"
|
||||||
#include "Types.h"
|
#include "Types.h"
|
||||||
|
|
||||||
@@ -39,6 +41,8 @@ public:
|
|||||||
status_t GetType(GlobalTypeCache* cache,
|
status_t GetType(GlobalTypeCache* cache,
|
||||||
const BString& name, Type*& _type);
|
const BString& name, Type*& _type);
|
||||||
// returns a reference
|
// returns a reference
|
||||||
|
AddressSectionType GetAddressSectionType(target_addr_t address)
|
||||||
|
const;
|
||||||
|
|
||||||
int32 CountFunctions() const;
|
int32 CountFunctions() const;
|
||||||
FunctionInstance* FunctionAt(int32 index) const;
|
FunctionInstance* FunctionAt(int32 index) const;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <ObjectList.h>
|
#include <ObjectList.h>
|
||||||
#include <Referenceable.h>
|
#include <Referenceable.h>
|
||||||
|
|
||||||
|
#include "AddressSectionTypes.h"
|
||||||
#include "Types.h"
|
#include "Types.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -43,6 +44,8 @@ public:
|
|||||||
virtual status_t GetType(GlobalTypeCache* cache,
|
virtual status_t GetType(GlobalTypeCache* cache,
|
||||||
const BString& name, Type*& _type) = 0;
|
const BString& name, Type*& _type) = 0;
|
||||||
// returns a reference
|
// returns a reference
|
||||||
|
virtual AddressSectionType GetAddressSectionType(target_addr_t address)
|
||||||
|
= 0;
|
||||||
|
|
||||||
virtual status_t CreateFrame(Image* image,
|
virtual status_t CreateFrame(Image* image,
|
||||||
FunctionInstance* functionInstance,
|
FunctionInstance* functionInstance,
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010, Rene Gollent, rene@gollent.com.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef ADDRESS_SECTION_TYPES_H
|
||||||
|
#define ADDRESS_SECTION_TYPES_H
|
||||||
|
|
||||||
|
|
||||||
|
enum AddressSectionType {
|
||||||
|
ADDRESS_SECTION_TYPE_UNKNOWN = 0,
|
||||||
|
ADDRESS_SECTION_TYPE_FUNCTION,
|
||||||
|
ADDRESS_SECTION_TYPE_PLT
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // ADDRESS_SECTION_TYPES_H
|
||||||
Reference in New Issue
Block a user