一. 安装bfd库
libbfd(Binary File Descriptor library是binutils中附带的一个C库。
从 http://ftp.gnu.org/gnu/binutils 下载binutils。
我们这里下载binutils-2.23.2.tar.gz
下载后,解压安装libbfd。方法如下:
tar -xzf binutils-2.23.2.tar.gz
cd binutils-2.23.2/bfd
./configure
make
make install
安装完成后,可以看到有如下文件生成。
/usr/local/include/bfd.h
/usr/local/lib/libbfd.a
二. 使用bfd库需要注意的地方
1. 头文件包含
程序使用bfd,需要包含bfd.h头文件。
但是,在包含bfd.h之前,还需要包含config.h。
即代码中需要有如下形式的文件包含:
- #include "config.h"
- #include <bfd.h>
那么这个config.h是什么东东呢?他不是系统的头文件,也不是bfd库的头文件,而是应用程序自己的头文件。
然而用户可能会感到奇怪,我的应用程序源码中并不存在这个config.h文件。那是因为你开发应用时,没有采用GNU autotools。
采用GNU autotools的项目,在编译前一般都会执行一下configure脚本,生成Makefile及config.h文件。
那么,对于没有使用GNU autotools的应用,怎么解决呢?本文这里提供一个简单的config.h文件。
这个文件的内容,相当于是使用GNU autotools开发一个hello world项目而得到的config.h。
- /* config.h. Generated from config.h.in by configure. */
- /* config.h.in. Generated from configure.ac by autoheader. */
-
- /* Name of package */
- #define PACKAGE "hello"
-
- /* Define to the address where bug reports for this package should be sent. */
- #define PACKAGE_BUGREPORT "bug-report@address"
-
- /* Define to the full name of this package. */
- #define PACKAGE_NAME "hello"
-
- /* Define to the full name and version of this package. */
- #define PACKAGE_STRING "hello 1.0"
-
- /* Define to the one symbol short name of this package. */
- #define PACKAGE_TARNAME "hello"
-
- /* Define to the home page for this package. */
- #define PACKAGE_URL ""
-
- /* Define to the version of this package. */
- #define PACKAGE_VERSION "1.0"
-
- /* Version number of package */
- #define VERSION "1.0"
2. 链接
需要带上这几个库:bfd iberty dl z
例如,假设hello.c是一个完整的使用bfd库的程序,则他的编译方法如下。
gcc hello.c -lbfd -liberty -ldl -lz
三. 应用实例
- #include <stdio.h>
- #include <stdint.h>
- #include "config.h"
- #include <bfd.h>
- #include <strings.h>
- #include <linux/elf.h>
-
- /*
- 这里定义3个static变量,并把他们放到一个单独的section中。
- 后面,我们通过bfd找出这个section,并得到这3个变量的内容。
- 同时,我们还通过符号查找操作,找到a_haha这个static变量的信息。
- */
- static uint64_t a_haha __attribute__((section ("my_test_sec"))) =3;
- static uint64_t b __attribute__((section ("my_test_sec"))) =7;
- static uint64_t c __attribute__((section ("my_test_sec"))) =8;
-
- /* 获取当前进程自己的elf文件路径 */
- int get_self_path(char *buf, int buf_len)
- {
- int ret = readlink("/proc/self/exe", buf, buf_len);
- buf[ret]='\0';
- return ret;
- }
-
- void section_proc(bfd *abfd, asection *sect, PTR obj)
- {
- if (strcmp(sect->name, "my_test_sec")==0)
- printf("section %s exists\n", sect->name);
- }
-
-
-
- void search_a_given_symbol(bfd *ibfd, const char *name)
- {
- long storage_needed;
- asymbol **symbol_table;
- long number_of_symbols;
- long i;
- symbol_info symbolinfo ;
-
- storage_needed = bfd_get_symtab_upper_bound(ibfd);
-
-
- symbol_table = (void *)(unsigned long)xmalloc(storage_needed);
- number_of_symbols = bfd_canonicalize_symtab (ibfd, symbol_table);
-
-
- printf("Scanning %i symbols\n", number_of_symbols);
- for(i=0;i<number_of_symbols;i++)
- {
- if (symbol_table[i]->section==NULL) continue;
-
- bfd_symbol_info(symbol_table[i],&symbolinfo);
- if (strcmp(name, symbolinfo.name)) continue;
-
- printf("Section %s ",symbol_table[i]->section->name);
- printf("Symbol \"%s\" value 0x%x\n",
- symbolinfo.name, symbolinfo.value);
- }
-
-
- }
-
- int main()
- {
- char our_self_path[1024];
- bfd *ibfd;
- char **matching;
-
- asection *psection;
-
- bfd_init();
-
- get_self_path(our_self_path, sizeof(our_self_path));
- printf("our elf file path:%s\n", our_self_path);
-
- ibfd = bfd_openr(our_self_path, NULL);
- bfd_check_format_matches(ibfd, bfd_object, &matching);
-
- printf("number of sections = %d\n", bfd_count_sections(ibfd));
-
- /* 遍历所有section,让section_proc对每一个section进行处理 */
- bfd_map_over_sections(ibfd, section_proc, NULL);
-
- /* 查找特定名称的section,打印出其信息 */
- psection = bfd_get_section_by_name(ibfd, "my_test_sec");
- printf("section name=%s; start_address=0x%llx; size=%d\n"
- , psection->name
- , psection->vma
- , psection->size);
-
- /* 打印出my_test_sec section中的3个uint64_t变量的值 */
- {
- uint64_t *pu64 = (void *) psection->vma;
- printf("%lu %lu %lu \n", pu64[0], pu64[1], pu64[2]);
- }
-
- printf("address of a_haha=%p\n", &a_haha);
-
- /* 遍历所有符号,以找出名称为a_haha的符号 */
- search_a_given_symbol(ibfd, "a_haha");
- return 0;
- }
最后,程序运行效果如下:
- [root@smb test]# gcc hello.c -lbfd -liberty -ldl -lz
- [root@smb test]# ./a.out
- our elf file path:/home/shared/sunmingbao/test/a.out
- number of sections = 34
- section my_test_sec exists
- section name=my_test_sec; start_address=0x6c9a28; size=24
- 3 7 8
- address of a_haha=0x6c9a28
- Scanning 1905 symbols
- Section my_test_sec Symbol "a_haha" value 0x6c9a28
- [root@smb test]#
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请
点击举报。