mirror of
https://github.com/KolibriOS/kolibrios.git
synced 2024-11-28 11:43:09 +03:00
6bd5a354f5
git-svn-id: svn://kolibrios.org@6446 a494cfbc-eb01-0410-851d-a64ba20cac60
386 lines
12 KiB
C++
386 lines
12 KiB
C++
#include "tok.h"
|
|
|
|
|
|
|
|
void obj_outrecord(int recordtype,unsigned int recordlength,unsigned char *data);
|
|
|
|
void outeachPUBDEF(struct idrec *ptr);
|
|
|
|
void obj_outLEDATA(unsigned int segm,unsigned int offset,unsigned int recordlength,
|
|
|
|
unsigned char *data);
|
|
|
|
|
|
|
|
#define MAXNUMEXTNAME 1024;
|
|
|
|
|
|
|
|
int *numextname;
|
|
|
|
int maxnumextname=MAXNUMEXTNAME;
|
|
|
|
unsigned int lenextstr=0; //¤«¨ áâப¨ á ¢¥è¨¬¨ ¨¬¥ ¬¨
|
|
|
|
int numextern=0;
|
|
|
|
|
|
|
|
int postseg,stackseg;
|
|
|
|
|
|
|
|
unsigned int findextname(int extnum)
|
|
|
|
{
|
|
|
|
for(unsigned int i=0;i<externnum;i++){
|
|
|
|
if(numextname[i]==extnum)return i+1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int MakeObj()
|
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
unsigned int count,sizeblock;
|
|
|
|
hout=CreateOutPut("obj","wb");
|
|
|
|
i=strlen(startfileinfo->filename);
|
|
|
|
string2[0]=(unsigned char)i;
|
|
|
|
strcpy((char *)&string2[1],startfileinfo->filename);
|
|
|
|
obj_outrecord(0x80,i+1,&string2[0]);// output the LNAMES
|
|
|
|
sprintf((char *)&string2[3],"%s %s",compilerstr,__DATE__);
|
|
|
|
i=strlen((char *)&string2[3]);
|
|
|
|
*(short *)&string2[0]=0;
|
|
|
|
string2[2]=(unsigned char)i;
|
|
|
|
obj_outrecord(0x88,i+3,&string2[0]);// output the LNAMES
|
|
|
|
for(count=0;count<totalmodule;count++){ //¨¬¥ ¢ª«îç ¥¬ëå ä ©«®¢
|
|
|
|
*(struct ftime *)&string2[2]=(startfileinfo+count)->time;
|
|
|
|
strcpy((char *)&string2[7],(startfileinfo+count)->filename);
|
|
|
|
i=strlen((startfileinfo+count)->filename);
|
|
|
|
*(short *)&string2[0]=0xE940;
|
|
|
|
string2[6]=(unsigned char)i;
|
|
|
|
obj_outrecord(0x88,i+7,&string2[0]);// output the LNAMES
|
|
|
|
}
|
|
|
|
count=outptr-startptr; //à §¬¥à ª®¤
|
|
|
|
unsigned char *data=output+startptr; // ç «® ¤ ëå
|
|
|
|
*(short *)&string2[0]=0xE940;
|
|
|
|
obj_outrecord(0x88,2,&string2[0]);//ª®¥æ ª®¬¥â ਩
|
|
|
|
if(!am32){
|
|
|
|
*(short *)&string2[0]=0xEA00;
|
|
|
|
string2[2]=1;
|
|
|
|
string2[3]=(unsigned char)(modelmem==SMALL?9:8);
|
|
|
|
obj_outrecord(0x88,4,&string2[0]);
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
*(short *)&string2[0]=0xA140;
|
|
|
|
obj_outrecord(0x88,2,&string2[0]);
|
|
|
|
}
|
|
|
|
obj_outrecord(0x96,39,(unsigned char *)"\000\005_TEXT\004CODE\004_BSS\003BSS\006DGROUP\005_DATA\004DATA");
|
|
|
|
// output the SEGDEF
|
|
|
|
if(!am32){
|
|
|
|
string2[0]=(unsigned char)0x28;
|
|
|
|
*(short *)&string2[1]=(short)outptr;//count;// Set the length of the segment of DATA or CODE
|
|
|
|
string2[3]=0x02; //¨¬ï ᥣ¬¥â _TEXT
|
|
|
|
*(short *)&string2[4]=0x0103; //ª« áá CODE Overlay NONE 1
|
|
|
|
obj_outrecord(0x98,6,string2);
|
|
|
|
i=2;
|
|
|
|
|
|
|
|
if(comfile==file_exe&&modelmem==SMALL){
|
|
|
|
string2[0]=(unsigned char)0x48;
|
|
|
|
*(short *)&string2[1]=outptrdata;// Set the length of the segment DATA
|
|
|
|
string2[3]=0x07; //¨¬ï ᥣ¬¥â _DATA
|
|
|
|
*(short *)&string2[4]=0x0108; //ª« áá DATA Overlay NONE
|
|
|
|
obj_outrecord(0x98,6,string2);
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
postseg=i;
|
|
|
|
string2[0]=(unsigned char)0x48;
|
|
|
|
*(short *)&string2[1]=(short)postsize;// Set the length of the segment BSS
|
|
|
|
string2[3]=0x04; //¨¬ï ᥣ¬¥â _BSS
|
|
|
|
*(short *)&string2[4]=0x0105; //ª« áá BSS Overlay NONE
|
|
|
|
obj_outrecord(0x98,6,string2);
|
|
|
|
i++;
|
|
|
|
|
|
|
|
if(comfile==file_exe&&modelmem==SMALL){
|
|
|
|
obj_outrecord(0x96,6,(unsigned char *)"\005STACK");
|
|
|
|
string2[0]=0x74;
|
|
|
|
*(short *)&string2[1]=(short)stacksize;// Set the length of the segment STACK
|
|
|
|
string2[3]=0x09; //¨¬ï ᥣ¬¥â STACK
|
|
|
|
*(short *)&string2[4]=0x0109; //ª« áá STACK Overlay NONE
|
|
|
|
obj_outrecord(0x98,6,string2);
|
|
|
|
stackseg=i;
|
|
|
|
}
|
|
|
|
string2[0]=6; //¨¬ï DGROUP
|
|
|
|
if(comfile==file_exe&&modelmem==SMALL){
|
|
|
|
*(short *)&string2[1]=0x2FF;
|
|
|
|
*(short *)&string2[3]=0x3FF;//postseg*256+255;//0x3FF;
|
|
|
|
*(short *)&string2[5]=0x4ff;//stackseg*256+255;//0x4FF;
|
|
|
|
i=7;
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
*(short *)&string2[1]=0x1FF;
|
|
|
|
// *(short *)&string2[3]=0x2FF;
|
|
|
|
*(short *)&string2[3]=0x2ff;//postseg*256+255;//0x3FF;
|
|
|
|
i=5;
|
|
|
|
}
|
|
|
|
obj_outrecord(0x9A,i,string2);
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
string2[0]=(unsigned char)0xA9;
|
|
|
|
*(long *)&string2[1]=(long)outptr;//count;// Set the length of the segment of DATA or CODE
|
|
|
|
string2[5]=0x02; //¨¬ï ᥣ¬¥â _TEXT
|
|
|
|
*(short *)&string2[6]=0x0103; //ª« áá CODE Overlay NONE
|
|
|
|
obj_outrecord(0x99,8,string2);
|
|
|
|
i=2;
|
|
|
|
/*
|
|
|
|
string2[0]=(unsigned char)0xA9;
|
|
|
|
*(long *)&string2[1]=0;// Set the length of the segment DATA
|
|
|
|
string2[5]=0x07; //¨¬ï ᥣ¬¥â _DATA
|
|
|
|
*(short *)&string2[6]=0x0108; //ª« áá DATA Overlay NONE
|
|
|
|
obj_outrecord(0x99,8,string2);
|
|
|
|
i++;*/
|
|
|
|
|
|
|
|
postseg=i;
|
|
|
|
string2[0]=(unsigned char)0xA9;
|
|
|
|
*(long *)&string2[1]=(long)postsize;// Set the length of the segment BSS
|
|
|
|
string2[5]=0x04; //¨¬ï ᥣ¬¥â _BSS
|
|
|
|
*(short *)&string2[6]=0x0105; //ª« áá BSS Overlay NONE
|
|
|
|
obj_outrecord(0x99,8,string2);
|
|
|
|
i++;
|
|
|
|
|
|
|
|
obj_outrecord(0x96,11,(unsigned char *)"\005STACK\004FLAT");//9,10
|
|
|
|
|
|
|
|
if(comfile!=file_w32){
|
|
|
|
string2[0]=0x75;
|
|
|
|
*(long *)&string2[1]=(long)stacksize;// Set the length of the segment STACK
|
|
|
|
string2[5]=0x09; //¨¬ï ᥣ¬¥â STACK
|
|
|
|
*(short *)&string2[6]=0x0109; //ª« áá STACK Overlay NONE
|
|
|
|
obj_outrecord(0x99,8,string2);
|
|
|
|
stackseg=i;
|
|
|
|
}
|
|
|
|
string2[0]=10;
|
|
|
|
|
|
|
|
obj_outrecord(0x9A,1,string2); //GRPDEF Group: FLAT
|
|
|
|
string2[0]=6; //¨¬ï DGROUP
|
|
|
|
i=1;
|
|
|
|
// *(short *)&string2[i]=0x2FF; //DATA
|
|
|
|
// i+=2;
|
|
|
|
*(short *)&string2[i]=postseg*256+255;//0x3FF; //BSS
|
|
|
|
i+=2;
|
|
|
|
if(comfile!=file_w32){
|
|
|
|
*(short *)&string2[i]=stackseg*256+255;//0x4FF
|
|
|
|
i+=2;
|
|
|
|
}
|
|
|
|
obj_outrecord(0x9A,i,string2);
|
|
|
|
}
|
|
|
|
// ¢ë¢®¤ EXTDEF
|
|
|
|
while(externnum>maxnumextname)maxnumextname+=MAXNUMEXTNAME;
|
|
|
|
numextname=(int *)MALLOC(maxnumextname*sizeof(int));
|
|
|
|
// output the PUBDEF records for each exteral procedures (all procedures)
|
|
|
|
outeachPUBDEF(treestart);
|
|
|
|
if(lenextstr!=0)obj_outrecord(0x8c,lenextstr,&string[0]);
|
|
|
|
// output the data (LEDATA) in 1K chunks as required!
|
|
|
|
i=0;
|
|
|
|
char *bufobj=(char *)MALLOC(512*5);
|
|
|
|
while(i<count){
|
|
|
|
unsigned int j;
|
|
|
|
sizeblock=1024;
|
|
|
|
restart:
|
|
|
|
for(j=0;j<posts;j++){
|
|
|
|
if((postbuf+j)->type>=CALL_EXT&&(postbuf+j)->type<=FIX_CODE32&&
|
|
|
|
(postbuf+j)->loc>=(i+startptr)&&(postbuf+j)->loc<(i+sizeblock+startptr)){
|
|
|
|
if((postbuf+j)->loc>(i+startptr+sizeblock-(am32==FALSE?2:4))){
|
|
|
|
sizeblock=(postbuf+j)->loc-i-startptr;//¨§¬¥¨âì à §¬¥à ¡«®ª
|
|
|
|
goto restart;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if((i+sizeblock)>count)sizeblock=count-i;
|
|
|
|
obj_outLEDATA(1,i+startptr,sizeblock,data+i);
|
|
|
|
int ofsfix=0;
|
|
|
|
for(j=0;j<posts;j++){
|
|
|
|
if((postbuf+j)->loc>=(i+startptr)&&(postbuf+j)->loc<(i+sizeblock+startptr)){
|
|
|
|
int hold=(postbuf+j)->loc-i-startptr;
|
|
|
|
if((postbuf+j)->type>=CALL_32I/*POST_VAR*/&&(postbuf+j)->type<=FIX_CODE32){
|
|
|
|
bufobj[ofsfix++]=(unsigned char)((am32==FALSE?0xC4:0xE4)|(hold/256));
|
|
|
|
bufobj[ofsfix++]=(unsigned char)(hold%256);
|
|
|
|
bufobj[ofsfix++]=0x14;
|
|
|
|
bufobj[ofsfix++]=1;
|
|
|
|
switch((postbuf+j)->type){
|
|
|
|
case POST_VAR:
|
|
|
|
case POST_VAR32:
|
|
|
|
bufobj[ofsfix++]=postseg;
|
|
|
|
break;
|
|
|
|
case FIX_VAR:
|
|
|
|
case FIX_VAR32:
|
|
|
|
bufobj[ofsfix++]=(unsigned char)((comfile==file_exe&&modelmem==SMALL)?2:1);
|
|
|
|
break;
|
|
|
|
case FIX_CODE:
|
|
|
|
case FIX_CODE32:
|
|
|
|
bufobj[ofsfix++]=1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if((postbuf+j)->type>=POST_VAR32&&(postbuf+j)->type<=FIX_CODE32){
|
|
|
|
|
|
|
|
}
|
|
|
|
else if((postbuf+j)->type==CALL_EXT){
|
|
|
|
int numext=findextname((postbuf+j)->num);
|
|
|
|
if(numext!=0){
|
|
|
|
bufobj[ofsfix++]=(unsigned char)((am32==FALSE?0x84:0xA4)|(hold/256));
|
|
|
|
bufobj[ofsfix++]=(unsigned char)(hold%256);
|
|
|
|
bufobj[ofsfix++]=0x56;
|
|
|
|
bufobj[ofsfix++]=(unsigned char)numext;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if((postbuf+j)->type==EXT_VAR){
|
|
|
|
int numext=findextname((postbuf+j)->num);
|
|
|
|
if(numext!=0){
|
|
|
|
bufobj[ofsfix++]=(unsigned char)((am32==FALSE?0xC4:0xE4)|(hold/256));
|
|
|
|
bufobj[ofsfix++]=(unsigned char)(hold%256);
|
|
|
|
bufobj[ofsfix++]=0x16;
|
|
|
|
bufobj[ofsfix++]=1;
|
|
|
|
bufobj[ofsfix++]=(unsigned char)numext;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(ofsfix!=0)obj_outrecord(0x9C+am32,ofsfix,(unsigned char *)bufobj);
|
|
|
|
i+=sizeblock;
|
|
|
|
}
|
|
|
|
free(bufobj);
|
|
|
|
if(comfile==file_exe&&modelmem==SMALL){
|
|
|
|
i=0;
|
|
|
|
while(i<outptrdata){
|
|
|
|
if((i+1024)>outptrdata)obj_outLEDATA(2,i,outptrdata-i,outputdata+i);
|
|
|
|
else obj_outLEDATA(2,i,1024,outputdata+i);
|
|
|
|
i+=1024;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(sobj!=FALSE){
|
|
|
|
// output end of OBJ notifier
|
|
|
|
string2[0]=0;
|
|
|
|
i=1;
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
count=EntryPoint();
|
|
|
|
*(short *)&string2[0]=0xC1; //£« ¢ë© ¬®¤ã«ì ¨¬¥¥â áâ àâ®¢ë© ¤à¥á ª®â®à ¥«ì§ï ¬¥ïâì.
|
|
|
|
*(short *)&string2[2]=0x101;
|
|
|
|
if(count<65536){
|
|
|
|
*(short *)&string2[4]=(short)count;
|
|
|
|
i=6;
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
*(long *)&string2[4]=(long)count;
|
|
|
|
i=8;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
obj_outrecord(i==8?0x8B:0x8A,i,string2);
|
|
|
|
free(numextname);
|
|
|
|
runfilesize=ftell(hout);
|
|
|
|
fclose(hout);
|
|
|
|
hout=NULL;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void obj_outLEDATA(unsigned int segm,unsigned int offset,unsigned int recordlength,unsigned char *data)
|
|
|
|
{
|
|
|
|
int checksum=0;
|
|
|
|
int i;
|
|
|
|
unsigned char buf[8];
|
|
|
|
buf[3]=(unsigned char)segm;
|
|
|
|
if(offset>(65536-1024)){
|
|
|
|
*(short *)&buf[1]=(short)(recordlength+6);
|
|
|
|
buf[0]=0xA1;
|
|
|
|
*(long *)&buf[4]=(long)offset;
|
|
|
|
i=8;
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
*(short *)&buf[1]=(short)(recordlength+4);
|
|
|
|
buf[0]=0xA0;
|
|
|
|
*(short *)&buf[4]=(short)offset;
|
|
|
|
i=6;
|
|
|
|
}
|
|
|
|
fwrite(buf,i,1,hout);
|
|
|
|
for(i--;i>=0;i--)checksum+=buf[i];
|
|
|
|
for(i=0;(unsigned int)i<recordlength;i++)checksum+=data[i];
|
|
|
|
fwrite(data,recordlength,1,hout);
|
|
|
|
checksum=-checksum;
|
|
|
|
fwrite(&checksum,1,1,hout);
|
|
|
|
}
|
|
|
|
|
|
|
|
void obj_outrecord(int recordtype,unsigned int recordlength,unsigned char *data)
|
|
|
|
// Outputs an OBJ record.
|
|
|
|
{
|
|
|
|
int checksum;
|
|
|
|
unsigned int i;
|
|
|
|
recordlength++;
|
|
|
|
checksum=recordtype;
|
|
|
|
fwrite(&recordtype,1,1,hout);
|
|
|
|
checksum+=(recordlength/256);
|
|
|
|
checksum+=(recordlength&255);
|
|
|
|
fwrite(&recordlength,2,1,hout);
|
|
|
|
recordlength--;
|
|
|
|
for(i=0;i<recordlength;i++)checksum+=data[i];
|
|
|
|
fwrite(data,recordlength,1,hout);
|
|
|
|
checksum=-checksum;
|
|
|
|
fwrite(&checksum,1,1,hout);
|
|
|
|
}
|
|
|
|
|
|
|
|
void outeachPUBDEF(struct idrec *ptr)
|
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
if(ptr!=NULL){
|
|
|
|
outeachPUBDEF(ptr->right);
|
|
|
|
if(ptr->rectok==tk_apiproc){
|
|
|
|
i=0;
|
|
|
|
for(unsigned int j=0;j<posts;j++){ //¯®¨áª ¨á¯®«ì§®¢ ¨ï ¯à®æ¥¤ãàë
|
|
|
|
if((postbuf+j)->num==(unsigned long)ptr->recnumber&&((postbuf+j)->type==CALL_32I||(postbuf+j)->type==CALL_32)){
|
|
|
|
i++;
|
|
|
|
(postbuf+j)->type=CALL_EXT;
|
|
|
|
externnum++;
|
|
|
|
if(externnum>=maxnumextname){
|
|
|
|
maxnumextname+=MAXNUMEXTNAME;
|
|
|
|
numextname=(int *)REALLOC(numextname,maxnumextname*sizeof(int));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(i)goto nameext;
|
|
|
|
goto endp;
|
|
|
|
}
|
|
|
|
if(externnum!=0&&ptr->rectok==tk_undefproc&&(ptr->flag&f_extern)!=0){
|
|
|
|
nameext:
|
|
|
|
numextname[numextern++]=ptr->recnumber;
|
|
|
|
i=strlen(ptr->recid);
|
|
|
|
if((lenextstr+i+2)>=STRLEN){
|
|
|
|
obj_outrecord(0x8c,lenextstr,&string[0]);
|
|
|
|
lenextstr=0;
|
|
|
|
}
|
|
|
|
string[lenextstr++]=(unsigned char)i;
|
|
|
|
strcpy((char *)&string[lenextstr],ptr->recid);
|
|
|
|
lenextstr+=i+1;
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
if((ptr->rectok==tk_proc||ptr->rectok==tk_interruptproc)&&ptr->recsegm>=NOT_DYNAMIC){
|
|
|
|
string2[0]=(unsigned char)(am32==0?0:1);
|
|
|
|
string2[1]=0x01;
|
|
|
|
}
|
|
|
|
else if((ptr->rectok>=tk_bits&&ptr->rectok<=tk_doublevar)||ptr->rectok==tk_structvar){
|
|
|
|
if((ptr->flag&f_extern))goto nameext;
|
|
|
|
if(am32){
|
|
|
|
string2[0]=1;
|
|
|
|
string2[1]=(unsigned char)(ptr->recpost==0?1:postseg);
|
|
|
|
}
|
|
|
|
else if(comfile==file_exe&&modelmem==SMALL){
|
|
|
|
string2[0]=1;
|
|
|
|
string2[1]=(unsigned char)(ptr->recpost==0?2:postseg);
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
string2[0]=(unsigned char)(ptr->recpost==0?0:1);
|
|
|
|
string2[1]=(unsigned char)(ptr->recpost==0?1:postseg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else goto endp;
|
|
|
|
for(i=0;ptr->recid[i]!=0;i++)string2[i+3]=ptr->recid[i];
|
|
|
|
string2[2]=(unsigned char)i;
|
|
|
|
if(ptr->recnumber<65536){
|
|
|
|
*(short *)&string2[i+3]=(short)ptr->recnumber;
|
|
|
|
string2[i+5]=0x00;
|
|
|
|
obj_outrecord(0x90,i+6,&string2[0]);
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
*(long *)&string2[i+3]=(long)ptr->recnumber;
|
|
|
|
string2[i+7]=0x00;
|
|
|
|
obj_outrecord(0x91,i+8,&string2[0]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
endp:
|
|
|
|
outeachPUBDEF(ptr->left);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|