1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-06-06 05:21:22 +03:00

Move all PSTRs to own section, allow string dedup (#6565)

* Move all PSTRs to own section, allow string dedup

GNU ld can deduplicate strings, and does so for most normal char *s
automatically.  However, for PSTRs we were using a unique section per
string *and* the section was not flagges as containing dedupable
0-terminated strings.

Modify the PSTR macro to emit assembly, which lets us set the section
flags required (SM) for the variables, and use inline assembly to get
the asm-block defined address.

Should result in smaller compiled binaries if any strings are
duplicated.

* Give each PSTR its own segment

* Allow disposing of unused strings before merging

Add the "a" section flag to allow the linker to throw away unneeded
strings.  Without this flag, the linker will not discard unreferenced
strings and ROMs will increase in size, possibly dramatically.
This commit is contained in:
Earle F. Philhower, III 2019-09-30 16:27:10 -07:00 committed by david gauchard
parent d4757542e4
commit 97c926ea91
2 changed files with 10 additions and 1 deletions

View File

@ -181,6 +181,9 @@ SECTIONS
*libwps.a:(.literal.* .text.*)
*(.irom0.literal .irom.literal .irom.text.literal .irom0.text .irom0.text.* .irom.text .irom.text.*)
/* Constant strings in flash (PSTRs) */
*(.irom0.pstr.*)
/* __FUNCTION__ locals */
*(.rodata._ZZ*__FUNCTION__)
*(.rodata._ZZ*__PRETTY_FUNCTION__)

View File

@ -23,6 +23,7 @@ extern "C" {
// Ref: https://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Variable-Attributes.html
// Place each progmem object into its own named section, avoiding conflicts
#define PROGMEM __attribute__((section( "\".irom.text." __FILE__ "." __STRINGIZE(__LINE__) "." __STRINGIZE(__COUNTER__) "\"")))
#define PROGMEM_PSTR "\".irom0.pstr." __FILE__ "." __STRINGIZE(__LINE__) "." __STRINGIZE(__COUNTER__) "\""
#endif
#ifndef PGM_P
#define PGM_P const char *
@ -34,7 +35,12 @@ extern "C" {
// PSTR() macro modified to start on a 32-bit boundary. This adds on average
// 1.5 bytes/string, but in return memcpy_P and strcpy_P will work 4~8x faster
#ifndef PSTR
#define PSTR(s) (__extension__({static const char __c[] __attribute__((__aligned__(4))) PROGMEM = (s); &__c[0];}))
// Adapted from AVR-specific code at https://forum.arduino.cc/index.php?topic=194603.0
#define PSTR(str) (__extension__({ \
PGM_P ptr; \
asm volatile ( ".pushsection " PROGMEM_PSTR ", \"aSM\", @progbits, 1 \n .align 4 \n 0: .string " __STRINGIZE(str) "\n .popsection \n" ); \
asm volatile ( "movi %0, 0b" : "=r" (ptr) ); \
ptr; }))
#endif
// Flash memory must be read using 32 bit aligned addresses else a processor