321 lines
8.8 KiB
C
321 lines
8.8 KiB
C
/*****************************************************************************/
|
|
/* AS-Portierung */
|
|
/* */
|
|
/* Verwaltung der Debug-Informationen zur Assemblierzeit */
|
|
/* */
|
|
/* Historie: 16. 5.1996 Grundsteinlegung */
|
|
/* 24. 7.1998 NoICE-Format */
|
|
/* 25. 7.1998 Adresserfassung Dateien */
|
|
/* 16. 8.1998 Case-Sensitivitaet NoICE */
|
|
/* NoICE-Zeileninfo nach Dateien sortiert */
|
|
/* 29. 1.1999 uninitialisierten Speicherzugriff beseitigt */
|
|
/* 2. 5.1999 optional mehrere Records im Atmel-Format schreiben */
|
|
/* */
|
|
/*****************************************************************************/
|
|
|
|
|
|
#include "stdinc.h"
|
|
#include <string.h>
|
|
|
|
#include "endian.h"
|
|
#include "strutil.h"
|
|
#include "chunks.h"
|
|
#include "asmdef.h"
|
|
#include "asmsub.h"
|
|
#include "asmpars.h"
|
|
#include "asmfnums.h"
|
|
|
|
#include "asmdebug.h"
|
|
|
|
|
|
typedef struct
|
|
{
|
|
Boolean InMacro;
|
|
LongInt LineNum;
|
|
Integer FileName;
|
|
ShortInt Space;
|
|
LargeInt Address;
|
|
Word Code;
|
|
} TLineInfo;
|
|
|
|
typedef struct _TLineInfoList
|
|
{
|
|
struct _TLineInfoList *Next;
|
|
TLineInfo Contents;
|
|
} TLineInfoList,*PLineInfoList;
|
|
|
|
String TempFileName;
|
|
FILE *TempFile;
|
|
PLineInfoList LineInfoRoot;
|
|
|
|
|
|
void AddLineInfo(Boolean InMacro, LongInt LineNum, char *FileName,
|
|
ShortInt Space, LargeInt Address, LargeInt Len)
|
|
BEGIN
|
|
PLineInfoList PNeu, PFirst, PLast, Run, Link;
|
|
int RecCnt, z;
|
|
Integer FNum;
|
|
|
|
/* wieviele Records schreiben ? */
|
|
|
|
if ((DebugMode == DebugAtmel) AND (CodeLen > 1)) RecCnt = CodeLen;
|
|
else RecCnt = 1;
|
|
|
|
FNum = GetFileNum(FileName);
|
|
|
|
/* Einfuegepunkt in Liste finden */
|
|
|
|
Run = LineInfoRoot;
|
|
if (Run == Nil)
|
|
Link = Nil;
|
|
else
|
|
BEGIN
|
|
while ((Run->Next != Nil) AND (Run->Next->Contents.Space < Space)) Run = Run->Next;
|
|
while ((Run->Next != Nil) AND (Run->Next->Contents.FileName < FNum)) Run = Run->Next;
|
|
while ((Run->Next != Nil) AND (Run->Next->Contents.Address < Address)) Run = Run->Next;
|
|
Link = Run->Next;
|
|
END
|
|
|
|
/* neue Teilliste bilden */
|
|
|
|
PLast = PFirst = NULL;
|
|
for (z = 0; z < RecCnt; z++)
|
|
BEGIN
|
|
PNeu = (PLineInfoList) malloc(sizeof(TLineInfoList));
|
|
PNeu->Contents.InMacro = InMacro;
|
|
PNeu->Contents.LineNum = LineNum;
|
|
PNeu->Contents.FileName = FNum;
|
|
PNeu->Contents.Space = Space;
|
|
PNeu->Contents.Address = Address + z;
|
|
PNeu->Contents.Code = ((CodeLen < z + 1) OR (DontPrint)) ? 0 : WAsmCode[z];
|
|
if (z == 0) PFirst = PNeu;
|
|
if (PLast != NULL) PLast->Next = PNeu;
|
|
PLast = PNeu;
|
|
END
|
|
|
|
/* Teilliste einhaengen */
|
|
|
|
if (Run == Nil) LineInfoRoot = PFirst;
|
|
else Run->Next = PFirst;
|
|
PLast->Next = Link;
|
|
|
|
if (Space == SegCode)
|
|
AddAddressRange(FNum, Address, Len);
|
|
END
|
|
|
|
|
|
void InitLineInfo(void)
|
|
BEGIN
|
|
TempFileName[0]='\0'; LineInfoRoot=Nil;
|
|
END
|
|
|
|
|
|
void ClearLineInfo(void)
|
|
BEGIN
|
|
PLineInfoList Run;
|
|
|
|
if (TempFileName[0]!='\0')
|
|
BEGIN
|
|
fclose(TempFile); unlink(TempFileName);
|
|
END
|
|
|
|
while (LineInfoRoot!=Nil)
|
|
BEGIN
|
|
Run=LineInfoRoot; LineInfoRoot=LineInfoRoot->Next;
|
|
free(Run);
|
|
END
|
|
|
|
InitLineInfo();
|
|
END
|
|
|
|
|
|
static void DumpDebugInfo_MAP(void)
|
|
BEGIN
|
|
PLineInfoList Run;
|
|
Integer ActFile;
|
|
int ModZ;
|
|
ShortInt ActSeg;
|
|
FILE *MAPFile;
|
|
String MAPName,Tmp;
|
|
|
|
strmaxcpy(MAPName,SourceFile,255); KillSuffix(MAPName); AddSuffix(MAPName,MapSuffix);
|
|
MAPFile=fopen(MAPName,"w"); if (MAPFile==Nil) ChkIO(10001);
|
|
|
|
Run=LineInfoRoot; ActSeg=(-1); ActFile=(-1); ModZ=0;
|
|
while (Run!=Nil)
|
|
BEGIN
|
|
if (Run->Contents.Space!=ActSeg)
|
|
BEGIN
|
|
ActSeg=Run->Contents.Space;
|
|
if (ModZ!=0)
|
|
BEGIN
|
|
errno=0; fprintf(MAPFile,"\n"); ChkIO(10004);
|
|
END
|
|
ModZ=0;
|
|
errno=0; fprintf(MAPFile,"Segment %s\n",SegNames[ActSeg]); ChkIO(10004);
|
|
ActFile=(-1);
|
|
END
|
|
if (Run->Contents.FileName!=ActFile)
|
|
BEGIN
|
|
ActFile=Run->Contents.FileName;
|
|
if (ModZ!=0)
|
|
BEGIN
|
|
errno=0; fprintf(MAPFile,"\n"); ChkIO(10004);
|
|
END
|
|
ModZ=0;
|
|
errno=0; fprintf(MAPFile,"File %s\n",GetFileName(Run->Contents.FileName)); ChkIO(10004);
|
|
END;
|
|
errno=0;
|
|
sprintf(Tmp,LongIntFormat,Run->Contents.LineNum);
|
|
fprintf(MAPFile,"%5s:%s ",Tmp,HexString(Run->Contents.Address,8));
|
|
ChkIO(10004);
|
|
if (++ModZ==5)
|
|
BEGIN
|
|
errno=0; fprintf(MAPFile,"\n"); ChkIO(10004); ModZ=0;
|
|
END
|
|
Run=Run->Next;
|
|
END
|
|
if (ModZ!=0)
|
|
BEGIN
|
|
errno=0; fprintf(MAPFile,"\n"); ChkIO(10004);
|
|
END
|
|
|
|
PrintDebSymbols(MAPFile);
|
|
|
|
PrintDebSections(MAPFile);
|
|
|
|
fclose(MAPFile);
|
|
END
|
|
|
|
static void DumpDebugInfo_Atmel(void)
|
|
BEGIN
|
|
static char *OBJString="AVR Object File";
|
|
PLineInfoList Run;
|
|
LongInt FNamePos,RecPos;
|
|
FILE *OBJFile;
|
|
String OBJName;
|
|
char *FName;
|
|
Byte TByte,TNum,NameCnt;
|
|
int z;
|
|
LongInt LTurn;
|
|
Word WTurn;
|
|
|
|
strmaxcpy(OBJName,SourceFile,255);
|
|
KillSuffix(OBJName); AddSuffix(OBJName,OBJSuffix);
|
|
OBJFile=fopen(OBJName,OPENWRMODE); if (OBJFile==Nil) ChkIO(10001);
|
|
|
|
/* initialer Kopf, Positionen noch unbekannt */
|
|
|
|
FNamePos=0; RecPos=0;
|
|
if (NOT Write4(OBJFile,&FNamePos)) ChkIO(10004);
|
|
if (NOT Write4(OBJFile,&RecPos)) ChkIO(10004);
|
|
TByte=9; if (fwrite(&TByte,1,1,OBJFile)!=1) ChkIO(10004);
|
|
NameCnt=GetFileCount()-1; if (fwrite(&NameCnt,1,1,OBJFile)!=1) ChkIO(10004);
|
|
if (fwrite(OBJString,1,strlen(OBJString)+1,OBJFile)!=strlen(OBJString)+1) ChkIO(10004);
|
|
|
|
/* Objekt-Records */
|
|
|
|
RecPos=ftell(OBJFile);
|
|
for (Run=LineInfoRoot; Run!=Nil; Run=Run->Next)
|
|
if (Run->Contents.Space==SegCode)
|
|
BEGIN
|
|
LTurn=Run->Contents.Address; if (NOT BigEndian) DSwap(<urn,4);
|
|
if (fwrite(((Byte *) <urn)+1,1,3,OBJFile)!=3) ChkIO(10004);
|
|
WTurn=Run->Contents.Code; if (NOT BigEndian) WSwap(&WTurn,2);
|
|
if (fwrite(&WTurn,1,2,OBJFile)!=2) ChkIO(10004);
|
|
TNum=Run->Contents.FileName-1; if (fwrite(&TNum,1,1,OBJFile)!=1) ChkIO(10004);
|
|
WTurn=Run->Contents.LineNum; if (NOT BigEndian) WSwap(&WTurn,2);
|
|
if (fwrite(&WTurn,1,2,OBJFile)!=2) ChkIO(10004);
|
|
TNum=Ord(Run->Contents.InMacro); if (fwrite(&TNum,1,1,OBJFile)!=1) ChkIO(10004);
|
|
END
|
|
|
|
/* Dateinamen */
|
|
|
|
FNamePos=ftell(OBJFile);
|
|
for (z=1; z<=NameCnt; z++)
|
|
BEGIN
|
|
FName=NamePart(GetFileName(z));
|
|
if (fwrite(FName,1,strlen(FName)+1,OBJFile)!=strlen(FName)+1) ChkIO(10004);
|
|
END
|
|
TByte=0;
|
|
if (fwrite(&TByte,1,1,OBJFile)!=1) ChkIO(10004);
|
|
|
|
/* korrekte Positionen in Kopf schreiben */
|
|
|
|
rewind(OBJFile);
|
|
if (NOT BigEndian) DSwap(&FNamePos,4);
|
|
if (fwrite(&FNamePos,1,4,OBJFile)!=4) ChkIO(10004);
|
|
if (NOT BigEndian) DSwap(&RecPos,4);
|
|
if (fwrite(&RecPos,1,4,OBJFile)!=4) ChkIO(10004);
|
|
|
|
fclose(OBJFile);
|
|
END
|
|
|
|
static void DumpDebugInfo_NOICE(void)
|
|
BEGIN
|
|
PLineInfoList Run;
|
|
Integer ActFile;
|
|
FILE *MAPFile;
|
|
String MAPName,Tmp1,Tmp2;
|
|
LargeWord Start,End;
|
|
Boolean HadLines;
|
|
|
|
strmaxcpy(MAPName,SourceFile,255); KillSuffix(MAPName); AddSuffix(MAPName,".noi");
|
|
MAPFile=fopen(MAPName,"w"); if (MAPFile==Nil) ChkIO(10001);
|
|
|
|
fprintf(MAPFile,"CASE %d\n",(CaseSensitive) ? 1 : 0);
|
|
|
|
PrintNoISymbols(MAPFile);
|
|
|
|
for (ActFile=0; ActFile<GetFileCount(); ActFile++)
|
|
BEGIN
|
|
HadLines=FALSE;
|
|
Run=LineInfoRoot;
|
|
while (Run!=Nil)
|
|
BEGIN
|
|
if ((Run->Contents.Space==SegCode) AND (Run->Contents.FileName==ActFile))
|
|
BEGIN
|
|
if (NOT HadLines)
|
|
BEGIN
|
|
GetAddressRange(ActFile,&Start,&End);
|
|
sprintf(Tmp1,LargeIntFormat,Start);
|
|
errno=0;
|
|
fprintf(MAPFile,"FILE %s %s\n",GetFileName(Run->Contents.FileName),Tmp1);
|
|
ChkIO(10004);
|
|
END
|
|
errno=0;
|
|
sprintf(Tmp1,LongIntFormat,Run->Contents.LineNum);
|
|
sprintf(Tmp2,LargeIntFormat,Run->Contents.Address-Start);
|
|
fprintf(MAPFile,"LINE %s %s\n",Tmp1,Tmp2);
|
|
ChkIO(10004);
|
|
HadLines=TRUE;
|
|
END
|
|
Run=Run->Next;
|
|
END
|
|
if (HadLines)
|
|
BEGIN
|
|
sprintf(Tmp1,LongIntFormat,End);
|
|
errno=0; fprintf(MAPFile,"ENDFILE %s\n",Tmp1); ChkIO(10004);
|
|
END
|
|
END
|
|
|
|
fclose(MAPFile);
|
|
END
|
|
|
|
|
|
void DumpDebugInfo(void)
|
|
BEGIN
|
|
switch (DebugMode)
|
|
BEGIN
|
|
case DebugMAP: DumpDebugInfo_MAP(); break;
|
|
case DebugAtmel: DumpDebugInfo_Atmel(); break;
|
|
case DebugNoICE: DumpDebugInfo_NOICE(); break;
|
|
default: break;
|
|
END
|
|
END
|
|
|
|
|
|
void asmdebug_init(void)
|
|
BEGIN
|
|
END
|