X-Recipient: archive-cygwin AT delorie DOT com X-Spam-Check-By: sourceware.org Message-ID: Date: Tue, 22 Jul 2008 18:17:04 -0500 From: "Nathan Thern" To: cygwin AT cygwin DOT com Subject: Re: .s file causing problems when linking In-Reply-To: <48864AB5.6D177B25@dessent.net> MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline References: <48864AB5 DOT 6D177B25 AT dessent DOT net> X-IsSubscribed: yes Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com On Tue, Jul 22, 2008 at 4:01 PM, Brian Dessent wrote: > You seem to have two separate issues here. >> The main executable is created with this command: >> > gcc -o scheme.exe cmpauxmd.o > > Wait, are you saying that you need to export symbols from the executable > that will be imported by another module? Yes. I tried to "export symbols" by creating a dll from the same object files from which the executable was created. >> cmpauxmd.o is created by: >> > ./makegen/m4.sh cmpauxmd.m4 > cmpauxmd.s >> > as -o cmpauxmd.o cmpauxmd.s > > Has this assembler file been specifically ported to PE or are you just > using the version some other platform? I'm following the build instructions for generic x86 *nix, going under the assumption that cygwin fits in that category. I believe the assembler file is OK; the executable runs successfully (it dies because it cannot find an image file to self-boot, but it does not core dump). >> The first module fails to link as follows: >> > gcc -shared -o prbfish.dll prbfish.o >> --> Lots of "prbfish.o:prbfish.c: undefined reference to X" where the >> X's are symbols defined in both cmpauxmd.o and > > How does being defined in cmpauxmd.o mean anything here? The link command "gcc -shared -o prbfish.dll prbfish.o " fails. When it fails, it generates tons of "undefined reference to ..." messages. To me that means the linker needs either a library or an object file that defines each symbol that got an "undefined reference" message. Using nm I can find those symbols defined in cmpauxmd.o and . > Is cmpauxmd.o > included in ? No. > I thought cmpauxmd.o was linked into the > main .exe. It was, but it still exists :-). I just mined it and the other .o's using nm and found all of the symbols I needed. > Or are you just saying that the symbol should be satisfied > by some other module in ? No, I'm not. I'm saying the symbol was _not defined_. This is not a problem on an OS like linux, but on cygwin the symbol must be defined for the link to succeed. > I appreciate that you're trying > to make the commands as simple as possible but this abbreviation only > hides and confuses, it's best to post the exact commands and the exact > resulting error messages. Well, the commands and error messages are long and unwieldy. I'd like to keep things more abstract and learn the principles rather than a one-shot solution. >> So I tried to create a helper lib just to provide symbols for prbfish.dll: >> > gcc -shared -o libscheme.dll cmpauxmd.o >> --> Cannot export asm_sc_apply_generic: symbol not found >> --> several more "Cannot export"s >> All the "Cannot export" symbols are defined in cmpauxmd.o > > That probably means the assembler file needs porting. That may be. If so, I'm in over my head. However, like I said, the procedure I'm following is for x86 *nix and is supposedly OS agnostic. (It may, however, assume ELF.) > Look at the > output of a gcc generated assembler file for a simple function > declaration and make sure your hand coded file uses the same sequence of > assember directives and pseudo-ops. For example: > > $ echo "void func() {}" | gcc -S -x c - -o - -fomit-frame-pointer > .file "" > .text > .globl _func > .def _func; .scl 2; .type 32; .endef > _func: > ret > > Notice that the assembler sequence for declaring an external in PE > assembler dialect requires this ".def/.scl/.type/.endef" sequence, which > is not present in say i386 ELF where the sequence would be something > like: > > $ echo "void func() {}" | gcc -S -x c - -o - -fomit-frame-pointer > .file "" > .text > .globl func > .type func, @function > func: > ret > .size func, .-func > .ident "GCC: (GNU) 4.4.0 20080718 (experimental)" > .section .note.GNU-stack,"",@progbits > > (You can also tell here another difference, that i386 PE is a leading > underscore target.) OK, This is extremely informative. Indeed, the generated .s file does not have the ".def/.scl/.type/.endef" sequence after .globl declarations. > Also, this assumes that you are going to use the GNU linker's > auto-export feature, or that you will manually specify a list of > functions to export with a .def file. If that is not the case then you > will need to emulate the action of __declspec(dllexport), which results > in stuff added to the .drectve section: > > $ echo "void __declspec(dllexport) func() {}" | \ > gcc -S -x c - -o - -fomit-frame-pointer > .file "" > .text > .globl _func > .def _func; .scl 2; .type 32; .endef > _func: > ret > .section .drectve > > .ascii " -export:func" > > >> Is my approach of building a helper lib the correct one? If so, how do >> I resolve the "Cannot export" errors? >> >> OR ... Is there another (better) way to inform ld of the symbols in >> scheme.exe in order to succesfully link the module .dll's? > > It is possible to export symbols from the .exe and then import them from > a .dll, but it takes more than what you're doing here, namely creating > an import library for the .exe and linking the dll against that. That is precisely what I tried to do: create a dll from the same .o's that created the .exe. > Again: > the linker must be told everything at the time of linking, there is no > lazy binding. But you may not want to actually do this because then the > resulting .dll has the filename of the .exe hardcoded into it. I > recently wrote this reply on another list and in the interest of not > typing things twice I'll just provide a link: > . > > Brian You have been very helpful, esp. the parts of your reply digging into the format of assembler files. They were daunting at first, but I re-read them several times and now understand much of it. I have found the offending parts of the cmpauxmd.s source and believe I now have a way forward. However... I am still not sure my way forward is the best one. Let me re-state it: I have an executable, scheme.exe, created from object files. A module library, prbfish.dll fails to link because it needs symbols that are in scheme.exe. I create a fake library, libfoo.dll, from the scheme.exe object files like so: > gcc -shared -o libfoo.dll *.o -Wl,--out-implib,libfoo.dll.a I can then use libfoo.dll.a as a dependency lib for prbfish.dll and it will link successfully. This seems very kludged. Surely there is a better way? Perhaps using dlltool to create a .def file from scheme.exe. I have tried this, but it seems I don't understand how to make dlltool do what I want. regards, NT -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/