summaryrefslogtreecommitdiffstats
path: root/lldb/source/Host/linux/Host.cpp
diff options
context:
space:
mode:
authorTodd Fiala <tfiala@google.com>2014-01-17 20:18:59 +0000
committerTodd Fiala <tfiala@google.com>2014-01-17 20:18:59 +0000
commitf3d61de5327caaf5f958046af57abcd128ec4421 (patch)
tree6d6c28a27e22912d30ab972269c3a197364b0fa9 /lldb/source/Host/linux/Host.cpp
parent6f78f3869d46d5481026a1bc149a1b560e21f9b8 (diff)
downloadbcm5719-llvm-f3d61de5327caaf5f958046af57abcd128ec4421.tar.gz
bcm5719-llvm-f3d61de5327caaf5f958046af57abcd128ec4421.zip
Enable Linux distribution in vendor portion of host triple.
This change does the following: * enables building lldb-gdbserver on linux_x86-64 platforms. Note - it builds but it has several run-time issues where many gdb remote protocol features are not properly implemented yet. I'm working on these one at a time. * lldb-gdbserver: does not enable the eLaunchFlagDebug launch flag on Linux. Currently the POSIX launch routine will assert if that flag is passed in, presumably because that launch mode is not yet available. This prevents lldb-gdbserver from asserting the moment it launches the debuggee process. * Adds ConstString& Host::GetDistributionId () This method is defined to return an empty result on all platforms except for Linux. On Linux, it makes one attempt to execute 'lsb_release -i' (both /usr/bin/lsb_release, where it appears on ubuntu, and /bin/lsb_release, where it appears on fedora if the redhat-lsb package is installed). If lsb_release is not found in either of those locations, or if 'lsb_release -i' does not return the first line starting with "Distributor ID:\t", then the distribution id is empty. The method will lower-case the id and replace whitespace with underscores. * Modify Host::GetArchitecture () so that linux replaces an unknown vendor portion with the results of GetDistributionId () if that is non-empty. This shows up now in qHostInfo remote packet responses and on the lldb host side. Tested with ubuntu and fedora (the latter both with the default of not having lsb_release installed, and with having lsb_release installed via the redhat-lsb package). Examples of triples on Linux after this change: # x86_64 Unbuntu 12.04 LTS: x86_64-ubuntu-linux-gnu # x86_64 Fedora 20 Desktop with redhat-lsb package installed x86_64-fedora-linux-gnu # x86_64 Fedora 20 Desktop without redhat-lsb-core installed # (i.e. no /bin/lsb_release available) # same as before the change x86_64--linux-gnu Note I intend to have Android respond with: {arch}-android-linux when I get to implementing Android lldb-gdbserver support. llvm-svn: 199510
Diffstat (limited to 'lldb/source/Host/linux/Host.cpp')
-rw-r--r--lldb/source/Host/linux/Host.cpp112
1 files changed, 112 insertions, 0 deletions
diff --git a/lldb/source/Host/linux/Host.cpp b/lldb/source/Host/linux/Host.cpp
index 232f0c34845..441a431fe0a 100644
--- a/lldb/source/Host/linux/Host.cpp
+++ b/lldb/source/Host/linux/Host.cpp
@@ -20,6 +20,7 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Error.h"
+#include "lldb/Core/Log.h"
#include "lldb/Target/Process.h"
#include "lldb/Host/Host.h"
@@ -494,3 +495,114 @@ Host::GetEnvironment (StringList &env)
env.AppendString(env_entry);
return i;
}
+
+const ConstString &
+Host::GetDistributionId ()
+{
+ // Try to run 'lbs_release -i', and use that response
+ // for the distribution id.
+
+ static bool s_evaluated;
+ static ConstString s_distribution_id;
+
+ if (!s_evaluated)
+ {
+ s_evaluated = true;
+
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_HOST));
+ if (log)
+ log->Printf ("attempting to determine Linux distribution...");
+
+ // check if the lsb_release command exists at one of the
+ // following paths
+ const char *const exe_paths[] = {
+ "/bin/lsb_release",
+ "/usr/bin/lsb_release"
+ };
+
+ for (int exe_index = 0;
+ exe_index < sizeof (exe_paths) / sizeof (exe_paths[0]);
+ ++exe_index)
+ {
+ const char *const get_distribution_info_exe = exe_paths[exe_index];
+ if (access (get_distribution_info_exe, F_OK))
+ {
+ // this exe doesn't exist, move on to next exe
+ if (log)
+ log->Printf ("executable doesn't exist: %s",
+ get_distribution_info_exe);
+ continue;
+ }
+
+ // execute the distribution-retrieval command, read output
+ std::string get_distribution_id_command (get_distribution_info_exe);
+ get_distribution_id_command += " -i";
+
+ FILE *file = popen (get_distribution_id_command.c_str (), "r");
+ if (!file)
+ {
+ if (log)
+ log->Printf (
+ "failed to run command: \"%s\", cannot retrieve "
+ "platform information",
+ get_distribution_id_command.c_str ());
+ return s_distribution_id;
+ }
+
+ // retrieve the distribution id string.
+ char distribution_id[256] = { '\0' };
+ if (fgets (distribution_id, sizeof (distribution_id) - 1, file)
+ != NULL)
+ {
+ if (log)
+ log->Printf ("distribution id command returned \"%s\"",
+ distribution_id);
+
+ const char *const distributor_id_key = "Distributor ID:\t";
+ if (strstr (distribution_id, distributor_id_key))
+ {
+ // strip newlines
+ std::string id_string (distribution_id +
+ strlen (distributor_id_key));
+ id_string.erase(
+ std::remove (
+ id_string.begin (),
+ id_string.end (),
+ '\n'),
+ id_string.end ());
+
+ // lower case it and convert whitespace to underscores
+ std::transform (
+ id_string.begin(),
+ id_string.end (),
+ id_string.begin (),
+ [] (char ch)
+ { return tolower ( isspace (ch) ? '_' : ch ); });
+
+ s_distribution_id.SetCString (id_string.c_str ());
+ if (log)
+ log->Printf ("distribion id set to \"%s\"",
+ s_distribution_id.GetCString ());
+ }
+ else
+ {
+ if (log)
+ log->Printf ("failed to find \"%s\" field in \"%s\"",
+ distributor_id_key, distribution_id);
+ }
+ }
+ else
+ {
+ if (log)
+ log->Printf (
+ "failed to retrieve distribution id, \"%s\" returned no"
+ " lines", get_distribution_id_command.c_str ());
+ }
+
+ // clean up the file
+ pclose(file);
+ }
+ }
+
+ return s_distribution_id;
+}
OpenPOWER on IntegriCloud