> I wish I had a better understanding of just what's going on in this > file. Maybe a lot of the hacks can be rewritten in a nicer way. For > instance, do we really need to hijack the return addresses and jump to > init1 in this weird way, only to enable it to access argc/arg0? Since > we know where they are on our stack (__builtin_frame_address (0) + 2 > or something like that), can't we just pass it a pointer? > > Let me actually try just that...
Eh, no, let's start even earlier than that. Please correct me if I (inevitably) get things wrong. _dl_init_first is Hurd-specific. It is called from the assembly code in dl-machine.h, specifically there's a RTLD_START_SPECIAL_INIT macro that's defined to call _dl_init_first on the Hurd, and to nothing otherwise. This RTLD_START_SPECIAL_INIT is used ("invoked") in i386/dl-machine.h, s390/s390-{32,64}/dl-machine.h, ia64/dl-machine.h, and alpha/dl-machine.h (but notably not in x86_64/dl-machine.h). In all cases, it's emphasized that "The special initializer gets called with the stack just as the application's entry point will see it; it can switch stacks if it moves these contents over." But I conclude that: - s390-gnu, ia64-gnu, and alpha-gnu ports are nonexistent, nor are they realistically ever going to happen, so we can ignore them completely - the implementation does not seem to actually switch stacks (in fact, I have removed the unused switch_stacks function in the last commit) -- so the "gets called with the stack just as the application's entry point will see it" property may not be important anymore? The only thing it really needs, it seems, is a pointer to argc/argv/envp & Hurd data block *somewhere*. It does not have to be on the stack (though where else would it be), or immediately preceding its call frame -- all that really matters is that there's a pointer. So my thinking goes, why don't we just hook into _dl_start, which already has this very pointer? And in fact, _dl_start calls _dl_sysdep_start, for which there is already a Hurd version. Can't we just call our logic from there, and not worry about the stack layout and overwriting return addresses? That would work for the SHARED case; we also need to do something for the static case. In that case, we are invoked by static-start.S; do I understand it right that the argc/argv/whatever is still located on-stack even on x86_64 in this case, and not passed in registers according to the calling convention? Then again, we should be able to just use __builtin_frame_address (0) + 2 and avoid most of the hacks? Please tell me if this makes any sense. Sergey