[llvm] 5b44c71 - [AIX]implement the --syms and using "symbol index and qualname" for --sym --symbol--description for llvm-objdump for xcoff
via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 1 09:37:59 PDT 2021
Author: zhijian
Date: 2021-10-01T12:37:51-04:00
New Revision: 5b44c716ee0ffcb0b8943b9e76eb69473188768a
URL: https://github.com/llvm/llvm-project/commit/5b44c716ee0ffcb0b8943b9e76eb69473188768a
DIFF: https://github.com/llvm/llvm-project/commit/5b44c716ee0ffcb0b8943b9e76eb69473188768a.diff
LOG: [AIX]implement the --syms and using "symbol index and qualname" for --sym --symbol--description for llvm-objdump for xcoff
Summary:
for xcoff :
implement the getSymbolFlag and getSymbolType() for option --syms.
llvm-objdump --sym , if the symbol is label, print the containing section for the symbol too.
when using llvm-objdump --sym --symbol--description, print the symbol index and qualname for symbol.
for example:
--symbol-description
00000000000000c0 l .text (csect: (idx: 2) .foov[PR]) (idx: 3) .foov
and without --symbol-description
00000000000000c0 l .text (csect: .foov) .foov
Reviewers: James Henderson,Esme Yi
Differential Revision: https://reviews.llvm.org/D109452
Added:
llvm/test/tools/llvm-objdump/XCOFF/symbol-table.test
Modified:
llvm/include/llvm/Object/XCOFFObjectFile.h
llvm/lib/Object/XCOFFObjectFile.cpp
llvm/test/tools/llvm-objdump/XCOFF/print-linenumber.test
llvm/tools/llvm-objdump/XCOFFDump.cpp
llvm/tools/llvm-objdump/XCOFFDump.h
llvm/tools/llvm-objdump/llvm-objdump.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/Object/XCOFFObjectFile.h b/llvm/include/llvm/Object/XCOFFObjectFile.h
index 8765832461fa8..4b195f13e5091 100644
--- a/llvm/include/llvm/Object/XCOFFObjectFile.h
+++ b/llvm/include/llvm/Object/XCOFFObjectFile.h
@@ -355,6 +355,7 @@ class XCOFFObjectFile : public ObjectFile {
Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
+ uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
@@ -431,6 +432,11 @@ class XCOFFObjectFile : public ObjectFile {
uint32_t getNumberOfSymbolTableEntries() const;
uint32_t getSymbolIndex(uintptr_t SymEntPtr) const;
+ uint64_t getSymbolSize(DataRefImpl Symb) const;
+ uintptr_t getSymbolByIndex(uint32_t Idx) const {
+ return reinterpret_cast<uintptr_t>(SymbolTblPtr) +
+ XCOFF::SymbolTableEntrySize * Idx;
+ }
uintptr_t getSymbolEntryAddressByIndex(uint32_t SymbolTableIndex) const;
Expected<StringRef> getSymbolNameByIndex(uint32_t SymbolTableIndex) const;
diff --git a/llvm/lib/Object/XCOFFObjectFile.cpp b/llvm/lib/Object/XCOFFObjectFile.cpp
index edbf3f4cda99f..c915bf703c7af 100644
--- a/llvm/lib/Object/XCOFFObjectFile.cpp
+++ b/llvm/lib/Object/XCOFFObjectFile.cpp
@@ -220,15 +220,85 @@ uint64_t XCOFFObjectFile::getSymbolValueImpl(DataRefImpl Symb) const {
return toSymbolRef(Symb).getValue();
}
+uint32_t XCOFFObjectFile::getSymbolAlignment(DataRefImpl Symb) const {
+ uint64_t Result = 0;
+ XCOFFSymbolRef XCOFFSym = toSymbolRef(Symb);
+ if (XCOFFSym.isCsectSymbol()) {
+ Expected<XCOFFCsectAuxRef> CsectAuxRefOrError =
+ XCOFFSym.getXCOFFCsectAuxRef();
+ if (!CsectAuxRefOrError)
+ // TODO: report the error up the stack.
+ consumeError(CsectAuxRefOrError.takeError());
+ else
+ Result = 1 << CsectAuxRefOrError.get().getAlignmentLog2();
+ }
+ return Result;
+}
+
uint64_t XCOFFObjectFile::getCommonSymbolSizeImpl(DataRefImpl Symb) const {
uint64_t Result = 0;
- llvm_unreachable("Not yet implemented!");
+ XCOFFSymbolRef XCOFFSym = toSymbolRef(Symb);
+ if (XCOFFSym.isCsectSymbol()) {
+ Expected<XCOFFCsectAuxRef> CsectAuxRefOrError =
+ XCOFFSym.getXCOFFCsectAuxRef();
+ if (!CsectAuxRefOrError)
+ // TODO: report the error up the stack.
+ consumeError(CsectAuxRefOrError.takeError());
+ else {
+ XCOFFCsectAuxRef CsectAuxRef = CsectAuxRefOrError.get();
+ assert(CsectAuxRef.getSymbolType() == XCOFF::XTY_CM);
+ Result = CsectAuxRef.getSectionOrLength();
+ }
+ }
return Result;
}
Expected<SymbolRef::Type>
XCOFFObjectFile::getSymbolType(DataRefImpl Symb) const {
- // TODO: Return the correct symbol type.
+ XCOFFSymbolRef XCOFFSym = toSymbolRef(Symb);
+
+ if (XCOFFSym.isFunction())
+ return SymbolRef::ST_Function;
+
+ if (XCOFF::C_FILE == XCOFFSym.getStorageClass())
+ return SymbolRef::ST_File;
+
+ int16_t SecNum = XCOFFSym.getSectionNumber();
+ if (SecNum <= 0)
+ return SymbolRef::ST_Other;
+
+ Expected<DataRefImpl> SecDRIOrErr =
+ getSectionByNum(XCOFFSym.getSectionNumber());
+
+ if (!SecDRIOrErr)
+ return SecDRIOrErr.takeError();
+
+ DataRefImpl SecDRI = SecDRIOrErr.get();
+
+ Expected<StringRef> SymNameOrError = XCOFFSym.getName();
+ if (SymNameOrError) {
+ // The "TOC" symbol is treated as SymbolRef::ST_Other.
+ if (SymNameOrError.get() == "TOC")
+ return SymbolRef::ST_Other;
+
+ // The symbol for a section name is treated as SymbolRef::ST_Other.
+ StringRef SecName;
+ if (is64Bit())
+ SecName = XCOFFObjectFile::toSection64(SecDRIOrErr.get())->getName();
+ else
+ SecName = XCOFFObjectFile::toSection32(SecDRIOrErr.get())->getName();
+
+ if (SecName == SymNameOrError.get())
+ return SymbolRef::ST_Other;
+ } else
+ return SymNameOrError.takeError();
+
+ if (isSectionData(SecDRI) || isSectionBSS(SecDRI))
+ return SymbolRef::ST_Data;
+
+ if (isDebugSection(SecDRI))
+ return SymbolRef::ST_Debug;
+
return SymbolRef::ST_Other;
}
@@ -500,8 +570,32 @@ void XCOFFObjectFile::getRelocationTypeName(
}
Expected<uint32_t> XCOFFObjectFile::getSymbolFlags(DataRefImpl Symb) const {
- uint32_t Result = 0;
- // TODO: Return correct symbol flags.
+ XCOFFSymbolRef XCOFFSym = toSymbolRef(Symb);
+ uint32_t Result = SymbolRef::SF_None;
+
+ if (XCOFFSym.getSectionNumber() == XCOFF::N_ABS)
+ Result |= SymbolRef::SF_Absolute;
+
+ XCOFF::StorageClass SC = XCOFFSym.getStorageClass();
+ if (XCOFF::C_EXT == SC || XCOFF::C_WEAKEXT == SC)
+ Result |= SymbolRef::SF_Global;
+
+ if (XCOFF::C_WEAKEXT == SC)
+ Result |= SymbolRef::SF_Weak;
+
+ if (XCOFFSym.isCsectSymbol()) {
+ Expected<XCOFFCsectAuxRef> CsectAuxEntOrErr =
+ XCOFFSym.getXCOFFCsectAuxRef();
+ if (CsectAuxEntOrErr) {
+ if (CsectAuxEntOrErr.get().getSymbolType() == XCOFF::XTY_CM)
+ Result |= SymbolRef::SF_Common;
+ } else
+ return CsectAuxEntOrErr.takeError();
+ }
+
+ if (XCOFFSym.getSectionNumber() == XCOFF::N_UNDEF)
+ Result |= SymbolRef::SF_Undefined;
+
return Result;
}
@@ -702,6 +796,25 @@ uint32_t XCOFFObjectFile::getSymbolIndex(uintptr_t SymbolEntPtr) const {
XCOFF::SymbolTableEntrySize;
}
+uint64_t XCOFFObjectFile::getSymbolSize(DataRefImpl Symb) const {
+ uint64_t Result = 0;
+ XCOFFSymbolRef XCOFFSym = toSymbolRef(Symb);
+ if (XCOFFSym.isCsectSymbol()) {
+ Expected<XCOFFCsectAuxRef> CsectAuxRefOrError =
+ XCOFFSym.getXCOFFCsectAuxRef();
+ if (!CsectAuxRefOrError)
+ // TODO: report the error up the stack.
+ consumeError(CsectAuxRefOrError.takeError());
+ else {
+ XCOFFCsectAuxRef CsectAuxRef = CsectAuxRefOrError.get();
+ uint8_t SymType = CsectAuxRef.getSymbolType();
+ if (SymType == XCOFF::XTY_SD || SymType == XCOFF::XTY_CM)
+ Result = CsectAuxRef.getSectionOrLength();
+ }
+ }
+ return Result;
+}
+
uintptr_t XCOFFObjectFile::getSymbolEntryAddressByIndex(uint32_t Index) const {
return getAdvancedSymbolEntryAddress(
reinterpret_cast<uintptr_t>(getPointerToSymbolTable()), Index);
diff --git a/llvm/test/tools/llvm-objdump/XCOFF/print-linenumber.test b/llvm/test/tools/llvm-objdump/XCOFF/print-linenumber.test
index bb4a002c54cf7..0f3acacae4389 100644
--- a/llvm/test/tools/llvm-objdump/XCOFF/print-linenumber.test
+++ b/llvm/test/tools/llvm-objdump/XCOFF/print-linenumber.test
@@ -18,7 +18,7 @@
# LINES32: Inputs/basic32.o: file format aixcoff-rs6000
# LINES32: Disassembly of section .text:
# LINES32: 00000000 <.text>:
-# LINES32: ; main():
+# LINES32: ; .main():
# LINES32-NEXT: ; /basic.c:1
# LINES32-NEXT: 0: 38 60 00 00 li 3, 0
# LINES32-NEXT: ; /basic.c:3
@@ -35,7 +35,7 @@
# LINES64: Inputs/basic64.o: file format aix5coff64-rs6000
# LINES64: Disassembly of section .text:
# LINES64: 0000000000000000 <.main>:
-# LINES64: ; main():
+# LINES64: ; .main():
# LINES64-NEXT: ; /basic.c:1
# LINES64-NEXT: 0: 38 60 00 00 li 3, 0
# LINES64-NEXT: ; /basic.c:3
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
index 0000000000000..2ce9b4279b206
--- /dev/null
+++ b/llvm/test/tools/llvm-objdump/XCOFF/symbol-table.test
@@ -0,0 +1,110 @@
+; Test the --syms option for xcoff object files.
+; Also test the --symbol-description option for xcoff object files, when specified with --syms.
+; RUN: llc -mtriple powerpc-ibm-aix -mcpu=pwr4 -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
+
+;; The IR below is generated by the following source code.
+;; bash> cat test.c
+;; const char* con= "Test for --symbols";
+;; int i;
+;; char c ;
+;; char *ap;
+;; float f;
+;; long long ll;
+;; static int si;
+;; extern int ei;
+;; int bar(const char *v) {
+;; si = 1;
+;; return (int)v[0] + (int)v[2] + si + ei;
+;; }
+;;
+;; void foo() {
+;; bar(con);
+;; }
+;;
+;; __attribute__ ((weak)) int wi=2;
+
+
+ at .str = private unnamed_addr constant [19 x i8] c"Test for --symbols\00", align 1
+ at con = global i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str, i32 0, i32 0), align 4
+ at si = internal global i32 0, align 4
+ at ei = external global i32, align 4
+ at wi = weak global i32 2, align 4
+ at i = global i32 0, align 4
+ at c = global i8 0, align 1
+ at ap = global i8* null, align 4
+ at f = global float 0.000000e+00, align 4
+ at ll = global i64 0, align 8
+
+define i32 @bar(i8* %v) {
+entry:
+ %v.addr = alloca i8*, align 4
+ store i8* %v, i8** %v.addr, align 4
+ store i32 1, i32* @si, align 4
+ %0 = load i8*, i8** %v.addr, align 4
+ %arrayidx = getelementptr inbounds i8, i8* %0, i32 0
+ %1 = load i8, i8* %arrayidx, align 1
+ %conv = zext i8 %1 to i32
+ %2 = load i8*, i8** %v.addr, align 4
+ %arrayidx1 = getelementptr inbounds i8, i8* %2, i32 2
+ %3 = load i8, i8* %arrayidx1, align 1
+ %conv2 = zext i8 %3 to i32
+ %add = add nsw i32 %conv, %conv2
+ %4 = load i32, i32* @si, align 4
+ %add3 = add nsw i32 %add, %4
+ %5 = load i32, i32* @ei, align 4
+ %add4 = add nsw i32 %add3, %5
+ ret i32 %add4
+}
+
+define void @foo() {
+entry:
+ %0 = load i8*, i8** @con, align 4
+ %call = call i32 @bar(i8* %0)
+ ret void
+}
+
+; SYM: SYMBOL TABLE:
+; SYM-NEXT: 00000000 df *DEBUG* 00000000 .file
+; SYM-NEXT: 00000000 *UND* 00000000 ei
+; SYM-NEXT: 00000000 l .text 00000091 .text
+; SYM-NEXT: 00000000 g F .text (csect: .text) 00000000 .bar
+; SYM-NEXT: 00000050 g F .text (csect: .text) 00000000 .foo
+; SYM-NEXT: 00000094 l .text 00000013 .rodata.str1.1L...str
+; SYM-NEXT: 000000a8 g O .data 00000004 con
+; SYM-NEXT: 000000ac w O .data 00000004 wi
+; SYM-NEXT: 000000b0 g O .data 00000004 i
+; SYM-NEXT: 000000b4 g O .data 00000001 c
+; SYM-NEXT: 000000b8 g O .data 00000004 ap
+; SYM-NEXT: 000000bc g O .data 00000004 f
+; SYM-NEXT: 000000c0 g O .data 00000008 ll
+; SYM-NEXT: 000000c8 g O .data 0000000c bar
+; SYM-NEXT: 000000d4 g O .data 0000000c foo
+; SYM-NEXT: 000000e0 l .data 00000000 TOC
+; SYM-NEXT: 000000e0 l O .data 00000004 si
+; SYM-NEXT: 000000e4 l O .data 00000004 ei
+; SYM-NEXT: 000000e8 l O .data 00000004 con
+; SYM-NEXT: 000000ec l O *COM* 00000004 si
+
+; SYM-DES: SYMBOL TABLE:
+; SYM-DES-NEXT: 00000000 df *DEBUG* 00000000 (idx: 0) .file
+; SYM-DES-NEXT: 00000000 *UND* 00000000 (idx: 1) ei[UA]
+; SYM-DES-NEXT: 00000000 l .text 00000091 (idx: 3) .text[PR]
+; SYM-DES-NEXT: 00000000 g F .text (csect: (idx: 3) .text[PR]) 00000000 (idx: 5) .bar
+; SYM-DES-NEXT: 00000050 g F .text (csect: (idx: 3) .text[PR]) 00000000 (idx: 7) .foo
+; SYM-DES-NEXT: 00000094 l .text 00000013 (idx: 9) .rodata.str1.1L...str[RO]
+; SYM-DES-NEXT: 000000a8 g O .data 00000004 (idx: 11) con[RW]
+; SYM-DES-NEXT: 000000ac w O .data 00000004 (idx: 13) wi[RW]
+; SYM-DES-NEXT: 000000b0 g O .data 00000004 (idx: 15) i[RW]
+; SYM-DES-NEXT: 000000b4 g O .data 00000001 (idx: 17) c[RW]
+; SYM-DES-NEXT: 000000b8 g O .data 00000004 (idx: 19) ap[RW]
+; SYM-DES-NEXT: 000000bc g O .data 00000004 (idx: 21) f[RW]
+; SYM-DES-NEXT: 000000c0 g O .data 00000008 (idx: 23) ll[RW]
+; SYM-DES-NEXT: 000000c8 g O .data 0000000c (idx: 25) bar[DS]
+; SYM-DES-NEXT: 000000d4 g O .data 0000000c (idx: 27) foo[DS]
+; SYM-DES-NEXT: 000000e0 l .data 00000000 (idx: 29) TOC[TC0]
+; SYM-DES-NEXT: 000000e0 l O .data 00000004 (idx: 31) si[TC]
+; SYM-DES-NEXT: 000000e4 l O .data 00000004 (idx: 33) ei[TC]
+; SYM-DES-NEXT: 000000e8 l O .data 00000004 (idx: 35) con[TC]
+; SYM-DES-NEXT: 000000ec l O *COM* 00000004 (idx: 37) si[BS]
diff --git a/llvm/tools/llvm-objdump/XCOFFDump.cpp b/llvm/tools/llvm-objdump/XCOFFDump.cpp
index c4cc5fe7e21c7..b8fb2ed3d0636 100644
--- a/llvm/tools/llvm-objdump/XCOFFDump.cpp
+++ b/llvm/tools/llvm-objdump/XCOFFDump.cpp
@@ -58,6 +58,24 @@ objdump::getXCOFFSymbolCsectSMC(const XCOFFObjectFile *Obj,
return CsectAuxEntOrErr.get().getStorageMappingClass();
}
+Optional<object::SymbolRef>
+objdump::getXCOFFSymbolContainingSymbolRef(const XCOFFObjectFile *Obj,
+ const SymbolRef &Sym) {
+
+ const XCOFFSymbolRef SymRef = Obj->toSymbolRef(Sym.getRawDataRefImpl());
+ if (!SymRef.isCsectSymbol())
+ return None;
+
+ Expected<XCOFFCsectAuxRef> CsectAuxEntOrErr = SymRef.getXCOFFCsectAuxRef();
+ if (!CsectAuxEntOrErr || !CsectAuxEntOrErr.get().isLabel())
+ return None;
+ uint32_t Idx =
+ static_cast<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/XCOFFDump.h b/llvm/tools/llvm-objdump/XCOFFDump.h
index dbf520021594b..6796f00aef6f1 100644
--- a/llvm/tools/llvm-objdump/XCOFFDump.h
+++ b/llvm/tools/llvm-objdump/XCOFFDump.h
@@ -20,6 +20,10 @@ Optional<XCOFF::StorageMappingClass>
getXCOFFSymbolCsectSMC(const object::XCOFFObjectFile *Obj,
const object::SymbolRef &Sym);
+Optional<object::SymbolRef>
+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/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index bb4a8715c181d..32c04bd294e32 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -2050,21 +2050,56 @@ void objdump::printSymbol(const ObjectFile *O, const SymbolRef &Symbol,
} else if (Common) {
outs() << "*COM*";
} else if (Section == O->section_end()) {
- outs() << "*UND*";
+ if (O->isXCOFF()) {
+ XCOFFSymbolRef XCOFFSym = dyn_cast<const XCOFFObjectFile>(O)->toSymbolRef(
+ Symbol.getRawDataRefImpl());
+ if (XCOFF::N_DEBUG == XCOFFSym.getSectionNumber())
+ outs() << "*DEBUG*";
+ else
+ outs() << "*UND*";
+ } else
+ outs() << "*UND*";
} else {
StringRef SegmentName = getSegmentName(MachO, *Section);
if (!SegmentName.empty())
outs() << SegmentName << ",";
StringRef SectionName = unwrapOrError(Section->getName(), FileName);
outs() << SectionName;
- }
+ if (O->isXCOFF()) {
+ Optional<SymbolRef> SymRef = getXCOFFSymbolContainingSymbolRef(
+ dyn_cast<const XCOFFObjectFile>(O), Symbol);
+ if (SymRef) {
+
+ Expected<StringRef> NameOrErr = SymRef.getValue().getName();
+
+ if (NameOrErr) {
+ outs() << " (csect:";
+ std::string SymName(NameOrErr.get());
+
+ if (Demangle)
+ SymName = demangle(SymName);
+
+ if (SymbolDescription)
+ SymName = getXCOFFSymbolDescription(
+ createSymbolInfo(O, SymRef.getValue()), SymName);
- if (Common || O->isELF()) {
- uint64_t Val =
- Common ? Symbol.getAlignment() : ELFSymbolRef(Symbol).getSize();
- outs() << '\t' << format(Fmt, Val);
+ outs() << ' ' << SymName;
+ outs() << ") ";
+ } else
+ reportWarning(toString(NameOrErr.takeError()), FileName);
+ }
+ }
}
+ if (Common)
+ outs() << '\t' << format(Fmt, Symbol.getAlignment());
+ else if (O->isXCOFF())
+ outs() << '\t'
+ << format(Fmt, dyn_cast<const XCOFFObjectFile>(O)->getSymbolSize(
+ Symbol.getRawDataRefImpl()));
+ else if (O->isELF())
+ outs() << '\t' << format(Fmt, ELFSymbolRef(Symbol).getSize());
+
if (O->isELF()) {
if (!SymbolVersions.empty()) {
const VersionEntry &Ver =
@@ -2096,10 +2131,14 @@ void objdump::printSymbol(const ObjectFile *O, const SymbolRef &Symbol,
outs() << " .hidden";
}
+ std::string SymName(Name);
if (Demangle)
- outs() << ' ' << demangle(std::string(Name)) << '\n';
- else
- outs() << ' ' << Name << '\n';
+ SymName = demangle(SymName);
+
+ if (O->isXCOFF() && SymbolDescription)
+ SymName = getXCOFFSymbolDescription(createSymbolInfo(O, Symbol), SymName);
+
+ outs() << ' ' << SymName << '\n';
}
static void printUnwindInfo(const ObjectFile *O) {
More information about the llvm-commits
mailing list