iPXE
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.
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.
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.
int elf_load (struct image *image, physaddr_t *entry, physaddr_t *max)
 Load ELF image into memory.

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()

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:3
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" retur dest)
Definition string.h:151
#define DBGC(...)
Definition compiler.h:505
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition netvsc.h:5
void * memcpy(void *dest, const void *src, size_t len) __nonnull
int prep_segment(void *segment, size_t filesz, size_t memsz)
Prepare segment for loading.
Definition segment.c:61
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
Elf32_Off p_offset
Definition elf.h:69
Elf32_Word p_filesz
Definition elf.h:72
Elf32_Word p_memsz
Definition elf.h:73
An executable image.
Definition image.h:24
const void * data
Read-only data.
Definition image.h:51
char * name
Name.
Definition image.h:38

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()

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 )
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}
unsigned long physaddr_t
Definition stdint.h:20
#define max(x, y)
Definition ath.h:41
#define PT_LOAD
Definition elf.h:79
#define ENOEXEC
Exec format error.
Definition errno.h:520
uint32_t end
Ending offset.
Definition netvsc.h:7
Elf32_Addr e_entry
Definition elf.h:30
Elf32_Addr p_vaddr
Definition elf.h:70
Elf32_Word p_type
Definition elf.h:68
Elf32_Addr p_paddr
Definition elf.h:71
size_t len
Length of raw file image.
Definition image.h:56
A process.
Definition process.h:18

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(* process )(struct image *image, const Elf_Phdr *phdr, physaddr_t dest),
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}
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 Elf_Off
Definition elf.h:19
Elf32_Phdr Elf_Phdr
Definition elf.h:18
Elf32_Off e_phoff
Definition elf.h:31
Elf32_Half e_phnum
Definition elf.h:36
Elf32_Half e_phentsize
Definition elf.h:35

References image::data, DBGC, dest, 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}
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
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 EI_MAG2
Definition elf.h:45
#define ELFMAG0
Definition elf.h:52
#define ELFMAG3
Definition elf.h:55
#define EI_MAG1
Definition elf.h:44
#define EI_CLASS
Definition elf.h:47
#define ELFMAG1
Definition elf.h:53
#define ELFMAG2
Definition elf.h:54
#define EI_MAG0
Definition elf.h:43
#define EI_MAG3
Definition elf.h:46
Elf32_Ehdr Elf_Ehdr
Definition elf.h:17
#define ELFCLASS
Definition elf.h:20
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition string.c:115
unsigned char e_ident[EI_NIDENT]
Definition elf.h:26

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().