[08/12] Rewrite abi-note.S in C.

Message ID 20200430174329.GD29015@arm.com
State New
Headers show
Series
  • aarch64: branch protection support
Related show

Commit Message

Szabolcs Nagy April 30, 2020, 5:43 p.m.

Comments

Zack Weinberg April 30, 2020, 8:07 p.m. | #1
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
Szabolcs Nagy May 1, 2020, 9:23 a.m. | #2
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.
Zack Weinberg May 1, 2020, 2:07 p.m. | #3
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

Patch

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