amiga-e/ec33a_src/ec33a_src/extra/tools/o2m.e

140 lines
3.5 KiB
Plaintext

-> 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