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: