iPXE
Functions
elf.c File Reference

ELF image format. More...

#include <string.h>
#include <errno.h>
#include <elf.h>
#include <ipxe/segment.h>
#include <ipxe/image.h>
#include <ipxe/uaccess.h>
#include <ipxe/elf.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
static int elf_load_segment (struct image *image, const Elf_Phdr *phdr, physaddr_t dest)
 Load ELF segment into memory. More...
 
static int elf_segment (struct image *image, const Elf_Ehdr *ehdr, const Elf_Phdr *phdr, int(*process)(struct image *image, const Elf_Phdr *phdr, physaddr_t dest), physaddr_t *entry, physaddr_t *max)
 Process ELF segment. More...
 
int elf_segments (struct image *image, const Elf_Ehdr *ehdr, int(*process)(struct image *image, const Elf_Phdr *phdr, physaddr_t dest), physaddr_t *entry, physaddr_t *max)
 Process ELF segments. More...
 
int elf_load (struct image *image, physaddr_t *entry, physaddr_t *max)
 Load ELF image into memory. More...
 

Detailed Description

ELF image format.

A "pure" ELF image is not a bootable image. There are various bootable formats based upon ELF (e.g. Multiboot), which share common ELF-related functionality.

Definition in file elf.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ elf_load_segment()

static int elf_load_segment ( struct image image,
const Elf_Phdr phdr,
physaddr_t  dest 
)
static

Load ELF segment into memory.

Parameters
imageELF file
phdrELF program header
destDestination address
Return values
rcReturn status code

Definition at line 52 of file elf.c.

53  {
54  void *buffer = phys_to_virt ( dest );
55  int rc;
56 
57  DBGC ( image, "ELF %s loading segment [%x,%x) to [%lx,%lx,%lx)\n",
58  image->name, phdr->p_offset, ( phdr->p_offset + phdr->p_filesz ),
59  dest, ( dest + phdr->p_filesz ), ( dest + phdr->p_memsz ) );
60 
61  /* Verify and prepare segment */
62  if ( ( rc = prep_segment ( buffer, phdr->p_filesz,
63  phdr->p_memsz ) ) != 0 ) {
64  DBGC ( image, "ELF %s could not prepare segment: %s\n",
65  image->name, strerror ( rc ) );
66  return rc;
67  }
68 
69  /* Copy image to segment */
70  memcpy ( buffer, ( image->data + phdr->p_offset ), phdr->p_filesz );
71 
72  return 0;
73 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
const void * data
Read-only data.
Definition: image.h:50
#define DBGC(...)
Definition: compiler.h:505
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition: netvsc.h:16
An executable image.
Definition: image.h:23
void * memcpy(void *dest, const void *src, size_t len) __nonnull
Elf32_Word p_memsz
Definition: elf.h:73
Elf32_Word p_filesz
Definition: elf.h:72
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
Elf32_Off p_offset
Definition: elf.h:69
if(len >=6 *4) __asm__ __volatile__("movsl" if(len >=5 *4) __asm__ __volatile__("movsl" if(len >=4 *4) __asm__ __volatile__("movsl" if(len >=3 *4) __asm__ __volatile__("movsl" if(len >=2 *4) __asm__ __volatile__("movsl" if(len >=1 *4) __asm__ __volatile__("movsl" if((len % 4) >=2) __asm__ __volatile__("movsw" if((len % 2) >=1) __asm__ __volatile__("movsb" return dest
Definition: string.h:150
int prep_segment(void *segment, size_t filesz, size_t memsz)
Prepare segment for loading.
Definition: segment.c:61
char * name
Name.
Definition: image.h:37

References buffer, image::data, DBGC, dest, memcpy(), image::name, Elf32_Phdr::p_filesz, Elf32_Phdr::p_memsz, Elf32_Phdr::p_offset, prep_segment(), rc, and strerror().

Referenced by elf_load().

◆ elf_segment()

static int elf_segment ( struct image image,
const Elf_Ehdr ehdr,
const Elf_Phdr phdr,
int(*)(struct image *image, const Elf_Phdr *phdr, physaddr_t dest process,
physaddr_t entry,
physaddr_t max 
)
static

Process ELF segment.

Parameters
imageELF file
ehdrELF executable header
phdrELF program header
processSegment processor
Return values
entryEntry point, if found
maxMaximum used address
rcReturn status code

Definition at line 86 of file elf.c.

91  {
94  unsigned long e_offset;
95  int rc;
96 
97  /* Do nothing for non-PT_LOAD segments */
98  if ( phdr->p_type != PT_LOAD )
99  return 0;
100 
101  /* Check segment lies within image */
102  if ( ( phdr->p_offset + phdr->p_filesz ) > image->len ) {
103  DBGC ( image, "ELF %s segment outside image\n", image->name );
104  return -ENOEXEC;
105  }
106 
107  /* Find start address: use physical address for preference,
108  * fall back to virtual address if no physical address
109  * supplied.
110  */
111  dest = phdr->p_paddr;
112  if ( ! dest )
113  dest = phdr->p_vaddr;
114  if ( ! dest ) {
115  DBGC ( image, "ELF %s segment loads to physical address 0\n",
116  image->name );
117  return -ENOEXEC;
118  }
119  end = ( dest + phdr->p_memsz );
120 
121  /* Update maximum used address, if applicable */
122  if ( end > *max )
123  *max = end;
124 
125  /* Process segment */
126  if ( ( rc = process ( image, phdr, dest ) ) != 0 )
127  return rc;
128 
129  /* Set execution address, if it lies within this segment */
130  if ( ( e_offset = ( ehdr->e_entry - dest ) ) < phdr->p_filesz ) {
131  *entry = ehdr->e_entry;
132  DBGC ( image, "ELF %s found physical entry point at %lx\n",
133  image->name, *entry );
134  } else if ( ( e_offset = ( ehdr->e_entry - phdr->p_vaddr ) )
135  < phdr->p_filesz ) {
136  if ( ! *entry ) {
137  *entry = ( dest + e_offset );
138  DBGC ( image, "ELF %s found virtual entry point at %lx"
139  " (virt %lx)\n", image->name, *entry,
140  ( ( unsigned long ) ehdr->e_entry ) );
141  }
142  }
143 
144  return 0;
145 }
A process.
Definition: process.h:17
Elf32_Addr p_paddr
Definition: elf.h:71
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define max(x, y)
Definition: ath.h:40
#define PT_LOAD
Definition: elf.h:79
#define ENOEXEC
Exec format error.
Definition: errno.h:519
#define DBGC(...)
Definition: compiler.h:505
An executable image.
Definition: image.h:23
Elf32_Word p_memsz
Definition: elf.h:73
Elf32_Addr p_vaddr
Definition: elf.h:70
Elf32_Word p_filesz
Definition: elf.h:72
size_t len
Length of raw file image.
Definition: image.h:55
Elf32_Addr e_entry
Definition: elf.h:30
Elf32_Word p_type
Definition: elf.h:68
Elf32_Off p_offset
Definition: elf.h:69
unsigned long physaddr_t
Definition: stdint.h:20
if(len >=6 *4) __asm__ __volatile__("movsl" if(len >=5 *4) __asm__ __volatile__("movsl" if(len >=4 *4) __asm__ __volatile__("movsl" if(len >=3 *4) __asm__ __volatile__("movsl" if(len >=2 *4) __asm__ __volatile__("movsl" if(len >=1 *4) __asm__ __volatile__("movsl" if((len % 4) >=2) __asm__ __volatile__("movsw" if((len % 2) >=1) __asm__ __volatile__("movsb" return dest
Definition: string.h:150
uint32_t end
Ending offset.
Definition: netvsc.h:18
char * name
Name.
Definition: image.h:37

References DBGC, dest, Elf32_Ehdr::e_entry, end, ENOEXEC, image::len, max, image::name, Elf32_Phdr::p_filesz, Elf32_Phdr::p_memsz, Elf32_Phdr::p_offset, Elf32_Phdr::p_paddr, Elf32_Phdr::p_type, Elf32_Phdr::p_vaddr, PT_LOAD, and rc.

Referenced by elf_segments().

◆ elf_segments()

int elf_segments ( struct image image,
const Elf_Ehdr ehdr,
int(*)(struct image *image, const Elf_Phdr *phdr, physaddr_t dest process,
physaddr_t entry,
physaddr_t max 
)

Process ELF segments.

Parameters
imageELF file
ehdrELF executable header
processSegment processor
Return values
entryEntry point, if found
maxMaximum used address
rcReturn status code

Definition at line 157 of file elf.c.

161  {
162  const Elf_Phdr *phdr;
163  Elf_Off phoff;
164  unsigned int phnum;
165  int rc;
166 
167  /* Initialise maximum used address */
168  *max = 0;
169 
170  /* Invalidate entry point */
171  *entry = 0;
172 
173  /* Read and process ELF program headers */
174  for ( phoff = ehdr->e_phoff , phnum = ehdr->e_phnum ; phnum ;
175  phoff += ehdr->e_phentsize, phnum-- ) {
176  if ( ( image->len < phoff ) ||
177  ( ( image->len - phoff ) < sizeof ( *phdr ) ) ) {
178  DBGC ( image, "ELF %s program header %d outside "
179  "image\n", image->name, phnum );
180  return -ENOEXEC;
181  }
182  phdr = ( image->data + phoff );
183  if ( ( rc = elf_segment ( image, ehdr, phdr, process,
184  entry, max ) ) != 0 )
185  return rc;
186  }
187 
188  /* Check for a valid execution address */
189  if ( ! *entry ) {
190  DBGC ( image, "ELF %s entry point %lx outside image\n",
191  image->name, ( ( unsigned long ) ehdr->e_entry ) );
192  return -ENOEXEC;
193  }
194 
195  return 0;
196 }
A process.
Definition: process.h:17
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define max(x, y)
Definition: ath.h:40
const void * data
Read-only data.
Definition: image.h:50
#define ENOEXEC
Exec format error.
Definition: errno.h:519
#define DBGC(...)
Definition: compiler.h:505
Elf32_Half e_phentsize
Definition: elf.h:35
An executable image.
Definition: image.h:23
static int elf_segment(struct image *image, const Elf_Ehdr *ehdr, const Elf_Phdr *phdr, int(*process)(struct image *image, const Elf_Phdr *phdr, physaddr_t dest), physaddr_t *entry, physaddr_t *max)
Process ELF segment.
Definition: elf.c:86
Elf32_Off e_phoff
Definition: elf.h:31
size_t len
Length of raw file image.
Definition: image.h:55
Elf32_Addr e_entry
Definition: elf.h:30
Elf32_Half e_phnum
Definition: elf.h:36
Elf32_Off Elf_Off
Definition: elf.h:19
char * name
Name.
Definition: image.h:37
ELF program header.
Definition: elf.h:67

References image::data, DBGC, Elf32_Ehdr::e_entry, Elf32_Ehdr::e_phentsize, Elf32_Ehdr::e_phnum, Elf32_Ehdr::e_phoff, elf_segment(), ENOEXEC, image::len, max, image::name, and rc.

Referenced by elf_load(), and elfboot_probe().

◆ elf_load()

int elf_load ( struct image image,
physaddr_t entry,
physaddr_t max 
)

Load ELF image into memory.

Parameters
imageELF file
Return values
entryEntry point
maxMaximum used address
rcReturn status code

Definition at line 206 of file elf.c.

206  {
207  static const uint8_t e_ident[] = {
208  [EI_MAG0] = ELFMAG0,
209  [EI_MAG1] = ELFMAG1,
210  [EI_MAG2] = ELFMAG2,
211  [EI_MAG3] = ELFMAG3,
212  [EI_CLASS] = ELFCLASS,
213  };
214  const Elf_Ehdr *ehdr;
215  int rc;
216 
217  /* Read ELF header */
218  if ( image->len < sizeof ( *ehdr ) ) {
219  DBGC ( image, "ELF %s too short for ELF header\n",
220  image->name );
221  return -ENOEXEC;
222  }
223  ehdr = image->data;
224  if ( memcmp ( ehdr->e_ident, e_ident, sizeof ( e_ident ) ) != 0 ) {
225  DBGC ( image, "ELF %s has invalid signature\n", image->name );
226  return -ENOEXEC;
227  }
228 
229  /* Load ELF segments into memory */
230  if ( ( rc = elf_segments ( image, ehdr, elf_load_segment,
231  entry, max ) ) != 0 )
232  return rc;
233 
234  return 0;
235 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
ELF header.
Definition: elf.h:25
#define max(x, y)
Definition: ath.h:40
const void * data
Read-only data.
Definition: image.h:50
#define ELFMAG1
Definition: elf.h:53
#define ENOEXEC
Exec format error.
Definition: errno.h:519
#define DBGC(...)
Definition: compiler.h:505
An executable image.
Definition: image.h:23
int elf_segments(struct image *image, const Elf_Ehdr *ehdr, int(*process)(struct image *image, const Elf_Phdr *phdr, physaddr_t dest), physaddr_t *entry, physaddr_t *max)
Process ELF segments.
Definition: elf.c:157
#define ELFMAG2
Definition: elf.h:54
unsigned char e_ident[EI_NIDENT]
Definition: elf.h:26
#define EI_MAG2
Definition: elf.h:45
size_t len
Length of raw file image.
Definition: image.h:55
#define ELFCLASS
Definition: elf.h:20
unsigned char uint8_t
Definition: stdint.h:10
static int elf_load_segment(struct image *image, const Elf_Phdr *phdr, physaddr_t dest)
Load ELF segment into memory.
Definition: elf.c:52
#define EI_CLASS
Definition: elf.h:47
#define ELFMAG3
Definition: elf.h:55
#define EI_MAG3
Definition: elf.h:46
#define ELFMAG0
Definition: elf.h:52
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:114
char * name
Name.
Definition: image.h:37
#define EI_MAG1
Definition: elf.h:44
#define EI_MAG0
Definition: elf.h:43

References image::data, DBGC, Elf32_Ehdr::e_ident, EI_CLASS, EI_MAG0, EI_MAG1, EI_MAG2, EI_MAG3, elf_load_segment(), elf_segments(), ELFCLASS, ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3, ENOEXEC, image::len, max, memcmp(), image::name, and rc.

Referenced by elfboot_exec(), and multiboot_load_elf().