Subject: problems building -current (ARM32)
To: None <port-arm32@netbsd.org, current-users@netbsd.org>
From: Richard Earnshaw <rearnsha@arm.com>
List: current-users
Date: 10/07/1998 16:30:21
Since the new signal code for the arm was checked in last week, I tried to 
build a version of -current over the weekend (a bit of a trial since my 
machine is still running something like 1.3, but with a -current kernel).

I've managed to build a system that will boot (after I replaced the ld.so 
with the version on my existing system -- it seems that either the shared 
library format has been changed in a non-backwards compatible manner, or 
there is a bug in the source to this, or I have built a bad binary 
somehow).  But that is not the problem I'm trying to track down at the 
moment.

The problem is that having booted the new system (fortunately it is on a 
spare disk), I should be able use it to rebuild -current using all the 
latest tools.  I'm running into a problem when I try to build the shared 
library for libbz2.  The error I get is during the link phase, when ld 
dies with the error

	ld: bzlib.so: gotslot at 0x8 is multiple valued: 0x20 vs 0x228

I built a debug version of the linker and the results from running this 
show that the problem is when trying to built the GOT entries for an 
internal symbol.

  perform_relocation: baserel symbolnum=47 addend=0 offset=0x20
  claim_rrs_internal_gotslot: bzlib.so: slot offset 0x8, addend = 0x20

and then shortly afterwards,

  perform_relocation: baserel symbolnum=47 addend=0x208 offset=0x20
  ld: bzlib.so: gotslot at 0x8 is multiple valued: 0x20 vs 0x228

What seems to be happening is as follows (please correct me if I'm wrong, 
since I haven't studied the workings of the linker in great detail):

The .so file (bzlib.so) has been stripped of all its internal symbols 
(LC0, LC1 and the like) so that all the internal symbols are now expressed 
as offsets from the start of the module.

When ld builds a shared library, it prescans the relocations/symbols, 
tentatively allocating one GOT slot for each symbol.  It then assigns the 
offsets to the GOT slots that are needed and passes over the relocations 
to fix things up, and at the same time adding the appropriate offsets 
(stored within the offset and the addend) to the got entry in order to 
generate the final offset.  The addend part of the relocated item is then 
patched to contain the offset into the GOT.   Hence the GOT entry must 
contain the result of both the offset and the addend, but a single entry 
can't contain two different values.

What seems to have changed over the previous version of the linker is that 
internal symbols are now much more forcibly stripped by ld -x than used to 
be the case, so in "the old days" symbols referenced by GOT relocations 
were not removed -- and hence each was allocated a separate slot.

gdb gives the following for the result of md_get_addend:

Breakpoint 10, md_get_addend (rp=0x1ec20, addr=0xefbfa608 "")
    at /usr/src/gnu/usr.bin/ld/ld/../arch/arm32/md.c:92
92              switch (rp->r_length) {
$50 = {r_address = 512, r_symbolnum = 47, r_pcrel = 0, r_length = 2, 
  r_extern = 0, r_neg = 0, r_baserel = 1, r_jmptable = 0, r_relative = 0}
(gdb) fin
Value returned is $51 = 0


Breakpoint 10, md_get_addend (rp=0x1ec40, addr=0xefbfa790 "\b\002")
    at /usr/src/gnu/usr.bin/ld/ld/../arch/arm32/md.c:92
92              switch (rp->r_length) {
$55 = {r_address = 904, r_symbolnum = 47, r_pcrel = 0, r_length = 2, 
  r_extern = 0, r_neg = 0, r_baserel = 1, r_jmptable = 0, r_relative = 0}
(gdb) fin
Value returned is $56 = 520


and objdump gives symbol 47 as 

  00000000 l       .text 0000 00 04 bzlib.so.o.gcc2_compiled.

and the relevant relocations as

  00000200 GOT32             *ABS*
and
  00000388 GOT32             *ABS*


Does anyone know if there is a fix for this?  I can probably provide more 
information if required.

Richard.