Matthew Fortune <matthew.fort...@imgtec.com> writes:
> Richard Sandiford <rdsandif...@googlemail.com> writes
>> I understand the need to deprecate the current -mgp32 -mfp64 behaviour.
>> I don't think we should deprecate -mfp64 itself though.  Instead, why
>> not keep -mfp32 as meaning FR0, -mfp64 meaning FR1 and add -mfpxx for
>> modeless?  So rather than deprecating the -mgp32 -mfp64 combination and
>> adding -mfr, we'd just make -mgp32 -mfp64 generate the new FR1 form in
>> which the odd-numbered registers are call-clobbered rather than the old
>> form in which they were call-saved.
>
> Extreme caution is the only reason why the design avoided changing fp64
> behaviour (basically in case anyone had serious objection). If you would
> be happy with a change of behaviour for -mgp32 -mfp64 then that is a
> great start.

Yeah, my first impression is that keeping the current interface would
be much better than adding a new set of options.

>> AIUI the old form never really worked reliably due to things like
>> newlib's setjmp not preserving the odd-numbered registers, so it doesn't
>> seem worth keeping around.  Also, the old form is identified by the GNU
>> attribute (4, 4) so it'd be easy for the linker to reject links between
>> the old and the new form.
>
> That is true. You will have noticed a number of changes over recent
> months to start fixing fp64 as currently defined but having found this
> new solution then such fixes are no longer important. The lack of
> support for gp32 fp64 in linux is further reason to permit redefining
> it. Would you be happy to retain the same builtin defines for FP64 if
> changing its behaviour (i.e. __mips_fpr=64)?

I think that should be OK.  I suppose a natural follow-on question
is what __mips_fpr should be for -mfpxx.  Maybe just 0?

If we want to be extra cautious we could define a second set of macros
alongside the old ones.

>> The scheme allows an ifunc to request a mode and effectively gives the
>> choice to the firstcomer.  Every other ifunc then has to live with the
>> choice.  I don't think that's a good idea, since the order that ifuncs
>> are called isn't well-defined or under direct user control.
>> 
>> Since ifuncs would have to live with a choice made by other ifuncs, in
>> practice they must all be prepared to deal with FR=1 if linked into a
>> fully-modeless or FR1 program, and to deal with FR=0 if linked into a
>> fully-modeless or FR0 program.  So IMO the dynamic linker should simply
>> set FR=1 for modeless programs if the hardware supports it and set it to
>> 0 for modeless programs otherwise, like you say in the first paragraph
>> of 9.4.
>
> The ifunc interaction should possibly be moved to a different
> proposal. We could reduce this down to a simple statement that
> interaction with ifunc needs to be considered when finalising MIPS ifunc
> support in general.

Sounds good.

>> You allow the mode to be changed midexecution if a new FR0 or FR1 object
>> is loaded.  Is it really worth supporting that though?
>> It has the same problem as the ifuncs: once you've dlopen()ed an object,
>> you fix the mode for the whole program, even after the dlclose().
>> Unless we know of specific cases where this is needed, maybe it would be
>> safer to fix the mode before execution based on DT_NEEDED libraries and
>> allow the mode of modeless programs to be overridden by an environment
>> variable.
>
> Scanning the entire set of DT_NEEDED libraries would achieve most of
> what full dynamic mode switching gives us, it is essentially the first
> stage of the dynamic mode switching described in the proposal
> anyway. However, I am concerned about excluding dlopen()ed objects from
> mode selection though (not so worried about excluding ifunc, that could
> just fix the mode before resolving the first one). One specific concern
> is for Android where I believe we have the situation where native
> applications are loaded as (a form of) shared library. This means a mode
> requirement can be introduced late on. In an Android environment it is
> unlikely to be acceptable to have to do something special to load an
> application that happens to have a specific mode requirement so dynamic
> selection is useful. This is more of a transitional problem than
> anything but making it a smooth process is quite important. I'm also not
> sure that there is much more effort required for a dynamic linker to
> take account of dlopen()ed objects in addition to DT_NEEDED, changes are
> needed in this code regardless.

As far as GNU/Linux goes, if we do end up with a function in something
like a modeless libm that is implemented as an FR-aware ifunc, that would
force the choice to be made early anyway.  So we have this very specific
case where everything in the initial process is modeless, no ifuncs take
advantage of the FR setting, and a dlopen()ed object was compiled as fr0
rather than modeless.  I agree it's possible but it seems unlikely.

I know nothing about the way Android loading works though. :-)
Could you describe it in more detail?  Is it significantly different
from glibc's dynamic loader running a PIE?

>> If we do end up using ELF flags then maybe adding two new EF_MIPS_ABI
>> enums would be better.  It's more likely to be trapped by old loaders
>> and avoids eating up those precious remaining bits.
>
> Sound's reasonable but I'm still trying to determine how this
> information can be propagated from loader to dynamic loader.

The dynamic loader has access to the ELF headers so I didn't think
it would need any help.

>> You didn't say specifically how a static program's crt code would know
>> whether it was linked as modeless or in a specific FR mode.
>> Maybe the linker could define a special hidden symbol?
>
> Why do you say crt rather than dlopen? The mode requirement should only
> matter if you want to change it and dlopen should be able to access
> information in the same way that a dynamic linker would. It may seem
> redundant but perhaps we end up having to mark an executable with mode
> requirements in two ways. The primary one being the ELF flag and the
> secondary one being a processor specific program header. The ELF flags
> are easy to use/already used for the program loader and when scanning
> the needs of an object being loaded, but the program header is something
> that is easy to inspect for an already-loaded object. Overall though, a
> new program header would be sufficient in all cases, with a few
> modifications here and there.

Sorry, what I meant was: how would an executable built with -static
be handled?  And I was assuming it would be up to the executable's
startup code to set the FR mode.  That startup code (from glibc)
would normally be modeless itself but would need to know whether
any FR0 or FR1 objects were linked in.  (FWIW ifuncs have a similar
problem: without the loader to help, the startup code has to resolve
the ifuncs itself.  The static linker defines special symbols around
a block of IRELATIVE relocs and then the startup code applies those
relocs in a similar way to the dynamic linker.  I was thinking a
linker-defined symbol could be used to record the FR mode too.)

But perhaps you were thinking of getting the kernel to set the FR mode
instead?

The same problem would apply to bare-metal though.  I suppose you
could put the onus on the bootloader to set the FR mode based on
the ELF flags, but the current libgloss approach is that bare-metal
programs should set their environment themselves.  E.g. libgloss's
crt0.S tries to detect whether an FPU is actually present, although
I'm doubtful how useful that is.

Thanks,
Richard

Reply via email to