-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[LLDB, x86, FreeBSD] Fix Architecture parsing by reading the ELF header. #162811
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Currently, LLDB in FreeBSD host sets the Process Architecture used by lldbserver as Default one. Which cause problem when trying to debug a 32bit binary on amd64 platform since the lldb itself will found mismatch architecture with lldbserver's return. Notice that this patch is only a partial fix for the debugging problem. We are still unable to debug x86 on x86_64 so that we don't provide testcase in this patch.
@llvm/pr-subscribers-lldb Author: None (aokblast) ChangesCurrently, LLDB in FreeBSD host sets the Process Architecture used by lldbserver as Default one. Which cause problem when trying to debug a 32bit binary on amd64 platform since the lldb itself will found mismatch architecture with lldbserver's return. Notice that this patch is only a partial fix for the debugging problem. We are still unable to debug x86 on x86_64 so that we don't provide testcase in this patch. See: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=289945 Full diff: https://github.com/llvm/llvm-project/pull/162811.diff 1 Files Affected:
diff --git a/lldb/source/Host/freebsd/Host.cpp b/lldb/source/Host/freebsd/Host.cpp
index 14c0e9f2209d2..fa7efad466bad 100644
--- a/lldb/source/Host/freebsd/Host.cpp
+++ b/lldb/source/Host/freebsd/Host.cpp
@@ -14,12 +14,13 @@
#include <sys/sysctl.h>
#include <sys/user.h>
-#include <machine/elf.h>
-
#include <cstdio>
#include <dlfcn.h>
#include <execinfo.h>
+#include "llvm/Object/ELF.h"
+
+#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Utility/DataBufferHeap.h"
@@ -97,17 +98,33 @@ GetFreeBSDProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr,
proc_args.AppendArgument(llvm::StringRef(cstr));
}
- return true;
-}
-
-static bool GetFreeBSDProcessCPUType(ProcessInstanceInfo &process_info) {
- if (process_info.ProcessIDIsValid()) {
- process_info.GetArchitecture() =
- HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
+ auto buffer_sp = FileSystem::Instance().CreateDataBuffer(pathname, 0x20, 0);
+ if (!buffer_sp) {
+ process_info.Clear();
return true;
}
- process_info.GetArchitecture().Clear();
- return false;
+ uint8_t exe_class =
+ llvm::object::getElfArchType(
+ {reinterpret_cast<const char *>(buffer_sp->GetBytes()),
+ size_t(buffer_sp->GetByteSize())})
+ .first;
+
+ switch (exe_class) {
+ case llvm::ELF::ELFCLASS32:
+ process_info.SetArchitecture(
+ HostInfo::GetArchitecture(HostInfo::eArchKind32));
+ break;
+ case llvm::ELF::ELFCLASS64:
+ process_info.SetArchitecture(
+ HostInfo::GetArchitecture(HostInfo::eArchKind64));
+ break;
+ case llvm::ELF::ELFCLASSNONE:
+ process_info.SetArchitecture(
+ HostInfo::GetArchitecture(HostInfo::eArchKindDefault));
+ break;
+ }
+
+ return true;
}
static bool GetFreeBSDProcessUserAndGroup(ProcessInstanceInfo &process_info) {
@@ -214,7 +231,6 @@ uint32_t Host::FindProcessesImpl(const ProcessInstanceInfoMatch &match_info,
// Make sure our info matches before we go fetch the name and cpu type
if (match_info_noname.Matches(process_info) &&
GetFreeBSDProcessArgs(&match_info, process_info)) {
- GetFreeBSDProcessCPUType(process_info);
if (match_info.Matches(process_info))
process_infos.push_back(process_info);
}
@@ -228,7 +244,6 @@ bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) {
if (GetFreeBSDProcessArgs(NULL, process_info)) {
// should use libprocstat instead of going right into sysctl?
- GetFreeBSDProcessCPUType(process_info);
GetFreeBSDProcessUserAndGroup(process_info);
return true;
}
|
I don't provide test case since it still failed on debugging x32 from x86_64 platform when receiving signal. However, it stop breaking when loading binary. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, I see that NetBSD and Linux do this too.
Though I doubt whether debugging works on those platforms either, and I don't think we have upstream tests for it so I won't demand them here.
This change applies to AArch64 as well, right? At least the code is generic, maybe AArch32 binaries aren't allowed on AArch64 FreeBSD.
If you do get this working overall, I would like to see tests that run on Linux. If it's not a massive amount of work I can help fix Linux, if it is though, FreeBSD only test case would be fine. I'll take something over nothing.
This is an interesting question. I think that there are already some aarch64 based chip, like this, does not support running arm32 naturally.
Ok! I plan to provide at least FreeBSD test cases. I would try my best to provide the Linux one if I can get a one shot. Since I don't have any powerful Linux machine for debugging. |
Makes sense, if x86 is your use case, no need to pursue anything else. Now I remember someone did submit fixes for Arm32 on Arm64 Linux debugging. So it may be working there already.
Linux is my usual host so just aim for a FreeBSD test and I'll adapt it later. I did briefly consider running the entire test suite on Arm64 but with all debugees as 32-bit. Then I realised how many assumptions are made in various places and decided against it. So a basic test that exercises the main debug APIs would be fine. Run to a breakpoint, read some memory, print a pointer. Anything that comes to mind that might be related to bit-ness. |
I can merge this if you need me to. |
Sure. Thanks for your help! |
The userspace part of this is called |
Wow. thanks for your link! I am curious that do arm guys treat these models specially? Like have special ubuntu release without 32bit sysroots? I don't discover any FEAT_AA32EL0 string in LLVM so it might not be toolchain to have special arch triple to support it. Or arm just run it normally and let the kernel trap when running 32bit code. |
To be honest I've never tried it. I believe the Android NDK ships with toolchains to do this though. On any debian system I'd expect to be able to install a cross-compiler for it (https://wiki.debian.org/Multiarch/HOWTO). I know I can for example install SystemZ tools on Arm Ubuntu. Arm also provides Linux GCC toolchains you can download separately. You wouldn't see this feature name in in the toolchain. Even if you ran Ubuntu on one of these AArch32-less systems, I bet you can install the 32-bit toolchains still, as the package manager doesn't look that deeply. You'd find out when you get some probably strange error from the system or dynamic linker. I don't think it's a very popular thing to do generally. Valuable for some I'm sure, but not something I have come across many times. And I don't think you asked this but for completeness, were we not able to get hold of a machine with or without this feature, Arm's Fixed Virtual Platforms (FVP) can be configured to emulate it. Possibly QEMU too, but it does not cover absolutely everything like FVP does (not a criticism, each one has its own goals). |
My impression is that 32-bit executables are much more common on x86. To the point where there are standard flags like |
#include <cstdio> | ||
#include <dlfcn.h> | ||
#include <execinfo.h> | ||
|
||
#include "llvm/Object/ELF.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please group this together with the llvm header below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I totally fix the issue for i386 on x86_64 platform. Also includes this suggestion. Thanks!
@aokblast for reference we build 32-bit FreeBSD arm packages in a 32-bit jail on an arm64 host, on Ampere eMAG systems. |
Thanks for your information! I am just curious on how arm handle these multiarch stuff. |
Currently, LLDB in FreeBSD host sets the Process Architecture used by lldbserver as Default one. Which cause problem when trying to debug a 32bit binary on amd64 platform since the lldb itself will found mismatch architecture with lldbserver's return.
Notice that this patch is only a partial fix for the debugging problem. We are still unable to debug x86 on x86_64 so that we don't provide testcase in this patch.
See: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=289945