summaryrefslogtreecommitdiff
path: root/simpleperf/dso.cpp
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2017-05-19 12:57:44 -0700
committerYabin Cui <yabinc@google.com>2017-05-19 15:12:04 -0700
commit63a1c3d83a68e9d94f37b71afe76d0769d744448 (patch)
treec1ce718db9892825761737404d0716280863971b /simpleperf/dso.cpp
parent542c1b32fa9b9b878ff353336dc36df4d6f442e7 (diff)
downloadextras-63a1c3d83a68e9d94f37b71afe76d0769d744448.tar.gz
simpleperf: support [vdso].
Before this CL, there is no way to parse symbols from [vdso] or unwind through it. In this CL, simpleperf dumps [vdso] segment in its own memory space to local file system, so it can be used for getting symbols or unwinding. It takes care that vdso files for 32bit version and 64bit version are not misused. Bug: None. Test: run simpleperf_unit_test. Test: run simpleperf on processes using vdso. Change-Id: I9233daf1d07df262a4a0fcdeadd3e544f3ccc906
Diffstat (limited to 'simpleperf/dso.cpp')
-rw-r--r--simpleperf/dso.cpp32
1 files changed, 27 insertions, 5 deletions
diff --git a/simpleperf/dso.cpp b/simpleperf/dso.cpp
index 40603fe8..4f202bcd 100644
--- a/simpleperf/dso.cpp
+++ b/simpleperf/dso.cpp
@@ -60,6 +60,8 @@ bool Dso::read_kernel_symbols_from_proc_;
std::unordered_map<std::string, BuildId> Dso::build_id_map_;
size_t Dso::dso_count_;
uint32_t Dso::g_dump_id_;
+std::unique_ptr<TemporaryFile> Dso::vdso_64bit_;
+std::unique_ptr<TemporaryFile> Dso::vdso_32bit_;
void Dso::SetDemangle(bool demangle) { demangle_ = demangle; }
@@ -119,6 +121,14 @@ void Dso::SetBuildIds(
build_id_map_ = std::move(map);
}
+void Dso::SetVdsoFile(std::unique_ptr<TemporaryFile> vdso_file, bool is_64bit) {
+ if (is_64bit) {
+ vdso_64bit_ = std::move(vdso_file);
+ } else {
+ vdso_32bit_ = std::move(vdso_file);
+ }
+}
+
BuildId Dso::FindExpectedBuildIdForPath(const std::string& path) {
auto it = build_id_map_.find(path);
if (it != build_id_map_.end()) {
@@ -131,12 +141,12 @@ BuildId Dso::GetExpectedBuildId() {
return FindExpectedBuildIdForPath(path_);
}
-std::unique_ptr<Dso> Dso::CreateDso(DsoType dso_type,
- const std::string& dso_path) {
- return std::unique_ptr<Dso>(new Dso(dso_type, dso_path));
+std::unique_ptr<Dso> Dso::CreateDso(DsoType dso_type, const std::string& dso_path,
+ bool force_64bit) {
+ return std::unique_ptr<Dso>(new Dso(dso_type, dso_path, force_64bit));
}
-Dso::Dso(DsoType type, const std::string& path)
+Dso::Dso(DsoType type, const std::string& path, bool force_64bit)
: type_(type),
path_(path),
debug_file_path_(path),
@@ -158,6 +168,12 @@ Dso::Dso(DsoType type, const std::string& path)
if (IsRegularFile(file_path)) {
debug_file_path_ = path_in_symfs;
}
+ } else if (path == "[vdso]") {
+ if (force_64bit && vdso_64bit_ != nullptr) {
+ debug_file_path_ = vdso_64bit_->path;
+ } else if (!force_64bit && vdso_32bit_ != nullptr) {
+ debug_file_path_ = vdso_32bit_->path;
+ }
}
size_t pos = path.find_last_of("/\\");
if (pos != std::string::npos) {
@@ -179,6 +195,8 @@ Dso::~Dso() {
read_kernel_symbols_from_proc_ = false;
build_id_map_.clear();
g_dump_id_ = 0;
+ vdso_64bit_ = nullptr;
+ vdso_32bit_ = nullptr;
}
}
@@ -326,11 +344,15 @@ static void VmlinuxSymbolCallback(const ElfFileSymbol& elf_symbol,
}
}
-bool CheckReadSymbolResult(ElfStatus result, const std::string& filename) {
+bool Dso::CheckReadSymbolResult(ElfStatus result, const std::string& filename) {
if (result == ElfStatus::NO_ERROR) {
LOG(VERBOSE) << "Read symbols from " << filename << " successfully";
return true;
} else if (result == ElfStatus::NO_SYMBOL_TABLE) {
+ if (path_ == "[vdso]") {
+ // Vdso only contains dynamic symbol table, and we can't change that.
+ return true;
+ }
// Lacking symbol table isn't considered as an error but worth reporting.
LOG(WARNING) << filename << " doesn't contain symbol table";
return true;