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