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

Reply via email to