Index: llvm/trunk/include/llvm/BinaryFormat/ELF.h =================================================================== --- llvm/trunk/include/llvm/BinaryFormat/ELF.h +++ llvm/trunk/include/llvm/BinaryFormat/ELF.h @@ -1351,13 +1351,26 @@ enum : unsigned { GNU_PROPERTY_STACK_SIZE = 1, GNU_PROPERTY_NO_COPY_ON_PROTECTED = 2, - GNU_PROPERTY_X86_FEATURE_1_AND = 0xc0000002 + GNU_PROPERTY_X86_FEATURE_1_AND = 0xc0000002, + GNU_PROPERTY_X86_FEATURE_2_NEEDED = 0xc0008001, + GNU_PROPERTY_X86_FEATURE_2_USED = 0xc0010001, }; -// CET properties -enum { +// x86 processor feature bits. +enum : unsigned { GNU_PROPERTY_X86_FEATURE_1_IBT = 1 << 0, - GNU_PROPERTY_X86_FEATURE_1_SHSTK = 1 << 1 + GNU_PROPERTY_X86_FEATURE_1_SHSTK = 1 << 1, + + GNU_PROPERTY_X86_FEATURE_2_X86 = 1 << 0, + GNU_PROPERTY_X86_FEATURE_2_X87 = 1 << 1, + GNU_PROPERTY_X86_FEATURE_2_MMX = 1 << 2, + GNU_PROPERTY_X86_FEATURE_2_XMM = 1 << 3, + GNU_PROPERTY_X86_FEATURE_2_YMM = 1 << 4, + GNU_PROPERTY_X86_FEATURE_2_ZMM = 1 << 5, + GNU_PROPERTY_X86_FEATURE_2_FXSR = 1 << 6, + GNU_PROPERTY_X86_FEATURE_2_XSAVE = 1 << 7, + GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT = 1 << 8, + GNU_PROPERTY_X86_FEATURE_2_XSAVEC = 1 << 9, }; // AMD specific notes. (Code Object V2) Index: llvm/trunk/test/tools/llvm-readobj/note-gnu-property.s =================================================================== --- llvm/trunk/test/tools/llvm-readobj/note-gnu-property.s +++ llvm/trunk/test/tools/llvm-readobj/note-gnu-property.s @@ -3,44 +3,48 @@ // 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 0x000000b8: +// GNU: Displaying notes found at file offset 0x00000040 with length 0x000000d8: // GNU-NEXT: Owner Data size Description -// GNU-NEXT: GNU 0x000000a8 NT_GNU_PROPERTY_TYPE_0 (property note) +// GNU-NEXT: GNU 0x000000c8 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 features: SHSTK -// GNU-NEXT: X86 features: IBT, SHSTK -// GNU-NEXT: X86 features: none +// GNU-NEXT: x86 feature: SHSTK +// GNU-NEXT: x86 feature: IBT, SHSTK +// GNU-NEXT: x86 feature: +// GNU-NEXT: x86 feature needed: x86, x87 +// GNU-NEXT: x86 feature used: XSAVEOPT, XSAVEC // GNU-NEXT: // GNU-NEXT: stack size: // GNU-NEXT: stack size: // GNU-NEXT: no copy on protected -// GNU-NEXT: X86 features: -// GNU-NEXT: X86 features: IBT, +// GNU-NEXT: x86 feature: +// GNU-NEXT: x86 feature: IBT, // GNU-NEXT: // LLVM: Notes [ // LLVM-NEXT: NoteSection { // LLVM-NEXT: Offset: 0x40 -// LLVM-NEXT: Size: 0xB8 +// LLVM-NEXT: Size: 0xD8 // LLVM-NEXT: Note { // LLVM-NEXT: Owner: GNU -// LLVM-NEXT: Data size: 0xA8 +// LLVM-NEXT: Data size: 0xC8 // LLVM-NEXT: Type: NT_GNU_PROPERTY_TYPE_0 (property note) // LLVM-NEXT: Property [ // LLVM-NEXT: stack size: 0x100 // LLVM-NEXT: stack size: 0x100 // LLVM-NEXT: no copy on protected -// LLVM-NEXT: X86 features: SHSTK -// LLVM-NEXT: X86 features: IBT, SHSTK -// LLVM-NEXT: X86 features: none +// LLVM-NEXT: x86 feature: SHSTK +// LLVM-NEXT: x86 feature: IBT, SHSTK +// LLVM-NEXT: x86 feature: +// LLVM-NEXT: x86 feature needed: x86, x87 +// LLVM-NEXT: x86 feature used: XSAVEOPT, XSAVEC // LLVM-NEXT: // LLVM-NEXT: stack size: // LLVM-NEXT: stack size: // LLVM-NEXT: no copy on protected -// LLVM-NEXT: X86 features: -// LLVM-NEXT: X86 features: IBT, +// LLVM-NEXT: x86 feature: +// LLVM-NEXT: x86 feature: IBT, // LLVM-NEXT: // LLVM-NEXT: ] // LLVM-NEXT: } @@ -86,6 +90,16 @@ .long 4 /* Data size */ .long 0 /* Empty flags, not an error */ .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 */ + .p2align 3 /* Align to 8 byte for 64 bit */ + + .long 0xc0010001 /* Type: GNU_PROPERTY_X86_FEATURE_2_USED */ + .long 4 /* Data size */ + .long 0x00000300 /* XSAVEOPT XSAVEC */ + .p2align 3 /* Align to 8 byte for 64 bit */ /* All notes below are broken. Test we are able to report them. */ @@ -121,7 +135,7 @@ .long 4 /* Data size */ .long 0xf000f001 /* GNU_PROPERTY_X86_FEATURE_1_IBT and bad bits */ .p2align 3 /* Align to 8 byte for 64 bit */ - + /* GNU_PROPERTY_NO_COPY_ON_PROTECTED with pr_datasz and without data */ .long 2 /* Type: GNU_PROPERTY_NO_COPY_ON_PROTECTED */ .long 1 /* Data size (corrupted) */ Index: llvm/trunk/tools/llvm-readobj/ELFDumper.cpp =================================================================== --- llvm/trunk/tools/llvm-readobj/ELFDumper.cpp +++ llvm/trunk/tools/llvm-readobj/ELFDumper.cpp @@ -3650,6 +3650,16 @@ ArrayRef Data) { std::string str; raw_string_ostream OS(str); + uint32_t pr_data; + auto DumpBit = [&](uint32_t Flag, StringRef Name) { + if (pr_data & Flag) { + pr_data &= ~Flag; + OS << Name; + if (pr_data) + OS << ", "; + } + }; + switch (Type) { default: OS << format("", Type); @@ -3669,31 +3679,46 @@ OS << format(" ", DataSize); return OS.str(); case GNU_PROPERTY_X86_FEATURE_1_AND: - OS << "X86 features: "; + OS << "x86 feature: "; if (DataSize != 4) { OS << format("", DataSize); return OS.str(); } - uint32_t CFProtection = - support::endian::read32(Data.data()); - if (CFProtection == 0) { - OS << "none"; + pr_data = support::endian::read32(Data.data()); + if (pr_data == 0) { + OS << ""; return OS.str(); } - if (CFProtection & GNU_PROPERTY_X86_FEATURE_1_IBT) { - OS << "IBT"; - CFProtection &= ~GNU_PROPERTY_X86_FEATURE_1_IBT; - if (CFProtection) - OS << ", "; + DumpBit(GNU_PROPERTY_X86_FEATURE_1_IBT, "IBT"); + DumpBit(GNU_PROPERTY_X86_FEATURE_1_SHSTK, "SHSTK"); + if (pr_data) + OS << format("", pr_data); + return OS.str(); + case GNU_PROPERTY_X86_FEATURE_2_NEEDED: + case GNU_PROPERTY_X86_FEATURE_2_USED: + OS << "x86 feature " + << (Type == GNU_PROPERTY_X86_FEATURE_2_NEEDED ? "needed: " : "used: "); + if (DataSize != 4) { + OS << format("", DataSize); + return OS.str(); } - if (CFProtection & GNU_PROPERTY_X86_FEATURE_1_SHSTK) { - OS << "SHSTK"; - CFProtection &= ~GNU_PROPERTY_X86_FEATURE_1_SHSTK; - if (CFProtection) - OS << ", "; + pr_data = support::endian::read32(Data.data()); + if (pr_data == 0) { + OS << ""; + return OS.str(); } - if (CFProtection) - OS << format("", CFProtection); + DumpBit(GNU_PROPERTY_X86_FEATURE_2_X86, "x86"); + DumpBit(GNU_PROPERTY_X86_FEATURE_2_X87, "x87"); + DumpBit(GNU_PROPERTY_X86_FEATURE_2_MMX, "MMX"); + DumpBit(GNU_PROPERTY_X86_FEATURE_2_XMM, "XMM"); + DumpBit(GNU_PROPERTY_X86_FEATURE_2_YMM, "YMM"); + DumpBit(GNU_PROPERTY_X86_FEATURE_2_ZMM, "ZMM"); + DumpBit(GNU_PROPERTY_X86_FEATURE_2_FXSR, "FXSR"); + 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); return OS.str(); } }