查找导致库函数链接的函数

时间:2015-02-13 17:44:21

标签: c++ linker embedded

我正在使用带有修改的gcc工具链的c ++的嵌入式系统,而sprintf在我的最终可执行文件中是大量支持函数(_svfiprintf_r,_sprintf_r,_svfprintf_r),即使我没有明确引用他们在我的代码中。

我认为这些功能使我的可执行文件对我的系统来说太大了。有没有一种有效的方法让链接器告诉我为什么(什么函数调用)链接给定的函数?

工具链是Xilinx Micoblaze的GNU工具。

1 个答案:

答案 0 :(得分:2)

GNU链接器选项--cref将列出引用符号的所有对象模块(到映射文件或stdout) - 这可能有助于跟踪库中的隐藏用法。


sprintf函数本身可能非常小,并且是根据这些基础函数实现的 - 您无法避免"支持"如果你使用sprintf函数 - 它们是什么工作。总共sprintf函数不是一个简单的函数,如果代码大小很重要,通常应该完全避免使用标准库格式化的I / O.

某些库支持缩小大小的stdio实现,这些实现删除了对浮点格式的支持,这种格式特别昂贵。

_r后缀表示可重入库实现。在可重入版本中,每个线程可能有自己的errno副本,然后它变成线程局部变量而不是全局变量。这些_r函数的开销很小。如果您没有在多线程环境中运行,除了额外的函数调用之外,它们可能没有任何开销。

前缀中的f仅表示"文件I / O"功能,但实际上是指任何"流I / O" operation - 提供给sprintf调用的缓冲区被低级函数视为输出流。

前缀中的v表示采用va_list参数的函数的版本,并且需要将更高级别的可变参数函数转换为常规函数以处理变量长度参数列表。< / p>

前缀中的i表示仅整数实现,因此您似乎已经选择删除浮点支持?

所以在这种情况下,我猜测调用链是sprintf - &gt; _sprintf_r - &gt; _svfprintf_r - &gt; _svfiprintf_r

叶子函数_svfiprintf_r也可能是完成所有工作的地方,其他的是薄包装器,它们只是传递一次调用。

要认识到的重要一点是sprintf是完全自包含的,如果它没有利用这些&#34;支持函数&#34;,它本身就会非常大。此外,各种格式化的I / O函数中有很多通用代码,如果它们都是自包含的,那么对于您使用的每个函数,代码的大小都会显着增加。例如,使用sprintf之后,添加printf应该相对便宜,因为它们共享大部分相同的底层代码。

如果您真的不能接受格式化I / O的标准库实现的开销,您可以考虑使用替代的轻量级实现,例如Spare Time Labs' Tiny printf,它提供sprintf的小型简化实现和printf。有趣的是,您可以看到一个类似的结构,其中两个函数本身都非常小,但在tfp_format中共享一个更常见的大型实现。