Beispiel #1
0
void
HostInfoBase::ComputeHostArchitectureSupport(ArchSpec &arch_32, ArchSpec &arch_64)
{
    llvm::Triple triple(llvm::sys::getProcessTriple());

    arch_32.Clear();
    arch_64.Clear();

    switch (triple.getArch())
    {
        default:
            arch_32.SetTriple(triple);
            break;

        case llvm::Triple::aarch64:
        case llvm::Triple::ppc64:
        case llvm::Triple::x86_64:
            arch_64.SetTriple(triple);
            arch_32.SetTriple(triple.get32BitArchVariant());
            break;

        case llvm::Triple::mips64:
        case llvm::Triple::mips64el:
        case llvm::Triple::sparcv9:
        case llvm::Triple::systemz:
            arch_64.SetTriple(triple);
            break;
    }
}
ObjectFile *
ObjectContainerUniversalMachO::GetObjectFile (const FileSpec *file)
{
    uint32_t arch_idx = 0;
    ArchSpec arch;
    // If the module hasn't specified an architecture yet, set it to the default 
    // architecture:
    if (!m_module->GetArchitecture().IsValid())
    {
        arch = Target::GetDefaultArchitecture ();
        if (!arch.IsValid())
            arch.SetTriple (LLDB_ARCH_DEFAULT);
    }
    else
        arch = m_module->GetArchitecture();
        
    ArchSpec curr_arch;
    for (arch_idx = 0; arch_idx < m_header.nfat_arch; ++arch_idx)
    {
        if (GetArchitectureAtIndex (arch_idx, curr_arch))
        {
            if (arch == curr_arch)
            {
                return ObjectFile::FindPlugin (m_module, file, m_offset + m_fat_archs[arch_idx].offset, m_fat_archs[arch_idx].size);
            }
        }
    }
    return NULL;
}
bool OptionGroupArchitecture::GetArchitecture(Platform *platform,
                                              ArchSpec &arch) {
  if (m_arch_str.empty())
    arch.Clear();
  else
    arch.SetTriple(m_arch_str.c_str(), platform);
  return arch.IsValid();
}
Beispiel #4
0
size_t
ObjectFilePECOFF::GetModuleSpecifications (const lldb_private::FileSpec& file,
                                           lldb::DataBufferSP& data_sp,
                                           lldb::offset_t data_offset,
                                           lldb::offset_t file_offset,
                                           lldb::offset_t length,
                                           lldb_private::ModuleSpecList &specs)
{
    const size_t initial_count = specs.GetSize();

    if (ObjectFilePECOFF::MagicBytesMatch(data_sp))
    {
        DataExtractor data;
        data.SetData(data_sp, data_offset, length);
        data.SetByteOrder(eByteOrderLittle);

        dos_header_t dos_header;
        coff_header_t coff_header;

        if (ParseDOSHeader(data, dos_header))
        {
            lldb::offset_t offset = dos_header.e_lfanew;
            uint32_t pe_signature = data.GetU32(&offset);
            if (pe_signature != IMAGE_NT_SIGNATURE)
                return false;
            if (ParseCOFFHeader(data, &offset, coff_header))
            {
                ArchSpec spec;
                if (coff_header.machine == MachineAmd64)
                {
                    spec.SetTriple("x86_64-pc-windows");
                    specs.Append(ModuleSpec(file, spec));
                }
                else if (coff_header.machine == MachineX86)
                {
                    spec.SetTriple("i386-pc-windows");
                    specs.Append(ModuleSpec(file, spec));
                    spec.SetTriple("i686-pc-windows");
                    specs.Append(ModuleSpec(file, spec));
                }
            }
        }
    }

    return specs.GetSize() - initial_count;
}
bool
PlatformLinux::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
{
    if (IsHost())
    {
        ArchSpec hostArch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
        if (hostArch.GetTriple().isOSLinux())
        {
            if (idx == 0)
            {
                arch = hostArch;
                return arch.IsValid();
            }
            else if (idx == 1)
            {
                // If the default host architecture is 64-bit, look for a 32-bit variant
                if (hostArch.IsValid() && hostArch.GetTriple().isArch64Bit())
                {
                    arch = HostInfo::GetArchitecture(HostInfo::eArchKind32);
                    return arch.IsValid();
                }
            }
        }
    }
    else
    {
        if (m_remote_platform_sp)
            return m_remote_platform_sp->GetSupportedArchitectureAtIndex(idx, arch);

        llvm::Triple triple;
        // Set the OS to linux
        triple.setOS(llvm::Triple::Linux);
        // Set the architecture
        switch (idx)
        {
            case 0: triple.setArchName("x86_64"); break;
            case 1: triple.setArchName("i386"); break;
            case 2: triple.setArchName("arm"); break;
            case 3: triple.setArchName("aarch64"); break;
            case 4: triple.setArchName("mips64"); break;
            case 5: triple.setArchName("hexagon"); break;
            case 6: triple.setArchName("mips"); break;
            case 7: triple.setArchName("mips64el"); break;
            case 8: triple.setArchName("mipsel"); break;
            default: return false;
        }
        // Leave the vendor as "llvm::Triple:UnknownVendor" and don't specify the vendor by
        // calling triple.SetVendorName("unknown") so that it is a "unspecified unknown".
        // This means when someone calls triple.GetVendorName() it will return an empty string
        // which indicates that the vendor can be set when two architectures are merged

        // Now set the triple into "arch" and return true
        arch.SetTriple(triple);
        return true;
    }
    return false;
}
bool PlatformRemoteGDBServer::GetSupportedArchitectureAtIndex(uint32_t idx,
                                                              ArchSpec &arch) {
  ArchSpec remote_arch = m_gdb_client.GetSystemArchitecture();

  if (idx == 0) {
    arch = remote_arch;
    return arch.IsValid();
  } else if (idx == 1 && remote_arch.IsValid() &&
             remote_arch.GetTriple().isArch64Bit()) {
    arch.SetTriple(remote_arch.GetTriple().get32BitArchVariant());
    return arch.IsValid();
  }
  return false;
}
Beispiel #7
0
bool PlatformOpenBSD::GetSupportedArchitectureAtIndex(uint32_t idx,
						      ArchSpec &arch) {
  if (IsHost()) {
    ArchSpec hostArch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
    if (hostArch.GetTriple().isOSOpenBSD()) {
      if (idx == 0) {
        arch = hostArch;
        return arch.IsValid();
      }
    }
  } else {
    if (m_remote_platform_sp)
      return m_remote_platform_sp->GetSupportedArchitectureAtIndex(idx, arch);

    llvm::Triple triple;
    // Set the OS to OpenBSD
    triple.setOS(llvm::Triple::OpenBSD);
    // Set the architecture
    switch (idx) {
    case 0:
      triple.setArchName("x86_64");
      break;
    case 1:
      triple.setArchName("i386");
      break;
    case 2:
      triple.setArchName("aarch64");
      break;
    case 3:
      triple.setArchName("arm");
      break;
    default:
      return false;
    }
    // Leave the vendor as "llvm::Triple:UnknownVendor" and don't specify the
    // vendor by
    // calling triple.SetVendorName("unknown") so that it is a "unspecified
    // unknown".
    // This means when someone calls triple.GetVendorName() it will return an
    // empty string
    // which indicates that the vendor can be set when two architectures are
    // merged

    // Now set the triple into "arch" and return true
    arch.SetTriple(triple);
    return true;
  }
  return false;
}
ObjectFileSP
ObjectContainerUniversalMachO::GetObjectFile(const FileSpec *file) {
  uint32_t arch_idx = 0;
  ArchSpec arch;
  // If the module hasn't specified an architecture yet, set it to the default
  // architecture:
  ModuleSP module_sp(GetModule());
  if (module_sp) {
    if (!module_sp->GetArchitecture().IsValid()) {
      arch = Target::GetDefaultArchitecture();
      if (!arch.IsValid())
        arch.SetTriple(LLDB_ARCH_DEFAULT);
    } else
      arch = module_sp->GetArchitecture();

    ArchSpec curr_arch;
    // First, try to find an exact match for the Arch of the Target.
    for (arch_idx = 0; arch_idx < m_header.nfat_arch; ++arch_idx) {
      if (GetArchitectureAtIndex(arch_idx, curr_arch) &&
          arch.IsExactMatch(curr_arch))
        break;
    }

    // Failing an exact match, try to find a compatible Arch of the Target.
    if (arch_idx >= m_header.nfat_arch) {
      for (arch_idx = 0; arch_idx < m_header.nfat_arch; ++arch_idx) {
        if (GetArchitectureAtIndex(arch_idx, curr_arch) &&
            arch.IsCompatibleMatch(curr_arch))
          break;
      }
    }

    if (arch_idx < m_header.nfat_arch) {
      DataBufferSP data_sp;
      lldb::offset_t data_offset = 0;
      return ObjectFile::FindPlugin(
          module_sp, file, m_offset + m_fat_archs[arch_idx].offset,
          m_fat_archs[arch_idx].size, data_sp, data_offset);
    }
  }
  return ObjectFileSP();
}
Beispiel #9
0
TEST(ArchSpecTest, TestSetTriple) {
  ArchSpec AS;

  // Various flavors of valid triples.
  EXPECT_TRUE(AS.SetTriple("12-10-apple-darwin"));
  EXPECT_EQ(uint32_t(llvm::MachO::CPU_TYPE_ARM), AS.GetMachOCPUType());
  EXPECT_EQ(10u, AS.GetMachOCPUSubType());
  EXPECT_TRUE(llvm::StringRef(AS.GetTriple().str())
                  .consume_front("armv7f-apple-darwin"));
  EXPECT_EQ(ArchSpec::eCore_arm_armv7f, AS.GetCore());

  AS = ArchSpec();
  EXPECT_TRUE(AS.SetTriple("18.100-apple-darwin"));
  EXPECT_EQ(uint32_t(llvm::MachO::CPU_TYPE_POWERPC), AS.GetMachOCPUType());
  EXPECT_EQ(100u, AS.GetMachOCPUSubType());
  EXPECT_TRUE(llvm::StringRef(AS.GetTriple().str())
                  .consume_front("powerpc-apple-darwin"));
  EXPECT_EQ(ArchSpec::eCore_ppc_ppc970, AS.GetCore());

  AS = ArchSpec();
  EXPECT_TRUE(AS.SetTriple("i686-pc-windows"));
  EXPECT_EQ(llvm::Triple::x86, AS.GetTriple().getArch());
  EXPECT_EQ(llvm::Triple::PC, AS.GetTriple().getVendor());
  EXPECT_EQ(llvm::Triple::Win32, AS.GetTriple().getOS());
  EXPECT_TRUE(
      llvm::StringRef(AS.GetTriple().str()).consume_front("i686-pc-windows"));
  EXPECT_STREQ("i686", AS.GetArchitectureName());
  EXPECT_EQ(ArchSpec::eCore_x86_32_i686, AS.GetCore());

  // Various flavors of invalid triples.
  AS = ArchSpec();
  EXPECT_FALSE(AS.SetTriple("unknown-unknown-unknown"));

  AS = ArchSpec();
  EXPECT_FALSE(AS.SetTriple("unknown"));

  AS = ArchSpec();
  EXPECT_FALSE(AS.SetTriple(""));
}
bool PlatformRemoteAppleWatch::GetSupportedArchitectureAtIndex(uint32_t idx,
                                                               ArchSpec &arch) {
  ArchSpec system_arch(GetSystemArchitecture());

  const ArchSpec::Core system_core = system_arch.GetCore();
  switch (system_core) {
  default:
    switch (idx) {
    case 0:
      arch.SetTriple("arm64-apple-watchos");
      return true;
    case 1:
      arch.SetTriple("armv7k-apple-watchos");
      return true;
    case 2:
      arch.SetTriple("armv7s-apple-watchos");
      return true;
    case 3:
      arch.SetTriple("armv7-apple-watchos");
      return true;
    case 4:
      arch.SetTriple("thumbv7k-apple-watchos");
      return true;
    case 5:
      arch.SetTriple("thumbv7-apple-watchos");
      return true;
    case 6:
      arch.SetTriple("thumbv7s-apple-watchos");
      return true;
    default:
      break;
    }
    break;

  case ArchSpec::eCore_arm_arm64:
    switch (idx) {
    case 0:
      arch.SetTriple("arm64-apple-watchos");
      return true;
    case 1:
      arch.SetTriple("armv7k-apple-watchos");
      return true;
    case 2:
      arch.SetTriple("armv7s-apple-watchos");
      return true;
    case 3:
      arch.SetTriple("armv7-apple-watchos");
      return true;
    case 4:
      arch.SetTriple("thumbv7k-apple-watchos");
      return true;
    case 5:
      arch.SetTriple("thumbv7-apple-watchos");
      return true;
    case 6:
      arch.SetTriple("thumbv7s-apple-watchos");
      return true;
    default:
      break;
    }
    break;

  case ArchSpec::eCore_arm_armv7k:
    switch (idx) {
    case 0:
      arch.SetTriple("armv7k-apple-watchos");
      return true;
    case 1:
      arch.SetTriple("armv7s-apple-watchos");
      return true;
    case 2:
      arch.SetTriple("armv7-apple-watchos");
      return true;
    case 3:
      arch.SetTriple("thumbv7k-apple-watchos");
      return true;
    case 4:
      arch.SetTriple("thumbv7-apple-watchos");
      return true;
    case 5:
      arch.SetTriple("thumbv7s-apple-watchos");
      return true;
    default:
      break;
    }
    break;

  case ArchSpec::eCore_arm_armv7s:
    switch (idx) {
    case 0:
      arch.SetTriple("armv7s-apple-watchos");
      return true;
    case 1:
      arch.SetTriple("armv7k-apple-watchos");
      return true;
    case 2:
      arch.SetTriple("armv7-apple-watchos");
      return true;
    case 3:
      arch.SetTriple("thumbv7k-apple-watchos");
      return true;
    case 4:
      arch.SetTriple("thumbv7-apple-watchos");
      return true;
    case 5:
      arch.SetTriple("thumbv7s-apple-watchos");
      return true;
    default:
      break;
    }
    break;

  case ArchSpec::eCore_arm_armv7:
    switch (idx) {
    case 0:
      arch.SetTriple("armv7-apple-watchos");
      return true;
    case 1:
      arch.SetTriple("armv7k-apple-watchos");
      return true;
    case 2:
      arch.SetTriple("thumbv7k-apple-watchos");
      return true;
    case 3:
      arch.SetTriple("thumbv7-apple-watchos");
      return true;
    default:
      break;
    }
    break;
  }
  arch.Clear();
  return false;
}
//----------------------------------------------------------------------
// Process Control
//----------------------------------------------------------------------
Error
ProcessMachCore::DoLoadCore ()
{
    Error error;
    if (!m_core_module_sp)
    {
        error.SetErrorString ("invalid core module");   
        return error;
    }

    ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
    if (core_objfile == NULL)
    {
        error.SetErrorString ("invalid core object file");   
        return error;
    }
    
    if (core_objfile->GetNumThreadContexts() == 0)
    {
        error.SetErrorString ("core file doesn't contain any LC_THREAD load commands, or the LC_THREAD architecture is not supported in this lldb");
        return error;
    }

    SectionList *section_list = core_objfile->GetSectionList();
    if (section_list == NULL)
    {
        error.SetErrorString ("core file has no sections");   
        return error;
    }
        
    const uint32_t num_sections = section_list->GetNumSections(0);
    if (num_sections == 0)
    {
        error.SetErrorString ("core file has no sections");   
        return error;
    }
    
    SetCanJIT(false);

    llvm::MachO::mach_header header;
    DataExtractor data (&header, 
                        sizeof(header), 
                        m_core_module_sp->GetArchitecture().GetByteOrder(),
                        m_core_module_sp->GetArchitecture().GetAddressByteSize());

    bool ranges_are_sorted = true;
    addr_t vm_addr = 0;
    for (uint32_t i=0; i<num_sections; ++i)
    {
        Section *section = section_list->GetSectionAtIndex (i).get();
        if (section)
        {
            lldb::addr_t section_vm_addr = section->GetFileAddress();
            FileRange file_range (section->GetFileOffset(), section->GetFileSize());
            VMRangeToFileOffset::Entry range_entry (section_vm_addr,
                                                    section->GetByteSize(),
                                                    file_range);
            
            if (vm_addr > section_vm_addr)
                ranges_are_sorted = false;
            vm_addr = section->GetFileAddress();
            VMRangeToFileOffset::Entry *last_entry = m_core_aranges.Back();
//            printf ("LC_SEGMENT[%u] arange=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), frange=[0x%8.8x - 0x%8.8x)\n",
//                    i, 
//                    range_entry.GetRangeBase(),
//                    range_entry.GetRangeEnd(),
//                    range_entry.data.GetRangeBase(),
//                    range_entry.data.GetRangeEnd());

            if (last_entry &&
                last_entry->GetRangeEnd() == range_entry.GetRangeBase() &&
                last_entry->data.GetRangeEnd() == range_entry.data.GetRangeBase())
            {
                last_entry->SetRangeEnd (range_entry.GetRangeEnd());
                last_entry->data.SetRangeEnd (range_entry.data.GetRangeEnd());
                //puts("combine");
            }
            else
            {
                m_core_aranges.Append(range_entry);
            }
        }
    }
    if (!ranges_are_sorted)
    {
        m_core_aranges.Sort();
    }

    if (m_dyld_addr == LLDB_INVALID_ADDRESS || m_mach_kernel_addr == LLDB_INVALID_ADDRESS)
    {
        // We need to locate the main executable in the memory ranges
        // we have in the core file.  We need to search for both a user-process dyld binary
        // and a kernel binary in memory; we must look at all the pages in the binary so
        // we don't miss one or the other.  If we find a user-process dyld binary, stop
        // searching -- that's the one we'll prefer over the mach kernel.
        const size_t num_core_aranges = m_core_aranges.GetSize();
        for (size_t i=0; i<num_core_aranges && m_dyld_addr == LLDB_INVALID_ADDRESS; ++i)
        {
            const VMRangeToFileOffset::Entry *entry = m_core_aranges.GetEntryAtIndex(i);
            lldb::addr_t section_vm_addr_start = entry->GetRangeBase();
            lldb::addr_t section_vm_addr_end = entry->GetRangeEnd();
            for (lldb::addr_t section_vm_addr = section_vm_addr_start;
                 section_vm_addr < section_vm_addr_end;
                 section_vm_addr += 0x1000)
            {
                GetDynamicLoaderAddress (section_vm_addr);
            }
        }
    }

    // If we found both a user-process dyld and a kernel binary, we need to decide
    // which to prefer.
    if (GetCorefilePreference() == eKernelCorefile)
    {
        if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS)
        {
            m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
        }
        else if (m_dyld_addr != LLDB_INVALID_ADDRESS)
        {
            m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
        }
    }
    else
    {
        if (m_dyld_addr != LLDB_INVALID_ADDRESS)
        {
            m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
        }
        else if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS)
        {
            m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
        }
    }

    // Even if the architecture is set in the target, we need to override
    // it to match the core file which is always single arch.
    ArchSpec arch (m_core_module_sp->GetArchitecture());
    if (arch.GetCore() == ArchSpec::eCore_x86_32_i486)
    {
        arch.SetTriple ("i386", m_target.GetPlatform().get());
    }
    if (arch.IsValid())
        m_target.SetArchitecture(arch);            

    return error;
}
Beispiel #12
0
const ArchSpec &
Host::GetArchitecture (SystemDefaultArchitecture arch_kind)
{
    static bool g_supports_32 = false;
    static bool g_supports_64 = false;
    static ArchSpec g_host_arch_32;
    static ArchSpec g_host_arch_64;

#if defined (__APPLE__)

    // Apple is different in that it can support both 32 and 64 bit executables
    // in the same operating system running concurrently. Here we detect the
    // correct host architectures for both 32 and 64 bit including if 64 bit
    // executables are supported on the system.

    if (g_supports_32 == false && g_supports_64 == false)
    {
        // All apple systems support 32 bit execution.
        g_supports_32 = true;
        uint32_t cputype, cpusubtype;
        uint32_t is_64_bit_capable = false;
        size_t len = sizeof(cputype);
        ArchSpec host_arch;
        // These will tell us about the kernel architecture, which even on a 64
        // bit machine can be 32 bit...
        if  (::sysctlbyname("hw.cputype", &cputype, &len, NULL, 0) == 0)
        {
            len = sizeof (cpusubtype);
            if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) != 0)
                cpusubtype = CPU_TYPE_ANY;
                
            len = sizeof (is_64_bit_capable);
            if  (::sysctlbyname("hw.cpu64bit_capable", &is_64_bit_capable, &len, NULL, 0) == 0)
            {
                if (is_64_bit_capable)
                    g_supports_64 = true;
            }
            
            if (is_64_bit_capable)
            {
#if defined (__i386__) || defined (__x86_64__)
                if (cpusubtype == CPU_SUBTYPE_486)
                    cpusubtype = CPU_SUBTYPE_I386_ALL;
#endif
                if (cputype & CPU_ARCH_ABI64)
                {
                    // We have a 64 bit kernel on a 64 bit system
                    g_host_arch_32.SetArchitecture (eArchTypeMachO, ~(CPU_ARCH_MASK) & cputype, cpusubtype);
                    g_host_arch_64.SetArchitecture (eArchTypeMachO, cputype, cpusubtype);
                }
                else
                {
                    // We have a 32 bit kernel on a 64 bit system
                    g_host_arch_32.SetArchitecture (eArchTypeMachO, cputype, cpusubtype);
                    cputype |= CPU_ARCH_ABI64;
                    g_host_arch_64.SetArchitecture (eArchTypeMachO, cputype, cpusubtype);
                }
            }
            else
            {
                g_host_arch_32.SetArchitecture (eArchTypeMachO, cputype, cpusubtype);
                g_host_arch_64.Clear();
            }
        }
    }
    
#else // #if defined (__APPLE__)

    if (g_supports_32 == false && g_supports_64 == false)
    {
        llvm::Triple triple(llvm::sys::getDefaultTargetTriple());

        g_host_arch_32.Clear();
        g_host_arch_64.Clear();

        switch (triple.getArch())
        {
        default:
            g_host_arch_32.SetTriple(triple);
            g_supports_32 = true;
            break;

        case llvm::Triple::x86_64:
        case llvm::Triple::sparcv9:
        case llvm::Triple::ppc64:
        case llvm::Triple::cellspu:
            g_host_arch_64.SetTriple(triple);
            g_supports_64 = true;
            break;
        }

        g_supports_32 = g_host_arch_32.IsValid();
        g_supports_64 = g_host_arch_64.IsValid();
    }
    
#endif // #else for #if defined (__APPLE__)
    
    if (arch_kind == eSystemDefaultArchitecture32)
        return g_host_arch_32;
    else if (arch_kind == eSystemDefaultArchitecture64)
        return g_host_arch_64;

    if (g_supports_64)
        return g_host_arch_64;
        
    return g_host_arch_32;
}
Beispiel #13
0
bool
Instruction::TestEmulation (Stream *out_stream, const char *file_name)
{
    if (!out_stream)
        return false;

    if (!file_name)
    {
        out_stream->Printf ("Instruction::TestEmulation:  Missing file_name.");
        return false;
    }
        
    FILE *test_file = fopen (file_name, "r");
    if (!test_file)
    {
        out_stream->Printf ("Instruction::TestEmulation: Attempt to open test file failed.");
        return false;
    }

    char buffer[256];
    if (!fgets (buffer, 255, test_file))
    {
        out_stream->Printf ("Instruction::TestEmulation: Error reading first line of test file.\n");
        fclose (test_file);
        return false;
    }
    
    if (strncmp (buffer, "InstructionEmulationState={", 27) != 0)
    {
        out_stream->Printf ("Instructin::TestEmulation: Test file does not contain emulation state dictionary\n");
        fclose (test_file);
        return false;
    }

    // Read all the test information from the test file into an OptionValueDictionary.

    OptionValueSP data_dictionary_sp (ReadDictionary (test_file, out_stream));
    if (data_dictionary_sp.get() == NULL)
    {
        out_stream->Printf ("Instruction::TestEmulation:  Error reading Dictionary Object.\n");
        fclose (test_file);
        return false;
    }

    fclose (test_file);

    OptionValueDictionary *data_dictionary = data_dictionary_sp->GetAsDictionary();
    static ConstString description_key ("assembly_string");
    static ConstString triple_key ("triple");

    OptionValueSP value_sp = data_dictionary->GetValueForKey (description_key);
    
    if (value_sp.get() == NULL)
    {
        out_stream->Printf ("Instruction::TestEmulation:  Test file does not contain description string.\n");
        return false;
    }

    SetDescription (value_sp->GetStringValue());
            
            
    value_sp = data_dictionary->GetValueForKey (triple_key);
    if (value_sp.get() == NULL)
    {
        out_stream->Printf ("Instruction::TestEmulation: Test file does not contain triple.\n");
        return false;
    }
    
    ArchSpec arch;
    arch.SetTriple (llvm::Triple (value_sp->GetStringValue()));

    bool success = false;
    std::unique_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
    if (insn_emulator_ap.get())
        success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary);

    if (success)
        out_stream->Printf ("Emulation test succeeded.");
    else
        out_stream->Printf ("Emulation test failed.");
        
    return success;
}
//----------------------------------------------------------------------
// Process Control
//----------------------------------------------------------------------
Error
ProcessMachCore::DoLoadCore ()
{
    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER | LIBLLDB_LOG_PROCESS));
    Error error;
    if (!m_core_module_sp)
    {
        error.SetErrorString ("invalid core module");   
        return error;
    }

    ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
    if (core_objfile == NULL)
    {
        error.SetErrorString ("invalid core object file");   
        return error;
    }
    
    if (core_objfile->GetNumThreadContexts() == 0)
    {
        error.SetErrorString ("core file doesn't contain any LC_THREAD load commands, or the LC_THREAD architecture is not supported in this lldb");
        return error;
    }

    SectionList *section_list = core_objfile->GetSectionList();
    if (section_list == NULL)
    {
        error.SetErrorString ("core file has no sections");   
        return error;
    }
        
    const uint32_t num_sections = section_list->GetNumSections(0);
    if (num_sections == 0)
    {
        error.SetErrorString ("core file has no sections");   
        return error;
    }
    
    SetCanJIT(false);

    llvm::MachO::mach_header header;
    DataExtractor data (&header, 
                        sizeof(header), 
                        m_core_module_sp->GetArchitecture().GetByteOrder(),
                        m_core_module_sp->GetArchitecture().GetAddressByteSize());

    bool ranges_are_sorted = true;
    addr_t vm_addr = 0;
    for (uint32_t i=0; i<num_sections; ++i)
    {
        Section *section = section_list->GetSectionAtIndex (i).get();
        if (section)
        {
            lldb::addr_t section_vm_addr = section->GetFileAddress();
            FileRange file_range (section->GetFileOffset(), section->GetFileSize());
            VMRangeToFileOffset::Entry range_entry (section_vm_addr,
                                                    section->GetByteSize(),
                                                    file_range);
            
            if (vm_addr > section_vm_addr)
                ranges_are_sorted = false;
            vm_addr = section->GetFileAddress();
            VMRangeToFileOffset::Entry *last_entry = m_core_aranges.Back();
//            printf ("LC_SEGMENT[%u] arange=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), frange=[0x%8.8x - 0x%8.8x)\n",
//                    i, 
//                    range_entry.GetRangeBase(),
//                    range_entry.GetRangeEnd(),
//                    range_entry.data.GetRangeBase(),
//                    range_entry.data.GetRangeEnd());

            if (last_entry &&
                last_entry->GetRangeEnd() == range_entry.GetRangeBase() &&
                last_entry->data.GetRangeEnd() == range_entry.data.GetRangeBase())
            {
                last_entry->SetRangeEnd (range_entry.GetRangeEnd());
                last_entry->data.SetRangeEnd (range_entry.data.GetRangeEnd());
                //puts("combine");
            }
            else
            {
                m_core_aranges.Append(range_entry);
            }
            // Some core files don't fill in the permissions correctly. If that is the case
            // assume read + execute so clients don't think the memory is not readable,
            // or executable. The memory isn't writable since this plug-in doesn't implement
            // DoWriteMemory.
            uint32_t permissions = section->GetPermissions();
            if (permissions == 0)
                permissions = lldb::ePermissionsReadable | lldb::ePermissionsExecutable;
            m_core_range_infos.Append(
                VMRangeToPermissions::Entry(section_vm_addr, section->GetByteSize(), permissions));
        }
    }
    if (!ranges_are_sorted)
    {
        m_core_aranges.Sort();
        m_core_range_infos.Sort();
    }

    if (m_dyld_addr == LLDB_INVALID_ADDRESS || m_mach_kernel_addr == LLDB_INVALID_ADDRESS)
    {
        // We need to locate the main executable in the memory ranges
        // we have in the core file.  We need to search for both a user-process dyld binary
        // and a kernel binary in memory; we must look at all the pages in the binary so
        // we don't miss one or the other.  Step through all memory segments searching for
        // a kernel binary and for a user process dyld -- we'll decide which to prefer 
        // later if both are present.

        const size_t num_core_aranges = m_core_aranges.GetSize();
        for (size_t i = 0; i < num_core_aranges; ++i)
        {
            const VMRangeToFileOffset::Entry *entry = m_core_aranges.GetEntryAtIndex(i);
            lldb::addr_t section_vm_addr_start = entry->GetRangeBase();
            lldb::addr_t section_vm_addr_end = entry->GetRangeEnd();
            for (lldb::addr_t section_vm_addr = section_vm_addr_start;
                 section_vm_addr < section_vm_addr_end;
                 section_vm_addr += 0x1000)
            {
                GetDynamicLoaderAddress (section_vm_addr);
            }
        }
    }


    if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS)
    {
        // In the case of multiple kernel images found in the core file via exhaustive
        // search, we may not pick the correct one.  See if the DynamicLoaderDarwinKernel's
        // search heuristics might identify the correct one.
        // Most of the time, I expect the address from SearchForDarwinKernel() will be the
        // same as the address we found via exhaustive search.

        if (GetTarget().GetArchitecture().IsValid() == false && m_core_module_sp.get())
        {
            GetTarget().SetArchitecture (m_core_module_sp->GetArchitecture());
        }

        // SearchForDarwinKernel will end up calling back into this this class in the GetImageInfoAddress
        // method which will give it the m_mach_kernel_addr/m_dyld_addr it already has.  Save that aside
        // and set m_mach_kernel_addr/m_dyld_addr to an invalid address temporarily so 
        // DynamicLoaderDarwinKernel does a real search for the kernel using its own heuristics.

        addr_t saved_mach_kernel_addr = m_mach_kernel_addr;
        addr_t saved_user_dyld_addr = m_dyld_addr;
        m_mach_kernel_addr = LLDB_INVALID_ADDRESS;
        m_dyld_addr = LLDB_INVALID_ADDRESS;

        addr_t better_kernel_address = DynamicLoaderDarwinKernel::SearchForDarwinKernel (this);

        m_mach_kernel_addr = saved_mach_kernel_addr;
        m_dyld_addr = saved_user_dyld_addr;

        if (better_kernel_address != LLDB_INVALID_ADDRESS)
        {
            if (log)
                log->Printf ("ProcessMachCore::DoLoadCore: Using the kernel address from DynamicLoaderDarwinKernel");
            m_mach_kernel_addr = better_kernel_address;
        }
    }


    // If we found both a user-process dyld and a kernel binary, we need to decide
    // which to prefer.
    if (GetCorefilePreference() == eKernelCorefile)
    {
        if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS)
        {
            if (log)
                log->Printf ("ProcessMachCore::DoLoadCore: Using kernel corefile image at 0x%" PRIx64, m_mach_kernel_addr);
            m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
        }
        else if (m_dyld_addr != LLDB_INVALID_ADDRESS)
        {
            if (log)
                log->Printf ("ProcessMachCore::DoLoadCore: Using user process dyld image at 0x%" PRIx64, m_dyld_addr);
            m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
        }
    }
    else
    {
        if (m_dyld_addr != LLDB_INVALID_ADDRESS)
        {
            if (log)
                log->Printf ("ProcessMachCore::DoLoadCore: Using user process dyld image at 0x%" PRIx64, m_dyld_addr);
            m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
        }
        else if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS)
        {
            if (log)
                log->Printf ("ProcessMachCore::DoLoadCore: Using kernel corefile image at 0x%" PRIx64, m_mach_kernel_addr);
            m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
        }
    }

    if (m_dyld_plugin_name != DynamicLoaderMacOSXDYLD::GetPluginNameStatic())
    {
        // For non-user process core files, the permissions on the core file segments are usually
        // meaningless, they may be just "read", because we're dealing with kernel coredumps or
        // early startup coredumps and the dumper is grabbing pages of memory without knowing
        // what they are.  If they aren't marked as "exeuctable", that can break the unwinder
        // which will check a pc value to see if it is in an executable segment and stop the
        // backtrace early if it is not ("executable" and "unknown" would both be fine, but 
        // "not executable" will break the unwinder).
        size_t core_range_infos_size = m_core_range_infos.GetSize();
        for (size_t i = 0; i < core_range_infos_size; i++)
        {
            VMRangeToPermissions::Entry *ent = m_core_range_infos.GetMutableEntryAtIndex (i);
            ent->data = lldb::ePermissionsReadable | lldb::ePermissionsExecutable;
        }
    }

    // Even if the architecture is set in the target, we need to override
    // it to match the core file which is always single arch.
    ArchSpec arch (m_core_module_sp->GetArchitecture());
    if (arch.GetCore() == ArchSpec::eCore_x86_32_i486)
    {
        arch.SetTriple ("i386", GetTarget().GetPlatform().get());
    }
    if (arch.IsValid())
        GetTarget().SetArchitecture(arch);

    return error;
}
Beispiel #15
0
bool
PlatformDarwin::ARMGetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
{
    ArchSpec system_arch (GetSystemArchitecture());
    const ArchSpec::Core system_core = system_arch.GetCore();
    switch (system_core)
    {
    default:
        switch (idx)
        {
            case  0: arch.SetTriple ("armv7-apple-ios");    return true;
            case  1: arch.SetTriple ("armv7f-apple-ios");   return true;
            case  2: arch.SetTriple ("armv7k-apple-ios");   return true;
            case  3: arch.SetTriple ("armv7s-apple-ios");   return true;
            case  4: arch.SetTriple ("armv6-apple-ios");    return true;
            case  5: arch.SetTriple ("armv5-apple-ios");    return true;
            case  6: arch.SetTriple ("armv4-apple-ios");    return true;
            case  7: arch.SetTriple ("arm-apple-ios");      return true;
            case  8: arch.SetTriple ("thumbv7-apple-ios");  return true;
            case  9: arch.SetTriple ("thumbv7f-apple-ios"); return true;
            case 10: arch.SetTriple ("thumbv7k-apple-ios"); return true;
            case 11: arch.SetTriple ("thumbv7s-apple-ios"); return true;
            case 12: arch.SetTriple ("thumbv6-apple-ios");  return true;
            case 13: arch.SetTriple ("thumbv5-apple-ios");  return true;
            case 14: arch.SetTriple ("thumbv4t-apple-ios"); return true;
            case 15: arch.SetTriple ("thumb-apple-ios");    return true;
        default: break;
        }
        break;

    case ArchSpec::eCore_arm_armv7f:
        switch (idx)
        {
            case  0: arch.SetTriple ("armv7f-apple-ios");   return true;
            case  1: arch.SetTriple ("armv7-apple-ios");    return true;
            case  2: arch.SetTriple ("armv6-apple-ios");    return true;
            case  3: arch.SetTriple ("armv5-apple-ios");    return true;
            case  4: arch.SetTriple ("armv4-apple-ios");    return true;
            case  5: arch.SetTriple ("arm-apple-ios");      return true;
            case  6: arch.SetTriple ("thumbv7f-apple-ios"); return true;
            case  7: arch.SetTriple ("thumbv7-apple-ios");  return true;
            case  8: arch.SetTriple ("thumbv6-apple-ios");  return true;
            case  9: arch.SetTriple ("thumbv5-apple-ios");  return true;
            case 10: arch.SetTriple ("thumbv4t-apple-ios"); return true;
            case 11: arch.SetTriple ("thumb-apple-ios");    return true;
            default: break;
        }
        break;

    case ArchSpec::eCore_arm_armv7k:
        switch (idx)
        {
            case  0: arch.SetTriple ("armv7k-apple-ios");   return true;
            case  1: arch.SetTriple ("armv7-apple-ios");    return true;
            case  2: arch.SetTriple ("armv6-apple-ios");    return true;
            case  3: arch.SetTriple ("armv5-apple-ios");    return true;
            case  4: arch.SetTriple ("armv4-apple-ios");    return true;
            case  5: arch.SetTriple ("arm-apple-ios");      return true;
            case  6: arch.SetTriple ("thumbv7k-apple-ios"); return true;
            case  7: arch.SetTriple ("thumbv7-apple-ios");  return true;
            case  8: arch.SetTriple ("thumbv6-apple-ios");  return true;
            case  9: arch.SetTriple ("thumbv5-apple-ios");  return true;
            case 10: arch.SetTriple ("thumbv4t-apple-ios"); return true;
            case 11: arch.SetTriple ("thumb-apple-ios");    return true;
            default: break;
        }
        break;

    case ArchSpec::eCore_arm_armv7s:
        switch (idx)
        {
            case  0: arch.SetTriple ("armv7s-apple-ios");   return true;
            case  1: arch.SetTriple ("armv7-apple-ios");    return true;
            case  2: arch.SetTriple ("armv6-apple-ios");    return true;
            case  3: arch.SetTriple ("armv5-apple-ios");    return true;
            case  4: arch.SetTriple ("armv4-apple-ios");    return true;
            case  5: arch.SetTriple ("arm-apple-ios");      return true;
            case  6: arch.SetTriple ("thumbv7s-apple-ios"); return true;
            case  7: arch.SetTriple ("thumbv7-apple-ios");  return true;
            case  8: arch.SetTriple ("thumbv6-apple-ios");  return true;
            case  9: arch.SetTriple ("thumbv5-apple-ios");  return true;
            case 10: arch.SetTriple ("thumbv4t-apple-ios"); return true;
            case 11: arch.SetTriple ("thumb-apple-ios");    return true;
            default: break;
        }
        break;

    case ArchSpec::eCore_arm_armv7:
        switch (idx)
        {
            case 0: arch.SetTriple ("armv7-apple-ios");    return true;
            case 1: arch.SetTriple ("armv6-apple-ios");    return true;
            case 2: arch.SetTriple ("armv5-apple-ios");    return true;
            case 3: arch.SetTriple ("armv4-apple-ios");    return true;
            case 4: arch.SetTriple ("arm-apple-ios");      return true;
            case 5: arch.SetTriple ("thumbv7-apple-ios");  return true;
            case 6: arch.SetTriple ("thumbv6-apple-ios");  return true;
            case 7: arch.SetTriple ("thumbv5-apple-ios");  return true;
            case 8: arch.SetTriple ("thumbv4t-apple-ios"); return true;
            case 9: arch.SetTriple ("thumb-apple-ios");    return true;
            default: break;
        }
        break;

    case ArchSpec::eCore_arm_armv6:
        switch (idx)
        {
            case 0: arch.SetTriple ("armv6-apple-ios");    return true;
            case 1: arch.SetTriple ("armv5-apple-ios");    return true;
            case 2: arch.SetTriple ("armv4-apple-ios");    return true;
            case 3: arch.SetTriple ("arm-apple-ios");      return true;
            case 4: arch.SetTriple ("thumbv6-apple-ios");  return true;
            case 5: arch.SetTriple ("thumbv5-apple-ios");  return true;
            case 6: arch.SetTriple ("thumbv4t-apple-ios"); return true;
            case 7: arch.SetTriple ("thumb-apple-ios");    return true;
            default: break;
        }
        break;

    case ArchSpec::eCore_arm_armv5:
        switch (idx)
        {
            case 0: arch.SetTriple ("armv5-apple-ios");    return true;
            case 1: arch.SetTriple ("armv4-apple-ios");    return true;
            case 2: arch.SetTriple ("arm-apple-ios");      return true;
            case 3: arch.SetTriple ("thumbv5-apple-ios");  return true;
            case 4: arch.SetTriple ("thumbv4t-apple-ios"); return true;
            case 5: arch.SetTriple ("thumb-apple-ios");    return true;
            default: break;
        }
        break;

    case ArchSpec::eCore_arm_armv4:
        switch (idx)
        {
            case 0: arch.SetTriple ("armv4-apple-ios");    return true;
            case 1: arch.SetTriple ("arm-apple-ios");      return true;
            case 2: arch.SetTriple ("thumbv4t-apple-ios"); return true;
            case 3: arch.SetTriple ("thumb-apple-ios");    return true;
            default: break;
        }
        break;
    }
    arch.Clear();
    return false;
}
//----------------------------------------------------------------------
// Process Control
//----------------------------------------------------------------------
Error
ProcessMachCore::DoLoadCore ()
{
    Error error;
    if (!m_core_module_sp)
    {
        error.SetErrorString ("invalid core module");   
        return error;
    }

    ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
    if (core_objfile == NULL)
    {
        error.SetErrorString ("invalid core object file");   
        return error;
    }
    
    if (core_objfile->GetNumThreadContexts() == 0)
    {
        error.SetErrorString ("core file doesn't contain any LC_THREAD load commands, or the LC_THREAD architecture is not supported in this lldb");
        return error;
    }

    SectionList *section_list = core_objfile->GetSectionList();
    if (section_list == NULL)
    {
        error.SetErrorString ("core file has no sections");   
        return error;
    }
        
    const uint32_t num_sections = section_list->GetNumSections(0);
    if (num_sections == 0)
    {
        error.SetErrorString ("core file has no sections");   
        return error;
    }
    
    SetCanJIT(false);

    llvm::MachO::mach_header header;
    DataExtractor data (&header, 
                        sizeof(header), 
                        m_core_module_sp->GetArchitecture().GetByteOrder(),
                        m_core_module_sp->GetArchitecture().GetAddressByteSize());

    bool ranges_are_sorted = true;
    addr_t vm_addr = 0;
    for (uint32_t i=0; i<num_sections; ++i)
    {
        Section *section = section_list->GetSectionAtIndex (i).get();
        if (section)
        {
            lldb::addr_t section_vm_addr = section->GetFileAddress();
            FileRange file_range (section->GetFileOffset(), section->GetFileSize());
            VMRangeToFileOffset::Entry range_entry (section_vm_addr,
                                                    section->GetByteSize(),
                                                    file_range);
            
            if (vm_addr > section_vm_addr)
                ranges_are_sorted = false;
            vm_addr = section->GetFileAddress();
            VMRangeToFileOffset::Entry *last_entry = m_core_aranges.Back();
//            printf ("LC_SEGMENT[%u] arange=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), frange=[0x%8.8x - 0x%8.8x)\n",
//                    i, 
//                    range_entry.GetRangeBase(),
//                    range_entry.GetRangeEnd(),
//                    range_entry.data.GetRangeBase(),
//                    range_entry.data.GetRangeEnd());

            if (last_entry &&
                last_entry->GetRangeEnd() == range_entry.GetRangeBase() &&
                last_entry->data.GetRangeEnd() == range_entry.data.GetRangeBase())
            {
                last_entry->SetRangeEnd (range_entry.GetRangeEnd());
                last_entry->data.SetRangeEnd (range_entry.data.GetRangeEnd());
                //puts("combine");
            }
            else
            {
                m_core_aranges.Append(range_entry);
            }
            
            // After we have added this section to our m_core_aranges map,
            // we can check the start of the section to see if it might
            // contain dyld for user space apps, or the mach kernel file 
            // for kernel cores.
            if (m_dyld_addr == LLDB_INVALID_ADDRESS)
                GetDynamicLoaderAddress (section_vm_addr);
        }
    }
    if (!ranges_are_sorted)
    {
        m_core_aranges.Sort();
    }

    // Even if the architecture is set in the target, we need to override
    // it to match the core file which is always single arch.
    ArchSpec arch (m_core_module_sp->GetArchitecture());
    if (arch.GetCore() == ArchSpec::eCore_x86_32_i486)
    {
        arch.SetTriple ("i386", m_target.GetPlatform().get());
    }
    if (arch.IsValid())
        m_target.SetArchitecture(arch);            

    if (m_dyld_addr == LLDB_INVALID_ADDRESS)
    {
        // We need to locate the main executable in the memory ranges
        // we have in the core file. We already checked the first address
        // in each memory zone above, so we just need to check each page
        // except the first page in each range and stop once we have found
        // our main executable
        const size_t num_core_aranges = m_core_aranges.GetSize();
        for (size_t i=0; i<num_core_aranges && m_dyld_addr == LLDB_INVALID_ADDRESS; ++i)
        {
            const VMRangeToFileOffset::Entry *entry = m_core_aranges.GetEntryAtIndex(i);
            lldb::addr_t section_vm_addr_start = entry->GetRangeBase();
            lldb::addr_t section_vm_addr_end = entry->GetRangeEnd();
            for (lldb::addr_t section_vm_addr = section_vm_addr_start + 0x1000;
                 section_vm_addr < section_vm_addr_end;
                 section_vm_addr += 0x1000)
            {
                if (GetDynamicLoaderAddress (section_vm_addr))
                {
                    break;
                }
            }
        }
    }
    return error;
}