#!/usr/bin/env python3 """Extract the loadable .text bytes from an as34/ld34 g.out file. g.out is not COFF. It uses the .go/linkhdr format from binutils/link.h (LINKMAGIC 0x3abf782e), packed with #pragma pack(2). IMPORTANT: link.h declares the header fields that hold addresses and sizes as `long`. On the original 32-bit Unix hosts that is 4 bytes; on x86-64 it is 8, so the written header is 156 bytes here instead of the historical 80. as34 and ld34 are both rebuilt with the same compiler, so they agree with each other and with this parser. A stable on-disk format would need `long` changed to int32_t in link.h. Layout as written by this 64-bit build (offsets in bytes): off field 0 short swapped 2 long magic 10 short flags 12 long time 20 long textstart file position of text 28 long textsize size in BYTES 36 long datastart 44 long datasize 52 long bsssize 60 long relocstart 68 long nrelocs 76 long symtabstart 84 long nsyms 92 long stabstart 100 long nstabs 108 long stringstart 116 long stringSize 124 long textLoadAddress BIT address 132 long dataLoadAddress 140 long bssLoadAddress 148 long entrypoint BIT address """ import hashlib import struct import sys LINKMAGIC = 0x3ABF782E def main(out_path, bin_path): d = open(out_path, "rb").read() fields = struct.unpack_from("