llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.13k stars 12.01k forks source link

Mismatch between binary and host architectures unless absolute path is given #25333

Open b94f29e5-d802-4b78-81f0-5f935d66544c opened 9 years ago

b94f29e5-d802-4b78-81f0-5f935d66544c commented 9 years ago
Bugzilla Link 24959
Version 3.7
OS Linux

Extended Description

The following behavior in LLDB 3.7.0 seems quite weird; unless I specify an absolute path, lldb will refuse to create a target for an executable that exists in $PATH. If I specify an absolute path then it works fine. (Perhaps related to bug 20400.)

llvm-config --host-target prints "i686-pc-linux-gnu".

Bellow is an lldb session that showcases the issue:

(lldb) target create ls error: '/usr/bin/ls' doesn't contain any 'host' platform architectures: i686

(lldb) target create /usr/bin/ls Current executable set to '/usr/bin/ls' (i386).

(lldb) target list Current targets:

b94f29e5-d802-4b78-81f0-5f935d66544c commented 9 years ago

I'm not sure if that's the cause of the issue I'm seeing. I'm more intrigued by the fact that using an absolute path to the binary somehow makes it work...

llvmbot commented 9 years ago

So it sounds like the PlatformLinux::GetSupportedArchitectureAtIndex() needs to be modified for 32 bit systems to say the following arch for the following indexes:

0 -> i686-pc-linux-gnu 1 -> i386-pc-linux-gnu

Not sure if any binaries ever claim to be i486, but if so, you would need to say:

0 -> i686-pc-linux-gnu 1 -> i386-pc-linux-gnu 2 -> i486-pc-linux-gnu

b94f29e5-d802-4b78-81f0-5f935d66544c commented 9 years ago

Sorry, I didn't mention this in my first message but the machine is 32-bit (i686).

I did include an example of what happens if I call 'target create' with either just the binary name or the absolute path (the latter behaves correctly). You can also see the output of 'target list' after the successful 'target create /usr/bin/ls' in my opening post.

llvmbot commented 9 years ago

So this is a bug in the linux platform. What should happen is the PlatformLinux should have the following function called:

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(); } } } }

And each architecture that is returned should be checked against the architecture in the binary. In this case it seems like you are running on a 64 bit machine and trying to load a 32 bit which should work because PlatformLinux::GetSupportedArchitectureAtIndex(0, arch) should return something like "i686-something-something" and PlatformLinux::GetSupportedArchitectureAtIndex(1, arch) should return "i386-something-something" and "i386-something-something" isn't matching what is in "ls". What shows up if you type:

(lldb) target create /usr/bin/ls (lldb) target list

It should show the triple for the "/usr/bin/ls" binary. It would be worth stepping through the code that calls PlatformLinux::GetSupportedArchitectureAtIndex() and see what is returned from each one and see why the triples don't match.