[lldb-dev] Problems selecting correct Platform

Greg Clayton gclayton at apple.com
Thu Mar 19 14:45:01 PDT 2015


> On Mar 19, 2015, at 12:15 PM, Ted Woodward <ted.woodward at codeaurora.org> wrote:
> 
> I've got a Hexagon platform, that launches the Hexagon simulator and is used
> for standalone development. Now I'm working on supporting Hexagon Linux, but
> it's not choosing the Linux platform, instead it's choosing the Hexagon
> platform.
> 
> I want LLDB to use the Hexagon Platform if my executable's triple is
> "hexagon-unknown-elf" (which is really hexagon-unknown-unknown) and use the
> Linux platform if my executable's triple is "hexagon-unknown-linux".
> 
> 
> First problem:
> "target create" doesn't search platforms for one matching the executable's
> triple. It used to, but when TargetList::CreateTarget was switched to call
> CreateTargetInternal, "target create" was changed to call the method that
> takes an ArchSpec instead of a triple. This method doesn't search for a
> compatible Platform, but instead chooses the current Platform.
> 
> Is this intended behavior?

No. Sounds like you have an old snapshot of LLDB. The current one was recently fixed to search for the platform with revision 216115.

> 
> Second problem:
> I change DoExecute() in CommandObjectTarget.cpp to call the ArchSpec version
> if the ArchSpec is valid, and the triple version if it is not. This has LLDB
> going through platforms to find a match, but there's another problem when it
> gets to PlatformLinux. PlatformLinux::GetSupportedArchitectureAtIndex() will
> only return host architectures.

This is a bug and should be fixed with code below...

> So in my case, running on Windows, it
> returns x86_64-pc-windows-msvc or i386-pc-windows-msvc. Neither is a match
> for Linux.
> 
> Shouldn't the Linux platform match anything with a triple *-*-linux? Or does
> the platform not matter if I'm just going to use gdb-remote to connect to
> gdbserver or LLGS on a remote Hexagon Linux board?

So a platform can say what architectures it supports. This is how we match architectures up to a binary that is supplied. Each platform should give an exhaustive list of the architectures they support.

The current code is:

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


This is only correct if Platform::IsHost() returns true. Otherwise linux will need to say all architectures that is supports:


x86_64-*-linux
i386-*-linux
arm*-*-linux
aarch64-*-linux
mips64-*linux

The "*" above for the vendor should be set an an "unspecified unknown". So the code should be:

bool
PlatformLinux::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
{
    if (IsHost())
    {
        if (idx == 0)
        {
            arch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
            return arch.IsValid();
        }
        else if (idx == 1)
       {
            // If the default host architecture is 64-bit, look for a 32-bit variant
            ArchSpec hostArch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
            if (hostArch.IsValid() && hostArch.GetTriple().isArch64Bit())
            {
                arch = HostInfo::GetArchitecture(HostInfo::eArchKind32);
                return arch.IsValid();
            }
        }
    }
    else
    {
	llvm::Triple triple;
        // Set the OS to linux
	triple.setOS(llvm::Triple::Linux);
        // Set the architecture
        switch (idx)
        {
        case 0:  arch.setArchName("x86_64"); break;
        case 1:  arch.setArchName("i386"); break;
        case 2:  arch.setArchName("arm"); break;
        case 3:  arch.setArchName("aarch64"); break;
        case 4:  arch.setArchName("mips64"); break;
        case 5:  arch.setArchName("hexagon"); 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;
}

Then things should work a bit better for you.





More information about the lldb-dev mailing list