summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ghc/ghc-cross.wrapper1
-rw-r--r--includes/mkDerivedConstants.cross.awk350
-rw-r--r--includes/mkSizeMacros.cross.awk82
-rw-r--r--rules/cross-compiling.mk24
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