Support ELF64 in the kernel.

This has been done by adding typedefs in elf_common.h to the correct ELF
structures for the architecture, and changing all Elf32_* uses to those
types. I don't know whether image loading works as I cannot test it yet,
there may be some 64-bit safety issues around. However, symbol lookup for
the kernel is working correctly.
This commit is contained in:
Alex Smith 2012-07-09 11:11:38 +01:00
parent bc3093488f
commit 3b802628b8
12 changed files with 287 additions and 277 deletions

View File

@ -5,23 +5,28 @@
#ifndef _KERNEL_ARCH_ELF_H
#define _KERNEL_ARCH_ELF_H
struct Elf32_Rel;
struct Elf32_Rela;
#include <elf_common.h>
struct elf_image_info;
#ifdef __cplusplus
extern "C" {
#endif
extern int arch_elf_relocate_rel(struct elf_image_info *image,
struct elf_image_info *resolve_image, struct Elf32_Rel *rel, int rel_len);
struct elf_image_info *resolve_image, elf_rel *rel, int rel_len);
extern int arch_elf_relocate_rela(struct elf_image_info *image,
struct elf_image_info *resolve_image, struct Elf32_Rela *rel, int rel_len);
struct elf_image_info *resolve_image, elf_rela *rel, int rel_len);
#ifdef __cplusplus
}
#endif
#include <arch_elf.h>
#endif /* _KERNEL_ARCH_ELF_H */

View File

@ -77,6 +77,14 @@ struct preloaded_elf64_image : public preloaded_image {
FixedWidthPointer<Elf64_Sym> debug_symbols;
} _PACKED;
#if B_HAIKU_64_BIT
typedef preloaded_elf64_image preloaded_elf_image;
#else
typedef preloaded_elf32_image preloaded_elf_image;
#endif
#ifdef _BOOT_MODE
extern status_t boot_elf_resolve_symbol(preloaded_elf32_image* image,
struct Elf32_Sym* symbol, Elf32_Addr* symbolAddress);

View File

@ -25,60 +25,67 @@ typedef struct elf_region {
} elf_region;
struct elf_image_info {
struct elf_image_info *next; // next image in the hash
char *name;
image_id id;
int32 ref_count;
struct vnode *vnode;
elf_region text_region;
elf_region data_region;
addr_t dynamic_section; // pointer to the dynamic section
struct elf_linked_image *linked_images;
struct elf_image_info* next; // next image in the hash
char* name;
image_id id;
int32 ref_count;
struct vnode* vnode;
elf_region text_region;
elf_region data_region;
addr_t dynamic_section; // pointer to the dynamic section
struct elf_linked_image* linked_images;
bool symbolic;
bool symbolic;
struct Elf32_Ehdr *elf_header;
elf_ehdr* elf_header;
// pointer to symbol participation data structures
char *needed;
uint32 *symhash;
struct Elf32_Sym *syms;
char *strtab;
struct Elf32_Rel *rel;
int rel_len;
struct Elf32_Rela *rela;
int rela_len;
struct Elf32_Rel *pltrel;
int pltrel_len;
int pltrel_type;
char* needed;
uint32* symhash;
elf_sym* syms;
char* strtab;
elf_rel* rel;
int rel_len;
elf_rela* rela;
int rela_len;
elf_rel* pltrel;
int pltrel_len;
int pltrel_type;
struct Elf32_Sym *debug_symbols;
uint32 num_debug_symbols;
const char *debug_string_table;
elf_sym* debug_symbols;
uint32 num_debug_symbols;
const char* debug_string_table;
// versioning related structures
uint32 num_version_definitions;
struct Elf32_Verdef *version_definitions;
uint32 num_needed_versions;
struct Elf32_Verneed *needed_versions;
Elf32_Versym *symbol_versions;
struct elf_version_info *versions;
uint32 num_versions;
uint32 num_version_definitions;
elf_verdef* version_definitions;
uint32 num_needed_versions;
elf_verneed* needed_versions;
elf_versym* symbol_versions;
struct elf_version_info* versions;
uint32 num_versions;
};
#define STRING(image, offset) ((char *)(&(image)->strtab[(offset)]))
#define STRING(image, offset) ((char*)(&(image)->strtab[(offset)]))
#define SYMNAME(image, sym) STRING(image, (sym)->st_name)
#define SYMBOL(image, num) (&(image)->syms[num])
#define HASHTABSIZE(image) ((image)->symhash[0])
#define HASHBUCKETS(image) ((unsigned int *)&(image)->symhash[2])
#define HASHCHAINS(image) ((unsigned int *)&(image)->symhash[2+HASHTABSIZE(image)])
#define HASHBUCKETS(image) ((unsigned int*)&(image)->symhash[2])
#define HASHCHAINS(image) ((unsigned int*)&(image)->symhash[2+HASHTABSIZE(image)])
extern
#ifdef __cplusplus
"C"
extern "C" {
#endif
status_t elf_resolve_symbol(struct elf_image_info *image, struct Elf32_Sym *sym,
struct elf_image_info *shared_image, addr_t *sym_addr);
extern status_t elf_resolve_symbol(struct elf_image_info* image,
elf_sym* symbol, struct elf_image_info* sharedImage,
addr_t* _symbolAddress);
#ifdef __cplusplus
}
#endif
#endif /* _KERNEL_ELF_PRIV_H */

View File

@ -152,12 +152,12 @@ typedef struct image_queue_t {
#define IMAGE_FLAG_RTLD_MASK 0x03
// RTLD_{LAZY,NOW} | RTLD_{LOCAL,GLOBAL}
#define STRING(image, offset) ((char *)(&(image)->strtab[(offset)]))
#define STRING(image, offset) ((char*)(&(image)->strtab[(offset)]))
#define SYMNAME(image, sym) STRING(image, (sym)->st_name)
#define SYMBOL(image, num) (&(image)->syms[num])
#define HASHTABSIZE(image) ((image)->symhash[0])
#define HASHBUCKETS(image) ((unsigned int *)&(image)->symhash[2])
#define HASHCHAINS(image) ((unsigned int *)&(image)->symhash[2+HASHTABSIZE(image)])
#define HASHBUCKETS(image) ((unsigned int*)&(image)->symhash[2])
#define HASHCHAINS(image) ((unsigned int*)&(image)->symhash[2+HASHTABSIZE(image)])
// The name of the area the runtime loader creates for debugging purposes.

View File

@ -89,6 +89,7 @@ struct Elf32_Sym {
#ifdef __cplusplus
uint8 Bind() const;
uint8 Type() const;
void SetInfo(uint8 bind, uint8 type);
#endif
};
@ -218,6 +219,11 @@ Elf32_Sym::Type() const
return ELF32_ST_TYPE(st_info);
}
inline void
Elf32_Sym::SetInfo(uint8 bind, uint8 type)
{
st_info = ELF32_ST_INFO(bind, type);
}
inline uint8
Elf32_Rel::SymbolIndex() const

View File

@ -91,6 +91,7 @@ struct Elf64_Sym {
#ifdef __cplusplus
uint8 Bind() const;
uint8 Type() const;
void SetInfo(uint8 bind, uint8 type);
#endif
};
@ -221,6 +222,13 @@ Elf64_Sym::Type() const
}
inline void
Elf64_Sym::SetInfo(uint8 bind, uint8 type)
{
st_info = ELF64_ST_INFO(bind, type);
}
inline uint8
Elf64_Rel::SymbolIndex() const
{

View File

@ -263,4 +263,39 @@
#define VER_FLG_WEAK 0x2 /* weak version identifier */
// Determine the correct ELF types to use for the architecture
#if B_HAIKU_64_BIT
# define _ELF_TYPE(type) Elf64_##type
#else
# define _ELF_TYPE(type) Elf32_##type
#endif
#define DEFINE_ELF_TYPE(type, name) \
struct _ELF_TYPE(type); \
typedef _ELF_TYPE(type) name
DEFINE_ELF_TYPE(Ehdr, elf_ehdr);
DEFINE_ELF_TYPE(Phdr, elf_phdr);
DEFINE_ELF_TYPE(Shdr, elf_shdr);
DEFINE_ELF_TYPE(Sym, elf_sym);
DEFINE_ELF_TYPE(Dyn, elf_dyn);
DEFINE_ELF_TYPE(Rel, elf_rel);
DEFINE_ELF_TYPE(Rela, elf_rela);
DEFINE_ELF_TYPE(Verdef, elf_verdef);
DEFINE_ELF_TYPE(Verdaux, elf_verdaux);
DEFINE_ELF_TYPE(Verneed, elf_verneed);
DEFINE_ELF_TYPE(Vernaux, elf_vernaux);
#undef DEFINE_ELF_TYPE
#undef _ELF_TYPE
typedef uint16 elf_versym;
#if B_HAIKU_64_BIT
# define ELF_CLASS ELFCLASS64
#else
# define ELF_CLASS ELFCLASS32
#endif
#endif /* _ELF_COMMON_H_ */

View File

@ -510,72 +510,6 @@ x86_init_user_debug()
}
// Currently got generic elf.cpp #ifdef'd out for x86_64, define stub versions here.
status_t
elf_load_user_image(const char *path, Team *team, int flags, addr_t *_entry)
{
return B_ERROR;
}
image_id
load_kernel_add_on(const char *path)
{
return 0;
}
status_t
unload_kernel_add_on(image_id id)
{
return B_ERROR;
}
status_t
elf_debug_lookup_symbol_address(addr_t address, addr_t *_baseAddress,
const char **_symbolName, const char **_imageName, bool *_exactMatch)
{
return B_ERROR;
}
addr_t
elf_debug_lookup_symbol(const char* searchName)
{
return 0;
}
struct elf_image_info *
elf_get_kernel_image()
{
return NULL;
}
image_id
elf_create_memory_image(const char* imageName, addr_t text, size_t textSize,
addr_t data, size_t dataSize)
{
return B_ERROR;
}
status_t
elf_add_memory_image_symbol(image_id id, const char* name, addr_t address,
size_t size, int32 type)
{
return B_ERROR;
}
status_t
elf_init(struct kernel_args *args)
{
return B_OK;
}
status_t
get_image_symbol(image_id image, const char *name, int32 symbolType,
void **_symbolLocation)
{
return B_OK;
}
status_t
_user_read_kernel_image_symbols(image_id id, struct Elf32_Sym* symbolTable,
int32* _symbolCount, char* stringTable, size_t* _stringTableSize,

View File

@ -46,7 +46,6 @@ if $(TARGET_ARCH) = x86_64 {
arch_commpage.cpp
arch_debug.cpp
arch_elf.cpp
arch_real_time_clock.cpp
arch_smp.cpp
arch_thread.cpp
@ -81,6 +80,7 @@ if $(TARGET_ARCH) = x86_64 {
local archGenericSources =
arch_cpu.cpp
arch_debug_console.cpp
arch_elf.cpp
arch_int.cpp
arch_platform.cpp
arch_timer.cpp

View File

@ -186,34 +186,33 @@ arch_elf_relocate_rela(struct elf_image_info *image,
#endif // !__x86_64__ || _BOOT_MODE
//#if defined(__x86_64__) || defined(_BOOT_MODE)
#ifdef _BOOT_MODE
#if defined(__x86_64__) || defined(_BOOT_MODE)
#ifdef _BOOT_MODE
status_t
boot_arch_elf_relocate_rel(preloaded_elf64_image* image, Elf64_Rel* rel,
int relLength)
//#else
//int
//arch_elf_relocate_rel(struct elf_image_info *image,
// struct elf_image_info *resolveImage, struct Elf32_Rel *rel, int relLength)
//#endif
#else
int
arch_elf_relocate_rel(struct elf_image_info *image,
struct elf_image_info *resolveImage, Elf64_Rel *rel, int relLength)
#endif
{
dprintf("arch_elf_relocate_rel: not supported on x86_64\n");
return B_ERROR;
}
//#ifdef _BOOT_MODE
#ifdef _BOOT_MODE
status_t
boot_arch_elf_relocate_rela(preloaded_elf64_image* image, Elf64_Rela* rel,
int relLength)
//#else
//int
//arch_elf_relocate_rela(struct elf_image_info *image,
// struct elf_image_info *resolveImage, struct Elf32_Rela *rel, int relLength)
//#endif
#else
int
arch_elf_relocate_rela(struct elf_image_info *image,
struct elf_image_info *resolveImage, Elf64_Rela *rel, int relLength)
#endif
{
for (int i = 0; i < relLength / (int)sizeof(Elf64_Rela); i++) {
int type = ELF64_R_TYPE(rel[i].r_info);
@ -225,11 +224,11 @@ boot_arch_elf_relocate_rela(preloaded_elf64_image* image, Elf64_Rela* rel,
Elf64_Sym* symbol = SYMBOL(image, symIndex);
status_t status;
//#ifdef _BOOT_MODE
#ifdef _BOOT_MODE
status = boot_elf_resolve_symbol(image, symbol, &symAddr);
//#else
// status = elf_resolve_symbol(image, symbol, resolveImage, &S);
//#endif
#else
status = elf_resolve_symbol(image, symbol, resolveImage, &symAddr);
#endif
if (status < B_OK)
return status;
}
@ -269,7 +268,6 @@ boot_arch_elf_relocate_rela(preloaded_elf64_image* image, Elf64_Rela* rel,
return B_OK;
}
#endif
#endif // __x86_64__ || _BOOT_MODE

View File

@ -9,7 +9,6 @@
/*! Contains the ELF loader */
#ifndef __x86_64__
#include <elf.h>
@ -67,8 +66,8 @@ static mutex sImageLoadMutex = MUTEX_INITIALIZER("kimages_load_lock");
static bool sInitialized = false;
static struct Elf32_Sym *elf_find_symbol(struct elf_image_info *image,
const char *name, const elf_version_info *version, bool lookupDefault);
static elf_sym *elf_find_symbol(struct elf_image_info *image, const char *name,
const elf_version_info *version, bool lookupDefault);
/*! Calculates hash for an image using its ID */
@ -76,7 +75,7 @@ static uint32
image_hash(void *_image, const void *_key, uint32 range)
{
struct elf_image_info *image = (struct elf_image_info *)_image;
image_id id = (image_id)_key;
image_id id = (image_id)(addr_t)_key;
if (image != NULL)
return image->id % range;
@ -90,7 +89,7 @@ static int
image_compare(void *_image, const void *_key)
{
struct elf_image_info *image = (struct elf_image_info *)_image;
image_id id = (image_id)_key;
image_id id = (image_id)(addr_t)_key;
return id - image->id;
}
@ -124,11 +123,11 @@ register_elf_image(struct elf_image_info *image)
// Haiku API version
imageInfo.api_version = 0;
struct Elf32_Sym* symbol = elf_find_symbol(image,
elf_sym* symbol = elf_find_symbol(image,
B_SHARED_OBJECT_HAIKU_VERSION_VARIABLE_NAME, NULL, true);
if (symbol != NULL && symbol->st_shndx != SHN_UNDEF
&& symbol->st_value > 0
&& ELF32_ST_TYPE(symbol->st_info) == STT_OBJECT
&& symbol->Type() == STT_OBJECT
&& symbol->st_size >= sizeof(uint32)) {
addr_t symbolAddress = symbol->st_value + image->text_region.delta;
if (symbolAddress >= image->text_region.start
@ -144,7 +143,7 @@ register_elf_image(struct elf_image_info *image)
B_SHARED_OBJECT_HAIKU_ABI_VARIABLE_NAME, NULL, true);
if (symbol != NULL && symbol->st_shndx != SHN_UNDEF
&& symbol->st_value > 0
&& ELF32_ST_TYPE(symbol->st_info) == STT_OBJECT
&& symbol->Type() == STT_OBJECT
&& symbol->st_size >= sizeof(uint32)) {
addr_t symbolAddress = symbol->st_value + image->text_region.delta;
if (symbolAddress >= image->text_region.start
@ -234,7 +233,7 @@ dump_address_info(int argc, char **argv)
static struct elf_image_info *
find_image(image_id id)
{
return (elf_image_info *)hash_lookup(sImagesHash, (void *)id);
return (elf_image_info *)hash_lookup(sImagesHash, (void *)(addr_t)id);
}
@ -316,9 +315,9 @@ elf_hash(const char *name)
static const char *
get_symbol_type_string(struct Elf32_Sym *symbol)
get_symbol_type_string(elf_sym *symbol)
{
switch (ELF32_ST_TYPE(symbol->st_info)) {
switch (symbol->Type()) {
case STT_FUNC:
return "func";
case STT_OBJECT:
@ -332,9 +331,9 @@ get_symbol_type_string(struct Elf32_Sym *symbol)
static const char *
get_symbol_bind_string(struct Elf32_Sym *symbol)
get_symbol_bind_string(elf_sym *symbol)
{
switch (ELF32_ST_BIND(symbol->st_info)) {
switch (symbol->Bind()) {
case STB_LOCAL:
return "loc ";
case STB_GLOBAL:
@ -368,7 +367,7 @@ dump_symbol(int argc, char **argv)
if (image->num_debug_symbols > 0) {
// search extended debug symbol table (contains static symbols)
for (uint32 i = 0; i < image->num_debug_symbols; i++) {
struct Elf32_Sym *symbol = &image->debug_symbols[i];
elf_sym *symbol = &image->debug_symbols[i];
const char *name = image->debug_string_table + symbol->st_name;
if (symbol->st_value > 0 && strstr(name, pattern) != 0) {
@ -383,7 +382,7 @@ dump_symbol(int argc, char **argv)
for (uint32 i = 0; i < HASHTABSIZE(image); i++) {
for (uint32 j = HASHBUCKETS(image)[i]; j != STN_UNDEF;
j = HASHCHAINS(image)[j]) {
struct Elf32_Sym *symbol = &image->syms[j];
elf_sym *symbol = &image->syms[j];
const char *name = SYMNAME(image, symbol);
if (symbol->st_value > 0 && strstr(name, pattern) != 0) {
@ -415,7 +414,7 @@ dump_symbols(int argc, char **argv)
// if the argument looks like a hex number, treat it as such
if (argc > 1) {
if (isdigit(argv[1][0])) {
uint32 num = strtoul(argv[1], NULL, 0);
addr_t num = strtoul(argv[1], NULL, 0);
if (IS_KERNEL_ADDRESS(num)) {
// find image at address
@ -430,12 +429,16 @@ dump_symbols(int argc, char **argv)
}
hash_close(sImagesHash, &iterator, false);
if (image == NULL)
kprintf("No image covers 0x%lx in the kernel!\n", num);
if (image == NULL) {
kprintf("No image covers %#" B_PRIxADDR " in the kernel!\n",
num);
}
} else {
image = (elf_image_info *)hash_lookup(sImagesHash, (void *)num);
if (image == NULL)
kprintf("image 0x%lx doesn't exist in the kernel!\n", num);
if (image == NULL) {
kprintf("image %#" B_PRIxADDR " doesn't exist in the "
"kernel!\n", num);
}
}
} else {
// look for image by name
@ -460,13 +463,13 @@ dump_symbols(int argc, char **argv)
// dump symbols
kprintf("Symbols of image %ld \"%s\":\nAddress Type Size Name\n",
image->id, image->name);
kprintf("Symbols of image %" B_PRId32 "\"%s\":\n"
"Address Type Size Name\n", image->id, image->name);
if (image->num_debug_symbols > 0) {
// search extended debug symbol table (contains static symbols)
for (i = 0; i < image->num_debug_symbols; i++) {
struct Elf32_Sym *symbol = &image->debug_symbols[i];
elf_sym *symbol = &image->debug_symbols[i];
if (symbol->st_value == 0 || symbol->st_size
>= image->text_region.size + image->data_region.size)
@ -484,7 +487,7 @@ dump_symbols(int argc, char **argv)
for (i = 0; i < HASHTABSIZE(image); i++) {
for (j = HASHBUCKETS(image)[i]; j != STN_UNDEF;
j = HASHCHAINS(image)[j]) {
struct Elf32_Sym *symbol = &image->syms[j];
elf_sym *symbol = &image->syms[j];
if (symbol->st_value == 0 || symbol->st_size
>= image->text_region.size + image->data_region.size)
@ -506,9 +509,9 @@ dump_symbols(int argc, char **argv)
static void
dump_elf_region(struct elf_region *region, const char *name)
{
kprintf(" %s.id %ld\n", name, region->id);
kprintf(" %s.start 0x%lx\n", name, region->start);
kprintf(" %s.size 0x%lx\n", name, region->size);
kprintf(" %s.id %" B_PRId32 "\n", name, region->id);
kprintf(" %s.start %#" B_PRIxADDR "\n", name, region->start);
kprintf(" %s.size %#" B_PRIxSIZE "\n", name, region->size);
kprintf(" %s.delta %ld\n", name, region->delta);
}
@ -518,22 +521,22 @@ dump_image_info(struct elf_image_info *image)
{
kprintf("elf_image_info at %p:\n", image);
kprintf(" next %p\n", image->next);
kprintf(" id %ld\n", image->id);
kprintf(" id %" B_PRId32 "\n", image->id);
dump_elf_region(&image->text_region, "text");
dump_elf_region(&image->data_region, "data");
kprintf(" dynamic_section 0x%lx\n", image->dynamic_section);
kprintf(" dynamic_section %#" B_PRIxADDR "\n", image->dynamic_section);
kprintf(" needed %p\n", image->needed);
kprintf(" symhash %p\n", image->symhash);
kprintf(" syms %p\n", image->syms);
kprintf(" strtab %p\n", image->strtab);
kprintf(" rel %p\n", image->rel);
kprintf(" rel_len 0x%x\n", image->rel_len);
kprintf(" rel_len %#x\n", image->rel_len);
kprintf(" rela %p\n", image->rela);
kprintf(" rela_len 0x%x\n", image->rela_len);
kprintf(" rela_len %#x\n", image->rela_len);
kprintf(" pltrel %p\n", image->pltrel);
kprintf(" pltrel_len 0x%x\n", image->pltrel_len);
kprintf(" pltrel_len %#x\n", image->pltrel_len);
kprintf(" debug_symbols %p (%ld)\n",
kprintf(" debug_symbols %p (%" B_PRIu32 ")\n",
image->debug_symbols, image->num_debug_symbols);
}
@ -546,16 +549,17 @@ dump_image(int argc, char **argv)
// if the argument looks like a hex number, treat it as such
if (argc > 1) {
uint32 num = strtoul(argv[1], NULL, 0);
addr_t num = strtoul(argv[1], NULL, 0);
if (IS_KERNEL_ADDRESS(num)) {
// semi-hack
dump_image_info((struct elf_image_info *)num);
} else {
image = (elf_image_info *)hash_lookup(sImagesHash, (void *)num);
if (image == NULL)
kprintf("image 0x%lx doesn't exist in the kernel!\n", num);
else
if (image == NULL) {
kprintf("image %#" B_PRIxADDR " doesn't exist in the kernel!\n",
num);
} else
dump_image_info(image);
}
return 0;
@ -567,7 +571,7 @@ dump_image(int argc, char **argv)
while ((image = (elf_image_info *)hash_next(sImagesHash, &iterator))
!= NULL) {
kprintf("%p (%ld) %s\n", image, image->id, image->name);
kprintf("%p (%" B_PRId32 ") %s\n", image, image->id, image->name);
}
hash_close(sImagesHash, &iterator, false);
@ -578,7 +582,7 @@ dump_image(int argc, char **argv)
// Currently unused
#if 0
static
void dump_symbol(struct elf_image_info *image, struct Elf32_Sym *sym)
void dump_symbol(struct elf_image_info *image, elf_sym *sym)
{
kprintf("symbol at %p, in image %p\n", sym, image);
@ -593,25 +597,24 @@ void dump_symbol(struct elf_image_info *image, struct Elf32_Sym *sym)
#endif
static struct Elf32_Sym *
static elf_sym *
elf_find_symbol(struct elf_image_info *image, const char *name,
const elf_version_info *lookupVersion, bool lookupDefault)
{
if (image->dynamic_section == 0 || HASHTABSIZE(image) == 0)
return NULL;
Elf32_Sym* versionedSymbol = NULL;
elf_sym* versionedSymbol = NULL;
uint32 versionedSymbolCount = 0;
uint32 hash = elf_hash(name) % HASHTABSIZE(image);
for (uint32 i = HASHBUCKETS(image)[hash]; i != STN_UNDEF;
i = HASHCHAINS(image)[i]) {
Elf32_Sym* symbol = &image->syms[i];
elf_sym* symbol = &image->syms[i];
// consider only symbols with the right name and binding
if (symbol->st_shndx == SHN_UNDEF
|| ((ELF32_ST_BIND(symbol->st_info) != STB_GLOBAL)
&& (ELF32_ST_BIND(symbol->st_info) != STB_WEAK))
|| ((symbol->Bind() != STB_GLOBAL) && (symbol->Bind() != STB_WEAK))
|| strcmp(SYMNAME(image, symbol), name) != 0) {
continue;
}
@ -705,7 +708,7 @@ elf_find_symbol(struct elf_image_info *image, const char *name,
static status_t
elf_parse_dynamic_section(struct elf_image_info *image)
{
struct Elf32_Dyn *d;
elf_dyn *d;
int32 neededOffset = -1;
TRACE(("top of elf_parse_dynamic_section\n"));
@ -714,7 +717,7 @@ elf_parse_dynamic_section(struct elf_image_info *image)
image->syms = 0;
image->strtab = 0;
d = (struct Elf32_Dyn *)image->dynamic_section;
d = (elf_dyn *)image->dynamic_section;
if (!d)
return B_ERROR;
@ -732,25 +735,25 @@ elf_parse_dynamic_section(struct elf_image_info *image)
+ image->text_region.delta);
break;
case DT_SYMTAB:
image->syms = (struct Elf32_Sym *)(d[i].d_un.d_ptr
image->syms = (elf_sym *)(d[i].d_un.d_ptr
+ image->text_region.delta);
break;
case DT_REL:
image->rel = (struct Elf32_Rel *)(d[i].d_un.d_ptr
image->rel = (elf_rel *)(d[i].d_un.d_ptr
+ image->text_region.delta);
break;
case DT_RELSZ:
image->rel_len = d[i].d_un.d_val;
break;
case DT_RELA:
image->rela = (struct Elf32_Rela *)(d[i].d_un.d_ptr
image->rela = (elf_rela *)(d[i].d_un.d_ptr
+ image->text_region.delta);
break;
case DT_RELASZ:
image->rela_len = d[i].d_un.d_val;
break;
case DT_JMPREL:
image->pltrel = (struct Elf32_Rel *)(d[i].d_un.d_ptr
image->pltrel = (elf_rel *)(d[i].d_un.d_ptr
+ image->text_region.delta);
break;
case DT_PLTRELSZ:
@ -760,18 +763,18 @@ elf_parse_dynamic_section(struct elf_image_info *image)
image->pltrel_type = d[i].d_un.d_val;
break;
case DT_VERSYM:
image->symbol_versions = (Elf32_Versym*)
image->symbol_versions = (elf_versym*)
(d[i].d_un.d_ptr + image->text_region.delta);
break;
case DT_VERDEF:
image->version_definitions = (Elf32_Verdef*)
image->version_definitions = (elf_verdef*)
(d[i].d_un.d_ptr + image->text_region.delta);
break;
case DT_VERDEFNUM:
image->num_version_definitions = d[i].d_un.d_val;
break;
case DT_VERNEED:
image->needed_versions = (Elf32_Verneed*)
image->needed_versions = (elf_verneed*)
(d[i].d_un.d_ptr + image->text_region.delta);
break;
case DT_VERNEEDNUM:
@ -820,7 +823,7 @@ assert_defined_image_version(elf_image_info* dependentImage,
}
// iterate through the defined versions to find the given one
Elf32_Verdef* definition = image->version_definitions;
elf_verdef* definition = image->version_definitions;
for (uint32 i = 0; i < image->num_version_definitions; i++) {
uint32 versionIndex = VER_NDX(definition->vd_ndx);
elf_version_info& info = image->versions[versionIndex];
@ -830,7 +833,7 @@ assert_defined_image_version(elf_image_info* dependentImage,
return B_OK;
}
definition = (Elf32_Verdef*)
definition = (elf_verdef*)
((uint8*)definition + definition->vd_next);
}
@ -854,7 +857,7 @@ init_image_version_infos(elf_image_info* image)
uint32 maxIndex = 0;
if (image->version_definitions != NULL) {
Elf32_Verdef* definition = image->version_definitions;
elf_verdef* definition = image->version_definitions;
for (uint32 i = 0; i < image->num_version_definitions; i++) {
if (definition->vd_version != 1) {
dprintf("Unsupported version definition revision: %u\n",
@ -866,13 +869,13 @@ init_image_version_infos(elf_image_info* image)
if (versionIndex > maxIndex)
maxIndex = versionIndex;
definition = (Elf32_Verdef*)
definition = (elf_verdef*)
((uint8*)definition + definition->vd_next);
}
}
if (image->needed_versions != NULL) {
Elf32_Verneed* needed = image->needed_versions;
elf_verneed* needed = image->needed_versions;
for (uint32 i = 0; i < image->num_needed_versions; i++) {
if (needed->vn_version != 1) {
dprintf("Unsupported version needed revision: %u\n",
@ -880,17 +883,17 @@ init_image_version_infos(elf_image_info* image)
return B_BAD_VALUE;
}
Elf32_Vernaux* vernaux
= (Elf32_Vernaux*)((uint8*)needed + needed->vn_aux);
elf_vernaux* vernaux
= (elf_vernaux*)((uint8*)needed + needed->vn_aux);
for (uint32 k = 0; k < needed->vn_cnt; k++) {
uint32 versionIndex = VER_NDX(vernaux->vna_other);
if (versionIndex > maxIndex)
maxIndex = versionIndex;
vernaux = (Elf32_Vernaux*)((uint8*)vernaux + vernaux->vna_next);
vernaux = (elf_vernaux*)((uint8*)vernaux + vernaux->vna_next);
}
needed = (Elf32_Verneed*)((uint8*)needed + needed->vn_next);
needed = (elf_verneed*)((uint8*)needed + needed->vn_next);
}
}
@ -910,12 +913,12 @@ init_image_version_infos(elf_image_info* image)
// version definitions
if (image->version_definitions != NULL) {
Elf32_Verdef* definition = image->version_definitions;
elf_verdef* definition = image->version_definitions;
for (uint32 i = 0; i < image->num_version_definitions; i++) {
if (definition->vd_cnt > 0
&& (definition->vd_flags & VER_FLG_BASE) == 0) {
Elf32_Verdaux* verdaux
= (Elf32_Verdaux*)((uint8*)definition + definition->vd_aux);
elf_verdaux* verdaux
= (elf_verdaux*)((uint8*)definition + definition->vd_aux);
uint32 versionIndex = VER_NDX(definition->vd_ndx);
elf_version_info& info = image->versions[versionIndex];
@ -924,19 +927,19 @@ init_image_version_infos(elf_image_info* image)
info.file_name = NULL;
}
definition = (Elf32_Verdef*)
definition = (elf_verdef*)
((uint8*)definition + definition->vd_next);
}
}
// needed versions
if (image->needed_versions != NULL) {
Elf32_Verneed* needed = image->needed_versions;
elf_verneed* needed = image->needed_versions;
for (uint32 i = 0; i < image->num_needed_versions; i++) {
const char* fileName = STRING(image, needed->vn_file);
Elf32_Vernaux* vernaux
= (Elf32_Vernaux*)((uint8*)needed + needed->vn_aux);
elf_vernaux* vernaux
= (elf_vernaux*)((uint8*)needed + needed->vn_aux);
for (uint32 k = 0; k < needed->vn_cnt; k++) {
uint32 versionIndex = VER_NDX(vernaux->vna_other);
elf_version_info& info = image->versions[versionIndex];
@ -944,10 +947,10 @@ init_image_version_infos(elf_image_info* image)
info.name = STRING(image, vernaux->vna_name);
info.file_name = fileName;
vernaux = (Elf32_Vernaux*)((uint8*)vernaux + vernaux->vna_next);
vernaux = (elf_vernaux*)((uint8*)vernaux + vernaux->vna_next);
}
needed = (Elf32_Verneed*)((uint8*)needed + needed->vn_next);
needed = (elf_verneed*)((uint8*)needed + needed->vn_next);
}
}
@ -961,12 +964,12 @@ check_needed_image_versions(elf_image_info* image)
if (image->needed_versions == NULL)
return B_OK;
Elf32_Verneed* needed = image->needed_versions;
elf_verneed* needed = image->needed_versions;
for (uint32 i = 0; i < image->num_needed_versions; i++) {
elf_image_info* dependency = sKernelImage;
Elf32_Vernaux* vernaux
= (Elf32_Vernaux*)((uint8*)needed + needed->vn_aux);
elf_vernaux* vernaux
= (elf_vernaux*)((uint8*)needed + needed->vn_aux);
for (uint32 k = 0; k < needed->vn_cnt; k++) {
uint32 versionIndex = VER_NDX(vernaux->vna_other);
elf_version_info& info = image->versions[versionIndex];
@ -976,10 +979,10 @@ check_needed_image_versions(elf_image_info* image)
if (error != B_OK)
return error;
vernaux = (Elf32_Vernaux*)((uint8*)vernaux + vernaux->vna_next);
vernaux = (elf_vernaux*)((uint8*)vernaux + vernaux->vna_next);
}
needed = (Elf32_Verneed*)((uint8*)needed + needed->vn_next);
needed = (elf_verneed*)((uint8*)needed + needed->vn_next);
}
return B_OK;
@ -990,11 +993,11 @@ check_needed_image_versions(elf_image_info* image)
Returns the resolved symbol's address in \a _symbolAddress.
*/
status_t
elf_resolve_symbol(struct elf_image_info *image, struct Elf32_Sym *symbol,
elf_resolve_symbol(struct elf_image_info *image, elf_sym *symbol,
struct elf_image_info *sharedImage, addr_t *_symbolAddress)
{
// Local symbols references are always resolved to the given symbol.
if (ELF32_ST_BIND(symbol->st_info) == STB_LOCAL) {
if (symbol->Bind() == STB_LOCAL) {
*_symbolAddress = symbol->st_value + image->text_region.delta;
return B_OK;
}
@ -1019,19 +1022,19 @@ elf_resolve_symbol(struct elf_image_info *image, struct Elf32_Sym *symbol,
// find the symbol
elf_image_info* foundImage = firstImage;
struct Elf32_Sym* foundSymbol = elf_find_symbol(firstImage, symbolName,
versionInfo, false);
elf_sym* foundSymbol = elf_find_symbol(firstImage, symbolName, versionInfo,
false);
if (foundSymbol == NULL
|| ELF32_ST_BIND(foundSymbol->st_info) == STB_WEAK) {
|| foundSymbol->Bind() == STB_WEAK) {
// Not found or found a weak definition -- try to resolve in the other
// image.
Elf32_Sym* secondSymbol = elf_find_symbol(secondImage, symbolName,
elf_sym* secondSymbol = elf_find_symbol(secondImage, symbolName,
versionInfo, false);
// If we found a symbol -- take it in case we didn't have a symbol
// before or the new symbol is not weak.
if (secondSymbol != NULL
&& (foundSymbol == NULL
|| ELF32_ST_BIND(secondSymbol->st_info) != STB_WEAK)) {
|| secondSymbol->Bind() != STB_WEAK)) {
foundImage = secondImage;
foundSymbol = secondSymbol;
}
@ -1039,7 +1042,7 @@ elf_resolve_symbol(struct elf_image_info *image, struct Elf32_Sym *symbol,
if (foundSymbol == NULL) {
// Weak undefined symbols get a value of 0, if unresolved.
if (ELF32_ST_BIND(symbol->st_info) == STB_WEAK) {
if (symbol->Bind() == STB_WEAK) {
*_symbolAddress = 0;
return B_OK;
}
@ -1050,12 +1053,11 @@ elf_resolve_symbol(struct elf_image_info *image, struct Elf32_Sym *symbol,
}
// make sure they're the same type
if (ELF32_ST_TYPE(symbol->st_info) != ELF32_ST_TYPE(foundSymbol->st_info)) {
if (symbol->Type() != foundSymbol->Type()) {
dprintf("elf_resolve_symbol: found symbol '%s' in image '%s' "
"(requested by image '%s') but wrong type (%d vs. %d)\n",
symbolName, foundImage->name, image->name,
ELF32_ST_TYPE(foundSymbol->st_info),
ELF32_ST_TYPE(symbol->st_info));
foundSymbol->Type(), symbol->Type());
return B_MISSING_SYMBOL;
}
@ -1074,8 +1076,7 @@ elf_relocate(struct elf_image_info *image)
// deal with the rels first
if (image->rel) {
TRACE(("total %i relocs\n",
image->rel_len / (int)sizeof(struct Elf32_Rel)));
TRACE(("total %i rel relocs\n", image->rel_len / (int)sizeof(elf_rel)));
status = arch_elf_relocate_rel(image, sKernelImage, image->rel,
image->rel_len);
@ -1084,21 +1085,25 @@ elf_relocate(struct elf_image_info *image)
}
if (image->pltrel) {
TRACE(("total %i plt-relocs\n",
image->pltrel_len / (int)sizeof(struct Elf32_Rel)));
if (image->pltrel_type == DT_REL) {
TRACE(("total %i plt-relocs\n",
image->pltrel_len / (int)sizeof(elf_rel)));
status = arch_elf_relocate_rel(image, sKernelImage, image->pltrel,
image->pltrel_len);
} else {
TRACE(("total %i plt-relocs\n",
image->pltrel_len / (int)sizeof(elf_rela)));
status = arch_elf_relocate_rela(image, sKernelImage,
(struct Elf32_Rela *)image->pltrel, image->pltrel_len);
(elf_rela *)image->pltrel, image->pltrel_len);
}
if (status < B_OK)
return status;
}
if (image->rela) {
TRACE(("total %i rel relocs\n",
image->rela_len / (int)sizeof(elf_rela)));
status = arch_elf_relocate_rela(image, sKernelImage, image->rela,
image->rela_len);
if (status < B_OK)
@ -1110,18 +1115,18 @@ elf_relocate(struct elf_image_info *image)
static int
verify_eheader(struct Elf32_Ehdr *elfHeader)
verify_eheader(elf_ehdr *elfHeader)
{
if (memcmp(elfHeader->e_ident, ELF_MAGIC, 4) != 0)
return B_NOT_AN_EXECUTABLE;
if (elfHeader->e_ident[4] != ELFCLASS32)
if (elfHeader->e_ident[4] != ELF_CLASS)
return B_NOT_AN_EXECUTABLE;
if (elfHeader->e_phoff == 0)
return B_NOT_AN_EXECUTABLE;
if (elfHeader->e_phentsize < sizeof(struct Elf32_Phdr))
if (elfHeader->e_phentsize < sizeof(elf_phdr))
return B_NOT_AN_EXECUTABLE;
return 0;
@ -1144,9 +1149,9 @@ unload_elf_image(struct elf_image_info *image)
static status_t
load_elf_symbol_table(int fd, struct elf_image_info *image)
{
struct Elf32_Ehdr *elfHeader = image->elf_header;
struct Elf32_Sym *symbolTable = NULL;
struct Elf32_Shdr *stringHeader = NULL;
elf_ehdr *elfHeader = image->elf_header;
elf_sym *symbolTable = NULL;
elf_shdr *stringHeader = NULL;
uint32 numSymbols = 0;
char *stringTable;
status_t status;
@ -1156,7 +1161,7 @@ load_elf_symbol_table(int fd, struct elf_image_info *image)
// get section headers
ssize_t size = elfHeader->e_shnum * elfHeader->e_shentsize;
struct Elf32_Shdr *sectionHeaders = (struct Elf32_Shdr *)malloc(size);
elf_shdr *sectionHeaders = (elf_shdr *)malloc(size);
if (sectionHeaders == NULL) {
dprintf("error allocating space for section headers\n");
return B_NO_MEMORY;
@ -1182,8 +1187,8 @@ load_elf_symbol_table(int fd, struct elf_image_info *image)
}
// read in symbol table
symbolTable
= (struct Elf32_Sym *)malloc(size = sectionHeaders[i].sh_size);
size = sectionHeaders[i].sh_size;
symbolTable = (elf_sym *)malloc(size);
if (symbolTable == NULL) {
status = B_NO_MEMORY;
goto error1;
@ -1197,7 +1202,7 @@ load_elf_symbol_table(int fd, struct elf_image_info *image)
goto error2;
}
numSymbols = size / sizeof(struct Elf32_Sym);
numSymbols = size / sizeof(elf_sym);
break;
}
}
@ -1245,7 +1250,7 @@ error1:
static status_t
insert_preloaded_image(struct preloaded_elf32_image *preloadedImage, bool kernel)
insert_preloaded_image(preloaded_elf_image *preloadedImage, bool kernel)
{
status_t status;
@ -1290,9 +1295,9 @@ insert_preloaded_image(struct preloaded_elf32_image *preloadedImage, bool kernel
// copy debug symbols to the kernel heap
if (preloadedImage->debug_symbols != NULL) {
int32 debugSymbolsSize = sizeof(Elf32_Sym)
int32 debugSymbolsSize = sizeof(elf_sym)
* preloadedImage->num_debug_symbols;
image->debug_symbols = (Elf32_Sym*)malloc(debugSymbolsSize);
image->debug_symbols = (elf_sym*)malloc(debugSymbolsSize);
if (image->debug_symbols != NULL) {
memcpy(image->debug_symbols, preloadedImage->debug_symbols,
debugSymbolsSize);
@ -1333,6 +1338,8 @@ error1:
// #pragma mark - userland symbol lookup
// TODO x86_64
#ifndef __x86_64__
class UserSymbolLookup {
public:
static UserSymbolLookup& Default()
@ -1393,7 +1400,7 @@ public:
const elf_region_t& textRegion = image.regions[0];
// search the image for the symbol
Elf32_Sym symbolFound;
elf_sym symbolFound;
addr_t deltaFound = INT_MAX;
bool exactMatch = false;
@ -1409,7 +1416,7 @@ public:
for (uint32 j = bucket; j != STN_UNDEF;
_Read(&hashChains[j], j) ? 0 : j = STN_UNDEF) {
Elf32_Sym symbol;
elf_sym symbol;
if (!_Read(image.syms + j, symbol))
continue;
@ -1420,8 +1427,7 @@ public:
// function and data symbols that have an st_value != 0 (0
// seems to be an indication for a symbol defined elsewhere
// -- couldn't verify that in the specs though).
if ((ELF32_ST_TYPE(symbol.st_info) != STT_FUNC
&& ELF32_ST_TYPE(symbol.st_info) != STT_OBJECT)
if ((symbol.Type() != STT_FUNC && symbol.Type() != STT_OBJECT)
|| symbol.st_value == 0
|| symbol.st_value + symbol.st_size + textRegion.delta
> textRegion.vmstart + textRegion.size) {
@ -1540,6 +1546,7 @@ UserSymbolLookup::_Read(const T* address, T& data)
UserSymbolLookup UserSymbolLookup::sLookup;
// doesn't need construction, but has an Init() method
#endif
// #pragma mark - public kernel API
@ -1550,7 +1557,7 @@ get_image_symbol(image_id id, const char *name, int32 symbolClass,
void **_symbol)
{
struct elf_image_info *image;
struct Elf32_Sym *symbol;
elf_sym *symbol;
status_t status = B_OK;
TRACE(("get_image_symbol(%s)\n", name));
@ -1595,7 +1602,7 @@ elf_debug_lookup_symbol_address(addr_t address, addr_t *_baseAddress,
const char **_symbolName, const char **_imageName, bool *_exactMatch)
{
struct elf_image_info *image;
struct Elf32_Sym *symbolFound = NULL;
elf_sym *symbolFound = NULL;
const char *symbolName = NULL;
addr_t deltaFound = INT_MAX;
bool exactMatch = false;
@ -1625,7 +1632,7 @@ elf_debug_lookup_symbol_address(addr_t address, addr_t *_baseAddress,
TRACE((" searching debug symbols...\n"));
for (i = 0; i < image->num_debug_symbols; i++) {
struct Elf32_Sym *symbol = &image->debug_symbols[i];
elf_sym *symbol = &image->debug_symbols[i];
if (symbol->st_value == 0 || symbol->st_size
>= image->text_region.size + image->data_region.size)
@ -1653,7 +1660,7 @@ elf_debug_lookup_symbol_address(addr_t address, addr_t *_baseAddress,
for (i = 0; i < HASHTABSIZE(image); i++) {
for (j = HASHBUCKETS(image)[i]; j != STN_UNDEF;
j = HASHCHAINS(image)[j]) {
struct Elf32_Sym *symbol = &image->syms[j];
elf_sym *symbol = &image->syms[j];
if (symbol->st_value == 0
|| symbol->st_size >= image->text_region.size
@ -1726,6 +1733,8 @@ elf_debug_lookup_user_symbol_address(Team* team, addr_t address,
addr_t *_baseAddress, const char **_symbolName, const char **_imageName,
bool *_exactMatch)
{
// TODO x86_64
#ifndef __x86_64__
if (team == NULL || team == team_get_kernel_team())
return B_BAD_VALUE;
@ -1736,6 +1745,9 @@ elf_debug_lookup_user_symbol_address(Team* team, addr_t address,
return lookup.LookupSymbolAddress(address, _baseAddress, _symbolName,
_imageName, _exactMatch);
#else
return B_ENTRY_NOT_FOUND;
#endif
}
@ -1754,7 +1766,7 @@ elf_debug_lookup_symbol(const char* searchName)
if (image->num_debug_symbols > 0) {
// search extended debug symbol table (contains static symbols)
for (uint32 i = 0; i < image->num_debug_symbols; i++) {
struct Elf32_Sym *symbol = &image->debug_symbols[i];
elf_sym *symbol = &image->debug_symbols[i];
const char *name = image->debug_string_table + symbol->st_name;
if (symbol->st_value > 0 && !strcmp(name, searchName))
@ -1765,7 +1777,7 @@ elf_debug_lookup_symbol(const char* searchName)
for (uint32 i = 0; i < HASHTABSIZE(image); i++) {
for (uint32 j = HASHBUCKETS(image)[i]; j != STN_UNDEF;
j = HASHCHAINS(image)[j]) {
struct Elf32_Sym *symbol = &image->syms[j];
elf_sym *symbol = &image->syms[j];
const char *name = SYMNAME(image, symbol);
if (symbol->st_value > 0 && !strcmp(name, searchName))
@ -1784,7 +1796,7 @@ status_t
elf_lookup_kernel_symbol(const char* name, elf_symbol_info* info)
{
// find the symbol
Elf32_Sym* foundSymbol = elf_find_symbol(sKernelImage, name, NULL, false);
elf_sym* foundSymbol = elf_find_symbol(sKernelImage, name, NULL, false);
if (foundSymbol == NULL)
return B_MISSING_SYMBOL;
@ -1797,8 +1809,8 @@ elf_lookup_kernel_symbol(const char* name, elf_symbol_info* info)
status_t
elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry)
{
struct Elf32_Ehdr elfHeader;
struct Elf32_Phdr *programHeaders = NULL;
elf_ehdr elfHeader;
elf_phdr *programHeaders = NULL;
char baseName[B_OS_NAME_LENGTH];
status_t status;
ssize_t length;
@ -1835,7 +1847,7 @@ elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry)
// read program header
programHeaders = (struct Elf32_Phdr *)malloc(
programHeaders = (elf_phdr *)malloc(
elfHeader.e_phnum * elfHeader.e_phentsize);
if (programHeaders == NULL) {
dprintf("error allocating space for program headers\n");
@ -1917,10 +1929,10 @@ elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry)
// clean garbage brought by mmap (the region behind the file,
// at least parts of it are the bss and have to be zeroed)
uint32 start = (uint32)regionAddress
addr_t start = (addr_t)regionAddress
+ (programHeaders[i].p_vaddr % B_PAGE_SIZE)
+ programHeaders[i].p_filesz;
uint32 amount = fileUpperBound
size_t amount = fileUpperBound
- (programHeaders[i].p_vaddr % B_PAGE_SIZE)
- (programHeaders[i].p_filesz);
memset((void *)start, 0, amount);
@ -2002,8 +2014,8 @@ error:
image_id
load_kernel_add_on(const char *path)
{
struct Elf32_Phdr *programHeaders;
struct Elf32_Ehdr *elfHeader;
elf_phdr *programHeaders;
elf_ehdr *elfHeader;
struct elf_image_info *image;
const char *fileName;
void *reservedAddress;
@ -2041,7 +2053,7 @@ load_kernel_add_on(const char *path)
goto done;
}
elfHeader = (struct Elf32_Ehdr *)malloc(sizeof(*elfHeader));
elfHeader = (elf_ehdr *)malloc(sizeof(*elfHeader));
if (!elfHeader) {
status = B_NO_MEMORY;
goto error;
@ -2071,7 +2083,7 @@ load_kernel_add_on(const char *path)
image->name = strdup(path);
vnode = NULL;
programHeaders = (struct Elf32_Phdr *)malloc(elfHeader->e_phnum
programHeaders = (elf_phdr *)malloc(elfHeader->e_phnum
* elfHeader->e_phentsize);
if (programHeaders == NULL) {
dprintf("%s: error allocating space for program headers\n", fileName);
@ -2148,7 +2160,7 @@ load_kernel_add_on(const char *path)
image->dynamic_section = programHeaders[i].p_vaddr;
continue;
default:
dprintf("%s: unhandled pheader type 0x%lx\n", fileName,
dprintf("%s: unhandled pheader type %#" B_PRIx32 "\n", fileName,
programHeaders[i].p_type);
continue;
}
@ -2185,7 +2197,7 @@ load_kernel_add_on(const char *path)
textSectionWritable = programHeaders[i].IsReadWrite();
snprintf(regionName, B_OS_NAME_LENGTH, "%s_text", fileName);
} else {
dprintf("%s: weird program header flags 0x%lx\n", fileName,
dprintf("%s: weird program header flags %#" B_PRIx32 "\n", fileName,
programHeaders[i].p_flags);
continue;
}
@ -2213,7 +2225,8 @@ load_kernel_add_on(const char *path)
programHeaders[i].p_filesz);
if (length < B_OK) {
status = length;
dprintf("%s: error reading in segment %ld\n", fileName, i);
dprintf("%s: error reading in segment %" B_PRId32 "\n", fileName,
i);
goto error5;
}
}
@ -2355,7 +2368,7 @@ elf_create_memory_image(const char* imageName, addr_t text, size_t textSize,
// allocate symbol and string tables -- we allocate an empty symbol table,
// so that elf_debug_lookup_symbol_address() won't try the dynamic symbol
// table, which we don't have.
Elf32_Sym* symbolTable = (Elf32_Sym*)malloc(0);
elf_sym* symbolTable = (elf_sym*)malloc(0);
char* stringTable = (char*)malloc(1);
MemoryDeleter symbolTableDeleter(symbolTable);
MemoryDeleter stringTableDeleter(stringTable);
@ -2440,19 +2453,19 @@ elf_add_memory_image_symbol(image_id id, const char* name, addr_t address,
// resize the symbol table
int32 symbolCount = image->num_debug_symbols + 1;
Elf32_Sym* symbolTable = (Elf32_Sym*)realloc(
(Elf32_Sym*)image->debug_symbols, sizeof(Elf32_Sym) * symbolCount);
elf_sym* symbolTable = (elf_sym*)realloc(
(elf_sym*)image->debug_symbols, sizeof(elf_sym) * symbolCount);
if (symbolTable == NULL)
return B_NO_MEMORY;
image->debug_symbols = symbolTable;
// enter the symbol
Elf32_Sym& symbol = symbolTable[symbolCount - 1];
uint32 symbolType = type == B_SYMBOL_TYPE_DATA ? STT_OBJECT : STT_FUNC;
elf_sym& symbol = symbolTable[symbolCount - 1];
symbol.SetInfo(STB_GLOBAL,
type == B_SYMBOL_TYPE_DATA ? STT_OBJECT : STT_FUNC);
symbol.st_name = stringIndex;
symbol.st_value = address;
symbol.st_size = size;
symbol.st_info = ELF32_ST_INFO(STB_GLOBAL, symbolType);
symbol.st_other = 0;
symbol.st_shndx = 0;
image->num_debug_symbols++;
@ -2475,14 +2488,14 @@ elf_init(kernel_args *args)
// Build a image structure for the kernel, which has already been loaded.
// The preloaded_images were already prepared by the VM.
image = args->kernel_image;
if (insert_preloaded_image(static_cast<struct preloaded_elf32_image *>(
image), true) < B_OK)
if (insert_preloaded_image(static_cast<preloaded_elf_image *>(image),
true) < B_OK)
panic("could not create kernel image.\n");
// Build image structures for all preloaded images.
for (image = args->preloaded_images; image != NULL; image = image->next)
insert_preloaded_image(static_cast<struct preloaded_elf32_image *>(
image), false);
insert_preloaded_image(static_cast<preloaded_elf_image *>(image),
false);
add_debugger_command("ls", &dump_address_info,
"lookup symbol for a particular address");
@ -2501,6 +2514,8 @@ elf_init(kernel_args *args)
// #pragma mark -
// TODO: x86_64
#ifndef __x86_64__
/*! 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

View File

@ -3543,13 +3543,7 @@ vm_free_unused_boot_loader_range(addr_t start, addr_t size)
static void
create_preloaded_image_areas(struct preloaded_image* _image)
{
// TODO: Make this a typedef somewhere. Will be done when I implement
// ELF loading for x86_64.
#ifdef B_HAIKU_64_BIT
preloaded_elf64_image* image = static_cast<preloaded_elf64_image*>(_image);
#else
preloaded_elf32_image* image = static_cast<preloaded_elf32_image*>(_image);
#endif
preloaded_elf_image* image = static_cast<preloaded_elf_image*>(_image);
char name[B_OS_NAME_LENGTH];
void* address;
int32 length;