Description: <short summary of the patch>
 TODO: Put a short summary on the line above and replace this paragraph
 with a longer explanation of this change. Complete the meta-information
 with other relevant fields (see below for details). To make it easier, the
 information below has been extracted from the changelog. Adjust it or drop
 it.
 .
 gcl (2.6.10-28) unstable; urgency=high
 .
   * enable prelink
Author: Camm Maguire <camm@debian.org>

---
The information above should follow the Patch Tagging Guidelines, please
checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here
are templates for supplementary fields that you might want to add:

Origin: <vendor|upstream|other>, <url of original patch>
Bug: <url in upstream bugtracker>
Bug-Debian: http://bugs.debian.org/<bugnumber>
Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber>
Forwarded: <no|not-needed|url proving that it has been forwarded>
Reviewed-By: <name and email of someone who approved the patch>
Last-Update: <YYYY-MM-DD>

--- gcl-2.6.10.orig/gcl-tk/guis.h
+++ gcl-2.6.10/gcl-tk/guis.h
@@ -3,6 +3,7 @@
 
 #include <stdlib.h>
 
+#define NO_PRELINK_UNEXEC_DIVERSION
 #include "include.h"
 
 #ifdef NeXT
--- gcl-2.6.10.orig/h/include.h
+++ gcl-2.6.10/h/include.h
@@ -104,6 +104,9 @@ Foundation, 675 Mass Ave, Cambridge, MA
 #ifdef HAVE_ALLOCA_H
 #include <alloca.h>
 #endif
+#ifdef HAVE_READLINE
+#include <readline/readline.h>
+#endif
 
 #include "../h/sfun_argd.h"
 #include "../h/compbas.h"
--- gcl-2.6.10.orig/h/notcomp.h
+++ gcl-2.6.10/h/notcomp.h
@@ -346,3 +346,4 @@ extern bool writable_malloc;
 #define sethash_with_check(a_,b_,c_) \
   ({object _b=(b_);while (type_of(_b)!=t_hashtable) _b=wrong_type_argument(sLhash_table,_b);sethash(a_,_b,c_);})
 
+#include "prelink.h"
--- gcl-2.6.10.orig/h/object.h
+++ gcl-2.6.10/h/object.h
@@ -456,6 +456,7 @@ object make_si_sfun();
 #define RETURNO(n,val1,listvals) RETURN(n,object,val1,listvals)
 
 /* eg: RETURN(3,object,val1,(RV(val2),RV(val3))) */
+#undef RETURN
 #define RETURN(n,typ,val1,listvals) \
    do{typ _val1 = val1; object *_p=&fcall.values[1]; listvals; fcall.nvalues= n; return _val1;}while(0)
 
--- /dev/null
+++ gcl-2.6.10/h/prelink.h
@@ -0,0 +1,45 @@
+/* prelink support for gcl images:
+   if GCL references variables (as opposed to functions) defined in
+   external shared libraries, ld will place COPY relocations in
+   .rela.dyn pointing to a location in .bss for these references.
+   Unexec will later incorporate this into a second .data section,
+   causing prelink to fail.  While one might prelink the raw images,
+   which would then be inherited by the saved images, this is not
+   convenient as part of the build process, so here we isolate the
+   problematic references and compile as position independent code,
+   changing the COPY reloc to some form of GOT.
+ */
+#ifdef NO_PRELINK_UNEXEC_DIVERSION
+#define PRELINK_EXTER
+#else
+#define PRELINK_EXTER extern
+
+#undef stdin
+#define stdin my_stdin
+#undef stdout
+#define stdout my_stdout
+#undef stderr
+#define stderr my_stderr
+
+#ifdef HAVE_READLINE
+#undef rl_instream
+#define rl_instream my_rl_instream
+#undef rl_completion_entry_function
+#define rl_completion_entry_function my_rl_completion_entry_function
+#undef rl_readline_name
+#define rl_readline_name my_rl_readline_name
+#undef rl_line_buffer
+#define rl_line_buffer my_rl_line_buffer
+#endif
+#endif
+
+PRELINK_EXTER void *my_stdin;
+PRELINK_EXTER void *my_stdout;
+PRELINK_EXTER void *my_stderr;
+
+#ifdef HAVE_READLINE
+PRELINK_EXTER void *my_rl_instream;
+PRELINK_EXTER void *my_rl_completion_entry_function;
+PRELINK_EXTER const char *my_rl_readline_name;
+PRELINK_EXTER char *my_rl_line_buffer;
+#endif
--- gcl-2.6.10.orig/h/protoize.h
+++ gcl-2.6.10/h/protoize.h
@@ -1905,3 +1905,6 @@ number_dpf(object,object,object);
 #if defined(DARWIN)
 void init_darwin_zone_compat ();
 #endif
+
+void
+prelink_init(void);
--- gcl-2.6.10.orig/o/error.c
+++ gcl-2.6.10/o/error.c
@@ -645,7 +645,7 @@ DEFUN_NEW("UNIVERSAL-ERROR-HANDLER",obje
 	int i;
 	/* 5 args */
 	for (i = 0;  i < error_fmt_string->st.st_fillp;  i++)
-		putchar(error_fmt_string->st.st_self[i]);
+	  fputc(error_fmt_string->st.st_self[i],stdout);
 	printf("\nLisp initialization failed.\n");
 	exit(0);
 	RETURN1(x0);
--- gcl-2.6.10.orig/o/file.d
+++ gcl-2.6.10/o/file.d
@@ -39,7 +39,6 @@ Foundation, 675 Mass Ave, Cambridge, MA
 #include "include.h"
 
 #ifdef HAVE_READLINE
-#include <readline/readline.h>
 #define kclgetc(FP)		rl_getc_em(((FILE *)FP))
 #define kclungetc(C, FP)	rl_ungetc_em(C, ((FILE *)FP))
 #define kclputc(C, FP)		rl_putc_em(C, ((FILE *)FP))
--- gcl-2.6.10.orig/o/gcl_readline.d
+++ gcl-2.6.10/o/gcl_readline.d
@@ -43,13 +43,7 @@ Foundation, 675 Mass Ave, Cambridge, MA
 #include <stdlib.h>
 #include <unistd.h>
 #include <string.h>
-#if 1
-#include <readline/readline.h>
 #include <readline/history.h>
-#else
-#include <readline.h>
-#include <history.h>
-#endif
 
 int readline_on = 0;		/* On (1) or off (0) */
 static int rl_ungetc_em_char = -1;
--- gcl-2.6.10.orig/o/main.c
+++ gcl-2.6.10/o/main.c
@@ -266,6 +266,7 @@ main(int argc, char **argv, char **envp)
 #include "ld_bind_now.h"
 #endif
   
+  prelink_init();
   
   setbuf(stdin, stdin_buf); 
   setbuf(stdout, stdout_buf);
--- gcl-2.6.10.orig/o/makefile
+++ gcl-2.6.10/o/makefile
@@ -20,7 +20,7 @@ OBJS:=$(addsuffix .o,typespec main alloc
 	num_pred num_comp num_arith num_sfun num_co num_log num_rand earith character sequence list hash\
 	array string regexpr structure toplevel file read backq print format pathname unixfsys unixfasl\
 	error unixtime unixsys unixsave funlink fat_string run_process nfunlink usig usig2 utils makefun\
-	sockets gmp_wrappers clxsocket init_pari nsocket sfasl)
+	sockets gmp_wrappers clxsocket init_pari nsocket sfasl prelink)
 OBJS:=$(OBJS) $(RL_OBJS) $(EXTRAS)
 
 INI_FILES=$(patsubst %.o,%.ini,${OBJS})
@@ -33,6 +33,9 @@ all:  $(OBJECTS)
 boot.o: boot.c $(DECL) boot.h
 	$(CC) -c $(CFLAGS) $(DEFS) -fPIC $*.c $(AUX_INFO) 
 
+prelink.o: prelink.c $(DECL)
+	$(CC) -fPIE -c $(CFLAGS) $(DEFS) $*.c $(AUX_INFO) 
+
 %.o: %.c $(DECL)
 	$(CC) -c $(CFLAGS) $(DEFS) $*.c $(AUX_INFO) 
 
--- /dev/null
+++ gcl-2.6.10/o/prelink.c
@@ -0,0 +1,19 @@
+#define NO_PRELINK_UNEXEC_DIVERSION
+
+#include "include.h"
+
+void
+prelink_init(void) {
+  
+  my_stdin=stdin;
+  my_stdout=stdout;
+  my_stderr=stderr;
+#ifdef HAVE_READLINE
+  my_rl_instream=rl_instream;
+  my_rl_completion_entry_function=rl_completion_entry_function;
+  my_rl_readline_name=rl_readline_name;
+  my_rl_line_buffer=rl_line_buffer;
+#endif
+
+}
+
--- gcl-2.6.10.orig/o/regexp.c
+++ gcl-2.6.10/o/regexp.c
@@ -171,6 +171,7 @@ min_initial_branch_length(regexp *, unsi
 
 #define	FAIL(m)	{ regerror(m); return(NULL); }
 #define	ISMULT(c)	((c) == '*' || (c) == '+' || (c) == '?')
+#undef META
 #define	META	"^$.[()|?+*\\"
 
 /*
--- gcl-2.6.10.orig/o/unexelf.c
+++ gcl-2.6.10/o/unexelf.c
@@ -996,16 +996,16 @@ unexec (char *new_name, char *old_name,
       /* Write out the sections. .data and .data1 (and data2, called
 	 ".data" in the strings table) get copied from the current process
 	 instead of the old file.  */
-      if (!strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data")
-	  || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
+      if (!strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".data")
+	  || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
 		      ".sdata")
-	  || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
+	  || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
 		      ".lit4")
-	  || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
+	  || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
 		      ".lit8")
-	  || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
+	  || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
 		      ".sdata1")
-	  || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
+	  || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
 		      ".data1")
 	  || !strcmp (old_section_names + NEW_SECTION_H (nn).sh_name,
 		      ".sbss"))
--- gcl-2.6.10.orig/unixport/makefile
+++ gcl-2.6.10/unixport/makefile
@@ -128,6 +128,8 @@ saved_%:raw_% $(RSYM) init_%.lsp raw_%_m
 	echo " (in-package \"USER\")(system:save-system \"$@\")" >>foo
 	ar x lib$*.a $$(ar t lib$*.a |grep ^gcl_)
 	$(PORTDIR)/raw_$*$(EXE) $(PORTDIR)/ -libdir $(GCLDIR)/ < foo
+#       check that saved image can be prelinked
+	! [ -x /usr/bin/objdump ] || ! /usr/bin/objdump -f $@ | grep "file format" | grep "elf" || ! /usr/bin/objdump -R $@ |grep R_.*_COPY
 
 $(RSYM): $(SPECIAL_RSYM) $(HDIR)/mdefs.h
 	$(CC) $(LD_FLAGS) $(CFLAGS) -I$(HDIR) -I$(ODIR) -o $(RSYM) $(SPECIAL_RSYM)
