linux toolchains 二进制相关工具

nm、readelf和共享库  的区别: http://ly50247.appspot.com/2010/12/7/nm_readelf_so.html

nm   :                                      nm用来列出目标文件的符号清单   下面列出该命令的任选项,大部分支持“-”开头的短格式和“-“开头的长格式。 -A、-o或--print-file-name:在找到的各个符号的名字前加上文件名,而不是在此文件的所有符号前只出现文件名一次。

readelf -- 显示elf文件信息:         readelf命令可以显示符号、段信息、二进制文件格式的信息等,这在分析编译器如何工从源代码创建二进制文件时非常有用。

                                                     LINUX 平台下三种主要的可执行文件格式:a.out(assembler and link editor output 汇编器和链接编辑器的输出)、COFF(Common Object File Format 通用对象文件格式)、ELF(Executable and Linking Format 可执行和链接格式)。


这说明nm输出的许多符号信息是用于链接的,而不是运行的。还有如果用g++ -g编译的话用nm -a还会读到调试信息。




Motorola tools chain:

[leosu@leo bin]$ pwd

/usr/local/motorola/toolchain/st40/2.4.0/bin

[leosu@leo bin]$ ls

sh4-motorola-linux-uclibc-addr2line  sh4-motorola-linux-uclibc-elfedit    sh4-motorola-linux-uclibc-gprof    sh4-motorola-linux-uclibc-ranlib

sh4-motorola-linux-uclibc-ar         sh4-motorola-linux-uclibc-g++        sh4-motorola-linux-uclibc-ld       sh4-motorola-linux-uclibc-readelf

sh4-motorola-linux-uclibc-as         sh4-motorola-linux-uclibc-gcc        sh4-motorola-linux-uclibc-ld.bfd   sh4-motorola-linux-uclibc-size

sh4-motorola-linux-uclibc-c++        sh4-motorola-linux-uclibc-gcc-4.5.3  sh4-motorola-linux-uclibc-nm       sh4-motorola-linux-uclibc-strings

sh4-motorola-linux-uclibc-c++filt    sh4-motorola-linux-uclibc-gccbug     sh4-motorola-linux-uclibc-objcopy  sh4-motorola-linux-uclibc-strip

sh4-motorola-linux-uclibc-cpp        sh4-motorola-linux-uclibc-gcov       sh4-motorola-linux-uclibc-objdump


使用示例:addr2line,指令地址翻译器 ..............................       $/usr/local/motorola/toolchain/st710x/1.2.0/bin/sh4-motorola-linux-gnu-addr2line -e usr/bin/streamer 0x299e1328



nm用于查看可执行文件或者动态/静态链接库的函数使用情况。
nm st40/*.so
U DES_ecb3_encrypt
U DES_set_key_unchecked
0001c624 T _dmalloc_chunk_heap_check
0001a8e0 T _dmalloc_chunk_log_changed
0001a428 T _dmalloc_chunk_log_stats
0001b7e8 T _dmalloc_chunk_malloc

GDB 积累:
gdb 中根据地址解析出来 源代码的地方:
(gdb) x 0x41bc34
0x41bc34 <_ZN5ekioh8EKMemory6callocEjj>:        0x4f222fe6

查看调用栈
(gdb) bt

链接正在运行的程序或进程
#gdb --pid pidnum
(gdb)attach PID
detach正在调试的程序:
(gdb)detach PID



设置断点:
(gdb) bt ekmalloc
(gdb) bt KreaTvGfxPlatform::startApplication

删除断点:
(gdb) delete [breakpoints][range]

删除所有断点:
(gdb) clear
(gdb) delete

暂停断点的执行:
(gdb) disable [breakpoints][range]

继续断点的执行:
(gdb) enable [breakpoints][range]


查看断点:
(gdb) info break


run
(gdb) run   or  r

continue
(gdb) c  or continue

退出函数:
(gdb) finish

退出gdb
(gdb) quit or q

symbol添加:
cc -g hello.c -o hello
g++ -g hello.cpp -o hello

help
(gdb) help


终止调试
(gdb) c
Continuing.

Ctrl+c    
Program received signal SIGINT, Interrupt.
0x2abe570e in pivot_root () from /lib/libc.so.0

(gdb) detach 594    
(gdb) q



/usr/local/motorola/toolchain/st40/2.0.1/sh4-motorola-linux-uclibc/sys-root/lib
/opt/nfs/rootdisk/lib

[leo@localhost lib]$ pwd
/usr/local/motorola/toolchain/st40/2.0.1/sh4-motorola-linux-uclibc/sys-root/lib
[leo@localhost lib]$ nm libdl-0.9.30rc3.so | grep dlopen
0000106c T dlopen
[leo@localhost lib]$ nm libdl-0.9.30rc3.so | grep malloc
U _dl_malloc_function
U malloc

原始c库使用:
cp /usr/local/motorola/toolchain/st40/2.0.1/sh4-motorola-linux-uclibc/sys-root/lib/libdl-0.9.30rc3.so  /opt/nfs/rootdisk/lib/libdl-0.9.30rc3.so 
cp /usr/local/motorola/toolchain/st40/2.0.1/sh4-motorola-linux-uclibc/sys-root/lib/libuClibc-0.9.30rc3.so  /opt/nfs/rootdisk/lib/libuClibc-0.9.30rc3.so 
cp /usr/local/motorola/toolchain/st40/2.0.1/sh4-motorola-linux-uclibc/sys-root/lib/libpthread-0.9.30rc3.so  /opt/nfs/rootdisk/lib/libpthread-0.9.30rc3.so 





自己编译一套Tool-Chain的经历

工具链binutils2.17 在http://mirrors.kernel.org/sourceware/binutils/releases/ 有下载;

GCC4.1.1 在http://mirrors.kernel.org/sourceware/gcc/releases/ 有下载;

GDB6.5 ,Insight等等工具在http://mirrors.kernel.org/sourceware/ 上都有下载;

1用源码安装binutils

a.binutils的介绍(网上的介绍在http://www.sourceware.org/binutils/)

binutils 是一套binary utilities,主要包括:

  • ld - the GNU linker.

  • as - the GNU assembler.

当然也会包含一些分析二进制文件实用工具:

  • addr2line - Converts addresses into filenames and line numbers.  addr2line,指令地址翻译器 ..............................

  • ar - A utility for creating, modifying and extracting from archives.

  • c++filt - Filter to demangle encoded C++ symbols.

  • gprof - Displays profiling information.

  • nlmconv - Converts object code into an NLM.

  • nm - Lists symbols from object files.

  • objcopy - Copys and translates object files.

  • objdump - Displays information from object files.

  • ranlib - Generates an index to the contents of an archive.

  • readelf - Displays information from any ELF format object file.

  • size - Lists the section sizes of an object or archive file.

  • strings - Lists printable strings from files.

  • strip - Discards symbols.

  • windres - A compiler for Windows resource files.

其中大多数工具使用BFD, the Binary File Descriptor library, 做一些低层的操作. 许多工具也直接使用 opcodes library 来汇编和反汇编机器指令.binutils已经移植到很多主流的Unix变种系统上,它们主要是用来给GNU system(GNU/Linux)提供编译和链接程序的工具.

源代码下载的地址:http://mirrors.kernel.org/sourceware/binutils

b.安装的简单过程.

    首先将下载的源码安装包拷贝到一个临时目录(我假设是/tmp):

    $ cp 你下载的目录地址 /tmp

    $ cd /tmp

    在这里简单讲一下压缩包最主要的格式及解压缩的方法:

  1. tar : 用tar 命令就可以了                  $ tar -xvf  binutils-2.17.tar

  2. gz : 用tar命令带上z参数                  $ tar -zxvf binutils-2.17.tar.gz

  3. bz2 : 用tar命令带上j参数                $ tar -jxvf binutils-2.17.tar.bz2

    然后进入目录 /tmp/binutils-2.17

     $ cd /tmp/binutils-2.17

     配置要安装的目标系统和目标目录

      --target 指示你将要安装的这套工具作用的文件是在哪个平台下的

      --divfix 安装的目标目录

      $ ./configure --target=arm-elf  --divfix=/选择你要将可执行程序安装到什么目录下

      编译源程序:$ make

      安装程序:$ make install


2, 用源码安装GCC

3, 在cygwin上用源码安装GDB及Insight

4, 开发辅助工具source-navigator以及split的介绍与安装






nm基本用法

   nm用来列出目标文件的符号清单。下面是nm命令的格式:

  nm [-a│--debug-syms] [-g│--extern-only]
          [-B] [-C│--demangle[=style]] [-D│--dynamic]
          [-S│--print-size] [-s│--print-armap]
          [-A│-o│--print-file-name][--special-syms]
          [-n│-v│--numeric-sort] [-p│--no-sort]
          [-r│--reverse-sort] [--size-sort] [-u│--undefined-only]
          [-t radix│--radix=radix] [-P│--portability]
          [--target=bfdname] [-f format│--format=format]
          [--defined-only] [-l│--line-numbers] [--no-demangle]
          [-V│--version] [-X 32_64] [--help] [objfile...]

  如果没有为nm命令指出目标文件,则nm假定目标文件是a.out。下面列出该命令的任选项,大部分支持"-"开头的短格式和"—"开头的长格式。

  • -A、-o或--print-file-name:在找到的各个符号的名字前加上文件名,而不是在此文件的所有符号前只出现文件名一次。

    例如nm libtest.a的输出如下:

    CPThread.o:
    00000068 T Main__8CPThreadPv
    00000038 T Start__8CPThread
    00000014 T _._8CPThread
    00000000 T __8CPThread
    00000000 ? __FRAME_BEGIN__
    .......................................

    则nm -A 的输出如下:

    libtest.a:CPThread.o:00000068 T Main__8CPThreadPv
    libtest.a:CPThread.o:00000038 T Start__8CPThread
    libtest.a:CPThread.o:00000014 T _._8CPThread
    libtest.a:CPThread.o:00000000 T __8CPThread
    libtest.a:CPThread.o:00000000 ? __FRAME_BEGIN__
    ..................................................................
  • -a或--debug-syms:显示所有的符号,包括debugger-only symbols。

  • -B:等同于--format=bsd,用来兼容MIPS的nm。

  • -C或--demangle:将低级符号名解析(demangle)成用户级名字。这样可以使得C++函数名具有可读性。

  • --no-demangle:默认的选项,不需要将低级符号名解析成用户级名。

  • -D或--dynamic:显示动态符号。该任选项仅对于动态目标(例如特定类型的共享库)有意义。

  • -f format:使用format格式输出。format可以选取bsd、sysv或posix,该选项在GNU的nm中有用。默认为bsd。

  • -g或--extern-only:仅显示外部符号。

  • -n、-v或--numeric-sort:按符号对应地址的顺序排序,而非按符号名的字符顺序。

  • -p或--no-sort:按目标文件中遇到的符号顺序显示,不排序。

  • -P或--portability:使用POSIX.2标准输出格式代替默认的输出格式。等同于使用任选项-f posix。

  • -s或--print-armap:当列出库中成员的符号时,包含索引。索引的内容包含:哪些模块包含哪些名字的映射。

  • -r或--reverse-sort:反转排序的顺序(例如,升序变为降序)。

  • --size-sort:按大小排列符号顺序。该大小是按照一个符号的值与它下一个符号的值进行计算的。

  • -t radix或--radix=radix:使用radix进制显示符号值。radix只能为"d"表示十进制、"o"表示八进制或"x"表示十六进制。

  • --target=bfdname:指定一个目标代码的格式,而非使用系统的默认格式。

  • -u或--undefined-only:仅显示没有定义的符号(那些外部符号)。

  • --defined-only:仅显示定义的符号。

  • -l或--line-numbers:对每个符号,使用调试信息来试图找到文件名和行号。对于已定义的符号,查找符号地址的行号。对于未定义符号,查找符号重定位项的行号。如果可以找到行号信息,显示在符号信息之后。

  • -V或--version:显示nm的版本号。

  • --help:显示nm的任选项。

   对于每一个符号,nm列出其值(the symbol value),类型(the symbol type)和其名字(the symbol name)。

   对于每一个符号来说,其类型如果是小写的,则表明该符号是local的;大写则表明该符号是global(external)的。
符号
类型
说明
A
该符号的值是绝对的,在以后的链接过程中,不允许进行改变。这样的符号值,常常出现在中断向量表中,例如用符号来表示各个中断向量函数在中断向量表中的位置。
B
该符号的值出现在非初始化数据段(bss)中。例如,在一个文件中定义全局static int test。则该符号test的类型为b,位于bss section中。其值表示该符号在bss段中的偏移。一般而言,bss段分配于RAM中
C
该符号为common。common symbol是未初始话数据段。该符号没有包含于一个普通section中。只有在链接过程中才进行分配。符号的值表示该符号需要的字节数。例如在一个c文件中,定义int test,并且该符号在别的地方会被引用,则该符号类型即为C。否则其类型为B。
D
该符号位于初始话数据段中。一般来说,分配到data section中。例如定义全局int baud_table[5] = {9600, 19200, 38400, 57600, 115200},则会分配于初始化数据段中。
G
该符号也位于初始化数据段中。主要用于small object提高访问small data object的一种方式。
I
该符号是对另一个符号的间接引用。
N
该符号是一个debugging符号。
R
该符号位于只读数据区。例如定义全局const int test[] = {123, 123};则test就是一个只读数据区的符号。注意在cygwin下如果使用gcc直接编译成MZ格式时,源文件中的test对应_test,并且其符号类型为D,即初始化数据段中。但是如果使用m6812-elf-gcc这样的交叉编译工具,源文件中的test对应目标文件的test,即没有添加下划线,并且其符号类型为R。一般而言,位于rodata section。值得注意的是,如果在一个函数中定义const char *test = “abc”, const char test_int = 3。使用nm都不会得到符号信息,但是字符串“abc”分配于只读存储器中,test在rodata section中,大小为4。
S
符号位于非初始化数据区,用于small object。
T
该符号位于代码区text section。
U
该符号在当前文件中是未定义的,即该符号的定义在别的文件中。例如,当前文件调用另一个文件中定义的函数,在这个被调用的函数在当前就是未定义的;但是在定义它的文件中类型是T。但是对于全局变量来说,在定义它的文件中,其符号类型为C,在使用它的文件中,其类型为U。
V
该符号是一个weak object。
W
The symbol is a weak symbol that has not been specifically tagged as a weak object symbol.
-
该符号是a.out格式文件中的stabs symbol。
?
该符号类型没有定义

readelf基本用法
readelf 负责显示ELF文件的信息

Usage: readelf  elf-file(s)
Display information about the contents of ELF format files
Options are:
-a --all        全部       Equivalent to: -h -l -S -s -r -d -V -A -I
-h --file-header    文件头   Display the ELF file header
-l --program-headers 程序 Display the program headers
     --segments          An alias for --program-headers
-S --section-headers 段头 Display the sections' header
     --sections          An alias for --section-headers
-e --headers     全部头      Equivalent to: -h -l -S
-s --syms        符号表      Display the symbol table
      --symbols          An alias for --syms
-n --notes        内核注释     Display the core notes (if present)
-r --relocs       重定位     Display the relocations (if present)
-u --unwind            Display the unwind info (if present)
-d --dynamic      动态段     Display the dynamic segment (if present)
-V --version-info 版本    Display the version sections (if present)
-A --arch-specific CPU构架   Display architecture specific information (if any).
-D --use-dynamic   动态段    Use the dynamic section info when displaying symbols
-x --hex-dump= 显示 段内内容Dump the contents of section 
-w[liaprmfFso] or
--debug-dump[=line,=info,=abbrev,=pubnames,=ranges,=macro,=frames,=str,=loc]
                  显示DWARF2调试段内容       Display the contents of DWARF2 debug sections
-I --histogram         Display histogram of bucket list lengths
-W --wide        宽行输出      Allow output width to exceed 80 characters
-H --help              Display this information
-v --version           Display the version number of readelf

你可能感兴趣的:(linux toolchains 二进制相关工具)