Subject: Incorrect Processing of .type directive in a.out-*-netbsd
To: None <bug-gnu-utils@portal.ca>
From: Curt Sampson <curt@portal.ca>
List: current-users
Date: 10/17/1996 20:22:12
Gas from binutils 2.7 is not correctly processing the .type directive
when configured for any NetBSD system that uses a.out object files.

According to the documentation in as.info, gas currently ignores
the .type directive when generating a.out object files. (I have
not verified this in the code itself.) NetBSD, however, uses the
`other' field in the a.out symbol record for type information.

My NetBSD test system for compiling/assembling/linking is an i386
running NetBSD 1.2, which is distributed with gcc 2.7.2, gas 1.92.3
(possibly customised), and an unknown, possibly customised, version
of ld. My system for testing gcc 2.7.2 and binutils 2.7 (as downloaded
from prep.ai.mit.edu) is a Sparcstation 1 running NetBSD 1.2. The
i386 gcc and i386 binutils on the Sparc were compiled with the gcc
that came with NetBSD/sparc (the same as NetBSD/i386).

I have been told by someone else that he had this exact same problem
when attempting to cross-compile for a NetBSD machine from an HP
PA-RISC machine. I do not know what architecture he was using or
what tools he was compiling with.

Here is how to reproduce the problem. Take the example file y.c
below. If this is compiled with standard gcc 2.7.2, it will produce
the output given in y.s below. The same output is produced by the
gcc distributed with NetBSD.

The following four files are:

    y.o.dump.gnu	`objdump -x' of the file produced by gnu as
			from binutils 2.7.
    y.o.dump.netbsd	`objdump -x' of the file produced by the gas
			distributed with NetBSD/i386.
    y.list.gnu		The output listing from assembling y.s with
			gas from binutils 2.7.
    y.list.netbsd	The output listing from assembling y.s with
			the gas distributed with NetBSD 1.2.

You will note that the only difference between these two object
files that objdump sees is that the `other' field of the a.out
symbol record is set to zero in the gcc-generated version, but
contains information in the netbsd-generated version.

(You will also note that the newer gnu assembler placed the
initialised global symbol _external_var at location 0, but the
NetBSD assembler placed it at location 0x60 in the data segment.
This does not appear to make any difference to the final operation
of the program.)

During the link stage I'm using crt0.o and libc.a from the NetBSD
1.2/i386 distribution in both environments; libgcc.a is the standard
one distributed with NetBSD on the i386, and on the sparc, with
the standard gnu tools, is generated by compiling gcc 2.7.2 as a
cross-compiler.

If y.o.gcc is linked with either the NetBSD or the gnu ld, it will
produce an executable that will incurr a segmentation violation
and then dump core. (The backtrace shows just two functions, `#0
0x8b43 in etext ()' and `#1  0x17d3 in main ()'.)

If y.o.netbsd is linked with either the NetBSD ld or the one I
created from the standard gnu binutils-2.7, it will run.

I have repeated this experiment with gcc and gas targeted to
m68k-unknown-netbsd instead of i386-unknown-netbsd and obtained
the same results.

Unfortuantely, I do not currently have the knowledge to know what
modifications I need to make to gas to make it generate correct
object files for NetBSD. At this time I need to know if you are
willing to generate a fix for this, and, if so, what the timeframe
for that fix might be. I am able to test any changes you make, and
I am also willing to provide accounts on systems that you can use
for testing.

cjs

Curt Sampson    curt@portal.ca		Info at http://www.portal.ca/
Internet Portal Services, Inc.	
Vancouver, BC   (604) 257-9400		De gustibus, aut bene aut nihil.

----- y.c
#include <stdio.h>

int external_var = 17;
int nontref_external_var;

main()
{
    unsigned char x = 0x12;

    printf("0x%x 0x%x\n", (unsigned) x, (unsigned) ~x);
    printf("0x03 <<16 = 0x%x\n", 0x03 << 16);
}

----- y.s
	.file	"y.c"
gcc2_compiled.:
___gnu_compiled_c:
.globl _external_var
.data
	.align 2
	.type	 _external_var,@object
	.size	 _external_var,4
_external_var:
	.long 17
.text
LC0:
	.ascii "0x%x 0x%x\12\0"
LC1:
	.ascii "0x03 <<16 = 0x%x\12\0"
	.align 2
.globl _main
	.type	 _main,@function
_main:
	pushl %ebp
	movl %esp,%ebp
	subl $4,%esp
	call ___main
	movb $18,-1(%ebp)
	movzbl -1(%ebp),%eax
	movl %eax,%edx
	notl %edx
	pushl %edx
	movzbl -1(%ebp),%eax
	pushl %eax
	pushl $LC0
	call _printf
	addl $12,%esp
	pushl $196608
	pushl $LC1
	call _printf
	addl $8,%esp
L5:
	leave
	ret
Lfe1:
	.size	 _main,Lfe1-_main
.comm _nontref_external_var,4

----- y.o.dump.gnu
y.o.gnu:     file format a.out-i386-netbsd
y.o.gnu
architecture: i386, flags 0x0000003f:
HAS_RELOC, EXEC_P, HAS_LINENO, HAS_DEBUG, HAS_SYMS, HAS_LOCALS
start address 0x00000000

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         00000060  00000000  00000000  00000020  2**2
                  CONTENTS, ALLOC, LOAD, RELOC, CODE
  1 .data         00000004  00000060  00000060  00000080  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000000  00000064  00000064  00000000  2**2
                  ALLOC
SYMBOL TABLE:
00000000 l       .text 0000 00 04 gcc2_compiled.
00000000 l       .text 0000 00 04 ___gnu_compiled_c
00000060 g       .data 0000 00 07 _external_var
00000020 g       .text 0000 00 05 _main
00000000         *UND* 0000 00 01 ___main
00000000         *UND* 0000 00 01 _printf
00000004 g       *COM* 0000 00 01 _nontref_external_var


RELOCATION RECORDS FOR [.text]:
OFFSET   TYPE              VALUE 
00000027 DISP32            ___main
0000003e 32                .text
00000043 DISP32            _printf
00000050 32                .text
00000055 DISP32            _printf

----- y.o.dump.netbsd
y.o.netbsd:     file format a.out-i386-netbsd
y.o.netbsd
architecture: i386, flags 0x0000003f:
HAS_RELOC, EXEC_P, HAS_LINENO, HAS_DEBUG, HAS_SYMS, HAS_LOCALS
start address 0x00000000

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         00000060  00000000  00000000  00000020  2**2
                  CONTENTS, ALLOC, LOAD, RELOC, CODE
  1 .data         00000004  00000060  00000060  00000080  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000000  00000064  00000064  00000000  2**2
                  ALLOC
SYMBOL TABLE:
00000000 l       .text 0000 00 04 gcc2_compiled.
00000000 l       .text 0000 00 04 ___gnu_compiled_c
00000060 g       .data 0000 01 07 _external_var
00000020 g       .text 0000 02 05 _main
00000000         *UND* 0000 00 01 ___main
00000000         *UND* 0000 00 01 _printf
00000004 g       *COM* 0000 00 01 _nontref_external_var


RELOCATION RECORDS FOR [.text]:
OFFSET   TYPE              VALUE 
00000055 DISP32            _printf
00000050 32                .text
00000043 DISP32            _printf
0000003e 32                .text
00000027 DISP32            ___main

----- y.list.gnu
GAS LISTING y.s				page 1


   1              		.file	"y.c"
   2              	gcc2_compiled.:
   3              	___gnu_compiled_c:
   4              	.globl _external_var
   5              	.data
   6              		.align 2
   7              		.type	 _external_var,@object
   8              		.size	 _external_var,4
   9              	_external_var:
  10 0000 11000000 		.long 17
  11              	.text
  12              	LC0:
  13 0000 30782578 		.ascii "0x%x 0x%x\12\0"
  13      20307825 
  13      780A00
  14              	LC1:
  15 000b 30783033 		.ascii "0x03 <<16 = 0x%x\12\0"
  15      203C3C31 
  15      36203D20 
  15      30782578 
  15      0A00
  16 001d 8D7600   		.align 2
  17              	.globl _main
  18              		.type	 _main,@function
  19              	_main:
  20 0020 55       		pushl %ebp
  21 0021 89E5     		movl %esp,%ebp
  22 0023 83EC04   		subl $4,%esp
  23 0026 E8FCFFFF 		call ___main
  23      FF
  24 002b C645FF12 		movb $18,-1(%ebp)
  25 002f 0FB645FF 		movzbl -1(%ebp),%eax
  26 0033 89C2     		movl %eax,%edx
  27 0035 F7D2     		notl %edx
  28 0037 52       		pushl %edx
  29 0038 0FB645FF 		movzbl -1(%ebp),%eax
  30 003c 50       		pushl %eax
  31 003d 68000000 		pushl $LC0
  31      00
  32 0042 E8FCFFFF 		call _printf
  32      FF
  33 0047 83C40C   		addl $12,%esp
  34 004a 68000003 		pushl $196608
  34      00
  35 004f 680B0000 		pushl $LC1
  35      00
  36 0054 E8FCFFFF 		call _printf
  36      FF
  37 0059 83C408   		addl $8,%esp
  38              	L5:
  39 005c C9       		leave
  40 005d C3       		ret
  41              	Lfe1:
  42              		.size	 _main,Lfe1-_main
  43              	.comm _nontref_external_var,4
GAS LISTING y.s			page 2


DEFINED SYMBOLS
                 y.s:2      .text:00000000 gcc2_compiled.
                 y.s:3      .text:00000000 ___gnu_compiled_c
                 y.s:9      .data:00000000 _external_var
                 y.s:19     .text:00000020 _main

UNDEFINED SYMBOLS
___main
_printf
_nontref_external_var

----- y.list.netbsd
GAS LISTING y.s 			page 1


   1              		.file	"y.c"
   2              	gcc2_compiled.:
   3              	___gnu_compiled_c:
   4              	.globl _external_var
   5              	.data
   6              		.align 2
   7              		.type	 _external_var,@object
   8              		.size	 _external_var,4
   9              	_external_var:
  10 0060 11000000 		.long 17
  11              	.text
  12              	LC0:
  13 0000 30782578 		.ascii "0x%x 0x%x\12\0"
  13      20307825 
  13      780A00
  14              	LC1:
  15 000b 30783033 		.ascii "0x03 <<16 = 0x%x\12\0"
  15      203C3C31 
  15      36203D20 
  15      30782578 
  15      0A00
  16 001d 000000   		.align 2
  17              	.globl _main
  18              		.type	 _main,@function
  19              	_main:
  20 0020 55       		pushl %ebp
  21 0021 89E5     		movl %esp,%ebp
  22 0023 83EC04   		subl $4,%esp
  23 0026 E8D5FFFF 		call ___main
  23      FF
  24 002b C645FF12 		movb $18,-1(%ebp)
  25 002f 0FB645FF 		movzbl -1(%ebp),%eax
  26 0033 89C2     		movl %eax,%edx
  27 0035 F7D2     		notl %edx
  28 0037 52       		pushl %edx
  29 0038 0FB645FF 		movzbl -1(%ebp),%eax
  30 003c 50       		pushl %eax
  31 003d 68000000 		pushl $LC0
  31      00
  32 0042 E8B9FFFF 		call _printf
  32      FF
  33 0047 83C40C   		addl $12,%esp
  34 004a 68000003 		pushl $196608
  34      00
  35 004f 680B0000 		pushl $LC1
  35      00
  36 0054 E8A7FFFF 		call _printf
  36      FF
  37 0059 83C408   		addl $8,%esp
  38              	L5:
  39 005c C9       		leave
  40 005d C3       		ret
  41              	Lfe1:
  42              		.size	 _main,Lfe1-_main
  43 005e 0000     	.comm _nontref_external_var,4
GAS LISTING y.s 			page 2


DEFINED SYMBOLS
                 y.s:2      text:00000000 gcc2_compiled.
                 y.s:3      text:00000000 ___gnu_compiled_c
                 y.s:9      data:00000060 _external_var
                 y.s:19     text:00000020 _main

UNDEFINED SYMBOLS
___main
_printf
_nontref_external_var