Here is the compiler's view of things... (long)
The idea is that for a code sequence like this
(64-bit, assume GOT pointer in %l3):
sethi %gdop_hix22(sym), %l1 ! R_SPARC_GOTDATA_OP_HIX22
xor %l1, %gdop_lox10(sym), %l1 ! R_SPARC_GOTDATA_OP_LOX10
ldx [%l3 + %l1], %l1 ! R_SPARC_GOTDATA_OP
ldx [%l1+64], %l2 ! value from sym+64
If the symbol "sym" is within +/- 2 GBytes of the GOT pointer
(or probably it's +/- 4 GB)
then the linker can re-write the code into:
sethi %gdop_hix22(sym), %l1 ! R_SPARC_GOTDATA_OP_HIX22
xor %l1, %gdop_lox10(sym), %l1 ! R_SPARC_GOTDATA_OP_LOX10
add %l3, %l1, %l1 ! R_SPARC_GOTDATA_OP
ldx [%l1+64], %l2 ! value from sym+64
That will remove one level of indirection,
and should be faster code.
Working out the correct transformation
for the way the linker needs to plug in
to get the right values is tedious.
The value that needs to be formed by
the sethi and xor is the displacement from the GOT to sym.
I am confused by the linker jargon,
but I believe this displacement is (S + A - GOT),
though if you interpret the location of the data
as it's GOT slot, then I think (G) is also correct.
I'll call this dispacement "D" for shorthand.
There are two cases to consider,
a positive displacement from the GOT,
and a negative displacement from the GOT.
And remember that we are generating
the same code sequence and relocations
for both 32-bit and 64-bit code,
though in 32-bit code, the upper 32-bits will be ignored.
So think of these computations as 64-bit wide.
For a positive displacement,
the expressions are equivalent to a normal sethi and "or",
just mask of the right bits,
(D & 0xffff,fc00) for the sethi (mid 22-bits),
shifted right by 10 bits, of course,
and (D & 0x3ff) for the xor (low 10-bits).
The upper 32-bits are all zeroes from the sethi,
and xor'ed with zero from the positive simm13 constant of xor.
For the negative displacement,
things are more complicated.
We use the simm13 constant of the xor instruction
to generate a negative number.
This gives us 0xffff,ffff,ffff,fxxx from the simm13,
where the xxx is yet to be determined.
The sethi instruction will
set the low 12 bits to zero and the upper 32 bits to zero.
So, the low 12 bits of the simm13 constant should be left alone
to xor with zeroes and stay the same (that's bits 0-11),
and that's (D & 0x3ff) in the expressions.
The upper 32-bits of zeroes from the sethi
will xor with ones with zeroes to get ones (that's bits 32-63).
The bits from 13-31 to go into the sethi
need to be the unary negate of the bits we want there,
because they will be xor'ed against ones (and inverted).
The bits 10-13 (represented by (D & 0x1c00),
we want to be ones in the simm13 part of the xor,
and should therefore be inverted in the sethi version.
I'm sure that was clear as mud.
I'll leave it as an exercise for the reader
to formulate the words above into expressions (:-).
One trick used in the expressions below
is to use (D >> 31) to get all zeroes
or all ones into the lower 32-bits
and use that to avoid having separate expressions
for positive and negative displacements.
Note that I think (D >> 32) is more appropriate.
Also note that computation for R_SPARC_GOTDATA_HIX22
should be identical to the computation for R_SPARC_GOTDATA_OP_HIX22,
and likewise, the computation for R_SPARC_GOTDATA_LOX10
should be identical to the computation for R_SPARC_GOTDATA_OP_LOX10.
The distinction is there because the _OP variants
can be treated as normal PIC code relocations
or can be re-written as shown above,
whereas the non-_OP variants
are forced to have their data within +/- 4GB of the GOT pointer,
or else it is a static link time failure.
I believe the right expressions are:
for R_SPARC_GOTDATA*_LOX10: (D & 0x3ff) | ((D >> 32) & 0x1c00)
for R_SPARC_GOTDATA*_HIX22: ((D >> 10) ^ (D >> 32)) & 0x3fffff
In the Studio 11 compilers,
we use the _OP variants only.
In a future release of the compiler,
we intend to start using the plain GOTDATA (non-_OP variants),
where there are some special sections too (SHT_GOTDATA).
Peter.
> Date: Thu, 08 Dec 2005 09:43:29 -0800
> From: Rod Evans <rie at eng.sun.com>
> Subject: Re: [tools-linking] new relocation types with Studio 11, and further
clarification?
> To: Glen Kriekenbeck <Glen.Kriekenbeck at sun.com>
> Cc: tools-linking at opensolaris.org
>
> Glen Kriekenbeck wrote:
>
> > 2. Also, the formulas in Linker and Libraries guide seem to be misleading.
> > For reloc types R_SPARC_GOTDATA_LOX22 and R_SPARC_GOTDATA_OP_LOX22
> > it says:
> >
> > ((S+A-GOT) >> 10) & 0x3ff) | (0x1c00 ^~ (((S+A-GOT) >> 50) & 0x1c00)).
>
> Ok, relocations aren't my strong point, and Mike (who could read all this
> gibberish in his sleep) is no longer a linker engineer. But I looked at
> the L&LM definitions, the comments in doreloc.c, and the original ARC case
> (PSARC/2003/477) and there's certainly a lot of inconsistency. However,
> Mike (now acting in a consulting capacity) kindly poked around the
> implementation details and believes these reflect the calculations actually
> being carried out:
>
> R_SPARC_GOTDATA_HIX22 80 T-imm22
> ((S + A - GOT) >> 10) ^ ((S + A - GOT) >> 31)
>
> R_SPARC_GOTDATA_LOX10 81 T-imm13
> ((S + A - GOT) & 0x3ff) | (((S + A - GOT) >> 31) & 0x1c00)
>
> R_SPARC_GOTDATA_OP_HIX22 82 T-imm22
> (G >> 10) ^ (G >> 31)
>
> R_SPARC_GOTDATA_OP_LOX10 83 T-imm13
> (G & 0x3ff) | ((G >> 31) & 0x1c00)
>
> The ARC case got it wrong in that it used 'G' to represent two things.
> The 'G' is defined to be the offset into the Global Offset Table. What we
> really wanted instead for the first two is the offset from the beginning of
the
> global offset table (which is S + A - GOT).
>
> The added twist is that the R_SPARC_GOTDATA_OP* relocation meaning changes if
> they are binding to local symbols. In that case they use the first formulas
> ((S+A-G)) and then the R_SPARC_GOTDATA_OP instruction get's a fixup.
>
> Hopefully this, and the ARC material will give you the details you need.
>
> Also, there's a couple of compiler folks lurking on this alias who I also
> believe were deeply involved with these relocations, so unless we hear
> differently, I'll assume they agree with the above definitions.
>
> I'll get the L&LM updated to reflect the correct definitions.
>
> --
>
> Rod.
> _______________________________________________
> tools-linking mailing list
> tools-linking at opensolaris.org