return symbol1->addr < symbol2->addr;
}
+DsoEntry::DsoEntry(DsoType type, const std::string& path)
+ : type(type), path(path), is_loaded(false) {
+}
+
const SymbolEntry* DsoEntry::FindSymbol(uint64_t offset_in_dso) {
+ if (!is_loaded) {
+ DsoFactory::GetInstance()->LoadDso(this);
+ is_loaded = true;
+ }
std::unique_ptr<SymbolEntry> symbol(new SymbolEntry{
"", // name
offset_in_dso, // addr
build_id_map_ = std::move(map);
}
+std::unique_ptr<DsoEntry> DsoFactory::CreateDso(DsoType dso_type, const std::string& dso_path) {
+ std::string path = dso_path;
+ if (dso_type == DSO_KERNEL) {
+ path = "[kernel.kallsyms]";
+ }
+ return std::unique_ptr<DsoEntry>(new DsoEntry(dso_type, path));
+}
+
+bool DsoFactory::LoadDso(DsoEntry* dso) {
+ switch (dso->type) {
+ case DSO_KERNEL:
+ return LoadKernel(dso);
+ case DSO_KERNEL_MODULE:
+ return LoadKernelModule(dso);
+ case DSO_ELF_FILE:
+ return LoadElfFile(dso);
+ default:
+ return false;
+ }
+}
+
static bool IsKernelFunctionSymbol(const KernelSymbol& symbol) {
return (symbol.type == 'T' || symbol.type == 't' || symbol.type == 'W' || symbol.type == 'w');
}
}
}
-std::unique_ptr<DsoEntry> DsoFactory::LoadKernel() {
- std::unique_ptr<DsoEntry> dso(new DsoEntry);
- dso->path = "[kernel.kallsyms]";
+bool DsoFactory::LoadKernel(DsoEntry* dso) {
BuildId build_id = GetExpectedBuildId(DEFAULT_KERNEL_FILENAME_FOR_BUILD_ID);
if (!vmlinux_.empty()) {
ParseSymbolsFromElfFile(vmlinux_, build_id,
- std::bind(VmlinuxSymbolCallback, std::placeholders::_1, dso.get()));
+ std::bind(VmlinuxSymbolCallback, std::placeholders::_1, dso));
} else {
BuildId real_build_id;
GetKernelBuildId(&real_build_id);
<< build_id.ToString() << ", real " << real_build_id.ToString();
if (match) {
ProcessKernelSymbols("/proc/kallsyms",
- std::bind(&KernelSymbolCallback, std::placeholders::_1, dso.get()));
+ std::bind(&KernelSymbolCallback, std::placeholders::_1, dso));
}
}
- FixupSymbolLength(dso.get());
+ FixupSymbolLength(dso);
return dso;
}
return (elf_symbol.is_func && elf_symbol.is_in_text_section);
}
-std::unique_ptr<DsoEntry> DsoFactory::LoadKernelModule(const std::string& dso_path) {
- std::unique_ptr<DsoEntry> dso(new DsoEntry);
- dso->path = dso_path;
- BuildId build_id = GetExpectedBuildId(dso_path);
- ParseSymbolsFromElfFile(symfs_dir_ + dso_path, build_id,
- std::bind(ParseSymbolCallback, std::placeholders::_1, dso.get(),
- SymbolFilterForKernelModule));
- FixupSymbolLength(dso.get());
+bool DsoFactory::LoadKernelModule(DsoEntry* dso) {
+ BuildId build_id = GetExpectedBuildId(dso->path);
+ ParseSymbolsFromElfFile(
+ symfs_dir_ + dso->path, build_id,
+ std::bind(ParseSymbolCallback, std::placeholders::_1, dso, SymbolFilterForKernelModule));
+ FixupSymbolLength(dso);
return dso;
}
}
}
-std::unique_ptr<DsoEntry> DsoFactory::LoadDso(const std::string& dso_path) {
- std::unique_ptr<DsoEntry> dso(new DsoEntry);
- dso->path = dso_path;
- BuildId build_id = GetExpectedBuildId(dso_path);
+bool DsoFactory::LoadElfFile(DsoEntry* dso) {
+ BuildId build_id = GetExpectedBuildId(dso->path);
ParseSymbolsFromElfFile(
- symfs_dir_ + dso_path, build_id,
- std::bind(ParseSymbolCallback, std::placeholders::_1, dso.get(), SymbolFilterForDso));
+ symfs_dir_ + dso->path, build_id,
+ std::bind(ParseSymbolCallback, std::placeholders::_1, dso, SymbolFilterForDso));
if (demangle_) {
for (auto& symbol : dso->symbols) {
DemangleInPlace(&symbol->name);
}
}
- FixupSymbolLength(dso.get());
+ FixupSymbolLength(dso);
return dso;
}
const std::unique_ptr<SymbolEntry>& symbol2);
};
+enum DsoType {
+ DSO_KERNEL,
+ DSO_KERNEL_MODULE,
+ DSO_ELF_FILE,
+};
+
struct DsoEntry {
+ DsoType type;
std::string path;
std::set<std::unique_ptr<SymbolEntry>, SymbolComparator> symbols;
+ DsoEntry(DsoType type, const std::string& path);
const SymbolEntry* FindSymbol(uint64_t offset_in_dso);
+
+ private:
+ bool is_loaded;
};
class DsoFactory {
bool SetSymFsDir(const std::string& symfs_dir);
void SetVmlinux(const std::string& vmlinux);
void SetBuildIds(const std::vector<std::pair<std::string, BuildId>>& build_ids);
- std::unique_ptr<DsoEntry> LoadKernel();
- std::unique_ptr<DsoEntry> LoadKernelModule(const std::string& dso_path);
- std::unique_ptr<DsoEntry> LoadDso(const std::string& dso_path);
+ std::unique_ptr<DsoEntry> CreateDso(DsoType dso_type, const std::string& dso_path = "");
+ bool LoadDso(DsoEntry* dso);
private:
DsoFactory();
+ bool LoadKernel(DsoEntry* dso);
+ bool LoadKernelModule(DsoEntry* dso);
+ bool LoadElfFile(DsoEntry* dso);
BuildId GetExpectedBuildId(const std::string& filename);
bool demangle_;
DsoEntry* SampleTree::FindKernelDsoOrNew(const std::string& filename) {
if (filename == DEFAULT_KERNEL_MMAP_NAME) {
if (kernel_dso_ == nullptr) {
- kernel_dso_ = DsoFactory::GetInstance()->LoadKernel();
+ kernel_dso_ = DsoFactory::GetInstance()->CreateDso(DSO_KERNEL);
}
return kernel_dso_.get();
}
auto it = module_dso_tree_.find(filename);
if (it == module_dso_tree_.end()) {
- module_dso_tree_[filename] = DsoFactory::GetInstance()->LoadKernelModule(filename);
+ module_dso_tree_[filename] = DsoFactory::GetInstance()->CreateDso(DSO_KERNEL_MODULE, filename);
it = module_dso_tree_.find(filename);
}
return it->second.get();
DsoEntry* SampleTree::FindUserDsoOrNew(const std::string& filename) {
auto it = user_dso_tree_.find(filename);
if (it == user_dso_tree_.end()) {
- user_dso_tree_[filename] = DsoFactory::GetInstance()->LoadDso(filename);
+ user_dso_tree_[filename] = DsoFactory::GetInstance()->CreateDso(DSO_ELF_FILE, filename);
it = user_dso_tree_.find(filename);
}
return it->second.get();