Am 11.09.23 um 13:01 schrieb Jeremie Courreges-Anglas:

This diff and the previous one were likely mangled by your MUA.  There
are hints available: 
https://www.kernel.org/doc/html/latest/process/email-clients.html
Or you may just send diffs as attachments (inline is still preferred).

Ah, sorry about that. I'll double check next time.

Using /usr/src/lib/check_sym I can spot:

/usr/local/lib/libobjfwtls.so.0.0 --> 
/usr/obj/pobj/objfw-1.0.2/fake-amd64/usr/local/lib/libobjfwtls.so.0.0
Dynamic export changes:
added:
         .objc_sel_nameof_isWaitingForDelimiter

Applying blindly our rules for shared libraries, this would warrant
a minor bump because of the additional interface.  But maybe the initial
'.' in the name means it's a local, private symbol?  nm -g tells me it's
a weak symbol so with public visibility.  Insights welcome.

Nope, this shouldn't be a bump. libobjfwtls.so.0.0 subclasses OFTLSStream from libobjfw.so.0.0 as OFOpenSSLTLSStream. What's new is that it overrides the private method of_isWaitingForDelimiter. It shouldn't override a private method, yes, but for now, that is the fix without changing the API/ABI and can be done since I control both libs. This works due to the dynamic dispatch. The .objc_sel_nameof_isWaitingForDelimiter is merely a new symbol that provides the string for the selector that gets registered with the runtime so it can be overridden. It's references by the .objc_method_list that is in turn referenced by the class structure that is in turn referenced by the ObjC module that is passed to __objc_exec via a constructor to register all classes, categories and selectors in the module with the runtime.

libobjfwtls in turn sets the global variable OFTLSStreamImplementation in libobjfw via the +load method of OFOpenSSLTLSStream, which in turn gets called by the runtime via this chain started by __objc_exec, at which point libobjfw knows to use OFOpenSSLTLSStream when an OFTLSStream is requested. The only way someone interfaces with libobjfwtls is by linking it in and not referencing any symbols from it.

Hope that explains :). All these structures are emitted by the compiler automatically. You can find a declaration of those structs emitted by the compiler here: https://objfw.nil.im/file?name=src/runtime/private.h&ci=trunk

Or, tl;dr: A method that existed before was overridden in a subclass. Because ObjC uses dynamic dispatch, this symbol is never referenced, as all method calls are dispatched via the runtime. But the metadata changes so the runtime knows this method is now overridden - without accessing that symbol.

--
Jonathan

Reply via email to