[PATCH] Add support for ELF notes

Sebastian Huber sebastian.huber at embedded-brains.de
Thu Mar 23 14:47:28 UTC 2023


This is a prototype patch for adding ELF notes.

ELF notes can be used to attach domain-specific data to ELF files.  This could
be used to store for example the RTEMS version, Git commit, configuration
options, expected test state, etc. in the executable ELF file.

Example:

readelf -n build/arm/xilinx_zynq_a9_qemu/testsuites/samples/ticker.exe

Displaying notes found in: .note.rtems
  Owner                Data size        Description
  RTEMS                0x00000004       Unknown note type: (0x00010000)
   description data: 06 00 00 00
  RTEMS                0x00000004       Unknown note type: (0x00010001)
   description data: 00 00 00 00
  RTEMS                0x00000004       Unknown note type: (0x00010002)
   description data: 00 00 00 00
  RTEMS                0x00000029       Unknown note type: (0x00010003)
   description data: 37 39 34 38 31 66 39 61 37 61 31 32 35 62 64 31 66 64 65 31 66 38 32 39 61 65 64 39 33 62 31 38 36 36 39 38 66 62 38 32 00
  RTEMS                0x00000008       Unknown note type: (0x00010004)
   description data: 44 45 46 41 55 4c 54 00
  RTEMS                0x00000004       Unknown note type: (0x00010005)
   description data: 01 00 00 00
  RTEMS                0x00000004       Unknown note type: (0x00010006)
   description data: 00 00 00 00
  RTEMS                0x00000004       Unknown note type: (0x00010007)
   description data: 00 00 00 00
  RTEMS                0x00000004       Unknown note type: (0x00010008)
   description data: 00 00 00 00
  RTEMS                0x00000004       Unknown note type: (0x00010009)
   description data: 00 00 00 00
  RTEMS                0x00000004       Unknown note type: (0x0001000a)
   description data: 00 00 00 00
  RTEMS                0x0000000b       Unknown note type: (0x0001000b)
   description data: 43 4c 4f 43 4b 20 54 49 43 4b 00
  RTEMS                0x00000004       Unknown note type: (0x0001000c)
   description data: 00 00 00 00

Update #4888.
---
 bsps/arm/shared/start/linkcmds.base  |   1 +
 bsps/arm/shared/start/start.S        |   2 +
 bsps/include/bsp/startelfnotes.h     |  98 +++++++++++++++++++
 cpukit/include/rtems/score/elfnote.h | 139 +++++++++++++++++++++++++++
 cpukit/include/rtems/test-info.h     |  11 +++
 testsuites/samples/ticker/init.c     |   2 +-
 6 files changed, 252 insertions(+), 1 deletion(-)
 create mode 100644 bsps/include/bsp/startelfnotes.h
 create mode 100644 cpukit/include/rtems/score/elfnote.h

diff --git a/bsps/arm/shared/start/linkcmds.base b/bsps/arm/shared/start/linkcmds.base
index 8c4d87dfdc..2c0fb87df0 100644
--- a/bsps/arm/shared/start/linkcmds.base
+++ b/bsps/arm/shared/start/linkcmds.base
@@ -436,6 +436,7 @@ SECTIONS {
 	.debug_sup      0 : { *(.debug_sup) }
 	.ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) }
 	.note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
+	.note.rtems 0 : { KEEP (*(.note.rtems)) }
 	/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
 
 	/*
diff --git a/bsps/arm/shared/start/start.S b/bsps/arm/shared/start/start.S
index bc8753df93..dd17197ee0 100644
--- a/bsps/arm/shared/start/start.S
+++ b/bsps/arm/shared/start/start.S
@@ -596,3 +596,5 @@ bsp_start_hook_0_done:
 
 	.set	bsp_start_vector_table_size, bsp_start_vector_table_end - bsp_start_vector_table_begin
 	.set	bsp_vector_table_size, bsp_start_vector_table_size
+
+#include <bsp/startelfnotes.h>
diff --git a/bsps/include/bsp/startelfnotes.h b/bsps/include/bsp/startelfnotes.h
new file mode 100644
index 0000000000..ad38edb03c
--- /dev/null
+++ b/bsps/include/bsp/startelfnotes.h
@@ -0,0 +1,98 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSBSPsSharedStartup
+ *
+ * @brief This header file provides ELF notes for the start file.
+ */
+
+/*
+ * Copyright (C) 2023 embedded brains GmbH
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _BSP_STARTELFNOTES_H
+#define _BSP_STARTELFNOTES_H
+
+#include <rtems/score/elfnote.h>
+
+#include <bspopts.h>
+#include <version-vc-key.h>
+
+#ifndef ASM
+#error "This header file shall be included by assembly files only."
+#endif
+
+ELF_NOTE_ASM_RTEMS( ELF_NOTE_RTEMS_MAJOR, .long __RTEMS_MAJOR__ )
+
+ELF_NOTE_ASM_RTEMS( ELF_NOTE_RTEMS_MINOR, .long __RTEMS_MINOR__ )
+
+ELF_NOTE_ASM_RTEMS( ELF_NOTE_RTEMS_REVISION, .long __RTEMS_REVISION__ )
+
+#ifdef RTEMS_VERSION_VC_KEY
+ELF_NOTE_ASM_RTEMS( ELF_NOTE_RTEMS_VERSION_VC_KEY, .asciz RTEMS_VERSION_VC_KEY )
+#else
+ELF_NOTE_ASM_RTEMS( ELF_NOTE_RTEMS_VERSION_VC_KEY, .asciz "" )
+#endif
+
+ELF_NOTE_ASM_RTEMS( ELF_NOTE_RTEMS_BUILD_LABEL, .asciz RTEMS_BUILD_LABEL )
+
+#ifdef RTEMS_DEBUG
+ELF_NOTE_ASM_RTEMS( ELF_NOTE_RTEMS_DEBUG, .long 1 )
+#else
+ELF_NOTE_ASM_RTEMS( ELF_NOTE_RTEMS_DEBUG, .long 0 )
+#endif
+
+#ifdef RTEMS_MULTIPROCESSING
+ELF_NOTE_ASM_RTEMS( ELF_NOTE_RTEMS_MULTIPROCESSING, .long 1 )
+#else
+ELF_NOTE_ASM_RTEMS( ELF_NOTE_RTEMS_MULTIPROCESSING, .long 0 )
+#endif
+
+#ifdef RTEMS_PARAVIRT
+ELF_NOTE_ASM_RTEMS( ELF_NOTE_RTEMS_PARAVIRT, .long 1 )
+#else
+ELF_NOTE_ASM_RTEMS( ELF_NOTE_RTEMS_PARAVIRT, .long 0 )
+#endif
+
+#ifdef RTEMS_POSIX_API
+ELF_NOTE_ASM_RTEMS( ELF_NOTE_RTEMS_POSIX_API, .long 1 )
+#else
+ELF_NOTE_ASM_RTEMS( ELF_NOTE_RTEMS_POSIX_API, .long 0 )
+#endif
+
+#ifdef RTEMS_PROFILING
+ELF_NOTE_ASM_RTEMS( ELF_NOTE_RTEMS_PROFILING, .long 1 )
+#else
+ELF_NOTE_ASM_RTEMS( ELF_NOTE_RTEMS_PROFILING, .long 0 )
+#endif
+
+#ifdef RTEMS_SMP
+ELF_NOTE_ASM_RTEMS( ELF_NOTE_RTEMS_SMP, .long 1 )
+#else
+ELF_NOTE_ASM_RTEMS( ELF_NOTE_RTEMS_SMP, .long 0 )
+#endif
+
+#endif /* _BSP_STARTELFNOTES_H */
diff --git a/cpukit/include/rtems/score/elfnote.h b/cpukit/include/rtems/score/elfnote.h
new file mode 100644
index 0000000000..af97b6ee50
--- /dev/null
+++ b/cpukit/include/rtems/score/elfnote.h
@@ -0,0 +1,139 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSScoreELFNote
+ *
+ * @brief This header file provides the interfaces of the
+ *   @ref RTEMSScoreELFNote.
+ */
+
+/*
+ * Copyright (C) 2023 embedded brains GmbH
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTEMS_SCORE_ELFNOTE_H
+#define _RTEMS_SCORE_ELFNOTE_H
+
+#include <rtems/score/basedefs.h>
+
+#ifndef ASM
+#include <elf.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup RTEMSScoreELFNote ELF Note Handler
+ *
+ * @ingroup RTEMSScore
+ *
+ * @brief This group contains the ELF Note Handler implementation.
+ *
+ * @{
+ */
+
+/**
+ * @brief Defines an ELF note.
+ *
+ * @param _elf_size is the ELF size of the executable, either 32 or 64.
+ *
+ * @param _section is the note section name.
+ *
+ * @param _name is the name.  It shall be a NUL-terminated string.
+ *
+ * @param _unique is a unique number for each use of the macro in a translation
+ *   unit.
+ *
+ * @param _type is the type of the note.  It shall be an ELF word integer.
+ *
+ * @param _desc is the description of the note.
+ *
+ */
+#define ELF_NOTE_DEFINE( _elf_size, _section, _name, _unique, _type, _desc ) \
+  static const struct { \
+    Elf##_elf_size##_Nhdr Note_header; \
+    RTEMS_ALIGNED( sizeof( Elf##_elf_size##_Word ) ) \
+      unsigned char Name[sizeof( _name )]; \
+    RTEMS_ALIGNED( sizeof( Elf##_elf_size##_Word ) ) \
+      __typeof__( _desc ) Description; \
+  } \
+  RTEMS_CONCAT( _note_, _unique ) \
+  RTEMS_USED \
+  RTEMS_UNUSED \
+  RTEMS_SECTION( ".note." _section ) \
+  RTEMS_ALIGNED( sizeof( Elf##_elf_size##_Word ) ) = \
+  { { sizeof( _name ),  sizeof( _desc ),  _type  }, _name, _desc }
+
+#define ELF_NOTE_ASM_DEFINE( _section, _name, _type, _desc ) \
+  .pushsection RTEMS_STRING( .note.##_section ), "a", %note ; \
+  .balign 4 ; \
+  .long 2f - 1f ; \
+  .long 4f - 3f ; \
+  .long _type ; \
+  1: .asciz _name ; \
+  2: .balign 4 ; \
+  3: _desc ; \
+  4: .balign 4 ; \
+  .popsection
+
+#define ELF_NOTE_RTEMS_TYPE( _index ) ( ( _index ) + 0x10000 )
+
+#if CPU_SIZEOF_POINTER == 8
+#define ELF_NOTE_RTEMS( _type, _desc ) \
+  ELF_NOTE_DEFINE( 64, "rtems", "RTEMS", _type, \
+    ELF_NOTE_RTEMS_TYPE( _type ), _desc )
+#else
+#define ELF_NOTE_RTEMS( _type, _desc ) \
+  ELF_NOTE_DEFINE( 32, "rtems", "RTEMS", _type, \
+    ELF_NOTE_RTEMS_TYPE( _type ), _desc )
+#endif
+
+#define ELF_NOTE_ASM_RTEMS( _type, _desc ) \
+  ELF_NOTE_ASM_DEFINE(rtems, "RTEMS", ELF_NOTE_RTEMS_TYPE( _type ), _desc )
+
+#define ELF_NOTE_RTEMS_MAJOR 0
+#define ELF_NOTE_RTEMS_MINOR 1
+#define ELF_NOTE_RTEMS_REVISION 2
+#define ELF_NOTE_RTEMS_VERSION_VC_KEY 3
+#define ELF_NOTE_RTEMS_BUILD_LABEL 4
+#define ELF_NOTE_RTEMS_DEBUG 5
+#define ELF_NOTE_RTEMS_MULTIPROCESSING 6
+#define ELF_NOTE_RTEMS_PARAVIRT 7
+#define ELF_NOTE_RTEMS_POSIX_API 8
+#define ELF_NOTE_RTEMS_PROFILING 9
+#define ELF_NOTE_RTEMS_SMP 10
+#define ELF_NOTE_RTEMS_TEST_NAME 11
+#define ELF_NOTE_RTEMS_TEST_STATE 12
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_SCORE_ELFNOTE_H */
diff --git a/cpukit/include/rtems/test-info.h b/cpukit/include/rtems/test-info.h
index 3b839533c2..aa67dc04d9 100644
--- a/cpukit/include/rtems/test-info.h
+++ b/cpukit/include/rtems/test-info.h
@@ -31,6 +31,7 @@
 #include <rtems.h>
 #include <rtems/printer.h>
 #include <rtems/score/atomic.h>
+#include <rtems/score/elfnote.h>
 #include <rtems/score/smpbarrier.h>
 
 #ifdef __cplusplus
@@ -95,16 +96,26 @@ typedef enum
 
 #if TEST_STATE_EXPECTED_FAIL
   #define TEST_STATE RTEMS_TEST_STATE_FAIL
+  #define TEST_STATE_NOTE 1
 #elif TEST_STATE_USER_INPUT
   #define TEST_STATE RTEMS_TEST_STATE_USER_INPUT
+  #define TEST_STATE_NOTE 2
 #elif TEST_STATE_INDETERMINATE
   #define TEST_STATE RTEMS_TEST_STATE_INDETERMINATE
+  #define TEST_STATE_NOTE 3
 #elif TEST_STATE_BENCHMARK
   #define TEST_STATE RTEMS_TEST_STATE_BENCHMARK
+  #define TEST_STATE_NOTE 4
 #else
   #define TEST_STATE RTEMS_TEST_STATE_PASS
+  #define TEST_STATE_NOTE 0
 #endif
 
+#define RTEMS_TEST_IDENT( name ) \
+  ELF_NOTE_RTEMS( ELF_NOTE_RTEMS_TEST_NAME, name ); \
+  ELF_NOTE_RTEMS( ELF_NOTE_RTEMS_TEST_STATE, TEST_STATE_NOTE ); \
+  const char rtems_test_name[] = name
+
 /**
  * @brief Prints a begin of test message using printf().
  *
diff --git a/testsuites/samples/ticker/init.c b/testsuites/samples/ticker/init.c
index 86f87ad736..370f308dc4 100644
--- a/testsuites/samples/ticker/init.c
+++ b/testsuites/samples/ticker/init.c
@@ -33,7 +33,7 @@
 #define CONFIGURE_INIT
 #include "system.h"
 
-const char rtems_test_name[] = "CLOCK TICK";
+RTEMS_TEST_IDENT( "CLOCK TICK" );
 
 /*
  *  Keep the names and IDs in global variables so another task can use them.
-- 
2.35.3



More information about the devel mailing list