This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: .s file causing problems when linking


On Tue, Jul 22, 2008 at 4:01 PM, Brian Dessent <brian@dessent.net> wrote:
> You seem to have two separate issues here.
>> The main executable is created with this command:
>> > gcc -o scheme.exe cmpauxmd.o <other.o's> <libs>
>
> 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 <module_libs>
>> --> Lots of "prbfish.o:prbfish.c: undefined reference to X" where the
>> X's are symbols defined in both cmpauxmd.o and <other.o's>
>
> How does being defined in cmpauxmd.o mean anything here?
The link command "gcc -shared -o prbfish.dll prbfish.o <module_libs>"
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 <other.o's>.

> Is cmpauxmd.o
> included in <module_libs>?
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 <module_libs>?
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 <other.o's> <libs>
>> --> 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:
> <http://thread.gmane.org/gmane.comp.gnu.mingw.user/27032/focus=27033>.
>
> 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/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]