diff options
Diffstat (limited to 'lldb/source/Host/linux/Host.cpp')
-rw-r--r-- | lldb/source/Host/linux/Host.cpp | 53 |
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; +} |