[LLD/ELF] - Should we implement .note.gnu.property and/or Intel CET in LLD ?

Linux GABI [1] introduced new .note.gnu.property section which contains a program
property note which describes special handling requirements for linker and run-time loader.

LLD does not support .note.gnu.property yet.

GABI specifies 2 types of entries:

  • GNU_PROPERTY_STACK_SIZE: Its pr_data field contains an integer in the format
    of the target processor. Linker should select the maximum value among all input
    relocatable objects and copy this property to the output. Run-time loader should
    raise the stack limit to the value specified in this property.

  • GNU_PROPERTY_NO_COPY_ON_PROTECTED: This indicates that there should be no
    copy relocations against protected data symbols. If a relocatable object contains this
    property, linker should treat protected data symbol as defined locally at run-time and
    copy this property to the output share object. Linker should add this property to the
    output share object if any protected symbol is expected to be defined locally at run-time.
    Run-time loader should disallow copy relocations against protected data symbols defined
    in share objects with GNU_PROPERTY_NO_COPY_ON_PROTECTED property.
    Its PR_DATASZ should be 0.

I am not sure how much the second is useful because I think LLD now restricts
doing the copy relocations against protected symbols,
so probably we can ignore it ATM.

The first is a bit more interesting. We do not proccess this notes and our output

is broken now, we just merge all records and seems have the same issue as gold has:

At the same time as far I know, Linux kernel does not yet has support for
GNU_PROPERTY_STACK_SIZE, so it probably means there are no users at all for it in the wild.

On another side, we have an Intel CET [2], [3]:

"Control-flow Enforcement Technology (CET) provides the following capabilities to defend
against ROP/JOP style control-flow subversion attacks:

  • Shadow Stack - return address protection to defend against Return Oriented Programming,
  • Indirect branch tracking - free branch protection to defend against Jump/Call Oriented Programming.​"

Intel CET uses following processor-specific program property types in .note.gnu.property [3, p85, p87]:

  • GNU_PROPERTY_X86_FEATURE_1_IBT This indicates that all executable sections are compatible
    with IBT (see Section 13.1.1) when endbr64 instruction starts each valid target where an indirect
    branch instruction can land. 8

  • GNU_PROPERTY_X86_FEATURE_1_SHSTK This indicates that all executable sections are compatible
    with SHSTK (see Section 13.1.2) where return address popped from shadow stack always matches
    return address popped from normal stack.

It is not yet supported by gold: 22915 – Gold doesn't support Intel CET
But supported by bfd: H.J. Lu - Re: [PATCH 1/2] x86: Support Intel IBT with IBT property and IBT-enable

Support requires both compiler and linker changes.

Also [3, p151] says that to support IBT the linker should generate a IBT-enabled PLT
together with a second PLT. That is also what is implemented in bfd it seems:
H.J. Lu - Re: [PATCH 1/2] x86: Support Intel IBT with IBT property and IBT-enable.

GCC started to support it recently and already uses it for building
libobjc, libgfortran, libmpx, libstdc+±v3, libatomic, libbacktrace and other libs:

Technology is backwards compatible. I used GCC version 8.0.1 20180319
(experimental) for experiments.
For following code and invocations:


int xxx() { return 1; }

/usr/local/bin/gcc 1.cpp -c -o test1.o -fcf-protection=full -mcet -B.
/usr/local/bin/gcc 1.cpp -c -o test2.o -B.

Compiler will generate special instructions and emit .note.gnu.property section.
0000000000000000 <_Z3xxxv>:
0: f3 0f 1e fa endbr64
4: b8 01 00 00 00 mov $0x1,%eax

9: c3 retq

readelf output:
Displaying notes found in: .note.gnu.property
Owner Data size Description

Properties: x86 feature: IBT, SHSTK

test2.o (no CET):
0000000000000000 <_Z3xxxv>:
0: b8 01 00 00 00 mov $0x1,%eax
5: c3 retq

endbr64 is no-op (for CPUs that do not support CET), more details are in specs above.
An important part for the linker
is that it should support .note.gnu.property to properly handle and combine
x86 specific properties or reject them, since with dumb merging of sections we seems

produce broken output here again.

Given all above I suggest to:

  1. Implement .note.gnu.property and support GNU_PROPERTY_STACK_SIZE​ + GNU_PROPERTY_NO_COPY_ON_PROTECTED

  2. For start - error out on all other flags we do not explicitly support (like GNU_PROPERTY_X86_FEATURE_, GNU_PROPERTY_X86_ISA_ and others

on p86-p88 of [3]).

  1. Deside if we want to support Intel CET.

[1] - Linux GABI https://github.com/hjl-tools/linux-abi/wiki/linux-abi-draft.pdf


[3] - “System V Application Binary Interface” ch.13 (Pages · hjl-tools/x86-psABI Wiki · GitHub)

I think we should wait until there is someone wanting to use these features with lld.



I agree. Aiming 100% coverage of the Linux ABI spec is not actually our goal. If we found that that is needed or useful, we should do that, but I don’t think we should support that for the sake of increasing the ABI spec coverage. Let’s see if the new extension will get traction.

I think we should wait until there is someone wanting to use these features with lld.

I’d think we shouldn’t do anything even for printing out a warning unless doing it is proved to be useful.

Just in case, a little update for this thread:

There was a talk about “Protecting the code: Control Flow Enforcement Technology” during the recent

llvm-dev meeting (https://llvm.org/devmtg/2018-04/talks.html#Talk_17).

It was mentioned that some support is already implemented in LLVM. I did not have chance to look close on

it though. Whole feature requires linker side support, current status: bfd support this, gold - still does not.

I would love to see some comments from O. Simhon​ in this thread probably.