从 archive/lib(我猜是 ELF?)中提取只读数据部分进行压缩
Extract read-only data sections from an archive/lib (ELF i guess?) for compression
更新:
所以问题如下:我的构建设置生成一个 archive/lib(二进制输出),我想从中提取一些数据,在我的例子中用于压缩,但这真的不是重点。
我的直觉告诉我,既然 linker 可以从 archive/lib 中提取常量数据,我应该 possible/easy "dump" 二进制 "contents" 包含在 archive/lib 中的符号,例如一个文件....
这就是我的问题:How to dump an symbol in an archive/lib (in ELF format)?
更新:
我正在构建基于 lvgl 的应用程序。
为了允许文本,我使用 lvgl 维护者提供的在线工具将 TrueType 字体转换为 C 代码(const 数据),该代码 linked 到应用程序中以呈现文本。
但是字体的结果数据集对于我可用的闪存来说太大了,但我有一大块未使用的 RAM。所以,我想使用 heatshrink 来压缩数据,并在 运行 时解压缩到 RAM。
这需要我的构建设置可以提取二进制数据,压缩它,然后 link 闪存,以便我的 运行-time 代码可以解压缩它。
我猜想,我可以将所有生成的字体数据填充到一个 "lib" 中,提取二进制数据,压缩它,并将 link 作为 "blob" 放入应用程序.
但是我无法从库中提取要压缩的数据
例如我的字体数据声明如下所示:
/*Store the image of the letters (glyph)*/
static const uint8_t _glyph_bitmap[] =
{ /* const Byte values follow (e.g. 0x00) */ };
static const lv_font_glyph_dsc_t _glyph_dsc[] =
{ /* struct initialization follows */ }
lv_font_t myfont
{ /* struct initialization follows */ }
所以我需要访问 myfont,以及它以二进制形式引用的声明。
我有一个工具,它创建表示一些二进制数据的 c 代码,以允许将数据编译并 linked 成最终的可执行文件(ARM 平台、GNU 工具链、定制硬件)。
我 运行 快用完闪存了,但还有备用 RAM。所以我正在考虑压缩库中的一些大型常量数据部分,并根据需要将它们解压缩到 RAM 中。
所以我可以编译 c 代码,并将其填充到存档中。但到目前为止,我一直没有运气尝试使用例如提取常量数据的二进制数据进行压缩。 objdump 或 objcopy。但是有件事告诉我,这是可能的(甚至可能很容易)。但是怎么办?我已经尝试 "google" 这个问题,但一无所获。
为什么不从编译后的二进制文件中提取数据,而是从生成的 C 代码中提取数据,对其进行压缩,然后使用压缩后的数据生成等效的 C 代码?
这种方法可能会简化实施、调试和测试的许多方面。
尤里卡!我想通了!
虽然我完全承认并感谢评论/其他答案中给出的建议,但我仍然感到困扰,我推测 "play the linker" 和从 [=101] 中提取硬编码数据块应该相对容易=].
好吧,事实证明使用 readelf
就像预期的那样相对容易(无论如何对于 elf 格式对象)
要转储符号,我使用了两个步骤:
通过查看对象中的符号找出符号索引:
$ readelf --syms company_logo.o
</code></p>
<p><code>Symbol table '.symtab' contains 17 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000 0 FILE LOCAL DEFAULT ABS company_logo.c
2: 00000000 0 SECTION LOCAL DEFAULT 1
3: 00000000 0 SECTION LOCAL DEFAULT 2
4: 00000000 0 SECTION LOCAL DEFAULT 3
5: 00000000 0 SECTION LOCAL DEFAULT 4
6: 00000000 0 NOTYPE LOCAL DEFAULT 4 $d
7: 00000000 0 SECTION LOCAL DEFAULT 6
8: 00000000 0 SECTION LOCAL DEFAULT 7
9: 00000000 0 SECTION LOCAL DEFAULT 9
10: 00000000 0 SECTION LOCAL DEFAULT 10
11: 00000000 0 SECTION LOCAL DEFAULT 12
12: 00000000 0 SECTION LOCAL DEFAULT 13
13: 00000000 0 SECTION LOCAL DEFAULT 14
14: 00000000 0 SECTION LOCAL DEFAULT 15
15: 00000000 12 OBJECT GLOBAL DEFAULT 4 company_logo
16: 00000000 21879 OBJECT GLOBAL DEFAULT 6 company_logo_map
转储符号的内容。
现在company_logo_map
是我的目标,所以使用它的索引6
,如下:
`readelf --hex-dump=6 company_logo.o`
` `
`Hex dump of section '.rodata.company_logo_map':`
` 0x00000000 00000000 00000000 00000000 00000000 ................`
` 0x00000010 00000000 00000000 00000000 00000000 ................`
` 0x00000020 00000000 00000000 00000000 00000000 ................`
` 0x00000030 00000000 00000000 00000000 00000000 ................`
` ... lots more data here`
更新: 所以问题如下:我的构建设置生成一个 archive/lib(二进制输出),我想从中提取一些数据,在我的例子中用于压缩,但这真的不是重点。
我的直觉告诉我,既然 linker 可以从 archive/lib 中提取常量数据,我应该 possible/easy "dump" 二进制 "contents" 包含在 archive/lib 中的符号,例如一个文件....
这就是我的问题:How to dump an symbol in an archive/lib (in ELF format)?
更新: 我正在构建基于 lvgl 的应用程序。 为了允许文本,我使用 lvgl 维护者提供的在线工具将 TrueType 字体转换为 C 代码(const 数据),该代码 linked 到应用程序中以呈现文本。 但是字体的结果数据集对于我可用的闪存来说太大了,但我有一大块未使用的 RAM。所以,我想使用 heatshrink 来压缩数据,并在 运行 时解压缩到 RAM。
这需要我的构建设置可以提取二进制数据,压缩它,然后 link 闪存,以便我的 运行-time 代码可以解压缩它。
我猜想,我可以将所有生成的字体数据填充到一个 "lib" 中,提取二进制数据,压缩它,并将 link 作为 "blob" 放入应用程序.
但是我无法从库中提取要压缩的数据
例如我的字体数据声明如下所示:
/*Store the image of the letters (glyph)*/
static const uint8_t _glyph_bitmap[] =
{ /* const Byte values follow (e.g. 0x00) */ };
static const lv_font_glyph_dsc_t _glyph_dsc[] =
{ /* struct initialization follows */ }
lv_font_t myfont
{ /* struct initialization follows */ }
所以我需要访问 myfont,以及它以二进制形式引用的声明。
我有一个工具,它创建表示一些二进制数据的 c 代码,以允许将数据编译并 linked 成最终的可执行文件(ARM 平台、GNU 工具链、定制硬件)。 我 运行 快用完闪存了,但还有备用 RAM。所以我正在考虑压缩库中的一些大型常量数据部分,并根据需要将它们解压缩到 RAM 中。 所以我可以编译 c 代码,并将其填充到存档中。但到目前为止,我一直没有运气尝试使用例如提取常量数据的二进制数据进行压缩。 objdump 或 objcopy。但是有件事告诉我,这是可能的(甚至可能很容易)。但是怎么办?我已经尝试 "google" 这个问题,但一无所获。
为什么不从编译后的二进制文件中提取数据,而是从生成的 C 代码中提取数据,对其进行压缩,然后使用压缩后的数据生成等效的 C 代码?
这种方法可能会简化实施、调试和测试的许多方面。
尤里卡!我想通了!
虽然我完全承认并感谢评论/其他答案中给出的建议,但我仍然感到困扰,我推测 "play the linker" 和从 [=101] 中提取硬编码数据块应该相对容易=].
好吧,事实证明使用 readelf
就像预期的那样相对容易(无论如何对于 elf 格式对象)要转储符号,我使用了两个步骤:
通过查看对象中的符号找出符号索引:
$ readelf --syms company_logo.o
</code></p> <p><code>Symbol table '.symtab' contains 17 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000 0 FILE LOCAL DEFAULT ABS company_logo.c
2: 00000000 0 SECTION LOCAL DEFAULT 1
3: 00000000 0 SECTION LOCAL DEFAULT 2
4: 00000000 0 SECTION LOCAL DEFAULT 3
5: 00000000 0 SECTION LOCAL DEFAULT 4
6: 00000000 0 NOTYPE LOCAL DEFAULT 4 $d
7: 00000000 0 SECTION LOCAL DEFAULT 6
8: 00000000 0 SECTION LOCAL DEFAULT 7
9: 00000000 0 SECTION LOCAL DEFAULT 9
10: 00000000 0 SECTION LOCAL DEFAULT 10
11: 00000000 0 SECTION LOCAL DEFAULT 12
12: 00000000 0 SECTION LOCAL DEFAULT 13
13: 00000000 0 SECTION LOCAL DEFAULT 14
14: 00000000 0 SECTION LOCAL DEFAULT 15
15: 00000000 12 OBJECT GLOBAL DEFAULT 4 company_logo
16: 00000000 21879 OBJECT GLOBAL DEFAULT 6 company_logo_map
转储符号的内容。
现在company_logo_map
是我的目标,所以使用它的索引6
,如下:
`readelf --hex-dump=6 company_logo.o`
` `
`Hex dump of section '.rodata.company_logo_map':`
` 0x00000000 00000000 00000000 00000000 00000000 ................`
` 0x00000010 00000000 00000000 00000000 00000000 ................`
` 0x00000020 00000000 00000000 00000000 00000000 ................`
` 0x00000030 00000000 00000000 00000000 00000000 ................`
` ... lots more data here`