Files
Retro68/BINUTILS-PATCHES.md
2026-05-26 20:16:59 +02:00

12 KiB

Binutils Patches for Retro68

This document describes the changes applied to binutils 2.39 (tracked via binutils-2.39-diff.patch) to support the Retro68 toolchain targeting classic Mac OS (m68k and PowerPC/XCOFF).


1. Enable the PowerPC XCOFF target unconditionally

What it does

The upstream bfd/targets.c wraps the powerpc_xcoff_vec target vector in #if 0 because it shares the same BFD magic number as RS/6000 and was therefore disabled by default to avoid conflicts. Retro68 needs this target always available for the powerpc-apple-macos cross-compiler.

Files changed

File Change
binutils/bfd/targets.c Changes #if 0 to #if 1 around the powerpc_xcoff_vec entry in _bfd_target_vector[].
binutils/bfd/config.bfd In the powerpc-*-macos* case, adds targ_cflags=-DAIX_WEAK_SUPPORT and targ_selvecs=powerpc_xcoff_vec (in addition to the already-present targ_defvec).

Re-applying to a newer binutils

Find the powerpc_xcoff_vec entry in bfd/targets.c and change its guard from #if 0 to #if 1. In bfd/config.bfd, locate the powerpc-*-macos* entry and add the two lines.


2. GAS: m68k-macos assembler format and AIX weak support

What it does

  • Registers ELF as the output format for m68k-*-macos* targets in the GAS target configuration (upstream only handled m68k-*-elf* and m68k-*-sysv4*).
  • Extends the AIX_WEAK_SUPPORT preprocessor define (needed for the C_WEAKEXT symbol class used in XCOFF) to also cover ppc-*-macos* targets, not just AIX 5+ targets.

Files changed

File Change
binutils/gas/configure.tgt Adds m68k-*-macos*) fmt=elf ;; entry.
binutils/gas/configure.ac Extends the ppc-*-aix[5-9].* pattern to also match ppc-*-macos* for AC_DEFINE(AIX_WEAK_SUPPORT, 1, ...).
binutils/gas/configure Generated configure updated to match.

Re-applying to a newer binutils

In gas/configure.tgt, add the m68k-*-macos* line adjacent to the other m68k-*-elf* entries. In gas/configure.ac, extend the ppc-*-aix[5-9].* pattern to include | ppc-*-macos* and regenerate configure.


3. LD: custom linker script for ppcmacos

What it does

The upstream ld/emulparams/ppcmacos.sh used the generic aix linker script (SCRIPT_NAME=aix). This is replaced with a new ppcmacos script that:

  • Defines sections in the correct order for a classic Mac OS XCOFF executable: .pad, .text, .data (including the TOC and constructor table), .bss, .loader, and .debug.
  • Aligns the text segment at 0x10000000 + SIZEOF_HEADERS.
  • Aligns the data segment to page boundaries relative to text.
  • Includes ${CONSTRUCTING+CONSTRUCTORS} in .data so that C++ global constructors and destructors are linked in.
  • Does not import the gdbserver tool from the build system (see configure change below).

Files changed

File Change
binutils/ld/emulparams/ppcmacos.sh Changes SCRIPT_NAME=aix to SCRIPT_NAME=ppcmacos.
binutils/ld/scripttempl/ppcmacos.sc New file. The full linker script template (75 lines).
binutils/configure Removes gdbserver from host_tools (prevents an unneeded build dependency).

Re-applying to a newer binutils

Copy ppcmacos.sc into ld/scripttempl/. Change SCRIPT_NAME in ld/emulparams/ppcmacos.sh. The configure change (removing gdbserver) should be verified against the current configure.ac and regenerated if necessary.


4. LD/objdump: AIX_WEAK_SUPPORT for powerpc-*-macos

What it does

The AIX_WEAK_SUPPORT flag enables proper handling of the C_WEAKEXT symbol class in XCOFF object files. Upstream only enabled it for AIX 5+ targets; Retro68 also needs it for powerpc-*-macos.

Files changed

File Change
binutils/binutils/configure.ac Extends the powerpc*-aix[5-9].* pattern to include `
binutils/binutils/configure Generated configure updated to match.

Re-applying to a newer binutils

In binutils/configure.ac, find the OBJDUMP_DEFS AIX pattern and extend it to include powerpc-*-macos, then regenerate configure.


5. BFD/XCOFF: weak symbol handling fixes

What it does

Several related fixes in the XCOFF linker to handle bfd_link_hash_undefweak and C_AIX_WEAKEXT symbols correctly when linking Mac OS PowerPC executables:

5a. Do not report unresolved weak symbols as errors

bfd/coff-rs6000.c (xcoff_ppc_relocate_section): adds a check h->root.type != bfd_link_hash_undefweak to the condition that reports an undefined-symbol error. Weak undefined symbols are allowed to remain unresolved; they resolve to zero.

5b. Handle undefweak as zero in relocation

Same function: adds an else if (h->root.type == bfd_link_hash_undefweak) branch that sets sec = 0 and val = 0, matching the ELF convention that a weak undefined symbol has value zero.

5c. Do not zero the size of C_AIX_WEAKEXT common sections

bfd/xcofflink.c (xcoff_link_add_symbols): when adding a common symbol to the hash table, the original code unconditionally set csect->size = 0. For C_AIX_WEAKEXT symbols this must be preserved (see AutomatedTests/LocalStatic.cc). Two guarded sites: once for the initial common-section creation, and once in the duplicate-symbol resolution path where a defweak symbol should not trigger the size zeroing.

5d. Do not propagate XCOFF_WAS_UNDEFINED through weak descriptor

bfd/xcofflink.c (xcoff_mark_symbol): when a descriptor's source symbol is marked XCOFF_WAS_UNDEFINED, the flag was unconditionally propagated to the descriptor. Adds a guard so the flag is only propagated when the descriptor is not bfd_link_hash_undefweak.

5e. Mark entry-point symbol before the static-section pass

bfd/xcofflink.c (bfd_xcoff_size_dynamic_sections): moves the xcoff_mark_symbol_by_name(entry, XCOFF_ENTRY) call to before the else branch that processes non-relocatable links, ensuring the entry-point symbol is always marked with XCOFF_ENTRY regardless of link mode.

Files changed

All changes are in binutils/bfd/coff-rs6000.c and binutils/bfd/xcofflink.c.

Re-applying to a newer binutils

Each of these is a small, targeted change. Locate the functions by name (xcoff_ppc_relocate_section, xcoff_link_add_symbols, xcoff_mark_symbol, bfd_xcoff_size_dynamic_sections) and apply the individual hunks. The xcoff_link_add_symbols changes reference C_AIX_WEAKEXT; verify the constant name has not changed.


6. BFD/XCOFF: keep constructor and exception-table sections

What it does

bfd/xcofflink.c (xcoff_link_add_symbols): when a symbol whose name starts with _GLOBAL__ (the GCC convention for constructor/destructor registration functions and exception-frame entries) is encountered, its csect is marked SEC_KEEP so that the XCOFF garbage-collector does not discard it.

A second loop in bfd_xcoff_size_dynamic_sections then explicitly calls xcoff_mark on all sections with SEC_KEEP set, ensuring they are included in the final output even when --gc-sections is in effect.

Files changed

File Change
binutils/bfd/xcofflink.c Adds the _GLOBAL__ name prefix check setting SEC_KEEP, and the SEC_KEEP mark loop.

Re-applying to a newer binutils

Find xcoff_link_add_symbols and bfd_xcoff_size_dynamic_sections; apply the two hunks in sequence.


7. ELF GC: keep .macsbug sections adjacent to their function

What it does

During ELF section garbage collection (bfd/elflink.c, _bfd_elf_gc_mark), after marking a section as live, checks whether the next section in the section list has a name equal to the current section's name plus .macsbug. If so, that section is also marked live.

This ensures that per-function MacsBug symbol records (which GCC places in .text.funcname.macsbug sections when -ffunction-sections is active) are not stripped by the linker's --gc-sections pass.

Files changed

File Change
binutils/bfd/elflink.c Adds a name-comparison block in _bfd_elf_gc_mark after the group_sec check.

Re-applying to a newer binutils

Locate _bfd_elf_gc_mark in bfd/elflink.c. After the group-section recursion block and before "Look through the section relocs", insert the new block. The logic is: compare section names character by character, and if the current name is a prefix of the next section's name and the suffix is exactly .macsbug, mark the next section.


8. BFD/XCOFF: long filename in auxiliary records

What it does

Fixes a buffer-overrun / incorrect read in bfd/coff-rs6000.c (_bfd_xcoff_swap_aux_in) when a C_FILE auxiliary entry has more than one auxiliary record (i.e. the filename is longer than FILNMLEN bytes and spans multiple aux entries).

The fix: when numaux > 1 and the current aux-entry index (indx) is 0, copy numaux * sizeof(AUXENT) bytes instead of just FILNMLEN bytes. The original unconditional memcpy(…, FILNMLEN) is retained for the normal single-aux-entry case.

Files changed

File Change
binutils/bfd/coff-rs6000.c Replaces the memcpy in the else branch of the C_FILE/x_n.x_n.x_zeroes check with a conditional copy.

Re-applying to a newer binutils

Locate _bfd_xcoff_swap_aux_in and the else branch of the filename read; apply the length-conditional logic.


9. objdump: pretty-print C_FILE auxiliary entries

What it does

Adds a C_FILE branch to coff_print_aux in bfd/coffcode.h that prints the filename stored in the auxiliary entry, resolving the string-table offset if necessary (the x_zeroes field indicates whether the name is inline or referenced by offset into the COFF string table).

Without this, objdump prints raw hex bytes for C_FILE auxiliaries, making XCOFF object dumps very hard to read.

Files changed

File Change
binutils/bfd/coffcode.h Adds a C_FILE case at the top of coff_print_aux for RS6000COFF targets.

Re-applying to a newer binutils

In bfd/coffcode.h, find coff_print_aux and the existing #ifdef RS6000COFF_C guard; insert the new C_FILE block immediately after the guard.


10. zlib/zutil.h: remove dead Metrowerks fdopen workaround

What it does

Removes a block that defined fdopen(fd, mode) as NULL for old Metrowerks CodeWarrior compilers on Mac OS. This block is now dead code and confuses modern compilers when MACOS or TARGET_OS_MAC is defined by the build environment.

Files changed

File Change
binutils/zlib/zutil.h Removes the #ifndef Z_SOLO / fdopen workaround block inside the `MACOS

Re-applying to a newer binutils

Locate the #if defined(MACOS) || defined(TARGET_OS_MAC) block in zlib/zutil.h and remove the inner fdopen workaround (leave the OS_CODE 7 line).


Summary of patches to re-apply when upgrading binutils

Priority Area Files Complexity
Essential Enable XCOFF target bfd/targets.c, bfd/config.bfd Trivial
Essential GAS m68k-macos format + AIX weak support gas/configure.tgt, gas/configure.ac Low
Essential Custom ppcmacos linker script ld/emulparams/ppcmacos.sh, ld/scripttempl/ppcmacos.sc Low (new file)
Essential XCOFF weak symbol fixes bfd/coff-rs6000.c, bfd/xcofflink.c Medium
Essential Keep constructor/EH sections bfd/xcofflink.c Low
Important ELF GC: keep .macsbug sections bfd/elflink.c Low
Important AIX_WEAK_SUPPORT for objdump binutils/configure.ac Trivial
Quality Long filename in XCOFF aux records bfd/coff-rs6000.c Low
Quality objdump C_FILE pretty-print bfd/coffcode.h Low
Quality Remove dead fdopen workaround zlib/zutil.h Trivial