Ejemplo n.º 1
0
bool
DYLDRendezvous::ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry)
{
    size_t address_size = m_process->GetAddressByteSize();

    entry.clear();
    
    if (!(addr = ReadMemory(addr, &entry.base_addr, address_size)))
        return false;
    
    if (!(addr = ReadMemory(addr, &entry.path_addr, address_size)))
        return false;
    
    if (!(addr = ReadMemory(addr, &entry.dyn_addr, address_size)))
        return false;
    
    if (!(addr = ReadMemory(addr, &entry.next, address_size)))
        return false;
    
    if (!(addr = ReadMemory(addr, &entry.prev, address_size)))
        return false;
    
    entry.path = ReadStringFromMemory(entry.path_addr);
    
    return true;
}
Ejemplo n.º 2
0
bool
DYLDRendezvous::ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry)
{
    entry.clear();

    entry.link_addr = addr;
    
    if (!(addr = ReadPointer(addr, &entry.base_addr)))
        return false;

    // mips adds an extra load offset field to the link map struct on
    // FreeBSD and NetBSD (need to validate other OSes).
    // http://svnweb.freebsd.org/base/head/sys/sys/link_elf.h?revision=217153&view=markup#l57
    const ArchSpec &arch = m_process->GetTarget().GetArchitecture();
    if ((arch.GetTriple().getOS() == llvm::Triple::FreeBSD 
        || arch.GetTriple().getOS() == llvm::Triple::NetBSD) && 
        (arch.GetMachine() == llvm::Triple::mips || arch.GetMachine() == llvm::Triple::mipsel
        || arch.GetMachine() == llvm::Triple::mips64 || arch.GetMachine() == llvm::Triple::mips64el))
    {
        addr_t mips_l_offs;
        if (!(addr = ReadPointer(addr, &mips_l_offs)))
            return false;
        if (mips_l_offs != 0 && mips_l_offs != entry.base_addr)
            return false;
    }
    
    if (!(addr = ReadPointer(addr, &entry.path_addr)))
        return false;
    
    if (!(addr = ReadPointer(addr, &entry.dyn_addr)))
        return false;
    
    if (!(addr = ReadPointer(addr, &entry.next)))
        return false;
    
    if (!(addr = ReadPointer(addr, &entry.prev)))
        return false;

    std::string file_path = ReadStringFromMemory(entry.path_addr);
    entry.file_spec.SetFile(file_path, false);

    // On Android L (5.0, 5.1) the load address of the "/system/bin/linker" isn't filled in
    // correctly. To get the correct load address we fetch the load address of the file from the
    // proc file system.
    if (arch.GetTriple().getEnvironment() == llvm::Triple::Android && entry.base_addr == 0 &&
        (file_path == "/system/bin/linker" || file_path == "/system/bin/linker64"))
    {
        lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
        bool is_loaded = false;
        Error error = m_process->GetFileLoadAddress(entry.file_spec, is_loaded, load_addr);
        if (error.Success() && is_loaded)
            entry.base_addr = load_addr;
    }

    return true;
}
Ejemplo n.º 3
0
bool DYLDRendezvous::ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry) {
  entry.clear();

  entry.link_addr = addr;

  if (!(addr = ReadPointer(addr, &entry.base_addr)))
    return false;

  // mips adds an extra load offset field to the link map struct on
  // FreeBSD and NetBSD (need to validate other OSes).
  // http://svnweb.freebsd.org/base/head/sys/sys/link_elf.h?revision=217153&view=markup#l57
  const ArchSpec &arch = m_process->GetTarget().GetArchitecture();
  if ((arch.GetTriple().getOS() == llvm::Triple::FreeBSD ||
       arch.GetTriple().getOS() == llvm::Triple::NetBSD) &&
      (arch.GetMachine() == llvm::Triple::mips ||
       arch.GetMachine() == llvm::Triple::mipsel ||
       arch.GetMachine() == llvm::Triple::mips64 ||
       arch.GetMachine() == llvm::Triple::mips64el)) {
    addr_t mips_l_offs;
    if (!(addr = ReadPointer(addr, &mips_l_offs)))
      return false;
    if (mips_l_offs != 0 && mips_l_offs != entry.base_addr)
      return false;
  }

  if (!(addr = ReadPointer(addr, &entry.path_addr)))
    return false;

  if (!(addr = ReadPointer(addr, &entry.dyn_addr)))
    return false;

  if (!(addr = ReadPointer(addr, &entry.next)))
    return false;

  if (!(addr = ReadPointer(addr, &entry.prev)))
    return false;

  std::string file_path = ReadStringFromMemory(entry.path_addr);
  entry.file_spec.SetFile(file_path, false);

  UpdateBaseAddrIfNecessary(entry, file_path);

  return true;
}
Ejemplo n.º 4
0
bool
DYLDRendezvous::ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry)
{
    entry.clear();

    entry.link_addr = addr;
    
    if (!(addr = ReadPointer(addr, &entry.base_addr)))
        return false;

    // mips adds an extra load offset field to the link map struct on
    // FreeBSD and NetBSD (need to validate other OSes).
    // http://svnweb.freebsd.org/base/head/sys/sys/link_elf.h?revision=217153&view=markup#l57
    const ArchSpec &arch = m_process->GetTarget().GetArchitecture();
    if (arch.GetCore() == ArchSpec::eCore_mips64)
    {
        assert (arch.GetTriple().getOS() == llvm::Triple::FreeBSD ||
                arch.GetTriple().getOS() == llvm::Triple::NetBSD);
        addr_t mips_l_offs;
        if (!(addr = ReadPointer(addr, &mips_l_offs)))
            return false;
        if (mips_l_offs != 0 && mips_l_offs != entry.base_addr)
            return false;
    }
    
    if (!(addr = ReadPointer(addr, &entry.path_addr)))
        return false;
    
    if (!(addr = ReadPointer(addr, &entry.dyn_addr)))
        return false;
    
    if (!(addr = ReadPointer(addr, &entry.next)))
        return false;
    
    if (!(addr = ReadPointer(addr, &entry.prev)))
        return false;
    
    entry.path = ReadStringFromMemory(entry.path_addr);
    
    return true;
}
Ejemplo n.º 5
0
bool HexagonDYLDRendezvous::ReadSOEntryFromMemory(lldb::addr_t addr,
                                                  SOEntry &entry) {
  entry.clear();
  entry.link_addr = addr;

  if (!(addr = ReadPointer(addr, &entry.base_addr)))
    return false;

  if (!(addr = ReadPointer(addr, &entry.path_addr)))
    return false;

  if (!(addr = ReadPointer(addr, &entry.dyn_addr)))
    return false;

  if (!(addr = ReadPointer(addr, &entry.next)))
    return false;

  if (!(addr = ReadPointer(addr, &entry.prev)))
    return false;

  entry.path = ReadStringFromMemory(entry.path_addr);

  return true;
}
Ejemplo n.º 6
0
bool
DYLDRendezvous::ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry)
{
    entry.clear();

    entry.link_addr = addr;
    
    if (!(addr = ReadPointer(addr, &entry.base_addr)))
        return false;

    // mips adds an extra load offset field to the link map struct on
    // FreeBSD and NetBSD (need to validate other OSes).
    // http://svnweb.freebsd.org/base/head/sys/sys/link_elf.h?revision=217153&view=markup#l57
    const ArchSpec &arch = m_process->GetTarget().GetArchitecture();
    if ((arch.GetTriple().getOS() == llvm::Triple::FreeBSD 
        || arch.GetTriple().getOS() == llvm::Triple::NetBSD) && 
        (arch.GetMachine() == llvm::Triple::mips || arch.GetMachine() == llvm::Triple::mipsel
        || arch.GetMachine() == llvm::Triple::mips64 || arch.GetMachine() == llvm::Triple::mips64el))
    {
        addr_t mips_l_offs;
        if (!(addr = ReadPointer(addr, &mips_l_offs)))
            return false;
        if (mips_l_offs != 0 && mips_l_offs != entry.base_addr)
            return false;
    }
    
    if (!(addr = ReadPointer(addr, &entry.path_addr)))
        return false;
    
    if (!(addr = ReadPointer(addr, &entry.dyn_addr)))
        return false;
    
    if (!(addr = ReadPointer(addr, &entry.next)))
        return false;
    
    if (!(addr = ReadPointer(addr, &entry.prev)))
        return false;

    std::string file_path = ReadStringFromMemory(entry.path_addr);
    entry.file_spec.SetFile(file_path, false);

    // If the load bias reported by the linker is incorrect then fetch the load address of the file
    // from the proc file system.
    if (isLoadBiasIncorrect(m_process->GetTarget(), file_path))
    {
        lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
        bool is_loaded = false;
        Error error = m_process->GetFileLoadAddress(entry.file_spec, is_loaded, load_addr);
        if (error.Success() && is_loaded)
            entry.base_addr = load_addr;
    }

    // The base_addr is not filled in for some case.
    // Try to figure it out based on the load address of the object file.
    // The issue observed for '/system/bin/linker' on Android L (5.0, 5.1)
    if (entry.base_addr == 0)
    {
        lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
        bool is_loaded = false;
        Error error = m_process->GetFileLoadAddress(entry.file_spec, is_loaded, load_addr);
        if (error.Success() && is_loaded)
            entry.base_addr = load_addr;
    }

    // The base_addr is not filled in for some case.
    // Try to figure it out based on the load address of the object file.
    // The issue observed for '/system/bin/linker' on Android L (5.0, 5.1)
    if (entry.base_addr == 0)
    {
        lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
        bool is_loaded = false;
        Error error = m_process->GetFileLoadAddress(entry.file_spec, is_loaded, load_addr);
        if (error.Success() && is_loaded)
            entry.base_addr = load_addr;
    }

    return true;
}