On Friday 03 July 2015 12:32 AM, Suprateeka R Hegde wrote:
> I found differences between GNU ld and gold
That seems to be some mistake I did. Looks like I have compared with
some other linkers. GNU ld and gold both are same in this regard.
On Friday 03 July 2015 01:59 AM, Cary Coutant wrote:
>>> The gABI doesn't require anything; it simply says that STT_NOTYPE
>>> means that the type is unspecified.
>>
>> So I assume that it is incorrect for gcc(1) to mark an undefined function
>> reference as STT_NOTYPE. I think that is the bug HJ pointed out.
>
> No, I don't think it's incorrect at all. It's merely a
> quality-of-implementation issue:
I agree, but there is a very thin line of differnece between standards
and quality. I would say standards drive the quality.
With so many additions to standards, may it be gABI, psABI, ISO/IEC
C/C++ or anything else, the quality of developer tool chain (that
complies to standards) are great today, compared to what it was
traditionally.
> setting the undef to STT_FUNC or
> STT_OBJECT allows the linker to diagnose a mismatch between reference
> and definition,
Yes, and it indeed helps a lot to know that a function is being bound to
an integer (which makes no sense). Its just like compilers warn/error if
it sees a declaration and definition mismatch in the same translation unit.
BTW, I binary edited and changed STT_NOTYPE of that undefined func to
STT_FUNC. I didnt know what function attribute in gcc(1) would help me
get a STT_FUNC with SHN_UNDEF. Even with that binary change, neither
ld.bfd nor ld.gold warned/diagnosed there is a mismatch. They
successfully bound the STT_FUNC/SHN_UNDEF with STT_OBJECT (from the
shared object) and in the resulting executable, the STT_FUNC/SHN_UNDEF
is changed to STT_OBJECT. And of course SEGV at rutime.
However, I got the expected warning/diagnostic with linkers on HP-UX and
Solaris (SPARC).
On the lighter side of it, I feel compilers are waiting for linkers to
honour type mismatch and linkers are waiting for compilers to emit type
info :-)
> but, traditionally, Unix linkers have always been
> happy to bind symbols without checking types, and I'll bet there's
> still plenty of code that depends on that.
I absolutely agree on the existing code depending on this behavior. But
then we (as compiler-n-linker/runtime developers) do need to improve the
tool-chain to be in-sync with the programming trend.
If I want to claim, yes, XandY are all state-of-the-art compiler and
linker tool chain, then I should ensure that:
- A new engineer working on a huge piece of undocumented legacy code,
should not find a SEGV at runtime, just because an undefined
"is_something_true()", binds to his newly inserted boolean
"is_something_true". The tool chain should warn/diagnose in that case
and aid in the develolment.
- An application developer need not worry too much on the system side of
it. Instead write code for readability and maintainability.
- An application developer should not worry too much if his code affects
for instance, loop-unrolling badly or prevents a
static-to-global-promotion, affects register allocation, etc. Its should
be our responsibility to detect them and advise/warn/diagnose.
I absolutelty agree that standards are not supposed to mandate all these
and they are just quality-of-implementation issues. But then standards
do help in a lot of way to make excellent tool chain. There are
instances where a simple port of code base from KnR C to C99 standards
have removed lots of potential bugs, as the new standard dis-allows
certain ambiguous constructs.
I was actually thinking, just like language standards, why not gABI also
have something like SYSV Generic ABI 98, 99, 2011, 2014, etc? And let
the newer versions be stricter. Let the tool chain implement options
accordingly (something like -gabi=99, -gabi=14, etc). This would not
break legacy code and compatibility.
I also want to know why should symbol resolution and symbol types be
tied to processors? I see that AArch64 ELF ABI says, "any symbol can be
of type STT_NOTYPE...". The AMD64 ABI does not say anything like that. I
agree that symbol handling is coupled with relocations, but something
generic and basic like "do not bind a function to integer" need not be
processor specific. Do I miss anything here?
Or is there any platform where the calling conventions allow binding a
function reference to user defined data (not plt/got/etc) with the fact
that data can hold address of a function?
--
Supra