1 // Copyright 2016 The Fuchsia Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // This is a minimal interface for the logic of loading ELF files. It 6 // is specifically designed to work entirely without memory allocation 7 // or long-lived data variables. Callers are responsible for all memory 8 // allocation. This code itself is position-independent code that does 9 // not need any writable memory anywhere but the stack. 10 11 #pragma once 12 13 #include <elf.h> 14 #include <zircon/types.h> 15 #include <stdbool.h> 16 #include <stddef.h> 17 #include <stdint.h> 18 19 #pragma GCC visibility push(hidden) 20 21 #ifdef _LP64 22 # define MY_ELFCLASS ELFCLASS64 23 typedef Elf64_Ehdr elf_ehdr_t; 24 typedef Elf64_Phdr elf_phdr_t; 25 #else 26 # define MY_ELFCLASS ELFCLASS32 27 typedef Elf32_Ehdr elf_ehdr_t; 28 typedef Elf32_Phdr elf_phdr_t; 29 #endif 30 31 typedef struct { 32 zx_vaddr_t e_entry; 33 uint_fast16_t e_phnum; 34 } elf_load_header_t; 35 36 // These routines use this error code to indicate an invalid file format, 37 // including wrong machine, wrong endian, etc. as well as a truncated file. 38 #define ERR_ELF_BAD_FORMAT ZX_ERR_NOT_FOUND 39 40 __BEGIN_CDECLS 41 42 // Validate the ELF headers and fill in basic header information. 'hdr_buf' 43 // represents bytes already read from the start of the file. 44 zx_status_t elf_load_prepare(zx_handle_t vmo, const void* hdr_buf, size_t buf_sz, 45 elf_load_header_t* header, uintptr_t* phoff); 46 47 // Read the ELF program headers in. 48 zx_status_t elf_load_read_phdrs(zx_handle_t vmo, elf_phdr_t* phdrs, 49 uintptr_t phoff, size_t phnum); 50 51 // Load the image into the process. 52 zx_status_t elf_load_map_segments(zx_handle_t vmar, 53 const elf_load_header_t* header, 54 const elf_phdr_t* phdrs, 55 zx_handle_t vmo, 56 zx_handle_t* segments_vmar, 57 zx_vaddr_t* bias, zx_vaddr_t* entry); 58 59 // Locate the PT_INTERP program header and extract its bounds in the file. 60 // Returns false if there was no PT_INTERP. 61 bool elf_load_find_interp(const elf_phdr_t* phdrs, size_t phnum, 62 uintptr_t* interp_off, size_t* interp_len); 63 64 __END_CDECLS 65 66 #pragma GCC visibility pop 67