Draft: Fix(dbgdwarf): Use target pointer size instead of host sizeof(pint/puint)

Summary

sizeof(pint) and sizeof(puint) are Pascal host-language expressions that resolve at compile time of the compiler itself, always returning the pointer size of the machine that built the compiler. When the compiler is used for cross-compilation (e.g. a 64-bit host producing 32-bit debug info, or vice versa), these values are wrong.

dbgdwarf.pas uses sizeof(pint) / sizeof(puint) in eleven places to represent the target pointer size — the width of addresses in the generated DWARF data. This produces structurally malformed DWARF output on any cross-compilation scenario where host and target pointer widths differ.

Root cause

The correct way to query the target pointer size within the compiler is voidpointertype.size, which is initialised by psystem.pas from the target CPU description and is already used for this purpose throughout the rest of the compiler (e.g. paramgr.pas, symdef.pas, ncgmem.pas).

Affected sites

Location Role
DW_AT_byte_size for method-pointer struct Total byte size of the {Proc, Self} layout
DW_AT_data_member_location block for Self field Byte offset of Self = one pointer width into the struct
DW_LNE_set_address extended-opcode length (×3) Length prefix = 1 (subopcode byte) + pointer width
address_size in .debug_aranges header Declared width of addresses in the aranges section
address_size in .debug_info compilation-unit header Declared width of addresses in the info section
DW_OP_addr-based location block sizes (×3) Byte count of a DWARF location expression containing one address
Bit-field natural alignment size max(pointer_width, field_size) for packed record members

The two most visibly broken cases for a typical x86_64 → i386 cross-compile are the address_size header bytes (emitted as 08 instead of 04), which cause standard consumers such as readelf, lldb, and GDB to misparse the entire .debug_info and .debug_aranges sections.

Fix

Replace every affected sizeof(pint) / sizeof(puint) with voidpointertype.size. No logic changes; purely a substitution of the host-time constant with the equivalent target-time value. voidpointertype is already imported via the existing symdef unit dependency in dbgdwarf.pas.

Testing

Verified that the native x86_64-linux build still compiles cleanly with this patch applied. A dedicated
cross-compilation regression test (compile a trivial program with -g targeting i386-linux and inspect the emitted address_size bytes via readelf --debug-dump=info) would be the ideal confirmation, but requires a ppcross386
bootstrap — this is being prepared separately and will be noted once available.

Notes

The sizeof(puint) instances in the aitconst_dtpoff TLS path (lines ~2450–2475) share the same class of bug but sit
inside a block already marked TODO: FIXME: dwarf for thread vars with its own pre-existing limitations. Those are intentionally left for a separate fix to keep this MR focused.

Edited by Graeme G

Merge request reports

Loading