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-20) unstable; urgency=medium
.
* Version_2_6_13pre25
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: <YYYY-MM-DD>
--- gcl-2.6.12.orig/configure
+++ gcl-2.6.12/configure
@@ -4435,7 +4435,6 @@ case $use in
# if test "$enable_debug" != "yes" ; then TO2FLAGS="-O" ; fi
;;
mips*)
- TCFLAGS="$TCFLAGS -mplt"
# if test "$enable_debug" != "yes" ; then TO3FLAGS="-O0" ; fi #FIXME needed asof gcc 4.6.2
;;
ia64*)
--- gcl-2.6.12.orig/configure.in
+++ gcl-2.6.12/configure.in
@@ -640,7 +640,6 @@ case $use in
# if test "$enable_debug" != "yes" ; then TO2FLAGS="-O" ; fi
;;
mips*)
- TCFLAGS="$TCFLAGS -mplt"
# if test "$enable_debug" != "yes" ; then TO3FLAGS="-O0" ; fi #FIXME needed asof gcc 4.6.2
;;
ia64*)
--- gcl-2.6.12.orig/h/elf32_mips_reloc.h
+++ gcl-2.6.12/h/elf32_mips_reloc.h
@@ -4,7 +4,12 @@
add_val(where,~0L,s+a-(ul)got);
break;
case R_MIPS_26:
- add_val(where,MASK(26),(s+a)>>2);
+ if (((s+a)>>28)!=(((ul)where)>>28)) {
+ gote=got+sym->st_size-1;
+ massert(!write_26_stub(s+a,got,gote));
+ store_val(where,MASK(26),((ul)gote)>>2);
+ } else
+ add_val(where,MASK(26),(s+a)>>2);
break;
case R_MIPS_32:
add_val(where,~0L,s+a);
@@ -19,7 +24,10 @@
case R_MIPS_CALL16:
gote=got+sym->st_size-1;
store_val(where,MASK(16),((void *)gote-(void *)got));
- *gote=s;
+ if (s>=ggot && s<ggote) {
+ massert(!write_stub(s,got,gote));
+ } else
+ *gote=s;
break;
case R_MIPS_HI16:
if (sym->st_other) s=gpd=(ul)got-(sym->st_other==2 ? 0 : (ul)where);
--- gcl-2.6.12.orig/h/elf32_mips_reloc_special.h
+++ gcl-2.6.12/h/elf32_mips_reloc_special.h
@@ -1,9 +1,88 @@
-static ul gpd; static Rel *hr;
+#include <page.h>
+
+static ul gpd,ggot,ggote,can_gp; static Rel *hr;
+
+typedef struct {
+ ul addr_hi,addr_lo,jr,nop;
+} mips_26_tramp;
+
+static int
+write_26_stub(ul s,ul *got,ul *gote) {
+
+ static mips_26_tramp t1={(0xf<<26)|(0x0<<21)|(0x19<<16), /*lui t9*/
+ (0xe<<26)|(0x19<<21)|(0x19<<16), /*ori t9,t9 */
+ 0x03200008, /*jr t9*/
+ 0x00200825}; /*mv at,at */;
+ mips_26_tramp *t=(void *)gote;
+
+ *t=t1;
+ t->addr_hi|=s>>16;
+ t->addr_lo|=s&0xffff;
+
+ return 0;
+
+}
+
+typedef struct {
+ ul entry,addr_hi,addr_lo,lw,jr,lwcan;
+} call_16_tramp;
+
+static int
+write_stub(ul s,ul *got,ul *gote) {
+
+ static call_16_tramp t1={0,
+ (0xf<<26)|(0x0<<21)|(0x19<<16), /*lui t9*/
+ (0xe<<26)|(0x19<<21)|(0x19<<16), /*ori t9,t9 */
+ (0x23<<26)|(0x19<<21)|(0x19<<16), /*lw t9,(0)t9*/
+ 0x03200008, /*jr t9*/
+ /*stub addresses need veneer setting gp to canonical*/
+ (0x23<<26)|(0x1c<<21)|(0x1c<<16)};/*lw gp,(0)gp*/
+ call_16_tramp *t=(void *)gote++;
+
+ *t=t1;
+ *got=can_gp;
+
+ t->entry=(ul)gote;
+ t->addr_hi|=s>>16;
+ t->addr_lo|=s&0xffff;
+
+ return 0;
+
+}
static int
find_special_params(void *v,Shdr *sec1,Shdr *sece,const char *sn,
const char *st1,Sym *ds1,Sym *dse,Sym *sym,Sym *syme) {
+ Shdr *sec;
+ ul *q,gotsym=0,locgotno=0,stub,stube;
+ void *p,*pe;
+
+ massert(sec=get_section(".dynamic",sec1,sece,sn));
+ for (p=(void *)sec->sh_addr,pe=p+sec->sh_size;p<pe;p+=sec->sh_entsize) {
+ q=p;
+ if (q[0]==DT_MIPS_GOTSYM)
+ gotsym=q[1];
+ if (q[0]==DT_MIPS_LOCAL_GOTNO)
+ locgotno=q[1];
+ if (q[0]==DT_PLTGOT)
+ can_gp=q[1]+0x7ff0;
+
+ }
+ massert(gotsym && locgotno && can_gp);
+
+ massert(sec=get_section(".MIPS.stubs",sec1,sece,sn));
+ stub=sec->sh_addr;
+ stube=sec->sh_addr+sec->sh_size;
+
+ massert(sec=get_section(".got",sec1,sece,sn));
+ ggot=sec->sh_addr+locgotno*sec->sh_entsize;
+ ggote=sec->sh_addr+sec->sh_size;
+
+ for (ds1+=gotsym,sym=ds1;sym<dse;sym++)
+ if (!sym->st_value || (sym->st_value>=stub && sym->st_value<stube))
+ sym->st_value=ggot+(sym-ds1)*sec->sh_entsize;
+
return 0;
}
@@ -13,9 +92,10 @@ label_got_symbols(void *v1,Shdr *sec1,Sh
Rel *r;
Sym *sym;
- Shdr *sec;
+ Shdr *sec,*ssec;
void *v,*ve;
ul q;
+ struct node *a;
for (q=0,sym=sym1;sym<syme;sym++) {
const char *s=st1+sym->st_name;
@@ -29,20 +109,32 @@ label_got_symbols(void *v1,Shdr *sec1,Sh
for (sym=sym1;sym<syme;sym++)
sym->st_size=0;
- for (*gs=0,sec=sec1;sec<sece;sec++)
- if (sec->sh_type==SHT_REL)
+ for (*gs=1,sec=sec1;sec<sece;sec++)/*can_gp in got[0]*/
+ if (sec->sh_type==SHT_REL)/*no addend*/
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_GOT16) {
+ if (!(sym=sym1+ELF_R_SYM(r->r_info))->st_size)
- sym=sym1+ELF_R_SYM(r->r_info);
+ switch(ELF_R_TYPE(r->r_info)) {
- if (!sym->st_size)
- sym->st_size=++*gs;
+ case R_MIPS_26:
+ if (((ul)(pagetochar(page(heap_end))+r->r_offset))>>28) {
+ sym->st_size=++*gs;
+ (*gs)+=sizeof(mips_26_tramp)/sizeof(ul)-1;
+ }
+ break;
+ case R_MIPS_CALL16:
+ sym->st_size=++*gs;
+ if (((ssec=sec1+sym->st_shndx)>=sece || !ALLOC_SEC(ssec)) &&
+ (a=find_sym_ptable(st1+sym->st_name)) &&
+ a->address>=ggot && a->address<ggote)
+ (*gs)+=sizeof(call_16_tramp)/sizeof(ul)-1;
+ break;
+ case R_MIPS_GOT16:
+ sym->st_size=++*gs;
+ break;
+ }
- }
-
return 0;
}
--- gcl-2.6.12.orig/o/nsocket.c
+++ gcl-2.6.12/o/nsocket.c
@@ -645,11 +645,11 @@ getCharGclSocket(object strm, object blo
{ int high;
AGAIN:
/* under cygwin a too large timout like (1<<30) does not work */
- timeout.tv_sec = (block != Ct ? 0 : 0);
+ timeout.tv_sec = 0;
timeout.tv_usec = 10000;
FD_ZERO(&readfds);
FD_SET(fd,&readfds);
- high = select(fd+1,&readfds,NULL,NULL,&timeout);
+ high = select(fd+1,&readfds,NULL,NULL,block==Ct ? NULL : &timeout);
if (high > 0)
{ object bufp = SOCKET_STREAM_BUFFER(strm);
int n;