Go to the first, previous, next, last section, table of contents.


Symbol Information in Symbol Tables

This chapter describes the format of symbol table entries and how stab assembler directives map to them. It also describes the transformations that the assembler and linker make on data from stabs.

Symbol Table Format

Each time the assembler encounters a stab directive, it puts each field of the stab into a corresponding field in a symbol table entry of its output file. If the stab contains a string field, the symbol table entry for that stab points to a string table entry containing the string data from the stab. Assembler labels become relocatable addresses. Symbol table entries in a.out have the format:

struct internal_nlist {
  unsigned long n_strx;         /* index into string table of name */
  unsigned char n_type;         /* type of symbol */
  unsigned char n_other;        /* misc info (usually empty) */
  unsigned short n_desc;        /* description field */
  bfd_vma n_value;              /* value of symbol */
};

If the stab has a string, the n_strx field holds the offset in bytes of the string within the string table. The string is terminated by a NUL character. If the stab lacks a string (for example, it was produced by a .stabn or .stabd directive), the n_strx field is zero.

Symbol table entries with n_type field values greater than 0x1f originated as stabs generated by the compiler (with one random exception). The other entries were placed in the symbol table of the executable by the assembler or the linker.

Transformations on Symbol Tables

The linker concatenates object files and does fixups of externally defined symbols.

You can see the transformations made on stab data by the assembler and linker by examining the symbol table after each pass of the build. To do this, use `nm -ap', which dumps the symbol table, including debugging information, unsorted. For stab entries the columns are: value, other, desc, type, string. For assembler and linker symbols, the columns are: value, type, string.

The low 5 bits of the stab type tell the linker how to relocate the value of the stab. Thus for stab types like N_RSYM and N_LSYM, where the value is an offset or a register number, the low 5 bits are N_ABS, which tells the linker not to relocate the value.

Where the value of a stab contains an assembly language label, it is transformed by each build step. The assembler turns it into a relocatable address and the linker turns it into an absolute address.

Transformations on Static Variables

This source line defines a static variable at file scope:

static int s_g_repeat

The following stab describes the symbol:

.stabs "s_g_repeat:S1",38,0,0,_s_g_repeat

The assembler transforms the stab into this symbol table entry in the `.o' file. The location is expressed as a data segment offset.

00000084 - 00 0000 STSYM s_g_repeat:S1

In the symbol table entry from the executable, the linker has made the relocatable address absolute.

0000e00c - 00 0000 STSYM s_g_repeat:S1

Transformations on Global Variables

Stabs for global variables do not contain location information. In this case, the debugger finds location information in the assembler or linker symbol table entry describing the variable. The source line:

char g_foo = 'c';

generates the stab:

.stabs "g_foo:G2",32,0,0,0

The variable is represented by two symbol table entries in the object file (see below). The first one originated as a stab. The second one is an external symbol. The upper case `D' signifies that the n_type field of the symbol table contains 7, N_DATA with local linkage. The stab's value is zero since the value is not used for N_GSYM stabs. The value of the linker symbol is the relocatable address corresponding to the variable.

00000000 - 00 0000  GSYM g_foo:G2
00000080 D _g_foo

These entries as transformed by the linker. The linker symbol table entry now holds an absolute address:

00000000 - 00 0000  GSYM g_foo:G2
...
0000e008 D _g_foo

Transformations of Stabs in separate sections

For object file formats using stabs in separate sections (see section Using Stabs in Their Own Sections), use objdump --stabs instead of nm to show the stabs in an object or executable file. objdump is a GNU utility; Sun does not provide any equivalent.

The following example is for a stab whose value is an address is relative to the compilation unit (see section Having the Linker Relocate Stabs in ELF). For example, if the source line

static int ld = 5;

appears within a function, then the assembly language output from the compiler contains:

.Ddata.data:
...
        .stabs "ld:V(0,3)",0x26,0,4,.L18-Ddata.data    # 0x26 is N_STSYM
...
.L18:
        .align 4
        .word 0x5

Because the value is formed by subtracting one symbol from another, the value is absolute, not relocatable, and so the object file contains

Symnum n_type n_othr n_desc n_value  n_strx String
31     STSYM  0      4      00000004 680    ld:V(0,3)

without any relocations, and the executable file also contains

Symnum n_type n_othr n_desc n_value  n_strx String
31     STSYM  0      4      00000004 680    ld:V(0,3)


Go to the first, previous, next, last section, table of contents.