Subversion Repositories pentevo

Rev

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

  1. /* asmrelocs.c */
  2. /****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                    */
  4. /*                                                                          */
  5. /* AS-Portierung                                                            */
  6. /*                                                                          */
  7. /* Verwaltung von Relokationslisten                                         */
  8. /*                                                                          */
  9. /* Historie: 25. 7.1999 Grundsteinlegung                                    */
  10. /*            1. 8.1999 Merge-Funktion implementiert                        */
  11. /*            8. 8.1999 Reloc-Liste gespeichert                             */
  12. /*           15. 9.1999 fehlende Includes                                   */
  13. /*                      Add in Merge                                        */
  14. /*           19. 1.2000 TransferRelocs begonnen                             */
  15. /*            8. 3.2000 'ambigious else'-Warnungen beseitigt                */
  16. /*           30.10.2000 added transfer of arbitrary lists                   */
  17. /*                                                                          */
  18. /****************************************************************************/
  19.  
  20. #include "stdinc.h"
  21. #include <string.h>
  22. #include "strutil.h"
  23. #include "asmdef.h"
  24. #include "asmsub.h"
  25. #include "asmcode.h"
  26. #include "asmrelocs.h"
  27. #include "errmsg.h"
  28. #include "fileformat.h"
  29.  
  30. /*---------------------------------------------------------------------------*/
  31.  
  32. PRelocEntry LastRelocs = NULL;
  33.  
  34. /*---------------------------------------------------------------------------*/
  35.  
  36. PRelocEntry MergeRelocs(PRelocEntry *list1, PRelocEntry *list2, Boolean Add)
  37. {
  38.   PRelocEntry PRun1, PRun2, PPrev, PNext, PLast, PRes;
  39.  
  40.   PRun1 = *list1;
  41.   PLast = PRes = NULL;
  42.  
  43.   /* ueber alle in Liste 1 */
  44.  
  45.   while (PRun1)
  46.   {
  47.     /* Uebereinstimmung suchen, die sich aufhebt */
  48.  
  49.     PNext = PRun1->Next;
  50.     PRun2 = *list2;
  51.     PPrev = NULL;
  52.     while (PRun2)
  53.       if ((!as_strcasecmp(PRun1->Ref, PRun2->Ref)) && ((PRun1->Add != PRun2->Add) != Add))
  54.       {
  55.         /* gefunden -> beide weg */
  56.  
  57.         free(PRun1->Ref);
  58.         free(PRun2->Ref);
  59.         if (!PPrev)
  60.           *list2 = PRun2->Next;
  61.         else
  62.           PPrev->Next = PRun2->Next;
  63.         free(PRun2);
  64.         free(PRun1);
  65.         PRun1 = NULL;
  66.         break;
  67.       }
  68.       else
  69.       {
  70.         PPrev = PRun2;
  71.         PRun2 = PRun2->Next;
  72.       }
  73.  
  74.     /* ansonsten an Ergebnisliste anhaengen */
  75.  
  76.     if (PRun1)
  77.     {
  78.       if (!PLast)
  79.         PRes = PLast = PRun1;
  80.       else
  81.       {
  82.         PLast->Next = PRun1;
  83.         PLast = PRun1;
  84.       }
  85.     }
  86.     PRun1 = PNext;
  87.   }
  88.  
  89.   /* Reste aus Liste 2 nicht vergessen */
  90.  
  91.   if (!PLast)
  92.     PRes = *list2;
  93.   else
  94.     PLast->Next = *list2;
  95.  
  96.   /* Quellisten jetzt leer */
  97.  
  98.   *list1 = *list2 = NULL;
  99.  
  100.   /* fertich */
  101.  
  102.   return PRes;
  103. }
  104.  
  105. void InvertRelocs(PRelocEntry *erg, PRelocEntry *src)
  106. {
  107.   PRelocEntry SRun;
  108.  
  109.   for (SRun = *src; SRun; SRun = SRun->Next)
  110.     SRun->Add = !(SRun->Add);
  111.  
  112.   *erg = *src;
  113. }
  114.  
  115. void FreeRelocs(PRelocEntry *list)
  116. {
  117.   PRelocEntry Run;
  118.  
  119.   while (*list)
  120.   {
  121.     Run = *list;
  122.     *list = (*list)->Next;
  123.     free(Run->Ref);
  124.     free(Run);
  125.   }
  126. }
  127.  
  128. PRelocEntry DupRelocs(PRelocEntry src)
  129. {
  130.   PRelocEntry First, Run, SRun, Neu;
  131.  
  132.   First = Run = NULL;
  133.   for (SRun = src; SRun; SRun = SRun->Next)
  134.   {
  135.     Neu = (PRelocEntry) malloc(sizeof(TRelocEntry));
  136.     Neu->Next = NULL;
  137.     Neu->Ref = as_strdup(SRun->Ref);
  138.     Neu->Add = SRun->Add;
  139.     if (!First)
  140.       First = Neu;
  141.     else
  142.       Run->Next = Neu;
  143.     Run = Neu;
  144.   }
  145.  
  146.   return First;
  147. }
  148.  
  149. void SetRelocs(PRelocEntry List)
  150. {
  151.   if (LastRelocs)
  152.   {
  153.     WrError(ErrNum_UnresRelocs);
  154.     FreeRelocs(&LastRelocs);
  155.   }
  156.   LastRelocs = List;
  157. }
  158.  
  159. void TransferRelocs2(PRelocEntry RelocList, LargeWord Addr, LongWord Type)
  160. {
  161.   PPatchEntry NewPatch;
  162.   PRelocEntry Curr;
  163.  
  164.   while (RelocList)
  165.   {
  166.     Curr = RelocList;
  167.     NewPatch = (PPatchEntry) malloc(sizeof(TPatchEntry));
  168.     NewPatch->Next = NULL;
  169.     NewPatch->Address = Addr;
  170.     NewPatch->Ref = Curr->Ref;
  171.     NewPatch->RelocType = Type;
  172.     if (!Curr->Add)
  173.       NewPatch->RelocType |= RelocFlagSUB;
  174.     if (PatchLast == NULL)
  175.       PatchList = NewPatch;
  176.     else
  177.       PatchLast->Next = NewPatch;
  178.     PatchLast = NewPatch;
  179.     RelocList = Curr->Next;
  180.     free(Curr);
  181.   }
  182. }
  183.  
  184. void TransferRelocs(LargeWord Addr, LongWord Type)
  185. {
  186.   TransferRelocs2(LastRelocs, Addr, Type);
  187.   LastRelocs = NULL;
  188. }
  189.  
  190. void SubPCRefReloc(void)
  191. {
  192.   PRelocEntry Run, Prev, New;
  193.  
  194.   if (!RelSegs)
  195.     return;
  196.  
  197.   /* search if PC subtraction evens out against an addition */
  198.  
  199.   for (Prev = NULL, Run = LastRelocs; Run; Prev = Run, Run = Run->Next)
  200.     if ((Run->Add) && (!strcmp(Run->Ref, RelName_SegStart)))
  201.     {
  202.       free(Run->Ref);
  203.       if (Prev)
  204.         Prev->Next = Run->Next;
  205.       else
  206.         LastRelocs = Run->Next;
  207.       free(Run);
  208.       return;
  209.     }
  210.  
  211.   /* in case we did not find one, add a new one */
  212.  
  213.   New = (PRelocEntry) malloc(sizeof(TRelocEntry));
  214.   New->Ref = as_strdup(RelName_SegStart);
  215.   New->Add = FALSE;
  216.   New->Next = NULL;
  217.   if (Prev)
  218.     Prev->Next = New;
  219.   else
  220.     LastRelocs = New;
  221. }
  222.  
  223. void AddExport(char *Name, LargeInt Value, LongWord Flags)
  224. {
  225.   PExportEntry PNew;
  226.  
  227.   PNew = (PExportEntry) malloc(sizeof(TExportEntry));
  228.   PNew->Next = NULL;
  229.   PNew->Name = as_strdup(Name);
  230.   PNew->Value = Value;
  231.   PNew->Flags = Flags;
  232.   if (!ExportList)
  233.     ExportList = PNew;
  234.   else
  235.     ExportLast->Next = PNew;
  236.   ExportLast = PNew;
  237. }
  238.