Richard Sandiford <rdsandif...@googlemail.com> writes
> >> 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?

I'm doing just that in my experimental implementation of all this.
 
> If we want to be extra cautious we could define a second set of macros
> alongside the old ones.
> 
> >> 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.

A reasonable point.
 
> 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?

I am working from fragments of information on this aspect still so I need to 
get more clarification from Android developers. My current understanding is 
that native parts of applications are actually shared libraries and form part 
of, but not necessarily the entry to, an application. Since such a shared 
library can't be 'required' by anything it must be loaded explicitly. I'll get 
clarification but the potential need for dynamic mode switching in Android need 
not affect the decision that GNU/Linux takes.
 
> >> 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.

As I understand it the dynamic loader only has specific access to the program 
headers of the executable not the ELF headers. There is no question that the 
dynamic loader has access to DSO ELF headers but we need the start point too.
 
> >> 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?

I was thinking the kernel would set an initial FR mode that was at least 
compatible with the ELF flags. Do you feel all this should be done in user 
space? We only get user mode FR control in MIPS r5 so this would make it more 
challenging to get into FR1 mode for MIPS32r2. I'd prefer not to be able to 
load an FR1 program than crash in the crt while trying to turn it on. There is 
however some expectation that the kernel would trap and emulate UFR on MIPS32r2 
for the dynamic loader case anyway.
 
> 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.

I admit to not being a fan of the CRT having to handle this but it does at 
least guarantee that the environment is matched to the program. I suspect this 
is the way it should be done for bare metal. There are too many bootloaders to 
get them all to do the right thing and/or carry the extra information about 
environment should they have flattened an ELF.

Is it OK to continue these library related discussions here or should I split 
the bare metal handling to newlib and linux libraries to glibc? There is value 
in keeping things together but equally it is perhaps off topic.

Regards,
Matthew


Reply via email to