Index: lld/trunk/ELF/InputFiles.cpp =================================================================== --- lld/trunk/ELF/InputFiles.cpp +++ lld/trunk/ELF/InputFiles.cpp @@ -772,6 +772,7 @@ using Elf_Nhdr = typename ELFT::Nhdr; using Elf_Note = typename ELFT::Note; + uint32_t FeaturesSet = 0; while (!Data.empty()) { // Read one NOTE record. if (Data.size() < sizeof(Elf_Nhdr)) @@ -797,8 +798,10 @@ uint32_t Size = read32le(Desc.data() + 4); if (Type == GNU_PROPERTY_X86_FEATURE_1_AND) { - // We found the field. - return read32le(Desc.data() + 8); + // We found a FEATURE_1_AND field. There may be more than one of these + // in a .note.gnu.propery section, for a relocatable object we + // accumulate the bits set. + FeaturesSet |= read32le(Desc.data() + 8); } // On 64-bit, a payload may be followed by a 4-byte padding to make its @@ -809,12 +812,11 @@ Desc = Desc.slice(Size + 8); // +8 for Type and Size } - // Go to next NOTE record if a note section didn't contain - // X86_FEATURES_1_AND description. + // Go to next NOTE record to look for more FEATURE_1_AND descriptions. Data = Data.slice(Nhdr->getSize()); } - return 0; + return FeaturesSet; } template Index: lld/trunk/test/ELF/i386-cet.s =================================================================== --- lld/trunk/test/ELF/i386-cet.s +++ lld/trunk/test/ELF/i386-cet.s @@ -31,14 +31,13 @@ .section ".note.gnu.property", "a" .long 4 -.long 0x10 +.long 0xc .long 0x5 .asciz "GNU" .long 0xc0000002 .long 4 .long 3 -.long 0 .text .globl func1 Index: lld/trunk/test/ELF/x86-property-relocatable.s =================================================================== --- lld/trunk/test/ELF/x86-property-relocatable.s +++ lld/trunk/test/ELF/x86-property-relocatable.s @@ -0,0 +1,36 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: ld.lld -r %t.o -o %t2.o +# RUN: llvm-readelf -n %t2.o | FileCheck -match-full-lines %s + +## Test that .note.gnu.property is passed through -r, and that we can handle +## more than one FEATURE_AND in the same object file. This is logically the +## same as if the features were combined in a single FEATURE_AND as the rule +## states that the bit in the output pr_data field if it is set in all +.text +ret + +.section ".note.gnu.property", "a" +.p2align 3 +.long 4 +.long 0x10 +.long 0x5 +.asciz "GNU" + +.long 0xc0000002 // GNU_PROPERTY_X86_FEATURE_1_AND +.long 4 +.long 1 // GNU_PROPERTY_X86_FEATURE_1_IBT +.long 0 + +.long 4 +.long 0x10 +.long 0x5 +.asciz "GNU" +.long 0xc0000002 // GNU_PROPERTY_X86_FEATURE_1_AND +.long 4 +.long 2 // GNU_PROPERTY_X86_FEATURE_1_SHSTK +.long 0 + +# CHECK: Owner Data size Description +# CHECK-NEXT: GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0 (property note) +# CHECK-NEXT: Properties: x86 feature: IBT, SHSTK