92f5c0435e
Apply a patch (patch-b*) to xen-3.1.0 to fix the ELF loader so that the symbol table is properly loaded for the NetBSD dom0 kernel. This is from the Xen repository, based on a patch inistally submitted by Christoph Egger to Xen (thanks !). Should fix PR port-xen/36671. While there also provide a debug Xen kernel, built with debug=1. Bump PKGREVISION.
166 lines
5.1 KiB
Text
166 lines
5.1 KiB
Text
$NetBSD: patch-bc,v 1.1 2007/08/17 17:26:05 bouyer Exp $
|
|
|
|
--- xen/common/libelf/libelf-loader.c.orig 2007-05-18 16:45:21.000000000 +0200
|
|
+++ xen/common/libelf/libelf-loader.c 2007-08-16 21:43:18.000000000 +0200
|
|
@@ -20,11 +20,15 @@
|
|
memset(elf, 0, sizeof(*elf));
|
|
elf->image = image;
|
|
elf->size = size;
|
|
- elf->ehdr = (elf_ehdr *) image;
|
|
+ elf->ehdr = (elf_ehdr *)image;
|
|
elf->class = elf->ehdr->e32.e_ident[EI_CLASS];
|
|
elf->data = elf->ehdr->e32.e_ident[EI_DATA];
|
|
|
|
- /* sanity check phdr */
|
|
+#ifdef VERBOSE
|
|
+ elf_set_verbose(elf);
|
|
+#endif
|
|
+
|
|
+ /* Sanity check phdr. */
|
|
offset = elf_uval(elf, elf->ehdr, e_phoff) +
|
|
elf_uval(elf, elf->ehdr, e_phentsize) * elf_phdr_count(elf);
|
|
if ( offset > elf->size )
|
|
@@ -34,7 +38,7 @@
|
|
return -1;
|
|
}
|
|
|
|
- /* sanity check shdr */
|
|
+ /* Sanity check shdr. */
|
|
offset = elf_uval(elf, elf->ehdr, e_shoff) +
|
|
elf_uval(elf, elf->ehdr, e_shentsize) * elf_shdr_count(elf);
|
|
if ( offset > elf->size )
|
|
@@ -44,13 +48,13 @@
|
|
return -1;
|
|
}
|
|
|
|
- /* find section string table */
|
|
+ /* Find section string table. */
|
|
section = elf_uval(elf, elf->ehdr, e_shstrndx);
|
|
shdr = elf_shdr_by_index(elf, section);
|
|
if ( shdr != NULL )
|
|
elf->sec_strtab = elf_section_start(elf, shdr);
|
|
|
|
- /* find symbol table, symbol string table */
|
|
+ /* Find symbol table and symbol string table. */
|
|
count = elf_shdr_count(elf);
|
|
for ( i = 0; i < count; i++ )
|
|
{
|
|
@@ -67,6 +71,7 @@
|
|
elf->sym_strtab = elf_section_start(elf, shdr);
|
|
break;
|
|
}
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
@@ -83,6 +88,101 @@
|
|
}
|
|
#endif
|
|
|
|
+/* Calculate the required additional kernel space for the elf image */
|
|
+void elf_parse_bsdsyms(struct elf_binary *elf, uint64_t pstart)
|
|
+{
|
|
+ uint64_t sz;
|
|
+ const elf_shdr *shdr;
|
|
+ int i, type;
|
|
+
|
|
+ if ( !elf->sym_tab )
|
|
+ return;
|
|
+
|
|
+ pstart = elf_round_up(elf, pstart);
|
|
+
|
|
+ /* Space to store the size of the elf image */
|
|
+ sz = sizeof(uint32_t);
|
|
+
|
|
+ /* Space for the elf and elf section headers */
|
|
+ sz += (elf_uval(elf, elf->ehdr, e_ehsize) +
|
|
+ elf_shdr_count(elf) * elf_uval(elf, elf->ehdr, e_shentsize));
|
|
+ sz = elf_round_up(elf, sz);
|
|
+
|
|
+ /* Space for the symbol and string tables. */
|
|
+ for ( i = 0; i < elf_shdr_count(elf); i++ )
|
|
+ {
|
|
+ shdr = elf_shdr_by_index(elf, i);
|
|
+ type = elf_uval(elf, (elf_shdr *)shdr, sh_type);
|
|
+ if ( (type == SHT_STRTAB) || (type == SHT_SYMTAB) )
|
|
+ sz = elf_round_up(elf, sz + elf_uval(elf, shdr, sh_size));
|
|
+ }
|
|
+
|
|
+ elf->bsd_symtab_pstart = pstart;
|
|
+ elf->bsd_symtab_pend = pstart + sz;
|
|
+}
|
|
+
|
|
+static void elf_load_bsdsyms(struct elf_binary *elf)
|
|
+{
|
|
+ elf_ehdr *sym_ehdr;
|
|
+ unsigned long sz;
|
|
+ char *maxva, *symbase, *symtab_addr;
|
|
+ elf_shdr *shdr;
|
|
+ int i, type;
|
|
+
|
|
+ if ( !elf->bsd_symtab_pstart )
|
|
+ return;
|
|
+
|
|
+#define elf_hdr_elm(_elf, _hdr, _elm, _val) \
|
|
+do { \
|
|
+ if ( elf_64bit(_elf) ) \
|
|
+ (_hdr)->e64._elm = _val; \
|
|
+ else \
|
|
+ (_hdr)->e32._elm = _val; \
|
|
+} while ( 0 )
|
|
+
|
|
+ symbase = elf_get_ptr(elf, elf->bsd_symtab_pstart);
|
|
+ symtab_addr = maxva = symbase + sizeof(uint32_t);
|
|
+
|
|
+ /* Set up Elf header. */
|
|
+ sym_ehdr = (elf_ehdr *)symtab_addr;
|
|
+ sz = elf_uval(elf, elf->ehdr, e_ehsize);
|
|
+ memcpy(sym_ehdr, elf->ehdr, sz);
|
|
+ maxva += sz; /* no round up */
|
|
+
|
|
+ elf_hdr_elm(elf, sym_ehdr, e_phoff, 0);
|
|
+ elf_hdr_elm(elf, sym_ehdr, e_shoff, elf_uval(elf, elf->ehdr, e_ehsize));
|
|
+ elf_hdr_elm(elf, sym_ehdr, e_phentsize, 0);
|
|
+ elf_hdr_elm(elf, sym_ehdr, e_phnum, 0);
|
|
+
|
|
+ /* Copy Elf section headers. */
|
|
+ shdr = (elf_shdr *)maxva;
|
|
+ sz = elf_shdr_count(elf) * elf_uval(elf, elf->ehdr, e_shentsize);
|
|
+ memcpy(shdr, elf->image + elf_uval(elf, elf->ehdr, e_shoff), sz);
|
|
+ maxva = (char *)(long)elf_round_up(elf, (long)maxva + sz);
|
|
+
|
|
+ for ( i = 0; i < elf_shdr_count(elf); i++ )
|
|
+ {
|
|
+ type = elf_uval(elf, shdr, sh_type);
|
|
+ if ( (type == SHT_STRTAB) || (type == SHT_SYMTAB) )
|
|
+ {
|
|
+ elf_msg(elf, "%s: shdr %i at 0x%p -> 0x%p\n", __func__, i,
|
|
+ elf_section_start(elf, shdr), maxva);
|
|
+ sz = elf_uval(elf, shdr, sh_size);
|
|
+ memcpy(maxva, elf_section_start(elf, shdr), sz);
|
|
+ /* Mangled to be based on ELF header location. */
|
|
+ elf_hdr_elm(elf, shdr, sh_offset, maxva - symtab_addr);
|
|
+ maxva = (char *)(long)elf_round_up(elf, (long)maxva + sz);
|
|
+ }
|
|
+ shdr = (elf_shdr *)((long)shdr +
|
|
+ (long)elf_uval(elf, elf->ehdr, e_shentsize));
|
|
+ }
|
|
+
|
|
+ /* Write down the actual sym size. */
|
|
+ *(uint32_t *)symbase = maxva - symtab_addr;
|
|
+
|
|
+#undef elf_ehdr_elm
|
|
+}
|
|
+
|
|
void elf_parse_binary(struct elf_binary *elf)
|
|
{
|
|
const elf_phdr *phdr;
|
|
@@ -133,6 +233,8 @@
|
|
memcpy(dest, elf->image + offset, filesz);
|
|
memset(dest + filesz, 0, memsz - filesz);
|
|
}
|
|
+
|
|
+ elf_load_bsdsyms(elf);
|
|
}
|
|
|
|
void *elf_get_ptr(struct elf_binary *elf, unsigned long addr)
|