1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
|
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <setjmp.h>
#include <stdio.h>
#include <math.h>
#include "include.h"
typedef struct {
const char *n;
unsigned long ad;
} Plt;
#ifdef LEADING_UNDERSCORE
#define stn(a_) (*(a_)=='_' ? (a_)+1 : (a_))
#else
#define stn(a_) a_
#endif
static int
pltcomp(const void *v1,const void *v2) {
const Plt *p1=v1,*p2=v2;
return strcmp(p1->n,p2->n);
}
extern int mcount();
extern int _mcount();
extern int __divdi3();
extern int __moddi3();
extern int __udivdi3();
extern int __umoddi3();
extern void sincos(double,double *,double *);
extern int __divsi3();
extern int __modsi3();
extern int __udivsi3();
extern int __umodsi3();
extern int $$divI();
extern int $$divU();
extern int $$remI();
extern int $$remU();
extern int __divq();
extern int __divqu();
extern int __remq();
extern int __remqu();
#define MY_PLT(a_) {#a_,(unsigned long)(void *)a_}
static Plt mplt[]={
/* This is an attempt to at least capture the addresses to
which the compiler directly refers in C code. (Some symbols
are not explicitly mentioned in the C source but are
generated by gcc, usually in a platform specific way). At
the time of this writing, these symbols alone are
sufficient for compiling maxima,acl2,and axiom on x86.
This table is not (currently at least) consulted in
actuality -- the mere mention of the symbols here (at
present) ensures that the symbols are assigned values by
the linker, which are used preferentially to these values
in sfasli.c. FIXME -- this should be made synchronous with
compiler changes; sort the list automatically. SORT THIS
LIST BY HAND FOR THE TIME BEING. */
#ifndef _WIN32
# include "plt.h"
#endif
};
object sSAplt_tableA;
DEFVAR("*PLT-TABLE*",sSAplt_tableA,SI,Cnil,"");
static int
arsort(const void *v1,const void *v2) {
const object *op1=v1,*op2=v2;
object o1=*op1,o2=*op2;
int j;
o1=o1->c.c_car;
o2=o2->c.c_car;
if ((j=strncmp(o1->st.st_self,
o2->st.st_self,
o1->st.st_dim<o2->st.st_dim ?
o1->st.st_dim : o2->st.st_dim)))
return j;
j=o1->st.st_dim-o2->st.st_dim;
return j>0 ? 1 : (!j ? 0 : -1);
}
static int
arsearch(const void *v1,const void *v2) {
const char *s=v1;
const object *op=v2;
int j;
if ((j=strncmp(s,(*op)->c.c_car->st.st_self,(*op)->c.c_car->st.st_dim)))
return j;
j=strlen(s)-(*op)->c.c_car->st.st_dim;
return j>0 ? 1 : (!j ? 0 : -1);
}
int
parse_plt() {
FILE *f;
char b[1024],b1[1024];
unsigned i,n,j;
unsigned long u;
#ifdef _WIN32
char *exe_start = NULL; /* point to start of .exe */
#endif
char *c,*d;
object st,fi,li,ar,*op;
Plt *p=mplt,*pe=p+sizeof(mplt)/sizeof(*mplt);
struct stat ss;
if (snprintf(b,sizeof(b),"%s",kcl_self)<=0)
FEerror("Cannot write map filename",0);
#ifdef _WIN32
exe_start = strstr ( b, ".exe" );
if ( NULL != exe_start ) *exe_start = '\0';
#endif
c=b+strlen(b);
if (sizeof(b)-(c-b)<5)
FEerror("Cannot write map filename",0);
strcpy(c,"_map");
strcpy(b1,b);
if (stat(b1,&ss))
return 0;
if (!(f=fopen(b1,"r")))
FEerror("Cannot open map file", 0);
for (i=j=0,li=Cnil;fgets(b,sizeof(b),f);) {
if (!memchr(b,10,sizeof(b)-1))
FEerror("plt buffer too small", 0);
if (!memcmp(b," .plt",4)) {
i=1;
continue;
}
if (*b!=' ' || b[1]!=' ' || !i) {
i=0;
continue;
}
if (sscanf(b,"%lx%n",&u,&n)!=1)
FEerror("Cannot read address", 0);
for (c=b+n;*c==32;c++);
for (d=c;*d!='@' && *d!='\r' && *d!='\n';d++);
*d=0;
st=make_simple_string(c);
fi=make_fixnum(u);
li=make_cons(make_cons(st,fi),li);
j++;
}
fclose(f);
unlink(b1);
ar=fSmake_vector1_1(j,aet_object,Cnil);
for (;j && !endp(li);li=li->c.c_cdr)
ar->v.v_self[--j]=li->c.c_car;
if (j || !endp(li))
FEerror("plt list mismatch", 0);
qsort(ar->v.v_self,ar->v.v_dim,sizeof(*ar->v.v_self),arsort);
for (;p<pe;p++)
if ((op=bsearch(p->n,ar->v.v_self,ar->v.v_dim,sizeof(*ar->v.v_self),arsearch)) &&
(*op)->c.c_cdr->FIX.FIXVAL != p->ad)
FEerror("plt/ld address mismatch",0);
sSAplt_tableA->s.s_dbind=ar;
return 0;
}
int
my_plt(const char *s,unsigned long *v) {
Plt *p=mplt,*pe=p+sizeof(mplt)/sizeof(*mplt),tp;
object *op;
if (sSAplt_tableA->s.s_dbind &&
(op=bsearch(s,sSAplt_tableA->s.s_dbind->v.v_self,
sSAplt_tableA->s.s_dbind->v.v_dim,
sizeof(*sSAplt_tableA->s.s_dbind->v.v_self),
arsearch))) {
*v=(*op)->c.c_cdr->FIX.FIXVAL;
return 0;
}
tp.n=stn(s);
if ((p=bsearch(&tp,p,pe-p,sizeof(*p),pltcomp))) {
*v=p->ad;
return 0;
}
return -1;
}
|