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.12-48) unstable; urgency=medium
 .
   * list_order.1
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: https://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: 2017-06-08

--- gcl-2.6.12.orig/configure
+++ gcl-2.6.12/configure
@@ -4188,6 +4188,7 @@ case $use in
 	    mips*)
 		case $canonical in
 		    mips64*linux*)
+#			assert_arg_to_cflags -mxgot
 			assert_arg_to_ldflags -Wl,-z,now;;
 		esac
 		;;
--- gcl-2.6.12.orig/configure.in
+++ gcl-2.6.12/configure.in
@@ -389,6 +389,7 @@ case $use in
 	    mips*)
 		case $canonical in
 		    mips64*linux*)
+#			assert_arg_to_cflags -mxgot
 			assert_arg_to_ldflags -Wl,-z,now;;
 		esac
 		;;
--- gcl-2.6.12.orig/h/elf64_mips_reloc.h
+++ gcl-2.6.12/h/elf64_mips_reloc.h
@@ -32,23 +32,14 @@
       if (s>=ggot && s<ggote) {
         massert(!write_stub(s,got,gote));
       } else
-        *gote=s+(a&~MASK(16))+((a&0x8000)<<1);
-      ((Rela *)r)->r_addend=((void *)gote-(void *)got)-s;
-      switch(tp) {
-        case R_MIPS_GOT_HI16:
-        case R_MIPS_CALL_HI16:
-	  r->r_info=((ul)R_MIPS_HI16<<56)|(r->r_info&MASK(32));
-	  relocate(sym1,r,((Rela *)r)->r_addend,start,got,gote);
-	  break;
-        case R_MIPS_GOT_LO16:
-        case R_MIPS_CALL_LO16:
-	  r->r_info=((ul)R_MIPS_LO16<<56)|(r->r_info&MASK(32));
-	  relocate(sym1,r,((Rela *)r)->r_addend,start,got,gote);
-	  break;
-        default:
-	  store_val(where,MASK(16),((void *)gote-(void *)got));
-	  break;
-      }
+        *gote=s+(MIPS_HIGH(a)<<16);
+      a=(void *)gote-(void *)got;
+      if (tp==R_MIPS_GOT_HI16||tp==R_MIPS_CALL_HI16)
+        a=MIPS_HIGH(a);
+      else if (tp==R_MIPS_GOT_LO16||tp==R_MIPS_CALL_LO16)
+	a&=MASK(16);
+      massert(!(a&~MASK(16)));
+      store_val(where,MASK(16),a);
       break;
     case R_MIPS_GOT_OFST:
       recurse(s+a);
@@ -63,8 +54,7 @@
     case R_MIPS_LO16:
       recurse(s+a);
       s+=a;
-      a=*where&MASK(16);
-      if (a&0x8000) a|=0xffffffffffff0000; 
+      a=(short)*where;
       a+=s&MASK(16);
       a+=(a&0x8000)<<1; 
       store_val(where,MASK(16),a);
--- gcl-2.6.12.orig/h/elf64_mips_reloc_special.h
+++ gcl-2.6.12/h/elf64_mips_reloc_special.h
@@ -16,6 +16,7 @@ static ul ggot,ggote,la; static Rela *hr
 
 #undef ELF_R_TYPE 
 #define ELF_R_TYPE(a_) ELF_R_TYPE1(a_)
+#define MIPS_HIGH(a_) ({ul _a=(a_);(_a-(short)_a)>>16;})
 
 typedef struct {
   ul entry,gotoff;
@@ -98,12 +99,12 @@ label_got_symbols(void *v1,Shdr *sec1,Sh
   Sym *sym;
   Shdr *sec;
   void *v,*ve;
-  ul q=0,a,b;
+  ul a,b;
 
   for (sym=sym1;sym<syme;sym++)
-    sym->st_size=0;
+    sym->st_other=sym->st_size=0;
 
-  for (*gs=0,sec=sec1;sec<sece;sec++)
+  for (sec=sec1;sec<sece;sec++)
     if (sec->sh_type==SHT_RELA)
       for (v=v1+sec->sh_offset,ve=v+sec->sh_size,r=v;v<ve;v+=sec->sh_entsize,r=v)
 	if (ELF_R_TYPE(r->r_info)==R_MIPS_CALL16||
@@ -116,24 +117,37 @@ label_got_symbols(void *v1,Shdr *sec1,Sh
 
 	  sym=sym1+ELF_R_SYM(r->r_info);
 
-	  a=r->r_addend>>15;
+	  /*unlikely to save got space by recording possible holes in addend range*/
+	  if ((a=MIPS_HIGH(r->r_addend)+1)>sym->st_other)
+	    sym->st_other=a;
+
+	}
 
-	  if (2*a>=sizeof(sym->st_size) || !((sym->st_size>>(a*16))&0xffff)) {
+  for (*gs=0,sec=sec1;sec<sece;sec++)
+    if (sec->sh_type==SHT_RELA)
+      for (v=v1+sec->sh_offset,ve=v+sec->sh_size,r=v;v<ve;v+=sec->sh_entsize,r=v)
+	if (ELF_R_TYPE(r->r_info)==R_MIPS_CALL16||
+	    ELF_R_TYPE(r->r_info)==R_MIPS_GOT_DISP||
+	    ELF_R_TYPE(r->r_info)==R_MIPS_GOT_HI16||
+	    ELF_R_TYPE(r->r_info)==R_MIPS_GOT_LO16||
+	    ELF_R_TYPE(r->r_info)==R_MIPS_CALL_HI16||
+	    ELF_R_TYPE(r->r_info)==R_MIPS_CALL_LO16||
+	    ELF_R_TYPE(r->r_info)==R_MIPS_GOT_PAGE) {
 
-	    q=++*gs;
-	    if (2*a<sizeof(sym->st_size)) {
-	      massert(q<=0xffff);
-	      sym->st_size|=(q<<(a*16));
-	    }
-	    
-	    massert(!make_got_room_for_stub(sec1,sece,sym,st1,gs));
+	  sym=sym1+ELF_R_SYM(r->r_info);
 
+	  if (sym->st_other) {
+	    sym->st_size=++*gs;
+	    if (sym->st_other>1)
+	      (*gs)+=sym->st_other-1;
+	    else
+	      massert(!make_got_room_for_stub(sec1,sece,sym,st1,gs));
+	    sym->st_other=0;
 	  }
 
 	  b=sizeof(r->r_addend)*4; 
 	  massert(!(r->r_addend>>b)); 
-	  q=2*a>=sizeof(sym->st_size) ? q : (sym->st_size>>(a*16))&0xffff; 
-	  r->r_addend|=(q<<=b); 
+	  r->r_addend|=((sym->st_size+MIPS_HIGH(r->r_addend))<<b);
 
 	}
   
--- gcl-2.6.12.orig/h/pool.h
+++ gcl-2.6.12/h/pool.h
@@ -20,7 +20,7 @@ static struct pool {
   ufixnum s;
 } *Pool;
 
-static struct flock pl;
+static struct flock pl,*plp=&pl;
 
 static const char *gcl_pool="/tmp/gcl_pool";
 
@@ -28,7 +28,7 @@ static int
 set_lock(void) {
   
   errno=0;
-  if (fcntl(pool,F_SETLKW,&pl)) {
+  if (fcntl(pool,F_SETLKW,plp)) {
     if (errno==EINTR)
       set_lock();
     return -1;
@@ -90,16 +90,13 @@ open_pool(void) {
       Pool->s=0;
       unlock_pool();
 
-      f.l_type=F_UNLCK;
-      massert(!fcntl(pool,F_SETLK,&f));
-
-      fprintf(stderr,"Initializing pool\n");
-      fflush(stderr);
-
     }
 
     f.l_type=F_RDLCK;
-    massert(!fcntl(pool,F_SETLK,&f));
+    plp=&f;
+    massert(!set_lock());
+
+    plp=&pl;
 
     register_pool(1);
     massert(!atexit(close_pool));
