On Wed, May 05, 2010 at 07:58:20PM +0100, Dave Korn wrote: >On 05/05/2010 18:56, Christopher Faylor wrote: > >> I like the idea but I have a few problems with this, some stylistic and >> some implementation. >> >> Stylistic: > > Those all make sense to me, but I won't rework it yet until we've seen your >PoC/discussed further. > >> Implementation: >> >> I don't like keeping a list of "places we know we need to ignore" separate >> from >> the Cygwin DLL. That means that if there is something new added besides >> data/bss >> this function becomes obsolete. >> >> I think this argues for most of this functionality being moved to the >> Cygwin DLL itself so that an application gets improvements for free. I >> should have suggested that when this function first made its way into >> the libcygwin.a (or maybe I did and someone will enlighten me about why that >> won't work). >> >> I'll see I can come up with a proof-of-concept of what I'm talking about >> soon. >> >> Btw, don't we have to worry about data/bss for DLLs too? Is that >> handled by this change or is that not an issue? > > We do have to worry and it is handled. This code gets linked statically >into each DLL and EXE, each instance referring just to its own pseudo-reloc >tables. The Cygwin DLL copies all the data and bss for both DLLs and EXEs (at >process attach time), then they all run their own pseudo-relocs (at first >thread attach time).
Yeah, I realized that two seconds after sending the message. However, is this particular problem really an issue for DLLs? DLLs should get their data/bss updated after _pei386_runtime_relocator() is called. So it seems like you'd get the same thing being written twice. It's not optimal but it shouldn't be fatal. The program's data/bss is different since that gets copied during DLL initialization and before _pei386_runtime_relocator() is (was) called. So I could see how it could be screwed up. > So we could move the core __write_memory and do_pseudo_relocs routines into >the DLL, and adjust the code in _cygwin_crt0_common to pass the per_process >struct to _pei386_runtime_relocator which could pass it and the reloc list >start/end pointers through to the code in the DLL, and it could then be code >in the DLL that knows which memory ranges it copied and should avoid >re-relocating. That's basically it and I have it more-or-less coded but I haven't finished thinking about DLLs. Maybe that's more complication than is warranted. I have to do more research there. We could, and I think should, put most of the code in pseudo_reloc.c in cygwin1.dll, though, rather than duplicate it in every source file. >Is that the kind of structure you were thinking of? The problem I saw >with any kind of approach based on actually knowing which ranges were >actually copied (as opposed to simply inferring that it was the data >and bss sections between their start and end labels) is that that all >takes place in the parent rather than the child, so how to communicate >it to the child where the relocating is taking place would be pretty >tricky, I thought. This information is all recorded for fork() so it should be doable. It is more complicated to do it outside of the program but, like I said, it allows us to fix problems by a new release of the DLL rather than telling people "You must relink your program". cgf