如何在 macOS 上使用 `nm` 在 C 程序中显示本地(非外部)符号?

How to display local (non-external) symbols in a C-program using `nm` on macOS?

我想在 macOS 上使用 nm 在 C 程序中显示本地(非外部)符号。

我已经阅读了 man nm,它基本上为我提供了以下用于显示交易品种信息的选项:

nm -m (Mach-O symbols)
nm -g (external symbols)
nm -a (all symbols) 

但是,对于下面的 main.c 程序,我希望 nm -a 也输出 foo,因为它被定义为使用 static 关键字的局部符号(内部链接):

nm -a main
0000000100000000 T __mh_execute_header
0000000100000f60 T _bar
0000000100000f30 T _main
                 U _printf
                 U dyld_stub_binder

但是,foo没有列在符号中。如何让 nm 列出所有符号(包括本地符号)?

main.c(编译为clang main.c -o main):

#include <stdio.h>

int main(int argc, char *argv[]) {
    printf("main");
}

static void foo() {
    printf("foo");
}

extern void bar() {
    printf("baz");
}

您找不到它是因为它不存在 -- 查看反汇编 (objdump -d)。

编译器通常会删除未使用的静态函数,即使在 -O0 时也是如此。要保留 foo 函数,您可以尝试使它既可用又重要(因此它不会内联)。

例如:

#include <stdio.h>

int main(int argc, char *argv[]) {
    printf("main");
}

static void foo() {
    for(int i=0;i<100;i++)
    printf("foo");
}

extern void bar() {
    printf("baz");
    foo();
}

我得到:

0000000000000000 T bar
0000000000000000 t foo
0000000000000000 T main
                 U printf

Linux 响起。您应该在 MacOS 上得到类似的结果。

要添加@PSkocik 出色的答案,您可以确保该函数将在最终二进制文件中发出:

static void foo() __attribute__((used));

static void foo() {
    printf("foo");
}