Permalink
Browse files

First batch of file additions for cross-compiler:

	new file:   ghc/ghc-cross.wrapper
	new file:   includes/mkDerivedConstants.cross.awk
	new file:   includes/mkSizeMacros.cross.awk
	new file:   rules/cross-compiling.mk

These are expected to sit quietly in the tree until
the rest of the machinery matures on an (upcoming)
branch. Reviews will begin to make sense as soon as
that has happened. Anyway, comments are welcome. See
<http://www.haskell.org/pipermail/cvs-ghc/2012-July/074456.html>
for background.

Disclaimer: these source files are not (yet) up to the
            quality standards set by the rest of the tree.

Cleanups, move-arounds and rewrites (i.e. .awk -> .hs), as
well as additional comments and documentation will happen
as soon as the basic functionality of a cross-compiler is
working reliably.
  • Loading branch information...
1 parent 9417612 commit 6ae696a1d1f25bf52923a3dd1c3b4a08e2033bfd @ggreif ggreif committed Jul 18, 2012
Showing with 457 additions and 0 deletions.
  1. +1 −0 ghc/ghc-cross.wrapper
  2. +350 −0 includes/mkDerivedConstants.cross.awk
  3. +82 −0 includes/mkSizeMacros.cross.awk
  4. +24 −0 rules/cross-compiling.mk
@@ -0,0 +1 @@
+exec "$executablename" -B"$topdir" ${1+"$@"} -pgma "$pgmgcc" -pgmc "$pgmgcc" -pgml "$pgmgcc"
@@ -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
+}
Oops, something went wrong.

0 comments on commit 6ae696a

Please sign in to comment.