LLDB  mainline
LinuxProcMaps.cpp
Go to the documentation of this file.
1 //===-- LinuxProcMaps.cpp ---------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "LinuxProcMaps.h"
10 #include "llvm/ADT/StringRef.h"
12 #include "lldb/Utility/Status.h"
14 
15 using namespace lldb_private;
16 
17 static Status
18 ParseMemoryRegionInfoFromProcMapsLine(llvm::StringRef maps_line,
19  MemoryRegionInfo &memory_region_info) {
20  memory_region_info.Clear();
21 
22  StringExtractor line_extractor(maps_line);
23 
24  // Format: {address_start_hex}-{address_end_hex} perms offset dev inode
25  // pathname perms: rwxp (letter is present if set, '-' if not, final
26  // character is p=private, s=shared).
27 
28  // Parse out the starting address
29  lldb::addr_t start_address = line_extractor.GetHexMaxU64(false, 0);
30 
31  // Parse out hyphen separating start and end address from range.
32  if (!line_extractor.GetBytesLeft() || (line_extractor.GetChar() != '-'))
33  return Status(
34  "malformed /proc/{pid}/maps entry, missing dash between address range");
35 
36  // Parse out the ending address
37  lldb::addr_t end_address = line_extractor.GetHexMaxU64(false, start_address);
38 
39  // Parse out the space after the address.
40  if (!line_extractor.GetBytesLeft() || (line_extractor.GetChar() != ' '))
41  return Status(
42  "malformed /proc/{pid}/maps entry, missing space after range");
43 
44  // Save the range.
45  memory_region_info.GetRange().SetRangeBase(start_address);
46  memory_region_info.GetRange().SetRangeEnd(end_address);
47 
48  // Any memory region in /proc/{pid}/maps is by definition mapped into the
49  // process.
50  memory_region_info.SetMapped(MemoryRegionInfo::OptionalBool::eYes);
51 
52  // Parse out each permission entry.
53  if (line_extractor.GetBytesLeft() < 4)
54  return Status("malformed /proc/{pid}/maps entry, missing some portion of "
55  "permissions");
56 
57  // Handle read permission.
58  const char read_perm_char = line_extractor.GetChar();
59  if (read_perm_char == 'r')
60  memory_region_info.SetReadable(MemoryRegionInfo::OptionalBool::eYes);
61  else if (read_perm_char == '-')
62  memory_region_info.SetReadable(MemoryRegionInfo::OptionalBool::eNo);
63  else
64  return Status("unexpected /proc/{pid}/maps read permission char");
65 
66  // Handle write permission.
67  const char write_perm_char = line_extractor.GetChar();
68  if (write_perm_char == 'w')
69  memory_region_info.SetWritable(MemoryRegionInfo::OptionalBool::eYes);
70  else if (write_perm_char == '-')
71  memory_region_info.SetWritable(MemoryRegionInfo::OptionalBool::eNo);
72  else
73  return Status("unexpected /proc/{pid}/maps write permission char");
74 
75  // Handle execute permission.
76  const char exec_perm_char = line_extractor.GetChar();
77  if (exec_perm_char == 'x')
78  memory_region_info.SetExecutable(MemoryRegionInfo::OptionalBool::eYes);
79  else if (exec_perm_char == '-')
80  memory_region_info.SetExecutable(MemoryRegionInfo::OptionalBool::eNo);
81  else
82  return Status("unexpected /proc/{pid}/maps exec permission char");
83 
84  line_extractor.GetChar(); // Read the private bit
85  line_extractor.SkipSpaces(); // Skip the separator
86  line_extractor.GetHexMaxU64(false, 0); // Read the offset
87  line_extractor.GetHexMaxU64(false, 0); // Read the major device number
88  line_extractor.GetChar(); // Read the device id separator
89  line_extractor.GetHexMaxU64(false, 0); // Read the major device number
90  line_extractor.SkipSpaces(); // Skip the separator
91  line_extractor.GetU64(0, 10); // Read the inode number
92 
93  line_extractor.SkipSpaces();
94  const char *name = line_extractor.Peek();
95  if (name)
96  memory_region_info.SetName(name);
97 
98  return Status();
99 }
100 
101 void lldb_private::ParseLinuxMapRegions(llvm::StringRef linux_map,
102  LinuxMapCallback const &callback) {
103  llvm::StringRef lines(linux_map);
104  llvm::StringRef line;
105  while (!lines.empty()) {
106  std::tie(line, lines) = lines.split('\n');
107  MemoryRegionInfo region;
108  Status error = ParseMemoryRegionInfoFromProcMapsLine(line, region);
109  if (!callback(region, error))
110  break;
111  }
112 }
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
void SetExecutable(OptionalBool val)
uint64_t GetU64(uint64_t fail_value, int base=0)
void SetMapped(OptionalBool val)
void ParseLinuxMapRegions(llvm::StringRef linux_map, LinuxMapCallback const &callback)
void SetName(const char *name)
void SetRangeEnd(BaseType end)
Definition: RangeMap.h:64
uint64_t GetHexMaxU64(bool little_endian, uint64_t fail_value)
size_t GetBytesLeft()
uint64_t addr_t
Definition: lldb-types.h:83
void SetReadable(OptionalBool val)
const char * Peek()
void SetRangeBase(BaseType b)
Definition: RangeMap.h:48
void SetWritable(OptionalBool val)
char GetChar(char fail_value='\0')
static Status ParseMemoryRegionInfoFromProcMapsLine(llvm::StringRef maps_line, MemoryRegionInfo &memory_region_info)
An error handling class.
Definition: Status.h:44
std::function< bool(const lldb_private::MemoryRegionInfo &, const lldb_private::Status &)> LinuxMapCallback
Definition: LinuxProcMaps.h:20