bitkeeper revision 1.1159.1.131 (413ddc610qK3tZi2_2-e23mt5avoNA)

Load (Net)BSD symbol table from ELF image if requested.
This commit is contained in:
cl349@freefall.cl.cam.ac.uk committed 2004-09-07 16:05:53 +00:00
1 parent 2a23966f2b
commit f11bc5a8fc
3 files changed
+145 -22

No files matched your search

@@ -180,7 +180,12 @@
* Xen guest identifier and loader selection
*/
.section __xen_guest
.asciz "GUEST_OS=netbsd,GUEST_VER=2.0,XEN_VER=2.0,LOADER=generic"
.ascii "GUEST_OS=netbsd,GUEST_VER=2.0,XEN_VER=2.0"
.ascii ",LOADER=generic"
#if (NKSYMS || defined(DDB) || defined(LKM)) && !defined(SYMTAB_SPACE)
.ascii ",BSD_SYMTAB"
#endif
.byte 0
/*
@@ -189,7 +194,7 @@
.data
.globl _C_LABEL(cpu)
.globl _C_LABEL(esym),_C_LABEL(boothowto)
.globl _C_LABEL(boothowto)
.globl _C_LABEL(bootinfo),_C_LABEL(atdevbase)
#ifdef COMPAT_OLDBOOT
.globl _C_LABEL(bootdev)
@@ -228,7 +233,6 @@ _C_LABEL(lapic_tpr):
_C_LABEL(cpu): .long 0 # are we 386, 386sx, or 486,
# or Pentium, or..
_C_LABEL(esym): .long 0 # ptr to end of syms
_C_LABEL(atdevbase): .long 0 # location of start of iomem in virtual
_C_LABEL(proc0paddr): .long 0
_C_LABEL(PTDpaddr): .long 0 # paddr of PTD, for libkvm
@@ -254,11 +258,6 @@ tmpstk:
#define _RELOC(x) ((x))
#define RELOC(x) _RELOC(_C_LABEL(x))
/* XXX assym.h */
#define MOD_START 48
#define MOD_LEN 56
/* XXX assym.h */
.text
.globl _C_LABEL(kernel_text)
.set _C_LABEL(kernel_text),KERNTEXTOFF
@@ -271,13 +270,6 @@ start:
movl %esi,%ebx # save start_info pointer
#if (NKSYMS || defined(DDB) || defined(LKM)) && !defined(SYMTAB_SPACE)
/* Save the symbol locations. */
movl MOD_START(%ebx),%esi
addl MOD_LEN(%ebx),%esi
movl %esi,RELOC(esym)
#endif
/* Clear BSS first so that there are no surprises... */
xorl %eax,%eax
movl $RELOC(__bss_start),%edi
@@ -2061,7 +2061,6 @@ init386(paddr_t first_avail)
#if NKSYMS || defined(DDB) || defined(LKM)
{
extern int end;
extern int *esym;
struct btinfo_symtab *symtab;
#ifdef DDB
@@ -2077,7 +2076,10 @@ init386(paddr_t first_avail)
(int *)symtab->esym);
}
else
ksyms_init(*(int *)&end, ((int *)&end) + 1, esym);
ksyms_init(*(int *)&end, ((int *)&end) + 1,
xen_start_info.mod_start ?
(void *)xen_start_info.mod_start :
(void *)xen_start_info.mfn_list);
}
#endif
#ifdef DDB
+134 -5
View File
@@ -17,11 +17,16 @@
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;
};
static int parseelfimage(char *elfbase,
@@ -29,6 +34,8 @@ static int parseelfimage(char *elfbase,
struct domain_setup_info *dsi);
static int loadelfimage(char *elfbase, void *pmh, unsigned long *parray,
unsigned long vstart);
static int loadelfsymtab(char *elfbase, void *pmh, unsigned long *parray,
struct domain_setup_info *dsi);
static long get_tot_pages(int xc_handle, u32 domid)
{
@@ -125,6 +132,9 @@ static int setup_guestos(int xc_handle,
xc_domain_setvmassist(xc_handle, dom, VMASST_CMD_enable,
VMASST_TYPE_writable_pagetables);
if (dsi.load_bsd_symtab)
loadelfsymtab(image, NULL, NULL, &dsi);
if ( (dsi.v_start & (PAGE_SIZE-1)) != 0 )
{
PERROR("Guest OS must load to a page boundary.\n");
@@ -138,13 +148,13 @@ static int setup_guestos(int xc_handle,
* read-only). We have a pair of simultaneous equations in two unknowns,
* which we solve by exhaustive search.
*/
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));
vpt_start = round_pgup(vphysmap_end);
for ( nr_pt_pages = 2; ; nr_pt_pages++ )
{
vinitrd_start = round_pgup(dsi.v_kernend);
vinitrd_end = vinitrd_start + initrd_len;
vphysmap_start = round_pgup(vinitrd_end);
vphysmap_end = vphysmap_start + (nr_pages * sizeof(unsigned long));
vpt_start = round_pgup(vphysmap_end);
vpt_end = vpt_start + (nr_pt_pages * PAGE_SIZE);
vstartinfo_start = vpt_end;
vstartinfo_end = vstartinfo_start + PAGE_SIZE;
@@ -200,6 +210,9 @@ static int setup_guestos(int xc_handle,
loadelfimage(image, pm_handle, page_array, dsi.v_start);
if (dsi.load_bsd_symtab)
loadelfsymtab(image, pm_handle, page_array, &dsi);
/* Load the initial ramdisk image. */
if ( initrd_len != 0 )
{
@@ -656,10 +669,15 @@ static int parseelfimage(char *elfbase,
if ( (p = strstr(guestinfo, "PT_MODE_WRITABLE")) != NULL )
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;
}
@@ -706,3 +724,114 @@ static int loadelfimage(char *elfbase, void *pmh, unsigned long *parray,
return 0;
}
static void map_memcpy(unsigned long dst, char *src, unsigned long size,
void *pmh, unsigned long *parray, unsigned long vstart)
{
char *va;
unsigned long chunksz, done, pa;
for ( done = 0; done < size; done += chunksz )
{
pa = dst + done - vstart;
va = map_pfn_writeable(pmh, parray[pa>>PAGE_SHIFT]);
chunksz = size - done;
if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) )
chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1));
memcpy(va + (pa & (PAGE_SIZE-1)), src + done, chunksz);
unmap_pfn(pmh, va);
}
}
#define ELFROUND (ELFSIZE / 8)
static int loadelfsymtab(char *elfbase, void *pmh, unsigned long *parray,
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;
p = malloc(sizeof(int) + sizeof(Elf_Ehdr) +
ehdr->e_shnum * sizeof(Elf_Shdr));
if (p == NULL)
return 0;
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);
shdr = (Elf_Shdr *)(p + sizeof(int) + sizeof(Elf_Ehdr));
memcpy(shdr, elfbase + ehdr->e_shoff, ehdr->e_shnum * sizeof(Elf_Shdr));
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 )
{
shdr[h].sh_offset = 0;
continue;
}
}
if ( (shdr[h].sh_type == SHT_STRTAB) ||
(shdr[h].sh_type == SHT_SYMTAB) )
{
if ( pmh != NULL )
map_memcpy(maxva, elfbase + shdr[h].sh_offset, shdr[h].sh_size,
pmh, parray, dsi->v_start);
/* 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);
}
shdr[h].sh_name = 0; /* Name is NULL. */
}
if ( dsi->symtab_len == 0 )
{
dsi->symtab_addr = 0;
goto out;
}
if ( pmh != NULL ) {
*(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;
/* Copy total length, crafted ELF header and section header table */
map_memcpy(symva, p, sizeof(int) + sizeof(Elf_Ehdr) +
ehdr->e_shnum * sizeof(Elf_Shdr), pmh, parray,
dsi->v_start);
}
dsi->symtab_len = maxva - dsi->symtab_addr;
dsi->v_end = round_pgup(maxva);
out:
if ( p != NULL )
free(p);
return 0;
}
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.