1#!/bin/bash 2# 3# The Go linker does not seem to know what to do with relative 4# addressing of rodata.* offset from %rip. GCC likes to use this 5# addressing mode on this architecture, so we quickly run into 6# mis-computation when the relative addressing used in a .syso file of 7# symbol located data is resolved to completely the wrong place by the 8# Go (internal) linker. 9# 10# As a workaround for this, we can modify the assembly source code 11# generated by GCC to not point at problematic '.rodata.*' sections, 12# and place this data in the good old '.text' section where Go's 13# linker can make sense of it. 14# 15# This script exists to generate a '.syso' file from some '*.c' files. 16# It works by recognizing the '*.c' command line arguments and 17# converting them into fixed-up '*.s' files. It then performs the 18# compilation for the collection of the '*.s' files. Upon success, it 19# purges the intermediate '*.s' files. 20# 21# The fragile aspect of this present script is which compiler 22# arguments should be used for the compilation from '.c' -> '.s' 23# files. What we do is accumulate arguments until we encounter our 24# first '*.c' file and use those to perform the '.c' -> '.s' 25# compilation. We build up a complete command line for gcc 26# substituting '.s' files for '.c' files in the original command 27# line. Then with the new command line assembled we invoke gcc with 28# those. If that works, we remove all of the intermediate '.s' files. 29 30GCC="${GCC:=gcc}" 31setup=0 32args=() 33final=() 34ses=() 35 36for arg in "$@"; do 37 if [[ "${arg##*.}" = "c" ]]; then 38 setup=1 39 s="${arg%.*}.s" 40 "${GCC}" "${args[@]}" -S -o "${s}" "${arg}" 41 sed -i -e 's/.*\.rodata\..*/\t.text/' "${s}" 42 final+=("${s}") 43 ses+=("${s}") 44 else 45 if [[ $setup -eq 0 ]]; then 46 args+=("${arg}") 47 fi 48 final+=("${arg}") 49 fi 50done 51 52#echo final: "${final[@]}" 53#echo args: "${args[@]}" 54#echo ses: "${ses[@]}" 55 56"${GCC}" "${final[@]}" 57if [[ $? -ne 0 ]]; then 58 echo "failed to compile" 59 exit 1 60fi 61rm -f "${ses[@]}" 62