simpleperf: Add links for ARM/RISCV mapping symbols Bug: none Test: run simpleperf_unit_test Change-Id: Ia59db0d998fd582e6f064e183ae947ffd23560d9
diff --git a/simpleperf/read_elf.cpp b/simpleperf/read_elf.cpp index 26037b2..a8c92dd 100644 --- a/simpleperf/read_elf.cpp +++ b/simpleperf/read_elf.cpp
@@ -130,15 +130,20 @@ } bool IsArmMappingSymbol(const char* name) { - // Mapping symbols in arm, which are described in "ELF for ARM Architecture" and - // "ELF for ARM 64-bit Architecture". The regular expression to match mapping symbol - // is ^\$(a|d|t|x)(\..*)?$ + // Matches ARM ELF mapping symbols (e.g., $a, $d, $t, $x, $x.foo). + // See: + // - ARM64 (ELF for the ARM 64-bit Architecture): + // https://github.com/ARM-software/abi-aa/blob/main/aaelf64/aaelf64.rst#mapping-symbols + // - ARM (ELF for the ARM Architecture): + // https://github.com/ARM-software/abi-aa/blob/main/aaelf32/aaelf32.rst#mapping-symbols + // Regex: ^\$(a|d|t|x)(\..*)?$ return name[0] == '$' && strchr("adtx", name[1]) != nullptr && (name[2] == '\0' || name[2] == '.'); } bool IsRISCVMappingSymbol(const char* name) { - // Mapping symbols in RISC-V, which are described in "RISC-V ABIs Specification". + // Mapping symbols in RISC-V, which are described in "RISC-V ABIs Specification", in + // https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#mapping-symbol. // It could be $d, $d.<any>, $x, $x.<any>, $x<isa> or $x<isa>.<any>. // We just loosely check the first character is '$' and the second character is 'd' or 'x'. return name[0] == '$' && strchr("dx", name[1]) != nullptr; @@ -237,8 +242,10 @@ } void ReadSymbolTable(llvm::object::symbol_iterator sym_begin, llvm::object::symbol_iterator sym_end, - const std::function<void(const ElfFileSymbol&)>& callback, bool is_arm, - bool is_riscv, const llvm::object::section_iterator& section_end) { + const std::function<void(const ElfFileSymbol&)>& callback, int machine, + const llvm::object::section_iterator& section_end) { + bool is_arm = (machine == llvm::ELF::EM_ARM || machine == llvm::ELF::EM_AARCH64); + bool is_riscv = machine == llvm::ELF::EM_RISCV; for (; sym_begin != sym_end; ++sym_begin) { ElfFileSymbol symbol; auto symbol_ref = static_cast<const llvm::object::ELFSymbolRef*>(&*sym_begin); @@ -422,29 +429,29 @@ } ElfStatus ParseSymbols(const ParseSymbolCallback& callback) override { - auto machine = GetELFHeader(elf_).e_machine; - bool is_arm = (machine == llvm::ELF::EM_ARM || machine == llvm::ELF::EM_AARCH64); - bool is_riscv = machine == llvm::ELF::EM_RISCV; AddSymbolForPltSection(elf_obj_, callback); // Some applications deliberately ship elf files with broken section tables. // So check the existence of .symtab section and .dynsym section before reading symbols. bool has_symtab; bool has_dynsym; CheckSymbolSections(elf_obj_, &has_symtab, &has_dynsym); + int machine = GetELFHeader(elf_).e_machine; if (has_symtab && elf_obj_->symbol_begin() != elf_obj_->symbol_end()) { - ReadSymbolTable(elf_obj_->symbol_begin(), elf_obj_->symbol_end(), callback, is_arm, is_riscv, + ReadSymbolTable(elf_obj_->symbol_begin(), elf_obj_->symbol_end(), callback, machine, elf_obj_->section_end()); return ElfStatus::NO_ERROR; - } else if (has_dynsym && elf_obj_->dynamic_symbol_begin()->getRawDataRefImpl() != - llvm::object::DataRefImpl()) { + } + if (has_dynsym && + elf_obj_->dynamic_symbol_begin()->getRawDataRefImpl() != llvm::object::DataRefImpl()) { ReadSymbolTable(elf_obj_->dynamic_symbol_begin(), elf_obj_->dynamic_symbol_end(), callback, - is_arm, is_riscv, elf_obj_->section_end()); + machine, elf_obj_->section_end()); } std::string debugdata; ElfStatus result = ReadSection(".gnu_debugdata", &debugdata); if (result == ElfStatus::SECTION_NOT_FOUND) { return ElfStatus::NO_SYMBOL_TABLE; - } else if (result == ElfStatus::NO_ERROR) { + } + if (result == ElfStatus::NO_ERROR) { std::string decompressed_data; if (XzDecompress(debugdata, &decompressed_data)) { auto debugdata_elf = @@ -458,11 +465,8 @@ } void ParseDynamicSymbols(const ParseSymbolCallback& callback) override { - auto machine = GetELFHeader(elf_).e_machine; - bool is_arm = (machine == llvm::ELF::EM_ARM || machine == llvm::ELF::EM_AARCH64); - bool is_riscv = machine == llvm::ELF::EM_RISCV; ReadSymbolTable(elf_obj_->dynamic_symbol_begin(), elf_obj_->dynamic_symbol_end(), callback, - is_arm, is_riscv, elf_obj_->section_end()); + GetELFHeader(elf_).e_machine, elf_obj_->section_end()); } ElfStatus ReadSection(const std::string& section_name, std::string* content) override {