Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow absolute path for library files. #16

Open
cjwelborn opened this issue Sep 13, 2019 · 10 comments
Open

Allow absolute path for library files. #16

cjwelborn opened this issue Sep 13, 2019 · 10 comments

Comments

@cjwelborn
Copy link

I noticed that any library file I use has to be located in the system/global directory. Things like -l ./libforme.so are not allowed. -l forme is not allowed either if the file is in the current directory. It would be nice to at least allow an absolute path to the libraries that are loaded.

I'm having other issues with libraries. I'll probably post another report for those.

@hexagonal-sun
Copy link
Owner

Hmm, seems to work for me:

 $ cat test.c
int foo(int n)
{
    return n * 2;
}
 $ gcc -shared -o foo.so test.c
 $ ./src/bic -l ./foo.so
BIC> int foo(int n);

BIC> foo(20);
40
BIC>

@cjwelborn
Copy link
Author

@hexagonal-sun, when I try the example you provided it works fine. When I try it on one of my own shared libs it doesn't:

Example Screenshot

The file is there, but for some reason it wants to search for it as if I typed 'colr'.

@cjwelborn
Copy link
Author

Which, by the way, bic -l colr doesn't work either, even though there is a file called libcolr.so in the current directory. I haven't looked at bic's code because I've been a little busy lately, but maybe I can help with this. I'll see what I can do.

@cjwelborn
Copy link
Author

bic -l colr does work if I copy/symlink the file into /usr/lib, but it won't work in ~/.local/lib.

@hexagonal-sun
Copy link
Owner

Very strange. Looking at the code it first attempts to open the file as written on the command line here and I would have expected this to work. If you could maybe debug this on your end that would be great.

bic -l colr does work if I copy/symlink the file into /usr/lib, but it won't work in ~/.local/lib.

bic doesn't look for libraries in ~/.local/lib. Is that somewhere that it should maybe look?

Ideally I need to find out how the system does proper library resolution and follow that. It seems as though dlopen doesn't cover all bases.

@cjwelborn
Copy link
Author

I'll take a look and get back to you. If I could load a local library file bic would be awesome for debugging. I'll check it out when I get home.

@cjwelborn
Copy link
Author

cjwelborn commented Sep 15, 2019

@hexagonal-sun, I figured out what the problem is, and it's related to issue #17. I don't have a fix for it right now, but let me tell you what I've found.

The library I am testing with, libcolr.so, is one of mine. It happens to depend on libm (which is a linker script pointing to /lib/x86_64-linux-gnu/libm.so.6 on my machine. The reason the first call to dlopen fails in open_library() is because it tries to pull-in the libm dependency and that fails like issue #17.

I made a little program that calls open_library() like bic does, except it just prints whether the call succeeded or not. I can make all of this work by manually specifying the dependencies, in order, on the command line. This works for my test program, and in bic:

bic -l /lib/x86_64-linux-gnu/libm.so.6 -l ./libcolr.so

It's a workaround. I wish bic could use the linker script, because then -l ./libcolr.so would be the only thing needed (i think). I know how much work that would be though. I haven't used dlopen very much. I may look into how it grabs the dependency libraries. The man page has only this to say:

If the object specified by filename has dependencies on other shared objects, then these are also automatically loaded by the dynamic linker using the same
rules. (This process may occur recursively, if those objects in turn have dependencies, and so on.)

This issue, and #17, led me to a couple other features that would be really useful to me, and if I'm able to, I will try to help and make a pull request:

  • #include "myfile.h" is currently a parse-error. It would be nice to be able to include local headers.
    Edit: I just saw that bic does accept -I/include/dir, but it's not in the usage string for --help.
  • CFILE: Parse, evaluate and call a function called 'main' within the file.
    The call a function called main thing, I can see being really useful. I wish I could just evaluate one or more C files, even if they don't have a main function (to pull in function definitions). bic currently throws an error if there is no main():
error: Could not resolve identifier main.

That last feature would enable "startup scripts" for bic, like .pystartup is for python, and would also allow using a shebang with bic (#!/usr/bin/env bic) on arbitrary C files (they would be like interpreted C scripts).

These two things probably need a new issue, but I've already made two in one day and I don't want to flood you with feature requests (especially with no pull-requests to go with them). The thing is, I have been looking for something like bic for a long time. I have cling (REPL for C++), and I've written my own little C-snippet compiler that just compiles arbitrary C code/files with decent defaults, but it's not a REPL. So I really appreciate you putting this out there. I'd like to hear what you think about the two bullet-points above, even if it's just "never gonna happen" or "make a PR or go home".

TLDR: Issue could probably be renamed: -l fails on dependency lib if it's a linker script.

@cjwelborn
Copy link
Author

Oh yeh, and I was wrong about the ~/.local/lib thing anyway. dlopen knows where to find libraries because of ldconfig (/etc/ld.so.conf), and if you wanted to load a library from anywhere else all you would need to do is provide the absolute path to it. I don't think bic has to mess with custom library paths like -L for gcc/clang.

@cjwelborn
Copy link
Author

cjwelborn commented Sep 15, 2019

I just found this, which could possibly help bic deal with GNU linker scripts. If you knew that libm was requested, you could get the absolute file path from <gnu/lib-names.h>. Something like:

#include <dlfcn.h>
#include <gnu/lib-names.h>

int open_library(char* libname) {
    if (strcmp(libname, "m") == 0) {
        if (dlopen(LIBM_SO, RTLD_NOW | RTLD_GLOBAL)) {
            printf("Loaded libm from lib-names.h: %s\n", LIBM_SO);
            return 1;
        }
    }
    // ...fallback to normal behavior.
    return 0;
}

The gnu/lib-names.h on my machine pulls in the definitions based on architecture, but it's format looks exactly like this (just macro definitions for file paths that dlopen can find).

It turns out that the linker-script stuff is specific to the linker program, not dlopen. Long story short, a parser for the scripts would probably need to be written which is a whole other can of worms to open.

@hexagonal-sun
Copy link
Owner

Many thanks for looking at this. I would have thought that dlopen() would be smart enough to know where to find libm and open it for you. I've just tried on my machine and it appears to work (I'm running Arch Linux):

 $ cat test.c
#include <math.h>
double mysin(double d)
{
    return sin(d);
}
 $ gcc -lm -shared -o foo.so test.c
 $ ./src/bic -l ./foo.so 
BIC> double mysin(double d);

BIC> mysin(0.5);
0.479426

So not too sure exactly what is going on.

If you knew that libm was requested, you could get the absolute file path from <gnu/lib-names.h>

I really like this idea and it's a proper fix for #17. I'll cobble something together and push it today. I'm not too sure if this will help opening libcolr.so though as dlopen() doesn't call back into bic's code to query where to find libm.

In regards to the other points you've raised, please feel free to raise issues for them. I think they're great ideas and the ability for bic to parse multiple source files without calling main() was something that was on my radar anyway. I never thought about using bic as a scripting engine with a #!/usr/bin/env bic before that would be really cool! Anyway if you could raise the issues we can talk about them in more depth there and flesh out how this will all work.

Thanks!

hexagonal-sun added a commit that referenced this issue Sep 15, 2019
As suggested by @cjwelborn in #16 the above header defines LIBM_SO which is what
we should be using when opening -lm.

Fixes: #17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants