Cleaned up ELF64 address handling.
* platform_allocate_elf_region() is removed, it is implemented in platform- independent code now (ELF*Class::AllocateRegion). For ELF64 it is now assumed that 64-bit addresses are mapped in the loader's 32-bit address space as (address - KERNEL_BASE_64BIT + KERNEL_BASE). * mapped_delta field from preloaded_*_image removed, now handled compile-time using the ELF*Class::Map method. * Also link the kernel with -z max-page-size=0x1000, removes the need for 2MB alignment on the data segment (not going to map the kernel with large pages for the time being).
This commit is contained in:
@@ -388,6 +388,7 @@ switch $(HAIKU_ARCH) {
|
|||||||
# code due to interrupts.
|
# code due to interrupts.
|
||||||
HAIKU_KERNEL_CCFLAGS += -mcmodel=kernel -mno-red-zone ;
|
HAIKU_KERNEL_CCFLAGS += -mcmodel=kernel -mno-red-zone ;
|
||||||
HAIKU_KERNEL_C++FLAGS += -mcmodel=kernel -mno-red-zone ;
|
HAIKU_KERNEL_C++FLAGS += -mcmodel=kernel -mno-red-zone ;
|
||||||
|
HAIKU_KERNEL_PIC_LINKFLAGS += -z max-page-size=0x1000 ;
|
||||||
|
|
||||||
# Bootloader is 32-bit.
|
# Bootloader is 32-bit.
|
||||||
HAIKU_BOOT_LINKFLAGS += -m elf_i386_haiku ;
|
HAIKU_BOOT_LINKFLAGS += -m elf_i386_haiku ;
|
||||||
|
|||||||
@@ -17,6 +17,10 @@
|
|||||||
#define KERNEL_SIZE 0x80000000
|
#define KERNEL_SIZE 0x80000000
|
||||||
#define KERNEL_TOP (KERNEL_BASE + (KERNEL_SIZE - 1))
|
#define KERNEL_TOP (KERNEL_BASE + (KERNEL_SIZE - 1))
|
||||||
|
|
||||||
|
#ifdef _BOOT_MODE
|
||||||
|
# define KERNEL_BASE_64BIT 0xffffffff80000000
|
||||||
|
#endif
|
||||||
|
|
||||||
/* User space layout is a little special:
|
/* User space layout is a little special:
|
||||||
* The user space does not completely cover the space not covered by the
|
* The user space does not completely cover the space not covered by the
|
||||||
* kernel. There is a gap of 64kb between the user and kernel space. The 64kb
|
* kernel. There is a gap of 64kb between the user and kernel space. The 64kb
|
||||||
|
|||||||
@@ -13,15 +13,16 @@
|
|||||||
|
|
||||||
// Base of the kernel address space.
|
// Base of the kernel address space.
|
||||||
// When compiling the bootloader, KERNEL_BASE is set to the x86 base address,
|
// When compiling the bootloader, KERNEL_BASE is set to the x86 base address,
|
||||||
// the correct 64-bit addresses are calculated differently.
|
// KERNEL_BASE_64BIT is set to where the kernel loaded to.
|
||||||
// For the kernel, this is the base of the kernel address space. This is NOT
|
// For the kernel, KERNEL_BASE is the base of the kernel address space. This is
|
||||||
// the address where the kernel is loaded to: the kernel is loaded in the top
|
// NOT the address where the kernel is loaded to: the kernel is loaded in the
|
||||||
// 2GB of the virtual address space as required by GCC's kernel code model.
|
// top 2GB of the virtual address space as required by GCC's kernel code model.
|
||||||
// The whole kernel address space is the top 512GB of the address space.
|
// The whole kernel address space is the top 512GB of the address space.
|
||||||
#ifdef _BOOT_MODE
|
#ifdef _BOOT_MODE
|
||||||
# define KERNEL_BASE 0x80000000
|
# define KERNEL_BASE 0x80000000
|
||||||
|
# define KERNEL_BASE_64BIT 0xffffffff80000000
|
||||||
#else
|
#else
|
||||||
# define KERNEL_BASE 0xFFFFFF8000000000
|
# define KERNEL_BASE 0xffffff8000000000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define KERNEL_SIZE 0x8000000000
|
#define KERNEL_SIZE 0x8000000000
|
||||||
@@ -34,8 +35,8 @@
|
|||||||
#define USER_SIZE 0x800000000000
|
#define USER_SIZE 0x800000000000
|
||||||
#define USER_TOP (USER_BASE + USER_SIZE)
|
#define USER_TOP (USER_BASE + USER_SIZE)
|
||||||
|
|
||||||
#define KERNEL_USER_DATA_BASE 0x7FFFEFFF0000
|
#define KERNEL_USER_DATA_BASE 0x7fffefff0000
|
||||||
#define USER_STACK_REGION 0x7FFFF0000000
|
#define USER_STACK_REGION 0x7ffff0000000
|
||||||
#define USER_STACK_REGION_SIZE (USER_TOP - USER_STACK_REGION)
|
#define USER_STACK_REGION_SIZE (USER_TOP - USER_STACK_REGION)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,6 @@ struct preloaded_elf32_image : public preloaded_image {
|
|||||||
Elf32_Ehdr elf_header;
|
Elf32_Ehdr elf_header;
|
||||||
elf32_region text_region;
|
elf32_region text_region;
|
||||||
elf32_region data_region;
|
elf32_region data_region;
|
||||||
uint32 mapped_delta;
|
|
||||||
|
|
||||||
FixedWidthPointer<Elf32_Sym> syms;
|
FixedWidthPointer<Elf32_Sym> syms;
|
||||||
FixedWidthPointer<Elf32_Rel> rel;
|
FixedWidthPointer<Elf32_Rel> rel;
|
||||||
@@ -65,7 +64,6 @@ struct preloaded_elf64_image : public preloaded_image {
|
|||||||
Elf64_Ehdr elf_header;
|
Elf64_Ehdr elf_header;
|
||||||
elf64_region text_region;
|
elf64_region text_region;
|
||||||
elf64_region data_region;
|
elf64_region data_region;
|
||||||
uint64 mapped_delta;
|
|
||||||
|
|
||||||
FixedWidthPointer<Elf64_Sym> syms;
|
FixedWidthPointer<Elf64_Sym> syms;
|
||||||
FixedWidthPointer<Elf64_Rel> rel;
|
FixedWidthPointer<Elf64_Rel> rel;
|
||||||
@@ -84,18 +82,8 @@ extern status_t boot_elf_resolve_symbol(preloaded_elf32_image* image,
|
|||||||
struct Elf32_Sym* symbol, Elf32_Addr* symbolAddress);
|
struct Elf32_Sym* symbol, Elf32_Addr* symbolAddress);
|
||||||
extern status_t boot_elf_resolve_symbol(preloaded_elf64_image* image,
|
extern status_t boot_elf_resolve_symbol(preloaded_elf64_image* image,
|
||||||
struct Elf64_Sym* symbol, Elf64_Addr* symbolAddress);
|
struct Elf64_Sym* symbol, Elf64_Addr* symbolAddress);
|
||||||
|
extern void boot_elf64_set_relocation(Elf64_Addr resolveAddress,
|
||||||
|
Elf64_Addr finalAddress);
|
||||||
// Helper method to set a relocation at the mapped address in the loader's
|
|
||||||
// address space.
|
|
||||||
template<typename ImageType, typename AddrType>
|
|
||||||
inline void
|
|
||||||
boot_elf_set_relocation(ImageType* image, AddrType resolveAddress,
|
|
||||||
AddrType finalAddress)
|
|
||||||
{
|
|
||||||
AddrType* dest = (AddrType*)(addr_t)(resolveAddress + image->mapped_delta);
|
|
||||||
*dest = finalAddress;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* KERNEL_BOOT_ELF_H */
|
#endif /* KERNEL_BOOT_ELF_H */
|
||||||
|
|||||||
@@ -72,13 +72,6 @@ extern size_t platform_get_user_input_text(Menu *menu, MenuItem *item,
|
|||||||
char *buffer, size_t bufferSize);
|
char *buffer, size_t bufferSize);
|
||||||
extern char* platform_debug_get_log_buffer(size_t* _size);
|
extern char* platform_debug_get_log_buffer(size_t* _size);
|
||||||
|
|
||||||
/* ELF functions */
|
|
||||||
|
|
||||||
extern status_t platform_allocate_elf_region(uint32 *_address, uint32 size,
|
|
||||||
uint8 protection, void **_mappedAddress);
|
|
||||||
extern status_t platform_allocate_elf_region(uint64 *_address, uint64 size,
|
|
||||||
uint8 protection, void **_mappedAddress);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* KERNEL_BOOT_PLATFORM_H */
|
#endif /* KERNEL_BOOT_PLATFORM_H */
|
||||||
|
|||||||
+100
-60
@@ -51,10 +51,12 @@ public:
|
|||||||
static status_t Create(int fd, preloaded_image** _image);
|
static status_t Create(int fd, preloaded_image** _image);
|
||||||
static status_t Load(int fd, preloaded_image* image);
|
static status_t Load(int fd, preloaded_image* image);
|
||||||
static status_t Relocate(preloaded_image* image);
|
static status_t Relocate(preloaded_image* image);
|
||||||
|
static status_t Resolve(ImageType* image, SymType* symbol,
|
||||||
|
AddrType* symbolAddress);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static status_t _LoadSymbolTable(int fd, ImageType* image);
|
static status_t _LoadSymbolTable(int fd, ImageType* image);
|
||||||
static status_t _ParseDynamicSection(ImageType* image, AddrType delta);
|
static status_t _ParseDynamicSection(ImageType* image);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -71,6 +73,25 @@ struct ELF32Class {
|
|||||||
typedef Elf32_Sym SymType;
|
typedef Elf32_Sym SymType;
|
||||||
typedef Elf32_Rel RelType;
|
typedef Elf32_Rel RelType;
|
||||||
typedef Elf32_Rela RelaType;
|
typedef Elf32_Rela RelaType;
|
||||||
|
|
||||||
|
static inline status_t
|
||||||
|
AllocateRegion(AddrType* _address, AddrType size, uint8 protection,
|
||||||
|
void **_mappedAddress)
|
||||||
|
{
|
||||||
|
status_t status = platform_allocate_region((void**)_address, size,
|
||||||
|
protection, false);
|
||||||
|
if (status < B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
*_mappedAddress = (void*)*_address;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void*
|
||||||
|
Map(AddrType address)
|
||||||
|
{
|
||||||
|
return (void*)address;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef ELFLoader<ELF32Class> ELF32Loader;
|
typedef ELFLoader<ELF32Class> ELF32Loader;
|
||||||
@@ -90,6 +111,31 @@ struct ELF64Class {
|
|||||||
typedef Elf64_Sym SymType;
|
typedef Elf64_Sym SymType;
|
||||||
typedef Elf64_Rel RelType;
|
typedef Elf64_Rel RelType;
|
||||||
typedef Elf64_Rela RelaType;
|
typedef Elf64_Rela RelaType;
|
||||||
|
|
||||||
|
static inline status_t
|
||||||
|
AllocateRegion(AddrType* _address, AddrType size, uint8 protection,
|
||||||
|
void **_mappedAddress)
|
||||||
|
{
|
||||||
|
// Assume the real 64-bit base address is KERNEL_BASE_64BIT and the
|
||||||
|
// mappings in the loader address space are at KERNEL_BASE.
|
||||||
|
|
||||||
|
void* address = (void*)(addr_t)(*_address & 0xffffffff);
|
||||||
|
|
||||||
|
status_t status = platform_allocate_region(&address, size, protection,
|
||||||
|
false);
|
||||||
|
if (status < B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
*_mappedAddress = address;
|
||||||
|
*_address = (AddrType)(addr_t)address + KERNEL_BASE_64BIT - KERNEL_BASE;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void*
|
||||||
|
Map(AddrType address)
|
||||||
|
{
|
||||||
|
return (void*)(addr_t)(address - KERNEL_BASE_64BIT + KERNEL_BASE);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef ELFLoader<ELF64Class> ELF64Loader;
|
typedef ELFLoader<ELF64Class> ELF64Loader;
|
||||||
@@ -227,15 +273,15 @@ ELFLoader<Class>::Load(int fd, preloaded_image* _image)
|
|||||||
// inbetween.
|
// inbetween.
|
||||||
totalSize = secondRegion->start + secondRegion->size - firstRegion->start;
|
totalSize = secondRegion->start + secondRegion->size - firstRegion->start;
|
||||||
if (totalSize > image->text_region.size + image->data_region.size
|
if (totalSize > image->text_region.size + image->data_region.size
|
||||||
+ 0x200000) {
|
+ 8 * 1024) {
|
||||||
status = B_BAD_DATA;
|
status = B_BAD_DATA;
|
||||||
goto error1;
|
goto error1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The kernel and the modules are relocatable, thus
|
// The kernel and the modules are relocatable, thus AllocateRegion()
|
||||||
// platform_allocate_elf_region() can automatically allocate an address,
|
// can automatically allocate an address, but shall prefer the specified
|
||||||
// but shall prefer the specified base address.
|
// base address.
|
||||||
if (platform_allocate_elf_region(&firstRegion->start, totalSize,
|
if (Class::AllocateRegion(&firstRegion->start, totalSize,
|
||||||
B_READ_AREA | B_WRITE_AREA, &mappedRegion) < B_OK) {
|
B_READ_AREA | B_WRITE_AREA, &mappedRegion) < B_OK) {
|
||||||
status = B_NO_MEMORY;
|
status = B_NO_MEMORY;
|
||||||
goto error1;
|
goto error1;
|
||||||
@@ -254,9 +300,6 @@ ELFLoader<Class>::Load(int fd, preloaded_image* _image)
|
|||||||
(uint64)image->data_region.start, (uint64)image->data_region.size,
|
(uint64)image->data_region.start, (uint64)image->data_region.size,
|
||||||
(int64)(AddrType)image->data_region.delta));
|
(int64)(AddrType)image->data_region.delta));
|
||||||
|
|
||||||
// Calculate the delta from a real load address to the mapped address
|
|
||||||
image->mapped_delta = (AddrType)(addr_t)mappedRegion - firstRegion->start;
|
|
||||||
|
|
||||||
// load program data
|
// load program data
|
||||||
|
|
||||||
for (int32 i = 0; i < elfHeader.e_phnum; i++) {
|
for (int32 i = 0; i < elfHeader.e_phnum; i++) {
|
||||||
@@ -273,14 +316,11 @@ ELFLoader<Class>::Load(int fd, preloaded_image* _image)
|
|||||||
else
|
else
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Calculate where to load the data to.
|
TRACE(("load segment %ld (%llu bytes) mapped at %p...\n", i,
|
||||||
addr_t dest = region->start + image->mapped_delta;
|
(uint64)header.p_filesz, Class::Map(region->start)));
|
||||||
|
|
||||||
TRACE(("load segment %ld (%llu bytes) mapped at 0x%lx...\n", i,
|
|
||||||
(uint64)header.p_filesz, dest));
|
|
||||||
|
|
||||||
length = read_pos(fd, header.p_offset,
|
length = read_pos(fd, header.p_offset,
|
||||||
(void*)(dest + (header.p_vaddr % B_PAGE_SIZE)),
|
Class::Map(region->start + (header.p_vaddr % B_PAGE_SIZE)),
|
||||||
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;
|
||||||
@@ -293,7 +333,7 @@ ELFLoader<Class>::Load(int fd, preloaded_image* _image)
|
|||||||
|
|
||||||
uint32 offset = (header.p_vaddr % B_PAGE_SIZE) + header.p_filesz;
|
uint32 offset = (header.p_vaddr % B_PAGE_SIZE) + header.p_filesz;
|
||||||
if (offset < region->size)
|
if (offset < region->size)
|
||||||
memset((void*)(dest + offset), 0, region->size - offset);
|
memset(Class::Map(region->start + offset), 0, region->size - offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
// offset dynamic section, and program entry addresses by the delta of the
|
// offset dynamic section, and program entry addresses by the delta of the
|
||||||
@@ -329,9 +369,7 @@ ELFLoader<Class>::Relocate(preloaded_image* _image)
|
|||||||
{
|
{
|
||||||
ImageType* image = static_cast<ImageType*>(_image);
|
ImageType* image = static_cast<ImageType*>(_image);
|
||||||
|
|
||||||
// Pull information out of the dynamic section. First pass through we set
|
status_t status = _ParseDynamicSection(image);
|
||||||
// the addresses we want in our address space.
|
|
||||||
status_t status = _ParseDynamicSection(image, image->mapped_delta);
|
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
@@ -373,13 +411,33 @@ ELFLoader<Class>::Relocate(preloaded_image* _image)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make a second pass through the dynamic section, storing the correct
|
|
||||||
// virtual addresses for the kernel.
|
|
||||||
_ParseDynamicSection(image, 0);
|
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Class>
|
||||||
|
/*static*/ status_t
|
||||||
|
ELFLoader<Class>::Resolve(ImageType* image, SymType* symbol,
|
||||||
|
AddrType* symbolAddress)
|
||||||
|
{
|
||||||
|
switch (symbol->st_shndx) {
|
||||||
|
case SHN_UNDEF:
|
||||||
|
// Since we do that only for the kernel, there shouldn't be
|
||||||
|
// undefined symbols.
|
||||||
|
return B_MISSING_SYMBOL;
|
||||||
|
case SHN_ABS:
|
||||||
|
*symbolAddress = symbol->st_value;
|
||||||
|
return B_NO_ERROR;
|
||||||
|
case SHN_COMMON:
|
||||||
|
// ToDo: finish this
|
||||||
|
TRACE(("elf_resolve_symbol: COMMON symbol, finish me!\n"));
|
||||||
|
return B_ERROR;
|
||||||
|
default:
|
||||||
|
// standard symbol
|
||||||
|
*symbolAddress = symbol->st_value + image->text_region.delta;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename Class>
|
template<typename Class>
|
||||||
/*static*/ status_t
|
/*static*/ status_t
|
||||||
@@ -487,7 +545,7 @@ error1:
|
|||||||
|
|
||||||
template<typename Class>
|
template<typename Class>
|
||||||
/*static*/ status_t
|
/*static*/ status_t
|
||||||
ELFLoader<Class>::_ParseDynamicSection(ImageType* image, AddrType delta)
|
ELFLoader<Class>::_ParseDynamicSection(ImageType* image)
|
||||||
{
|
{
|
||||||
image->syms = 0;
|
image->syms = 0;
|
||||||
image->rel = 0;
|
image->rel = 0;
|
||||||
@@ -501,8 +559,7 @@ ELFLoader<Class>::_ParseDynamicSection(ImageType* image, AddrType delta)
|
|||||||
if(image->dynamic_section.start == 0)
|
if(image->dynamic_section.start == 0)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
DynType* d = (DynType*)(addr_t)(image->dynamic_section.start
|
DynType* d = (DynType*)Class::Map(image->dynamic_section.start);
|
||||||
+ image->mapped_delta);
|
|
||||||
|
|
||||||
for (int i = 0; d[i].d_tag != DT_NULL; i++) {
|
for (int i = 0; d[i].d_tag != DT_NULL; i++) {
|
||||||
switch (d[i].d_tag) {
|
switch (d[i].d_tag) {
|
||||||
@@ -510,26 +567,26 @@ ELFLoader<Class>::_ParseDynamicSection(ImageType* image, AddrType delta)
|
|||||||
case DT_STRTAB:
|
case DT_STRTAB:
|
||||||
break;
|
break;
|
||||||
case DT_SYMTAB:
|
case DT_SYMTAB:
|
||||||
image->syms = (SymType*)(d[i].d_un.d_ptr
|
image->syms = (SymType*)Class::Map(d[i].d_un.d_ptr
|
||||||
+ image->text_region.delta + delta);
|
+ image->text_region.delta);
|
||||||
break;
|
break;
|
||||||
case DT_REL:
|
case DT_REL:
|
||||||
image->rel = (RelType*)(d[i].d_un.d_ptr
|
image->rel = (RelType*)Class::Map(d[i].d_un.d_ptr
|
||||||
+ image->text_region.delta + delta);
|
+ image->text_region.delta);
|
||||||
break;
|
break;
|
||||||
case DT_RELSZ:
|
case DT_RELSZ:
|
||||||
image->rel_len = d[i].d_un.d_val;
|
image->rel_len = d[i].d_un.d_val;
|
||||||
break;
|
break;
|
||||||
case DT_RELA:
|
case DT_RELA:
|
||||||
image->rela = (RelaType*)(d[i].d_un.d_ptr
|
image->rela = (RelaType*)Class::Map(d[i].d_un.d_ptr
|
||||||
+ image->text_region.delta + delta);
|
+ image->text_region.delta);
|
||||||
break;
|
break;
|
||||||
case DT_RELASZ:
|
case DT_RELASZ:
|
||||||
image->rela_len = d[i].d_un.d_val;
|
image->rela_len = d[i].d_un.d_val;
|
||||||
break;
|
break;
|
||||||
case DT_JMPREL:
|
case DT_JMPREL:
|
||||||
image->pltrel = (RelType*)(d[i].d_un.d_ptr
|
image->pltrel = (RelType*)Class::Map(d[i].d_un.d_ptr
|
||||||
+ image->text_region.delta + delta);
|
+ image->text_region.delta);
|
||||||
break;
|
break;
|
||||||
case DT_PLTRELSZ:
|
case DT_PLTRELSZ:
|
||||||
image->pltrel_len = d[i].d_un.d_val;
|
image->pltrel_len = d[i].d_un.d_val;
|
||||||
@@ -656,35 +713,11 @@ elf_relocate_image(preloaded_image* image)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename ImageType, typename SymType, typename AddrType>
|
|
||||||
inline status_t
|
|
||||||
resolve_symbol(ImageType* image, SymType* symbol, AddrType* symbolAddress)
|
|
||||||
{
|
|
||||||
switch (symbol->st_shndx) {
|
|
||||||
case SHN_UNDEF:
|
|
||||||
// Since we do that only for the kernel, there shouldn't be
|
|
||||||
// undefined symbols.
|
|
||||||
return B_MISSING_SYMBOL;
|
|
||||||
case SHN_ABS:
|
|
||||||
*symbolAddress = symbol->st_value;
|
|
||||||
return B_NO_ERROR;
|
|
||||||
case SHN_COMMON:
|
|
||||||
// ToDo: finish this
|
|
||||||
TRACE(("elf_resolve_symbol: COMMON symbol, finish me!\n"));
|
|
||||||
return B_ERROR;
|
|
||||||
default:
|
|
||||||
// standard symbol
|
|
||||||
*symbolAddress = symbol->st_value + image->text_region.delta;
|
|
||||||
return B_NO_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
boot_elf_resolve_symbol(preloaded_elf32_image* image, struct Elf32_Sym* symbol,
|
boot_elf_resolve_symbol(preloaded_elf32_image* image, struct Elf32_Sym* symbol,
|
||||||
Elf32_Addr* symbolAddress)
|
Elf32_Addr* symbolAddress)
|
||||||
{
|
{
|
||||||
return resolve_symbol(image, symbol, symbolAddress);
|
return ELF32Loader::Resolve(image, symbol, symbolAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -693,6 +726,13 @@ status_t
|
|||||||
boot_elf_resolve_symbol(preloaded_elf64_image* image, struct Elf64_Sym* symbol,
|
boot_elf_resolve_symbol(preloaded_elf64_image* image, struct Elf64_Sym* symbol,
|
||||||
Elf64_Addr* symbolAddress)
|
Elf64_Addr* symbolAddress)
|
||||||
{
|
{
|
||||||
return resolve_symbol(image, symbol, symbolAddress);
|
return ELF64Loader::Resolve(image, symbol, symbolAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
boot_elf64_set_relocation(Elf64_Addr resolveAddress, Elf64_Addr finalAddress)
|
||||||
|
{
|
||||||
|
Elf64_Addr* dest = (Elf64_Addr*)ELF64Class::Map(resolveAddress);
|
||||||
|
*dest = finalAddress;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -662,20 +662,6 @@ platform_free_region(void *address, size_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
platform_allocate_elf_region(uint32 *_address, uint32 size, uint8 protection,
|
|
||||||
void **_mappedAddress)
|
|
||||||
{
|
|
||||||
void *address = mmu_allocate((void *)*_address, size);
|
|
||||||
if (address == NULL)
|
|
||||||
return B_NO_MEMORY;
|
|
||||||
|
|
||||||
*_address = (uint32)address;
|
|
||||||
*_mappedAddress = address;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
platform_release_heap(struct stage2_args *args, void *base)
|
platform_release_heap(struct stage2_args *args, void *base)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -666,20 +666,6 @@ platform_free_region(void *address, size_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
platform_allocate_elf_region(uint32 *_address, uint32 size, uint8 protection,
|
|
||||||
void **_mappedAddress)
|
|
||||||
{
|
|
||||||
void *address = mmu_allocate((void *)*_address, size);
|
|
||||||
if (address == NULL)
|
|
||||||
return B_NO_MEMORY;
|
|
||||||
|
|
||||||
*_address = (uint32)address;
|
|
||||||
*_mappedAddress = address;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
platform_release_heap(struct stage2_args *args, void *base)
|
platform_release_heap(struct stage2_args *args, void *base)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -769,43 +769,6 @@ platform_free_region(void *address, size_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
platform_allocate_elf_region(uint32 *_address, uint32 size, uint8 protection,
|
|
||||||
void **_mappedAddress)
|
|
||||||
{
|
|
||||||
void *address = mmu_allocate((void *)*_address, size);
|
|
||||||
if (address == NULL)
|
|
||||||
return B_NO_MEMORY;
|
|
||||||
|
|
||||||
*_address = (uint32)address;
|
|
||||||
*_mappedAddress = address;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
platform_allocate_elf_region(uint64 *_address, uint64 size, uint8 protection,
|
|
||||||
void **_mappedAddress)
|
|
||||||
{
|
|
||||||
// The 64-bit kernel is loaded to 0xFFFFFFFF80000000. You'll notice that
|
|
||||||
// the low 32 bits of this address are the same as the 32-bit KERNEL_BASE
|
|
||||||
// (0x80000000). Therefore, the way this function is implemented is to use
|
|
||||||
// mmu_allocate() and then set the upper 32 bits to all 1s. The long mode
|
|
||||||
// switch code will remap everything to the correct addresses.
|
|
||||||
|
|
||||||
void *address = mmu_allocate((void *)(addr_t)(*_address & 0xFFFFFFFF), size);
|
|
||||||
if (address == NULL)
|
|
||||||
return B_NO_MEMORY;
|
|
||||||
|
|
||||||
// This is the address that the ELF loading code will access the mapping
|
|
||||||
// through.
|
|
||||||
*_mappedAddress = address;
|
|
||||||
|
|
||||||
*_address = (uint64)(uint32)address | 0xFFFFFFFF00000000LL;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
platform_release_heap(struct stage2_args *args, void *base)
|
platform_release_heap(struct stage2_args *args, void *base)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -34,21 +34,3 @@ platform_free_region(void *address, size_t size)
|
|||||||
return arch_mmu_free(address, size);
|
return arch_mmu_free(address, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
platform_allocate_elf_region(uint32 *_address, uint32 size, uint8 protection,
|
|
||||||
void **_mappedAddress)
|
|
||||||
{
|
|
||||||
if (size == 0)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
|
|
||||||
void *address = arch_mmu_allocate((void *)*_address, size, protection,
|
|
||||||
exactAddress);
|
|
||||||
if (address == NULL)
|
|
||||||
return B_NO_MEMORY;
|
|
||||||
|
|
||||||
*_address = (uint32)address;
|
|
||||||
*_mappedAddress = address;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -34,21 +34,3 @@ platform_free_region(void *address, size_t size)
|
|||||||
return arch_mmu_free(address, size);
|
return arch_mmu_free(address, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
platform_allocate_elf_region(uint32 *_address, uint32 size, uint8 protection,
|
|
||||||
void **_mappedAddress)
|
|
||||||
{
|
|
||||||
if (size == 0)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
|
|
||||||
void *address = arch_mmu_allocate((void *)*_address, size, protection,
|
|
||||||
exactAddress);
|
|
||||||
if (address == NULL)
|
|
||||||
return B_NO_MEMORY;
|
|
||||||
|
|
||||||
*_address = (uint32)address;
|
|
||||||
*_mappedAddress = address;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -678,20 +678,6 @@ platform_free_region(void *address, size_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
platform_allocate_elf_region(uint32 *_address, uint32 size, uint8 protection,
|
|
||||||
void **_mappedAddress)
|
|
||||||
{
|
|
||||||
void *address = mmu_allocate((void *)*_address, size);
|
|
||||||
if (address == NULL)
|
|
||||||
return B_NO_MEMORY;
|
|
||||||
|
|
||||||
*_address = (uint32)address;
|
|
||||||
*_mappedAddress = address;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
platform_release_heap(struct stage2_args *args, void *base)
|
platform_release_heap(struct stage2_args *args, void *base)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -79,15 +79,6 @@ platform_free_region(void* address, size_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
platform_allocate_elf_region(uint32 *_address, uint32 size, uint8 protection,
|
|
||||||
void **_mappedAddress)
|
|
||||||
{
|
|
||||||
#warning IMPLEMENT platform_allocate_elf_region
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
platform_release_heap(struct stage2_args* args, void* base)
|
platform_release_heap(struct stage2_args* args, void* base)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -681,24 +681,6 @@ platform_free_region(void *address, size_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
platform_allocate_elf_region(uint32 *_address, uint32 size, uint8 protection,
|
|
||||||
void **_mappedAddress)
|
|
||||||
{
|
|
||||||
#ifdef __ARM__
|
|
||||||
void *address = mmu_allocate((void *)*_address, size);
|
|
||||||
if (address == NULL)
|
|
||||||
return B_NO_MEMORY;
|
|
||||||
|
|
||||||
*_address = (uint32)address;
|
|
||||||
*_mappedAddress = address;
|
|
||||||
return B_OK;
|
|
||||||
#else
|
|
||||||
return B_ERROR;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
platform_release_heap(struct stage2_args *args, void *base)
|
platform_release_heap(struct stage2_args *args, void *base)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ boot_arch_elf_relocate_rela(preloaded_elf64_image* image, Elf64_Rela* rel,
|
|||||||
return B_BAD_DATA;
|
return B_BAD_DATA;
|
||||||
}
|
}
|
||||||
#ifdef _BOOT_MODE
|
#ifdef _BOOT_MODE
|
||||||
boot_elf_set_relocation(image, relocAddr, relocValue);
|
boot_elf64_set_relocation(relocAddr, relocValue);
|
||||||
#else
|
#else
|
||||||
*(Elf64_Addr *)relocAddr = relocValue;
|
*(Elf64_Addr *)relocAddr = relocValue;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ SECTIONS
|
|||||||
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
|
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
|
||||||
|
|
||||||
/* writable data */
|
/* writable data */
|
||||||
. = ALIGN (0x200000);
|
. = ALIGN (0x1000);
|
||||||
__data_start = .;
|
__data_start = .;
|
||||||
.data : { *(.data .data.* .gnu.linkonce.d.*) }
|
.data : { *(.data .data.* .gnu.linkonce.d.*) }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user