ELF64 and x86_64 support in the debug kit.

This commit is contained in:
Alex Smith
2012-08-07 20:22:36 +01:00
parent 8a1903353e
commit a731ad19e6
6 changed files with 98 additions and 47 deletions
+1 -1
View File
@@ -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
View File
@@ -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;
+4 -4
View File
@@ -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;
+11 -13
View File
@@ -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;
} }
-1
View File
@@ -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, bonefish@users.sf.net.
* Copyright 2012, Alex Smith, alex@alex-smith.me.uk.
* 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;
}