ELF64 and x86_64 support in the debug kit.
This commit is contained in:
@@ -123,7 +123,7 @@ BDebugEventInputStream::Seek(off_t streamOffset)
|
|||||||
if (fStream != NULL)
|
if (fStream != NULL)
|
||||||
return B_UNSUPPORTED;
|
return B_UNSUPPORTED;
|
||||||
|
|
||||||
if (streamOffset < 0 || streamOffset > fBufferCapacity)
|
if (streamOffset < 0 || streamOffset > (off_t)fBufferCapacity)
|
||||||
return B_BUFFER_OVERFLOW;
|
return B_BUFFER_OVERFLOW;
|
||||||
|
|
||||||
fStreamPosition = 0;
|
fStreamPosition = 0;
|
||||||
|
|||||||
+30
-28
@@ -82,17 +82,17 @@ SymbolTableBasedImage::~SymbolTableBasedImage()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const Elf32_Sym*
|
const elf_sym*
|
||||||
SymbolTableBasedImage::LookupSymbol(addr_t address, addr_t* _baseAddress,
|
SymbolTableBasedImage::LookupSymbol(addr_t address, addr_t* _baseAddress,
|
||||||
const char** _symbolName, size_t *_symbolNameLen, bool *_exactMatch) const
|
const char** _symbolName, size_t *_symbolNameLen, bool *_exactMatch) const
|
||||||
{
|
{
|
||||||
const Elf32_Sym* symbolFound = NULL;
|
const elf_sym* symbolFound = NULL;
|
||||||
const char* symbolName = NULL;
|
const char* symbolName = NULL;
|
||||||
bool exactMatch = false;
|
bool exactMatch = false;
|
||||||
addr_t deltaFound = ~(addr_t)0;
|
addr_t deltaFound = ~(addr_t)0;
|
||||||
|
|
||||||
for (int32 i = 0; i < fSymbolCount; i++) {
|
for (int32 i = 0; i < fSymbolCount; i++) {
|
||||||
const Elf32_Sym* symbol = &fSymbolTable[i];
|
const elf_sym* symbol = &fSymbolTable[i];
|
||||||
|
|
||||||
if (symbol->st_value == 0
|
if (symbol->st_value == 0
|
||||||
|| symbol->st_size >= (size_t)fInfo.text_size + fInfo.data_size) {
|
|| symbol->st_size >= (size_t)fInfo.text_size + fInfo.data_size) {
|
||||||
@@ -141,10 +141,9 @@ SymbolTableBasedImage::NextSymbol(int32& iterator, const char** _symbolName,
|
|||||||
if (++iterator >= fSymbolCount)
|
if (++iterator >= fSymbolCount)
|
||||||
return B_ENTRY_NOT_FOUND;
|
return B_ENTRY_NOT_FOUND;
|
||||||
|
|
||||||
const Elf32_Sym* symbol = &fSymbolTable[iterator];
|
const elf_sym* symbol = &fSymbolTable[iterator];
|
||||||
|
|
||||||
if ((ELF32_ST_TYPE(symbol->st_info) != STT_FUNC
|
if ((symbol->Type() != STT_FUNC && symbol->Type() != STT_OBJECT)
|
||||||
&& ELF32_ST_TYPE(symbol->st_info) != STT_OBJECT)
|
|
||||||
|| symbol->st_value == 0) {
|
|| symbol->st_value == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -153,8 +152,8 @@ SymbolTableBasedImage::NextSymbol(int32& iterator, const char** _symbolName,
|
|||||||
*_symbolNameLen = _SymbolNameLen(*_symbolName);
|
*_symbolNameLen = _SymbolNameLen(*_symbolName);
|
||||||
*_symbolAddress = symbol->st_value + fLoadDelta;
|
*_symbolAddress = symbol->st_value + fLoadDelta;
|
||||||
*_symbolSize = symbol->st_size;
|
*_symbolSize = symbol->st_size;
|
||||||
*_symbolType = ELF32_ST_TYPE(symbol->st_info) == STT_FUNC
|
*_symbolType = symbol->Type() == STT_FUNC ? B_SYMBOL_TYPE_TEXT
|
||||||
? B_SYMBOL_TYPE_TEXT : B_SYMBOL_TYPE_DATA;
|
: B_SYMBOL_TYPE_DATA;
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -268,7 +267,7 @@ ImageFile::_LoadFile(const char* path, addr_t* _textAddress, size_t* _textSize,
|
|||||||
return errno;
|
return errno;
|
||||||
|
|
||||||
fFileSize = st.st_size;
|
fFileSize = st.st_size;
|
||||||
if (fFileSize < sizeof(Elf32_Ehdr))
|
if (fFileSize < (off_t)sizeof(elf_ehdr))
|
||||||
return B_NOT_AN_EXECUTABLE;
|
return B_NOT_AN_EXECUTABLE;
|
||||||
|
|
||||||
// map it
|
// map it
|
||||||
@@ -277,7 +276,7 @@ ImageFile::_LoadFile(const char* path, addr_t* _textAddress, size_t* _textSize,
|
|||||||
return errno;
|
return errno;
|
||||||
|
|
||||||
// examine the elf header
|
// examine the elf header
|
||||||
Elf32_Ehdr* elfHeader = (Elf32_Ehdr*)fMappedFile;
|
elf_ehdr* elfHeader = (elf_ehdr*)fMappedFile;
|
||||||
if (memcmp(elfHeader->e_ident, ELF_MAGIC, 4) != 0)
|
if (memcmp(elfHeader->e_ident, ELF_MAGIC, 4) != 0)
|
||||||
return B_NOT_AN_EXECUTABLE;
|
return B_NOT_AN_EXECUTABLE;
|
||||||
|
|
||||||
@@ -286,27 +285,28 @@ ImageFile::_LoadFile(const char* path, addr_t* _textAddress, size_t* _textSize,
|
|||||||
|
|
||||||
// verify the location of the program headers
|
// verify the location of the program headers
|
||||||
int32 programHeaderCount = elfHeader->e_phnum;
|
int32 programHeaderCount = elfHeader->e_phnum;
|
||||||
if (elfHeader->e_phoff < sizeof(Elf32_Ehdr)
|
if (elfHeader->e_phoff < sizeof(elf_ehdr)
|
||||||
|| elfHeader->e_phentsize < sizeof(Elf32_Phdr)
|
|| elfHeader->e_phentsize < sizeof(elf_phdr)
|
||||||
|| elfHeader->e_phoff + programHeaderCount * elfHeader->e_phentsize
|
|| (off_t)(elfHeader->e_phoff + programHeaderCount
|
||||||
|
* elfHeader->e_phentsize)
|
||||||
> fFileSize) {
|
> fFileSize) {
|
||||||
return B_NOT_AN_EXECUTABLE;
|
return B_NOT_AN_EXECUTABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Elf32_Phdr* programHeaders
|
elf_phdr* programHeaders
|
||||||
= (Elf32_Phdr*)(fMappedFile + elfHeader->e_phoff);
|
= (elf_phdr*)(fMappedFile + elfHeader->e_phoff);
|
||||||
|
|
||||||
// verify the location of the section headers
|
// verify the location of the section headers
|
||||||
int32 sectionCount = elfHeader->e_shnum;
|
int32 sectionCount = elfHeader->e_shnum;
|
||||||
if (elfHeader->e_shoff < sizeof(Elf32_Ehdr)
|
if (elfHeader->e_shoff < sizeof(elf_ehdr)
|
||||||
|| elfHeader->e_shentsize < sizeof(Elf32_Shdr)
|
|| elfHeader->e_shentsize < sizeof(elf_shdr)
|
||||||
|| elfHeader->e_shoff + sectionCount * elfHeader->e_shentsize
|
|| (off_t)(elfHeader->e_shoff + sectionCount * elfHeader->e_shentsize)
|
||||||
> fFileSize) {
|
> fFileSize) {
|
||||||
return B_NOT_AN_EXECUTABLE;
|
return B_NOT_AN_EXECUTABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Elf32_Shdr* sectionHeaders
|
elf_shdr* sectionHeaders
|
||||||
= (Elf32_Shdr*)(fMappedFile + elfHeader->e_shoff);
|
= (elf_shdr*)(fMappedFile + elfHeader->e_shoff);
|
||||||
|
|
||||||
// find the text and data segment -- we need load address and size
|
// find the text and data segment -- we need load address and size
|
||||||
*_textAddress = 0;
|
*_textAddress = 0;
|
||||||
@@ -314,7 +314,7 @@ ImageFile::_LoadFile(const char* path, addr_t* _textAddress, size_t* _textSize,
|
|||||||
*_dataAddress = 0;
|
*_dataAddress = 0;
|
||||||
*_dataSize = 0;
|
*_dataSize = 0;
|
||||||
for (int32 i = 0; i < programHeaderCount; i++) {
|
for (int32 i = 0; i < programHeaderCount; i++) {
|
||||||
Elf32_Phdr* header = (Elf32_Phdr*)
|
elf_phdr* header = (elf_phdr*)
|
||||||
((uint8*)programHeaders + i * elfHeader->e_phentsize);
|
((uint8*)programHeaders + i * elfHeader->e_phentsize);
|
||||||
if (header->p_type == PT_LOAD) {
|
if (header->p_type == PT_LOAD) {
|
||||||
if ((header->p_flags & PF_WRITE) == 0) {
|
if ((header->p_flags & PF_WRITE) == 0) {
|
||||||
@@ -330,25 +330,27 @@ ImageFile::_LoadFile(const char* path, addr_t* _textAddress, size_t* _textSize,
|
|||||||
|
|
||||||
// find the symbol table
|
// find the symbol table
|
||||||
for (int32 i = 0; i < elfHeader->e_shnum; i++) {
|
for (int32 i = 0; i < elfHeader->e_shnum; i++) {
|
||||||
Elf32_Shdr* sectionHeader = (Elf32_Shdr*)
|
elf_shdr* sectionHeader = (elf_shdr*)
|
||||||
((uint8*)sectionHeaders + i * elfHeader->e_shentsize);
|
((uint8*)sectionHeaders + i * elfHeader->e_shentsize);
|
||||||
|
|
||||||
if (sectionHeader->sh_type == SHT_SYMTAB) {
|
if (sectionHeader->sh_type == SHT_SYMTAB) {
|
||||||
Elf32_Shdr& stringHeader = *(Elf32_Shdr*)
|
elf_shdr& stringHeader = *(elf_shdr*)
|
||||||
((uint8*)sectionHeaders
|
((uint8*)sectionHeaders
|
||||||
+ sectionHeader->sh_link * elfHeader->e_shentsize);
|
+ sectionHeader->sh_link * elfHeader->e_shentsize);
|
||||||
|
|
||||||
if (stringHeader.sh_type != SHT_STRTAB)
|
if (stringHeader.sh_type != SHT_STRTAB)
|
||||||
return B_BAD_DATA;
|
return B_BAD_DATA;
|
||||||
|
|
||||||
if (sectionHeader->sh_offset + sectionHeader->sh_size > fFileSize
|
if ((off_t)(sectionHeader->sh_offset + sectionHeader->sh_size)
|
||||||
|| stringHeader.sh_offset + stringHeader.sh_size > fFileSize) {
|
> fFileSize
|
||||||
|
|| (off_t)(stringHeader.sh_offset + stringHeader.sh_size)
|
||||||
|
> fFileSize) {
|
||||||
return B_BAD_DATA;
|
return B_BAD_DATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
fSymbolTable = (Elf32_Sym*)(fMappedFile + sectionHeader->sh_offset);
|
fSymbolTable = (elf_sym*)(fMappedFile + sectionHeader->sh_offset);
|
||||||
fStringTable = (char*)(fMappedFile + stringHeader.sh_offset);
|
fStringTable = (char*)(fMappedFile + stringHeader.sh_offset);
|
||||||
fSymbolCount = sectionHeader->sh_size / sizeof(Elf32_Sym);
|
fSymbolCount = sectionHeader->sh_size / sizeof(elf_sym);
|
||||||
fStringTableSize = stringHeader.sh_size;
|
fStringTableSize = stringHeader.sh_size;
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@@ -388,7 +390,7 @@ KernelImage::Init(const image_info& info)
|
|||||||
return error;
|
return error;
|
||||||
|
|
||||||
// allocate the tables
|
// allocate the tables
|
||||||
fSymbolTable = new(std::nothrow) Elf32_Sym[fSymbolCount];
|
fSymbolTable = new(std::nothrow) elf_sym[fSymbolCount];
|
||||||
fStringTable = new(std::nothrow) char[fStringTableSize];
|
fStringTable = new(std::nothrow) char[fStringTableSize];
|
||||||
if (fSymbolTable == NULL || fStringTable == NULL)
|
if (fSymbolTable == NULL || fStringTable == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <elf_common.h>
|
||||||
#include <image.h>
|
#include <image.h>
|
||||||
#include <OS.h>
|
#include <OS.h>
|
||||||
|
|
||||||
@@ -16,7 +17,6 @@
|
|||||||
|
|
||||||
struct image_t;
|
struct image_t;
|
||||||
struct runtime_loader_debug_area;
|
struct runtime_loader_debug_area;
|
||||||
struct Elf32_Sym;
|
|
||||||
|
|
||||||
|
|
||||||
namespace BPrivate {
|
namespace BPrivate {
|
||||||
@@ -35,7 +35,7 @@ public:
|
|||||||
{ return (addr_t)fInfo.text; }
|
{ return (addr_t)fInfo.text; }
|
||||||
size_t TextSize() const { return fInfo.text_size; }
|
size_t TextSize() const { return fInfo.text_size; }
|
||||||
|
|
||||||
virtual const Elf32_Sym* LookupSymbol(addr_t address,
|
virtual const elf_sym* LookupSymbol(addr_t address,
|
||||||
addr_t* _baseAddress,
|
addr_t* _baseAddress,
|
||||||
const char** _symbolName,
|
const char** _symbolName,
|
||||||
size_t *_symbolNameLen,
|
size_t *_symbolNameLen,
|
||||||
@@ -60,7 +60,7 @@ public:
|
|||||||
SymbolTableBasedImage();
|
SymbolTableBasedImage();
|
||||||
virtual ~SymbolTableBasedImage();
|
virtual ~SymbolTableBasedImage();
|
||||||
|
|
||||||
virtual const Elf32_Sym* LookupSymbol(addr_t address,
|
virtual const elf_sym* LookupSymbol(addr_t address,
|
||||||
addr_t* _baseAddress,
|
addr_t* _baseAddress,
|
||||||
const char** _symbolName,
|
const char** _symbolName,
|
||||||
size_t *_symbolNameLen,
|
size_t *_symbolNameLen,
|
||||||
@@ -76,7 +76,7 @@ protected:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
addr_t fLoadDelta;
|
addr_t fLoadDelta;
|
||||||
Elf32_Sym* fSymbolTable;
|
elf_sym* fSymbolTable;
|
||||||
char* fStringTable;
|
char* fStringTable;
|
||||||
int32 fSymbolCount;
|
int32 fSymbolCount;
|
||||||
size_t fStringTableSize;
|
size_t fStringTableSize;
|
||||||
|
|||||||
@@ -196,7 +196,7 @@ public:
|
|||||||
const image_t* image, int32 symbolCount);
|
const image_t* image, int32 symbolCount);
|
||||||
virtual ~LoadedImage();
|
virtual ~LoadedImage();
|
||||||
|
|
||||||
virtual const Elf32_Sym* LookupSymbol(addr_t address,
|
virtual const elf_sym* LookupSymbol(addr_t address,
|
||||||
addr_t* _baseAddress,
|
addr_t* _baseAddress,
|
||||||
const char** _symbolName,
|
const char** _symbolName,
|
||||||
size_t *_symbolNameLen,
|
size_t *_symbolNameLen,
|
||||||
@@ -251,7 +251,7 @@ SymbolLookup::Init()
|
|||||||
|
|
||||||
// find the runtime loader debug area
|
// find the runtime loader debug area
|
||||||
runtime_loader_debug_area *remoteDebugArea = NULL;
|
runtime_loader_debug_area *remoteDebugArea = NULL;
|
||||||
int32 cookie = 0;
|
ssize_t cookie = 0;
|
||||||
area_info areaInfo;
|
area_info areaInfo;
|
||||||
while (get_next_area_info(fTeam, &cookie, &areaInfo) == B_OK) {
|
while (get_next_area_info(fTeam, &cookie, &areaInfo) == B_OK) {
|
||||||
if (strcmp(areaInfo.name, RUNTIME_LOADER_DEBUG_AREA_NAME) == 0) {
|
if (strcmp(areaInfo.name, RUNTIME_LOADER_DEBUG_AREA_NAME) == 0) {
|
||||||
@@ -340,7 +340,7 @@ SymbolLookup::LookupSymbolAddress(addr_t address, addr_t *_baseAddress,
|
|||||||
if (_imageName != NULL)
|
if (_imageName != NULL)
|
||||||
*_imageName = image->Name();
|
*_imageName = image->Name();
|
||||||
|
|
||||||
const Elf32_Sym* symbolFound = image->LookupSymbol(address, _baseAddress,
|
const elf_sym* symbolFound = image->LookupSymbol(address, _baseAddress,
|
||||||
_symbolName, _symbolNameLen, _exactMatch);
|
_symbolName, _symbolNameLen, _exactMatch);
|
||||||
|
|
||||||
TRACE(("SymbolLookup::LookupSymbolAddress(): done: symbol: %p, image name: "
|
TRACE(("SymbolLookup::LookupSymbolAddress(): done: symbol: %p, image name: "
|
||||||
@@ -557,7 +557,7 @@ SymbolLookup::LoadedImage::~LoadedImage()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const Elf32_Sym*
|
const elf_sym*
|
||||||
SymbolLookup::LoadedImage::LookupSymbol(addr_t address, addr_t* _baseAddress,
|
SymbolLookup::LoadedImage::LookupSymbol(addr_t address, addr_t* _baseAddress,
|
||||||
const char** _symbolName, size_t *_symbolNameLen, bool *_exactMatch) const
|
const char** _symbolName, size_t *_symbolNameLen, bool *_exactMatch) const
|
||||||
{
|
{
|
||||||
@@ -566,7 +566,7 @@ SymbolLookup::LoadedImage::LookupSymbol(addr_t address, addr_t* _baseAddress,
|
|||||||
(void*)fImage->regions[0].vmstart, fImage->regions[0].size));
|
(void*)fImage->regions[0].vmstart, fImage->regions[0].size));
|
||||||
|
|
||||||
// search the image for the symbol
|
// search the image for the symbol
|
||||||
const struct Elf32_Sym *symbolFound = NULL;
|
const elf_sym *symbolFound = NULL;
|
||||||
addr_t deltaFound = INT_MAX;
|
addr_t deltaFound = INT_MAX;
|
||||||
bool exactMatch = false;
|
bool exactMatch = false;
|
||||||
const char *symbolName = NULL;
|
const char *symbolName = NULL;
|
||||||
@@ -575,7 +575,7 @@ SymbolLookup::LoadedImage::LookupSymbol(addr_t address, addr_t* _baseAddress,
|
|||||||
const elf_region_t *textRegion = fImage->regions; // local
|
const elf_region_t *textRegion = fImage->regions; // local
|
||||||
|
|
||||||
for (int32 i = 0; i < symbolCount; i++) {
|
for (int32 i = 0; i < symbolCount; i++) {
|
||||||
const struct Elf32_Sym *symbol = &fSymbolLookup->Read(fImage->syms[i]);
|
const elf_sym *symbol = &fSymbolLookup->Read(fImage->syms[i]);
|
||||||
|
|
||||||
// The symbol table contains not only symbols referring to functions
|
// The symbol table contains not only symbols referring to functions
|
||||||
// and data symbols within the shared object, but also referenced
|
// and data symbols within the shared object, but also referenced
|
||||||
@@ -584,8 +584,7 @@ SymbolLookup::LoadedImage::LookupSymbol(addr_t address, addr_t* _baseAddress,
|
|||||||
// that have an st_value != 0 (0 seems to be an indication for a
|
// that have an st_value != 0 (0 seems to be an indication for a
|
||||||
// symbol defined elsewhere -- couldn't verify that in the specs
|
// symbol defined elsewhere -- couldn't verify that in the specs
|
||||||
// though).
|
// though).
|
||||||
if ((ELF32_ST_TYPE(symbol->st_info) != STT_FUNC
|
if ((symbol->Type() != STT_FUNC && symbol->Type() != STT_OBJECT)
|
||||||
&& ELF32_ST_TYPE(symbol->st_info) != STT_OBJECT)
|
|
||||||
|| symbol->st_value == 0
|
|| symbol->st_value == 0
|
||||||
|| symbol->st_value + symbol->st_size + textRegion->delta
|
|| symbol->st_value + symbol->st_size + textRegion->delta
|
||||||
> textRegion->vmstart + textRegion->size) {
|
> textRegion->vmstart + textRegion->size) {
|
||||||
@@ -643,10 +642,9 @@ SymbolLookup::LoadedImage::NextSymbol(int32& iterator, const char** _symbolName,
|
|||||||
if (++iterator >= fSymbolCount)
|
if (++iterator >= fSymbolCount)
|
||||||
return B_ENTRY_NOT_FOUND;
|
return B_ENTRY_NOT_FOUND;
|
||||||
|
|
||||||
const struct Elf32_Sym* symbol
|
const elf_sym* symbol
|
||||||
= &fSymbolLookup->Read(fImage->syms[iterator]);
|
= &fSymbolLookup->Read(fImage->syms[iterator]);
|
||||||
if ((ELF32_ST_TYPE(symbol->st_info) != STT_FUNC
|
if ((symbol->Type() != STT_FUNC && symbol->Type() != STT_OBJECT)
|
||||||
&& ELF32_ST_TYPE(symbol->st_info) != STT_OBJECT)
|
|
||||||
|| symbol->st_value == 0) {
|
|| symbol->st_value == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -656,8 +654,8 @@ SymbolLookup::LoadedImage::NextSymbol(int32& iterator, const char** _symbolName,
|
|||||||
*_symbolNameLen = fSymbolLookup->_SymbolNameLen(*_symbolName);
|
*_symbolNameLen = fSymbolLookup->_SymbolNameLen(*_symbolName);
|
||||||
*_symbolAddress = symbol->st_value + fTextDelta;
|
*_symbolAddress = symbol->st_value + fTextDelta;
|
||||||
*_symbolSize = symbol->st_size;
|
*_symbolSize = symbol->st_size;
|
||||||
*_symbolType = ELF32_ST_TYPE(symbol->st_info) == STT_FUNC
|
*_symbolType = symbol->Type() == STT_FUNC ? B_SYMBOL_TYPE_TEXT
|
||||||
? B_SYMBOL_TYPE_TEXT : B_SYMBOL_TYPE_DATA;
|
: B_SYMBOL_TYPE_DATA;
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
struct image_t;
|
struct image_t;
|
||||||
struct runtime_loader_debug_area;
|
struct runtime_loader_debug_area;
|
||||||
struct Elf32_Sym;
|
|
||||||
|
|
||||||
|
|
||||||
namespace BPrivate {
|
namespace BPrivate {
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2005, Ingo Weinhold, [email protected].
|
||||||
|
* Copyright 2012, Alex Smith, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <debug_support.h>
|
||||||
|
|
||||||
|
#include "arch_debug_support.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct stack_frame {
|
||||||
|
struct stack_frame *previous;
|
||||||
|
void *return_address;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
arch_debug_get_instruction_pointer(debug_context *context, thread_id thread,
|
||||||
|
void **ip, void **stackFrameAddress)
|
||||||
|
{
|
||||||
|
// get the CPU state
|
||||||
|
debug_cpu_state cpuState;
|
||||||
|
status_t error = debug_get_cpu_state(context, thread, NULL, &cpuState);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
*ip = (void*)cpuState.rip;
|
||||||
|
*stackFrameAddress = (void*)cpuState.rbp;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
arch_debug_get_stack_frame(debug_context *context, void *stackFrameAddress,
|
||||||
|
debug_stack_frame_info *stackFrameInfo)
|
||||||
|
{
|
||||||
|
stack_frame stackFrame;
|
||||||
|
ssize_t bytesRead = debug_read_memory(context, stackFrameAddress,
|
||||||
|
&stackFrame, sizeof(stackFrame));
|
||||||
|
if (bytesRead < B_OK)
|
||||||
|
return bytesRead;
|
||||||
|
if (bytesRead != sizeof(stackFrame))
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
stackFrameInfo->frame = stackFrameAddress;
|
||||||
|
stackFrameInfo->parent_frame = stackFrame.previous;
|
||||||
|
stackFrameInfo->return_address = stackFrame.return_address;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user