从存档/库中提取只读数据节(我猜是ELF吗?)以进行压缩

时间:2019-01-24 21:56:05

标签: gcc arm elf binutils

更新: 我正在基于lvgl构建应用程序。 为了允许文本,我使用lvgl维护者提供的在线工具将TrueType字体转换为C代码(const数据),该代码链接到应用程序中以呈现文本。 但是字体的结果数据集对于我的可用闪存来说太大了,但是我有很大一部分未使用的RAM。因此,我想使用heatshrink压缩数据,并在运行时将其解压缩到RAM。

这要求我的构建设置可以提取二进制数据,对其进行压缩并链接到闪存,以便我的运行时代码可以对其进行解压缩。

我猜想,我可以将所有生成的字体数据填充到“ lib”中,提取二进制数据,对其进行压缩,然后以“ 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代码,以允许将数据编译并链接到最终的可执行文件(ARM平台,GNU工具链,自定义硬件)中。 我的闪存快用完了,但还有可用的RAM。因此,我正在考虑压缩库中的一些大型常量数据段,然后根据需要将其解压缩到RAM。 因此,我可以编译C代码,并将其填充到存档中。但是到目前为止,我没有运气尝试尝试使用例如提取常数数据的二进制数据进行压缩。 objdump或objcopy。但是有件事告诉我,这是可能的(甚至可能很容易)。但是如何?我曾尝试“谷歌”问题,但空手而归。

2 个答案:

答案 0 :(得分:0)

为什么不从编译的二进制文件中提取数据,为什么不从生成的C代码中提取数据,对其进行压缩并使用压缩后的数据生成等效的C代码呢?

这种方法可能会简化实现,调试和测试的许多方面。

答案 1 :(得分:0)

尤里卡!我想通了!

尽管我完全承认并赞赏注释/其他答案中的建议,但仍然令我感到困扰的是,我认为“播放链接器”并从例如目标文件中提取硬编码数据的斑点应该相对容易。 / p>

好吧,事实证明,使用readelf

相对容易(无论如何对于elf格式的对象)

要转储符号,我使用了两个步骤:

  1. 通过查看对象中的符号来找出符号索引:

    $ readelf --syms company_logo.o

    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

  2. 转储符号的内容。

现在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`