Subject: kern/21844: netwinder kernal cannot be linked because link_set_* sections overlap with .data
To: None <gnats-bugs@gnats.netbsd.org>
From: None <uwe@netbsd.org>
List: netbsd-bugs
Date: 06/10/2003 21:12:20
>Number: 21844
>Category: kern
>Synopsis: netwinder kernal cannot be linked because link_set_* sections overlap with .data
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Tue Jun 10 21:13:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator: Valeriy E. Ushakov
>Release: -current as of 2003-06-10
>Organization:
>Environment:
N/A
>Description:
When linking netwinder kernel:
/usr/nb/tools/bin/arm--netbsdelf-ld -T ../../../../arch/netwinder/conf/kern.ldscript -X -o netbsd ${SYSTEM_OBJ} ${EXTRA_OBJ} vers.o
/usr/nb/tools/bin/arm--netbsdelf-ld: section .data [001a8000 -> 001ec957] overlaps section link_set_malloc_types [001a7fcc -> 001a80b7]
The problem is that the kernel ld script for netwinder does not list link_set_* sections, so they are transfered to the ld output as-is after the .text section, however the kernel ld script explicitely places .data section after the .text section with:
. = ALIGN(0x8000);
.data :
AT ((LOADADDR(.text) + SIZEOF(.text) + (0x8000 - 1)) & ~(0x8000 - 1))
{ ... }
if sizes of .text section and link_set_* section are such that there is not enough room for the link_set_* sections in the last page occupied by the .text section, the link_set_* section will be overlapped by the .data section b/c of the explicit .data section placement
E.g. this error has been triggered by the change that made the igsfb.o to be:
$ /usr/nb/tools/bin/arm--netbsdelf-size igsfb.o
text data bss dec hex filename
8604 36 0 8640 21c0 igsfb.o
Undoing the change that triggered the error results in the linkable kernel with these section sizes/locations:
Sections:
Idx Name Size VMA LMA File off Algn
0 .start 000000a8 0000c000 0000c000 00004000 2**0
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .text 0019be48 f000c0a8 0000c0a8 000040a8 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
2 link_set_malloc_types 000000ec f01a7ef0 001a7ef0 0019fef0 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 link_set_evcnts 00000004 f01a7fdc 001a7fdc 0019ffdc 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .data 00044958 f01a8000 001a8000 001a0000 2**2
CONTENTS, ALLOC, LOAD, DATA
and igsfb.o is
$ /usr/nb/tools/bin/arm--netbsdelf-size igsfb.o
text data bss dec hex filename
8384 36 0 8420 20e4 igsfb.o
So in this kernel the .text section plus link_set_* sections end at:
F000C0A8 + 19BE48 + EC + 4 = F01A7FE0
When igsfb.o .text grows in size by 0t220 == 0xdc bytes, the kernel .text plus link_set_* sections end at
F000C0A8 + 19BE48 + EC + 4 + DC
F01A80BC
and that overlaps with the .data section placed at F01A8000 based on the size of the .text section only.
>How-To-Repeat:
This problem is hard to reproduce b/c the kernel .text size must be such that the .text section ends very close to the address aligned at 0x8000. Adding some code (e.g. printfs) to some source file to cause the .text section to grow is probably the easiest way to reproduce this problem "in the wild".
Once .text is of the appropriate size, the juxtaposed link_set_* sections will overlap with the .data section and trigger the error.
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted: