1.命令简介c ++++ filt命令可用于解析C ++和Java中的修改符号,例如变量和函数的名称。
我们知道,在C ++和Java中,允许函数重载,这意味着我们可以编写具有相同名称但参数类型不同的多个函数。
实现取决于编译器的名称处理机制,即编译器将修改函数的名称并添加参数信息。
请考虑以下程序:使用g ++编译上面的print.cpp以生成目标文件print.o。
g ++-cprint.cpp-oprint.o,然后使用命令字符串在print.o中找到可打印的字符串。
stringsprint.oreadelfGCC:(GNU)4.8.520150623(RedHat4.8.5-4).symtab.strtab.shstrtab.rela.text.data.bss.rodata.rela.init_array.comment.note.GNU-stack.rela.eh_frameprint。
发现cpp_ZStL8__ioinit_Z41__static_initialization_and_destruction_0ii_ZL5dTest_GLOBAL__sub_I__Z5printRKSs_Z5printRKSs_ZSt4cout_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc_ZStlsIcSt11char_traitsIcESaIcEERSt13basic_ostreamIT_T0_ES7_RKSbIS4_S5_T1_E_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6__ZNSolsEPFRSoS_E_ZNSt8ios_base4InitC1Ev__dso_handle_ZNSt8ios_base4InitD1Ev__cxa_atexit其中两个字符串_ZL5dTest和_Z5printRKSs,基于它包含,我们一般能够猜测,对应DTEST常量和功能的源代码打印两个字符串()的内容。
使用c ++ filt进行符号分析(symboldemangling)以验证我们的猜想。
c ++ filt_ZL5dTestdTestc ++ filt_Z5printRKSsprint(std :: basic_string,std :: allocator> const&)猜测是正确的。
修改源文件中的变量名和函数名后,可以使用c ++ filt命令将其恢复。
正是c + + filt命令的功能。
2.命令格式c ++ filt [-_ | --strip-underscore] [-n | --no-strip-underscore] [-p | --no-params] [-t | --types] [- i | --no-verbose] [-sformat | --format = format] [-help] [-version] [symbol ...]请注意,如果符号参数[symbol ...]如果未给出,则c ++ filt将从标准输入中读取符号名称。
3.选项说明-_,-strip-underscore在某些系统中,C和C ++编译器在每个名称之前添加一个下划线。
例如,C名称foo获得低级名称_foo。
此选项用于删除初始下划线。
c ++ filt是否默认删除下划线取决于目标-n,--no-strip-underscore不会删除初始下划线-p,--no-params解析函数名称时,no显示函数的类型参数-t,--types尝试解析类型和函数名-i,--no-verbose输出不包含任何实现细节-s,--format = FORMATc ++ filt可以解析不同的编译器修饰此选项是用于指定符号修改的方法:“ auto”:根据可执行文件自动选择符号解析方法,这是默认选项“ gnu”:GNUC ++编译器(g ++)的符号修改方法。
清醒的” “:Lucidcompiler(lcc)符号修改方法“ arm”:C ++ AnnotatedReferenceManual指定的方法“ hp”:HPcompiler(aCC)符号修改方法“ edg”:EDGcompiler符号修改方法“ gnu-v3”:GNUC + +带有V3ABI符号修改方法“ java”的编译器(g ++):GNUJavacompiler(gcj)符号修改方法“ gnat”:GNUadacompiler(GNAT)符号修改方法-帮助显示帮助信息-版本显示版本信息@来自文件的FILE在FILE中读取命令行选项,并且读取的选项将插入@FILE选项的位置。
如果文件不存在或无法读取,则将直接处理@FILE选项,而不是将其忽略。
4.常见示例(1)解析由编译器g ++修改的函数名称。
在第一部分“ 1”中获取函数print()的名称。
命令介绍”举个例子。
c ++ filt-sgnu-v3_Z5printRKSsprint(std :: basic_string,std :: allocator> const&)(2)解析由编译器g ++修改的函数名称,但不显示函数参数类型。
c ++ filt-p_Z5printRKSsprint(3)解析由编译器g ++修改的变量名。
在第一部分“ 1”中获取变量dTest的名称。
命令介绍”举个例子。
c ++ filt_ZL5dTestdTest参考[1] c ++ filtmanual [2] mangle和demangle