ia64/xen-unstable
changeset 2450:7809f000f2f0
bitkeeper revision 1.1159.1.131 (413ddc610qK3tZi2_2-e23mt5avoNA)
Load (Net)BSD symbol table from ELF image if requested.
Load (Net)BSD symbol table from ELF image if requested.
author | cl349@freefall.cl.cam.ac.uk |
---|---|
date | Tue Sep 07 16:05:53 2004 +0000 (2004-09-07) |
parents | 875c25208085 |
children | 69045df0ee90 |
files | netbsd-2.0-xen-sparse/sys/arch/xen/i386/locore.S netbsd-2.0-xen-sparse/sys/arch/xen/i386/machdep.c tools/libxc/xc_linux_build.c |
line diff
1.1 --- a/netbsd-2.0-xen-sparse/sys/arch/xen/i386/locore.S Tue Sep 07 12:37:03 2004 +0000 1.2 +++ b/netbsd-2.0-xen-sparse/sys/arch/xen/i386/locore.S Tue Sep 07 16:05:53 2004 +0000 1.3 @@ -180,7 +180,12 @@ 1.4 * Xen guest identifier and loader selection 1.5 */ 1.6 .section __xen_guest 1.7 - .asciz "GUEST_OS=netbsd,GUEST_VER=2.0,XEN_VER=2.0,LOADER=generic" 1.8 + .ascii "GUEST_OS=netbsd,GUEST_VER=2.0,XEN_VER=2.0" 1.9 + .ascii ",LOADER=generic" 1.10 +#if (NKSYMS || defined(DDB) || defined(LKM)) && !defined(SYMTAB_SPACE) 1.11 + .ascii ",BSD_SYMTAB" 1.12 +#endif 1.13 + .byte 0 1.14 1.15 1.16 /* 1.17 @@ -189,7 +194,7 @@ 1.18 .data 1.19 1.20 .globl _C_LABEL(cpu) 1.21 - .globl _C_LABEL(esym),_C_LABEL(boothowto) 1.22 + .globl _C_LABEL(boothowto) 1.23 .globl _C_LABEL(bootinfo),_C_LABEL(atdevbase) 1.24 #ifdef COMPAT_OLDBOOT 1.25 .globl _C_LABEL(bootdev) 1.26 @@ -228,7 +233,6 @@ 1.27 1.28 _C_LABEL(cpu): .long 0 # are we 386, 386sx, or 486, 1.29 # or Pentium, or.. 1.30 -_C_LABEL(esym): .long 0 # ptr to end of syms 1.31 _C_LABEL(atdevbase): .long 0 # location of start of iomem in virtual 1.32 _C_LABEL(proc0paddr): .long 0 1.33 _C_LABEL(PTDpaddr): .long 0 # paddr of PTD, for libkvm 1.34 @@ -254,11 +258,6 @@ tmpstk: 1.35 #define _RELOC(x) ((x)) 1.36 #define RELOC(x) _RELOC(_C_LABEL(x)) 1.37 1.38 -/* XXX assym.h */ 1.39 -#define MOD_START 48 1.40 -#define MOD_LEN 56 1.41 -/* XXX assym.h */ 1.42 - 1.43 .text 1.44 .globl _C_LABEL(kernel_text) 1.45 .set _C_LABEL(kernel_text),KERNTEXTOFF 1.46 @@ -271,13 +270,6 @@ start: 1.47 1.48 movl %esi,%ebx # save start_info pointer 1.49 1.50 -#if (NKSYMS || defined(DDB) || defined(LKM)) && !defined(SYMTAB_SPACE) 1.51 - /* Save the symbol locations. */ 1.52 - movl MOD_START(%ebx),%esi 1.53 - addl MOD_LEN(%ebx),%esi 1.54 - movl %esi,RELOC(esym) 1.55 -#endif 1.56 - 1.57 /* Clear BSS first so that there are no surprises... */ 1.58 xorl %eax,%eax 1.59 movl $RELOC(__bss_start),%edi
2.1 --- a/netbsd-2.0-xen-sparse/sys/arch/xen/i386/machdep.c Tue Sep 07 12:37:03 2004 +0000 2.2 +++ b/netbsd-2.0-xen-sparse/sys/arch/xen/i386/machdep.c Tue Sep 07 16:05:53 2004 +0000 2.3 @@ -2061,7 +2061,6 @@ init386(paddr_t first_avail) 2.4 #if NKSYMS || defined(DDB) || defined(LKM) 2.5 { 2.6 extern int end; 2.7 - extern int *esym; 2.8 struct btinfo_symtab *symtab; 2.9 2.10 #ifdef DDB 2.11 @@ -2077,7 +2076,10 @@ init386(paddr_t first_avail) 2.12 (int *)symtab->esym); 2.13 } 2.14 else 2.15 - ksyms_init(*(int *)&end, ((int *)&end) + 1, esym); 2.16 + ksyms_init(*(int *)&end, ((int *)&end) + 1, 2.17 + xen_start_info.mod_start ? 2.18 + (void *)xen_start_info.mod_start : 2.19 + (void *)xen_start_info.mfn_list); 2.20 } 2.21 #endif 2.22 #ifdef DDB
3.1 --- a/tools/libxc/xc_linux_build.c Tue Sep 07 12:37:03 2004 +0000 3.2 +++ b/tools/libxc/xc_linux_build.c Tue Sep 07 16:05:53 2004 +0000 3.3 @@ -17,11 +17,16 @@ 3.4 struct domain_setup_info 3.5 { 3.6 unsigned long v_start; 3.7 + unsigned long v_end; 3.8 unsigned long v_kernstart; 3.9 unsigned long v_kernend; 3.10 unsigned long v_kernentry; 3.11 3.12 unsigned int use_writable_pagetables; 3.13 + unsigned int load_bsd_symtab; 3.14 + 3.15 + unsigned long symtab_addr; 3.16 + unsigned long symtab_len; 3.17 }; 3.18 3.19 static int parseelfimage(char *elfbase, 3.20 @@ -29,6 +34,8 @@ static int parseelfimage(char *elfbase, 3.21 struct domain_setup_info *dsi); 3.22 static int loadelfimage(char *elfbase, void *pmh, unsigned long *parray, 3.23 unsigned long vstart); 3.24 +static int loadelfsymtab(char *elfbase, void *pmh, unsigned long *parray, 3.25 + struct domain_setup_info *dsi); 3.26 3.27 static long get_tot_pages(int xc_handle, u32 domid) 3.28 { 3.29 @@ -125,6 +132,9 @@ static int setup_guestos(int xc_handle, 3.30 xc_domain_setvmassist(xc_handle, dom, VMASST_CMD_enable, 3.31 VMASST_TYPE_writable_pagetables); 3.32 3.33 + if (dsi.load_bsd_symtab) 3.34 + loadelfsymtab(image, NULL, NULL, &dsi); 3.35 + 3.36 if ( (dsi.v_start & (PAGE_SIZE-1)) != 0 ) 3.37 { 3.38 PERROR("Guest OS must load to a page boundary.\n"); 3.39 @@ -138,13 +148,13 @@ static int setup_guestos(int xc_handle, 3.40 * read-only). We have a pair of simultaneous equations in two unknowns, 3.41 * which we solve by exhaustive search. 3.42 */ 3.43 + vinitrd_start = round_pgup(dsi.v_end); 3.44 + vinitrd_end = vinitrd_start + initrd_len; 3.45 + vphysmap_start = round_pgup(vinitrd_end); 3.46 + vphysmap_end = vphysmap_start + (nr_pages * sizeof(unsigned long)); 3.47 + vpt_start = round_pgup(vphysmap_end); 3.48 for ( nr_pt_pages = 2; ; nr_pt_pages++ ) 3.49 { 3.50 - vinitrd_start = round_pgup(dsi.v_kernend); 3.51 - vinitrd_end = vinitrd_start + initrd_len; 3.52 - vphysmap_start = round_pgup(vinitrd_end); 3.53 - vphysmap_end = vphysmap_start + (nr_pages * sizeof(unsigned long)); 3.54 - vpt_start = round_pgup(vphysmap_end); 3.55 vpt_end = vpt_start + (nr_pt_pages * PAGE_SIZE); 3.56 vstartinfo_start = vpt_end; 3.57 vstartinfo_end = vstartinfo_start + PAGE_SIZE; 3.58 @@ -200,6 +210,9 @@ static int setup_guestos(int xc_handle, 3.59 3.60 loadelfimage(image, pm_handle, page_array, dsi.v_start); 3.61 3.62 + if (dsi.load_bsd_symtab) 3.63 + loadelfsymtab(image, pm_handle, page_array, &dsi); 3.64 + 3.65 /* Load the initial ramdisk image. */ 3.66 if ( initrd_len != 0 ) 3.67 { 3.68 @@ -656,10 +669,15 @@ static int parseelfimage(char *elfbase, 3.69 if ( (p = strstr(guestinfo, "PT_MODE_WRITABLE")) != NULL ) 3.70 dsi->use_writable_pagetables = 1; 3.71 3.72 + if ( (p = strstr(guestinfo, "BSD_SYMTAB")) != NULL ) 3.73 + dsi->load_bsd_symtab = 1; 3.74 + 3.75 dsi->v_kernstart = kernstart; 3.76 dsi->v_kernend = kernend; 3.77 dsi->v_kernentry = ehdr->e_entry; 3.78 3.79 + dsi->v_end = dsi->v_kernend; 3.80 + 3.81 return 0; 3.82 } 3.83 3.84 @@ -706,3 +724,114 @@ static int loadelfimage(char *elfbase, v 3.85 return 0; 3.86 } 3.87 3.88 +static void map_memcpy(unsigned long dst, char *src, unsigned long size, 3.89 + void *pmh, unsigned long *parray, unsigned long vstart) 3.90 +{ 3.91 + char *va; 3.92 + unsigned long chunksz, done, pa; 3.93 + 3.94 + for ( done = 0; done < size; done += chunksz ) 3.95 + { 3.96 + pa = dst + done - vstart; 3.97 + va = map_pfn_writeable(pmh, parray[pa>>PAGE_SHIFT]); 3.98 + chunksz = size - done; 3.99 + if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) ) 3.100 + chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1)); 3.101 + memcpy(va + (pa & (PAGE_SIZE-1)), src + done, chunksz); 3.102 + unmap_pfn(pmh, va); 3.103 + } 3.104 +} 3.105 + 3.106 +#define ELFROUND (ELFSIZE / 8) 3.107 + 3.108 +static int loadelfsymtab(char *elfbase, void *pmh, unsigned long *parray, 3.109 + struct domain_setup_info *dsi) 3.110 +{ 3.111 + Elf_Ehdr *ehdr = (Elf_Ehdr *)elfbase, *sym_ehdr; 3.112 + Elf_Shdr *shdr; 3.113 + unsigned long maxva, symva; 3.114 + char *p; 3.115 + int h, i; 3.116 + 3.117 + p = malloc(sizeof(int) + sizeof(Elf_Ehdr) + 3.118 + ehdr->e_shnum * sizeof(Elf_Shdr)); 3.119 + if (p == NULL) 3.120 + return 0; 3.121 + 3.122 + maxva = (dsi->v_kernend + ELFROUND - 1) & ~(ELFROUND - 1); 3.123 + symva = maxva; 3.124 + maxva += sizeof(int); 3.125 + dsi->symtab_addr = maxva; 3.126 + dsi->symtab_len = 0; 3.127 + maxva += sizeof(Elf_Ehdr) + ehdr->e_shnum * sizeof(Elf_Shdr); 3.128 + maxva = (maxva + ELFROUND - 1) & ~(ELFROUND - 1); 3.129 + 3.130 + shdr = (Elf_Shdr *)(p + sizeof(int) + sizeof(Elf_Ehdr)); 3.131 + memcpy(shdr, elfbase + ehdr->e_shoff, ehdr->e_shnum * sizeof(Elf_Shdr)); 3.132 + 3.133 + for ( h = 0; h < ehdr->e_shnum; h++ ) 3.134 + { 3.135 + if ( shdr[h].sh_type == SHT_STRTAB ) 3.136 + { 3.137 + /* Look for a strtab @i linked to symtab @h. */ 3.138 + for ( i = 0; i < ehdr->e_shnum; i++ ) 3.139 + if ( (shdr[i].sh_type == SHT_SYMTAB) && 3.140 + (shdr[i].sh_link == h) ) 3.141 + break; 3.142 + /* Skip symtab @h if we found no corresponding strtab @i. */ 3.143 + if ( i == ehdr->e_shnum ) 3.144 + { 3.145 + shdr[h].sh_offset = 0; 3.146 + continue; 3.147 + } 3.148 + } 3.149 + 3.150 + if ( (shdr[h].sh_type == SHT_STRTAB) || 3.151 + (shdr[h].sh_type == SHT_SYMTAB) ) 3.152 + { 3.153 + if ( pmh != NULL ) 3.154 + map_memcpy(maxva, elfbase + shdr[h].sh_offset, shdr[h].sh_size, 3.155 + pmh, parray, dsi->v_start); 3.156 + 3.157 + /* Mangled to be based on ELF header location. */ 3.158 + shdr[h].sh_offset = maxva - dsi->symtab_addr; 3.159 + 3.160 + dsi->symtab_len += shdr[h].sh_size; 3.161 + maxva += shdr[h].sh_size; 3.162 + maxva = (maxva + ELFROUND - 1) & ~(ELFROUND - 1); 3.163 + } 3.164 + 3.165 + shdr[h].sh_name = 0; /* Name is NULL. */ 3.166 + } 3.167 + 3.168 + if ( dsi->symtab_len == 0 ) 3.169 + { 3.170 + dsi->symtab_addr = 0; 3.171 + goto out; 3.172 + } 3.173 + 3.174 + if ( pmh != NULL ) { 3.175 + *(int *)p = maxva - dsi->symtab_addr; 3.176 + sym_ehdr = (Elf_Ehdr *)(p + sizeof(int)); 3.177 + memcpy(sym_ehdr, ehdr, sizeof(Elf_Ehdr)); 3.178 + sym_ehdr->e_phoff = 0; 3.179 + sym_ehdr->e_shoff = sizeof(Elf_Ehdr); 3.180 + sym_ehdr->e_phentsize = 0; 3.181 + sym_ehdr->e_phnum = 0; 3.182 + sym_ehdr->e_shstrndx = SHN_UNDEF; 3.183 + 3.184 + /* Copy total length, crafted ELF header and section header table */ 3.185 + map_memcpy(symva, p, sizeof(int) + sizeof(Elf_Ehdr) + 3.186 + ehdr->e_shnum * sizeof(Elf_Shdr), pmh, parray, 3.187 + dsi->v_start); 3.188 + } 3.189 + 3.190 + dsi->symtab_len = maxva - dsi->symtab_addr; 3.191 + dsi->v_end = round_pgup(maxva); 3.192 + 3.193 + out: 3.194 + if ( p != NULL ) 3.195 + free(p); 3.196 + 3.197 + return 0; 3.198 +}