Index: third_party/crazy_linker/crazy_linker/src/crazy_linker_elf_view.h |
diff --git a/third_party/crazy_linker/crazy_linker/src/crazy_linker_elf_view.h b/third_party/crazy_linker/crazy_linker/src/crazy_linker_elf_view.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..c60dd6ea427ecc30f56fe53f6753776f42d7f750 |
--- /dev/null |
+++ b/third_party/crazy_linker/crazy_linker/src/crazy_linker_elf_view.h |
@@ -0,0 +1,109 @@ |
+// Copyright (c) 2013 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef CRAZY_LINKER_ELF_VIEW_H |
+#define CRAZY_LINKER_ELF_VIEW_H |
+ |
+#include <string.h> |
+ |
+#include "crazy_linker_error.h" |
+#include "elf_traits.h" |
+ |
+namespace crazy { |
+ |
+class Error; |
+ |
+// An ElfView holds information describing a given ELF binary file for |
+// the crazy linker. This can be used to describe either system or crazy |
+// libraries. |
+class ElfView { |
+ public: |
+ ElfView() { ::memset(this, 0, sizeof(*this)); } |
+ |
+ ~ElfView() {} |
+ |
+ // Initialize this ElfView from its load address and a copy of its program |
+ // header table. |
+ // |load_address| is the desired library load address. |
+ // |phdr| is a pointer to the library's program header. Note that this can |
+ // point to any memory location that contains a valid copy of the header. |
+ // I.e. the library does not have to be mapped in the process. |
+ // |phdr_count| number of entries in program header table. |
+ // On failure, return false and set |error| message. |
+ // On success, return true, and sets all fields of the ElfView to the |
+ // appropriate values. Note that functions phdr() or dynamic() will always |
+ // return an address relative to |load_address|, even if the binary was |
+ // not loaded yet in the process. |
+ bool InitUnmapped(size_t load_address, |
+ const ELF::Phdr* phdr, |
+ size_t phdr_count, |
+ Error* error); |
+ |
+ const ELF::Phdr* phdr() const { return phdr_; } |
+ size_t phdr_count() const { return phdr_count_; } |
+ const ELF::Dyn* dynamic() const { return dynamic_; } |
+ size_t dynamic_count() const { return dynamic_count_; } |
+ size_t dynamic_flags() const { return dynamic_flags_; } |
+ size_t load_address() const { return load_address_; } |
+ size_t load_size() const { return load_size_; } |
+ size_t load_bias() const { return load_bias_; } |
+ |
+ // Helper class to iterate over the dynamic table. |
+ // Usage example: |
+ // DynamicIterator iter; |
+ // for ( ; iter.HasNext(); iter.SkipNext()) { |
+ // if (iter.GetTag() == DT_SOME_TAG) { |
+ // ... use iter.GetValue() |
+ // ... or iter.GetAddress(load_address) |
+ // } |
+ // } |
+ class DynamicIterator { |
+ public: |
+ DynamicIterator(const ElfView* view) { |
+ dyn_ = view->dynamic(); |
+ dyn_limit_ = dyn_ + view->dynamic_count(); |
+ } |
+ |
+ ~DynamicIterator() {} |
+ |
+ bool HasNext() const { return dyn_ < dyn_limit_; } |
+ void GetNext() { dyn_ += 1; } |
+ |
+ ELF::Addr GetTag() const { return dyn_->d_tag; } |
+ |
+ ELF::Addr GetValue() const { return dyn_->d_un.d_val; } |
+ |
+ ELF::Addr* GetValuePointer() const { |
+ return const_cast<ELF::Addr*>(&dyn_->d_un.d_val); |
+ } |
+ |
+ uintptr_t GetOffset() const { return dyn_->d_un.d_ptr; } |
+ |
+ uintptr_t GetAddress(size_t load_bias) const { |
+ return load_bias + dyn_->d_un.d_ptr; |
+ } |
+ |
+ private: |
+ const ELF::Dyn* dyn_; |
+ const ELF::Dyn* dyn_limit_; |
+ }; |
+ |
+ // Ensure the RELRO section is read-only after relocations. Assume the |
+ // ELF binary is mapped.On failure, return false and set |error| message. |
+ bool ProtectRelroSection(Error* error); |
+ |
+ protected: |
+ const ELF::Phdr* phdr_; |
+ size_t phdr_count_; |
+ const ELF::Dyn* dynamic_; |
+ size_t dynamic_count_; |
+ size_t dynamic_flags_; |
+ size_t load_address_; |
+ size_t load_size_; |
+ size_t load_bias_; |
+}; |
+ |
+} // namespace crazy |
+ |
+#endif // CRAZY_LINKER_ELF_VIEW_H |