385abae
Description: <short summary of the patch>
385abae
 TODO: Put a short summary on the line above and replace this paragraph
385abae
 with a longer explanation of this change. Complete the meta-information
385abae
 with other relevant fields (see below for details). To make it easier, the
385abae
 information below has been extracted from the changelog. Adjust it or drop
385abae
 it.
385abae
 .
385abae
 gcl (2.6.12-76) unstable; urgency=medium
385abae
 .
385abae
   * Version_2_6_13pre66
385abae
Author: Camm Maguire <camm@debian.org>
385abae
385abae
---
385abae
The information above should follow the Patch Tagging Guidelines, please
385abae
checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here
385abae
are templates for supplementary fields that you might want to add:
385abae
385abae
Origin: <vendor|upstream|other>, <url of original patch>
385abae
Bug: <url in upstream bugtracker>
385abae
Bug-Debian: https://bugs.debian.org/<bugnumber>
385abae
Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber>
385abae
Forwarded: <no|not-needed|url proving that it has been forwarded>
385abae
Reviewed-By: <name and email of someone who approved the patch>
385abae
Last-Update: 2018-03-26
385abae
385abae
--- gcl-2.6.12.orig/configure
385abae
+++ gcl-2.6.12/configure
385abae
@@ -4121,7 +4121,6 @@ $as_echo_n "checking working gprof... "
385abae
 		       s390*) enableval="no";;#mcount smashes float args in make_shortfloat 20180313
385abae
 		       sh4*)  enableval="no";;
385abae
 		       ia64*) enableval="no";;
385abae
-		       alpha*) enableval="no";;#write_stub currently depends on t12 set in call
385abae
 		       hppa*) enableval="no";;
385abae
 		       arm*)  enableval="no";;#FIXME mcount compiled as a 24/22 bit reloc even with -mlong-calls, marginally accessible
385abae
 		       aarch64*) enableval="no";;#unreproducible buildd bug 20170824
385abae
--- gcl-2.6.12.orig/configure.in
385abae
+++ gcl-2.6.12/configure.in
385abae
@@ -334,7 +334,6 @@ AC_ARG_ENABLE([gprof],[  --enable-gprof
385abae
 		       s390*) enableval="no";;#mcount smashes float args in make_shortfloat 20180313
385abae
 		       sh4*)  enableval="no";;
385abae
 		       ia64*) enableval="no";;
385abae
-		       alpha*) enableval="no";;#write_stub currently depends on t12 set in call
385abae
 		       hppa*) enableval="no";;
385abae
 		       arm*)  enableval="no";;#FIXME mcount compiled as a 24/22 bit reloc even with -mlong-calls, marginally accessible
385abae
 		       aarch64*) enableval="no";;#unreproducible buildd bug 20170824
385abae
--- gcl-2.6.12.orig/h/elf64_alpha_reloc.h
385abae
+++ gcl-2.6.12/h/elf64_alpha_reloc.h
385abae
@@ -1,14 +1,14 @@
385abae
     case R_ALPHA_GPDISP:
385abae
-      gotoff=(ul)(got+(a>>32)-1);
385abae
+      gotoff=(ul)(got+HIGH(a)-1);
385abae
       s=gotoff-p;
385abae
       store_val(where,MASK(16),(s-(short)s)>>16);
385abae
-      store_val((void *)where+(a&MASK(32)),MASK(16),s);
385abae
+      store_val((void *)where+LOW(a),MASK(16),s);
385abae
       break;
385abae
     case R_ALPHA_SREL32:
385abae
       store_val(where,MASK(32),s+a-p);
385abae
       break;
385abae
     case R_ALPHA_GPREL32:
385abae
-      store_val(where,MASK(32),s+a-gotoff);
385abae
+      store_val(where,MASK(32),s+LOW(a)-(ul)(got+HIGH(a)-1));
385abae
       break;
385abae
     case R_ALPHA_LITUSE:
385abae
     case R_ALPHA_HINT:
385abae
@@ -20,8 +20,8 @@
385abae
       store_val(where,MASK(32),s+a);
385abae
       break;
385abae
     case R_ALPHA_LITERAL:
385abae
-      s+=a&MASK(32);
385abae
-      a=(a>>32)-1;
385abae
+      s+=LOW(a);
385abae
+      a=HIGH(a)-1;
385abae
       if (s>=ggot1 && s
385abae
         massert(!write_stub(s,got+a));
385abae
       } else 
385abae
--- gcl-2.6.12.orig/h/elf64_alpha_reloc_special.h
385abae
+++ gcl-2.6.12/h/elf64_alpha_reloc_special.h
385abae
@@ -1,10 +1,32 @@
385abae
-static ul ggot1,ggote,gotoff;
385abae
+static ul ggot1,ggote,gotoff,mcount;
385abae
+
385abae
+static int
385abae
+write_stub_mcount(ul s,ul *gote) {
385abae
+
385abae
+  unsigned int *goti;
385abae
+
385abae
+  /*mcount calls written using at register, address not available in stub*/
385abae
+  /*mcount guaranteed to be within 32bits*/
385abae
+  *gote=(ul)(goti=(void *)(gote+1));
385abae
+  *goti++=(0x9<<26)|(0x1b<<21)|(0x1f<<16)|((s-(short)s)>>16); /*ldah	t12,(symhigh)(zero)*/
385abae
+  *goti++=(0x8<<26)|(0x1b<<21)|(0x1b<<16)|(s&MASK(16));       /*lda	t12,(symlow)(t12)*/
385abae
+  *goti++=(0x29<<26)|(0x1b<<21)|(0x1b<<16)|0;                 /*ldq	t12,0(t12)*/
385abae
+  *goti++=(0x1a<<26)|(0x1f<<21)|(0x1b<<16)|0x4000;            /*jsr	zero,(t12),$pc+4*/
385abae
+  *goti++=0;                                                  /*halt*/
385abae
+  *goti++=0;                                                  /*halt*/
385abae
+
385abae
+  return 0;
385abae
+
385abae
+}
385abae
 
385abae
 static int
385abae
 write_stub(ul s,ul *gote) {
385abae
 
385abae
   unsigned int *goti;
385abae
 
385abae
+  if (s==mcount)
385abae
+    return write_stub_mcount(mcount,gote);
385abae
+
385abae
   *gote=(ul)(goti=(void *)(gote+2));
385abae
   *++gote=s;
385abae
   *goti++=(0x29<<26)|(0x1b<<21)|(0x1b<<16)|0xfff8; /*ldq	t12,-8(t12)*/
385abae
@@ -35,15 +57,19 @@ static int
385abae
 find_special_params(void *v,Shdr *sec1,Shdr *sece,const char *sn,
385abae
 		    const char *st1,Sym *ds1,Sym *dse,Sym *sym1,Sym *syme) {
385abae
 
385abae
+  Sym *sym;
385abae
   Shdr *sec;
385abae
   Rela *r;
385abae
-  void *ve;
385abae
+  void *ve,*dst1;
385abae
 
385abae
   massert((sec=get_section(".got",sec1,sece,sn)));
385abae
 
385abae
   ggot1=sec->sh_addr;
385abae
   ggote=ggot1+sec->sh_size;
385abae
 
385abae
+  massert(sec=get_section(".dynstr",sec1,sece,sn));/*FIXME pass as parameter*/
385abae
+  dst1=v+sec->sh_offset;
385abae
+
385abae
   massert((sec=get_section(".rel.dyn",sec1,sece,sn))||
385abae
 	  (sec=get_section(".rela.dyn",sec1,sece,sn)));
385abae
 
385abae
@@ -51,13 +77,20 @@ find_special_params(void *v,Shdr *sec1,S
385abae
   ve=v+sec->sh_size;
385abae
 
385abae
   for (r=v;v<ve;v+=sec->sh_entsize,r=v) 
385abae
-    if (ELF_R_TYPE(r->r_info) && !ds1[ELF_R_SYM(r->r_info)].st_value)
385abae
-      ds1[ELF_R_SYM(r->r_info)].st_value=r->r_offset;
385abae
+    if (ELF_R_TYPE(r->r_info) && !(sym=ds1+ELF_R_SYM(r->r_info))->st_value) {
385abae
+      sym->st_value=r->r_offset;
385abae
+      if (!strncmp("_mcount",dst1+sym->st_name,7))
385abae
+	mcount=sym->st_value;
385abae
+    }
385abae
 
385abae
   return 0;
385abae
 
385abae
 }
385abae
 
385abae
+#define HIGH(a_) ((a_)>>32)
385abae
+#define LOW(a_)  ((a_)&MASK(32))
385abae
+#define SET_HIGH(a_,b_) ({ul _a=(a_);(a_)=((b_)<<32)|LOW(_a);})
385abae
+
385abae
 static int
385abae
 label_got_symbols(void *v1,Shdr *sec1,Shdr *sece,Sym *sym1,Sym *syme,const char *st1,const char *sn,ul *gs) {
385abae
 
385abae
@@ -67,12 +100,18 @@ label_got_symbols(void *v1,Shdr *sec1,Sh
385abae
   void *v,*ve;
385abae
   ul q,gotp;
385abae
 
385abae
-  for (sym=sym1;sym
385abae
-    sym->st_size=0;
385abae
+  for (sym=sym1;sym
385abae
+    massert(!HIGH(sym->st_value));
385abae
+    massert(!HIGH(sym->st_size));
385abae
+  }
385abae
 
385abae
   for (*gs=gotp=0,sec=sec1;sec
385abae
     if (sec->sh_type==SHT_RELA)
385abae
-      for (v=v1+sec->sh_offset,ve=v+sec->sh_size,r=v;v<ve;v+=sec->sh_entsize,r=v)
385abae
+      for (v=v1+sec->sh_offset,ve=v+sec->sh_size,r=v;v<ve;v+=sec->sh_entsize,r=v) {
385abae
+
385abae
+	if (HIGH(r->r_addend))
385abae
+	  fprintf(stderr,"zeroing high addend %lx\n",HIGH(r->r_addend));/*never reached fix(Cnil) code, to be eliminated*/
385abae
+	SET_HIGH(r->r_addend,0UL);
385abae
 
385abae
 	switch(ELF_R_TYPE(r->r_info)) {
385abae
 
385abae
@@ -81,49 +120,60 @@ label_got_symbols(void *v1,Shdr *sec1,Sh
385abae
 	  if (!r->r_addend) {
385abae
 
385abae
 	    sym=sym1+ELF_R_SYM(r->r_info);
385abae
-	    q=(gotp-sym->st_size)*sizeof(*gs);
385abae
+	    q=(HIGH(sym->st_size)-gotp)*sizeof(*gs);
385abae
 
385abae
-	    if (!sym->st_size || q!=(short)q) {
385abae
-	      sym->st_size=++*gs;
385abae
+	    if (!HIGH(sym->st_size) || q!=(short)q) {/*new cached got entry if first or out of range*/
385abae
+	      SET_HIGH(sym->st_size,++*gs);
385abae
 	      massert(!make_got_room_for_stub(sec1,sece,sym,st1,gs));
385abae
 	    }
385abae
 
385abae
-	    q=sym->st_size;
385abae
+	    q=HIGH(sym->st_size);
385abae
 
385abae
 	  } else
385abae
 
385abae
 	    q=++*gs;
385abae
 
385abae
-	  if (r->r_addend>>32)
385abae
-	    fprintf(stderr,"zeroing high addend %lx\n",r->r_addend>>32);
385abae
-	  r->r_addend&=0xffffffff;
385abae
-	  massert((q&0xffffffff)==q);
385abae
-	  r->r_addend|=(q<<32);
385abae
+	  SET_HIGH(r->r_addend,q);
385abae
 
385abae
-	  q=(q-gotp)*sizeof(*gs);
385abae
+	  q=(q-gotp)*sizeof(*gs);/*check 16bit range gprel address in range*/
385abae
 	  massert(q==(short)q);
385abae
 
385abae
 	  break;
385abae
 
385abae
 	case R_ALPHA_GPDISP:
385abae
 
385abae
-	  for (sym=fsym;sym<syme && (sym->st_shndx!=1 || sym->st_value!=r->r_offset);sym++);
385abae
+	  for (sym=fsym;sym<syme && (sym->st_shndx!=1 || LOW(sym->st_value)!=r->r_offset);sym++);/*ordered search*/
385abae
 
385abae
 	  if (sym
385abae
 	    fsym=sym;
385abae
-	    gotp=*gs+1;
385abae
+	    SET_HIGH(fsym->st_value,gotp=*gs+1);
385abae
 	  }
385abae
 
385abae
-	  if (r->r_addend>>32)
385abae
-	    fprintf(stderr,"zeroing high addend %lx\n",r->r_addend>>32);
385abae
-	  r->r_addend&=0xffffffff;
385abae
-	  massert((gotp&0xffffffff)==gotp);
385abae
-	  r->r_addend|=(gotp<<32);
385abae
+	  SET_HIGH(r->r_addend,gotp);
385abae
+
385abae
+	  break;
385abae
+
385abae
+	case R_ALPHA_GPREL32:
385abae
+
385abae
+	  q=LOW(sym1[ELF_R_SYM(r->r_info)].st_value)+r->r_addend;
385abae
+
385abae
+	  /*unordered search*/
385abae
+	  for (sym=sym1;sym<syme && (sym->st_shndx!=1 || LOW(sym->st_value)>q || LOW(sym->st_value)+LOW(sym->st_size)
385abae
+	  massert(sym
385abae
+
385abae
+	  SET_HIGH(r->r_addend,HIGH(sym->st_value));
385abae
 
385abae
 	  break;
385abae
 
385abae
 	}
385abae
 
385abae
+      }
385abae
+
385abae
+  for (sym=sym1;sym
385abae
+    SET_HIGH(sym->st_value,0UL);
385abae
+    SET_HIGH(sym->st_size,0UL);
385abae
+  }
385abae
+
385abae
   return 0;
385abae
   
385abae
 }