mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
firmware should always have been -ffreestanding, as it doesn't execute in the host environment. -ffreestanding implies -fno-builtin, so replace the option. inttypes.h isn't a freestanding header, but the 32bitbios_support.c only wants the stdint.h types so switch to the more appropriate include. This removes the build time dependency on a 32bit libc just to compile the hvmloader and friends. Update README and the TravisCI configuration. Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> Reviewed-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Ian Jackson <iwj@xenproject.org> Release-Acked-by: Ian Jackson <iwj@xenproject.org>
157 lines
4.5 KiB
C
157 lines
4.5 KiB
C
/*
|
|
* 32bitbios_support.c - relocation of 32bit BIOS implementation
|
|
*
|
|
* Stefan Berger, stefanb@us.ibm.com
|
|
* Copyright (c) 2006, International Business Machines Corporation.
|
|
*
|
|
* Keir Fraser, keir@xensource.com
|
|
* Copyright (c) 2007, XenSource Inc.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms and conditions of the GNU General Public License,
|
|
* version 2, as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
* more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along with
|
|
* this program; If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <stdint.h>
|
|
#include <xen/libelf/elfstructs.h>
|
|
|
|
#include "util.h"
|
|
#include "config.h"
|
|
|
|
#include "../rombios/32bit/32bitbios_flat.h"
|
|
|
|
static uint32_t relocate_32bitbios(char *elfarray, uint32_t elfarraysize)
|
|
{
|
|
Elf32_Ehdr *ehdr = (Elf32_Ehdr *)elfarray;
|
|
Elf32_Shdr *shdr = (Elf32_Shdr *)&elfarray[ehdr->e_shoff];
|
|
uint32_t reloc_off, reloc_size;
|
|
char *highbiosarea;
|
|
int i;
|
|
|
|
/*
|
|
* Step 1. General elf cleanup, and compute total relocation size.
|
|
*/
|
|
reloc_off = 0;
|
|
for ( i = 0; i < ehdr->e_shnum; i++ )
|
|
{
|
|
/* By default all section data points into elf image data array. */
|
|
shdr[i].sh_addr = (Elf32_Addr)&elfarray[shdr[i].sh_offset];
|
|
|
|
/* Fix up a corner case of address alignment. */
|
|
if ( shdr[i].sh_addralign == 0 )
|
|
shdr[i].sh_addralign = 1;
|
|
|
|
/* Any section which contains run-time data must be relocated. */
|
|
if ( shdr[i].sh_flags & SHF_ALLOC )
|
|
{
|
|
uint32_t mask = shdr[i].sh_addralign - 1;
|
|
reloc_off = (reloc_off + mask) & ~mask;
|
|
reloc_off += shdr[i].sh_size;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Step 2. Now we know the relocation size, allocate a chunk of high mem.
|
|
*/
|
|
reloc_size = reloc_off;
|
|
printf("%d bytes of ROMBIOS high-memory extensions:\n", reloc_size);
|
|
highbiosarea = mem_alloc(reloc_size, 1024);
|
|
BUG_ON(highbiosarea == NULL);
|
|
printf(" Relocating to 0x%x-0x%x ... ",
|
|
(uint32_t)&highbiosarea[0],
|
|
(uint32_t)&highbiosarea[reloc_size]);
|
|
|
|
/*
|
|
* Step 3. Copy run-time data into the newly-allocated high-memory chunk.
|
|
*/
|
|
reloc_off = 0;
|
|
for ( i = 0; i < ehdr->e_shnum; i++ )
|
|
{
|
|
uint32_t mask = shdr[i].sh_addralign - 1;
|
|
|
|
/* Nothing to do for non-run-time sections. */
|
|
if ( !(shdr[i].sh_flags & SHF_ALLOC) )
|
|
continue;
|
|
|
|
/* Copy from old location. */
|
|
reloc_off = (reloc_off + mask) & ~mask;
|
|
if ( shdr[i].sh_type == SHT_NOBITS )
|
|
memset(&highbiosarea[reloc_off], 0, shdr[i].sh_size);
|
|
else
|
|
memcpy(&highbiosarea[reloc_off], (void *)shdr[i].sh_addr,
|
|
shdr[i].sh_size);
|
|
|
|
/* Update address to new location. */
|
|
shdr[i].sh_addr = (Elf32_Addr)&highbiosarea[reloc_off];
|
|
reloc_off += shdr[i].sh_size;
|
|
}
|
|
BUG_ON(reloc_off != reloc_size);
|
|
|
|
/*
|
|
* Step 4. Perform relocations in high memory.
|
|
*/
|
|
for ( i = 0; i < ehdr->e_shnum; i++ )
|
|
{
|
|
Elf32_Sym *syms, *sym;
|
|
Elf32_Rel *rels;
|
|
char *code;
|
|
uint32_t *loc, fix;
|
|
int j;
|
|
|
|
if ( shdr[i].sh_type == SHT_RELA )
|
|
printf("Unsupported section type SHT_RELA\n");
|
|
|
|
if ( shdr[i].sh_type != SHT_REL )
|
|
continue;
|
|
|
|
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++ )
|
|
{
|
|
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) )
|
|
{
|
|
case R_386_PC32:
|
|
*loc += fix - (uint32_t)loc;
|
|
break;
|
|
|
|
case R_386_32:
|
|
*loc += fix;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
printf("done\n");
|
|
|
|
return (uint32_t)highbiosarea;
|
|
}
|
|
|
|
uint32_t rombios_highbios_setup(void)
|
|
{
|
|
return relocate_32bitbios((char *)highbios_array, sizeof(highbios_array));
|
|
}
|
|
|
|
/*
|
|
* Local variables:
|
|
* mode: C
|
|
* c-file-style: "BSD"
|
|
* c-basic-offset: 4
|
|
* tab-width: 4
|
|
* indent-tabs-mode: nil
|
|
* End:
|
|
*/
|