Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/SMGCommunity/Petari/llms.txt

Use this file to discover all available pages before exploring further.

Every object file compiled by mwcc contains a .comment ELF section. This section carries per-symbol metadata — primarily alignment values and “force active” (export) flags — that mwld reads during the link step. Its presence or absence has consequences that are important to understand when reproducing an original build.

Effect on linker behavior

When a .comment section is absent, mwld skips two operations it would otherwise perform:
  1. It does not adjust symbol alignment.
  2. It does not remove unused symbols (dead-stripping is disabled).
For most decompilation work this is the desired behavior. Split objects are reconstructed from the final post-linked binary, which is already aligned and stripped to its final state. Allowing mwld to re-run alignment and dead-stripping on those objects would change the output. Because objects generated by powerpc-eabi-as (the GNU assembler) contain no .comment section, assembler-built objects benefit from this passthrough behavior automatically.

When the .comment section is required

Two situations require the .comment section to be present in the generated object:
  • Common BSS inflation bug reproduction — The older linker (GC 2.6 and earlier) only inflates the size of the first common BSS symbol in a TU when the .comment section is present. Without it, the linker records correct sizes and the inflated layout cannot be reproduced. See Common BSS.
  • Newer linker requirement — CodeWarrior for GameCube 2.7 and later will produce an internal linker error if common BSS is used without a valid .comment section.

Export behavior when .comment is generated

When decomp-toolkit generates a .comment section for an object, it marks all global symbols in that object as “exported” (force active). This prevents mwld from dead-stripping any symbols, because the mere presence of the .comment section re-enables dead-stripping. The export flag counteracts that by pinning every symbol in place. This is also useful for preventing the linker from discarding entire objects. A missing .comment section blocks removal of individual unused symbols inside an object, but the linker will still discard the entire object if it believes it is unreferenced. Generating a .comment section and setting the export flag closes that gap.

Binary format

The .comment section has a fixed-layout header followed by one 8-byte entry per ELF symbol (including the null symbol at index 0).
Offset  Size  Description
------  ----  -----------
0x00    0x0B  Magic: 43 6F 64 65 57 61 72 72 69 6F 72  ("CodeWarrior")
0x0B    0x01  Version byte
0x0C    0x04  Compiler version (major, minor, patch, 0x01)
0x10    0x01  Pool data flag
0x11    0x01  Float type
0x12    0x02  Processor type: 00 16 (Gekko)
0x14    0x01  Unknown, always 2C
0x15    0x01  Quirk flags (bitfield)
0x16    0x16  Padding (zeros until 0x2C)
Version byte (0x0B) — known values:
ValueHexCodeWarrior version
808GameCube 1.0 and later
100AGameCube 1.3.2 and later
110BGameCube 2.7 and later
120CGameCube 2.7 and later (difference from 11 unknown)
140EGameCube 3.0a3 and later
150FGameCube 3.0a3 and later (difference from 14 unknown)
The version byte is configurable via the mw_comment_version key in config.yml. It is not known whether mwld actually changes behavior based on this value, but it should match the compiler version used to build the project to produce a byte-identical .comment section.
Compiler version (0x0C, 4 bytes): The first three bytes are the major, minor, and patch version of the compiler. The fourth byte is always 0x01.
Version 2.3.3 build 144  →  02 03 00 01
Note that the version string reported by mwcc --help may differ from the internal version number stored here. Pool data flag (0x10):
00  Data pooling disabled
01  Data pooling enabled
Float type (0x11):
00  Floating point disabled
01  Software floating point
02  Hardware floating point
Quirk flags (0x15) — known bits:
01  Incompatible return small structs
02  Incompatible SFPE double params
04  Unsafe global reg vars

Symbol entries

Starting at offset 0x2C, there is one 8-byte entry for every ELF symbol in the object, in index order. The first entry corresponds to the null ELF symbol and is all zeros.
Offset  Size  Description
------  ----  -----------
0x00    0x04  Alignment (4-byte big-endian integer)
0x04    0x01  Visibility flags
0x05    0x01  Active flags
0x06    0x02  Padding: 00 00
Visibility flags (0x04):
ValueMeaning
00Default visibility
0DWeak
0EUnknown; also appears to indicate weak
Active flags (0x05):
ValueMeaning
00Default
08Force active / export — prevents dead-stripping. When set on a section symbol, the entire section is preserved as-is. Used by mwcc when data pooling is active (e.g. a symbol named ...data.0) to protect hard-coded section-relative offsets. Equivalent to #pragma force_active on or __declspec(export).
10Unknown
20Unknown

Build docs developers (and LLMs) love