[Bug target/70063] New: msp430 stack corruption for naked functions

2016-03-03 Thread awygle at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70063

Bug ID: 70063
   Summary: msp430 stack corruption for naked functions
   Product: gcc
   Version: 5.3.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: target
  Assignee: unassigned at gcc dot gnu.org
  Reporter: awygle at gmail dot com
  Target Milestone: ---

Created attachment 37853
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=37853&action=edit
A nearly minimal example of code producing the bug

When compiling msp430 code including functions which have both arguments and
the naked attribute using -O0, the stack is corrupted and the return pointer is
lost.

This looks like an msp430-style retread of
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54220 to me.

Code:

# 1 "bug.c"
# 1 ""
# 1 ""
# 1 "bug.c"

__attribute__((naked))
void buggy(int* arg1, int* arg2) {
  asm volatile("sub #4, r1");
  (*arg1) = 2;
  (*arg2) = 3;
  asm volatile ("nop");
  asm volatile ("nop");
  asm volatile ("nop");
  asm volatile ("nop");
  asm volatile ("nop");
  asm volatile ("ret");
}

int main() {

  int x, y;
  x = 0;
  y = 1;

  buggy(&x, &y);

  while(1) {}

}

Compiling:

[awygle %] msp430-elf-gcc -v -Wall -Wextra -fno-strict-aliasing -fwrapv
-fno-aggressive-loop-optimizations -mmcu=msp430fr5969 bug.c -o bug.elf
-save-temps

Using built-in specs.
COLLECT_GCC=msp430-elf-gcc
COLLECT_LTO_WRAPPER=/home/awygle/toolchain/install/libexec/gcc/msp430-elf/5.3.0/lto-wrapper
Target: msp430-elf
Configured with: ../gcc-5.3.0/configure
--prefix=/home/awygle/toolchain/install/ --target=msp430-elf --without-headers
--with-newlib --enable-languages=c,c++ --disable-multilib -v
Thread model: single
gcc version 5.3.0 (GCC)
COLLECT_GCC_OPTIONS='-v' '-Wall' '-Wextra' '-fno-strict-aliasing' '-fwrapv'
'-fno-aggressive-loop-optimizations' '-mmcu=msp430fr5969' '-o' 'bug.elf'
'-save-temps'
 /home/awygle/toolchain/install/libexec/gcc/msp430-elf/5.3.0/cc1 -E -quiet -v
bug.c -mmcu=msp430fr5969 -Wall -Wextra -fno-strict-aliasing -fwrapv
-fno-aggressive-loop-optimizations -fpch-preprocess -o bug.i
ignoring nonexistent directory
"/home/awygle/toolchain/install/lib/gcc/msp430-elf/5.3.0/../../../../msp430-elf/sys-include"
#include "..." search starts here:
#include <...> search starts here:
 /home/awygle/toolchain/install/lib/gcc/msp430-elf/5.3.0/include
 /home/awygle/toolchain/install/lib/gcc/msp430-elf/5.3.0/include-fixed

/home/awygle/toolchain/install/lib/gcc/msp430-elf/5.3.0/../../../../msp430-elf/include
End of search list.
COLLECT_GCC_OPTIONS='-v' '-Wall' '-Wextra' '-fno-strict-aliasing' '-fwrapv'
'-fno-aggressive-loop-optimizations' '-mmcu=msp430fr5969' '-o' 'bug.elf'
'-save-temps'
 /home/awygle/toolchain/install/libexec/gcc/msp430-elf/5.3.0/cc1 -fpreprocessed
bug.i -quiet -dumpbase bug.c -mmcu=msp430fr5969 -auxbase bug -Wall -Wextra
-version -fno-strict-aliasing -fwrapv -fno-aggressive-loop-optimizations -o
bug.s
GNU C11 (GCC) version 5.3.0 (msp430-elf)
compiled by GNU C version 4.9.2, GMP version 6.0.0, MPFR version
3.1.2-p11, MPC version 1.0.3
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
GNU C11 (GCC) version 5.3.0 (msp430-elf)
compiled by GNU C version 4.9.2, GMP version 6.0.0, MPFR version
3.1.2-p11, MPC version 1.0.3
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 4cbf41f67559bdb236a322a0045966e6
COLLECT_GCC_OPTIONS='-v' '-Wall' '-Wextra' '-fno-strict-aliasing' '-fwrapv'
'-fno-aggressive-loop-optimizations' '-mmcu=msp430fr5969' '-o' 'bug.elf'
'-save-temps'

/home/awygle/toolchain/install/lib/gcc/msp430-elf/5.3.0/../../../../msp430-elf/bin/as
--traditional-format -mP -mmcu=msp430fr5969 -md -o bug.o bug.s
COMPILER_PATH=/home/awygle/toolchain/install/libexec/gcc/msp430-elf/5.3.0/:/home/awygle/toolchain/install/libexec/gcc/msp430-elf/5.3.0/:/home/awygle/toolchain/install/libexec/gcc/msp430-elf/:/home/awygle/toolchain/install/lib/gcc/msp430-elf/5.3.0/:/home/awygle/toolchain/install/lib/gcc/msp430-elf/:/home/awygle/toolchain/install/lib/gcc/msp430-elf/5.3.0/../../../../msp430-elf/bin/
LIBRARY_PATH=/home/awygle/toolchain/install/lib/gcc/msp430-elf/5.3.0/:/home/awygle/toolchain/install/lib/gcc/msp430-elf/5.3.0/../../../../msp430-elf/lib/
COLLECT_GCC_OPTIONS='-v' '-Wall' '-Wextra' '-fno-strict-aliasing' '-fwrapv'
'-fno-aggressive-loop-optimizations' '-mmcu=msp430fr5969' 

[Bug target/70063] msp430 stack corruption for naked functions

2016-03-03 Thread awygle at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70063

--- Comment #1 from Andrew Wygle  ---
A quick correction - as my example above accidentally shows, compiling with
optimizations isn't a guarantee of avoiding this problem, it just sometimes
helps if the arguments are unused, as the optimizer will remove the attempt to
save them.

[Bug target/70713] New: msp430 interrupt attribute prevents overriding weak symbols

2016-04-18 Thread awygle at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70713

Bug ID: 70713
   Summary: msp430 interrupt attribute prevents overriding weak
symbols
   Product: gcc
   Version: 5.3.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: target
  Assignee: unassigned at gcc dot gnu.org
  Reporter: awygle at gmail dot com
  Target Milestone: ---

Because the interrupt attribute in the msp430 port creates a .word directive
inside of the generated assembly, thus:

test.c:
__attribute__((weak, interrupt(USCI_A1_VECTOR)))
  void TEST_WEAKNESS(void) {
UCA1TXBUF = 'e';
  }

msp430-elf-gcc -mmcu=msp430fr6989 -S test.c

test.s:
  .file "test.c"
.text
  .balign 2
  .weak TEST_WEAKNESS
  .section  __interrupt_vector_43,"ax",@progbits
  .word TEST_WEAKNESS
  .text
TEST_WEAKNESS:
; start of function
; attributes: interrupt
; framesize_regs: 0
; framesize_locals:   0
; framesize_outgoing: 0
; framesize:  0
; elim ap -> fp   2
; elim fp -> sp   0
; saved regs:(none)
  ; start of prologue
  ; end of prologue
  MOV.W #101, &UCA1TXBUF
  NOP
  ; start of epilogue
  RETI
  .size TEST_WEAKNESS, .-TEST_WEAKNESS


When we compile and attempt to link with a non-weak symbol, thus:

test2.c:
__attribute__((interrupt(USCI_A1_VECTOR)))
  void TEST_WEAKNESS(void) {
UCA1TXBUF = 'E';
  }

msp430-elf-gcc -mmcu=msp430fr6989 -S test2.c

test2.s:
  .file "test2.c"
.text
  .balign 2
  .global TEST_WEAKNESS
  .section  __interrupt_vector_43,"ax",@progbits
  .word TEST_WEAKNESS
  .text
TEST_WEAKNESS:
; start of function
; attributes: interrupt
; framesize_regs: 0
; framesize_locals:   0
; framesize_outgoing: 0
; framesize:  0
; elim ap -> fp   2
; elim fp -> sp   0
; saved regs:(none)
  ; start of prologue
  ; end of prologue
  MOV.W #69, &UCA1TXBUF
  NOP
  ; start of epilogue
  RETI
  .size TEST_WEAKNESS, .-TEST_WEAKNESS

The error:
msp430-elf-gcc -mmcu=msp430fr6989 test.s test2.s -o test.elf
msp430-elf/bin/ld: test.elf section `__interrupt_vector_43' will not fit in
region `VECT43'
msp430-elf/bin/ld: region `VECT43' overflowed by 2 bytes
collect2: error: ld returned 1 exit status


I was able to get this to work by making the section lines part of a comdat
group, so that
  .section  __interrupt_vector_43,"ax",@progbits
becomes
  .section  __interrupt_vector_43,"axG",@progbits,TEST_WEAKNESS,comdat
in both cases. There seem to be no ill-effects from doing this (provided the
group name is based on the function name), but I lack the gcc experience to say
for sure, or to cause such code to be emitted.

[Bug target/70063] msp430 stack corruption for naked functions

2016-04-28 Thread awygle at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70063

--- Comment #3 from Andrew Wygle  ---
This appears to be fixed in GCC 6.1

[Bug target/80993] New: [msp430] __attribute__((interrupt)) should imply __attribute__((used))

2017-06-06 Thread awygle at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80993

Bug ID: 80993
   Summary: [msp430] __attribute__((interrupt)) should imply
__attribute__((used))
   Product: gcc
   Version: 6.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: target
  Assignee: unassigned at gcc dot gnu.org
  Reporter: awygle at gmail dot com
  Target Milestone: ---

Enabling link-time optimization on the MSP430 causes any interrupt handlers
which are not called directly to be cheerfully eaten. Thus any interrupt causes
the processor to execute essentially random data, resulting in uncontrolled
jumps and general badness. This problem can be resolved with
__attribute__((used)), which should be implied by __attribute__((interrupt)).

[Bug target/78554] New: Internal Compiler Error in msp430 target with -mlarge, -O{s123}

2016-11-27 Thread awygle at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78554

Bug ID: 78554
   Summary: Internal Compiler Error in msp430 target with -mlarge,
-O{s123}
   Product: gcc
   Version: 6.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: target
  Assignee: unassigned at gcc dot gnu.org
  Reporter: awygle at gmail dot com
  Target Milestone: ---

When compiling code for an MSP430 using large model (-mlarge) and any
optimization above 0, assigning the address of a global variable to an __int20
unsigned (__UINTPTR_TYPE__) which is part of a structure causes an internal
compiler error, as in the following .i file:

# 1 "test.c"
# 1 ""
# 1 ""
# 1 "test.c"
unsigned char test_val = 0;

typedef __int20 unsigned reg_t;

struct holds_reg {
  reg_t r0;
};

struct holds_reg ex = { 0 };

int main() {
  ex.r0 = (reg_t)(&test_val);
  return 0;
}


The invocation of msp430-elf-gcc:


msp430-elf-gcc -mmcu=msp430fr5969 -mlarge -O1 -save-temps test.c
test.c: In function ‘main’:
test.c:14:1: error: unrecognizable insn:
 }
 ^
(insn 6 5 8 2 (set (mem/c:HI (reg/f:PSI 25) [2 ex.r0+0 S2 A16])
(subreg:HI (symbol_ref:PSI ("test_val") [flags 0x2] ) 0)) test.c:12 -1
 (nil))
test.c:14:1: internal compiler error: in extract_insn, at recog.c:2287
0x8aa29a _fatal_insn(char const*, rtx_def const*, char const*, int, char
const*)
../../gcc-6.2.0/gcc/rtl-error.c:108
0x8aa2c9 _fatal_insn_not_found(rtx_def const*, char const*, int, char const*)
../../gcc-6.2.0/gcc/rtl-error.c:116
0x882087 extract_insn(rtx_insn*)
../../gcc-6.2.0/gcc/recog.c:2287
0x6e1ba5 instantiate_virtual_regs_in_insn
../../gcc-6.2.0/gcc/function.c:1582
0x6e1ba5 instantiate_virtual_regs
../../gcc-6.2.0/gcc/function.c:1950
0x6e1ba5 execute
../../gcc-6.2.0/gcc/function.c:1999
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.


Some things which don't cause this error include assigning the address of a
variable which is local to main or assigning the address directly to a __int20
unsigned which is not part of a struct. The error does not occur on -msmall or
on -O0.

[Bug target/78818] New: msp430 persistent attribute is not applied correctly in some cases

2016-12-14 Thread awygle at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78818

Bug ID: 78818
   Summary: msp430 persistent attribute is not applied correctly
in some cases
   Product: gcc
   Version: 6.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: target
  Assignee: unassigned at gcc dot gnu.org
  Reporter: awygle at gmail dot com
  Target Milestone: ---

The MS430 variable attribute "persistent" places variables in a special section
.persistent so that they will not be re-initialized on reset and so that the
linker can place them in non-volatile storage. Variables with this attribute
aren't placed in this section when:

1) the variables are specified as "static" AND are not initialized or are
initialized to 0. In this case the variables are placed in the .bss section.
2) the program is compiled with the -fdata-sections optimization option. In
this case the variables are placed in either .bss.foo or .text.foo.

An example program and two compilations:

test.i:
# 1 "test.c"
# 1 ""
# 1 ""
# 1 "test.c"

__attribute__((persistent)) int persist = 1;
__attribute__((persistent)) int global_persist = 0;
static __attribute__((persistent)) int static_persist = 1;
static __attribute__((persistent)) int static_nopersist = 0;

void main() {

  while(1);
}


Compilation without -fdata-sections:

% msp430-elf-gcc -msim -c test.i -o test.o
% msp430-elf-objdump -x --syms test.o

test.o: file format elf32-msp430
test.o
architecture: MSP430X, flags 0x0011:
HAS_RELOC, HAS_SYMS
start address 0x

Sections:
Idx Name  Size  VMA   LMA   File off  Algn
  0 .text 0004      0034  2**1
  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
  1 .data       0038  2**0
  CONTENTS, ALLOC, LOAD, DATA
  2 .bss  0002      0038  2**1
  ALLOC
  3 .persistent   0006      0038  2**1
  CONTENTS, ALLOC, LOAD, DATA
  4 .comment  0012      003e  2**0
  CONTENTS, READONLY
  5 .MSP430.attributes 0017      0050  2**0
  CONTENTS, READONLY
SYMBOL TABLE:
 ldf *ABS*   test.c
 ld  .text   .text
 ld  .data   .data
 ld  .bss    .bss
 ld  .persistent .persistent
0004 l O .persistent0002 static_persist
 l O .bss   0002 static_nopersist
 ld  .comment    .comment
 ld  .MSP430.attributes  .MSP430.attributes
 g O .persistent0002 persist
0002 g O .persistent0002 global_persist
 *UND*   __crt0_init_bss
 g F .text  0004 main


RELOCATION RECORDS FOR [.text]:
OFFSET   TYPE  VALUE
0002 R_MSP430X_ABS16   .L2

Compilation with -fdata-sections:

% msp430-elf-gcc -msim -fdata-sections -c test.i -o test.o
% msp430-elf-objdump -x --syms test.o

test.o: file format elf32-msp430
test.o
architecture: MSP430X, flags 0x0011:
HAS_RELOC, HAS_SYMS
start address 0x

Sections:
Idx Name  Size  VMA   LMA   File off  Algn
  0 .text 0004      0034  2**1
  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
  1 .data       0038  2**0
  CONTENTS, ALLOC, LOAD, DATA
  2 .bss        0038  2**0
  ALLOC
  3 .data.persist 0002      0038  2**1
  CONTENTS, ALLOC, LOAD, DATA
  4 .bss.global_persist 0002      003a  2**1
  ALLOC
  5 .data.static_persist 0002      003a  2**1
  CONTENTS, ALLOC, LOAD, DATA
  6 .bss.static_nopersist 0002      003c  2**1
  ALLOC
  7 .comment  0012      003c  2**0
  CONTENTS, READONLY
  8 .MSP430.attributes 0017      004e  2**0
  CONTENTS, READONLY
SYMBOL TABLE:
 ldf *ABS*   test.c
 ld  .text   .text
 ld  .data   .data
 ld  .bss    .bss
 ld  .data.persist   .data.persist
 ld  .bss.global_persist .bss.global_persist
 ld  .data.static_persist    .data.static_persist
 l O .data.static_persist   0002 static_persist
 ld  .bss.static_nopersist   .bss.static_nopersist
 l O .bss.static_nopersist  0002 static_nopersist
 ld  .co

[Bug target/78838] New: msp430 option -mcode-region=either, -ffunction-sections, and interrupt function attributes cause incorrect section to be created

2016-12-16 Thread awygle at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78838

Bug ID: 78838
   Summary: msp430 option -mcode-region=either,
-ffunction-sections, and interrupt function attributes
cause incorrect section to be created
   Product: gcc
   Version: 6.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: target
  Assignee: unassigned at gcc dot gnu.org
  Reporter: awygle at gmail dot com
  Target Milestone: ---

On the msp430 target, when using -mcode-region with -ffunction-sections (as is
semi-suggested by the documentation), any functions which are marked with the
interrupt attribute and which also specify an interrupt number are placed into
an incorrect section ".either.lowtext", which is clearly nonsensical. An
example is below.

interrupt_bug.i:

# 1 "interrupt_bug.c"
# 1 ""
# 1 ""
# 1 "interrupt_bug.c"

__attribute__((interrupt(2))) void causes_error(void) {
}

void main() {

  while(1);
}

Compiling with -ffunction-sections:

% msp430-elf-gcc -msim -mlarge -mcode-region=either -ffunction-sections
-save-temps -c interrupt_bug.c -o interrupt_bug.o
% msp430-elf-gcc -msim -mlarge -mcode-region=either -ffunction-sections
-save-temps interrupt_bug.o -o interrupt_bug.elf
/home/awygle/toolchain/install/bin/../lib/gcc/msp430-elf/6.2.0/../../../../msp430-elf/bin/ld:
error: no section named .lower.lowtext or .upper.lowtext in linker script
% msp430-elf-objdump --syms interrupt_bug.o

interrupt_bug.o: file format elf32-msp430

SYMBOL TABLE:
 ldf *ABS*   interrupt_bug.c
 ld  .text   .text
 ld  .data   .data
 ld  .bss    .bss
 ld  .either.lowtext .either.lowtext
 ld  __interrupt_vector_2    __interrupt_vector_2
 ld  .either.text.main   .either.text.main
 ld  .comment    .comment
 ld  .MSP430.attributes  .MSP430.attributes
 g F .either.lowtext0004 causes_error
 g F .either.text.main  0004 main


Note that main() is in the section .either.text.main, while causes_error() is
in the section .either.lowtext.

Compiling without -ffunction-sections:

% msp430-elf-gcc -msim -mlarge -mcode-region=either -save-temps -c
interrupt_bug.c -o interrupt_bug.o
% msp430-elf-gcc -msim -mlarge -mcode-region=either -save-temps interrupt_bug.o
-o interrupt_bug.elf
% msp430-elf-objdump --syms interrupt_bug.o

interrupt_bug.o: file format elf32-msp430

SYMBOL TABLE:
 ldf *ABS*   interrupt_bug.c
 ld  .text   .text
 ld  .data   .data
 ld  .bss    .bss
 ld  .lowtext    .lowtext
 ld  __interrupt_vector_2    __interrupt_vector_2
 ld  .either.text    .either.text
 ld  .comment    .comment
 ld  .MSP430.attributes  .MSP430.attributes
 g F .lowtext   0004 causes_error
 g F .either.text   0004 main


Now causes_error() is in the .lowtext section, as expected.

[Bug target/78849] New: ICE on initialization of global struct containing __int20 array at varasm.c:4968

2016-12-17 Thread awygle at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78849

Bug ID: 78849
   Summary: ICE on initialization of global struct containing
__int20 array at varasm.c:4968
   Product: gcc
   Version: 6.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: target
  Assignee: unassigned at gcc dot gnu.org
  Reporter: awygle at gmail dot com
  Target Milestone: ---

The following code (constructor_bug.i) produces an internal compiler error when
compiled for the msp430-elf target:

# 1 "constructor_bug.c"
# 1 ""
# 1 ""
# 1 "constructor_bug.c"

struct causes_problems {
  __int20 array[2];
  char value;
};

struct causes_problems instance = {
  {
0,
1,
  },
  0,
};

void main(void) {
  while(1);
}

% msp430-elf-gcc -msim constructor_bug.i
constructor_bug.c:17:1: internal compiler error: in
output_constructor_regular_field, at varasm.c:4968
 }
 ^
0xb06039 output_constructor_regular_field
../../gcc-6.2.0/gcc/varasm.c:4968
0xb06039 output_constructor
../../gcc-6.2.0/gcc/varasm.c:5276
0xb05254 assemble_variable_contents
../../gcc-6.2.0/gcc/varasm.c:2062
0xb0bdca assemble_variable(tree_node*, int, int, int)
../../gcc-6.2.0/gcc/varasm.c:2238
0xb0fadd varpool_node::assemble_decl()
../../gcc-6.2.0/gcc/varpool.c:582
0x600403 output_in_order
../../gcc-6.2.0/gcc/cgraphunit.c:2231
0x6006a3 symbol_table::compile()
../../gcc-6.2.0/gcc/cgraphunit.c:2468
0x6025d9 symbol_table::finalize_compilation_unit()
../../gcc-6.2.0/gcc/cgraphunit.c:2564
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.

% msp430-elf-gcc -v
Using built-in specs.
COLLECT_GCC=msp430-elf-gcc
COLLECT_LTO_WRAPPER=/home/awygle/toolchain/install/libexec/gcc/msp430-elf/6.2.0/lto-wrapper
Target: msp430-elf
Configured with: ../gcc-6.2.0/configure
--prefix=/home/awygle/toolchain/install/ --target=msp430-elf --without-headers
--with-newlib --enable-languages=c,c++ -v
Thread model: single
gcc version 6.2.0 (GCC)


As far as I can tell this is a minimal test case, by which I mean that any of
the following prevents the error:

* Reducing the length of the array to 1
* Removing the "value" field from the struct
* Moving the array field to the end of the struct
* Not initializing the struct
* Moving the struct variable definition and initialization into the main()
function

I filed this under "target" but I suspect it would apply to any
non-byte-aligned __intN type - however, only one of those seems to exist right
now and it's in the msp430 target. I tried to reproduce this bug on the AVR
target using __int24 without success, but my avr-gcc version is 4.8.2 rather
than 6.2.

Thanks

[Bug target/78818] msp430 persistent attribute is not applied correctly in some cases

2017-01-03 Thread awygle at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78818

--- Comment #1 from Andrew Wygle  ---
Compiling with -mdata-region=either also causes this problem, with variables
ending up in either .either.data or .either.bss.