* Importing a variable from a DLL @ 1999-08-25 15:38 James Stern 1999-08-25 23:29 ` Mumit Khan 1999-08-31 23:49 ` James Stern 0 siblings, 2 replies; 16+ messages in thread From: James Stern @ 1999-08-25 15:38 UTC (permalink / raw) To: cygwin The last time I posted to this list, I was asking a question about a mysterious symbol, _size_of_stack_reserve__, that gdb mentioned when my program crashed. Mumit Khan explained that this simply meant the code had a bug elsewhere. I looked and sure enough, I found an extern variable that the DLL defines and the main executable (main.exe) uses. Declaring the variable __declspec (dllimport) in the appropriate source file solved that. But then I reran the program and encountered the same problem with another variable. So I hunted for documentation on dllimport. I found only a few lines in full-man/info/* but more in the MSVC documentation. As I understand it, the situtation is this: Suppose that source file s1.cc used in main.exe references extern variable v1 from the DLL. Then s1.cc has to declare v1 as __declspec (dllimport). If s2.cc through s20.cc also use v1, they must do likewise. If this is true, I'll have to change about 140 declarations in the legacy application I'm porting. Each will need a macro, M, that expands to either __declspec (dllimport) or to nothing. These declarations appear in header files so I'll also have to properly define M in every source file that includes one of these headers. Is there an easier way to do this? For example, is there a way to specify at link time that a variable is imported? I realize that the application has too many extern variables but it's legacy and not mine to rewrite. I also realize that fixups of this nature are harder to do for variables than for functions but I thought I should doublecheck anyway. Thank you. === -- Opinions expressed above are not necessarily my employer's. James M. Stern ITG Inc. Culver City, CA (213) 270-7955 __________________________________________________ Do You Yahoo!? Bid and sell for free at http://auctions.yahoo.com -- Want to unsubscribe from this list? Send a message to cygwin-unsubscribe@sourceware.cygnus.com ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Importing a variable from a DLL 1999-08-25 15:38 Importing a variable from a DLL James Stern @ 1999-08-25 23:29 ` Mumit Khan 1999-08-26 3:33 ` Re[2]: " Paul Sokolovsky 1999-08-31 23:49 ` Mumit Khan 1999-08-31 23:49 ` James Stern 1 sibling, 2 replies; 16+ messages in thread From: Mumit Khan @ 1999-08-25 23:29 UTC (permalink / raw) To: stern; +Cc: cygwin James Stern <jsternitg@yahoo.com> writes: > > As I understand it, the situtation is this: Suppose > that source file s1.cc used in main.exe references > extern variable v1 from the DLL. Then s1.cc has to > declare v1 as __declspec (dllimport). If s2.cc > through s20.cc also use v1, they must do likewise. > > If this is true, I'll have to change about 140 > declarations in the legacy application I'm porting. > Each will need a macro, M, that expands to either > __declspec (dllimport) or to nothing. > > These declarations appear in header files so I'll also > have to properly define M in every source file that > includes one of these headers. > > Is there an easier way to do this? For example, is > there a way to specify at link time that a variable is > imported? Not really. I did research this issue when I first started the dllimport/dllexport implemention, but came to the conclusion that it just won't work given how DLLs work. There is no silver bullet, sorry. Most software suffer from the unfortunate reality of bad modularization, and it gets in the way of making DLLs since the "ownership" of symbols are spread across headers shared by various modules. Languages like C require extra care, which just makes matters worse. My first lecture in a corporate software engr course I used to teach involved long boring discussions on the importance of design before writing the first line of code. One essential, and often overlooked, part of the design process is the layout of the modules in terms of files (since files are what we typically use in most implementations). Too bad that I myself often break that guideline on a regular basis. > I realize that the application has too many extern > variables but it's legacy and not mine to rewrite. First thing I do is to make sure no implementation file (eg., C and C++ files, not headers) *ever* use extern statements, and that each header belongs to one particular module. If your source files do contain extern decls, something is wrong and needs to be handled. My last group had the misfortune of porting a project of few million lines of C++, with a bit of C glue, and we had two engineers working 50% of the time tackling these issues. We did manage to turn all of the 50+ shared libraries into DLLs, but it was a long fight. > I also realize that fixups of this nature are harder > to do for variables than for functions but I thought I > should doublecheck anyway. Functions are trivial to handle via thunks (via import libraries created by dlltool or implib or some such tool); it's the variables that you have to worry about, which have no traditional way to "fix up" in the DLL model. You'll just have to deal with it. I know of one case where the developers talked about writing a custom PE loader to deal with this (at the expense of compatibility of existing tools), but that project never saw daylight outside of the South Bay cafes. Bearer of bad news, Mumit -- Want to unsubscribe from this list? Send a message to cygwin-unsubscribe@sourceware.cygnus.com ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re[2]: Importing a variable from a DLL 1999-08-25 23:29 ` Mumit Khan @ 1999-08-26 3:33 ` Paul Sokolovsky 1999-08-26 6:41 ` Mumit Khan 1999-08-31 23:49 ` Paul Sokolovsky 1999-08-31 23:49 ` Mumit Khan 1 sibling, 2 replies; 16+ messages in thread From: Paul Sokolovsky @ 1999-08-26 3:33 UTC (permalink / raw) To: Mumit Khan, James Stern; +Cc: cygwin Hello Mumit, Mumit Khan <khan@xraylith.wisc.EDU> wrote: MK> There is no silver bullet, sorry. [] MK> Functions are trivial to handle via thunks (via import MK> libraries created by dlltool or implib or some such tool); MK> it's the variables that you have to worry about, which have MK> no traditional way to "fix up" in the DLL model. But at least there might be achieved proper diagnostics of such issues, if dlltool would correctly mark data symbols in def, that implib would only contain __imp_<symbol> and not <symbol>, and we'd get link error when linking with object which doesn't have __declspec(dllimport) on that symbol, and not runtime segfaults, as we have now. MK> You'll just have to deal with it. MK> I know of one case where the developers talked about writing MK> a custom PE loader to deal with this (at the expense of MK> compatibility of existing tools), but that project never saw MK> daylight outside of the South Bay cafes. It would be better just use ELF and forget about all the gore. But rules defined by others. MK> Bearer of bad news, MK> Mumit Best regards, Paul mailto:paul-ml@is.lg.ua -- Want to unsubscribe from this list? Send a message to cygwin-unsubscribe@sourceware.cygnus.com ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Re[2]: Importing a variable from a DLL 1999-08-26 3:33 ` Re[2]: " Paul Sokolovsky @ 1999-08-26 6:41 ` Mumit Khan 1999-08-26 8:05 ` Re[4]: " Paul Sokolovsky 1999-08-31 23:49 ` Re[2]: " Mumit Khan 1999-08-31 23:49 ` Paul Sokolovsky 1 sibling, 2 replies; 16+ messages in thread From: Mumit Khan @ 1999-08-26 6:41 UTC (permalink / raw) To: Paul Sokolovsky, James Stern, cygwin Paul Sokolovsky <paul-ml@is.lg.ua> writes: > > But at least there might be achieved proper diagnostics of such > issues, if dlltool would correctly mark data symbols in def, that > implib would only contain __imp_<symbol> and not <symbol>, and we'd > get link error when linking with object which doesn't have > __declspec(dllimport) on that symbol, and not runtime segfaults, > as we have now. Sure, but it doesn't solve James' problem. If James could create the import libraries with all the data marked DATA, it would imply he already *knows* which these data items are! Once you know, one tricky part of porting a legacy application over -- after this, it's a matter of searching for the symbol names and attaching dllimport attribute in user code. However, your point is well taken that we should go and fix dlltool. I believe I did fix it locally at one point, but definitely didn't submit the changes (don't remember why, perhaps it didn't work). Contributions welcome of course. > It would be better just use ELF and forget about all the gore. > But rules defined by others. Welcome to real life. Regards, Mumit -- Want to unsubscribe from this list? Send a message to cygwin-unsubscribe@sourceware.cygnus.com ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re[4]: Importing a variable from a DLL 1999-08-26 6:41 ` Mumit Khan @ 1999-08-26 8:05 ` Paul Sokolovsky 1999-08-26 23:10 ` Mumit Khan 1999-08-31 23:49 ` Paul Sokolovsky 1999-08-31 23:49 ` Re[2]: " Mumit Khan 1 sibling, 2 replies; 16+ messages in thread From: Paul Sokolovsky @ 1999-08-26 8:05 UTC (permalink / raw) To: Mumit Khan, Anders Norlander, James Stern; +Cc: cygwin Hello Mumit, Mumit Khan <khan@xraylith.wisc.EDU> wrote: MK> Paul Sokolovsky <paul-ml@is.lg.ua> writes: >> >> But at least there might be achieved proper diagnostics of such >> issues, if dlltool would correctly mark data symbols in def, that >> implib would only contain __imp_<symbol> and not <symbol>, and we'd >> get link error when linking with object which doesn't have >> __declspec(dllimport) on that symbol, and not runtime segfaults, >> as we have now. MK> Sure, but it doesn't solve James' problem. If James could create the MK> import libraries with all the data marked DATA, it would imply he MK> already *knows* which these data items are! I am still feeling misunderstood. Let me go with it once again, with examples. So, dlltool has ability to create implib from def - it's all nice with it, it supports DATA, sure. But it has ability to dump all defined symbols into def file - about this operation I am talking. So, suppose we have library of ---a.h extern int data; int code(); ---- ---a.c int data; int code() { return 0; } ---- We compile a: gcc -c a.c And now creating def of it: dlltool a.o --export-all --output-def a.def What we now get is: ---a.def ; G:\GCC-2.95\BIN\DLLTOOL.EXE --export-all --output-def a.def a.o EXPORTS data @ 1 ; code @ 2 ; ---- and it's bad! Suppose we'd get instead ---a.def ; G:\GCC-2.95\BIN\DLLTOOL.EXE --export-all --output-def a.def a.o EXPORTS data @ 1 DATA; code @ 2 ; ---- We create implib from that: dlltool --def a.def --ouput-lib liba.a And then compile client application: ---client.c #include "a.h" int main() { data=1; } ---- When we link it gcc client.o -la What we get? Of course, "client.c: undefined reference to `data'"! We now grepping, finding out that 'a.h' declares that 'data' and tag it __declspec(dllimport). Repeat while needed. So, it doesn't solve problem we're talking about automagically, but it defines clean procedure, which, while being incremental, will converge fast. Much faster than having to catch segfaults for hours and then having users complain of occasional ones for months, as we have now. MK> Regards, MK> Mumit Best regards, Paul mailto:paul-ml@is.lg.ua -- Want to unsubscribe from this list? Send a message to cygwin-unsubscribe@sourceware.cygnus.com ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Re[4]: Importing a variable from a DLL 1999-08-26 8:05 ` Re[4]: " Paul Sokolovsky @ 1999-08-26 23:10 ` Mumit Khan 1999-08-27 8:00 ` Re[6]: " Paul Sokolovsky 1999-08-31 23:49 ` Re[4]: " Mumit Khan 1999-08-31 23:49 ` Paul Sokolovsky 1 sibling, 2 replies; 16+ messages in thread From: Mumit Khan @ 1999-08-26 23:10 UTC (permalink / raw) To: Paul Sokolovsky; +Cc: Anders Norlander, James Stern, cygwin Paul Sokolovsky <paul-ml@is.lg.ua> writes: > > I am still feeling misunderstood. Let me go with it once again, > with examples. > > So, dlltool has ability to create implib from def - it's all nice > with it, it supports DATA, sure. No, no, I do get your point. And, it's a very good one that I had ignored earlier in this thread. I'm currently adding changes to GCC so that exported data items have the correct "data" tag in the .drectve section. This will enable us to handle this in dlltool and dllwrap when the import libraries are created. I'll hopefully test the gcc and dlltool changes this weekend (it's pretty trivial). With this change, you can do the following: /* dll file. */ __declspec(dllexport) int exported_var; __declspec(dllexport) void exported_fund () { } /* end dll file. */ $ gcc -c dll.c $ dllwrap -o foo.dll --output-lib libfoo.a dll.o Now the import library will have what Paul suggests. Regards, Mumit -- Want to unsubscribe from this list? Send a message to cygwin-unsubscribe@sourceware.cygnus.com ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re[6]: Importing a variable from a DLL 1999-08-26 23:10 ` Mumit Khan @ 1999-08-27 8:00 ` Paul Sokolovsky 1999-08-27 8:17 ` Mumit Khan 1999-08-31 23:49 ` Paul Sokolovsky 1999-08-31 23:49 ` Re[4]: " Mumit Khan 1 sibling, 2 replies; 16+ messages in thread From: Paul Sokolovsky @ 1999-08-27 8:00 UTC (permalink / raw) To: Mumit Khan; +Cc: cygwin Hello Mumit, Mumit Khan <khan@xraylith.wisc.EDU> wrote: MK> I'm currently adding changes to GCC so that exported data items have MK> the correct "data" tag in the .drectve section. This will enable us MK> to handle this in dlltool and dllwrap when the import libraries are MK> created. I'll hopefully test the gcc and dlltool changes this weekend MK> (it's pretty trivial). I also made mine, it requires changing only dlltool.c: (against b20 distribution) *** dlltool.c.org Tue Oct 27 03:04:10 1998 --- dlltool.c Thu Aug 26 22:31:32 1999 *************** *** 1144,1149 **** --- 1144,1150 ---- { asymbol *sym; const char *symbol_name; + int data; sym = bfd_minisymbol_to_symbol (abfd, false, from, store); if (sym == NULL) *************** *** 1153,1166 **** if (bfd_get_symbol_leading_char (abfd) == symbol_name[0]) ++symbol_name; ! def_exports (xstrdup (symbol_name) , 0, -1, 0, 0, 0); if (add_stdcall_alias && strchr (symbol_name, '@')) { char *exported_name = xstrdup (symbol_name); char *atsym = strchr (exported_name, '@'); *atsym = '\0'; ! def_exports (exported_name, xstrdup (symbol_name), -1, 0, 0, 0); } } } --- 1154,1171 ---- if (bfd_get_symbol_leading_char (abfd) == symbol_name[0]) ++symbol_name; ! /* Don't use bfd_decode_symclass() - remember, symbols with constant ! values dumped to code section */ ! data = !(sym->flags&BSF_FUNCTION); ! ! def_exports (xstrdup (symbol_name) , 0, -1, 0, 0, data); if (add_stdcall_alias && strchr (symbol_name, '@')) { char *exported_name = xstrdup (symbol_name); char *atsym = strchr (exported_name, '@'); *atsym = '\0'; ! def_exports (exported_name, xstrdup (symbol_name), -1, 0, 0, data); } } } MK> Now the import library will have what Paul suggests. MK> Regards, MK> Mumit Best regards, Paul mailto:paul-ml@is.lg.ua -- Want to unsubscribe from this list? Send a message to cygwin-unsubscribe@sourceware.cygnus.com ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Re[6]: Importing a variable from a DLL 1999-08-27 8:00 ` Re[6]: " Paul Sokolovsky @ 1999-08-27 8:17 ` Mumit Khan 1999-08-31 23:49 ` Mumit Khan 1999-08-31 23:49 ` Paul Sokolovsky 1 sibling, 1 reply; 16+ messages in thread From: Mumit Khan @ 1999-08-27 8:17 UTC (permalink / raw) To: Paul Sokolovsky; +Cc: cygwin Paul Sokolovsky <paul-ml@is.lg.ua> writes: > > I also made mine, it requires changing only dlltool.c: (against > b20 distribution) > > *** dlltool.c.org Tue Oct 27 03:04:10 1998 > --- dlltool.c Thu Aug 26 22:31:32 1999 > *************** > *** 1144,1149 **** > --- 1144,1150 ---- > { > asymbol *sym; > const char *symbol_name; > + int data; > > sym = bfd_minisymbol_to_symbol (abfd, false, from, store); > if (sym == NULL) > *************** > *** 1153,1166 **** > if (bfd_get_symbol_leading_char (abfd) == symbol_name[0]) > ++symbol_name; > > ! def_exports (xstrdup (symbol_name) , 0, -1, 0, 0, 0); > > if (add_stdcall_alias && strchr (symbol_name, '@')) > { > char *exported_name = xstrdup (symbol_name); > char *atsym = strchr (exported_name, '@'); > *atsym = '\0'; > ! def_exports (exported_name, xstrdup (symbol_name), -1, 0, 0, 0); > } > } > } > --- 1154,1171 ---- > if (bfd_get_symbol_leading_char (abfd) == symbol_name[0]) > ++symbol_name; > > ! /* Don't use bfd_decode_symclass() - remember, symbols with constant > ! values dumped to code section */ > ! data = !(sym->flags&BSF_FUNCTION); > ! > ! def_exports (xstrdup (symbol_name) , 0, -1, 0, 0, data); > > if (add_stdcall_alias && strchr (symbol_name, '@')) > { > char *exported_name = xstrdup (symbol_name); > char *atsym = strchr (exported_name, '@'); > *atsym = '\0'; > ! def_exports (exported_name, xstrdup (symbol_name), -1, 0, 0, data); > } > } > } > Thanks. This is only a partial solution for --export-all case. The other one is handled by looking at .drectve section for symbols exported explicitly via dllexport attribute. See scan_drectve_symbols in dlltool.c. A small GCC change is necessary to support that one. btw, please use the -p option when creating diffs; it helps to see the function name in the patch. Regards, Mumit -- Want to unsubscribe from this list? Send a message to cygwin-unsubscribe@sourceware.cygnus.com ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Re[6]: Importing a variable from a DLL 1999-08-27 8:17 ` Mumit Khan @ 1999-08-31 23:49 ` Mumit Khan 0 siblings, 0 replies; 16+ messages in thread From: Mumit Khan @ 1999-08-31 23:49 UTC (permalink / raw) To: Paul Sokolovsky; +Cc: cygwin Paul Sokolovsky <paul-ml@is.lg.ua> writes: > > I also made mine, it requires changing only dlltool.c: (against > b20 distribution) > > *** dlltool.c.org Tue Oct 27 03:04:10 1998 > --- dlltool.c Thu Aug 26 22:31:32 1999 > *************** > *** 1144,1149 **** > --- 1144,1150 ---- > { > asymbol *sym; > const char *symbol_name; > + int data; > > sym = bfd_minisymbol_to_symbol (abfd, false, from, store); > if (sym == NULL) > *************** > *** 1153,1166 **** > if (bfd_get_symbol_leading_char (abfd) == symbol_name[0]) > ++symbol_name; > > ! def_exports (xstrdup (symbol_name) , 0, -1, 0, 0, 0); > > if (add_stdcall_alias && strchr (symbol_name, '@')) > { > char *exported_name = xstrdup (symbol_name); > char *atsym = strchr (exported_name, '@'); > *atsym = '\0'; > ! def_exports (exported_name, xstrdup (symbol_name), -1, 0, 0, 0); > } > } > } > --- 1154,1171 ---- > if (bfd_get_symbol_leading_char (abfd) == symbol_name[0]) > ++symbol_name; > > ! /* Don't use bfd_decode_symclass() - remember, symbols with constant > ! values dumped to code section */ > ! data = !(sym->flags&BSF_FUNCTION); > ! > ! def_exports (xstrdup (symbol_name) , 0, -1, 0, 0, data); > > if (add_stdcall_alias && strchr (symbol_name, '@')) > { > char *exported_name = xstrdup (symbol_name); > char *atsym = strchr (exported_name, '@'); > *atsym = '\0'; > ! def_exports (exported_name, xstrdup (symbol_name), -1, 0, 0, data); > } > } > } > Thanks. This is only a partial solution for --export-all case. The other one is handled by looking at .drectve section for symbols exported explicitly via dllexport attribute. See scan_drectve_symbols in dlltool.c. A small GCC change is necessary to support that one. btw, please use the -p option when creating diffs; it helps to see the function name in the patch. Regards, Mumit -- Want to unsubscribe from this list? Send a message to cygwin-unsubscribe@sourceware.cygnus.com ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re[6]: Importing a variable from a DLL 1999-08-27 8:00 ` Re[6]: " Paul Sokolovsky 1999-08-27 8:17 ` Mumit Khan @ 1999-08-31 23:49 ` Paul Sokolovsky 1 sibling, 0 replies; 16+ messages in thread From: Paul Sokolovsky @ 1999-08-31 23:49 UTC (permalink / raw) To: Mumit Khan; +Cc: cygwin Hello Mumit, Mumit Khan <khan@xraylith.wisc.EDU> wrote: MK> I'm currently adding changes to GCC so that exported data items have MK> the correct "data" tag in the .drectve section. This will enable us MK> to handle this in dlltool and dllwrap when the import libraries are MK> created. I'll hopefully test the gcc and dlltool changes this weekend MK> (it's pretty trivial). I also made mine, it requires changing only dlltool.c: (against b20 distribution) *** dlltool.c.org Tue Oct 27 03:04:10 1998 --- dlltool.c Thu Aug 26 22:31:32 1999 *************** *** 1144,1149 **** --- 1144,1150 ---- { asymbol *sym; const char *symbol_name; + int data; sym = bfd_minisymbol_to_symbol (abfd, false, from, store); if (sym == NULL) *************** *** 1153,1166 **** if (bfd_get_symbol_leading_char (abfd) == symbol_name[0]) ++symbol_name; ! def_exports (xstrdup (symbol_name) , 0, -1, 0, 0, 0); if (add_stdcall_alias && strchr (symbol_name, '@')) { char *exported_name = xstrdup (symbol_name); char *atsym = strchr (exported_name, '@'); *atsym = '\0'; ! def_exports (exported_name, xstrdup (symbol_name), -1, 0, 0, 0); } } } --- 1154,1171 ---- if (bfd_get_symbol_leading_char (abfd) == symbol_name[0]) ++symbol_name; ! /* Don't use bfd_decode_symclass() - remember, symbols with constant ! values dumped to code section */ ! data = !(sym->flags&BSF_FUNCTION); ! ! def_exports (xstrdup (symbol_name) , 0, -1, 0, 0, data); if (add_stdcall_alias && strchr (symbol_name, '@')) { char *exported_name = xstrdup (symbol_name); char *atsym = strchr (exported_name, '@'); *atsym = '\0'; ! def_exports (exported_name, xstrdup (symbol_name), -1, 0, 0, data); } } } MK> Now the import library will have what Paul suggests. MK> Regards, MK> Mumit Best regards, Paul mailto:paul-ml@is.lg.ua -- Want to unsubscribe from this list? Send a message to cygwin-unsubscribe@sourceware.cygnus.com ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Re[4]: Importing a variable from a DLL 1999-08-26 23:10 ` Mumit Khan 1999-08-27 8:00 ` Re[6]: " Paul Sokolovsky @ 1999-08-31 23:49 ` Mumit Khan 1 sibling, 0 replies; 16+ messages in thread From: Mumit Khan @ 1999-08-31 23:49 UTC (permalink / raw) To: Paul Sokolovsky; +Cc: Anders Norlander, James Stern, cygwin Paul Sokolovsky <paul-ml@is.lg.ua> writes: > > I am still feeling misunderstood. Let me go with it once again, > with examples. > > So, dlltool has ability to create implib from def - it's all nice > with it, it supports DATA, sure. No, no, I do get your point. And, it's a very good one that I had ignored earlier in this thread. I'm currently adding changes to GCC so that exported data items have the correct "data" tag in the .drectve section. This will enable us to handle this in dlltool and dllwrap when the import libraries are created. I'll hopefully test the gcc and dlltool changes this weekend (it's pretty trivial). With this change, you can do the following: /* dll file. */ __declspec(dllexport) int exported_var; __declspec(dllexport) void exported_fund () { } /* end dll file. */ $ gcc -c dll.c $ dllwrap -o foo.dll --output-lib libfoo.a dll.o Now the import library will have what Paul suggests. Regards, Mumit -- Want to unsubscribe from this list? Send a message to cygwin-unsubscribe@sourceware.cygnus.com ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re[4]: Importing a variable from a DLL 1999-08-26 8:05 ` Re[4]: " Paul Sokolovsky 1999-08-26 23:10 ` Mumit Khan @ 1999-08-31 23:49 ` Paul Sokolovsky 1 sibling, 0 replies; 16+ messages in thread From: Paul Sokolovsky @ 1999-08-31 23:49 UTC (permalink / raw) To: Mumit Khan, Anders Norlander, James Stern; +Cc: cygwin Hello Mumit, Mumit Khan <khan@xraylith.wisc.EDU> wrote: MK> Paul Sokolovsky <paul-ml@is.lg.ua> writes: >> >> But at least there might be achieved proper diagnostics of such >> issues, if dlltool would correctly mark data symbols in def, that >> implib would only contain __imp_<symbol> and not <symbol>, and we'd >> get link error when linking with object which doesn't have >> __declspec(dllimport) on that symbol, and not runtime segfaults, >> as we have now. MK> Sure, but it doesn't solve James' problem. If James could create the MK> import libraries with all the data marked DATA, it would imply he MK> already *knows* which these data items are! I am still feeling misunderstood. Let me go with it once again, with examples. So, dlltool has ability to create implib from def - it's all nice with it, it supports DATA, sure. But it has ability to dump all defined symbols into def file - about this operation I am talking. So, suppose we have library of ---a.h extern int data; int code(); ---- ---a.c int data; int code() { return 0; } ---- We compile a: gcc -c a.c And now creating def of it: dlltool a.o --export-all --output-def a.def What we now get is: ---a.def ; G:\GCC-2.95\BIN\DLLTOOL.EXE --export-all --output-def a.def a.o EXPORTS data @ 1 ; code @ 2 ; ---- and it's bad! Suppose we'd get instead ---a.def ; G:\GCC-2.95\BIN\DLLTOOL.EXE --export-all --output-def a.def a.o EXPORTS data @ 1 DATA; code @ 2 ; ---- We create implib from that: dlltool --def a.def --ouput-lib liba.a And then compile client application: ---client.c #include "a.h" int main() { data=1; } ---- When we link it gcc client.o -la What we get? Of course, "client.c: undefined reference to `data'"! We now grepping, finding out that 'a.h' declares that 'data' and tag it __declspec(dllimport). Repeat while needed. So, it doesn't solve problem we're talking about automagically, but it defines clean procedure, which, while being incremental, will converge fast. Much faster than having to catch segfaults for hours and then having users complain of occasional ones for months, as we have now. MK> Regards, MK> Mumit Best regards, Paul mailto:paul-ml@is.lg.ua -- Want to unsubscribe from this list? Send a message to cygwin-unsubscribe@sourceware.cygnus.com ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Re[2]: Importing a variable from a DLL 1999-08-26 6:41 ` Mumit Khan 1999-08-26 8:05 ` Re[4]: " Paul Sokolovsky @ 1999-08-31 23:49 ` Mumit Khan 1 sibling, 0 replies; 16+ messages in thread From: Mumit Khan @ 1999-08-31 23:49 UTC (permalink / raw) To: Paul Sokolovsky, James Stern, cygwin Paul Sokolovsky <paul-ml@is.lg.ua> writes: > > But at least there might be achieved proper diagnostics of such > issues, if dlltool would correctly mark data symbols in def, that > implib would only contain __imp_<symbol> and not <symbol>, and we'd > get link error when linking with object which doesn't have > __declspec(dllimport) on that symbol, and not runtime segfaults, > as we have now. Sure, but it doesn't solve James' problem. If James could create the import libraries with all the data marked DATA, it would imply he already *knows* which these data items are! Once you know, one tricky part of porting a legacy application over -- after this, it's a matter of searching for the symbol names and attaching dllimport attribute in user code. However, your point is well taken that we should go and fix dlltool. I believe I did fix it locally at one point, but definitely didn't submit the changes (don't remember why, perhaps it didn't work). Contributions welcome of course. > It would be better just use ELF and forget about all the gore. > But rules defined by others. Welcome to real life. Regards, Mumit -- Want to unsubscribe from this list? Send a message to cygwin-unsubscribe@sourceware.cygnus.com ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re[2]: Importing a variable from a DLL 1999-08-26 3:33 ` Re[2]: " Paul Sokolovsky 1999-08-26 6:41 ` Mumit Khan @ 1999-08-31 23:49 ` Paul Sokolovsky 1 sibling, 0 replies; 16+ messages in thread From: Paul Sokolovsky @ 1999-08-31 23:49 UTC (permalink / raw) To: Mumit Khan, James Stern; +Cc: cygwin Hello Mumit, Mumit Khan <khan@xraylith.wisc.EDU> wrote: MK> There is no silver bullet, sorry. [] MK> Functions are trivial to handle via thunks (via import MK> libraries created by dlltool or implib or some such tool); MK> it's the variables that you have to worry about, which have MK> no traditional way to "fix up" in the DLL model. But at least there might be achieved proper diagnostics of such issues, if dlltool would correctly mark data symbols in def, that implib would only contain __imp_<symbol> and not <symbol>, and we'd get link error when linking with object which doesn't have __declspec(dllimport) on that symbol, and not runtime segfaults, as we have now. MK> You'll just have to deal with it. MK> I know of one case where the developers talked about writing MK> a custom PE loader to deal with this (at the expense of MK> compatibility of existing tools), but that project never saw MK> daylight outside of the South Bay cafes. It would be better just use ELF and forget about all the gore. But rules defined by others. MK> Bearer of bad news, MK> Mumit Best regards, Paul mailto:paul-ml@is.lg.ua -- Want to unsubscribe from this list? Send a message to cygwin-unsubscribe@sourceware.cygnus.com ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Importing a variable from a DLL 1999-08-25 23:29 ` Mumit Khan 1999-08-26 3:33 ` Re[2]: " Paul Sokolovsky @ 1999-08-31 23:49 ` Mumit Khan 1 sibling, 0 replies; 16+ messages in thread From: Mumit Khan @ 1999-08-31 23:49 UTC (permalink / raw) To: stern; +Cc: cygwin James Stern <jsternitg@yahoo.com> writes: > > As I understand it, the situtation is this: Suppose > that source file s1.cc used in main.exe references > extern variable v1 from the DLL. Then s1.cc has to > declare v1 as __declspec (dllimport). If s2.cc > through s20.cc also use v1, they must do likewise. > > If this is true, I'll have to change about 140 > declarations in the legacy application I'm porting. > Each will need a macro, M, that expands to either > __declspec (dllimport) or to nothing. > > These declarations appear in header files so I'll also > have to properly define M in every source file that > includes one of these headers. > > Is there an easier way to do this? For example, is > there a way to specify at link time that a variable is > imported? Not really. I did research this issue when I first started the dllimport/dllexport implemention, but came to the conclusion that it just won't work given how DLLs work. There is no silver bullet, sorry. Most software suffer from the unfortunate reality of bad modularization, and it gets in the way of making DLLs since the "ownership" of symbols are spread across headers shared by various modules. Languages like C require extra care, which just makes matters worse. My first lecture in a corporate software engr course I used to teach involved long boring discussions on the importance of design before writing the first line of code. One essential, and often overlooked, part of the design process is the layout of the modules in terms of files (since files are what we typically use in most implementations). Too bad that I myself often break that guideline on a regular basis. > I realize that the application has too many extern > variables but it's legacy and not mine to rewrite. First thing I do is to make sure no implementation file (eg., C and C++ files, not headers) *ever* use extern statements, and that each header belongs to one particular module. If your source files do contain extern decls, something is wrong and needs to be handled. My last group had the misfortune of porting a project of few million lines of C++, with a bit of C glue, and we had two engineers working 50% of the time tackling these issues. We did manage to turn all of the 50+ shared libraries into DLLs, but it was a long fight. > I also realize that fixups of this nature are harder > to do for variables than for functions but I thought I > should doublecheck anyway. Functions are trivial to handle via thunks (via import libraries created by dlltool or implib or some such tool); it's the variables that you have to worry about, which have no traditional way to "fix up" in the DLL model. You'll just have to deal with it. I know of one case where the developers talked about writing a custom PE loader to deal with this (at the expense of compatibility of existing tools), but that project never saw daylight outside of the South Bay cafes. Bearer of bad news, Mumit -- Want to unsubscribe from this list? Send a message to cygwin-unsubscribe@sourceware.cygnus.com ^ permalink raw reply [flat|nested] 16+ messages in thread
* Importing a variable from a DLL 1999-08-25 15:38 Importing a variable from a DLL James Stern 1999-08-25 23:29 ` Mumit Khan @ 1999-08-31 23:49 ` James Stern 1 sibling, 0 replies; 16+ messages in thread From: James Stern @ 1999-08-31 23:49 UTC (permalink / raw) To: cygwin The last time I posted to this list, I was asking a question about a mysterious symbol, _size_of_stack_reserve__, that gdb mentioned when my program crashed. Mumit Khan explained that this simply meant the code had a bug elsewhere. I looked and sure enough, I found an extern variable that the DLL defines and the main executable (main.exe) uses. Declaring the variable __declspec (dllimport) in the appropriate source file solved that. But then I reran the program and encountered the same problem with another variable. So I hunted for documentation on dllimport. I found only a few lines in full-man/info/* but more in the MSVC documentation. As I understand it, the situtation is this: Suppose that source file s1.cc used in main.exe references extern variable v1 from the DLL. Then s1.cc has to declare v1 as __declspec (dllimport). If s2.cc through s20.cc also use v1, they must do likewise. If this is true, I'll have to change about 140 declarations in the legacy application I'm porting. Each will need a macro, M, that expands to either __declspec (dllimport) or to nothing. These declarations appear in header files so I'll also have to properly define M in every source file that includes one of these headers. Is there an easier way to do this? For example, is there a way to specify at link time that a variable is imported? I realize that the application has too many extern variables but it's legacy and not mine to rewrite. I also realize that fixups of this nature are harder to do for variables than for functions but I thought I should doublecheck anyway. Thank you. === -- Opinions expressed above are not necessarily my employer's. James M. Stern ITG Inc. Culver City, CA (213) 270-7955 __________________________________________________ Do You Yahoo!? Bid and sell for free at http://auctions.yahoo.com -- Want to unsubscribe from this list? Send a message to cygwin-unsubscribe@sourceware.cygnus.com ^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~1999-08-31 23:49 UTC | newest] Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 1999-08-25 15:38 Importing a variable from a DLL James Stern 1999-08-25 23:29 ` Mumit Khan 1999-08-26 3:33 ` Re[2]: " Paul Sokolovsky 1999-08-26 6:41 ` Mumit Khan 1999-08-26 8:05 ` Re[4]: " Paul Sokolovsky 1999-08-26 23:10 ` Mumit Khan 1999-08-27 8:00 ` Re[6]: " Paul Sokolovsky 1999-08-27 8:17 ` Mumit Khan 1999-08-31 23:49 ` Mumit Khan 1999-08-31 23:49 ` Paul Sokolovsky 1999-08-31 23:49 ` Re[4]: " Mumit Khan 1999-08-31 23:49 ` Paul Sokolovsky 1999-08-31 23:49 ` Re[2]: " Mumit Khan 1999-08-31 23:49 ` Paul Sokolovsky 1999-08-31 23:49 ` Mumit Khan 1999-08-31 23:49 ` James Stern
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).