Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

core: introduce crossfile arrays (xfa) v3 #15002

Merged
merged 27 commits into from
Feb 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
66092f5
core: Introduce cross file arrays (XFA)
kaspar030 May 4, 2018
97e1be0
tests: Add xfa test
May 6, 2018
6adeec0
atmega_common: add arch specific XFA ldscript to properly place .roxfa
May 9, 2018
12a2243
unittests: Add XFA tests
May 14, 2018
abca94b
tests/xfa: Add static check of XFA linking
May 14, 2018
a23b29d
pic32_common: Add CPU specific xfa.ld variant
May 14, 2018
3099e02
xfa: add a test script
cladmi Jun 4, 2018
d8d34e0
cpu/cortexm_common: add XFA handling to linkerscript
kaspar030 Sep 10, 2020
bdd59ae
core: disable -Warray-bounds for XFA users
kaspar030 Sep 10, 2020
2474fa7
cpu/esp32: add XFA support
kaspar030 Sep 10, 2020
91b987a
cpu/esp8266: add ld/ to linker search path, use it
kaspar030 Sep 10, 2020
06ec602
cpu/esp8266: add XFA support
kaspar030 Sep 10, 2020
f411fd4
cpu/msp430_common: add XFA support
kaspar030 Nov 3, 2020
ac549ab
xfa: remove common -Txfa.ld include
kaspar030 Nov 3, 2020
ee9d6c8
cpu/native: add XFA support
kaspar030 Nov 3, 2020
858b5ca
xfa: remove obsolete empty xfa.ld
kaspar030 Nov 3, 2020
b3b04fa
cpu/fe310: add XFA support
kaspar030 Nov 3, 2020
61d9f34
cpu/lpc23xx: add XFA support
kaspar030 Nov 3, 2020
b54afa1
xfa: remove duplicate "const" from _XFA_CONST
kaspar030 Nov 3, 2020
6711388
cpu/mips_pic32_common: fix XFA support
kaspar030 Nov 3, 2020
50dc68b
core/xfa: make const XFA's volatile
kaspar030 Dec 1, 2020
e827f0b
core/xfa: add comments explaining the pragmas
kaspar030 Dec 1, 2020
2bc7bb4
core/xfa: make externc happy
kaspar030 Dec 2, 2020
249ed5f
core/include/xfa.h: uncrustify
kaspar030 Dec 2, 2020
d310044
core/xfa: fix doxygen issues
kaspar030 Dec 8, 2020
df4dc36
core/xfa: add "experimental" note
kaspar030 Jan 5, 2021
439b2d5
core: uncrustify xfa.h
kaspar030 Feb 18, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Makefile.include
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,10 @@ TOOLCHAINS_SUPPORTED ?= gnu
# Import all toolchain settings
include $(RIOTMAKE)/toolchain/$(TOOLCHAIN).inc.mk

# Append ldscript path after importing CPU and board makefiles to allow
# overriding the core ldscripts
LINKFLAGS += -L$(RIOTBASE)/core/ldscripts

# Tell ccache to pass the original file to the compiler, instead of passing the
# preprocessed code. Without this setting, the compilation will fail with
# -Wimplicit-fallthrough warnings even when the fall through case is properly
Expand Down
3 changes: 3 additions & 0 deletions boards/native/Makefile.include
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ else
LINKFLAGS += -ldl
endif

# XFA (cross file array) support
LINKFLAGS += -T$(RIOTBASE)/cpu/native/ldscripts/xfa.ld

# clean up unused functions
CFLAGS += -ffunction-sections -fdata-sections
ifeq ($(OS),Darwin)
Expand Down
186 changes: 186 additions & 0 deletions core/include/xfa.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
/*
* Copyright (C) 2016 Kaspar Schleiser <kaspar@schleiser.de>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/

/**
* @ingroup core_util
* @brief Cross File Arrays
* @{
*
* This macro, in combination with an entry in the linker scripts, allows the
* definition of constant arrays to be spread over multiple C compilation
* units. These arrays are called "cross-file arrays" or short xfa.
*
* @experimental This API is considered experimental and will probably change
* without notice!
*
* @file
* @author Kaspar Schleiser <kaspar@schleiser.de>
*/

#ifndef XFA_H
#define XFA_H

/*
* Unfortunately, current gcc trips over accessing XFA's because of their
* zero-size start/end array that are used of symbol markers, with an "array
* index out of bounds" warning. So until a solution for that is found, we
* need to disable array bounds checks for files using XFAs.
*/
#ifndef DOXYGEN
_Pragma("GCC diagnostic ignored \"-Warray-bounds\"")
kaspar030 marked this conversation as resolved.
Show resolved Hide resolved
#endif

/**
* @brief helper macro for other XFA_* macros
*
* @internal
*/
#define _XFA(name, prio) __attribute__((used, section(".xfa." #name "." #prio)))

/**
* @brief helper macro for other XFA_* macros
*
* @internal
*/
#define _XFA_CONST(name, \
prio) __attribute__((used, \
section(".roxfa." #name "." #prio)))

/**
* @brief Define a read-only cross-file array
*
* This macro defines the symbols necessary to use XFA_START() and XFA_END().
* It needs to be part of one single compilation unit.
*
* The pragmas prevent these errors:
*
* error: ISO C forbids empty initializer braces
* error: ISO C forbids zero-size array ‘xfatest_const_end’
*
* @param[in] type name of the cross-file array
* @param[in] name name of the cross-file array
*/
#define XFA_INIT_CONST(type, name) \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wpedantic\"") \
fjmolinas marked this conversation as resolved.
Show resolved Hide resolved
_XFA_CONST(name, 0_) const volatile type name [0] = {}; \
_XFA_CONST(name, 9_) const volatile type name ## _end [0] = {}; \
_Pragma("GCC diagnostic pop") \
extern const unsigned __xfa_dummy

/**
* @brief Define a writable cross-file array
*
* This macro defines the symbols necessary to use XFA_START() and XFA_END().
* It needs to be part of one single compilation unit.
*
* The pragmas prevent these errors:
*
* error: ISO C forbids empty initializer braces
* error: ISO C forbids zero-size array ‘xfatest_end’
*
* @param[in] type name of the cross-file array
* @param[in] name name of the cross-file array
*/
#define XFA_INIT(type, name) \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wpedantic\"") \
_XFA(name, 0_) type name [0] = {}; \
_XFA(name, 9_) type name ## _end [0] = {}; \
_Pragma("GCC diagnostic pop") \
extern const unsigned __xfa_dummy

/**
* @brief Declare an external read-only cross-file array
*
* This macro defines the symbols necessary to use XFA_START() and XFA_END().
* Think of this as XFA_INIT() but with "extern" keyword.
* It is supposed to be used in compilation units where the cross file array is
* being accessed, but not defined using XFA_INIT.
*
* @param[in] type name of the cross-file array
* @param[in] name name of the cross-file array
*/
#define XFA_USE_CONST(type, name) \
extern const type name []; \
extern const type name ## _end []

/**
* @brief Declare an external writable cross-file array
*
* This macro defines the symbols necessary to use XFA_START() and XFA_END().
* Think of this as XFA_INIT() but with "extern" keyword.
* It is supposed to be used in compilation units where the cross file array is
* being accessed, but not defined using XFA_INIT.
*
* @param[in] type name of the cross-file array
* @param[in] name name of the cross-file array
*/
#define XFA_USE(type, name) \
extern type name []; \
extern type name ## _end []

/**
* @brief Define variable in writable cross-file array
*
* Variables will end up sorted by prio.
*
* Add this to the type in a variable definition, e.g.:
*
* XFA(driver_params, 0) driver_params_t _onboard = { .pin=42 };
*
* @param[in] xfa_name name of the xfa
* @param[in] prio priority within the xfa
*/
#define XFA(xfa_name, prio) _XFA(xfa_name, 5_ ## prio)

/**
* @brief Define variable in read-only cross-file array
*
* Variables will end up sorted by prio.
*
* Add this to the type in a variable definition, e.g.:
*
* XFA(driver_params, 0) driver_params_t _onboard = { .pin=42 };
*
* @param[in] xfa_name name of the xfa
* @param[in] prio priority within the xfa
*/
#define XFA_CONST(xfa_name, prio) _XFA_CONST(xfa_name, 5_ ## prio)

/**
* @brief Add a pointer to cross-file array
*
* Pointers will end up sorted by prio.
*
* @param[in] xfa_name name of the xfa
* @param[in] prio priority within the xfa
* @param[in] name symbol name
* @param[in] entry pointer variable to add to xfa
*/
#define XFA_ADD_PTR(xfa_name, prio, name, entry) \
fjmolinas marked this conversation as resolved.
Show resolved Hide resolved
_XFA_CONST(xfa_name, 5_ ## prio) \
const typeof(entry) xfa_name ## _ ## prio ## _ ## name = entry

/**
* @brief Calculate number of entries in cross-file array
*/
#define XFA_LEN(type, \
name) (((const char *)name ## _end - (const char *)name) / \
sizeof(type))

#ifdef __cplusplus
extern "C" {
#endif
/* making externc happy */
#ifdef __cplusplus
}
#endif

#endif /* XFA_H */
/** @} */
16 changes: 16 additions & 0 deletions cpu/atmega_common/ldscripts/xfa.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
SECTIONS
{
.data :
{
/* Special case for AVR (Harvard architecture) where .rodata is merged
* into .data by the toolchain default ldscripts. */
KEEP (*(SORT(.roxfa.*)))
KEEP (*(SORT(.xfa.*)))
}
__data_start = ADDR(.data);
__data_load_start = LOADADDR(.data);
__data_end = (__data_start + SIZEOF(.data));
__data_load_end = (__data_load_start + SIZEOF(.data));
}

INSERT AFTER .text;
2 changes: 2 additions & 0 deletions cpu/cortexm_common/ldscripts/cortexm_base.ld
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ SECTIONS
*(.text .text.* .gnu.linkonce.t.*)
*(.glue_7t) *(.glue_7)
*(.rodata .rodata* .gnu.linkonce.r.*)
KEEP (*(SORT(.roxfa.*)))
*(.ARM.extab* .gnu.linkonce.armextab.*)

/* Support C constructors, and C destructors in both user code
Expand Down Expand Up @@ -167,6 +168,7 @@ SECTIONS
_srelocate = .;
*(.ramfunc .ramfunc.*);
*(.data .data.*);
KEEP (*(SORT(.xfa.*)))
KEEP (*(.openocd .openocd.*))
. = ALIGN(4);
_erelocate = .;
Expand Down
2 changes: 2 additions & 0 deletions cpu/esp32/ld/esp32.common.ld
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ SECTIONS
_data_start = ABSOLUTE(.);
*(.data)
*(.data.*)
KEEP (*(SORT(.xfa.*)))
*(.gnu.linkonce.d.*)
*(.data1)
*(.sdata)
Expand Down Expand Up @@ -243,6 +244,7 @@ SECTIONS
_rodata_start = ABSOLUTE(.);
*(.rodata)
*(.rodata.*)
KEEP (*(SORT(.roxfa.*)))
*(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */
*(.gnu.linkonce.r.*)
*(.rodata1)
Expand Down
7 changes: 4 additions & 3 deletions cpu/esp8266/Makefile.include
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,10 @@ endif

ARCHIVES += -lgcc -lwpa -lcore -lnet80211 -lphy -lpp -lstdc++

LINKFLAGS += -T$(RIOTCPU)/$(CPU)/ld/esp8266.rom.ld
LINKFLAGS += -T$(RIOTCPU)/$(CPU)/ld/esp8266.riot-os.ld
LINKFLAGS += -T$(RIOTCPU)/$(CPU)/ld/esp8266.peripherals.ld
LINKFLAGS += -L$(RIOTCPU)/$(CPU)/ld
LINKFLAGS += -Tesp8266.rom.ld
LINKFLAGS += -Tesp8266.riot-os.ld
LINKFLAGS += -Tesp8266.peripherals.ld

LINKFLAGS += -Wl,-wrap=pp_attach
LINKFLAGS += -Wl,-wrap=pm_attach
2 changes: 2 additions & 0 deletions cpu/esp8266/ld/esp8266.riot-os.ld
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ SECTIONS
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
*(.jcr)
KEEP (*(SORT(.xfa.*)))
_data_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr

Expand Down Expand Up @@ -139,6 +140,7 @@ SECTIONS
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
KEEP (*(SORT(.roxfa.*)))
/* C++ exception handlers table: */
__XT_EXCEPTION_DESCS__ = ABSOLUTE(.);
*(.xt_except_desc)
Expand Down
2 changes: 2 additions & 0 deletions cpu/lpc23xx/ldscripts/lpc23xx.ld
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ SECTIONS
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*crtend.o(.dtors))
KEEP (*(SORT(.roxfa.*)))

. = ALIGN(4);
_efixed = .; /* End of text section */
Expand Down Expand Up @@ -163,6 +164,7 @@ SECTIONS
*(.ramfunc .ramfunc.*);
*(.data .data.*);
KEEP (*(.openocd .openocd.*))
KEEP (*(SORT(.xfa.*)))
. = ALIGN(4);
_erelocate = .;
} > ram AT> rom
Expand Down
3 changes: 1 addition & 2 deletions cpu/mips_pic32_common/Makefile.include
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ include $(RIOTCPU)/mips32r2_common/Makefile.include
CFLAGS += -D_SYS__PTHREADTYPES_H_

CFLAGS += -DCPU_FAM_$(call uppercase_and_underscore,$(CPU_FAM))

LINKFLAGS += -L$(RIOTCPU)/mips_pic32_common/ldscripts
INCLUDES += -I$(RIOTCPU)/mips_pic32_common/include

DIRS += $(RIOTCPU)/$(CPU)/$(CPU_MODEL)
21 changes: 21 additions & 0 deletions cpu/mips_pic32_common/ldscripts/xfa.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
SECTIONS
{
.data :
{
KEEP (*(SORT(.xfa.*)))
}
_fdata = ADDR(.data);
_edata = (_fdata + SIZEOF(.data));
}

INSERT BEFORE .sbss;

SECTIONS
{
.rodata :
{
KEEP (*(SORT(.roxfa.*)))
}
}

INSERT AFTER .dtors;
24 changes: 24 additions & 0 deletions cpu/msp430_common/ldscripts/xfa.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
SECTIONS
{
.rodata :
{
KEEP (*(SORT(.roxfa.*)))
} > ROM
}

INSERT AFTER .rodata;

SECTIONS
{
.data :
{
KEEP (*(SORT(.xfa.*)))
} > RAM AT> ROM

. = ALIGN(2);
_edata = .;
PROVIDE (edata = .);
PROVIDE (__dataend = .);
}

INSERT AFTER .data;
19 changes: 19 additions & 0 deletions cpu/native/ldscripts/xfa.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
SECTIONS
{
.data :
{
KEEP (*(SORT(.xfa.*)))
}
}

INSERT AFTER .text;

SECTIONS
{
.rodata :
{
KEEP (*(SORT(.roxfa.*)))
}
}

INSERT AFTER .text;
2 changes: 2 additions & 0 deletions cpu/riscv_common/ldscripts/riscv_base.ld
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ SECTIONS
*(.rdata)
*(.rodata .rodata.*)
*(.gnu.linkonce.r.*)
KEEP (*(SORT(.roxfa.*)))
} >flash AT>flash :flash

. = ALIGN(4);
Expand Down Expand Up @@ -182,6 +183,7 @@ SECTIONS
*(.srodata.cst4)
*(.srodata.cst2)
*(.srodata .srodata.*)
KEEP (*(SORT(.xfa.*)))
} >ram AT>flash :ram_init

. = ALIGN(4);
Expand Down
Loading