前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MSVC/GCC/NDK:将二进制文件生成obj文件

MSVC/GCC/NDK:将二进制文件生成obj文件

作者头像
10km
发布2021-01-26 16:18:40
2K0
发布2021-01-26 16:18:40
举报
文章被收录于专栏:10km的专栏

如何将二进制文件作为数据添加到自己程序中?这是我最近遇到的问题,google上找到这两篇说得已经很清楚:

《Embedding of binary data into programs》 《Embedding Blobs in Binaries》

一种方法是将想二进制文件生成c代码,与项目一起编译,这方法对于小数据没问题,但如果二进制文件太大,生成的c代码更是巨大,增加编译器负担,好处就是完全没有跨平台问题。网上可以找到相关的工具(搜索 bin2cbin2h),比如这个embed-resource

第二种方式就是用GNU的objcopy工具来实现。 objcopy本身就提供了二进制数据转成obj文件的能力 执行如下指令即可将 file.bin 生成 elf32-i386 格式的obj文件 file.o

代码语言:javascript
复制
objcopy -I binary -O elf32-i386 -B i386 file.bin file.o

另外GNU的ld也可以实现,

代码语言:javascript
复制
ld -r -b binary -o file.o file.bin

objcopy不同,ld不需要指定输出格式,默认即为当前平台的obj格式,比如Windows平台下的MinGW ld则默认为pe-x86-64,NDK 的ld默认为elf32-littlearm 可以通过执行 ld --print-output-format 显示ld默认的输出格式

NDK

在NDK(NDK 19c)下需要找到正确的ld或objcopy才行, 之前我使用 $android-ndk-r19c/toolchains/llvm/prebuilt\windows-x86_64/bin/x86_64-linux-android-objcopy$android-ndk-r19c/toolchains/llvm/prebuilt\windows-x86_64/bin/llvm-objcopy都不能生成结果。 使用$android-ndk-r19c/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64/arm-linux-androideabi/bin/objcopy$android-ndk-r19c/toolchains/llvm/prebuilt/windows-x86_64/arm-linux-androideabi/bin/objcopy执行正常

如下执行NDK 的objcopy生成 elf32-littlearm格式的obj

代码语言:javascript
复制
:: 将ndk objcopy位置添加到搜索路径
$ SET PATH=${android-ndk-r19c}/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64/arm-linux-androideabi/bin;%PATH%

$ objcopy -I binary -O elf32-littlearm -B arm fall.jpg fall_elf32_littlearm.o

或如下使用ld来生成obj文件

代码语言:javascript
复制
ld -r -b binary -o fall_elf32_littlearm.o fall.jpg 

执行objdump查看

代码语言:javascript
复制
$ objdump -t -f fall_elf32_littlearm.o

fall_elf32_littlearm.o:     file format elf32-littlearm
architecture: arm, flags 0x00000010:
HAS_SYMS
start address 0x00000000

SYMBOL TABLE:
00000000 l    d  .data  00000000 .data
00000000 g       .data  00000000 _binary_fall_jpg_start
000085b9 g       .data  00000000 _binary_fall_jpg_end
000085b9 g       *ABS*  00000000 _binary_fall_jpg_size

MSVC

msvc并没有提供类型GNU objcopy的命令行工具可以直接将二进制文件转为obj文件.怎么办?有两个解决方案:

  • 如这篇文章中所说《Embedding of binary data into programs》,在网上搜索 bin2coffbin2obj可以找到第三方的工具.比如这个github上的bin2coff(我没测试)。
  • 如果你已经安装了MinGW编译器,使用MinGW提供的objcopyld就可以生成MS COFF格式的obj文件了

如下生成MSVC所需的PE格式obj文件

代码语言:javascript
复制
objcopy -I binary -O pe-x86-64 -B i386 fall.jpg fall_pe-x86-64.obj

或如下使用ld来生成obj文件

代码语言:javascript
复制
ld -r -b binary -o fall_pe-x86-64.obj fall.jpg 

执行objdump查看生成的fall_pe-x86-64.obj

代码语言:javascript
复制
>objdump -t fall_pe-x86-64.obj

fall_pe-x86-64.obj:     file format pe-x86-64

SYMBOL TABLE:
[  0](sec  1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000000000 _binary_fall_jpg_start
[  1](sec  1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000000085b9 _binary_fall_jpg_end
[  2](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000000085b9 _binary_fall_jpg_size

也可执行MSVC的dumpbin查看生成的obj文件,可以确认生成的是MSVC格式obj

代码语言:javascript
复制
>dumpbin /symbols /headers fall_pe-x86-64.obj
Microsoft (R) COFF/PE Dumper Version 14.00.24215.1
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file fall_pe-x86-64.obj

File Type: COFF OBJECT

FILE HEADER VALUES
            8664 machine (x64)
               1 number of sections
               0 time date stamp
            85F8 file pointer to symbol table
               3 number of symbols
               0 size of optional header
               5 characteristics
                   Relocations stripped
                   Line numbers stripped

SECTION HEADER #1
   .data name
       0 physical address
       0 virtual address
    85B9 size of raw data
      3C file pointer to raw data (0000003C to 000085F4)
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
C0100040 flags
         Initialized Data
         1 byte align
         Read Write

COFF SYMBOL TABLE
000 00000000 SECT1  notype       External     | _binary_fall_jpg_start
001 000085B9 SECT1  notype       External     | _binary_fall_jpg_end
002 000085B9 ABS    notype       External     | _binary_fall_jpg_size

String Table Size = 0x46 bytes

  Summary

        85B9 .data

CMAKE

习惯于使用cmake进行项目集成编译的人会想如何将生成obj的过程集成到cmake脚本中自动化执行。关于这个问题可以参考这篇文章 《Embedding binary resources with CMake and C++11》 我就是参考它来实现的

参考资料 《Embedding of binary data into programs》 《Embedding Blobs in Binaries》 《objcopy》 《llvm-objcopy - object copying and editing tool》

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/01/19 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • NDK
  • MSVC
  • CMAKE
相关产品与服务
命令行工具
腾讯云命令行工具 TCCLI 是管理腾讯云资源的统一工具。使用腾讯云命令行工具,您可以快速调用腾讯云 API 来管理您的腾讯云资源。此外,您还可以基于腾讯云的命令行工具来做自动化和脚本处理,以更多样的方式进行组合和重用。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档