debug-symbolsnm

debug_info/debugging symbols: why isn't nm displaying them for my executable?


Why doesn't nm display the debugging symbols like it does for object files ?

Is that also normal that all the symbol addresses in my objects files are all 0?

MRE:

#include "foo.h"

int     main()
{
    foo();
    return 0;
}
void    foo()
{
}
#ifndef FOO_H
# define FOO_H
void    foo();
#endif
$ gcc -c -g -o foo.o foo.c
$ nm -a foo.o 
0000000000000000 N .debug_abbrev
0000000000000000 N .debug_info
0000000000000000 N .debug_line
0000000000000000 N .debug_line_str
0000000000000000 N .debug_str
0000000000000000 T foo
0000000000000000 a foo.c
0000000000000000 t .text
$ ar rc libfoo.a foo.o
$ nm -a libfoo.a

foo.o:
0000000000000000 N .debug_abbrev
0000000000000000 N .debug_info
0000000000000000 N .debug_line
0000000000000000 N .debug_line_str
0000000000000000 N .debug_str
0000000000000000 T foo
0000000000000000 a foo.c
0000000000000000 t .text
$
$ gcc -g main.c -L . -lfoo
$ nm -a a.out 
0000000000000000 a 
0000000000004010 B __bss_start
                 w __cxa_finalize@GLIBC_2.2.5
0000000000004000 D __data_start
0000000000004000 W data_start
0000000000004008 D __dso_handle
0000000000003e20 d _DYNAMIC
0000000000004010 D _edata
0000000000004018 B _end
0000000000001138 T _fini
000000000000112e T foo
0000000000000000 a foo.c
0000000000003fe8 d _GLOBAL_OFFSET_TABLE_
                 w __gmon_start__
0000000000002004 r __GNU_EH_FRAME_HDR
0000000000001000 T _init
0000000000002000 R _IO_stdin_used
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
                 U __libc_start_main@GLIBC_2.34
0000000000001119 T main
0000000000000000 a main.c
0000000000001020 T _start
0000000000004010 D __TMC_END__
$ 
$ file a.out
a.out: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=48cebaa6f43e93bb1805faa5b71d41f1d1e71501, for GNU/Linux 4.4.0, with debug_info, not stripped
$ 
$ readelf -S a.out
There are 34 section headers, starting at offset 0x37c0:

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .interp           PROGBITS         0000000000000318  00000318
       000000000000001c  0000000000000000   A       0     0     1
  [ 2] .note.gnu.pr[...] NOTE             0000000000000338  00000338
       0000000000000040  0000000000000000   A       0     0     8
  [ 3] .note.gnu.bu[...] NOTE             0000000000000378  00000378
       0000000000000024  0000000000000000   A       0     0     4
  [ 4] .note.ABI-tag     NOTE             000000000000039c  0000039c
       0000000000000020  0000000000000000   A       0     0     4
  [ 5] .gnu.hash         GNU_HASH         00000000000003c0  000003c0
       000000000000001c  0000000000000000   A       6     0     8
  [ 6] .dynsym           DYNSYM           00000000000003e0  000003e0
       0000000000000090  0000000000000018   A       7     1     8
  [ 7] .dynstr           STRTAB           0000000000000470  00000470
       0000000000000088  0000000000000000   A       0     0     1
  [ 8] .gnu.version      VERSYM           00000000000004f8  000004f8
       000000000000000c  0000000000000002   A       6     0     2
  [ 9] .gnu.version_r    VERNEED          0000000000000508  00000508
       0000000000000030  0000000000000000   A       7     1     8
  [10] .rela.dyn         RELA             0000000000000538  00000538
       00000000000000c0  0000000000000018   A       6     0     8
  [11] .init             PROGBITS         0000000000001000  00001000
       000000000000001b  0000000000000000  AX       0     0     4
  [12] .text             PROGBITS         0000000000001020  00001020
       0000000000000115  0000000000000000  AX       0     0     16
  [13] .fini             PROGBITS         0000000000001138  00001138
       000000000000000d  0000000000000000  AX       0     0     4
  [14] .rodata           PROGBITS         0000000000002000  00002000
       0000000000000004  0000000000000004  AM       0     0     4
  [15] .eh_frame_hdr     PROGBITS         0000000000002004  00002004
       0000000000000024  0000000000000000   A       0     0     4
  [16] .eh_frame         PROGBITS         0000000000002028  00002028
       0000000000000074  0000000000000000   A       0     0     8
  [17] .init_array       INIT_ARRAY       0000000000003e10  00002e10
       0000000000000008  0000000000000008  WA       0     0     8
  [18] .fini_array       FINI_ARRAY       0000000000003e18  00002e18
       0000000000000008  0000000000000008  WA       0     0     8
  [19] .dynamic          DYNAMIC          0000000000003e20  00002e20
       00000000000001a0  0000000000000010  WA       7     0     8
  [20] .got              PROGBITS         0000000000003fc0  00002fc0
       0000000000000028  0000000000000008  WA       0     0     8
  [21] .got.plt          PROGBITS         0000000000003fe8  00002fe8
       0000000000000018  0000000000000008  WA       0     0     8
  [22] .data             PROGBITS         0000000000004000  00003000
       0000000000000010  0000000000000000  WA       0     0     8
  [23] .bss              NOBITS           0000000000004010  00003010
       0000000000000008  0000000000000000  WA       0     0     1
  [24] .comment          PROGBITS         0000000000000000  00003010
       0000000000000036  0000000000000001  MS       0     0     1
  [25] .debug_aranges    PROGBITS         0000000000000000  00003046
       0000000000000060  0000000000000000           0     0     1
  [26] .debug_info       PROGBITS         0000000000000000  000030a6
       00000000000000ab  0000000000000000           0     0     1
  [27] .debug_abbrev     PROGBITS         0000000000000000  00003151
       000000000000007b  0000000000000000           0     0     1
  [28] .debug_line       PROGBITS         0000000000000000  000031cc
       00000000000000a1  0000000000000000           0     0     1
  [29] .debug_str        PROGBITS         0000000000000000  0000326d
       000000000000003d  0000000000000001  MS       0     0     1
  [30] .debug_line_str   PROGBITS         0000000000000000  000032aa
       000000000000003e  0000000000000001  MS       0     0     1
  [31] .symtab           SYMTAB           0000000000000000  000032e8
       0000000000000258  0000000000000018          32     7     8
  [32] .strtab           STRTAB           0000000000000000  00003540
       000000000000011f  0000000000000000           0     0     1
  [33] .shstrtab         STRTAB           0000000000000000  0000365f
       000000000000015c  0000000000000000           0     0     1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  D (mbind), l (large), p (processor specific)

Solution

  • Those debugging symbols output by nm -a foo.o are the names of linkage sections containing debugging info. The compiler puts all section names into the symbol table of an object file because the linker will need them to merge input sections into output sections in the output file. By default nm does not report symbols that are section names: with -a it does. The linker does not put the names of the merged output sections into the symbol table of the output file because they can no longer be needed for any further merging - unless the linkage is a partial linkage (-Wl,-r) - in which case they are put into the symbol table.

    Illustration:

    $ cat foobar.c
    static const int bint = 47;
    
    void foo() __attribute__((section(".text.foo")));
    void foo()
    {
    }
    int bar() __attribute__((section(".text.bar")));
    int bar()
    {
        return bint;
    }
    
    
    $ cat foobar.h
    #ifndef FOOBAR_H
    # define FOOBAR_H
    void    foo();
    int    bar(); 
    #endif
    
    
    $ cat main.c
    #include "foobar.h"
    
    int     main()
    {
        foo();
        return bar();
    }
    
    $ gcc -g -c main.c foobar.c
    

    The symbol table of foobar.o is:

    $ readelf --syms foobar.o
    
    Symbol table '.symtab' contains 14 entries:
       Num:    Value          Size Type    Bind   Vis      Ndx Name
         0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
         1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS foobar.c
         2: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 .rodata
         3: 0000000000000000     4 OBJECT  LOCAL  DEFAULT    4 bint
         4: 0000000000000000     0 SECTION LOCAL  DEFAULT    5 .text.foo
         5: 0000000000000000     0 SECTION LOCAL  DEFAULT    6 .text.bar
         6: 0000000000000000     0 SECTION LOCAL  DEFAULT    7 .debug_info
         7: 0000000000000000     0 SECTION LOCAL  DEFAULT    9 .debug_abbrev
         8: 0000000000000000     0 SECTION LOCAL  DEFAULT   12 .debug_rnglists
         9: 0000000000000000     0 SECTION LOCAL  DEFAULT   14 .debug_line
        10: 0000000000000000     0 SECTION LOCAL  DEFAULT   16 .debug_str
        11: 0000000000000000     0 SECTION LOCAL  DEFAULT   17 .debug_line_str
        12: 0000000000000000    11 FUNC    GLOBAL DEFAULT    5 foo
        13: 0000000000000000    15 FUNC    GLOBAL DEFAULT    6 bar
        
    

    All sections, including debug sections, are represented.

    By default nm does not report section names:

    $ nm foobar.o
    0000000000000000 T bar
    0000000000000000 r bint
    0000000000000000 T foo
    

    But nm -a does:

    $ nm -a foobar.o
    0000000000000000 T bar
    0000000000000000 r bint
    0000000000000000 N .debug_abbrev
    0000000000000000 N .debug_info
    0000000000000000 N .debug_line
    0000000000000000 N .debug_line_str
    0000000000000000 N .debug_rnglists
    0000000000000000 N .debug_str
    0000000000000000 T foo
    0000000000000000 a foobar.c
    0000000000000000 r .rodata
    0000000000000000 t .text.bar
    0000000000000000 t .text.foo
    

    Now link a program and generate the mapfile:

    $ gcc -g -o prog main.o foobar.o -Wl,-Map=mapfile
    

    The (abbreviated) mapfile shows the input-to-output section merges:

    Merging program properties
    ...[cut]...
    Memory Configuration
    ...[cut]...
    Name             Origin             Length             Attributes
    *default*        0x0000000000000000 0xffffffffffffffff
    
    Linker script and memory map
    ...[cut]...
    .text           0x0000000000001040      0x121
    ...[cut]...
     .text          0x0000000000001147        0x0 foobar.o
     .text.foo      0x0000000000001147        0xb foobar.o
                    0x0000000000001147                foo
     .text.bar      0x0000000000001152        0xf foobar.o
                    0x0000000000001152                bar                
    ...[cut]...                
    .rodata         0x0000000000002000        0x8
    ...[cut]...
     .rodata        0x0000000000002004        0x4 foobar.o
    ...[cut]...
    .debug_info     0x0000000000000000       0xf9
     *(.debug_info .gnu.linkonce.wi.*)
     .debug_info    0x0000000000000000       0x74 main.o
     .debug_info    0x0000000000000074       0x85 foobar.o
    .debug_abbrev   0x0000000000000000       0xcc
     *(.debug_abbrev)
     .debug_abbrev  0x0000000000000000       0x65 main.o
     .debug_abbrev  0x0000000000000065       0x67 foobar.o
    .debug_line     0x0000000000000000       0xba
     *(.debug_line .debug_line.* .debug_line_end)
     .debug_line    0x0000000000000000       0x57 main.o
     .debug_line    0x0000000000000057       0x63 foobar.o
    ...[cut]...
    .debug_str      0x0000000000000000       0x98
     *(.debug_str)
     .debug_str     0x0000000000000000       0x98 main.o
                                             0x93 (size before relaxing)
     .debug_str     0x0000000000000098       0x93 foobar.o
    ...[cut]...
    .debug_line_str
                    0x0000000000000000       0x34
     *(.debug_line_str)
     .debug_line_str
                    0x0000000000000000       0x34 main.o
                                             0x54 (size before relaxing)
     .debug_line_str
                    0x0000000000000034       0x51 foobar.o     
    ...[cut] ...
    OUTPUT(prog elf64-x86-64) 
    

    Note e.g. how the input function sections text.foo and text.bar are merged into the output .text section; the input debug_info sections from main.o and foobar.o are merged into the output debug_info section, etc.

    All the section names are gone from the symbol table of the output file:

    $ readelf -W --syms prog
    
    Symbol table '.dynsym' contains 6 entries:
       Num:    Value          Size Type    Bind   Vis      Ndx Name
         0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
         1: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.34 (2)
         2: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_deregisterTMCloneTable
         3: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
         4: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_registerTMCloneTable
         5: 0000000000000000     0 FUNC    WEAK   DEFAULT  UND __cxa_finalize@GLIBC_2.2.5 (3)
    
    Symbol table '.symtab' contains 39 entries:
       Num:    Value          Size Type    Bind   Vis      Ndx Name
         0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
         1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS Scrt1.o
         2: 000000000000038c    32 OBJECT  LOCAL  DEFAULT    4 __abi_tag
         3: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
         4: 0000000000001070     0 FUNC    LOCAL  DEFAULT   14 deregister_tm_clones
         5: 00000000000010a0     0 FUNC    LOCAL  DEFAULT   14 register_tm_clones
         6: 00000000000010e0     0 FUNC    LOCAL  DEFAULT   14 __do_global_dtors_aux
         7: 0000000000004010     1 OBJECT  LOCAL  DEFAULT   24 completed.0
         8: 0000000000003df8     0 OBJECT  LOCAL  DEFAULT   20 __do_global_dtors_aux_fini_array_entry
         9: 0000000000001120     0 FUNC    LOCAL  DEFAULT   14 frame_dummy
        10: 0000000000003df0     0 OBJECT  LOCAL  DEFAULT   19 __frame_dummy_init_array_entry
        11: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS main.c
        12: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS foobar.c
        13: 0000000000002004     4 OBJECT  LOCAL  DEFAULT   16 bint
        14: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
        15: 0000000000002118     0 OBJECT  LOCAL  DEFAULT   18 __FRAME_END__
        16: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS 
        17: 0000000000003e00     0 OBJECT  LOCAL  DEFAULT   21 _DYNAMIC
        18: 0000000000002008     0 NOTYPE  LOCAL  DEFAULT   17 __GNU_EH_FRAME_HDR
        19: 0000000000003fc0     0 OBJECT  LOCAL  DEFAULT   22 _GLOBAL_OFFSET_TABLE_
        20: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.34
        21: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_deregisterTMCloneTable
        22: 0000000000004000     0 NOTYPE  WEAK   DEFAULT   23 data_start
        23: 0000000000004010     0 NOTYPE  GLOBAL DEFAULT   23 _edata
        24: 0000000000001152    15 FUNC    GLOBAL DEFAULT   14 bar
        25: 0000000000001164     0 FUNC    GLOBAL HIDDEN    15 _fini
        26: 0000000000004000     0 NOTYPE  GLOBAL DEFAULT   23 __data_start
        27: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
        28: 0000000000004008     0 OBJECT  GLOBAL HIDDEN    23 __dso_handle
        29: 0000000000002000     4 OBJECT  GLOBAL DEFAULT   16 _IO_stdin_used
        30: 0000000000001147    11 FUNC    GLOBAL DEFAULT   14 foo
        31: 0000000000004018     0 NOTYPE  GLOBAL DEFAULT   24 _end
        32: 0000000000001040    38 FUNC    GLOBAL DEFAULT   14 _start
        33: 0000000000004010     0 NOTYPE  GLOBAL DEFAULT   24 __bss_start
        34: 0000000000001129    30 FUNC    GLOBAL DEFAULT   14 main
        35: 0000000000004010     0 OBJECT  GLOBAL HIDDEN    23 __TMC_END__
        36: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_registerTMCloneTable
        37: 0000000000000000     0 FUNC    WEAK   DEFAULT  UND __cxa_finalize@GLIBC_2.2.5
        38: 0000000000001000     0 FUNC    GLOBAL HIDDEN    11 _init
    

    But the output section names remain section names:

    $ readelf -S prog
    There are 36 section headers, starting at offset 0x3b10:
    
    Section Headers:
      [Nr] Name              Type             Address           Offset
           Size              EntSize          Flags  Link  Info  Align
      [ 0]                   NULL             0000000000000000  00000000
           0000000000000000  0000000000000000           0     0     0
      [ 1] .interp           PROGBITS         0000000000000318  00000318
           000000000000001c  0000000000000000   A       0     0     1
      [ 2] .note.gnu.pr[...] NOTE             0000000000000338  00000338
           0000000000000030  0000000000000000   A       0     0     8
      [ 3] .note.gnu.bu[...] NOTE             0000000000000368  00000368
           0000000000000024  0000000000000000   A       0     0     4
      [ 4] .note.ABI-tag     NOTE             000000000000038c  0000038c
           0000000000000020  0000000000000000   A       0     0     4
      [ 5] .gnu.hash         GNU_HASH         00000000000003b0  000003b0
           0000000000000024  0000000000000000   A       6     0     8
      [ 6] .dynsym           DYNSYM           00000000000003d8  000003d8
           0000000000000090  0000000000000018   A       7     1     8
      [ 7] .dynstr           STRTAB           0000000000000468  00000468
           0000000000000088  0000000000000000   A       0     0     1
      [ 8] .gnu.version      VERSYM           00000000000004f0  000004f0
           000000000000000c  0000000000000002   A       6     0     2
      [ 9] .gnu.version_r    VERNEED          0000000000000500  00000500
           0000000000000030  0000000000000000   A       7     1     8
      [10] .rela.dyn         RELA             0000000000000530  00000530
           00000000000000c0  0000000000000018   A       6     0     8
      [11] .init             PROGBITS         0000000000001000  00001000
           000000000000001b  0000000000000000  AX       0     0     4
      [12] .plt              PROGBITS         0000000000001020  00001020
           0000000000000010  0000000000000010  AX       0     0     16
      [13] .plt.got          PROGBITS         0000000000001030  00001030
           0000000000000010  0000000000000010  AX       0     0     16
      [14] .text             PROGBITS         0000000000001040  00001040
           0000000000000121  0000000000000000  AX       0     0     16
      [15] .fini             PROGBITS         0000000000001164  00001164
           000000000000000d  0000000000000000  AX       0     0     4
      [16] .rodata           PROGBITS         0000000000002000  00002000
           0000000000000008  0000000000000000   A       0     0     4
      [17] .eh_frame_hdr     PROGBITS         0000000000002008  00002008
           000000000000003c  0000000000000000   A       0     0     4
      [18] .eh_frame         PROGBITS         0000000000002048  00002048
           00000000000000d4  0000000000000000   A       0     0     8
      [19] .init_array       INIT_ARRAY       0000000000003df0  00002df0
           0000000000000008  0000000000000008  WA       0     0     8
      [20] .fini_array       FINI_ARRAY       0000000000003df8  00002df8
           0000000000000008  0000000000000008  WA       0     0     8
      [21] .dynamic          DYNAMIC          0000000000003e00  00002e00
           00000000000001c0  0000000000000010  WA       7     0     8
      [22] .got              PROGBITS         0000000000003fc0  00002fc0
           0000000000000040  0000000000000008  WA       0     0     8
      [23] .data             PROGBITS         0000000000004000  00003000
           0000000000000010  0000000000000000  WA       0     0     8
      [24] .bss              NOBITS           0000000000004010  00003010
           0000000000000008  0000000000000000  WA       0     0     1
      [25] .comment          PROGBITS         0000000000000000  00003010
           0000000000000026  0000000000000001  MS       0     0     1
      [26] .debug_aranges    PROGBITS         0000000000000000  00003036
           0000000000000070  0000000000000000           0     0     1
      [27] .debug_info       PROGBITS         0000000000000000  000030a6
           00000000000000f9  0000000000000000           0     0     1
      [28] .debug_abbrev     PROGBITS         0000000000000000  0000319f
           00000000000000cc  0000000000000000           0     0     1
      [29] .debug_line       PROGBITS         0000000000000000  0000326b
           00000000000000ba  0000000000000000           0     0     1
      [30] .debug_str        PROGBITS         0000000000000000  00003325
           0000000000000098  0000000000000001  MS       0     0     1
      [31] .debug_line_str   PROGBITS         0000000000000000  000033bd
           0000000000000034  0000000000000001  MS       0     0     1
      [32] .debug_rnglists   PROGBITS         0000000000000000  000033f1
           0000000000000021  0000000000000000           0     0     1
      [33] .symtab           SYMTAB           0000000000000000  00003418
           00000000000003a8  0000000000000018          34    20     8
      [34] .strtab           STRTAB           0000000000000000  000037c0
           00000000000001df  0000000000000000           0     0     1
      [35] .shstrtab         STRTAB           0000000000000000  0000399f
           000000000000016c  0000000000000000           0     0     1
           
    

    The .text section of course survives, but .text.foo and .text.bar don't, having been merged into .text.

    On the other hand, if we perform a partial linkage:

    $ gcc -r -g -o prog.o main.o foobar.o
    

    then the section names go into the symbol table:

    $ readelf --syms prog.o
    
    Symbol table '.symtab' contains 24 entries:
       Num:    Value          Size Type    Bind   Vis      Ndx Name
         0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
         1: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 .note.gnu.property
         2: 0000000000000000     0 SECTION LOCAL  DEFAULT    2 .text
         3: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 .text.foo
         4: 0000000000000000     0 SECTION LOCAL  DEFAULT    5 .text.bar
         5: 0000000000000000     0 SECTION LOCAL  DEFAULT    6 .rodata
         6: 0000000000000000     0 SECTION LOCAL  DEFAULT    7 .eh_frame
         7: 0000000000000000     0 SECTION LOCAL  DEFAULT    9 .data
         8: 0000000000000000     0 SECTION LOCAL  DEFAULT   10 .bss
         9: 0000000000000000     0 SECTION LOCAL  DEFAULT   11 .comment
        10: 0000000000000000     0 SECTION LOCAL  DEFAULT   12 .note.GNU-stack
        11: 0000000000000000     0 SECTION LOCAL  DEFAULT   13 .debug_aranges
        12: 0000000000000000     0 SECTION LOCAL  DEFAULT   15 .debug_info
        13: 0000000000000000     0 SECTION LOCAL  DEFAULT   17 .debug_abbrev
        14: 0000000000000000     0 SECTION LOCAL  DEFAULT   18 .debug_line
        15: 0000000000000000     0 SECTION LOCAL  DEFAULT   20 .debug_str
        16: 0000000000000000     0 SECTION LOCAL  DEFAULT   21 .debug_line_str
        17: 0000000000000000     0 SECTION LOCAL  DEFAULT   22 .debug_rnglists
        18: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS main.c
        19: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS foobar.c
        20: 0000000000000000     4 OBJECT  LOCAL  DEFAULT    6 bint
        21: 0000000000000000    30 FUNC    GLOBAL DEFAULT    2 main
        22: 0000000000000000    11 FUNC    GLOBAL DEFAULT    4 foo
        23: 0000000000000000    15 FUNC    GLOBAL DEFAULT    5 bar
    

    and they are reported by:

    $ nm -a prog.o
    0000000000000000 T bar
    0000000000000000 r bint
    0000000000000000 b .bss
    0000000000000000 n .comment
    0000000000000000 d .data
    0000000000000000 N .debug_abbrev
    0000000000000000 N .debug_aranges
    0000000000000000 N .debug_info
    0000000000000000 N .debug_line
    0000000000000000 N .debug_line_str
    0000000000000000 N .debug_rnglists
    0000000000000000 N .debug_str
    0000000000000000 r .eh_frame
    0000000000000000 T foo
    0000000000000000 a foobar.c
    0000000000000000 T main
    0000000000000000 a main.c
    0000000000000000 r .note.gnu.property
    0000000000000000 n .note.GNU-stack
    0000000000000000 r .rodata
    0000000000000000 t .text
    0000000000000000 t .text.bar
    0000000000000000 t .text.foo