1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *  * Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  *  * Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in
12  *    the documentation and/or other materials provided with the
13  *    distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 #pragma once
30 
31 #include <sys/cdefs.h>
32 
33 #include <mutex>
34 #include <set>
35 #include <string>
36 
37 #include <platform/bionic/macros.h>
38 
39 class MapEntry {
40  public:
41   MapEntry() = default;
MapEntry(uintptr_t start,uintptr_t end,uintptr_t offset,const char * name,size_t name_len,int flags)42   MapEntry(uintptr_t start, uintptr_t end, uintptr_t offset, const char* name, size_t name_len,
43            int flags)
44       : start_(start), end_(end), offset_(offset), name_(name, name_len), flags_(flags) {}
45 
MapEntry(uintptr_t pc)46   explicit MapEntry(uintptr_t pc) : start_(pc), end_(pc) {}
47 
48   void Init();
49 
50   uintptr_t GetLoadBias();
51 
SetInvalid()52   void SetInvalid() {
53     valid_ = false;
54     init_ = true;
55     load_bias_read_ = true;
56   }
57 
valid()58   bool valid() { return valid_; }
start()59   uintptr_t start() const { return start_; }
end()60   uintptr_t end() const { return end_; }
offset()61   uintptr_t offset() const { return offset_; }
elf_start_offset()62   uintptr_t elf_start_offset() const { return elf_start_offset_; }
set_elf_start_offset(uintptr_t elf_start_offset)63   void set_elf_start_offset(uintptr_t elf_start_offset) { elf_start_offset_ = elf_start_offset; }
name()64   const std::string& name() const { return name_; }
flags()65   int flags() const { return flags_; }
66 
67  private:
68   uintptr_t start_;
69   uintptr_t end_;
70   uintptr_t offset_;
71   uintptr_t load_bias_ = 0;
72   uintptr_t elf_start_offset_ = 0;
73   std::string name_;
74   int flags_;
75   bool init_ = false;
76   bool valid_ = false;
77   bool load_bias_read_ = false;
78 };
79 
80 // Ordering comparator that returns equivalence for overlapping entries
81 struct compare_entries {
operatorcompare_entries82   bool operator()(const MapEntry* a, const MapEntry* b) const { return a->end() <= b->start(); }
83 };
84 
85 class MapData {
86  public:
87   MapData() = default;
88   ~MapData();
89 
90   const MapEntry* find(uintptr_t pc, uintptr_t* rel_pc = nullptr);
91 
NumMaps()92   size_t NumMaps() { return entries_.size(); }
93 
94   void ReadMaps();
95 
96  private:
97   std::mutex m_;
98   std::set<MapEntry*, compare_entries> entries_;
99 
100   void ClearEntries();
101 
102   BIONIC_DISALLOW_COPY_AND_ASSIGN(MapData);
103 };
104