#include "ClangMapFileParser.h" #include "ClangSectionParser.h" #include "ClangSymbolParser.h" #include #include #include #include "../ParseBuffer.h" namespace mapfileparser { static std::string ReadUntilLine(std::istream& is, const char* delimiterLine) { std::string line; std::getline(is, line); while (!is.eof() && line != delimiterLine) std::getline(is, line); return line; } static void ReadObjectFiles(std::istream& is, std::vector& objectFiles) { std::string line; const char* symbolsHeader = "# Sections:"; std::getline(is, line); while (!is.eof() && line != symbolsHeader) { int32_t objectFileIndex = 0; size_t lineLength = line.length(); ParseBuffer name(lineLength); sscanf(line.c_str(), "[%d] %s", &objectFileIndex, name.buffer); objectFiles.push_back(std::string(name.buffer)); std::getline(is, line); } } static void ReadSections(std::istream& is, std::vector
& sections) { std::string line; const char* symbolsHeader = "# Symbols:"; std::getline(is, line); while (!is.eof() && line != symbolsHeader) { sections.push_back(ClangSectionParser::Parse(line)); std::getline(is, line); } } static void ReadSymbols(std::istream& is, std::vector& symbols, const std::vector& objectFiles) { std::string line; while (!is.eof()) { std::getline(is, line); if (line.length() == 0) continue; if (line == "# Dead Stripped Symbols:") break; // Each managed method has _m in its name, so only record those. if (line.find("_m") == std::string::npos) continue; ClangSymbol clangSymbol = ClangSymbolParser::Parse(line); clangSymbol.symbol.segmentType = kSegmentTypeCode; clangSymbol.symbol.objectFile = objectFiles[clangSymbol.objectFileIndex]; symbols.push_back(clangSymbol.symbol); } } MapFile ClangMapFileParser::Parse(std::istream& is) { MapFile mapFile; std::string line; ReadUntilLine(is, "# Object files:"); std::vector objectFiles; ReadObjectFiles(is, objectFiles); // Read sections headers line std::getline(is, line); ReadSections(is, mapFile.sections); // Read symbols headers line std::getline(is, line); ReadSymbols(is, mapFile.symbols, objectFiles); return mapFile; } }