From: jont AT harlequin DOT co DOT uk (Jon Thackray) Subject: forwarded message from MDaemon AT pruimpit 15 Sep 1997 03:48:37 -0700 Message-ID: <199709150959.KAA08462.cygnus.gnu-win32@zaphod.long.harlequin.co.uk> To: gnu-win32 AT cygnus DOT com What's going on here? Did my message get to the list? ------- start of forwarded message (RFC 934 encapsulation) ------- Content-Length: 8611 Received: from holly.cam.harlequin.co.uk (holly.cam.harlequin.co.uk [193.128.4.58]) by propos.long.harlequin.co.uk (8.8.4/8.6.12) with ESMTP id LAA01212 for ; Sat, 13 Sep 1997 11:51:11 +0100 (BST) Received: from smtp1.xs4all.nl (smtp1.xs4all.nl [194.109.6.51]) by holly.cam.harlequin.co.uk (8.8.4/8.8.4) with ESMTP id LAA00215 for ; Sat, 13 Sep 1997 11:51:11 +0100 (BST) Received: from PRUIMPIT (asd-isdn03-02.dial.xs4all.nl [194.109.46.67]) by smtp1.xs4all.nl (8.8.6/XS4ALL) with SMTP id MAA04366 for ; Sat, 13 Sep 1997 12:50:10 +0200 (MET DST) Received: from PRUIMPIT [192.9.200.51] by PRUIMPIT [192.9.200.51] with RAW (MDaemon.v2.0.rW.b2.32-R) for ; Sat, 13 Sep 97 12:42:58 +0100 X-MDSend-Notifications-To: [trash] Reply-To: MDaemon AT PRUIMPIT Message-ID: Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Actual-To: jont AT harlequin DOT co DOT uk X-Actual-From: MDaemon AT PRUIMPIT X-MDMail-Server: MDaemon v2.0 rW b2 32-R From: MDaemon AT PRUIMPIT To: jont Subject: Warning: No Such User! Date: Sat, 13 Sep 97 12:42:58 +0100 gnu-win32-outgoing AT PRUIMPIT - no such user here. - --ORIGINAL MESSAGE BEGINS-- Received: from pop.xs4all.nl [194.109.6.25] by PRUIMPIT [192.9.200.51] with POP (MDaemon.v2.0.rW.b2.32-R) for ; Sat, 13 Sep 97 12:15:55 +0100 Received: from smtp1.xs4all.nl (smtp1.xs4all.nl [194.109.6.51]) by magigimmix.xs4all.nl (8.8.6/XS4ALL) with ESMTP id VAA00264 for ; Sun, 7 Sep 1997 21:33:20 +0200 (MET DST) Received: from nf2.netforward.com (nf2.netforward.com [204.57.67.146]) by smtp1.xs4all.nl (8.8.6/XS4ALL) with ESMTP id VAA21803 for ; Sun, 7 Sep 1997 21:33:12 +0200 (MET DST) X-Forwarder: NetForward.com Received: (from daemon AT localhost) by cygnus.com (8.8.5/8.8.5) id GAA09698 for gnu-win32-outgoing; Wed, 3 Sep 1997 06:38:41 -0700 (PDT) Received: from holly.cam.harlequin.co.uk (holly.cam.harlequin.co.uk [193.128.4.58]) by cygnus.com (8.8.5/8.8.5) with ESMTP id GAA09693 for ; Wed, 3 Sep 1997 06:38:09 -0700 (PDT) Received: from propos.long.harlequin.co.uk (propos.long.harlequin.co.uk [193.128.93.50]) by holly.cam.harlequin.co.uk (8.8.4/8.8.4) with ESMTP id OAA07412 for ; Wed, 3 Sep 1997 14:37:59 +0100 (BST) Received: from zaphod.long.harlequin.co.uk (zaphod.long.harlequin.co.uk [193.128.93.30]) by propos.long.harlequin.co.uk (8.8.4/8.6.12) with SMTP id OAA29564; Wed, 3 Sep 1997 14:37:27 +0100 (BST) Received: by zaphod.long.harlequin.co.uk (SMI-8.6) id OAA03966; Wed, 3 Sep 1997 14:33:08 +0100 Date: Wed, 3 Sep 1997 14:33:08 +0100 Message-Id: <199709031333 DOT OAA03966 AT zaphod DOT long DOT harlequin DOT co DOT uk> From: Jon Thackray To: gnu-win32 AT cygnus DOT com Subject: b18 linker problems Sender: owner-gnu-win32 AT cygnus DOT com Precedence: bulk X-UIDL: 4f71c84cf185f73f3e65ebb1d0a3a30b Status: N X-MDMail-Server: MDaemon v2.0 rW b2 32-R X-MDaemon-Deliver-To: gnu-win32-outgoing AT PRUIMPIT It seems that the b18 linker does incorrect things with pc relative relocation to symbols not in the .text section (or more specifically not in section 0, as will be revealed later). The following email contains a number of exhibits demonstrating the problem, and where I think it lies. First is a small assembler program demonstrating the problem. The problem can be shown under as if there is a pc relative relocation to a symbol not in the .text section, as in the example below. If one rearranges the sections by replaacing .text with .text$i and vice versa then all is ok. A language translator which does not place its text in section 0 may also encounter the problem. I include three outputs from objdump of the link of this program. The first link was done with a raw b18 and demonstrates the problem. The second link was done using b17 ld, and shows that the problem is a regression. The third link is done with a version of ld that I have modified to produce a fix for the problem. The problem seems to lie in a combination of _bfd_coff_generic_relocate_section within cofflink.c and coff_i386_rtype_to_howto in coff-i386.c I include annotated code from cofflink.c and coff-i386.c demonstrating where I think the problem lies. .section .text$i .global foo1 .global foo2 foo1: mov $0, %eax ret foo2: mov $1, %eax ret .text .global main .global foo1 .global foo2 main: call foo1 call foo2 mov $0, %eax ret with b18 ld bash$ objdump --disassemble foo.exe foo.exe: file format pei-i386 Disassembly of section .text: 00401000
: 0: e8 1b 00 00 00 call 00401020 5: e8 1c 00 00 00 call 00401026 a: b8 00 00 00 00 movl $0x0,%eax f: c3 ret 00401010 : 0: b8 00 00 00 00 movl $0x0,%eax 5: c3 ret 00401016 : 0: b8 01 00 00 00 movl $0x1,%eax 5: c3 ret 0040101c : ... with b17 ld objdump --disassemble foo.exe foo.exe: file format pei-i386 Disassembly of section .text: 00401000
: 0: e8 0b 00 00 00 call 00401010 5: e8 0c 00 00 00 call 00401016 a: b8 00 00 00 00 movl $0x0,%eax f: c3 ret 00401010 : 0: b8 00 00 00 00 movl $0x0,%eax 5: c3 ret 00401016 : 0: b8 01 00 00 00 movl $0x1,%eax 5: c3 ret 0040101c : ... After modifying b18 objdump --disassemble foo.exe foo.exe: file format pei-i386 Disassembly of section .text: 00401000
: 0: e8 0b 00 00 00 call 00401010 5: e8 0c 00 00 00 call 00401016 a: b8 00 00 00 00 movl $0x0,%eax f: c3 ret 00401010 : 0: b8 00 00 00 00 movl $0x0,%eax 5: c3 ret 00401016 : 0: b8 01 00 00 00 movl $0x1,%eax 5: c3 ret 0040101c : ... Annotated excerpt from bfd/coff-i386.c (annotations within C style comments) static reloc_howto_type * coff_i386_rtype_to_howto (abfd, sec, rel, h, sym, addendp) bfd *abfd; asection *sec; struct internal_reloc *rel; struct coff_link_hash_entry *h; struct internal_syment *sym; bfd_vma *addendp; { reloc_howto_type *howto; howto = howto_table + rel->r_type; #ifdef COFF_WITH_PE *addendp = 0; /* For gun-win32 on the PC, this will happen */ #endif if (howto->pc_relative) *addendp += sec->vma; if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0) { /* This is a common symbol. The section contents include the size (sym->n_value) as an addend. The relocate_section function will be adding in the final value of the symbol. We need to subtract out the current size in order to get the correct result. */ BFD_ASSERT (h != NULL); #ifndef COFF_WITH_PE /* I think we *do* want to bypass this. If we don't, I have seen some data parameters get the wrong relcation address. If I link two versions with and without this section bypassed and then do a binary comparison, the addresses which are different can be looked up in the map. The case in which this section has been bypassed has addresses which correspond to values I can find in the map */ *addendp -= sym->n_value; #endif } /* If the output symbol is common (in which case this must be a relocateable link), we need to add in the final size of the common symbol. */ if (h != NULL && h->root.type == bfd_link_hash_common) *addendp += h->root.u.c.size; #ifdef COFF_WITH_PE if (howto->pc_relative) *addendp -= 4; /* This will also happen */ if (rel->r_type == R_IMAGEBASE) { *addendp -= pe_data(sec->output_section->owner)->pe_opthdr.ImageBase; } #endif return howto; } Annotated excerpt from bfd/cofflink.c (annotations within C style comments) if (sym != NULL && sym->n_scnum != 0) addend = - sym->n_value; else addend = 0; /* In the example case, addend is assigned the value -sym->n_value. * However, this is irrelevant because howto overwites the value of * addend to be -4 (to deal with the fact that the 386 computes * pc-relative addresses from the start of the next instruction, * whereas the address we'll subtract out later will be the address at * which the relocation takes place, ie 4 less). In the modified * example, where the section names are switched, addend is simply set * to zero. */ howto = bfd_coff_rtype_to_howto (input_bfd, input_section, rel, h, sym, &addend); if (howto == NULL) return false; /* If we are doing a relocateable link, then we can just ignore a PC relative reloc that is pcrel_offset. It will already have the correct value. If this is not a relocateable link, then we should ignore the symbol value. */ if (howto->pc_relative && howto->pcrel_offset) { if (info->relocateable) continue; if (sym != NULL && sym->n_scnum != 0) addend += sym->n_value; /* This would undo the earlier subtraction, except that howto has * junked the result. The overall effect is that we end up pointing * to an address which is too large by an amount equal to the symbol * value. */ } A simple fix for the above is to leave out the two modifications of addend by sym->n_value. This produces the corect result for the example code above, and also for the code I was originally trying to link. However, I suspect there is more to this than meets my eye. - - For help on using this list (especially unsubscribing), send a message to "gnu-win32-request AT cygnus DOT com" with one line of text: "help". ------- end ------- - For help on using this list (especially unsubscribing), send a message to "gnu-win32-request AT cygnus DOT com" with one line of text: "help".