How prevent from dynamic relocation (rela.dyn)? - c

I am trying to run a simple program on an powerpc embedded system without any operating system. I am using GNU compiler-linker tools and PSIM as simulator. I've written my own very simple Linker Directive file.
I've used a global variable in my static library and want to use that variable in my sample program. But while linking the sample program GNU ld gives an error and stops. It says that it cannot find rela.dyn in linker directive file. Actually I do not want to use dynamically relocatable library, because I dont have a dynamic loader. What am I doing wrong?

Hard to say without more info. If you don't have an underlying OS, did you use -ffreestanding to avoid linking in the platform runtime?
Edit: -ffreestanding requires -shared? -ffreestanding means to compile to a non-hosted environment. How can such an environment support shared libraries?

-ffreestanding, as Solar says. If that fails, run ld with the --verbose option to see exactly what it is trying to link in: that will enable you to debug further.

Related

How to cross compile GSL library for arm-none-eabi-gcc?

I need to use the GSL library in my program on LPCXpresso 4367(ARM CORTEX M4). I tried to follow the library linking procedure for LPC xpresso but the MCU linker is giving me these errors:
MCUXpressoIDE_10.3.0_2200\workspace\test1\Debug/../src/test1.c:53: undefined reference to 'gsl_linalg_LU_decomp'
MCUXpressoIDE_10.3.0_2200\workspace\test1\Debug/../src/test1.c:56: undefined reference to 'gsl_matrix_alloc'
MCUXpressoIDE_10.3.0_2200\workspace\test1\Debug/../src/test1.c:57: undefined reference to 'gsl_linalg_LU_invert'
and so on for other functions as well.
I have the libgsl.a and libgslcblas.a precompiled libraries for windows which works perfectly on codeblocks on windows with GCC compiler.
I read that I need to crosscompile library for the arm-none-eabi-gcc toolchain. But can someone please provide me the procedure as well?
the libgsl.a and libgslcblas.a precompiled libraries for windows
Those won't do for ARM.
In order to work on another platform, these libs need to be compiled from source code with the proper compiler (and settings - Cortex-M4F requires Thumb2 instruction set).
As the libraries are precompiled for Windows they don't work for ARM (as it is said in the other answer)
You need to cross compile the libraries first. If you install the GSL libraries following this procedure, you only need to change the parameters in the ./config according to your platform, for example I used:
./config --host=arm-linux-gnueabihf --prefix=/home/yourname/gsl_arm
Inside the .zip file with the gsl-2.5 files, there is a file called INSTALL. There you can find more details on the options for cross compiling.
Make sure to make clean before if you have already compiled the library for different settings. After cross-compiling the library when you run make check on the terminal you will probably get errors, but still it works. Continue with make install and you are ready to use it.

Overcome DLL Hell with Code::Blocks

I'm using Code::Blocks for a project. I have not used an IDE on Linux in years, so I'm a bit out of touch with Linux IDEs.
I'm working with an OpenSSL project that uses FIPS validated library. I duplicated the GCC compiler toolchain and modified it to use OpenSSL's fipsld (and set it as default).
When the project's code executes under Code::Blocks via F8, FIPS_mode_set fails with error 252104805 (0xF06D065). 0xF06D065 is:
$ openssl errstr 0xF06D065
error:0F06D065:common libcrypto routines:FIPS_mode_set:fips mode not supported
which tells me Code::Blocks is not using the OpenSSL I specified in /usr/local/ssl/lib. Rather, the program is using the non-FIPS library provided by Debian in /usr/lib/x86_64-linux-gnu/.
An image of the link library settings is below. Note that the libraries are fully specified, and nothing is left to chance.
CodeBlocks is clearly doing things with LD_LIBRARY_PATH (shown below).
I've also verified the project is using the correct search directories - /usr/local/ssl/include for headers and /usr/local/ssl/lib for the linker.
With compiler logging set to "Full Command Line" set, here's what I get from the build log:
-------------- Build: Debug in ac ---------------
Compiling: main.cpp
/home/jwalton/Desktop/ac/main.cpp:8:5: warning: unused parameter ‘argc’ [-Wunused-parameter]
/home/jwalton/Desktop/ac/main.cpp:8:5: warning: unused parameter ‘argv’ [-Wunused-parameter]
Linking console executable: bin/Debug/ac
Output size is 569.67 KB
Process terminated with status 0 (0 minutes, 0 seconds)
0 errors, 2 warnings
I'm aware of Basile Starynkevitch's suggestions on rpath's and LD_PRELOAD tricks, but this seems like one of those things the IDE should be handling for me (Visual Studio will handle it properly, and even gives us an input box to set Working Directories to find additional libraries).
Any ideas how to make Code::Blocks use the shared objects in /usr/local/ssl/lib when executing the program under the debugger?
Your IDE instructs the compiler to link against the specified libraries, but not to load them at run time. For this latter thing to happen, you need to pass another option to the linker, namely
-rpath=/path/to/directory/with/your/libraries
or, if the linker is invoked by the compiler,
-Wl,-rpath=/same/thing
Code::Blocks don't use shared objects (DLL are a Windows thing). Because Code::Blocks is simply an IDE. IDEs are glorified source code editors with the ability to run external software development tools. You could (and sometimes you should, at least to learn how things happen) edit your code with a plain good editor like emacs, and build it with commands. Your IDE is just running commands, notably a compiler and a linker, probably using gcc
So what is using shared objects in /usr/local/ssl/lib/ is the compiler and linker (and the runtime dynamic linker). BTW, /usr/local/ssl/lib/ is a very strange name for a directory containing shared objects; you should have configured OpenSSL to be installed in /usr/local/lib/ !
First, I really believe you should reconfigure and recompile and rebuild and reinstall your SSL to get it installed under /usr/local/ (or perhaps /opt/) prefix (i.e. shared libraries in /usr/local/lib).
Then you could add appropriate options for the ld linker (from binutils). You probably want -L/usr/local/ssl/lib (to the gcc command which is running ld), and you may want to pass -Wl,-rpath (see this).
I would suggest to reinstall your SSL in /usr/local/, add /usr/local/lib/ into /etc/ld.so.conf (or at least into your LD_LIBRARY_PATH...) and run ldconfig
Otherwise, add at least /usr/local/ssl/lib/ in front of your LD_LIBRARY_PATH (and also -L/usr/local/ssl/lib/ to your linking command).
Read Program Library HowTo, the answers to this, and Drepper's How To Write Shared libraries paper.
Just open the terminal and type
export LD_LIBRARY_PATH=/path/to/your/libraries
sudo ldconfig

How can I compile a library archive with a source code file with gcc?

TL;DR - I need to compile archive.a with test.o to make an executable.
Background - I am trying to call a function in a separate library from a software package I am modifying but the function (a string parser) is creating a segmentation violation. The failure is definitely happening in the library and the developer has asked for a test case where the error occurs. Rather than having him try to compile the rather large software package that I'm working on I'd rather just send him a simple program that calls the appropriate function (hopefully dying at the same place). His library makes use of several system libraries as well (lapack, cblas, etc.) so the linking needs to hit everything I think.
I can link to the .o files that are created when I make his library but of course they don't link to the appropriate system libraries.
This seems like it should be straight forward, but it's got me all flummoxed.
The .a extension indicates that it is a static library. So in order to link against it you can use the switches for the linking stage:
gcc -o myprog -L<path to your library> main.o ... -larchive
Generally you use -L to add the path where libraries are stored (unless it is in the current directory) and you use -l<libname> to sepecify a library. The libraryname is without extension. If the library is named libarchive.a you would still give -larchive.
If you want to specify the full name of the library, then you would use i.e. -l:libname.a
update
If the libraypath is /usr/lib/libmylibrary.a you would use
-L/usr/lib -lmylibrary

How to created a shared library (dylib) using automake that JNI/JNA can use?

How do I convince LibTools to generate a library identical to what gcc does automatically?
This works if I do things explicitly:
gcc -o libclique.dylib -shared disc.c phylip.c Slist.c clique.c
cp libclique.dylib [JavaTestDir]/libclique.dylib
But if I do:
Makefile libclique.la (which is what automake generates)
cp .libs/libclique.1.dylib [JavaTestDir]/libclique.dylib
Java finds the library but can't find the entry point.
I read the "How to create a shared library (.so) in an automake script?" thread and it helped a lot. I got the dylib created with a -shared flag (according to the generated Makefile). But when I try to use it from Java Native Access I get a "symbol not found" error.
Looking at the libclique.la that is generated by Makefile it doesn't seem to have any critical information in it, just looks to be link overloads and moving things around for the convenience of subsequent C/C++ compiler steps (which I don't have), so I would expect libclique.1.dylib to be a functioning dynamic library.
I'm guessing that is where I'm going wrong, but, given that JNA links directly to a dylib and is not compiled with it (per the example in the discussion cited above), it seems all the subsequent compilation steps described in the LibTools manual are moot.
Note: I'm testing on a Mac, but I'm going to have to do this on Windows and Linux machines also, which is why I'm trying to put this into Automake.
Note2: I'm using Eclipse for my Java development and, yes, I did import the dylib.
Thanks
You should be building a plugin and in particular pass
libclique_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
This way you tell libtool you want a dynamically loadable module rather than a shared library (which for ELF are the same thing, but for Mach-O are not.)

Compile shared library with link to other .so

I want to link an existing shared library (FlashRuntimeExtensions.so) to my C-code while compiling my own shared library. But whatever I try I always get the same error; that the file is in a wrong format. Does anybody have an idea on how to solve this?
Here is my compile command:
$ g++ -Wall ane.c FlashRuntimeExtensions.so -o aneObject
FlashRuntimeExtensions.so: could not read symbols: File in wrong format
collect2: ld gaf exit-status 1 terug
Your command line tries to generate x86 code and link it to ARM code using the native g++ available in your distribution.
This will not work. Use the Android NDK available here: http://developer.android.com/tools/sdk/ndk/index.html
The NDK includes a set of cross-toolchains (compilers, linkers, etc..) that can generate native ARM binaries on Linux, OS X, and Windows (with Cygwin) platforms.
In general .so will be linked using -l.
for example, pthread -lpthread we use.
gcc sample.c -o myoutput -lpthread
But as per #chill's statement, what you are doing in command is correct only.
I suggest you to refer the following link.
C++ Linker Error SDL Image - could not read symbols
It should be an architecture mismatch. I faced this problem once, I have solved it by building the libs in same target platform and it is obvious. If you are using linux or Unix like OS you can see that by file command and if you are using windows you can see that using Dependency Walker. You need to make sure that all the libs matches architecture.

Resources