Process.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. /*
  2. * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include "Process.h"
  7. Thread* Process::find_thread(pid_t tid, u64 timestamp)
  8. {
  9. auto it = threads.find(tid);
  10. if (it == threads.end())
  11. return nullptr;
  12. for (auto& thread : it->value) {
  13. if (thread.start_valid < timestamp && (thread.end_valid == 0 || thread.end_valid > timestamp))
  14. return &thread;
  15. }
  16. return nullptr;
  17. }
  18. void Process::handle_thread_create(pid_t tid, u64 timestamp)
  19. {
  20. auto it = threads.find(tid);
  21. if (it == threads.end()) {
  22. threads.set(tid, {});
  23. it = threads.find(tid);
  24. }
  25. auto thread = Thread { tid, timestamp, 0 };
  26. it->value.append(move(thread));
  27. }
  28. void Process::handle_thread_exit(pid_t tid, u64 timestamp)
  29. {
  30. auto* thread = find_thread(tid, timestamp);
  31. if (!thread)
  32. return;
  33. thread->end_valid = timestamp;
  34. }
  35. HashMap<String, OwnPtr<MappedObject>> g_mapped_object_cache;
  36. static MappedObject* get_or_create_mapped_object(const String& path)
  37. {
  38. if (auto it = g_mapped_object_cache.find(path); it != g_mapped_object_cache.end())
  39. return it->value.ptr();
  40. auto file_or_error = MappedFile::map(path);
  41. if (file_or_error.is_error()) {
  42. g_mapped_object_cache.set(path, {});
  43. return nullptr;
  44. }
  45. auto elf = ELF::Image(file_or_error.value()->bytes());
  46. if (!elf.is_valid()) {
  47. g_mapped_object_cache.set(path, {});
  48. return nullptr;
  49. }
  50. auto new_mapped_object = adopt_own(*new MappedObject {
  51. .file = file_or_error.release_value(),
  52. .elf = elf,
  53. });
  54. auto* ptr = new_mapped_object.ptr();
  55. g_mapped_object_cache.set(path, move(new_mapped_object));
  56. return ptr;
  57. }
  58. void LibraryMetadata::handle_mmap(FlatPtr base, size_t size, const String& name)
  59. {
  60. String path;
  61. if (name.contains("Loader.so"))
  62. path = "Loader.so";
  63. else if (!name.contains(":"))
  64. return;
  65. else
  66. path = name.substring(0, name.view().find_first_of(":").value());
  67. String full_path;
  68. if (name.contains(".so"))
  69. full_path = String::formatted("/usr/lib/{}", path);
  70. else
  71. full_path = path;
  72. auto* mapped_object = get_or_create_mapped_object(full_path);
  73. if (!mapped_object) {
  74. full_path = String::formatted("/usr/local/lib/{}", path);
  75. mapped_object = get_or_create_mapped_object(full_path);
  76. if (!mapped_object)
  77. return;
  78. }
  79. FlatPtr text_base {};
  80. mapped_object->elf.for_each_program_header([&](const ELF::Image::ProgramHeader& ph) {
  81. if (ph.is_executable())
  82. text_base = ph.vaddr().get();
  83. return IterationDecision::Continue;
  84. });
  85. m_libraries.set(name, adopt_own(*new Library { base, size, name, text_base, mapped_object }));
  86. }
  87. String LibraryMetadata::Library::symbolicate(FlatPtr ptr, u32* offset) const
  88. {
  89. if (!object)
  90. return String::formatted("?? <{:p}>", ptr);
  91. return object->elf.symbolicate(ptr - base + text_base, offset);
  92. }
  93. const LibraryMetadata::Library* LibraryMetadata::library_containing(FlatPtr ptr) const
  94. {
  95. for (auto& it : m_libraries) {
  96. auto& library = *it.value;
  97. if (ptr >= library.base && ptr < (library.base + library.size))
  98. return &library;
  99. }
  100. return nullptr;
  101. }