<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Apr 9, 2020 at 9:25 AM Gedare Bloom <<a href="mailto:gedare@rtems.org">gedare@rtems.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Wed, Apr 8, 2020 at 10:53 PM Sebastian Huber<br>
<<a href="mailto:sebastian.huber@embedded-brains.de" target="_blank">sebastian.huber@embedded-brains.de</a>> wrote:<br>
><br>
> On 09/04/2020 03:32, Chris Johns wrote:<br>
><br>
> > On 2020-04-09 03:43, Sebastian Huber wrote:<br>
> >> On 08/04/2020 19:34, Jonathan Brandmeyer wrote:<br>
> >>> Instead of treating weak references as a single level of<br>
> >>> indirection, I think you have to treat them as a single overridable<br>
> >>> interface.  In a dynamically-linked application, we might try to<br>
> >>> perform an override using the LD_PRELOAD feature. But in a<br>
> >>> statically-linked application we have to do it differently.  The<br>
> >>> overriding archive must be named in full, and it must be named as an<br>
> >>> object to be linked instead of a library to be searched.<br>
> >>> Furthermore, an interface can have only one override that ends up in<br>
> >>> the linked application.<br>
> >> Yes, you can only have one strong implementation, otherwise you get<br>
> >> multiple definition errors.<br>
> ><br>
> > I have only ever considered weak references as an overridable<br>
> > interface within a user's application and not layered within RTEMS<br>
> > itself. I am not sure about automatic indirection within an archive.<br>
> Yes, this is one use case. You could use also a normal function in a<br>
> separate file to get something similar.<br>
> ><br>
> > In the case of different heap allocators why not have confdefs.h<br>
> > select the one we want and manage the indirection with a const table<br>
> > of pointers?<br>
><br>
> Yes it can be done with new configuration options, however, this would<br>
> be my least favorite choice. I created an example how I would like to<br>
> use weak functions:<br></blockquote><div><br></div><div></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
><br>
> <a href="https://lists.rtems.org/pipermail/devel/2020-April/059196.html" rel="noreferrer" target="_blank">https://lists.rtems.org/pipermail/devel/2020-April/059196.html</a><br>
><br>
Thanks for the code example it was helpful to me. What I understood is that:<br>
1) An internal interface may be declared weakly aliased in RTEMS.<br>
2) Implementations each need to go to a different file.<br>
    * Not clear to me if there can be more than 2: 1 weak, 1 strong?<br></blockquote><div><br></div><div>In the linked application, there will be exactly one implementation.  You can provide objects with as many strong implementations as you like, as long as there is a clear way to distinguish between them at link time.</div><div><br></div>In this specific example, Mr. Huber lead off with the use of a trivial heap definition: Malloc bumps pointers in a pool, and free does nothing.  The other extreme might be a port of jemalloc to RTEMS.  You could implement this with the following layout:</div><div class="gmail_quote"><br></div><div class="gmail_quote">librtemsbsp.a provides the default RTEMS heap.  IIRC it's a single-threaded first-fit search with deferred coalescing.  It provides weak references for all of the heap functions: malloc, calloc, posix_memalign, and so on.  Some of them can be defined in terms of the more general versions.  Instead of hiding that fact as implementation details, they are explicitly documented as such.  That way if someone wants to provide an override for the heap, they know exactly which portions must be replaced, and which portions may be left as their defaults.<br></div><div class="gmail_quote"><br></div><div class="gmail_quote">librtems-heap-trivial.a is scoped to provide overrides of the particular functions that it wishes to make strong, and no others.  It can probably get away with using the default implementations of calloc and posix_memalign.<br></div><div class="gmail_quote"><br></div><div class="gmail_quote">librtems-heap-jemalloc.a does the same thing.  IIRC, it has some special paths set aside for aligned allocation requests, so it would also override the default definition of posix_memalign.<br></div><div class="gmail_quote"><br></div><div class="gmail_quote">All of the heap overriders provide pkg-config files that name the full path to their archives explicitly.  Ie, `pkg-config --libs rtems-heap-trivial` would emit "/rtems_root/target_pair/lib/librtems-heap-trivial.a" instead of "-lrtems-heap-trivial".  Users are explicitly told about this override point, and that --libs should really be treated more like --objs if such an option exists.</div><div class="gmail_quote"><br></div><div class="gmail_quote">Luxury improvement: Teach pkg-config about an --objs flag.<br></div><div class="gmail_quote"><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
3) A strong implementation may be pulled in by invoking a different,<br>
    non-aliased function implemented in the same file as (one of) the<br>
    strong implementations.<br></blockquote><div><br></div><div>A strong implementation may be pulled in by linking one explicitly.  The source of the reference is irrelevant.  There can be as many strong implementations as you like, but mixing both strong and weak implementations in the same archive is not allowed.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
Am I understanding this? I tried to map this to something in OOP but<br>
the abstraction failed somewhere in my cortex. It is almost like an<br>
interface class where you can instantiate objects of only one of the<br>
implementations.<br></blockquote><div><br></div><div>The closest example I can think of is the use of mock objects.  The difference is that the linker is performing the injection and it is for the entire linked program instead of on a per-test basis.<br></div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
I am a little concerned that the approach is fragile still, based on<br>
the discussion about how weak aliases may be resolved dependent upon<br>
link order in command lines, etc.<br></blockquote><div><br></div><div>I don't think there's any way around this.  If you are using weak symbols, the final link state will depend on the order that the linker sees the definitions.<br></div></div><br>-- <br><div dir="ltr" class="gmail_signature">Jonathan Brandmeyer<br>PlanetiQ</div></div>