diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -682,14 +682,14 @@ void printNotes() override; void printELFLinkerOptions() override; void printStackSizes() override; + void printSymbolSection(const Elf_Sym &Symbol, unsigned SymIndex, + DataRegion ShndxTable) const; private: void printRelrReloc(const Elf_Relr &R) override; void printRelRelaReloc(const Relocation &R, const RelSymbol &RelSym) override; - void printSymbolSection(const Elf_Sym &Symbol, unsigned SymIndex, - DataRegion ShndxTable) const; void printSymbol(const Elf_Sym &Symbol, unsigned SymIndex, DataRegion ShndxTable, Optional StrTable, bool IsDynamic, @@ -720,6 +720,11 @@ ArrayRef InputFilenames, const Archive *A) override; + void printSymbol(const Elf_Sym &Symbol, unsigned SymIndex, + DataRegion ShndxTable, + Optional StrTable, bool IsDynamic, + bool /*NonVisibilityBitsUsed*/) const override; + private: std::unique_ptr FileScope; }; @@ -7542,3 +7547,56 @@ std::string(formatv("{0}bit", 8 * Obj.getBytesInAddress()))); this->printLoadName(); } +template +void JSONELFDumper::printSymbol(const Elf_Sym &Symbol, unsigned SymIndex, + DataRegion ShndxTable, + Optional StrTable, + bool IsDynamic, + bool /*NonVisibilityBitsUsed*/) const { + std::string FullSymbolName = this->getFullSymbolName( + Symbol, SymIndex, ShndxTable, StrTable, IsDynamic); + unsigned char SymbolType = Symbol.getType(); + ScopedPrinter &W = this->W; + + DictScope D(W, "Symbol"); + W.printNumber("Name", FullSymbolName, Symbol.st_name); + W.printHex("Value", Symbol.st_value); + W.printNumber("Size", Symbol.st_size); + W.printEnum("Binding", Symbol.getBinding(), makeArrayRef(ElfSymbolBindings)); + if (this->Obj.getHeader().e_machine == ELF::EM_AMDGPU && + SymbolType >= ELF::STT_LOOS && SymbolType < ELF::STT_HIOS) + W.printEnum("Type", SymbolType, makeArrayRef(AMDGPUSymbolTypes)); + else + W.printEnum("Type", SymbolType, makeArrayRef(ElfSymbolTypes)); + if (Symbol.st_other == 0) + // Usually st_other flag is zero. Do not pollute the output + // by flags enumeration in that case. + W.printString("Other", "{}"); + else { + std::vector> SymOtherFlags(std::begin(ElfSymOtherFlags), + std::end(ElfSymOtherFlags)); + if (this->Obj.getHeader().e_machine == EM_MIPS) { + // Someones in their infinite wisdom decided to make STO_MIPS_MIPS16 + // flag overlapped with other ST_MIPS_xxx flags. So consider both + // cases separately. + if ((Symbol.st_other & STO_MIPS_MIPS16) == STO_MIPS_MIPS16) + SymOtherFlags.insert(SymOtherFlags.end(), + std::begin(ElfMips16SymOtherFlags), + std::end(ElfMips16SymOtherFlags)); + else + SymOtherFlags.insert(SymOtherFlags.end(), + std::begin(ElfMipsSymOtherFlags), + std::end(ElfMipsSymOtherFlags)); + } else if (this->Obj.getHeader().e_machine == EM_AARCH64) { + SymOtherFlags.insert(SymOtherFlags.end(), + std::begin(ElfAArch64SymOtherFlags), + std::end(ElfAArch64SymOtherFlags)); + } else if (this->Obj.getHeader().e_machine == EM_RISCV) { + SymOtherFlags.insert(SymOtherFlags.end(), + std::begin(ElfRISCVSymOtherFlags), + std::end(ElfRISCVSymOtherFlags)); + } + W.printFlags("Other", Symbol.st_other, makeArrayRef(SymOtherFlags), 0x3u); + } + this->printSymbolSection(Symbol, SymIndex, ShndxTable); +}