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 handledm68k-*-elf*andm68k-*-sysv4*). - Extends the
AIX_WEAK_SUPPORTpreprocessor define (needed for theC_WEAKEXTsymbol class used in XCOFF) to also coverppc-*-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.dataso that C++ global constructors and destructors are linked in. - Does not import the
gdbservertool 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 |