IA-64 gABI Issue 72: COMDAT
Revised 19 October 1999
C++ has many situations where the compiler may need to emit code or data, but may not be able to identify a unique compilation unit where it should be emitted. The approach chosen by the C++ ABI group to deal with this problem, is to allow the compiler to emit the required information in multiple compilation units, in a form which allows the linker to remove all but one copy. This is essentially the feature called COMDAT in several existing implementations.
Various other implementations (notably Windows NT) and proposals obtain more generality by varying the duplicate removal semantics. The most obviously useful variant supports grouping of sections for removal purposes, but treats duplication as an error, using it to support link-time removal of unreferenced sections. The proposal below treats this simple grouping as the default semantics, and provides duplicate removal as an option.
Our objectives include:
The proposal below is based on the HP definition, with minor modifications and more precise definitions.
This attribute flag may be set in any section header, and no other modification or indication is made in the grouped sections. All additional information is contained in the associated SHT_GROUP section (see below).
Some sections occur in interrelated groups. For instance, an out-of-line definition of an inline function might require, in addition to its .text section, a read-only data section containing literals referenced, one or more debug information sections, and/or other informational sections. Furthermore, there may be internal references among these sections that would not make sense if one of them were removed or replaced by a duplicate from another object. Therefore, we assume that such groups are to be included or omitted from the linked object as a unit. (Except for the GRP_COMDAT flag described below, this definition does not specify the circumstances under which the members of a group might be discarded from the linked object.)
To facilitate this, we define a SHT_GROUP section:
The section header attributes of a Group Section are:
name | unspecified |
sh_type |
SHT_GROUP |
sh_link |
.symtab section index |
sh_info |
symbol index |
sh_flags |
none |
sh_entsize |
size of section indices (4 ) |
requirements | may not be stripped |
The section group's sh_link
field identifies a symbol
table section, and its sh_info
field the index of a
symbol in that section.
The name of that symbol is treated as the identifier of the section group.
The section data of a SHT_GROUP section is a flag word followed by a sequence of section indices. The flag word may contain the following flags:
The section indices in the SHT_GROUP section identify the sections which make up the group.
The sh_size
value is sh_entsize
times
one plus the number of sections in the group.
The linker may choose to discard a section in a group, i.e. not include its data in the linked object, based on COMDAT duplicate semantics (above), or for other implementation-defined reasons (e.g. removing unreferenced code). If it does so, the group semantics requires that all of the group members be removed as a unit.
(Note, however, that this is not intended to imply that special-case behavior like removing debug information requires removing the sections to which it refers, even if they are in a group. We could clarify this issue by tying the removal semantics to the section which contains the identifying symbol, but this seems overly restrictive and unnecessary.
The above rules allow a group to be removed without leaving dangling references, with only minimal processing of the symbol table.