From 7986b7e36d3d60f19acd0f0f52d4ecc16244eaca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sat, 27 Oct 2007 12:01:52 +0000 Subject: [PATCH] Make use of the kernel's elf loader code instead of duplicating it. Add placeholder for m68k. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22748 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/boot/arch/m68k/Jamfile | 18 ++ src/system/boot/arch/ppc/Jamfile | 15 +- src/system/boot/arch/ppc/elf.cpp | 385 ------------------------------ src/system/boot/arch/x86/Jamfile | 15 +- src/system/boot/arch/x86/elf.cpp | 135 ----------- 5 files changed, 44 insertions(+), 524 deletions(-) create mode 100644 src/system/boot/arch/m68k/Jamfile delete mode 100644 src/system/boot/arch/ppc/elf.cpp delete mode 100644 src/system/boot/arch/x86/elf.cpp diff --git a/src/system/boot/arch/m68k/Jamfile b/src/system/boot/arch/m68k/Jamfile new file mode 100644 index 0000000000..c832184b8f --- /dev/null +++ b/src/system/boot/arch/m68k/Jamfile @@ -0,0 +1,18 @@ +SubDir HAIKU_TOP src system boot arch m68k ; + +{ + local defines = + _BOOT_MODE + ; + + defines = [ FDefines $(defines) ] ; + SubDirCcFlags $(defines) -Wall -Wno-multichar ; + SubDirC++Flags $(defines) -Wall -Wno-multichar -fno-rtti ; +} + +KernelMergeObject boot_arch_m68k.o : + arch_elf.cpp +; + +SEARCH on [ FGristFiles arch_elf.cpp ] + = [ FDirName $(HAIKU_TOP) src system kernel arch $(TARGET_ARCH) ] ; diff --git a/src/system/boot/arch/ppc/Jamfile b/src/system/boot/arch/ppc/Jamfile index 69ebe2f5dd..c61afd6b9d 100644 --- a/src/system/boot/arch/ppc/Jamfile +++ b/src/system/boot/arch/ppc/Jamfile @@ -1,7 +1,18 @@ SubDir HAIKU_TOP src system boot arch ppc ; -SubDirC++Flags -fno-rtti ; +{ + local defines = + _BOOT_MODE + ; + + defines = [ FDefines $(defines) ] ; + SubDirCcFlags $(defines) -Wall -Wno-multichar ; + SubDirC++Flags $(defines) -Wall -Wno-multichar -fno-rtti ; +} KernelMergeObject boot_arch_ppc.o : - elf.cpp + arch_elf.cpp ; + +SEARCH on [ FGristFiles arch_elf.cpp ] + = [ FDirName $(HAIKU_TOP) src system kernel arch $(TARGET_ARCH) ] ; diff --git a/src/system/boot/arch/ppc/elf.cpp b/src/system/boot/arch/ppc/elf.cpp deleted file mode 100644 index 446ab20286..0000000000 --- a/src/system/boot/arch/ppc/elf.cpp +++ /dev/null @@ -1,385 +0,0 @@ -/* - * Copyright 2005, Ingo Weinhold . - * All rights reserved. Distributed under the terms of the MIT License. - */ -/* -** Copyright 2002, Travis Geiselbrecht. All rights reserved. -** Distributed under the terms of the NewOS License. -*/ - -#include - -#include - -#include -#include - - -#define CHATTY 0 - - -status_t -boot_arch_elf_relocate_rel(struct preloaded_image *image, - struct Elf32_Rel *rel, int rel_len) -{ - // there are no rel entries in PPC elf - return B_NO_ERROR; -} - - -static inline void -write_word32(addr_t P, Elf32_Word value) -{ - *(Elf32_Word*)P = value; -} - - -static inline void -write_word30(addr_t P, Elf32_Word value) -{ - // bits 0:29 - *(Elf32_Word*)P = (*(Elf32_Word*)P & 0x3) | (value << 2); -} - - -static inline bool -write_low24_check(addr_t P, Elf32_Word value) -{ - // bits 6:29 - if ((value & 0x3f000000) && (~value & 0x3f800000)) - return false; - *(Elf32_Word*)P = (*(Elf32_Word*)P & 0xfc000003) - | ((value & 0x00ffffff) << 2); - return true; -} - - -static inline bool -write_low14_check(addr_t P, Elf32_Word value) -{ - // bits 16:29 - if ((value & 0x3fffc000) && (~value & 0x3fffe000)) - return false; - *(Elf32_Word*)P = (*(Elf32_Word*)P & 0xffff0003) - | ((value & 0x00003fff) << 2); - return true; -} - - -static inline void -write_half16(addr_t P, Elf32_Word value) -{ - // bits 16:29 - *(Elf32_Half*)P = (Elf32_Half)value; -} - - -static inline bool -write_half16_check(addr_t P, Elf32_Word value) -{ - // bits 16:29 - if ((value & 0xffff0000) && (~value & 0xffff8000)) - return false; - *(Elf32_Half*)P = (Elf32_Half)value; - return true; -} - - -static inline Elf32_Word -lo(Elf32_Word value) -{ - return (value & 0xffff); -} - - -static inline Elf32_Word -hi(Elf32_Word value) -{ - return ((value >> 16) & 0xffff); -} - - -static inline Elf32_Word -ha(Elf32_Word value) -{ - return (((value >> 16) + (value & 0x8000 ? 1 : 0)) & 0xffff); -} - - -status_t -boot_arch_elf_relocate_rela(struct preloaded_image *image, - struct Elf32_Rela *rel, int rel_len) -{ - int i; - struct Elf32_Sym *sym; - int vlErr; - addr_t S = 0; // symbol address - addr_t R = 0; // section relative symbol address - - addr_t G = 0; // GOT address - addr_t L = 0; // PLT address - - #define P ((addr_t)(image->text_region.delta + rel[i].r_offset)) - #define A ((addr_t)rel[i].r_addend) - #define B (image->text_region.delta) - - // TODO: Get the GOT address! - #define REQUIRE_GOT \ - if (G == 0) { \ - dprintf("arch_elf_relocate_rela(): Failed to get GOT address!\n"); \ - return B_ERROR; \ - } - - // TODO: Get the PLT address! - #define REQUIRE_PLT \ - if (L == 0) { \ - dprintf("arch_elf_relocate_rela(): Failed to get PLT address!\n"); \ - return B_ERROR; \ - } - - for (i = 0; i * (int)sizeof(struct Elf32_Rela) < rel_len; i++) { -#if CHATTY - dprintf("looking at rel type %d, offset 0x%lx, sym 0x%lx, addend 0x%lx\n", - ELF32_R_TYPE(rel[i].r_info), rel[i].r_offset, ELF32_R_SYM(rel[i].r_info), rel[i].r_addend); -#endif - switch (ELF32_R_TYPE(rel[i].r_info)) { - case R_PPC_SECTOFF: - case R_PPC_SECTOFF_LO: - case R_PPC_SECTOFF_HI: - case R_PPC_SECTOFF_HA: - dprintf("arch_elf_relocate_rela(): Getting section relative " - "symbol addresses not yet supported!\n"); - return B_ERROR; - - case R_PPC_ADDR32: - case R_PPC_ADDR24: - case R_PPC_ADDR16: - case R_PPC_ADDR16_LO: - case R_PPC_ADDR16_HI: - case R_PPC_ADDR16_HA: - case R_PPC_ADDR14: - case R_PPC_ADDR14_BRTAKEN: - case R_PPC_ADDR14_BRNTAKEN: - case R_PPC_REL24: - case R_PPC_REL14: - case R_PPC_REL14_BRTAKEN: - case R_PPC_REL14_BRNTAKEN: - case R_PPC_GLOB_DAT: - case R_PPC_UADDR32: - case R_PPC_UADDR16: - case R_PPC_REL32: - case R_PPC_SDAREL16: - case R_PPC_ADDR30: - case R_PPC_JMP_SLOT: - sym = SYMBOL(image, ELF32_R_SYM(rel[i].r_info)); - - vlErr = boot_elf_resolve_symbol(image, sym, &S); - if (vlErr < 0) { - dprintf("boot_arch_elf_relocate_rela(): Failed to relocate " - "entry index %d, rel type %d, offset 0x%lx, sym 0x%lx, " - "addend 0x%lx\n", i, ELF32_R_TYPE(rel[i].r_info), - rel[i].r_offset, ELF32_R_SYM(rel[i].r_info), - rel[i].r_addend); - return vlErr; - } - break; - } - - switch (ELF32_R_TYPE(rel[i].r_info)) { - case R_PPC_NONE: - break; - - case R_PPC_COPY: - // TODO: Implement! - dprintf("arch_elf_relocate_rela(): R_PPC_COPY not yet " - "supported!\n"); - return B_ERROR; - - case R_PPC_ADDR32: - case R_PPC_GLOB_DAT: - case R_PPC_UADDR32: - write_word32(P, S + A); - break; - - case R_PPC_ADDR24: - if (write_low24_check(P, (S + A) >> 2)) - break; -dprintf("R_PPC_ADDR24 overflow\n"); - return B_BAD_DATA; - - case R_PPC_ADDR16: - case R_PPC_UADDR16: - if (write_half16_check(P, S + A)) - break; -dprintf("R_PPC_ADDR16 overflow\n"); - return B_BAD_DATA; - - case R_PPC_ADDR16_LO: - write_half16(P, lo(S + A)); - break; - - case R_PPC_ADDR16_HI: - write_half16(P, hi(S + A)); - break; - - case R_PPC_ADDR16_HA: - write_half16(P, ha(S + A)); - break; - - case R_PPC_ADDR14: - case R_PPC_ADDR14_BRTAKEN: - case R_PPC_ADDR14_BRNTAKEN: - if (write_low14_check(P, (S + A) >> 2)) - break; -dprintf("R_PPC_ADDR14 overflow\n"); - return B_BAD_DATA; - - case R_PPC_REL24: - if (write_low24_check(P, (S + A - P) >> 2)) - break; -dprintf("R_PPC_REL24 overflow: 0x%lx\n", (S + A - P) >> 2); - return B_BAD_DATA; - - case R_PPC_REL14: - case R_PPC_REL14_BRTAKEN: - case R_PPC_REL14_BRNTAKEN: - if (write_low14_check(P, (S + A - P) >> 2)) - break; -dprintf("R_PPC_REL14 overflow\n"); - return B_BAD_DATA; - - case R_PPC_GOT16: - REQUIRE_GOT; - if (write_half16_check(P, G + A)) - break; -dprintf("R_PPC_GOT16 overflow\n"); - return B_BAD_DATA; - - case R_PPC_GOT16_LO: - REQUIRE_GOT; - write_half16(P, lo(G + A)); - break; - - case R_PPC_GOT16_HI: - REQUIRE_GOT; - write_half16(P, hi(G + A)); - break; - - case R_PPC_GOT16_HA: - REQUIRE_GOT; - write_half16(P, ha(G + A)); - break; - - case R_PPC_JMP_SLOT: - { - // If the relative offset is small enough, we fabricate a - // relative branch instruction ("b "). - addr_t jumpOffset = S - P; - if ((jumpOffset & 0xfc000000) != 0 - && (~jumpOffset & 0xfe000000) != 0) { - // Offset > 24 bit. - // TODO: Implement! - // See System V PPC ABI supplement, p. 5-6! - dprintf("arch_elf_relocate_rela(): R_PPC_JMP_SLOT: " - "Offsets > 24 bit currently not supported!\n"); -dprintf("jumpOffset: %p\n", (void*)jumpOffset); - return B_ERROR; - } else { - // Offset <= 24 bit - // 0:5 opcode (= 18), 6:29 address, 30 AA, 31 LK - // "b" instruction: opcode = 18, AA = 0, LK = 0 - // address: 24 high-order bits of 26 bit offset - *(uint32*)P = 0x48000000 | ((jumpOffset) & 0x03fffffc); - } - break; - } - - case R_PPC_RELATIVE: - write_word32(P, B + A); - break; - - case R_PPC_LOCAL24PC: -// TODO: Implement! -// low24* -// if (write_low24_check(P, ?) -// break; -// return B_BAD_DATA; - dprintf("arch_elf_relocate_rela(): R_PPC_LOCAL24PC not yet " - "supported!\n"); - return B_ERROR; - - case R_PPC_REL32: - write_word32(P, S + A - P); - break; - - case R_PPC_PLTREL24: - REQUIRE_PLT; - if (write_low24_check(P, (L + A - P) >> 2)) - break; -dprintf("R_PPC_PLTREL24 overflow\n"); - return B_BAD_DATA; - - case R_PPC_PLT32: - REQUIRE_PLT; - write_word32(P, L + A); - break; - - case R_PPC_PLTREL32: - REQUIRE_PLT; - write_word32(P, L + A - P); - break; - - case R_PPC_PLT16_LO: - REQUIRE_PLT; - write_half16(P, lo(L + A)); - break; - - case R_PPC_PLT16_HI: - REQUIRE_PLT; - write_half16(P, hi(L + A)); - break; - - case R_PPC_PLT16_HA: - write_half16(P, ha(L + A)); - break; - - case R_PPC_SDAREL16: -// TODO: Implement! -// if (write_half16_check(P, S + A - _SDA_BASE_)) -// break; -// return B_BAD_DATA; - dprintf("arch_elf_relocate_rela(): R_PPC_SDAREL16 not yet " - "supported!\n"); - return B_ERROR; - - case R_PPC_SECTOFF: - if (write_half16_check(P, R + A)) - break; -dprintf("R_PPC_SECTOFF overflow\n"); - return B_BAD_DATA; - - case R_PPC_SECTOFF_LO: - write_half16(P, lo(R + A)); - break; - - case R_PPC_SECTOFF_HI: - write_half16(P, hi(R + A)); - break; - - case R_PPC_SECTOFF_HA: - write_half16(P, ha(R + A)); - break; - - case R_PPC_ADDR30: - write_word30(P, (S + A - P) >> 2); - break; - - default: - dprintf("arch_elf_relocate_rela: unhandled relocation type %d\n", ELF32_R_TYPE(rel[i].r_info)); - return B_ERROR; - } - } - - return B_NO_ERROR; -} - diff --git a/src/system/boot/arch/x86/Jamfile b/src/system/boot/arch/x86/Jamfile index 5afcfbffc3..eda7fd439f 100644 --- a/src/system/boot/arch/x86/Jamfile +++ b/src/system/boot/arch/x86/Jamfile @@ -1,7 +1,18 @@ SubDir HAIKU_TOP src system boot arch x86 ; -SubDirC++Flags -fno-rtti ; +{ + local defines = + _BOOT_MODE + ; + + defines = [ FDefines $(defines) ] ; + SubDirCcFlags $(defines) -Wall -Wno-multichar ; + SubDirC++Flags $(defines) -Wall -Wno-multichar -fno-rtti ; +} KernelMergeObject boot_arch_x86.o : - elf.cpp + arch_elf.c ; + +SEARCH on [ FGristFiles arch_elf.c ] + = [ FDirName $(HAIKU_TOP) src system kernel arch $(TARGET_ARCH) ] ; diff --git a/src/system/boot/arch/x86/elf.cpp b/src/system/boot/arch/x86/elf.cpp deleted file mode 100644 index 1c03982ef9..0000000000 --- a/src/system/boot/arch/x86/elf.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/* -** Copyright 2002, Travis Geiselbrecht. All rights reserved. -** Distributed under the terms of the NewOS License. -*/ - - -#include - -#include - -#include -#include - - -//#define TRACE_ARCH_ELF -#ifdef TRACE_ARCH_ELF -# define TRACE(x) dprintf x -#else -# define TRACE(x) ; -#endif - - -#ifdef TRACE_ARCH_ELF -static const char *kRelocations[] = { - "R_386_NONE", - "R_386_32", /* add symbol value */ - "R_386_PC32", /* add PC relative symbol value */ - "R_386_GOT32", /* add PC relative GOT offset */ - "R_386_PLT32", /* add PC relative PLT offset */ - "R_386_COPY", /* copy data from shared object */ - "R_386_GLOB_DAT", /* set GOT entry to data address */ - "R_386_JMP_SLOT", /* set GOT entry to code address */ - "R_386_RELATIVE", /* add load address of shared object */ - "R_386_GOTOFF", /* add GOT relative symbol address */ - "R_386_GOTPC", /* add PC relative GOT table address */ -}; -#endif - - -status_t -boot_arch_elf_relocate_rel(struct preloaded_image *image, - struct Elf32_Rel *rel, int rel_len) -{ - struct Elf32_Sym *sym; - addr_t S; - addr_t A; - addr_t P; - addr_t final_val; - int i; - - S = A = P = 0; - - for (i = 0; i * (int)sizeof(struct Elf32_Rel) < rel_len; i++) { - TRACE(("looking at rel type %s, offset 0x%lx\n", kRelocations[ELF32_R_TYPE(rel[i].r_info)], rel[i].r_offset)); - - // calc S - switch (ELF32_R_TYPE(rel[i].r_info)) { - case R_386_32: - case R_386_PC32: - case R_386_GLOB_DAT: - case R_386_JMP_SLOT: - case R_386_GOTOFF: - { - int vlErr; - - sym = SYMBOL(image, ELF32_R_SYM(rel[i].r_info)); - - vlErr = boot_elf_resolve_symbol(image, sym, &S); - if (vlErr < 0) - return vlErr; - TRACE(("S %p (%s)\n", (void *)S, SYMNAME(image, sym))); - } - } - // calc A - switch (ELF32_R_TYPE(rel[i].r_info)) { - case R_386_32: - case R_386_PC32: - case R_386_GOT32: - case R_386_PLT32: - case R_386_RELATIVE: - case R_386_GOTOFF: - case R_386_GOTPC: - A = *(addr_t *)(image->text_region.delta + rel[i].r_offset); - TRACE(("A %p\n", (void *)A)); - break; - } - // calc P - switch (ELF32_R_TYPE(rel[i].r_info)) { - case R_386_PC32: - case R_386_GOT32: - case R_386_PLT32: - case R_386_GOTPC: - P = image->text_region.delta + rel[i].r_offset; - TRACE(("P %p\n", (void *)P)); - break; - } - - switch (ELF32_R_TYPE(rel[i].r_info)) { - case R_386_NONE: - continue; - case R_386_32: - final_val = S + A; - break; - case R_386_PC32: - final_val = S + A - P; - break; - case R_386_RELATIVE: - // B + A; - final_val = image->text_region.delta + A; - break; - case R_386_JMP_SLOT: - case R_386_GLOB_DAT: - final_val = S; - break; - - default: - dprintf("arch_elf_relocate_rel: unhandled relocation type %d\n", ELF32_R_TYPE(rel[i].r_info)); - return EPERM; - } - *(addr_t *)(image->text_region.delta + rel[i].r_offset) = final_val; - TRACE(("-> offset %p = %p\n", (void *)(image->text_region.delta + rel[i].r_offset), (void *)final_val)); - } - - return B_NO_ERROR; -} - - -status_t -boot_arch_elf_relocate_rela(struct preloaded_image *image, - struct Elf32_Rela *rel, int rel_len) -{ - dprintf("arch_elf_relocate_rela: not supported on x86\n"); - return B_ERROR; -} -