1

For this question of mine, my goal was to create a software, main, that takes a plugin, libfunc.so, and libfunc.so would modify the value of burger.

main.c :

#include <stdio.h>
#include <stdlib.h> // for exit()
#include <dlfcn.h>
#include "main.h"

int burger = 3;

int main(){
   void (*ptr_func)();
   void *handle;

   handle = dlopen("./libfunc.so", RTLD_NOW);
   if (!handle) {
      fprintf(stderr, "%s\n", dlerror());
      exit(1);
   }

   *(void**)(&ptr_func) = dlsym(handle, "some_func");
   if (!ptr_func){
      fprintf(stderr, "%s\n", dlerror());
      dlclose(handle);
      exit(1);
   }

   printf("before ptr_func %d\n", burger);
   ptr_func();
   printf("after %d\n", burger);

   return 0;
}

The declaration of burger, main.h:

#ifndef MAIN_H__
#define MAIN_H__
extern int burger;
#endif

and the plugin [func.c] as this:

#include <stdio.h>
#include "main.h"

void some_func(){
   burger += 10;
}

compiled all of these with clang and I got no error:

$ clang -rdynamic main.c -o main
$ clang -shared -fPIC func.c -o libfunc.so

But the problem arises with gcc:

$ gcc -rdynamic main.c -o main
$ gcc -shared -fPIC func.c -o libfunc.so
/usr/lib/gcc/x86_64-pc-cygwin/9.3.0/../../../../x86_64-pc-cygwin/bin/ld: /tmp/cc
vgKpEc.o:func.c:(.rdata$.refptr.burger[.refptr.burger]+0x0): undefined reference
 to `burger'

Yes, I've tried removing the extern and it compiled successfully but the output was:

$ ./main.exe
before ptr_func 3
after 3

clang on the other hand compiled this successfully and working as I expected:

$ ./main
before ptr_func 3
after 13

The same as without extern compiled in clang

Do this two rivals really don't like to be consistent?

Here's the gist of it https://gist.github.com/harieamjari/8c816f39fe04d38d83022301872272ea

Additional notes: The clang I have was from Termux. (an android application that simulates linux). And the gcc I have was from cygwin.

gcc version 9.3.0

clang version 9.0.0

NOTICE From my Termux, I installed gnu-8 and compiled the MWE above, but I do not experience an error.

Maybe I should use Windows.h for this matter instead of using dlfcn.h in cygwin.

Spade 000
  • 109
  • 1
  • 11
  • Try reordering the command to compile: `$ gcc -shared -fPIC -o libfunc.so func.c` – alx - recommends codidact Jul 25 '20 at 09:49
  • This seems to an issue with Cygwin on Windows. Can you try with `-Wl,--out-implib` option i.e. `gcc -shared -fPIC func.c -o -Wl,--out-implib libfunc.so`? – P.P Jul 25 '20 at 10:17
  • @P.P "error: libfunc.so: No such file or directory. " in my cygwin – Spade 000 Jul 25 '20 at 10:24
  • Should be (misplaced `-o`): `gcc -shared -fPIC func.c -Wl,--out-implib -o libfunc.so` – P.P Jul 25 '20 at 10:43
  • @P.P Yes I saw the mistake and also run that command, but the problem still persists. Does your GNU gcc work? You could git clone the gist and run make. – Spade 000 Jul 25 '20 at 10:47
  • 1
    I haven't tested - but it *should* be fine on Linux. – P.P Jul 25 '20 at 10:48
  • The issue is that the GCC system does not ordinarily export dynamic symbols from programs (as opposed to from shared libraries). On an ELF-based target, you would probably be looking to pass the `--export-dynamic` option through to the linker when you build the main program (`-Wl,--export-dynamic`). On Cygwin, you might be able to use the `--export-all-symbols` linker option instead. – John Bollinger Jul 25 '20 at 15:09
  • Another alternative would be to move `burger` to its own shared library (linked normally, not `dlopen()`ed). – John Bollinger Jul 25 '20 at 15:10
  • Are you using Windows or Unix or something in-between? – Lorinczy Zsigmond Jul 25 '20 at 19:02
  • @Lorinczy The problem persists for cygwin's GNU gcc. But for clang and gnu gcc in my Termux, the error doesn't appear. – Spade 000 Jul 26 '20 at 01:48
  • @John `gcc -shared -fPIC -Wl,--export-all-symbols -o libfunc.so func.c` didn't work unfortunately. – Spade 000 Jul 26 '20 at 03:04
  • And this problem also persist in MinGW. I guess windows was really not designed for developers. – Spade 000 Jul 27 '20 at 05:55
  • I'm no apologist for Windows, but I do think "windows was really not designed for developers" is a bit over the top. Shared library formats and behavior vary from OS to OS, and it is by no means uncommon for there to be approaches in that area that work fine on one OS and do not work at all on another. I think Windows' formats draw a stronger distinction between dynamically linked programs and shared libraries than ELF-based systems do. What you're after may nevertheless be possible in Windows, but if not, I still think that moving `burger` to its own shared library could be made to do. – John Bollinger Jul 27 '20 at 13:53
  • @John for this matter, I'm now trying to use windows api https://learn.microsoft.com/en-us/windows/win32/dlls/creating-a-simple-dynamic-link-library. The examples posted compiled and worked successfully in MinGW. IIRC, the arguments I passed to gcc when compiling the dll was, "gcc -shared -fPIC myPuts.c -o MyPuts.dll" and "gcc main.c -o main". I also took a look at this thread https://stackoverflow.com/questions/17601949/building-a-shared-library-using-gcc-on-linux-and-mingw-on-windows. It does seem like I'm getting close to figuring out how to put together the puzzle. – Spade 000 Jul 27 '20 at 14:52

0 Answers0