1 // Copyright 2016 The Chromium OS Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "dso.h" 6 7 #include <elf.h> 8 #include <fcntl.h> 9 #include <string.h> 10 #include <sys/stat.h> 11 #include <sys/sysmacros.h> 12 #include <unistd.h> 13 14 #include <algorithm> 15 #include <vector> 16 17 #include <build_id.h> 18 #include <read_elf.h> 19 20 #include "base/logging.h" 21 #include "compat/string.h" 22 #include "file_reader.h" 23 24 namespace quipper { 25 26 void InitializeLibelf() { 27 // Unnecessary. 28 } 29 30 bool ReadElfBuildId(const string &filename, string *buildid) { 31 BuildId id; 32 ElfStatus status = GetBuildIdFromElfFile(filename, &id); 33 if (status == ElfStatus::NO_ERROR) { 34 *buildid = id.ToString(); 35 return true; 36 } 37 return false; 38 } 39 40 bool ReadElfBuildId(int fd, string *buildid) { 41 // TODO: Implement. b/74410255. 42 return false; 43 } 44 45 // read /sys/module/<module_name>/notes/.note.gnu.build-id 46 bool ReadModuleBuildId(const string &module_name, string *buildid) { 47 string note_filename = 48 "/sys/module/" + module_name + "/notes/.note.gnu.build-id"; 49 50 FileReader file(note_filename); 51 if (!file.IsOpen()) return false; 52 53 return ReadBuildIdNote(&file, buildid); 54 } 55 56 bool ReadBuildIdNote(DataReader *data, string *buildid) { 57 // Non-simpleperf implementation, as a reader is given. 58 Elf64_Nhdr note_header; 59 60 while (data->ReadData(sizeof(note_header), ¬e_header)) { 61 size_t name_size = Align<4>(note_header.n_namesz); 62 size_t desc_size = Align<4>(note_header.n_descsz); 63 64 string name; 65 if (!data->ReadString(name_size, &name)) return false; 66 string desc; 67 if (!data->ReadDataString(desc_size, &desc)) return false; 68 if (note_header.n_type == NT_GNU_BUILD_ID && name == ELF_NOTE_GNU) { 69 *buildid = desc; 70 return true; 71 } 72 } 73 return false; 74 } 75 76 bool IsKernelNonModuleName(string name) { 77 // List from kernel: tools/perf/util/dso.c : __kmod_path__parse() 78 static const std::vector<string> kKernelNonModuleNames{ 79 "[kernel.kallsyms]", 80 "[guest.kernel.kallsyms", 81 "[vdso]", 82 "[vsyscall]", 83 }; 84 85 for (const auto &n : kKernelNonModuleNames) { 86 if (name.compare(0, n.size(), n) == 0) return true; 87 } 88 return false; 89 } 90 91 // Do the |DSOInfo| and |struct stat| refer to the same inode? 92 bool SameInode(const DSOInfo &dso, const struct stat *s) { 93 return dso.maj == major(s->st_dev) && dso.min == minor(s->st_dev) && 94 dso.ino == s->st_ino; 95 } 96 97 } // namespace quipper 98