Message ID | 20200430174329.GD29015@arm.com |
---|---|
State | New |
Headers | show |
Series | aarch64: branch protection support | expand |
On Thu, Apr 30, 2020 at 1:43 PM Szabolcs Nagy <szabolcs.nagy@arm.com> wrote: > > Using C code with __asm() allows the compiler to add target > specific object file markings based on CFLAGS. > This is e.g. needed for building glibc with branch-protection > on AArch64. Hmm. If we're going to do this, should we maybe go further and use actual C? This snippet produces a matching .note.ABI-tag section for me: #include <stdint.h> #include <config.h> #include <endian.h> #include <abi-tag.h> const int32_t __attribute__((section(".note.ABI-tag"))) __abi_tag[] = { 4, /* name length: 4 */ 16, /* data length: 4 32-bit numbers */ 1, #if BYTE_ORDER == BIG_ENDIAN 0x474E5500, /* "GNU\0" */ #else 0x00554E47, /* same, little-endian */ #endif __ABI_TAG_OS, __ABI_TAG_VERSION }; I don't see a problem with hardwiring a name length of 4, and code elsewhere appears to assume that the payload will always be 4 32-bit integers, so maybe it's OK to hardwire the 16 too. If it's not OK, perhaps we could figure out a way to count the commas in __ABI_TAG_VERSION in the preprocessor and do a little math. The other potential problem I can think of is that there's a symbol pointing into the .note.ABI-tag section now; I don't know if that might break anything. zw
The 04/30/2020 16:07, Zack Weinberg wrote: > On Thu, Apr 30, 2020 at 1:43 PM Szabolcs Nagy <szabolcs.nagy@arm.com> wrote: > > > > Using C code with __asm() allows the compiler to add target > > specific object file markings based on CFLAGS. > > This is e.g. needed for building glibc with branch-protection > > on AArch64. > > Hmm. If we're going to do this, should we maybe go further and use > actual C? This snippet produces a matching .note.ABI-tag section for > me: yes this makes sense. > #include <stdint.h> > #include <config.h> > #include <endian.h> > #include <abi-tag.h> > const int32_t > __attribute__((section(".note.ABI-tag"))) > __abi_tag[] = { > 4, /* name length: 4 */ > 16, /* data length: 4 32-bit numbers */ > 1, > #if BYTE_ORDER == BIG_ENDIAN > 0x474E5500, /* "GNU\0" */ > #else > 0x00554E47, /* same, little-endian */ > #endif > __ABI_TAG_OS, > __ABI_TAG_VERSION > }; > > I don't see a problem with hardwiring a name length of 4, and code > elsewhere appears to assume that the payload will always be 4 32-bit > integers, so maybe it's OK to hardwire the 16 too. If it's not OK, > perhaps we could figure out a way to count the commas in > __ABI_TAG_VERSION in the preprocessor and do a little math. > > The other potential problem I can think of is that there's a symbol > pointing into the .note.ABI-tag section now; I don't know if that > might break anything. what about /* Note: Custom type is used as ElfW(Nhdr) is wrong on 64 bit targets. */ __attribute__((used, aligned(4), section(".note.ABI-tag"))) static const struct { int32_t namesz; int32_t descsz; int32_t type; char name[4]; int32_t desc[4]; } __abi_tag = { 4, /* name length: 4 */ 16, /* data length: 4 32-bit numbers */ 1, "GNU", { __ABI_TAG_OS, __ABI_TAG_VERSION } }; this fixes the alignment, makes the symbol local, does not need endian.h and uses identifiers according to the gabi specification.
On Fri, May 1, 2020 at 5:24 AM Szabolcs Nagy <szabolcs.nagy@arm.com> wrote: > what about > > /* Note: Custom type is used as ElfW(Nhdr) is wrong on 64 bit targets. */ > > __attribute__((used, aligned(4), section(".note.ABI-tag"))) > static const struct > { > int32_t namesz; > int32_t descsz; > int32_t type; > char name[4]; > int32_t desc[4]; > } __abi_tag = { > 4, /* name length: 4 */ > 16, /* data length: 4 32-bit numbers */ > 1, > "GNU", > { __ABI_TAG_OS, __ABI_TAG_VERSION } > }; > > this fixes the alignment, makes the symbol local, does not need > endian.h and uses identifiers according to the gabi specification. Looks good to me. Fixing the array length means the compiler should complain if __ABI_TAG_VERSION ever expands to the wrong number of initializers. zw
From 0647d5658df82f89d8bf73dec65ef4aa6a4b77a9 Mon Sep 17 00:00:00 2001 From: Szabolcs Nagy <szabolcs.nagy@arm.com> Date: Wed, 1 Apr 2020 16:02:03 +0100 Subject: [PATCH 08/12] Rewrite abi-note.S in C. Using C code with __asm() allows the compiler to add target specific object file markings based on CFLAGS. This is e.g. needed for building glibc with branch-protection on AArch64. --- csu/{abi-note.S => abi-note.c} | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) rename csu/{abi-note.S => abi-note.c} (85%) diff --git a/csu/abi-note.S b/csu/abi-note.c similarity index 85% rename from csu/abi-note.S rename to csu/abi-note.c index 2b4b5f8824..5d86b452d9 100644 --- a/csu/abi-note.S +++ b/csu/abi-note.c @@ -56,17 +56,21 @@ offset length contents #include <config.h> #include <abi-tag.h> /* OS-specific ABI tag value */ +#define STRINGIFY(...) STRINGIFY_1 (__VA_ARGS__) +#define STRINGIFY_1(...) #__VA_ARGS__ + /* The linker (GNU ld 2.8 and later) recognizes an allocated section whose name begins with `.note' and creates a PT_NOTE program header entry pointing at it. */ - .section ".note.ABI-tag", "a" - .p2align 2 - .long 1f - 0f /* name length */ - .long 3f - 2f /* data length */ - .long 1 /* note type */ -0: .asciz "GNU" /* vendor name */ -1: .p2align 2 -2: .long __ABI_TAG_OS /* note data: the ABI tag */ - .long __ABI_TAG_VERSION -3: .p2align 2 /* pad out section */ +__asm ( + " .section \".note.ABI-tag\", \"a\"\n" + " .p2align 2\n" + " .long 1f - 0f\n" /* name length */ + " .long 3f - 2f\n" /* data length */ + " .long 1\n" /* note type */ + "0: .asciz \"GNU\"\n" /* vendor name */ + "1: .p2align 2\n" + "2: .long " STRINGIFY (__ABI_TAG_OS) "\n" /* note data: the ABI tag */ + " .long " STRINGIFY (__ABI_TAG_VERSION) "\n" + "3: .p2align 2"); /* pad out section */ -- 2.17.1