Changed the boot ELF code to use templates and added ELF64 support.

The actual implementation of the ELF loading methods have been put into
an ELFLoader template class that takes a single template parameter, which
is a structure containing all the necessary ELF typedefs. It's a bit
verbose, but I thought it was a neater solution than using a bunch of
standalone functions with a huge number of template parameters. There is
no change to code outside of elf.cpp, the ELF32/ELF64 differences are
handled internally.
This commit is contained in:
Alex Smith
2012-06-23 12:05:16 +01:00
parent 3a2a3367dc
commit ccadfaeeb5
6 changed files with 415 additions and 306 deletions
+5 -8
View File
@@ -5,24 +5,21 @@
#ifndef KERNEL_BOOT_ARCH_H #ifndef KERNEL_BOOT_ARCH_H
#define KERNEL_BOOT_ARCH_H #define KERNEL_BOOT_ARCH_H
#include <SupportDefs.h> #include <SupportDefs.h>
#include <boot/elf.h> #include <boot/elf.h>
#ifdef __cplusplus
extern "C" {
#endif
/* ELF support */ /* ELF support */
extern status_t boot_arch_elf_relocate_rel(preloaded_elf32_image* image, extern status_t boot_arch_elf_relocate_rel(preloaded_elf32_image* image,
struct Elf32_Rel* rel, int rel_len); struct Elf32_Rel* rel, int rel_len);
extern status_t boot_arch_elf_relocate_rel(preloaded_elf64_image* image,
struct Elf64_Rel* rel, int rel_len);
extern status_t boot_arch_elf_relocate_rela(preloaded_elf32_image* image, extern status_t boot_arch_elf_relocate_rela(preloaded_elf32_image* image,
struct Elf32_Rela* rel, int rel_len); struct Elf32_Rela* rel, int rel_len);
extern status_t boot_arch_elf_relocate_rela(preloaded_elf64_image* image,
struct Elf64_Rela* rel, int rel_len);
#ifdef __cplusplus
}
#endif
#endif /* KERNEL_BOOT_ARCH_H */ #endif /* KERNEL_BOOT_ARCH_H */
+7 -10
View File
@@ -1,6 +1,7 @@
/* /*
** Copyright 2003-2004, Axel Dörfler, [email protected]. All rights reserved. * Copyright 2003-2004, Axel Dörfler, [email protected]. All rights reserved.
** Distributed under the terms of the OpenBeOS License. * Copyright 2012, Alex Smith, [email protected].
* Distributed under the terms of the OpenBeOS License.
*/ */
#ifndef KERNEL_BOOT_ELF_H #ifndef KERNEL_BOOT_ELF_H
#define KERNEL_BOOT_ELF_H #define KERNEL_BOOT_ELF_H
@@ -76,15 +77,11 @@ struct preloaded_elf64_image : public preloaded_image {
FixedWidthPointer<Elf64_Sym> debug_symbols; FixedWidthPointer<Elf64_Sym> debug_symbols;
} _PACKED; } _PACKED;
#ifdef __cplusplus
extern "C" {
#endif
extern status_t boot_elf_resolve_symbol(struct preloaded_elf32_image *image, extern status_t boot_elf_resolve_symbol(preloaded_elf32_image* image,
struct Elf32_Sym *symbol, addr_t *symbolAddress); struct Elf32_Sym* symbol, Elf32_Addr* symbolAddress);
extern status_t boot_elf_resolve_symbol(preloaded_elf64_image* image,
struct Elf64_Sym* symbol, Elf64_Addr* symbolAddress);
#ifdef __cplusplus
}
#endif
#endif /* KERNEL_BOOT_ELF_H */ #endif /* KERNEL_BOOT_ELF_H */
-8
View File
@@ -15,14 +15,6 @@
#include <arch_elf.h> #include <arch_elf.h>
typedef uint32 Elf32_Addr;
typedef uint16 Elf32_Half;
typedef uint32 Elf32_Off;
typedef int32 Elf32_Sword;
typedef uint32 Elf32_Word;
typedef Elf32_Half Elf32_Versym;
/*** ELF header ***/ /*** ELF header ***/
#define EI_NIDENT 16 #define EI_NIDENT 16
+2 -2
View File
@@ -39,7 +39,7 @@ UsePrivateHeaders shared storage ;
{ {
defines += defines +=
ALTERNATE_BOOT_ARCH=\\\"x86_64\\\" ALTERNATE_BOOT_ARCH=\\\"x86_64\\\"
BOOT_SUPPORT_ELF64 #BOOT_SUPPORT_ELF64
BOOT_SUPPORT_PARTITION_EFI BOOT_SUPPORT_PARTITION_EFI
@@ -50,7 +50,7 @@ UsePrivateHeaders shared storage ;
{ {
defines += defines +=
ALTERNATE_BOOT_ARCH=\\\"x86\\\" ALTERNATE_BOOT_ARCH=\\\"x86\\\"
BOOT_SUPPORT_ELF64 #BOOT_SUPPORT_ELF64
BOOT_SUPPORT_PARTITION_EFI BOOT_SUPPORT_PARTITION_EFI
+386 -264
View File
@@ -30,233 +30,114 @@
static bool sLoadElfSymbols = true; static bool sLoadElfSymbols = true;
void // #pragma mark - Generic ELF loader
elf_init()
{
// TODO: This cannot work, since the driver settings are loaded *after* the
// kernel has been loaded successfully.
#if 0
void *settings = load_driver_settings("kernel");
if (settings == NULL)
return;
sLoadElfSymbols = !get_driver_boolean_parameter(settings, "load_symbols",
false, false); template<typename Class>
unload_driver_settings(settings); class ELFLoader {
private:
typedef typename Class::ImageType ImageType;
typedef typename Class::RegionType RegionType;
typedef typename Class::EhdrType EhdrType;
typedef typename Class::PhdrType PhdrType;
typedef typename Class::ShdrType ShdrType;
typedef typename Class::DynType DynType;
typedef typename Class::SymType SymType;
typedef typename Class::RelType RelType;
typedef typename Class::RelaType RelaType;
public:
static status_t Create(int fd, preloaded_image** _image);
static status_t Load(int fd, preloaded_image* image);
static status_t Relocate(preloaded_image* image);
private:
static status_t _LoadSymbolTable(int fd, ImageType* image);
static status_t _ParseDynamicSection(ImageType* image);
};
struct ELF32Class {
static const uint8 kIdentClass = ELFCLASS32;
typedef preloaded_elf32_image ImageType;
typedef elf32_region RegionType;
typedef Elf32_Ehdr EhdrType;
typedef Elf32_Phdr PhdrType;
typedef Elf32_Shdr ShdrType;
typedef Elf32_Dyn DynType;
typedef Elf32_Sym SymType;
typedef Elf32_Rel RelType;
typedef Elf32_Rela RelaType;
};
typedef ELFLoader<ELF32Class> ELF32Loader;
#ifdef BOOT_SUPPORT_ELF64
struct ELF64Class {
static const uint8 kIdentClass = ELFCLASS64;
typedef preloaded_elf64_image ImageType;
typedef elf64_region RegionType;
typedef Elf64_Ehdr EhdrType;
typedef Elf64_Phdr PhdrType;
typedef Elf64_Shdr ShdrType;
typedef Elf64_Dyn DynType;
typedef Elf64_Sym SymType;
typedef Elf64_Rel RelType;
typedef Elf64_Rela RelaType;
};
typedef ELFLoader<ELF64Class> ELF64Loader;
#endif #endif
}
static status_t template<typename Class>
verify_elf_header(struct Elf32_Ehdr &header) /*static*/ status_t
ELFLoader<Class>::Create(int fd, preloaded_image** _image)
{ {
if (memcmp(header.e_ident, ELF_MAGIC, 4) != 0 ImageType* image = (ImageType*)kernel_args_malloc(sizeof(ImageType));
|| header.e_ident[4] != ELFCLASS32
|| header.e_phoff == 0
|| !header.IsHostEndian()
|| header.e_phentsize != sizeof(struct Elf32_Phdr))
return B_BAD_TYPE;
return B_OK;
}
static status_t
elf_parse_dynamic_section(preloaded_elf32_image *image)
{
image->syms = 0;
image->rel = 0;
image->rel_len = 0;
image->rela = 0;
image->rela_len = 0;
image->pltrel = 0;
image->pltrel_len = 0;
image->pltrel_type = 0;
struct Elf32_Dyn *d = (struct Elf32_Dyn *)image->dynamic_section.start;
if (!d)
return B_ERROR;
for (int i = 0; d[i].d_tag != DT_NULL; i++) {
switch (d[i].d_tag) {
case DT_HASH:
case DT_STRTAB:
break;
case DT_SYMTAB:
image->syms = (struct Elf32_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->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->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->text_region.delta);
break;
case DT_PLTRELSZ:
image->pltrel_len = d[i].d_un.d_val;
break;
case DT_PLTREL:
image->pltrel_type = d[i].d_un.d_val;
break;
default:
continue;
}
}
// lets make sure we found all the required sections
if (image->syms == NULL)
return B_ERROR;
return B_OK;
}
static status_t
load_elf_symbol_table(int fd, preloaded_elf32_image *image)
{
struct Elf32_Ehdr &elfHeader = image->elf_header;
Elf32_Sym *symbolTable = NULL;
Elf32_Shdr *stringHeader = NULL;
uint32 numSymbols = 0;
char *stringTable;
status_t status;
// get section headers
ssize_t size = elfHeader.e_shnum * elfHeader.e_shentsize;
Elf32_Shdr *sectionHeaders = (struct Elf32_Shdr *)malloc(size);
if (sectionHeaders == NULL) {
dprintf("error allocating space for section headers\n");
return B_NO_MEMORY;
}
ssize_t length = read_pos(fd, elfHeader.e_shoff, sectionHeaders, size);
if (length < size) {
TRACE(("error reading in program headers\n"));
status = B_ERROR;
goto error1;
}
// find symbol table in section headers
for (int32 i = 0; i < elfHeader.e_shnum; i++) {
if (sectionHeaders[i].sh_type == SHT_SYMTAB) {
stringHeader = &sectionHeaders[sectionHeaders[i].sh_link];
if (stringHeader->sh_type != SHT_STRTAB) {
TRACE(("doesn't link to string table\n"));
status = B_BAD_DATA;
goto error1;
}
// read in symbol table
symbolTable = (Elf32_Sym *)kernel_args_malloc(
size = sectionHeaders[i].sh_size);
if (symbolTable == NULL) {
status = B_NO_MEMORY;
goto error1;
}
length = read_pos(fd, sectionHeaders[i].sh_offset, symbolTable,
size);
if (length < size) {
TRACE(("error reading in symbol table\n"));
status = B_ERROR;
goto error1;
}
numSymbols = size / sizeof(Elf32_Sym);
break;
}
}
if (symbolTable == NULL) {
TRACE(("no symbol table\n"));
status = B_BAD_VALUE;
goto error1;
}
// read in string table
stringTable = (char *)kernel_args_malloc(size = stringHeader->sh_size);
if (stringTable == NULL) {
status = B_NO_MEMORY;
goto error2;
}
length = read_pos(fd, stringHeader->sh_offset, stringTable, size);
if (length < size) {
TRACE(("error reading in string table\n"));
status = B_ERROR;
goto error3;
}
TRACE(("loaded %ld debug symbols\n", numSymbols));
// insert tables into image
image->debug_symbols = symbolTable;
image->num_debug_symbols = numSymbols;
image->debug_string_table = stringTable;
image->debug_string_table_size = size;
free(sectionHeaders);
return B_OK;
error3:
kernel_args_free(stringTable);
error2:
kernel_args_free(symbolTable);
error1:
free(sectionHeaders);
return status;
}
status_t
elf_load_image(int fd, preloaded_image **_image)
{
size_t totalSize;
status_t status;
TRACE(("elf_load_image(fd = %d, _image = %p)\n", fd, _image));
preloaded_elf32_image *image = (preloaded_elf32_image *)kernel_args_malloc(
sizeof(preloaded_elf32_image));
if (image == NULL) if (image == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
struct Elf32_Ehdr &elfHeader = image->elf_header; EhdrType& elfHeader = image->elf_header;
ssize_t length = read_pos(fd, 0, &elfHeader, sizeof(Elf32_Ehdr)); ssize_t length = read_pos(fd, 0, &elfHeader, sizeof(EhdrType));
if (length < (ssize_t)sizeof(Elf32_Ehdr)) { if (length < (ssize_t)sizeof(EhdrType)) {
kernel_args_free(image); kernel_args_free(image);
return B_BAD_TYPE; return B_BAD_TYPE;
} }
status = verify_elf_header(elfHeader); if (memcmp(elfHeader.e_ident, ELF_MAGIC, 4) != 0
if (status < B_OK) { || elfHeader.e_ident[4] != Class::kIdentClass
|| elfHeader.e_phoff == 0
|| !elfHeader.IsHostEndian()
|| elfHeader.e_phentsize != sizeof(PhdrType)) {
kernel_args_free(image); kernel_args_free(image);
return status; return B_BAD_TYPE;
} }
image->elf_class = elfHeader.e_ident[EI_CLASS]; image->elf_class = elfHeader.e_ident[EI_CLASS];
*_image = image;
return B_OK;
}
template<typename Class>
/*static*/ status_t
ELFLoader<Class>::Load(int fd, preloaded_image* _image)
{
size_t totalSize;
ssize_t length;
status_t status;
ImageType* image = static_cast<ImageType*>(_image);
EhdrType& elfHeader = image->elf_header;
ssize_t size = elfHeader.e_phnum * elfHeader.e_phentsize; ssize_t size = elfHeader.e_phnum * elfHeader.e_phentsize;
Elf32_Phdr *programHeaders = (struct Elf32_Phdr *)malloc(size); PhdrType* programHeaders = (PhdrType*)malloc(size);
if (programHeaders == NULL) { if (programHeaders == NULL) {
dprintf("error allocating space for program headers\n"); dprintf("error allocating space for program headers\n");
status = B_NO_MEMORY; status = B_NO_MEMORY;
@@ -276,7 +157,7 @@ elf_load_image(int fd, preloaded_image **_image)
image->text_region.size = 0; image->text_region.size = 0;
for (int32 i = 0; i < elfHeader.e_phnum; i++) { for (int32 i = 0; i < elfHeader.e_phnum; i++) {
Elf32_Phdr &header = programHeaders[i]; PhdrType& header = programHeaders[i];
switch (header.p_type) { switch (header.p_type) {
case PT_LOAD: case PT_LOAD:
@@ -294,7 +175,7 @@ elf_load_image(int fd, preloaded_image **_image)
continue; continue;
} }
elf32_region *region; RegionType* region;
if (header.IsReadWrite()) { if (header.IsReadWrite()) {
if (image->data_region.size != 0) { if (image->data_region.size != 0) {
dprintf("elf: rw already handled!\n"); dprintf("elf: rw already handled!\n");
@@ -327,8 +208,8 @@ elf_load_image(int fd, preloaded_image **_image)
} }
// get the segment order // get the segment order
elf32_region *firstRegion; RegionType* firstRegion;
elf32_region *secondRegion; RegionType* secondRegion;
if (image->text_region.start < image->data_region.start) { if (image->text_region.start < image->data_region.start) {
firstRegion = &image->text_region; firstRegion = &image->text_region;
secondRegion = &image->data_region; secondRegion = &image->data_region;
@@ -363,13 +244,13 @@ elf_load_image(int fd, preloaded_image **_image)
// load program data // load program data
for (int i = 0; i < elfHeader.e_phnum; i++) { for (int32 i = 0; i < elfHeader.e_phnum; i++) {
Elf32_Phdr &header = programHeaders[i]; PhdrType& header = programHeaders[i];
if (header.p_type != PT_LOAD) if (header.p_type != PT_LOAD)
continue; continue;
elf32_region *region; RegionType* region;
if (header.IsReadWrite()) if (header.IsReadWrite())
region = &image->data_region; region = &image->data_region;
else if (header.IsExecutable()) else if (header.IsExecutable())
@@ -384,7 +265,7 @@ elf_load_image(int fd, preloaded_image **_image)
header.p_filesz); header.p_filesz);
if (length < (ssize_t)header.p_filesz) { if (length < (ssize_t)header.p_filesz) {
status = B_BAD_DATA; status = B_BAD_DATA;
dprintf("error reading in seg %d\n", i); dprintf("error reading in seg %ld\n", i);
goto error2; goto error2;
} }
@@ -406,11 +287,10 @@ elf_load_image(int fd, preloaded_image **_image)
image->debug_string_table = NULL; image->debug_string_table = NULL;
if (sLoadElfSymbols) if (sLoadElfSymbols)
load_elf_symbol_table(fd, image); _LoadSymbolTable(fd, image);
free(programHeaders); free(programHeaders);
*_image = image;
return B_OK; return B_OK;
error2: error2:
@@ -424,6 +304,266 @@ error1:
} }
template<typename Class>
/*static*/ status_t
ELFLoader<Class>::Relocate(preloaded_image* _image)
{
ImageType* image = static_cast<ImageType*>(_image);
status_t status = _ParseDynamicSection(image);
if (status != B_OK)
return status;
// deal with the rels first
if (image->rel) {
TRACE(("total %i relocs\n", image->rel_len / (int)sizeof(RelType)));
status = boot_arch_elf_relocate_rel(image, image->rel, image->rel_len);
if (status < B_OK)
return status;
}
if (image->pltrel) {
TRACE(("total %i plt-relocs\n",
image->pltrel_len / (int)sizeof(RelType)));
RelType* pltrel = image->pltrel;
if (image->pltrel_type == DT_REL) {
status = boot_arch_elf_relocate_rel(image, pltrel,
image->pltrel_len);
} else {
status = boot_arch_elf_relocate_rela(image, (RelaType *)pltrel,
image->pltrel_len);
}
if (status < B_OK)
return status;
}
if (image->rela) {
TRACE(("total %i rela relocs\n",
image->rela_len / (int)sizeof(RelaType)));
status = boot_arch_elf_relocate_rela(image, image->rela,
image->rela_len);
if (status < B_OK)
return status;
}
return B_OK;
}
template<typename Class>
/*static*/ status_t
ELFLoader<Class>::_LoadSymbolTable(int fd, ImageType* image)
{
EhdrType& elfHeader = image->elf_header;
SymType* symbolTable = NULL;
ShdrType* stringHeader = NULL;
uint32 numSymbols = 0;
char* stringTable;
status_t status;
// get section headers
ssize_t size = elfHeader.e_shnum * elfHeader.e_shentsize;
ShdrType* sectionHeaders = (ShdrType*)malloc(size);
if (sectionHeaders == NULL) {
dprintf("error allocating space for section headers\n");
return B_NO_MEMORY;
}
ssize_t length = read_pos(fd, elfHeader.e_shoff, sectionHeaders, size);
if (length < size) {
TRACE(("error reading in program headers\n"));
status = B_ERROR;
goto error1;
}
// find symbol table in section headers
for (int32 i = 0; i < elfHeader.e_shnum; i++) {
if (sectionHeaders[i].sh_type == SHT_SYMTAB) {
stringHeader = &sectionHeaders[sectionHeaders[i].sh_link];
if (stringHeader->sh_type != SHT_STRTAB) {
TRACE(("doesn't link to string table\n"));
status = B_BAD_DATA;
goto error1;
}
// read in symbol table
size = sectionHeaders[i].sh_size;
symbolTable = (SymType*)kernel_args_malloc(size);
if (symbolTable == NULL) {
status = B_NO_MEMORY;
goto error1;
}
length = read_pos(fd, sectionHeaders[i].sh_offset, symbolTable,
size);
if (length < size) {
TRACE(("error reading in symbol table\n"));
status = B_ERROR;
goto error1;
}
numSymbols = size / sizeof(SymType);
break;
}
}
if (symbolTable == NULL) {
TRACE(("no symbol table\n"));
status = B_BAD_VALUE;
goto error1;
}
// read in string table
size = stringHeader->sh_size;
stringTable = (char*)kernel_args_malloc(size);
if (stringTable == NULL) {
status = B_NO_MEMORY;
goto error2;
}
length = read_pos(fd, stringHeader->sh_offset, stringTable, size);
if (length < size) {
TRACE(("error reading in string table\n"));
status = B_ERROR;
goto error3;
}
TRACE(("loaded %ld debug symbols\n", numSymbols));
// insert tables into image
image->debug_symbols = symbolTable;
image->num_debug_symbols = numSymbols;
image->debug_string_table = stringTable;
image->debug_string_table_size = size;
free(sectionHeaders);
return B_OK;
error3:
kernel_args_free(stringTable);
error2:
kernel_args_free(symbolTable);
error1:
free(sectionHeaders);
return status;
}
template<typename Class>
/*static*/ status_t
ELFLoader<Class>::_ParseDynamicSection(ImageType* image)
{
image->syms = 0;
image->rel = 0;
image->rel_len = 0;
image->rela = 0;
image->rela_len = 0;
image->pltrel = 0;
image->pltrel_len = 0;
image->pltrel_type = 0;
DynType* d = (DynType*)image->dynamic_section.start;
if (!d)
return B_ERROR;
for (int i = 0; d[i].d_tag != DT_NULL; i++) {
switch (d[i].d_tag) {
case DT_HASH:
case DT_STRTAB:
break;
case DT_SYMTAB:
image->syms = (SymType*)(d[i].d_un.d_ptr
+ image->text_region.delta);
break;
case DT_REL:
image->rel = (RelType*)(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 = (RelaType*)(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 = (RelType*)(d[i].d_un.d_ptr
+ image->text_region.delta);
break;
case DT_PLTRELSZ:
image->pltrel_len = d[i].d_un.d_val;
break;
case DT_PLTREL:
image->pltrel_type = d[i].d_un.d_val;
break;
default:
continue;
}
}
// lets make sure we found all the required sections
if (image->syms == NULL)
return B_ERROR;
return B_OK;
}
// #pragma mark -
void
elf_init()
{
// TODO: This cannot work, since the driver settings are loaded *after* the
// kernel has been loaded successfully.
#if 0
void *settings = load_driver_settings("kernel");
if (settings == NULL)
return;
sLoadElfSymbols = !get_driver_boolean_parameter(settings, "load_symbols",
false, false);
unload_driver_settings(settings);
#endif
}
status_t
elf_load_image(int fd, preloaded_image** _image)
{
status_t status;
TRACE(("elf_load_image(fd = %d, _image = %p)\n", fd, _image));
#if BOOT_SUPPORT_ELF64
status = ELF64Loader::Create(fd, _image);
if (status == B_OK) {
return ELF64Loader::Load(fd, *_image);
} else if (status == B_BAD_TYPE) {
#endif
status = ELF32Loader::Create(fd, _image);
if (status == B_OK)
return ELF32Loader::Load(fd, *_image);
#if BOOT_SUPPORT_ELF64
}
#endif
return status;
}
status_t status_t
elf_load_image(Directory* directory, const char* path) elf_load_image(Directory* directory, const char* path)
{ {
@@ -469,56 +609,20 @@ elf_load_image(Directory *directory, const char *path)
status_t status_t
elf_relocate_image(preloaded_image *_image) elf_relocate_image(preloaded_image* image)
{ {
preloaded_elf32_image *image = static_cast<preloaded_elf32_image *>(_image); #ifdef BOOT_SUPPORT_ELF64
if (image->elf_class == ELFCLASS64)
status_t status = elf_parse_dynamic_section(image); return ELF64Loader::Relocate(image);
if (status != B_OK) else
return status; #endif
return ELF32Loader::Relocate(image);
// deal with the rels first
if (image->rel) {
TRACE(("total %i relocs\n",
image->rel_len / (int)sizeof(struct Elf32_Rel)));
status = boot_arch_elf_relocate_rel(image, image->rel, image->rel_len);
if (status < B_OK)
return status;
}
if (image->pltrel) {
TRACE(("total %i plt-relocs\n",
image->pltrel_len / (int)sizeof(struct Elf32_Rel)));
struct Elf32_Rel *pltrel = image->pltrel;
if (image->pltrel_type == DT_REL) {
status = boot_arch_elf_relocate_rel(image, pltrel,
image->pltrel_len);
} else {
status = boot_arch_elf_relocate_rela(image,
(struct Elf32_Rela *)pltrel, image->pltrel_len);
}
if (status < B_OK)
return status;
}
if (image->rela) {
TRACE(("total %i rela relocs\n",
image->rela_len / (int)sizeof(struct Elf32_Rela)));
status = boot_arch_elf_relocate_rela(image, image->rela,
image->rela_len);
if (status < B_OK)
return status;
}
return B_OK;
} }
status_t template<typename ImageType, typename SymType, typename AddrType>
boot_elf_resolve_symbol(struct preloaded_elf32_image *image, inline status_t
struct Elf32_Sym *symbol, addr_t *symbolAddress) resolve_symbol(ImageType* image, SymType* symbol, AddrType* symbolAddress)
{ {
switch (symbol->st_shndx) { switch (symbol->st_shndx) {
case SHN_UNDEF: case SHN_UNDEF:
@@ -538,3 +642,21 @@ boot_elf_resolve_symbol(struct preloaded_elf32_image *image,
return B_NO_ERROR; return B_NO_ERROR;
} }
} }
status_t
boot_elf_resolve_symbol(preloaded_elf32_image* image, struct Elf32_Sym* symbol,
Elf32_Addr* symbolAddress)
{
return resolve_symbol(image, symbol, symbolAddress);
}
#ifdef BOOT_SUPPORT_ELF64
status_t
boot_elf_resolve_symbol(preloaded_elf64_image* image, struct Elf64_Sym* symbol,
Elf64_Addr* symbolAddress)
{
return resolve_symbol(image, symbol, symbolAddress);
}
#endif
+1
View File
@@ -16,4 +16,5 @@ extern status_t elf_load_image(int fd, preloaded_image **_image);
extern status_t elf_relocate_image(preloaded_image* image); extern status_t elf_relocate_image(preloaded_image* image);
#endif /* LOADER_ELF_H */ #endif /* LOADER_ELF_H */