This allows elf_load() to return back the load address where this ELF is being loaded which is necessary for multiboot2 support.
Signed-off-by: Doug Goldstein <car...@cardoe.com> --- src/arch/x86/image/elfboot.c | 4 ++-- src/arch/x86/image/multiboot.c | 2 +- src/image/elf.c | 18 +++++++++++++----- src/include/ipxe/elf.h | 5 +++-- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/arch/x86/image/elfboot.c b/src/arch/x86/image/elfboot.c index dc35689..9a47e2c 100644 --- a/src/arch/x86/image/elfboot.c +++ b/src/arch/x86/image/elfboot.c @@ -51,7 +51,7 @@ static int elfboot_exec ( struct image *image ) { int rc; /* Load the image using core ELF support */ - if ( ( rc = elf_load ( image, &entry, &max ) ) != 0 ) { + if ( ( rc = elf_load ( image, NULL, &entry, &max ) ) != 0 ) { DBGC ( image, "ELF %p could not load: %s\n", image, strerror ( rc ) ); return rc; @@ -129,7 +129,7 @@ static int elfboot_probe ( struct image *image ) { /* Check that this image uses flat physical addressing */ if ( ( rc = elf_segments ( image, &ehdr, elfboot_check_segment, - &entry, &max ) ) != 0 ) { + NULL, &entry, &max ) ) != 0 ) { DBGC ( image, "Unloadable ELF image\n" ); return rc; } diff --git a/src/arch/x86/image/multiboot.c b/src/arch/x86/image/multiboot.c index 0c85df7..c153bb7 100644 --- a/src/arch/x86/image/multiboot.c +++ b/src/arch/x86/image/multiboot.c @@ -372,7 +372,7 @@ static int multiboot_load_elf ( struct image *image, physaddr_t *entry, int rc; /* Load ELF image*/ - if ( ( rc = elf_load ( image, entry, max ) ) != 0 ) { + if ( ( rc = elf_load ( image, NULL, entry, max ) ) != 0 ) { DBGC ( image, "MULTIBOOT %p ELF image failed to load: %s\n", image, strerror ( rc ) ); return rc; diff --git a/src/image/elf.c b/src/image/elf.c index 5c2f9db..f8e3b38 100644 --- a/src/image/elf.c +++ b/src/image/elf.c @@ -85,7 +85,7 @@ static int elf_load_segment ( struct image *image, Elf_Phdr *phdr, static int elf_segment ( struct image *image, Elf_Ehdr *ehdr, Elf_Phdr *phdr, int ( * process ) ( struct image *image, Elf_Phdr *phdr, physaddr_t dest ), - physaddr_t *entry, physaddr_t *max ) { + physaddr_t *load, physaddr_t *entry, physaddr_t *max ) { physaddr_t dest; physaddr_t end; unsigned long e_offset; @@ -123,6 +123,10 @@ static int elf_segment ( struct image *image, Elf_Ehdr *ehdr, Elf_Phdr *phdr, if ( ( rc = process ( image, phdr, dest ) ) != 0 ) return rc; + /* Set the load address if it hadn't been set yet */ + if ( load && *load == 0 ) + *load = dest; + /* Set execution address, if it lies within this segment */ if ( ( e_offset = ( ehdr->e_entry - dest ) ) < phdr->p_filesz ) { *entry = ehdr->e_entry; @@ -154,7 +158,7 @@ static int elf_segment ( struct image *image, Elf_Ehdr *ehdr, Elf_Phdr *phdr, int elf_segments ( struct image *image, Elf_Ehdr *ehdr, int ( * process ) ( struct image *image, Elf_Phdr *phdr, physaddr_t dest ), - physaddr_t *entry, physaddr_t *max ) { + physaddr_t *load, physaddr_t *entry, physaddr_t *max ) { Elf_Phdr phdr; Elf_Off phoff; unsigned int phnum; @@ -166,6 +170,10 @@ int elf_segments ( struct image *image, Elf_Ehdr *ehdr, /* Invalidate entry point */ *entry = 0; + /* Invalidate load address */ + if ( load ) + *load = 0; + /* Read and process ELF program headers */ for ( phoff = ehdr->e_phoff , phnum = ehdr->e_phnum ; phnum ; phoff += ehdr->e_phentsize, phnum-- ) { @@ -176,7 +184,7 @@ int elf_segments ( struct image *image, Elf_Ehdr *ehdr, } copy_from_user ( &phdr, image->data, phoff, sizeof ( phdr ) ); if ( ( rc = elf_segment ( image, ehdr, &phdr, process, - entry, max ) ) != 0 ) + load, entry, max ) ) != 0 ) return rc; } @@ -198,7 +206,7 @@ int elf_segments ( struct image *image, Elf_Ehdr *ehdr, * @ret max Maximum used address * @ret rc Return status code */ -int elf_load ( struct image *image, physaddr_t *entry, physaddr_t *max ) { +int elf_load ( struct image *image, physaddr_t *load, physaddr_t *entry, physaddr_t *max ) { static const uint8_t e_ident[] = { [EI_MAG0] = ELFMAG0, [EI_MAG1] = ELFMAG1, @@ -219,7 +227,7 @@ int elf_load ( struct image *image, physaddr_t *entry, physaddr_t *max ) { /* Load ELF segments into memory */ if ( ( rc = elf_segments ( image, &ehdr, elf_load_segment, - entry, max ) ) != 0 ) + load, entry, max ) ) != 0 ) return rc; return 0; diff --git a/src/include/ipxe/elf.h b/src/include/ipxe/elf.h index 033c3f7..4d511de 100644 --- a/src/include/ipxe/elf.h +++ b/src/include/ipxe/elf.h @@ -22,7 +22,8 @@ typedef Elf32_Off Elf_Off; extern int elf_segments ( struct image *image, Elf_Ehdr *ehdr, int ( * process ) ( struct image *image, Elf_Phdr *phdr, physaddr_t dest ), - physaddr_t *entry, physaddr_t *max ); -extern int elf_load ( struct image *image, physaddr_t *entry, physaddr_t *max ); + physaddr_t *load, physaddr_t *entry, physaddr_t *max ); +extern int elf_load ( struct image *image, physaddr_t *load, + physaddr_t *entry, physaddr_t *max ); #endif /* _IPXE_ELF_H */ -- git-series 0.9.1 _______________________________________________ ipxe-devel mailing list ipxe-devel@lists.ipxe.org https://lists.ipxe.org/mailman/listinfo.cgi/ipxe-devel