summaryrefslogtreecommitdiff
path: root/simpleperf/read_elf.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'simpleperf/read_elf.cpp')
-rw-r--r--simpleperf/read_elf.cpp48
1 files changed, 27 insertions, 21 deletions
diff --git a/simpleperf/read_elf.cpp b/simpleperf/read_elf.cpp
index 0f6aa415..65dd5739 100644
--- a/simpleperf/read_elf.cpp
+++ b/simpleperf/read_elf.cpp
@@ -217,20 +217,6 @@ static ElfStatus OpenObjectFileInMemory(const char* data, size_t size, BinaryWra
return ElfStatus::NO_ERROR;
}
-ElfStatus GetBuildIdFromElfFile(const std::string& filename, BuildId* build_id) {
- return GetBuildIdFromEmbeddedElfFile(filename, 0, 0, build_id);
-}
-
-ElfStatus GetBuildIdFromEmbeddedElfFile(const std::string& filename, uint64_t file_offset,
- uint32_t file_size, BuildId* build_id) {
- BinaryWrapper wrapper;
- ElfStatus result = OpenObjectFile(filename, file_offset, file_size, &wrapper);
- if (result != ElfStatus::NO_ERROR) {
- return result;
- }
- return GetBuildIdFromObjectFile(wrapper.obj, build_id);
-}
-
template <class ELFT>
ElfStatus ReadSectionFromELFFile(const llvm::object::ELFObjectFile<ELFT>* elf, const std::string& section_name,
std::string* content) {
@@ -571,10 +557,10 @@ template <typename T>
class ElfFileImpl {};
template <typename ELFT>
-class ElfFileImpl<llvm::object::ELFFile<ELFT>> : public ElfFile {
+class ElfFileImpl<llvm::object::ELFObjectFile<ELFT>> : public ElfFile {
public:
- ElfFileImpl(BinaryWrapper&& wrapper, const llvm::object::ELFFile<ELFT>* elf)
- : wrapper_(std::move(wrapper)), elf_(elf) {}
+ ElfFileImpl(BinaryWrapper&& wrapper, const llvm::object::ELFObjectFile<ELFT>* elf_obj)
+ : wrapper_(std::move(wrapper)), elf_obj_(elf_obj), elf_(elf_obj->getELFFile()) {}
bool Is64Bit() override {
return elf_->getHeader()->getFileClass() == llvm::ELF::ELFCLASS64;
@@ -598,8 +584,30 @@ class ElfFileImpl<llvm::object::ELFFile<ELFT>> : public ElfFile {
return segments;
}
+ ElfStatus GetBuildId(BuildId* build_id) override {
+ llvm::StringRef data = elf_obj_->getData();
+ const char* binary_start = data.data();
+ const char* binary_end = data.data() + data.size();
+ for (auto it = elf_obj_->section_begin(); it != elf_obj_->section_end(); ++it) {
+ const llvm::object::ELFSectionRef& section_ref = *it;
+ if (section_ref.getType() == llvm::ELF::SHT_NOTE) {
+ if (it->getContents(data)) {
+ return ElfStatus::READ_FAILED;
+ }
+ if (data.data() < binary_start || data.data() + data.size() > binary_end) {
+ return ElfStatus::NO_BUILD_ID;
+ }
+ if (GetBuildIdFromNoteSection(data.data(), data.size(), build_id)) {
+ return ElfStatus::NO_ERROR;
+ }
+ }
+ }
+ return ElfStatus::NO_BUILD_ID;
+ }
+
private:
BinaryWrapper wrapper_;
+ const llvm::object::ELFObjectFile<ELFT>* elf_obj_;
const llvm::object::ELFFile<ELFT>* elf_;
};
@@ -622,14 +630,12 @@ std::unique_ptr<ElfFile> ElfFile::Open(const std::string& filename, ElfStatus* s
}
if (*status == ElfStatus::NO_ERROR) {
if (auto obj = llvm::dyn_cast<llvm::object::ELF32LEObjectFile>(wrapper.obj)) {
- using elf_t = std::decay_t<decltype(*obj->getELFFile())>;
return std::unique_ptr<ElfFile>(
- new ElfFileImpl<elf_t>(std::move(wrapper), obj->getELFFile()));
+ new ElfFileImpl<llvm::object::ELF32LEObjectFile>(std::move(wrapper), obj));
}
if (auto obj = llvm::dyn_cast<llvm::object::ELF64LEObjectFile>(wrapper.obj)) {
- using elf_t = std::decay_t<decltype(*obj->getELFFile())>;
return std::unique_ptr<ElfFile>(
- new ElfFileImpl<elf_t>(std::move(wrapper), obj->getELFFile()));
+ new ElfFileImpl<llvm::object::ELF64LEObjectFile>(std::move(wrapper), obj));
}
*status = ElfStatus::FILE_MALFORMED;
}