How to link specific standard library in gdb? - c

When analyzing core on different machine, that binary was built for I ran into:
warning: .dynamic section for "/lib64/libc.so.6" is not at the expected address (wrong library or version mismatch?)
Is there a way to change which libc gdb is looking for?

Thanks to #Kevin Boone!
set sysroot helped I set it to ./ and put desired libc in ./lib64 and then loaded core using core-file

Related

ld and lld use only paths I input

I am trying to cross compile for my raspberry pi, unfortunately the pi has an older version of libstdc++ than my build machine and when I try to run my executable it says "./<exe_name>: /usr/lib/arm-linux-gnueabihf/libstdc++.so.6: version `GLIBCXX_3.4.26' not found (required by ./<exe_name>). I've gotten it working by using "-static", but really I'd like to be able to tell both ld (the gcc linker) and lld (the clang linker) "Only look in these paths for any libraries" it keeps finding the system one and linking against it. I've rsynced the raspberry pi's /usr/lib and /lib directores over to the host machine and I'd like to say "use /path_to_raspberry_pi_rsync/lib and /path_to_raspberry_pi_rsync/usr/lib" only.
Bonus points for getting ld and lld to tell me what path it's using when it tries to link.
I'd like to be able to tell both ld (the gcc linker) and lld (the clang linker) "Only look in these paths for any libraries"
Both will do that if you supply proper -L/path/to/target/libraries with sufficient contents.
it keeps finding the system one and linking against it. I've rsynced the raspberry pi's /usr/lib and /lib directores over to the host machine and I'd like to say "use /path_to_raspberry_pi_rsync/lib and /path_to_raspberry_pi_rsync/usr/lib" only.
Your problem most likely stems from the fact that what you rsynced are runtime libraries, not actual development libraries. So if e.g. /path_to_raspberry_pi_rsync/usr/lib contains libstdc++.so.6, but doesn't contain libstdc++.so symlink, then the linker will keep looking for libstdc++.so., until it finds one in the system directory.
In addition, once you succeed limiting your link to just the "rsync"d libraries, it is likely that your link will fail with unresolved libstdc++ symbols. That is because you need a matching set of headers and libraries.
Your best bet is to obtain a proper toolchain targeting your runtime environment.
Bonus points for getting ld and lld to tell me what path it's using when it tries to link.
With ld, you can add -Wl,-t flag and it will tell you about each and every library and object file it opens. lld may support this flag as well.

Cross compiling for Raspberry pi 2 error

I wanted to start cross compiling for raspberry pi2 on Ubuntu 32bit (in virtual box), so I downloaded the toolchain on the github site (https://github.com/raspberrypi/tools) and tried to compile a simple hello world program with the command (I've included the path to the bin folder that contains arm-linux-gnueabihf-gcc-4.8.3 to the PATH variable.):
arm-linux-gnueabihf-gcc-4.8.3 HelloWorld.c
However, I always get the following error message:
path/to/the/linker/in/the/toolchain/ld:/path/to/the/libc.so.6file/in/the/toolchain/libc.so.6: file format not recognized; treating as linker script
and subsequently a syntax error.
When I look into libc.so.6, I see a single line containing:
libc-2.13.so
The libc-2.13.so file is present in the same folder as the libc.so.6 file. When I invoke
file libc-2.13.so
I get:
libc-2.13.so: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), BuildID[sha1]=dbd0cdca5a677bea1417be1272f4c5ef43bd3e22, for GNU/Linux 2.6.26, stripped
I don't know what could cause this error since obviously the linker from the toolchain and the libc.so.6 file from the toolchain are processed so the file format should be recognized, right?
Can someone point me in the right direction here? Thanks!
I will suggest you alternate way to do Cross compilation. I tried it and it works. You can use crosstool-NG. It gives you graphical way to setup your toolchain for cross compilation. There are lot of option for setting up toolchain. You can explore that.
Now you are doing for ARM-RPi but tomorrow if your Target CPU changed then it will be very easy to reconfigure the toolchain again.
You can find easy steps given in this article. I hope this works for you.
When I look into libc.so.6, I see a single line containing:
libc-2.13.so
I just ran into this.
The problem is way simpler than you think. When you un-gz'd and untar'd the toolchain, what happened is that libc.so.6 became a text file. It is supposed to be a "symbolic link" file pointing at the correct file "libc-2.13.so".
If you are using windows and 7-Zip, make sure to click "Run AS Administrator" when you start 7-zip. If you simply drag and drop, the error is not so obvious.
In my first effort, I had to include the path to gcc in the command. Then I just compiled programs on the RPi.
~/toolchain/raspbian-toolchain-gcc-4.7.2-linux32/bin/arm-linux-gnueabihf-gcc whets.c

Buildroot ARM Toolchain for arm7tdmi to compile SourceForge Archopen

I'm interested in compiling the sourceforge project https://svn.code.sf.net/p/archopen/code/ArchOpen/trunk/, and more especifically the app AOnes, which is a NES emulator for Archos Gmini 400 (Inactive old project)
Analyzing the source code, I saw that the Gmini400 is an arm7tdmi device, no MMU and the toolchain used to compile was a buildroot one named arm-linux-nofpu.
I supposed (according to the buildroot-2009-02 menuconfig) that no-fpu means soft floating point, so i tried to build such a toolchain.
I build a toolchain with buildroot-2013-02 (both year 2009 and 2010 don't work for me) with the following options:
arm7tdmi
no MMU
Software Floating Point
Enable elf2flt support (i saw there were such a reference in the
Makefile of ArchOpen)
I let the other options as they were and made the build.
I made a checkout of ArchOpen, launch the configuration script to choose Gmini4XX as the target (and not Gmini 402 chich is quite different), selected to defaut.rules and edit the resulting Makefile.conf to adapt the tools paths and names (as my generated toolchain name is different)
First error:
[thread.o]
{standard input}: Assembler messages:
{standard input}:1236: Error: Rn must not overlap other operand -- swpb r0,r3,[r0]
Well, this code is supposed to be working, but i opened thread.h and corrected the source to pass through (adding a "&")
Second error:
undefined reference to __aeabi_idivmod and undefined reference to __aeabi_ldivmod
As google says, it seems to be a -lgcc missing problem.
I edited the wav folder makefile to add -lgcc and specified -L/lib_folder_of_my_toolchain_containing_libgcc.a
Third error:
in gcc/config/arm/lib1funcs.asm : multiple definition of __divsi3
in gcc/config/arm/lib1funcs.asm : undefined reference to raise
in libgcc.a (some .o inside) : undefined reference to __aeabi_unwind_cpp_pr0
I've no idea to solve this...
Does anyone have an idea? Does anyone can help me to get a working arm7 toolchain compatible with this archopen code?
Thanks!
Well, in this particular case, back to 2005 was a good solution...
With a ubuntu 5.04, buildroot has been built with the defaut generic ARM (little endian) configuration, except for the following options:
GCC 3.3.5
No use the daily uClibc snapshot
The processor has no MMU
No support large file
Use softfloat by default
No install busybox (as I only wanted the toolchain)
No create an Ext2 filesystem (same reason than above)
The build fail just after having compiled the last GCC phase. At this point, add the buildroot/build_arm_nofpu/staging_dir/bin in the PATH env. variable, download the libfloat source (libfloat-990616.orig.tar.bz2) tarball, edit the Makefile changing gcc, ld and as repectively by arm-linux-uclibc-gcc, arm-linux-uclibc-ld and arm-linux-uclibc-as and build libfloat (make clean & make). Copy libfloat.a into buildroot/build_arm_nofpu/staging_dir/lib and run the buildroot make again (without cleaning). The build should end successfully. With this toolchain, mediOS will compile without any warning.

Contiki, MSP430: relocation truncated to fit symbols errors

I am currently trying to compile a program with the following commands in Contiki for the tmote sky platform:
1) "make sky-shell-exec.sky TARGET=sky"
2) "make sky-shell-exec.sky CORE=sky-shell-exec.sky TARGET=sky"
I get that the first command works but that the second errors out with the following:
"contiki-sky.a(symbols.o):(.rodata+0x1f00): relocation truncated to fit: R_MSP430_16_BYTE against symbol '_efartext' defined in ABS section in sky-shell-exec.sky
contiki-sky.a(symbols.o):(.rodata+0x1f1c): relocation truncated to fit: R_MSP430_16_BYTE against symbol '_vectors_end' defined in .vectors section in sky-shell-exec.sky"
My msp430-gcc version is 4.7.0 20120322 (mspgcc dev 20120716).
I tried looking around but didn't find this error anywhere.
I assume that this means my symbol table is out of space and I should condense code. I have tried doing just this and am at a point where I can't reduce the code base anymore. Am I right in thinking this?
Does anyone know what this means and possibly of a way to fix it?
Thanks!
It turns out my error was more specific to my working code base than I had thought. I was using a modified version of contiki 2.6 with msp430-gcc 4.7.0. I had had a VM with instant contiki 2.7 and then branched the modified contiki 2.6 to work on while on the same VM. msp430-gcc 4.7.0 works fine for contiki 2.7 but when I went to work on my branch of contiki 2.6 everything broke. The issue to my best guess was arising out of differences in Makefile.include between the two code bases. I am assuming contiki 2.6 wasn't built for msp430-gcc 4.7.0 in mind. So to work on 2.6 I am currently switching to msp430-gcc 4.5.3 and making a completely separate VM for contiki 2.6, which seems to be working so far... though with some issues in the sky-shell-exec example. So I will probably end up using msp430-gcc 4.6.3 instead.
I have not dealt with this platform, but first build without debug configuration. Next can you check the linker file.

How to work with external libraries when cross compiling?

I am writing some code for raspberry pi ARM target on x86 ubuntu machine. I am using the gcc-linaro-armhf toolchain. I am able to cross compile and run some independent programs on pi. Now, I want to link my code with external library such as ncurses. How can I achieve this.
Should I just link my program with the existing ncurses lib on host machine and then run on ARM? (I don't think this will work)
Do I need to get source or prebuilt version of lib for arm, put it in my lib path and then compile?
What is the best practice in this kind of situation?
I also want to know how it works for the c stdlib. In my program I used the stdio functions and it worked after cross compiling without doing anything special. I just provided path for my arm gcc in makefile. So, I want to know, how it got correct std headers and libs?
Regarding your general questions:
Why the C library works:
The C library is part of your cross toolchain. That's why the headers are found and the program correctly links and runs. This is also true for some other very basic system libraries like libm and libstdc++ (not in every case, depends on the toolchain configuration).
In general when dealing with cross-development you need some way to get your desired libraries cross-compiled. Using binaries in this case is very rare. That is, especially with ARM hardware, because there are so many different configurations and often everything is stripped down much in different ways. That's why binaries are not very much binary compatible between different devices and Linux configurations.
If you're running Ubuntu on the Raspberry Pi then there is a chance that you may find a suitable ncurses library on the internet or even in some Ubuntu apt repository. The typical way, however, will be to cross compile the library with the specific toolchain you have got.
In cases when a lot and complex libraries need to be cross-compiled there are solutions that make life a bit easier like buildroot or ptxdist. These programs build complete Linux kernels and root file systems for embedded devices.
In your case, however, as long as you only want ncurses you can compile the source code yourself. You just need to download the sources, run configure while specifying your toolchain using the --host option. The --prefix option will choose the installation directory. After running make and make install, considering everything went fine, you will have got a set of headers and the ARM-compiled library for your application to link against.
Regarding cross compilation you will surely find loads of information on the internet and maybe ncurses has got some pointers in its shipped documentation, too.
For the query How the C library works in cross-tools
When compiling and building cross-tool chain during configuration they will provide sysroot.
like --with-sysroot=${CLFS_CROSS_TOOLS}
--with-sysroot
--with-sysroot=dir
Tells GCC to consider dir as the root of a tree that contains (a subset of) the root filesystem of the target operating system. Target system headers, libraries and run-time object files will be searched for in there. More specifically, this acts as if --sysroot=dir was added to the default options of the built compiler. The specified directory is not copied into the install tree, unlike the options --with-headers and --with-libs that this option obsoletes. The default value, in case --with-sysroot is not given an argument, is ${gcc_tooldir}/sys-root. If the specified directory is a subdirectory of ${exec_prefix}, then it will be found relative to the GCC binaries if the installation tree is moved.
So instead of looking /lib /usr/include it will look /Toolchain/(libc) and (include files) when its compiling
you can check by
arm-linux-gnueabihf-gcc -print-sysroot
this show where to look for libc .
also
arm-linux-gnueabihf-gcc -print-search-dirs
gives you clear picture
Clearly, you will need an ncurses compiled for the ARM that you are targeting - the one on the host will do you absolutely no good at all [unless your host has an ARM processor - but you said x86, so clearly not the case].
There MAY be some prebuilt libraries available, but I suspect it's more work to find one (that works and matches your specific conditions) than to build the library yourself from sources - it shouldn't be that hard, and I expect ncurses doesn't take that many minutes to build.
As to your first question, if you intend to use ncurses library with your cross-compiler toolchain, you'll have its arm-built binaries prepared.
Your second question is how it works with std libs, well it's really NOT the system libc/libm the toolchain is using to compile/link your program is. Maybe you'll see it from --print-file-name= option of your compiler:
arm-none-linux-gnuabi-gcc --print-file-name=libm.a
...(my working folder)/arm-2011.03(arm-toolchain folder)/bin/../arm-none-linux-gnuabi/libc/usr/lib/libm.a
arm-none-linux-gnuabi-gcc --print-file-name=libpthread.so
...(my working folder)/arm-2011.03(arm-toolchain folder)/bin/../arm-none-linux-gnuabi/libc/usr/lib/libpthread.so
I think your Raspberry toolchain might be the same. You can try this out.
Vinay's answer is pretty solid. Just a correction when compiling the ncurses library for raspberry pi the option to set your rootfs is --sysroot=<dir> and not --with-sysroot . Thats what I found when I was using the following compiler:
arm-linux-gnueabihf-gcc --version
arm-linux-gnueabihf-gcc (crosstool-NG linaro-1.13.1+bzr2650 - Linaro GCC 2014.03) 4.8.3 20140303 (prerelease)
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Resources