Where do object file "Version References" come from? - c++

Currently I'm in a directory which has a file libshared-object.so (name changed for generality).
When I run
$ objdump -p libshared-object.so
I receive the following output:
libshared-object.so: file format elf64-x86-64
Program Header:
LOAD off 0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**21
filesz 0x00000000000828ee memsz 0x00000000000828ee flags r-x
LOAD off 0x0000000000083768 vaddr 0x0000000000283768 paddr 0x0000000000283768 align 2**21
filesz 0x00000000000048e0 memsz 0x0000000000004af0 flags rw-
DYNAMIC off 0x0000000000084af0 vaddr 0x0000000000284af0 paddr 0x0000000000284af0 align 2**3
filesz 0x00000000000002a0 memsz 0x00000000000002a0 flags rw-
NOTE off 0x00000000000001c8 vaddr 0x00000000000001c8 paddr 0x00000000000001c8 align 2**2
filesz 0x0000000000000024 memsz 0x0000000000000024 flags r--
EH_FRAME off 0x0000000000072c6c vaddr 0x0000000000072c6c paddr 0x0000000000072c6c align 2**2
filesz 0x0000000000002ed4 memsz 0x0000000000002ed4 flags r--
STACK off 0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**4
filesz 0x0000000000000000 memsz 0x0000000000000000 flags rw-
RELRO off 0x0000000000083768 vaddr 0x0000000000283768 paddr 0x0000000000283768 align 2**0
filesz 0x0000000000001898 memsz 0x0000000000001898 flags r--
Dynamic Section:
NEEDED libQt5Widgets.so.5
NEEDED libQt5Compositor.so.5
NEEDED libQt5Quick.so.5
NEEDED libQt5Qml.so.5
NEEDED libQt5Network.so.5
NEEDED libQt5Gui.so.5
NEEDED libQt5Core.so.5
NEEDED libGL.so.1
NEEDED libpthread.so.0
NEEDED libstdc++.so.6
NEEDED libm.so.6
NEEDED libgcc_s.so.1
NEEDED libc.so.6
SONAME libshared-object.so.1
RPATH /opt/qt5/lib
INIT 0x000000000003fc68
FINI 0x000000000006c234
INIT_ARRAY 0x0000000000283768
INIT_ARRAYSZ 0x00000000000000e8
FINI_ARRAY 0x0000000000283850
FINI_ARRAYSZ 0x0000000000000008
GNU_HASH 0x00000000000001f0
STRTAB 0x00000000000101e8
SYMTAB 0x00000000000036d8
STRSZ 0x0000000000022072
SYMENT 0x0000000000000018
PLTGOT 0x0000000000285000
PLTRELSZ 0x0000000000008df0
PLTREL 0x0000000000000007
JMPREL 0x0000000000036e78
RELA 0x0000000000033458
RELASZ 0x0000000000003a20
RELAENT 0x0000000000000018
VERNEED 0x0000000000033348
VERNEEDNUM 0x0000000000000006
VERSYM 0x000000000003225a
RELACOUNT 0x0000000000000052
Version References:
required from libm.so.6:
0x09691a75 0x00 09 GLIBC_2.2.5
required from libgcc_s.so.1:
0x0b792650 0x00 08 GCC_3.0
required from libc.so.6:
0x06969194 0x00 10 GLIBC_2.14
0x09691a75 0x00 07 GLIBC_2.2.5
required from libQt5Core.so.5:
0x00058a25 0x00 06 Qt_5
required from libQt5Gui.so.5:
0x0dcbd2c9 0x00 12 Qt_5_PRIVATE_API
0x00058a25 0x00 03 Qt_5
required from libstdc++.so.6:
0x0bafd178 0x00 11 CXXABI_1.3.8
0x056bafd3 0x00 05 CXXABI_1.3
0x0297f871 0x00 04 GLIBCXX_3.4.21
0x08922974 0x00 02 GLIBCXX_3.4
Of particular interest is the very last of this information, the Version References:
Version References:
required from libm.so.6:
0x09691a75 0x00 09 GLIBC_2.2.5
required from libgcc_s.so.1:
0x0b792650 0x00 08 GCC_3.0
required from libc.so.6:
0x06969194 0x00 10 GLIBC_2.14
0x09691a75 0x00 07 GLIBC_2.2.5
required from libQt5Core.so.5:
0x00058a25 0x00 06 Qt_5
required from libQt5Gui.so.5:
0x0dcbd2c9 0x00 12 Qt_5_PRIVATE_API
0x00058a25 0x00 03 Qt_5
required from libstdc++.so.6:
0x0bafd178 0x00 11 CXXABI_1.3.8
0x056bafd3 0x00 05 CXXABI_1.3
0x0297f871 0x00 04 GLIBCXX_3.4.21
0x08922974 0x00 02 GLIBCXX_3.4
Question: Where do these version references come from? Take, for example, the line required from libQt5Gui.so.5: .. Qt_5 and Qt_5_PRIVATE_API.
Are references to version Qt_5 and Qt_5_PRIVATE_API coming from the C code that generated libQt5Gui.so.5? Or from some linker option passed to to gcc or ld? Or from something else?

Or from something else?
From something else.
When you build a shared library (say libfoo.so), you can (though don't have to) supply a linker version script giving certain symbols a version tag.
When you later link an executable or a shared library (say libbar.so) against libfoo.so, iff you use a versioned symbol, the version tag of that symbol is recorded in libbar.so (that is what you observed in your question).
This setup allows libfoo.so to change its symbols in ABI-incompatible way, and still support old client programs that were linked against the old symbols.
For example, libc.so.6 on x86_64 has the following versions of memcpy:
0000000000091620 g iD .text 000000000000003d GLIBC_2.14 memcpy
000000000008c420 g iD .text 0000000000000047 (GLIBC_2.2.5) memcpy
Programs that were linked against glibc-2.13 or older will use the GLIBC_2.2.5 version, programs that were linked against glibc-2.14 or newer will use the GLIBC_2.14 version.
If you try to run a program linked against glibc-2.14 on a system with glibc-2.13, you will get an error (missing symbol version), similar to this.
Before the introduction of symbol versioning, changing the ABI of an existing symbol required that you ship an entirely separate library. This is called external library versioning. You can read more about it here.

Related

C++ executable fail to look up LD_LIBRARY_PATH

I am building a simple C++ benchmark using a custom compilation tool (which has in-built clang plugin) and it simply is another regular C++ compiler. However whenever I try to run the compiled (and linked) binary, it never looks up for LD_LIBRARY_PATH to find the correct libstdc++ version. It always look for the standard /usr/lib64 and the libstdc++ version there is too old for my executable. I want to point my binary to look up in LD_LIBRARY_PATH when it runs. (I don't have root access.)
Below is the output when running it:
[xx#login-01 src]$ ./executable.x
./executable.x: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.26' not found (required by ./executable.x)
Below is output from gcc --version command. This GCC version is sufficient but my executable doesn't look for its lib path, which is in LD_LIBRARY_PATH.
gcc (GCC) 9.2.0
Copyright (C) 2019 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.
echo $LD_LIBRARY_PATH output is below. Notice it has correct GCC lib path.
/cm/local/apps/gcc/9.2.0/lib:/cm/local/apps/gcc/9.2.0/lib64:/home/ri-wshilpage/tools/LLVM/llvm-project/build/lib:/home/ri-wshilpage/tools/LLVM/llvm-project/build/lib/libomp.so:/opt/gcc/8.1.0/snos/lib64:/opt/cray/pe/papi/6.0.0.7/lib64:/cm/shared/apps/pbspro/19.2.8.20200925072630/lib/
Below I have checked the output from readelf -d ./executable.x and its RPATH shows only /usr/lib64 and the lib path of the custom compiler.
Dynamic section at offset 0x92d58 contains 34 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libhipSYCL-rt.so]
0x0000000000000001 (NEEDED) Shared library: [libboost_context.so.1.66.0]
0x0000000000000001 (NEEDED) Shared library: [libboost_fiber.so.1.66.0]
0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
0x0000000000000001 (NEEDED) Shared library: [libomp.so]
0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x0000000000000001 (NEEDED) Shared library: [libpthread.so.0]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000000f (RPATH) Library rpath: [/lustre/home/xx/sycl-compilers/hipSYCL/build/install/bin/../lib/:/usr/lib64]
0x000000000000000c (INIT) 0x407000
0x000000000000000d (FINI) 0x477d98
0x0000000000000019 (INIT_ARRAY) 0x493980
0x000000000000001b (INIT_ARRAYSZ) 160 (bytes)
0x000000000000001a (FINI_ARRAY) 0x493a20
0x000000000000001c (FINI_ARRAYSZ) 8 (bytes)
0x0000000000000004 (HASH) 0x400320
0x000000006ffffef5 (GNU_HASH) 0x400b70
0x0000000000000005 (STRTAB) 0x402798
0x0000000000000006 (SYMTAB) 0x400e90
0x000000000000000a (STRSZ) 12941 (bytes)
0x000000000000000b (SYMENT) 24 (bytes)
0x0000000000000015 (DEBUG) 0x0
0x0000000000000003 (PLTGOT) 0x494000
0x0000000000000002 (PLTRELSZ) 4056 (bytes)
0x0000000000000014 (PLTREL) RELA
0x0000000000000017 (JMPREL) 0x405fe8
0x0000000000000007 (RELA) 0x405df0
0x0000000000000008 (RELASZ) 504 (bytes)
0x0000000000000009 (RELAENT) 24 (bytes)
0x000000006ffffffe (VERNEED) 0x405c40
0x000000006fffffff (VERNEEDNUM) 6
0x000000006ffffff0 (VERSYM) 0x405a26
0x0000000000000000 (NULL) 0x0
And finally here's the Makefile.
#-----------------------------------------------------------------------
# This file compiles for OpenMP and MPI hybrid operations using the GNU
# compile chain.
MINIFE_TYPES = \
-DMINIFE_SCALAR=double \
-DMINIFE_LOCAL_ORDINAL=int \
-DMINIFE_GLOBAL_ORDINAL=int \
-DMINIFE_RESTRICT=__restrict__
MINIFE_MATRIX_TYPE = -DMINIFE_CSR_MATRIX
#-----------------------------------------------------------------------
CXX = syclcc
CC = syclcc
OPTIMIZE = yes
CPPFLAGS = --gcc-toolchain=/lustre/projects/bristol/modules/gcc/9.2.0 --hipsycl-targets=omp -I. -I../utils -I../fem $(MINIFE_TYPES) -I../../include/ $(MINIFE_MATRIX_TYPE) \
-std=c++17 -I/home/xx/tools/LLVM/llvm-project/build/projects/openmp/runtime/src
ifeq ($(OPTIMIZE),yes)
CFLAGS += -O3
endif
CXXFLAGS = $(CFLAGS)
include make_targets
Also note that I have built LLVM from source (version 12.0.1) and used it to build my custom compiler. Everything works fine except for the executable not looking up at LD_LIBRARY_PATH for shared libraries.
Edit:
Check the output from ldd ./executable.x below.
./executable.x: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.26' not found (required by ./executable.x)
linux-vdso.so.1 (0x0000155555551000)
libhipSYCL-rt.so => /lustre/home/xx/sycl-compilers/hipSYCL/build/install/bin/../lib/libhipSYCL-rt.so (0x00001555554ff000)
libboost_context.so.1.66.0 => /usr/lib64/libboost_context.so.1.66.0 (0x0000155555128000)
libboost_fiber.so.1.66.0 => /usr/lib64/libboost_fiber.so.1.66.0 (0x0000155554ec5000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x0000155554b30000)
libm.so.6 => /usr/lib64/libm.so.6 (0x00001555547ae000)
libomp.so => /home/xx/tools/LLVM/llvm-project/build/lib/libomp.so (0x000015555540d000)
libgcc_s.so.1 => /usr/lib64/libgcc_s.so.1 (0x0000155554596000)
libpthread.so.0 => /usr/lib64/libpthread.so.0 (0x0000155554376000)
libc.so.6 => /usr/lib64/libc.so.6 (0x0000155553fb4000)
libdl.so.2 => /usr/lib64/libdl.so.2 (0x0000155553db0000)
/lib64/ld-linux-x86-64.so.2 (0x000015555532b000)
librt.so.1 => /usr/lib64/librt.so.1 (0x0000155553ba7000)
libboost_filesystem.so.1.66.0 => /usr/lib64/libboost_filesystem.so.1.66.0 (0x000015555398c000)
libboost_system.so.1.66.0 => /usr/lib64/libboost_system.so.1.66.0 (0x0000155553787000)

simavr ignores memory content of located sections

Question also posted in https://github.com/buserror/simavr/issues/484
For a project with an Atmega324P I use special sections to ensure that some code is located on desired addresses. Works fine on real target, but these sections are not loaded proper in simavr.
Any idea what is going wrong and how to solve this problem?
To reproduce this problem I use an Ubuntu system with avr-gcc (5.4.0), avr-gdb (10.1.90.20210103-git) and simavr (1.6+dfsg-3).
Create file main.c
#define ATT_SECTION_APP __attribute__((section(".app")))
int main () ATT_SECTION_APP;
int main () {
asm("nop");
return 0;
}
Build project and locate section .app to 0x7100
avr-gcc -c -o main.o main.c
avr-gcc -o main.elf -Wl,-section-start=.app=0x7100 -mmcu=atmega324p main.o
Check result in elf-file
Disassemble elf-file with avr-objdump -d main.elf
Disassembly of section .app:
00007100 <main>:
7100: cf 93 push r28
7102: df 93 push r29
7104: cd b7 in r28, 0x3d ; 61
7106: de b7 in r29, 0x3e ; 62
7108: 00 00 nop
710a: 80 e0 ldi r24, 0x00 ; 0
710c: 90 e0 ldi r25, 0x00 ; 0
710e: df 91 pop r29
7110: cf 91 pop r28
7112: 08 95 ret
Start simavr
simavr -g -m atmega324p main.elf
Start avr-gdb and show memory on location 0x7100
Start in another shell avr-gdb with avr-gdb main.elf.
Then execute the following commands on gdb console:
target remote localhost:1234
x/20b 0x7100
As you can see, the memory locations starting with 0x7100 are cleared (= 0xff) instead of showing the same content as in disassembly view. Symbols like main are shown as desired.
(gdb) target remote localhost:1234
Remote debugging using localhost:1234
0x00000000 in __vectors ()
(gdb) x/20b 0x7100
0x7100 <main>: 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
0x7108 <main+8>: 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
0x7110 <main+16>: 0xff 0xff 0xff 0xff

Why file command report dynamic linked with gcc -static

gcc -static -g -O2 -static -o init init-init.o
file init
# init: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, with debug_info, not stripped
ldd init
# ldd (0x7fd49e2ed000)
objdump -p init
init: file format elf64-x86-64
Program Header:
LOAD off 0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**21
filesz 0x00000000000076e4 memsz 0x00000000000076e4 flags r-x
LOAD off 0x0000000000007e30 vaddr 0x0000000000207e30 paddr 0x0000000000207e30 align 2**21
filesz 0x00000000000002d8 memsz 0x0000000000001488 flags rw-
DYNAMIC off 0x0000000000007e60 vaddr 0x0000000000207e60 paddr 0x0000000000207e60 align 2**3
filesz 0x0000000000000150 memsz 0x0000000000000150 flags rw-
STACK off 0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**4
filesz 0x0000000000000000 memsz 0x0000000000000000 flags rw-
RELRO off 0x0000000000007e30 vaddr 0x0000000000207e30 paddr 0x0000000000207e30 align 2**0
filesz 0x00000000000001d0 memsz 0x00000000000001d0 flags r--
Dynamic Section:
SYMBOLIC 0x0000000000000000
INIT 0x00000000000002c0
FINI 0x0000000000006473
GNU_HASH 0x0000000000000158
STRTAB 0x00000000000001b0
SYMTAB 0x0000000000000180
STRSZ 0x0000000000000007
SYMENT 0x0000000000000018
DEBUG 0x0000000000000000
PLTGOT 0x0000000000207fb0
RELA 0x00000000000001b8
RELASZ 0x0000000000000108
RELAENT 0x0000000000000018
BIND_NOW 0x0000000000000000
FLAGS_1 0x0000000008000001
RELACOUNT 0x000000000000000b
readelf init -h
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: DYN (Shared object file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x1158
Start of program headers: 64 (bytes into file)
Start of section headers: 308248 (bytes into file)
Flags: 0x0
Why Type: DYN (Shared object file) ?
Trying to compile supermin under alpine, but src/Makefile.am#L159
require init is static linked by file command.
ET_DYN is used for position-independent executables (PIE), whether they are statically linked or not. The lack of a program interpreter and DT_NEEDED entries in the dynamic section indicate that the program is indeed statically linked. You can check that using readelf -l (no .interp) and readelf -d (no NEEDED).
Running the program under strace will also verify that no shared objects are loaded at program start.

Cross-Compiled GNU ARM (BeagleBoneBlack) from Windows. Runtime Error on *.elf: "No such file or directory"

I'm in the (very) early stages of developing a UAV flight controller on a BeagleBone Black. I should mention that I'm quite the novice when it comes to the BBB, Linux and embedded systems.My academic focus has been on control theory - this is my first attempt at a practical implementation outside of Matlab Simulations. My current system is as follows:
Host-> Windows 8.1 x64 running Eclipse Luna (4.4.0)
Target -> BeagleBone Black rev. B running Ubuntu 13.10
Target Info
root#arm:~# uname -a
Linux arm 3.8.13-bone32 #1 SMP Fri Dec 13 20:05:25 UTC 2013 armv7l armv7l armv7l GNU/Linux
Target gcc version
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/arm-linux-gnueabihf/4.8/lto-wrapper
Target: arm-linux-gnueabihf
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.8.1-10ubuntu9' --with-bugurl=file:///usr/shar
e/doc/gcc-4.8/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.8
--enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --w
ith-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enabl
e-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libitm --disable-libquadmath --ena
ble-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr
/lib/jvm/java-1.5.0-gcj-4.8-armhf/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-armhf --
with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-armhf --with-arch-directory=arm --with-ecj-jar=/usr/share/ja
va/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --enable-multilib --disable-sjlj-exceptions --with-arch=armv7-
a --with-fpu=vfpv3-d16 --with-float=hard --with-mode=thumb --disable-werror --enable-checking=release --build=arm-lin
ux-gnueabihf --host=arm-linux-gnueabihf --target=arm-linux-gnueabihf
Thread model: posix
gcc version 4.8.1 (Ubuntu/Linaro 4.8.1-10ubuntu9)
I've installed the Sourcery Codebench Lite toolchain and am using the GNU Make file. I’ve set up the Eclipse environment as per the instructional video provided by Michael Jantz (link removed due to limit - if interested search "Cross-Compile and Remote Browsing for BeagleBone" on YouTube) with some minor tweaks to get it running on my system. These tweaks consisted primarily of removing the "--specs=rdimon.specs" and "-lrdimon" linking flags as I kept getting a "no such file or directory" when compiling. With these two flags removed the simple "Hello ARM World" program compiles without any issues.
After transferring the compiled ELF file to my BeagleBone, setting permissions and the executable flags via:
chmod ugo-x Test6.elf
and running it via:
./Test6.elf
I get the following message:
root#arm:/home/ubuntu/RDKTestProgs# ./Test6.elf
bash: ./Test6.elf: No such file or directory
I initially thought the mismatch between my 64-bit host system and the 32-bit GNU Make shouldn’t be an issue, but to eliminate my doubt I found a 64-bit GNU Make file (link removed due to limit) although I’m not sure of its integrity. In any case, both GNU Make files yield the same result when trying to execute the program on the BBB.
After looking through a several posts I discovered the “ readelf“, “strace” and “strings” tools, which yielded the following outputs.
Readelf:
root#arm:/home/ubuntu/RDKTestProgs# readelf -d Test6.elf
Dynamic section at offset 0x858 contains 27 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libc.so.6]
0x00000001 (NEEDED) Shared library: [libstdc++.so.6]
0x00000001 (NEEDED) Shared library: [libm.so.6]
0x00000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x0000000c (INIT) 0x8550
0x0000000d (FINI) 0x87a0
0x00000019 (INIT_ARRAY) 0x10848
0x0000001b (INIT_ARRAYSZ) 8 (bytes)
0x0000001a (FINI_ARRAY) 0x10850
0x0000001c (FINI_ARRAYSZ) 4 (bytes)
0x00000004 (HASH) 0x8168
0x00000005 (STRTAB) 0x82bc
0x00000006 (SYMTAB) 0x81bc
0x0000000a (STRSZ) 444 (bytes)
0x0000000b (SYMENT) 16 (bytes)
0x00000015 (DEBUG) 0x0
0x00000003 (PLTGOT) 0x10958
0x00000002 (PLTRELSZ) 72 (bytes)
0x00000014 (PLTREL) REL
0x00000017 (JMPREL) 0x8508
0x00000011 (REL) 0x84f8
0x00000012 (RELSZ) 16 (bytes)
0x00000013 (RELENT) 8 (bytes)
0x6ffffffe (VERNEED) 0x8498
0x6fffffff (VERNEEDNUM) 3
0x6ffffff0 (VERSYM) 0x8478
0x00000000 (NULL) 0x0
root#arm:/home/ubuntu/RDKTestProgs# strings Test6.elf
/lib/ld-linux.so.3
libc.so.6
abort
__libc_start_main
__aeabi_atexit
libstdc++.so.6
__gmon_start__
_Jv_RegisterClasses
_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
_ITM_deregisterTMCloneTable
_ITM_registerTMCloneTable
_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
_ZNSt8ios_base4InitD1Ev
_ZNSolsEPFRSoS_E
_ZNSt8ios_base4InitC1Ev
_ZSt4cout
libm.so.6
libgcc_s.so.1
__aeabi_unwind_cpp_pr0
__aeabi_unwind_cpp_pr1
GLIBCXX_3.4
GCC_3.5
GLIBC_2.4
?8FAFJF
x`9`{h
Hello ARM World!
Strace:
root#arm:/home/ubuntu/RDKTestProgs# strace ./Test6
strace: Can't stat './Test6': No such file or directory
root#arm:/home/ubuntu/RDKTestProgs# strace ./Test6.elf
execve("./Test6.elf", ["./Test6.elf"], [/* 22 vars */]) = -1 ENOENT (No such file or directory)
write(2, "strace: exec: No such file or di"..., 40strace: exec: No such file or directory
) = 40
exit_group(1) = ?
+++ exited with 1 +++
Strings:
root#arm:/home/ubuntu/RDKTestProgs# strings Test6.elf
/lib/ld-linux.so.3
libc.so.6
abort
__libc_start_main
__aeabi_atexit
libstdc++.so.6
__gmon_start__
_Jv_RegisterClasses
_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
_ITM_deregisterTMCloneTable
_ITM_registerTMCloneTable
_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
_ZNSt8ios_base4InitD1Ev
_ZNSolsEPFRSoS_E
_ZNSt8ios_base4InitC1Ev
_ZSt4cout
libm.so.6
libgcc_s.so.1
__aeabi_unwind_cpp_pr0
__aeabi_unwind_cpp_pr1
GLIBCXX_3.4
GCC_3.5
GLIBC_2.4
?8FAFJF
x`9`{h
Hello ARM World!
I searched through my BeagelBoneBlack for the 4 shared library files indicated from the “readelf” function and found that they are in fact present. The issue is however, that some of these files are found in the usr/lib/arm-linux-gnueabihf/directory whereas others are found in the /lib/arm-linux-gnueabihf# directory. To fix this I created symbolic links to the files not found in the /usr/lib/arm-linux-gnueabihf/ directory. This still did not solve the problem. So I created symbolic links to files not found in the /lib/arm-linux-gnueabihf/ directory. Again, no luck.
Is there a way to check which directory is being used on execution? What else could possibly be missing from the Test6.elf file? I’m at a loss at the moment. Any advice or guidance would be greatly appreciated! Cheers!
P.S. I also managed to check for the GLIBCXX_3.4, GLIBC_2.4 and GCC_3.5 as shown below, but again, some of these pertain to files in /usr/lib/arm-linux-gnueabihf others are found in the /lib/arm-linux-gnueabihf. Thanks again!
root#arm:/lib/arm-linux-gnueabihf# strings libgcc_s.so.1 | grep GCC
GCC_3.0
GCC_3.3
GCC_3.3.1
GCC_3.3.4
GCC_3.4
GCC_3.4.2
GCC_4.0.0
GCC_4.2.0
GCC_4.3.0
GCC_4.7.0
GCC_3.5
root#arm:/usr/lib/arm-linux-gnueabihf# strings libstdc++.so.6.0.18 | grep GLIBC
GLIBCXX_3.4
GLIBCXX_3.4.1
GLIBCXX_3.4.2
GLIBCXX_3.4.3
GLIBCXX_3.4.4
GLIBCXX_3.4.5
GLIBCXX_3.4.6
GLIBCXX_3.4.7
GLIBCXX_3.4.8
GLIBCXX_3.4.9
GLIBCXX_3.4.10
GLIBCXX_3.4.11
GLIBCXX_3.4.12
GLIBCXX_3.4.13
GLIBCXX_3.4.14
GLIBCXX_3.4.15
GLIBCXX_3.4.16
GLIBCXX_3.4.17
GLIBCXX_3.4.18
GLIBCXX_3.4.19
GLIBC_2.4
GLIBC_2.17
GLIBCXX_DEBUG_MESSAGE_LENGTH
And finally, here's the "Hello ARM World" program
//============================================================================
// Name : main.cpp
// Author : RDK
// Version :
// Copyright : Your copyright notice
// Description : Hello World in C++
//============================================================================
#include <iostream>
using namespace std;
//
// Print a greeting message on standard output and exit.
//
// On embedded platforms this might require semi-hosting or similar.
//
// For example, for toolchains derived from GNU Tools for Embedded,
// to enable semi-hosting, the following was added to the linker:
//
// --specs=rdimon.specs -Wl,--start-group -lgcc -lc -lc -lm -lrdimon -Wl,--end-group
//
// Adjust it for other toolchains.
//
int
main()
{
cout << "Hello ARM World!" << endl;
return 0;
}
Right on! So I've got it working. Here are my steps, hopefully they're sound and wont cause me issues in the future.
From this post, I tried to find out where the Test6.elf expected to find the linux loader for dynamically linked libraries. This yielded:
root#arm:/home/ubuntu/RDKTestProgs# readelf -l ./Test6.elf | grep ld-linux
[Requesting program interpreter: /lib/ld-linux.so.3]
I checked my /lib folder and sure enough the ld-linux.so.3 file was missing. Instead I found it in the /lib/arm-linux-gnueabihf/ folder
So I created a symbolic link in the /lib folder via:
ln -s /lib/arm-linux-gnueabihf/ld-linux.so.3 /lib/ld-linux.so.3
And boom! It works. What I still find strange however is that the ldd ./Test6.elf still returns:
root#arm:/home/ubuntu/RDKTestProgs# ldd ./Test6.elf
not a dynamic executable
Is there a good reason for this, or is this somehow normal? - It doesn't seem right to me.
I also noticed that my current compiler settings (and hence toolchain) for Float ABI are set to soft, yet my BeagleBoneBlack is running arm-linux-gnueabihf - hard float. Will this cause me problems in the future? Should I be looking for a different toolchain?
Cheers!
I was having a similar situation with a library called 'ibstdc++.so.6'. I develop in Eclipse on Ubuntu 14.04, and deploy on beaglebone with Debian. I never had this issue before when I use to developed on Eclipse Ubuntu 12.04 and deploy on Amstrong.
The way I resolced the problem was reading the anwsers above and what I did I set my cross-compiler to arm-linux-gnueabihf-g++. Seems that the library that I was missing is just included in the hard floating version of the compiler and not in the soft floating. Change the cross compiler setting on Eclipse and resolved the problem.

NASM and GDB Symbols: "Can't find any code sections in symbol file."

I am trying to get a simple example working from an assembly book I am reading. I am trying to get gdb to work with my simple assembly program that I am assembling with the NASM assembler. Below is the code, and the object file in elf format.
; Version : 1.0
; Created Date : 11/12/2011
; Last Update : 11/12/2011
; Author : Jeff Duntemann
; Description : A simple assembly app for Linux, using NASM 2.05,
; demonstrating the use of Linux INT 80H syscalls
; to display text.
; Build using these commands:
; nasm -f elf -g -F stabs eatsyscall.asm
; ld -o eatsyscall eatsyscall.o
;
SECTION .data ; Section containing initialized data
EatMsg: db "Eat at Joe's!",10
EatLen: equ $-EatMsg
SECTION .bss ; Section containing uninitialized data
SECTION .txt ; Section containing code
global _start ; Linker needs this to find the entry point!
_start:
nop ; This no_op keeps gdb happy (see text)
mov eax,4 ; Specify sys_write syscall
mov ebx,1 ; Specify File Descriptor 1: Standard Output
mov ecx,EatMsg ; Pass offset of the message
mov edx,EatLen ; Pass the length of the mesage
int 80H ; Make syscall to output the text to stdout
mov eax,1 ; Specify Exit syscall
mov ebx,0 ; Return a code of zero
int 80H ; Make syscall to terminate the program
and
mehoggan#mehoggan:~/Code/AsmWork/eatsyscall$ objdump -s ./eatsyscall.o
./eatsyscall.o: file format elf32-i386
Contents of section .data:
0000 45617420 6174204a 6f652773 210a Eat at Joe's!.
Contents of section .txt:
0000 90b80400 0000bb01 000000b9 00000000 ................
0010 ba0e0000 00cd80b8 01000000 bb000000 ................
0020 00cd80 ...
Contents of section .stab:
0000 00000000 64000100 00000000 ....d.......
Contents of section .stabstr:
0000 00
I am using the following command to assemble:
nasm -f elf -g -F stabs eatsyscall.asm
and I am using the following command to link:
ld -o eatsyscall eatsyscall.o
When I run GDB on the executable I get the following:
mehoggan#mehoggan:~/Code/AsmWork/eatsyscall$ gdb eatsyscall
GNU gdb (Ubuntu/Linaro 7.3-0ubuntu2) 7.3-2011.08
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /home/mehoggan/Code/AsmWork/eatsyscall/eatsyscall...Can't find any code sections in symbol file
(gdb) quit
What do I need to do in addition to what I am doing above to get gdb to read the debug symbols specified to NASM with the -g flag?
FYI
mehoggan#mehoggan:~/Code/AsmWork/eatsyscall$ cat /etc/*release*
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=11.10
DISTRIB_CODENAME=oneiric
DISTRIB_DESCRIPTION="Ubuntu 11.10"
mehoggan#mehoggan:~/Code/AsmWork/eatsyscall$ uname -a
Linux mehoggan 3.0.0-12-generic-pae #20-Ubuntu SMP Fri Oct 7 16:37:17 UTC 2011 i686 i686 i386 GNU/Linux
mehoggan#mehoggan:~/Code/AsmWork/eatsyscall$
--Update--
Even if I take the 64 bit route with the following commands I am still having no success:
mehoggan#mehoggan:~/Code/AsmWork/eatsyscall$ nasm -f elf64 -g -F stabs eatsyscall.asm
mehoggan#mehoggan:~/Code/AsmWork/eatsyscall$ ld -o eatsyscall eatsyscall.o -melf_x86_64
mehoggan#mehoggan:~/Code/AsmWork/eatsyscall$ ./eatsyscall
bash: ./eatsyscall: cannot execute binary file
mehoggan#mehoggan:~/Code/AsmWork/eatsyscall$ objdump -s eatsyscall.o
eatsyscall.o: file format elf64-x86-64
Contents of section .data:
0000 45617420 6174204a 6f652773 210a Eat at Joe's!.
Contents of section .txt:
0000 9048b804 00000000 00000048 bb010000 .H.........H....
0010 00000000 0048b900 00000000 00000048 .....H.........H
0020 ba0e0000 00000000 00cd8048 b8010000 ...........H....
0030 00000000 0048bb00 00000000 000000cd .....H..........
0040 80 .
Contents of section .stab:
0000 00000000 64000100 00000000 ....d.......
Contents of section .stabstr:
0000 00 .
mehoggan#mehoggan:~/Code/AsmWork/eatsyscall$
How about using section .text istead of section .txt ?`
That is:
SECTION .data ; Section containing initialized data
EatMsg: db "Eat at Joe's!",10
EatLen: equ $-EatMsg
SECTION .bss ; Section containing uninitialized data
SECTION .text ; instead of .txt
Should work just fine afterwards in gdb and if you are on a x64 architecture, use the x64 flags.
I think I am having the same problem as you. Almost literally. I'm working through the same example in the Duntemann book. (The only difference in the source code is that I changed part of the string from Joe to Bob whilst trying to confirm that differences I made in the source code had the expected effect on the compiled executable.)
What I've discovered is slightly curious. I have two computers and am working alternately on each one using a synched dropbox directory. The older machine is running Ubuntu Karmic, because that has the best support for much of the stuff in Duntemann's book. I tried to put Karmic on the new machine as well, but some stuff simply won't install on it because it's no longer supported. So I'm running Ubuntu Oneiric on it instead.
Here's the thing. I can compile and run the exes on both machines. But anything compiled on the Oneiric machine seems to lack symbol information that gdb/kdbg/Insight is happy to work with. The stuff compiled on the Karmic machine works fine. And once built on the Karmic machine and synched with Dropbox, gdb/kdbg/Insight will run THAT exe fine on the Oneiric machine.
So the problem appears to be the compilation process on Oneiric. It is missing or changing something that messes up the ability of the debuggers to work with it properly.
Here is a dump of the Karmic object file:
$ cat karmic.txt
eatsyscall.o: file format elf32-i38
Contents of section .data:
0000 45617420 61742042 6f622773 210a Eat at Bob's!.
Contents of section .text:
0000 90b80400 0000bb01 000000b9 00000000 ................
0010 ba0e0000 00cd80b8 01000000 bb000000 ................
0020 00cd80 ...
Contents of section .comment:
0000 00546865 204e6574 77696465 20417373 .The Netwide Ass
0010 656d626c 65722032 2e30352e 303100 embler 2.05.01.
Contents of section .stab:
0000 01000000 00000a00 02000000 01000000 ................
0010 64000000 00000000 00000000 44001a00 d...........D...
0020 00000000 00000000 44001b00 01000000 ........D.......
0030 00000000 44001c00 06000000 00000000 ....D...........
0040 44001d00 0b000000 00000000 44001e00 D...........D...
0050 10000000 00000000 44001f00 15000000 ........D.......
0060 00000000 44002100 17000000 00000000 ....D.!.........
0070 44002200 1c000000 00000000 44002300 D.".........D.#.
0080 21000000 !...
Contents of section .stabstr:
0000 00656174 73797363 616c6c2e 61736d00 .eatsyscall.asm.
Here is a dump of the Oneiric object file:
$ cat oneiric.txt
eatsyscall.o: file format elf32-i386
Contents of section .data:
0000 45617420 61742042 6f622773 210a Eat at Bob's!.
Contents of section .text:
0000 90b80400 0000bb01 000000b9 00000000 ................
0010 ba0e0000 00cd80b8 01000000 bb000000 ................
0020 00cd80 ...
Contents of section .stab:
0000 01000000 00000b00 02000000 01000000 ................
0010 64000000 00000000 00000000 44001a00 d...........D...
0020 00000000 00000000 44001b00 01000000 ........D.......
0030 00000000 44001c00 06000000 00000000 ....D...........
0040 44001d00 0b000000 00000000 44001e00 D...........D...
0050 10000000 00000000 44001f00 15000000 ........D.......
0060 00000000 44002100 17000000 00000000 ....D.!.........
0070 44002200 1c000000 00000000 44002300 D.".........D.#.
0080 21000000 00000000 64000000 00000000 !.......d.......
Contents of section .stabstr:
0000 00656174 73797363 616c6c2e 61736d00 .eatsyscall.asm.
You can see that the two files are different (there are several extra bytes at the end of the non-working Oneiric file). And whatever nasm is doing on Oneiric is not playing properly with the debugger, it would seem.
Seems to work fine with current CVS version of GDB: "GNU gdb (GDB) 7.3.50.20111108-cvs", and also with GDB 7.2.
It sounds like "Ubuntu/Linaro 7.3-0ubuntu2" is broken in some way.
try using section/segment .text instead of .txt or .code :)