Skip to content

Commit

Permalink
[AIX]implement the --syms and using "symbol index and qualname" for -…
Browse files Browse the repository at this point in the history
…-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
  • Loading branch information
diggerlin committed Oct 1, 2021
1 parent 907d5da commit 5b44c71
Show file tree
Hide file tree
Showing 7 changed files with 305 additions and 15 deletions.
6 changes: 6 additions & 0 deletions llvm/include/llvm/Object/XCOFFObjectFile.h
Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down
121 changes: 117 additions & 4 deletions llvm/lib/Object/XCOFFObjectFile.cpp
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/tools/llvm-objdump/XCOFF/print-linenumber.test
Expand Up @@ -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
Expand All @@ -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
Expand Down
110 changes: 110 additions & 0 deletions 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;


@.str = private unnamed_addr constant [19 x i8] c"Test for --symbols\00", align 1
@con = global i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str, i32 0, i32 0), align 4
@si = internal global i32 0, align 4
@ei = external global i32, align 4
@wi = weak global i32 2, align 4
@i = global i32 0, align 4
@c = global i8 0, align 1
@ap = global i8* null, align 4
@f = global float 0.000000e+00, align 4
@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]
18 changes: 18 additions & 0 deletions llvm/tools/llvm-objdump/XCOFFDump.cpp
Expand Up @@ -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());
Expand Down
4 changes: 4 additions & 0 deletions llvm/tools/llvm-objdump/XCOFFDump.h
Expand Up @@ -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,
Expand Down

0 comments on commit 5b44c71

Please sign in to comment.