Subversion Repositories pentevo

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

  1. /* asmdebug.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Verwaltung der Debug-Informationen zur Assemblierzeit                     */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11.  
  12. #include "stdinc.h"
  13. #include <string.h>
  14. #include "strutil.h"
  15.  
  16. #include "be_le.h"
  17. #include "chunks.h"
  18. #include "asmdef.h"
  19. #include "asmsub.h"
  20. #include "asmpars.h"
  21. #include "asmfnums.h"
  22. #include "errmsg.h"
  23.  
  24. #include "asmdebug.h"
  25.  
  26.  
  27. typedef struct
  28. {
  29.   Boolean InMacro;
  30.   LongInt LineNum;
  31.   Integer FileName;
  32.   ShortInt Space;
  33.   LargeInt Address;
  34.   Word Code;
  35. } TLineInfo;
  36.  
  37. typedef struct sLineInfoList
  38. {
  39.   struct sLineInfoList *Next;
  40.   TLineInfo Contents;
  41. } TLineInfoList, *PLineInfoList;
  42.  
  43. String TempFileName;
  44. FILE *TempFile;
  45. PLineInfoList LineInfoRoot;
  46.  
  47.  
  48. void AddLineInfo(Boolean InMacro, LongInt LineNum, char *FileName,
  49.                  ShortInt Space, LargeInt Address, LargeInt Len)
  50. {
  51.   PLineInfoList PNeu, PFirst, PLast, Run, Link;
  52.   int RecCnt, z;
  53.   Integer FNum;
  54.  
  55.   /* do not accept line infor for pseudo segments */
  56.  
  57.   if (Space >= SegCount)
  58.     return;
  59.  
  60.   /* wieviele Records schreiben ? */
  61.  
  62.   RecCnt = ((DebugMode == DebugAtmel) && (CodeLen > 1)) ? CodeLen : 1;
  63.  
  64.   FNum = GetFileNum(FileName);
  65.  
  66.   /* Einfuegepunkt in Liste finden */
  67.  
  68.   Run = LineInfoRoot;
  69.   if (!Run)
  70.     Link = NULL;
  71.   else
  72.   {
  73.     while ((Run->Next) && (Run->Next->Contents.Space < Space))
  74.       Run = Run->Next;
  75.     while ((Run->Next) && (Run->Next->Contents.FileName < FNum))
  76.       Run = Run->Next;
  77.     while ((Run->Next) && (Run->Next->Contents.Address < Address))
  78.       Run = Run->Next;
  79.     Link = Run->Next;
  80.   }
  81.  
  82.   /* neue Teilliste bilden */
  83.  
  84.   PLast = PFirst = NULL;
  85.   for (z = 0; z < RecCnt; z++)
  86.   {
  87.     PNeu = (PLineInfoList) malloc(sizeof(TLineInfoList));
  88.     PNeu->Contents.InMacro = InMacro;
  89.     PNeu->Contents.LineNum = LineNum;
  90.     PNeu->Contents.FileName = FNum;
  91.     PNeu->Contents.Space = Space;
  92.     PNeu->Contents.Address = Address + z;
  93.     PNeu->Contents.Code = ((CodeLen < z + 1) || (DontPrint)) ? 0 : WAsmCode[z];
  94.     if (z == 0)
  95.       PFirst = PNeu;
  96.     if (PLast != NULL)
  97.       PLast->Next = PNeu;
  98.     PLast = PNeu;
  99.   }
  100.  
  101.   /* Teilliste einhaengen */
  102.  
  103.   if (!Run)
  104.     LineInfoRoot = PFirst;
  105.   else
  106.     Run->Next = PFirst;
  107.   PLast->Next = Link;
  108.  
  109.   if (Space == SegCode)
  110.     AddAddressRange(FNum, Address, Len);
  111. }
  112.  
  113.  
  114. void InitLineInfo(void)
  115. {
  116.   TempFileName[0] = '\0';
  117.   LineInfoRoot = NULL;
  118. }
  119.  
  120.  
  121. void ClearLineInfo(void)
  122. {
  123.   PLineInfoList Run;
  124.  
  125.   if (TempFileName[0] != '\0')
  126.   {
  127.     fclose(TempFile);
  128.     unlink(TempFileName);
  129.   }
  130.  
  131.   while (LineInfoRoot)
  132.   {
  133.     Run = LineInfoRoot;
  134.     LineInfoRoot = LineInfoRoot->Next;
  135.     free(Run);
  136.   }
  137.  
  138.   InitLineInfo();
  139. }
  140.  
  141.  
  142. static void DumpDebugInfo_MAP(void)
  143. {
  144.   PLineInfoList Run;
  145.   Integer ActFile;
  146.   int ModZ;
  147.   ShortInt ActSeg;
  148.   FILE *MAPFile;
  149.   String MAPName;
  150.   char Tmp[30], Tmp2[30];
  151.  
  152.   strmaxcpy(MAPName, SourceFile, STRINGSIZE);
  153.   KillSuffix(MAPName);
  154.   AddSuffix(MAPName, MapSuffix);
  155.   MAPFile = fopen(MAPName, "w");
  156.   if (!MAPFile)
  157.     ChkIO(ErrNum_OpeningFile);
  158.  
  159.   Run = LineInfoRoot;
  160.   ActSeg = -1;
  161.   ActFile = -1;
  162.   ModZ = 0;
  163.   while (Run)
  164.   {
  165.     if (Run->Contents.Space != ActSeg)
  166.     {
  167.       ActSeg = Run->Contents.Space;
  168.       if (ModZ != 0)
  169.       {
  170.         errno = 0; fprintf(MAPFile, "\n"); ChkIO(ErrNum_FileWriteError);
  171.       }
  172.       ModZ = 0;
  173.       errno = 0; fprintf(MAPFile, "Segment %s\n", SegNames[ActSeg]); ChkIO(ErrNum_FileWriteError);
  174.       ActFile = -1;
  175.     }
  176.     if (Run->Contents.FileName != ActFile)
  177.     {
  178.       ActFile = Run->Contents.FileName;
  179.       if (ModZ != 0)
  180.       {
  181.         errno = 0; fprintf(MAPFile, "\n"); ChkIO(ErrNum_FileWriteError);
  182.       }
  183.       ModZ = 0;
  184.       errno = 0; fprintf(MAPFile, "File %s\n", GetFileName(Run->Contents.FileName)); ChkIO(ErrNum_FileWriteError);
  185.     };
  186.     errno = 0;
  187.     as_snprintf(Tmp, sizeof(Tmp), LongIntFormat, Run->Contents.LineNum);
  188.     HexString(Tmp2, sizeof(Tmp2), Run->Contents.Address, 8);
  189.     fprintf(MAPFile, "%5s:%s ", Tmp, Tmp2);
  190.     ChkIO(ErrNum_FileWriteError);
  191.     if (++ModZ == 5)
  192.     {
  193.       errno = 0; fprintf(MAPFile, "\n"); ChkIO(ErrNum_FileWriteError); ModZ = 0;
  194.     }
  195.     Run = Run->Next;
  196.   }
  197.   if (ModZ != 0)
  198.   {
  199.     errno = 0; fprintf(MAPFile, "\n"); ChkIO(ErrNum_FileWriteError);
  200.   }
  201.  
  202.   PrintDebSymbols(MAPFile);
  203.  
  204.   PrintDebSections(MAPFile);
  205.  
  206.   fclose(MAPFile);
  207. }
  208.  
  209. static void DumpDebugInfo_Atmel(void)
  210. {
  211.   static const char *OBJString = "AVR Object File";
  212.   PLineInfoList Run;
  213.   LongInt FNamePos, RecPos;
  214.   FILE *OBJFile;
  215.   String OBJName;
  216.   const char *FName;
  217.   Byte TByte, TNum, NameCnt;
  218.   int z;
  219.   LongInt LTurn;
  220.   Word WTurn;
  221.  
  222.   strmaxcpy(OBJName, SourceFile, STRINGSIZE);
  223.   KillSuffix(OBJName);
  224.   AddSuffix(OBJName, OBJSuffix);
  225.   OBJFile = fopen(OBJName, OPENWRMODE);
  226.   if (!OBJFile)
  227.     ChkIO(ErrNum_OpeningFile);
  228.  
  229.   /* initialer Kopf, Positionen noch unbekannt */
  230.  
  231.   FNamePos = 0;
  232.   RecPos = 0;
  233.   if (!Write4(OBJFile, &FNamePos)) ChkIO(ErrNum_FileWriteError);
  234.   if (!Write4(OBJFile, &RecPos)) ChkIO(ErrNum_FileWriteError);
  235.   TByte = 9;
  236.   if (fwrite(&TByte, 1, 1, OBJFile) != 1) ChkIO(ErrNum_FileWriteError);
  237.   NameCnt = GetFileCount() - 1;
  238.   if (fwrite(&NameCnt, 1, 1, OBJFile) != 1) ChkIO(ErrNum_FileWriteError);
  239.   if ((int)fwrite(OBJString, 1, strlen(OBJString) + 1, OBJFile) != (int)strlen(OBJString) + 1) ChkIO(ErrNum_FileWriteError);
  240.  
  241.   /* Objekt-Records */
  242.  
  243.   RecPos = ftell(OBJFile);
  244.   for (Run = LineInfoRoot; Run; Run = Run->Next)
  245.     if (Run->Contents.Space == SegCode)
  246.     {
  247.       LTurn = Run->Contents.Address;
  248.       if (!HostBigEndian)
  249.         DSwap(&LTurn, 4);
  250.       if (fwrite(((Byte *) &LTurn)+1, 1, 3, OBJFile) != 3) ChkIO(ErrNum_FileWriteError);
  251.       WTurn = Run->Contents.Code;
  252.       if (!HostBigEndian)
  253.         WSwap(&WTurn, 2);
  254.       if (fwrite(&WTurn, 1, 2, OBJFile) != 2) ChkIO(ErrNum_FileWriteError);
  255.       TNum = Run->Contents.FileName - 1;
  256.       if (fwrite(&TNum, 1, 1, OBJFile) != 1) ChkIO(ErrNum_FileWriteError);
  257.       WTurn = Run->Contents.LineNum;
  258.       if (!HostBigEndian)
  259.         WSwap(&WTurn, 2);
  260.       if (fwrite(&WTurn, 1, 2, OBJFile) != 2) ChkIO(ErrNum_FileWriteError);
  261.       TNum = Ord(Run->Contents.InMacro);
  262.       if (fwrite(&TNum, 1, 1, OBJFile) != 1) ChkIO(ErrNum_FileWriteError);
  263.     }
  264.  
  265.   /* Dateinamen */
  266.  
  267.   FNamePos = ftell(OBJFile);
  268.   for (z = 1; z <= NameCnt; z++)
  269.   {
  270.     FName = NamePart(GetFileName(z));
  271.     if ((int)fwrite(FName, 1, strlen(FName) + 1, OBJFile) != (int)strlen(FName) + 1) ChkIO(ErrNum_FileWriteError);
  272.   }
  273.   TByte = 0;
  274.   if (fwrite(&TByte, 1, 1, OBJFile) != 1) ChkIO(ErrNum_FileWriteError);
  275.  
  276.   /* korrekte Positionen in Kopf schreiben */
  277.  
  278.   rewind(OBJFile);
  279.   if (!HostBigEndian) DSwap(&FNamePos, 4);
  280.   if (fwrite(&FNamePos, 1, 4, OBJFile) != 4) ChkIO(ErrNum_FileWriteError);
  281.   if (!HostBigEndian) DSwap(&RecPos, 4);
  282.   if (fwrite(&RecPos, 1, 4, OBJFile) != 4) ChkIO(ErrNum_FileWriteError);
  283.  
  284.   fclose(OBJFile);
  285. }
  286.  
  287. static void DumpDebugInfo_NOICE(void)
  288. {
  289.   PLineInfoList Run;
  290.   Integer ActFile;
  291.   FILE *MAPFile;
  292.   String MAPName, Tmp1, Tmp2;
  293.   LargeWord Start, End;
  294.   Boolean HadLines;
  295.  
  296.   strmaxcpy(MAPName, SourceFile, STRINGSIZE);
  297.   KillSuffix(MAPName);
  298.   AddSuffix(MAPName, ".noi");
  299.   MAPFile = fopen(MAPName, "w");
  300.   if (!MAPFile)
  301.     ChkIO(ErrNum_OpeningFile);
  302.  
  303.   fprintf(MAPFile, "CASE %d\n", (CaseSensitive) ? 1 : 0);
  304.  
  305.   PrintNoISymbols(MAPFile);
  306.  
  307.   for (ActFile = 0; ActFile < GetFileCount(); ActFile++)
  308.   {
  309.     HadLines = FALSE;
  310.     Run = LineInfoRoot;
  311.     while (Run)
  312.     {
  313.       if ((Run->Contents.Space == SegCode) && (Run->Contents.FileName == ActFile))
  314.       {
  315.         if (!HadLines)
  316.         {
  317.           GetAddressRange(ActFile, &Start, &End);
  318.           as_snprintf(Tmp1, sizeof(Tmp1), "%X", Start);
  319.           errno = 0;
  320.           fprintf(MAPFile, "FILE %s 0x%s\n", GetFileName(Run->Contents.FileName), Tmp1);
  321.           ChkIO(ErrNum_FileWriteError);
  322.         }
  323.         errno = 0;
  324.         as_snprintf(Tmp1, sizeof(Tmp1), LongIntFormat, Run->Contents.LineNum);
  325.         as_snprintf(Tmp2, sizeof(Tmp2), "%X", Run->Contents.Address - Start);
  326.         fprintf(MAPFile, "LINE %s 0x%s\n", Tmp1, Tmp2);
  327.         ChkIO(ErrNum_FileWriteError);
  328.         HadLines = TRUE;
  329.       }
  330.       Run = Run->Next;
  331.     }
  332.     if (HadLines)
  333.     {
  334.       as_snprintf(Tmp1, sizeof(Tmp1), "%X", End);
  335.       errno = 0; fprintf(MAPFile, "ENDFILE 0x%s\n", Tmp1); ChkIO(ErrNum_FileWriteError);
  336.     }
  337.   }
  338.  
  339.   fclose(MAPFile);
  340. }
  341.  
  342.  
  343. void DumpDebugInfo(void)
  344. {
  345.   switch (DebugMode)
  346.   {
  347.     case DebugMAP:
  348.       DumpDebugInfo_MAP();
  349.       break;
  350.     case DebugAtmel:
  351.       DumpDebugInfo_Atmel();
  352.       break;
  353.     case DebugNoICE:
  354.       DumpDebugInfo_NOICE();
  355.       break;
  356.     default:
  357.       break;
  358.   }
  359. }
  360.  
  361.  
  362. void asmdebug_init(void)
  363. {
  364. }
  365.