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 | } |