* debugger/mcs51/break.c, debugger/mcs51/cmd.c,
[fw/sdcc] / as / link / hc08 / lkelf.c
1 /*-------------------------------------------------------------------------
2   lkelf.c - Create an executable ELF/DWARF file
3
4    Written By -  Erik Petrich, epetrich@users.sourceforge.net (2004)
5
6    This program is free software; you can redistribute it and/or modify it
7    under the terms of the GNU General Public License as published by the
8    Free Software Foundation; either version 2, or (at your option) any
9    later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 -------------------------------------------------------------------------*/
20
21 #include <assert.h>
22 #include <ctype.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <stdlib.h>
26 #include "aslink.h"
27
28 #ifdef _WIN32
29 #  ifdef __MINGW32__ /* GCC MINGW32 depends on configure */
30 #    include "sdccconf.h"
31 #  else
32 #    include "sdcc_vc.h"
33 #  endif
34 #else /* Assume Un*x style system */
35 #  include "sdccconf.h"
36 #endif
37
38 static int execStartMSB;
39 static int execStartLSB;
40 static char execStartMSBfound;
41 static char execStartLSBfound;
42
43 typedef TYPE_UDWORD Elf32_Addr;
44 typedef TYPE_WORD Elf32_Half;
45 typedef TYPE_UDWORD Elf32_Off;
46 typedef TYPE_DWORD Elf32_Sword;
47 typedef TYPE_UDWORD Elf32_Word;
48
49 enum
50 {
51   EI_MAG0 = 0,
52   EI_MAG1,
53   EI_MAG2,
54   EI_MAG3,
55   EI_CLASS,
56   EI_DATA,
57   EI_VERSION,
58   EI_PAD,
59   EI_NIDENT = 16
60 };
61
62 enum
63 {
64   ELFMAG0 = 0x7f,
65   ELFMAG1 = 'E',
66   ELFMAG2 = 'L',
67   ELFMAG3 = 'F'
68 };
69
70 enum
71 {
72   ET_NONE = 0,
73   ET_REL,
74   ET_EXEC,
75   ET_DYN,
76   ET_CORE
77 };
78
79 /* These e_machine values are from "Motorola 8- and 16-bit Embedded */
80 /* Application Binary Interface (M8/16EABI)" version 2.0 */
81 enum
82 {
83   EM_NONE = 0,
84   EM_68HC05 = 72,
85   EM_68HC08 = 71,
86   EM_68HC11 = 70,
87   EM_68HC12 = 53,
88   EM_68HC16 = 69
89 };
90
91 enum
92 {
93   EV_NONE = 0,
94   EV_CURRENT
95 };
96
97 enum
98 {
99   ELFCLASSNONE = 0,
100   ELFCLASS32,
101   ELFCLASS64
102 };
103
104 enum
105 {
106   ELFDATANONE = 0,
107   ELFDATA2LSB,
108   ELFDATA2MSB
109 };
110
111 enum
112 {
113   SHT_NULL = 0,
114   SHT_PROGBITS,
115   SHT_SYMTAB,
116   SHT_STRTAB,
117   SHT_RELA,
118   SHT_HASH,
119   SHT_DYNAMIC,
120   SHT_NOTE,
121   SHT_NOBITS,
122   SHT_REL,
123   SHT_SHLIB,
124   SHT_DYNSYM
125 };
126
127 enum
128 {
129   SHF_WRITE = (1 << 0),
130   SHF_ALLOC = (1 << 1),
131   SHF_EXECINSTR = (1 << 2),
132 };
133
134 enum
135 {
136   PT_NULL = 0,
137   PT_LOAD
138 };
139
140 enum
141 {
142   PF_X = (1 << 0),
143   PF_W = (1 << 1),
144   PF_R = (1 << 2)
145 };
146
147 typedef struct
148 {
149   unsigned char e_ident[EI_NIDENT];
150   Elf32_Half e_type;
151   Elf32_Half e_machine;
152   Elf32_Word e_version;
153   Elf32_Addr e_entry;
154   Elf32_Off e_phoff;
155   Elf32_Off e_shoff;
156   Elf32_Word e_flags;
157   Elf32_Half e_ehsize;
158   Elf32_Half e_phentsize;
159   Elf32_Half e_phnum;
160   Elf32_Half e_shentsize;
161   Elf32_Half e_shnum;
162   Elf32_Half e_shstrndx;
163 } Elf32_Ehdr;
164
165 typedef struct
166 {
167   Elf32_Word sh_name;
168   Elf32_Word sh_type;
169   Elf32_Word sh_flags;
170   Elf32_Addr sh_addr;
171   Elf32_Off sh_offset;
172   Elf32_Word sh_size;
173   Elf32_Word sh_link;
174   Elf32_Word sh_info;
175   Elf32_Word sh_addralign;
176   Elf32_Word sh_entsize;
177 } Elf32_Shdr;
178
179 typedef struct
180 {
181   Elf32_Word p_type;
182   Elf32_Off p_offset;
183   Elf32_Addr p_vaddr;
184   Elf32_Addr p_paddr;
185   Elf32_Word p_filesz;
186   Elf32_Word p_memsz;
187   Elf32_Word p_flags;
188   Elf32_Word p_align;
189 } Elf32_Phdr;
190
191 typedef struct strtabString
192 {
193   char * string;
194   struct strtabString * prev;
195   struct strtabString * next;
196   Elf32_Word index;
197 } strtabString;
198
199 typedef struct
200 {
201   strtabString * first;
202   strtabString * last;
203 } strtabList;
204
205 static strtabList shstrtab;
206
207
208 typedef struct listEntry
209 {
210   void * item;
211   struct listEntry * prev;
212   struct listEntry * next;
213 } listEntry;
214
215 typedef struct
216 {
217   listEntry * first;
218   listEntry * last;
219   int count;
220 } listHeader;
221
222
223
224 static void
225 listAdd (listHeader * lhp, void * item)
226 {
227   listEntry * lep;
228   
229   lep = new (sizeof (*lep));
230   lep->item = item;
231   lep->prev = lhp->last;
232   if (lep->prev)
233     lep->prev->next = lep;
234   
235   lhp->last = lep;
236   if (!lhp->first)
237     lhp->first = lep;
238   
239   lhp->count++;
240 }
241
242 static listHeader *
243 listNew (void)
244 {
245   listHeader * lhp;
246   
247   lhp = new (sizeof (*lhp));
248   
249   return lhp;
250 }
251
252
253 #if 0
254 static Elf32_Word  
255 strtabFind (strtabList * strtab, char * str)
256 {
257   strtabString * sp;
258   sp = strtab->first;
259   
260   while (sp)
261     {
262       if (!strcmp (str, sp->string))
263         return sp->index;
264       sp = sp->next;
265     }
266   
267   return 0;
268 }
269 #endif
270
271 /*-------------------------------------------------------------------*/
272 /* strtabFindOrAdd - Finds a string in a string table or adds the    */
273 /*   string if it does not already exist. Returns the offset of the  */
274 /*   string in the table.                                            */
275 /*-------------------------------------------------------------------*/
276 static Elf32_Word  
277 strtabFindOrAdd (strtabList * strtab, char * str)
278 {
279   strtabString * sp;
280   sp = strtab->first;
281
282   while (sp)
283     {
284       if (!strcmp (str, sp->string))
285         return sp->index;
286       sp = sp->next;
287     }
288   
289   sp = new (sizeof(*sp));
290   if (strtab->last)
291     sp->index = strtab->last->index + 1 + strlen (strtab->last->string);
292   else
293     sp->index = 1;
294   sp->string = new (1+strlen (str));
295   strcpy (sp->string, str);
296   
297   sp->prev = strtab->last;
298   if (sp->prev)
299     sp->prev->next = sp;
300   strtab->last = sp;
301   if (!strtab->first)
302     strtab->first = sp;
303   
304   return sp->index;
305 }
306
307 /*-------------------------------------------------------------------*/
308 /* fputElfStrtab - writes a string table to a file                   */
309 /*-------------------------------------------------------------------*/
310 static void
311 fputElfStrtab (strtabList *strtab, FILE *fp)
312 {
313   strtabString * sp;
314   
315   fputc (0, fp);        /* index 0 must be the null character */
316   
317   sp = strtab->first;
318   while (sp)
319     {
320       fputs (sp->string, fp);
321       fputc (0, fp);
322       sp = sp->next;
323     }
324 }
325
326 /*-------------------------------------------------------------------*/
327 /* fputElf32_Word - writes an Elf32_Word value to a file             */
328 /*-------------------------------------------------------------------*/
329 static void
330 fputElf32_Word (Elf32_Word x, FILE *fp)
331 {
332   if (hilo == 0)
333     {
334       fputc (x & 0xff, fp);
335       fputc ((x >> 8) & 0xff, fp);
336       fputc ((x >> 16) & 0xff, fp);
337       fputc ((x >> 24) & 0xff, fp);
338     }
339   else
340     {
341       fputc ((x >> 24) & 0xff, fp);
342       fputc ((x >> 16) & 0xff, fp);
343       fputc ((x >> 8) & 0xff, fp);
344       fputc (x & 0xff, fp);
345     }
346 }
347
348 /*-------------------------------------------------------------------*/
349 /* fputElf32_Off - writes an Elf32_Off value to a file               */
350 /*-------------------------------------------------------------------*/
351 static void
352 fputElf32_Off (Elf32_Off x, FILE *fp)
353 {
354   if (hilo == 0)
355     {
356       fputc (x & 0xff, fp);
357       fputc ((x >> 8) & 0xff, fp);
358       fputc ((x >> 16) & 0xff, fp);
359       fputc ((x >> 24) & 0xff, fp);
360     }
361   else
362     {
363       fputc ((x >> 24) & 0xff, fp);
364       fputc ((x >> 16) & 0xff, fp);
365       fputc ((x >> 8) & 0xff, fp);
366       fputc (x & 0xff, fp);
367     }
368 }
369
370 /*-------------------------------------------------------------------*/
371 /* fputElf32_Addr - writes an Elf32_Addr value to a file             */
372 /*-------------------------------------------------------------------*/
373 static void
374 fputElf32_Addr (Elf32_Addr x, FILE *fp)
375 {
376   if (hilo == 0)
377     {
378       fputc (x & 0xff, fp);
379       fputc ((x >> 8) & 0xff, fp);
380       fputc ((x >> 16) & 0xff, fp);
381       fputc ((x >> 24) & 0xff, fp);
382     }
383   else
384     {
385       fputc ((x >> 24) & 0xff, fp);
386       fputc ((x >> 16) & 0xff, fp);
387       fputc ((x >> 8) & 0xff, fp);
388       fputc (x & 0xff, fp);
389     }
390 }
391
392 /*-------------------------------------------------------------------*/
393 /* fputElf32_Half - writes an Elf32_Half value to a file             */
394 /*-------------------------------------------------------------------*/
395 static void
396 fputElf32_Half (Elf32_Half x, FILE *fp)
397 {
398   if (hilo == 0)
399     {
400       fputc (x & 0xff, fp);
401       fputc ((x >> 8) & 0xff, fp);
402     }
403   else
404     {
405       fputc ((x >> 8) & 0xff, fp);
406       fputc (x & 0xff, fp);
407     }
408 }
409
410 /*------------------------------------------------------------------------*/
411 /* fputElf32_Ehdr - writes an Elf32_Ehdr struct (ELF header) to a file    */
412 /*------------------------------------------------------------------------*/
413 static void
414 fputElf32_Ehdr (Elf32_Ehdr * ehdr, FILE * fp)
415 {
416   int i;
417   
418   for (i=0; i<EI_NIDENT; i++)
419     fputc (ehdr->e_ident[i], fp);
420     
421   fputElf32_Half (ehdr->e_type, fp);
422   fputElf32_Half (ehdr->e_machine, fp);
423   fputElf32_Word (ehdr->e_version, fp);
424   fputElf32_Addr (ehdr->e_entry, fp);
425   fputElf32_Off (ehdr->e_phoff, fp);
426   fputElf32_Off (ehdr->e_shoff, fp);
427   fputElf32_Word (ehdr->e_flags, fp);
428   fputElf32_Half (ehdr->e_ehsize, fp);
429   fputElf32_Half (ehdr->e_phentsize, fp);
430   fputElf32_Half (ehdr->e_phnum, fp);
431   fputElf32_Half (ehdr->e_shentsize, fp);
432   fputElf32_Half (ehdr->e_shnum, fp);
433   fputElf32_Half (ehdr->e_shstrndx, fp);
434 }
435
436 /*-------------------------------------------------------------------------*/
437 /* fputElf32_Ehdr - writes an Elf32_Shdr struct (section header) to a file */
438 /*-------------------------------------------------------------------------*/
439 static void
440 fputElf32_Shdr (Elf32_Shdr * shdr, FILE * fp)
441 {
442   fputElf32_Word (shdr->sh_name, fp);
443   fputElf32_Word (shdr->sh_type, fp);
444   fputElf32_Word (shdr->sh_flags, fp);
445   fputElf32_Addr (shdr->sh_addr, fp);
446   fputElf32_Off (shdr->sh_offset, fp);
447   fputElf32_Word (shdr->sh_size, fp);
448   fputElf32_Word (shdr->sh_link, fp);
449   fputElf32_Word (shdr->sh_info, fp);
450   fputElf32_Word (shdr->sh_addralign, fp);
451   fputElf32_Word (shdr->sh_entsize, fp);
452 }
453
454 /*-------------------------------------------------------------------------*/
455 /* fputElf32_Ehdr - writes an Elf32_Phdr struct (segment header) to a file */
456 /*-------------------------------------------------------------------------*/
457 static void
458 fputElf32_Phdr (Elf32_Phdr * phdr, FILE * fp)
459 {
460   fputElf32_Word (phdr->p_type, fp);
461   fputElf32_Off (phdr->p_offset, fp);
462   fputElf32_Addr (phdr->p_vaddr, fp);
463   fputElf32_Addr (phdr->p_paddr, fp);
464   fputElf32_Word (phdr->p_filesz, fp);
465   fputElf32_Word (phdr->p_memsz, fp);
466   fputElf32_Word (phdr->p_flags, fp);
467   fputElf32_Word (phdr->p_align, fp);
468 }
469
470
471 /*--------------------------------------------------------------------------*/
472 /* elfGenerateAbs - generates segments and sections for an absolute area.   */
473 /*   This is a little more complicated than a relative area since it may    */
474 /*   contain noncontiguous regions.                                         */
475 /*--------------------------------------------------------------------------*/
476 static void
477 elfGenerateAbs (struct area *ap, listHeader * segments, listHeader * sections)
478 {
479   Elf32_Addr ofs;
480   Elf32_Addr addr;
481   Elf32_Word size;
482   Elf32_Phdr * phdrp;
483   Elf32_Shdr * shdrp;
484   size_t res;
485
486   if (!ap->a_image)
487     {
488       return;
489     }
490   
491   ofs = 0;
492   for (;;)
493     {
494       /* Find the start of a contiguously */
495       /* used region within this area */
496       while (ofs < ap->a_size && !ap->a_used[ofs])
497         ofs++;
498       if (ofs >= ap->a_size)
499         return;
500
501       /* Find the end of the region */
502       addr = ap->a_addr + ofs;
503       while (ofs < ap->a_size && ap->a_used[ofs])
504         ofs++;
505       size = ap->a_addr + ofs - addr;
506       
507       /* create a segment header for this region if loadable */
508       if (!(ap->a_flag & A_NOLOAD))
509         {
510           phdrp = new (sizeof (*phdrp));  
511           phdrp->p_type = PT_LOAD;
512           phdrp->p_offset = ftell (ofp);
513           phdrp->p_vaddr = addr;
514           phdrp->p_paddr = addr;
515           phdrp->p_filesz = size;
516           phdrp->p_memsz = size;
517           phdrp->p_flags = PF_R;
518           if (ap->a_flag & A_CODE)
519             phdrp->p_flags |= PF_X;
520           phdrp->p_align = 1;
521           listAdd (segments, phdrp);
522         }
523   
524       /* create a section header for this region */
525       shdrp = new (sizeof (*shdrp));  
526       shdrp->sh_name = strtabFindOrAdd (&shstrtab, ap->a_id);
527       shdrp->sh_type = SHT_PROGBITS;
528       shdrp->sh_flags = 0;
529       if (!(ap->a_flag & A_NOLOAD))
530         shdrp->sh_flags |= SHF_ALLOC;
531       if (ap->a_flag & A_CODE)
532         shdrp->sh_flags |= SHF_EXECINSTR;
533       shdrp->sh_addr = addr;
534       shdrp->sh_offset = ftell (ofp);
535       shdrp->sh_size = size;
536       shdrp->sh_link = 0;
537       shdrp->sh_info = 0;
538       shdrp->sh_addralign = 0;
539       shdrp->sh_entsize = 0;
540       listAdd (sections, shdrp);
541       
542       res = fwrite (&ap->a_image[addr-ap->a_addr], 1, size, ofp);
543       assert(res == size);
544     }  
545 }
546
547 /*--------------------------------------------------------------------------*/
548 /* elfGenerateRel - generates a segment and section for a relative area.    */
549 /*--------------------------------------------------------------------------*/
550 static void
551 elfGenerateRel (struct area *ap, listHeader * segments, listHeader * sections)
552 {
553   Elf32_Phdr * phdrp;
554   Elf32_Shdr * shdrp;
555   size_t res;
556   
557   if (!ap->a_image)
558     {
559       return;
560     }
561
562   /* create a segment header for this area if loadable */
563   if (!(ap->a_flag & A_NOLOAD))
564     {
565       phdrp = new (sizeof (*phdrp));  
566       phdrp->p_type = PT_LOAD;
567       phdrp->p_offset = ftell (ofp);
568       phdrp->p_vaddr = ap->a_addr;
569       phdrp->p_paddr = ap->a_addr;
570       phdrp->p_filesz = ap->a_size;
571       phdrp->p_memsz = ap->a_size;
572       phdrp->p_flags = PF_R;
573       if (ap->a_flag & A_CODE)
574         phdrp->p_flags |= PF_X;
575       phdrp->p_align = 1;
576       listAdd (segments, phdrp);
577     }
578   
579   /* create a section header for this area */
580   shdrp = new (sizeof (*shdrp));  
581   shdrp->sh_name = strtabFindOrAdd (&shstrtab, ap->a_id);
582   shdrp->sh_type = SHT_PROGBITS;
583   shdrp->sh_flags = 0;
584   if (!(ap->a_flag & A_NOLOAD))
585     shdrp->sh_flags |= SHF_ALLOC;
586   if (ap->a_flag & A_CODE)
587     shdrp->sh_flags |= SHF_EXECINSTR;
588   shdrp->sh_addr = ap->a_addr;
589   shdrp->sh_offset = ftell (ofp);
590   shdrp->sh_size = ap->a_size;
591   shdrp->sh_link = 0;
592   shdrp->sh_info = 0;
593   shdrp->sh_addralign = 0;
594   shdrp->sh_entsize = 0;
595   listAdd (sections, shdrp);
596   
597   res = fwrite (ap->a_image, 1, ap->a_size, ofp);
598   assert(res == ap->a_size);
599 }
600
601 /*--------------------------------------------------------------------------*/
602 /* elfGenerate - generates the complete ELF file                            */
603 /*--------------------------------------------------------------------------*/
604 static void
605 elfGenerate (void)
606 {
607   listHeader * sections = listNew();
608   listHeader * segments = listNew();
609   struct area *ap;
610   Elf32_Ehdr ehdr;
611   Elf32_Shdr * shdrp;
612   Elf32_Phdr * phdrp;
613   listEntry * lep;
614   int i;
615   Elf32_Word shstrtabName;
616   
617   /* create the null section header for index 0 */
618   shdrp = new (sizeof (*shdrp));
619   shdrp->sh_name = 0;
620   shdrp->sh_type = SHT_NULL;
621   shdrp->sh_flags = 0;
622   shdrp->sh_addr = 0;
623   shdrp->sh_offset = 0;
624   shdrp->sh_size = 0;
625   shdrp->sh_link = 0;
626   shdrp->sh_info = 0;
627   shdrp->sh_addralign = 0;
628   shdrp->sh_entsize = 0;
629   listAdd (sections, shdrp);
630
631   /* Initialize the ELF header */
632   for (i=0; i<EI_NIDENT; i++)
633     ehdr.e_ident[i] = 0;
634   ehdr.e_ident[EI_MAG0] = ELFMAG0;
635   ehdr.e_ident[EI_MAG1] = ELFMAG1;
636   ehdr.e_ident[EI_MAG2] = ELFMAG2;
637   ehdr.e_ident[EI_MAG3] = ELFMAG3;
638   ehdr.e_ident[EI_CLASS] = ELFCLASS32;
639   if (hilo == 0)
640     ehdr.e_ident[EI_DATA] = ELFDATA2LSB;
641   else
642     ehdr.e_ident[EI_DATA] = ELFDATA2MSB;
643   ehdr.e_ident[EI_VERSION] = 1;
644   ehdr.e_type = ET_EXEC;
645   ehdr.e_machine = EM_68HC08; /* FIXME: get rid of hardcoded value - EEP */
646   ehdr.e_phentsize = sizeof (*phdrp);
647   ehdr.e_shentsize = sizeof (*shdrp);
648   ehdr.e_ehsize = sizeof (ehdr);
649   ehdr.e_phnum = 0;
650   ehdr.e_shnum = 0;
651   ehdr.e_shstrndx = 0;
652   ehdr.e_version = 1;
653   ehdr.e_entry = 0;
654   if (execStartMSBfound && execStartLSBfound)
655     ehdr.e_entry = (execStartMSB << 8) + execStartLSB;
656   
657   /* Write out the ELF header as a placeholder; we will update */
658   /* it with the final values when everything is complete */
659   fputElf32_Ehdr (&ehdr, ofp);
660   
661   /* Iterate over the linker areas to generate */
662   /* the ELF sections and segments */
663   ap = areap;
664   while (ap)
665     {
666       if (ap->a_size)
667         {
668           if (ap->a_flag & A_ABS)
669             elfGenerateAbs (ap, segments, sections);
670           else
671             elfGenerateRel (ap, segments, sections);
672         }
673       ap = ap->a_ap;
674     }
675   
676   /* Create the string table section after the other sections */
677   shdrp = new (sizeof (*shdrp));
678   shdrp->sh_name = strtabFindOrAdd (&shstrtab, ".shstrtab");
679   shdrp->sh_type = SHT_STRTAB;
680   shdrp->sh_flags = 0;
681   shdrp->sh_addr = 0;
682   shdrp->sh_offset = ftell (ofp);
683   shdrp->sh_size = shstrtab.last->index + strlen (shstrtab.last->string) + 1;
684   shdrp->sh_link = 0;
685   shdrp->sh_info = 0;
686   shdrp->sh_addralign = 0;
687   shdrp->sh_entsize = 0;
688   listAdd (sections, shdrp);
689   fputElfStrtab (&shstrtab, ofp);
690   
691   /* Find the index of the section string table */
692   /* header and save it in the ELF header */
693   ehdr.e_shstrndx = 0;
694   shstrtabName = shdrp->sh_name;
695   lep = sections->first;
696   while (lep)
697     {
698       shdrp = lep->item;
699       if (shdrp->sh_name == shstrtabName)
700         break;
701       ehdr.e_shstrndx++;
702       lep = lep->next;
703     }
704   
705   /* Write out the segment headers */
706   ehdr.e_phnum = segments->count;
707   ehdr.e_phoff = ftell (ofp);
708   lep = segments->first;
709   while (lep)
710     {
711       phdrp = lep->item;
712       fputElf32_Phdr (phdrp, ofp);
713       lep = lep->next;
714     }
715
716   /* Write out the section headers */
717   ehdr.e_shnum = sections->count;
718   ehdr.e_shoff = ftell (ofp);
719   lep = sections->first;
720   while (lep)
721     {
722       shdrp = lep->item;
723       fputElf32_Shdr (shdrp, ofp);
724       lep = lep->next;
725     }
726
727   /* All the values in the ELF header have now been computed; write */
728   /* over the placeholder header with the final values */
729   fseek (ofp, 0, SEEK_SET);
730   fputElf32_Ehdr (&ehdr, ofp);
731   fseek (ofp, 0, SEEK_END);      
732 }
733
734 /*--------------------------------------------------------------------------*/
735 /* elf - incrementally called by the linker core to generate ELF file data. */
736 /*    The parameter is nonzero when there is data available and zero when   */
737 /*    the linker is finished.                                               */
738 /*--------------------------------------------------------------------------*/
739 void
740 elf (int i)
741 {
742   Addr_T address;
743
744   /* Buffer the data until we have it all */
745   if (i)
746     {      
747       if (hilo == 0)
748         address = rtval[0] + (rtval[1] << 8); /* little endian order */
749       else
750         address = rtval[1] + (rtval[0] << 8); /* big endian order */
751
752       /* If this area doesn't have an image buffer, create one */
753       if (!ap->a_image)
754         {
755           ap->a_image = new (ap->a_size);
756           if (ap->a_flag & A_ABS)
757             ap->a_used = new (ap->a_size);
758         }
759
760       /* Copy the data into the image buffer */
761       for (i = 2; i < rtcnt ; i++)
762         {
763           if (rtflg[i])
764             {
765               ap->a_image[address-ap->a_addr] = rtval[i];
766               if (ap->a_used)
767                 ap->a_used[address-ap->a_addr] = 1;
768               
769               /* Make note of the reset vector */
770               if (!(ap->a_flag & A_NOLOAD))
771                 {
772                   if (address == 0xfffe)
773                     {
774                       execStartMSB = rtval[i];
775                       execStartMSBfound = 1;
776                     }
777                   if (address == 0xffff)
778                     {
779                       execStartLSB = rtval[i];
780                       execStartLSBfound = 1;
781                     }
782                 }
783               address++;
784             }
785         }
786     }
787   else
788     elfGenerate();
789 }