[PATCH] Don't set TEXT_START_ADDR for MIPS n64

Richard Sandiford rdsandiford@googlemail.com
Mon Jun 30 00:48:00 GMT 2008


"Maciej W. Rozycki" <macro@linux-mips.org> writes:
> On Sun, 29 Jun 2008, Richard Sandiford wrote:
>> My point is that there _is_ a negative impact for pure n64 binaries.
>> As of 4.2, GCC tries to use absolute references in executables if we
>> know it's safe to do so.  For example:
>> 
>>     static int x;
>>     int get_x (void) { return x; }
>> 
>> can use %hi/%lo-style accesses to refer to "x".  It can also use
>> absolute accesses to set up $gp in functions that still need it.
>> 
>> This behaviour (selected by -mno-shared) changes the ABI of ET_REL
>> objects but it does _not_ change the ABI of the final executable.
>> The option simply changes internal details of the executable, such as
>> whether it calls via a JAL instead of via a local GOT entry, or whether
>> it loads a symbol value using %hi and %lo instead of relying on the GOT.
>> GCC 4.3 and above use this mode whenever you configure for sufficiently
>> recent binutils.
>> 
>> When it comes to n64, there is little benefit to using absolute
>> accesses for 64-bit symbols; it is often cheaper to load from the GOT.
>> Thus -mno-shared only does something useful if you compile with -msym32.
>
>  What you are referring to is not a pure n64 binary.  The ABI specifies
> the use of GOT for all symbols, both local and external, by means of
> %got_disp() and %got_page()/%got_ofst() relocations.  As GOT entries are
> 64-bit, there is no visible difference resulting from the exact bit
> pattern stored there.  Anything beyond this is not pure n64, though 
> certainly it can be useful.

You seem to have ignored the distinction I was making between ET_REL
and ET_EXEC.  The use of the GOT for local data is not a part of the
ET_EXEC binary interface, so from an ABI perspective, an ET_EXEC object
created with -msym32 really is a pure n64 binary.

>> So when passed "-mabi=64 -O", GCC 4.3 generates:
>> 
>>         lui     $3,%hi(%neg(%gp_rel(get_x)))
>>         daddu   $3,$3,$25
>>         daddiu  $3,$3,%lo(%neg(%gp_rel(get_x)))
>>         ld      $2,%got_page(x)($3)
>>         j       $31
>>         lw      $2,%got_ofst(x)($2)
>> 
>> When passed "-mabi=64 -O -msym32", GCC 4.3 generates:
>> 
>>         lui     $2,%hi(x)
>>         j       $31
>>         lw      $2,%lo(x)($2)
>> 
>> As I said above, the second version can still produce a pure n64 binary,
>> so -msym32 is already useful for such binaries.  The problem is that
>> you cannot link such an object with the default scripts, because the
>> text address is set so high.  The question then is: should the onus be
>> on users of -msym32 to change the default, or should the onus be on
>> those who want a +4GB start address to change the default?  I think the
>> former is the more user-friendly option.  And I think it's the most
>> friendly option even without the non-PIC support mentioned yesterday,
>> although that does IMO tip the scales even more.
>
>  What I am suggesting is the use of "-msym32" should select an alternative
> linker script.

I think this is an unnecessary complication, given that it is easy
to support both -msym32 and -mno-sym32 with the same linker script.

>> Yes, changing the start address has a user-visible effect, just as
>> changing the number of instructions in (say) printf() has a user-visible
>> effect.  I don't think either changes the ABI.  Nothing should rely on
>> printf() having a certain number of instructions, and nothing should
>> rely on the start address being exactly 120000000.  Code that wants to
>> know the size of printf() should look at the symbol info, and code that
>> wants to know the load addresses should read them from the program headers.
>> I think the ABI simply defines a range of valid load addresses, and the
>> new address is just as valid as the old one.
>
>  Well, if you *have* to change the start address (which is a valid XUSEG
> address) so that the resulting binary is usable at all, then this is a
> serious change of the ABI.

As I said before, -msym32 changes the ABI of ET_REL objects.
It does not change the ABI of ET_EXEC objects.  The linker has
to behave differently to support the different ET_REL ABI,
but the ET_EXEC ABI remains the same.

Richard



More information about the Binutils mailing list