MapInfo.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. /*
  2. * Copyright (C) 2017 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. #include <sys/mman.h>
  17. #include <sys/types.h>
  18. #include <unistd.h>
  19. #include <memory>
  20. #include <mutex>
  21. #include <string>
  22. #include <android-base/stringprintf.h>
  23. #include <unwindstack/Elf.h>
  24. #include <unwindstack/MapInfo.h>
  25. #include <unwindstack/Maps.h>
  26. #include <unwindstack/Memory.h>
  27. namespace unwindstack {
  28. bool MapInfo::InitFileMemoryFromPreviousReadOnlyMap(MemoryFileAtOffset* memory) {
  29. // One last attempt, see if the previous map is read-only with the
  30. // same name and stretches across this map.
  31. if (prev_map == nullptr || prev_map->flags != PROT_READ) {
  32. return false;
  33. }
  34. uint64_t map_size = end - prev_map->end;
  35. if (!memory->Init(name, prev_map->offset, map_size)) {
  36. return false;
  37. }
  38. uint64_t max_size;
  39. if (!Elf::GetInfo(memory, &max_size) || max_size < map_size) {
  40. return false;
  41. }
  42. if (!memory->Init(name, prev_map->offset, max_size)) {
  43. return false;
  44. }
  45. elf_offset = offset - prev_map->offset;
  46. elf_start_offset = prev_map->offset;
  47. return true;
  48. }
  49. Memory* MapInfo::GetFileMemory() {
  50. std::unique_ptr<MemoryFileAtOffset> memory(new MemoryFileAtOffset);
  51. if (offset == 0) {
  52. if (memory->Init(name, 0)) {
  53. return memory.release();
  54. }
  55. return nullptr;
  56. }
  57. // These are the possibilities when the offset is non-zero.
  58. // - There is an elf file embedded in a file, and the offset is the
  59. // the start of the elf in the file.
  60. // - There is an elf file embedded in a file, and the offset is the
  61. // the start of the executable part of the file. The actual start
  62. // of the elf is in the read-only segment preceeding this map.
  63. // - The whole file is an elf file, and the offset needs to be saved.
  64. //
  65. // Map in just the part of the file for the map. If this is not
  66. // a valid elf, then reinit as if the whole file is an elf file.
  67. // If the offset is a valid elf, then determine the size of the map
  68. // and reinit to that size. This is needed because the dynamic linker
  69. // only maps in a portion of the original elf, and never the symbol
  70. // file data.
  71. uint64_t map_size = end - start;
  72. if (!memory->Init(name, offset, map_size)) {
  73. return nullptr;
  74. }
  75. // Check if the start of this map is an embedded elf.
  76. uint64_t max_size = 0;
  77. if (Elf::GetInfo(memory.get(), &max_size)) {
  78. elf_start_offset = offset;
  79. if (max_size > map_size) {
  80. if (memory->Init(name, offset, max_size)) {
  81. return memory.release();
  82. }
  83. // Try to reinit using the default map_size.
  84. if (memory->Init(name, offset, map_size)) {
  85. return memory.release();
  86. }
  87. elf_start_offset = 0;
  88. return nullptr;
  89. }
  90. return memory.release();
  91. }
  92. // No elf at offset, try to init as if the whole file is an elf.
  93. if (memory->Init(name, 0) && Elf::IsValidElf(memory.get())) {
  94. elf_offset = offset;
  95. // Need to check how to set the elf start offset. If this map is not
  96. // the r-x map of a r-- map, then use the real offset value. Otherwise,
  97. // use 0.
  98. if (prev_map == nullptr || prev_map->offset != 0 || prev_map->flags != PROT_READ ||
  99. prev_map->name != name) {
  100. elf_start_offset = offset;
  101. }
  102. return memory.release();
  103. }
  104. // See if the map previous to this one contains a read-only map
  105. // that represents the real start of the elf data.
  106. if (InitFileMemoryFromPreviousReadOnlyMap(memory.get())) {
  107. return memory.release();
  108. }
  109. // Failed to find elf at start of file or at read-only map, return
  110. // file object from the current map.
  111. if (memory->Init(name, offset, map_size)) {
  112. return memory.release();
  113. }
  114. return nullptr;
  115. }
  116. Memory* MapInfo::CreateMemory(const std::shared_ptr<Memory>& process_memory) {
  117. if (end <= start) {
  118. return nullptr;
  119. }
  120. elf_offset = 0;
  121. // Fail on device maps.
  122. if (flags & MAPS_FLAGS_DEVICE_MAP) {
  123. return nullptr;
  124. }
  125. // First try and use the file associated with the info.
  126. if (!name.empty()) {
  127. Memory* memory = GetFileMemory();
  128. if (memory != nullptr) {
  129. return memory;
  130. }
  131. }
  132. if (process_memory == nullptr) {
  133. return nullptr;
  134. }
  135. // Need to verify that this elf is valid. It's possible that
  136. // only part of the elf file to be mapped into memory is in the executable
  137. // map. In this case, there will be another read-only map that includes the
  138. // first part of the elf file. This is done if the linker rosegment
  139. // option is used.
  140. std::unique_ptr<MemoryRange> memory(new MemoryRange(process_memory, start, end - start, 0));
  141. if (Elf::IsValidElf(memory.get())) {
  142. memory_backed_elf = true;
  143. return memory.release();
  144. }
  145. // Find the read-only map by looking at the previous map. The linker
  146. // doesn't guarantee that this invariant will always be true. However,
  147. // if that changes, there is likely something else that will change and
  148. // break something.
  149. if (offset == 0 || name.empty() || prev_map == nullptr || prev_map->name != name ||
  150. prev_map->offset >= offset) {
  151. return nullptr;
  152. }
  153. // Make sure that relative pc values are corrected properly.
  154. elf_offset = offset - prev_map->offset;
  155. // Use this as the elf start offset, otherwise, you always get offsets into
  156. // the r-x section, which is not quite the right information.
  157. elf_start_offset = prev_map->offset;
  158. MemoryRanges* ranges = new MemoryRanges;
  159. ranges->Insert(
  160. new MemoryRange(process_memory, prev_map->start, prev_map->end - prev_map->start, 0));
  161. ranges->Insert(new MemoryRange(process_memory, start, end - start, elf_offset));
  162. memory_backed_elf = true;
  163. return ranges;
  164. }
  165. Elf* MapInfo::GetElf(const std::shared_ptr<Memory>& process_memory, ArchEnum expected_arch) {
  166. {
  167. // Make sure no other thread is trying to add the elf to this map.
  168. std::lock_guard<std::mutex> guard(mutex_);
  169. if (elf.get() != nullptr) {
  170. return elf.get();
  171. }
  172. bool locked = false;
  173. if (Elf::CachingEnabled() && !name.empty()) {
  174. Elf::CacheLock();
  175. locked = true;
  176. if (Elf::CacheGet(this)) {
  177. Elf::CacheUnlock();
  178. return elf.get();
  179. }
  180. }
  181. Memory* memory = CreateMemory(process_memory);
  182. if (locked) {
  183. if (Elf::CacheAfterCreateMemory(this)) {
  184. delete memory;
  185. Elf::CacheUnlock();
  186. return elf.get();
  187. }
  188. }
  189. elf.reset(new Elf(memory));
  190. // If the init fails, keep the elf around as an invalid object so we
  191. // don't try to reinit the object.
  192. elf->Init();
  193. if (elf->valid() && expected_arch != elf->arch()) {
  194. // Make the elf invalid, mismatch between arch and expected arch.
  195. elf->Invalidate();
  196. }
  197. if (locked) {
  198. Elf::CacheAdd(this);
  199. Elf::CacheUnlock();
  200. }
  201. }
  202. // If there is a read-only map then a read-execute map that represents the
  203. // same elf object, make sure the previous map is using the same elf
  204. // object if it hasn't already been set.
  205. if (prev_map != nullptr && elf_start_offset != offset && prev_map->offset == elf_start_offset &&
  206. prev_map->name == name) {
  207. std::lock_guard<std::mutex> guard(prev_map->mutex_);
  208. if (prev_map->elf.get() == nullptr) {
  209. prev_map->elf = elf;
  210. prev_map->memory_backed_elf = memory_backed_elf;
  211. }
  212. }
  213. return elf.get();
  214. }
  215. bool MapInfo::GetFunctionName(uint64_t addr, std::string* name, uint64_t* func_offset) {
  216. {
  217. // Make sure no other thread is trying to update this elf object.
  218. std::lock_guard<std::mutex> guard(mutex_);
  219. if (elf == nullptr) {
  220. return false;
  221. }
  222. }
  223. // No longer need the lock, once the elf object is created, it is not deleted
  224. // until this object is deleted.
  225. return elf->GetFunctionName(addr, name, func_offset);
  226. }
  227. uint64_t MapInfo::GetLoadBias(const std::shared_ptr<Memory>& process_memory) {
  228. uint64_t cur_load_bias = load_bias.load();
  229. if (cur_load_bias != static_cast<uint64_t>(-1)) {
  230. return cur_load_bias;
  231. }
  232. {
  233. // Make sure no other thread is trying to add the elf to this map.
  234. std::lock_guard<std::mutex> guard(mutex_);
  235. if (elf != nullptr) {
  236. if (elf->valid()) {
  237. cur_load_bias = elf->GetLoadBias();
  238. load_bias = cur_load_bias;
  239. return cur_load_bias;
  240. } else {
  241. load_bias = 0;
  242. return 0;
  243. }
  244. }
  245. }
  246. // Call lightweight static function that will only read enough of the
  247. // elf data to get the load bias.
  248. std::unique_ptr<Memory> memory(CreateMemory(process_memory));
  249. cur_load_bias = Elf::GetLoadBias(memory.get());
  250. load_bias = cur_load_bias;
  251. return cur_load_bias;
  252. }
  253. MapInfo::~MapInfo() {
  254. uintptr_t id = build_id.load();
  255. if (id != 0) {
  256. delete reinterpret_cast<std::string*>(id);
  257. }
  258. }
  259. std::string MapInfo::GetBuildID() {
  260. uintptr_t id = build_id.load();
  261. if (build_id != 0) {
  262. return *reinterpret_cast<std::string*>(id);
  263. }
  264. // No need to lock, at worst if multiple threads do this at the same
  265. // time it should be detected and only one thread should win and
  266. // save the data.
  267. std::unique_ptr<std::string> cur_build_id(new std::string);
  268. // Now need to see if the elf object exists.
  269. // Make sure no other thread is trying to add the elf to this map.
  270. mutex_.lock();
  271. Elf* elf_obj = elf.get();
  272. mutex_.unlock();
  273. if (elf_obj != nullptr) {
  274. *cur_build_id = elf_obj->GetBuildID();
  275. } else {
  276. // This will only work if we can get the file associated with this memory.
  277. // If this is only available in memory, then the section name information
  278. // is not present and we will not be able to find the build id info.
  279. std::unique_ptr<Memory> memory(GetFileMemory());
  280. if (memory != nullptr) {
  281. *cur_build_id = Elf::GetBuildID(memory.get());
  282. }
  283. }
  284. id = reinterpret_cast<uintptr_t>(cur_build_id.get());
  285. uintptr_t expected_id = 0;
  286. if (build_id.compare_exchange_weak(expected_id, id)) {
  287. // Value saved, so make sure the memory is not freed.
  288. cur_build_id.release();
  289. }
  290. return *reinterpret_cast<std::string*>(id);
  291. }
  292. std::string MapInfo::GetPrintableBuildID() {
  293. std::string raw_build_id = GetBuildID();
  294. if (raw_build_id.empty()) {
  295. return "";
  296. }
  297. std::string printable_build_id;
  298. for (const char& c : raw_build_id) {
  299. // Use %hhx to avoid sign extension on abis that have signed chars.
  300. printable_build_id += android::base::StringPrintf("%02hhx", c);
  301. }
  302. return printable_build_id;
  303. }
  304. } // namespace unwindstack