-> o2m.e, convert assembly (and a subset of C) .o files to E modules. MODULE 'dos/doshunks', 'tools/file' DEF type,codesize,codeadr,relocadr=NIL,relocsize -> filled by process() OBJECT syminfo next,sym,len,val ENDOBJECT DEF slist=NIL PROC main() HANDLE DEF infile[100]:STRING, outfile[100]:STRING, m, l WriteF('o2m v0.1 by $#%! 1993\n') StringF(infile,'\s.o',arg) StringF(outfile,'\s.m',arg) WriteF('Converting "\s" to "\s"\n',infile,outfile) m,l:=readfile(infile) process(m,l) writeinfos() writemodule(outfile) EXCEPT SELECT exception CASE "MEM"; WriteF('No Mem!\n') CASE "OPEN"; WriteF('Could not open file\n') CASE "IN"; WriteF('Problems while reading\n') CASE "FORM"; WriteF('Hunk format error!\n') ENDSELECT ENDPROC PROC process(o:PTR TO LONG,len) HANDLE DEF n,hunk,s:PTR TO syminfo,c IF o[]++<>HUNK_UNIT THEN Raise("FORM") o:=o[]++*4+o IF o[]=HUNK_NAME o++ o:=o[]++*4+o ENDIF type:=o[]++ IF (type<>HUNK_CODE) AND (type<>HUNK_DATA) THEN Raise("CODE") codesize:=o[]++ codeadr:=o o:=codesize*4+o WHILE (hunk:=o[]++)<>HUNK_END IF hunk=HUNK_RELOC32 IF relocadr THEN Raise("1REL") n:=o[]++ IF o[]++ THEN Raise("1REL") relocadr:=o o:=n*4+o IF o[]++ THEN Raise("1REL") relocsize:=n ELSEIF hunk=HUNK_EXT WHILE Char(o)=EXT_DEF n:=o[]++ AND $FFFFFF s:=NewR(SIZEOF syminfo) s.sym:=o c:=Char(o) IF (c>="A") AND (c<="Z") THEN PutChar(o,c+32) s.len:=n*4 s.next:=slist slist:=s o:=n*4+o s.val:=o[]++ ENDWHILE IF o[]++ THEN Raise("DEF") ELSE Raise("HUNK") ENDIF ENDWHILE EXCEPT SELECT exception CASE "HUNK"; WriteF('Only hunk_code, hunk_ext and hunk_reloc32 allowed\n') CASE "CODE"; WriteF('hunk_code or hunk_data expected\n') CASE "1REL"; WriteF('At most one relochunk expected\n') CASE "DEF"; WriteF('Only XDEFs allowed, no XREFs\n') ENDSELECT Raise("FORM") ENDPROC PROC writeinfos() DEF list:PTR TO syminfo, s[50]:STRING list:=slist WriteF('codesize=\d, numreloc=\d\n',codesize*4,relocsize) WHILE list StrCopy(s,list.sym,list.len) WriteF('\s=$\h ',s,list.val) list:=list.next ENDWHILE WriteF('\n') ENDPROC PROC writemodule(modname) DEF handle,list:PTR TO syminfo, s[50]:STRING, res[50]:STRING, num, l, ll IF (handle:=Open(modname,NEWFILE))=NIL THEN Raise("OPEN") Write(handle,["EM","OD",5,0,1000,0,0,0,0,0,0,2,0,0,3,0,codesize]:INT,34) Write(handle,codeadr,codesize*4) IF relocadr IF relocsize Write(handle,[7,0,relocsize]:INT,6) Write(handle,relocadr,relocsize*4) ENDIF ENDIF Write(handle,[4]:INT,2) list:=slist WHILE list StrCopy(s,list.sym,list.len) num:=findargs(s,res) l:=EstrLen(res) ll:=l+IF Even(l) THEN 2 ELSE 1 Write(handle,[ll]:INT,2) Write(handle,res,ll) Write(handle,[list.val]:LONG,4) IF type=HUNK_CODE Write(handle,[1,num,0,0,0]:INT,10) ELSE Write(handle,[2]:INT,2) ENDIF list:=list.next WriteF('\s/\d ',res,num) ENDWHILE Write(handle,[-1,0,0]:INT,6) Close(handle) WriteF('\n') ENDPROC PROC findargs(sym,res) DEF fpos,lpos,ipos,a=0,c,s lpos:=IF (ipos:=InStr(sym,'_i'))>1 THEN ipos ELSE EstrLen(sym) fpos:=0 WHILE sym[fpos]="_" DO fpos++ WHILE sym[lpos-1]="_" DO lpos-- IF lpos>fpos THEN StrCopy(res,sym+fpos,lpos-fpos) ELSE StrCopy(res,sym) IF ipos>1 s:=ipos+sym WHILE c:=s[]++ DO IF c="i" THEN INC a ENDIF ENDPROC a