Overridden weak symbol being discarded when using -flto
Building a file which overrides _write (to enable redirection to an external communication interface) with link-time optimization produces the error:
`_write' referenced in section `.text._write_r' of c:/program files (x86)/gnu tools arm embedded/4.9 2014q4/
collect2.exe: error: ld returned 1 exit status
This is reproducible using both 4.8.4 and 4.9.3 (Q4 2014 release), only when using link-time optimization. I am running on Windows 7 64-bit edition. Is this a bug in the compiler, or is there a problem with my invocation? Thanks.
The compiler and linker are invoked as follows:
arm-none-
arm-none-
The main.c in question is:
#include <stdio.h>
int _write(int file, char *ptr, int len)
{
int i;
file = file;
for (i = 0; i < len; i++)
{
// put character to UART omitted
}
return len;
}
int main()
{
for(;;)
{
}
}
/* [] END OF FILE */
cm0gcc.ld is as follows:
/* Linker script for ARM M-profile Simulator
*
* Version: Sourcery G++ Lite 2010q1-188
* Support: https:/
*
* Copyright (c) 2007, 2008, 2009, 2010 CodeSourcery, Inc.
*
* The authors hereby grant permission to use, copy, modify, distribute,
* and license this software and its documentation for any purpose, provided
* that existing copyright notices are retained in all copies and that this
* notice is included verbatim in any distributions. No written agreement,
* license, or royalty fee is required for any of the authorized uses.
* Modifications to this software may be copyrighted by their authors
* and need not follow the licensing terms described here, provided that
* the new terms are clearly indicated on the first page of each file where
* they apply.
*/
OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
SEARCH_DIR(.)
GROUP(-lgcc -lc -lnosys)
MEMORY
{
rom (rx) : ORIGIN = 0x0, LENGTH = 131072
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 16384
}
/* Bring in the interrupt routines & vector */
EXTERN(main)
/* Provide fall-back values */
PROVIDE(
PROVIDE(
/* Set stack top to end of RAM, and stack limit move down by
* size of .stack section.
*/
PROVIDE(__cy_stack = ORIGIN(ram) + LENGTH(ram));
PROVIDE(
SECTIONS
{
appl_start = 0;
.text appl_start :
{
CREATE_
*(.romvectors)
. = MAX(., 0x100);
*(.text .text.* .gnu.linkonce.t.*)
*(.plt)
*(.gnu.warning)
*(.glue_7t) *(.glue_7) *(.vfp11_veneer)
*(.ARM.extab* .gnu.linkonce.
*(.
} >rom
.eh_frame_hdr : ALIGN (4)
{
KEEP (*(.eh_frame_hdr))
} >rom
.eh_frame : ALIGN (4)
{
KEEP (*(.eh_frame))
} >rom
/* .ARM.exidx is sorted, so has to go in its own output section. */
PROVIDE_HIDDEN (__exidx_start = .);
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.
} >rom
__exidx_end = .;
.rodata : ALIGN (4)
{
*(.rodata .rodata.* .gnu.linkonce.r.*)
. = ALIGN(4);
KEEP(*(.init))
. = ALIGN(4);
__preinit_
KEEP (*(.preinit_array))
__preinit_
. = ALIGN(4);
__init_
KEEP (*(SORT(
KEEP (*(.init_array))
__init_
. = ALIGN(4);
KEEP(*(.fini))
. = ALIGN(4);
__fini_
KEEP (*(.fini_array))
KEEP (*(SORT(
__fini_
. = ALIGN(0x4);
KEEP (*crtbegin.
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*crtend.o(.ctors))
. = ALIGN(0x4);
KEEP (*crtbegin.
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*crtend.o(.dtors))
. = ALIGN(4);
__cy_regions = .;
LONG (__cy_region_
LONG (__cy_region_
LONG (__cy_region_
LONG (__cy_region_
__cy_
. = ALIGN (8);
_etext = .;
} >rom
.ramvectors (NOLOAD) : ALIGN(8)
{
__cy_
KEEP(
}
.noinit (NOLOAD) : ALIGN(8)
{
KEEP(
}
.data : ALIGN(8)
{
__cy_
KEEP(*(.jcr))
*(.got.plt) *(.got)
*(.shdata)
*(.data .data.* .gnu.linkonce.d.*)
. = ALIGN (8);
*(.ram)
_edata = .;
} >ram AT>rom
.bss : ALIGN(8)
{
PROVIDE(
*(.shbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
. = ALIGN (8);
*(.ram.b)
_end = .;
__end = .;
} >ram AT>rom
PROVIDE(end = .);
PROVIDE(
__cy_
__cy_
__cy_
/* The .stack and .heap sections don't contain any symbols.
* They are only used for linker to calculate RAM utilization.
*/
.heap (NOLOAD) :
{
. = _end;
. += 0x80;
__cy_heap_limit = .;
} >ram
.stack (__cy_stack - 0x0800) (NOLOAD) :
{
__cy_
. += 0x0800;
} >ram
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(
.stab 0 (NOLOAD) : { *(.stab) }
.stabstr 0 (NOLOAD) : { *(.stabstr) }
/* DWARF debug sections.
* Symbols in the DWARF debugging sections are relative to the beginning
* of the section so we begin them at 0.
*/
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* DWARF 2.1 */
.debug_ranges 0 : { *(.debug_ranges) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
.note.
.ARM.attributes 0 : { KEEP (*(.ARM.
/DISCARD/ : { *(.note.GNU-stack) }
}
Question information
- Language:
- English Edit question
- Status:
- Answered
- Assignee:
- No assignee Edit question
- Last query:
- Last reply:
Can you help with this problem?
Provide an answer of your own, or ask Kyle for more information if necessary.