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