1/* @LICENSE(UNSW_OZPLB) */
2
3/*
4 * Australian Public Licence B (OZPLB)
5 *
6 * Version 1-0
7 *
8 * Copyright (c) 1999-2004 University of New South Wales
9 *
10 * All rights reserved.
11 *
12 * Developed by: Operating Systems and Distributed Systems Group (DiSy)
13 *               University of New South Wales
14 *               http://www.disy.cse.unsw.edu.au
15 *
16 * Permission is granted by University of New South Wales, free of charge, to
17 * any person obtaining a copy of this software and any associated
18 * documentation files (the "Software") to deal with the Software without
19 * restriction, including (without limitation) the rights to use, copy,
20 * modify, adapt, merge, publish, distribute, communicate to the public,
21 * sublicense, and/or sell, lend or rent out copies of the Software, and
22 * to permit persons to whom the Software is furnished to do so, subject
23 * to the following conditions:
24 *
25 *     * Redistributions of source code must retain the above copyright
26 *       notice, this list of conditions and the following disclaimers.
27 *
28 *     * Redistributions in binary form must reproduce the above
29 *       copyright notice, this list of conditions and the following
30 *       disclaimers in the documentation and/or other materials provided
31 *       with the distribution.
32 *
33 *     * Neither the name of University of New South Wales, nor the names of its
34 *       contributors, may be used to endorse or promote products derived
35 *       from this Software without specific prior written permission.
36 *
37 * EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT
38 * PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND
39 * NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS,
40 * WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
41 * BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS
42 * REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE,
43 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT,
44 * THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF
45 * ERRORS, WHETHER OR NOT DISCOVERABLE.
46 *
47 * TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL
48 * NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL
49 * THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT,
50 * NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER
51 * LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR
52 * OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS
53 * OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR
54 * OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT,
55 * CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN
56 * CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER
57 * DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS
58 * CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS,
59 * DAMAGES OR OTHER LIABILITY.
60 *
61 * If applicable legislation implies representations, warranties, or
62 * conditions, or imposes obligations or liability on University of New South
63 * Wales or one of its contributors in respect of the Software that
64 * cannot be wholly or partly excluded, restricted or modified, the
65 * liability of University of New South Wales or the contributor is limited, to
66 * the full extent permitted by the applicable legislation, at its
67 * option, to:
68 * a.  in the case of goods, any one or more of the following:
69 * i.  the replacement of the goods or the supply of equivalent goods;
70 * ii.  the repair of the goods;
71 * iii. the payment of the cost of replacing the goods or of acquiring
72 *  equivalent goods;
73 * iv.  the payment of the cost of having the goods repaired; or
74 * b.  in the case of services:
75 * i.  the supplying of the services again; or
76 * ii.  the payment of the cost of having the services supplied again.
77 *
78 * The construction, validity and performance of this licence is governed
79 * by the laws in force in New South Wales, Australia.
80 */
81
82/*
83  Authors: Luke Deller, Ben Leslie
84  Created: 24/Sep/1999
85*/
86
87/**
88\file
89
90\brief Generic ELF library
91
92The ELF library is designed to make the task of parsing and getting information
93out of an ELF file easier.
94
95It provides function to obtain the various different fields in the ELF header, and
96the program and segment information.
97
98Also importantly, it provides a function elf_loadFile which will load a given
99ELF file into memory.
100
101*/
102
103#pragma once
104
105#include <stdbool.h>
106#include <stddef.h>
107#include <stdint.h>
108#include <elf.h>
109
110struct elf {
111    void *elfFile;
112    size_t elfSize;
113    unsigned char elfClass; /* 32-bit or 64-bit */
114};
115typedef struct elf elf_t;
116
117enum elf_addr_type {
118    VIRTUAL,
119    PHYSICAL
120};
121typedef enum elf_addr_type elf_addr_type_t;
122
123/* ELF header functions */
124/**
125 * Initialises an elf_t structure and checks that the ELF file is valid.
126 * This function must be called to validate the ELF before any other function.
127 * Otherwise, attempting to call other functions with an invalid ELF file may
128 * result in undefined behaviour.
129 *
130 * @param file ELF file to use
131 * @param size Size of the ELF file
132 * @param res elf_t to initialise
133 *
134 * \return 0 on success, otherwise < 0
135 */
136int elf_newFile(void *file, size_t size, elf_t *res);
137
138/**
139 * Initialises and elf_t structure and checks that the ELF file is valid.
140 * The validity of a potential ELF file can be determined by the arguments
141 * check_pht and check_st.
142 * If both check_pht and check_st are true, this function is equivalent to
143 * elf_newFile.
144 * Calling other functions with an invalid ELF file may result in undefined
145 * behaviour.
146 *
147 * @param file ELF file to use
148 * @param size Size of the ELF file
149 * @param check_pht Whether to check the ELF program header table is valid
150 * @param check_st Whether to check the ELF section table is valid
151 * @param res elf_t to initialise
152 *
153 * \return 0 on success, otherwise < 0
154 */
155int elf_newFile_maybe_unsafe(void *file, size_t size, bool check_pht, bool check_st, elf_t *res);
156
157/**
158 * Checks that file starts with the ELF magic number.
159 * File must be at least 4 bytes (SELFMAG).
160 *
161 * @param file to check
162 *
163 * \return 0 on success, otherwise < 0
164 */
165int elf_check_magic(char *file);
166
167/**
168 * Checks that elfFile points to an ELF file with a valid ELF header.
169 *
170 * @param elfFile Potential ELF file to check
171 *
172 * \return 0 on success, otherwise < 0
173 */
174int elf_checkFile(elf_t *elfFile);
175
176/**
177 * Checks that elfFile points to an ELF file with a valid program header table.
178 *
179 * @param elfFile Potential ELF file to check
180 *
181 * \return 0 on success, otherwise < 0
182 */
183int elf_checkProgramHeaderTable(elf_t *elfFile);
184
185/**
186 * Checks that elfFile points to an ELF file with a valid section table.
187 *
188 * @param elfFile Potential ELF file to check
189 *
190 * \return 0 on success, otherwise < 0
191 */
192int elf_checkSectionTable(elf_t *elfFile);
193
194/**
195 * Find the entry point of an ELF file.
196 *
197 * @param elfFile Pointer to a valid ELF structure
198 *
199 * \return The entry point address.
200 */
201uintptr_t elf_getEntryPoint(elf_t *elfFile);
202
203/**
204 * Determine number of program headers in an ELF file.
205 *
206 * @param elfFile Pointer to a valid ELF structure.
207 *
208 * \return Number of program headers in the ELF file.
209 */
210size_t elf_getNumProgramHeaders(elf_t *elfFile);
211
212/**
213 * Determine number of sections in an ELF file.
214 *
215 * @param elfFile Pointer to a valid ELF structure.
216 *
217 * \return Number of sections in the ELF file.
218 */
219size_t elf_getNumSections(elf_t *elfFile);
220
221/**
222 * Get the index of the section header string table of an ELF file.
223 *
224 * @param elf Pointer to a valid ELF structure.
225 *
226 * \return The index of the section header string table.
227 */
228size_t elf_getSectionStringTableIndex(elf_t *elf);
229
230/**
231 * Get a string table section of an ELF file.
232 *
233 * @param elfFile Pointer to a valid ELF structure.
234 * @param string_section The section number of the string table.
235 *
236 * \return The string table, or NULL if the section is not a string table.
237 */
238const char *elf_getStringTable(elf_t *elfFile, size_t string_segment);
239
240/**
241 * Get the string table for section header names.
242 *
243 * @param elfFile Pointer to a valid ELF structure.
244 *
245 * \return The string table, or NULL if there is no table.
246 */
247const char *elf_getSectionStringTable(elf_t *elfFile);
248
249
250/* Section header functions */
251/**
252 * Get a section of an ELF file.
253 *
254 * @param elfFile Pointer to a valid ELF structure
255 * @param i The section number
256 *
257 * \return The section, or NULL if there is no section.
258 */
259void *elf_getSection(elf_t *elfFile, size_t i);
260
261/**
262 * Get the section of an ELF file with a given name.
263 *
264 * @param elfFile Pointer to a valid ELF structure
265 * @param str Name of the section
266 * @param i Pointer to store the section number
267 *
268 * \return The section, or NULL if there is no section.
269 */
270void *elf_getSectionNamed(elf_t *elfFile, const char *str, size_t *i);
271
272/**
273 * Return the name of a given section.
274 *
275 * @param elfFile Pointer to a valid ELF structure
276 * @param i Index of the section
277 *
278 * \return The name of a given section.
279 */
280const char *elf_getSectionName(elf_t *elfFile, size_t i);
281
282/**
283 * Return the offset to the name of a given section in the section header
284 * string table.
285 *
286 * @param elfFile Pointer to a valid ELF structure
287 * @param i Index of the section
288 *
289 * \return The offset to the name of a given section in the section header
290 * string table.
291 */
292size_t elf_getSectionNameOffset(elf_t *elfFile, size_t i);
293
294/**
295 * Return the type of a given section
296 *
297 * @param elfFile Pointer to a valid ELF structure
298 * @param i Index of the section
299 *
300 * \return The type of a given section.
301 */
302uint32_t elf_getSectionType(elf_t *elfFile, size_t i);
303
304/**
305 * Return the flags of a given section
306 *
307 * @param elfFile Pointer to a valid ELF structure
308 * @param i Index of the section
309 *
310 * \return The flags of a given section.
311 */
312size_t elf_getSectionFlags(elf_t *elfFile, size_t i);
313
314/**
315 * Return the address of a given section
316 *
317 * @param elfFile Pointer to a valid ELF structure
318 * @param i Index of the section
319 *
320 * \return The address of a given section.
321 */
322uintptr_t elf_getSectionAddr(elf_t *elfFile, size_t i);
323
324/**
325 * Return the offset of a given section
326 *
327 * @param elfFile Pointer to a valid ELF structure
328 * @param i Index of the section
329 *
330 * \return The offset of a given section.
331 */
332size_t elf_getSectionOffset(elf_t *elfFile, size_t i);
333
334/**
335 * Return the size of a given section
336 *
337 * @param elfFile Pointer to a valid ELF structure
338 * @param i Index of the section
339 *
340 * \return The size of a given section.
341 */
342size_t elf_getSectionSize(elf_t *elfFile, size_t i);
343
344/**
345 * Return the related section index of a given section
346 *
347 * @param elfFile Pointer to a valid ELF structure
348 * @param i Index of the section
349 *
350 * \return The related section index of a given section.
351 */
352uint32_t elf_getSectionLink(elf_t *elfFile, size_t i);
353
354/**
355 * Return extra information of a given section
356 *
357 * @param elfFile Pointer to a valid ELF structure
358 * @param i Index of the section
359 *
360 * \return Extra information of a given section.
361 */
362uint32_t elf_getSectionInfo(elf_t *elfFile, size_t i);
363
364/**
365 * Return the alignment of a given section
366 *
367 * @param elfFile Pointer to a valid ELF structure
368 * @param i Index of the section
369 *
370 * \return The alignment of a given section.
371 */
372size_t elf_getSectionAddrAlign(elf_t *elfFile, size_t i);
373
374/**
375 * Return the entry size of a given section
376 *
377 * @param elfFile Pointer to a valid ELF structure
378 * @param i Index of the section
379 *
380 * \return The entry size of a given section.
381 */
382size_t elf_getSectionEntrySize(elf_t *elfFile, size_t i);
383
384
385/* Program header functions */
386
387/**
388 * Return the segment data for a given program header.
389 *
390 * @param elf Pointer to a valid ELF structure
391 * @param ph Index of the program header
392 *
393 * \return Pointer to the segment data
394 */
395void *elf_getProgramSegment(elf_t *elf, size_t ph);
396
397/**
398 * Return the type for a given program header.
399 *
400 * @param elfFile Pointer to a valid ELF structure
401 * @param ph Index of the program header
402 *
403 * \return The type of a given program header.
404 */
405uint32_t elf_getProgramHeaderType(elf_t *elfFile, size_t ph);
406
407/**
408 * Return the segment offset for a given program header.
409 *
410 * @param elfFile Pointer to a valid ELF structure
411 * @param ph Index of the program header
412 *
413 * \return The offset of this program header from the start of the file.
414 */
415size_t elf_getProgramHeaderOffset(elf_t *elfFile, size_t ph);
416
417/**
418 * Return the base virtual address of given program header.
419 *
420 * @param elfFile Pointer to a valid ELF structure
421 * @param ph Index of the program header
422 *
423 * \return The memory size of the specified program header.
424 */
425uintptr_t elf_getProgramHeaderVaddr(elf_t *elfFile, size_t ph);
426
427/**
428 * Return the base physical address of given program header.
429 *
430 * @param elfFile Pointer to a valid ELF structure
431 * @param ph Index of the program header
432 *
433 * \return The memory size of the specified program header.
434 */
435uintptr_t elf_getProgramHeaderPaddr(elf_t *elfFile, size_t ph);
436
437/**
438 * Return the file size of a given program header.
439 *
440 * @param elfFile Pointer to a valid ELF structure
441 * @param ph Index of the program header
442 *
443 * \return The file size of the specified program header.
444 */
445size_t elf_getProgramHeaderFileSize(elf_t *elfFile, size_t ph);
446
447/**
448 * Return the memory size of a given program header.
449 *
450 * @param elfFile Pointer to a valid ELF structure
451 * @param ph Index of the program header
452 *
453 * \return The memory size of the specified program header.
454 */
455size_t elf_getProgramHeaderMemorySize(elf_t *elfFile, size_t ph);
456
457/**
458 * Return the flags for a given program header.
459 *
460 * @param elfFile Pointer to a valid ELF structure
461 * @param ph Index of the program header
462 *
463 * \return The flags of a given program header.
464 */
465uint32_t elf_getProgramHeaderFlags(elf_t *elfFile, size_t ph);
466
467/**
468 * Return the alignment for a given program header.
469 *
470 * @param elfFile Pointer to a valid ELF structure
471 * @param ph Index of the program header
472 *
473 * \return The alignment of the given program header.
474 */
475size_t elf_getProgramHeaderAlign(elf_t *elfFile, size_t ph);
476
477
478/* Utility functions */
479
480/**
481 * Determine the memory bounds of an ELF file
482 *
483 * @param elfFile Pointer to a valid ELF structure
484 * @param addr_type If PHYSICAL return bounds of physical memory, otherwise
485 *                  return bounds of virtual memory
486 * @param min Pointer to return value of the minimum
487 * @param max Pointer to return value of the maximum
488 *
489 * \return true on success. false on failure, if for example, it is an invalid ELF file
490 */
491int elf_getMemoryBounds(elf_t *elfFile, elf_addr_type_t addr_type, uintptr_t *min, uintptr_t *max);
492
493/**
494 *
495 * \return true if the address in in this program header
496 */
497int elf_vaddrInProgramHeader(elf_t *elfFile, size_t ph, uintptr_t vaddr);
498
499/**
500 * Return the physical translation of a physical address, with respect
501 * to a given program header
502 *
503 */
504uintptr_t elf_vtopProgramHeader(elf_t *elfFile, size_t ph, uintptr_t vaddr);
505
506/**
507 * Load an ELF file into memory
508 *
509 * @param elfFile Pointer to a valid ELF file
510 * @param addr_type If PHYSICAL load using the physical address, otherwise using the
511 *                  virtual addresses
512 *
513 * \return true on success, false on failure.
514 *
515 * The function assumes that the ELF file is loaded in memory at some
516 * address different to the target address at which it will be loaded.
517 * It also assumes direct access to the source and destination address, i.e:
518 * Memory must be able to be loaded with a simple memcpy.
519 *
520 * Obviously this also means that if we are loading a 64bit ELF on a 32bit
521 * platform, we assume that any memory addresses are within the first 4GB.
522 *
523 */
524int elf_loadFile(elf_t *elfFile, elf_addr_type_t addr_type);
525