iPXE
Functions
elf.c File Reference

ELF image format. More...

#include <errno.h>
#include <elf.h>
#include <ipxe/uaccess.h>
#include <ipxe/segment.h>
#include <ipxe/image.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, Elf_Phdr *phdr, physaddr_t dest)
 Load ELF segment into memory. More...
 
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)
 Process ELF segment. More...
 
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)
 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,
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 51 of file elf.c.

52  {
54  int rc;
55 
56  DBGC ( image, "ELF %p loading segment [%x,%x) to [%lx,%lx,%lx)\n",
57  image, phdr->p_offset, ( phdr->p_offset + phdr->p_filesz ),
58  dest, ( dest + phdr->p_filesz ), ( dest + phdr->p_memsz ) );
59 
60  /* Verify and prepare segment */
61  if ( ( rc = prep_segment ( buffer, phdr->p_filesz,
62  phdr->p_memsz ) ) != 0 ) {
63  DBGC ( image, "ELF %p could not prepare segment: %s\n",
64  image, strerror ( rc ) );
65  return rc;
66  }
67 
68  /* Copy image to segment */
69  memcpy_user ( buffer, 0, image->data, phdr->p_offset, phdr->p_filesz );
70 
71  return 0;
72 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
userptr_t data
Raw file image.
Definition: image.h:41
#define DBGC(...)
Definition: compiler.h:505
userptr_t phys_to_user(unsigned long phys_addr)
Convert physical address to user pointer.
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition: netvsc.h:16
An executable image.
Definition: image.h:24
Elf32_Word p_memsz
Definition: elf.h:73
uint32_t userptr_t
A pointer to a user buffer.
Definition: libkir.h:159
int prep_segment(userptr_t segment, size_t filesz, size_t memsz)
Prepare segment for loading.
Definition: segment.c:60
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
void memcpy_user(userptr_t dest, off_t dest_off, userptr_t src, off_t src_off, size_t len)
Copy data between user buffers.

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

Referenced by elf_load().

◆ elf_segment()

static int elf_segment ( struct image image,
Elf_Ehdr ehdr,
Elf_Phdr phdr,
int(*)(struct image *image, 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 85 of file elf.c.

88  {
91  unsigned long e_offset;
92  int rc;
93 
94  /* Do nothing for non-PT_LOAD segments */
95  if ( phdr->p_type != PT_LOAD )
96  return 0;
97 
98  /* Check segment lies within image */
99  if ( ( phdr->p_offset + phdr->p_filesz ) > image->len ) {
100  DBGC ( image, "ELF %p segment outside image\n", image );
101  return -ENOEXEC;
102  }
103 
104  /* Find start address: use physical address for preference,
105  * fall back to virtual address if no physical address
106  * supplied.
107  */
108  dest = phdr->p_paddr;
109  if ( ! dest )
110  dest = phdr->p_vaddr;
111  if ( ! dest ) {
112  DBGC ( image, "ELF %p segment loads to physical address 0\n",
113  image );
114  return -ENOEXEC;
115  }
116  end = ( dest + phdr->p_memsz );
117 
118  /* Update maximum used address, if applicable */
119  if ( end > *max )
120  *max = end;
121 
122  /* Process segment */
123  if ( ( rc = process ( image, phdr, dest ) ) != 0 )
124  return rc;
125 
126  /* Set execution address, if it lies within this segment */
127  if ( ( e_offset = ( ehdr->e_entry - dest ) ) < phdr->p_filesz ) {
128  *entry = ehdr->e_entry;
129  DBGC ( image, "ELF %p found physical entry point at %lx\n",
130  image, *entry );
131  } else if ( ( e_offset = ( ehdr->e_entry - phdr->p_vaddr ) )
132  < phdr->p_filesz ) {
133  if ( ! *entry ) {
134  *entry = ( dest + e_offset );
135  DBGC ( image, "ELF %p found virtual entry point at %lx"
136  " (virt %lx)\n", image, *entry,
137  ( ( unsigned long ) ehdr->e_entry ) );
138  }
139  }
140 
141  return 0;
142 }
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:39
#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:24
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:43
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

References DBGC, dest, Elf32_Ehdr::e_entry, end, ENOEXEC, image::len, max, 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,
Elf_Ehdr ehdr,
int(*)(struct image *image, 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 154 of file elf.c.

157  {
158  Elf_Phdr phdr;
159  Elf_Off phoff;
160  unsigned int phnum;
161  int rc;
162 
163  /* Initialise maximum used address */
164  *max = 0;
165 
166  /* Invalidate entry point */
167  *entry = 0;
168 
169  /* Read and process ELF program headers */
170  for ( phoff = ehdr->e_phoff , phnum = ehdr->e_phnum ; phnum ;
171  phoff += ehdr->e_phentsize, phnum-- ) {
172  if ( phoff > image->len ) {
173  DBGC ( image, "ELF %p program header %d outside "
174  "image\n", image, phnum );
175  return -ENOEXEC;
176  }
177  copy_from_user ( &phdr, image->data, phoff, sizeof ( phdr ) );
178  if ( ( rc = elf_segment ( image, ehdr, &phdr, process,
179  entry, max ) ) != 0 )
180  return rc;
181  }
182 
183  /* Check for a valid execution address */
184  if ( ! *entry ) {
185  DBGC ( image, "ELF %p entry point %lx outside image\n",
186  image, ( ( unsigned long ) ehdr->e_entry ) );
187  return -ENOEXEC;
188  }
189 
190  return 0;
191 }
A process.
Definition: process.h:17
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
userptr_t data
Raw file image.
Definition: image.h:41
#define max(x, y)
Definition: ath.h:39
#define ENOEXEC
Exec format error.
Definition: errno.h:519
static __always_inline void copy_from_user(void *dest, userptr_t src, off_t src_off, size_t len)
Copy data from user buffer.
Definition: uaccess.h:411
#define DBGC(...)
Definition: compiler.h:505
Elf32_Half e_phentsize
Definition: elf.h:35
An executable image.
Definition: image.h:24
Elf32_Off e_phoff
Definition: elf.h:31
size_t len
Length of raw file image.
Definition: image.h:43
Elf32_Addr e_entry
Definition: elf.h:30
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)
Process ELF segment.
Definition: elf.c:85
Elf32_Half e_phnum
Definition: elf.h:36
Elf32_Off Elf_Off
Definition: elf.h:19
ELF program header.
Definition: elf.h:67

References copy_from_user(), 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, 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 201 of file elf.c.

201  {
202  static const uint8_t e_ident[] = {
203  [EI_MAG0] = ELFMAG0,
204  [EI_MAG1] = ELFMAG1,
205  [EI_MAG2] = ELFMAG2,
206  [EI_MAG3] = ELFMAG3,
207  [EI_CLASS] = ELFCLASS,
208  };
209  Elf_Ehdr ehdr;
210  int rc;
211 
212  /* Read ELF header */
213  copy_from_user ( &ehdr, image->data, 0, sizeof ( ehdr ) );
214  if ( memcmp ( &ehdr.e_ident[EI_MAG0], e_ident,
215  sizeof ( e_ident ) ) != 0 ) {
216  DBGC ( image, "ELF %p has invalid signature\n", image );
217  return -ENOEXEC;
218  }
219 
220  /* Load ELF segments into memory */
221  if ( ( rc = elf_segments ( image, &ehdr, elf_load_segment,
222  entry, max ) ) != 0 )
223  return rc;
224 
225  return 0;
226 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
ELF header.
Definition: elf.h:25
userptr_t data
Raw file image.
Definition: image.h:41
#define max(x, y)
Definition: ath.h:39
#define ELFMAG1
Definition: elf.h:53
#define ENOEXEC
Exec format error.
Definition: errno.h:519
static __always_inline void copy_from_user(void *dest, userptr_t src, off_t src_off, size_t len)
Copy data from user buffer.
Definition: uaccess.h:411
static int elf_load_segment(struct image *image, Elf_Phdr *phdr, physaddr_t dest)
Load ELF segment into memory.
Definition: elf.c:51
#define DBGC(...)
Definition: compiler.h:505
An executable image.
Definition: image.h:24
#define ELFMAG2
Definition: elf.h:54
unsigned char e_ident[EI_NIDENT]
Definition: elf.h:26
#define EI_MAG2
Definition: elf.h:45
#define ELFCLASS
Definition: elf.h:20
unsigned char uint8_t
Definition: stdint.h:10
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)
Process ELF segments.
Definition: elf.c:154
#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
#define EI_MAG1
Definition: elf.h:44
#define EI_MAG0
Definition: elf.h:43

References copy_from_user(), 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, max, memcmp(), and rc.

Referenced by elfboot_exec(), and multiboot_load_elf().