diff options
-rw-r--r-- | ghc/ghc-cross.wrapper | 1 | ||||
-rw-r--r-- | includes/mkDerivedConstants.cross.awk | 350 | ||||
-rw-r--r-- | includes/mkSizeMacros.cross.awk | 82 | ||||
-rw-r--r-- | rules/cross-compiling.mk | 24 |
4 files changed, 457 insertions, 0 deletions
diff --git a/ghc/ghc-cross.wrapper b/ghc/ghc-cross.wrapper new file mode 100644 index 0000000000..56564e589d --- /dev/null +++ b/ghc/ghc-cross.wrapper @@ -0,0 +1 @@ +exec "$executablename" -B"$topdir" ${1+"$@"} -pgma "$pgmgcc" -pgmc "$pgmgcc" -pgml "$pgmgcc" diff --git a/includes/mkDerivedConstants.cross.awk b/includes/mkDerivedConstants.cross.awk new file mode 100644 index 0000000000..c66655e922 --- /dev/null +++ b/includes/mkDerivedConstants.cross.awk @@ -0,0 +1,350 @@ +## This script rewrites normal C structs into successively +## greater ones so that field offset computation becomes a +## sizeof lookup and thus amenable to compile-time computations. + +## Usage: pipe stg/Regs.h into 'awk' running this script +## to obtain a .c file that can be compiled to .o +## with the gcc from the cross toolchain. Then +## use another 'awk' script to process the 'nm' +## output of the object file. + +## Motivation: since in general we can not run executables +## created by the cross toolchain, we need another +## way of finding out field offsets and type sizes +## of the target platform. + +BEGIN { + interesting = 0 + seed = 0 + print "/* this file is generated by mkDerivedConstants.cross.awk, do not touch */" + print "/* needs to be compiled with the target gcc */" + print "" + print "#include \"Rts.h\"" + print "#include \"Capability.h\"" + print "" + ## these do not have a proper typedef; supply them here + print "#define FLAG_STRUCT_TYPE(IT) typedef struct IT ## _FLAGS IT ## _FLAGS" + print "FLAG_STRUCT_TYPE(GC);" + print "FLAG_STRUCT_TYPE(DEBUG);" + print "FLAG_STRUCT_TYPE(COST_CENTRE);" + print "FLAG_STRUCT_TYPE(PROFILING);" + print "FLAG_STRUCT_TYPE(TRACE);" + print "FLAG_STRUCT_TYPE(CONCURRENT);" + print "FLAG_STRUCT_TYPE(MISC);" + print "FLAG_STRUCT_TYPE(PAR);" + print "FLAG_STRUCT_TYPE(TICKY);" + ## these we do know how to get the field size, + ## so do not bother mining it + print "#define DO_NOT_MINE_UNION_MEMBER(STRUCT, NESTED_MEMBER, ID) char nestedfieldsize$ ## STRUCT ## $ ## ID [sizeof ((STRUCT*)0)->NESTED_MEMBER]" + print "DO_NOT_MINE_UNION_MEMBER(StgHeader, prof.hp.ldvw, prof_hp_ldvw);" + print "DO_NOT_MINE_UNION_MEMBER(StgFunInfoExtraFwd, b.bitmap, b_bitmap);" + print "DO_NOT_MINE_UNION_MEMBER(StgFunInfoExtraRev, b.bitmap, b_bitmap);" +} + +## pass through embedded unions +eat_union && /^[ \t]*}[ \t]*[_0-9a-zA-Z][_0-9a-zA-Z]*[ \t]*;[ \t]*$/ { + sub(/^[ \t]*}[ \t]*/, "") + sub(/[ \t]*;[ \t]*$/, "") + new_offset_struct_name = struct_name $0 + print "" + + eat_union = 0 + + if (!offset_struct_name) + { + print "char starting" new_offset_struct_name "[2];" + } + else + { + assumptions = assumptions "\n" "char sizeof" new_offset_struct_name "[offsetof(^^^, " $0 ")];" + assumptions = assumptions "\n" "typedef char verify_size" new_offset_struct_name "[sizeof sizeof" new_offset_struct_name " == offsetof(^^^, " $0 ") ? 1 : -1];" + } + + offset_struct_name = new_offset_struct_name + next +} + +eat_union { + next +} + +/# [0-9]* "rts\// { + ours = 1 + next +} + +/# [0-9]* "includes\// { + ours = 1 + next +} + +## filter out non-ghc headers +/# [0-9]* "/ { + ours = 0 + next +} + +!ours { + next +} + +!interesting { + struct_name = "$" seed "$" + offset_struct_name = "" + known_struct_name = "" + eat_union = 0 + assumptions = "" +} + +## kill empty line +/^[ \t]*$/ { + next +} + +/^# [0-9]/ { + print + next +} + +/^typedef struct[ \t][ \t]*[_0-9a-zA-Z]*[ \t]*{[ \t]*$/ { + if (interesting) error "previous struct not closed?" + interesting = 1 + print "" + print "/* ### Creating offset structs for " $3 " ### */" + next +} + +/^struct[ \t][ \t]*[_0-9a-zA-Z]*[ \t]*{[ \t]*$/ { + if (interesting) error "previous struct not closed?" + interesting = 1 + known_struct_name = $2 + sub(/_$/, "", known_struct_name); + print "" + print "/* ### Creating offset structs for " known_struct_name " ### */" + print "char associate$" known_struct_name "$" seed ";" + next +} + +## end of struct +## +interesting && /^[ \t]*}[ \t]*[_0-9a-zA-Z][_0-9a-zA-Z]*[ \t]*;[ \t]*$/{ + sub(/;$/, "", $2) + + print "char associate$" $2 "$" seed ";" + print "char SIZEOF$" seed "[sizeof(" $2 ")];" + print "" + print "" + gsub(/\^\^\^/, $2, assumptions); + print assumptions + ++seed + interesting = 0 + next +} + +## Ptr-typedef +interesting && /^[ \t]*}[ \t]*\*[_0-9a-zA-Z][_0-9a-zA-Z]*Ptr[ \t]*;[ \t]*$/{ + sub(/Ptr;$/, "", $2) + sub(/^\*/, "", $2) + + print "char associate$" $2 "$" seed ";" + print "char SIZEOF$" seed "[sizeof(" $2 ")];" + print "" + print "" + gsub(/\^\^\^/, $2, assumptions); + print assumptions + ++seed + interesting = 0 + next +} + +interesting && /^[ \t]*}[; \t]*$/ { + print "char SIZEOF$" seed "[sizeof(" known_struct_name ")];" + print "" + print "" + gsub(/\^\^\^/, known_struct_name, assumptions); + print assumptions + ++seed + interesting = 0 +} + +# collapse whitespace after '*' +interesting { + # normalize some types + sub(/struct StgClosure_[ \t]*\*/, "StgClosure *") + gsub(/\*[ \t]*volatile/, "*") + # group stars together + gsub(/\*[ \t]*/, "*") + sub(/\*/, " *") + print "// " $0 + # remove volatile + sub(/[ \t]volatile[ \t]/, " ") + # remove const + sub(/[ \t]const[ \t]/, " ") +} + +## (pointer to struct) member of struct +## +interesting && /^[ \t]*struct[ \t][ \t]*[_0-9a-zA-Z][_0-9a-zA-Z]*[ \t]*\*[ \t]*[_0-9a-zA-Z][_0-9a-zA-Z]*[ \t]*;[ \t]*$/ { + if (!$4) { + sub(/^\*/, "", $3) + $4 = $3 + } + sub(/;$/, "", $4) + + new_offset_struct_name = struct_name $4 + print "" + + if (!offset_struct_name) + { + print "char starting" new_offset_struct_name "[2];" + } + else + { + assumptions = assumptions "\n" "char sizeof" new_offset_struct_name "[offsetof(^^^, " $4 ")];" + assumptions = assumptions "\n" "typedef char verify_size" new_offset_struct_name "[sizeof sizeof" new_offset_struct_name " == offsetof(^^^, " $4 ") ? 1 : -1];" + } + print "char fieldsize" new_offset_struct_name "[sizeof(struct " $2 "*)];" + print "" + print "" + offset_struct_name = new_offset_struct_name + next +} + +## (simple pointer) member of struct +## +interesting && /^[ \t]*[_0-9a-zA-Z][_0-9a-zA-Z]*[ \t][ \t]*\*\**[_0-9a-zA-Z][_0-9a-zA-Z]*[ \t]*;[ \t]*$/ { + sub(/;$/, "", $2) + sub(/^\**/, "", $2) + + new_offset_struct_name = struct_name $2 + print "" + + if (!offset_struct_name) + { + print "char starting" new_offset_struct_name "[2];" + } + else + { + assumptions = assumptions "\n" "char sizeof" new_offset_struct_name "[offsetof(^^^, " $2 ")];" + assumptions = assumptions "\n" "typedef char verify_size" new_offset_struct_name "[sizeof sizeof" new_offset_struct_name " == offsetof(^^^, " $2 ") ? 1 : -1];" + } + print "char fieldsize" new_offset_struct_name "[sizeof(" $1 "*)];" + print "" + print "" + offset_struct_name = new_offset_struct_name + next +} + +## member of struct +## +interesting && /^[ \t]*[_0-9a-zA-Z][_0-9a-zA-Z]*[ \t][ \t]*[_0-9a-zA-Z][_0-9a-zA-Z]*;[ \t]*$/ { + sub(/;$/, "", $2) + + new_offset_struct_name = struct_name $2 + print "" + + if (!offset_struct_name) + { + print "char starting" new_offset_struct_name "[2];" + } + else + { + assumptions = assumptions "\n" "char sizeof" new_offset_struct_name "[offsetof(^^^, " $2 ")];" + assumptions = assumptions "\n" "typedef char verify_size" new_offset_struct_name "[sizeof sizeof" new_offset_struct_name " == offsetof(^^^, " $2 ") ? 1 : -1];" + } + print "char fieldsize" new_offset_struct_name "[sizeof(" $1 ")];" + print "" + print "" + offset_struct_name = new_offset_struct_name + next +} + +## struct member of struct +## +interesting && /^[ \t]*struct[ \t][ \t]*[_0-9a-zA-Z][_0-9a-zA-Z]*[ \t][ \t]*[_0-9a-zA-Z][_0-9a-zA-Z]*;[ \t]*$/ { + sub(/;$/, "", $3) + + new_offset_struct_name = struct_name $3 + print "" + + if (!offset_struct_name) + { + print "char starting" new_offset_struct_name "[2];" + } + else + { + assumptions = assumptions "\n" "char sizeof" new_offset_struct_name "[offsetof(^^^, " $3 ")];" + assumptions = assumptions "\n" "typedef char verify_size" new_offset_struct_name "[sizeof sizeof" new_offset_struct_name " == offsetof(^^^, " $3 ") ? 1 : -1];" + } + print "char fieldsize" new_offset_struct_name "[sizeof(struct " $2 ")];" + print "" + print "" + offset_struct_name = new_offset_struct_name + next +} + +## embedded union +interesting && /^[ \t]*union[ \t]*{[ \t]*$/ { + eat_union = 1 + next +} + +## array member +interesting && /^[ \t]*[_0-9a-zA-Z][_0-9a-zA-Z]*[ \t][ \t]*\**[_0-9a-zA-Z][_0-9a-zA-Z]*\[.*\];[ \t]*$/ { + sub(/;[ \t]*$/, "", $0) + + full = $0 + sub(/^[ \t]*[_0-9a-zA-Z][_0-9a-zA-Z]*[ \t][ \t]*/, "", full) + split(full, parts, "[") + mname = parts[1] + sub(/^\**/, "", mname) + + new_offset_struct_name = struct_name mname + print "" + + if (!offset_struct_name) + { + print "char starting" new_offset_struct_name "[2];" + } + else + { + assumptions = assumptions "\n" "char sizeof" new_offset_struct_name "[offsetof(^^^, " mname ")];" + assumptions = assumptions "\n" "typedef char verify_size" new_offset_struct_name "[sizeof sizeof" new_offset_struct_name " == offsetof(^^^, " mname ") ? 1 : -1];" + } + + print "" + print "" + offset_struct_name = new_offset_struct_name + next +} + + +## padded member of struct +## of this form: StgHalfInt slow_apply_offset; StgHalfWord __pad_slow_apply_offset;; +## +interesting && /^[ \t]*[_0-9a-zA-Z][_0-9a-zA-Z]*[ \t][ \t]*[_0-9a-zA-Z][_0-9a-zA-Z]*;[ \t]*[_0-9a-zA-Z][_0-9a-zA-Z]*[ \t][ \t]*__pad_[a-zA-Z][_0-9a-zA-Z]*;;*[ \t]*$/ { + mname = $2 + sub(/;$/, "", mname) + + new_offset_struct_name = struct_name mname + print "" + + if (!offset_struct_name) + { + print "char starting" new_offset_struct_name "[2];" + } + else + { + assumptions = assumptions "\n" "char sizeof" new_offset_struct_name "[offsetof(^^^, " mname ")];" + assumptions = assumptions "\n" "typedef char verify_size" new_offset_struct_name "[sizeof sizeof" new_offset_struct_name " == offsetof(^^^, " mname ") ? 1 : -1];" + } + print "" + print "" + offset_struct_name = new_offset_struct_name + next +} + +interesting && /;[ \t]*$/ { + print "Member not recognized: " $0 > "/dev/stderr" + exit 1 +}
\ No newline at end of file diff --git a/includes/mkSizeMacros.cross.awk b/includes/mkSizeMacros.cross.awk new file mode 100644 index 0000000000..e33e4ff4e5 --- /dev/null +++ b/includes/mkSizeMacros.cross.awk @@ -0,0 +1,82 @@ +BEGIN { + print "#define OFFSET(s_type, field) OFFSET_ ## s_type ## _ ## field" + print "#define FIELD_SIZE(s_type, field) FIELD_SIZE_ ## s_type ## _ ## field" + print "#define TYPE_SIZE(type) TYPE_SIZE_ ## type" + print "" +} + +/^0[0-9a-zA-Z]* C _*associate\$/ { + sub(/_*associate\$/, "", $3) + split($3, arr, "$") + assoc[arr[2]] = arr[1] + next +} + +/^00*2 C _*starting\$[0-9]*\$[_0-9a-zA-Z]*$/ { + sub(/_*starting\$/, "", $3) + split($3, arr, "$") + sub(/^0*/, "", $1) + print "#define OFFSET_" assoc[arr[1]] "_" arr[2] " 0x0" + next +} + +/^0[0-9a-zA-Z]* C _*sizeof\$[0-9]*\$[_0-9a-zA-Z]*$/ { + sub(/_*sizeof\$/, "", $3) + split($3, arr, "$") + sub(/^0*/, "", $1) + print "#define OFFSET_" assoc[arr[1]] "_" arr[2] " 0x" $1 + next +} + +/^0[0-9a-zA-Z]* C _*fieldsize\$[0-9]*\$[_0-9a-zA-Z]*$/ { + sub(/_*fieldsize\$/, "", $3) + split($3, arr, "$") + sub(/^0*/, "", $1) + print "#define FIELD_SIZE_" assoc[arr[1]] "_" arr[2] " 0x" $1 "UL" + next +} + +/^0[0-9a-zA-Z]* C _*nestedfieldsize\$[_0-9a-zA-Z]*\$[_0-9a-zA-Z]*$/ { + sub(/_*nestedfieldsize\$/, "", $3) + split($3, arr, "$") + sub(/^0*/, "", $1) + print "#define FIELD_SIZE_" arr[1] "_" arr[2] " 0x" $1 "UL" + next +} + +/^0[0-9a-zA-Z]* C _*SIZEOF\$[0-9]*$/ { + sub(/_*SIZEOF\$/, "", $3) + sub(/^0*/, "", $1) + print "#define TYPE_SIZE_" assoc[$3] " 0x" $1 + next +} + +{ print "// " $0 } + +END { + ## some indirect offsets + print "#define OFFSET_StgHeader_prof_ccs (OFFSET_StgHeader_prof + OFFSET_StgProfHeader_ccs)" + print "#define OFFSET_StgHeader_prof_hp_ldvw (OFFSET_StgHeader_prof + OFFSET_StgProfHeader_hp + 0)" + print "#define OFFSET_StgTSO_prof_cccs (OFFSET_StgTSO_prof + OFFSET_StgTSOProfInfo_cccs)" + print "#define OFFSET_RTS_FLAGS_ProfFlags_showCCSOnException (OFFSET_RTS_FLAGS_ProfFlags + OFFSET_PROFILING_FLAGS_showCCSOnException)" + + + print "#define OFFSET_RTS_FLAGS_DebugFlags_apply (OFFSET_RTS_FLAGS_DebugFlags + OFFSET_DEBUG_FLAGS_apply)" + print "#define OFFSET_RTS_FLAGS_DebugFlags_sanity (OFFSET_RTS_FLAGS_DebugFlags + OFFSET_DEBUG_FLAGS_sanity)" + print "#define OFFSET_RTS_FLAGS_DebugFlags_weak (OFFSET_RTS_FLAGS_DebugFlags + OFFSET_DEBUG_FLAGS_weak)" + print "#define OFFSET_RTS_FLAGS_GcFlags_initialStkSize (OFFSET_RTS_FLAGS_GcFlags + OFFSET_GC_FLAGS_initialStkSize)" + print "#define OFFSET_RTS_FLAGS_MiscFlags_tickInterval (OFFSET_RTS_FLAGS_MiscFlags + OFFSET_MISC_FLAGS_tickInterval)" + + print "#define OFFSET_StgFunInfoExtraFwd_b_bitmap (OFFSET_StgFunInfoExtraFwd_b + 0)" + print "#define OFFSET_StgFunInfoExtraRev_b_bitmap (OFFSET_StgFunInfoExtraRev_b + 0)" + + ## some indirect field sizes + print "#define FIELD_SIZE_StgHeader_prof_ccs FIELD_SIZE_StgProfHeader_ccs" + print "#define FIELD_SIZE_StgTSO_prof_cccs FIELD_SIZE_StgTSOProfInfo_cccs" + print "#define FIELD_SIZE_RTS_FLAGS_ProfFlags_showCCSOnException FIELD_SIZE_PROFILING_FLAGS_showCCSOnException" + print "#define FIELD_SIZE_RTS_FLAGS_DebugFlags_apply FIELD_SIZE_DEBUG_FLAGS_apply" + print "#define FIELD_SIZE_RTS_FLAGS_DebugFlags_sanity FIELD_SIZE_DEBUG_FLAGS_sanity" + print "#define FIELD_SIZE_RTS_FLAGS_DebugFlags_weak FIELD_SIZE_DEBUG_FLAGS_weak" + print "#define FIELD_SIZE_RTS_FLAGS_GcFlags_initialStkSize FIELD_SIZE_GC_FLAGS_initialStkSize" + print "#define FIELD_SIZE_RTS_FLAGS_MiscFlags_tickInterval FIELD_SIZE_MISC_FLAGS_tickInterval" +} diff --git a/rules/cross-compiling.mk b/rules/cross-compiling.mk new file mode 100644 index 0000000000..9f9ec6f542 --- /dev/null +++ b/rules/cross-compiling.mk @@ -0,0 +1,24 @@ +# ----------------------------------------------------------------------------- +# +# (c) 2012 The University of Glasgow +# +# This file is part of the GHC build system. +# +# To understand how the build system works and how to modify it, see +# http://hackage.haskell.org/trac/ghc/wiki/Building/Architecture +# http://hackage.haskell.org/trac/ghc/wiki/Building/Modifying +# +# ----------------------------------------------------------------------------- + +define cross-compiling # $1 = then, $2 = else, $3 = then, ... +ifneq "$(TARGETPLATFORM)" "$(HOSTPLATFORM)" +ifneq "$(BUILDPLATFORM)" "$(HOSTPLATFORM)" +$(warning When cross-compiling, the build and host platforms must be equal (--build=$(BUILDPLATFORM) --host=$(HOSTPLATFORM) --target=$(TARGETPLATFORM))) +endif +$1 +$3 +else +$2 +$4 +endif +endef |