1/*
2 * Copyright (c) 1999-2004 University of New South Wales
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7/*
8  Authors: Luke Deller, Ben Leslie
9  Created: 24/Sep/1999
10*/
11
12/**
13\file
14
15\brief Generic ELF library
16
17The ELF library is designed to make the task of parsing and getting information
18out of an ELF file easier.
19
20It provides function to obtain the various different fields in the ELF header, and
21the program and segment information.
22
23Also importantly, it provides a function elf_loadFile which will load a given
24ELF file into memory.
25
26*/
27
28#pragma once
29
30#include <types.h>
31#include <printf.h>
32
33#include "elf32.h"
34#include "elf64.h"
35
36#define ISELF32(elfFile) ( ((struct Elf32_Header*)elfFile)->e_ident[EI_CLASS] == ELFCLASS32 )
37#define ISELF64(elfFile) ( ((struct Elf64_Header*)elfFile)->e_ident[EI_CLASS] == ELFCLASS64 )
38
39/*
40 * constants for Elf32_Phdr.p_flags
41 */
42#define PF_X        1   /* readable segment */
43#define PF_W        2   /* writeable segment */
44#define PF_R        4   /* executable segment */
45
46/*
47 * constants for indexing into Elf64_Header_t.e_ident
48 */
49#define EI_MAG0     0
50#define EI_MAG1     1
51#define EI_MAG2     2
52#define EI_MAG3     3
53#define EI_CLASS    4
54#define EI_DATA     5
55#define EI_VERSION  6
56
57#define ELFMAG0         '\177'
58#define ELFMAG1         'E'
59#define ELFMAG2         'L'
60#define ELFMAG3         'F'
61
62#define ELFCLASS32      1
63#define ELFCLASS64      2
64
65#define PT_NULL 0
66#define PT_LOAD 1
67#define PT_DYNAMIC 2
68#define PT_INTERP 3
69#define PT_NOTE 4
70#define PT_SHLIB 5
71#define PT_PHDR 6
72#define PT_TLS 7
73#define PT_NUM 8
74
75#define ELFDATA2LSB 1
76#define ELFDATA2MSB 2
77
78/* Section Header type bits */
79#define SHT_PROGBITS 1
80#define SHT_SYMTAB 2
81#define SHT_NOBITS 8
82#define SHT_REL 9
83
84/* Section Header flag bits */
85#define SHF_WRITE 1
86#define SHF_ALLOC 2
87#define SHF_EXECINSTR  4
88
89/* Dynamic section entry types */
90#define DT_NULL 0
91#define DT_HASH 4
92#define DT_STRTAB 5
93#define DT_SYMTAB 6
94#define DT_RELA 7
95#define DT_RELASZ 8
96#define DT_RELAENT 9
97#define DT_STRSZ 10
98#define DT_SYMENT 11
99#define DT_REL 17
100#define DT_RELSZ 18
101#define DT_RELENT 19
102
103/**/
104#define ELF_PRINT_PROGRAM_HEADERS 1
105#define ELF_PRINT_SECTIONS 2
106#define ELF_PRINT_ALL (ELF_PRINT_PROGRAM_HEADERS | ELF_PRINT_SECTIONS)
107
108/**
109 * Checks that elfFile points to a valid elf file.
110 *
111 * @param elfFile Potential ELF file to check
112 *
113 * \return 0 on success. -1 if not and elf, -2 if not 32 bit.
114 */
115int elf_checkFile(void *elfFile);
116
117/**
118 * Determine number of sections in an ELF file.
119 *
120 * @param elfFile Pointer to a valid ELF header.
121 *
122 * \return Number of sections in the ELF file.
123 */
124unsigned elf_getNumSections(void *elfFile);
125
126/**
127 * Determine number of program headers in an ELF file.
128 *
129 * @param elfFile Pointer to a valid ELF header.
130 *
131 * \return Number of program headers in the ELF file.
132 */
133uint16_t elf_getNumProgramHeaders(void *elfFile);
134
135/**
136 * Return the base physical address of given program header in an ELF file
137 *
138 * @param elfFile Pointer to a valid ELF header
139 * @param ph Index of the program header
140 *
141 * \return The memory size of the specified program header
142 */
143uint64_t elf_getProgramHeaderPaddr(void *elfFile, uint16_t ph);
144
145/**
146 * Return the base virtual address of given program header in an ELF file
147 *
148 * @param elfFile Pointer to a valid ELF header
149 * @param ph Index of the program header
150 *
151 * \return The memory size of the specified program header
152 */
153uint64_t elf_getProgramHeaderVaddr(void *elfFile, uint16_t ph);
154
155/**
156 * Return the memory size of a given program header in an ELF file
157 *
158 * @param elfFile Pointer to a valid ELF header
159 * @param ph Index of the program header
160 *
161 * \return The memory size of the specified program header
162 */
163uint64_t elf_getProgramHeaderMemorySize(void *elfFile, uint16_t ph);
164
165/**
166 * Return the file size of a given program header in an ELF file
167 *
168 * @param elfFile Pointer to a valid ELF header
169 * @param ph Index of the program header
170 *
171 * \return The file size of the specified program header
172 */
173uint64_t elf_getProgramHeaderFileSize(void *elfFile, uint16_t ph);
174
175/**
176 * Return the start offset of he file
177 *
178 * @param elfFile Pointer to a valid ELF header
179 * @param ph Index of the program header
180 *
181 * \return The offset of this program header with relation to the start
182 * of the elfFile.
183 */
184uint64_t elf_getProgramHeaderOffset(void *elfFile, uint16_t ph);
185
186/**
187 * Return the flags for a given program header
188 *
189 * @param elfFile Pointer to a valid ELF header
190 * @param ph Index of the program header
191 *
192 * \return The flags of a given program header
193 */
194uint32_t elf_getProgramHeaderFlags(void *elfFile, uint16_t ph);
195
196/**
197 * Return the type for a given program header
198 *
199 * @param elfFile Pointer to a valid ELF header
200 * @param ph Index of the program header
201 *
202 * \return The type of a given program header
203 */
204uint32_t elf_getProgramHeaderType(void *elfFile, uint16_t ph);
205
206/**
207 * Return the physical translation of a physical address, with respect
208 * to a given program header
209 *
210 */
211uint64_t elf_vtopProgramHeader(void *elfFile, uint16_t ph, uint64_t vaddr);
212
213/**
214 *
215 * \return true if the address in in this program header
216 */
217int elf_vaddrInProgramHeader(void *elfFile, uint16_t ph, uint64_t vaddr);
218
219/**
220 * Determine the memory bounds of an ELF file
221 *
222 * @param elfFile Pointer to a valid ELF header
223 * @param phys If true return bounds of physical memory, otherwise return
224 *   bounds of virtual memory
225 * @param min Pointer to return value of the minimum
226 * @param max Pointer to return value of the maximum
227 *
228 * \return true on success. false on failure, if for example, it is an invalid ELF file
229 */
230int elf_getMemoryBounds(void *elfFile, int phys, uint64_t *min, uint64_t *max);
231
232/**
233 * Find the entry point of an ELF file.
234 *
235 * @param elfFile Pointer to a valid ELF header
236 *
237 * \return The entry point address as a 64-bit integer.
238 */
239uint64_t elf_getEntryPoint(void *elfFile);
240
241/**
242 * Load an ELF file into memory
243 *
244 * @param elfFile Pointer to a valid ELF file
245 * @param phys If true load using the physical address, otherwise using the virtual addresses
246 *
247 * \return true on success, false on failure.
248 *
249 * The function assumes that the ELF file is loaded in memory at some
250 * address different to the target address at which it will be loaded.
251 * It also assumes direct access to the source and destination address, i.e:
252 * Memory must be able to be loaded with a simple memcpy.
253 *
254 * Obviously this also means that if we are loading a 64bit ELF on a 32bit
255 * platform, we assume that any memory addresses are within the first 4GB.
256 *
257 */
258int elf_loadFile(void *elfFile, int phys);
259
260char *elf_getStringTable(void *elfFile, int string_segment);
261char *elf_getSegmentStringTable(void *elfFile);
262void *elf_getSectionNamed(void *elfFile, char *str);
263char *elf_getSectionName(void *elfFile, int i);
264uint64_t elf_getSectionSize(void *elfFile, int i);
265uint64_t elf_getSectionAddr(void *elfFile, int i);
266
267/**
268 * Return the flags for a given sections
269 *
270 * @param elfFile Pointer to a valid ELF header
271 * @param i Index of the sections
272 *
273 * \return The flags of a given section
274 */
275uint32_t elf_getSectionFlags(void *elfFile, int i);
276
277/**
278 * Return the type for a given sections
279 *
280 * @param elfFile Pointer to a valid ELF header
281 * @param i Index of the sections
282 *
283 * \return The type of a given section
284 */
285uint32_t elf_getSectionType(void *elfFile, int i);
286
287void *elf_getSection(void *elfFile, int i);
288void elf_getProgramHeaderInfo(void *elfFile, uint16_t ph, uint64_t *p_vaddr,
289                              uint64_t *p_paddr, uint64_t *p_filesz,
290                              uint64_t *p_offset, uint64_t *p_memsz);
291
292#if 0
293/*
294 * Returns a pointer to the program segment table, which is an array of
295 * ELF64_Phdr_t structs.  The size of the array can be found by calling
296 * getNumProgramSegments.
297 */
298struct Elf32_Phdr *elf_getProgramSegmentTable(void *elfFile);
299#endif
300#if 0
301/**
302 * Returns a pointer to the program segment table, which is an array of
303 * ELF64_Phdr_t structs.  The size of the array can be found by calling
304 * getNumProgramSegments.
305 */
306struct Elf32_Shdr *elf_getSectionTable(void *elfFile);
307#endif
308
309