blob: fdfbcf6e18af3d9fad70fcb356ef4d42a0b85e39 [file] [log] [blame]
PulkoMandy2aeca062014-06-28 23:18:25 +02001Index: Makefile.in
2===================================================================
3--- Makefile.in (révision 9037)
4+++ Makefile.in (copie de travail)
5@@ -47,7 +47,7 @@
6 SRC = lk_readnl.c lkaomf51.c lkar.c lkarea.c lkdata.c lkelf.c lkeval.c \
7 lkhead.c lklex.c lklib.c lklibr.c lklist.c lkmain.c lkmem.c \
8 lknoice.c lkout.c lkrel.c lkrloc.c lkrloc3.c lks19.c lksdcclib.c \
9- lksym.c sdld.c lksdcdb.c lkbank.c
10+ lksym.c sdld.c lksdcdb.c lkbank.c lkrrel.c
11
12 LKSOURCES = $(SRC) $(ASXXLIBSRC:%.c=$(ASXXLIB)/%.c)
13
14Index: aslink.h
15===================================================================
16--- aslink.h (révision 9037)
17+++ aslink.h (copie de travail)
18@@ -1019,6 +1019,8 @@
19 */
20 #endif
21
22+extern int hflag; /* Generate relocatable executable
23+ */
24 extern int pflag; /* print linker command file flag
25 */
26 extern int uflag; /* Listing relocation flag
27Index: lkdata.c
28===================================================================
29--- lkdata.c (révision 9037)
30+++ lkdata.c (copie de travail)
31@@ -66,6 +66,9 @@
32 int objflg; /* Linked file/library object output flag
33 */
34
35+int hflag; /* Generate relocatable executable
36+ */
37+
38 #if NOICE
39 int jflag; /* NoICE output flag
40 */
41Index: lkmain.c
42===================================================================
43--- lkmain.c (révision 9037)
44+++ lkmain.c (copie de travail)
45@@ -233,6 +233,7 @@
46 startp->f_idp = "";
47
48 pflag = 1;
49+ hflag = 0;
50
51 for(i=1; i<argc; i++) {
52 ip = ib;
53@@ -958,6 +959,11 @@
54 }
55 return(0);
56
57+ case 'h':
58+ case 'H':
59+ hflag = 1;
60+ break;
61+
62 case 'I':
63 if (is_sdld() && !(TARGET_IS_Z80 || TARGET_IS_GB)) {
64 iramsav();
65Index: lkrloc3.c
66===================================================================
67--- lkrloc3.c (révision 9037)
68+++ lkrloc3.c (copie de travail)
69@@ -31,6 +31,7 @@
70 */
71
72 #include "aslink.h"
73+#include "lkrrel.h"
74
75 /*)Module lkrloc3.c
76 *
77@@ -332,6 +333,9 @@
78 * Do remaining relocations
79 */
80 while (more()) {
81+ int output_relocation_record;
82+ int raddr;
83+
84 error = 0;
85 mode = (int) eval();
86
87@@ -390,6 +394,95 @@
88 reli -= paga + pags;
89 }
90
91+ /* KevT 28-05-2005 */
92+
93+ if (hflag)
94+ {
95+ output_relocation_record = 0;
96+ if (mode & R3_SYM)
97+ {
98+ /* If the symbol is defined in a absolute area, then we do not
99+ output a record. This allows us to reference absolute addresses
100+ in our code, but it can still be relocated */
101+
102+ /* If the symbol is relative, it is within our relocatable program */
103+
104+ /* printf("Symbol: %s\n",s[rindex]->s_id); */
105+ if ((s[rindex]->s_axp->a_bap->a_flag & A4_ABS)==0)
106+ {
107+ output_relocation_record=1;
108+ }
109+ }
110+ else
111+ {
112+ /* If the area is absolute then we do not output a record.
113+ This allows us to reference absolute memory, but still the code
114+ can be relocated. */
115+ /* If the area is relative, it refers to data that is part of the
116+ relocatable program */
117+
118+ /* printf("Area: %s\n",a[rindex]->a_bap->a_id); */
119+ if ((a[rindex]->a_bap->a_flag & A4_ABS)==0)
120+ {
121+ output_relocation_record=1;
122+ }
123+ }
124+
125+ if (output_relocation_record)
126+ {
127+ a_uint relocate_address = pc+(rtp-rtofst);
128+ if (hilo)
129+ {
130+ raddr = reli + ((rtval[rtp]&0x0ff)<<8) + (rtval[rtp+1]&0x0ff);
131+ }
132+ else
133+ {
134+ raddr = reli + ((rtval[rtp+1]&0x0ff)<<8) + (rtval[rtp]&0x0ff);
135+ }
136+ /*printf("Relocation modify address: %04x\n",relocate_address); */
137+ /*printf("Relocation address: %04x\n",raddr); */
138+ if (mode & R3_BYTE)
139+ {
140+ if (mode & R3_BYTX)
141+ {
142+ if (mode & R3_MSB)
143+ {
144+
145+relrec8hi(relocate_address,raddr);
146+ }
147+ else
148+ {
149+
150+relrec8lo(relocate_address,raddr);
151+ }
152+ }
153+ else
154+ {
155+ printf("not supported");
156+ }
157+ }
158+ else
159+ {
160+ if (mode & R3_BYTX)
161+ {
162+ if (mode & R3_MSB)
163+ {
164+ printf("not supported");
165+ }
166+ else
167+ {
168+ printf("not supported");
169+ }
170+ }
171+ else
172+ {
173+ relrec16(relocate_address);
174+ }
175+ }
176+ }
177+ }
178+
179+
180 /*
181 * R3_BYTE or R3_WORD operation
182 */
183@@ -755,6 +848,12 @@
184 if (uflag != 0) {
185 lkulist(0);
186 }
187+
188+ /* output relocation data */
189+ if (hflag) {
190+ relrecwrite();
191+ }
192+
193 if (oflag != 0) {
194 lkflush();
195 lkfclose();
196Index: lkrrel.c
197===================================================================
198--- lkrrel.c (révision 0)
199+++ lkrrel.c (copie de travail)
200@@ -0,0 +1,251 @@
201+/* (c) Kevin Thacker, May 2005 */
202+#include <stdio.h>
203+#include <string.h>
204+#include <stdlib.h>
205+#include "aslink.h"
206+#include "lkrrel.h"
207+
208+struct relrechead
209+{
210+ int count;
211+ struct relrec *head;
212+};
213+
214+/* 16-bit values, add full 16-bit base address */
215+
216+static struct relrechead head16= {0,NULL};
217+/* 8-bit, but add high byte of 16-bit base address */
218+static struct relrechead head8hi = {0,NULL};
219+/* 8-bit, but add low byte of 16-bit base address */
220+static struct relrechead head8lo = {0,NULL};
221+
222+/* internal; free's list */
223+static void relrecfree(struct relrechead *head)
224+{
225+ struct relrec *cur = head->head;
226+
227+ while (cur!=NULL)
228+ {
229+ struct relrec *next = cur->next;
230+ free(cur);
231+
232+ cur = next;
233+ }
234+}
235+
236+/* free relocation record list; e.g. on exit */
237+void freerelrec()
238+{
239+ relrecfree(&head16);
240+ relrecfree(&head8hi);
241+ relrecfree(&head8lo);
242+}
243+
244+/* internal; allocate a relocation record */
245+static void newrelrec(struct relrechead *head, a_uint addr, a_uint symaddr)
246+{
247+ struct relrec *rec;
248+
249+ rec = (struct relrec *) malloc(sizeof(struct relrec));
250+
251+ /* error if allocation failed */
252+ if (rec==NULL)
253+ return;
254+
255+ rec->addr = addr;
256+ rec->symaddr = symaddr;
257+
258+ /* add to start of list */
259+ rec->next = head->head;
260+ head->head = rec;
261+ head->count++;
262+}
263+
264+/* add item to 16-bit relocation record list */
265+void relrec16(a_uint addr)
266+{
267+ newrelrec(&head16, addr,0);
268+}
269+
270+/* add item to 8-bit (high) relocation record list */
271+void relrec8hi(a_uint addr, a_uint symaddr)
272+{
273+ newrelrec(&head8hi, addr,symaddr);
274+}
275+
276+/* add address to 8-bit (low) relocation list */
277+void relrec8lo(a_uint addr, a_uint symaddr)
278+{
279+ newrelrec(&head8lo, addr,symaddr);
280+}
281+
282+/* internal; compare two addresses within two relocate records */
283+static int relreccompare(const void *a, const void *b)
284+{
285+ const struct relrec *relreca = (const struct relrec *)a;
286+ const struct relrec *relrecb = (const struct relrec *)b;
287+
288+ return (relreca->addr-relrecb->addr);
289+}
290+
291+/* sort a list of relocate records and return an array of the records */
292+static struct relrec *relrecsort(struct relrechead *head)
293+{
294+ int count;
295+ struct relrec *reclist;
296+ struct relrec *cur;
297+
298+ if (head->count==0)
299+ return NULL;
300+
301+ /* allocate list to hold all items */
302+ reclist = (struct relrec *)malloc(sizeof(struct relrec)*head->count);
303+
304+ if (reclist==NULL)
305+ return NULL;
306+
307+ /* fill list */
308+ count = 0;
309+ cur = head->head;
310+ while (cur!=NULL)
311+ {
312+ memcpy(&reclist[count],cur,sizeof(struct relrec));
313+ count++;
314+ cur = cur->next;
315+ }
316+
317+ /* sort into ascending address order */
318+ qsort(reclist, count, sizeof(struct relrec),relreccompare);
319+
320+ return reclist;
321+}
322+
323+int outbyte(int addr, char byte)
324+{
325+ rtval[0] = addr&0x0ff;
326+ rtval[1] = (addr>>8)&0x0ff;
327+ rtval[2] = byte&0x0ff;
328+ addr+=1;
329+ rtflg[0] = 1;
330+ rtflg[1] = 1;
331+ rtflg[2] = 1;
332+ rtcnt = 3;
333+ lkout(1);
334+ return addr;
335+}
336+
337+void relrecwritelist1(struct relrechead *list,int *addrptr)
338+{
339+ int i;
340+ struct relrec *relreclist;
341+ int addr;
342+
343+ addr = *addrptr;
344+
345+ relreclist = relrecsort(list);
346+
347+ if (relreclist!=NULL)
348+ {
349+ int prevaddr = 0;
350+ for (i=0; i<list->count; i++)
351+ {
352+ struct relrec *cur = &relreclist[i];
353+
354+ int delta = cur->addr-prevaddr;
355+
356+ if (delta>254)
357+ {
358+ int largedelta = delta-1;
359+ addr = outbyte(addr,0x0ff);
360+ addr = outbyte(addr,largedelta&0x0ff);
361+ addr = outbyte(addr,(largedelta>>8)&0x0ff);
362+ delta = 1;
363+ }
364+ prevaddr = cur->addr;
365+ addr = outbyte(addr,delta&0x0ff);
366+ }
367+
368+ free(relreclist);
369+ }
370+
371+ addr = outbyte(addr, 0);
372+
373+ *addrptr = addr;
374+
375+}
376+
377+void relrecwritelist2(struct relrechead *list,int *addrptr)
378+{
379+ int i;
380+ struct relrec *relreclist;
381+ int addr;
382+
383+ addr = *addrptr;
384+
385+ relreclist = relrecsort(list);
386+
387+ if (relreclist!=NULL)
388+ {
389+ int prevaddr = 0;
390+ for (i=0; i<list->count; i++)
391+ {
392+ struct relrec *cur = &relreclist[i];
393+ int delta = cur->addr-prevaddr;
394+ prevaddr = cur->addr;
395+
396+ if (delta>254)
397+ {
398+ int largedelta = delta-1;
399+ addr = outbyte(addr,0x0ff);
400+ addr = outbyte(addr,largedelta&0x0ff);
401+ addr = outbyte(addr,(largedelta>>8)&0x0ff);
402+ delta = 1;
403+ }
404+
405+ addr = outbyte(addr,delta&0x0ff);
406+ addr = outbyte(addr,cur->symaddr&0x0ff);
407+ }
408+
409+ free(relreclist);
410+ }
411+
412+ addr = outbyte(addr,0);
413+
414+ *addrptr = addr;
415+
416+}
417+
418+
419+void relrecwrite()
420+{
421+ int areasize = 0;
422+
423+ struct area *cur = areap;
424+ while (cur!=NULL)
425+ {
426+ areasize+=cur->a_size;
427+ cur=cur->a_ap;
428+ }
429+
430+ printf("total length before relocation records: %04x\n",areasize);
431+
432+ /* re-write offset to relocation records */
433+ rtval[0] = 0;
434+ rtval[1] = 0;
435+ rtval[2] = areasize&0x0ff;
436+ rtval[3] = (areasize>>8)&0x0ff;
437+ rtflg[0] = 1;
438+ rtflg[1] = 1;
439+ rtflg[2] = 1;
440+ rtflg[3] = 1;
441+ rtcnt = 4;
442+ lkout(1);
443+
444+
445+ int addr = areasize;
446+
447+
448+ relrecwritelist1(&head16,&addr);
449+ relrecwritelist1(&head8lo,&addr);
450+ relrecwritelist2(&head8hi,&addr);
451+}
452Index: lkrrel.h
453===================================================================
454--- lkrrel.h (révision 0)
455+++ lkrrel.h (copie de travail)
456@@ -0,0 +1,17 @@
457+/* relocation record */
458+struct relrec
459+{
460+ /* next item */
461+ struct relrec *next;
462+
463+ /* address of relocate */
464+ a_uint addr;
465+
466+ a_uint symaddr;
467+};
468+
469+void relrec16(a_uint addr);
470+void relrec8lo(a_uint addr, a_uint symaddr);
471+void relrec8hi(a_uint addr, a_uint symaddr);
472+void freerelrec();
473+void relrecwrite();