[fpc-devel] Internal symbols
J. Gareth Moreton
gareth at moreton-family.com
Sun Feb 3 05:08:46 CET 2019
Hi everyone,
So I've come across a couple of issues recently regarding
internally-defined symbols. One of them involves assembly language, which
is always asking for trouble, but one can be triggered through regular
Pascal code.
Basically, if you declare a public symbol (either using the "public"
directive or putting it in the interface section of a unit) with a name
that's identical to an internal symbol (I used "FPC_ABSMASK_DOUBLE"), you
get a 'duplicate symbol' linker error... in fact, Lazarus doesn't even
display the error (see bug #34996) - it only appears if you run the
compiler from the command line.
You can get around the above issue if you simply rename the constant or
keep it private. However, there is one other issue that is not so easy to
circumvent, and that's when you try to call an internal function through
assembly language (in this instance, I'm assuming the code is not
cross-platform and I'll be calling the x86_64 version of fpc_int_real,
which is "nostackframe" and only modifies XMM0 and RAX):
{ Asm is Intel-style }
MOVSD XMM4, [RIP+TwoPi]
MOVSD XMM5, XMM0
DIVSD XMM0, XMM4
CALL fpc_int_real
MULSD XMM0, XMM4
SUBSD XMM5, XMM0
MOVSD XMM0, XMM5
This snippet of code is equivalent to "D := D - (Int(D / TwoPi) *
TwoPi);", effectively a floating-point version of "D mod TwoPi".
The problem here is that fpc_int_real is not found by the compiler...
however, if you attempt to use "CALL int" instead, you get the following
linker error:
"Error: Undefined symbol: SYSTEM_::=::_INT$DOUBLE::=::DOUBLE"
This is because int() is internally changed to fpc_int_real() by the
compiler when it appears in Pascal code. I could just write my own copy
of fpc_int_real, but that defeats the purpose of it somewhat, not least in
that it causes code duplication and hence increases code size and
maintenance issues. An idea is to improve assembler parsing by correctly
changing such symbols to point to their internal counterparts, but this
runs into the issue that some functions, like abs(), are not actually
functions at all when compiled, but become distinct nodes in the PPU files
and translate into direct lines of assembly language (e.g. abs(DValue)
becomes "ANDPD DValue, [RIP+FPC_ABSMASK_DOUBLE]"), and you can't hope to
smartly change "CALL abs" into such a line of code.
I suppose I'm asking for a discussion on this, because there doesn't seem
to be a clean solution to this. Allowing the compiler access to internal
symbols is possible, but probably asking for trouble, while properly
translating assembler calls to internal routines leads to some troublesome
situations. What do you guys think?
Gareth aka. Kit
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-devel/attachments/20190203/4a2af51e/attachment.html>
More information about the fpc-devel
mailing list