[ipxe-devel] [PATCH 2/6] [image] let elf_load() provide load addr

Doug Goldstein cardoe at cardoe.com
Thu Jan 26 21:34:57 UTC 2017


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 <cardoe at 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



More information about the ipxe-devel mailing list