[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: RFC: ABI support for special memory area



On Friday 17 March 2017 02:55 AM, H.J. Lu wrote:
>> Since ld.so is not meant only for programs with C style linkage, what if
>> the real implementation library is written in C++ and wants to export
>> only mangled names (interfaces) without any "extern C" kludge? Or is
>> this considered to be a standard C library call just like mmap etc.?
> 
> Only the __gnu_mbind_setup symbol is used.  We can change the
> second argument to "void *data" and make it dependent on memory
> type.  But to support a new memory type, we have to update ld.so.  I'd
> like to use the same ld.so binary to support any memory types even if
> it means that we need to pass info to __gnu_mbind_setup which isn't
> used by all memory types.

Ah! Now I understand the design completely (I think). Looks like Carlos
understood this quite earlier in the discussion.

You are saying that the interface -

int __gnu_mbind_setup (unsigned int type, void *addr, size_t length);

- is fixed in ld.so and also in the real implementation library. And,
the real implementation in turn calls the actual-real-implementation, as
shown in your libmbind code:

int
__gnu_mbind_setup (unsigned int type, void *addr, size_t length)
{
  // in turn calls actual implementation
  return vendor_specific_mbind_setup (vendor specific types);
}


All these while, based on the current description, I was of the
impression that your design allows __gnu_mbind_setup interface itself to
be overridden in the real implementation, something like:

int
__gnu_mbind_setup (__nvm_kmem_t *nvm_obj, void *nvm_handle)
{
  // actual implementation directly here in the body
}

So I was wondering how and hence most of my points were out-of-phase.

>  The question is what the possible info needed
> for all memory types is.

Thats too much to predict right now. And the current interface you
defined also does not seem to be generic. For instance, my NVM
implementation, though not complete, needs a totally different set of
arguments. So going by the current design, I will have to use
__gnu_mbind_setup (unsigned int type, void *addr, size_t length) just to
call my real setup, without using any of the arguments passed by ld.so.

Assuming I am in sync with you now, I would say that the pseudo code I
showed earlier works for you as well as for me as well as for anybody
else. In other words it is more generic.

With that approach, there is

1. No need to update ld.so every time for every new mem type
2. No need to know all possible info needed for all mem types
3. No need to encode all types in the API (as Carlos said)

We just use pointer to implementation interface - struct
__gnu_mbind_context that I showed. And we can have a default struct
instantiated in ld.so and a global pointer pointing to that. And later
the global pointer can be made to point to the vendor specific struct,
before ld.so actually calls __gnu_mbind_setup, thereby completing a
successful override (if necessary, that is when special memory types are
in use).

Or similar mechanisms to override default struct instantiated in ld.so.
There are many well known ways to override the default struct as we all
know.

Personally I think this would be a better way to provide the ABI support
in a generic way.

That said, I am OK to live with minor kludges and we can keep the design
as is.

> 
>> And you may also want to define the flow for fully archive bound static
>> binaries.
> 
> For static executable, __gnu_mbind_setup will be called on all MBIND
> segments before constructors are called.  __gnu_mbind_setup in libc.a
> is weak and will be overridden by the real one in libmbind.a.

Lets add this also in the ABI support document.

--
Supra