I need to change the internal name of libcrypto.so.0.9.8 shared library to libcrypto.so for a specific purpose. I am unable to do so with the chatr command which only displays the internal name.
There is a restriction that I am unable to re compile the shared library with +h option giving the internal name, which was my initial idea.
Thanks in advance.
Use the LD_PRELOAD environment variable. It allows you to interpose libraries.
Basically you setup a symlink, in a directory you control, named libcrypto.so.0.9.8, which points to the library you want to use, (I guess): /lib/libcrypto.so. Aim LD_PRELOAD at the symlink.
LD_PRELOAD will NOT work with setuid programs in HPUX.
You did carefully verify that all of the entry points you use in your code are in libcrypto.so?
Since I have no real idea what is going on this may not be an ideal solution. It is a best guess.
Related
For some reason, I can not set $LD_LIBRARY_PATH to global env. I try to set it up in golang code use os.Setenv.
os.Setenv("LD_LIBRARY_PATH", my_library_paths)
lib := C.dlopen(C.CString(libpath), C.RTLD_LAZY)
I use another C++ function to get $LD_LIBRARY_PATH, it shows corretly.
But lib returns '<nil>', and C.dlerror() shows
>> %!(EXTRA string=libhasp_linux_x86_64_demo.so: cannot open shared object file: No such file or directory)
Means $LD_LIBRARY_PATH does not work in dlopen, cgo can not find depend libraries.
I don't know why.Hope some one can help me.Thanks!
It looks like you're trying to call os.Setenv("LD_LIBRARY_PATH", ...) and then C.dlopen() from within the same process.
From the man page dlopen(3):
Otherwise, the dynamic linker searches for the object as follows
...
If, at the time that the program was started, the environment variable LD_LIBRARY_PATH was defined to contain a colon-separated list of directories, then these are searched.
The key phrase being, at the time the program is started. We can see in the implementation for dlopen in the glibc source elf/dl-load.c that it looks at a global variable __rtld_env_path_list.dirs that has already been set when searching for libraries to load; it does not look at the current value of $LD_LIBRARY_PATH.
If you want to use LD_LIBRARY_PATH to find things in C.dlopen, then you'll need to set it before your process starts (by running e.g. LD_LIBRARY_PATH=/my/path go run my-app.go).
As KJ Tsanaktsidis correctly answered, LD_LIBRARY_PATH has no effect after the process has started; you must set it before starting the process.
A common technique is to examine current value of LD_LIBRARY_PATH, and if it's not to your liking, set it to new value and re-exec the process.
That said, it's not clear why you want set LD_LIBRARY_PATH in the first place. dlopen will happily open a library which is not on LD_LIBRARY_PATH if you invoke dlopen with absolute path. That is, instead of doing this:
os.Setenv("LD_LIBRARY_PATH", my_library_paths)
lib := C.dlopen(C.CString(libpath), C.RTLD_LAZY)
do this:
lib := C.dlopen(C.CString(absolute_path_to_library), C.RTLD_LAZY)
I have a script library stored in .../lib/ that I want to embed into my program. So far, that sounds simple: On Windows, I'd use Windows Resource Files - on MacOS, I'd put them into a Resource folder and use the proper API to access the current bundle and it's resources. On plain Linux, I am not too sure how to do it... But, I want to be cross-platform anyway.
Now, I know that there are tools like IncBin (https://github.com/graphitemaster/incbin) and alike, but they are best used for single files. What I have, however, might even require some kind of file system abstraction.
So here is the few guesses and estimates I did. I'd like to know if there is possibly a better solution - or others, in general.
Create a Zip file and use MiniZ in order to read it's contents off a char array. Basically, running the zip file through IncBin and passing it as a buffer to MiniZ to let me work on that.
Use an abstracted FS layer like PhysicsFS or TTVFS and add the possibility to work off a Zip file or any other kind of archive.
Are there other solutions? Thanks!
I had this same issue, and I solved it by locating the library relative to argv[0]. But that only works if you invoke the program by its absolute path -- i.e., not via $PATH in the shell. So I invoke my program by a one-line script in ~/bin, or any other directory that's in your search path:
exec /wherever/bin/program "$#"
When the program is run, argv[0] is set to "/wherever/bin/program", and it knows to look in "/wherever/lib" for the related scripts.
Of course if you're installing directly into standard locations, you can rely on the standard directory structure, such as /usr/local/bin/program for the executable and /etc/program for related scripts & config files. The technique above is just when you want to be able to install a whole bundle in an arbitrary place.
EDIT: If you don't want the one-line shell script, you can also say:
alias program=/wherever/bin/program
I'm developing a C++ program under Linux. I want to put some stuff (to be specific, LLVM bitcode files, but that's not important) in libraries, so I want the following directory structure:
/somewhere/bin/myBin
/somewhere/lib/myLib.bc
How do I find the lib directory? I tried to compute a relative part from argv[0], but if /somewhere is in my PATH, argv[0] will just contain myBin. Is there some way to get this path? Or do I have to set it at compile time?
How do GNU autotools deal with this? What happens exactly if I supply the --prefix option to ./configure?
Edit: The word library is a bit misleading in my case. My library consist of LLVM bitcode, so it's not an actual (shared) object file, just a file I want to open from my program. You can think of it as an image or text file.
maybe what you want is :
/usr/lib
unix directory reference: http://www.comptechdoc.org/os/linux/usersguide/linux_ugfilestruct.html
Assume your lib directory is "../lib" relative to executable
First you need to identify where myBin located, You can get it by reading /proc/self/exe
Then concat your binary file path with "../lib" will give you the lib directory.
You will have to use a compiler flag to tell the program. For example, if you have a plugin dir:
# Makefile.am
AM_CPPFLAGS = -DPLUGIN_DIR=\"${pkglibdir}\"
bin_PROGRAMS = awesome_prog
pkglib_LTLIBRARIES = someplugin.la
The list of directories to be searched is stored in the file /etc/ld.so.conf.
In Linux, the environment variable LD_LIBRARY_PATH is a colon-separated set of directories where libraries should be searched for first, before the standard set of directories; this is useful when debugging a new library or using a nonstandard library for special purposes.
LD_LIBRARY_PATH is handy for development and testing:
$ export LD_LIBRARY_PATH=/path/to/mylib.so
$ ./myprogram
[read more]
Addressing only the portion of the question "how to GNU autotools deal with this?"...
When you assign a --prefix to configure, basically two things happen: 1) it instructs the build system that everything is to be installed in ${prefix}, and 2) it looks in ${prefix}/share/config.site for any additional information about how the system is set up (it is common for that file not to exist.) It does absolutely nothing to help find libraries, but depends on the user having set up the tool chain properly. If you want to use a library in /foo/lib, you must have your toolchain set up to look there (eg, by putting /foo/lib in /etc/ld.so.conf, or by putting -L/foo/lib in LDFLAGS and "/foo/lib" in LD_LIBRARY_PATH)
The configure script relies on you to have the environment set up. It does not help you set up that environment, but does help by alerting you that you have not done so.
You could use the readlink system call on /proc/self/exe to get the path of your executable. You might then use realpath etc.
I want to open a number of files (log4cxx configs, other logs etc) relative to binary's location.
Unfortunately, both getwd() and getcwd() are giving me the directory, from which I try to run binary at known path, instead of giving me the path where the binary is located (and where the data is).
How to get the app's path to use it with chdir()? Any methods besides argv[0] and without trying to parse /proc/$PID/ (that's not portable enough)?
Walk the PATH and find an executable of the same name as argv[0]?
However, it would probably be better to provide the user a way to configure where the data is. An env var or config file or CL parameter or something. It's very frustrating dealing with programs that try to be helpful but are actually just stupid.
This is exactly the kind of thing autoconf lives for, and supporting those standard directories is pretty much mandatory if you ever want anyone other than the programmers who wrote your software to use it. Once set up properly, to debug out of your home directory all you have to do is pass a different --prefix= value to configure.
C++ How to get a filename (and path) of the executing .so module in Unix?
Something similar to GetModuleFileName on Windows.
Although it is not a POSIX standard interface, the dladdr() function is available on many systems including Linux, Solaris, Darwin/Mac OS X, FreeBSD, HP-UX, and IRIX. This function takes an address, which could be a pointer to a static function within the module for example (if cast to void *), and fills in a Dl_info structure with information including the path name of the shared object containing that address (in the dli_fname member).
Unfortunately, there is no way to do that using UNIX or POSIX. If you need to use it to look up some sort of data, you should use the $PATH environment variable and search for the data in a path that is relative to each entry in $PATH. For example, it is not uncommon to store binaries in "installdir/bin" for some installation directory "installdir" and to store the associated data in "installdir/share/name_of_program" for some installation directory and some program named "name_of_program". If that is the case, then looking at "../share/name_of_program/name_of_resource_file" relative to each entry in getenv("PATH") is a good way of searching for resources. Another thing you could do is allow the necessary information to be provided on the commandline or in some configuration file, and only perform the search if needed as a fallback option.
Edit
Now that you've stated your rationale for this, I would advise you to simply use the QSettings class from Qt for your configuration information, as it uses the preferred native mechanism for each platform (the registry on Windows, a PLIST file on Mac OS X, the Gnome GConf database on Linux). You may want to take a look at my C++ Project Template as it uses Qt to do just this, and it provides simple commandline options to easily tweak the configuration settings ("--prefset", "--prefget", and "--preflist" manipulate QSettings).
That said, if you absolutely must use an XML configuration file of your own instead of using the preferred native mechanism, I strongly advise you to place the system-wide configuration in "installdir/etc" while placing your library in "installdir/lib" for some installation directory "installdir", as that is the typical place for configuration files on UNIX systems, and "installdir/lib" should ONLY be used for library files, not for configuration files and other errata. I suggest you place a user-specific version of the configuration file in "$XDG_CONFIG_HOME" (if it is defined) or in "$HOME/.config" (where "$HOME" is the user's home folder).
When searching for the system-wide configuration file, I would recommend that you search within $XDG_CONFIG_DIRS if it is defined; if it isn't defined, then falling back to "/etc/xdg" or searching for "../etc/name_of_your_program.conf.xml" relative to "$PATH" and possibly also relative to the "$LD_LIBRARY_PATH", "$DYLD_LIBRARY_PATH", "$DYLD_FALLBACK_LIBRARY_PATH"), the contents of "/etc/ld.so.conf" if it exists, and the contents of "/etc/ld.so.conf.d/*.conf" if those files exist, halting your search as soon as you encounter the first valid such configuration file would be a sensible approach.
Credit goes to Roger for pointing out the XDG Basedir Spec and for his excellent constructive criticisms.
Possible solutions:
You can read the /proc/{PID}/mmap file for the list of shared libraries. Where {PID} is the process pid (you can get it using getpid()).
Call the command line tool ldd for the program binary file (stored in argv[0]).
If you write a solution from scratch take a look of ldd commands source code from uClibc how to get the list of shared libs from an elf binary.