diff --git a/ChangeLog b/ChangeLog index 27e51cec1..351503cb9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2004-12-19 Marco Gerards + + * conf/powerpc-ieee1275.rmk (MOSTLYCLEANFILES): Remove + `symlist.c', add `grubof_symlist.c'. + (symlist.c): Variable removed. + (grubof_HEADERS): Variable added. + (grubof_symlist.c): New target. + (kernel_syms.lst): Use `grubof_HEADERS' instead of + `kernel_img_HEADERS'. + (grubof_SOURCES): Add `kern/powerpc/dl.c' and `grubof_symlist.c'. + * kern/powerpc/dl.c: New file. + * kern/powerpc/ieee1275/init.c (grub_arch_dl_check_header): + Function removed. + (grub_arch_dl_relocate_symbols): Likewise. + (grub_register_exported_symbols): Likewise. + 2004-12-13 Marco Gerards * fs/ext2.c (grub_ext2_open): Don't use data after freeing it. diff --git a/conf/powerpc-ieee1275.mk b/conf/powerpc-ieee1275.mk index e84d8487e..475b57829 100644 --- a/conf/powerpc-ieee1275.mk +++ b/conf/powerpc-ieee1275.mk @@ -6,13 +6,18 @@ COMMON_CFLAGS = -ffreestanding -msoft-float # Images. -MOSTLYCLEANFILES += symlist.c kernel_syms.lst +MOSTLYCLEANFILES += grubof_symlist.c kernel_syms.lst DEFSYMFILES += kernel_syms.lst -symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) gensymlist.sh +grubof_HEADERS = arg.h boot.h device.h disk.h dl.h elf.h env.h err.h \ + file.h fs.h kernel.h misc.h mm.h net.h rescue.h symbol.h \ + term.h types.h machine/biosdisk.h \ + partition.h pc_partition.h machine/time.h machine/ieee1275.h + +grubof_symlist.c: $(addprefix include/grub/,$(grubof_HEADERS)) gensymlist.sh sh $(srcdir)/gensymlist.sh $(filter %.h,$^) > $@ -kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) genkernsyms.sh +kernel_syms.lst: $(addprefix include/grub/,$(grubof_HEADERS)) genkernsyms.sh sh $(srcdir)/genkernsyms.sh $(filter %h,$^) > $@ # Utilities. @@ -363,11 +368,11 @@ grubof_SOURCES = boot/powerpc/ieee1275/crt0.S boot/powerpc/ieee1275/cmain.c \ partmap/apple.c kern/partition.c \ kern/env.c normal/arg.c loader/powerpc/ieee1275/linux.c \ loader/powerpc/ieee1275/linux_normal.c commands/boot.c \ - normal/powerpc/setjmp.S -CLEANFILES += grubof grubof-boot_powerpc_ieee1275_crt0.o grubof-boot_powerpc_ieee1275_cmain.o grubof-boot_powerpc_ieee1275_ieee1275.o grubof-kern_main.o grubof-kern_device.o grubof-kern_disk.o grubof-kern_dl.o grubof-kern_file.o grubof-kern_fs.o grubof-kern_err.o grubof-fs_fshelp.o grubof-kern_misc.o grubof-kern_mm.o grubof-kern_loader.o grubof-kern_rescue.o grubof-kern_term.o grubof-kern_powerpc_ieee1275_init.o grubof-term_powerpc_ieee1275_ofconsole.o grubof-kern_powerpc_ieee1275_openfw.o grubof-fs_ext2.o grubof-fs_ufs.o grubof-fs_minix.o grubof-fs_hfs.o grubof-fs_jfs.o grubof-normal_cmdline.o grubof-normal_command.o grubof-normal_main.o grubof-normal_menu.o grubof-disk_powerpc_ieee1275_ofdisk.o grubof-partmap_amiga.o grubof-partmap_pc.o grubof-partmap_apple.o grubof-kern_partition.o grubof-kern_env.o grubof-normal_arg.o grubof-loader_powerpc_ieee1275_linux.o grubof-loader_powerpc_ieee1275_linux_normal.o grubof-commands_boot.o grubof-normal_powerpc_setjmp.o -MOSTLYCLEANFILES += grubof-boot_powerpc_ieee1275_crt0.d grubof-boot_powerpc_ieee1275_cmain.d grubof-boot_powerpc_ieee1275_ieee1275.d grubof-kern_main.d grubof-kern_device.d grubof-kern_disk.d grubof-kern_dl.d grubof-kern_file.d grubof-kern_fs.d grubof-kern_err.d grubof-fs_fshelp.d grubof-kern_misc.d grubof-kern_mm.d grubof-kern_loader.d grubof-kern_rescue.d grubof-kern_term.d grubof-kern_powerpc_ieee1275_init.d grubof-term_powerpc_ieee1275_ofconsole.d grubof-kern_powerpc_ieee1275_openfw.d grubof-fs_ext2.d grubof-fs_ufs.d grubof-fs_minix.d grubof-fs_hfs.d grubof-fs_jfs.d grubof-normal_cmdline.d grubof-normal_command.d grubof-normal_main.d grubof-normal_menu.d grubof-disk_powerpc_ieee1275_ofdisk.d grubof-partmap_amiga.d grubof-partmap_pc.d grubof-partmap_apple.d grubof-kern_partition.d grubof-kern_env.d grubof-normal_arg.d grubof-loader_powerpc_ieee1275_linux.d grubof-loader_powerpc_ieee1275_linux_normal.d grubof-commands_boot.d grubof-normal_powerpc_setjmp.d + normal/powerpc/setjmp.S kern/powerpc/dl.c grubof_symlist.c +CLEANFILES += grubof grubof-boot_powerpc_ieee1275_crt0.o grubof-boot_powerpc_ieee1275_cmain.o grubof-boot_powerpc_ieee1275_ieee1275.o grubof-kern_main.o grubof-kern_device.o grubof-kern_disk.o grubof-kern_dl.o grubof-kern_file.o grubof-kern_fs.o grubof-kern_err.o grubof-fs_fshelp.o grubof-kern_misc.o grubof-kern_mm.o grubof-kern_loader.o grubof-kern_rescue.o grubof-kern_term.o grubof-kern_powerpc_ieee1275_init.o grubof-term_powerpc_ieee1275_ofconsole.o grubof-kern_powerpc_ieee1275_openfw.o grubof-fs_ext2.o grubof-fs_ufs.o grubof-fs_minix.o grubof-fs_hfs.o grubof-fs_jfs.o grubof-normal_cmdline.o grubof-normal_command.o grubof-normal_main.o grubof-normal_menu.o grubof-disk_powerpc_ieee1275_ofdisk.o grubof-partmap_amiga.o grubof-partmap_pc.o grubof-partmap_apple.o grubof-kern_partition.o grubof-kern_env.o grubof-normal_arg.o grubof-loader_powerpc_ieee1275_linux.o grubof-loader_powerpc_ieee1275_linux_normal.o grubof-commands_boot.o grubof-normal_powerpc_setjmp.o grubof-kern_powerpc_dl.o grubof-grubof_symlist.o +MOSTLYCLEANFILES += grubof-boot_powerpc_ieee1275_crt0.d grubof-boot_powerpc_ieee1275_cmain.d grubof-boot_powerpc_ieee1275_ieee1275.d grubof-kern_main.d grubof-kern_device.d grubof-kern_disk.d grubof-kern_dl.d grubof-kern_file.d grubof-kern_fs.d grubof-kern_err.d grubof-fs_fshelp.d grubof-kern_misc.d grubof-kern_mm.d grubof-kern_loader.d grubof-kern_rescue.d grubof-kern_term.d grubof-kern_powerpc_ieee1275_init.d grubof-term_powerpc_ieee1275_ofconsole.d grubof-kern_powerpc_ieee1275_openfw.d grubof-fs_ext2.d grubof-fs_ufs.d grubof-fs_minix.d grubof-fs_hfs.d grubof-fs_jfs.d grubof-normal_cmdline.d grubof-normal_command.d grubof-normal_main.d grubof-normal_menu.d grubof-disk_powerpc_ieee1275_ofdisk.d grubof-partmap_amiga.d grubof-partmap_pc.d grubof-partmap_apple.d grubof-kern_partition.d grubof-kern_env.d grubof-normal_arg.d grubof-loader_powerpc_ieee1275_linux.d grubof-loader_powerpc_ieee1275_linux_normal.d grubof-commands_boot.d grubof-normal_powerpc_setjmp.d grubof-kern_powerpc_dl.d grubof-grubof_symlist.d -grubof: grubof-boot_powerpc_ieee1275_crt0.o grubof-boot_powerpc_ieee1275_cmain.o grubof-boot_powerpc_ieee1275_ieee1275.o grubof-kern_main.o grubof-kern_device.o grubof-kern_disk.o grubof-kern_dl.o grubof-kern_file.o grubof-kern_fs.o grubof-kern_err.o grubof-fs_fshelp.o grubof-kern_misc.o grubof-kern_mm.o grubof-kern_loader.o grubof-kern_rescue.o grubof-kern_term.o grubof-kern_powerpc_ieee1275_init.o grubof-term_powerpc_ieee1275_ofconsole.o grubof-kern_powerpc_ieee1275_openfw.o grubof-fs_ext2.o grubof-fs_ufs.o grubof-fs_minix.o grubof-fs_hfs.o grubof-fs_jfs.o grubof-normal_cmdline.o grubof-normal_command.o grubof-normal_main.o grubof-normal_menu.o grubof-disk_powerpc_ieee1275_ofdisk.o grubof-partmap_amiga.o grubof-partmap_pc.o grubof-partmap_apple.o grubof-kern_partition.o grubof-kern_env.o grubof-normal_arg.o grubof-loader_powerpc_ieee1275_linux.o grubof-loader_powerpc_ieee1275_linux_normal.o grubof-commands_boot.o grubof-normal_powerpc_setjmp.o +grubof: grubof-boot_powerpc_ieee1275_crt0.o grubof-boot_powerpc_ieee1275_cmain.o grubof-boot_powerpc_ieee1275_ieee1275.o grubof-kern_main.o grubof-kern_device.o grubof-kern_disk.o grubof-kern_dl.o grubof-kern_file.o grubof-kern_fs.o grubof-kern_err.o grubof-fs_fshelp.o grubof-kern_misc.o grubof-kern_mm.o grubof-kern_loader.o grubof-kern_rescue.o grubof-kern_term.o grubof-kern_powerpc_ieee1275_init.o grubof-term_powerpc_ieee1275_ofconsole.o grubof-kern_powerpc_ieee1275_openfw.o grubof-fs_ext2.o grubof-fs_ufs.o grubof-fs_minix.o grubof-fs_hfs.o grubof-fs_jfs.o grubof-normal_cmdline.o grubof-normal_command.o grubof-normal_main.o grubof-normal_menu.o grubof-disk_powerpc_ieee1275_ofdisk.o grubof-partmap_amiga.o grubof-partmap_pc.o grubof-partmap_apple.o grubof-kern_partition.o grubof-kern_env.o grubof-normal_arg.o grubof-loader_powerpc_ieee1275_linux.o grubof-loader_powerpc_ieee1275_linux_normal.o grubof-commands_boot.o grubof-normal_powerpc_setjmp.o grubof-kern_powerpc_dl.o grubof-grubof_symlist.o $(BUILD_CC) -o $@ $^ $(BUILD_LDFLAGS) $(grubof_LDFLAGS) grubof-boot_powerpc_ieee1275_crt0.o: boot/powerpc/ieee1275/crt0.S @@ -682,6 +687,22 @@ grubof-normal_powerpc_setjmp.d: normal/powerpc/setjmp.S -include grubof-normal_powerpc_setjmp.d +grubof-kern_powerpc_dl.o: kern/powerpc/dl.c + $(BUILD_CC) -Ikern/powerpc -I$(srcdir)/kern/powerpc $(BUILD_CPPFLAGS) $(BUILD_CFLAGS) -DGRUB_UTIL=1 $(grubof_CFLAGS) -c -o $@ $< + +grubof-kern_powerpc_dl.d: kern/powerpc/dl.c + set -e; $(BUILD_CC) -Ikern/powerpc -I$(srcdir)/kern/powerpc $(BUILD_CPPFLAGS) $(BUILD_CFLAGS) -DGRUB_UTIL=1 $(grubof_CFLAGS) -M $< | sed 's,dl\.o[ :]*,grubof-kern_powerpc_dl.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@ + +-include grubof-kern_powerpc_dl.d + +grubof-grubof_symlist.o: grubof_symlist.c + $(BUILD_CC) -I. -I$(srcdir)/. $(BUILD_CPPFLAGS) $(BUILD_CFLAGS) -DGRUB_UTIL=1 $(grubof_CFLAGS) -c -o $@ $< + +grubof-grubof_symlist.d: grubof_symlist.c + set -e; $(BUILD_CC) -I. -I$(srcdir)/. $(BUILD_CPPFLAGS) $(BUILD_CFLAGS) -DGRUB_UTIL=1 $(grubof_CFLAGS) -M $< | sed 's,grubof_symlist\.o[ :]*,grubof-grubof_symlist.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@ + +-include grubof-grubof_symlist.d + grubof_HEADERS = grub/powerpc/ieee1275/ieee1275.h grubof_CFLAGS = $(COMMON_CFLAGS) -DGRUBOF grubof_ASFLAGS = $(COMMON_ASFLAGS) diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk index 6b040bd2b..2c1753719 100644 --- a/conf/powerpc-ieee1275.rmk +++ b/conf/powerpc-ieee1275.rmk @@ -6,13 +6,18 @@ COMMON_CFLAGS = -ffreestanding -msoft-float # Images. -MOSTLYCLEANFILES += symlist.c kernel_syms.lst +MOSTLYCLEANFILES += grubof_symlist.c kernel_syms.lst DEFSYMFILES += kernel_syms.lst -symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) gensymlist.sh +grubof_HEADERS = arg.h boot.h device.h disk.h dl.h elf.h env.h err.h \ + file.h fs.h kernel.h misc.h mm.h net.h rescue.h symbol.h \ + term.h types.h machine/biosdisk.h \ + partition.h pc_partition.h machine/time.h machine/ieee1275.h + +grubof_symlist.c: $(addprefix include/grub/,$(grubof_HEADERS)) gensymlist.sh sh $(srcdir)/gensymlist.sh $(filter %.h,$^) > $@ -kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) genkernsyms.sh +kernel_syms.lst: $(addprefix include/grub/,$(grubof_HEADERS)) genkernsyms.sh sh $(srcdir)/genkernsyms.sh $(filter %h,$^) > $@ # Utilities. @@ -45,7 +50,7 @@ grubof_SOURCES = boot/powerpc/ieee1275/crt0.S boot/powerpc/ieee1275/cmain.c \ partmap/apple.c kern/partition.c \ kern/env.c normal/arg.c loader/powerpc/ieee1275/linux.c \ loader/powerpc/ieee1275/linux_normal.c commands/boot.c \ - normal/powerpc/setjmp.S + normal/powerpc/setjmp.S kern/powerpc/dl.c grubof_symlist.c grubof_HEADERS = grub/powerpc/ieee1275/ieee1275.h grubof_CFLAGS = $(COMMON_CFLAGS) -DGRUBOF grubof_ASFLAGS = $(COMMON_ASFLAGS) diff --git a/kern/powerpc/dl.c b/kern/powerpc/dl.c new file mode 100644 index 000000000..92b911c42 --- /dev/null +++ b/kern/powerpc/dl.c @@ -0,0 +1,144 @@ +/* dl.c - arch-dependent part of loadable module support */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002, 2004 Free Software Foundation, Inc. + * + * GRUB is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include + +/* Check if EHDR is a valid ELF header. */ +int +grub_arch_dl_check_header (void *ehdr, unsigned size) +{ + Elf32_Ehdr *e = ehdr; + + /* Check the header size. */ + if (size < sizeof (Elf32_Ehdr)) + return 0; + + /* Check the magic numbers. */ + if (!((e->e_ident[EI_MAG0] == ELFMAG0) + && (e->e_ident[EI_MAG1] == ELFMAG1) + && (e->e_ident[EI_MAG2] == ELFMAG2) + && (e->e_ident[EI_MAG3] == ELFMAG3) + && (e->e_ident[EI_CLASS] == ELFCLASS32) + && (e->e_ident[EI_DATA] == ELFDATA2MSB) + && (e->e_ident[EI_VERSION] == EV_CURRENT) + && (e->e_type == ET_REL) && (e->e_machine == EM_PPC) + && (e->e_version == EV_CURRENT))) + return 0; + + /* Make sure that every section is within the core. */ + if (size < e->e_shoff + e->e_shentsize * e->e_shnum) + return 0; + + return 1; +} + + +/* Relocate symbols. */ +grub_err_t +grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) +{ + Elf32_Ehdr *e = ehdr; + Elf32_Shdr *s; + Elf32_Sym *symtab; + Elf32_Word entsize; + unsigned i; + + /* Find a symbol table. */ + for (i = 0, s = (Elf32_Shdr *) ((char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (Elf32_Shdr *) ((char *) s + e->e_shentsize)) + if (s->sh_type == SHT_SYMTAB) + break; + + if (i == e->e_shnum) + return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found"); + + symtab = (Elf32_Sym *) ((char *) e + s->sh_offset); + entsize = s->sh_entsize; + + for (i = 0, s = (Elf32_Shdr *) ((char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (Elf32_Shdr *) ((char *) s + e->e_shentsize)) + if (s->sh_type == SHT_RELA) + { + grub_dl_segment_t seg; + + /* Find the target segment. */ + for (seg = mod->segment; seg; seg = seg->next) + if (seg->section == s->sh_info) + break; + + if (seg) + { + Elf32_Rela *rel, *max; + + for (rel = (Elf32_Rela *) ((char *) e + s->sh_offset), + max = rel + s->sh_size / s->sh_entsize; + rel < max; + rel++) + { + Elf32_Word *addr; + Elf32_Sym *sym; + grub_uint32_t value; + + if (seg->size < rel->r_offset) + return grub_error (GRUB_ERR_BAD_MODULE, + "reloc offset is out of the segment"); + + addr = (Elf32_Word *) ((char *) seg->addr + rel->r_offset); + sym = (Elf32_Sym *) ((char *) symtab + + entsize * ELF32_R_SYM (rel->r_info)); + + /* On the PPC the value does not have an explicit + addend, add it. */ + value = sym->st_value + rel->r_addend; + switch (ELF32_R_TYPE (rel->r_info)) + { + case R_PPC_ADDR16_LO: + *(Elf32_Half *) addr = value; + break; + + case R_PPC_REL24: + { + Elf32_Sword delta = value - (Elf32_Word) addr; + + if (delta << 6 >> 6 != delta) + return grub_error (GRUB_ERR_BAD_MODULE, "Relocation overflow"); + *addr = (*addr & 0xfc000003) | (delta & 0x3fffffc); + break; + } + + case R_PPC_ADDR16_HA: + *(Elf32_Half *) addr = (value + 0x8000) >> 16; + break; + + case R_PPC_ADDR32: + *addr = value; + break; + } + } + } + } + + return GRUB_ERR_NONE; +} diff --git a/kern/powerpc/ieee1275/init.c b/kern/powerpc/ieee1275/init.c index 5aff96e02..0161d6459 100644 --- a/kern/powerpc/ieee1275/init.c +++ b/kern/powerpc/ieee1275/init.c @@ -84,31 +84,12 @@ grub_machine_init (void) grub_ofdisk_init (); } -int -grub_arch_dl_check_header (void *ehdr __attribute ((unused)), - grub_size_t size __attribute ((unused))) -{ - return 0; -} - -grub_err_t -grub_arch_dl_relocate_symbols (grub_dl_t mod __attribute ((unused)), - void *ehdr __attribute ((unused))) -{ - return 0; -} - void grub_stop (void) { for (;;); } -void -grub_register_exported_symbols (void) -{ -} - grub_uint32_t grub_get_rtc (void) {