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