[m-dev.] cvs diff: SPARC position-indepenent code
Tyson Richard DOWD
trd at students.cs.mu.oz.au
Sun Feb 9 11:42:23 AEDT 1997
> Hi,
>
> (Um, who's turn is it next? Eeny, meeny, miny, mo... Tyson.)
>
> Tyson, here's another cvs diff for review.
>
> -----------------------------------------------------------------------------
>
> Add support for generation position-independent code on SPARCs.
> (Currently we use non-PIC .so files, which means that although
> they're shared on disk, they're not shared at runtime.)
> Note that this change is not yet enabled -- the code I've added
> will only be used if you compile with `-fpic', but the default
> is still to compile without `-fpic'.
If this suffers the same PIC/non-PIC compatability problems that
we encounter under Linux, it should be documented somewhere (eg
a new README.Sparc or README.Sun).
Also, we should document that -fpic is limited - from the gcc
documentation.
"Such code accesses all constant addresses through a global
offset table (GOT). If the GOT size for the linked executable
exceeds a machine-specific maximum size, you get an error
message from the linker indicating that `-fpic' does not work;
in that case, recompile with `-fPIC' instead. (These maximums
are 16k on the m88k, 8k on the Sparc, and 32k on the m68k and
RS/6000. The 386 has no such limit.)"
I have no idea how large something has to be to break that
limit.
> +
> + /*
> + ** At each entry point, where we may have been jump to from
> + ** code in a difference C file, we need to set up `l7'.
s/difference/different/
> + ** We do this by getting the value the of the IP register using a `call'
> + ** instruction whose target is the very next label; this will
> + ** put the address of the call instruction in register `o7'.
> + ** We then use the value obtained in register `o7' to compute the correct
> + ** value of register `l7' by doing something with _GLOBAL_OFFSET_TABLE_
> + ** (I don't understand the details exactly, this code is
> + ** basically copied from the output of `gcc -fpic -S'.)
> + ** Note that `1f' means the label `1:' following the current
> + ** instruction, and `0b' means the label `0:' before the current
> + ** instruction.
> + */
> + #define INLINE_ASM_FIXUP_REGS \
> + "0:\n" \
> + " call 1f\n" \
> + " nop\n" \
> + "1:\n" \
> + " sethi %hi(_GLOBAL_OFFSET_TABLE_-(0b-.)),%l7\n" \
> + " or %l7,%lo(_GLOBAL_OFFSET_TABLE_-(0b-.)),%l7\n" \
> + " add %l7,%o7,%l7\n" \
> + /* tell gcc we clobber l7, o7, and memory */ \
> + : : : "%l7", "%o7", "memory"
Looks like two 16 bit lookups, somehow using 0b as the index?
Since you loaded the IP of label 0: in l7, you're
looking up an offset to that IP, and adding it.
So GLOBAL_OFFSET_TABLE[ob] is the difference between ob and the context
table for label 0:. Not quite sure what the -(Ob-.) means though.
Looks fine to commit, though, but documentation must be done
before release.
--
Tyson Dowd # Another great idea from the
# people who brought you
trd at .cs.mu.oz.au # Beer Milkshakes!
http://www.cs.mu.oz.au/~trd # Confidence --- Red Dwarf
More information about the developers
mailing list