1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3    Copyright (c) 2001 William L. Pitts
4 */
5 
6 #include <command.h>
7 #include <cpu_func.h>
8 #include <elf.h>
9 #include <env.h>
10 #include <errno.h>
11 #include <net.h>
12 #include <vxworks.h>
13 #ifdef CONFIG_X86
14 #include <vesa.h>
15 #include <asm/e820.h>
16 #include <linux/linkage.h>
17 #endif
18 
19 /**
20  * bootelf_exec() - start the ELF image execution.
21  *
22  * @entry: address of entry point of ELF.
23  *
24  * May by used to allow ports to override the default behavior.
25  */
bootelf_exec(ulong (* entry)(int,char * const[]),int argc,char * const argv[])26 unsigned long bootelf_exec(ulong (*entry)(int, char * const[]),
27 			   int argc, char *const argv[])
28 {
29 	return entry(argc, argv);
30 }
31 
32 /**
33  * bootelf() - Boot ELF from memory.
34  *
35  * @addr:  Loading address of ELF in memory.
36  * @flags: Bits like ELF_PHDR to control boot details.
37  * @argc: May be used to pass command line arguments (maybe unused).
38  *	  Necessary for backward compatibility with the CLI command.
39  *	  If unused, must be 0.
40  * @argv: see @argc. If unused, must be NULL.
41  * Return: Number returned by ELF application.
42  *
43  * Sets errno = ENOEXEC if the ELF image is not valid.
44  */
bootelf(unsigned long addr,Bootelf_flags flags,int argc,char * const argv[])45 unsigned long bootelf(unsigned long addr, Bootelf_flags flags,
46 		      int argc, char *const argv[])
47 {
48 	unsigned long entry_addr;
49 	char *args[] = {"", NULL};
50 
51 	errno = 0;
52 
53 	if (!valid_elf_image(addr)) {
54 		errno = ENOEXEC;
55 		return 1;
56 	}
57 
58 	entry_addr = flags.phdr ? load_elf_image_phdr(addr)
59 					    : load_elf_image_shdr(addr);
60 
61 	if (!flags.autostart)
62 		return 0;
63 
64 	if (!argc && !argv) {
65 		argc = 1;
66 		argv = args;
67 	}
68 
69 	return bootelf_exec((void *)entry_addr, argc, argv);
70 }
71 
72 /*
73  * A very simple ELF64 loader, assumes the image is valid, returns the
74  * entry point address.
75  *
76  * Note if U-Boot is 32-bit, the loader assumes the to segment's
77  * physical address and size is within the lower 32-bit address space.
78  */
load_elf64_image_phdr(unsigned long addr)79 unsigned long load_elf64_image_phdr(unsigned long addr)
80 {
81 	Elf64_Ehdr *ehdr; /* Elf header structure pointer */
82 	Elf64_Phdr *phdr; /* Program header structure pointer */
83 	int i;
84 
85 	ehdr = (Elf64_Ehdr *)addr;
86 	phdr = (Elf64_Phdr *)(addr + (ulong)ehdr->e_phoff);
87 
88 	/* Load each program header */
89 	for (i = 0; i < ehdr->e_phnum; ++i, ++phdr) {
90 		void *dst = (void *)(ulong)phdr->p_paddr;
91 		void *src = (void *)addr + phdr->p_offset;
92 
93 		/* Only load PT_LOAD program header */
94 		if (phdr->p_type != PT_LOAD)
95 			continue;
96 
97 		debug("Loading phdr %i to 0x%p (%lu bytes)\n",
98 		      i, dst, (ulong)phdr->p_filesz);
99 		if (phdr->p_filesz)
100 			memcpy(dst, src, phdr->p_filesz);
101 		if (phdr->p_filesz != phdr->p_memsz)
102 			memset(dst + phdr->p_filesz, 0x00,
103 			       phdr->p_memsz - phdr->p_filesz);
104 		flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
105 			    roundup(phdr->p_memsz, ARCH_DMA_MINALIGN));
106 	}
107 
108 	if (ehdr->e_machine == EM_PPC64 && (ehdr->e_flags &
109 					    EF_PPC64_ELFV1_ABI)) {
110 		/*
111 		 * For the 64-bit PowerPC ELF V1 ABI, e_entry is a function
112 		 * descriptor pointer with the first double word being the
113 		 * address of the entry point of the function.
114 		 */
115 		uintptr_t addr = ehdr->e_entry;
116 
117 		return *(Elf64_Addr *)addr;
118 	}
119 
120 	return ehdr->e_entry;
121 }
122 
load_elf64_image_shdr(unsigned long addr)123 unsigned long load_elf64_image_shdr(unsigned long addr)
124 {
125 	Elf64_Ehdr *ehdr; /* Elf header structure pointer */
126 	Elf64_Shdr *shdr; /* Section header structure pointer */
127 	unsigned char *strtab = 0; /* String table pointer */
128 	unsigned char *image; /* Binary image pointer */
129 	int i; /* Loop counter */
130 
131 	ehdr = (Elf64_Ehdr *)addr;
132 
133 	/* Find the section header string table for output info */
134 	shdr = (Elf64_Shdr *)(addr + (ulong)ehdr->e_shoff +
135 			     (ehdr->e_shstrndx * sizeof(Elf64_Shdr)));
136 
137 	if (shdr->sh_type == SHT_STRTAB)
138 		strtab = (unsigned char *)(addr + (ulong)shdr->sh_offset);
139 
140 	/* Load each appropriate section */
141 	for (i = 0; i < ehdr->e_shnum; ++i) {
142 		shdr = (Elf64_Shdr *)(addr + (ulong)ehdr->e_shoff +
143 				     (i * sizeof(Elf64_Shdr)));
144 
145 		if (!(shdr->sh_flags & SHF_ALLOC) ||
146 		    shdr->sh_addr == 0 || shdr->sh_size == 0) {
147 			continue;
148 		}
149 
150 		if (strtab) {
151 			debug("%sing %s @ 0x%08lx (%ld bytes)\n",
152 			      (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load",
153 			       &strtab[shdr->sh_name],
154 			       (unsigned long)shdr->sh_addr,
155 			       (long)shdr->sh_size);
156 		}
157 
158 		if (shdr->sh_type == SHT_NOBITS) {
159 			memset((void *)(uintptr_t)shdr->sh_addr, 0,
160 			       shdr->sh_size);
161 		} else {
162 			image = (unsigned char *)addr + (ulong)shdr->sh_offset;
163 			memcpy((void *)(uintptr_t)shdr->sh_addr,
164 			       (const void *)image, shdr->sh_size);
165 		}
166 		flush_cache(rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN),
167 			    roundup((shdr->sh_addr + shdr->sh_size),
168 				     ARCH_DMA_MINALIGN) -
169 				rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN));
170 	}
171 
172 	if (ehdr->e_machine == EM_PPC64 && (ehdr->e_flags &
173 					    EF_PPC64_ELFV1_ABI)) {
174 		/*
175 		 * For the 64-bit PowerPC ELF V1 ABI, e_entry is a function
176 		 * descriptor pointer with the first double word being the
177 		 * address of the entry point of the function.
178 		 */
179 		uintptr_t addr = ehdr->e_entry;
180 
181 		return *(Elf64_Addr *)addr;
182 	}
183 
184 	return ehdr->e_entry;
185 }
186 
187 /*
188  * A very simple ELF loader, assumes the image is valid, returns the
189  * entry point address.
190  *
191  * The loader firstly reads the EFI class to see if it's a 64-bit image.
192  * If yes, call the ELF64 loader. Otherwise continue with the ELF32 loader.
193  */
load_elf_image_phdr(unsigned long addr)194 unsigned long load_elf_image_phdr(unsigned long addr)
195 {
196 	Elf32_Ehdr *ehdr; /* Elf header structure pointer */
197 	Elf32_Phdr *phdr; /* Program header structure pointer */
198 	int i;
199 
200 	ehdr = (Elf32_Ehdr *)addr;
201 	if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
202 		return load_elf64_image_phdr(addr);
203 
204 	phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff);
205 
206 	/* Load each program header */
207 	for (i = 0; i < ehdr->e_phnum; ++i, ++phdr) {
208 		void *dst = (void *)(uintptr_t)phdr->p_paddr;
209 		void *src = (void *)addr + phdr->p_offset;
210 
211 		/* Only load PT_LOAD program header */
212 		if (phdr->p_type != PT_LOAD)
213 			continue;
214 
215 		debug("Loading phdr %i to 0x%p (%i bytes)\n",
216 		      i, dst, phdr->p_filesz);
217 		if (phdr->p_filesz)
218 			memcpy(dst, src, phdr->p_filesz);
219 		if (phdr->p_filesz != phdr->p_memsz)
220 			memset(dst + phdr->p_filesz, 0x00,
221 			       phdr->p_memsz - phdr->p_filesz);
222 		flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
223 			    roundup(phdr->p_memsz, ARCH_DMA_MINALIGN));
224 	}
225 
226 	return ehdr->e_entry;
227 }
228 
load_elf_image_shdr(unsigned long addr)229 unsigned long load_elf_image_shdr(unsigned long addr)
230 {
231 	Elf32_Ehdr *ehdr; /* Elf header structure pointer */
232 	Elf32_Shdr *shdr; /* Section header structure pointer */
233 	unsigned char *strtab = 0; /* String table pointer */
234 	unsigned char *image; /* Binary image pointer */
235 	int i; /* Loop counter */
236 
237 	ehdr = (Elf32_Ehdr *)addr;
238 	if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
239 		return load_elf64_image_shdr(addr);
240 
241 	/* Find the section header string table for output info */
242 	shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
243 			     (ehdr->e_shstrndx * sizeof(Elf32_Shdr)));
244 
245 	if (shdr->sh_type == SHT_STRTAB)
246 		strtab = (unsigned char *)(addr + shdr->sh_offset);
247 
248 	/* Load each appropriate section */
249 	for (i = 0; i < ehdr->e_shnum; ++i) {
250 		shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
251 				     (i * sizeof(Elf32_Shdr)));
252 
253 		if (!(shdr->sh_flags & SHF_ALLOC) ||
254 		    shdr->sh_addr == 0 || shdr->sh_size == 0) {
255 			continue;
256 		}
257 
258 		if (strtab) {
259 			debug("%sing %s @ 0x%08lx (%ld bytes)\n",
260 			      (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load",
261 			       &strtab[shdr->sh_name],
262 			       (unsigned long)shdr->sh_addr,
263 			       (long)shdr->sh_size);
264 		}
265 
266 		if (shdr->sh_type == SHT_NOBITS) {
267 			memset((void *)(uintptr_t)shdr->sh_addr, 0,
268 			       shdr->sh_size);
269 		} else {
270 			image = (unsigned char *)addr + shdr->sh_offset;
271 			memcpy((void *)(uintptr_t)shdr->sh_addr,
272 			       (const void *)image, shdr->sh_size);
273 		}
274 		flush_cache(rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN),
275 			    roundup((shdr->sh_addr + shdr->sh_size),
276 				    ARCH_DMA_MINALIGN) -
277 			    rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN));
278 	}
279 
280 	return ehdr->e_entry;
281 }
282 
283 /*
284  * Determine if a valid ELF image exists at the given memory location.
285  * First look at the ELF header magic field, then make sure that it is
286  * executable.
287  */
valid_elf_image(unsigned long addr)288 int valid_elf_image(unsigned long addr)
289 {
290 	Elf32_Ehdr *ehdr; /* Elf header structure pointer */
291 
292 	ehdr = (Elf32_Ehdr *)addr;
293 
294 	if (!IS_ELF(*ehdr)) {
295 		printf("## No elf image at address 0x%08lx\n", addr);
296 		return 0;
297 	}
298 
299 	if (ehdr->e_type != ET_EXEC) {
300 		printf("## Not a 32-bit elf image at address 0x%08lx\n", addr);
301 		return 0;
302 	}
303 
304 	return 1;
305 }
306