Index: llvm/include/llvm/BinaryFormat/DynamicTags.def =================================================================== --- llvm/include/llvm/BinaryFormat/DynamicTags.def +++ llvm/include/llvm/BinaryFormat/DynamicTags.def @@ -120,6 +120,7 @@ // AArch64 specific dynamic table entries AARCH64_DYNAMIC_TAG(AARCH64_BTI_PLT, 0x70000001) AARCH64_DYNAMIC_TAG(AARCH64_PAC_PLT, 0x70000003) +AARCH64_DYNAMIC_TAG(AARCH64_VARIANT_PCS, 0x70000005) // Hexagon specific dynamic table entries HEXAGON_DYNAMIC_TAG(HEXAGON_SYMSZ, 0x70000000) Index: llvm/test/tools/llvm-readobj/ELF/AArch64/aarch64-variant_pcs.s =================================================================== --- /dev/null +++ llvm/test/tools/llvm-readobj/ELF/AArch64/aarch64-variant_pcs.s @@ -0,0 +1,70 @@ +// RUN: llvm-mc -filetype=obj -triple aarch64-linux-gnu %s -o %t +// RUN: llvm-readelf -symbols %t | FileCheck %s --check-prefix=GNU +// RUN: llvm-readobj -symbols %t | FileCheck %s --check-prefix=LLVM + +// GNU: NOTYPE LOCAL DEFAULT [VARIANT_PCS] [[#]] pcs_func_local +// GNU-NEXT: IFUNC LOCAL DEFAULT [VARIANT_PCS] [[#]] pcs_ifunc_local +// GNU-NEXT: NOTYPE GLOBAL DEFAULT [VARIANT_PCS] [[#]] pcs_func_global_def +// GNU-NEXT: IFUNC GLOBAL DEFAULT [VARIANT_PCS] [[#]] pcs_ifunc_global_def + +// LLVM: Symbol { +// LLVM: Name: pcs_func_local (23) +// LLVM-NEXT: Value: 0x0 +// LLVM-NEXT: Size: 0 +// LLVM-NEXT: Binding: Local (0x0) +// LLVM-NEXT: Type: None (0x0) +// LLVM-NEXT: Other [ (0x80) +// LLVM-NEXT: ] +// LLVM-NEXT: Section: .text (0x2) +// LLVM-NEXT: } +// LLVM-NEXT: Symbol { +// LLVM-NEXT: Name: pcs_ifunc_local (7) +// LLVM-NEXT: Value: 0x0 +// LLVM-NEXT: Size: 0 +// LLVM-NEXT: Binding: Local (0x0) +// LLVM-NEXT: Type: GNU_IFunc (0xA) +// LLVM-NEXT: Other [ (0x80) +// LLVM-NEXT: ] +// LLVM-NEXT: Section: .text (0x2) +// LLVM-NEXT: } +// LLVM-NEXT: Symbol { +// LLVM-NEXT: Name: pcs_func_global_def (59) +// LLVM-NEXT: Value: 0x0 +// LLVM-NEXT: Size: 0 +// LLVM-NEXT: Binding: Global (0x1) +// LLVM-NEXT: Type: None (0x0) +// LLVM-NEXT: Other [ (0x80) +// LLVM-NEXT: ] +// LLVM-NEXT: Section: .text (0x2) +// LLVM-NEXT: } +// LLVM-NEXT: Symbol { +// LLVM-NEXT: Name: pcs_ifunc_global_def (38) +// LLVM-NEXT: Value: 0x0 +// LLVM-NEXT: Size: 0 +// LLVM-NEXT: Binding: Global (0x1) +// LLVM-NEXT: Type: GNU_IFunc (0xA) +// LLVM-NEXT: Other [ (0x80) +// LLVM-NEXT: ] +// LLVM-NEXT: Section: .text (0x2) +// LLVM-NEXT: } + +.text + +.global pcs_func_global_def +.global pcs_ifunc_global_def +.local pcs_func_local +.local pcs_ifunc_local + +.variant_pcs pcs_func_global_def +.variant_pcs pcs_ifunc_global_def +.variant_pcs pcs_func_local +.variant_pcs pcs_ifunc_local + +.type pcs_ifunc_global_def, %gnu_indirect_function +.type pcs_ifunc_local, %gnu_indirect_function + +pcs_func_global_def: +pcs_ifunc_global_def: +pcs_func_local: +pcs_ifunc_local: + ret Index: llvm/test/tools/llvm-readobj/ELF/dynamic-tags-machine-specific.test =================================================================== --- llvm/test/tools/llvm-readobj/ELF/dynamic-tags-machine-specific.test +++ llvm/test/tools/llvm-readobj/ELF/dynamic-tags-machine-specific.test @@ -351,18 +351,20 @@ # RUN: llvm-readobj --dynamic-table %t.aarch64 | FileCheck %s --check-prefix=LLVM-AARCH64 # RUN: llvm-readelf --dynamic-table %t.aarch64 | FileCheck %s --check-prefix=GNU-AARCH64 -# LLVM-AARCH64: DynamicSection [ (3 entries) -# LLVM-AARCH64-NEXT: Tag Type Name/Value -# LLVM-AARCH64-NEXT: 0x0000000070000001 AARCH64_BTI_PLT 1 -# LLVM-AARCH64-NEXT: 0x0000000070000003 AARCH64_PAC_PLT 2 -# LLVM-AARCH64-NEXT: 0x0000000000000000 NULL 0x0 +# LLVM-AARCH64: DynamicSection [ (4 entries) +# LLVM-AARCH64-NEXT: Tag Type Name/Value +# LLVM-AARCH64-NEXT: 0x0000000070000001 AARCH64_BTI_PLT 1 +# LLVM-AARCH64-NEXT: 0x0000000070000003 AARCH64_PAC_PLT 2 +# LLVM-AARCH64-NEXT: 0x0000000070000005 AARCH64_VARIANT_PCS 3 +# LLVM-AARCH64-NEXT: 0x0000000000000000 NULL 0x0 # LLVM-AARCH64-NEXT:] -# GNU-AARCH64: Dynamic section at offset {{.*}} contains 3 entries: -# GNU-AARCH64-NEXT: Tag Type Name/Value -# GNU-AARCH64-NEXT: 0x0000000070000001 (AARCH64_BTI_PLT) 1 -# GNU-AARCH64-NEXT: 0x0000000070000003 (AARCH64_PAC_PLT) 2 -# GNU-AARCH64-NEXT: 0x0000000000000000 (NULL) 0x0 +# GNU-AARCH64: Dynamic section at offset {{.*}} contains 4 entries: +# GNU-AARCH64-NEXT: Tag Type Name/Value +# GNU-AARCH64-NEXT: 0x0000000070000001 (AARCH64_BTI_PLT) 1 +# GNU-AARCH64-NEXT: 0x0000000070000003 (AARCH64_PAC_PLT) 2 +# GNU-AARCH64-NEXT: 0x0000000070000005 (AARCH64_VARIANT_PCS) 3 +# GNU-AARCH64-NEXT: 0x0000000000000000 (NULL) 0x0 --- !ELF FileHeader: @@ -378,6 +380,8 @@ Value: 1 - Tag: DT_AARCH64_PAC_PLT Value: 2 + - Tag: DT_AARCH64_VARIANT_PCS + Value: 3 - Tag: DT_NULL Value: 0 ProgramHeaders: Index: llvm/tools/llvm-readobj/ELFDumper.cpp =================================================================== --- llvm/tools/llvm-readobj/ELFDumper.cpp +++ llvm/tools/llvm-readobj/ELFDumper.cpp @@ -2471,6 +2471,7 @@ switch (Type) { case DT_AARCH64_BTI_PLT: case DT_AARCH64_PAC_PLT: + case DT_AARCH64_VARIANT_PCS: return std::to_string(Value); default: break; @@ -4033,9 +4034,22 @@ printEnum(Symbol.getBinding(), makeArrayRef(ElfSymbolBindings)); Fields[5].Str = printEnum(Symbol.getVisibility(), makeArrayRef(ElfSymbolVisibilities)); - if (Symbol.st_other & ~0x3) - Fields[5].Str += - " []"; + + if (Symbol.st_other & ~0x3) { + if (this->Obj.getHeader().e_machine == ELF::EM_AARCH64) { + uint8_t other = Symbol.st_other & ~0x3; + if (other & STO_AARCH64_VARIANT_PCS) { + other &= ~STO_AARCH64_VARIANT_PCS; + Fields[5].Str += " [VARIANT_PCS"; + if (other != 0) + Fields[5].Str.append(" | " + to_hexString(other, false)); + Fields[5].Str.append("]"); + } + } else { + Fields[5].Str += + " []"; + } + } Fields[6].Column += NonVisibilityBitsUsed ? 13 : 0; Fields[6].Str = getSymbolSectionNdx(Symbol, SymIndex);