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 #pragma once
6
7 #include <elf.h>
8 #include <fbl/array.h>
9 #include <fbl/function.h>
10 #include <fbl/string_piece.h>
11 #include <lib/zx/process.h>
12 #include <stdint.h>
13
14 // TODO(jakehehrlich): Replace ArrayRef here with something more like std::span
15 // in fbl.
16 template <class T>
17 class ArrayRef {
18 public:
19 ArrayRef() = default;
20 template <size_t N>
ArrayRef(const T (& arr)[N])21 ArrayRef(const T (&arr)[N])
22 : ptr_(arr), sz_(N) {}
ArrayRef(const fbl::Array<T> & arr)23 ArrayRef(const fbl::Array<T>& arr)
24 : ptr_(arr.get()), sz_(arr.size()) {}
ArrayRef(const T * ptr,size_t sz)25 ArrayRef(const T* ptr, size_t sz)
26 : ptr_(ptr), sz_(sz) {}
27
empty()28 bool empty() const {
29 return sz_ == 0;
30 }
31
get()32 const T* get() const {
33 return ptr_;
34 }
35
begin()36 const T* begin() const {
37 return ptr_;
38 }
39
end()40 const T* end() const {
41 return ptr_ + sz_;
42 }
43
size()44 size_t size() const {
45 return sz_;
46 }
47
48 const T& operator[](size_t idx) const {
49 return ptr_[idx];
50 }
51
52 private:
53 const T* ptr_ = nullptr;
54 size_t sz_ = 0;
55 };
56
57 template <class T>
58 bool operator==(ArrayRef<T> a, ArrayRef<T> b) {
59 if (a.size() != b.size()) {
60 return false;
61 }
62 for (size_t i = 0; i < a.size(); ++i) {
63 if (a[i] != b[i]) {
64 return false;
65 }
66 }
67 return true;
68 }
69
70 template <typename T>
MakeArrayRef(const T * p,size_t sz)71 ArrayRef<T> MakeArrayRef(const T* p, size_t sz) {
72 return {p, sz};
73 }
74
75 template <typename T, size_t N>
MakeArrayRef(const T (& arr)[N])76 ArrayRef<T> MakeArrayRef(const T (&arr)[N]) {
77 return {arr};
78 }
79
80 struct ModuleInfo {
81 fbl::StringPiece name;
82 uintptr_t vaddr;
83 ArrayRef<uint8_t> build_id;
84 const Elf64_Ehdr& ehdr;
85 ArrayRef<Elf64_Phdr> phdrs;
86 };
87
88 #if defined(__aarch64__)
89 constexpr Elf64_Half kNativeElfMachine = EM_AARCH64;
90 #elif defined(__x86_64__)
91 constexpr Elf64_Half kNativeElfMachine = EM_X86_64;
92 #endif
93
94 using ModuleAction = fbl::Function<void(const ModuleInfo&)>;
95 extern zx_status_t ForEachModule(const zx::process&, ModuleAction);
96