1 //===-- source/Host/linux/Host.cpp ------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 // C Includes
11 #include <stdio.h>
12 #include <sys/utsname.h>
13 #include <sys/types.h>
14 #include <sys/stat.h>
15 #include <fcntl.h>
16 
17 
18 // C++ Includes
19 // Other libraries and framework includes
20 // Project includes
21 #include "lldb/Core/Error.h"
22 #include "lldb/Target/Process.h"
23 
24 #include "lldb/Host/Host.h"
25 #include "lldb/Core/DataBufferHeap.h"
26 #include "lldb/Core/DataExtractor.h"
27 
28 using namespace lldb;
29 using namespace lldb_private;
30 
31 bool
32 Host::GetOSVersion(uint32_t &major,
33                    uint32_t &minor,
34                    uint32_t &update)
35 {
36     struct utsname un;
37     int status;
38 
39     if (uname(&un))
40         return false;
41 
42     status = sscanf(un.release, "%u.%u.%u", &major, &minor, &update);
43      return status == 3;
44 }
45 
46 Error
47 Host::LaunchProcess (ProcessLaunchInfo &launch_info)
48 {
49     Error error;
50     assert(!"Not implemented yet!!!");
51     return error;
52 }
53 
54 lldb::DataBufferSP
55 Host::GetAuxvData(lldb_private::Process *process)
56 {
57     static const size_t path_size = 128;
58     static char path[path_size];
59     lldb::DataBufferSP buf_sp;
60 
61     int fd;
62 
63     // Ideally, we would simply create a FileSpec and call ReadFileContents.
64     // However, files in procfs have zero size (since they are, in general,
65     // dynamically generated by the kernel) which is incompatible with the
66     // current ReadFileContents implementation.  Therefore we simply stream the
67     // data into a DataBuffer ourselves.
68     if (snprintf(path, path_size, "/proc/%d/auxv", process->GetID()) < 0)
69         return buf_sp;
70 
71     if ((fd = open(path, O_RDONLY, 0)) < 0)
72         return buf_sp;
73 
74     size_t bytes_read = 0;
75     std::auto_ptr<DataBufferHeap> buf_ap(new DataBufferHeap(1024, 0));
76     for (;;)
77     {
78         size_t avail = buf_ap->GetByteSize() - bytes_read;
79         ssize_t status = read(fd, buf_ap->GetBytes() + bytes_read, avail);
80 
81         if (status < 0)
82             break;
83 
84         bytes_read += status;
85 
86         if (status == 0)
87         {
88             buf_ap->SetByteSize(bytes_read);
89             buf_sp.reset(buf_ap.release());
90             break;
91         }
92 
93         if (avail - status == 0)
94             buf_ap->SetByteSize(2 * buf_ap->GetByteSize());
95     }
96 
97     return buf_sp;
98 }
99