目标文件格式分析工具-ar-nm等等
- 格式:pdf
- 大小:192.29 KB
- 文档页数:16
gcc系列⼯具介绍编译器相关知识学习GNU GCC简介GNU GCC是⼀套⾯向嵌⼊式领域的交叉编译⼯具,⽀持多种编程语⾔、多种优化选项并且能够⽀持分步编译、⽀持多种反汇编⽅式、⽀持多种调试信息格式,⽬前⽀持X86、ARM7、StrongARM、PPC4XX、MPC8XX、MIPS R3000等多种CPU。
根据不同的⽬标环境,gcc会有形如:arm-linux-gcc,mips-linux-gcc等对应的⼯具,除了名字和编译运⾏的平台不同,都适⽤于本教程。
GNU GCC的基本功能包括:输出预处理后的C/C++源程序(展开头⽂件和替换宏)输出C/C++源程序的汇编代码输出⼆进制⽬标⽂件⽣成静态库⽣成可执⾏程序转换⽂件格式GCC编译程序的基本过程:gcc根据输⼊⽂件的后缀来确定⽂件的类型,然后根据⽤户的编译选项(包括优化选项、调试信息选项等)将其编译成相应的汇编临时⽂件(后缀为.s);as将该汇编⽂件编译成⽬标⽂件(后缀为.o); ld 根据⽤户的链接选项(包括指定链接命令⽂件等)将⽬标⽂件和各种库链接起来⽣成可执⾏⽂件。
GCC 组成:1. gcc:C/C++交叉编译器gcc是编译的前端程序,它通过调⽤其他程序来实现将程序源⽂件编译成⽬标⽂件的功能。
编译时,它⾸先调⽤预处理程序(cpp)对输⼊的源程序进⾏处理,然后调⽤ cc1 将预处理后的程序编译成汇编代码,最后由as将汇编代码编译成⽬标代码。
gcc具有丰富的命令选项,可以控制编译的各个阶段,满⾜⽤户的各种编译需求。
2. as:汇编器as将汇编语⾔程序转换为ELF (Executable and Linking Format,执⾏时链接⽂件格式)格式的可重定位⽬标代码,这些⽬标代码同其它⽬标模块或函数库易于定位和链接。
as产⽣⼀个交叉参考表和⼀个标准的符号表,产⽣的代码和数据能够放在多个区 (Section)中。
3. ld:连接器ld根据链接定位⽂件Linkcmds中的代码区、数据区、BSS区和栈区等定位信息,将可重定位的⽬标模块链接成⼀个单⼀的、绝对定位的⽬标程序。
arm-linux工具的功能如下:arm-linux-addr2line 把程序地址转换为文件名和行号。
在命令行中给它一个地址和一个可执行文件名,它就会使用这个可执行文件的调试信息指出在给出的地址上是哪个文件以及行号。
arm-linux-ar 建立、修改、提取归档文件。
归档文件是包含多个文件内容的一个大文件,其结构保证了可以恢复原始文件内容。
arm-linux-c++flit 连接器使用它来过滤 C++ 和 Java 符号,防止重载函数冲突。
arm-linux-gprof 显示程序调用段的各种数据。
arm-linux-ld 是连接器,它把一些目标和归档文件结合在一起,重定位数据,并连接符号引用。
通常,建立一个新编译程序的最后一步就是调用ld。
arm-linux-nm 列出目标文件中的符号。
arm-linux-objcopy 把一种目标文件中的内容复制到另一种类型的目标文件中。
arm-linux-objdump 显示一个或者更多目标文件的信息。
使用选项来控制其显示的信息,它所显示的信息通常只有编写编译工具的人才感兴趣。
arm-linux-ranlib 产生归档文件索引,并将其保存到这个归档文件中。
在索引中列出了归档文件各成员所定义的可重分配目标文件。
arm-linux-readelf 显示elf格式可执行文件的信息。
arm-linux-size 列出目标文件每一段的大小以及总体的大小。
默认情况下,对于每个目标文件或者一个归档文件中的每个模块只产生一行输出。
arm-linux-string 打印某个文件的可打印字符串,这些字符串最少4个字符长,也可以使用选项-n设置字符串的最小长度。
默认情况下,它只打印目标文件初始化和可加载段中的可打印字符;对于其他类型的文件它打印整个文件的可打印字符。
这个程序对于了解非文本文件的内容很有帮助。
arm-linux-strip 丢弃目标文件中的全部或者特定符号。
arm-linux-gcc -wall -O2 -c -o $@ $<-o 只激活预处理,编译,和汇编,也就是他只把程序做成obj文件-Wall 指定产生全部的警告信息-O2 编译器对程序提供的编译优化选项,在编译的时候使用该选项,可以使生成的执行文件的执行效率提高-c 表示只要求编译器进行编译,而不要进行链接,生成以源文件的文件名命名但把其后缀由 .c 或 .cc 变成 .o 的目标文件-S 只激活预处理和编译,就是指把文件编译成为汇编代码arm-linux-ld 直接指定代码段,数据段,BSS段的起始地址-Tbss ADDRESS Set address of .bss section-Tdata ADDRESS Set address of .data section-Ttext ADDRESS Set address of .text section示例:${CROSS}ld -Ttext=0x33000000 led.o -o led.elf使用连接脚本设置地址:arm-linux-ld -Tbeep.lds start.o beep.o -o beep.elf其中beep.lds 为连接脚本如下:arm-linux-objcopy被用来复制一个目标文件的内容到另一个文件中,可用于不同源文件的之间的格式转换示例:arm-linux-objcopy –o binary –S elf_file bin_file常用的选项:input-file , outflie输入和输出文件,如果没有outfile,则输出文件名为输入文件名2.-l bfdname或—input-target=bfdname用来指明源文件的格式,bfdname是BFD库中描述的标准格式名,如果没指明,则arm-linux-objcopy自己分析3.-O bfdname 输出的格式4.-F bfdname 同时指明源文件,目的文件的格式5.-R sectionname 从输出文件中删除掉所有名为sectionname的段6.-S 不从源文件中复制重定位信息和符号信息到目标文件中7.-g 不从源文件中复制调试符号到目标文件中arm-linux-objdump查看目标文件(.o文件)和库文件(.a文件)信息arm-linux-objdump -D -m arm beep.elf > beep.dis-D 显示文件中所有汇编信息-m machine指定反汇编目标文件时使用的架构,当待反汇编文件本身没有描述架构信息的时候(比如S-records),这个选项很有用。
分析工具哪个比较好用(6款主流海工分析软件功能对比)本文重点介绍当前几款主要海工分析软件,并且分析海工软件的特点对比与发展趋势,希望对从事海洋工程设计工作的工程师学习和应用有所帮助!一、当前其他主流海工分析软件1、WAMITWAMIT(Wave Analysis MIT)是计算零航速浮式结构物与波浪相互作用的分析软件,由麻省理工学院的J.N Newman先生开发,于1987年首次推出。
1999年,C. H. Lee与Newman共同成立WAMIT公司。
WAMIT软件发展中比较重要的版本是2000年推出的WAMIT6.0及其升级版。
在该系列版本中WAMIT具备了高阶面源计算方法。
其高阶模块具备了不同周期、不同波浪来向作用下的二阶载荷波浪计算分析的能力。
WAMIT当前最新版本为7.0,该版本主要增加了并行运算功能。
WAMIT 自诞生以来逐渐成为浮体分析计算领域的标志性软件,其计算结果经常作为计算结果精度对比的参照物,足以证明WAMIT软件在业界所具有的广泛影响力和认可度。
当前,全世界共有超过100个机构、公司和研究院所在使用WAMIT。
WAMIT基本模块具备的计算功能包括:浮式结构物静水刚度、附加质量、辐射阻尼、波浪力(包括绕射力)、二阶定常波浪力。
WAMIT高阶模块计算功能包括:高阶面源法及考虑二阶速度势影响的二阶差频、和频载荷。
WAMIT在求解二阶差频、和频载荷时可以通过压力积分求解(同AQWA解法),也可以通过自由表面法(Free Surface)来进行计算。
相比而言,通过自由表面法得到的结果更精确,但是也付出更多的计算时间。
WAMIT还可以通过广义刚度法实现更广泛的计算分析,譬如多个结构物铰接、添加月池阻尼等。
另外,WAMIT可以考虑液舱晃荡的影响,其计算结果能够较好的反映出液舱共振运动对于整体运动性能的耦合影响。
WAMIT软件没有前处理功能,计算模型需要通过第三方软件建立。
运行完毕后,WAMIT会输出面元模型文件,但需要通过其他程序查看,如利用Tecplot。
固件解构详细方法固件解构是指将硬件设备的固件文件进行分析和解析的过程,通过分析固件文件的结构和内容,可以获取有关硬件设备的信息,包括硬件架构、操作系统、驱动程序等。
本文将介绍一种固件解构的详细方法,帮助读者了解如何进行固件解构的工作。
一、收集固件文件首先,我们需要收集到硬件设备的固件文件。
固件文件通常是一种二进制文件,可以从设备的官方网站或者其他渠道下载得到。
确保所收集的固件文件与目标设备的型号和版本相匹配,以避免解构时出现错误。
二、文件格式分析在进行固件解构之前,我们需要对固件文件的格式进行分析。
固件文件可能采用不同的文件格式,如BIN、IMG、BIN、EXE等。
我们可以使用文件格式分析工具,如binwalk、firmware-mod-kit等来分析固件文件的格式和结构。
这些工具可以识别固件文件中的文件系统、压缩格式、文件头等信息,为后续的解构工作提供参考。
三、文件提取一旦我们了解了固件文件的格式和结构,就可以开始进行文件的提取工作。
固件文件通常由多个模块或者组件组成,如操作系统、驱动程序、应用程序等。
我们可以使用相应的工具来提取这些组件,如binwalk、dd、7-zip等。
提取时需要注意保持文件的完整性,确保提取出来的文件可以正常使用。
四、文件解析在完成文件提取之后,我们需要对提取出来的文件进行解析。
这些文件可能是二进制文件、可执行文件、配置文件等。
我们可以使用相应的工具来进行解析,如IDA Pro、Hopper、Ghidra等。
通过分析这些文件,我们可以了解到固件文件中的各个组件的功能和作用。
五、逆向工程逆向工程是固件解构的重要步骤之一,它可以帮助我们理解固件文件的内部工作原理。
在逆向工程的过程中,我们可以使用反汇编工具、调试工具等来分析固件文件的汇编代码、调用关系、函数功能等。
通过逆向工程,我们可以深入了解固件文件的实现细节,找出其中的漏洞或者改进的空间。
六、代码分析固件文件中的代码是实现各个功能的核心部分,对代码进行分析可以帮助我们了解固件文件的运行机制。
∙nm --列出目标文件(.o)的符号清单。
NND,太激动了。
刚知道此命令时让我三天没睡好觉。
我就使劲用了一把。
∙常用法:∙nm -s filename.a/filename.o/a.out 里边所有的符号列表一清二楚。
例:# nm -s a.out080495b8 A __bss_start08048334 t call_gmon_start080495b8 b completed.5751080494b8 d __CTOR_END__080494b4 d __CTOR_LIST__080495ac D __data_start080495ac W data_start08048450 t __do_global_ctors_aux08048360 t __do_global_dtors_aux080495b0 D __dso_handle080494c0 d __DTOR_END__080494bc d __DTOR_LIST__080494c8 d _DYNAMIC080495b8 A _edata080495bc A _end0804847c T _fini08048498 R _fp_hw08048390 t frame_dummy080484b0 r __FRAME_END__08049594 d _GLOBAL_OFFSET_TABLE_w __gmon_start__0804844c T __i686.get_pc_thunk.bx080482b8 T _init080494b4 a __init_array_end080494b4 a __init_array_start0804849c R _IO_stdin_used080494c4 d __JCR_END__080494c4 d __JCR_LIST__w _Jv_RegisterClasses080483e0 T __libc_csu_fini080483f0 T __libc_csu_initU __libc_start_main@@GLIBC_2.0080483b4 T main080495b4 d p.5749U puts@@GLIBC_2.008048310 T _start选项/属性:-a或--debug-syms:显示调试符号。
第7章C语言开发工具实验目的●学习理解Linux环境中将C程序转换成可执行文件所经历的过程●学习使用Linux环境中将C程序转换成可执行文件所采用的命令●学习使用indent、gcc、make、gdb命令实验指导Linux操作系统提供了非常好的编程环境,Linux系统支持多种高级语言。
C语言是Linux中最常用的系统编程语言之一,Linux内核绝大部分代码是用C语言编写的,Linux 平台上的相当多的应用软件也是用C语言开发的。
使用C语言,软件开发人员可以通过函数库和系统调用非常方便实现系统服务。
另外,还有很多有用的工具为程序开发和维护提供便利。
Linux操作系统拥有许多用于程序的生成以及分析的软件工具。
其中包括用于编辑和缩进代码、编译与连接程序、处理模块化程序、创建程序库、剖析代码、检验代码可移植性、源代码管理、调试、跟踪以及检测运行效率等等的工具。
在这一章里,我们将介绍一些常用的C语言工具,主要包括gcc、make工具。
make工具可以用来跟踪那些更新过的模块,并确保在编译时使用所有程序模块的最新版本。
7.1 编写程序的工具我们编写程序可以用Linux文本编辑器(如:pico编辑器、vi编辑器、gedit编辑器、emacs 编辑器和xemacs编辑器)。
我们首先使用vi 编辑器来编辑hello.c,这是一个C 语言的文件。
$ vi hello.c输入下列程序代码:#include <sdtio.h>#include <sdtlib.h>int main(){int i,j;for (i=0,j=10; i < j; i++){。
目标文件格式分析工具: ar,nm,objdump,objcopy,readelf如果普通编程不需要了解这些东西,如果想精确控制你的目标文件的格式或者你想查看一下文件里的内容以便作出某种判断,那么你可以看一下下面的工具:ar,nm,objdump,objcopy。
具体用法请参考man在线手册。
ar基本用法ar命令可以用来创建、修改库,也可以从库中提出单个模块。
库是一单独的文件,里面包含了按照特定的结构组织起来的其它的一些文件(称做此库文件的member)。
原始文件的内容、模式、时间戳、属主、组等属性都保留在库文件中。
下面是ar命令的格式:ar [-]{dmpqrtx}[abcfilNoPsSuvV] [membername] [count] archive files...例如我们可以用ar rv libtest.a hello.o hello1.o来生成一个库,库名字是test,链接时可以用-ltest链接。
该库中存放了两个模块hello.o和hello1.o。
选项前可以有‘-'字符,也可以没有。
下面我们来看看命令的操作选项和任选项。
现在我们把{dmpqrtx}部分称为操作选项,而[abcfilNoPsSuvV]部分称为任选项。
{dmpqrtx}中的操作选项在命令中只能并且必须使用其中一个,它们的含义如下:•d:从库中删除模块。
按模块原来的文件名指定要删除的模块。
如果使用了任选项v 则列出被删除的每个模块。
•m:该操作是在一个库中移动成员。
当库中如果有若干模块有相同的符号定义(如函数定义),则成员的位置顺序很重要。
如果没有指定任选项,任何指定的成员将移到库的最后。
也可以使用'a','b',或'I'任选项移动到指定的位置。
•p:显示库中指定的成员到标准输出。
如果指定任选项v,则在输出成员的内容前,将显示成员的名字。
如果没有指定成员的名字,所有库中的文件将显示出来。
•q:快速追加。
增加新模块到库的结尾处。
并不检查是否需要替换。
'a','b',或'I'任选项对此操作没有影响,模块总是追加的库的结尾处。
如果使用了任选项v则列出每个模块。
这时,库的符号表没有更新,可以用'ar s'或ranlib来更新库的符号表索引。
•r:在库中插入模块(替换)。
当插入的模块名已经在库中存在,则替换同名的模块。
如果若干模块中有一个模块在库中不存在,ar显示一个错误消息,并不替换其他同名模块。
默认的情况下,新的成员增加在库的结尾处,可以使用其他任选项来改变增加的位置。
•t:显示库的模块表清单。
一般只显示模块名。
•x:从库中提取一个成员。
如果不指定要提取的模块,则提取库中所有的模块。
下面在看看可与操作选项结合使用的任选项:•a:在库的一个已经存在的成员后面增加一个新的文件。
如果使用任选项a,则应该为命令行中membername参数指定一个已经存在的成员名。
•b:在库的一个已经存在的成员前面增加一个新的文件。
如果使用任选项b,则应该为命令行中membername参数指定一个已经存在的成员名。
•c:创建一个库。
不管库是否存在,都将创建。
•f:在库中截短指定的名字。
缺省情况下,文件名的长度是不受限制的,可以使用此参数将文件名截短,以保证与其它系统的兼容。
•i:在库的一个已经存在的成员前面增加一个新的文件。
如果使用任选项i,则应该为命令行中membername参数指定一个已经存在的成员名(类似任选项b)。
•l:暂未使用•N:与count参数一起使用,在库中有多个相同的文件名时指定提取或输出的个数。
•o:当提取成员时,保留成员的原始数据。
如果不指定该任选项,则提取出的模块的时间将标为提取出的时间。
•P:进行文件名匹配时使用全路径名。
ar在创建库时不能使用全路径名(这样的库文件不符合POSIX标准),但是有些工具可以。
•s:写入一个目标文件索引到库中,或者更新一个存在的目标文件索引。
甚至对于没有任何变化的库也作该动作。
对一个库做ar s等同于对该库做ranlib。
•S:不创建目标文件索引,这在创建较大的库时能加快时间。
•u:一般说来,命令ar r...插入所有列出的文件到库中,如果你只想插入列出文件中那些比库中同名文件新的文件,就可以使用该任选项。
该任选项只用于r操作选项。
•v:该选项用来显示执行操作选项的附加信息。
•V:显示ar的版本。
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__8CPThreadPv00000038 T Start__8CPThread00000014 T _._8CPThread00000000 T __8CPThread00000000 ? __FRAME_BEGIN__.......................................则nm -A 的输出如下:libtest.a:CPThread.o:00000068 T Main__8CPThreadPvlibtest.a:CPThread.o:00000038 T Start__8CPThreadlibtest.a:CPThread.o:00000014 T _._8CPThreadlibtest.a:CPThread.o:00000000 T __8CPThreadlibtest.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。