[lldb-dev] Problems selecting correct Platform

Ted Woodward ted.woodward at codeaurora.org
Thu Mar 19 15:52:51 PDT 2015




> -----Original Message-----
> From: Greg Clayton [mailto:gclayton at apple.com]
> Sent: Thursday, March 19, 2015 4:45 PM
> 
> > 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.

I've got 216115. My snapshot includes up to 227289 from 1/27/15. We're
trying to get better about staying closer to top-of-tree, but it's something
we're not good enough at yet.

226712 from 1/21/15 changed how "target create" called CreateTarget() in
TargetList.cpp. Before that rev, it called the CreateTarget() that took a
triple, but after that rev it calls the CreateTarget() that takes an
ArchSpec. These 2 methods do different things; the triple one calls the
(internal) ArchSpec one at the end. One thing that is missing in the one
that takes an ArchSpec is the chunk of code that searches for a valid
platform for the specified architecture:

        else if (platform_arch.IsValid())
        {
            // if "arch" isn't valid, yet "platform_arch" is, it means we
have an executable file with
            // a single architecture which should be used
            ArchSpec fixed_platform_arch;
            if (!platform_sp->IsCompatibleArchitecture(platform_arch, false,
&fixed_platform_arch))
            {
                platform_sp =
Platform::GetPlatformForArchitecture(platform_arch, &fixed_platform_arch);
                if (platform_sp)
 
debugger.GetPlatformList().SetSelectedPlatform(platform_sp);
            }
        }

That code is not currently called by a "target create".

Vince, would changing the CreateTarget() call in CommandObjectTarget.cpp
back to the pre-226712 call break the remote-linux platform run process fix?

> > 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?

I added the code below to PlatformLinux.cpp and now my Windows LLDB
correctly selects the remote-linux platform for Hexagon Linux. Thanks!

> 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.

--
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a
Linux Foundation Collaborative Project




More information about the lldb-dev mailing list