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


Using Stabs in Their Own Sections

Many object file formats allow tools to create object files with custom sections containing any arbitrary data. For any such object file format, stabs can be embedded in special sections. This is how stabs are used with ELF and SOM, and aside from ECOFF and XCOFF, is how stabs are used with COFF.

How to Embed Stabs in Sections

The assembler creates two custom sections, a section named .stab which contains an array of fixed length structures, one struct per stab, and a section named .stabstr containing all the variable length strings that are referenced by stabs in the .stab section. The byte order of the stabs binary data depends on the object file format. For ELF, it matches the byte order of the ELF file itself, as determined from the EI_DATA field in the e_ident member of the ELF header. For SOM, it is always big-endian (is this true??? FIXME). For COFF, it matches the byte order of the COFF headers. The meaning of the fields is the same as for a.out (see section Symbol Table Format), except that the n_strx field is relative to the strings for the current compilation unit (which can be found using the synthetic N_UNDF stab described below), rather than the entire string table.

The first stab in the .stab section for each compilation unit is synthetic, generated entirely by the assembler, with no corresponding .stab directive as input to the assembler. This stab contains the following fields:

n_strx
Offset in the .stabstr section to the source filename.
n_type
N_UNDF.
n_other
Unused field, always zero. This may eventually be used to hold overflows from the count in the n_desc field.
n_desc
Count of upcoming symbols, i.e., the number of remaining stabs for this source file.
n_value
Size of the string table fragment associated with this source file, in bytes.

The .stabstr section always starts with a null byte (so that string offsets of zero reference a null string), followed by random length strings, each of which is null byte terminated.

The ELF section header for the .stab section has its sh_link member set to the section number of the .stabstr section, and the .stabstr section has its ELF section header sh_type member set to SHT_STRTAB to mark it as a string table. SOM and COFF have no way of linking the sections together or marking them as string tables.

For COFF, the .stab and .stabstr sections may be simply concatenated by the linker. GDB then uses the n_desc fields to figure out the extent of the original sections. Similarly, the n_value fields of the header symbols are added together in order to get the actual position of the strings in a desired .stabstr section. Although this design obviates any need for the linker to relocate or otherwise manipulate .stab and .stabstr sections, it also requires some care to ensure that the offsets are calculated correctly. For instance, if the linker were to pad in between the .stabstr sections before concatenating, then the offsets to strings in the middle of the executable's .stabstr section would be wrong.

The GNU linker is able to optimize stabs information by merging duplicate strings and removing duplicate header file information (see section Names of Include Files). When some versions of the GNU linker optimize stabs in sections, they remove the leading N_UNDF symbol and arranges for all the n_strx fields to be relative to the start of the .stabstr section.

Having the Linker Relocate Stabs in ELF

This section describes some Sun hacks for Stabs in ELF; it does not apply to COFF or SOM.

To keep linking fast, you don't want the linker to have to relocate very many stabs. Making sure this is done for N_SLINE, N_RBRAC, and N_LBRAC stabs is the most important thing (see the descriptions of those stabs for more information). But Sun's stabs in ELF has taken this further, to make all addresses in the n_value field (functions and static variables) relative to the source file. For the N_SO symbol itself, Sun simply omits the address. To find the address of each section corresponding to a given source file, the compiler puts out symbols giving the address of each section for a given source file. Since these are ELF (not stab) symbols, the linker relocates them correctly without having to touch the stabs section. They are named Bbss.bss for the bss section, Ddata.data for the data section, and Drodata.rodata for the rodata section. For the text section, there is no such symbol (but there should be, see below). For an example of how these symbols work, See section Transformations of Stabs in separate sections. GCC does not provide these symbols; it instead relies on the stabs getting relocated. Thus addresses which would normally be relative to Bbss.bss, etc., are already relocated. The Sun linker provided with Solaris 2.2 and earlier relocates stabs using normal ELF relocation information, as it would do for any section. Sun has been threatening to kludge their linker to not do this (to speed up linking), even though the correct way to avoid having the linker do these relocations is to have the compiler no longer output relocatable values. Last I heard they had been talked out of the linker kludge. See Sun point patch 101052-01 and Sun bug 1142109. With the Sun compiler this affects `S' symbol descriptor stabs (see section Static Variables) and functions (see section Procedures). In the latter case, to adopt the clean solution (making the value of the stab relative to the start of the compilation unit), it would be necessary to invent a Ttext.text symbol, analogous to the Bbss.bss, etc., symbols. I recommend this rather than using a zero value and getting the address from the ELF symbols.

Finding the correct Bbss.bss, etc., symbol is difficult, because the linker simply concatenates the .stab sections from each `.o' file without including any information about which part of a .stab section comes from which `.o' file. The way GDB does this is to look for an ELF STT_FILE symbol which has the same name as the last component of the file name from the N_SO symbol in the stabs (for example, if the file name is `../../gdb/main.c', it looks for an ELF STT_FILE symbol named main.c). This loses if different files have the same name (they could be in different directories, a library could have been copied from one system to another, etc.). It would be much cleaner to have the Bbss.bss symbols in the stabs themselves. Having the linker relocate them there is no more work than having the linker relocate ELF symbols, and it solves the problem of having to associate the ELF and stab symbols. However, no one has yet designed or implemented such a scheme.


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