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.
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 +}