#2408 closed enhancement (fixed)
Linker set based initialization
Reported by: | Sebastian Huber | Owned by: | Sebastian Huber |
---|---|---|---|
Priority: | normal | Milestone: | 5.1 |
Component: | unspecified | Version: | 4.10 |
Severity: | normal | Keywords: | |
Cc: | Blocked By: | ||
Blocking: |
Description
Linker sets are used for example in Linux, FreeBSD (they are used in the RTEMS port of the FreeBSD network stack, e.g. libbsd), eCos and for global C++ constructors. They provide a space efficient and flexible means to initialize modules. A linker set consists of
- dedicated input sections for the linker (e.g.
.ctors
and.ctors.*
in the case of global constructors), - a begin marker (e.g. provided by
crtbegin.o
, and - an end marker (e.g. provided by
ctrend.o
).
A module may place a certain data item into the dedicated input section. The linker will collect all such data items in this section and creates a begin and end marker. The initialization code can then use the begin and end markers to find all the collected data items (e.g. function pointers).
Lets look how this works using a simple example. For this we need three files myset.h
,
#ifndef MYSET_H #define MYSET_H /* The linker set items */ typedef struct { void (*func)(void); } item; /* * Macro to create a linker set item. The first parameter is * the designator of the item. It must be unique within the * module scope. The second parameter is the desired function. */ #define MYSET_ITEM(i, f) \ __attribute__((used)) \ __attribute__((section(".rtemsroset.myset.content"))) \ static item i = { f } #endif /* MYSET_H */
module.c
#include "myset.h" #include <stdio.h> /* * Some global function that needs a module specific * intialization done by f(). */ void g(void) { printf("g()\n"); } /* The module constructor */ static void f(void) { printf("f()\n"); } /* * This registers the module constructor f() * in the linker set "myset". */ MYSET_ITEM(i, &f);
and init.c
.
#include "myset.h" #include <stddef.h> /* Should be in a proper header file */ void g(void); /* Define the start marker */ __attribute__((used)) __attribute__((section(".rtemsroset.myset.begin"))) static volatile const item begin[0]; /* Define the end marker */ __attribute__((used)) __attribute__((section(".rtemsroset.myset.end"))) static volatile const item end[0]; int main(void) { size_t n = &end[0] - &begin[0]; size_t i; /* Call all functions of the linker set */ for (i = 0; i < n; ++i) { (*begin[i].func)(); } /* * This will pull in the module.c and register its item in the * linker set "myset". So g() can rely on f() being called first. */ g(); return (0); }
In the linker command file of the GNU linker we need the following statement.
.rtemsroset : { KEEP (*(SORT(.rtemsroset.*)))
The KEEP()
ensures that a garbage collection by the linker will not discard the content of this section. This would be normally the case since the linker set items are not referenced directly. The SORT()
directive sorts the input sections lexicographically. Please note the lexicographical order of the .begin
, .content
and .end
section name parts in the previous example which ensures that the position of the begin and end markers are right. The interesting part of linker map file of the previous example may look like this.
.rtemsroset 0x0000000001001990 0x4 load address 0x000000000002268c *(SORT(.rtemsroset.*)) .rtemsroset.myset.begin 0x0000000001001990 0x0 init.o .rtemsroset.myset.content 0x0000000001001990 0x4 module.o .rtemsroset.myset.end 0x0000000001001994 0x0 init.o
So what is the benefit of using linker sets to initialize modules? Currently in RTEMS all available managers (semaphore, message queue, barrier, etc.) are initialized since the initialization code doesn't know what is actually used by the application. With the linker set approach we need to initialize only those managers that are used by the application. In case an application uses message queues, then it must call rtems_message_queue_create()
. In the module implementing this function we can place a linker set item and register the message queue handler constructor. Otherwise, in case the application doesn't use message queues, then there will be no reference to the rtems_message_queue_create()
function and the constructor is not registered, thus nothing of the message queue handler will be in the final executable.
Change History (58)
comment:1 Changed on 09/03/15 at 13:39:08 by Sebastian Huber
comment:2 Changed on 10/28/15 at 13:08:32 by Sebastian Huber
comment:3 Changed on 12/08/15 at 12:53:24 by Sebastian Huber <sebastian.huber@…>
comment:4 Changed on 12/09/15 at 07:00:51 by Sebastian Huber
The POSIX API is disabled in 4.9 and 4.10. In 4.11 and 4.12 sizes are
presented with POSIX enabled/disabled. The 4.12 without prefix is with the
linker set based initialization. In 4.12 the Newlib internal locks are
enabled.12. The PNOLS version is with POSIX enabled and the old initialization
infrastructure.
Executable sizes for the SPARC/SIS ticker.exe.
Text | Data | BSS | Workspace | Non-Text | |
---|---|---|---|---|---|
4.9 | 80384 | 2532 | 2996 | 51432 | 56960 |
4.10 | 124384 | 1828 | 2384 | 51056 | 55268 |
4.11 | 100592 | 1616 | 7008 | 44120 | 52744 |
4.11/POSIX | 104608 | 1760 | 8528 | 45200 | 55488 |
4.12/PNOLS | 105296 | 1872 | 8512 | 45376 | 55760 |
4.12/POSIX | 101680 | 1808 | 6592 | 45336 | 53736 |
4.12 | 101472 | 1808 | 6528 | 44336 | 52672 |
The huge increase in the test size from 4.9 to 4.10 is mostly due to the
introduction of the pipe() support which pulls in sprintf().
The increase of the BSS section from 4.10 to 4.11 is due to the static
initialization of the scheduler data structures (move from workspace to BSS).
Executable sizes for the SPARC/SIS minimum.exe.
Text | Data | BSS | Workspace | Non-Text | |
---|---|---|---|---|---|
4.9 | 45808 | 2324 | 2708 | 3288 | 8320 |
4.10 | 30032 | 1300 | 1296 | 3240 | 5836 |
4.11 | 34032 | 320 | 2976 | 2000 | 5296 |
4.11/POSIX | 41664 | 1168 | 4480 | 2216 | 7864 |
4.12/PNOLS | 39904 | 1232 | 4480 | 2136 | 7848 |
4.12/POSIX | 29104 | 272 | 2304 | 2128 | 4704 |
4.12 | 28976 | 272 | 2240 | 1928 | 4440 |
comment:5 Changed on 12/10/15 at 07:33:58 by Sebastian Huber <sebastian.huber@…>
comment:6 Changed on 12/11/15 at 07:57:40 by Sebastian Huber
comment:7 Changed on 01/26/16 at 17:04:55 by Sebastian Huber
Owner: | set to Sebastian Huber |
---|---|
Status: | new → assigned |
comment:8 Changed on 02/03/16 at 09:29:51 by Sebastian Huber <sebastian.huber@…>
comment:9 Changed on 02/03/16 at 09:30:01 by Sebastian Huber <sebastian.huber@…>
comment:10 Changed on 02/03/16 at 09:30:14 by Sebastian Huber <sebastian.huber@…>
comment:11 Changed on 02/03/16 at 09:30:24 by Sebastian Huber <sebastian.huber@…>
comment:12 Changed on 02/03/16 at 09:30:35 by Sebastian Huber <sebastian.huber@…>
comment:13 Changed on 02/03/16 at 09:30:46 by Sebastian Huber <sebastian.huber@…>
comment:14 Changed on 02/03/16 at 09:30:57 by Sebastian Huber <sebastian.huber@…>
comment:15 Changed on 02/03/16 at 09:31:07 by Sebastian Huber <sebastian.huber@…>
comment:16 Changed on 02/03/16 at 09:31:18 by Sebastian Huber <sebastian.huber@…>
comment:17 Changed on 02/03/16 at 09:31:28 by Sebastian Huber <sebastian.huber@…>
comment:18 Changed on 02/03/16 at 09:31:39 by Sebastian Huber <sebastian.huber@…>
comment:19 Changed on 02/03/16 at 09:31:50 by Sebastian Huber <sebastian.huber@…>
comment:20 Changed on 02/03/16 at 09:32:00 by Sebastian Huber <sebastian.huber@…>
comment:21 Changed on 02/03/16 at 09:32:11 by Sebastian Huber <sebastian.huber@…>
comment:22 Changed on 02/03/16 at 09:32:32 by Sebastian Huber <sebastian.huber@…>
comment:23 Changed on 02/03/16 at 09:32:42 by Sebastian Huber <sebastian.huber@…>
comment:24 Changed on 02/03/16 at 09:32:53 by Sebastian Huber <sebastian.huber@…>
comment:25 Changed on 02/03/16 at 09:33:04 by Sebastian Huber <sebastian.huber@…>
comment:26 Changed on 02/03/16 at 09:33:14 by Sebastian Huber <sebastian.huber@…>
comment:27 Changed on 02/03/16 at 09:33:25 by Sebastian Huber <sebastian.huber@…>
comment:28 Changed on 02/03/16 at 09:33:36 by Sebastian Huber <sebastian.huber@…>
comment:29 Changed on 02/03/16 at 09:33:46 by Sebastian Huber <sebastian.huber@…>
comment:30 Changed on 02/03/16 at 09:33:57 by Sebastian Huber <sebastian.huber@…>
comment:31 Changed on 02/03/16 at 09:34:07 by Sebastian Huber <sebastian.huber@…>
comment:32 Changed on 02/03/16 at 09:34:18 by Sebastian Huber <sebastian.huber@…>
comment:33 Changed on 02/03/16 at 09:34:29 by Sebastian Huber <sebastian.huber@…>
comment:34 Changed on 02/03/16 at 09:34:39 by Sebastian Huber <sebastian.huber@…>
comment:35 Changed on 02/03/16 at 09:35:01 by Sebastian Huber <sebastian.huber@…>
comment:36 Changed on 02/03/16 at 09:35:22 by Sebastian Huber <sebastian.huber@…>
comment:37 Changed on 02/03/16 at 09:35:33 by Sebastian Huber <sebastian.huber@…>
comment:38 Changed on 02/03/16 at 09:35:44 by Sebastian Huber <sebastian.huber@…>
comment:39 Changed on 02/03/16 at 09:35:55 by Sebastian Huber <sebastian.huber@…>
comment:40 Changed on 02/03/16 at 09:36:06 by Sebastian Huber <sebastian.huber@…>
comment:41 Changed on 02/03/16 at 09:38:47 by Sebastian Huber
Implementation is complete. Documentation is missing.
comment:42 Changed on 02/04/16 at 11:59:09 by Sebastian Huber
Status: | assigned → accepted |
---|
comment:43 Changed on 03/01/16 at 14:01:44 by Sebastian Huber <sebastian.huber@…>
comment:44 Changed on 03/11/16 at 00:13:28 by Joel Sherrill
Just checking. Is this ready to close or do you have additional plans?
comment:46 Changed on 10/12/16 at 09:13:53 by Sebastian Huber <sebastian.huber@…>
comment:48 Changed on 11/15/16 at 06:05:10 by Sebastian Huber
No, documentation is still incomplete. I am not satisfied with the GCC 7 support.
comment:49 Changed on 12/06/16 at 11:03:23 by Sebastian Huber <sebastian.huber@…>
comment:51 Changed on 12/12/16 at 07:09:08 by Sebastian Huber
Resolution: | → fixed |
---|---|
Status: | accepted → closed |
Documentation complete.
comment:52 Changed on 05/11/17 at 07:31:02 by Sebastian Huber
Milestone: | 4.12 → 4.12.0 |
---|
comment:53 Changed on 11/09/17 at 06:27:14 by Sebastian Huber
Milestone: | 4.12.0 → 5.1 |
---|
Milestone renamed
comment:54 Changed on 04/20/18 at 13:25:21 by Sebastian Huber <sebastian.huber@…>
In 6d21a3f2/rtems:
comment:55 Changed on 04/20/18 at 13:25:54 by Sebastian Huber <sebastian.huber@…>
In c4ccf26c/rtems:
See also [Developer/Projects/Open/SequencedInitialization].