diff: detect linking with inconsistent grades

Fergus Henderson fjh at cs.mu.oz.au
Thu Oct 2 04:49:15 AEST 1997


I just got bitten by linking files that were compiled with incompatible
options, so I decided it must be time to fix that...

Can someone please review this change?

--------------------

Ensure that you get a link error if you attempt to link files
compiled with different grades.

runtime/mercury_grade.h:
	Define a macro MR_GRADE_VAR, which is set to MR_grade_<gr>,
	where <gr> is one of asm_fast, asm_fast_gc_prof_tr, etc.
	Declare MR_GRADE_VAR as a variable.

runtime/mercury_grade.c:
	Define the MR_GRADE_VAR variable.

compiler/llds_out.m:
	Include a reference to MR_GRADE_VAR in the generated C file.
	This ensures that when the file is compiled,
	the object file will contain a reference to MR_grade_<gr>.

cvs diff -N compiler/llds_out.m runtime/mercury_grade.c runtime/mercury_grade.h scripts/mgnuc.in
Index: compiler/llds_out.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/llds_out.m,v
retrieving revision 1.57
diff -u -r1.57 llds_out.m
--- llds_out.m	1997/09/26 07:43:38	1.57
+++ llds_out.m	1997/10/01 16:05:18
@@ -143,8 +143,8 @@
 		{ library__version(Version) },
 		io__write_strings(
 			["/*\n** Automatically generated from `", BaseName,
-			".m' by the\n** Mercury compiler, version ", Version,
-			".  Do not edit.\n*/\n"]),
+			".m' by the Mercury compiler,\n** version ", Version,
+			".\n** Do not edit.\n*/\n"]),
 		io__write_string("/*\n"),
 		io__write_string("INIT "),
 		output_init_name(BaseName),
@@ -152,6 +152,7 @@
 		io__write_string("ENDINIT\n"),
 		io__write_string("*/\n\n"),
 		io__write_string("#include ""imp.h""\n"),
+		io__write_string("\n"),
 		output_c_module_init_list(BaseName, Modules),
 		io__told
 	;
@@ -182,8 +183,8 @@
 		{ library__version(Version) },
 		io__write_strings(
 			["/*\n** Automatically generated from `", BaseName,
-			".m' by the\n** Mercury compiler, version ", Version,
-			".  Do not edit.\n*/\n"]),
+			".m' by the Mercury compiler,\n** version ", Version,
+			".\n** Do not edit.\n*/\n"]),
 		( { SplitFiles = yes(_) } ->
 			[]
 		;
@@ -259,7 +260,12 @@
 	io__write_string("\t}\n"),
 	io__write_string("#endif\n"),
 	output_c_data_init_list(Modules),
-	io__write_string("}\n").
+	io__write_string("}\n"),
+	io__write_string("\n"),
+	io__write_string(
+		"/* ensure everything is compiled with the same grade */\n"),
+	io__write_string(
+		"static const void *const MR_grade = &MR_GRADE_VAR;\n").
 
 :- pred output_c_module_init_list_2(list(c_module), string, int, int, int, int,
 	io__state, io__state).
Index: runtime/mercury_grade.c
===================================================================
RCS file: mercury_grade.c
diff -N mercury_grade.c
--- /dev/null	Thu Oct  2 03:51:12 1997
+++ mercury_grade.c	Thu Oct  2 01:23:01 1997
@@ -0,0 +1,15 @@
+/*
+** Copyright (C) 1997 The University of Melbourne.
+** This file may only be copied under the terms of the GNU Library General
+** Public License - see the file COPYING.LIB in the Mercury distribution.
+*/
+#include "imp.h"
+#include "mercury_grade.h"
+
+/*
+** Define MR_grade_<gr>, where <gr> is the grade that this file is compiled in.
+** Every generated .c file includes a reference to this constant;
+** if any such file was compiled with a different grade than this file,
+** then it will have an unresolved reference which will cause a link error.
+*/
+const char MR_GRADE_VAR = 0;
Index: runtime/mercury_grade.h
===================================================================
RCS file: mercury_grade.h
diff -N mercury_grade.h
--- /dev/null	Thu Oct  2 03:51:12 1997
+++ mercury_grade.h	Thu Oct  2 03:07:32 1997
@@ -0,0 +1,140 @@
+/*
+** Copyright (C) 1997 The University of Melbourne.
+** This file may only be copied under the terms of the GNU Library General
+** Public License - see the file COPYING.LIB in the Mercury distribution.
+*/
+
+/*
+** mercury_grades.h - defines the MR_GRADE macro.
+**
+** This is used to get the linker to ensure that different object files
+** were compiled with consistent grades.
+**
+** Any condition compilation macros that affect link compatibility
+** should be included here.
+*/
+
+#ifndef MERCURY_GRADES_H
+#define MERCURY_GRADES_H
+
+/* convert a macro to a string */
+#define MR_STRINGIFY(x)		MR_STRINGIFY_2(x)
+#define MR_STRINGIFY_2(x)	#x
+
+/* paste two macros together */
+#define MR_PASTE2(p1,p2)	MR_PASTE2_2(p1,p2)
+#define MR_PASTE2_2(p1,p2)	p1##p2
+
+/* paste 9 macros together */
+#define MR_PASTE10(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10) \
+				MR_PASTE8_2(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10)
+#define MR_PASTE10_2(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10) \
+				p1##p2##p3##p4##p5##p6##p7##p8##p9##p10
+
+/*
+** Here we build up the MR_GRADE macro part at a time,
+** based on the compilation flags.
+**
+** IMPORTANT: any changes here will probably require similar
+** changes to compiler/handle_options.m and scripts/mgnuc.in.
+*/
+
+#ifdef USE_ASM_LABELS
+  #define MR_GRADE_PART_1	asm_
+#else
+  #define MR_GRADE_PART_1
+#endif
+
+#ifdef USE_GCC_NONLOCAL_GOTOS
+  #ifdef USE_GCC_GLOBAL_REGISTERS
+    #define MR_GRADE_PART_2	fast
+  #else
+    #define MR_GRADE_PART_2	jump
+  #endif
+#else
+  #ifdef USE_GCC_GLOBAL_REGS
+    #define MR_GRADE_PART_2	reg
+  #else
+    #define MR_GRADE_PART_2	none
+  #endif
+#endif
+
+#ifdef CONSERVATIVE_GC
+  #define MR_GRADE_PART_3	_gc
+#elif defined(NATIVE_GC)
+  #define MR_GRADE_PART_3	_agc
+#else
+  #define MR_GRADE_PART_3
+#endif
+
+#ifdef PROFILE_TIME
+  #ifdef PROFILE_CALLS
+    #define MR_GRADE_PART_4	_prof
+  #else
+    #define MR_GRADE_PART_4	_proftime
+  #endif
+#else
+  #ifdef PROFILE_CALLS
+    #define MR_GRADE_PART_4	_profcalls
+  #else
+    #define MR_GRADE_PART_4
+  #endif
+#endif
+
+#ifdef MR_USE_TRAIL
+  #define MR_GRADE_PART_5	_tr
+#else
+  #define MR_GRADE_PART_5
+#endif
+
+#if TAGBITS == 0
+  #define MR_GRADE_PART_6	_notags
+#elif defined(HIGHTAGS)
+  #define MR_GRADE_PART_6	MR_PASTE2(_hightags, TAGBITS)
+#else
+  #define MR_GRADE_PART_6	MR_PASTE2(_tags, TAGBITS)
+#endif
+
+#ifdef BOXED_FLOAT
+  #define MR_GRADE_PART_7
+#else				/* "ubf" stands for "unboxed float" */
+  #define MR_GRADE_PART_7	_ubf
+#endif
+
+#ifdef COMPACT_ARGS
+  #define MR_GRADE_PART_8	
+#else				/* "sa" stands for "simple args" */
+  #define MR_GRADE_PART_8	_sa
+#endif
+
+#ifdef SPEED
+  #define MR_GRADE_PART_9
+#else
+  #define MR_GRADE_PART_9	_debug
+#endif
+
+#ifdef PIC_REG
+  #define MR_GRADE_PART_10	_picreg
+#else
+  #define MR_GRADE_PART_10
+#endif
+
+#define MR_GRADE		MR_PASTE10(			\
+					MR_GRADE_PART_1,	\
+					MR_GRADE_PART_2,	\
+					MR_GRADE_PART_3,	\
+					MR_GRADE_PART_4,	\
+					MR_GRADE_PART_5,	\
+					MR_GRADE_PART_6,	\
+					MR_GRADE_PART_7,	\
+					MR_GRADE_PART_8,	\
+					MR_GRADE_PART_9,	\
+					MR_GRADE_PART_10	\
+				)
+
+#define MR_GRADE_VAR		MR_PASTE2(MR_grade_,MR_GRADE)
+#define MR_GRADE_STRING 	MR_STRINGIFY(MR_GRADE)
+
+extern const char MR_GRADE_VAR;
+
+#endif /* MERCURY_GRADES_H */

-- 
Fergus Henderson <fjh at cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3         |     -- the last words of T. S. Garp.



More information about the developers mailing list