[llvm] 61106ca - Reland https://reviews.llvm.org/D113825 after fixing the test expectations.

via llvm-commits llvm-commits at lists.llvm.org
Sun Jan 16 21:29:47 PST 2022


Author: esmeyi
Date: 2022-01-17T00:28:25-05:00
New Revision: 61106ca7525663ec2ed08c5f304d6fb6946744f7

URL: https://github.com/llvm/llvm-project/commit/61106ca7525663ec2ed08c5f304d6fb6946744f7
DIFF: https://github.com/llvm/llvm-project/commit/61106ca7525663ec2ed08c5f304d6fb6946744f7.diff

LOG: Reland https://reviews.llvm.org/D113825 after fixing the test expectations.

Added: 
    

Modified: 
    llvm/include/llvm/Object/XCOFFObjectFile.h
    llvm/lib/Object/XCOFFObjectFile.cpp
    llvm/test/tools/llvm-readobj/XCOFF/symbols-invalid.test
    llvm/test/tools/llvm-readobj/XCOFF/symbols.test
    llvm/test/tools/llvm-readobj/XCOFF/symbols64.test
    llvm/tools/llvm-readobj/XCOFFDumper.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Object/XCOFFObjectFile.h b/llvm/include/llvm/Object/XCOFFObjectFile.h
index 94136afc45ea2..ac911e534f341 100644
--- a/llvm/include/llvm/Object/XCOFFObjectFile.h
+++ b/llvm/include/llvm/Object/XCOFFObjectFile.h
@@ -348,6 +348,57 @@ struct XCOFFSectAuxEntForStat {
   uint8_t Pad[10];
 }; // 32-bit XCOFF file only.
 
+struct XCOFFFunctionAuxEnt32 {
+  support::ubig32_t OffsetToExceptionTbl;
+  support::ubig32_t SizeOfFunction;
+  support::ubig32_t PtrToLineNum;
+  support::big32_t SymIdxOfNextBeyond;
+  uint8_t Pad[2];
+};
+
+struct XCOFFFunctionAuxEnt64 {
+  support::ubig64_t PtrToLineNum;
+  support::ubig32_t SizeOfFunction;
+  support::big32_t SymIdxOfNextBeyond;
+  uint8_t Pad;
+  XCOFF::SymbolAuxType AuxType; // Contains _AUX_FCN; Type of auxiliary entry
+};
+
+struct XCOFFExceptionAuxEnt {
+  support::ubig64_t OffsetToExceptionTbl;
+  support::ubig32_t SizeOfFunction;
+  support::big32_t SymIdxOfNextBeyond;
+  uint8_t Pad;
+  XCOFF::SymbolAuxType AuxType; // Contains _AUX_EXCEPT; Type of auxiliary entry
+};
+
+struct XCOFFBlockAuxEnt32 {
+  uint8_t ReservedZeros1[2];
+  support::ubig16_t LineNumHi;
+  support::ubig16_t LineNumLo;
+  uint8_t ReservedZeros2[12];
+};
+
+struct XCOFFBlockAuxEnt64 {
+  support::ubig32_t LineNum;
+  uint8_t Pad[13];
+  XCOFF::SymbolAuxType AuxType; // Contains _AUX_SYM; Type of auxiliary entry
+};
+
+struct XCOFFSectAuxEntForDWARF32 {
+  support::ubig32_t LengthOfSectionPortion;
+  uint8_t Pad1[4];
+  support::ubig32_t NumberOfRelocEnt;
+  uint8_t Pad2[6];
+};
+
+struct XCOFFSectAuxEntForDWARF64 {
+  support::ubig64_t LengthOfSectionPortion;
+  support::ubig64_t NumberOfRelocEnt;
+  uint8_t Pad;
+  XCOFF::SymbolAuxType AuxType; // Contains _AUX_SECT; Type of Auxillary entry
+};
+
 template <typename AddressType> struct XCOFFRelocation {
   // Masks for packing/unpacking the r_rsize field of relocations.
 

diff  --git a/llvm/lib/Object/XCOFFObjectFile.cpp b/llvm/lib/Object/XCOFFObjectFile.cpp
index 9b0a5efacba7a..f2f6d700ddd8c 100644
--- a/llvm/lib/Object/XCOFFObjectFile.cpp
+++ b/llvm/lib/Object/XCOFFObjectFile.cpp
@@ -1112,8 +1112,12 @@ bool XCOFFSymbolRef::isFunction() const {
     return true;
 
   Expected<XCOFFCsectAuxRef> ExpCsectAuxEnt = getXCOFFCsectAuxRef();
-  if (!ExpCsectAuxEnt)
+  if (!ExpCsectAuxEnt) {
+    // If we could not get the CSECT auxiliary entry, then treat this symbol as
+    // if it isn't a function. Consume the error and return `false` to move on.
+    consumeError(ExpCsectAuxEnt.takeError());
     return false;
+  }
 
   const XCOFFCsectAuxRef CsectAuxRef = ExpCsectAuxEnt.get();
 

diff  --git a/llvm/test/tools/llvm-readobj/XCOFF/symbols-invalid.test b/llvm/test/tools/llvm-readobj/XCOFF/symbols-invalid.test
index b1e10af4f68bd..e1b1aac29b4ed 100644
--- a/llvm/test/tools/llvm-readobj/XCOFF/symbols-invalid.test
+++ b/llvm/test/tools/llvm-readobj/XCOFF/symbols-invalid.test
@@ -1,23 +1,68 @@
-## This file tests the raw data output ability when a file auxiliary entry does
+## Test that we report warnings or dump raw data when symbols are invalid.
+
+# RUN: yaml2obj %s --docnum=1 -o %t1
+# RUN: llvm-readobj --syms %t1 2>&1 | FileCheck %s -DFILE=%t1 --check-prefix=CASE1
+
+# CASE1: warning: '[[FILE]]': the non-function C_EXT symbol at index 1 should have only 1 auxiliary entry, i.e. the CSECT auxiliary entry
+
+--- !XCOFF
+FileHeader:
+  MagicNumber: 0x1DF
+Symbols:
+  - Name: .sym
+  - Name:               .fun
+    StorageClass:       [[STORAGECLASS='C_EXT']]
+    NumberOfAuxEntries: 2
+
+# RUN: yaml2obj %s --docnum=1 -DSTORAGECLASS='C_WEAKEXT' -o %t2
+# RUN: llvm-readobj --syms %t2 2>&1 | FileCheck %s -DFILE=%t2 --check-prefix=CASE2
+
+# CASE2: warning: '[[FILE]]': the non-function C_WEAKEXT symbol at index 1 should have only 1 auxiliary entry, i.e. the CSECT auxiliary entry
+
+# RUN: yaml2obj %s --docnum=1 -DSTORAGECLASS='C_HIDEXT' -o %t3
+# RUN: llvm-readobj --syms %t3 2>&1 | FileCheck %s -DFILE=%t3 --check-prefix=CASE3
+
+# CASE3: warning: '[[FILE]]': the non-function C_HIDEXT symbol at index 1 should have only 1 auxiliary entry, i.e. the CSECT auxiliary entry
+
+# RUN: yaml2obj %s --docnum=1 -DSTORAGECLASS='C_STAT' -o %t4
+# RUN: llvm-readobj --syms %t4 2>&1 | FileCheck %s -DFILE=%t4 --check-prefix=CASE4
+
+# CASE4: warning: '[[FILE]]': the C_STAT symbol at index 1 should not have more than 1 auxiliary entry
+
+# RUN: yaml2obj %s --docnum=1 -DSTORAGECLASS='C_DWARF' -o %t5
+# RUN: llvm-readobj --syms %t5 2>&1 | FileCheck %s -DFILE=%t5 --check-prefix=CASE5
+
+# CASE5: warning: '[[FILE]]': the C_DWARF symbol at index 1 should not have more than 1 auxiliary entry
+
+# RUN: yaml2obj %s --docnum=1 -DSTORAGECLASS='C_BLOCK' -o %t6
+# RUN: llvm-readobj --syms %t6 2>&1 | FileCheck %s -DFILE=%t6 --check-prefix=CASE6
+
+# CASE6: warning: '[[FILE]]': the C_BLOCK symbol at index 1 should not have more than 1 auxiliary entry
+
+# RUN: yaml2obj %s --docnum=1 -DSTORAGECLASS='C_FCN' -o %t7
+# RUN: llvm-readobj --syms %t7 2>&1 | FileCheck %s -DFILE=%t7 --check-prefix=CASE7
+
+# CASE7: warning: '[[FILE]]': the C_FCN symbol at index 1 should not have more than 1 auxiliary entry
+
+## This case tests the raw data output ability when a file auxiliary entry does
 ## not have the matching auxiliary type.
+# RUN: yaml2obj %s --docnum=2 -o %t8
+# RUN: llvm-readobj --syms %t8 | FileCheck %s --strict-whitespace --match-full-lines --check-prefix=CASE8
 
-# RUN: yaml2obj %s -o %t
-# RUN: llvm-readobj --syms %t | FileCheck %s
-
-# CHECK:      Symbols [
-# CHECK-NEXT:   Symbol {
-# CHECK-NEXT:     Index: 0
-# CHECK-NEXT:     Name: .fun
-# CHECK-NEXT:     Value (SymbolTableIndex): 0x0
-# CHECK-NEXT:     Section: N_UNDEF
-# CHECK-NEXT:     Source Language ID: TB_C (0x0)
-# CHECK-NEXT:     CPU Version ID: 0x0
-# CHECK-NEXT:     StorageClass: C_FILE (0x67)
-# CHECK-NEXT:     NumberOfAuxEntries: 1
-# CHECK-NEXT:     !Unexpected raw auxiliary entry data:
-# CHECK-NEXT:     00000000 00000001 00020300 00000000 00fb
-# CHECK-NEXT:   }
-# CHECK-NEXT: ]
+#      CASE8:Symbols [
+# CASE8-NEXT:  Symbol {
+# CASE8-NEXT:    Index: 0
+# CASE8-NEXT:    Name: .fun
+# CASE8-NEXT:    Value (SymbolTableIndex): 0x0
+# CASE8-NEXT:    Section: N_UNDEF
+# CASE8-NEXT:    Source Language ID: TB_C (0x0)
+# CASE8-NEXT:    CPU Version ID: 0x0
+# CASE8-NEXT:    StorageClass: C_FILE (0x67)
+# CASE8-NEXT:    NumberOfAuxEntries: 1
+# CASE8-NEXT:    !Unexpected raw auxiliary entry data:
+# CASE8-NEXT:    00000000 00000001 00020300 00000000 00fb
+# CASE8-NEXT:  }
+# CASE8-NEXT:]
 
 --- !XCOFF
 FileHeader:

diff  --git a/llvm/test/tools/llvm-readobj/XCOFF/symbols.test b/llvm/test/tools/llvm-readobj/XCOFF/symbols.test
index 9abe480a77479..f72144c6f1a06 100644
--- a/llvm/test/tools/llvm-readobj/XCOFF/symbols.test
+++ b/llvm/test/tools/llvm-readobj/XCOFF/symbols.test
@@ -87,6 +87,52 @@ Symbols:
         SectionOrLength:        256
         StabInfoIndex:          2
         StabSectNum:            3
+## The C_WEAKEXT symbol with a Function auxiliary entry and a CSECT auxiliary entry.
+  - Name:               .fun3
+    Value:              0x0
+    Section:            N_DEBUG
+    Type:               0x20
+    StorageClass:       C_WEAKEXT
+    NumberOfAuxEntries: 2
+    AuxEntries:
+      - Type:                 AUX_FCN
+        OffsetToExceptionTbl: 2
+        SizeOfFunction:       3
+        SymIdxOfNextBeyond:   4
+        PtrToLineNum:         5
+      - Type:                   AUX_CSECT
+        ParameterHashIndex:     11
+        TypeChkSectNum:         22
+        SymbolAlignmentAndType: 33
+        StorageMappingClass:    XMC_PR
+        SectionOrLength:        256
+        StabInfoIndex:          44
+        StabSectNum:            55
+## The C_DWARF symbol with a SECT auxiliary entry.
+  - Name:               .fun4
+    Section:            N_DEBUG
+    StorageClass:       C_DWARF
+    NumberOfAuxEntries: 1
+    AuxEntries:
+      - Type:                   AUX_SECT
+        LengthOfSectionPortion: 2
+        NumberOfRelocEnt:       3
+## The C_BLOCK symbol with a Block auxiliary entry.
+  - Name:               .fun5
+    StorageClass:       C_BLOCK
+    NumberOfAuxEntries: 1
+    AuxEntries:
+      - Type:      AUX_SYM
+        LineNumHi: 2
+        LineNumLo: 3
+## The C_FCN symbol with a Block auxiliary entry.
+  - Name:               .fun6
+    StorageClass:       C_FCN
+    NumberOfAuxEntries: 1
+    AuxEntries:
+      - Type:      AUX_SYM
+        LineNumHi: 2
+        LineNumLo: 3
 
 # SYMBOL32:      Symbols [
 # SYMBOL32-NEXT:   Symbol {
@@ -189,4 +235,73 @@ Symbols:
 # SYMBOL32-NEXT:       StabSectNum: 0x3
 # SYMBOL32-NEXT:     }
 # SYMBOL32-NEXT:   }
+# SYMBOL32-NEXT:   Symbol {
+# SYMBOL32-NEXT:     Index: 12
+# SYMBOL32-NEXT:     Name: .fun3
+# SYMBOL32-NEXT:     Value (RelocatableAddress): 0x0
+# SYMBOL32-NEXT:     Section: N_DEBUG
+# SYMBOL32-NEXT:     Type: 0x20
+# SYMBOL32-NEXT:     StorageClass: C_WEAKEXT (0x6F)
+# SYMBOL32-NEXT:     NumberOfAuxEntries: 2
+# SYMBOL32-NEXT:     Function Auxiliary Entry {
+# SYMBOL32-NEXT:       Index: 13
+# SYMBOL32-NEXT:       OffsetToExceptionTable: 0x2
+# SYMBOL32-NEXT:       SizeOfFunction: 0x3
+# SYMBOL32-NEXT:       PointerToLineNum: 0x5
+# SYMBOL32-NEXT:       SymbolIndexOfNextBeyond: 4
+# SYMBOL32-NEXT:     }
+# SYMBOL32-NEXT:     CSECT Auxiliary Entry {
+# SYMBOL32-NEXT:       Index: 14
+# SYMBOL32-NEXT:       SectionLen: 256
+# SYMBOL32-NEXT:       ParameterHashIndex: 0xB
+# SYMBOL32-NEXT:       TypeChkSectNum: 0x16
+# SYMBOL32-NEXT:       SymbolAlignmentLog2: 4
+# SYMBOL32-NEXT:       SymbolType: XTY_SD (0x1)
+# SYMBOL32-NEXT:       StorageMappingClass: XMC_PR (0x0)
+# SYMBOL32-NEXT:       StabInfoIndex: 0x2C
+# SYMBOL32-NEXT:       StabSectNum: 0x37
+# SYMBOL32-NEXT:     }
+# SYMBOL32-NEXT:   }
+# SYMBOL32-NEXT:   Symbol {
+# SYMBOL32-NEXT:     Index: 15
+# SYMBOL32-NEXT:     Name: .fun4
+# SYMBOL32-NEXT:     Value (OffsetInDWARF): 0x0
+# SYMBOL32-NEXT:     Section: N_DEBUG
+# SYMBOL32-NEXT:     Type: 0x0
+# SYMBOL32-NEXT:     StorageClass: C_DWARF (0x70)
+# SYMBOL32-NEXT:     NumberOfAuxEntries: 1
+# SYMBOL32-NEXT:     Sect Auxiliary Entry For DWARF {
+# SYMBOL32-NEXT:       Index: 16
+# SYMBOL32-NEXT:       LengthOfSectionPortion: 0x2
+# SYMBOL32-NEXT:       NumberOfRelocEntries: 3
+# SYMBOL32-NEXT:     }
+# SYMBOL32-NEXT:   }
+# SYMBOL32-NEXT:   Symbol {
+# SYMBOL32-NEXT:     Index: 17
+# SYMBOL32-NEXT:     Name: .fun5
+# SYMBOL32-NEXT:     Value (RelocatableAddress): 0x0
+# SYMBOL32-NEXT:     Section: N_UNDEF
+# SYMBOL32-NEXT:     Type: 0x0
+# SYMBOL32-NEXT:     StorageClass: C_BLOCK (0x64)
+# SYMBOL32-NEXT:     NumberOfAuxEntries: 1
+# SYMBOL32-NEXT:     Block Auxiliary Entry {
+# SYMBOL32-NEXT:       Index: 18
+# SYMBOL32-NEXT:       LineNumber (High 2 Bytes): 0x2
+# SYMBOL32-NEXT:       LineNumber (Low 2 Bytes): 0x3
+# SYMBOL32-NEXT:     }
+# SYMBOL32-NEXT:   }
+# SYMBOL32-NEXT:   Symbol {
+# SYMBOL32-NEXT:     Index: 19
+# SYMBOL32-NEXT:     Name: .fun6
+# SYMBOL32-NEXT:     Value (RelocatableAddress): 0x0
+# SYMBOL32-NEXT:     Section: N_UNDEF
+# SYMBOL32-NEXT:     Type: 0x0
+# SYMBOL32-NEXT:     StorageClass: C_FCN (0x65)
+# SYMBOL32-NEXT:     NumberOfAuxEntries: 1
+# SYMBOL32-NEXT:     Block Auxiliary Entry {
+# SYMBOL32-NEXT:       Index: 20
+# SYMBOL32-NEXT:       LineNumber (High 2 Bytes): 0x2
+# SYMBOL32-NEXT:       LineNumber (Low 2 Bytes): 0x3
+# SYMBOL32-NEXT:     }
+# SYMBOL32-NEXT:   }
 # SYMBOL32-NEXT: ]

diff  --git a/llvm/test/tools/llvm-readobj/XCOFF/symbols64.test b/llvm/test/tools/llvm-readobj/XCOFF/symbols64.test
index 617f9ed51990c..591c131063fe3 100644
--- a/llvm/test/tools/llvm-readobj/XCOFF/symbols64.test
+++ b/llvm/test/tools/llvm-readobj/XCOFF/symbols64.test
@@ -72,6 +72,71 @@ Symbols:
         StorageMappingClass:    XMC_PR
         SectionOrLengthLo:      2
         SectionOrLengthHi:      3
+## The C_WEAKEXT symbol with a Function auxiliary entry and a CSECT auxiliary entry.
+  - Name:               .fun3
+    Value:              0x0
+    Section:            N_DEBUG
+    Type:               0x20
+    StorageClass:       C_WEAKEXT
+    NumberOfAuxEntries: 2
+    AuxEntries:
+      - Type:                 AUX_FCN
+        SizeOfFunction:       3
+        SymIdxOfNextBeyond:   4
+        PtrToLineNum:         5
+      - Type:                   AUX_CSECT
+        ParameterHashIndex:     2
+        TypeChkSectNum:         3
+        SymbolAlignmentAndType: 1
+        StorageMappingClass:    XMC_PR
+        SectionOrLengthLo:      4
+        SectionOrLengthHi:      5
+## The C_EXT symbol with a Function auxiliary entry, a CSECT auxiliary entry, and an Exception auxiliary entry.
+  - Name:               .fun4
+    Value:              0x0
+    Section:            .text
+    Type:               0x20
+    StorageClass:       C_EXT
+    NumberOfAuxEntries: 3
+    AuxEntries:
+      - Type:                 AUX_FCN
+        SizeOfFunction:       3
+        SymIdxOfNextBeyond:   4
+        PtrToLineNum:         5
+      - Type:                 AUX_EXCEPT
+        OffsetToExceptionTbl: 2
+        SizeOfFunction:       3
+        SymIdxOfNextBeyond:   4
+      - Type:                   AUX_CSECT
+        ParameterHashIndex:     2
+        TypeChkSectNum:         3
+        SymbolAlignmentAndType: 1
+        StorageMappingClass:    XMC_PR
+        SectionOrLengthLo:      4
+        SectionOrLengthHi:      5
+## The C_DWARF symbol with a SECT auxiliary entry.
+  - Name:               .fun5
+    Section:            N_DEBUG
+    StorageClass:       C_DWARF
+    NumberOfAuxEntries: 1
+    AuxEntries:
+      - Type:                   AUX_SECT
+        LengthOfSectionPortion: 2
+        NumberOfRelocEnt:       3
+## The C_BLOCK symbol with a Block auxiliary entry.
+  - Name:               .fun6
+    StorageClass:       C_BLOCK
+    NumberOfAuxEntries: 1
+    AuxEntries:
+      - Type:    AUX_SYM
+        LineNum: 3
+## The C_FCN symbol with a Block auxiliary entry.
+  - Name:               .fun7
+    StorageClass:       C_FCN
+    NumberOfAuxEntries: 1
+    AuxEntries:
+      - Type:    AUX_SYM
+        LineNum: 3
 
 # SYMBOL64:      Symbols [
 # SYMBOL64-NEXT:   Symbol {
@@ -159,4 +224,106 @@ Symbols:
 # SYMBOL64-NEXT:       Auxiliary Type: AUX_CSECT (0xFB)
 # SYMBOL64-NEXT:     }
 # SYMBOL64-NEXT:   }
+# SYMBOL64-NEXT:   Symbol {
+# SYMBOL64-NEXT:     Index: 10
+# SYMBOL64-NEXT:     Name: .fun3
+# SYMBOL64-NEXT:     Value (RelocatableAddress): 0x0
+# SYMBOL64-NEXT:     Section: N_DEBUG
+# SYMBOL64-NEXT:     Type: 0x20
+# SYMBOL64-NEXT:     StorageClass: C_WEAKEXT (0x6F)
+# SYMBOL64-NEXT:     NumberOfAuxEntries: 2
+# SYMBOL64-NEXT:     Function Auxiliary Entry {
+# SYMBOL64-NEXT:       Index: 11
+# SYMBOL64-NEXT:       SizeOfFunction: 0x3
+# SYMBOL64-NEXT:       PointerToLineNum: 0x5
+# SYMBOL64-NEXT:       SymbolIndexOfNextBeyond: 4
+# SYMBOL64-NEXT:       Auxiliary Type: AUX_FCN (0xFE)
+# SYMBOL64-NEXT:     }
+# SYMBOL64-NEXT:     CSECT Auxiliary Entry {
+# SYMBOL64-NEXT:       Index: 12
+# SYMBOL64-NEXT:       SectionLen: 21474836484
+# SYMBOL64-NEXT:       ParameterHashIndex: 0x2
+# SYMBOL64-NEXT:       TypeChkSectNum: 0x3
+# SYMBOL64-NEXT:       SymbolAlignmentLog2: 0
+# SYMBOL64-NEXT:       SymbolType: XTY_SD (0x1)
+# SYMBOL64-NEXT:       StorageMappingClass: XMC_PR (0x0)
+# SYMBOL64-NEXT:       Auxiliary Type: AUX_CSECT (0xFB)
+# SYMBOL64-NEXT:     }
+# SYMBOL64-NEXT:   }
+# SYMBOL64-NEXT:   Symbol {
+# SYMBOL64-NEXT:     Index: 13
+# SYMBOL64-NEXT:     Name: .fun4
+# SYMBOL64-NEXT:     Value (RelocatableAddress): 0x0
+# SYMBOL64-NEXT:     Section: .text
+# SYMBOL64-NEXT:     Type: 0x20
+# SYMBOL64-NEXT:     StorageClass: C_EXT (0x2)
+# SYMBOL64-NEXT:     NumberOfAuxEntries: 3
+# SYMBOL64-NEXT:     Function Auxiliary Entry {
+# SYMBOL64-NEXT:       Index: 14
+# SYMBOL64-NEXT:       SizeOfFunction: 0x3
+# SYMBOL64-NEXT:       PointerToLineNum: 0x5
+# SYMBOL64-NEXT:       SymbolIndexOfNextBeyond: 4
+# SYMBOL64-NEXT:       Auxiliary Type: AUX_FCN (0xFE)
+# SYMBOL64-NEXT:     }
+# SYMBOL64-NEXT:     Exception Auxiliary Entry {
+# SYMBOL64-NEXT:       Index: 15
+# SYMBOL64-NEXT:       OffsetToExceptionTable: 0x2
+# SYMBOL64-NEXT:       SizeOfFunction: 0x3
+# SYMBOL64-NEXT:       SymbolIndexOfNextBeyond: 4
+# SYMBOL64-NEXT:       Auxiliary Type: AUX_EXCEPT (0xFF)
+# SYMBOL64-NEXT:     }
+# SYMBOL64-NEXT:     CSECT Auxiliary Entry {
+# SYMBOL64-NEXT:       Index: 16
+# SYMBOL64-NEXT:       SectionLen: 21474836484
+# SYMBOL64-NEXT:       ParameterHashIndex: 0x2
+# SYMBOL64-NEXT:       TypeChkSectNum: 0x3
+# SYMBOL64-NEXT:       SymbolAlignmentLog2: 0
+# SYMBOL64-NEXT:       SymbolType: XTY_SD (0x1)
+# SYMBOL64-NEXT:       StorageMappingClass: XMC_PR (0x0)
+# SYMBOL64-NEXT:       Auxiliary Type: AUX_CSECT (0xFB)
+# SYMBOL64-NEXT:     }
+# SYMBOL64-NEXT:   }
+# SYMBOL64-NEXT:   Symbol {
+# SYMBOL64-NEXT:     Index: 17
+# SYMBOL64-NEXT:     Name: .fun5
+# SYMBOL64-NEXT:     Value (OffsetInDWARF): 0x0
+# SYMBOL64-NEXT:     Section: N_DEBUG
+# SYMBOL64-NEXT:     Type: 0x0
+# SYMBOL64-NEXT:     StorageClass: C_DWARF (0x70)
+# SYMBOL64-NEXT:     NumberOfAuxEntries: 1
+# SYMBOL64-NEXT:     Sect Auxiliary Entry For DWARF {
+# SYMBOL64-NEXT:       Index: 18
+# SYMBOL64-NEXT:       LengthOfSectionPortion: 0x2
+# SYMBOL64-NEXT:       NumberOfRelocEntries: 3
+# SYMBOL64-NEXT:       Auxiliary Type: AUX_SECT (0xFA)
+# SYMBOL64-NEXT:     }
+# SYMBOL64-NEXT:   }
+# SYMBOL64-NEXT:   Symbol {
+# SYMBOL64-NEXT:     Index: 19
+# SYMBOL64-NEXT:     Name: .fun6
+# SYMBOL64-NEXT:     Value (RelocatableAddress): 0x0
+# SYMBOL64-NEXT:     Section: N_UNDEF
+# SYMBOL64-NEXT:     Type: 0x0
+# SYMBOL64-NEXT:     StorageClass: C_BLOCK (0x64)
+# SYMBOL64-NEXT:     NumberOfAuxEntries: 1
+# SYMBOL64-NEXT:     Block Auxiliary Entry {
+# SYMBOL64-NEXT:       Index: 20
+# SYMBOL64-NEXT:       LineNumber: 0x3
+# SYMBOL64-NEXT:       Auxiliary Type: AUX_SYM (0xFD)
+# SYMBOL64-NEXT:     }
+# SYMBOL64-NEXT:   }
+# SYMBOL64-NEXT:   Symbol {
+# SYMBOL64-NEXT:     Index: 21
+# SYMBOL64-NEXT:     Name: .fun7
+# SYMBOL64-NEXT:     Value (RelocatableAddress): 0x0
+# SYMBOL64-NEXT:     Section: N_UNDEF
+# SYMBOL64-NEXT:     Type: 0x0
+# SYMBOL64-NEXT:     StorageClass: C_FCN (0x65)
+# SYMBOL64-NEXT:     NumberOfAuxEntries: 1
+# SYMBOL64-NEXT:     Block Auxiliary Entry {
+# SYMBOL64-NEXT:       Index: 22
+# SYMBOL64-NEXT:       LineNumber: 0x3
+# SYMBOL64-NEXT:       Auxiliary Type: AUX_SYM (0xFD)
+# SYMBOL64-NEXT:     }
+# SYMBOL64-NEXT:   }
 # SYMBOL64-NEXT: ]

diff  --git a/llvm/tools/llvm-readobj/XCOFFDumper.cpp b/llvm/tools/llvm-readobj/XCOFFDumper.cpp
index 38e459cd5425b..e34b105cfbf0a 100644
--- a/llvm/tools/llvm-readobj/XCOFFDumper.cpp
+++ b/llvm/tools/llvm-readobj/XCOFFDumper.cpp
@@ -44,9 +44,16 @@ class XCOFFDumper : public ObjDumper {
   template <typename T> void printSectionHeaders(ArrayRef<T> Sections);
   template <typename T> void printGenericSectionHeader(T &Sec) const;
   template <typename T> void printOverflowSectionHeader(T &Sec) const;
+  template <typename T> const T *getAuxEntPtr(uintptr_t AuxAddress);
   void printFileAuxEnt(const XCOFFFileAuxEnt *AuxEntPtr);
   void printCsectAuxEnt(XCOFFCsectAuxRef AuxEntRef);
   void printSectAuxEntForStat(const XCOFFSectAuxEntForStat *AuxEntPtr);
+  void printExceptionAuxEnt(const XCOFFExceptionAuxEnt *AuxEntPtr);
+  void printFunctionAuxEnt(const XCOFFFunctionAuxEnt32 *AuxEntPtr);
+  void printFunctionAuxEnt(const XCOFFFunctionAuxEnt64 *AuxEntPtr);
+  void printBlockAuxEnt(const XCOFFBlockAuxEnt32 *AuxEntPtr);
+  void printBlockAuxEnt(const XCOFFBlockAuxEnt64 *AuxEntPtr);
+  template <typename T> void printSectAuxEntForDWARF(const T *AuxEntPtr);
   void printSymbol(const SymbolRef &);
   template <typename RelTy> void printRelocation(RelTy Reloc);
   template <typename Shdr, typename RelTy>
@@ -289,6 +296,77 @@ void XCOFFDumper::printSectAuxEntForStat(
   W.printNumber("NumberOfLineNum", AuxEntPtr->NumberOfLineNum);
 }
 
+void XCOFFDumper::printExceptionAuxEnt(const XCOFFExceptionAuxEnt *AuxEntPtr) {
+  assert(Obj.is64Bit() && "64-bit interface called on 32-bit object file.");
+
+  DictScope SymDs(W, "Exception Auxiliary Entry");
+  W.printNumber("Index",
+                Obj.getSymbolIndex(reinterpret_cast<uintptr_t>(AuxEntPtr)));
+  W.printHex("OffsetToExceptionTable", AuxEntPtr->OffsetToExceptionTbl);
+  W.printHex("SizeOfFunction", AuxEntPtr->SizeOfFunction);
+  W.printNumber("SymbolIndexOfNextBeyond", AuxEntPtr->SymIdxOfNextBeyond);
+  W.printEnum("Auxiliary Type", static_cast<uint8_t>(AuxEntPtr->AuxType),
+              makeArrayRef(SymAuxType));
+}
+
+void XCOFFDumper::printFunctionAuxEnt(const XCOFFFunctionAuxEnt32 *AuxEntPtr) {
+  assert(!Obj.is64Bit() && "32-bit interface called on 64-bit object file.");
+
+  DictScope SymDs(W, "Function Auxiliary Entry");
+  W.printNumber("Index",
+                Obj.getSymbolIndex(reinterpret_cast<uintptr_t>(AuxEntPtr)));
+  W.printHex("OffsetToExceptionTable", AuxEntPtr->OffsetToExceptionTbl);
+  W.printHex("SizeOfFunction", AuxEntPtr->SizeOfFunction);
+  W.printHex("PointerToLineNum", AuxEntPtr->PtrToLineNum);
+  W.printNumber("SymbolIndexOfNextBeyond", AuxEntPtr->SymIdxOfNextBeyond);
+}
+
+void XCOFFDumper::printFunctionAuxEnt(const XCOFFFunctionAuxEnt64 *AuxEntPtr) {
+  assert(Obj.is64Bit() && "64-bit interface called on 32-bit object file.");
+
+  DictScope SymDs(W, "Function Auxiliary Entry");
+  W.printNumber("Index",
+                Obj.getSymbolIndex(reinterpret_cast<uintptr_t>(AuxEntPtr)));
+  W.printHex("SizeOfFunction", AuxEntPtr->SizeOfFunction);
+  W.printHex("PointerToLineNum", AuxEntPtr->PtrToLineNum);
+  W.printNumber("SymbolIndexOfNextBeyond", AuxEntPtr->SymIdxOfNextBeyond);
+  W.printEnum("Auxiliary Type", static_cast<uint8_t>(AuxEntPtr->AuxType),
+              makeArrayRef(SymAuxType));
+}
+
+void XCOFFDumper::printBlockAuxEnt(const XCOFFBlockAuxEnt32 *AuxEntPtr) {
+  assert(!Obj.is64Bit() && "32-bit interface called on 64-bit object file.");
+
+  DictScope SymDs(W, "Block Auxiliary Entry");
+  W.printNumber("Index",
+                Obj.getSymbolIndex(reinterpret_cast<uintptr_t>(AuxEntPtr)));
+  W.printHex("LineNumber (High 2 Bytes)", AuxEntPtr->LineNumHi);
+  W.printHex("LineNumber (Low 2 Bytes)", AuxEntPtr->LineNumLo);
+}
+
+void XCOFFDumper::printBlockAuxEnt(const XCOFFBlockAuxEnt64 *AuxEntPtr) {
+  assert(Obj.is64Bit() && "64-bit interface called on 32-bit object file.");
+
+  DictScope SymDs(W, "Block Auxiliary Entry");
+  W.printNumber("Index",
+                Obj.getSymbolIndex(reinterpret_cast<uintptr_t>(AuxEntPtr)));
+  W.printHex("LineNumber", AuxEntPtr->LineNum);
+  W.printEnum("Auxiliary Type", static_cast<uint8_t>(AuxEntPtr->AuxType),
+              makeArrayRef(SymAuxType));
+}
+
+template <typename T>
+void XCOFFDumper::printSectAuxEntForDWARF(const T *AuxEntPtr) {
+  DictScope SymDs(W, "Sect Auxiliary Entry For DWARF");
+  W.printNumber("Index",
+                Obj.getSymbolIndex(reinterpret_cast<uintptr_t>(AuxEntPtr)));
+  W.printHex("LengthOfSectionPortion", AuxEntPtr->LengthOfSectionPortion);
+  W.printNumber("NumberOfRelocEntries", AuxEntPtr->NumberOfRelocEnt);
+  if (Obj.is64Bit())
+    W.printEnum("Auxiliary Type", static_cast<uint8_t>(XCOFF::AUX_SECT),
+                makeArrayRef(SymAuxType));
+}
+
 const EnumEntry<XCOFF::StorageClass> SymStorageClass[] = {
 #define ECase(X)                                                               \
   { #X, XCOFF::X }
@@ -314,11 +392,13 @@ static StringRef GetSymbolValueName(XCOFF::StorageClass SC) {
   case XCOFF::C_WEAKEXT:
   case XCOFF::C_HIDEXT:
   case XCOFF::C_STAT:
+  case XCOFF::C_FCN:
+  case XCOFF::C_BLOCK:
     return "Value (RelocatableAddress)";
   case XCOFF::C_FILE:
     return "Value (SymbolTableIndex)";
-  case XCOFF::C_FCN:
-  case XCOFF::C_BLOCK:
+  case XCOFF::C_DWARF:
+    return "Value (OffsetInDWARF)";
   case XCOFF::C_FUN:
   case XCOFF::C_STSYM:
   case XCOFF::C_BINCL:
@@ -330,7 +410,6 @@ static StringRef GetSymbolValueName(XCOFF::StorageClass SC) {
   case XCOFF::C_RPSYM:
   case XCOFF::C_RSYM:
   case XCOFF::C_ECOML:
-  case XCOFF::C_DWARF:
     assert(false && "This StorageClass for the symbol is not yet implemented.");
     return "";
   default:
@@ -352,6 +431,22 @@ const EnumEntry<XCOFF::CFileCpuId> CFileCpuIdClass[] = {
 #undef ECase
 };
 
+template <typename T> const T *XCOFFDumper::getAuxEntPtr(uintptr_t AuxAddress) {
+  const T *AuxEntPtr = reinterpret_cast<const T *>(AuxAddress);
+  Obj.checkSymbolEntryPointer(reinterpret_cast<uintptr_t>(AuxEntPtr));
+  return AuxEntPtr;
+}
+
+static void printUnexpectedRawAuxEnt(ScopedPrinter &W, uintptr_t AuxAddress) {
+  W.startLine() << "!Unexpected raw auxiliary entry data:\n";
+  W.startLine() << format_bytes(
+                       ArrayRef<uint8_t>(
+                           reinterpret_cast<const uint8_t *>(AuxAddress),
+                           XCOFF::SymbolTableEntrySize),
+                       None, XCOFF::SymbolTableEntrySize)
+                << "\n";
+}
+
 void XCOFFDumper::printSymbol(const SymbolRef &S) {
   DataRefImpl SymbolDRI = S.getRawDataRefImpl();
   XCOFFSymbolRef SymbolEntRef = Obj.toSymbolRef(SymbolDRI);
@@ -363,16 +458,18 @@ void XCOFFDumper::printSymbol(const SymbolRef &S) {
   StringRef SymbolName =
       unwrapOrError(Obj.getFileName(), SymbolEntRef.getName());
 
-  W.printNumber("Index", Obj.getSymbolIndex(SymbolEntRef.getEntryAddress()));
+  uint32_t SymbolIdx = Obj.getSymbolIndex(SymbolEntRef.getEntryAddress());
+  XCOFF::StorageClass SymbolClass = SymbolEntRef.getStorageClass();
+
+  W.printNumber("Index", SymbolIdx);
   W.printString("Name", SymbolName);
-  W.printHex(GetSymbolValueName(SymbolEntRef.getStorageClass()),
-             SymbolEntRef.getValue());
+  W.printHex(GetSymbolValueName(SymbolClass), SymbolEntRef.getValue());
 
   StringRef SectionName =
       unwrapOrError(Obj.getFileName(), Obj.getSymbolSectionName(SymbolEntRef));
 
   W.printString("Section", SectionName);
-  if (SymbolEntRef.getStorageClass() == XCOFF::C_FILE) {
+  if (SymbolClass == XCOFF::C_FILE) {
     W.printEnum("Source Language ID", SymbolEntRef.getLanguageIdForCFile(),
                 makeArrayRef(CFileLangIdClass));
     W.printEnum("CPU Version ID", SymbolEntRef.getCPUTypeIddForCFile(),
@@ -380,15 +477,24 @@ void XCOFFDumper::printSymbol(const SymbolRef &S) {
   } else
     W.printHex("Type", SymbolEntRef.getSymbolType());
 
-  W.printEnum("StorageClass",
-              static_cast<uint8_t>(SymbolEntRef.getStorageClass()),
+  W.printEnum("StorageClass", static_cast<uint8_t>(SymbolClass),
               makeArrayRef(SymStorageClass));
   W.printNumber("NumberOfAuxEntries", NumberOfAuxEntries);
 
   if (NumberOfAuxEntries == 0)
     return;
 
-  switch (SymbolEntRef.getStorageClass()) {
+  auto checkNumOfAux = [=] {
+    if (NumberOfAuxEntries > 1)
+      reportUniqueWarning("the " +
+                          enumToString(static_cast<uint8_t>(SymbolClass),
+                                       makeArrayRef(SymStorageClass)) +
+                          " symbol at index " + Twine(SymbolIdx) +
+                          " should not have more than 1 "
+                          "auxiliary entry");
+  };
+
+  switch (SymbolClass) {
   case XCOFF::C_FILE:
     // If the symbol is C_FILE and has auxiliary entries...
     for (int I = 1; I <= NumberOfAuxEntries; I++) {
@@ -397,55 +503,62 @@ void XCOFFDumper::printSymbol(const SymbolRef &S) {
 
       if (Obj.is64Bit() &&
           *Obj.getSymbolAuxType(AuxAddress) != XCOFF::SymbolAuxType::AUX_FILE) {
-        W.startLine() << "!Unexpected raw auxiliary entry data:\n";
-        W.startLine() << format_bytes(
-                             ArrayRef<uint8_t>(
-                                 reinterpret_cast<const uint8_t *>(AuxAddress),
-                                 XCOFF::SymbolTableEntrySize),
-                             0, XCOFF::SymbolTableEntrySize)
-                      << "\n";
+        printUnexpectedRawAuxEnt(W, AuxAddress);
         continue;
       }
 
       const XCOFFFileAuxEnt *FileAuxEntPtr =
-          reinterpret_cast<const XCOFFFileAuxEnt *>(AuxAddress);
-#ifndef NDEBUG
-      Obj.checkSymbolEntryPointer(reinterpret_cast<uintptr_t>(FileAuxEntPtr));
-#endif
+          getAuxEntPtr<XCOFFFileAuxEnt>(AuxAddress);
       printFileAuxEnt(FileAuxEntPtr);
     }
     break;
   case XCOFF::C_EXT:
   case XCOFF::C_WEAKEXT:
   case XCOFF::C_HIDEXT: {
-    // If the symbol is for a function, and it has more than 1 auxiliary entry,
-    // then one of them must be function auxiliary entry which we do not
-    // support yet.
-    if (SymbolEntRef.isFunction() && NumberOfAuxEntries >= 2)
-      report_fatal_error("Function auxiliary entry printing is unimplemented.");
-
-    // If there is more than 1 auxiliary entry, instead of printing out
-    // error information, print out the raw Auxiliary entry.
-    // For 32-bit object, print from first to the last - 1. The last one must be
-    // a CSECT Auxiliary Entry.
-    // For 64-bit object, print from first to last and skips if SymbolAuxType is
-    // AUX_CSECT.
+    if (!SymbolEntRef.isFunction() && NumberOfAuxEntries > 1)
+      reportUniqueWarning("the non-function " +
+                          enumToString(static_cast<uint8_t>(SymbolClass),
+                                       makeArrayRef(SymStorageClass)) +
+                          " symbol at index " + Twine(SymbolIdx) +
+                          " should have only 1 auxiliary entry, i.e. the CSECT "
+                          "auxiliary entry");
+
+    // For 32-bit objects, print the function auxiliary symbol table entry. The
+    // last one must be a CSECT auxiliary entry.
+    // For 64-bit objects, both a function auxiliary entry and an exception
+    // auxiliary entry may appear, print them in the loop and skip printing the
+    // CSECT auxiliary entry, which will be printed outside the loop.
     for (int I = 1; I <= NumberOfAuxEntries; I++) {
-      if (I == NumberOfAuxEntries && !Obj.is64Bit())
+      if ((I == NumberOfAuxEntries && !Obj.is64Bit()) ||
+          !SymbolEntRef.isFunction())
         break;
 
       uintptr_t AuxAddress = XCOFFObjectFile::getAdvancedSymbolEntryAddress(
           SymbolEntRef.getEntryAddress(), I);
-      if (Obj.is64Bit() &&
-          *Obj.getSymbolAuxType(AuxAddress) == XCOFF::SymbolAuxType::AUX_CSECT)
-        continue;
 
-      W.startLine() << "!Unexpected raw auxiliary entry data:\n";
-      W.startLine() << format_bytes(
-          ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(AuxAddress),
-                            XCOFF::SymbolTableEntrySize));
+      if (Obj.is64Bit()) {
+        XCOFF::SymbolAuxType Type = *Obj.getSymbolAuxType(AuxAddress);
+        if (Type == XCOFF::SymbolAuxType::AUX_CSECT)
+          continue;
+        if (Type == XCOFF::SymbolAuxType::AUX_FCN) {
+          const XCOFFFunctionAuxEnt64 *AuxEntPtr =
+              getAuxEntPtr<XCOFFFunctionAuxEnt64>(AuxAddress);
+          printFunctionAuxEnt(AuxEntPtr);
+        } else if (Type == XCOFF::SymbolAuxType::AUX_EXCEPT) {
+          const XCOFFExceptionAuxEnt *AuxEntPtr =
+              getAuxEntPtr<XCOFFExceptionAuxEnt>(AuxAddress);
+          printExceptionAuxEnt(AuxEntPtr);
+        } else {
+          printUnexpectedRawAuxEnt(W, AuxAddress);
+        }
+      } else {
+        const XCOFFFunctionAuxEnt32 *AuxEntPtr =
+            getAuxEntPtr<XCOFFFunctionAuxEnt32>(AuxAddress);
+        printFunctionAuxEnt(AuxEntPtr);
+      }
     }
 
+    // Print the CSECT auxiliary entry.
     auto ErrOrCsectAuxRef = SymbolEntRef.getXCOFFCsectAuxRef();
     if (!ErrOrCsectAuxRef)
       reportUniqueWarning(ErrOrCsectAuxRef.takeError());
@@ -454,34 +567,56 @@ void XCOFFDumper::printSymbol(const SymbolRef &S) {
 
     break;
   }
-  case XCOFF::C_STAT:
-    if (NumberOfAuxEntries > 1)
-      report_fatal_error(
-          "C_STAT symbol should not have more than 1 auxiliary entry.");
-
-    const XCOFFSectAuxEntForStat *StatAuxEntPtr;
-    StatAuxEntPtr = reinterpret_cast<const XCOFFSectAuxEntForStat *>(
-        XCOFFObjectFile::getAdvancedSymbolEntryAddress(
-            SymbolEntRef.getEntryAddress(), 1));
-#ifndef NDEBUG
-    Obj.checkSymbolEntryPointer(reinterpret_cast<uintptr_t>(StatAuxEntPtr));
-#endif
+  case XCOFF::C_STAT: {
+    checkNumOfAux();
+
+    const XCOFFSectAuxEntForStat *StatAuxEntPtr =
+        getAuxEntPtr<XCOFFSectAuxEntForStat>(
+            XCOFFObjectFile::getAdvancedSymbolEntryAddress(
+                SymbolEntRef.getEntryAddress(), 1));
     printSectAuxEntForStat(StatAuxEntPtr);
     break;
-  case XCOFF::C_DWARF:
+  }
+  case XCOFF::C_DWARF: {
+    checkNumOfAux();
+
+    uintptr_t AuxAddress = XCOFFObjectFile::getAdvancedSymbolEntryAddress(
+        SymbolEntRef.getEntryAddress(), 1);
+
+    if (Obj.is64Bit()) {
+      const XCOFFSectAuxEntForDWARF64 *AuxEntPtr =
+          getAuxEntPtr<XCOFFSectAuxEntForDWARF64>(AuxAddress);
+      printSectAuxEntForDWARF<XCOFFSectAuxEntForDWARF64>(AuxEntPtr);
+    } else {
+      const XCOFFSectAuxEntForDWARF32 *AuxEntPtr =
+          getAuxEntPtr<XCOFFSectAuxEntForDWARF32>(AuxAddress);
+      printSectAuxEntForDWARF<XCOFFSectAuxEntForDWARF32>(AuxEntPtr);
+    }
+    break;
+  }
   case XCOFF::C_BLOCK:
-  case XCOFF::C_FCN:
-    report_fatal_error("Symbol table entry printing for this storage class "
-                       "type is unimplemented.");
+  case XCOFF::C_FCN: {
+    checkNumOfAux();
+
+    uintptr_t AuxAddress = XCOFFObjectFile::getAdvancedSymbolEntryAddress(
+        SymbolEntRef.getEntryAddress(), 1);
+
+    if (Obj.is64Bit()) {
+      const XCOFFBlockAuxEnt64 *AuxEntPtr =
+          getAuxEntPtr<XCOFFBlockAuxEnt64>(AuxAddress);
+      printBlockAuxEnt(AuxEntPtr);
+    } else {
+      const XCOFFBlockAuxEnt32 *AuxEntPtr =
+          getAuxEntPtr<XCOFFBlockAuxEnt32>(AuxAddress);
+      printBlockAuxEnt(AuxEntPtr);
+    }
     break;
+  }
   default:
     for (int i = 1; i <= NumberOfAuxEntries; i++) {
-      W.startLine() << "!Unexpected raw auxiliary entry data:\n";
-      W.startLine() << format_bytes(
-          ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(
-                                XCOFFObjectFile::getAdvancedSymbolEntryAddress(
-                                    SymbolEntRef.getEntryAddress(), i)),
-                            XCOFF::SymbolTableEntrySize));
+      printUnexpectedRawAuxEnt(W,
+                               XCOFFObjectFile::getAdvancedSymbolEntryAddress(
+                                   SymbolEntRef.getEntryAddress(), i));
     }
     break;
   }


        


More information about the llvm-commits mailing list