找到导致函数被链接的调用链

问题描述 投票:0回答:1

我正在开发一个嵌入式系统,在使用 nm 分析二进制文件时,我发现了许多来自标准库函数的符号,例如:

00001524 std::time_get<char, std::istreambuf_iterator<char, std::char_traits<char> > >::_M_extract_via_format(std::istreambuf_iterator<char, std::char_traits<char> >, std::istreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, std::_Ios_Iostate&, tm*, char const*) const [clone .localalias]

这意味着有一个

std::time_get
函数被链接进来,它有 1524 字节大。 我想找出是什么调用链导致了对
std::time_get
的调用,因为我实际上并没有在代码的任何部分中引用它。

尝试使用链接器标志

--cref
并查看映射文件,我可以找到该符号,但找不到调用它的内容。它只告诉我
libstdc++_nano.a(locale-inst.o)
引用了它:

.text._ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE21_M_extract_via_formatES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmPKc
                0x00000000080a07bc      0x5fc /opt/st/stm32cubeide_1.10.1/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.10.3-2021.10.linux64_1.0.0.202111181127/tools/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m+dp/hard/libstdc++_nano.a(locale-inst.o)
                0x00000000080a07bc                std::time_get<char, std::istreambuf_iterator<char, std::char_traits<char> > >::_M_extract_via_format(std::istreambuf_iterator<char, std::char_traits<char> >, std::istreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, std::_Ios_Iostate&, tm*, char const*) const

我怎样才能从那里找到来电者?

c++ linker static-analysis
1个回答
0
投票

您可以使用链接器

-y
标志来回答这个问题(尽管这非常乏味)。

示例:

// foo.c
int foo() { return 42; }

// bar.c
int bar() { return foo(); }

// main.c
int main() { return bar(); }
gcc -w -c main.c foo.c bar.c
ar r libfoo.a foo.o
ar r libbar.a bar.o

gcc main.o -L. -lbar -lfoo -Wl,-y,foo
 
/usr/bin/ld: ./libbar.a(bar.o): reference to foo
/usr/bin/ld: ./libfoo.a(foo.o): definition of foo

这告诉您

foo
已被选入链接,因为
bar.o
有对其的引用。重复
bar

gcc main.o -L. -lbar -lfoo -Wl,-y,bar
/usr/bin/ld: main.o: reference to bar
/usr/bin/ld: ./libbar.a(bar.o): definition of bar

您还可以使用

-M
标志来获取相同的信息:

gcc main.o -L. -lbar -lfoo -Wl,-M

将会有类似这样的输出:

 .text          0x0000000000001070       0xb9 /usr/lib/gcc/x86_64-linux-gnu/13/crtbeginS.o
 .text          0x0000000000001129       0x10 main.o
                0x0000000000001129                main           <<<---
 .text          0x0000000000001139       0x10 ./libbar.a(bar.o)
                0x0000000000001139                bar            <<<---
 .text          0x0000000000001149        0xb ./libfoo.a(foo.o)
                0x0000000000001149                foo            <<<---

<<<---
标记显示哪个符号导致相应的
.o
被拉入链接。

© www.soinside.com 2019 - 2024. All rights reserved.