home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / sml_nj / 93src.lha / src / runtime / export.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-02-09  |  19.6 KB  |  765 lines

  1. /* export.c
  2.  *
  3.  * COPYRIGHT (c) 1989 by AT&T Bell Laboratories.
  4.  */
  5.  
  6. #include "tags.h"
  7. #include "ml_os.h"
  8.  
  9. #define bulletproofWrite(a,b,c) if (bulletproofWrite0(a,b,c)) return 1;else{}
  10.  
  11. #ifdef THINK_C
  12. #include <unix.h>
  13. #include <fcntl.h>
  14. #include <errno.h>
  15. #else
  16. #ifdef NeXT
  17. #ifdef NeXT_3_0
  18. #include <mach-o/loader.h>
  19. #else
  20. #include <sys/loader.h>
  21. #endif
  22. #else
  23. #include <a.out.h>
  24. #endif NeXT
  25. #endif THINK_C
  26.  
  27. #define CEIL(x,quantum) ((((int)(x))+(quantum)-1)&~((quantum)-1))
  28.  
  29. #ifdef MIPS
  30. #define N_DATADDR 0x10000000
  31. #define N_TXTADDR 0x400000 /* start of headers; text segment follows */
  32. #define getpagesize() 4096
  33. #endif
  34.  
  35. #ifdef AUX
  36. #define N_TXTADDR 0x0 /* start of headers; text segment follows */
  37. #define N_DATADDR ah->data_start
  38. #endif
  39.  
  40. #ifdef HPUX
  41. #  define N_DATADDR DATA_OFFSET
  42. #endif HPUX
  43.  
  44. #ifdef NS32
  45. #  define N_DATADDR(x)    0x400000
  46. #endif NS32
  47.  
  48. #if defined(I386) && defined(MACH)
  49. #  define N_DATADDR(x)    ETEXT
  50. #endif
  51.  
  52. #ifndef N_DATADDR
  53. #  define N_DATADDR(x)  CEIL((x).a_text,getpagesize())
  54. #endif
  55.  
  56. #if !defined(N_TXTADDR)
  57. #  ifdef NeXT
  58. #    ifdef NeXT_3_0
  59. #      include <mach/m68k/vm_param.h>
  60. #    else
  61. #      include <machine/vm_param.h>
  62. #    endif
  63. #    ifdef USRTEXT
  64. #      define N_TXTADDR(x)  USRTEXT
  65. #    endif USRTEXT
  66. #  endif
  67. #  ifdef VAX
  68. #    define N_TXTADDR(x)  0
  69. #  endif
  70. #  ifdef NS32
  71. #    define N_TXTADDR(x)  0
  72. #    define exec aouthdr
  73. #    define a_magic        magic
  74. #    define    a_text        tsize
  75. #    define a_data        dsize
  76. #    define    a_bss        bsize
  77. #    define    a_entry        entry
  78. #    define    a_trsize    text_start
  79. #    define    a_drsize    data_start
  80. #  endif
  81. #  ifdef SPARC
  82. #    include <machine/vmparam.h>
  83. #    define N_TXTADDR(x)  USRTEXT
  84. #  endif
  85. #  ifdef I386
  86. #    ifdef DYNIX
  87. #     define N_TXTADDR(x) N_ADDRADJ(x)
  88. #    else
  89. #     define N_TXTADDR(x) ((int) startptr)
  90. #    endif
  91. #  endif
  92. #  ifndef sony_news
  93. #    ifdef M68
  94. #      ifdef HPUX
  95. #        define N_TXTADDR TEXT_OFFSET
  96. #      else
  97. #        ifdef MORE
  98. #          define N_TXTADDR(x) 0
  99. #        else
  100. #          define N_TXTADDR(x)  getpagesize()
  101. #        endif MORE
  102. #      endif HPUX
  103. #    endif M68
  104. #  else sony_news
  105. #    define N_TXTADDR(x)  0
  106. #  endif /* !sony_news */
  107. #endif /* !N_TXTADDR */
  108.  
  109. #ifdef HPUX
  110. #  define ZMAGIC SHARE_MAGIC
  111. #endif HPUX
  112.  
  113. #ifdef AUX
  114. #  define ZMAGIC 0413
  115. #endif
  116.  
  117. #ifdef BSD386
  118. # ifdef ZMAGIC
  119. # undef ZMAGIC
  120. # endif ZMAGIC
  121. #define ZMAGIC QMAGIC
  122. #endif BSD386
  123.  
  124.  
  125. /* Garbage collection is already done.
  126.  * Data to be saved is:
  127.  *  0 -> ceil(etext)         text
  128.  *  ceil(etext) -> arenabase     data
  129.  *  arenabase -> old_high     heap
  130.  *  
  131.  *  > set a_entry as address of start procedure
  132.  */
  133.  
  134. extern int old_high;
  135.  
  136. static int textstart,datastart;
  137.  
  138. #ifdef MIPS
  139. extern long startptr[];        /* fool damn global pointer stuff */
  140. #else
  141. extern int startptr;
  142. #endif
  143.  
  144. #if defined(SPARC) && defined(MACH)
  145. getpagesize(){return 8192;}
  146. #endif
  147.  
  148. #if defined(HPUX) || defined(AUX)
  149. getpagesize(){return 4096;}
  150. #endif /* HPUX || AUX */
  151.  
  152. #ifdef V9
  153. getpagesize(){return 1024;}
  154. #endif
  155.  
  156. #if defined(VAX) || defined(MIPS) || defined(SPARC) || defined(M68) || defined(I386)
  157. #ifndef THINK_C
  158. #ifndef NeXT
  159. #ifndef MIPS
  160. #ifndef AUX
  161. int export (filid)  /* nonzero return means error occurred, check errno */
  162.     int filid;
  163. {
  164.     int bytcount;
  165.    static struct exec E;  /* make it static so all fields=0 */
  166.  
  167. #ifdef HPUX
  168.     E.a_magic.file_type = ZMAGIC;
  169.     E.a_magic.system_id = HP9000S200_ID;
  170. #ifdef M_DATA_WTHRU
  171.     E.a_miscinfo |= M_DATA_WTHRU;
  172. #endif
  173. #else
  174. #if defined(sun3) || (defined(SPARC) && !defined(MACH))
  175.     E.a_magic = NMAGIC;
  176. #else
  177. #  if defined(NS32)
  178.     E.a_magic = NS32GMAGIC;
  179. #  else
  180.     E.a_magic = ZMAGIC;
  181. #  endif
  182. #endif
  183. #endif
  184.  
  185. #if defined(M68) && (! defined(HPUX))
  186. #  ifndef sony_news
  187.     E.a_machtype = 2;    /* M_68020 */
  188. #  endif sony_news
  189. #  ifdef MORE
  190.     E.a_machtype = MID_HP300; /* M_68020 */
  191. #  else
  192.     E.a_machtype = M_68020; /* M_68020 */
  193. #  endif MORE
  194. #endif
  195. #ifdef SPARC
  196.     E.a_toolversion = 1;
  197.     E.a_machtype = M_SPARC;
  198. #endif
  199.  
  200.     textstart = N_TXTADDR(E);
  201. #ifdef HPUX
  202.     E.a_text = (int) CEIL((ETEXT+textstart),getpagesize())-textstart;
  203. #else
  204. # if defined(DYNIX)
  205.     E.a_text = (int) CEIL(ETEXT,getpagesize());
  206. # else
  207.     E.a_text = (int) CEIL(ETEXT,getpagesize())-textstart;
  208. # endif
  209. #if defined(SPARC) && defined(MACH)
  210.     datastart = (int) CEIL(ETEXT,getpagesize());
  211. #else
  212.     datastart = N_DATADDR(E);
  213. #endif /* !defined(SPARC) || !defined(MACH) */
  214.     E.a_bss = 0;
  215. #ifndef NS32
  216.     E.a_syms = 0;
  217. #endif NS32
  218. #endif HPUX
  219.     E.a_entry = startptr;
  220.     E.a_trsize = 0;
  221.     E.a_drsize = 0;
  222. #ifdef HPUX
  223.     E.a_data = CEIL(old_high-ETEXT, getpagesize());
  224. #else
  225.     E.a_data = CEIL(old_high-datastart, getpagesize());
  226. #endif HPUX
  227.     fchmod(filid,0755);
  228. #ifdef NS32
  229.     coff_cough (filid, &bytcount, E.a_text, E.a_data, E.a_entry);
  230. #else
  231.     bulletproofWrite(filid,&E,sizeof(E));
  232.     bytcount = sizeof(E);
  233. #endif NS32
  234. #if VAX || NS32
  235.     {int i, nzeros = getpagesize()-sizeof(E);
  236.     char zeros[1024];
  237.         for(i=0;i<nzeros;i++) zeros[i]=0;
  238.         bulletproofWrite(filid,zeros,nzeros);
  239.  
  240.     }
  241. #endif
  242. #if sony_news || MORE
  243.     {int i, nzeros = getpagesize()-bytcount;
  244.      char zeros[4096];
  245.      for(i=0;i<nzeros;i++) zeros[i]=0;
  246.      bulletproofWrite(filid,zeros,nzeros);
  247.     }
  248. #endif sony_news
  249. #ifdef HPUX
  250.     lseek(filid,N_TXTADDR(E),0);
  251.     bulletproofWrite(filid,0,E.a_text);
  252.     lseek(filid,N_DATADDR(E),0);
  253.     bulletproofWrite(filid,CEIL(ETEXT,getpagesize()),E.a_data);
  254. #else
  255. #if defined(SPARC) && defined(MACH) || defined(BSD386)
  256.     bulletproofWrite(filid,textstart+sizeof(E),E.a_text-sizeof(E));
  257. #else
  258. # if defined(DYNIX)
  259.      bulletproofWrite(filid,textstart+sizeof(E),E.a_text-sizeof(E)-N_ADDRADJ(E))
  260. # else
  261.      bulletproofWrite(filid,textstart,E.a_text);
  262. # endif
  263. #endif /* !defined(SPARC) || !defined(MACH) && !defined(BSD386) */
  264.     bulletproofWrite(filid,datastart,E.a_data);
  265. #endif HPUX
  266.     return 0;
  267. }
  268.  
  269. #ifdef NS32
  270. coff_cough(fd,countp,tsize,dsize,entry)
  271. int fd, *countp, tsize, dsize, entry;
  272. {
  273. static struct filehdr fhdr;
  274. static struct aouthdr ahdr;
  275. static struct scnhdr thdr;
  276. static struct scnhdr dhdr;
  277. static struct scnhdr bhdr;
  278. int allhdrsize = sizeof(fhdr) + sizeof(ahdr) + 3*sizeof(thdr);
  279. int pagesize = getpagesize();
  280.  
  281. fhdr.f_magic = NS32GMAGIC;
  282. fhdr.f_nscns = 3;
  283. fhdr.f_timdat = /* don't care */ 0;
  284. fhdr.f_symptr = /* null? */ 0;
  285. fhdr.f_nsyms = 0;
  286. fhdr.f_opthdr = sizeof(struct aouthdr);
  287. fhdr.f_flags = F_RELFLG|F_EXEC|F_LNNO|F_LSYMS|F_AR32WR;
  288.  
  289. ahdr.magic = /* OOPS */ 0x010b;
  290. ahdr.vstamp = /* don't care */ 0;
  291. ahdr.tsize = tsize;
  292. ahdr.dsize = dsize;
  293. ahdr.bsize = 0;
  294. ahdr.msize = /* OOPS */ 0x10;
  295. ahdr.mod_start = /* OOPS */ 0x20;
  296. ahdr.entry = entry;
  297. ahdr.text_start = 0;
  298. ahdr.data_start = 0x400000;
  299. ahdr.entry_mod = /* unused? */ 0;
  300. ahdr.flags = U_SYS_42|U_AL_4096;
  301.  
  302. strncpy(thdr.s_name,_TEXT,8);
  303. thdr.s_paddr = thdr.s_vaddr = ahdr.data_start;
  304. thdr.s_size = ahdr.tsize;
  305. thdr.s_scnptr = CEIL(allhdrsize,pagesize);
  306. thdr.s_relptr = /* null? */ 0;
  307. thdr.s_lnnoptr = /* null? */ 0;
  308. thdr.s_nreloc = 0;
  309. thdr.s_nlnno = 0;
  310. thdr.s_flags = STYP_TEXT;
  311. thdr.s_symptr = /* null? */ 0;
  312. thdr.s_modno = /* OOPS */ 0;
  313. thdr.s_pad = /* don't care */ 0;
  314.  
  315. strncpy(dhdr.s_name,_DATA,8);
  316. dhdr.s_paddr = dhdr.s_vaddr = ahdr.data_start;
  317. dhdr.s_size = ahdr.dsize;
  318. dhdr.s_scnptr = thdr.s_scnptr + CEIL(thdr.s_size,pagesize);
  319. dhdr.s_relptr = /* null? */ 0;
  320. dhdr.s_lnnoptr = /* null? */ 0;
  321. dhdr.s_nreloc = 0;
  322. dhdr.s_nlnno = 0;
  323. dhdr.s_flags = STYP_DATA;
  324. dhdr.s_symptr = /* null? */ 0;
  325. dhdr.s_modno = /* OOPS */ 0;
  326. dhdr.s_pad = /* don't care */ 0;
  327.  
  328. strncpy(bhdr.s_name,_BSS,8);
  329. bhdr.s_paddr = bhdr.s_vaddr = ahdr.data_start + ahdr.dsize;
  330. bhdr.s_size = /* none */ 0;
  331. bhdr.s_scnptr = /* null */ 0;
  332. bhdr.s_relptr = /* null? */ 0;
  333. bhdr.s_lnnoptr = /* null? */ 0;
  334. bhdr.s_nreloc = 0;
  335. bhdr.s_nlnno = 0;
  336. bhdr.s_flags = STYP_BSS;
  337. bhdr.s_symptr = /* null? */ 0;
  338. bhdr.s_modno = /* OOPS */ 0;
  339. bhdr.s_pad = /* don't care */ 0;
  340.  bulletproofWrite(fd,&fhdr,sizeof(fhdr));
  341.  bulletproofWrite(fd,&ahdr,sizeof(ahdr));
  342.  bulletproofWrite(fd,&thdr,sizeof(thdr));
  343.  bulletproofWrite(fd,&dhdr,sizeof(dhdr));
  344.  bulletproofWrite(fd,&bhdr,sizeof(bhdr));
  345.  *countp = allhdrsize;
  346.  return 0;
  347. }
  348. #endif NS32
  349. #else AUX
  350.  
  351. #include <stdio.h>
  352. #ifdef __STDC__
  353. #define insist(condition) do { if (!(condition)) { \
  354.     chatting("==> Inconsistent object for export: !(%s)\n", #condition); \
  355.     return 1; } } while(0)
  356. #else
  357. #define insist(condition) do { if (!(condition)) { \
  358.     chatting("==> Inconsistent object for export: !(%s)\n", "condition"); \
  359.     return 1; } } while(0)
  360. #endif
  361.  
  362. int export (filid) /*nonzero return means error, check errno */
  363.     int filid;
  364. {
  365.     int i;
  366.     int dataremaining;        /* # of bytes left in data *segment* */
  367.     int textcount;        /* # of bytes in text segment */
  368.     int seendata;        /* true iff have seen .data *section* hdr */
  369. #define HDBUF 512
  370.     char headerbuffer[HDBUF];
  371.  
  372. #define AOUTHSZ sizeof(AOUTHDR)
  373.  
  374.     /* A/UX stores header information at N_TXTADDR */
  375.     struct filehdr *fh = (FILHDR *) headerbuffer;
  376.     struct aouthdr *ah = (AOUTHDR *) (headerbuffer + FILHSZ);
  377.     struct scnhdr *sh = (SCNHDR *) (headerbuffer + FILHSZ + AOUTHSZ);
  378.  
  379.     int headersize = FILHSZ+AOUTHSZ+(((FILHDR *) N_TXTADDR)->f_nscns * SCNHSZ);
  380.  
  381.     insist(headersize <= HDBUF);
  382.  
  383.     memcpy(headerbuffer, N_TXTADDR, headersize);  /* copy headers for mods */
  384.  
  385.     /* validate & adjust file header */
  386.     insist(fh->f_magic == MC68MAGIC);
  387.     fh->f_symptr = 0;
  388.     fh->f_nsyms = 0;
  389.     insist(fh->f_opthdr == sizeof(*ah));
  390.     fh->f_flags = F_RELFLG|F_EXEC|F_LNNO|F_LSYMS|F_AR32W; /* stripped */
  391.  
  392.     /* validate & adjust optional header */
  393.     insist(ah->magic == ZMAGIC);
  394.     insist(ah->tsize == ETEXT - (N_TXTADDR + headersize));
  395.     ah->dsize = old_high - N_DATADDR;
  396.     ah->bsize = 0;
  397.     insist(ah->entry == startptr);
  398.     insist(ah->text_start == N_TXTADDR + headersize);
  399.  
  400.     /* adjust section headers */
  401.     textcount = 0;
  402.     dataremaining = ah->dsize;
  403.     seendata = 0;
  404.     for (i=0; i<fh->f_nscns; i++, sh++) {
  405.     insist(sh->s_paddr == sh->s_vaddr);
  406.     insist(sh->s_relptr == 0);
  407.     sh->s_lnnoptr = 0;
  408.     insist(sh->s_nreloc == 0);
  409.     sh->s_nlnno = 0;
  410.     switch(sh->s_flags) {
  411.       case STYP_TEXT:
  412.         insist(sh->s_scnptr == headersize);
  413.         textcount += sh->s_size;
  414.         break;
  415.       case STYP_DATA:
  416.       case STYP_BSS:
  417.         if (seendata) { /* turn into a dummy section */
  418.         sh->s_paddr = sh->s_vaddr = ah->data_start + ah->dsize;
  419.         sh->s_size = 0;
  420.         sh->s_scnptr = 0;
  421.         } else {
  422.         insist((sh->s_flags & STYP_BSS) == 0);
  423.         if (sh->s_flags == STYP_DATA) {
  424.             sh->s_size = dataremaining;
  425.             seendata = 1;
  426.         } else {
  427.             dataremaining -= sh->s_size;
  428.         }
  429.         }
  430.         break;
  431.       default: insist(0);
  432.     }
  433.     }
  434.     insist(textcount == ah->tsize);
  435.  
  436.     fchmod(filid,0755);
  437.     bulletproofWrite(filid,fh,headersize); /* headers */
  438.     bulletproofWrite(filid,N_TXTADDR+headersize,ah->tsize); /* text */
  439.     bulletproofWrite(filid,N_DATADDR,ah->dsize); /* data */
  440.     return 0;
  441. }
  442. #endif AUX
  443. #else MIPS
  444.  
  445. /* See MIPS Assembly language programmer's guide, 
  446.    Chapter 9 (Object file format) */
  447.  
  448. #include <stdio.h>
  449. #ifdef __STDC__
  450. #define insist(condition) do { if (!(condition)) { \
  451.     chatting("==> Inconsistent object for export: !(%s)\n", #condition); \
  452.     return 1; } } while(0)
  453. #else
  454. #define insist(condition) do { if (!(condition)) { \
  455.     chatting("==> Inconsistent object for export: !(%s)\n", "condition"); \
  456.     return 1; } } while(0)
  457. #endif
  458. /* #define verbose chatting */
  459. static verbose(){}
  460.  
  461. #undef export
  462.  
  463. int export (filid) /*nonzero return means error, check errno */
  464.     int filid;
  465. {
  466.      /* plan: increase .data section to get up to old_high, make following
  467.        sections zero */
  468.  
  469.     int bytcount;
  470.     int i;
  471.     int dataremaining;        /* # of bytes left in data *segment* */
  472.     int textcount;        /* # of bytes in text segment */
  473.     int seendata;        /* true iff have seen .data *section* hdr */
  474. #define HDBUF 512
  475.    char headerbuffer[HDBUF];
  476.     
  477.  
  478.     /* MIPS stores header information at N_TXTADDR */
  479.     struct filehdr *fh = (struct filehdr *) headerbuffer;
  480.     struct aouthdr *ah = (struct aouthdr *) (headerbuffer + sizeof(*fh));
  481.     struct scnhdr *sh = (struct scnhdr *) (headerbuffer + sizeof(*fh) + sizeof(*ah));
  482.  
  483.     int headersize = sizeof(*fh)+sizeof(*ah)+
  484.                        (((struct filehdr *) N_TXTADDR)->f_nscns * sizeof(*sh));
  485.  
  486.  
  487.  
  488.     headersize = CEIL(headersize,16);
  489.  
  490.     insist(headersize <= HDBUF);
  491.  
  492.     memcpy(headerbuffer, N_TXTADDR, headersize);  /* copy headers for mods */
  493.  
  494.     /* validate & adjust file header */
  495. #ifdef MIPSEB
  496.     insist(fh->f_magic == MIPSEBMAGIC);  /* big-endian */
  497. #else
  498.     insist(fh->f_magic == MIPSELMAGIC);  /* little-endian */
  499. #endif
  500.  
  501.     if (fh->f_symptr || fh->f_nsyms) {
  502.     verbose("Discarding %d bytes of symbolic header & symbol table info\n",
  503.         fh->f_nsyms);
  504.     fh->f_symptr = 0;
  505.     fh->f_nsyms = 0;
  506.     }
  507.     insist(fh->f_opthdr == sizeof(*ah));
  508.     fh->f_flags = F_RELFLG | F_EXEC | F_LNNO | F_LSYMS; /* stripped */
  509.     verbose("validated file header\n");
  510.  
  511.     /* validate & adjust optional header */
  512.     insist(ah->magic == ZMAGIC);
  513.     insist(ah->tsize == CEIL (((int) &etext)-N_TXTADDR, getpagesize()));
  514.     ah->dsize = CEIL(old_high - N_DATADDR,getpagesize());
  515.     ah->bsize = 0;
  516.     insist(ah->entry == startptr[0]);
  517.     insist(ah->text_start == N_TXTADDR);
  518.     insist(ah->data_start == N_DATADDR);
  519.     ah->bss_start = CEIL(ah->data_start+ah->dsize, getpagesize());
  520.     /* don't change masks or gp value */
  521.     verbose("validated optional header\n");
  522.  
  523.     /* adjust section headers */
  524.     textcount = 0;
  525.     dataremaining = ah->dsize;
  526.     seendata = 0;
  527.     for (i=0; i<fh->f_nscns; i++, sh++) {
  528.     insist(sh->s_paddr == sh->s_vaddr);
  529.     insist(sh->s_relptr == 0);
  530.     sh->s_lnnoptr = 0;    /* Destroy gp tables */
  531.     insist(sh->s_nreloc == 0);
  532.     insist(sh->s_nlnno == 0);
  533.     switch(sh->s_flags) {
  534.       case STYP_TEXT:
  535.         insist(sh->s_scnptr == headersize);    /* fall through */
  536.       case STYP_INIT:
  537.         textcount += sh->s_size;
  538.         break;
  539.       case STYP_RDATA:
  540.       case STYP_DATA:
  541.       case STYP_LIT8:
  542.       case STYP_LIT4:
  543.       case STYP_SDATA:
  544.       case STYP_SBSS:
  545.       case STYP_BSS:
  546.         if (seendata) { /* turn into a dummy section */
  547.         sh->s_paddr = sh->s_vaddr = ah->data_start + ah->dsize;
  548.         sh->s_size = 0;
  549.         sh->s_scnptr = 0;
  550.         } else {
  551.         insist((sh->s_flags & (STYP_SBSS | STYP_BSS)) == 0);
  552.         if (sh->s_flags == STYP_DATA) {
  553.             sh->s_size = dataremaining;
  554.             seendata = 1;
  555.         } else {
  556.             dataremaining -= sh->s_size;
  557.         }
  558.         }
  559.         break;
  560. #if defined(SGI)  && defined(_STYP_RESOURCE)
  561.        case _STYP_RESOURCE: break;    /* appears under v 4.0 */
  562. #endif
  563. #if defined(STYP_COMMENT)
  564.     /* the following appears on SGI, compiler version 3.10 */
  565.       case STYP_COMMENT: break;
  566. #endif
  567.       default: insist(0);
  568.     }
  569.     verbose("Adjusted %s section\n", sh->s_name);
  570.     }
  571.     insist(CEIL(textcount + headersize,getpagesize())==ah->tsize);
  572.  
  573.     fchmod(filid,0755);
  574.     bulletproofWrite(filid,fh,headersize); /* headers */
  575.     bulletproofWrite(filid,N_TXTADDR+headersize,ah->tsize-headersize); /* text */
  576.     bulletproofWrite(filid,N_DATADDR,ah->dsize); /* data */
  577.  return 0;
  578. }
  579. #endif MIPS
  580. #else NeXT
  581. #ifdef NeXT_3_0
  582. #include <mach/m68k/thread_status.h>
  583. #define NeXT_THREAD_STATE_REGS M68K_THREAD_STATE_REGS
  584. #define NeXT_THREAD_STATE_REGS_COUNT M68K_THREAD_STATE_REGS_COUNT
  585. #define NeXT_thread_state_regs m68k_thread_state_regs
  586. #endif
  587. extern int mach_maplimit;
  588. int export(filid) int filid;  /* nonzero return means error, check errno */
  589. {static struct mach_header E;  /* make it static so all fields=0 */
  590. static struct segment_command tcmd;
  591. static struct section tsectn;
  592. static struct segment_command dcmd;
  593. static struct section dsectn;
  594. static struct section bsectn;
  595. static struct thread_command uthr;
  596. static unsigned long thflavor;
  597. static unsigned long thcount;
  598. static struct NeXT_thread_state_regs ntregs;
  599. static unsigned int hdrsize;
  600. static unsigned int lcmd[] = {
  601.       /* this is the hex representation of the load commands to load the C shared
  602.        * library (contributed by oneill@cs.sfu.ca)
  603.        */
  604.     0x00000006, 0x00000030, 0x00000014, 0x0000002c,
  605.     0x05000000, 0x2f757372, 0x2f73686c, 0x69622f6c,
  606.     0x69627379, 0x735f732e, 0x422e7368, 0x6c696200
  607.     };
  608. int datasize, bsssize;
  609.  
  610. E.magic = MH_MAGIC;
  611. #ifdef CPU_SUBTYPE_NeXT
  612. /** NeXT 1.0 **/  /* this probably doesn't work anymore */
  613. E.cputype = CPU_TYPE_MC68030;
  614. E.cpusubtype = CPU_SUBTYPE_NeXT;
  615. #else
  616. /** NeXT 2.0 **/
  617. E.cputype = CPU_TYPE_MC680x0;
  618. E.cpusubtype = CPU_SUBTYPE_MC68040;
  619. #endif
  620. E.filetype = MH_EXECUTE;
  621. E.ncmds = 4;
  622. E.sizeofcmds = sizeof(tcmd) + sizeof(tsectn)
  623.     + sizeof(dcmd) + sizeof(dsectn) + sizeof(bsectn) + sizeof(lcmd)
  624.     + sizeof(uthr) + sizeof(thflavor) + sizeof(thcount) + sizeof(ntregs);
  625. E.flags = MH_NOUNDEFS;
  626.  
  627. hdrsize = E.sizeofcmds + sizeof(E);
  628.  textstart = N_TXTADDR(E);
  629.  
  630.  
  631. tcmd.cmd = LC_SEGMENT;
  632. tcmd.cmdsize = sizeof(tcmd) + sizeof(tsectn);
  633. strcpy(tcmd.segname,SEG_TEXT);
  634. tcmd.vmaddr = textstart;
  635. tcmd.vmsize = (int) CEIL(ETEXT,getpagesize())-textstart;
  636. tcmd.fileoff = 0;
  637. tcmd.filesize = tcmd.vmsize;
  638. tcmd.maxprot = VM_PROT_ALL;
  639. tcmd.initprot = VM_PROT_READ|VM_PROT_EXECUTE;
  640. tcmd.nsects = 1;
  641. tcmd.flags = 0;
  642.  
  643. strcpy(tsectn.sectname,SECT_TEXT);
  644. strcpy(tsectn.segname,tcmd.segname);
  645. tsectn.addr = tcmd.vmaddr + hdrsize;
  646. tsectn.size = tcmd.vmsize - hdrsize;
  647. tsectn.offset = hdrsize;
  648. tsectn.align = 2;
  649. tsectn.reloff = 0;
  650. tsectn.nreloc = 0;
  651. tsectn.flags = 0;
  652. tsectn.reserved1 = tsectn.reserved2 = 0;
  653.  
  654.  
  655. dcmd.cmd = LC_SEGMENT;
  656. dcmd.cmdsize = sizeof(dcmd) + sizeof(dsectn) + sizeof(bsectn);
  657. strcpy(dcmd.segname,SEG_DATA);
  658. dcmd.vmaddr = tcmd.vmaddr + tcmd.vmsize;
  659. datasize = CEIL(old_high-dcmd.vmaddr, getpagesize());
  660. bsssize = mach_maplimit-old_high;
  661. dcmd.vmsize = bsssize+datasize;
  662. dcmd.fileoff = tcmd.fileoff + tcmd.filesize;
  663. dcmd.filesize = datasize;
  664. dcmd.maxprot = VM_PROT_ALL;
  665. dcmd.initprot = VM_PROT_ALL;
  666. dcmd.nsects = 2;
  667. dcmd.flags = 0;
  668.  
  669. strcpy(dsectn.sectname,SECT_DATA);
  670. strcpy(dsectn.segname,dcmd.segname);
  671. dsectn.addr = dcmd.vmaddr;
  672. dsectn.size = datasize;
  673. dsectn.offset = dcmd.fileoff;
  674. dsectn.align = 2;
  675. dsectn.reloff = 0;
  676. dsectn.nreloc = 0;
  677. dsectn.flags = 0;
  678. dsectn.reserved1 = dsectn.reserved2 = 0;
  679.  
  680. strcpy(bsectn.sectname,SECT_BSS);
  681. strcpy(bsectn.segname,dcmd.segname);
  682. bsectn.addr = dsectn.addr + dsectn.size;
  683. bsectn.size = bsssize;
  684. bsectn.offset = 0;
  685. bsectn.align = 2;
  686. bsectn.reloff = 0;
  687. bsectn.nreloc = 0;
  688. bsectn.flags = S_ZEROFILL;
  689. bsectn.reserved1 = bsectn.reserved2 = 0;
  690.  
  691. uthr.cmd = LC_UNIXTHREAD;
  692. uthr.cmdsize = sizeof(uthr) + sizeof(thflavor) + sizeof(thcount) + sizeof(ntregs);
  693.  
  694. thflavor = NeXT_THREAD_STATE_REGS;
  695.  
  696. thcount = NeXT_THREAD_STATE_REGS_COUNT;
  697.  
  698. ntregs.areg[0] = 0xfeadface;
  699. ntregs.pc = startptr;
  700.  
  701.  fchmod(filid,0755);
  702.  bulletproofWrite(filid,&E,sizeof(E));
  703.  bulletproofWrite(filid,&tcmd,sizeof(tcmd));
  704.  bulletproofWrite(filid,&tsectn,sizeof(tsectn));
  705.  bulletproofWrite(filid,&dcmd,sizeof(dcmd));
  706.  bulletproofWrite(filid,&dsectn,sizeof(dsectn));
  707.  bulletproofWrite(filid,&bsectn,sizeof(bsectn));
  708.  bulletproofWrite(filid,&lcmd,sizeof(lcmd));
  709.  bulletproofWrite(filid,&uthr,sizeof(uthr));
  710.  bulletproofWrite(filid,&thflavor,sizeof(thflavor));
  711.  bulletproofWrite(filid,&thcount,sizeof(thcount));
  712.  bulletproofWrite(filid,&ntregs,sizeof(ntregs));
  713.  bulletproofWrite(filid,tsectn.addr,tsectn.size);
  714.  bulletproofWrite(filid,dsectn.addr,dsectn.size);
  715.  return 0;
  716. }
  717. #endif NeXT
  718. #else THINK_C
  719. /* export defined in MacExpImp.c */
  720. #endif THINK_C
  721. #else 
  722. #ifdef AIX
  723. #include "export-rs6000-aix"
  724. #else
  725. #ifdef HPPA
  726. #include "export-hppa-hpux8"
  727. #else
  728. int export(filid) /* nonzero return means error, check errno */
  729. int filid;
  730. { extern int errno;
  731.   errno=76; /*   76  ENOSYS  Function not implemented */
  732.   return 1;
  733. }
  734. #endif HPPA
  735. #endif AIX
  736. #endif
  737.  
  738. /* bulletproofWrite:
  739.  * Write nbytes from buffer to the file fd, taking care of incomplete writes.
  740.  *
  741.  * NOTE: return non-zero if i/o error occurs
  742.  */
  743. int bulletproofWrite0 (fd, buf, nbytes)
  744.     int        fd;
  745.     char    *buf;
  746.     int        nbytes;
  747. {
  748.     extern int    errno;
  749.     int        bytesWritten = 0, i;
  750.  
  751.     do {
  752.     if ((i = write(fd, buf, nbytes-bytesWritten)) < 0) return 1;
  753.     bytesWritten += i;
  754.     buf += i;
  755.     if (bytesWritten < nbytes)
  756.         chatting("[Write incomplete (%d/%d), retrying]\n", bytesWritten, nbytes);
  757.     } while (bytesWritten < nbytes);
  758.   return 0;
  759.  
  760. } /* end of bulletproofWrite */
  761.  
  762.  
  763.  
  764.  
  765.