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