cross-compiling GTK for Raspberry Pi - c

I am trying to complete this tutorial [here]here. I am running Ubuntu 32bit and I am trying to cross compile for a Raspberry Pi with Raspbian.
When I ran make, I get his error:
/home/alby/rpi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/../lib/gcc /arm-linux-gnueabihf/4.8.3/../../../../arm-linux-gnueabihf/bin/ld: warning: libgraphite2.so.2.0.0, needed by /home/alby/rpi/usr/lib/arm-linux-gnueabihf/libharfbuzz.so.0, not found (try using -rpath or -rpath-link)
/home/alby/rpi/usr/lib/arm-linux-gnueabihf/libharfbuzz.so.0: undefined reference to `gr_seg_advance_X'
/home/alby/rpi/usr/lib/arm-linux-gnueabihf/libharfbuzz.so.0: undefined reference to `gr_slot_can_insert_before'
etc..
libharfbuzz.so.0 is in the correct location. I checked for dependency
readelf -d libharfbuzz.so.0 | grep NEEDED
and this is the output:
0x00000001 (NEEDED) Shared library: [libgobject-2.0.so.0]
0x00000001 (NEEDED) Shared library: [libglib-2.0.so.0]
0x00000001 (NEEDED) Shared library: [libfreetype.so.6]
0x00000001 (NEEDED) Shared library: [libgraphite2.so.2.0.0]
0x00000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x00000001 (NEEDED) Shared library: [libc.so.6]
0x00000001 (NEEDED) Shared library: [ld-linux-armhf.so.3]
This is the first time I try cross-compilation, maybe I am missing something very obvious, but I cannot find out what it is.
thanks Alb

Related

How to make gcc print out the exact paths of the shared libraries needed by the executable

I was hoping to create an automated tool that copies the needed shared libraries for any C program to a directory, so one can ship directly to end-users.
For example, I have a C program that uses openssl. Subsequently, it needs the following shared libraries to execute.
$ gcc test.c -lssl -lcrypto
$ readelf -d a.out
Dynamic section at offset 0x2dd8 contains 28 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libssl.so.1.1]
0x0000000000000001 (NEEDED) Shared library: [libcrypto.so.1.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000000c (INIT) 0x1000
0x000000000000000d (FINI) 0x11b4
...
How can I make gcc output the exact path of the .so-files, so that I can copy them to a local directory and bundle into a zipfile?
(I'm planning to use the -rpath switch, to add that local directory to runtime library search path)
You can use dynamic injection. (On linux)You modify the environment variables as below
export DYLD_LIBRARY_PATH=path/of/your/shared/library
export DYLD_INSERT_LIBRARIES="name/of/library"
export DYLD_FORCE_FLAT_NAMESPACE=1 //by default
You can create the .sh script to run on run time like below
#!/bin/sh
export DYLD_LIBRARY_PATH=path/of/your/shared/library
export DYLD_INSERT_LIBRARIES="name/of/library"
export DYLD_FORCE_FLAT_NAMESPACE=1 //by default
$#

GDB command 'info sharedlibrary' can't show all the libraries

I am doing cross compile debugging.
My build server CPU is amd64. My device CPU is MIPS.
When I am trying to do debug the elf file compiled by myself. The gdb can only show ld.so.1
(gdb) info sharedlibrary
From To Syms Read Shared Object Library
0x7704f9c0 0x7706c490 Yes (*) /lib/ld.so.1
(*): Shared library is missing debugging information.
(gdb) q
I checked the /proc/xxxx/maps file. It showed that the shared libraries are loaded.
root#TRA:/proc/13679# cat maps
......
76549000-76d48000 rwxp 00000000 00:00 0 [stack:13682]
76d48000-76d4a000 r-xp 00000000 00:0c 5268 /usr/lib/strongswan/plugins/libstrongswan-addrblock.so
76d4a000-76d59000 ---p 00002000 00:0c 5268 /usr/lib/strongswan/plugins/libstrongswan-addrblock.so
......
If I debug the file which is installed from Debian Package server, then GDB can show all the shared libraries.
(gdb) info sharedlibrary
From To Syms Read Shared Object Library
0x77341bc0 0x77342c80 Yes (*) /lib/mips-linux-gnu/libdl.so.2
0x771d77e0 0x772ff6f0 Yes (*) /lib/mips-linux-gnu/libc.so.6
0x773549c0 0x77371490 Yes (*) /lib/ld.so.1
(*): Shared library is missing debugging information.
(gdb)
GDB version is:
GNU gdb (Debian 7.7.1+dfsg-5) 7.7.1
My questions is:
Why the GDB command 'info sharedlibrary' can't show all the libraries? How can I fix it?
(EDIT)
(Does every executable file need the library ld.so? It is missing.)
The output of command "mips-linux-gnu-readelf -d src/charon/.libs/charon"
Dynamic section at offset 0x1fc contains 33 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libstrongswan.so.0]
0x00000001 (NEEDED) Shared library: [libhydra.so.0]
0x00000001 (NEEDED) Shared library: [libcharon.so.0]
0x00000001 (NEEDED) Shared library: [libm.so.6]
0x00000001 (NEEDED) Shared library: [libpthread.so.0]
0x00000001 (NEEDED) Shared library: [libdl.so.2]
0x00000001 (NEEDED) Shared library: [libc.so.6]
0x0000001d (RUNPATH) Library runpath: [/usr/lib/strongswan]
0x0000000c (INIT) 0xd00
0x0000000d (FINI) 0x2eb0
0x00000004 (HASH) 0x32c
0x00000005 (STRTAB) 0x904
0x00000006 (SYMTAB) 0x4d4
0x0000000a (STRSZ) 787 (bytes)
0x0000000b (SYMENT) 16 (bytes)
0x70000035 (MIPS_RLD_MAP_REL) 0x134dc
0x00000015 (DEBUG) 0x0
0x00000003 (PLTGOT) 0x13760
0x00000011 (REL) 0xcf0
0x00000012 (RELSZ) 16 (bytes)
0x00000013 (RELENT) 8 (bytes)
0x70000001 (MIPS_RLD_VERSION) 1
0x70000005 (MIPS_FLAGS) NOTPOT
0x70000006 (MIPS_BASE_ADDRESS) 0x0
0x7000000a (MIPS_LOCAL_GOTNO) 18
0x70000011 (MIPS_SYMTABNO) 67
0x70000012 (MIPS_UNREFEXTNO) 37
0x70000013 (MIPS_GOTSYM) 0x11
0x6ffffffb (FLAGS_1) Flags: PIE
0x6ffffffe (VERNEED) 0xca0
0x6fffffff (VERNEEDNUM) 2
0x6ffffff0 (VERSYM) 0xc18
0x00000000 (NULL) 0x0
EDIT
Debuging GDB:
The gdb query ‘qXfer:libraries-svr4:read’ returned empty library list.
Breakpoint 7, svr4_current_sos_via_xfer_libraries (list=0x7fff8be59ad0, annex=<optimized out>)
at /gdb/gdb-7.11.1/gdb/solib-svr4.c:1301
1301 result = svr4_ parse_libraries (svr4_library_document, list);
1: svr4_library_document = 0x15cd9c0 "<library-list-svr4 version=\"1.0\"/>"
(gdb)
For Debian packages which are not compiled by me, the gdb query ‘qXfer:libraries-svr4:read’ returned full shared library list.
How does gdbserver construct the reply of this query ‘qXfer:libraries-svr4:read’?
EDIT
One more clue:
The pkgs installed from debian Jessie distribute is not PIE code.
The code I compiled is PIE code.
root#TRA:/proc/14956# readelf -r /usr/lib/strongswan/charon
Relocation section '.rel.dyn' at offset 0xcf0 contains 2 entries:
Offset Info Type Sym.Value Sym. Name
00000000 00000000 R_MIPS_NONE
00013870 00000003 R_MIPS_REL32
root#TRA:/proc/14956# readelf -r /usr/bin/id
There are no relocations in this file.
root#TRA:/proc/14956#
EDIT
After debugging gdbserver, I found one strange info.
The DT_DEBUG entry of the running proc is 0. After loader relocate the code, the DT_DEBUG should not be 0.(?) Does the system not support PIE code? I am using Debian Jessie MIPS system.
gdbserver source code:
if (dyn->d_tag == DT_DEBUG && map == -1)
map = dyn->d_un.d_val;
gdbserver dbg print
(gdb) p *dyn
$19 = {d_tag = 21, d_un = {d_val = 0, d_ptr = 0}}
(gdb)
EDIT
Get some information from this link:
https://sourceware.org/ml/binutils/2015-06/msg00166.html
I installed gdbserver from Debian Jessie mips-pkg server. But it seems not support PIE. Where can I install the mips-gdbserver which can support PIE?
Or how can I disable the gcc compiler generate PIE code?
I tried these flags (-fno-pie -fPIC) in cross-compile, but it still generate PIE code.
libtool: link: mips-linux-gnu-gcc -mfp32 -fno-pie -fPIC
-ggdb -O0 -Wall -Wno-format -Wno-format-security
-Wno-pointer-sign -I/cross-mips/usr/include -I/cross-mips/usr/include/libnl3
-I/cross-mips/usr/include/mips-linux-gnu
-I/work/strongswan/src/util
-include /work/strongswan/config.h
-o .libs/charon charon.o -L/cross-mips/lib/mips-linux-gnu
- L/cross-mips -L/cross-mips/usr/lib/mips-linux-gnu
../../src/libstrongswan/.libs/libstrongswan.so
-lm -lpthread -ldl -Wl,-rpath -Wl,/usr/lib/strongswan
Check the generated code:
mips-linux-gnu-readelf -r src/charon/.libs/charon
Relocation section '.rel.dyn' at offset 0xcf0 contains 2 entries:
Offset Info Type Sym.Value Sym. Name
00000000 00000000 R_MIPS_NONE
00013870 00000003 R_MIPS_REL32
Solution
Unfortunately the reason is my compiler gcc-6 is brocken. I used 'gcc version 6.3.0 20170516 (Debian 6.3.0-18)'. It is configured with '--enable-default-pie'. And there is no way to disable PIE. And this PIE breaks static library links. I have to change my compiler to gcc5.
From the info you provided, it seems that there are two likely causes:
Either you fully strip your binary, and gdbserver requires some symbol, or
You are building a PIE binary, and gdbserver on your system doesn't support such binaries.
(It's also possible that it's the combination of 1 and 2 that causes the problem.)
Since you know that the distribution binaries work, your best bet is probably to understand the differences between them and your binary, and minimizing such differences until gdbserver starts working.

Gentoo ld generates RUNPATH in library when -Wl,-rpath is used

I have such a directory structure: symlink pointing onto directory and symlink point to a library:
$ libtrotl.so -> /usr/local/lib64/tora-3.1/../libtrotl.so
$ instantclient -> /usr/lib/oracle/12.1/client64/lib
When I dlopen library libtrotl.so, all dependent libs are resolved and loaded.
Thanks to RPATH.
$ readelf -d libtrotl.so
Dynamic section at offset 0x17e7a8 contains 31 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libclntsh.so.12.1]
0x0000000000000001 (NEEDED) Shared library: [libboost_system.so.1.60.0]
0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000000e (SONAME) Library soname: [libtrotl.so]
0x000000000000000f (RPATH) Library rpath: [$ORIGIN/instantclient/]
0x000000000000000c (INIT) 0xe7898
$ ldd libtrotl.so
linux-vdso.so.1 (0x00007ffdc25d1000)
libclntsh.so.12.1 => /home/ivan/.TOra3/poracle/./instantclient/libclntsh.so.12.1 (0x00007f6cd0c37000)
libboost_system.so.1.60.0 => /lib64/libboost_system.so.1.60.0 (0x00007f6cd0a24000)
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f6cd069c000)
libm.so.6 => /lib64/libm.so.6 (0x00007f6cd0393000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f6cd017b000)
libc.so.6 => /lib64/libc.so.6 (0x00007f6ccfdb9000)
libmql1.so => /home/ivan/.TOra3/poracle/./instantclient/libmql1.so (0x00007f6ccfb43000)
libipc1.so => /home/ivan/.TOra3/poracle/./instantclient/libipc1.so (0x00007f6ccf7c4000)
libnnz12.so => /home/ivan/.TOra3/poracle/./instantclient/libnnz12.so (0x00007f6ccf0ba000)
I just use -Wl,-rpath,"\$ORIGIN/instantclient/" as compile flag and it works everywhere - except for Gentoo.
Gentoo linker(GNU gold (Gentoo 2.25.1 p1.1 2.25.1) 1.11) adds RUNPATH insead of RPATH.
0x000000000000001d (RUNPATH) Library runpath: [$ORIGIN/instantclient/]
Then dynamic linker does not resolve libraries.
(Gentoo)$ ldd libtrotl.so
linux-vdso.so.1 (0x00007ffe5c3e9000)
libclntsh.so.12.1 => /home/ivan/.TOra3/poracle/./instantclient/libclntsh.so.12.1 (0x00007f245dc9e000)
libstdc++.so.6 => /usr/lib/gcc/x86_64-pc-linux-gnu/4.9.4/libstdc++.so.6 (0x00007f245d933000)
libm.so.6 => /lib64/libm.so.6 (0x00007f245d62e000)
libgcc_s.so.1 => /usr/lib/gcc/x86_64-pc-linux-gnu/4.9.4/libgcc_s.so.1 (0x00007f245d417000)
libc.so.6 => /lib64/libc.so.6 (0x00007f245d07d000)
libmql1.so => not found
libipc1.so => not found
libnnz12.so => not found
libons.so => not found
As you can see, in second case library libmql1.so is not found although it is present in instantclient sub-directory. How can I set RPATH on Gentoo?
DT_RPATH tags are deprecated, DT_RUNPATH is the modern implementation with a couple different semantics. Gentoo link editors (both ld and gold) will not generate the deprecated tags by default. You can (but probably shouldn't) disable these by passing -Wl,--disable-new-dtags, but that is not recommended as I said.
There is an older pot from Qt that explains the difference of these two when using plugins: http://blog.qt.io/blog/2011/10/28/rpath-and-runpath/

How to see the order of shared library loading

Given an ELF binary or shared object, how can I most easily see the order in which the needed shared libraries will be loaded?
Are they loaded in the order they are listed by readelf -d?
how can I most easily see the order in which the needed shared libraries will be loaded?
Use LD_DEBUG:
LD_DEBUG=files /bin/ls
13444:
13444: file=libc.so.6 [0]; needed by who [0]
...
13444: file=libnss_files.so.2 [0]; needed by who [0]
...
For more info man ld.so.
Are they loaded in the order they are listed by readelf -d?
Not necessarily e.g. it will be influenced by preloading (LD_PRELOAD, /etc/ld.so.preload).
Using LD_DEBUG=files allows you to see in which order the libraries are searched, and in which order they are initialized. The latter may be different from the former.
Are they loaded in the order they are listed by readelf -d
Depends on what you mean by "loaded". A library is "fully loaded" once it's initializer returned.
Under that definition, no: the order of NEEDED dependencies listed in readelf -d and the order of loading are not the same.
Consider a.out which depends on libA.so and libB.so:
readelf -d a.out | grep NEEDED
0x0000000000000001 (NEEDED) Shared library: [libA.so]
0x0000000000000001 (NEEDED) Shared library: [libB.so]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
And further, libA.so itself depends on libC.so and libD.so:
readelf -d libA.so | grep NEEDED
0x0000000000000001 (NEEDED) Shared library: [libC.so]
0x0000000000000001 (NEEDED) Shared library: [libD.so]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
The order in which the libraries are searched:
LD_DEBUG=files ./a.out |& grep 'needed by'
49169: file=libA.so [0]; needed by ./a.out [0]
49169: file=libB.so [0]; needed by ./a.out [0]
49169: file=libc.so.6 [0]; needed by ./a.out [0]
49169: file=libC.so [0]; needed by ./libA.so [0]
49169: file=libD.so [0]; needed by ./libA.so [0]
The order in which libraries are "fully loaded":
LD_DEBUG=files ./a.out |& grep 'calling init'
69038: calling init: /lib/x86_64-linux-gnu/libc.so.6
69038: calling init: ./libD.so
69038: calling init: ./libC.so
69038: calling init: ./libB.so
69038: calling init: ./libA.so
Other factors that could affect loading order:
LD_PRELOAD or /etc/ld.so.preload.
Any of the libraries can perform dlopen in its initializer.

Link problems with libc++abi when linking against libc++ via cmake

I'm trying to build a simple ("hello world") C++ program with LLVM/Clang 3.7.0 built from sources against the toolchain's libc++, with the command line:
clang++ -std=c++14 -stdlib=libc++ -fno-exceptions hello.cpp
However, I get the following errors:
/usr/bin/ld: warning: libc++abi.so.1, needed by /bulk/workbench/llvm/3.7.0
/toolchain4/bin/../lib/libc++.so, not found (try using -rpath or -rpath-link)
/bulk/workbench/llvm/3.7.0/toolchain4/bin/../lib/libc++.so: undefined reference to `__cxa_rethrow_primary_exception'
/bulk/workbench/llvm/3.7.0/toolchain4/bin/../lib/libc++.so: undefined reference to `__cxa_decrement_exception_refcount'
/bulk/workbench/llvm/3.7.0/toolchain4/bin/../lib/libc++.so: undefined reference to `std::out_of_range::~out_of_range()'
[...]
The LD_LIBRARY_PATH is not set and the toolchain's install directory is added to my working PATH by:
export PATH=$PATH:/bulk/workbench/llvm/3.7.0/toolchain4/bin/
I'm on Ubuntu GNU/Linux 14.04 and I have not installed anything LLVM or Clang related packages from any repository.
According to the libc++ documentation:
On Linux libc++ can typically be used with only ‘-stdlib=libc++’. However some libc++ installations require the user manually link libc++abi themselves. If you are running into linker errors when using libc++ try adding ‘-lc++abi’ to the link line.
Doing as suggested gives a successful build.
So, my question is this:
Why do I have to specify the -lc++abi dependency explicitly on the line of the build command?
Doing
readelf -d $(llvm-config --libdir)/libc++.so
gives
Dynamic section at offset 0xb68c8 contains 31 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libc++abi.so.1]
0x0000000000000001 (NEEDED) Shared library: [libpthread.so.0]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
0x0000000000000001 (NEEDED) Shared library: [librt.so.1]
0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x000000000000000e (SONAME) Library soname: [libc++.so.1]
0x000000000000000f (RPATH) Library rpath: [$ORIGIN/../lib]
0x000000000000000c (INIT) 0x350a8
[...]
Shouldn't the embedded RPATH in the dynamic section of the ELF be considered by ld as described in its man page under the section -rpath-link=dir?
Moreover, when I set the LD_LIBRARY_PATH with
LD_LIBRARY_PATH=$(llvm-config --libdir)
the initial build command (without specifying -lc++abi) works, as also described in the 5th clause of the aforementioned man entry.

Resources