diff --git a/llvm/include/llvm/Object/XCOFFObjectFile.h b/llvm/include/llvm/Object/XCOFFObjectFile.h --- a/llvm/include/llvm/Object/XCOFFObjectFile.h +++ b/llvm/include/llvm/Object/XCOFFObjectFile.h @@ -431,6 +431,10 @@ uint32_t getNumberOfSymbolTableEntries() const; uint32_t getSymbolIndex(uintptr_t SymEntPtr) const; + uintptr_t getSymbolByIndex(uint32_t Idx) const { + return reinterpret_cast(SymbolTblPtr) + + XCOFF::SymbolTableEntrySize * Idx; + } uintptr_t getSymbolEntryAddressByIndex(uint32_t SymbolTableIndex) const; Expected getSymbolNameByIndex(uint32_t SymbolTableIndex) const; diff --git a/llvm/test/tools/llvm-objdump/XCOFF/symbol-table.test b/llvm/test/tools/llvm-objdump/XCOFF/symbol-table.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-objdump/XCOFF/symbol-table.test @@ -0,0 +1,40 @@ +; RUN: llc -mtriple powerpc-ibm-aix -verify-machineinstrs -mcpu=pwr4 \ +; RUN: -filetype=obj -o %t.o < %s +; RUN: llvm-objdump --syms %t.o | FileCheck --check-prefix=SYM %s +; RUN: llvm-objdump --syms --symbol-description %t.o | FileCheck --check-prefix=SYM-DES %s + +define i32 @_Z3bari(i32 %i) { +entry: + %i.addr = alloca i32, align 4 + store i32 %i, i32* %i.addr, align 4 + %0 = load i32, i32* %i.addr, align 4 + %add = add nsw i32 %0, 1 + ret i32 %add +} + +define i32 @_Z3fooi(i32 %i) { +entry: + %i.addr = alloca i32, align 4 + store i32 %i, i32* %i.addr, align 4 + %0 = load i32, i32* %i.addr, align 4 + %add = add nsw i32 %0, 2 + ret i32 %add +} + +; SYM: SYMBOL TABLE: +; SYM-NEXT: 00000000 *UND* .file +; SYM-NEXT: 00000000 l .text .text +; SYM-NEXT: 00000000 l .text(Csect: .text) ._Z3bari +; SYM-NEXT: 00000030 l .text(Csect: .text) ._Z3fooi +; SYM-NEXT: 00000060 l .data _Z3bari +; SYM-NEXT: 0000006c l .data _Z3fooi +; SYM-NEXT: 00000078 l .data TOC + +; SYM-DES: SYMBOL TABLE: +; SYM-DES-NEXT: 00000000 *UND* (idx: 0) .file +; SYM-DES-NEXT: 00000000 l .text (idx: 1) .text[PR] +; SYM-DES-NEXT: 00000000 l .text(Csect: (idx: 1) .text[PR]) (idx: 3) ._Z3bari +; SYM-DES-NEXT: 00000030 l .text(Csect: (idx: 1) .text[PR]) (idx: 5) ._Z3fooi +; SYM-DES-NEXT: 00000060 l .data (idx: 7) _Z3bari[DS] +; SYM-DES-NEXT: 0000006c l .data (idx: 9) _Z3fooi[DS] +; SYM-DES-NEXT: 00000078 l .data (idx: 11) TOC[TC0] diff --git a/llvm/tools/llvm-objdump/XCOFFDump.h b/llvm/tools/llvm-objdump/XCOFFDump.h --- a/llvm/tools/llvm-objdump/XCOFFDump.h +++ b/llvm/tools/llvm-objdump/XCOFFDump.h @@ -20,6 +20,10 @@ getXCOFFSymbolCsectSMC(const object::XCOFFObjectFile *Obj, const object::SymbolRef &Sym); +Optional +getXCOFFSymbolContainingSymbolRef(const object::XCOFFObjectFile *Obj, + const object::SymbolRef &Sym); + bool isLabel(const object::XCOFFObjectFile *Obj, const object::SymbolRef &Sym); std::string getXCOFFSymbolDescription(const SymbolInfoTy &SymbolInfo, diff --git a/llvm/tools/llvm-objdump/XCOFFDump.cpp b/llvm/tools/llvm-objdump/XCOFFDump.cpp --- a/llvm/tools/llvm-objdump/XCOFFDump.cpp +++ b/llvm/tools/llvm-objdump/XCOFFDump.cpp @@ -58,6 +58,23 @@ return CsectAuxEntOrErr.get().getStorageMappingClass(); } +Optional +objdump::getXCOFFSymbolContainingSymbolRef(const XCOFFObjectFile *Obj, + const SymbolRef &Sym) { + + const XCOFFSymbolRef SymRef = Obj->toSymbolRef(Sym.getRawDataRefImpl()); + if (!SymRef.isCsectSymbol()) + return None; + + auto CsectAuxEntOrErr = SymRef.getXCOFFCsectAuxRef(); + if (!CsectAuxEntOrErr || !CsectAuxEntOrErr.get().isLabel()) + return None; + uint32_t Idx = (uint32_t)CsectAuxEntOrErr.get().getSectionOrLength(); + DataRefImpl DRI; + DRI.p = Obj->getSymbolByIndex(Idx); + return SymbolRef(DRI, Obj); +} + bool objdump::isLabel(const XCOFFObjectFile *Obj, const SymbolRef &Sym) { const XCOFFSymbolRef SymRef = Obj->toSymbolRef(Sym.getRawDataRefImpl()); diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -2045,6 +2045,26 @@ outs() << SegmentName << ","; StringRef SectionName = unwrapOrError(Section->getName(), FileName); outs() << SectionName; + if (O->isXCOFF()) { + Optional SymRef = getXCOFFSymbolContainingSymbolRef( + dyn_cast(O), Symbol); + if (SymRef) { + outs() << "(Csect:"; + + StringRef CName = unwrapOrError(SymRef.getValue().getName(), FileName, + ArchiveName, ArchitectureName); + std::string SymName(CName); + if (Demangle) + SymName = demangle(std::string(CName)); + + if (SymbolDescription) + SymName = getXCOFFSymbolDescription( + createSymbolInfo(O, SymRef.getValue()), SymName); + + outs() << ' ' << SymName; + outs() << ") "; + } + } } if (Common || O->isELF()) { @@ -2084,10 +2104,14 @@ outs() << " .hidden"; } + std::string SymName(Name); if (Demangle) - outs() << ' ' << demangle(std::string(Name)) << '\n'; - else - outs() << ' ' << Name << '\n'; + SymName = demangle(std::string(Name)); + + if (O->isXCOFF() && SymbolDescription) + SymName = getXCOFFSymbolDescription(createSymbolInfo(O, Symbol), SymName); + + outs() << ' ' << SymName << '\n'; } static void printUnwindInfo(const ObjectFile *O) {