/* lkaomf51.c - Create an absolute object memory format 51 file Copyright (C) 2002 Jesus Calvino-Fraga, jesusc at ieee dot org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include "aslink.h" #define EQ(A,B) !strcmp((A),(B)) #define MEMSIZE 0x1000000 #ifndef DODUMP #define DODUMP 0 #endif typedef struct { char PathName[PATH_MAX]; char ModuleName[PATH_MAX]; } _infn; int numin=0; _infn * infn=NULL; typedef struct { char name[0x100]; int FileNameNumber; int Procedure;//If the symbol belongs to a function int Static; //If the symbol is only public on its file int Address; int UsageType; } _symbol; int numsym=0; _symbol * symbol=NULL; typedef struct { char name[0x100]; int FileNameNumber; int BeginAdd; int EndAdd; int RegBank; } _procedure; int numproc=0; _procedure * procedure=NULL; typedef struct { int Number; int Address; int Procedure; int FileNameNumber; } _linenum; int numlinenum=0; _linenum * linenum=NULL; #if 0 typedef struct { char * name; int usage; } _UsageType; _UsageType UsageType[]= { {"CSEG", 0}, {"GSINIT", 0}, {"GSINIT0", 0}, {"GSINIT1", 0}, {"GSINIT2", 0}, {"GSINIT3", 0}, {"GSINIT4", 0}, {"GSINIT5", 0}, {"GSFINAL", 0}, {"HOME", 0}, {"XINIT", 0}, {"XSEG", 1}, {"XISEG", 1}, {"REG_BANK_0", 2}, {"REG_BANK_1", 2}, {"REG_BANK_2", 2}, {"REG_BANK_3", 2}, {"DSEG", 2}, {"OSEG", 2}, {"SSEG", 2}, {"ISEG", 3}, {"BSEG", 4}, {"", 5} /*A typeless number?*/ }; #endif char * UsageTypeName[]={"CODE", "XDATA", "DATA", "IDATA", "BIT", "NUMBER"}; int AddNumber; short * ihxBuff=NULL; FILE * aomf51out; int GlobalChkSum=0; int HexSize, HexBegin=0x1000000; int GetName(char * filepath, char * name) { int j, k; for(j=strlen(filepath); j>0; j--) if( (filepath[j-1]=='/')||(filepath[j-1]=='\\') ) break; for(k=0; (filepath[j]!=0)&&(filepath[j]!='.'); j++, k++) name[k]=filepath[j]; name[k]=0; return j; } void SaveLinkedFilePath(char * filepath) { int j; if((yflag) && (!rflag)) { int ext; infn = realloc(infn, sizeof(_infn)*(numin+1)); /*Get the module name=filename, no drive, no dir, no ext*/ ext = GetName(filepath, infn[numin].ModuleName); //printf("%s, %s\n", infn[numin].PathName, infn[numin].ModuleName); strcpy(infn[numin].PathName, filepath); /*If there is an extension remove it*/ if (infn[numin].PathName[ext] == '.') infn[numin].PathName[ext] = '\0'; /*Check if this filename is already in*/ for (j=0; j=0)?procedure[symbol[j].Procedure].name:"GLOBAL", symbol[j].Address, k<6?UsageTypeName[k]:"???"); } fprintf(DumpFile,"\nPROCEDURES:\n"); for(j=0; j %s\n", linenum[j].Number, linenum[j].Address, infn[linenum[j].FileNameNumber].PathName, (linenum[j].Procedure>=0)?procedure[linenum[j].Procedure].name:"I don't know"); } fclose(DumpFile); } void ParseRegisters(_symbol * symbol, const char * Registers) { char c; int i; char regs[0x100][4]; int address[4]; int nRegs = sscanf(Registers, "[ %[^,] %c %[^,] %c %[^,] %c %[^,] ]", regs[0], &c, regs[1], &c, regs[2], &c, regs[3]); nRegs = (nRegs + 1) / 2; for (i=0; iProcedure && symbol->Procedure < numproc) symbol->Address = address[0] + procedure[symbol->Procedure].RegBank * 8; } void OutputAOEMF51(void) { int i, j, k, recsize; char MHRname[0x100], Mname[0x100]; char aomf51FileName[PATH_MAX]; strcpy(aomf51FileName, infn[0].PathName); strcat(aomf51FileName, ".omf"); aomf51out=fopen(aomf51FileName, "wb"); if(aomf51out==NULL) { printf("Couldn't create file %s\n", aomf51FileName); return; } GetName(infn[0].PathName, MHRname); GlobalChkSum=0; /*Module header record*/ OutputByte(0x02);/*REC TYPE*/ OutputWord((strlen(MHRname)+1)+3);/*Record Length*/ OutputName(MHRname);/*Module Name*/ OutputByte(0xff);/*TRN ID: RL51?*/ OutputByte(0x00); OutputChkSum(); for(j=0; j2) /*If there are any symbols*/ { OutputByte(0x12); /*REC TYPE*/ OutputWord(recsize); /*Record Length*/ OutputByte(0x01); /*DEF TYPE: Public symbols*/ for(k=0; k2) /*If there are any symbols*/ { OutputByte(0x12); /*REC TYPE*/ OutputWord(recsize); /*Record Length*/ OutputByte(0x00); /*DEF TYPE: Local symbols*/ for(k=0; k2) /*If there are any symbols*/ { OutputByte(0x12); /*REC TYPE*/ OutputWord(recsize); /*Record Length*/ OutputByte(0x00); /*DEF TYPE: Local symbols*/ for(i=0; i2) /*If there are any line numbers*/ { OutputByte(0x12); /*REC TYPE*/ OutputWord(recsize); /*Record Length*/ OutputByte(0x03); /*DEF TYPE: Line numbers*/ for(i=0; i i) { /*Content Record*/ OutputByte(0x06);/*REC TYPE*/ OutputWord(k-i+4);/*Record Length*/ OutputByte(0x00);/*SEG ID*/ OutputWord(i); /*Offset*/ for ( ; i= 0) break; } } /*Scope Definition record: end module block*/ OutputByte(0x10);/*REC TYPE*/ OutputWord((strlen(Mname)+1)+2);/*Record Length*/ OutputByte(0x03);/*BLK TYP: module end*/ OutputName(Mname);/*Module Name*/ OutputChkSum(); /*Module end record*/ OutputByte(0x04);/*REC TYPE*/ OutputWord((strlen(MHRname)+1)+5);/*Record Length*/ OutputName(MHRname);/*Module Name*/ OutputWord(0x00); OutputByte(0x0f);/*REG MSK: All the register banks?*/ OutputByte(0x00); OutputChkSum(); fclose(aomf51out); } void CollectInfoFromCDB(void) { int i, j, k, CurrentModule; FILE * CDBin; char buff[0x1000]; char SourceName[PATH_MAX]; //"S:{G|F|L.}$$$(),
,," char Sfmt[]="%[^$] %c %[^$] %c %[^$] %c %s"; char c; char module[0x100]; char scope[0x100]; char name[0x100]; char level[0x100]; char block[0x100]; char TypeInfo[0x100]; char AddressSpace; int OnStack; int StackOffset; int IsISR; int IntNr; int RegBank; char Registers[0x100]; int Address, CLine; if(numin==0) return; if (yfp != NULL) { fclose(yfp); yfp=NULL; } /*Build the source filename*/ strcpy(SourceName, infn[0].PathName); strcat(SourceName, ".cdb"); CDBin=fopen(SourceName, "r"); if(CDBin==NULL) { printf("Couldn't open file '%s'\n", SourceName); lkexit(1); } CurrentModule=0; /*Set the active module as the first one*/ while(!feof(CDBin)) { if(NULL==fgets(buff, sizeof(buff)-1, CDBin)) { if(ferror(CDBin)) { perror("Can't read file"); lkexit(1); } else if(!feof(CDBin)) { fprintf(stderr, "Unknown error while reading file '%s'\n", SourceName); lkexit(1); } } if(!feof(CDBin)) switch(buff[0]) { /*Example: "M:adq"*/ case 'M': sscanf(&buff[2], "%s", name); for(j=0; j(),
,,*/ sscanf(block, "%[^)] %c %c %c %c %d %c %d %c %s", TypeInfo, &c, &c, &AddressSpace, &c, &OnStack, &c, &StackOffset, &c, Registers); i=-1; k=-1; switch(scope[2]) { case 'G': /*Global symbol*/ break; case 'F': /*Local symbol to a module*/ for(j=0; j(),
,,,,, */ sscanf(block, "%[^)] %c %c %c %c %d %c %d %c %d %c %d %c %d", TypeInfo, &c, &c, &AddressSpace, &c, &OnStack, &c, &StackOffset, &c, &IsISR, &c, &IntNr, &c, &RegBank); /*The same may have been already defined */ for(j=0; j=procedure[k].BeginAdd) && (linenum[j].Address<=procedure[k].EndAdd) && (linenum[j].FileNameNumber==procedure[k].FileNameNumber) ) { linenum[j].Procedure=k; } } } fclose(CDBin); } int hex2dec (unsigned char hex_digit) { if (isdigit (hex_digit)) return hex_digit-'0'; else return toupper (hex_digit)-'A'+10; } unsigned char GetByte(char * buffer) { return hex2dec(buffer[0])*0x10+hex2dec(buffer[1]); } unsigned short GetWord(char * buffer) { return hex2dec(buffer[0])*0x1000+ hex2dec(buffer[1])*0x100+ hex2dec(buffer[2])*0x10+ hex2dec(buffer[3]); } int ReadHexFile(int * Begin) { char ihxFileName[PATH_MAX]; char buffer[1024]; FILE * filein; int j; unsigned char linesize, recordtype, rchksum, value; int address, hi_addr = 0; int MaxAddress = 0; int chksum; /*If the hexfile is already open, close it*/ if(ofp!=NULL) { fclose(ofp); ofp=NULL; } strcpy(ihxFileName, infn[0].PathName); strcat(ihxFileName, ".ihx"); if ( (filein=fopen(ihxFileName, "r")) == NULL ) { printf("Error: Can't open file `%s`.\r\n", ihxFileName); return 0; } ihxBuff = calloc(MEMSIZE, sizeof(short)); if (ihxBuff==NULL) { printf("Insufficient memory\n"); fclose(filein); return -1; } for (j=0; j