You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
109 lines
2.5 KiB
109 lines
2.5 KiB
/*
|
|
* Copyright (C) 2020 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "read_symbol_map.h"
|
|
|
|
#include <errno.h>
|
|
#include <stdlib.h>
|
|
|
|
#include <algorithm>
|
|
#include <optional>
|
|
#include <string>
|
|
#include <string_view>
|
|
#include <vector>
|
|
|
|
#include "dso.h"
|
|
|
|
namespace simpleperf {
|
|
namespace {
|
|
|
|
std::optional<std::string_view> ConsumeWord(std::string_view& content_ref) {
|
|
size_t begin = content_ref.find_first_not_of(" \t");
|
|
if (begin == content_ref.npos) {
|
|
return {};
|
|
}
|
|
|
|
size_t end = content_ref.find_first_of(" \t", begin + 1);
|
|
if (end == content_ref.npos) {
|
|
end = content_ref.size();
|
|
}
|
|
|
|
auto res = content_ref.substr(begin, end - begin);
|
|
content_ref.remove_prefix(end);
|
|
return res;
|
|
}
|
|
|
|
std::optional<uint64_t> ConsumeUInt(std::string_view& content_ref) {
|
|
auto word = ConsumeWord(content_ref);
|
|
if (!word) {
|
|
return {};
|
|
}
|
|
|
|
errno = 0;
|
|
const char* start = word.value().data();
|
|
char* stop;
|
|
auto res = strtoull(start, &stop, 0);
|
|
if (errno != 0 || stop - start != word.value().size()) {
|
|
return {};
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
void ReadSymbol(std::string_view content, std::vector<Symbol>* symbols) {
|
|
auto addr = ConsumeUInt(content);
|
|
if (!addr) {
|
|
return;
|
|
}
|
|
|
|
auto size = ConsumeUInt(content);
|
|
if (!size) {
|
|
return;
|
|
}
|
|
|
|
auto name = ConsumeWord(content);
|
|
if (!name) {
|
|
return;
|
|
}
|
|
|
|
if (ConsumeWord(content)) {
|
|
return;
|
|
}
|
|
|
|
symbols->emplace_back(name.value(), addr.value(), size.value());
|
|
}
|
|
|
|
} // namespace
|
|
|
|
std::vector<Symbol> ReadSymbolMapFromString(const std::string& content) {
|
|
std::vector<Symbol> symbols;
|
|
|
|
for (size_t begin = 0;;) {
|
|
size_t end = content.find_first_of("\n\r", begin);
|
|
|
|
if (end == content.npos) {
|
|
ReadSymbol({content.c_str() + begin, content.size() - begin}, &symbols);
|
|
std::sort(symbols.begin(), symbols.end(), Symbol::CompareValueByAddr);
|
|
return symbols;
|
|
}
|
|
|
|
ReadSymbol({content.c_str() + begin, end - begin}, &symbols);
|
|
begin = end + 1;
|
|
}
|
|
}
|
|
|
|
} // namespace simpleperf
|