iPXE
Functions
elfboot.c File Reference

ELF bootable image. More...

#include <string.h>
#include <errno.h>
#include <elf.h>
#include <librm.h>
#include <ipxe/image.h>
#include <ipxe/elf.h>
#include <ipxe/features.h>
#include <ipxe/init.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
 FEATURE (FEATURE_IMAGE, "ELF", DHCP_EB_FEATURE_ELF, 1)
 
static int elfboot_exec (struct image *image)
 Execute ELF image. More...
 
static int elfboot_check_segment (struct image *image, const Elf_Phdr *phdr, physaddr_t dest)
 Check that ELF segment uses flat physical addressing. More...
 
static int elfboot_probe (struct image *image)
 Probe ELF image. More...
 
struct image_type elfboot_image_type __image_type (PROBE_NORMAL)
 ELF image type. More...
 

Detailed Description

ELF bootable image.

Definition in file elfboot.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ FEATURE()

FEATURE ( FEATURE_IMAGE  ,
"ELF"  ,
DHCP_EB_FEATURE_ELF  ,
 
)

◆ elfboot_exec()

static int elfboot_exec ( struct image image)
static

Execute ELF image.

Parameters
imageELF image
Return values
rcReturn status code

Definition at line 50 of file elfboot.c.

50  {
51  physaddr_t entry;
53  int rc;
54 
55  /* Load the image using core ELF support */
56  if ( ( rc = elf_load ( image, &entry, &max ) ) != 0 ) {
57  DBGC ( image, "ELF %s could not load: %s\n",
58  image->name, strerror ( rc ) );
59  return rc;
60  }
61 
62  /* An ELF image has no callback interface, so we need to shut
63  * down before invoking it.
64  */
65  shutdown_boot();
66 
67  /* Jump to OS with flat physical addressing */
68  DBGC ( image, "ELF %s starting execution at %lx\n",
69  image->name, entry );
70  __asm__ __volatile__ ( PHYS_CODE ( "pushl %%ebp\n\t" /* gcc bug */
71  "call *%%edi\n\t"
72  "popl %%ebp\n\t" /* gcc bug */ )
73  : : "D" ( entry )
74  : "eax", "ebx", "ecx", "edx", "esi", "memory" );
75 
76  DBGC ( image, "ELF %s returned\n", image->name );
77 
78  /* It isn't safe to continue after calling shutdown() */
79  while ( 1 ) {}
80 
81  return -ECANCELED; /* -EIMPOSSIBLE, anyone? */
82 }
#define PHYS_CODE(asm_code_str)
Definition: librm.h:167
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define max(x, y)
Definition: ath.h:40
#define DBGC(...)
Definition: compiler.h:505
An executable image.
Definition: image.h:23
#define ECANCELED
Operation canceled.
Definition: errno.h:343
int elf_load(struct image *image, physaddr_t *entry, physaddr_t *max)
Load ELF image into memory.
Definition: elf.c:206
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
__asm__ __volatile__("call *%9" :"=a"(result), "=c"(discard_ecx), "=d"(discard_edx) :"d"(0), "a"(code), "b"(0), "c"(in_phys), "D"(0), "S"(out_phys), "m"(hypercall))
unsigned long physaddr_t
Definition: stdint.h:20
__asm__(".section \".rodata\", \"a\", " PROGBITS "\n\t" "\nprivate_key_data:\n\t" ".size private_key_data, ( . - private_key_data )\n\t" ".equ private_key_len, ( . - private_key_data )\n\t" ".previous\n\t")
static void shutdown_boot(void)
Shut down system for OS boot.
Definition: init.h:77
char * name
Name.
Definition: image.h:37

References __asm__(), __volatile__(), DBGC, ECANCELED, elf_load(), max, image::name, PHYS_CODE, rc, shutdown_boot(), and strerror().

◆ elfboot_check_segment()

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

Check that ELF segment uses flat physical addressing.

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

Definition at line 92 of file elfboot.c.

93  {
94 
95  /* Check that ELF segment uses flat physical addressing */
96  if ( phdr->p_vaddr != dest ) {
97  DBGC ( image, "ELF %s uses virtual addressing (phys %x, virt "
98  "%x)\n", image->name, phdr->p_paddr, phdr->p_vaddr );
99  return -ENOEXEC;
100  }
101 
102  return 0;
103 }
Elf32_Addr p_paddr
Definition: elf.h:71
#define ENOEXEC
Exec format error.
Definition: errno.h:519
#define DBGC(...)
Definition: compiler.h:505
An executable image.
Definition: image.h:23
Elf32_Addr p_vaddr
Definition: elf.h:70
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
char * name
Name.
Definition: image.h:37

References DBGC, dest, ENOEXEC, image::name, Elf32_Phdr::p_paddr, and Elf32_Phdr::p_vaddr.

Referenced by elfboot_probe().

◆ elfboot_probe()

static int elfboot_probe ( struct image image)
static

Probe ELF image.

Parameters
imageELF file
Return values
rcReturn status code

Definition at line 111 of file elfboot.c.

111  {
112  const Elf32_Ehdr *ehdr;
113  static const uint8_t e_ident[] = {
114  [EI_MAG0] = ELFMAG0,
115  [EI_MAG1] = ELFMAG1,
116  [EI_MAG2] = ELFMAG2,
117  [EI_MAG3] = ELFMAG3,
118  [EI_CLASS] = ELFCLASS32,
119  [EI_DATA] = ELFDATA2LSB,
121  };
122  physaddr_t entry;
123  physaddr_t max;
124  int rc;
125 
126  /* Read ELF header */
127  if ( image->len < sizeof ( *ehdr ) ) {
128  DBGC ( image, "ELF %s too short for ELF header\n",
129  image->name );
130  return -ENOEXEC;
131  }
132  ehdr = image->data;
133  if ( memcmp ( ehdr->e_ident, e_ident, sizeof ( e_ident ) ) != 0 ) {
134  DBGC ( image, "ELF %s invalid identifier\n", image->name );
135  return -ENOEXEC;
136  }
137 
138  /* Check that this image uses flat physical addressing */
139  if ( ( rc = elf_segments ( image, ehdr, elfboot_check_segment,
140  &entry, &max ) ) != 0 ) {
141  DBGC ( image, "ELF %s is not loadable: %s\n",
142  image->name, strerror ( rc ) );
143  return rc;
144  }
145 
146  return 0;
147 }
#define EI_DATA
Definition: elf.h:48
static int elfboot_check_segment(struct image *image, const Elf_Phdr *phdr, physaddr_t dest)
Check that ELF segment uses flat physical addressing.
Definition: elfboot.c:92
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
ELF header.
Definition: elf.h:25
#define max(x, y)
Definition: ath.h:40
#define EI_VERSION
Definition: elf.h:49
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
#define ELFCLASS32
Definition: elf.h:58
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
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
size_t len
Length of raw file image.
Definition: image.h:55
unsigned char uint8_t
Definition: stdint.h:10
#define EI_CLASS
Definition: elf.h:47
unsigned long physaddr_t
Definition: stdint.h:20
#define ELFMAG3
Definition: elf.h:55
#define EV_CURRENT
Definition: elf.h:64
#define ELFDATA2LSB
Definition: elf.h:61
#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_DATA, EI_MAG0, EI_MAG1, EI_MAG2, EI_MAG3, EI_VERSION, elf_segments(), elfboot_check_segment(), ELFCLASS32, ELFDATA2LSB, ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3, ENOEXEC, EV_CURRENT, image::len, max, memcmp(), image::name, rc, and strerror().

◆ __image_type()

struct image_type elfboot_image_type __image_type ( PROBE_NORMAL  )

ELF image type.