Subversion Repositories pentevo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1186 savelij 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
}