Subject: port-arm/26160: objcopy creates unbootable kernel sometimes
To: None <>
From: None <>
List: netbsd-bugs
Date: 07/04/2004 10:21:34
>Number:         26160
>Category:       port-arm
>Synopsis:       objcopy creates unbootable kernel sometimes
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    port-arm-maintainer
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Jul 04 08:23:00 UTC 2004
>Originator:     Martin Husemann
>Release:        NetBSD 2.0F
System: NetBSD 2.0F NetBSD 2.0F (DROWSY) #1: Sat Jun 19 15:21:30 CEST 2004 shark
Architecture: arm
Machine: shark
Sometimes shark a.out kernels are unbootable. Richard Earnshaw analyzed
this to be a bug in objcopy, causing wrong vma for .data and .bss sections.
See for details.
This bug can be worked around by using a ldscript that combines all link_set
sections into .text. Richard proposed a fixed ldscript that does this and
which works for the current kernel sources, but Jason Thorpe insisted on
the dynamic property of link_set additions (i.e. not having to change
ldscripts) and suggested to fix objcopy instead, see for details.

Now we did not manage to fix objcopy yet, and this needs to be handled
for the 2.0 release.

Try to boot a kernel from the autobuild and be unlucky.

There have been various fixes proposed:

 - Write a proper bootloader and start using the ELF kernel itself
   (probably the best long term solution)
 - Fix binutils
 - Hardcode the sections in a ldscript
 - Generate the ldscript on the fly by examining sections found in
   all kernel object files. The following fragment (where *.o should
   be replaced by ${SYSTEM_OBJ}) generates the needed dynamic part;
   the (fixed) head and tail need to be added and maybe this should
   all be done by awk instead...

#! /bin/sh

SETS=`objdump -x *.o | fgrep "RELOCATION RECORDS FOR [link_set" | \
        sort -u | sed 's/^.*\[\(.*\)\]:$/\1/'`

for s in $SETS; do
        printf "  . = ALIGN(4);\n"
        printf "  PROVIDE (__start_%s = .);\n" $s
        printf "  *(%s)\n" $s
        printf "  PROVIDE (__stop_%s = .);\n" $s