- 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.
This commit is contained in:
parent
6bfde02405
commit
d184a1dc59
@ -256,4 +256,9 @@ __ElfType(Auxinfo);
|
|||||||
|
|
||||||
#define ET_DYN_LOAD_ADDR 0x0120000
|
#define ET_DYN_LOAD_ADDR 0x0120000
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constant to mark start of symtab/strtab saved by trampoline
|
||||||
|
*/
|
||||||
|
#define SYMTAB_MAGIC 0x64656267
|
||||||
|
|
||||||
#endif /* !_MACHINE_ELF_H_ */
|
#endif /* !_MACHINE_ELF_H_ */
|
||||||
|
@ -96,12 +96,17 @@ load_kernel(void * kstart)
|
|||||||
#ifdef __mips_n64
|
#ifdef __mips_n64
|
||||||
Elf64_Ehdr *eh;
|
Elf64_Ehdr *eh;
|
||||||
Elf64_Phdr phdr[64] /* XXX */;
|
Elf64_Phdr phdr[64] /* XXX */;
|
||||||
|
Elf64_Phdr shdr[64] /* XXX */;
|
||||||
#else
|
#else
|
||||||
Elf32_Ehdr *eh;
|
Elf32_Ehdr *eh;
|
||||||
Elf32_Phdr phdr[64] /* XXX */;
|
Elf32_Phdr phdr[64] /* XXX */;
|
||||||
|
Elf32_Shdr shdr[64] /* XXX */;
|
||||||
#endif
|
#endif
|
||||||
int i;
|
int i, j;
|
||||||
void *entry_point;
|
void *entry_point;
|
||||||
|
vm_offset_t lastaddr = 0;
|
||||||
|
int symtabindex = -1;
|
||||||
|
int symstrindex = -1;
|
||||||
|
|
||||||
#ifdef __mips_n64
|
#ifdef __mips_n64
|
||||||
eh = (Elf64_Ehdr *)kstart;
|
eh = (Elf64_Ehdr *)kstart;
|
||||||
@ -112,6 +117,27 @@ load_kernel(void * kstart)
|
|||||||
memcpy(phdr, (void *)(kstart + eh->e_phoff ),
|
memcpy(phdr, (void *)(kstart + eh->e_phoff ),
|
||||||
eh->e_phnum * sizeof(phdr[0]));
|
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++) {
|
for (i = 0; i < eh->e_phnum; i++) {
|
||||||
volatile char c;
|
volatile char c;
|
||||||
|
|
||||||
@ -120,12 +146,44 @@ load_kernel(void * kstart)
|
|||||||
|
|
||||||
memcpy((void *)(phdr[i].p_vaddr),
|
memcpy((void *)(phdr[i].p_vaddr),
|
||||||
(void*)(kstart + phdr[i].p_offset), phdr[i].p_filesz);
|
(void*)(kstart + phdr[i].p_offset), phdr[i].p_filesz);
|
||||||
|
|
||||||
/* Clean space from oversized segments, eg: bss. */
|
/* Clean space from oversized segments, eg: bss. */
|
||||||
if (phdr[i].p_filesz < phdr[i].p_memsz)
|
if (phdr[i].p_filesz < phdr[i].p_memsz)
|
||||||
bzero((void *)(phdr[i].p_vaddr + phdr[i].p_filesz),
|
bzero((void *)(phdr[i].p_vaddr + phdr[i].p_filesz),
|
||||||
phdr[i].p_memsz - 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;
|
return entry_point;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user