Date: Sun, 24 Jan 2010 02:59:22 +0000 (UTC) From: Oleksandr Tymoshenko <gonzo@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r202908 - in head/sys/mips: include mips Message-ID: <201001240259.o0O2xMWb096979@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: gonzo Date: Sun Jan 24 02:59:22 2010 New Revision: 202908 URL: http://svn.freebsd.org/changeset/base/202908 Log: - Copy symbol-related tables (.symtab and .strtab) to the end of relocated kernel. We use magic number to signal kernel that symbol data is present. Modified: head/sys/mips/include/elf.h head/sys/mips/mips/elf_trampoline.c Modified: head/sys/mips/include/elf.h ============================================================================== --- head/sys/mips/include/elf.h Sun Jan 24 02:33:14 2010 (r202907) +++ head/sys/mips/include/elf.h Sun Jan 24 02:59:22 2010 (r202908) @@ -256,4 +256,9 @@ __ElfType(Auxinfo); #define ET_DYN_LOAD_ADDR 0x0120000 +/* + * Constant to mark start of symtab/strtab saved by trampoline + */ +#define SYMTAB_MAGIC 0x64656267 + #endif /* !_MACHINE_ELF_H_ */ Modified: head/sys/mips/mips/elf_trampoline.c ============================================================================== --- head/sys/mips/mips/elf_trampoline.c Sun Jan 24 02:33:14 2010 (r202907) +++ head/sys/mips/mips/elf_trampoline.c Sun Jan 24 02:59:22 2010 (r202908) @@ -96,12 +96,17 @@ load_kernel(void * kstart) #ifdef __mips_n64 Elf64_Ehdr *eh; Elf64_Phdr phdr[64] /* XXX */; + Elf64_Phdr shdr[64] /* XXX */; #else Elf32_Ehdr *eh; Elf32_Phdr phdr[64] /* XXX */; + Elf32_Shdr shdr[64] /* XXX */; #endif - int i; + int i, j; void *entry_point; + vm_offset_t lastaddr = 0; + int symtabindex = -1; + int symstrindex = -1; #ifdef __mips_n64 eh = (Elf64_Ehdr *)kstart; @@ -112,6 +117,27 @@ load_kernel(void * kstart) memcpy(phdr, (void *)(kstart + eh->e_phoff ), eh->e_phnum * sizeof(phdr[0])); + memcpy(shdr, (void *)(kstart + eh->e_shoff), + sizeof(*shdr) * eh->e_shnum); + + if (eh->e_shnum * eh->e_shentsize != 0 && eh->e_shoff != 0) { + for (i = 0; i < eh->e_shnum; i++) { + if (shdr[i].sh_type == SHT_SYMTAB) { + /* + * XXX: check if .symtab is in PT_LOAD? + */ + if (shdr[i].sh_offset != 0 && + shdr[i].sh_size != 0) { + symtabindex = i; + symstrindex = shdr[i].sh_link; + } + } + } + } + + /* + * Copy loadable segments + */ for (i = 0; i < eh->e_phnum; i++) { volatile char c; @@ -120,12 +146,44 @@ load_kernel(void * kstart) memcpy((void *)(phdr[i].p_vaddr), (void*)(kstart + phdr[i].p_offset), phdr[i].p_filesz); + /* Clean space from oversized segments, eg: bss. */ if (phdr[i].p_filesz < phdr[i].p_memsz) bzero((void *)(phdr[i].p_vaddr + phdr[i].p_filesz), phdr[i].p_memsz - phdr[i].p_filesz); + + if (lastaddr < phdr[i].p_vaddr + phdr[i].p_memsz) + lastaddr = phdr[i].p_vaddr + phdr[i].p_memsz; } + /* Now grab the symbol tables. */ + if (symtabindex >= 0 && symstrindex >= 0) { + *(Elf_Size *)lastaddr = SYMTAB_MAGIC; + lastaddr += sizeof(Elf_Size); + *(Elf_Size *)lastaddr = shdr[symtabindex].sh_size + + shdr[symstrindex].sh_size + 2*sizeof(Elf_Size); + lastaddr += sizeof(Elf_Size); + /* .symtab size */ + *(Elf_Size *)lastaddr = shdr[symtabindex].sh_size; + lastaddr += sizeof(shdr[symtabindex].sh_size); + /* .symtab data */ + memcpy((void*)lastaddr, + shdr[symtabindex].sh_offset + kstart, + shdr[symtabindex].sh_size); + lastaddr += shdr[symtabindex].sh_size; + + /* .strtab size */ + *(Elf_Size *)lastaddr = shdr[symstrindex].sh_size; + lastaddr += sizeof(shdr[symstrindex].sh_size); + + /* .strtab data */ + memcpy((void*)lastaddr, + shdr[symstrindex].sh_offset + kstart, + shdr[symstrindex].sh_size); + } else + /* Do not take any chances */ + *(Elf_Size *)lastaddr = 0; + return entry_point; }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201001240259.o0O2xMWb096979>