cmacosx86symbolsnm

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


I want to display local (non-external) symbols in a C-program using nm on macOS.

I've read the man nm, and it essentially gives me the following options for displaying symbol information:

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

However, for the main.c program below, I'd expect nm -a to also output foo, since it's defined as a local symbol (internal linkage) by using the static keyword:

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

But, foo is not listed among the symbols. How can I make nm list all symbols (including local ones)?

main.c (compiled as 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");
}

Solution

  • You're not finding it because it isn't there -- look at the disassembly (objdump -d).

    Compilers routinely eliminate unused static functions even at -O0. To keep the foo function you can try making it both used and nontrivial (so it doesn't get inlined).

    E.g., for:

    #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();
    }
    

    I get:

    0000000000000000 T bar
    0000000000000000 t foo
    0000000000000000 T main
                     U printf
    

    with clang on Linux. You should get similar results on MacOS.