diff --git a/src/ar65/objfile.c b/src/ar65/objfile.c
index 1f5bd8abe..6fb40f9af 100644
--- a/src/ar65/objfile.c
+++ b/src/ar65/objfile.c
@@ -286,6 +286,3 @@ void ObjExtract (const char* Name)
 
 
 
-
-
-
diff --git a/src/ca65/dbginfo.c b/src/ca65/dbginfo.c
index 33362aca3..90b25c218 100644
--- a/src/ca65/dbginfo.c
+++ b/src/ca65/dbginfo.c
@@ -33,6 +33,8 @@
 
 
 
+#include <string.h>
+
 /* ca65 */
 #include "error.h"
 #include "expr.h"
diff --git a/src/ca65/expr.c b/src/ca65/expr.c
index 4ada4317a..3e09dee13 100644
--- a/src/ca65/expr.c
+++ b/src/ca65/expr.c
@@ -33,6 +33,8 @@
 
 
 
+#include <string.h>
+
 /* common */
 #include "check.h"
 #include "exprdefs.h"
diff --git a/src/ca65/filetab.c b/src/ca65/filetab.c
index 8448d44df..4e1d28c44 100644
--- a/src/ca65/filetab.c
+++ b/src/ca65/filetab.c
@@ -33,6 +33,8 @@
 
 
 
+#include <string.h>
+
 /* common */
 #include "check.h"
 #include "hashstr.h"
diff --git a/src/ca65/nexttok.c b/src/ca65/nexttok.c
index f460cdc91..5de8b9cb6 100644
--- a/src/ca65/nexttok.c
+++ b/src/ca65/nexttok.c
@@ -34,10 +34,11 @@
 
 
 #include <stdio.h>
+#include <string.h>
 
 /* common */
 #include "check.h"
-		   
+
 /* ca65 */
 #include "error.h"
 #include "expr.h"
diff --git a/src/ca65/options.c b/src/ca65/options.c
index ed1bd2405..31e37421e 100644
--- a/src/ca65/options.c
+++ b/src/ca65/options.c
@@ -33,6 +33,8 @@
 
 
 
+#include <string.h>
+
 /* common */
 #include "optdefs.h"
 #include "xmalloc.h"
diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c
index 9373ec01b..cbc23b721 100644
--- a/src/ca65/pseudo.c
+++ b/src/ca65/pseudo.c
@@ -41,6 +41,7 @@
 
 /* common */
 #include "bitops.h"
+#include "cddefs.h"
 #include "check.h"
 #include "symdefs.h"
 #include "tgttrans.h"
@@ -173,6 +174,32 @@ static long IntArg (long Min, long Max)
 
 
 
+static void ConDes (const char* Name, unsigned Type)
+/* Parse remaining line for constructor/destructor of the remaining type */
+{
+    long Prio;
+
+    /* Optional constructor priority */
+    if (Tok == TOK_COMMA) {
+    	/* Priority value follows */
+    	NextTok ();
+    	Prio = ConstExpression ();
+    	if (Prio < CD_PRIO_MIN || Prio > CD_PRIO_MAX) {
+    	    /* Value out of range */
+    	    Error (ERR_RANGE);
+    	    return;
+    	}
+    } else {
+    	/* Use the default priority value */
+    	Prio = CD_PRIO_DEF;
+    }
+
+    /* Define the symbol */
+    SymConDes (Name, Type, (unsigned) Prio);
+}
+
+
+
 /*****************************************************************************/
 /*	      	    	       Handler functions			     */
 /*****************************************************************************/
@@ -320,7 +347,7 @@ static void DoByte (void)
 	    NextTok ();
 	    /* Do smart handling of dangling comma */
 	    if (Tok == TOK_SEP) {
-		Error (ERR_UNEXPECTED_EOL);
+	     	Error (ERR_UNEXPECTED_EOL);
 	 	break;
 	    }
 	}
@@ -346,6 +373,76 @@ static void DoCode (void)
 
 
 
+static void DoConDes (void)
+/* Export a symbol as constructor/destructor */
+{
+    static const char* Keys[] = {
+       	"CONSTRUCTOR",
+	"DESTRUCTOR",
+    };
+    char Name [sizeof (SVal)];
+    long Type;
+
+    /* Symbol name follows */
+    if (Tok != TOK_IDENT) {
+    	ErrorSkip (ERR_IDENT_EXPECTED);
+    	return;
+    }
+    strcpy (Name, SVal);
+    NextTok ();
+
+    /* Type follows. May be encoded as identifier or numerical */
+    ConsumeComma ();
+    if (Tok == TOK_IDENT) {
+
+	/* Map the following keyword to a number, then skip it */
+	Type = GetSubKey (Keys, sizeof (Keys) / sizeof (Keys [0]));
+	NextTok ();
+
+	/* Check if we got a valid keyword */
+	if (Type < 0) {
+	    Error (ERR_SYNTAX);
+	    SkipUntilSep ();
+	    return;
+	}
+
+    } else {
+
+	/* Read the type as numerical value */
+       	Type = ConstExpression ();
+    	if (Type < CD_TYPE_MIN || Type > CD_TYPE_MAX) {
+    	    /* Value out of range */
+    	    Error (ERR_RANGE);
+    	    return;
+    	}
+
+    }
+
+    /* Parse the remainder of the line and export the symbol */
+    ConDes (Name, (unsigned) Type);
+}
+
+
+
+static void DoConstructor (void)
+/* Export a symbol as constructor */
+{
+    char Name [sizeof (SVal)];
+
+    /* Symbol name follows */
+    if (Tok != TOK_IDENT) {
+    	ErrorSkip (ERR_IDENT_EXPECTED);
+    	return;
+    }
+    strcpy (Name, SVal);
+    NextTok ();
+
+    /* Parse the remainder of the line and export the symbol */
+    ConDes (Name, CD_TYPE_CON);
+}
+
+
+
 static void DoData (void)
 /* Switch to the data segment */
 {
@@ -422,6 +519,25 @@ static void DoDefine (void)
 
 
 
+static void DoDestructor (void)
+/* Export a symbol as destructor */
+{
+    char Name [sizeof (SVal)];
+
+    /* Symbol name follows */
+    if (Tok != TOK_IDENT) {
+    	ErrorSkip (ERR_IDENT_EXPECTED);
+    	return;
+    }
+    strcpy (Name, SVal);
+    NextTok ();
+
+    /* Parse the remainder of the line and export the symbol */
+    ConDes (Name, CD_TYPE_DES);
+}
+
+
+
 static void DoDWord (void)
 /* Define dwords */
 {
@@ -736,41 +852,6 @@ static void DoInclude (void)
 
 
 
-static void DoInitializer (void)
-/* Export a symbol as initializer */
-{
-    char Name [sizeof (SVal)];
-    long Val;
-
-    /* Symbol name follows */
-    if (Tok != TOK_IDENT) {
-    	ErrorSkip (ERR_IDENT_EXPECTED);
-    	return;
-    }
-    strcpy (Name, SVal);
-    NextTok ();
-
-    /* Optional initializer value */
-    if (Tok == TOK_COMMA) {
-    	/* Initializer value follows */
-    	NextTok ();
-    	Val = ConstExpression ();
-    	if (Val < EXP_INIT_MIN || Val > EXP_INIT_MAX) {
-    	    /* Value out of range */
-    	    Error (ERR_RANGE);
-    	    return;
-    	}
-    } else {
-    	/* Use the default initializer value */
-    	Val = EXP_INIT_DEF;
-    }
-
-    /* Define the symbol */
-    SymInitializer (Name, (unsigned) Val);
-}
-
-
-
 static void DoInvalid (void)
 /* Handle a token that is invalid here, since it should have been handled on
  * a much lower level of the expression hierarchy. Getting this sort of token
@@ -1171,7 +1252,9 @@ static CtrlDesc CtrlCmdTab [] = {
     { ccNone,       	DoCase		},
     { ccNone,		DoCode		},
     { ccNone,		DoUnexpected,	},	/* .CONCAT */
+    { ccNone,		DoConDes	},
     { ccNone,		DoUnexpected	},	/* .CONST */
+    { ccNone,		DoConstructor	},
     { ccNone,		DoUnexpected	},	/* .CPU */
     { ccNone,		DoData		},
     { ccNone,		DoDbg,		},
@@ -1179,6 +1262,7 @@ static CtrlDesc CtrlCmdTab [] = {
     { ccNone,        	DoDebugInfo	},
     { ccNone,		DoDefine	},
     { ccNone,		DoUnexpected	},	/* .DEFINED */
+    { ccNone,		DoDestructor	},
     { ccNone,		DoDWord		},
     { ccKeepToken,	DoConditionals	},	/* .ELSE */
     { ccKeepToken,	DoConditionals	},	/* .ELSEIF */
@@ -1215,7 +1299,6 @@ static CtrlDesc CtrlCmdTab [] = {
     { ccNone,		DoImportZP	},
     { ccNone,		DoIncBin	},
     { ccNone,      	DoInclude	},
-    { ccNone,		DoInitializer	},
     { ccNone,		DoInvalid	},	/* .LEFT */
     { ccNone,		DoLineCont	},
     { ccNone,		DoList		},
diff --git a/src/ca65/repeat.c b/src/ca65/repeat.c
index b442c165f..d2a0de67a 100644
--- a/src/ca65/repeat.c
+++ b/src/ca65/repeat.c
@@ -33,6 +33,8 @@
 
 
 
+#include <string.h>
+
 /* common */
 #include "xmalloc.h"
 
@@ -106,7 +108,7 @@ static void RepeatTokenCheck (TokList* L)
 /* Called each time a token from a repeat token list is set. Is used to check
  * for and replace identifiers that are the repeat counter.
  */
-{		  
+{
     if (Tok == TOK_IDENT && L->Data != 0 && strcmp (SVal, L->Data) == 0) {
  	/* Must replace by the repeat counter */
  	Tok  = TOK_INTCON;
diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c
index b14a974d6..7fb2fe97c 100644
--- a/src/ca65/scanner.c
+++ b/src/ca65/scanner.c
@@ -133,7 +133,9 @@ struct DotKeyword {
     { "CASE",  	    	TOK_CASE	},
     { "CODE", 	    	TOK_CODE    	},
     { "CONCAT",	  	TOK_CONCAT	},
+    { "CONDES",		TOK_CONDES	},
     { "CONST", 	    	TOK_CONST	},
+    { "CONSTRUCTOR",	TOK_CONSTRUCTOR	},
     { "CPU", 	  	TOK_CPU		},
     { "DATA",  	  	TOK_DATA	},
     { "DBG",		TOK_DBG		},
@@ -142,6 +144,7 @@ struct DotKeyword {
     { "DEF",   		TOK_DEFINED	},
     { "DEFINE",	    	TOK_DEFINE	},
     { "DEFINED",	TOK_DEFINED	},
+    { "DESTRUCTOR",	TOK_DESTRUCTOR	},
     { "DWORD", 		TOK_DWORD	},
     { "ELSE",  		TOK_ELSE	},
     { "ELSEIF",		TOK_ELSEIF	},
@@ -182,7 +185,6 @@ struct DotKeyword {
     { "IMPORTZP",	TOK_IMPORTZP	},
     { "INCBIN",		TOK_INCBIN	},
     { "INCLUDE",    	TOK_INCLUDE 	},
-    { "INITIALIZER",	TOK_INITIALIZER },
     { "LEFT",		TOK_LEFT	},
     { "LINECONT",	TOK_LINECONT	},
     { "LIST",		TOK_LIST	},
diff --git a/src/ca65/scanner.h b/src/ca65/scanner.h
index 0849eb529..f6fddc588 100644
--- a/src/ca65/scanner.h
+++ b/src/ca65/scanner.h
@@ -120,8 +120,10 @@ enum Token {
     TOK_BYTE,
     TOK_CASE,
     TOK_CODE,
-    TOK_CONCAT,
+    TOK_CONCAT,	    
+    TOK_CONDES,
     TOK_CONST,
+    TOK_CONSTRUCTOR,
     TOK_CPU,
     TOK_DATA,
     TOK_DBG,
@@ -129,6 +131,7 @@ enum Token {
     TOK_DEBUGINFO,
     TOK_DEFINE,
     TOK_DEFINED,
+    TOK_DESTRUCTOR,
     TOK_DWORD,
     TOK_ELSE,
     TOK_ELSEIF,
@@ -165,7 +168,6 @@ enum Token {
     TOK_IMPORTZP,
     TOK_INCBIN,
     TOK_INCLUDE,
-    TOK_INITIALIZER,
     TOK_LEFT,
     TOK_LINECONT,
     TOK_LIST,
diff --git a/src/ca65/symtab.c b/src/ca65/symtab.c
index 8c2af8671..76055f927 100644
--- a/src/ca65/symtab.c
+++ b/src/ca65/symtab.c
@@ -36,6 +36,7 @@
 #include <string.h>
 
 /* common */
+#include "cddefs.h"
 #include "check.h"
 #include "hashstr.h"
 #include "symdefs.h"
@@ -63,9 +64,8 @@
 #define SF_EXPORT      	0x0004		/* Export this symbol */
 #define SF_IMPORT   	0x0008		/* Import this symbol */
 #define SF_GLOBAL	0x0010		/* Global symbol */
-#define SF_INITIALIZER	0x0020		/* Exported initializer */
-#define SF_ZP  	       	0x0040		/* Declared as zeropage symbol */
-#define SF_ABS		0x0080 		/* Declared as absolute symbol */
+#define SF_ZP  	       	0x0020		/* Declared as zeropage symbol */
+#define SF_ABS		0x0040 		/* Declared as absolute symbol */
 #define SF_INDEXED	0x0800		/* Index is valid */
 #define SF_CONST    	0x1000		/* The symbol has a constant value */
 #define SF_MULTDEF     	0x2000		/* Multiply defined symbol */
@@ -97,15 +97,16 @@ struct SymEntry {
 	long	    	    Val;  	/* Value (if CONST set) */
 	SymEntry*  	    Sym;	/* Symbol (if trampoline entry) */
     } V;
-    unsigned char  	    InitVal;	/* Initializer value */
+    unsigned char      	    ConDesPrio[CD_TYPE_COUNT];	/* ConDes priorities... */
+					/* ...actually value+1 (used as flag) */
     char       	       	    Name [1];	/* Dynamic allocation */
 };
 
 
 
 /* Definitions for the hash table */
-#define MAIN_HASHTAB_SIZE   	213
-#define SUB_HASHTAB_SIZE    	53
+#define MAIN_HASHTAB_SIZE    	213
+#define SUB_HASHTAB_SIZE     	53
 typedef struct SymTable SymTable;
 struct SymTable {
     unsigned   	     	TableSlots;	/* Number of hash table slots */
@@ -140,7 +141,7 @@ static unsigned     	ExportCount = 0;/* Counter for export symbols */
 
 static int IsLocal (const char* Name)
 /* Return true if Name is the name of a local symbol */
-{	       
+{
     return (*Name == LocalStart);
 }
 
@@ -166,7 +167,7 @@ static SymEntry* NewSymEntry (const char* Name)
     S->Pos	= CurPos;
     S->Flags	= 0;
     S->V.Expr	= 0;
-    S->InitVal	= 0;
+    memset (S->ConDesPrio, 0, sizeof (S->ConDesPrio));
     memcpy (S->Name, Name, Len+1);
 
     /* Insert it into the list of all entries */
@@ -579,15 +580,16 @@ void SymGlobal (const char* Name, int ZP)
 
 
 
-void SymInitializer (const char* Name, unsigned InitVal)
-/* Mark the given symbol as an initializer. This will also mark the symbol as
- * an export. Initializers may never be zero page symbols.
+void SymConDes (const char* Name, unsigned Type, unsigned Prio)
+/* Mark the given symbol as a module constructor/destructor. This will also
+ * mark the symbol as an export. Initializers may never be zero page symbols.
  */
 {
     SymEntry* S;
 
-    /* Check the InitVal parameter */
-    CHECK (InitVal >= EXP_INIT_MIN && InitVal <= EXP_INIT_MAX);
+    /* Check the parameters */
+    CHECK (Type >= CD_TYPE_MIN && Type <= CD_TYPE_MAX);
+    CHECK (Prio >= CD_PRIO_MIN && Prio <= CD_PRIO_MAX);
 
     /* Don't accept local symbols */
     if (IsLocal (Name)) {
@@ -613,18 +615,18 @@ void SymInitializer (const char* Name, unsigned InitVal)
 	Error (ERR_SYM_REDECL_MISMATCH);
     }
 
-    /* If the symbol was already declared as an initializer, check if the new
-     * initializer value is the same as the old one.
+    /* If the symbol was already declared as a condes, check if the new
+     * priority value is the same as the old one.
      */
-    if (S->Flags & SF_INITIALIZER) {
-	if (S->InitVal != InitVal) {
+    if (S->ConDesPrio[Type] != CD_PRIO_NONE) {
+	if (S->ConDesPrio[Type] != Prio) {
 	    Error (ERR_SYM_REDECL_MISMATCH);
 	}
     }
-    S->InitVal = InitVal;
+    S->ConDesPrio[Type] = Prio;
 
     /* Set the symbol data */
-    S->Flags |= SF_EXPORT | SF_INITIALIZER | SF_REFERENCED;
+    S->Flags |= SF_EXPORT | SF_REFERENCED;
 }
 
 
@@ -1064,6 +1066,7 @@ void WriteExports (void)
 /* Write the exports list to the object file */
 {
     SymEntry* S;
+    unsigned Type;
 
     /* Tell the object file module that we're about to start the exports */
     ObjStartExports ();
@@ -1086,14 +1089,26 @@ void WriteExports (void)
 	    /* Add zeropage/abs bits */
 	    ExprMask |= (S->Flags & SF_ZP)? EXP_ZP : EXP_ABS;
 
-	    /* Add the initializer bits */
-	    if (S->Flags & SF_INITIALIZER) {
-	     	ExprMask |= S->InitVal;
+	    /* Count the number of ConDes types */
+	    for (Type = 0; Type < CD_TYPE_COUNT; ++Type) {
+	    	if (S->ConDesPrio[Type] != CD_PRIO_NONE) {
+	    	    INC_EXP_CONDES_COUNT (ExprMask);
+	    	}
 	    }
 
 	    /* Write the type */
 	    ObjWrite8 (ExprMask);
 
+	    /* Write any ConDes declarations */
+	    if (GET_EXP_CONDES_COUNT (ExprMask) > 0) {
+		for (Type = 0; Type < CD_TYPE_COUNT; ++Type) {
+		    unsigned char Prio = S->ConDesPrio[Type];
+		    if (Prio != CD_PRIO_NONE) {
+			ObjWrite8 (CD_BUILD (Type, Prio));
+		    }
+		}
+	    }
+
 	    /* Write the name */
        	    ObjWriteStr (S->Name);
 
@@ -1158,11 +1173,6 @@ void WriteDbgSyms (void)
 		/* Add zeropage/abs bits */
 		ExprMask |= (S->Flags & SF_ZP)? EXP_ZP : EXP_ABS;
 
-		/* Add the initializer bits */
-		if (S->Flags & SF_INITIALIZER) {
-		    ExprMask |= S->InitVal;
-		}
-
 		/* Write the type */
 		ObjWrite8 (ExprMask);
 
diff --git a/src/ca65/symtab.h b/src/ca65/symtab.h
index 959bc3a0c..f25b2e09e 100644
--- a/src/ca65/symtab.h
+++ b/src/ca65/symtab.h
@@ -86,9 +86,9 @@ void SymGlobal (const char* Name, int ZP);
  * either imported or exported.
  */
 
-void SymInitializer (const char* Name, unsigned InitVal);
-/* Mark the given symbol as an initializer. This will also mark the symbol as
- * an export. Initializers may never be zero page symbols.
+void SymConDes (const char* Name, unsigned Type, unsigned Prio);
+/* Mark the given symbol as a module constructor/destructor. This will also
+ * mark the symbol as an export. Initializers may never be zero page symbols.
  */
 
 int SymIsConst (SymEntry* Sym);
diff --git a/src/cc65/asmline.c b/src/cc65/asmline.c
index db8c16812..7303a82e3 100644
--- a/src/cc65/asmline.c
+++ b/src/cc65/asmline.c
@@ -34,10 +34,13 @@
 
 
 #include <stdio.h>
-
-#include "../common/xmalloc.h"
-#include "../common/xsprintf.h"
-
+#include <string.h>
+	  
+/* common */
+#include "xmalloc.h"
+#include "xsprintf.h"
+	  
+/* cc65 */
 #include "error.h"
 #include "asmline.h"
 
diff --git a/src/cc65/declattr.c b/src/cc65/declattr.c
index b06c36aed..9dbc71095 100644
--- a/src/cc65/declattr.c
+++ b/src/cc65/declattr.c
@@ -33,6 +33,8 @@
 
 
 
+#include <string.h>
+
 /* cc65 */
 #include "error.h"
 #include "scanner.h"
@@ -125,7 +127,7 @@ void ParseAttribute (const Declaration* D, DeclAttr* A)
 /* Parse an additional __attribute__ modifier */
 {
     ident    AttrName;
-    attrib_t AttrType;		     
+    attrib_t AttrType;
 
     /* Initialize the attribute description with "no attribute" */
     A->AttrType = atNone;
diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c
index f4020cf3b..c68009c02 100644
--- a/src/cc65/pragma.c
+++ b/src/cc65/pragma.c
@@ -34,8 +34,10 @@
 
 
 #include <stdlib.h>
+#include <string.h>
 #include <ctype.h>
-
+		   
+/* cc65 */
 #include "codegen.h"
 #include "error.h"
 #include "expr.h"
diff --git a/src/cc65/symentry.c b/src/cc65/symentry.c
index 03223fc97..35ed800b4 100644
--- a/src/cc65/symentry.c
+++ b/src/cc65/symentry.c
@@ -33,8 +33,12 @@
 
 
 
-#include "../common/xmalloc.h"
-
+#include <string.h>
+		   
+/* common */
+#include "xmalloc.h"
+	  
+/* cc65 */
 #include "symentry.h"
 
 
@@ -43,7 +47,7 @@
 /*	       	  	  	     Code				     */
 /*****************************************************************************/
 
-
+	  
 
 SymEntry* NewSymEntry (const char* Name, unsigned Flags)
 /* Create a new symbol table with the given name */
diff --git a/src/ld65/initfunc.c b/src/common/cddefs.h
similarity index 60%
rename from src/ld65/initfunc.c
rename to src/common/cddefs.h
index 60ea52805..5d8717931 100644
--- a/src/ld65/initfunc.c
+++ b/src/common/cddefs.h
@@ -1,15 +1,15 @@
 /*****************************************************************************/
 /*                                                                           */
-/*				  initfunc.c				     */
+/*				   cddefs.h				     */
 /*                                                                           */
-/*			Init/cleanup function handling			     */
+/*	       	Definitions for module constructor/destructors		     */
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2000      Ullrich von Bassewitz                                       */
-/*               Wacholderweg 14                                             */
-/*               D-70597 Stuttgart                                           */
-/* EMail:        uz@musoftware.de                                            */
+/* (C) 2000     Ullrich von Bassewitz                                        */
+/*              Wacholderweg 14                                              */
+/*              D-70597 Stuttgart                                            */
+/* EMail:       uz@musoftware.de                                             */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -33,47 +33,48 @@
 
 
 
-/* common */
-#include "coll.h"
-
-/* ld65 */
-#include "exports.h"
-#include "segments.h"
-#include "initfunc.h"
+#ifndef CDDEFS_H
+#define CDDEFS_H
 
 
 
 /*****************************************************************************/
-/*		 		     Data				     */
+/*     	       	    		     Data				     */
 /*****************************************************************************/
 
 
 
-/* List of all exports that are also initializers/cleanup functions */
-static Collection   InitFunctions	= STATIC_COLLECTION_INITIALIZER;
-static Collection   CleanupFunctions	= STATIC_COLLECTION_INITIALIZER;
+/* ConDes types. Count is only 7 because we want to encode 0..count in 3 bits */
+#define	CD_TYPE_COUNT  	7		/* Number of table types */
+#define CD_TYPE_MIN    	0		/* Minimum numeric type value */
+#define CD_TYPE_MAX    	6		/* Maximum numeric type value */
+
+/* ConDes priorities, zero is no valid priority and used to mark an empty
+ * (missing) decl for this type throughout the code.
+ */
+#define CD_PRIO_NONE	0		/* No priority (no decl) */
+#define CD_PRIO_MIN    	1		/* Lowest priority */
+#define CD_PRIO_DEF	7		/* Default priority */
+#define CD_PRIO_MAX	32		/* Highest priority */
+
+/* Predefined types */
+#define CD_TYPE_CON	0 		/* Constructor */
+#define CD_TYPE_DES	1		/* Destructor */
+
+/* When part of an export in an object file, type and priority are encoded in
+ * one byte. In this case, the following macros access the fields:
+ */
+#define CD_GET_TYPE(v) 	       	(((v) >> 5) & 0x07)
+#define CD_GET_PRIO(v)	       	(((v) & 0x1F) + 1)
+
+/* Macro to build the byte value: */
+#define CD_BUILD(type,prio)    	((((type) & 0x07) << 5) | (((prio) - 1) & 0x1F))
 
 
 
-/*****************************************************************************/
-/*     	       	     	   	     Code  	      	  	  	     */
-/*****************************************************************************/
-
-
-
-void AddInitFunc (Export* E)
-/* Add the given export to the list of initializers */
-{
-    CollAppend (&InitFunctions, E);
-}
-
-
-
-void AddCleanupFunc (Export* E)
-/* Add the given export to the list of cleanup functions */
-{
-    CollAppend (&CleanupFunctions, E);
-}
+/* End of cddefs.h */
+
+#endif
 
 
 
diff --git a/src/common/coll.c b/src/common/coll.c
index 8ce56a8c7..d6929f707 100644
--- a/src/common/coll.c
+++ b/src/common/coll.c
@@ -225,14 +225,64 @@ void CollReplace (Collection* C, void* Item, unsigned Index)
 
 
 
-void CollSort (Collection* C, int (*Compare) (const void*, const void*))
-/* Sort the collection using the given compare function.
- * BEWARE: The function uses qsort internally, so the Compare function does
- * actually get pointers to the object pointers, not just object pointers!
- */
+static void QuickSort (Collection* C, int Lo, int Hi,
+	               int (*Compare) (void*, const void*, const void*),
+		       void* Data)
+/* Internal recursive sort function. */
 {
-    /* Use qsort */
-    qsort (C->Items, C->Count, sizeof (void*), Compare);
+    /* Get a pointer to the items */
+    void** Items = C->Items;
+
+    /* Quicksort */
+    while (Hi > Lo) {
+   	int I = Lo + 1;
+   	int J = Hi;
+   	while (I <= J) {
+   	    while (I <= J && Compare (Data, Items[Lo], Items[I]) >= 0) {
+   	     	++I;
+   	    }
+   	    while (I <= J && Compare (Data, Items[Lo], Items[J]) < 0) {
+   	     	--J;
+   	    }
+   	    if (I <= J) {
+		/* Swap I and J */
+		void* Tmp = Items[I];
+		Items[I]  = Items[J];
+		Items[J]  = Tmp;
+   	     	++I;
+   	     	--J;
+   	    }
+      	}
+   	if (J != Lo) {
+	    /* Swap J and Lo */
+	    void* Tmp = Items[J];
+	    Items[J]  = Items[Lo];
+	    Items[Lo] = Tmp;
+   	}
+	if (J > (Hi + Lo) / 2) {
+	    QuickSort (C, J + 1, Hi, Compare, Data);
+	    Hi = J - 1;
+	} else {
+	    QuickSort (C, Lo, J - 1, Compare, Data);
+	    Lo = J + 1;
+	}
+    }
+}
+
+
+
+void CollSort (Collection* C,
+	       int (*Compare) (void*, const void*, const void*),
+	       void* Data)
+/* Sort the collection using the given compare function. The data pointer is
+ * passed as *first* element to the compare function, it's not used by the
+ * sort function itself. The other two pointer passed to the Compare function
+ * are pointers to objects.
+ */
+{
+    if (C->Count > 1) {
+	QuickSort (C, 0, C->Count-1, Compare, Data);
+    }
 }
 
 
diff --git a/src/common/coll.h b/src/common/coll.h
index 144442f65..ba1d4f601 100644
--- a/src/common/coll.h
+++ b/src/common/coll.h
@@ -113,10 +113,13 @@ void CollReplace (Collection* C, void* Item, unsigned Index);
  * just the pointer will et replaced.
  */
 
-void CollSort (Collection* C, int (*Compare) (const void*, const void*));
-/* Sort the collection using the given compare function.
- * BEWARE: The function uses qsort internally, so the Compare function does
- * actually get pointers to the object pointers, not just object pointers!
+void CollSort (Collection* C,
+	       int (*Compare) (void*, const void*, const void*),
+	       void* Data);
+/* Sort the collection using the given compare function. The data pointer is
+ * passed as *first* element to the compare function, it's not used by the
+ * sort function itself. The other two pointer passed to the Compare function
+ * are pointers to objects.
  */
 
 
diff --git a/src/common/objdefs.h b/src/common/objdefs.h
index 8ea626deb..7678f4763 100644
--- a/src/common/objdefs.h
+++ b/src/common/objdefs.h
@@ -46,7 +46,7 @@
 
 /* Defines for magic and version */
 #define OBJ_MAGIC	0x616E7A55
-#define OBJ_VERSION	0x0007
+#define OBJ_VERSION	0x0008
 
 /* Size of an object file header */
 #define	OBJ_HDR_SIZE	56
diff --git a/src/common/symdefs.h b/src/common/symdefs.h
index f4e192bf5..bf5ebe284 100644
--- a/src/common/symdefs.h
+++ b/src/common/symdefs.h
@@ -58,28 +58,26 @@
 
 /* Export size */
 #define EXP_ABS	       	0x00		/* Export as normal value */
-#define EXP_ZP 	      	0x20		/* Export as zero page value */
-#define EXP_MASK_SIZE 	0x20		/* Size mask */
+#define EXP_ZP 	       	0x08   	       	/* Export as zero page value */
+#define EXP_MASK_SIZE 	0x08		/* Size mask */
 
 #define IS_EXP_ABS(x)  	(((x) & EXP_MASK_SIZE) == EXP_ABS)
 #define IS_EXP_ZP(x)  	(((x) & EXP_MASK_SIZE) == EXP_ZP)
 
 /* Export value type */
 #define EXP_CONST     	0x00		/* Mask bit for const values */
-#define EXP_EXPR      	0x40   	 	/* Mask bit for expr values */
-#define EXP_MASK_VAL  	0x40		/* Value mask */
+#define EXP_EXPR      	0x10   	 	/* Mask bit for expr values */
+#define EXP_MASK_VAL  	0x10		/* Value mask */
 
 #define IS_EXP_CONST(x)	(((x) & EXP_MASK_VAL) == EXP_CONST)
 #define IS_EXP_EXPR(x) 	(((x) & EXP_MASK_VAL) == EXP_EXPR)
 
-/* Export initializer flag */
-#define EXP_INIT_MIN	0x01		/* Minimum value */
-#define EXP_INIT_MAX	0x1F		/* Maximum value */
-#define EXP_INIT_DEF	0x18		/* Default value */
-#define EXP_MASK_INIT 	0x1F		/* Initializer value mask */
+/* Number of module constructor/destructor declarations for an export */
+#define EXP_CONDES_MASK	0x07
 
-#define IS_EXP_INIT(x)		(((x) & EXP_MASK_INIT) != 0)
-#define GET_EXP_INIT_VAL(x)	((x) & EXP_MASK_INIT)
+#define IS_EXP_CONDES(x)	(((x) & EXP_CONDES_MASK) != 0)
+#define GET_EXP_CONDES_COUNT(x)	((x) & EXP_CONDES_MASK)
+#define INC_EXP_CONDES_COUNT(x) ((x)++)
 
 
 
diff --git a/src/common/target.c b/src/common/target.c
index 74864d243..3a5fc2171 100644
--- a/src/common/target.c
+++ b/src/common/target.c
@@ -34,6 +34,7 @@
 
 
 #include <stdlib.h>
+#include <string.h>
 #include <ctype.h>
 
 #include "target.h"
diff --git a/src/da65/config.c b/src/da65/config.c
index d76aa6993..275ba7d50 100644
--- a/src/da65/config.c
+++ b/src/da65/config.c
@@ -34,6 +34,7 @@
 
 
 #include <stdio.h>
+#include <string.h>
 #if defined(_MSC_VER)
 /* Microsoft compiler */
 #  include <io.h>
diff --git a/src/ld65/condes.c b/src/ld65/condes.c
new file mode 100644
index 000000000..7c9e7f73b
--- /dev/null
+++ b/src/ld65/condes.c
@@ -0,0 +1,188 @@
+/*****************************************************************************/
+/*                                                                           */
+/*				   condes.h				     */
+/*                                                                           */
+/*		     Module constructor/destructor support		     */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 2000      Ullrich von Bassewitz                                       */
+/*               Wacholderweg 14                                             */
+/*               D-70597 Stuttgart                                           */
+/* EMail:        uz@musoftware.de                                            */
+/*                                                                           */
+/*                                                                           */
+/* This software is provided 'as-is', without any expressed or implied       */
+/* warranty.  In no event will the authors be held liable for any damages    */
+/* arising from the use of this software.                                    */
+/*                                                                           */
+/* Permission is granted to anyone to use this software for any purpose,     */
+/* including commercial applications, and to alter it and redistribute it    */
+/* freely, subject to the following restrictions:                            */
+/*                                                                           */
+/* 1. The origin of this software must not be misrepresented; you must not   */
+/*    claim that you wrote the original software. If you use this software   */
+/*    in a product, an acknowledgment in the product documentation would be  */
+/*    appreciated but is not required.                                       */
+/* 2. Altered source versions must be plainly marked as such, and must not   */
+/*    be misrepresented as being the original software.                      */
+/* 3. This notice may not be removed or altered from any source              */
+/*    distribution.                                                          */
+/*                                                                           */
+/*****************************************************************************/
+
+
+
+/* common */
+#include "check.h"
+#include "coll.h"
+#include "xmalloc.h"
+
+/* ld65 */
+#include "exports.h"
+#include "segments.h"
+#include "condes.h"
+
+
+
+/*****************************************************************************/
+/*     		 		     Data				     */
+/*****************************************************************************/
+
+
+
+/* Struct describing one condes type */
+typedef struct ConDesDesc ConDesDesc;
+struct ConDesDesc {
+    Collection		ExpList;	/* List of exported symbols */
+    char*     		Label;		/* Name of table label */
+    char*     		SegName;	/* Name of segment the table is in */
+    unsigned char	Enable;		/* Table enabled */
+};
+
+/* Array for all types */
+static ConDesDesc ConDes[CD_TYPE_COUNT] = {
+    { STATIC_COLLECTION_INITIALIZER, 0, 0, 0 },
+    { STATIC_COLLECTION_INITIALIZER, 0, 0, 0 },
+    { STATIC_COLLECTION_INITIALIZER, 0, 0, 0 },
+    { STATIC_COLLECTION_INITIALIZER, 0, 0, 0 },
+    { STATIC_COLLECTION_INITIALIZER, 0, 0, 0 },
+    { STATIC_COLLECTION_INITIALIZER, 0, 0, 0 },
+    { STATIC_COLLECTION_INITIALIZER, 0, 0, 0 },
+};
+
+
+
+/*****************************************************************************/
+/*     	       	     	   	     Code  	      	  	  	     */
+/*****************************************************************************/
+
+
+
+void ConDesAddExport (struct Export* E)
+/* Add the given export to the list of constructors/destructor */
+{
+    unsigned Type;
+
+    /* Insert the export into all tables for which declarations exist */
+    for (Type = 0; Type < CD_TYPE_COUNT; ++Type) {
+  	unsigned Prio = E->ConDes[Type];
+  	if (Prio != CD_PRIO_NONE) {
+       	    CollAppend (&ConDes[Type].ExpList, E);
+  	}
+    }
+}
+
+
+
+void ConDesSetSegName (unsigned Type, const char* SegName)
+/* Set the segment name where the table should go */
+{
+    /* Check the parameters */
+    PRECONDITION (Type >= CD_TYPE_MIN && Type <= CD_TYPE_MAX && SegName != 0);
+
+    /* Setting the segment name twice is bad */
+    CHECK (ConDes[Type].SegName == 0);
+
+    /* Set the name */
+    ConDes[Type].SegName = xstrdup (SegName);
+}
+
+
+
+void ConDesSetLabel (unsigned Type, const char* Name)
+/* Set the label for the given ConDes type */
+{
+    /* Check the parameters */
+    PRECONDITION (Type >= CD_TYPE_MIN && Type <= CD_TYPE_MAX && Name != 0);
+
+    /* Setting the label twice is bad */
+    CHECK (ConDes[Type].Label == 0);
+
+    /* Set the name */
+    ConDes[Type].Label = xstrdup (Name);
+}
+
+
+
+const char* ConDesGetSegName (unsigned Type)
+/* Return the segment name for the given ConDes type */
+{
+    /* Check the parameters */
+    PRECONDITION (Type >= CD_TYPE_MIN && Type <= CD_TYPE_MAX);
+
+    /* Return the name */
+    return ConDes[Type].SegName;
+}
+
+
+
+const char* ConDesGetLabel (unsigned Type)
+/* Return the label for the given ConDes type */
+{
+    /* Check the parameters */
+    PRECONDITION (Type >= CD_TYPE_MIN && Type <= CD_TYPE_MAX);
+
+    /* Return the name */
+    return ConDes[Type].Label;
+}
+
+
+
+int ConDesHasSegName (unsigned Type)
+/* Return true if a segment name is already defined for this ConDes type */
+{
+    return (ConDesGetSegName(Type) != 0);
+}
+
+
+
+int ConDesHasLabel (unsigned Type)
+/* Return true if a label is already defined for this ConDes type */
+{
+    return (ConDesGetLabel(Type) != 0);
+}
+
+
+
+void ConDesCreate (void)
+/* Create the condes tables if requested */
+{
+}
+
+
+
+void ConDesDump (void)
+/* Dump ConDes data to stdout for debugging */
+{
+    unsigned Type;
+    for (Type = 0; Type < CD_TYPE_COUNT; ++Type) {
+       	Collection* ExpList = &ConDes[Type].ExpList;
+	printf ("CONDES(%u): %u symbols\n", Type, CollCount (ExpList));
+    }
+}
+
+
+
+
+
diff --git a/src/ld65/initfunc.h b/src/ld65/condes.h
similarity index 72%
rename from src/ld65/initfunc.h
rename to src/ld65/condes.h
index fef48e11a..72d295acd 100644
--- a/src/ld65/initfunc.h
+++ b/src/ld65/condes.h
@@ -1,8 +1,8 @@
 /*****************************************************************************/
 /*                                                                           */
-/*				  initfunc.h				     */
+/*				   condes.h				     */
 /*                                                                           */
-/*			Init/cleanup function handling			     */
+/*		     Module constructor/destructor support		     */
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
@@ -33,13 +33,13 @@
 
 
 
-#ifndef INITFUNC_H
-#define INITFUNC_H
+#ifndef CONDES_H
+#define CONDES_H
 
 
 
 /*****************************************************************************/
-/*				   Forwards				     */
+/*	      	  		   Forwards				     */
 /*****************************************************************************/
 
 
@@ -54,15 +54,36 @@ struct Export;
 
 
 
-void AddInitFunc (struct Export* E);
-/* Add the given export to the list of initializers */
+void ConDesAddExport (struct Export* E);
+/* Add the given export to the list of constructors/destructor */
 
-void AddCleanupFunc (struct Export* E);
-/* Add the given export to the list of cleanup functions */
+void ConDesSetSegName (unsigned Type, const char* SegName);
+/* Set the segment name where the table should go */
+
+void ConDesSetLabel (unsigned Type, const char* Name);
+/* Set the label for the given ConDes type */
+
+const char* ConDesGetSegName (unsigned Type);
+/* Return the segment name for the given ConDes type */
+
+const char* ConDesGetLabel (unsigned Type);
+/* Return the label for the given ConDes type */
+
+int ConDesHasSegName (unsigned Type);
+/* Return true if a segment name is already defined for this ConDes type */
+
+int ConDesHasLabel (unsigned Type);
+/* Return true if a label is already defined for this ConDes type */
+
+void ConDesCreate (void);
+/* Create the condes tables if requested */
+
+void ConDesDump (void);
+/* Dump ConDes data to stdout for debugging */
 
 
 
-/* End of initfunc.h */
+/* End of condes.h */
 
 #endif
 
diff --git a/src/ld65/config.c b/src/ld65/config.c
index d3f637654..314fc235c 100644
--- a/src/ld65/config.c
+++ b/src/ld65/config.c
@@ -42,14 +42,15 @@
 #include "check.h"
 #include "bitops.h"
 #include "xmalloc.h"
-	  
+
 /* ld65 */
-#include "error.h"
-#include "global.h"
 #include "bin.h"
-#include "o65.h"
 #include "binfmt.h"
+#include "condes.h"
+#include "error.h"
 #include "exports.h"
+#include "global.h"
+#include "o65.h"
 #include "scanner.h"
 #include "config.h"
 
@@ -115,6 +116,141 @@ static unsigned O65Attr	= 0;
 
 
 
+/*****************************************************************************/
+/*				   Forwards				     */
+/*****************************************************************************/
+
+
+
+static File* NewFile (const char* Name);
+/* Create a new file descriptor and insert it into the list */
+
+
+
+/*****************************************************************************/
+/*				List management				     */
+/*****************************************************************************/
+
+
+
+static File* FindFile (const char* Name)
+/* Find a file with a given name. */
+{
+    File* F = FileList;
+    while (F) {
+ 	if (strcmp (F->Name, Name) == 0) {
+ 	    return F;
+ 	}
+ 	F = F->Next;
+    }
+    return 0;
+}
+
+
+
+static File* GetFile (const char* Name)
+/* Get a file entry with the given name. Create a new one if needed. */
+{
+    File* F = FindFile (Name);
+    if (F == 0) {
+	/* Create a new one */
+	F = NewFile (Name);
+    }
+    return F;
+}
+
+
+
+static void FileInsert (File* F, Memory* M)
+/* Insert the memory area into the files list */
+{
+    M->F = F;
+    if (F->MemList == 0) {
+	/* First entry */
+	F->MemList = M;
+    } else {
+	F->MemLast->FNext = M;
+    }
+    F->MemLast = M;
+}
+
+
+
+static Memory* CfgFindMemory (const char* Name)
+/* Find the memory are with the given name. Return NULL if not found */
+{
+    Memory* M = MemoryList;
+    while (M) {
+       	if (strcmp (M->Name, Name) == 0) {
+       	    return M;
+       	}
+       	M = M->Next;
+    }
+    return 0;
+}
+
+
+
+static Memory* CfgGetMemory (const char* Name)
+/* Find the memory are with the given name. Print an error on an invalid name */
+{
+    Memory* M = CfgFindMemory (Name);
+    if (M == 0) {
+ 	CfgError ("Invalid memory area `%s'", Name);
+    }
+    return M;
+}
+
+
+
+static SegDesc* CfgFindSegDesc (const char* Name)
+/* Find the segment descriptor with the given name, return NULL if not found. */
+{
+    SegDesc* S = SegDescList;
+    while (S) {
+     	if (strcmp (S->Name, Name) == 0) {
+    	    /* Found */
+    	    return S;
+       	}
+     	S = S->Next;
+    }
+
+    /* Not found */
+    return 0;
+}
+
+
+
+static void SegDescInsert (SegDesc* S)
+/* Insert a segment descriptor into the list of segment descriptors */
+{
+    /* Insert the struct into the list */
+    S->Next = SegDescList;
+    SegDescList = S;
+    ++SegDescCount;
+}
+
+
+
+static void MemoryInsert (Memory* M, SegDesc* S)
+/* Insert the segment descriptor into the memory area list */
+{
+    /* Create a new node for the entry */
+    MemListNode* N = xmalloc (sizeof (MemListNode));
+    N->Seg  = S;
+    N->Next = 0;
+
+    if (M->SegLast == 0) {
+       	/* First entry */
+       	M->SegList = N;
+    } else {
+ 	M->SegLast->Next = N;
+    }
+    M->SegLast = N;
+}
+
+
+
 /*****************************************************************************/
 /*			   Constructors/Destructors			     */
 /*****************************************************************************/
@@ -156,13 +292,9 @@ static Memory* NewMemory (const char* Name)
     unsigned Len = strlen (Name);
 
     /* Check for duplicate names */
-    Memory* M =	MemoryList;
-    while (M) {
-    	if (strcmp (M->Name, Name) == 0) {
-       	    CfgError ("Memory area `%s' defined twice", Name);
-	    break;
-       	}
-    	M = M->Next;
+    Memory* M =	CfgFindMemory (Name);
+    if (M) {
+	CfgError ("Memory area `%s' defined twice", Name);
     }
 
     /* Allocate memory */
@@ -208,13 +340,9 @@ static SegDesc* NewSegDesc (const char* Name)
     unsigned Len = strlen (Name);
 
     /* Check for duplicate names */
-    SegDesc* S = SegDescList;
-    while (S) {
-     	if (strcmp (S->Name, Name) == 0) {
-       	    CfgError ("Segment `%s' defined twice", Name);
-	    break;
-       	}
-     	S = S->Next;
+    SegDesc* S = CfgFindSegDesc (Name);
+    if (S) {
+	CfgError ("Segment `%s' defined twice", Name);
     }
 
     /* Verify that the given segment does really exist */
@@ -278,49 +406,6 @@ static void AttrCheck (unsigned Attr, unsigned Mask, const char* Name)
 
 
 
-static File* FindFile (const char* Name)
-/* Find a file with a given name. */
-{
-    File* F = FileList;
-    while (F) {
- 	if (strcmp (F->Name, Name) == 0) {
- 	    return F;
- 	}
- 	F = F->Next;
-    }
-    return 0;
-}
-
-
-
-static File* GetFile (const char* Name)
-/* Get a file entry with the given name. Create a new one if needed. */
-{
-    File* F = FindFile (Name);
-    if (F == 0) {
-	/* Create a new one */
-	F = NewFile (Name);
-    }
-    return F;
-}
-
-
-
-static void FileInsert (File* F, Memory* M)
-/* Insert the memory area into the files list */
-{
-    M->F = F;
-    if (F->MemList == 0) {
-	/* First entry */
-	F->MemList = M;
-    } else {
-	F->MemLast->FNext = M;
-    }
-    F->MemLast = M;
-}
-
-
-
 static void ParseMemory (void)
 /* Parse a MEMORY section */
 {
@@ -351,7 +436,7 @@ static void ParseMemory (void)
 	while (CfgTok == CFGTOK_IDENT) {
 
 	    /* Map the identifier to a token */
-	    unsigned AttrTok;
+	    cfgtok_t AttrTok;
 	    CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Attribute");
 	    AttrTok = CfgTok;
 
@@ -477,7 +562,7 @@ static void ParseFiles (void)
 	while (CfgTok == CFGTOK_IDENT) {
 
 	    /* Map the identifier to a token */
-	    unsigned AttrTok;
+	    cfgtok_t AttrTok;
 	    CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Attribute");
 	    AttrTok = CfgTok;
 
@@ -528,63 +613,6 @@ static void ParseFiles (void)
 
 
 
-static Memory* CfgFindMemory (const char* Name)
-/* Find the memory are with the given name. Return NULL if not found */
-{
-    Memory* M = MemoryList;
-    while (M) {
-       	if (strcmp (M->Name, Name) == 0) {
-       	    return M;
-       	}
-       	M = M->Next;
-    }
-    return 0;
-}
-
-
-
-static Memory* CfgGetMemory (const char* Name)
-/* Find the memory are with the given name. Print an error on an invalid name */
-{
-    Memory* M = CfgFindMemory (Name);
-    if (M == 0) {
- 	CfgError ("Invalid memory area `%s'", Name);
-    }
-    return M;
-}
-
-
-
-static void SegDescInsert (SegDesc* S)
-/* Insert a segment descriptor into the list of segment descriptors */
-{
-    /* Insert the struct into the list */
-    S->Next = SegDescList;
-    SegDescList = S;
-    ++SegDescCount;
-}
-
-
-
-static void MemoryInsert (Memory* M, SegDesc* S)
-/* Insert the segment descriptor into the memory area list */
-{
-    /* Create a new node for the entry */
-    MemListNode* N = xmalloc (sizeof (MemListNode));
-    N->Seg  = S;
-    N->Next = 0;
-
-    if (M->SegLast == 0) {
-       	/* First entry */
-       	M->SegList = N;
-    } else {
- 	M->SegLast->Next = N;
-    }
-    M->SegLast = N;
-}
-
-
-
 static void ParseSegments (void)
 /* Parse a SEGMENTS section */
 {
@@ -623,7 +651,7 @@ static void ParseSegments (void)
 	while (CfgTok == CFGTOK_IDENT) {
 
 	    /* Map the identifier to a token */
-	    unsigned AttrTok;
+	    cfgtok_t AttrTok;
 	    CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Attribute");
 	    AttrTok = CfgTok;
 
@@ -649,9 +677,11 @@ static void ParseSegments (void)
        		    CfgSpecialToken (Types, ENTRY_COUNT (Types), "Type");
 		    switch (CfgTok) {
        	       	       	case CFGTOK_RO:	   S->Flags |= SF_RO;               break;
+			case CFGTOK_RW:	   /* Default */		    break;
 		     	case CFGTOK_BSS:   S->Flags |= SF_BSS;              break;
 		     	case CFGTOK_ZP:	   S->Flags |= (SF_BSS | SF_ZP);    break;
 		     	case CFGTOK_WPROT: S->Flags |= (SF_RO | SF_WPROT);  break;
+		     	default:	   Internal ("Unexpected token: %d", CfgTok);
 		    }
 		    break;
 
@@ -788,7 +818,7 @@ static void ParseO65 (void)
     while (CfgTok == CFGTOK_IDENT) {
 
 	/* Map the identifier to a token */
-	unsigned AttrTok;
+	cfgtok_t AttrTok;
        	CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Attribute");
 	AttrTok = CfgTok;
 
@@ -843,7 +873,7 @@ static void ParseO65 (void)
 	    	     	break;
 
 	    	    default:
-	    	     	Error ("Unexpected type token");
+	    	     	CfgError ("Unexpected type token");
 	    	}
 	    	break;
 
@@ -863,7 +893,7 @@ static void ParseO65 (void)
 			break;
 
 		    default:
-			Error ("Unexpected OS token");
+			CfgError ("Unexpected OS token");
 		}
 		break;
 
@@ -892,7 +922,7 @@ static void ParseFormats (void)
     while (CfgTok == CFGTOK_IDENT) {
 
 	/* Map the identifier to a token */
-	unsigned FormatTok;
+	cfgtok_t FormatTok;
        	CfgSpecialToken (Formats, ENTRY_COUNT (Formats), "Format");
 	FormatTok = CfgTok;
 
@@ -922,16 +952,165 @@ static void ParseFormats (void)
 
 
 
+static void ParseConDes (void)
+/* Parse the CONDES feature */
+{
+    static const IdentTok Attributes [] = {
+       	{   "SEGMENT",		CFGTOK_SEGMENT		},
+	{   "LABEL",  		CFGTOK_LABEL  		},
+	{   "TYPE",		CFGTOK_TYPE   		},
+    };
+
+    static const IdentTok Types [] = {
+       	{   "CONSTRUCTOR",	CFGTOK_CONSTRUCTOR	},
+	{   "DESTRUCTOR",      	CFGTOK_DESTRUCTOR	},
+    };
+
+    /* Attribute values. */
+    char SegName[sizeof (CfgSVal)];
+    char Label[sizeof (CfgSVal)];
+    int Type = -1;	/* Initialize to avoid gcc warnings */
+
+    /* Bitmask to remember the attributes we got already */
+    enum {
+	atNone		= 0x0000,
+	atSegName	= 0x0001,
+	atLabel		= 0x0002,
+	atType		= 0x0004
+    };
+    unsigned AttrFlags = atNone;
+
+    /* Parse the attributes */
+    while (1) {
+
+	/* Map the identifier to a token */
+	cfgtok_t AttrTok;
+       	CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Attribute");
+	AttrTok = CfgTok;
+
+	/* An optional assignment follows */
+	CfgNextTok ();
+	CfgOptionalAssign ();
+
+	/* Check which attribute was given */
+	switch (AttrTok) {
+
+	    case CFGTOK_SEGMENT:
+	  	/* Don't allow this twice */
+		FlagAttr (&AttrFlags, atSegName, "SEGMENT");
+	      	/* We expect an identifier */
+		CfgAssureIdent ();
+		/* Remember the value for later */
+		strcpy (SegName, CfgSVal);
+	    	break;
+
+	    case CFGTOK_LABEL:
+	       	/* Don't allow this twice */
+		FlagAttr (&AttrFlags, atLabel, "LABEL");
+	      	/* We expect an identifier */
+		CfgAssureIdent ();
+		/* Remember the value for later */
+		strcpy (Label, CfgSVal);
+		break;
+
+
+	    case CFGTOK_TYPE:
+	  	/* Don't allow this twice */
+		FlagAttr (&AttrFlags, atType, "TYPE");
+		/* The type may be given as id or numerical */
+		if (CfgTok == CFGTOK_INTCON) {
+		    CfgRangeCheck (CD_TYPE_MIN, CD_TYPE_MAX);
+		    Type = (int) CfgIVal;
+		} else {
+		    CfgSpecialToken (Types, ENTRY_COUNT (Types), "Type");
+		    switch (CfgTok) {
+		     	case CFGTOK_CONSTRUCTOR: Type = CD_TYPE_CON;	break;
+		     	case CFGTOK_DESTRUCTOR:	 Type = CD_TYPE_DES;	break;
+		     	default: FAIL ("Unexpected type token");
+		    }
+		}
+		break;
+
+	    default:
+		FAIL ("Unexpected attribute token");
+
+	}
+
+       	/* Skip the attribute value */
+	CfgNextTok ();
+
+	/* Semicolon ends the ConDes decl, otherwise accept an optional comma */
+	if (CfgTok == CFGTOK_SEMI) {
+	    break;
+	} else if (CfgTok == CFGTOK_COMMA) {
+	    CfgNextTok ();
+	}
+    }
+
+    /* Check if we have all mandatory attributes */
+    AttrCheck (AttrFlags, atSegName, "SEGMENT");
+    AttrCheck (AttrFlags, atLabel, "LABEL");
+    AttrCheck (AttrFlags, atType, "TYPE");
+
+    /* Check if the condes has already attributes defined */
+    if (ConDesHasSegName(Type) || ConDesHasLabel(Type)) {
+	CfgError ("CONDES attributes for type %d are already defined", Type);
+    }
+
+    /* Define the attributes */
+    ConDesSetSegName (Type, SegName);
+    ConDesSetLabel (Type, Label);
+}
+
+
+
+static void ParseFeatures (void)
+/* Parse a features section */
+{
+    static const IdentTok Features [] = {
+       	{   "CONDES",  	CFGTOK_CONDES	},
+    };
+
+    while (CfgTok == CFGTOK_IDENT) {
+
+	/* Map the identifier to a token */
+	cfgtok_t FeatureTok;
+       	CfgSpecialToken (Features, ENTRY_COUNT (Features), "Feature");
+       	FeatureTok = CfgTok;
+
+	/* Skip the name and the following colon */
+	CfgNextTok ();
+	CfgConsumeColon ();
+
+	/* Parse the format options */
+	switch (FeatureTok) {
+
+	    case CFGTOK_CONDES:
+		ParseConDes ();
+		break;
+
+	    default:
+		Error ("Unexpected feature token");
+	}
+
+	/* Skip the semicolon */
+	CfgConsumeSemi ();
+    }
+}
+
+
+
 static void ParseConfig (void)
 /* Parse the config file */
 {
     static const IdentTok BlockNames [] = {
-	{   "MEMORY",  	CFGTOK_MEMORY    },
-	{   "FILES",    CFGTOK_FILES     },
-        {   "SEGMENTS", CFGTOK_SEGMENTS  },
-	{   "FORMATS", 	CFGTOK_FORMATS   },
+	{   "MEMORY",  	CFGTOK_MEMORY	},
+	{   "FILES",    CFGTOK_FILES    },
+        {   "SEGMENTS", CFGTOK_SEGMENTS },
+	{   "FORMATS", 	CFGTOK_FORMATS  },
+	{   "FEATURES", CFGTOK_FEATURES	},
     };
-    unsigned BlockTok;
+    cfgtok_t BlockTok;
 
     do {
 
@@ -947,23 +1126,27 @@ static void ParseConfig (void)
 	switch (BlockTok) {
 
 	    case CFGTOK_MEMORY:
-		ParseMemory ();
-		break;
+	     	ParseMemory ();
+	     	break;
 
 	    case CFGTOK_FILES:
-		ParseFiles ();
-		break;
+	     	ParseFiles ();
+	     	break;
 
 	    case CFGTOK_SEGMENTS:
-		ParseSegments ();
-		break;
+	     	ParseSegments ();
+	     	break;
 
 	    case CFGTOK_FORMATS:
-		ParseFormats ();
+	     	ParseFormats ();
+	     	break;
+
+	    case CFGTOK_FEATURES:
+		ParseFeatures ();
 		break;
 
 	    default:
-		FAIL ("Unexpected block token");
+	     	FAIL ("Unexpected block token");
 
 	}
 
diff --git a/src/ld65/exports.c b/src/ld65/exports.c
index ae72b280f..515b8527d 100644
--- a/src/ld65/exports.c
+++ b/src/ld65/exports.c
@@ -45,10 +45,10 @@
 #include "xmalloc.h"
 
 /* ld65 */
-#include "global.h"
+#include "condes.h"
 #include "error.h"
 #include "fileio.h"
-#include "initfunc.h"
+#include "global.h"
 #include "objdata.h"
 #include "expr.h"
 #include "exports.h"
@@ -202,17 +202,18 @@ static Export* NewExport (unsigned char Type, const char* Name, ObjData* Obj)
 
     /* Initialize the fields */
     E->Next     = 0;
-    E->Flags  	= 0;
+    E->Flags   	= 0;
     E->Obj      = Obj;
     E->ImpCount = 0;
     E->ImpList  = 0;
     E->Expr    	= 0;
     E->Type    	= Type;
+    memset (E->ConDes, 0, sizeof (E->ConDes));
     if (Name) {
         E->Name = xstrdup (Name);
     } else {
-	/* Name will get added later */
-	E->Name = 0;
+       	/* Name will get added later */
+       	E->Name = 0;
     }
 
     /* Return the new entry */
@@ -229,9 +230,9 @@ void InsertExport (Export* E)
     Import* Imp;
     unsigned HashVal;
 
-    /* If this is an initializer, insert it into the initializer list */
-    if (IS_EXP_INIT (E->Type)) {
-	AddInitFunc (E);
+    /* Insert the export into any condes tables if needed */
+    if (IS_EXP_CONDES (E->Type)) {
+       	ConDesAddExport (E);
     }
 
     /* Create a hash value for the given name */
@@ -272,7 +273,7 @@ void InsertExport (Export* E)
       	   	    }
       	   	} else {
       	   	    /* Duplicate entry, ignore it */
-      	   	    Warning ("Duplicate external identifier: `%s'", L->Name);
+       	   	    Warning ("Duplicate external identifier: `%s'", L->Name);
       		}
       		return;
       	    }
@@ -293,6 +294,7 @@ Export* ReadExport (FILE* F, ObjData* O)
 /* Read an export from a file */
 {
     unsigned char Type;
+    unsigned      ConDesCount;
     Export* E;
 
     /* Read the type */
@@ -301,6 +303,29 @@ Export* ReadExport (FILE* F, ObjData* O)
     /* Create a new export without a name */
     E = NewExport (Type, 0, O);
 
+    /* Read the constructor/destructor decls if we have any */
+    ConDesCount = GET_EXP_CONDES_COUNT (Type);
+    if (ConDesCount > 0) {
+
+	unsigned char ConDes[CD_TYPE_COUNT];
+	unsigned I;
+
+	/* Read the data into temp storage */
+	ReadData (F, ConDes, ConDesCount);
+
+	/* Re-order the data. In the file, each decl is encoded into a byte
+	 * which contains the type and the priority. In memory, we will use
+	 * an array of types which contain the priority. This array was
+	 * cleared by the constructor (NewExport), so we must only set the
+	 * fields that contain values.
+	 */
+	for (I = 0; I < ConDesCount; ++I) {
+	    unsigned ConDesType = CD_GET_TYPE (ConDes[I]);
+	    unsigned ConDesPrio = CD_GET_PRIO (ConDes[I]);
+	    E->ConDes[ConDesType] = ConDesPrio;
+	}
+    }
+
     /* Read the name */
     E->Name = ReadStr (F);
 
@@ -562,7 +587,7 @@ void PrintExportMap (FILE* F)
 	      	     GetExportVal (E),
 	      	     E->ImpCount? 'R' : ' ',
 	      	     IS_EXP_ZP (E->Type)? 'Z' : ' ',
-		     IS_EXP_INIT (E->Type)? 'I' : ' ');
+		     IS_EXP_CONDES (E->Type)? 'I' : ' ');
 	    if (++Count == 2) {
 	      	Count = 0;
 	      	fprintf (F, "\n");
diff --git a/src/ld65/exports.h b/src/ld65/exports.h
index df3567610..8ee675f0c 100644
--- a/src/ld65/exports.h
+++ b/src/ld65/exports.h
@@ -41,6 +41,7 @@
 #include <stdio.h>
 
 /* common */
+#include "cddefs.h"
 #include "exprdefs.h"
 #include "filepos.h"
 
@@ -81,7 +82,8 @@ struct Export {
     Import*  		ImpList;	/* List of imports for this symbol */
     FilePos  		Pos;		/* File position of definition */
     ExprNode*  		Expr;		/* Expression (0 if not def'd) */
-    unsigned char	Type;		/* Type of export */
+    unsigned char	Type;		/* Type of export */		  
+    unsigned char	ConDes[CD_TYPE_COUNT];	/* Constructor/destructor decls */
     char*      	       	Name;		/* Name - dynamically allocated */
 };
 
@@ -157,7 +159,7 @@ void CircularRefError (const Export* E);
 /* Print an error about a circular reference using to define the given export */
 
 
-	     
+
 /* End of exports.h */
 
 #endif
diff --git a/src/ld65/fileio.c b/src/ld65/fileio.c
index c13a202f2..4998fe3ed 100644
--- a/src/ld65/fileio.c
+++ b/src/ld65/fileio.c
@@ -284,9 +284,12 @@ FilePos* ReadFilePos (FILE* F, FilePos* Pos)
 
 void* ReadData (FILE* F, void* Data, unsigned Size)
 /* Read data from the file */
-{
-    if (fread (Data, 1, Size, F) != Size) {
-	Error ("Read error (file corrupt?)");
+{     
+    /* Explicitly allow reading zero bytes */
+    if (Size > 0) {
+	if (fread (Data, 1, Size, F) != Size) {
+	    Error ("Read error (file corrupt?)");
+	}
     }
     return Data;
 }
diff --git a/src/ld65/main.c b/src/ld65/main.c
index 63ab842a4..415c39ab6 100644
--- a/src/ld65/main.c
+++ b/src/ld65/main.c
@@ -48,6 +48,7 @@
 
 /* ld65 */
 #include "binfmt.h"
+#include "condes.h"
 #include "config.h"
 #include "error.h"
 #include "exports.h"
@@ -404,6 +405,9 @@ int main (int argc, char* argv [])
     /* Read the config file */
     CfgRead ();
 
+    /* Create the condes tables if requested */
+    ConDesCreate ();
+
     /* Assign start addresses for the segments, define linker symbols */
     CfgAssignSegments ();
 
@@ -424,6 +428,7 @@ int main (int argc, char* argv [])
     /* Dump the data for debugging */
     if (Verbose > 1) {
 	SegDump ();
+	ConDesDump ();
     }
 
     /* Return an apropriate exit code */
diff --git a/src/ld65/make/gcc.mak b/src/ld65/make/gcc.mak
index abe8edf49..1b4affcc8 100644
--- a/src/ld65/make/gcc.mak
+++ b/src/ld65/make/gcc.mak
@@ -19,6 +19,7 @@ CVT=cfg/cvt-cfg.pl
 
 OBJS = 	bin.o		\
 	binfmt.o	\
+	condes.o	\
 	config.o	\
 	dbgsyms.o	\
 	error.o		\
@@ -28,7 +29,6 @@ OBJS = 	bin.o		\
 	fileio.o	\
 	fragment.o	\
 	global.o        \
-	initfunc.o	\
 	library.o	\
 	main.o	       	\
 	mapfile.o	\
diff --git a/src/ld65/scanner.c b/src/ld65/scanner.c
index 56870f11e..7b0770016 100644
--- a/src/ld65/scanner.c
+++ b/src/ld65/scanner.c
@@ -56,7 +56,7 @@
 
 
 /* Current token and attributes */
-unsigned        CfgTok;
+cfgtok_t	CfgTok;
 char   	       	CfgSVal [CFG_MAX_IDENT_LEN+1];
 unsigned long   CfgIVal;
 
@@ -322,7 +322,7 @@ Again:
 
 
 
-void CfgConsume (unsigned T, const char* Msg)
+void CfgConsume (cfgtok_t T, const char* Msg)
 /* Skip a token, print an error message if not found */
 {
     if (CfgTok != T) {
@@ -535,3 +535,4 @@ void CfgCloseInput (void)
 
 
 
+			  
diff --git a/src/ld65/scanner.h b/src/ld65/scanner.h
index 02d534978..d5f86e3ec 100644
--- a/src/ld65/scanner.h
+++ b/src/ld65/scanner.h
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998     Ullrich von Bassewitz                                        */
-/*              Wacholderweg 14                                              */
-/*              D-70597 Stuttgart                                            */
-/* EMail:       uz@musoftware.de                                             */
+/* (C) 1998-2000 Ullrich von Bassewitz                                       */
+/*               Wacholderweg 14                                             */
+/*               D-70597 Stuttgart                                           */
+/* EMail:        uz@musoftware.de                                            */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -45,67 +45,77 @@
 
 
 /* Config file tokens */
-#define	CFGTOK_NONE		0
-#define CFGTOK_INTCON		1
-#define CFGTOK_STRCON		2
-#define CFGTOK_IDENT		3
-#define CFGTOK_LCURLY		4
-#define CFGTOK_RCURLY		5
-#define CFGTOK_SEMI		6
-#define CFGTOK_COMMA		7
-#define CFGTOK_EQ		8
-#define CFGTOK_COLON  	 	9
-#define CFGTOK_DOT		10
-#define CFGTOK_EOF		11
+typedef enum {
+    CFGTOK_NONE,
+    CFGTOK_INTCON,
+    CFGTOK_STRCON,
+    CFGTOK_IDENT,
+    CFGTOK_LCURLY,
+    CFGTOK_RCURLY,
+    CFGTOK_SEMI,
+    CFGTOK_COMMA,
+    CFGTOK_EQ,
+    CFGTOK_COLON,
+    CFGTOK_DOT,
+    CFGTOK_EOF,
 
-/* Special identifiers */
-#define CFGTOK_MEMORY          	20
-#define CFGTOK_FILES      	21
-#define CFGTOK_SEGMENTS   	22
-#define CFGTOK_FORMATS		23
+    /* Special identifiers */
+    CFGTOK_MEMORY,
+    CFGTOK_FILES,
+    CFGTOK_SEGMENTS,
+    CFGTOK_FORMATS,
+    CFGTOK_FEATURES,
 
-#define CFGTOK_START		30
-#define CFGTOK_SIZE		31
-#define CFGTOK_TYPE 		32
-#define CFGTOK_FILE   		33
-#define CFGTOK_DEFINE 		34
-#define CFGTOK_FILL		35
-#define CFGTOK_FILLVAL		36
-#define CFGTOK_EXPORT 		37
-#define CFGTOK_IMPORT		38
-#define CFGTOK_OS      	       	39
-#define CFGTOK_FORMAT		40
+    CFGTOK_START,
+    CFGTOK_SIZE,
+    CFGTOK_TYPE,
+    CFGTOK_FILE,
+    CFGTOK_DEFINE,
+    CFGTOK_FILL,
+    CFGTOK_FILLVAL,
+    CFGTOK_EXPORT,
+    CFGTOK_IMPORT,
+    CFGTOK_OS,
+    CFGTOK_FORMAT,
 
-#define CFGTOK_LOAD   		50
-#define CFGTOK_RUN     	       	51
-#define CFGTOK_ALIGN   		52
-#define CFGTOK_OFFSET  		53
+    CFGTOK_LOAD,
+    CFGTOK_RUN,
+    CFGTOK_ALIGN,
+    CFGTOK_OFFSET,
 
-#define CFGTOK_RO      	       	60
-#define CFGTOK_RW      	       	61
-#define CFGTOK_BSS     	       	62
-#define CFGTOK_ZP		63
-#define CFGTOK_WPROT		64
+    CFGTOK_RO,
+    CFGTOK_RW,
+    CFGTOK_BSS,
+    CFGTOK_ZP,
+    CFGTOK_WPROT,
 
-#define CFGTOK_O65     	       	70
-#define CFGTOK_BIN     	       	71
+    CFGTOK_O65,
+    CFGTOK_BIN,
 
-#define CFGTOK_SMALL		80
-#define CFGTOK_LARGE		81
+    CFGTOK_SMALL,
+    CFGTOK_LARGE,
 
-#define CFGTOK_TRUE   		90
-#define CFGTOK_FALSE  		91
+    CFGTOK_TRUE,
+    CFGTOK_FALSE,
 
-#define CFGTOK_LUNIX		100
-#define CFGTOK_OSA65		101
+    CFGTOK_LUNIX,
+    CFGTOK_OSA65,
+
+    CFGTOK_CONDES,
+    CFGTOK_SEGMENT,
+    CFGTOK_LABEL,
+    CFGTOK_CONSTRUCTOR,
+    CFGTOK_DESTRUCTOR
+
+} cfgtok_t;
 
 
 
 /* Mapping table entry, special identifier --> token */
 typedef struct IdentTok_ IdentTok;
 struct IdentTok_ {
-    const char*	 	Ident;	     	/* Identifier */
-    unsigned	 	Tok;	     	/* Token for identifier */
+    const char*	Ident;	     	/* Identifier */
+    cfgtok_t	Tok;	     	/* Token for identifier */
 };
 #define ENTRY_COUNT(s) 	(sizeof (s) / sizeof (s [0]))
 
@@ -113,7 +123,7 @@ struct IdentTok_ {
 
 /* Current token and attributes */
 #define CFG_MAX_IDENT_LEN  255
-extern unsigned		CfgTok;
+extern cfgtok_t		CfgTok;
 extern char    	       	CfgSVal [CFG_MAX_IDENT_LEN+1];
 extern unsigned long	CfgIVal;
 
@@ -138,7 +148,7 @@ void CfgError (const char* Format, ...) attribute((format(printf,1,2)));
 void CfgNextTok (void);
 /* Read the next token from the input stream */
 
-void CfgConsume (unsigned T, const char* Msg);
+void CfgConsume (cfgtok_t T, const char* Msg);
 /* Skip a token, print an error message if not found */
 
 void CfgConsumeSemi (void);
@@ -196,4 +206,4 @@ void CfgCloseInput (void);
 
 
 
-				       
+
diff --git a/src/od65/dump.c b/src/od65/dump.c
index f5b880bda..d44e12efd 100644
--- a/src/od65/dump.c
+++ b/src/od65/dump.c
@@ -37,6 +37,7 @@
 #include <time.h>
 
 /* common */
+#include "cddefs.h"
 #include "exprdefs.h"
 #include "filepos.h"
 #include "objdefs.h"
@@ -196,24 +197,42 @@ static unsigned SkipFragment (FILE* F)
 
 
 
-static const char* GetExportFlags (unsigned Flags)
+static const char* GetExportFlags (unsigned Flags, const unsigned char* ConDes)
 /* Get the export flags as a (static) string */
 {
     /* Static buffer */
-    static char TypeDesc[128];
+    static char TypeDesc[256];
+    static char* T;
 
-    /* Get the flags */
+    unsigned Count;
+    unsigned I;
+
+    /* Adressing mode */
     TypeDesc[0] = '\0';
     switch (Flags & EXP_MASK_SIZE) {
- 	case EXP_ABS:   strcat (TypeDesc, "EXP_ABS");		break;
- 	case EXP_ZP:	strcat (TypeDesc, "EXP_ZP");		break;
+       	case EXP_ABS:   strcat (TypeDesc, "EXP_ABS");		break;
+       	case EXP_ZP:  	strcat (TypeDesc, "EXP_ZP");		break;
     }
+
+    /* Type of expression */
     switch (Flags & EXP_MASK_VAL) {
- 	case EXP_CONST:	strcat (TypeDesc, ",EXP_CONST");	break;
- 	case EXP_EXPR:	strcat (TypeDesc, ",EXP_EXPR");		break;
+       	case EXP_CONST:	strcat (TypeDesc, ",EXP_CONST");	break;
+       	case EXP_EXPR:	strcat (TypeDesc, ",EXP_EXPR");		break;
     }
-    if (IS_EXP_INIT (Flags)) {
-	sprintf (TypeDesc+strlen(TypeDesc), ",EXP_INIT=%u", GET_EXP_INIT_VAL(Flags));
+
+    /* Constructor/destructor declarations */
+    T = TypeDesc + strlen (TypeDesc);
+    Count = GET_EXP_CONDES_COUNT (Flags);
+    if (Count > 0) {
+	T += sprintf (T, ",EXP_CONDES=");
+	for (I = 0; I < Count; ++I) {
+	    unsigned Type = CD_GET_TYPE (ConDes[I]);
+	    unsigned Prio = CD_GET_PRIO (ConDes[I]);
+	    if (I > 0) {
+		*T++ = ',';
+	    }
+       	    T += sprintf (T, "[%u,%u]", Type, Prio);
+	}
     }
 
     /* Return the result */
@@ -537,10 +556,10 @@ void DumpObjImports (FILE* F, unsigned long Offset)
 void DumpObjExports (FILE* F, unsigned long Offset)
 /* Dump the exports in the object file */
 {
-    ObjHeader H;
-    unsigned  Count;
-    unsigned  I;
-    FilePos   Pos;
+    ObjHeader 	  H;
+    unsigned  	  Count;
+    unsigned  	  I;
+    FilePos   	  Pos;
 
     /* Seek to the header position */
     FileSeek (F, Offset);
@@ -563,12 +582,18 @@ void DumpObjExports (FILE* F, unsigned long Offset)
 
 	unsigned long 	Value = 0;
 	int 		HaveValue;
+	unsigned char	Type;
+	unsigned char	ConDes [CD_TYPE_COUNT];
+	char* 		Name;
+	unsigned	Len;
+
 
        	/* Read the data for one export */
-       	unsigned char Type  = Read8 (F);
-	char* 	      Name  = ReadStr (F);
-	unsigned      Len   = strlen (Name);
-	if (Type & EXP_EXPR) {
+       	Type  = Read8 (F);
+	ReadData (F, ConDes, GET_EXP_CONDES_COUNT (Type));
+	Name  = ReadStr (F);
+	Len   = strlen (Name);
+       	if (IS_EXP_EXPR (Type)) {
 	    SkipExpr (F);
 	    HaveValue = 0;
 	} else {
@@ -581,7 +606,7 @@ void DumpObjExports (FILE* F, unsigned long Offset)
 	printf ("    Index:%27u\n", I);
 
 	/* Print the data */
-       	printf ("      Type:%22s0x%02X  (%s)\n", "", Type, GetExportFlags (Type));
+       	printf ("      Type:%22s0x%02X  (%s)\n", "", Type, GetExportFlags (Type, ConDes));
 	printf ("      Name:%*s\"%s\"\n", 24-Len, "", Name);
 	if (HaveValue) {
 	    printf ("      Value:%15s0x%08lX  (%lu)\n", "", Value, Value);
@@ -630,12 +655,17 @@ void DumpObjDbgSyms (FILE* F, unsigned long Offset)
 
 	unsigned long 	Value = 0;
 	int 	   	HaveValue;
+	unsigned char	Type;
+	unsigned char	ConDes [CD_TYPE_COUNT];
+	char* 		Name;
+	unsigned	Len;
 
        	/* Read the data for one symbol */
-       	unsigned char Type  = Read8 (F);
-	char* 	      Name  = ReadStr (F);
-	unsigned      Len   = strlen (Name);
-	if (Type & EXP_EXPR) {
+       	Type  = Read8 (F);
+	ReadData (F, ConDes, GET_EXP_CONDES_COUNT (Type));
+	Name  = ReadStr (F);
+	Len   = strlen (Name);
+	if (IS_EXP_EXPR (Type)) {
 	    SkipExpr (F);
 	    HaveValue = 0;
 	} else {
@@ -648,7 +678,7 @@ void DumpObjDbgSyms (FILE* F, unsigned long Offset)
 	printf ("    Index:%27u\n", I);
 
 	/* Print the data */
-       	printf ("      Type:%22s0x%02X  (%s)\n", "", Type, GetExportFlags (Type));
+       	printf ("      Type:%22s0x%02X  (%s)\n", "", Type, GetExportFlags (Type, ConDes));
 	printf ("      Name:%*s\"%s\"\n", 24-Len, "", Name);
 	if (HaveValue) {
 	    printf ("      Value:%15s0x%08lX  (%lu)\n", "", Value, Value);
diff --git a/src/od65/fileio.c b/src/od65/fileio.c
index f700f3186..1950400e0 100644
--- a/src/od65/fileio.c
+++ b/src/od65/fileio.c
@@ -179,8 +179,11 @@ FilePos* ReadFilePos (FILE* F, FilePos* Pos)
 void* ReadData (FILE* F, void* Data, unsigned Size)
 /* Read data from the file */
 {
-    if (fread (Data, 1, Size, F) != Size) {
-	Error ("Read error (file corrupt?)");
+    /* Accept zero sized reads */
+    if (Size > 0) {
+	if (fread (Data, 1, Size, F) != Size) {
+	    Error ("Read error (file corrupt?)");
+	}	   
     }
     return Data;
 }