aboutsummaryrefslogtreecommitdiff
path: root/devel/electron12/files/patch-base_debug_proc__maps__linux.cc
blob: 67a023f2e5af23fab92f5b4383529ac2a26bc83b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
--- base/debug/proc_maps_linux.cc.orig	2021-04-14 01:08:36 UTC
+++ base/debug/proc_maps_linux.cc
@@ -13,13 +13,18 @@
 #include "base/strings/string_split.h"
 #include "build/build_config.h"
 
-#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID)
+#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) || defined(OS_BSD)
 #include <inttypes.h>
 #endif
 
 namespace base {
 namespace debug {
 
+#if defined(OS_BSD)
+const char kProcSelfMapsPath[] = "/proc/curproc/map";
+#else
+const char kProcSelfMapsPath[] = "/proc/self/maps";
+
 // Scans |proc_maps| starting from |pos| returning true if the gate VMA was
 // found, otherwise returns false.
 static bool ContainsGateVMA(std::string* proc_maps, size_t pos) {
@@ -35,15 +40,16 @@ static bool ContainsGateVMA(std::string* proc_maps, si
   return false;
 #endif
 }
+#endif
 
 bool ReadProcMaps(std::string* proc_maps) {
   // seq_file only writes out a page-sized amount on each call. Refer to header
   // file for details.
   const long kReadSize = sysconf(_SC_PAGESIZE);
 
-  base::ScopedFD fd(HANDLE_EINTR(open("/proc/self/maps", O_RDONLY)));
+  base::ScopedFD fd(HANDLE_EINTR(open(kProcSelfMapsPath, O_RDONLY)));
   if (!fd.is_valid()) {
-    DPLOG(ERROR) << "Couldn't open /proc/self/maps";
+    DPLOG(ERROR) << "Couldn't open " << kProcSelfMapsPath;
     return false;
   }
   proc_maps->clear();
@@ -57,7 +63,7 @@ bool ReadProcMaps(std::string* proc_maps) {
 
     ssize_t bytes_read = HANDLE_EINTR(read(fd.get(), buffer, kReadSize));
     if (bytes_read < 0) {
-      DPLOG(ERROR) << "Couldn't read /proc/self/maps";
+      DPLOG(ERROR) << "Couldn't read " << kProcSelfMapsPath;
       proc_maps->clear();
       return false;
     }
@@ -68,6 +74,7 @@ bool ReadProcMaps(std::string* proc_maps) {
     if (bytes_read == 0)
       break;
 
+#if !defined(OS_BSD)
     // The gate VMA is handled as a special case after seq_file has finished
     // iterating through all entries in the virtual memory table.
     //
@@ -78,6 +85,7 @@ bool ReadProcMaps(std::string* proc_maps) {
     // Avoid this by searching for the gate VMA and breaking early.
     if (ContainsGateVMA(proc_maps, pos))
       break;
+#endif
   }
 
   return true;
@@ -105,11 +113,32 @@ bool ParseProcMaps(const std::string& input,
 
     MappedMemoryRegion region;
     const char* line = lines[i].c_str();
-    char permissions[5] = {'\0'};  // Ensure NUL-terminated string.
+    char permissions[6] = {'\0'};  // Ensure NUL-terminated string.
+    int path_index = 0;
+
+#if defined(OS_BSD)
+    if (lines[i].empty())
+      continue;
+
+    char cow;
+
+    // Format:
+    //
+    // start    end      resident private_resident obj                perms ref_count shadow_count flags  cow needs_copy type  fullpath cred ruid
+    // 0x200000 0x202000 2        6                0xfffff80005be9000 r--   3         1            0x1000 COW NC         vnode /bin/cat NCH  -1
+    //
+    if (sscanf(line, "%" SCNxPTR " %" SCNxPTR " %*ld %*ld %*[^ ] %5[^ ] %*d %*d %*x %c%*s %*s %*s %n",
+	       &region.start, &region.end, permissions, &cow, &path_index) < 4) {
+      DPLOG(WARNING) << "sscanf failed for line: " << line;
+      return false;
+    }
+
+    const char* fullpath = line + path_index;
+    const char* cred     = strchr(fullpath, ' ');
+#else
     uint8_t dev_major = 0;
     uint8_t dev_minor = 0;
     long inode = 0;
-    int path_index = 0;
 
     // Sample format from man 5 proc:
     //
@@ -125,6 +154,7 @@ bool ParseProcMaps(const std::string& input,
       DPLOG(WARNING) << "sscanf failed for line: " << line;
       return false;
     }
+#endif
 
     region.permissions = 0;
 
@@ -143,14 +173,31 @@ bool ParseProcMaps(const std::string& input,
     else if (permissions[2] != '-')
       return false;
 
+#if defined(OS_BSD)
+    if (cow == 'C') {
+      region.permissions |= MappedMemoryRegion::PRIVATE;
+    } else if (cow != 'N') {
+      DPLOG(WARNING) << "unknown value for COW in line " << line << ": " << cow;
+      return false;
+    }
+#else
     if (permissions[3] == 'p')
       region.permissions |= MappedMemoryRegion::PRIVATE;
     else if (permissions[3] != 's' && permissions[3] != 'S')  // Shared memory.
       return false;
+#endif
 
     // Pushing then assigning saves us a string copy.
     regions.push_back(region);
+#if defined(OS_BSD)
+    if (cred != nullptr) {
+      regions.back().path.assign(line + path_index, cred - fullpath);
+    } else {
+      regions.back().path.assign(line + path_index);
+    }
+#else
     regions.back().path.assign(line + path_index);
+#endif
   }
 
   regions_out->swap(regions);