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_VIEW_H |
| 6 #define CRAZY_LINKER_ELF_VIEW_H |
| 7 |
| 8 #include <string.h> |
| 9 |
| 10 #include "crazy_linker_error.h" |
| 11 #include "elf_traits.h" |
| 12 |
| 13 namespace crazy { |
| 14 |
| 15 class Error; |
| 16 |
| 17 // An ElfView holds information describing a given ELF binary file for |
| 18 // the crazy linker. This can be used to describe either system or crazy |
| 19 // libraries. |
| 20 class ElfView { |
| 21 public: |
| 22 ElfView() { ::memset(this, 0, sizeof(*this)); } |
| 23 |
| 24 ~ElfView() {} |
| 25 |
| 26 // Initialize this ElfView from its load address and a copy of its program |
| 27 // header table. |
| 28 // |load_address| is the desired library load address. |
| 29 // |phdr| is a pointer to the library's program header. Note that this can |
| 30 // point to any memory location that contains a valid copy of the header. |
| 31 // I.e. the library does not have to be mapped in the process. |
| 32 // |phdr_count| number of entries in program header table. |
| 33 // On failure, return false and set |error| message. |
| 34 // On success, return true, and sets all fields of the ElfView to the |
| 35 // appropriate values. Note that functions phdr() or dynamic() will always |
| 36 // return an address relative to |load_address|, even if the binary was |
| 37 // not loaded yet in the process. |
| 38 bool InitUnmapped(size_t load_address, |
| 39 const ELF::Phdr* phdr, |
| 40 size_t phdr_count, |
| 41 Error* error); |
| 42 |
| 43 const ELF::Phdr* phdr() const { return phdr_; } |
| 44 size_t phdr_count() const { return phdr_count_; } |
| 45 const ELF::Dyn* dynamic() const { return dynamic_; } |
| 46 size_t dynamic_count() const { return dynamic_count_; } |
| 47 size_t dynamic_flags() const { return dynamic_flags_; } |
| 48 size_t load_address() const { return load_address_; } |
| 49 size_t load_size() const { return load_size_; } |
| 50 size_t load_bias() const { return load_bias_; } |
| 51 |
| 52 // Helper class to iterate over the dynamic table. |
| 53 // Usage example: |
| 54 // DynamicIterator iter; |
| 55 // for ( ; iter.HasNext(); iter.SkipNext()) { |
| 56 // if (iter.GetTag() == DT_SOME_TAG) { |
| 57 // ... use iter.GetValue() |
| 58 // ... or iter.GetAddress(load_address) |
| 59 // } |
| 60 // } |
| 61 class DynamicIterator { |
| 62 public: |
| 63 DynamicIterator(const ElfView* view) { |
| 64 dyn_ = view->dynamic(); |
| 65 dyn_limit_ = dyn_ + view->dynamic_count(); |
| 66 } |
| 67 |
| 68 ~DynamicIterator() {} |
| 69 |
| 70 bool HasNext() const { return dyn_ < dyn_limit_; } |
| 71 void GetNext() { dyn_ += 1; } |
| 72 |
| 73 ELF::Addr GetTag() const { return dyn_->d_tag; } |
| 74 |
| 75 ELF::Addr GetValue() const { return dyn_->d_un.d_val; } |
| 76 |
| 77 ELF::Addr* GetValuePointer() const { |
| 78 return const_cast<ELF::Addr*>(&dyn_->d_un.d_val); |
| 79 } |
| 80 |
| 81 uintptr_t GetOffset() const { return dyn_->d_un.d_ptr; } |
| 82 |
| 83 uintptr_t GetAddress(size_t load_bias) const { |
| 84 return load_bias + dyn_->d_un.d_ptr; |
| 85 } |
| 86 |
| 87 private: |
| 88 const ELF::Dyn* dyn_; |
| 89 const ELF::Dyn* dyn_limit_; |
| 90 }; |
| 91 |
| 92 // Ensure the RELRO section is read-only after relocations. Assume the |
| 93 // ELF binary is mapped.On failure, return false and set |error| message. |
| 94 bool ProtectRelroSection(Error* error); |
| 95 |
| 96 protected: |
| 97 const ELF::Phdr* phdr_; |
| 98 size_t phdr_count_; |
| 99 const ELF::Dyn* dynamic_; |
| 100 size_t dynamic_count_; |
| 101 size_t dynamic_flags_; |
| 102 size_t load_address_; |
| 103 size_t load_size_; |
| 104 size_t load_bias_; |
| 105 }; |
| 106 |
| 107 } // namespace crazy |
| 108 |
| 109 #endif // CRAZY_LINKER_ELF_VIEW_H |
OLD | NEW |