Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #151250 > unrolled thread

Linker error I've never seen before

Started byFrederick Gotham <cauldwell.thomas@gmail.com>
First post2020-04-09 05:49 -0700
Last post2020-04-10 09:09 -0500
Articles 16 — 9 participants

Back to article view | Back to comp.lang.c


Contents

  Linker error I've never seen before Frederick Gotham <cauldwell.thomas@gmail.com> - 2020-04-09 05:49 -0700
    Re: Linker error I've never seen before Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2020-04-09 05:59 -0700
      Re: Linker error I've never seen before Frederick Gotham <cauldwell.thomas@gmail.com> - 2020-04-09 06:06 -0700
        Re: Linker error I've never seen before Richard Damon <Richard@Damon-Family.org> - 2020-04-09 09:24 -0400
          Re: Linker error I've never seen before Frederick Gotham <cauldwell.thomas@gmail.com> - 2020-04-09 06:40 -0700
            Re: Linker error I've never seen before felix@palmen-it.de (Felix Palmen) - 2020-04-09 16:46 +0200
              Re: Linker error I've never seen before BGB <cr88192@gmail.com> - 2020-04-09 13:17 -0500
    Re: Linker error I've never seen before Frederick Gotham <cauldwell.thomas@gmail.com> - 2020-04-09 06:22 -0700
      Re: Linker error I've never seen before gazelle@shell.xmission.com (Kenny McCormack) - 2020-04-09 13:47 +0000
        Re: Linker error I've never seen before scott@slp53.sl.home (Scott Lurndal) - 2020-04-09 14:57 +0000
      Re: Linker error I've never seen before Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2020-04-09 13:08 -0700
    Re: Linker error I've never seen before jacobnavia <jacob@jacob.remcomp.fr> - 2020-04-09 19:40 +0200
    Re: Linker error I've never seen before BGB <cr88192@gmail.com> - 2020-04-09 13:10 -0500
      Re: Linker error I've never seen before felix@palmen-it.de (Felix Palmen) - 2020-04-10 09:16 +0200
        Re: Linker error I've never seen before BGB <cr88192@gmail.com> - 2020-04-10 08:54 -0500
          Re: Linker error I've never seen before BGB <cr88192@gmail.com> - 2020-04-10 09:09 -0500

#151250 — Linker error I've never seen before

FromFrederick Gotham <cauldwell.thomas@gmail.com>
Date2020-04-09 05:49 -0700
SubjectLinker error I've never seen before
Message-ID<2aab30ec-f3e7-4b46-9be5-bbc5ddd01f91@googlegroups.com>
About ten years ago I thought that I'd seen every kind of compiler and linker error.

Today I'm stumped. It's a linker error that has me stumped.

Let's say I have already compiled a dynamic shared library, and my library is called 'Monkey'. So on MS-Windows, I have "libMonkey.dll", and on Linux and Mac, I have "libMonkey.so".

So then I write a program that makes use of my Monkey library, and I compile it like so:

    gcc -o new_program new_program.c -lMonkey

This compilation of "new_program" is failing, and the linker is saying that there are undefined references in the Monkey library. I've never seen this before. My Monkey library has already been successfully compiled. I can't see how "new_program" would fail to link. I've never known a linker to complain that a dynamic shared library, which has already been compiled, contains undefined references. I'm only trying to link with a library that's already been compiled.

I'm working on ARM 32-Bit embedded Linux, and so I build in two steps like this:

    arm-linux-gnueabihf-gcc -o frederick.o -c frederick.c

    arm-linux-gnueabihf-gcc -o frederick frederick.o -lMonkey

The first command succeeds and creates the object file.

The second command fails with this output:

    libMonkey.so: undefined reference to `log_debug'
    libMonkey.so: undefined reference to `log_error'
    libMonkey.so: undefined reference to `log_trace'
    libMonkey.so: undefined reference to `log_info'
    collect2: error: ld returned 1 exit status

I've never seen a linker do this before.

Any got a clue what's going on?

[toc] | [next] | [standalone]


#151251

FromMalcolm McLean <malcolm.arthur.mclean@gmail.com>
Date2020-04-09 05:59 -0700
Message-ID<677f2dca-afc7-4ec7-bb3f-9fe3b31b72af@googlegroups.com>
In reply to#151250
On Thursday, 9 April 2020 13:49:55 UTC+1, Frederick Gotham  wrote:
> About ten years ago I thought that I'd seen every kind of compiler and linker error.
> 
> Today I'm stumped. It's a linker error that has me stumped.
> 
> Let's say I have already compiled a dynamic shared library, and my library is called 'Monkey'. So on MS-Windows, I have "libMonkey.dll", and on Linux and Mac, I have "libMonkey.so".
> 
> So then I write a program that makes use of my Monkey library, and I compile it like so:
> 
>     gcc -o new_program new_program.c -lMonkey
> 
> This compilation of "new_program" is failing, and the linker is saying that there are undefined references in the Monkey library. I've never seen this before. My Monkey library has already been successfully compiled. I can't see how "new_program" would fail to link. I've never known a linker to complain that a dynamic shared library, which has already been compiled, contains undefined references. I'm only trying to link with a library that's already been compiled.
> 
> I'm working on ARM 32-Bit embedded Linux, and so I build in two steps like this:
> 
>     arm-linux-gnueabihf-gcc -o frederick.o -c frederick.c
> 
>     arm-linux-gnueabihf-gcc -o frederick frederick.o -lMonkey
> 
> The first command succeeds and creates the object file.
> 
> The second command fails with this output:
> 
>     libMonkey.so: undefined reference to `log_debug'
>     libMonkey.so: undefined reference to `log_error'
>     libMonkey.so: undefined reference to `log_trace'
>     libMonkey.so: undefined reference to `log_info'
>     collect2: error: ld returned 1 exit status
> 
> I've never seen a linker do this before.
> 
> Any got a clue what's going on?
>
I'd guess that the lib Monkey people haven't been following comp.lang.c
and dont separate out their IO. So the library still has an external
dependency (though only for logging and error handling).

YOu need to find out where log_error and the linke are defined, and
link them. Or supply your own stubs. Which means finding out the
functions' signatures.

[toc] | [prev] | [next] | [standalone]


#151252

FromFrederick Gotham <cauldwell.thomas@gmail.com>
Date2020-04-09 06:06 -0700
Message-ID<b20e89cc-9db7-453a-be3a-81cb621f4d74@googlegroups.com>
In reply to#151251
On Thursday, April 9, 2020 at 1:59:54 PM UTC+1, Malcolm McLean wrote:

> I'd guess that the lib Monkey people haven't been following comp.lang.c
> and dont separate out their IO. So the library still has an external
> dependency (though only for logging and error handling).


I would expect my own program, "new_program", to compile successfully. Then if I go to run my program, I would understand if it can't find certain dynamic shared libraries.

But that's not what's happening. My program is failing to link even though libMonkey has already been successfully compiled to a binary.


> YOu need to find out where log_error and the linke are defined, and
> link them. Or supply your own stubs. Which means finding out the
> functions' signatures.


I've searched through the entire repository for any library exporting those functions, and I haven't found any. I searched like this:

    find -iname "*.so" | xargs -n1 readelf -d | grep -i "log_trace"
    find -iname "*.a" | xargs -n1 nm | grep -i "log_trace"

For the time being I will make a dummy library with stubs. I have the function signatures.

[toc] | [prev] | [next] | [standalone]


#151254

FromRichard Damon <Richard@Damon-Family.org>
Date2020-04-09 09:24 -0400
Message-ID<LmFjG.824878$Zw7.259473@fx34.iad>
In reply to#151252
On 4/9/20 9:06 AM, Frederick Gotham wrote:
> On Thursday, April 9, 2020 at 1:59:54 PM UTC+1, Malcolm McLean wrote:
> 
>> I'd guess that the lib Monkey people haven't been following comp.lang.c
>> and dont separate out their IO. So the library still has an external
>> dependency (though only for logging and error handling).
> 
> 
> I would expect my own program, "new_program", to compile successfully. Then if I go to run my program, I would understand if it can't find certain dynamic shared libraries.
> 
> But that's not what's happening. My program is failing to link even though libMonkey has already been successfully compiled to a binary.
> 

A library does not need to satisfy all its own requirements, it may well
need another library, or even for the calling program to define
functions for it to call back to. A library is different in that respect
than a final executable.

> 
>> YOu need to find out where log_error and the linke are defined, and
>> link them. Or supply your own stubs. Which means finding out the
>> functions' signatures.
> 
> 
> I've searched through the entire repository for any library exporting those functions, and I haven't found any. I searched like this:
> 
>     find -iname "*.so" | xargs -n1 readelf -d | grep -i "log_trace"
>     find -iname "*.a" | xargs -n1 nm | grep -i "log_trace"
> 
> For the time being I will make a dummy library with stubs. I have the function signatures.
> 

Read the documentation for libMonkey, they likely define these functions
as call backs to the application to allow you to adjust its logging
behavior. You need not just the signatures, but what they are supposed
to do. It may be that a basically nil stub would work, but it also might
not.

[toc] | [prev] | [next] | [standalone]


#151255

FromFrederick Gotham <cauldwell.thomas@gmail.com>
Date2020-04-09 06:40 -0700
Message-ID<9a46faa7-5850-45a6-91d6-2f417d7f688f@googlegroups.com>
In reply to#151254
On Thursday, April 9, 2020 at 2:25:08 PM UTC+1, Richard Damon wrote:

> Read the documentation for libMonkey, they likely define these functions
> as call backs to the application to allow you to adjust its logging
> behavior. You need not just the signatures, but what they are supposed
> to do. It may be that a basically nil stub would work, but it also might
> not.

I figured it out. Here's what I did in my C++ program:

extern "C" {
	
#if 0	
	int log_error(const char* func, const char *format, ...) __attribute__((visibility("default")));
	int log_info(const char* func, const char *format, ...) __attribute__((visibility("default")));
	int log_debug(const char* func, const char *format, ...) __attribute__((visibility("default")));
	int log_trace(const char* func, const char *format, ...) __attribute__((visibility("default")));
#endif

	int log_error(const char* func, const char *format, ...) 
	{
		return 0;
	}

	int log_info(const char* func, const char *format, ...)
	{
		return 0;
	}

	int log_debug(const char* func, const char *format, ...)
	{
		return 0;
	}

	int log_trace(const char* func, const char *format, ...)
	{
		return 0;
	}
}

int main(void)
{

}


Now it compiles just fine without having to pass any special options to the linker.

[toc] | [prev] | [next] | [standalone]


#151262

Fromfelix@palmen-it.de (Felix Palmen)
Date2020-04-09 16:46 +0200
Message-ID<a2p3mg-1cc2.ln1@mail.home.palmen-it.de>
In reply to#151255
* Frederick Gotham <cauldwell.thomas@gmail.com>:
> I figured it out. Here's what I did in my C++ program:

What's that '#if 0' block good for? :o

Anyways, if that's how the library is meant to be used, an obvious
feature request would be to provide a "null logger" by default. If the
application is interested in the log messages, it could actively set
callbacks...

-- 
 Dipl.-Inform. Felix Palmen  <felix@palmen-it.de>   ,.//..........
 {web}  http://palmen-it.de  {jabber} [see email]   ,//palmen-it.de
 {pgp public key}     http://palmen-it.de/pub.txt   //   """""""""""
 {pgp fingerprint} A891 3D55 5F2E 3A74 3965 B997 3EF2 8B0A BC02 DA2A

[toc] | [prev] | [next] | [standalone]


#151275

FromBGB <cr88192@gmail.com>
Date2020-04-09 13:17 -0500
Message-ID<r6nos8$1ae$1@dont-email.me>
In reply to#151262
On 4/9/2020 9:46 AM, Felix Palmen wrote:
> * Frederick Gotham <cauldwell.thomas@gmail.com>:
>> I figured it out. Here's what I did in my C++ program:
> 
> What's that '#if 0' block good for? :o
> 
> Anyways, if that's how the library is meant to be used, an obvious
> feature request would be to provide a "null logger" by default. If the
> application is interested in the log messages, it could actively set
> callbacks...
> 

(Hmm, seems I should have read the full thread first)

But, yeah, I agree. The library doing logging in this way is both 
non-portable and annoying, and the use of explicit callback registration 
or similar would have been preferable.

[toc] | [prev] | [next] | [standalone]


#151253

FromFrederick Gotham <cauldwell.thomas@gmail.com>
Date2020-04-09 06:22 -0700
Message-ID<3085aa51-dee1-466f-8800-0978c2f0afef@googlegroups.com>
In reply to#151250
I got it to compile with this option passed to the linker:

    -Wl,--allow-shlib-undefined

[toc] | [prev] | [next] | [standalone]


#151256

Fromgazelle@shell.xmission.com (Kenny McCormack)
Date2020-04-09 13:47 +0000
Message-ID<r6n90u$fis$1@news.xmission.com>
In reply to#151253
In article <3085aa51-dee1-466f-8800-0978c2f0afef@googlegroups.com>,
Frederick Gotham  <cauldwell.thomas@gmail.com> wrote:
>I got it to compile with this option passed to the linker:
>
>    -Wl,--allow-shlib-undefined

Yes, but you're just delaying the problem to runtime.

The program won't run (at least when it tries to call those functions).

Actually, it has been a while since I've tested this - On Linux, does it
fail immediately, or does it only fail when it tries to call the function?

-- 
Marshall: 10/22/51
Jessica: 4/4/79

[toc] | [prev] | [next] | [standalone]


#151263

Fromscott@slp53.sl.home (Scott Lurndal)
Date2020-04-09 14:57 +0000
Message-ID<4JGjG.1048869$K87.276783@fx46.iad>
In reply to#151256
gazelle@shell.xmission.com (Kenny McCormack) writes:
>In article <3085aa51-dee1-466f-8800-0978c2f0afef@googlegroups.com>,
>Frederick Gotham  <cauldwell.thomas@gmail.com> wrote:
>>I got it to compile with this option passed to the linker:
>>
>>    -Wl,--allow-shlib-undefined
>
>Yes, but you're just delaying the problem to runtime.
>
>The program won't run (at least when it tries to call those functions).
>
>Actually, it has been a while since I've tested this - On Linux, does it
>fail immediately, or does it only fail when it tries to call the function?

That entirely depends on the environment or the caller of dlopen;  Lazy
binding is the default, but options (to dlopen and via environment
variables) exist to bind at load.

[toc] | [prev] | [next] | [standalone]


#151279

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2020-04-09 13:08 -0700
Message-ID<87y2r4juce.fsf@nosuchdomain.example.com>
In reply to#151253
Frederick Gotham <cauldwell.thomas@gmail.com> writes:
> I got it to compile with this option passed to the linker:
>
>     -Wl,--allow-shlib-undefined

No, you got it to *link* with that option.  It was already compiling
(or you wouldn't have gotten to the point of a linker error in the
first place).

I hadn't known about the "--allow-shlib-undefined" option before,
but it looks like it just inhibits error messages.  I wouldn't be
surprised if the resulting program failed at run time.

I see you've fixed the problem by defining your own log_error et
al functions.  I don't know whether you posted the above before or
afte that post.

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips Healthcare
void Void(void) { Void(); } /* The recursive call of the void */

[toc] | [prev] | [next] | [standalone]


#151273

Fromjacobnavia <jacob@jacob.remcomp.fr>
Date2020-04-09 19:40 +0200
Message-ID<r6nmmn$fns$1@dont-email.me>
In reply to#151250
Le 09/04/2020 à 14:49, Frederick Gotham a écrit :
> 
> About ten years ago I thought that I'd seen every kind of compiler and linker error.
> 
> Today I'm stumped. It's a linker error that has me stumped.
> 
> Let's say I have already compiled a dynamic shared library, and my library is called 'Monkey'. So on MS-Windows, I have "libMonkey.dll", and on Linux and Mac, I have "libMonkey.so".
> 
> So then I write a program that makes use of my Monkey library, and I compile it like so:
> 
>      gcc -o new_program new_program.c -lMonkey
> 
> This compilation of "new_program" is failing, and the linker is saying that there are undefined references in the Monkey library. I've never seen this before. My Monkey library has already been successfully compiled. I can't see how "new_program" would fail to link. I've never known a linker to complain that a dynamic shared library, which has already been compiled, contains undefined references. I'm only trying to link with a library that's already been compiled.
> 
> I'm working on ARM 32-Bit embedded Linux, and so I build in two steps like this:
> 
>      arm-linux-gnueabihf-gcc -o frederick.o -c frederick.c
> 
>      arm-linux-gnueabihf-gcc -o frederick frederick.o -lMonkey
> 
> The first command succeeds and creates the object file.
> 
> The second command fails with this output:
> 
>      libMonkey.so: undefined reference to `log_debug'
>      libMonkey.so: undefined reference to `log_error'
>      libMonkey.so: undefined reference to `log_trace'
>      libMonkey.so: undefined reference to `log_info'
>      collect2: error: ld returned 1 exit status
> 
> I've never seen a linker do this before.
> 
> Any got a clue what's going on?
> 
> 

Yes, just include the icu libraries for instance.
/icu/icu4c-57_1-src/icu/source/tools/ctestfw/unicode/ctest.h

195 T_CTEST_API void T_CTEST_EXPORT2
196 log_info(const char* pattern, ...);

[toc] | [prev] | [next] | [standalone]


#151274

FromBGB <cr88192@gmail.com>
Date2020-04-09 13:10 -0500
Message-ID<r6nof2$u1u$1@dont-email.me>
In reply to#151250
On 4/9/2020 7:49 AM, Frederick Gotham wrote:
> 
> About ten years ago I thought that I'd seen every kind of compiler and linker error.
> 
> Today I'm stumped. It's a linker error that has me stumped.
> 
> Let's say I have already compiled a dynamic shared library, and my library is called 'Monkey'. So on MS-Windows, I have "libMonkey.dll", and on Linux and Mac, I have "libMonkey.so".
> 
> So then I write a program that makes use of my Monkey library, and I compile it like so:
> 
>      gcc -o new_program new_program.c -lMonkey
> 
> This compilation of "new_program" is failing, and the linker is saying that there are undefined references in the Monkey library. I've never seen this before. My Monkey library has already been successfully compiled. I can't see how "new_program" would fail to link. I've never known a linker to complain that a dynamic shared library, which has already been compiled, contains undefined references. I'm only trying to link with a library that's already been compiled.
> 
> I'm working on ARM 32-Bit embedded Linux, and so I build in two steps like this:
> 
>      arm-linux-gnueabihf-gcc -o frederick.o -c frederick.c
> 
>      arm-linux-gnueabihf-gcc -o frederick frederick.o -lMonkey
> 
> The first command succeeds and creates the object file.
> 
> The second command fails with this output:
> 
>      libMonkey.so: undefined reference to `log_debug'
>      libMonkey.so: undefined reference to `log_error'
>      libMonkey.so: undefined reference to `log_trace'
>      libMonkey.so: undefined reference to `log_info'
>      collect2: error: ld returned 1 exit status
> 
> I've never seen a linker do this before.
> 
> Any got a clue what's going on?
> 

Linux generally treats SO's more like object files in this regard, so it 
is necessary when linking against an SO to supply *all* of the 
dependencies both for the current program as well as anything the SO's 
make use of (unlike Windows and DLL's, where each DLL remembers its own 
set of dependencies). Linking an SO is essentially combining all of the 
smaller object files into a bigger object file, which is linked at 
runtime (unlike static libs which puts a collection of object files into 
an 'ar' archive, and directly links everything into the main binary).

When loading, the "ld.so" binary effectively gets invoked in the 
background to load and link together all of the ELF objects into a 
combined image (via a mechanism not too different from how "#!" works 
for shell scripts), taking the list of libraries to from the main 
binary, and producing a combined image (effectively, the kernel only 
needs to understand statically linked binaries in this case, and how to 
invoke ELF's "interpreter" in other cases).

The linker, however, will try to helpfully check that all of the symbols 
are accounted for (rather than having it fail at runtime), but since the 
SO in this case may not remember what it was linked against, the linker 
is unable to satisfy additional dependencies (hence the unresolved symbols).


The mechanism for PE/COFF and DLL's is a little different, as it is 
basically a recursive graph walk in this case, with the loader loading 
each DLL in series, and then loading any depended-on DLLs (via the 
import tables), ... until everything is loaded. DLL's are otherwise 
pretty much already linked beforehand, with the loader basically 
applying a list of relocations (to fixup the load address), and then 
fills in a table of "imports" keyed to the corresponding "exports" table 
of each target DLL.


Side note:
This is also part of why DLL's need imports and exports to be given 
explicitly (and implicitly forms a directed acyclic graph); unlike Linux 
where all this is implicit and a linked SO will use any symbol with a 
given name regardless of where it came from (and also allows for things 
like casually sharing global variables and similar between libraries, 
...), more like how things work with normal object files.


Or such...

[toc] | [prev] | [next] | [standalone]


#151284

Fromfelix@palmen-it.de (Felix Palmen)
Date2020-04-10 09:16 +0200
Message-ID<54j5mg-rjv2.ln1@mail.home.palmen-it.de>
In reply to#151274
* BGB <cr88192@gmail.com>:
> Linux generally treats SO's more like object files in this regard, so it 
> is necessary when linking against an SO to supply *all* of the 
> dependencies both for the current program as well as anything the SO's 
> make use of (unlike Windows and DLL's, where each DLL remembers its own 
> set of dependencies).

Sorry, but that's wrong. An ELF shared object has DT_NEEDED entries, no
matter whether it's a library or an executable. When linking ELF shared
objects, you only supply the /direct/ dependencies to the linker
(unlike when linking static libraries, which are indeed just archives of
plain object files).

> The mechanism for PE/COFF and DLL's is a little different, as it is 
> basically a recursive graph walk in this case, with the loader loading 
> each DLL in series, and then loading any depended-on DLLs (via the 
> import tables), ... until everything is loaded. DLL's are otherwise 
> pretty much already linked beforehand, with the loader basically 
> applying a list of relocations (to fixup the load address), and then 
> fills in a table of "imports" keyed to the corresponding "exports" table 
> of each target DLL.

PE DLLs have an extra indirection; for needed libraries, you
(statically) link an "import library" that requires a specific DLL and
symbols from /that/ DLL. Yes, this is a difference, but not to the
extent you describe here ;)

> where all this is implicit and a linked SO will use any symbol with a 
> given name regardless of where it came from

This last part is actually true. An ELF shared object has a list of
needed libraries and a list of imported symbols, but it doesn't specify
which symbol to use from which library, while a PE DLL will specify
that.

Therefore, the solution from later in this thread would never work on
Windows. That's something you'll learn once you try to implement e.g.
"plugins" for Windows. If your DLL needs symbols from your main binary,
you need to create an import library of your main binary and link that
with the DLL, or communicate the interface of your main binary to the
plugin at runtime, e.g. by calling a function in the plugin that takes a
struct full of function pointers. Just exporting symbols from your main
binary won't do.

Another reason why the library discussed here seems a bit "fishy".

-- 
 Dipl.-Inform. Felix Palmen  <felix@palmen-it.de>   ,.//..........
 {web}  http://palmen-it.de  {jabber} [see email]   ,//palmen-it.de
 {pgp public key}     http://palmen-it.de/pub.txt   //   """""""""""
 {pgp fingerprint} A891 3D55 5F2E 3A74 3965 B997 3EF2 8B0A BC02 DA2A

[toc] | [prev] | [next] | [standalone]


#151288

FromBGB <cr88192@gmail.com>
Date2020-04-10 08:54 -0500
Message-ID<r6ptqo$djc$1@dont-email.me>
In reply to#151284
On 4/10/2020 2:16 AM, Felix Palmen wrote:
> * BGB <cr88192@gmail.com>:
>> Linux generally treats SO's more like object files in this regard, so it
>> is necessary when linking against an SO to supply *all* of the
>> dependencies both for the current program as well as anything the SO's
>> make use of (unlike Windows and DLL's, where each DLL remembers its own
>> set of dependencies).
> 
> Sorry, but that's wrong. An ELF shared object has DT_NEEDED entries, no
> matter whether it's a library or an executable. When linking ELF shared
> objects, you only supply the /direct/ dependencies to the linker
> (unlike when linking static libraries, which are indeed just archives of
> plain object files).
> 

This doesn't entirely match my observations though, where sometimes a 
full dependency list is needed for things to link correctly. Could be 
wrong, could be missremembering some things...


Not gone and compared, eg, how desktop Linux compares with WSL, 
Raspbian, and Android+Termux, or GCC vs Clang behavior, ..., which I was 
generally lumping all together as "Linux".


Admittedly, I have also tended to mostly avoid 3rd partly libraries 
(most things not needing much more than libc, libm, and sometimes libdl 
or similar).


>> The mechanism for PE/COFF and DLL's is a little different, as it is
>> basically a recursive graph walk in this case, with the loader loading
>> each DLL in series, and then loading any depended-on DLLs (via the
>> import tables), ... until everything is loaded. DLL's are otherwise
>> pretty much already linked beforehand, with the loader basically
>> applying a list of relocations (to fixup the load address), and then
>> fills in a table of "imports" keyed to the corresponding "exports" table
>> of each target DLL.
> 
> PE DLLs have an extra indirection; for needed libraries, you
> (statically) link an "import library" that requires a specific DLL and
> symbols from /that/ DLL. Yes, this is a difference, but not to the
> extent you describe here ;)
> 

More or less, import libraries are one solution.

Some linkers allow linking directly against the DLL, which then serves a 
similar role to the import library.

IIRC, the import library more serves to tell the linker what symbols a 
given DLL exports, rather than containing much in the way of code.


>> where all this is implicit and a linked SO will use any symbol with a
>> given name regardless of where it came from
> 
> This last part is actually true. An ELF shared object has a list of
> needed libraries and a list of imported symbols, but it doesn't specify
> which symbol to use from which library, while a PE DLL will specify
> that.
> 
> Therefore, the solution from later in this thread would never work on
> Windows. That's something you'll learn once you try to implement e.g.
> "plugins" for Windows. If your DLL needs symbols from your main binary,
> you need to create an import library of your main binary and link that
> with the DLL, or communicate the interface of your main binary to the
> plugin at runtime, e.g. by calling a function in the plugin that takes a
> struct full of function pointers. Just exporting symbols from your main
> binary won't do.
> 

Yeah, as noted, there is a difference.

Using tables of function pointers, or using some sort of 
"FooGetProcAddress" style interface (get a function to get functions by 
name, then fetch each function by name), is something I am pretty 
familiar with.


As can be noted, I tend to write a lot more code on Windows than I do on 
Linux.

Also, my own projects generally use COFF and PE/COFF, so I am a little 
more familiar with how it works.

Though, on my CPU/ISA project is using a slightly modified version of 
PE/COFF, which splits the ".data/.bss" sections off into their own 
region, and optionally LZ4 compresses the binary to save space and to 
speed up loading from an SDcard. Also a few (target related) tweaks to 
the ".reloc" data, and effectively replaces the "resource section" data 
with an embedded "WAD" file, ...


> Another reason why the library discussed here seems a bit "fishy".
> 

Yep.

[toc] | [prev] | [next] | [standalone]


#151289

FromBGB <cr88192@gmail.com>
Date2020-04-10 09:09 -0500
Message-ID<r6punb$k5a$1@dont-email.me>
In reply to#151288
On 4/10/2020 8:54 AM, BGB wrote:
> On 4/10/2020 2:16 AM, Felix Palmen wrote:
>> * BGB <cr88192@gmail.com>:
>>> Linux generally treats SO's more like object files in this regard, so it
>>> is necessary when linking against an SO to supply *all* of the
>>> dependencies both for the current program as well as anything the SO's
>>> make use of (unlike Windows and DLL's, where each DLL remembers its own
>>> set of dependencies).
>>
>> Sorry, but that's wrong. An ELF shared object has DT_NEEDED entries, no
>> matter whether it's a library or an executable. When linking ELF shared
>> objects, you only supply the /direct/ dependencies to the linker
>> (unlike when linking static libraries, which are indeed just archives of
>> plain object files).
>>
> 
> This doesn't entirely match my observations though, where sometimes a 
> full dependency list is needed for things to link correctly. Could be 
> wrong, could be missremembering some things...
> 
> Not gone and compared, eg, how desktop Linux compares with WSL, 
> Raspbian, and Android+Termux, or GCC vs Clang behavior, ..., which I was 
> generally lumping all together as "Linux".
> 
> Admittedly, I have also tended to mostly avoid 3rd partly libraries 
> (most things not needing much more than libc, libm, and sometimes libdl 
> or similar).
> 

Then just remembers... Yeah, I am at the moment (on WSL) running a 
program which is linked against SDL (-lSDL) without also (manually) 
linking against X and similar, which also works on Termux without 
changing anything, ...

Errm, yeah, this was a bit of an oversight on my part...
Not sure how I missed this...

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c


csiph-web