Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Debugging 从使用ARM-GCC编译的elf文件中提取详细的符号信息(结构成员)_Debugging_Gcc_Arm_Elf_Objdump - Fatal编程技术网

Debugging 从使用ARM-GCC编译的elf文件中提取详细的符号信息(结构成员)

Debugging 从使用ARM-GCC编译的elf文件中提取详细的符号信息(结构成员),debugging,gcc,arm,elf,objdump,Debugging,Gcc,Arm,Elf,Objdump,我正在使用ARM-GCC4.7.4为Cortex-M4编译代码。对于我们的调试工具,我需要以人类可读的格式(例如.txt)了解所有变量的名称、类型和地址。映射文件提供了大部分信息,不幸的是,它不适用于以下结构内容: typedef struct { float32_t Ref; // Input: Reference Value float32_t Fdb; // Variable: Feedback Value

我正在使用ARM-GCC4.7.4为Cortex-M4编译代码。对于我们的调试工具,我需要以人类可读的格式(例如.txt)了解所有变量的名称、类型和地址。映射文件提供了大部分信息,不幸的是,它不适用于以下结构内容:

typedef struct {    float32_t   Ref;        // Input:   Reference Value
            float32_t   Fdb;        // Variable:    Feedback Value
            float32_t   Err;        // Input:   Control Error
            float32_t   Kp;     // Parameter:   Gain of the Proportional Part
            float32_t   Up;         // Output:  Output of Proportional Part
            float32_t   Ki;     // Parameter:   Gain of the Integral Part
            float32_t   Ui;     // Output:  Output of the Integral Part
            float32_t   OutPreSat;  // Output:  Not saturated Output
            float32_t   OutMax;     // Parameter:   Maximum Output
            float32_t   OutMin;     // Parameter:   Minimum Output
            float32_t   Out;        // Output:  Saturated Output
        } PI_REG;

 PI_REG BU_Uctrl_Udc_PI_Reg = BU_UCTRL_UDC_PI_REG_INIT;
因此,我尝试使用nm、readelf和objdump工具从.elf文件中获取一些信息,该文件是用dwarf-2格式的参数-g3编译的。只有使用objdump,我才能找到我搜索的信息:

objdump –Wi myfile.elf >symbols.txt
有关typedef PI_REG的以下信息可在symbols.txt文件中找到:

 <1><38883>: Abbrev Number: 2 (DW_TAG_base_type)
    <38884>   DW_AT_byte_size   : 4
    <38885>   DW_AT_encoding    : 4 (float)
    <38886>   DW_AT_name        : (indirect string, offset: 0x2c63e): float 
 <1><38891>: Abbrev Number: 11 (DW_TAG_typedef)
    <38892>   DW_AT_name        : (indirect string, offset: 0xb336d): float32_t
    <38896>   DW_AT_decl_file   : 4 
    <38897>   DW_AT_decl_line   : 370   
    <38899>   DW_AT_type        : <0x38883>
 <1><390d7>: Abbrev Number: 14 (DW_TAG_structure_type)
    <390d8>   DW_AT_byte_size   : 44    
    <390d9>   DW_AT_decl_file   : 6 
    <390da>   DW_AT_decl_line   : 26    
    <390db>   DW_AT_sibling     : <0x39176> 
 <2><390df>: Abbrev Number: 16 (DW_TAG_member)
    <390e0>   DW_AT_name        : Ref   
    <390e4>   DW_AT_decl_file   : 6 
    <390e5>   DW_AT_decl_line   : 26    
    <390e6>   DW_AT_type        : <0x38891> 
    <390ea>   DW_AT_data_member_location: 2 byte block: 23 0 (DW_OP_plus_uconst: 0) 
 <2><390ed>: Abbrev Number: 16 (DW_TAG_member)
    <390ee>   DW_AT_name        : Fdb   
    <390f2>   DW_AT_decl_file   : 6 
    <390f3>   DW_AT_decl_line   : 27    
    <390f4>   DW_AT_type        : <0x38891> 
    <390f8>   DW_AT_data_member_location: 2 byte block: 23 4 (DW_OP_plus_uconst: 4)
坦率地说,自动收集上述信息的脚本文件要比我的应用程序复杂得多。此外,我必须承认,我真的不知道我如何才能写这样一个脚本。有没有更简单的方法来获取这类信息?虽然我想我已经尝试了所有相关的参数,但是是否有一些参数可以帮助我处理objdump呢?或者是否存在能够实现这一点的工具?最后,我需要一个这样的表(另外,最好有所有的枚举,当然也可以在.elf文件中找到这些枚举):

带有参数--text的工具Fromelf(包含在KeilµVision中)正好提供了这样一个表,但不幸的是,我不能使用它,因为它可能需要.elf文件,或者在本例中称为.axf文件,使用Arm编译器工具链编译。此外,还有许可证问题


谢谢您的提示。

您应该能够要求GDB为您打印此信息,例如:

gdb -q a.out
(gdb) ptype PI_REG

您可以使用EclipseCDT的GDBMI接口以编程方式获取此信息

private def loadElfFile(String elfFilePath) {
    var plugin = new MIPlugin

    var file = new File(elfFilePath)

    var cmdFactory = new CommandFactory("mi2")
    session = plugin.createSession(
        MISession::PROGRAM,
        'gdb',
        cmdFactory,
        file,
        #[],
        true,
        new NullProgressMonitor
    )
}
在那里,您可以查询全局变量及其类型。地址存储在值的hexAddress属性中


这种方法的问题是速度缓慢。一个有50个成员的结构需要大约10秒的时间来处理。查询所有结构需要几分钟。对于IDE工具用例(如模型转换),这是不切实际的。你必须深入到精灵和矮人那里。

你需要的是帕霍尔吗?它可以转储具有大小和偏移量的可变结构

pahole −−reorganize −C foo xxx.out

struct foo {
int a; / 0 4 /
char c[4]; / 4 4 /
void b; / 8 8 /
long g; / 16 8 /
}; / size: 24, cachelines: 1 /
/ last cacheline: 24 bytes /
/ saved 8 bytes! /

Linux内核源代码中有一个脚本和示例,使用的示例输入。“C”被编译成汇编程序(使用
-S
),并通过
sed
命令进行处理,以生成偏移列表。@artless noise感谢您的评论。我试图熟悉Kbuild的sed-y和cmd_偏移量,但遗憾的是,我完全不懂。如果有一个简单的解决方案,可以被像我这样头脑简单的Windows用户使用和理解,我仍然会很感激任何建议。当然,没有这样简单的解决办法也会有所帮助。谢谢你的回答。ptype PI_REG有效地传递了我在问题开头所述的结构。缺点是,我没有地址,而且我必须知道每个结构或变量的名称。我需要的是一个包含所有全局符号的表格,就像我在问题末尾所说的一样,它是在构建后自动生成的(独立于单个名称的知识)。尽管如此,您对GDB的提示开启了许多新的可能性,也许我会在一千个GDB命令中找到一个。我很感激任何进一步的暗示。
gdb -q a.out
(gdb) ptype PI_REG
private def loadElfFile(String elfFilePath) {
    var plugin = new MIPlugin

    var file = new File(elfFilePath)

    var cmdFactory = new CommandFactory("mi2")
    session = plugin.createSession(
        MISession::PROGRAM,
        'gdb',
        cmdFactory,
        file,
        #[],
        true,
        new NullProgressMonitor
    )
}
pahole −−reorganize −C foo xxx.out

struct foo {
int a; / 0 4 /
char c[4]; / 4 4 /
void b; / 8 8 /
long g; / 16 8 /
}; / size: 24, cachelines: 1 /
/ last cacheline: 24 bytes /
/ saved 8 bytes! /