[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Bug ld/23648] New: Symbols based on MEMORY regions confuse --gc-section
From: |
nbowler at draconx dot ca |
Subject: |
[Bug ld/23648] New: Symbols based on MEMORY regions confuse --gc-sections. |
Date: |
Thu, 13 Sep 2018 08:40:49 +0000 |
https://sourceware.org/bugzilla/show_bug.cgi?id=23648
Bug ID: 23648
Summary: Symbols based on MEMORY regions confuse --gc-sections.
Product: binutils
Version: 2.32 (HEAD)
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: ld
Assignee: unassigned at sourceware dot org
Reporter: nbowler at draconx dot ca
Target Milestone: ---
It seems that ld's --gc-sections feature can get confused by the
MEMORY command.
It is possible to define symbols that depend on the memory regions in a
linker script. The --gc-sections function appears to discard sections
as if the MEMORY command was omitted from the linker script.
If removing the MEMORY command affects which sections get referenced,
this means --gc-sections will discard sections that are actually needed
by the link. The results are obviously not good.
For example, consider the following linker script:
% cat >test.ld <<'EOF'
MEMORY { code : ORIGIN = 0, LENGTH = 8M }
SECTIONS {
ENTRY(entry)
.text 1M : { *(.text*) } >code
}
foo = LENGTH(code) > 32M ? test0 : test1;
EOF
And a C source file that uses the linker-defined "foo" like this:
% cat >test.c <<'EOF'
void test0(void) { }
void test1(void) { }
void entry(void)
{
extern void foo(void);
foo();
}
EOF
Compiled like this:
% gcc -ffunction-sections -c test.c
The intention of the example is to call one or the other function based
on the link-time MEMORY configuration. This works fine normally:
% ld -Ttest.ld test.o
% readelf -Ws a.out
[...]
6: 0000000000100007 7 FUNC GLOBAL DEFAULT 1 test1
7: 0000000000100007 0 FUNC GLOBAL DEFAULT 1 foo
8: 0000000000100000 7 FUNC GLOBAL DEFAULT 1 test0
So foo = test1, as expected since LENGTH(code) is less than 32M.
However, if we add --gc-sections, things go awry:
% ld -Ttest.ld --gc-sections --print-gc-sections test.o
ld: Removing unused section '.text.test1' in file 'test.o'
Uhoh...
% readelf -Ws a.out
[...]
5: 0000000000000000 0 FUNC GLOBAL DEFAULT ABS foo
6: 0000000000100000 7 FUNC GLOBAL DEFAULT 1 test0
So test1 is discarded, the unused test0 is kept, and foo is set to
garbage. The resulting code is correspondingly broken.
Testing suggests that --gc-sections evaluates "foo" as if LENGTH(code)
returned -1, regardless of what is specified in the MEMORY command.
This is equivalent to what you'd get if the MEMORY command was omitted.
This appears to be independent of target, as I tried several targets
(and versions) with identical effect.
--
You are receiving this mail because:
You are on the CC list for the bug.
- [Bug ld/23648] New: Symbols based on MEMORY regions confuse --gc-sections.,
nbowler at draconx dot ca <=
- [Bug ld/23648] Symbols based on MEMORY regions confuse --gc-sections., nbowler at draconx dot ca, 2018/09/13
- [Bug ld/23648] Symbols based on MEMORY regions confuse --gc-sections., amodra at gmail dot com, 2018/09/18
- [Bug ld/23648] Symbols based on MEMORY regions confuse --gc-sections., cvs-commit at gcc dot gnu.org, 2018/09/19
- [Bug ld/23648] Symbols based on MEMORY regions confuse --gc-sections., amodra at gmail dot com, 2018/09/19
- [Bug ld/23648] Symbols based on MEMORY regions confuse --gc-sections., cvs-commit at gcc dot gnu.org, 2018/09/19