Added syscall _kern_read_kernel_image_symbols() for reading a kernel
image's symbol and string tables. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27687 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -34,6 +34,10 @@ status_t elf_debug_lookup_user_symbol_address(struct team* team, addr_t address,
|
||||
status_t elf_get_image_info_for_address(addr_t address, image_info* info);
|
||||
status_t elf_init(struct kernel_args *args);
|
||||
|
||||
status_t _user_read_kernel_image_symbols(image_id id,
|
||||
struct Elf32_Sym* symbolTable, int32* _symbolCount,
|
||||
char* stringTable, size_t* _stringTableSize, addr_t* _imageDelta);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -20,6 +20,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
struct dirent;
|
||||
struct Elf32_Sym;
|
||||
struct fd_info;
|
||||
struct fd_set;
|
||||
struct fs_info;
|
||||
@@ -188,6 +189,10 @@ extern void _kern_image_relocated(image_id id);
|
||||
extern void _kern_loading_app_failed(status_t error);
|
||||
extern status_t _kern_get_image_info(image_id id, image_info *info, size_t size);
|
||||
extern status_t _kern_get_next_image_info(team_id team, int32 *cookie, image_info *info, size_t size);
|
||||
extern status_t _kern_read_kernel_image_symbols(image_id id,
|
||||
struct Elf32_Sym* symbolTable, int32* _symbolCount,
|
||||
char* stringTable, size_t* _stringTableSize,
|
||||
addr_t* _imageDelta);
|
||||
|
||||
// VFS functions
|
||||
extern dev_t _kern_mount(const char *path, const char *device,
|
||||
|
||||
@@ -1878,3 +1878,104 @@ elf_init(kernel_args *args)
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
/*! Reads the symbol and string table for the kernel image with the given ID.
|
||||
\a _symbolCount and \a _stringTableSize are both in- and output parameters.
|
||||
When called they call the size of the buffers given by \a symbolTable and
|
||||
\a stringTable respectively. When the function returns successfully, they
|
||||
will contain the actual sizes (which can be greater than the original ones).
|
||||
The function will copy as much as possible into the buffers. For only
|
||||
getting the required buffer sizes, it can be invoked with \c NULL buffers.
|
||||
On success \a _imageDelta will contain the offset to be added to the symbol
|
||||
values in the table to get the actual symbol addresses.
|
||||
*/
|
||||
status_t
|
||||
_user_read_kernel_image_symbols(image_id id, struct Elf32_Sym* symbolTable,
|
||||
int32* _symbolCount, char* stringTable, size_t* _stringTableSize,
|
||||
addr_t* _imageDelta)
|
||||
{
|
||||
// check params
|
||||
if (_symbolCount == NULL || _stringTableSize == NULL)
|
||||
return B_BAD_VALUE;
|
||||
if (!IS_USER_ADDRESS(_symbolCount) || !IS_USER_ADDRESS(_stringTableSize)
|
||||
|| _imageDelta != NULL && !IS_USER_ADDRESS(_imageDelta)
|
||||
|| symbolTable != NULL && !IS_USER_ADDRESS(symbolTable)
|
||||
|| stringTable != NULL && !IS_USER_ADDRESS(stringTable)) {
|
||||
return B_BAD_ADDRESS;
|
||||
}
|
||||
|
||||
// get buffer sizes
|
||||
int32 maxSymbolCount;
|
||||
size_t maxStringTableSize;
|
||||
if (user_memcpy(&maxSymbolCount, _symbolCount, sizeof(maxSymbolCount))
|
||||
!= B_OK
|
||||
|| user_memcpy(&maxStringTableSize, _stringTableSize,
|
||||
sizeof(maxStringTableSize)) != B_OK) {
|
||||
return B_BAD_ADDRESS;
|
||||
}
|
||||
|
||||
// find the image
|
||||
MutexLocker _(sImageMutex);
|
||||
struct elf_image_info* image = find_image(id);
|
||||
if (image == NULL)
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
|
||||
// get the tables and infos
|
||||
addr_t imageDelta = image->text_region.delta;
|
||||
const Elf32_Sym* symbols;
|
||||
int32 symbolCount;
|
||||
const char* strings;
|
||||
|
||||
if (image->debug_symbols != NULL) {
|
||||
symbols = image->debug_symbols;
|
||||
symbolCount = image->num_debug_symbols;
|
||||
strings = image->debug_string_table;
|
||||
} else {
|
||||
symbols = image->syms;
|
||||
symbolCount = image->symhash[1];
|
||||
strings = image->strtab;
|
||||
}
|
||||
|
||||
// The string table size isn't stored in the elf_image_info structure. Find
|
||||
// out by iterating through all symbols.
|
||||
size_t stringTableSize = 0;
|
||||
for (int32 i = 0; i < symbolCount; i++) {
|
||||
size_t index = symbols[i].st_name;
|
||||
if (index > stringTableSize)
|
||||
stringTableSize = index;
|
||||
}
|
||||
stringTableSize += strlen(strings + stringTableSize) + 1;
|
||||
// add size of the last string
|
||||
|
||||
// copy symbol table
|
||||
int32 symbolsToCopy = min_c(symbolCount, maxSymbolCount);
|
||||
if (symbolTable != NULL && symbolsToCopy > 0) {
|
||||
if (user_memcpy(symbolTable, symbols, sizeof(Elf32_Sym) * symbolsToCopy)
|
||||
!= B_OK) {
|
||||
return B_BAD_ADDRESS;
|
||||
}
|
||||
}
|
||||
|
||||
// copy string table
|
||||
size_t stringsToCopy = min_c(stringTableSize, maxStringTableSize);
|
||||
if (stringTable != NULL && stringsToCopy > 0) {
|
||||
if (user_memcpy(stringTable, strings, stringsToCopy)
|
||||
!= B_OK) {
|
||||
return B_BAD_ADDRESS;
|
||||
}
|
||||
}
|
||||
|
||||
// copy sizes
|
||||
if (user_memcpy(_symbolCount, &symbolCount, sizeof(symbolCount)) != B_OK
|
||||
|| user_memcpy(_stringTableSize, &stringTableSize,
|
||||
sizeof(stringTableSize)) != B_OK
|
||||
|| _imageDelta != NULL && user_memcpy(_imageDelta, &imageDelta,
|
||||
sizeof(imageDelta)) != B_OK) {
|
||||
return B_BAD_ADDRESS;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user