Subject: Re: EGCS enabled on mips
To: None <tech-toolchain@netbsd.org>
From: der Mouse <mouse@Rodents.Montreal.QC.CA>
List: tech-toolchain
Date: 11/01/1998 14:40:05
>>> 	    lui	  $1,   %hi (expr1)		# ..carry compensation  needed
>>> 	    addiu  $1,   %lo(expr1)		# NB: %lo is sign extended
>> I can't see why the loader has to be able to pair up these
>> instructions.
> Due to ancient reloc tradition, the offset bits of the addiu
> instruction count as part of expr1.  [...]

"Eww."

Okay, yes, that clears it up.  Thank you.

>> Certainly the SPARC has no such problems, and there too the low part
>> is signed (though the split is 22/10, not 16/16).
> [...the SPARC instruction set has three bits of overlap between the
> 22 in a sethi and the 13 in an immediate field...]

> 	sethi	%hi(expr+5), %o1
> 	ld	[ %o1 + %lo(expr+5) ], %o0

I always thought this was what the r_addend field is for.
<sparc/reloc.h> says, in part,

/*
 * SPARC relocation info.
 *
 * Symbol-relative relocation is done by:
 *      1. locating the appropriate symbol
 *      2. if defined, adding (value + r_addend), subtracting pc if pc-rel,
 *         and then shifting down 2 or 10 or 13 if necessary.
 * The resulting value is then to be stuffed into the appropriate bits
 * in the object (the low 22, or the high 30, or ..., etc).
 */
struct reloc_info_sparc {
        u_long  r_address;      /* relocation addr (offset in segment) */
        u_int   r_index:24,     /* segment (r_extern==0) or symbol index */
                r_extern:1,     /* if set, r_index is symbol index */
                :2;             /* unused */
        enum reloc_type r_type:5; /* relocation type, from above */
        long    r_addend;       /* value to add to symbol value */
};

The r_addend is there to store the 5 in, and the comment doesn't say
anything about picking out the bits already present in the low part.

> What you really end up with, if you disassemble the .o, is this:

> 	sethi	0, %o1			# %hi(expr) reloc pointing to this
> 	ld	[ %o1 + 5 ], %o0	# %lo(expr) reloc pointing to this

What you describe is not what I see on the SPARC.  I wrote a small .s
file, just two lines,

	sethi	%hi(extsym+5),%l0
	ld	[%l0+%lo(extsym+5)],%l1

and assembled it.  The resulting .o file contained:

 0:		a.out header:
 0:    008a0107		a_midmag (flags=0 mid=MID_SPARC magic=OMAGIC)
 4:    00000008		a_text = 8
 8:    00000000		a_data = 0
 c:    00000000		a_bss = 0
10:    0000000c		a_syms = 12
14:    00000000		a_entry = 0
18:    00000018		a_trsize = 18
1c:    00000000		a_drsize = 0
20:		text segment:
20:    21000000		sethi %hi(0), %l0
24:    e2042000		ld [%l0+0], %l1
28:		data segment:
28:		text relocations:
28:    00000000		r_address = 0
2c:    00000088		r_index=0 r_extern=1 r_type=8=RELOC_HI22
30:    00000005		r_addend = 5
34:    00000004		r_address = 4
38:    0000008b		r_index=0 r_extern=1 r_type=11=RELOC_LO10
3c:    00000005		r_addend = 5
40:		data relocations:
40:		symbol table:
40:    00000004		n_strx = 4
44:    01000000		n_type=1=N_UNDF|N_EXT n_other=0 n_desc=0
48:    00000000		n_value = 0
4c:		string table:
4c:    0000000b		string table size = 11
50:    65787473		"exts"
54:    796d00		"ym\0"

I even tried patching, by hand, the immediate bits in the ld
instruction to 2 (e2042002).  After loading this with another .o file
that defines extsym, the files resulting with and without the change
from e2042000 to e2042002 were the same.

Of course, as the above picking-apart indicates, this *was* on an a.out
SPARC.  I have no ELF SPARC handy to try it on (does sparc -current use
ELF yet?).

					der Mouse

			       mouse@rodents.montreal.qc.ca
		     7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B