Index: include/llvm/BinaryFormat/ELF.h =================================================================== --- include/llvm/BinaryFormat/ELF.h +++ include/llvm/BinaryFormat/ELF.h @@ -1352,7 +1352,9 @@ GNU_PROPERTY_STACK_SIZE = 1, GNU_PROPERTY_NO_COPY_ON_PROTECTED = 2, GNU_PROPERTY_X86_FEATURE_1_AND = 0xc0000002, + GNU_PROPERTY_X86_ISA_1_NEEDED = 0xc0008000, GNU_PROPERTY_X86_FEATURE_2_NEEDED = 0xc0008001, + GNU_PROPERTY_X86_ISA_1_USED = 0xc0010000, GNU_PROPERTY_X86_FEATURE_2_USED = 0xc0010001, }; @@ -1361,6 +1363,31 @@ GNU_PROPERTY_X86_FEATURE_1_IBT = 1 << 0, GNU_PROPERTY_X86_FEATURE_1_SHSTK = 1 << 1, + GNU_PROPERTY_X86_ISA_1_CMOV = 1 << 0, + GNU_PROPERTY_X86_ISA_1_SSE = 1 << 1, + GNU_PROPERTY_X86_ISA_1_SSE2 = 1 << 2, + GNU_PROPERTY_X86_ISA_1_SSE3 = 1 << 3, + GNU_PROPERTY_X86_ISA_1_SSSE3 = 1 << 4, + GNU_PROPERTY_X86_ISA_1_SSE4_1 = 1 << 5, + GNU_PROPERTY_X86_ISA_1_SSE4_2 = 1 << 6, + GNU_PROPERTY_X86_ISA_1_AVX = 1 << 7, + GNU_PROPERTY_X86_ISA_1_AVX2 = 1 << 8, + GNU_PROPERTY_X86_ISA_1_FMA = 1 << 9, + GNU_PROPERTY_X86_ISA_1_AVX512F = 1 << 10, + GNU_PROPERTY_X86_ISA_1_AVX512CD = 1 << 11, + GNU_PROPERTY_X86_ISA_1_AVX512ER = 1 << 12, + GNU_PROPERTY_X86_ISA_1_AVX512PF = 1 << 13, + GNU_PROPERTY_X86_ISA_1_AVX512VL = 1 << 14, + GNU_PROPERTY_X86_ISA_1_AVX512DQ = 1 << 15, + GNU_PROPERTY_X86_ISA_1_AVX512BW = 1 << 16, + GNU_PROPERTY_X86_ISA_1_AVX512_4FMAPS = 1 << 17, + GNU_PROPERTY_X86_ISA_1_AVX512_4VNNIW = 1 << 18, + GNU_PROPERTY_X86_ISA_1_AVX512_BITALG = 1 << 19, + GNU_PROPERTY_X86_ISA_1_AVX512_IFMA = 1 << 20, + GNU_PROPERTY_X86_ISA_1_AVX512_VBMI = 1 << 21, + GNU_PROPERTY_X86_ISA_1_AVX512_VBMI2 = 1 << 22, + GNU_PROPERTY_X86_ISA_1_AVX512_VNNI = 1 << 23, + GNU_PROPERTY_X86_FEATURE_2_X86 = 1 << 0, GNU_PROPERTY_X86_FEATURE_2_X87 = 1 << 1, GNU_PROPERTY_X86_FEATURE_2_MMX = 1 << 2, Index: test/tools/llvm-readobj/note-gnu-property.s =================================================================== --- test/tools/llvm-readobj/note-gnu-property.s +++ test/tools/llvm-readobj/note-gnu-property.s @@ -3,15 +3,17 @@ // RUN: llvm-readobj -elf-output-style GNU --notes %t | FileCheck %s --check-prefix=GNU // RUN: llvm-readobj -elf-output-style LLVM --notes %t | FileCheck %s --check-prefix=LLVM -// GNU: Displaying notes found at file offset 0x00000040 with length 0x000000d8: +// GNU: Displaying notes found at file offset 0x00000040 with length 0x000000f8: // GNU-NEXT: Owner Data size Description -// GNU-NEXT: GNU 0x000000c8 NT_GNU_PROPERTY_TYPE_0 (property note) +// GNU-NEXT: GNU 0x000000e8 NT_GNU_PROPERTY_TYPE_0 (property note) // GNU-NEXT: Properties: stack size: 0x100 // GNU-NEXT: stack size: 0x100 // GNU-NEXT: no copy on protected // GNU-NEXT: x86 feature: SHSTK // GNU-NEXT: x86 feature: IBT, SHSTK // GNU-NEXT: x86 feature: +// GNU-NEXT: x86 ISA needed: CMOV, SSE +// GNU-NEXT: x86 ISA used: AVX512_VBMI2, AVX512_VNNI // GNU-NEXT: x86 feature needed: x86, x87 // GNU-NEXT: x86 feature used: XSAVEOPT, XSAVEC // GNU-NEXT: @@ -25,10 +27,10 @@ // LLVM: Notes [ // LLVM-NEXT: NoteSection { // LLVM-NEXT: Offset: 0x40 -// LLVM-NEXT: Size: 0xD8 +// LLVM-NEXT: Size: 0xF8 // LLVM-NEXT: Note { // LLVM-NEXT: Owner: GNU -// LLVM-NEXT: Data size: 0xC8 +// LLVM-NEXT: Data size: 0xE8 // LLVM-NEXT: Type: NT_GNU_PROPERTY_TYPE_0 (property note) // LLVM-NEXT: Property [ // LLVM-NEXT: stack size: 0x100 @@ -37,6 +39,8 @@ // LLVM-NEXT: x86 feature: SHSTK // LLVM-NEXT: x86 feature: IBT, SHSTK // LLVM-NEXT: x86 feature: +// LLVM-NEXT: x86 ISA needed: CMOV, SSE +// LLVM-NEXT: x86 ISA used: AVX512_VBMI2, AVX512_VNNI // LLVM-NEXT: x86 feature needed: x86, x87 // LLVM-NEXT: x86 feature used: XSAVEOPT, XSAVEC // LLVM-NEXT: @@ -91,6 +95,16 @@ .long 0 /* Empty flags, not an error */ .p2align 3 /* Align to 8 byte for 64 bit */ + .long 0xc0008000 /* Type: GNU_PROPERTY_X86_ISA_1_NEEDED */ + .long 4 /* Data size */ + .long 0x00000003 /* CMOV SSE */ + .p2align 3 /* Align to 8 byte for 64 bit */ + + .long 0xc0010000 /* Type: GNU_PROPERTY_X86_ISA_1_USED */ + .long 4 /* Data size */ + .long 0x00c00000 /* AVX512_VBMI2 AVX512_VNNI */ + .p2align 3 /* Align to 8 byte for 64 bit */ + .long 0xc0008001 /* Type: GNU_PROPERTY_X86_FEATURE_2_NEEDED */ .long 4 /* Data size */ .long 0x00000003 /* X86 X87 */ Index: tools/llvm-readobj/ELFDumper.cpp =================================================================== --- tools/llvm-readobj/ELFDumper.cpp +++ tools/llvm-readobj/ELFDumper.cpp @@ -3650,12 +3650,12 @@ ArrayRef Data) { std::string str; raw_string_ostream OS(str); - uint32_t pr_data; + uint32_t PrData; auto DumpBit = [&](uint32_t Flag, StringRef Name) { - if (pr_data & Flag) { - pr_data &= ~Flag; + if (PrData & Flag) { + PrData &= ~Flag; OS << Name; - if (pr_data) + if (PrData) OS << ", "; } }; @@ -3684,16 +3684,57 @@ OS << format("", DataSize); return OS.str(); } - pr_data = support::endian::read32(Data.data()); - if (pr_data == 0) { + PrData = support::endian::read32(Data.data()); + if (PrData == 0) { OS << ""; return OS.str(); } DumpBit(GNU_PROPERTY_X86_FEATURE_1_IBT, "IBT"); DumpBit(GNU_PROPERTY_X86_FEATURE_1_SHSTK, "SHSTK"); - if (pr_data) - OS << format("", pr_data); + if (PrData) + OS << format("", PrData); return OS.str(); + case GNU_PROPERTY_X86_ISA_1_NEEDED: + case GNU_PROPERTY_X86_ISA_1_USED: + OS << "x86 ISA " + << (Type == GNU_PROPERTY_X86_ISA_1_NEEDED ? "needed: " : "used: "); + if (DataSize != 4) { + OS << format("", DataSize); + return OS.str(); + } + PrData = support::endian::read32(Data.data()); + if (PrData == 0) { + OS << ""; + return OS.str(); + } + DumpBit(GNU_PROPERTY_X86_ISA_1_CMOV, "CMOV"); + DumpBit(GNU_PROPERTY_X86_ISA_1_SSE, "SSE"); + DumpBit(GNU_PROPERTY_X86_ISA_1_SSE2, "SSE2"); + DumpBit(GNU_PROPERTY_X86_ISA_1_SSE3, "SSE3"); + DumpBit(GNU_PROPERTY_X86_ISA_1_SSSE3, "SSSE3"); + DumpBit(GNU_PROPERTY_X86_ISA_1_SSE4_1, "SSE4_1"); + DumpBit(GNU_PROPERTY_X86_ISA_1_SSE4_2, "SSE4_2"); + DumpBit(GNU_PROPERTY_X86_ISA_1_AVX, "AVX"); + DumpBit(GNU_PROPERTY_X86_ISA_1_AVX2, "AVX2"); + DumpBit(GNU_PROPERTY_X86_ISA_1_FMA, "FMA"); + DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512F, "AVX512F"); + DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512CD, "AVX512CD"); + DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512ER, "AVX512ER"); + DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512PF, "AVX512PF"); + DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512VL, "AVX512VL"); + DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512DQ, "AVX512DQ"); + DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512BW, "AVX512BW"); + DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512_4FMAPS, "AVX512_4FMAPS"); + DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512_4VNNIW, "AVX512_4VNNIW"); + DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512_BITALG, "AVX512_BITALG"); + DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512_IFMA, "AVX512_IFMA"); + DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512_VBMI, "AVX512_VBMI"); + DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512_VBMI2, "AVX512_VBMI2"); + DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512_VNNI, "AVX512_VNNI"); + if (PrData) + OS << format("", PrData); + return OS.str(); + break; case GNU_PROPERTY_X86_FEATURE_2_NEEDED: case GNU_PROPERTY_X86_FEATURE_2_USED: OS << "x86 feature " @@ -3702,8 +3743,8 @@ OS << format("", DataSize); return OS.str(); } - pr_data = support::endian::read32(Data.data()); - if (pr_data == 0) { + PrData = support::endian::read32(Data.data()); + if (PrData == 0) { OS << ""; return OS.str(); } @@ -3717,8 +3758,8 @@ DumpBit(GNU_PROPERTY_X86_FEATURE_2_XSAVE, "XSAVE"); DumpBit(GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT, "XSAVEOPT"); DumpBit(GNU_PROPERTY_X86_FEATURE_2_XSAVEC, "XSAVEC"); - if (pr_data) - OS << format("", pr_data); + if (PrData) + OS << format("", PrData); return OS.str(); } }