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