-/**
- * Read a hex value.
- */
-uintptr_t readHex(StringPiece& sp) {
- uintptr_t val = 0;
- const char* p = sp.begin();
- for (; p != sp.end(); ++p) {
- unsigned int v;
- if (*p >= '0' && *p <= '9') {
- v = (*p - '0');
- } else if (*p >= 'a' && *p <= 'f') {
- v = (*p - 'a') + 10;
- } else if (*p >= 'A' && *p <= 'F') {
- v = (*p - 'A') + 10;
- } else {
- break;
- }
- val = (val << 4) + v;
- }
- sp.assign(p, sp.end());
- return val;
-}
-
-/**
- * Skip over non-space characters.
- */
-void skipNS(StringPiece& sp) {
- const char* p = sp.begin();
- for (; p != sp.end() && (*p != ' ' && *p != '\t'); ++p) { }
- sp.assign(p, sp.end());
-}
-
-/**
- * Skip over space and tab characters.
- */
-void skipWS(StringPiece& sp) {
- const char* p = sp.begin();
- for (; p != sp.end() && (*p == ' ' || *p == '\t'); ++p) { }
- sp.assign(p, sp.end());
-}
-
-/**
- * Parse a line from /proc/self/maps
- */
-bool parseProcMapsLine(StringPiece line,
- uintptr_t& from,
- uintptr_t& to,
- uintptr_t& fileOff,
- bool& isSelf,
- StringPiece& fileName) {
- isSelf = false;
- // from to perm offset dev inode path
- // 00400000-00405000 r-xp 00000000 08:03 35291182 /bin/cat
- if (line.empty()) {
- return false;
- }
-
- // Remove trailing newline, if any
- if (line.back() == '\n') {
- line.pop_back();
- }
-
- // from
- from = readHex(line);
- if (line.empty() || line.front() != '-') {
- return false;
- }
- line.pop_front();
-
- // to
- to = readHex(line);
- if (line.empty() || line.front() != ' ') {
- return false;
- }
- line.pop_front();
-
- // perms
- skipNS(line);
- if (line.empty() || line.front() != ' ') {
- return false;
- }
- line.pop_front();
-
- uintptr_t fileOffset = readHex(line);
- if (line.empty() || line.front() != ' ') {
- return false;
- }
- line.pop_front();
- // main mapping starts at 0 but there can be multi-segment binary
- // such as
- // from to perm offset dev inode path
- // 00400000-00405000 r-xp 00000000 08:03 54011424 /bin/foo
- // 00600000-00605000 r-xp 00020000 08:03 54011424 /bin/foo
- // 00800000-00805000 r-xp 00040000 08:03 54011424 /bin/foo
- // if the offset > 0, this indicates to the caller that the baseAddress
- // need to be used for undo relocation step.
- fileOff = fileOffset;
-
- // dev
- skipNS(line);
- if (line.empty() || line.front() != ' ') {
- return false;
- }
- line.pop_front();
-
- // inode
- skipNS(line);
- if (line.empty() || line.front() != ' ') {
- return false;
- }
-
- // if inode is 0, such as in case of ANON pages, there should be atleast
- // one white space before EOL
- skipWS(line);
- if (line.empty()) {
- // There will be no fileName for ANON text pages
- // if the parsing came this far without a fileName, then from/to address
- // may contain text in ANON pages.
- isSelf = true;
- fileName.clear();
- return true;
- }
-
- fileName = line;
- return true;
-}
-