[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