[Lldb-commits] [PATCH] D87868: [RFC] When calling the process mmap try to call all found instead of just the first one

Pavel Labath via Phabricator via lldb-commits lldb-commits at lists.llvm.org
Fri Oct 2 06:42:40 PDT 2020


labath added a comment.
Herald added a subscriber: pengfei.

That sounds like a plan. FWIW, here's the implementation I hacked up today:

  Status NativeProcessLinux::AllocateMemory(size_t size, uint32_t permissions,
                                            lldb::addr_t &addr) {
    PopulateMemoryRegionCache();
    auto region_it = llvm::find_if(m_mem_region_cache, [](const auto &pair) {
      return pair.first.GetExecutable() == MemoryRegionInfo::eYes;
    });
    if (region_it == m_mem_region_cache.end())
      return Status("No executable memory region found!");
    addr_t exe_addr = region_it->first.GetRange().GetRangeBase();
  
    NativeThreadLinux &thread = *GetThreadByID(GetID());
    assert(thread.GetState() == eStateStopped);
  
    int prot = PROT_NONE;
    if (permissions & ePermissionsReadable)
      prot |= PROT_READ;
    if (permissions & ePermissionsWritable)
      prot |= PROT_WRITE;
    if (permissions & ePermissionsExecutable)
      prot |= PROT_EXEC;
  
    NativeRegisterContextLinux &reg_ctx = thread.GetRegisterContext();
    DataBufferSP registers_sp;
    reg_ctx.ReadAllRegisterValues(registers_sp);
    uint8_t memory[2];
    size_t bytes_read;
    ReadMemory(exe_addr, memory, 2, bytes_read);
  
    reg_ctx.SetPC(exe_addr);
    reg_ctx.WriteRegisterFromUnsigned(lldb_rax_x86_64, SYS_mmap);
    reg_ctx.WriteRegisterFromUnsigned(lldb_rdi_x86_64, 0);
    reg_ctx.WriteRegisterFromUnsigned(lldb_rsi_x86_64, size);
    reg_ctx.WriteRegisterFromUnsigned(lldb_rdx_x86_64, prot);
    reg_ctx.WriteRegisterFromUnsigned(lldb_r10_x86_64,
                                      MAP_ANONYMOUS | MAP_PRIVATE);
    reg_ctx.WriteRegisterFromUnsigned(lldb_r8_x86_64, -1);
    reg_ctx.WriteRegisterFromUnsigned(lldb_r9_x86_64, 0);
    WriteMemory(exe_addr, "\x0f\x05", 2, bytes_read);
    PtraceWrapper(PTRACE_SINGLESTEP, thread.GetID(), nullptr, nullptr);
    int status;
    ::pid_t wait_pid = llvm::sys::RetryAfterSignal(-1, ::waitpid, thread.GetID(),
                                                   &status, __WALL);
    assert((unsigned)wait_pid == thread.GetID());
    addr = reg_ctx.ReadRegisterAsUnsigned(lldb_rax_x86_64, -ESRCH);
  
    WriteMemory(exe_addr, memory, 2, bytes_read);
    reg_ctx.WriteAllRegisterValues(registers_sp);
  
    if (addr > -4096)
      return Status(-addr, eErrorTypePOSIX);
    return Status();
  }

It needs more error handling, and generalization to non-x86 architectures, but it actually works, and is enough to make all but one test pass (TestBitfields.py seems to fail due to some data corruption -- quite puzzling).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D87868/new/

https://reviews.llvm.org/D87868



More information about the lldb-commits mailing list