teawater さんのプロフィール冒充另类フォトブログリスト ツール ヘルプ
    2006/04/03

    移植GDB(2) native v0.0 (更新时间:2006-02-21)

    http://www.linuxforum.net/forum/showthreaded.php?Cat=&Board=program&Number=595833
    附件中有txt版本 需要登陆后才能看见

    移植GDB(2) native v0.0
    teawater<teawater@gmail.com>
    转载请标明来自 http://www.linuxforum.net




    修改记录:
    v0.0
            2006-02-21,v0.0版本编写完成。
                        没有详细介绍GDB/gdb/solib.c上动态链接库支持的扩展。
            2006-02-02,文档创建。




    目录
    1.写在前面
    2.long ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data)
    3.struct user
    4.GDB/gdb/config/ARCH/TARGET.mh
    5.GDB/gdb/config/ARCH/nm-TARGET.h
    6.GDB/gdb/ARCH-NAT.c 和 GDB/gdb/ARCH-TARGET-NAT.c
    6.1.概述
    6.2.跟寄存器读取有关的函数
    6.3.gregset相关函数
    7.本地core文件支持
    7.1.概述
    7.2.struct core_fns
    7.3.GDB分析core文件的过程
    7.4.让TARGET支持core文件分析的方法
    8.动态连接库支持




    1.写在前面
    本文针对GDB-6.3进行编写。

    native表示对某个ARCH在某个OS上(称为一个TARGET)调试的支持,当然要让ARCH支持本地调试首先要让GDB支持这个TARGET,这个可以参见“移植GDB(1)”。
    GDB对被调试程序的调试主要是通过调用当前TARGET提供的调试接口(ptrace、procfs等,后面将详细介绍)对被调试程序进行控制,同时取得这个程序的寄存器和内存的信息,所以这个调试接口相关的代码就是native代码中比较重要的部分。一般来说不同ARCH在同一个OS会使用同一个调试接口,只是其中略有不同,所以移植一个ARCH到GDB已经支持的一个OS中的时候,只需要根据这个ARCH的情况进行一些编码就可以。而关于调试接口的编写将在“移植GDB(3)”中进行介绍。
    在“GDBINT 11. Native Debugging”中,是对native的介绍,本文的部分内容也将取自其中。

    在以下章节,将先对移植中需要增加和修改的文件依次进行详细介绍,然后对frame进行介绍。下面是文件名中使用的缩写和GDB代码中的定义。
    GDBINT        GDB Internals Manual的缩写。
    GDB           指GDB源文件目录。
    ARCH          体系结构名称。
    TARGET        体系结构下的调试目标,一般是一种操作系统,比如Linux。




    2.long ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data)
    ptrace是一个系统调用,其作用是让一个进程观测和控制另一个进程的执行,因为后面有不少跟其相关的内容,所以先在这里对其进行介绍。注意不同的OS下ptrace的参数等可能略有不同,这里只是简单介绍,具体情况要以实际OS为准。
    不同的参数request值表示不同的控制功能,参数pid是被控制进程的进程ID。
    ptrace的请求和功能说明如下:
    PTRACE_TRACEME,被控制进程向控制进程发出跟踪请求。
    PTRACE_PEEKTEXT,读取被控制进程代码段的一个字,addr给出地址。
    PTRACE_PEEKDATA,读取被控制进程数据段的一个字,addr给出地址。
    PTRACE_PEEKUSR,读取被控制进程user结构中的一个字,addr给出地址。
    PTRACE_POKETEXT,向被控制进程代码段写入一个字,addr给出地址,data给出数据。
    PTRACE_POKEDATA,向被控制进程数据段写入一个字,addr给出地址,data给出数据。
    PTRACE_POKEUSR,向被控制进程user结构写入一个字,addr给出地址,data给出数据。
    PTRACE_CONT,如果data参数为non-zero并且不是SIGSTOP时,它被解释成一个信号传递给被控制进程,否则,无信号被传递。
    PTRACE_KILL,向被控制进程发送SIGKILL信号来终止其。
    PTRACE_SINGLESTEP,使被控制进程单步执行。




    3.struct user
    这个结构在Linux中被定义在Linux Kernel目录include/asm-ARCH/user.h中,因为其中记录了寄存器等跟ARCH和OS相关的信息,所以不同的ARCH和OS是不同的。

    在某些OS比如Linux的很多ARCH的ptrace实现中,PTRACE_PEEKUSR和PTRACE_POKEUSR都只对寄存器相关的参数读写起作用,其他部分根本不进行实际的操作,所以实际对user结构的使用要视实际情况来做。




    4.GDB/gdb/config/ARCH/TARGET.mh
    这个文件是设置一些编译GDB需要的跟当前TARGET有关的文件。下面介绍一下其中可设置的信息。


    NAT_FILE=
    这个是指定描述TARGET的头文件,一般来说这个头文件的写法为nm-TARGET.h存放在GDB/gdb/config/ARCH/目录中,具体内容将在后面介绍。

    NATDEPFILES=
    这个是指定要编译的.o文件,后面将介绍的跟TARGET有关的.c文件编译成的.o文件需要在这里指出。这个TARGET需要的ARCH-TARGET-NAT.o文件也需要在这里指定,有些ARCH会有一个通用的ARCH-NAT.o文件也在这里指定。
    下面介绍一下常见的.o文件:
    inftarg.o
    这个文件中包含了通过ptrace对被调试程序进行控制的调试接口。
    procfs.o
    这个文件中包含了通过/proc对被调试程序进行控制的调试接口。
    sol-thread.o
    这个文件中包含了Solaris线程调试接口。
    corelow.o
    这个文件包含了core调试接口,给GDB增加了对core文件进行分析的功能。
    core-aout.o
    这个文件向上面的corelow.o提供了对未知格式的core文件的支持。
    core-regset.o
    这个文件向上面的corelow.o提供了对elf格式同时支持regsets结构的OS的core文件的支持。
    infptrace.o
    这个文件中包含了一些使用ptrace的接口,如果NATDEPFILES=包含inftarg.o则最好包含这个文件。
    fork-child.o
    这个文件中包含了fork和exec启动被调试程序的接口,一般的NATDEPFILES=都需要包含这个文件。
    gcore.o
    给GDB增加一个gcore的命令,用来给当前被调试程序产生core文件。
    thread-db.o
    这个.o文件包含了对target multi-thread的支持。
    proc-service.o
    用来向不支持proc_service的编译环境提供proc-service函数,thread-db.o文件需要proc-service函数。
    linux-nat.o
    这个.o文件包含了很多Linux相关的命令等,建议当TARGET所在的OS是Linux的时候包含这个.o文件。
    solib.o
    这个.o文件中包含了通用的动态链接库处理函数,具体可见下面对SOLIB_ADD等宏的介绍。
    solib-TYPE.o
    有一系列.o文件,比如solib-svr4.o solib-aix.o,他们是向solib.o提供对某个具体动态库支持的.o文件。
    这其中跟Linux比较密切的有solib-svr4.o和solib-legacy.o。

    LOADLIBES=
    指定连接时候需要的库文件,如果TARGET的OS是Linux,因为需要在GDB启动的时候转载动态链接库libthread_db,所以通常使用“-ldl -rdynamic”。

    具体这个文件的编写还可以参照其他TARGET的.mh文件。




    5.GDB/gdb/config/ARCH/nm-TARGET.h
    这个文件是TARGET的头文件,在native的代码这个文件是比较重要的。
    一般来说这个文件都包含一个“config/nm-TARGET.h”名称的头文件,因为这个TARGET的OS在GDB中已经支持,比如config/nm-linux.h(注意:TARGET和OS名称一样),则可以包含这个头文件来设置一些跟这个OS相关的选项。

    在GDBINT 11.6中介绍了头文件中可以设置的宏,下面将对其中一部分进行介绍:
    FETCH_INFERIOR_REGISTERS
    定义这个宏表明当前的TARGET将定义自己的fetch_inferior_registers函数和store_inferior_registers函数。具体这两个函数将在后面进行介绍。

    KERNEL_U_SIZE
    定义user结构的长度,一般是定义一个函数,然后函数中返回sizeof(struct user)。比较独特的是MIPS的Nm-linux.h,直接写了个504,也是其的sizeof(struct user)的长度,注释说这么写的好处是对交叉编译的支持更好,不过我觉得要是头文件都没配置好,再友好后面也要出错吧。

    KERNEL_U_ADDR
    定义user结构在Kernel中的地址。这个宏的作用是这样的,因为user结构中有些指针是指向这个结构中另一个参数,通过取得指针的值然后减去KERNEL_U_ADDR,就可以取得指针指向参数相对于user结构的偏移,也就可以方便的取得其中的值。
    很多系统不需要这个值,可以直接将其设置为0。

    U_REGS_OFFSET
    定义user结构中寄存器信息元素(一般命名为regs)在整个结构中的偏移,比如很多TARGET的user结构中的寄存器信息元素在最开头,这个宏就会定义为0。

    REGISTER_U_ADDR (addr, blockend, regno)
    这个宏的作用是根据从U_REGS_OFFSET得到的寄存器信息在user结构中的偏移blockend取得序号为regno的寄存器在user结构中的偏移并将其存入addr。
    这个宏实际只有一个作用,就是如果定义这个宏则在GDB/gdb/core-aout.c中生成一个函数register_addr,所以也可以不在头文件中定义REGISTER_U_ADDR而直接在TARGET相关的.c文件中编写一个register_addr,但是不要REGISTER_U_ADDR宏和register_addr同时编写。具体register_addr将在后面进行详细介绍。
    还要注意如果你的TARGET编译的.o文件中不包含core-aout.o也就是默认生成register_addr的库文件,则需要在你自己的项目库文件中包含register_addr,光在头文件中包含REGISTER_U_ADDR就不行了。同时因为register_addr函数的作用是在GDB自带的fetch_inferior_registers函数和store_inferior_registers函数中被调用,也就是没定义FETCH_INFERIOR_REGISTERS的时候,所以如果当前TARGET定义了FETCH_INFERIOR_REGISTERS,REGISTER_U_ADDR和register_addr都不需要被定义。

    CHILD_PREPARE_TO_STORE
    这个宏会在ptrace、procfs和gnuhurd调试接口的child_prepare_to_store函数使用,这个函数的作用是在对寄存器进行设置以前,有时候需要先进行一些操作,比如在某些TARGET下无法设置一个寄存器,只能设置全部寄存器,则需要将全部寄存器的值读出来,再进行设置,这个操作就将在child_prepare_to_store调用。
    当TARGET需要这种设置寄存器以前的操作的时候,可以将函数定义为这个宏。
    在GDB的现有代码中,只有GDB/gdb/config/nm-gnu.h中设置了这个宏。

    I386_USE_GENERIC_WATCHPOINTS
    顾名思义这个宏只有ARCH为I386的TARGET需要,定义这个宏表明使用GDB/gdb/i386-nat.c中的特定断点功能,我估计其中使用了i386的调试寄存器。

    ONE_PROCESS_WRITETEXT
    定义这个宏表明被调试进程的TEXT节只允许一个进程对其写,当设置断点的时候如果发生错误则会返回相应的错误信息。在现有的GDB代码中没有TARGET使用这个宏。

    SHELL_COMMAND_CONCAT
    当GDB运行被调试程序的时候,这个宏将被添加到程序名称的前面,一般来说这个宏不需要设置。

    SHELL_FILE
    这个宏用来指定GDB运行被调试程序的SHELL的目录名,一般不需要设置,使用GDB/gdb/fork-child.c中默认指定的"/bin/sh"就可以。

    SOLIB_ADD (filename, from_tty, targ, readsyms)
    增加动态链接库的符号信息到当前GDB的符号表中,一般情况可以使用GDB/gdb/solib.c中的代码,直接包含solib.h就可以,注意前面介绍过的config/nm-linux.h包含solib.h文件。这个GDB/gdb/solib.c中的代码是可以通过向struct target_so_ops *current_target_so_ops中增加结构来扩展支持很多类型的动态库,现在支持的有aix、sunos、svr4等,关于其扩展的方式将在以后的版本中进行介绍。

    SOLIB_CREATE_INFERIOR_HOOK
    这个宏将在运行被调试程序后调用,一般运行一些动态连接库重定位相关的代码。跟上面一个宏一样使用GDB/gdb/solib.c中的代码,直接包含solib.h就可以。

    CLEAR_SOLIB
    这个宏会在GDB清除所有符号的时候调用,用来清除动态链接库的信息。跟上面一个宏一样使用GDB/gdb/solib.c中的代码,直接包含solib.h就可以。

    START_INFERIOR_TRAPS_EXPECTED
    当启动被调试程序的时候,一般会有两次TRAP(指被调试程序被断点中断,进入KERNEL),第一次是SHELL的执行,第二次是被调试程序的执行。如果编写的TARGET是两次TRAP则不需要进行设置,如果不是可以用这个宏进行指定。
    根据现有GDB的代码,建议定义这个宏的时候对其先undef一下。举例:
    #undef START_INFERIOR_TRAPS_EXPECTED
    #define START_INFERIOR_TRAPS_EXPECTED 4

    DEBUG_PTRACE
    在GDB/gdb/infptrace.c文件137行开始也就是判断是否定义了DEBUG_PTRACE开始,使用前面定义的call_ptrace函数来替换ptrace进行调试,这样可以在call_ptrace设置断点方便调试GDB。

    PTRACE_TYPE_ARG5
    判断的位置跟DEBUG_PTRACE一样,但是目的不同。这个宏用来确定当前TARGET的ptrace是否有第5个参数,如果是则使用call_ptrace函数替换ptrace进行调试,而在call_ptrace对是否定义了PTRACE_TYPE_ARG5进行了检查,保证可以正常编译。
    这个宏应该是定义在configure的时候生成的GDB/gdb/config.h文件中的,不需要在文件中指定。

    PTRACE_ARG3_TYPE
    ptrace系统调用的第三个参数的类型。如果不设置则会按照GDB/gdb/inferior.h文件中的将其定义为PTRACE_TYPE_ARG3,而这个PTRACE_TYPE_ARG3定义在configure的时候生成的GDB/gdb/config.h文件中。

    PTRACE_XFER_TYPE
    这个宏用来标记传输ptrace数据的类型,主要是用来帮助计算数据的长度。
    注意这个宏并不是一个通用的宏,只是在部分TARGET的.c代码中进行了使用,所以如果你没使用可以不进行设置。

    USE_PROC_FS
    如果定义这个宏则前面介绍过的跟当前TARGET相关的.o文件中的进行寄存器信息转换(GDB内部表示方式和/proc表示方式)函数进行编译,否则不进行编译。

    HAVE_OPTIONAL_PROC_FS
    只有少数的TARGET使用这个宏,这个宏的作用是表明当前TARGET同时支持ptrace和procfs两种调试接口,在当前系统有/proc文件系统的时候优先使用procfs调试接口。在GDB/gdb/inftarg.c的初始化函数_initialize_inftarg中,就可以看到先会检查系统中的/proc文件系统是否正常,如果正常就不初始化ptrace调试接口。

    PROC_NAME_FMT
    这个宏就是在上面这个宏中介绍的检查代码中使用的,其用来标明当前/proc文件系统中下进程文件的名称。




    6.GDB/gdb/ARCH-NAT.c 和 GDB/gdb/ARCH-TARGET-NAT.c
    6.1.概述
    这两个文件是跟TARGET相关的.c文件,主要包含一些TARGET相关的函数。而这个两个函数的关系可以说第一个可以比较方便的应用于同一ARCH的多个TARGET,所以主要是一些ARCH相关的函数,当然实际使用的时候可以编写者自己灵活掌握。


    6.2.跟寄存器读取有关的函数
    CORE_ADDR register_addr (int regno, CORE_ADDR blockend)
    前面介绍宏REGISTER_U_ADDR的时候已经介绍过这个函数,这个函数跟宏REGISTER_U_ADDR的功能一样,根据从U_REGS_OFFSET得到的寄存器信息在user结构中的偏移blockend取得序号为regno的寄存器在user结构中的偏移并返回。
    其他关于这个函数信息可以看上面REGISTER_U_ADDR的介绍内容。

    void fetch_inferior_registers (int regno)
    这个函数只有在定义了FETCH_INFERIOR_REGISTERS宏后才能包含在TARGET自己的库函数里。这个函数的作用是将指定序号regno的寄存器的值通过调试接口比如ptrace从被调试程序中读出,然后调用GDB/gdb/regcache.c:regcache_raw_supply函数将这个寄存器的信息存储到GDB/gdb/regcache.c:current_regcache中。如果regno为-1则表示要将所有寄存器的信息存储到GDB/gdb/regcache.c:current_regcache中。

    void store_inferior_registers (int regno)
    这个函数只有在定义了FETCH_INFERIOR_REGISTERS宏后才能包含在TARGET自己的库函数里。这个函数的作用从GDB/gdb/regcache.c:current_regcache中通过GDB/gdb/regcache.c:regcache_raw_collect函数读出regno指定的寄存器信息,然后通过调试接口比如ptrace写如被调试程序中。如果regno为-1则表示要将所有GDB/gdb/regcache.c:current_regcache中的寄存器的信息存储到被调试程序中。


    6.3.gregset相关函数
    下面介绍的四个函数是用来将GDB内部使用的格式的寄存器信息和本地OS使用的gregset格式的寄存器信息(在Linux中被定义在Linux Kernel目录include/asm-ARCH/elf.h中)进行相互转化的函数。其中gdb_gregset_t存储普通寄存器和控制寄存器信息,gdb_fpregset_t存储浮点寄存器的信息。注意有这几个函数的时候别忘记包含头文件gregset.h。

    void fill_gregset (gdb_gregset_t *gregsetp, int regno)
    这个函数从GDB/gdb/regcache.c:current_regcache中通过GDB/gdb/regcache.c:regcache_raw_collect函数读出regno指定的寄存器信息,然后转化成gdb_gregset_t的格式,存入gregsetp中。如果regno为-1则表示要将所有GDB/gdb/regcache.c:current_regcache中的寄存器的信息转化存储到gregsetp中。

    void supply_gregset (gdb_gregset_t *gregsetp)
    将gregsetp中的信息先转化成GDB内部使用的寄存器格式,然后调用GDB/gdb/regcache.c:regcache_raw_supply函数这些信息存储到GDB/gdb/regcache.c:current_regcache的每个寄存器中。

    void fill_fpregset (gdb_fpregset_t *fpregsetp, int regno)
    这个函数从GDB/gdb/regcache.c:current_regcache中通过GDB/gdb/regcache.c:regcache_raw_collect函数读出regno指定的浮点寄存器信息,然后转化成gdb_fpregset_t的格式,存入fpregsetp中。如果regno为-1则表示要将所有GDB/gdb/regcache.c:current_regcache中的浮点寄存器的信息转化存储到fpregsetp中。

    void supply_fpregset (gdb_fpregset_t *fpregsetp)
    将fpregsetp中的信息先转化成GDB内部使用的浮点寄存器格式,然后调用GDB/gdb/regcache.c:regcache_raw_supply函数这些信息存储到GDB/gdb/regcache.c:current_regcache的每个浮点寄存器中。

    还有两个函数supply_fpxregset和fill_fpxregset是用来对i386扩展浮点寄存器(SSE)进行格式转化用的,因为只有i386使用,而且结构比较清晰,所以就不进行介绍了。




    7.本地core文件支持
    7.1.概述
    前面已经介绍过,core文件的支持是通过corelow.o也就是GDB/gdb/corelow.c文件来实现的,其中的调试接口在用户用GDB的-c选项或者使用target core命令的方式分析core文件的时候将会被调用,而在调用这些调试接口的时候,将先会进行一些处理,然后对core_file_fns列表中注册的每个core_fns结构的进行扫描,选择合适的core_fns结构,调用其中的函数。也有可能是调用“移植GDB(1)”中介绍过的用set_gdbarch_regset_from_core_section注册的函数。具体整个过程将在下面进行详细的介绍。


    7.2.struct core_fns
    这个结构定义在文件GDB/gdb/gdbcore.h中,因为core文件有不同的类型,所以需要可以根据情况进行扩展,而core_fns结构就是其扩展接口。
    下面来介绍一下core_fns结构中的每个元素:
    enum bfd_flavour core_flavour;
    这个变量表示注册的这组函数关联的core文件的类型,在GDB中常见的就是bfd_target_unknown_flavour和bfd_target_elf_flavour,分别代表未知和elf格式。对core_flavour和core文件类型进行比较的只有一个函数GDB/gdb/corelow.c:default_core_sniffer,具体使用在介绍core_sniffer的时候进行介绍。
    int (*check_format) (bfd *);
    并不是每个被指定来的当作core文件分析的文件都是BFD支持的core文件,比如一个特殊的core_fns结构,分析的core文件并不符合BFD结构中bfd_core格式,为了也能对其进行分析,则需要注册check_format函数。函数如果确定当前core文件的格式可以用当前的core_fns结构分析就非0,否则返回0。如果支持的core文件就是BFD支持的bfd_core格式,就注册函数GDB/gdb/corelow.c:default_check_format,这个函数不会进行任何判断而直接返回0。
    int (*core_sniffer) (struct core_fns *, bfd *);
    注册在这个函数指针的函数会根据当前core文件的BFD格式和当前的core_fns结构支持的BFD格式,如果相同就返回非0,不同就返回0。一般这个指针注册前面提到的函数GDB/gdb/corelow.c:default_core_sniffer,这个函数结构很简单,取出当前core文件的BFD格式和当前core_fns结构的core_flavour结构进行比较,相同就返回真。
    注意如果前面的check_format返回了真,则要保证在这里也返回真,否则将影响GDB的运行,后面7.3会作详细解释。
    void (*core_read_registers) (char *core_reg_sect, unsigned core_reg_size, int which, CORE_ADDR reg_addr);
    注册在这个指针上的函数用来从core文件内容中将寄存器信息读出然后进行转化用函数regcache_raw_supply存储到current_regcache中。其参数core_reg_sect是指向core文件中寄存器信息的指针;core_reg_size是这些信息的长度;which是信息的类型,0是普通寄存器,2是浮点寄存器,3是前面提过的扩展浮点寄存器;reg_addr,指从u.u_ar0到寄存器信息的偏移,用来确定老式的core文件的section中的寄存器信息的位置,具体看注释。
    一般来说这个函数的编写方式是先根据which确定core_reg_sect中信息的格式是普通类型gdb_gregset_t或者浮点类型gdb_fpregset_t,然后进行转化然后调用regcache_raw_supply将每个寄存器的信息写入current_regcache或者直接调用前面介绍过的supply_gregset进行这个工作。
    struct core_fns *next;
    指向下一个core_fns结构。将一个core_fns结构加入列表core_file_fns使用函数GDB/gdb/corelow.c:deprecated_add_core_fns,这个函数会将每个结构依次用next连起来。


    7.3.GDB分析core文件的过程
    第一步,当用户用GDB的-c选项或者使用target core命令的方式分析core文件的时候,会调用GDB/gdb/corelow.c:core_open函数。经过一些打开等的操作,就会调用GDB/bfd/format.c:bfd_check_format和GDB/gdb/corelow.c:gdb_check_format,这里的作用就是检查core文件的格式是否正确。前面的bfd_check_format函数是检查当前打开的core文件格式是否是bfd_core,而后面的函数gdb_check_format会循环调用core_file_fns列表中每个core_fns结构的check_format函数指针,只要有一个返回真就返回真,这两个函数如果都返回假则报错退出。这里调用的目的就是判断当前的core文件格式是否能被GDB处理。
    第二步,经过一部分的处理,然后调用函数GDB/gdb/corelow.c:sniff_core_bfd。这个函数会先用函数GDB/gdb/gdbarch.c:gdbarch_regset_from_core_section_p检查当前的core_gdbarch是否支持regset_from_core_section,如果是则直接返回,这么做因为支持regset_from_core_section就可以通过其取得寄存器信息,不需要使用core_fns结构中的core_read_registers(下面介绍到取得寄存器信息的部分中很清晰),所以不需要再执行后面的代码,关于regset_from_core_section的信息可以见“移植GDB(1)5.5”最后部分的介绍。
    后面开始的代码就是调用core_file_fns列表中每个core_fns结构的core_sniffer函数指针,如果返回真就记录下这个core_fns结构,最后进行检查,如果没有记录到任何core_fns结构,就以core_file_fns列表中第一个core_fns结构设置进去。
    最后sniff_core_bfd返回,返回值存储在本地全局变量core_vec中,后面需要使用core_fns结构的时候,都将直接使用core_vec。这里也说明了core_sniffer函数指针和设置core_vec的密切关系,所以在前面介绍core_sniffer函数指针的时候说前面的check_format返回了真,则要保证在这里也返回真。
    第三步,最后经过一系列的处理,调用GDB/gdb/target.h:target_fetch_registers宏,取得全部寄存器的信息,这个宏会调用current_target.to_fetch_registers,最终会调用GDB/gdb/corelow.c:get_core_registers。
    在get_core_registers函数中,会先检查core_gdbarch中的regset_from_core_section是否设置以及core_vec中的core_read_registers是否可用,如果他们都不可用则会报错返回。这里再次说明了这2个指针的存在作用,都是用来从core文件中取得寄存器信息,并且只设置其中一个就可以。
    然后是三次调用GDB/gdb/corelow.c:get_core_register_section,这三次调用分别是对普通寄存器,浮点寄存器和扩展浮点寄存器的读取。在get_core_register_section函数中,先根据参数name也就是存储了寄存器信息的section的名称取得了section的长度size和内容contents。然后检查core_gdbarch中的regset_from_core_section是否设置,如果设置了则调用gdbarch_regset_from_core_section根据name和size取得一个regset结构,然后调用regset结构中的函数supply_regset设置寄存器的信息,在“移植GDB(1)5.5”中已经介绍过这些函数等,所以这里不作详细介绍。最后调用core_vec->core_read_registers读取寄存器信息。函数get_core_register_section返回。
    get_core_registers最后调用GDB/gdb/regcache.c:deprecated_registers_fetched函数,标记全部寄存器已经都被从被调试程序取出值了。


    7.4.让TARGET支持core文件分析的方法
    通过前面的介绍,可以知道如果想在TARGET中支持core文件的分析,可以使用两种方式:第一种是给gdbarch用set_gdbarch_regset_from_core_section设置regset_from_core_section;第二种是用deprecated_add_core_fns向列表core_file_fns设置core_fns结构。
    第一种方式需要在gdbarch的代码中进行设置,其不能方便的支持多种core文件结构,而且如果core文件不是标准的BFD的结构bfd_core也不能用这种方式支持。
    第二种方式可以在TARGET的GDB/gdb/ARCH-TARGET-NAT.c文件中的_initialize_名称类型的初始化函数(这个函数的初始化原理将在“移植GDB(3)”中进行介绍)中用deprecated_add_core_fns向列表core_file_fns设置自己定义的core_fns结构;也可以在GDB/gdb/config/ARCH/TARGET.mh中定义前面介绍过的core-aout.o文件和core-regset.o文件,这两个文件关联的格式分别是bfd_target_unknown_flavour和bfd_target_elf_flavour。实际的使用中这两种设置core_fns结构的方式可以根据需要混合使用。




    8.动态连接库支持
    主要的支持方式可以见前面SOLIB_ADD、SOLIB_CREATE_INFERIOR_HOOK、CLEAR_SOLIB几个宏的介绍。

    コメント (1 件)

    しばらくお待ちください。
    入力されたコメントは長すぎます。短くしてください。
    何も入力されていません。もう一度やり直してください。
    現在、コメントを追加できません。後でもう一度やり直してください。
    コメントと書くには、保護者 (ほごしゃ) の方の許可 (きょか) をもらってください。許可をリクエストする
    保護者 (ほごしゃ) の方が、あなたがコメントを書けないようにしています。
    現在、コメントを削除できません。後でもう一度やり直してください。
    1 日に投稿できるコメントの最大数を超えました。24 時間経過してから、もう一度やり直してください。
    あなたが他のユーザーに対して迷惑行為を行っている可能性があると確認されたため、お使いのアカウントによるコメントの投稿を無効にしています。誤って無効にされたと思われる場合は、Windows Live のサポートにお問い合わせください。
    コメントを投稿する前に、以下のセキュリティ チェックを完了してください。
    セキュリティ チェックに入力する文字は、画像に表示されている文字または音声で流れた文字と一致していなければいけません。

    コメントを投稿するには、お使いの Windows Live ID でサインインしてください (Hotmail、Messenger、または Xbox LIVE を既に使用している場合は、そのアカウントが Windows Live ID です)。サインイン


    Windows Live ID をお持ちでない場合は、アカウントを新規登録してください。

    名前なしさんの投稿:

    Amberdigital Branch,Southern Stars Enterprises Co is specializing in the development and manufacturing of advertising displays, advertising player and LCD displays. Established in 1996, we have explored and developed the international market with professionalism. We have built a widespread marketing network, and set up a capable management team dedicated to provide beyond-expectation services to our customers.

    amberdigital Contact Us
    Southern Stars Enterprises Co (Hong Kong Office)
    Add:3 Fl, No.2, Lane 2, Kam Tsin Tsuen, Sheung Shui, Hong Kong
    Tel:+852 2681 4099
    Fax:+852 2681 4586

    Southern Stars Enterprises Co (Shenzhen Office)
    Add:DE, 16/F, Building 2, Nanguo Tower, Sungang Road, Shenzhen, China
    Tel:+86 755 2592 9100
    Fax:+86 755 2592 7171

    E-mail:sstar@netvigator.com
    website:www.amberdigital.com.hk
    alibaba:amberdigital.en.alibaba.com[fc

    8 月 25 日

    トラックバック

    この記事のトラックバックの URL は次のとおりです。
    http://teawater.spaces.live.com/blog/cns!48DDFFCE89F7F319!1356.trak
    この記事を参照しているブログ
    • なし