summaryrefslogtreecommitdiffstats
path: root/lldb/source/Host/linux/Host.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Host/linux/Host.cpp')
-rw-r--r--lldb/source/Host/linux/Host.cpp53
1 files changed, 53 insertions, 0 deletions
diff --git a/lldb/source/Host/linux/Host.cpp b/lldb/source/Host/linux/Host.cpp
index 4ebacc54c17..432dfd509de 100644
--- a/lldb/source/Host/linux/Host.cpp
+++ b/lldb/source/Host/linux/Host.cpp
@@ -10,12 +10,20 @@
// C Includes
#include <stdio.h>
#include <sys/utsname.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Error.h"
+#include "lldb/Target/Process.h"
+
#include "lldb/Host/Host.h"
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/DataExtractor.h"
using namespace lldb;
using namespace lldb_private;
@@ -43,3 +51,48 @@ Host::LaunchProcess (ProcessLaunchInfo &launch_info)
return error;
}
+lldb::DataBufferSP
+Host::GetAuxvData(lldb_private::Process *process)
+{
+ static const size_t path_size = 128;
+ static char path[path_size];
+ lldb::DataBufferSP buf_sp;
+
+ int fd;
+
+ // Ideally, we would simply create a FileSpec and call ReadFileContents.
+ // However, files in procfs have zero size (since they are, in general,
+ // dynamically generated by the kernel) which is incompatible with the
+ // current ReadFileContents implementation. Therefore we simply stream the
+ // data into a DataBuffer ourselves.
+ if (snprintf(path, path_size, "/proc/%d/auxv", process->GetID()) < 0)
+ return buf_sp;
+
+ if ((fd = open(path, O_RDONLY, 0)) < 0)
+ return buf_sp;
+
+ size_t bytes_read = 0;
+ std::auto_ptr<DataBufferHeap> buf_ap(new DataBufferHeap(1024, 0));
+ for (;;)
+ {
+ size_t avail = buf_ap->GetByteSize() - bytes_read;
+ ssize_t status = read(fd, buf_ap->GetBytes() + bytes_read, avail);
+
+ if (status < 0)
+ break;
+
+ bytes_read += status;
+
+ if (status == 0)
+ {
+ buf_ap->SetByteSize(bytes_read);
+ buf_sp.reset(buf_ap.release());
+ break;
+ }
+
+ if (avail - status == 0)
+ buf_ap->SetByteSize(2 * buf_ap->GetByteSize());
+ }
+
+ return buf_sp;
+}
OpenPOWER on IntegriCloud