Chinaunix首页 | 论坛 | 博客
  • 博客访问: 101602
  • 博文数量: 33
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 45
  • 用 户 组: 普通用户
  • 注册时间: 2016-11-04 11:29
个人简介

所学,所得,所知

文章分类

全部博文(33)

文章存档

2017年(28)

2016年(5)

我的朋友

分类: LINUX

2016-11-04 11:34:03

Normal 0 7.8 磅 0 2 false false false EN-US ZH-CN X-NONE /* Style Definitions */ table.MsoNormalTable {mso-style-name:普通表格; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-priority:99; mso-style-qformat:yes; mso-style-parent:""; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.5pt; mso-bidi-font-size:11.0pt; font-family:"Calibri","sans-serif"; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-font-kerning:1.0pt;}

移植GDB(3) init.ctarget_ops v0.0
teawater
转载请标明来自




修改记录:
v0.0
2006-02-27
v0.0版本编写完成。没有对target_ops结构的每个元素进行详细介绍。
2006-02-07
,文档创建。




目录
1.
写在前面
2.GDB/gdb/init.c
2.struct target_ops
3.struct target_ops current_target
3.1.
概述
3.2.
本地调试接口的装载




1.
写在前面
本文针对GDB-6.3进行编写。
下面是本文将使用的缩写:
GDBINT GDB Internals Manual
的缩写。
GDB
GDB源文件目录。
ARCH
体系结构名称。
TARGET
体系结构下的调试目标,一般是一种操作系统,比如Linux




2.GDB/gdb/init.c
这个文件是在编译的时候动态生成的,具体生成的位置在/GDB/gdb/Makefile.in1075行开始的代码,这个文件会在configure的时候作为模板生成/GDB/gdb/Makefile,那段生成init.c的代码就会在make的时候被调用。
这段生成init.c的代码主要的过程就是扫描所有编译中指定的库文件,比如指定在移植GDB(1)”TARGET.mt文件和移植GDB(2)”TARGET.mh文件的库文件,然后找出其中_initialize_NAME(后面的NAME可以是任意名称)为名称的函数,在init.c文件中生成一个函数initialize_all_files,对每个_initialize_NAME进行调用。
这个initialize_all_files函数将被GDB初始化函数GDB/gdb/top.c:gdb_init调用,也就是每次GDB初始化的时候都会对其进行调用。
所以库文件就可以通过包含一个_initialize_NAME名字的文件来进行一些初始化的操作,比如在移植GDB(1)5.2”就介绍了在_initialize_ARCH_tdep函数中调用gdbarch_register函数注册gdbarch,下面将介绍的target_ops大部分也都是通过_initialize_NAME函数进行初始化和注册的。




2.struct target_ops
struct target_ops
定义在GDB/gdb/target.h文件中,GDB中所有被调试的目标的控制和访问函数都被封装成这个结构,然后根据需要将结构装载到current_target(后面会详细介绍),当GDB调试的时候直接对current_target结构中的函数指针进行调用就可以。比如GDB的模拟功能sim、远程调试功能remote以及本地调试接口ptraceprocfs等都以target_ops结构封装的。
大部分的target_ops结构都是先在前面介绍过的_initialize_NAME函数中进行初始化,然后调用函数GDB/gdb/target.c:add_target注册到列表GDB/gdb/target.c:target_structs上。




3.struct target_ops current_target
3.1.
概述
这个结构就是GDB用来控制当前被调试目标的结构,当系统初始化(设置为dummy_target)、读入可执行文件(设置为exec_ops)或者执行target命令以后,就会调用GDB/gdb/target.c:push_target函数将需要的target_ops结构初始化到current_target上。当调用一些GDB命令的时候,则会调用current_target中的函数指针,也就对被调试目标进行了调试。


3.2.
本地调试接口的装载
因为这个.本地调试接口的装载过程不是很直接,所以在这里对其进行一些介绍。

第一步,在GDB读入可执行文件的时候,会自动将GDB/gdb/exec.c:exec_ops装载到current_target上。

第一步,当运行运行run的时候会调用GDB/gdb/infcmd.c:run_command函数,在这个函数进行了一系列的分析处理后,最后会调用GDB/gdb/target.h:target_create_inferior宏,这个宏调用current_target.to_create_inferior,这里将调用注册在exec_ops上的函数GDB/gdb/target.c:find_default_create_inferior

第二步,find_default_create_inferior函数首先调用函数GDB/gdb/target.c:find_default_run_target,在这个函数将通过前面介绍过的target_structs列表,扫描每个用add_target注册的target_ops结构。先检查这个target_ops结构有没有注册to_can_run函数指针,如果有对这个函数指针进行调用,一般来说本地调试结接口的target_ops结构都会注册这个函数指针,而且函数都会返回1,而非本地调试接口的target_ops结构则不会,所以都返回真的时候就记录这个target_ops结构在指针runable上,同时给count1
最后在扫描结束的时候检查count是否为1,不为1则报错,所以建议一个TARGET中只包含一个本地调试接口,最后返回runable

第三步,然后调用这个返回的target_ops结构的to_create_inferior,这里会将这个调试接口的target_ops结构初始化到current_target上。比如在GDB/gdb/inftarg.c:child_create_inferior就调用了GDB/gdb/inftarg.c:ptrace_himptrace_him第一步工作就是调用push_targetdeprecated_child_ops装载到current_target上。

阅读(2208) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~