bfd对多目标的支持

 

快乐虾

http://blog.csdn.net/lights_joy/

lights@hb165.com

   

 

本文适用于

bfinutils-2.18

   

欢迎转载,但请保留作者信息

 

 

bfd库是一个用于处理二进制文件的库,它可以读写ELF, COFF之类格式的文件,但不涉及CPU的反汇编操作(这个将由opcodes完成)。在binutilsgdb等程序中都使用了它。那么它是如何做到支持如此多的目标呢?

Bfd的主要信息由一个叫bfd的结构体进行描述:

/* Extracted from bfd.c.  */

struct bfd

{

………………………………..

  /* A pointer to the target jump table.  */

  const struct bfd_target *xvec;

………………………………..

  /* Pointer to structure which contains architecture information.  */

  const struct bfd_arch_info *arch_info;

………………………………..

  /* Used by the back end to hold private data.  */

  union

    {

      struct aout_data_struct *aout_data;

      struct artdata *aout_ar_data;

      struct _oasys_data *oasys_obj_data;

      struct _oasys_ar_data *oasys_ar_data;

      struct coff_tdata *coff_obj_data;

      struct pe_tdata *pe_obj_data;

      struct xcoff_tdata *xcoff_obj_data;

      struct ecoff_tdata *ecoff_obj_data;

      struct ieee_data_struct *ieee_data;

      struct ieee_ar_data_struct *ieee_ar_data;

      struct srec_data_struct *srec_data;

      struct ihex_data_struct *ihex_data;

      struct tekhex_data_struct *tekhex_data;

      struct elf_obj_tdata *elf_obj_data;

      struct nlm_obj_tdata *nlm_obj_data;

      struct bout_data_struct *bout_data;

      struct mmo_data_struct *mmo_data;

      struct sun_core_struct *sun_core_data;

      struct sco5_core_struct *sco5_core_data;

      struct trad_core_struct *trad_core_data;

      struct som_data_struct *som_data;

      struct hpux_core_struct *hpux_core_data;

      struct hppabsd_core_struct *hppabsd_core_data;

      struct sgi_core_struct *sgi_core_data;

      struct lynx_core_struct *lynx_core_data;

      struct osf_core_struct *osf_core_data;

      struct cisco_core_struct *cisco_core_data;

      struct versados_data_struct *versados_data;

      struct netbsd_core_struct *netbsd_core_data;

      struct mach_o_data_struct *mach_o_data;

      struct mach_o_fat_data_struct *mach_o_fat_data;

      struct bfd_pef_data_struct *pef_data;

      struct bfd_pef_xlib_data_struct *pef_xlib_data;

      struct bfd_sym_data_struct *sym_data;

      void *any;

    }

  tdata;

……………………………..

};

从这三个成员大致就可以猜出bfd支持多目标所使用的方法了。它用了一个叫xvec的成员来保存具体目标的信息,包括其操作函数和相关的一些参数。而arch_info这个成员则定义了一种目标体系结构的硬件参数,如位数,是否big-endian等等,这个值定义好了之后就不再改变,这也是将它定义为const的原因。最后读写的数据将由tdata这个union来表示,对于不同的目标需要进行不同的解释。

在这里,bfd_target无疑扮演了一个苦力的角色,它将完成具体文件格式的分析。这个结构体的定义为:

typedef struct bfd_target

{

  /* Identifies the kind of target, e.g., SunOS4, Ultrix, etc.  */

  char *name;

 

 /* The "flavour" of a back end is a general indication about

    the contents of a file.  */

  enum bfd_flavour flavour;

……………………………….

 

  /* Entries for byte swapping for data. These are different from the

     other entry points, since they don't take a BFD as the first argument.

     Certain other handlers could do the same.  */

  bfd_uint64_t   (*bfd_getx64) (const void *);

  bfd_int64_t    (*bfd_getx_signed_64) (const void *);

  void           (*bfd_putx64) (bfd_uint64_t, void *);

  bfd_vma        (*bfd_getx32) (const void *);

  bfd_signed_vma (*bfd_getx_signed_32) (const void *);

  void           (*bfd_putx32) (bfd_vma, void *);

  bfd_vma        (*bfd_getx16) (const void *);

  bfd_signed_vma (*bfd_getx_signed_16) (const void *);

  void           (*bfd_putx16) (bfd_vma, void *);

………………………………………

 

} bfd_target;

这个结构的信息分为两类,一类是基本信息描述,如名称等,另一类是在处理这个目标时的回调函数,这些函数将由bfd相关的主控函数进行调用。对于不同的目标都必须定义一个具体的结构体。如bfin-elf格式,它的target就定义为:

const bfd_target bfd_elf32_bfin_vec =

{

  /* name: identify kind of target */

  TARGET_LITTLE_NAME,

……………………………….

  /* Routines to byte-swap various sized integers from the data sections */

  bfd_getl64, bfd_getl_signed_64, bfd_putl64,

    bfd_getl32, bfd_getl_signed_32, bfd_putl32,

    bfd_getl16, bfd_getl_signed_16, bfd_putl16,

………………………………

};

targets.c这个文件中,列出了bfd支持的所有目标,它将这些变量都放在一个称为_bfd_target_vector的数组中:

static const bfd_target * const _bfd_target_vector[] =

{

#ifdef SELECT_VECS

 

     SELECT_VECS,

 

#else /* not SELECT_VECS */

……………………………

     &arm_epoc_pe_big_vec,

     &arm_epoc_pe_little_vec,

     &arm_epoc_pei_big_vec,

………………………….

     &bfd_elf32_avr_vec,

     &bfd_elf32_bfin_vec,

     &bfd_elf32_bfinfdpic_vec,

………………………….

#endif /* not SELECT_VECS */

 

/* Always support S-records, for convenience.  */

     &srec_vec,

     &symbolsrec_vec,

/* And tekhex */

     &tekhex_vec,

/* Likewise for binary output.  */

     &binary_vec,

/* Likewise for ihex.  */

     &ihex_vec,

………………………………..

 

     NULL /* end of list marker */

};

通过SELECT_VECS这个宏的定义,可以控制让bfd只支持自己需要的目标。

在对一个文件进行读写之前,可以通过bfd_set_default_target函数来设置自己需要的目标。

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌云阁主

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值