| 90 | } |
| 91 | |
| 92 | bool ParseProcMaps(const std::string& input, |
| 93 | std::vector<MappedMemoryRegion>* regions_out) { |
| 94 | CHECK(regions_out); |
| 95 | std::vector<MappedMemoryRegion> regions; |
| 96 | |
| 97 | // This isn't async safe nor terribly efficient, but it doesn't need to be at |
| 98 | // this point in time. |
| 99 | std::vector<std::string> lines; |
| 100 | SplitString(input, '\n', &lines); |
| 101 | |
| 102 | for (size_t i = 0; i < lines.size(); ++i) { |
| 103 | // Due to splitting on '\n' the last line should be empty. |
| 104 | if (i == lines.size() - 1) { |
| 105 | if (!lines[i].empty()) { |
| 106 | DLOG(WARNING) << "Last line not empty"; |
| 107 | return false; |
| 108 | } |
| 109 | break; |
| 110 | } |
| 111 | |
| 112 | MappedMemoryRegion region; |
| 113 | const char* line = lines[i].c_str(); |
| 114 | char permissions[5] = {'\0'}; // Ensure NUL-terminated string. |
| 115 | uint8_t dev_major = 0; |
| 116 | uint8_t dev_minor = 0; |
| 117 | long inode = 0; |
| 118 | int path_index = 0; |
| 119 | |
| 120 | // Sample format from man 5 proc: |
| 121 | // |
| 122 | // address perms offset dev inode pathname |
| 123 | // 08048000-08056000 r-xp 00000000 03:0c 64593 /usr/sbin/gpm |
| 124 | // |
| 125 | // The final %n term captures the offset in the input string, which is used |
| 126 | // to determine the path name. It *does not* increment the return value. |
| 127 | // Refer to man 3 sscanf for details. |
| 128 | if (sscanf(line, "%" SCNxPTR "-%" SCNxPTR " %4c %llx %hhx:%hhx %ld %n", |
| 129 | ®ion.start, ®ion.end, permissions, ®ion.offset, |
| 130 | &dev_major, &dev_minor, &inode, &path_index) < 7) { |
| 131 | DPLOG(WARNING) << "sscanf failed for line: " << line; |
| 132 | return false; |
| 133 | } |
| 134 | |
| 135 | region.permissions = 0; |
| 136 | |
| 137 | if (permissions[0] == 'r') |
| 138 | region.permissions |= MappedMemoryRegion::READ; |
| 139 | else if (permissions[0] != '-') |
| 140 | return false; |
| 141 | |
| 142 | if (permissions[1] == 'w') |
| 143 | region.permissions |= MappedMemoryRegion::WRITE; |
| 144 | else if (permissions[1] != '-') |
| 145 | return false; |
| 146 | |
| 147 | if (permissions[2] == 'x') |
| 148 | region.permissions |= MappedMemoryRegion::EXECUTE; |
| 149 | else if (permissions[2] != '-') |