00001
00002
00003
00004
00005
00006 #include<linux/linkage.h>
00007 #include<linux/mm.h>
00008 #include <asm/uaccess.h>
00009
00010 #include<starlet.h>
00011
00012 #include<descrip.h>
00013
00014 #include<iafdef.h>
00015 #include<ihadef.h>
00016 #include<ihddef.h>
00017 #include<ihidef.h>
00018 #include<ihpdef.h>
00019 #include<ihsdef.h>
00020 #include<ihvndef.h>
00021 #include<isddef.h>
00022 #include<shldef.h>
00023
00024 #include<imcbdef.h>
00025
00026 #include<va_rangedef.h>
00027
00028 #include<system_data_cells.h>
00029
00030 #include<ssdef.h>
00031
00032 #include<kfedef.h>
00033 #include <exe_routines.h>
00034 #include <misc_routines.h>
00035 #include <linux/slab.h>
00036
00037 #include <fcbdef.h>
00038 #include <fabdef.h>
00039 #include <rabdef.h>
00040
00041 #include <vfddef.h>
00042
00043 #include <linux/file.h>
00044
00045 int img_known_image(struct dsc$descriptor * name, void ** kfe_p) {
00046 struct _kfe * kfe = exe_gl_known_files;
00047 for (;kfe;kfe = kfe->kfe_l_kfelink) {
00048 char * tmpstr;
00049 char * kfestr = &kfe->kfe_l_obsolete_1;
00050 tmpstr = strrchr(kfestr,']');
00051 if (tmpstr==0)
00052 tmpstr=strrchr(kfestr,':');
00053 if (tmpstr==0)
00054 tmpstr=strrchr(kfestr,'/');
00055 if (tmpstr)
00056 kfestr=tmpstr+1;
00057 char * namestr=name->dsc_a_pointer;
00058 int namelen=name->dsc_w_length;
00059 tmpstr = strrchr(namestr,']');
00060 if (tmpstr==0)
00061 tmpstr=strrchr(namestr,':');
00062 if (tmpstr==0)
00063 tmpstr=strrchr(namestr,'/');
00064 if (tmpstr)
00065 namelen-=1+tmpstr-namestr;
00066 if (tmpstr)
00067 namestr=tmpstr+1;
00068 if (0==strncmp(kfestr,namestr,namelen)) {
00069 if (kfe_p)
00070 *kfe_p=kfe;
00071 return 1;
00072 }
00073 }
00074 return 0;
00075 }
00076
00077 asmlinkage int exe_imgact_wrap(struct struct_args * s) {
00078 return exe_imgact(s->s1,s->s2,s->s3,s->s4,s->s5,s->s6,s->s7,s->s8);
00079 }
00080
00081 asmlinkage int exe_imgact(void * name, void * dflnam, void * hdrbuf, unsigned long imgctl, unsigned long long * inadr, unsigned long long * retadr, unsigned long long * ident, unsigned long acmode) {
00082 struct dsc_descriptor *dscname=name;
00083 struct dsc_descriptor *dscdflnam=dflnam;
00084 struct file * f;
00085 struct _ihd * header=hdrbuf;
00086 struct _ihd * ehdr32=header;
00087 #ifdef CONFIG_VMS
00088 struct _iha * active;
00089 struct _isd * section;
00090 struct _ihi * ihid;
00091 struct _ihvn * vers;
00092 struct _ihs * debug;
00093 struct _va_range img_inadr;
00094 char * buffer;
00095 mm_segment_t fs;
00096 loff_t pos=0;
00097 int no;
00098 struct _imcb * im = kmalloc(sizeof(struct _imcb),GFP_KERNEL);
00099 memset(im,0,sizeof(struct _imcb));
00100
00101 f=rms_open_exec(dscdflnam->dsc_a_pointer);
00102 if (f==0) {
00103 kfree(im);
00104 return 0;
00105 }
00106 struct vms_fd * vms_fd = fget(f);
00107 struct _rabdef * rab = vms_fd->vfd_l_fd_p;
00108 struct _fabdef * fab = rab->rab_l_fab;
00109 int chan = fab->fab_l_stv;
00110 #if 0
00111 printk("imgact chan %x\n",chan);
00112 struct _ccb * ccb = &ctl_ga_ccb_table[chan];
00113 ccb->ccb_l_wind = 0;
00114 #endif
00115
00116 struct _kfe * kfe;
00117 if (img_known_image(dscdflnam,&kfe))
00118 ctl_gl_pcb->pcb$l_priv|=kfe->kfe$q_procpriv;
00119
00120
00121 im->imcb_l_context=f;
00122 #if 0
00123 fs = get_fs();
00124 set_fs(KERNEL_DS);
00125 rms_generic_file_read(f, header, 512, &pos);
00126 set_fs(fs);
00127 #else
00128 kernel_read(f, 0, header, 512);
00129 #endif
00130
00131 sys_close(f);
00132 if (ehdr32->ihd_w_majorid!=IHD$K_MAJORID || ehdr32->ihd$w_minorid!=IHD$K_MINORID) {
00133 return exe_imgact_elf(dscdflnam,ehdr32);
00134 }
00135
00136 im->imcb_l_flink=img$gl_imcb_list;
00137 img_gl_imcb_list=im;
00138
00139 int base = 0;
00140 if (inadr) {
00141 struct _va_range * addr = inadr;
00142 base = addr->va_range_ps_start_va;
00143 }
00144
00145 active=(unsigned long)ehdr32+ehdr32->ihd_w_activoff;
00146 section=(unsigned long)ehdr32+ehdr32->ihd_w_size;
00147 ihid=(unsigned long)ehdr32+ehdr32->ihd_w_imgidoff;
00148 vers=(unsigned long)ehdr32+ehdr32->ihd_w_version_array_off;
00149 debug=(unsigned long)ehdr32+ehdr32->ihd_w_symdbgoff;
00150
00151
00152 #if 0
00153 img_inadr.va_range_ps_start_va=0x3e000000;
00154 img_inadr.va_range_ps_end_va=0x3e000000+(((f->f_dentry->d_inode->i_size>>12)+1)<<12);
00155 exe_create_region_32 ((f->f_dentry->d_inode->i_size>>12)+1,0x45|_PAGE_RW ,0x187500 ,0,0,0,img_inadr.va_range$ps_start_va);
00156 exe_crmpsc(&img_inadr,0,0,0,0,0,0,f,0,ctl$gl_iaflnkptr,0,0);
00157 #endif
00158
00159 if (ehdr32->ihd_w_majorid!=IHD$K_MAJORID)
00160 return 0;
00161
00162 buffer=section;
00163
00164 while (section<(buffer+512*ehdr32->ihd_b_hdrblkcnt)) {
00165 if (section->isd_w_size==0)
00166 break;
00167 if (section->isd_w_size==0xffffffff) {
00168 int no=((unsigned long)section-(unsigned long)buffer)>>9;
00169 section=buffer+512*(no+1);
00170 continue;
00171 }
00172 if (section->isd_v_gbl==1) {
00173 goto skip_it;
00174 }
00175 int rw = section->isd_l_flags&(ISD$M_WRT|ISD$M_FIXUPVEC);
00176
00177 img_inadr.va_range_ps_start_va=base+(section->isd$v_vpn<<PAGE_SHIFT);
00178 img_inadr.va_range_ps_end_va=img_inadr.va_range$ps_start_va+section->isd$w_pagcnt*PAGE_SIZE;
00179 #ifdef __arch_um__
00180 exe_create_region_32 (section->isd$w_pagcnt*PAGE_SIZE,0x51 ,0x187500 ,0,0,0,img_inadr.va_range$ps_start_va);
00181 #else
00182 int rwfl=0;
00183 if (rw)
00184 rwfl=_PAGE_RW;
00185 exe_create_region_32 (section->isd$w_pagcnt*PAGE_SIZE,0x45|rwfl ,0x187500 ,0,0,0,img_inadr.va_range$ps_start_va);
00186 #endif
00187
00188 exe_crmpsc(&img_inadr,0,0,0,0,0,0,chan,0,section->isd$l_vbn,0,0);
00189 skip_it:
00190 section=(unsigned long)section+section->isd_w_size;
00191 }
00192
00193 struct _iaf * iaf=(unsigned long)base+(((int)ehdr32->ihd_l_iafva)<<9);
00194 iaf->iaf_l_fixuplnk=ctl$gl_fixuplnk;
00195 ctl_gl_fixuplnk=iaf;
00196 iaf->iaf_l_iaflink=hdrbuf;
00197 iaf->iaf_l_permctx=base;
00198 section=buffer;
00199
00200 no=0;
00201
00202 while (section<(buffer+512*ehdr32->ihd_b_hdrblkcnt)) {
00203 if (section->isd_w_size==0)
00204 break;
00205 if (section->isd_w_size==0xffffffff) {
00206 int no=((unsigned long)section-(unsigned long)buffer)>>9;
00207 section=buffer+512*(no+1);
00208 continue;
00209 }
00210 if (section->isd_v_gbl==0) {
00211 goto skip_it2;
00212 }
00213
00214 int sts;
00215 char * path;
00216 int pathlen;
00217 path="SYS_LIBRARY:";
00218 pathlen=strlen(path);
00219 char image[256];
00220 memset(image,0,256);
00221 char * imagebase=§ion->isd_t_gblnam;
00222 char * imgnam = imagebase;
00223 int len = strlen(imgnam);
00224 memcpy(image,path,pathlen);
00225 memcpy(image+pathlen,imagebase,strlen(imagebase));
00226 #if 0
00227 memcpy(image+pathlen+strlen(imagebase),".exe",4);
00228 image[pathlen+strlen(imagebase)+4]=0;
00229 #endif
00230
00231 struct dsc_descriptor aname;
00232 struct dsc_descriptor dflnam;
00233 aname.dsc_w_length=len;
00234 aname.dsc_a_pointer=imgnam;
00235 dflnam.dsc_w_length=pathlen+strlen(imagebase)+4*0;
00236 dflnam.dsc_a_pointer=image;
00237
00238 char * hdrbuf=kmalloc(512,GFP_KERNEL);
00239 memset(hdrbuf, 0, 512);
00240
00241 img_inadr.va_range_ps_start_va=img_inadr.va_range$ps_end_va;
00242 img_inadr.va_range_ps_end_va=0;
00243
00244 struct _shl * shlst = (long)iaf+iaf->iaf_l_shlstoff;
00245 int shli=no;
00246 shlst[shli].shl_l_baseva=img_inadr.va_range$ps_start_va;
00247
00248 struct _iaf * tmpiaf=ctl_gl_fixuplnk;
00249 for(;tmpiaf;tmpiaf=tmpiaf->iaf_l_fixuplnk) {
00250 struct _ihd * ihd=tmpiaf->iaf_l_iaflink;
00251 struct _ihi * ihi=(unsigned long)ihd+ihd->ihd_w_imgidoff;
00252
00253 if (0==strncmp(&ihi->ihi_t_imgnam[1],imgnam,ihi->ihi$t_imgnam[0])) {
00254
00255 int shli=no;
00256 struct _shl * shlst2=(long)tmpiaf+tmpiaf->iaf_l_shlstoff;
00257 shlst[shli].shl_l_baseva=shlst2[0].shl$l_baseva;
00258 goto skip_it2;
00259 }
00260 }
00261
00262 struct _va_range out;
00263 printk("Loading image %s from %s\n",imgnam,image);
00264 sts=exe_imgact(&aname,&dflnam,hdrbuf,0,&img_inadr,&out,0,0);
00265 kfree(hdrbuf);
00266 img_inadr.va_range_ps_start_va=out.va_range$ps_end_va;
00267 img_inadr.va_range_ps_end_va=out.va_range$ps_end_va;
00268
00269 printk("imgact got sts %x\n",sts);
00270 #if 0
00271 sts=exe_imgfix();
00272 printf("imgfix got sts %x\n",sts);
00273 #endif
00274
00275 #if 0
00276 int rw = section->isd_l_flags&ISD$M_WRT;
00277
00278 img_inadr.va_range_ps_start_va=section->isd$v_vpn<<PAGE_SHIFT;
00279 img_inadr.va_range_ps_end_va=img_inadr.va_range$ps_start_va+section->isd$w_pagcnt*PAGE_SIZE;
00280 #ifdef __arch_um__
00281 exe_create_region_32 (section->isd$w_pagcnt*PAGE_SIZE,0x51 ,0x187500 ,0,0,0,img_inadr.va_range$ps_start_va);
00282 #else
00283 int rwfl=0;
00284 if (rw)
00285 rwfl=_PAGE_RW;
00286 exe_create_region_32 (section->isd$w_pagcnt*PAGE_SIZE,0x45|rwfl ,0x187500 ,0,0,0,img_inadr.va_range$ps_start_va);
00287 #endif
00288
00289 exe_crmpsc(&img_inadr,0,0,0,0,0,0,f,0,section->isd$l_vbn,0,0);
00290 #endif
00291 skip_it2:
00292 section=(unsigned long)section+section->isd_w_size;
00293 no++;
00294 }
00295
00296 if (retadr) {
00297 struct _va_range * r=retadr;
00298 r->va_range_ps_start_va=0;
00299 r->va_range_ps_end_va=img_inadr.va_range$ps_end_va;
00300 }
00301
00302 #else
00303 loff_t pos=0;
00304 mm_segment_t fs;
00305 #ifndef CONFIG_VMS
00306 f=open_exec(dscdflnam->dsc_a_pointer);
00307 if (f==0) return 0;
00308 #endif
00309 #if 0
00310 fs = get_fs();
00311 set_fs(KERNEL_DS);
00312 generic_file_read(f, header, 512, &pos);
00313 set_fs(fs);
00314 #else
00315 kernel_read(f, 0, header, 512);
00316 #endif
00317 return exe_imgact_elf(dscdflnam,ehdr32);
00318 #endif
00319 }
00320