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:530
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 ( ( image->len < phdr->p_offset ) ||
103 ( ( image->len - phdr->p_offset ) < phdr->p_filesz ) ) {
104 DBGC ( image, "ELF %s segment outside image\n", image->name );
105 return -ENOEXEC;
106 }
107
108 /* Find start address: use physical address for preference,
109 * fall back to virtual address if no physical address
110 * supplied.
111 */
112 dest = phdr->p_paddr;
113 if ( ! dest )
114 dest = phdr->p_vaddr;
115 if ( ! dest ) {
116 DBGC ( image, "ELF %s segment loads to physical address 0\n",
117 image->name );
118 return -ENOEXEC;
119 }
120 end = ( dest + phdr->p_memsz );
121
122 /* Update maximum used address, if applicable */
123 if ( end > *max )
124 *max = end;
125
126 /* Process segment */
127 if ( ( rc = process ( image, phdr, dest ) ) != 0 )
128 return rc;
129
130 /* Set execution address, if it lies within this segment */
131 if ( ( e_offset = ( ehdr->e_entry - dest ) ) < phdr->p_filesz ) {
132 *entry = ehdr->e_entry;
133 DBGC ( image, "ELF %s found physical entry point at %lx\n",
134 image->name, *entry );
135 } else if ( ( e_offset = ( ehdr->e_entry - phdr->p_vaddr ) )
136 < phdr->p_filesz ) {
137 if ( ! *entry ) {
138 *entry = ( dest + e_offset );
139 DBGC ( image, "ELF %s found virtual entry point at %lx"
140 " (virt %lx)\n", image->name, *entry,
141 ( ( unsigned long ) ehdr->e_entry ) );
142 }
143 }
144
145 return 0;
146}
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:563
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:63
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 158 of file elf.c.

162 {
163 const Elf_Phdr *phdr;
164 Elf_Off phoff;
165 unsigned int phnum;
166 int rc;
167
168 /* Initialise maximum used address */
169 *max = 0;
170
171 /* Invalidate entry point */
172 *entry = 0;
173
174 /* Read and process ELF program headers */
175 for ( phoff = ehdr->e_phoff , phnum = ehdr->e_phnum ; phnum ;
176 phoff += ehdr->e_phentsize, phnum-- ) {
177 if ( ( image->len < phoff ) ||
178 ( ( image->len - phoff ) < sizeof ( *phdr ) ) ) {
179 DBGC ( image, "ELF %s program header %d outside "
180 "image\n", image->name, phnum );
181 return -ENOEXEC;
182 }
183 phdr = ( image->data + phoff );
184 if ( ( rc = elf_segment ( image, ehdr, phdr, process,
185 entry, max ) ) != 0 )
186 return rc;
187 }
188
189 /* Check for a valid execution address */
190 if ( ! *entry ) {
191 DBGC ( image, "ELF %s entry point %lx outside image\n",
192 image->name, ( ( unsigned long ) ehdr->e_entry ) );
193 return -ENOEXEC;
194 }
195
196 return 0;
197}
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 207 of file elf.c.

207 {
208 static const uint8_t e_ident[] = {
209 [EI_MAG0] = ELFMAG0,
210 [EI_MAG1] = ELFMAG1,
211 [EI_MAG2] = ELFMAG2,
212 [EI_MAG3] = ELFMAG3,
213 [EI_CLASS] = ELFCLASS,
214 };
215 const Elf_Ehdr *ehdr;
216 int rc;
217
218 /* Read ELF header */
219 if ( image->len < sizeof ( *ehdr ) ) {
220 DBGC ( image, "ELF %s too short for ELF header\n",
221 image->name );
222 return -ENOEXEC;
223 }
224 ehdr = image->data;
225 if ( memcmp ( ehdr->e_ident, e_ident, sizeof ( e_ident ) ) != 0 ) {
226 DBGC ( image, "ELF %s has invalid signature\n", image->name );
227 return -ENOEXEC;
228 }
229
230 /* Load ELF segments into memory */
231 if ( ( rc = elf_segments ( image, ehdr, elf_load_segment,
232 entry, max ) ) != 0 )
233 return rc;
234
235 return 0;
236}
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:158
#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().