aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorKeir Fraser <keir@xensource.com>2007-03-16 23:56:26 +0000
committerKeir Fraser <keir@xensource.com>2007-03-16 23:56:26 +0000
commit36200329b198717624bfa37f410e3a650168a9c7 (patch)
treebc20f58ef7c4f229f4609f37ec442b0a03a37140 /tools
parentb54ada182dafe4daf08074aa54764236d4182a11 (diff)
downloadxen-36200329b198717624bfa37f410e3a650168a9c7.tar.gz
xen-36200329b198717624bfa37f410e3a650168a9c7.tar.bz2
xen-36200329b198717624bfa37f410e3a650168a9c7.zip
hvmloader: More simplification of highmem bios relocation code.
Signed-off-by: Keir Fraser <keir@xensource.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/firmware/hvmloader/32bitbios_support.c112
-rw-r--r--tools/firmware/hvmloader/util.h2
2 files changed, 48 insertions, 66 deletions
diff --git a/tools/firmware/hvmloader/32bitbios_support.c b/tools/firmware/hvmloader/32bitbios_support.c
index e835037d96..7cb32a299d 100644
--- a/tools/firmware/hvmloader/32bitbios_support.c
+++ b/tools/firmware/hvmloader/32bitbios_support.c
@@ -31,18 +31,15 @@
#include "../rombios/32bit/jumptable.h"
/* Relocate ELF file of type ET_REL */
-static int relocate_elf(char *elfarray)
+static void relocate_elf(char *elfarray)
{
Elf32_Ehdr *ehdr = (Elf32_Ehdr *)elfarray;
Elf32_Shdr *shdr = (Elf32_Shdr *)&elfarray[ehdr->e_shoff];
- int i;
-
- if ( ehdr->e_type != ET_REL )
- {
- printf("Not a relocatable BIOS object file. Has type %d, need %d\n",
- ehdr->e_type, ET_REL);
- return -1;
- }
+ Elf32_Sym *syms, *sym;
+ Elf32_Rel *rels;
+ char *code;
+ uint32_t *loc, fix;
+ int i, j;
for ( i = 0; i < ehdr->e_shnum; i++ )
shdr[i].sh_addr = (Elf32_Addr)&elfarray[shdr[i].sh_offset];
@@ -50,43 +47,33 @@ static int relocate_elf(char *elfarray)
for ( i = 0; i < ehdr->e_shnum; i++ )
{
if ( shdr[i].sh_type == SHT_RELA )
- return -2;
+ printf("Unsupported section type SHT_RELA\n");
+
+ if ( shdr[i].sh_type != SHT_REL )
+ continue;
- if ( shdr[i].sh_type == SHT_REL )
+ syms = (Elf32_Sym *)shdr[shdr[i].sh_link].sh_addr;
+ rels = (Elf32_Rel *)shdr[i].sh_addr;
+ code = (char *)shdr[shdr[i].sh_info].sh_addr;
+
+ for ( j = 0; j < shdr[i].sh_size / sizeof(Elf32_Rel); j++ )
{
- Elf32_Shdr *targetsec = (Elf32_Shdr *)&(shdr[shdr[i].sh_info]);
- Elf32_Shdr *symtabsec = (Elf32_Shdr *)&(shdr[shdr[i].sh_link]);
- Elf32_Sym *syms = (Elf32_Sym *)symtabsec->sh_addr;
- Elf32_Rel *rels = (Elf32_Rel *)shdr[i].sh_addr;
- char *code = (char *)targetsec->sh_addr;
- int j;
-
- /* must not have been stripped */
- if ( shdr[i].sh_size == 0 )
- return -6;
-
- for ( j = 0; j < shdr[i].sh_size / sizeof(Elf32_Rel); j++ )
+ sym = &syms[ELF32_R_SYM(rels[j].r_info)];
+ loc = (uint32_t *)&code[rels[j].r_offset];
+ fix = shdr[sym->st_shndx].sh_addr + sym->st_value;
+
+ switch ( ELF32_R_TYPE(rels[j].r_info) )
{
- int idx = ELF32_R_SYM(rels[j].r_info);
- Elf32_Sym *symbol = &syms[idx];
- uint32_t *loc = (uint32_t *)&code[rels[j].r_offset];
- uint32_t fix = shdr[symbol->st_shndx].sh_addr +
- symbol->st_value;
-
- switch ( ELF32_R_TYPE(rels[j].r_info) )
- {
- case R_386_PC32:
- *loc += (fix - (uint32_t)loc);
- break;
-
- case R_386_32:
- *loc += fix;
- break;
- }
+ case R_386_PC32:
+ *loc += fix - (uint32_t)loc;
+ break;
+
+ case R_386_32:
+ *loc += fix;
+ break;
}
}
}
- return 0;
}
/* Scan the rombios for the destination of the jump table. */
@@ -97,27 +84,21 @@ static char *get_jump_table_start(void)
for ( bios_mem = (char *)ROMBIOS_BEGIN;
bios_mem != (char *)ROMBIOS_END;
bios_mem++ )
- {
- if ( strncmp(bios_mem, "___JMPT", 7) == 0 )
+ if ( !strncmp(bios_mem, "___JMPT", 7) )
return bios_mem;
- }
return NULL;
}
/* Copy relocated jumptable into the rombios. */
-static int copy_jumptable(char *elfarray)
+static void copy_jumptable(char *elfarray)
{
Elf32_Ehdr *ehdr = (Elf32_Ehdr *)elfarray;
Elf32_Shdr *shdr = (Elf32_Shdr *)&elfarray[ehdr->e_shoff];
- Elf32_Shdr *shdr_strings = (Elf32_Shdr *)&shdr[ehdr->e_shstrndx];
- char *secstrings = (char *)&elfarray[shdr_strings->sh_offset];
- uint32_t *rombiosjumptable = (uint32_t *)get_jump_table_start();
+ char *secstrings = &elfarray[shdr[ehdr->e_shstrndx].sh_offset];
+ char *jump_table = get_jump_table_start();
int i;
- if ( rombiosjumptable == NULL )
- return -3;
-
/* Find the section with the jump table and copy to lower BIOS memory. */
for ( i = 0; i < ehdr->e_shnum; i++ )
if ( !strcmp(JUMPTABLE_SECTION_NAME, secstrings + shdr[i].sh_name) )
@@ -126,38 +107,39 @@ static int copy_jumptable(char *elfarray)
if ( i == ehdr->e_shnum )
{
printf("Could not find " JUMPTABLE_SECTION_NAME " section in file.\n");
- return -4;
+ return;
}
- memcpy(rombiosjumptable, (uint32_t *)shdr[i].sh_addr, shdr[i].sh_size);
+ if ( jump_table == NULL )
+ {
+ printf("Could not find jump table in file.\n");
+ return;
+ }
- return 0;
+ memcpy(jump_table, (char *)shdr[i].sh_addr, shdr[i].sh_size);
}
-static int relocate_32bitbios(char *elfarray, uint32_t elfarraysize)
+static void relocate_32bitbios(char *elfarray, uint32_t elfarraysize)
{
uint32_t mask = (64 * 1024) - 1;
char *highbiosarea;
- int rc;
highbiosarea = (char *)(long)
e820_malloc((elfarraysize + mask) & ~mask, /* round to 64kb */
E820_RESERVED,
(uint64_t)0xffffffff);
-
if ( highbiosarea == NULL )
- return -5;
+ {
+ printf("No available memory for BIOS high memory area\n");
+ return;
+ }
memcpy(highbiosarea, elfarray, elfarraysize);
- rc = relocate_elf(highbiosarea);
- if ( rc == 0 )
- rc = copy_jumptable(highbiosarea);
-
- return rc;
+ relocate_elf(highbiosarea);
+ copy_jumptable(highbiosarea);
}
-int highbios_setup(void)
+void highbios_setup(void)
{
- return relocate_32bitbios((char *)highbios_array,
- sizeof(highbios_array));
+ relocate_32bitbios((char *)highbios_array, sizeof(highbios_array));
}
diff --git a/tools/firmware/hvmloader/util.h b/tools/firmware/hvmloader/util.h
index 5025748437..cc1f42dba9 100644
--- a/tools/firmware/hvmloader/util.h
+++ b/tools/firmware/hvmloader/util.h
@@ -88,7 +88,7 @@ uint64_t e820_malloc(uint64_t size, uint32_t type, uint64_t mask);
#define E820_MAP ((struct e820entry *)(E820_MAP_PAGE + E820_MAP_OFFSET))
/* Prepare the 32bit BIOS */
-int highbios_setup(void);
+void highbios_setup(void);
#define isdigit(c) ((c) >= '0' && (c) <= '9')