当前位置: 首页 > 知识库问答 >
问题:

第三方C静态库:Add-ffunction-段落-fdata-段落

公羊信厚
2023-03-14

我有一个c静态库(用arm gcc编译),它是由第三方提供的。我不可能(让第三方)重新编译这个库。

在调查库内容时,我发现gcc选项-ffunction部分和-fdata部分没有用于编译库。但这将非常有助于减少项目的二进制大小。

编译使用:(ARM嵌入式处理器的GNU工具)4.8.4 20140526(版本)[ARM/Embedded-4_8-branch修订版211358]。

有没有办法将每个数据和每个函数放在各自独立的部分中,以便在不需要重新编译代码的情况下为该库启用函数级链接?

我想到了这个可能的方法:

  • 将库拆分为其目标文件
  • 对于每个对象文件:
    • 编写代码将符号移动到自己的部分

    这是否可行,或者你是否有其他建议,最好只使用arm-gcc提供的工具?

共有1个答案

公良浩邈
2023-03-14

我知道这很古老,但我也遇到了这个问题,我想我会提供我的发现。

TL;这是可能的,但非常困难。你不能简单地将符号移动到它们自己的部分。搬迁会让你痛苦。

当编译器生成机器代码时,如果提供或不提供-ffunction-节-fdata-节标志,它将生成稍微不同的指令。这是由于编译器能够对符号的位置做出假设。这些假设根据提供的标志而改变。

这最好用例子来说明。以下面非常简单的代码片段为例:

int a, b;

int getAPlusB()
{
    return a + b;
}

以下是arm none eabi objdump-xdr测试的结果。o

arm none-eabi-gcc-c-Os-mthumb-mcpu=cortexm3-mlittle-endian-o测试。o测试。c

SYMBOL TABLE:
00000000 g     F .text  0000000c getAPlusB
00000004 g     O .bss   00000004 b
00000000 g     O .bss   00000004 a

Disassembly of section .text:

00000024 <getAPlusB>:
  24:   4b01        ldr r3, [pc, #4]    ; (2c <getAPlusB+0x8>)
  26:   cb09        ldmia   r3, {r0, r3}
  28:   4418        add r0, r3
  2a:   4770        bx  lr
  2c:   00000000    .word   0x00000000
            2c: R_ARM_ABS32 .bss

arm none eabi gcc-c-Os-F功能部分-fdata部分-mthumb-mcpu=cortexm3-mlittle endian-o测试。o测试。c

SYMBOL TABLE:
00000000 g     F .text.getAPlusB    00000014 getAPlusB
00000000 g     O .bss.b 00000004 b
00000000 g     O .bss.a 00000004 a

Disassembly of section .text.getAPlusB:

00000000 <getAPlusB>:
   0:   4b02        ldr r3, [pc, #8]    ; (c <getAPlusB+0xc>)
   2:   6818        ldr r0, [r3, #0]
   4:   4b02        ldr r3, [pc, #8]    ; (10 <getAPlusB+0x10>)
   6:   681b        ldr r3, [r3, #0]
   8:   4418        add r0, r3
   a:   4770        bx  lr
    ...
            c: R_ARM_ABS32  .bss.a
            10: R_ARM_ABS32 .bss.b

两者之间的区别很微妙,但很重要。启用标志的代码执行两个单独的加载,而禁用的代码执行一个“多次加载”启用的代码之所以这样做,是因为它知道这两个符号都包含在同一个部分中,以特定的顺序。启用代码后,情况并非如此。这些符号分为两个独立的部分,虽然它们可能会保持其顺序和接近性,但不能保证。此外,如果两个部分都未被引用,链接器可能会决定一个部分未被使用,并将其删除。

另一个例子:

int a, b;

int getB()
{
  return b;
}

和生成的代码。首先没有标志:

SYMBOL TABLE:
00000000 g     F .text  0000000c getB
00000004 g     O .bss   00000004 b
00000000 g     O .bss   00000004 a

Disassembly of section .text:

00000018 <getB>:
  18:   4b01        ldr r3, [pc, #4]    ; (20 <getB+0x8>)
  1a:   6858        ldr r0, [r3, #4]
  1c:   4770        bx  lr
  1e:   bf00        nop
  20:   00000000    .word   0x00000000
            20: R_ARM_ABS32 .bss

还有国旗:

SYMBOL TABLE:
00000000 g     F .text.getB 00000014 getB
00000000 g     O .bss.b 00000004 b
00000000 g     O .bss.a 00000004 a

Disassembly of section .text.getB:

00000000 <getB>:
   0:   4b01        ldr r3, [pc, #4]    ; (8 <getB+0x8>)
   2:   6818        ldr r0, [r3, #0]
   4:   4770        bx  lr
   6:   bf00        nop
   8:   00000000    .word   0x00000000
            8: R_ARM_ABS32  .bss.b

在这种情况下,差异甚至更加微妙。启用的代码加载时偏移量为0,而禁用的代码使用4。由于禁用的代码引用节的开头,它需要偏移到b的位置。然而,启用的代码引用仅包含b的节,因此不需要偏移量。如果我们将其拆分并只更改重定位,新代码将包含对a所在节的引用,但不包含b。这再次可能导致链接器垃圾收集错误的节。

这只是我在研究这个问题时遇到的两种情况,可能还有更多。

生成功能等同于使用-ffunction sections-fdata sections标志编译的代码的有效目标文件,需要解析机器指令,查找这些以及可能出现的任何其他重新定位问题。这不是一项容易完成的任务。

 类似资料:
  • 原则 一个段落只能有一个主题,或一个中心句子。 段落的中心句子放在段首,对全段内容进行概述。后面陈述的句子为核心句服务。 一个段落的长度不能超过七行,最佳段落长度小于等于四行。 段落的句子语气要使用陈述和肯定语气,避免使用感叹语气。 段落之间使用一个空行隔开。 段落开头不要留出空白字符。 引用 引用第三方内容时,应注明出处。 One man’s constant is another man’s

  • 段落是被空行分割的文字片段,左侧必须对齐(没有空格,或者有相同多的空格)。 缩进的段落被视为引文。这里是段落 缩进的段落被视为引文。这里也是段落 缩进的段落被视为引文。这里还是段落 缩进的段落被视为引文。 源码 | 这里是段落 缩进的段落被视为引文。 | 这里也是段落 缩进的段落被视为引文。 | 这里还是段落 缩进的段落被视为引文。 注解 段落,可以前空2格,或使用 |,做

  • 问题内容: 我有一个Go库,它为C ++ OpenImageIO库(OpenImageiGO)提供绑定。我一直在通过与libOpenImageIO的标准动态链接来构建绑定,但现在尝试静态链接。我遇到了一个问题,无论我尝试使用哪种标志组合,外部链接器都会失败,并出现大量“未定义的引用”错误。我似乎回想起过去曾提到过的这个问题,他说链接器看到符号的顺序存在问题。但我似乎再也找不到此信息。 这是我最近一

  • 主要内容:HTML 段落,实例,不要忘记结束标签,实例,HTML 折行,实例,HTML 输出- 使用提醒,本站实例,更多实例,HTML 标签参考手册HTML 可以将文档分割为若干段落。 HTML 段落 段落是通过 <p> 标签定义的。 实例 <p>这是一个段落 </p> <p>这是另一个段落</p> 注意:浏览器会自动地在段落的前后添加空行。(</p> 是块级元素) 不要忘记结束标签 即使忘了使用结束标签,大多数浏览器也会正确地将 HTML 显示出来: 实例 <p>这是一个段落 <p>这是另一个

  • 在 word 中,一般都是通过段落来组织文本,段落是十分重要的组成部分。而 word 中的段落,主要有字体和段落两大属性。本节重点介绍字体和段落属性,在CSS中的对应属性及应用方法。 字体属性 word中的字体属性包括字体、字形、字号、字体颜色、下划线、效果等,如图 11‑11 所示: 图11-11 word中的字体属性 字体通过 font-family属性进行设置,为属性设置两个值,并把英文字体

  • 在本章中,您将学习如何创建段落以及如何使用Java将其添加到文档中。 段落是Word文件中页面的一部分。 完成本章后,您将能够创建段落并对其执行读取操作。 创建一个段落 首先,让我们使用前面章节中讨论的引用类创建一个Paragraph。 按照上一章,首先创建一个Document,然后我们可以创建一个Paragraph。 以下代码段用于创建电子表格 - //Create Blank document