OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2013 The Chromium 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 #ifndef CRAZY_LINKER_ELF_LOADER_H |
| 6 #define CRAZY_LINKER_ELF_LOADER_H |
| 7 |
| 8 #include "crazy_linker_error.h" |
| 9 #include "crazy_linker_system.h" // For ScopedFileDescriptor |
| 10 #include "elf_traits.h" |
| 11 |
| 12 namespace crazy { |
| 13 |
| 14 // Helper class used to load an ELF binary in memory. |
| 15 // |
| 16 // Note that this doesn't not perform any relocation, the purpose |
| 17 // of this class is strictly to map all loadable segments from the |
| 18 // file to their correct location. |
| 19 // |
| 20 class ElfLoader { |
| 21 public: |
| 22 ElfLoader(); |
| 23 ~ElfLoader(); |
| 24 |
| 25 // Try to load a library at a given address. On failure, this will |
| 26 // update the linker error message and returns false. |
| 27 // |
| 28 // |lib_path| is the full library path, and |wanted_address| should |
| 29 // be the desired load address, or 0 to enable randomization. |
| 30 // |
| 31 // |file_offset| is an offset in the file where the ELF header will |
| 32 // be looked for. |
| 33 // |
| 34 // |wanted_address| is the wanted load address (of the first loadable |
| 35 // segment), or 0 to enable randomization. |
| 36 // |
| 37 // On success, the library's loadable segments will be mapped in |
| 38 // memory with their original protection. However, no further processing |
| 39 // will be performed. |
| 40 // |
| 41 // On failure, returns false and assign an error message to |error|. |
| 42 bool LoadAt(const char* lib_path, |
| 43 off_t file_offset, |
| 44 uintptr_t wanted_address, |
| 45 Error* error); |
| 46 |
| 47 // Only call the following functions after a succesfull LoadAt() call. |
| 48 |
| 49 size_t phdr_count() { return phdr_num_; } |
| 50 ELF::Addr load_start() { return reinterpret_cast<ELF::Addr>(load_start_); } |
| 51 ELF::Addr load_size() { return load_size_; } |
| 52 ELF::Addr load_bias() { return load_bias_; } |
| 53 const ELF::Phdr* loaded_phdr() { return loaded_phdr_; } |
| 54 |
| 55 private: |
| 56 FileDescriptor fd_; |
| 57 const char* path_; |
| 58 |
| 59 ELF::Ehdr header_; |
| 60 size_t phdr_num_; |
| 61 |
| 62 void* phdr_mmap_; // temporary copy of the program header. |
| 63 ELF::Phdr* phdr_table_; |
| 64 ELF::Addr phdr_size_; // and its size. |
| 65 |
| 66 off_t file_offset_; |
| 67 void* wanted_load_address_; |
| 68 void* load_start_; // First page of reserved address space. |
| 69 ELF::Addr load_size_; // Size in bytes of reserved address space. |
| 70 ELF::Addr load_bias_; // load_bias, add this value to all "vaddr" |
| 71 // values in the library to get the corresponding |
| 72 // memory address. |
| 73 |
| 74 const ELF::Phdr* loaded_phdr_; // points to the loaded program header. |
| 75 |
| 76 // Individual steps used by ::LoadAt() |
| 77 bool ReadElfHeader(Error* error); |
| 78 bool ReadProgramHeader(Error* error); |
| 79 bool ReserveAddressSpace(Error* error); |
| 80 bool LoadSegments(Error* error); |
| 81 bool FindPhdr(Error* error); |
| 82 bool CheckPhdr(ELF::Addr, Error* error); |
| 83 }; |
| 84 |
| 85 } // namespace crazy |
| 86 |
| 87 #endif // CRAZY_LINKER_ELF_LOADER_H |
OLD | NEW |