This patch combines common code from Linux and FreeBSD into
a new POSIX platform.  It also contains fixes for 64bit FreeBSD.

The patch is based on changes by Mark Peek <mp@FreeBSD.org> and
"K. Macy" <kmacy@freebsd.org> in their github repo located at
https://github.com/fbsd/lldb.

llvm-svn: 147609
diff --git a/lldb/source/Host/linux/Host.cpp b/lldb/source/Host/linux/Host.cpp
index 4ebacc5..432dfd5 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 @@
     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;
+}