arduino / Arduino

Arduino IDE 1.x
https://www.arduino.cc/en/software
Other
14.12k stars 7k forks source link

Compiler optimization fails to generate code for code with section attribute. #5346

Closed gitmeister closed 8 years ago

gitmeister commented 8 years ago

Removing -Os compiler option allows code to be generated.

See https://github.com/Optiboot/optiboot/issues/187

facchinm commented 8 years ago

Hi @gitmeister , can you post a sketch showing the described behaviour? Variables accessed only in IRQs should be declared volatile and maybe __attribute__((used)) to avoid being stripped. Could you also activate verbose compilation with All warnings and paste it here? Thanks!

gitmeister commented 8 years ago

The code isn't running in an ISR, it's just placed in ".init0" so that it's the first thing running after the bootloader (which in this case is Optiboot 6.2). The code is "test_reset.ino" from the Optiboot project. If compiled as-is using Arduino IDE 1.6.11 the function resetFlagsInit() will not be linked into ".init0" so the reset cause will never be available in register R2 (as provided by the bootloader). You will always see a Reset Value of 0x0. Removing the (currently commented) dummy line (which never executes because the reset flags will never be 0xEE) forces the code to be linked and now you'll get Reset Value of 0x8 which is correct (WDT Reset). You get the same effect if you remove -Os (Optimization).

/*
 * test_reset
 * May 2015 by Bill Westfield (WestfW)
 * Released to the public domain.
 *
 * This sketch demonstrates retrival of the Reset Cause register (MCUSR) of the AVR.
 * Normally, MCUSR itself is destroyed by the use of a bootloader, but Optiboot v4.6
 * and later save the contents in register r2, where it can be accessed by an
 * application.
 */
#include <avr/wdt.h>

/*
 * First, we need a variable to hold the reset cause that can be written before
 * early sketch initialization (that might change r2), and won't be reset by the
 * various initialization code.
 * avr-gcc provides for this via the ".noinit" section.
 */
uint8_t resetFlags __attribute__ ((section(".noinit")));

/*
 * Next, we need to put some code to save reset cause from the bootload (in r2)
 * to the variable.  Again, avr-gcc provides special code sections for this.
 */
void resetFlagsInit(void) __attribute__ ((naked)) __attribute__ ((section (".init0")));
void resetFlagsInit(void) {
  /*
   * save the reset flags passed from the bootloader
   * This is a "simple" matter of storing (STS) r2 in the special variable
   * that we have created.  We use assembler to access the right variable.
   */
  __asm__ __volatile__ ("sts %0, r2\n" : "=m" (resetFlags) :);
}

void setup() {
  Serial.begin(9600);  // Initialize serial port

  Serial.println("Reset flag test");

  Serial.print("Have reset flag value 0x");
  Serial.print(resetFlags, HEX);

  // REMOVE TO ALLOW COMPILATION
  //if (resetFlags==0xEE) resetFlagsInit();

  /*
   * check for the usual bits.  Note that the symnbols defined in wdt.h are
   * bit numbers, so they have to be shifted before comparison.
   */
  if (resetFlags & (1<<WDRF))
  {
    Serial.print(" Watchdog");
    resetFlags &= ~(1<<WDRF);
  }
  if (resetFlags & (1<<BORF))
  {
    Serial.print(" Brownout");
    resetFlags &= ~(1<<BORF);
  }
  if (resetFlags & (1<<EXTRF))
  {
    Serial.print(" External");
    resetFlags &= ~(1<<EXTRF);
  }
  if (resetFlags & (1<<PORF))
  {
    Serial.print(" PowerOn");
    resetFlags &= ~(1<<PORF);
  }
  if (resetFlags != 0x00)
  {
    // It should never enter here
    Serial.print(" Unknown");
  }
  Serial.println("");
}

void loop() {
  Serial.println("Send something to reset through watchdog peripheral");
  while (Serial.read() < 0) ;
  wdt_enable(WDTO_15MS);
  while (1); // To prevent the loop to start again before WDT resets the board
}

Here's the compilation output:

C:\Program Files\Arduino\arduino-builder -dump-prefs -logger=machine -hardware C:\Program Files\Arduino\hardware -hardware C:\Documents and Settings\Marc\Local Settings\Application Data\Arduino15\packages -hardware C:\Documents and Settings\Marc\My Documents\Arduino\hardware -tools C:\Program Files\Arduino\tools-builder -tools C:\Program Files\Arduino\hardware\tools\avr -tools C:\Documents and Settings\Marc\Local Settings\Application Data\Arduino15\packages -built-in-libraries C:\Program Files\Arduino\libraries -libraries C:\Documents and Settings\Marc\My Documents\Arduino\libraries -fqbn=FioOptiboot:avr:FioOptiboot -ide-version=10611 -build-path C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp -warnings=all -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avrdude.path=C:\Documents and Settings\Marc\Local Settings\Application Data\Arduino15\packages\arduino\tools\avrdude\6.0.1-arduino5 -prefs=runtime.tools.avr-gcc.path=C:\Program Files\Arduino\hardware\tools\avr -verbose C:\Documents and Settings\Marc\My Documents\Arduino\FIO-WDT\FIO-WDT.ino C:\Program Files\Arduino\arduino-builder -compile -logger=machine -hardware C:\Program Files\Arduino\hardware -hardware C:\Documents and Settings\Marc\Local Settings\Application Data\Arduino15\packages -hardware C:\Documents and Settings\Marc\My Documents\Arduino\hardware -tools C:\Program Files\Arduino\tools-builder -tools C:\Program Files\Arduino\hardware\tools\avr -tools C:\Documents and Settings\Marc\Local Settings\Application Data\Arduino15\packages -built-in-libraries C:\Program Files\Arduino\libraries -libraries C:\Documents and Settings\Marc\My Documents\Arduino\libraries -fqbn=FioOptiboot:avr:FioOptiboot -ide-version=10611 -build-path C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp -warnings=all -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avrdude.path=C:\Documents and Settings\Marc\Local Settings\Application Data\Arduino15\packages\arduino\tools\avrdude\6.0.1-arduino5 -prefs=runtime.tools.avr-gcc.path=C:\Program Files\Arduino\hardware\tools\avr -verbose C:\Documents and Settings\Marc\My Documents\Arduino\FIO-WDT\FIO-WDT.ino Using board 'FioOptiboot' from platform in folder: C:\Documents and Settings\Marc\My Documents\Arduino\hardware\FioOptiboot\avr Using core 'arduino' from platform in folder: C:\Program Files\Arduino\hardware\arduino\avr Detecting libraries used... "C:\Program Files\Arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=8000000L -DARDUINO=10611 -DARDUINO_AVR_FIO -DARDUINO_ARCH_AVR "-IC:\Program Files\Arduino\hardware\arduino\avr\cores\arduino" "-IC:\Program Files\Arduino\hardware\arduino\avr\variants\eightanaloginputs" "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\sketch\FIO-WDT.ino.cpp" -o "nul" "C:\Program Files\Arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=8000000L -DARDUINO=10611 -DARDUINO_AVR_FIO -DARDUINO_ARCH_AVR "-IC:\Program Files\Arduino\hardware\arduino\avr\cores\arduino" "-IC:\Program Files\Arduino\hardware\arduino\avr\variants\eightanaloginputs" "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\sketch\FIO-WDT.ino.cpp" -o "nul" Generating function prototypes... "C:\Program Files\Arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=8000000L -DARDUINO=10611 -DARDUINO_AVR_FIO -DARDUINO_ARCH_AVR "-IC:\Program Files\Arduino\hardware\arduino\avr\cores\arduino" "-IC:\Program Files\Arduino\hardware\arduino\avr\variants\eightanaloginputs" "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\sketch\FIO-WDT.ino.cpp" -o "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\preproc\ctags_target_for_gcc_minus_e.cpp" "C:\Program Files\Arduino\tools-builder\ctags\5.8-arduino10/ctags" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\preproc\ctags_target_for_gcc_minus_e.cpp" Compiling sketch... "C:\Program Files\Arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -flto -mmcu=atmega328p -DF_CPU=8000000L -DARDUINO=10611 -DARDUINO_AVR_FIO -DARDUINO_ARCH_AVR "-IC:\Program Files\Arduino\hardware\arduino\avr\cores\arduino" "-IC:\Program Files\Arduino\hardware\arduino\avr\variants\eightanaloginputs" "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\sketch\FIO-WDT.ino.cpp" -o "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\sketch\FIO-WDT.ino.cpp.o" Compiling libraries... Compiling core... "C:\Program Files\Arduino\hardware\tools\avr/bin/avr-gcc" -c -g -x assembler-with-cpp -flto -mmcu=atmega328p -DF_CPU=8000000L -DARDUINO=10611 -DARDUINO_AVR_FIO -DARDUINO_ARCH_AVR "-IC:\Program Files\Arduino\hardware\arduino\avr\cores\arduino" "-IC:\Program Files\Arduino\hardware\arduino\avr\variants\eightanaloginputs" "C:\Program Files\Arduino\hardware\arduino\avr\cores\arduino\wiring_pulse.S" -o "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\wiring_pulse.S.o" Using previously compiled file: C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\WInterrupts.c.o Using previously compiled file: C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\hooks.c.o Using previously compiled file: C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\wiring.c.o Using previously compiled file: C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\wiring_analog.c.o Using previously compiled file: C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\wiring_digital.c.o Using previously compiled file: C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\wiring_pulse.c.o Using previously compiled file: C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\wiring_shift.c.o Using previously compiled file: C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\CDC.cpp.o Using previously compiled file: C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\HardwareSerial.cpp.o Using previously compiled file: C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\HardwareSerial0.cpp.o Using previously compiled file: C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\HardwareSerial1.cpp.o Using previously compiled file: C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\HardwareSerial2.cpp.o Using previously compiled file: C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\HardwareSerial3.cpp.o Using previously compiled file: C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\IPAddress.cpp.o Using previously compiled file: C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\PluggableUSB.cpp.o Using previously compiled file: C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\Print.cpp.o Using previously compiled file: C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\Stream.cpp.o Using previously compiled file: C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\Tone.cpp.o Using previously compiled file: C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\USBCore.cpp.o Using previously compiled file: C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\WMath.cpp.o Using previously compiled file: C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\WString.cpp.o Using previously compiled file: C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\abi.cpp.o Using previously compiled file: C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\main.cpp.o Using previously compiled file: C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\new.cpp.o "C:\Program Files\Arduino\hardware\tools\avr/bin/avr-gcc-ar" rcs "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\core.a" "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\wiring_pulse.S.o" "C:\Program Files\Arduino\hardware\tools\avr/bin/avr-gcc-ar" rcs "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\core.a" "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\WInterrupts.c.o" "C:\Program Files\Arduino\hardware\tools\avr/bin/avr-gcc-ar" rcs "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\core.a" "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\hooks.c.o" "C:\Program Files\Arduino\hardware\tools\avr/bin/avr-gcc-ar" rcs "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\core.a" "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\wiring.c.o" "C:\Program Files\Arduino\hardware\tools\avr/bin/avr-gcc-ar" rcs "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\core.a" "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\wiring_analog.c.o" "C:\Program Files\Arduino\hardware\tools\avr/bin/avr-gcc-ar" rcs "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\core.a" "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\wiring_digital.c.o" "C:\Program Files\Arduino\hardware\tools\avr/bin/avr-gcc-ar" rcs "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\core.a" "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\wiring_pulse.c.o" "C:\Program Files\Arduino\hardware\tools\avr/bin/avr-gcc-ar" rcs "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\core.a" "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\wiring_shift.c.o" "C:\Program Files\Arduino\hardware\tools\avr/bin/avr-gcc-ar" rcs "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\core.a" "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\CDC.cpp.o" "C:\Program Files\Arduino\hardware\tools\avr/bin/avr-gcc-ar" rcs "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\core.a" "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\HardwareSerial.cpp.o" "C:\Program Files\Arduino\hardware\tools\avr/bin/avr-gcc-ar" rcs "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\core.a" "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\HardwareSerial0.cpp.o" "C:\Program Files\Arduino\hardware\tools\avr/bin/avr-gcc-ar" rcs "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\core.a" "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\HardwareSerial1.cpp.o" "C:\Program Files\Arduino\hardware\tools\avr/bin/avr-gcc-ar" rcs "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\core.a" "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\HardwareSerial2.cpp.o" "C:\Program Files\Arduino\hardware\tools\avr/bin/avr-gcc-ar" rcs "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\core.a" "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\HardwareSerial3.cpp.o" "C:\Program Files\Arduino\hardware\tools\avr/bin/avr-gcc-ar" rcs "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\core.a" "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\IPAddress.cpp.o" "C:\Program Files\Arduino\hardware\tools\avr/bin/avr-gcc-ar" rcs "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\core.a" "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\PluggableUSB.cpp.o" "C:\Program Files\Arduino\hardware\tools\avr/bin/avr-gcc-ar" rcs "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\core.a" "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\Print.cpp.o" "C:\Program Files\Arduino\hardware\tools\avr/bin/avr-gcc-ar" rcs "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\core.a" "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\Stream.cpp.o" "C:\Program Files\Arduino\hardware\tools\avr/bin/avr-gcc-ar" rcs "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\core.a" "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\Tone.cpp.o" "C:\Program Files\Arduino\hardware\tools\avr/bin/avr-gcc-ar" rcs "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\core.a" "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\USBCore.cpp.o" "C:\Program Files\Arduino\hardware\tools\avr/bin/avr-gcc-ar" rcs "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\core.a" "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\WMath.cpp.o" "C:\Program Files\Arduino\hardware\tools\avr/bin/avr-gcc-ar" rcs "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\core.a" "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\WString.cpp.o" "C:\Program Files\Arduino\hardware\tools\avr/bin/avr-gcc-ar" rcs "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\core.a" "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\abi.cpp.o" "C:\Program Files\Arduino\hardware\tools\avr/bin/avr-gcc-ar" rcs "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\core.a" "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\main.cpp.o" "C:\Program Files\Arduino\hardware\tools\avr/bin/avr-gcc-ar" rcs "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\core.a" "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\core\new.cpp.o" Linking everything together... "C:\Program Files\Arduino\hardware\tools\avr/bin/avr-gcc" -Wall -Wextra -Os -flto -fuse-linker-plugin -Wl,--gc-sections -mmcu=atmega328p -o "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp/FIO-WDT.ino.elf" "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp\sketch\FIO-WDT.ino.cpp.o" "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp/core\core.a" "-LC:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp" -lm "C:\Program Files\Arduino\hardware\tools\avr/bin/avr-objcopy" -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp/FIO-WDT.ino.elf" "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp/FIO-WDT.ino.eep" "C:\Program Files\Arduino\hardware\tools\avr/bin/avr-objcopy" -O ihex -R .eeprom "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp/FIO-WDT.ino.elf" "C:\DOCUME~1\Marc\LOCALS~1\Temp\build29fe7f9f7333c3f1b45cf7bf627b121d.tmp/FIO-WDT.ino.hex"

Sketch uses 1,876 bytes (5%) of program storage space. Maximum is 32,256 bytes. Global variables use 327 bytes (15%) of dynamic memory, leaving 1,721 bytes for local variables. Maximum is 2,048 bytes.

facchinm commented 8 years ago

Got it. Adding __attribute__ ((used)) to the function signature does the trick indeed (I only checked with readelf, please check functionality). I don't know if we can classify it as a bug or a "feature", but I'd expect (as you did) that a function declaring itself in a .init section should not be pruned. Maybe escalating this to mainline is the right way to proceed. In the meantime, please test the "workaround", thanks!

matthijskooijman commented 8 years ago

If this is indeed a bug, it's a bug in gcc. However, I suspect the main cause here is one of ordering and separated responsibility. I suspect the LTO optimizer / code generater does not see any reason why this function should be present in the binary. It does not really care about these section attributes, since that just decides where a function is stored. Even the linker does not really care about these functions, it just places them in the binary based on its section. I think the linker doesn't really know that these "init" functions are automatically called, that's something that the avr-libc initialization routines and linker scripts arrange for.

The reason this was not an issue before, I suspect, is that without LTO, there is no pruning of unused functions. The linker does do pruning of unused sections, and Arduino compiles with options to put each function into its own section, which effectively results in pruning of unused functions. However, the .init sections are referenced by the avr-libc initialization code, so these are not removed.

Summarizing: previously, the linker did both the pruning of functions and recognize the init sections, so everything worked. Now, the LTO-optimizer (i.e. the compiler part of the linking step) does the pruning, and the actual linker knows ab out sections, so there is some missing information there.

Adding the "used" attribute solves this by providing more information to the LTO-compiler. To properly fix this, I guess this needs some involvement of the gcc linker plugin or similar, but I'm not entirely sure. I'd invite you to report this case to the gcc bugzilla (search for existing reports first, and best to reduce your example further), to see what they think.

gitmeister commented 8 years ago

1) Adding __attribute__ ((used)) indeed allows full functionality. Thanks facchinm. 2) What matthijskooijman says makes tons of sense and as he states the .initN sections are exceptions as they have no external linkage as they are called sequentially by avr-libc. The fact that they created the ((used)) attribute likely means they foresaw this case. I might try one last thing and try modifying the linker options to "keep" sections like ".init0". Just in case it offers an Arduino-specific solution.

EDIT: Ok, scratch that, the linker scripts already KEEP the init sections it's really an optimization thing.

gitmeister commented 8 years ago

Will forward to GCC team. Thanks folks.

Ok to close if you wish.

matthijskooijman commented 8 years ago

One more observation: ISRs are essentially similar, in that the avr-libc init code / linker scripts arrange for them to be called, but the compiler does not know about this. Hence, the ISR macro also adds the used attribute IIRC.

EDIT: Ok, scratch that, the linker scripts already KEEP the init sections it's really an optimization thing.

That would be consistent with my earlier conclusion about LTO being the one that removes the functions - the linker never sees them.

I'm closing this, thanks for forwarding to gcc (if you create a bug report, please post the link here for future reference).