Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bca82de1 authored by Christopher Ferris's avatar Christopher Ferris Committed by android-build-merger
Browse files

Merge "Implement support for linker rosegment option."

am: d3a7ddcf

Change-Id: I52f0c696e844a988ef358ca2d26759045f968606
parents adeed270 d3a7ddcf
Loading
Loading
Loading
Loading
+0 −4
Original line number Diff line number Diff line
@@ -116,10 +116,6 @@ cc_test_library {

    target: {
        linux_glibc: {
            // The host uses rosegment, which isn't supported yet.
            ldflags: [
                "-Wl,--no-rosegment",
            ],
            // This forces the creation of eh_frame with unwind information
            // for host.
            cflags: [
+2 −0
Original line number Diff line number Diff line
@@ -178,6 +178,7 @@ cc_test {
        "tests/JitDebugTest.cpp",
        "tests/LocalUnwinderTest.cpp",
        "tests/LogFake.cpp",
        "tests/MapInfoCreateMemoryTest.cpp",
        "tests/MapInfoGetElfTest.cpp",
        "tests/MapInfoGetLoadBiasTest.cpp",
        "tests/MapsTest.cpp",
@@ -188,6 +189,7 @@ cc_test {
        "tests/MemoryOfflineBufferTest.cpp",
        "tests/MemoryOfflineTest.cpp",
        "tests/MemoryRangeTest.cpp",
        "tests/MemoryRangesTest.cpp",
        "tests/MemoryRemoteTest.cpp",
        "tests/MemoryTest.cpp",
        "tests/RegsInfoTest.cpp",
+48 −1
Original line number Diff line number Diff line
@@ -102,7 +102,54 @@ Memory* MapInfo::CreateMemory(const std::shared_ptr<Memory>& process_memory) {
  if (!(flags & PROT_READ)) {
    return nullptr;
  }
  return new MemoryRange(process_memory, start, end - start, 0);

  // Need to verify that this elf is valid. It's possible that
  // only part of the elf file to be mapped into memory is in the executable
  // map. In this case, there will be another read-only map that includes the
  // first part of the elf file. This is done if the linker rosegment
  // option is used.
  std::unique_ptr<MemoryRange> memory(new MemoryRange(process_memory, start, end - start, 0));
  bool valid;
  uint64_t max_size;
  Elf::GetInfo(memory.get(), &valid, &max_size);
  if (valid) {
    // Valid elf, we are done.
    return memory.release();
  }

  if (name.empty() || maps_ == nullptr) {
    return nullptr;
  }

  // Find the read-only map that has the same name and has an offset closest
  // to the current offset but less than the offset of the current map.
  // For shared libraries, there should be a r-x map that has a non-zero
  // offset and then a r-- map that has a zero offset.
  // For shared libraries loaded from an apk, there should be a r-x map that
  // has a non-zero offset and then a r-- map that has a non-zero offset less
  // than the offset from the r-x map.
  uint64_t closest_offset = 0;
  MapInfo* ro_map_info = nullptr;
  for (auto map_info : *maps_) {
    if (map_info->flags == PROT_READ && map_info->name == name && map_info->offset < offset &&
        map_info->offset >= closest_offset) {
      ro_map_info = map_info;
      closest_offset = ro_map_info->offset;
    }
  }

  if (ro_map_info != nullptr) {
    // Make sure that relative pc values are corrected properly.
    elf_offset = offset - closest_offset;

    MemoryRanges* ranges = new MemoryRanges;
    ranges->Insert(new MemoryRange(process_memory, ro_map_info->start,
                                   ro_map_info->end - ro_map_info->start, 0));
    ranges->Insert(new MemoryRange(process_memory, start, end - start, elf_offset));

    return ranges;
  }
  return nullptr;
}

Elf* MapInfo::GetElf(const std::shared_ptr<Memory>& process_memory, bool init_gnu_debugdata) {
+3 −3
Original line number Diff line number Diff line
@@ -66,13 +66,13 @@ bool Maps::Parse() {
        if (strncmp(name, "/dev/", 5) == 0 && strncmp(name + 5, "ashmem/", 7) != 0) {
          flags |= unwindstack::MAPS_FLAGS_DEVICE_MAP;
        }
        maps_.push_back(new MapInfo(start, end, pgoff, flags, name));
        maps_.push_back(new MapInfo(this, start, end, pgoff, flags, name));
      });
}

void Maps::Add(uint64_t start, uint64_t end, uint64_t offset, uint64_t flags,
               const std::string& name, uint64_t load_bias) {
  MapInfo* map_info = new MapInfo(start, end, offset, flags, name);
  MapInfo* map_info = new MapInfo(this, start, end, offset, flags, name);
  map_info->load_bias = load_bias;
  maps_.push_back(map_info);
}
@@ -97,7 +97,7 @@ bool BufferMaps::Parse() {
        if (strncmp(name, "/dev/", 5) == 0 && strncmp(name + 5, "ashmem/", 7) != 0) {
          flags |= unwindstack::MAPS_FLAGS_DEVICE_MAP;
        }
        maps_.push_back(new MapInfo(start, end, pgoff, flags, name));
        maps_.push_back(new MapInfo(this, start, end, pgoff, flags, name));
      });
}

+12 −0
Original line number Diff line number Diff line
@@ -316,6 +316,18 @@ size_t MemoryRange::Read(uint64_t addr, void* dst, size_t size) {
  return memory_->Read(read_addr, dst, read_length);
}

void MemoryRanges::Insert(MemoryRange* memory) {
  maps_.emplace(memory->offset() + memory->length(), memory);
}

size_t MemoryRanges::Read(uint64_t addr, void* dst, size_t size) {
  auto entry = maps_.upper_bound(addr);
  if (entry != maps_.end()) {
    return entry->second->Read(addr, dst, size);
  }
  return 0;
}

bool MemoryOffline::Init(const std::string& file, uint64_t offset) {
  auto memory_file = std::make_shared<MemoryFileAtOffset>();
  if (!memory_file->Init(file, offset)) {
Loading