1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef _LIBUNWINDSTACK_MAP_INFO_H 18 #define _LIBUNWINDSTACK_MAP_INFO_H 19 20 #include <stdint.h> 21 22 #include <atomic> 23 #include <memory> 24 #include <mutex> 25 #include <string> 26 27 #include <unwindstack/Elf.h> 28 29 namespace unwindstack { 30 31 class MemoryFileAtOffset; 32 33 struct MapInfo { MapInfoMapInfo34 MapInfo(MapInfo* prev_map, MapInfo* prev_real_map, uint64_t start, uint64_t end, uint64_t offset, 35 uint64_t flags, const char* name) 36 : start(start), 37 end(end), 38 offset(offset), 39 flags(flags), 40 name(name), 41 prev_map(prev_map), 42 prev_real_map(prev_real_map), 43 load_bias(INT64_MAX), 44 build_id(0) {} MapInfoMapInfo45 MapInfo(MapInfo* prev_map, MapInfo* prev_real_map, uint64_t start, uint64_t end, uint64_t offset, 46 uint64_t flags, const std::string& name) 47 : start(start), 48 end(end), 49 offset(offset), 50 flags(flags), 51 name(name), 52 prev_map(prev_map), 53 prev_real_map(prev_real_map), 54 load_bias(INT64_MAX), 55 build_id(0) {} 56 ~MapInfo(); 57 58 uint64_t start = 0; 59 uint64_t end = 0; 60 uint64_t offset = 0; 61 uint16_t flags = 0; 62 std::string name; 63 std::shared_ptr<Elf> elf; 64 // The offset of the beginning of this mapping to the beginning of the 65 // ELF file. 66 // elf_offset == offset - elf_start_offset. 67 // This value is only non-zero if the offset is non-zero but there is 68 // no elf signature found at that offset. 69 uint64_t elf_offset = 0; 70 // This value is the offset into the file of the map in memory that is the 71 // start of the elf. This is not equal to offset when the linker splits 72 // shared libraries into a read-only and read-execute map. 73 uint64_t elf_start_offset = 0; 74 75 MapInfo* prev_map = nullptr; 76 // This is the previous map that is not empty with a 0 offset. For 77 // example, this set of maps: 78 // 1000-2000 r--p 000000 00:00 0 libc.so 79 // 2000-3000 ---p 000000 00:00 0 libc.so 80 // 3000-4000 r-xp 003000 00:00 0 libc.so 81 // The last map's prev_map would point to the 2000-3000 map, while the 82 // prev_real_map would point to the 1000-2000 map. 83 MapInfo* prev_real_map = nullptr; 84 85 std::atomic_int64_t load_bias; 86 87 // This is a pointer to a new'd std::string. 88 // Using an atomic value means that we don't need to lock and will 89 // make it easier to move to a fine grained lock in the future. 90 std::atomic_uintptr_t build_id; 91 92 // Set to true if the elf file data is coming from memory. 93 bool memory_backed_elf = false; 94 95 // This function guarantees it will never return nullptr. 96 Elf* GetElf(const std::shared_ptr<Memory>& process_memory, ArchEnum expected_arch); 97 98 uint64_t GetLoadBias(const std::shared_ptr<Memory>& process_memory); 99 100 Memory* CreateMemory(const std::shared_ptr<Memory>& process_memory); 101 102 bool GetFunctionName(uint64_t addr, std::string* name, uint64_t* func_offset); 103 104 // Returns the raw build id read from the elf data. 105 std::string GetBuildID(); 106 107 // Returns the printable version of the build id (hex dump of raw data). 108 std::string GetPrintableBuildID(); 109 IsBlankMapInfo110 inline bool IsBlank() { return offset == 0 && flags == 0 && name.empty(); } 111 112 private: 113 MapInfo(const MapInfo&) = delete; 114 void operator=(const MapInfo&) = delete; 115 116 Memory* GetFileMemory(); 117 bool InitFileMemoryFromPreviousReadOnlyMap(MemoryFileAtOffset* memory); 118 119 // Protect the creation of the elf object. 120 std::mutex mutex_; 121 }; 122 123 } // namespace unwindstack 124 125 #endif // _LIBUNWINDSTACK_MAP_INFO_H 126