--- xen-2.0/xen/common/elf.c.BACKUP Fri Mar 11 04:52:14 2005 +++ xen-2.0/xen/common/elf.c Thu Mar 24 14:18:54 2005 @@ -127,10 +127,15 @@ int parseelfimage(char *elfbase, dsi->use_writable_pagetables = 1; } + if ( (p = strstr(guestinfo, "BSD_SYMTAB")) != NULL ) + dsi->load_bsd_symtab = 1; + dsi->v_kernstart = kernstart; dsi->v_kernend = kernend; dsi->v_kernentry = ehdr->e_entry; + dsi->v_end = dsi->v_kernend; + return 0; } @@ -152,6 +157,100 @@ int loadelfimage(char *elfbase) memset((char *)phdr->ELF_ADDR + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz); } + + return 0; +} + +#define ELFROUND (ELFSIZE / 8) + +int loadelfsymtab(char *elfbase, int doload, struct domain_setup_info *dsi) +{ + Elf_Ehdr *ehdr = (Elf_Ehdr *)elfbase, *sym_ehdr; + Elf_Shdr *shdr; + unsigned long maxva, symva; + char *p; + int h, i; + + maxva = (dsi->v_kernend + ELFROUND - 1) & ~(ELFROUND - 1); + symva = maxva; + maxva += sizeof(int); + dsi->symtab_addr = maxva; + dsi->symtab_len = 0; + maxva += sizeof(Elf_Ehdr) + ehdr->e_shnum * sizeof(Elf_Shdr); + maxva = (maxva + ELFROUND - 1) & ~(ELFROUND - 1); + if (doload) { + p = (void *)symva; + + shdr = (Elf_Shdr *)(p + sizeof(int) + sizeof(Elf_Ehdr)); + memcpy(shdr, elfbase + ehdr->e_shoff, ehdr->e_shnum * sizeof(Elf_Shdr)); + } else { + shdr = (Elf_Shdr *)(elfbase + ehdr->e_shoff); + p = NULL; /* XXX: gcc */ + } + + for ( h = 0; h < ehdr->e_shnum; h++ ) + { + if ( shdr[h].sh_type == SHT_STRTAB ) + { + /* Look for a strtab @i linked to symtab @h. */ + for ( i = 0; i < ehdr->e_shnum; i++ ) + if ( (shdr[i].sh_type == SHT_SYMTAB) && + (shdr[i].sh_link == h) ) + break; + /* Skip symtab @h if we found no corresponding strtab @i. */ + if ( i == ehdr->e_shnum ) + { + if (doload) { + shdr[h].sh_offset = 0; + } + continue; + } + } + + if ( (shdr[h].sh_type == SHT_STRTAB) || + (shdr[h].sh_type == SHT_SYMTAB) ) + { + if (doload) { + memcpy((void *)maxva, elfbase + shdr[h].sh_offset, + shdr[h].sh_size); + + /* Mangled to be based on ELF header location. */ + shdr[h].sh_offset = maxva - dsi->symtab_addr; + + } + dsi->symtab_len += shdr[h].sh_size; + maxva += shdr[h].sh_size; + maxva = (maxva + ELFROUND - 1) & ~(ELFROUND - 1); + } + + if (doload) { + shdr[h].sh_name = 0; /* Name is NULL. */ + } + } + + if ( dsi->symtab_len == 0 ) + { + dsi->symtab_addr = 0; + goto out; + } + + if (doload) { + *(int *)p = maxva - dsi->symtab_addr; + sym_ehdr = (Elf_Ehdr *)(p + sizeof(int)); + memcpy(sym_ehdr, ehdr, sizeof(Elf_Ehdr)); + sym_ehdr->e_phoff = 0; + sym_ehdr->e_shoff = sizeof(Elf_Ehdr); + sym_ehdr->e_phentsize = 0; + sym_ehdr->e_phnum = 0; + sym_ehdr->e_shstrndx = SHN_UNDEF; + } + +#define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK) /* XXX */ + + dsi->symtab_len = maxva - dsi->symtab_addr; + dsi->v_end = round_pgup(maxva); + + out: return 0; } --- xen-2.0/xen/arch/x86/domain.c.BACKUP Fri Mar 11 04:52:13 2005 +++ xen-2.0/xen/arch/x86/domain.c Thu Mar 24 15:16:14 2005 @@ -113,7 +113,7 @@ static inline void kb_wait(void) } -void machine_restart(char * __unused) +void machine_restart(char *unused) { #ifdef CONFIG_SMP int cpuid; @@ -663,6 +663,9 @@ int construct_dom0(struct domain *p, if ( rc != 0 ) return rc; + if (dsi.load_bsd_symtab) + loadelfsymtab(image_start, 0, &dsi); + /* Set up domain options */ if ( dsi.use_writable_pagetables ) vm_assist(p, VMASST_CMD_enable, VMASST_TYPE_writable_pagetables); @@ -680,7 +683,7 @@ int construct_dom0(struct domain *p, * read-only). We have a pair of simultaneous equations in two unknowns, * which we solve by exhaustive search. */ - vinitrd_start = round_pgup(dsi.v_kernend); + vinitrd_start = round_pgup(dsi.v_end); vinitrd_end = vinitrd_start + initrd_len; vphysmap_start = round_pgup(vinitrd_end); vphysmap_end = vphysmap_start + (nr_pages * sizeof(unsigned long)); @@ -879,6 +882,9 @@ int construct_dom0(struct domain *p, /* Copy the OS image. */ (void)loadelfimage(image_start); + + if (dsi.load_bsd_symtab) + loadelfsymtab(image_start, 1, &dsi); /* Copy the initial ramdisk. */ if ( initrd_len != 0 ) --- xen-2.0/xen/include/xen/sched.h.BACKUP Fri Mar 11 04:52:12 2005 +++ xen-2.0/xen/include/xen/sched.h Thu Mar 24 13:13:18 2005 @@ -119,11 +119,16 @@ struct domain struct domain_setup_info { unsigned long v_start; + unsigned long v_end; unsigned long v_kernstart; unsigned long v_kernend; unsigned long v_kernentry; unsigned int use_writable_pagetables; + unsigned int load_bsd_symtab; + + unsigned long symtab_addr; + unsigned long symtab_len; }; #include /* for KERNEL_DS */ --- xen-2.0/xen/include/xen/elf.h.BACKUP Fri Mar 11 04:52:13 2005 +++ xen-2.0/xen/include/xen/elf.h Thu Mar 24 14:15:12 2005 @@ -526,6 +526,7 @@ typedef struct { struct domain_setup_info; extern int loadelfimage(char *); +extern int loadelfsymtab(char *, int, struct domain_setup_info *); extern int parseelfimage(char *, unsigned long, struct domain_setup_info *); #endif /* __XEN_ELF_H__ */