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_get_image_info_for_address(addr_t address, image_info* info);
|
||||||
status_t elf_init(struct kernel_args *args);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct dirent;
|
struct dirent;
|
||||||
|
struct Elf32_Sym;
|
||||||
struct fd_info;
|
struct fd_info;
|
||||||
struct fd_set;
|
struct fd_set;
|
||||||
struct fs_info;
|
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 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_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_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
|
// VFS functions
|
||||||
extern dev_t _kern_mount(const char *path, const char *device,
|
extern dev_t _kern_mount(const char *path, const char *device,
|
||||||
|
|||||||
@@ -1878,3 +1878,104 @@ elf_init(kernel_args *args)
|
|||||||
return B_OK;
|
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