struct / union in initializer, RFE #901.
[sdcc.git] / sdcc / sdas / linksrc / lkelf.c
bloba9aa78ac7d6ad42a03970f2e3fcda0353bc1a1af
1 /* lkelf.c - Create an executable ELF/DWARF file
3 Copyright (C) 2004 Erik Petrich, epetrich at users dot sourceforge dot net
4 Copyright (C) 2015 Peter Dons Tychsen at pdt dot dontech dot dk
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 3, or (at your option) any
9 later version.
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.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 #include <ctype.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <stdlib.h>
23 #include <asxxxx_config.h>
25 #include "aslink.h"
27 static int execStartMSB;
28 static int execStartLSB;
29 static char execStartMSBfound;
30 static char execStartLSBfound;
32 typedef TYPE_UDWORD Elf32_Addr;
33 typedef TYPE_WORD Elf32_Half;
34 typedef TYPE_UDWORD Elf32_Off;
35 typedef TYPE_DWORD Elf32_Sword;
36 typedef TYPE_UDWORD Elf32_Word;
38 enum
40 EI_MAG0 = 0,
41 EI_MAG1,
42 EI_MAG2,
43 EI_MAG3,
44 EI_CLASS,
45 EI_DATA,
46 EI_VERSION,
47 EI_PAD,
48 EI_NIDENT = 16
51 enum
53 ELFMAG0 = 0x7f,
54 ELFMAG1 = 'E',
55 ELFMAG2 = 'L',
56 ELFMAG3 = 'F'
59 enum
61 ET_NONE = 0,
62 ET_REL,
63 ET_EXEC,
64 ET_DYN,
65 ET_CORE
68 /* These e_machine values are from "Motorola 8- and 16-bit Embedded */
69 /* Application Binary Interface (M8/16EABI)" version 2.0 */
70 enum
72 EM_NONE = 0,
73 EM_68HC05 = 72,
74 EM_68HC08 = 71,
75 EM_68HC11 = 70,
76 EM_68HC12 = 53,
77 EM_68HC16 = 69,
78 EM_STM8 = 186
81 enum
83 EV_NONE = 0,
84 EV_CURRENT
87 enum
89 ELFCLASSNONE = 0,
90 ELFCLASS32,
91 ELFCLASS64
94 enum
96 ELFDATANONE = 0,
97 ELFDATA2LSB,
98 ELFDATA2MSB
101 enum
103 SHT_NULL = 0,
104 SHT_PROGBITS,
105 SHT_SYMTAB,
106 SHT_STRTAB,
107 SHT_RELA,
108 SHT_HASH,
109 SHT_DYNAMIC,
110 SHT_NOTE,
111 SHT_NOBITS,
112 SHT_REL,
113 SHT_SHLIB,
114 SHT_DYNSYM
117 enum
119 SHF_WRITE = (1 << 0),
120 SHF_ALLOC = (1 << 1),
121 SHF_EXECINSTR = (1 << 2),
124 enum
126 SHN_UNDEF = 0,
127 SHN_ABS = 0xfff1
130 #define ELF32_ST_INFO(b,t) (((b)<<4)+((t)&0xf))
132 enum
134 PT_NULL = 0,
135 PT_LOAD
138 enum
140 PF_X = (1 << 0),
141 PF_W = (1 << 1),
142 PF_R = (1 << 2)
145 typedef struct
147 unsigned char e_ident[EI_NIDENT];
148 Elf32_Half e_type;
149 Elf32_Half e_machine;
150 Elf32_Word e_version;
151 Elf32_Addr e_entry;
152 Elf32_Off e_phoff;
153 Elf32_Off e_shoff;
154 Elf32_Word e_flags;
155 Elf32_Half e_ehsize;
156 Elf32_Half e_phentsize;
157 Elf32_Half e_phnum;
158 Elf32_Half e_shentsize;
159 Elf32_Half e_shnum;
160 Elf32_Half e_shstrndx;
161 } Elf32_Ehdr;
163 typedef struct
165 Elf32_Word sh_name;
166 Elf32_Word sh_type;
167 Elf32_Word sh_flags;
168 Elf32_Addr sh_addr;
169 Elf32_Off sh_offset;
170 Elf32_Word sh_size;
171 Elf32_Word sh_link;
172 Elf32_Word sh_info;
173 Elf32_Word sh_addralign;
174 Elf32_Word sh_entsize;
175 } Elf32_Shdr;
177 typedef struct
179 Elf32_Word p_type;
180 Elf32_Off p_offset;
181 Elf32_Addr p_vaddr;
182 Elf32_Addr p_paddr;
183 Elf32_Word p_filesz;
184 Elf32_Word p_memsz;
185 Elf32_Word p_flags;
186 Elf32_Word p_align;
187 } Elf32_Phdr;
189 typedef struct
191 Elf32_Word st_name;
192 Elf32_Addr st_value;
193 Elf32_Word st_size;
194 unsigned char st_info;
195 unsigned char st_other;
196 Elf32_Half st_shndx;
197 } Elf32_Sym;
199 typedef struct strtabString
201 char * string;
202 struct strtabString * prev;
203 struct strtabString * next;
204 Elf32_Word index;
205 } strtabString;
207 typedef struct
209 strtabString * first;
210 strtabString * last;
211 } strtabList;
213 static strtabList shstrtab;
214 static strtabList strtab;
217 typedef struct listEntry
219 void * item;
220 struct listEntry * prev;
221 struct listEntry * next;
222 } listEntry;
224 typedef struct
226 listEntry * first;
227 listEntry * last;
228 int count;
229 } listHeader;
233 static void
234 listAdd (listHeader * lhp, void * item)
236 listEntry * lep;
238 lep = (listEntry *)new (sizeof (*lep));
239 lep->item = item;
240 lep->prev = lhp->last;
241 if (lep->prev)
242 lep->prev->next = lep;
244 lhp->last = lep;
245 if (!lhp->first)
246 lhp->first = lep;
248 lhp->count++;
251 static listHeader *
252 listNew (void)
254 listHeader * lhp;
256 lhp = (listHeader *)new (sizeof (*lhp));
258 return lhp;
261 /*---------------------------------------------------------------------*/
262 /* strtabFind - Find section header index in a list of section headers */
263 /* Returns the offset of the section */
264 /*---------------------------------------------------------------------*/
265 static Elf32_Half
266 strtabFindShndx (strtabList * strtab, char * str)
268 strtabString * sp;
269 Elf32_Half shndx = 0;
270 sp = strtab->first;
272 while (sp)
274 if (!strcmp (str, sp->string))
275 return shndx;
276 shndx++;
277 sp = sp->next;
280 return 0;
283 /*-------------------------------------------------------------------*/
284 /* strtabFindOrAdd - Finds a string in a string table or adds the */
285 /* string if it does not already exist. Returns the offset of the */
286 /* string in the table. */
287 /*-------------------------------------------------------------------*/
288 static Elf32_Word
289 strtabFindOrAdd (strtabList * strtab, char * str)
291 strtabString * sp;
292 sp = strtab->first;
294 while (sp)
296 if (!strcmp (str, sp->string))
297 return sp->index;
298 sp = sp->next;
301 sp = (strtabString *)new (sizeof(*sp));
302 if (strtab->last)
303 sp->index = strtab->last->index + 1 + strlen (strtab->last->string);
304 else
305 sp->index = 1;
306 sp->string = new (1+strlen (str));
307 strcpy (sp->string, str);
309 sp->prev = strtab->last;
310 if (sp->prev)
311 sp->prev->next = sp;
312 strtab->last = sp;
313 if (!strtab->first)
314 strtab->first = sp;
316 return sp->index;
319 /*-------------------------------------------------------------------*/
320 /* fputElfStrtab - writes a string table to a file */
321 /*-------------------------------------------------------------------*/
322 static void
323 fputElfStrtab (strtabList *strtab, FILE *fp)
325 strtabString * sp;
327 fputc (0, fp); /* index 0 must be the null character */
329 sp = strtab->first;
330 while (sp)
332 fputs (sp->string, fp);
333 fputc (0, fp);
334 sp = sp->next;
338 /*-------------------------------------------------------------------*/
339 /* fputElf32_Word - writes an Elf32_Word value to a file */
340 /*-------------------------------------------------------------------*/
341 static void
342 fputElf32_Word (Elf32_Word x, FILE *fp)
344 if (hilo == 0)
346 fputc (x & 0xff, fp);
347 fputc ((x >> 8) & 0xff, fp);
348 fputc ((x >> 16) & 0xff, fp);
349 fputc ((x >> 24) & 0xff, fp);
351 else
353 fputc ((x >> 24) & 0xff, fp);
354 fputc ((x >> 16) & 0xff, fp);
355 fputc ((x >> 8) & 0xff, fp);
356 fputc (x & 0xff, fp);
360 /*-------------------------------------------------------------------*/
361 /* fputElf32_Off - writes an Elf32_Off value to a file */
362 /*-------------------------------------------------------------------*/
363 static void
364 fputElf32_Off (Elf32_Off x, FILE *fp)
366 if (hilo == 0)
368 fputc (x & 0xff, fp);
369 fputc ((x >> 8) & 0xff, fp);
370 fputc ((x >> 16) & 0xff, fp);
371 fputc ((x >> 24) & 0xff, fp);
373 else
375 fputc ((x >> 24) & 0xff, fp);
376 fputc ((x >> 16) & 0xff, fp);
377 fputc ((x >> 8) & 0xff, fp);
378 fputc (x & 0xff, fp);
382 /*-------------------------------------------------------------------*/
383 /* fputElf32_Addr - writes an Elf32_Addr value to a file */
384 /*-------------------------------------------------------------------*/
385 static void
386 fputElf32_Addr (Elf32_Addr x, FILE *fp)
388 if (hilo == 0)
390 fputc (x & 0xff, fp);
391 fputc ((x >> 8) & 0xff, fp);
392 fputc ((x >> 16) & 0xff, fp);
393 fputc ((x >> 24) & 0xff, fp);
395 else
397 fputc ((x >> 24) & 0xff, fp);
398 fputc ((x >> 16) & 0xff, fp);
399 fputc ((x >> 8) & 0xff, fp);
400 fputc (x & 0xff, fp);
404 /*-------------------------------------------------------------------*/
405 /* fputElf32_Half - writes an Elf32_Half value to a file */
406 /*-------------------------------------------------------------------*/
407 static void
408 fputElf32_Half (Elf32_Half x, FILE *fp)
410 if (hilo == 0)
412 fputc (x & 0xff, fp);
413 fputc ((x >> 8) & 0xff, fp);
415 else
417 fputc ((x >> 8) & 0xff, fp);
418 fputc (x & 0xff, fp);
422 /*------------------------------------------------------------------------*/
423 /* fputElf32_Ehdr - writes an Elf32_Ehdr struct (ELF header) to a file */
424 /*------------------------------------------------------------------------*/
425 static void
426 fputElf32_Ehdr (Elf32_Ehdr * ehdr, FILE * fp)
428 int i;
430 for (i=0; i<EI_NIDENT; i++)
431 fputc (ehdr->e_ident[i], fp);
433 fputElf32_Half (ehdr->e_type, fp);
434 fputElf32_Half (ehdr->e_machine, fp);
435 fputElf32_Word (ehdr->e_version, fp);
436 fputElf32_Addr (ehdr->e_entry, fp);
437 fputElf32_Off (ehdr->e_phoff, fp);
438 fputElf32_Off (ehdr->e_shoff, fp);
439 fputElf32_Word (ehdr->e_flags, fp);
440 fputElf32_Half (ehdr->e_ehsize, fp);
441 fputElf32_Half (ehdr->e_phentsize, fp);
442 fputElf32_Half (ehdr->e_phnum, fp);
443 fputElf32_Half (ehdr->e_shentsize, fp);
444 fputElf32_Half (ehdr->e_shnum, fp);
445 fputElf32_Half (ehdr->e_shstrndx, fp);
448 /*-------------------------------------------------------------------------*/
449 /* fputElf32_Ehdr - writes an Elf32_Shdr struct (section header) to a file */
450 /*-------------------------------------------------------------------------*/
451 static void
452 fputElf32_Shdr (Elf32_Shdr * shdr, FILE * fp)
454 fputElf32_Word (shdr->sh_name, fp);
455 fputElf32_Word (shdr->sh_type, fp);
456 fputElf32_Word (shdr->sh_flags, fp);
457 fputElf32_Addr (shdr->sh_addr, fp);
458 fputElf32_Off (shdr->sh_offset, fp);
459 fputElf32_Word (shdr->sh_size, fp);
460 fputElf32_Word (shdr->sh_link, fp);
461 fputElf32_Word (shdr->sh_info, fp);
462 fputElf32_Word (shdr->sh_addralign, fp);
463 fputElf32_Word (shdr->sh_entsize, fp);
466 /*-------------------------------------------------------------------------*/
467 /* fputElf32_Ehdr - writes an Elf32_Phdr struct (segment header) to a file */
468 /*-------------------------------------------------------------------------*/
469 static void
470 fputElf32_Phdr (Elf32_Phdr * phdr, FILE * fp)
472 fputElf32_Word (phdr->p_type, fp);
473 fputElf32_Off (phdr->p_offset, fp);
474 fputElf32_Addr (phdr->p_vaddr, fp);
475 fputElf32_Addr (phdr->p_paddr, fp);
476 fputElf32_Word (phdr->p_filesz, fp);
477 fputElf32_Word (phdr->p_memsz, fp);
478 fputElf32_Word (phdr->p_flags, fp);
479 fputElf32_Word (phdr->p_align, fp);
482 /*-------------------------------------------------------------------------*/
483 /* fputElf32_Sym - writes an Elf32_Sym struct (symbol) to a file */
484 /*-------------------------------------------------------------------------*/
485 static void
486 fputElf32_Sym (Elf32_Sym * symhdr, FILE * fp)
488 fputElf32_Word (symhdr->st_name, fp);
489 fputElf32_Addr (symhdr->st_value, fp);
490 fputElf32_Word (symhdr->st_size, fp);
491 fputc (symhdr->st_info, fp);
492 fputc (symhdr->st_other, fp);
493 fputElf32_Half (symhdr->st_shndx, fp);
496 enum
498 STB_LOCAL = 0,
499 STB_GLOBAL,
500 STB_WEAK
503 enum
505 STT_NOTYPE = 0,
506 STT_OBJECT,
507 STT_FUNC
510 /*--------------------------------------------------------------------------*/
511 /* elfGenerateSyms - generates symbol headers for a list of symbols */
512 /*--------------------------------------------------------------------------*/
513 static void
514 elfGenerateSyms(struct head *hp)
516 int i;
517 struct sym *sym;
518 Elf32_Sym *symhdr;
520 /* Add empty */
521 symhdr = (Elf32_Sym *)new (sizeof (*symhdr));
522 fputElf32_Sym (symhdr, ofp);
524 /* Add all modules */
525 while(hp)
527 /* Add all symbols */
528 for(i=0;i<hp->h_nsym;i++)
530 sym = hp->s_list[i];
531 if(sym->s_id)
533 symhdr = (Elf32_Sym *)new (sizeof (*symhdr));
534 symhdr->st_name = strtabFindOrAdd(&strtab,sym->s_id);
535 symhdr->st_value = sym->s_addr + sym->s_axp->a_addr;
536 symhdr->st_shndx = strtabFindShndx(&shstrtab,sym->s_axp->a_bap->a_id);
537 symhdr->st_info = ELF32_ST_INFO(STB_GLOBAL,STT_FUNC);
538 if(!symhdr->st_shndx)
540 symhdr->st_shndx = SHN_ABS;
543 fputElf32_Sym (symhdr, ofp);
546 hp = hp->h_hp;
550 /*--------------------------------------------------------------------------*/
551 /* elfGenerateAbs - generates segments and sections for an absolute area. */
552 /* This is a little more complicated than a relative area since it may */
553 /* contain noncontiguous regions. */
554 /*--------------------------------------------------------------------------*/
555 static void
556 elfGenerateAbs (struct area *ap, listHeader * segments, listHeader * sections)
558 Elf32_Addr ofs;
559 Elf32_Addr addr;
560 Elf32_Word size;
561 Elf32_Phdr * phdrp;
562 Elf32_Shdr * shdrp;
564 if (!ap->a_image)
566 return;
569 ofs = 0;
570 for (;;)
572 /* Find the start of a contiguously */
573 /* used region within this area */
574 while (ofs < ap->a_imagesize && !ap->a_used[ofs])
575 ofs++;
576 if (ofs >= ap->a_imagesize)
577 return;
579 /* Find the end of the region */
580 addr = ap->a_addr + ofs;
581 while (ofs < ap->a_imagesize && ap->a_used[ofs])
582 ofs++;
583 size = ap->a_addr + ofs - addr;
585 /* create a segment header for this region if loadable */
586 if (!(ap->a_flag & A_NOLOAD))
588 phdrp = (Elf32_Phdr *)new (sizeof (*phdrp));
589 phdrp->p_type = PT_LOAD;
590 phdrp->p_offset = ftell (ofp);
591 phdrp->p_vaddr = addr;
592 phdrp->p_paddr = addr;
593 phdrp->p_filesz = size;
594 phdrp->p_memsz = size;
595 phdrp->p_flags = PF_R;
596 if (ap->a_flag & A_CODE)
597 phdrp->p_flags |= PF_X;
598 phdrp->p_align = 1;
599 listAdd (segments, phdrp);
602 /* create a section header for this region */
603 shdrp = (Elf32_Shdr *)new (sizeof (*shdrp));
604 shdrp->sh_name = strtabFindOrAdd (&shstrtab, ap->a_id);
605 shdrp->sh_type = SHT_PROGBITS;
606 shdrp->sh_flags = 0;
607 if (!(ap->a_flag & A_NOLOAD))
608 shdrp->sh_flags |= SHF_ALLOC;
609 if (ap->a_flag & A_CODE)
610 shdrp->sh_flags |= SHF_EXECINSTR;
611 shdrp->sh_addr = addr;
612 shdrp->sh_offset = ftell (ofp);
613 shdrp->sh_size = size;
614 shdrp->sh_link = 0;
615 shdrp->sh_info = 0;
616 shdrp->sh_addralign = 0;
617 shdrp->sh_entsize = 0;
618 listAdd (sections, shdrp);
620 fwrite (&ap->a_image[addr-ap->a_addr], 1, size, ofp);
624 /*--------------------------------------------------------------------------*/
625 /* elfGenerateRel - generates a segment and section for a relative area. */
626 /*--------------------------------------------------------------------------*/
627 static void
628 elfGenerateRel (struct area *ap, listHeader * segments, listHeader * sections)
630 Elf32_Phdr * phdrp;
631 Elf32_Shdr * shdrp;
633 if (!ap->a_image)
635 return;
638 /* create a segment header for this area if loadable */
639 if (!(ap->a_flag & A_NOLOAD))
641 phdrp = (Elf32_Phdr *)new (sizeof (*phdrp));
642 phdrp->p_type = PT_LOAD;
643 phdrp->p_offset = ftell (ofp);
644 phdrp->p_vaddr = ap->a_addr;
645 phdrp->p_paddr = ap->a_addr;
646 phdrp->p_filesz = ap->a_size;
647 phdrp->p_memsz = ap->a_size;
648 phdrp->p_flags = PF_R;
649 if (ap->a_flag & A_CODE)
650 phdrp->p_flags |= PF_X;
651 phdrp->p_align = 1;
652 listAdd (segments, phdrp);
655 /* create a section header for this area */
656 shdrp = (Elf32_Shdr *)new (sizeof (*shdrp));
657 shdrp->sh_name = strtabFindOrAdd (&shstrtab, ap->a_id);
658 shdrp->sh_type = SHT_PROGBITS;
659 shdrp->sh_flags = 0;
660 if (!(ap->a_flag & A_NOLOAD))
661 shdrp->sh_flags |= SHF_ALLOC;
662 if (ap->a_flag & A_CODE)
663 shdrp->sh_flags |= SHF_EXECINSTR;
664 shdrp->sh_addr = ap->a_addr;
665 shdrp->sh_offset = ftell (ofp);
666 shdrp->sh_size = ap->a_size;
667 shdrp->sh_link = 0;
668 shdrp->sh_info = 0;
669 shdrp->sh_addralign = 0;
670 shdrp->sh_entsize = 0;
671 listAdd (sections, shdrp);
673 fwrite (ap->a_image, 1, ap->a_size, ofp);
676 /*--------------------------------------------------------------------------*/
677 /* elfGenerate - generates the complete ELF file */
678 /*--------------------------------------------------------------------------*/
679 static void
680 elfGenerate (void)
682 listHeader * sections = listNew();
683 listHeader * segments = listNew();
684 struct area *ap;
685 Elf32_Ehdr ehdr;
686 Elf32_Shdr * shdrp;
687 Elf32_Phdr * phdrp;
688 listEntry * lep;
689 int i;
690 Elf32_Word shstrtabName;
692 /* create the null section header for index 0 */
693 shdrp = (Elf32_Shdr *)new (sizeof (*shdrp));
694 shdrp->sh_name = 0;
695 shdrp->sh_type = SHT_NULL;
696 shdrp->sh_flags = 0;
697 shdrp->sh_addr = 0;
698 shdrp->sh_offset = 0;
699 shdrp->sh_size = 0;
700 shdrp->sh_link = 0;
701 shdrp->sh_info = 0;
702 shdrp->sh_addralign = 0;
703 shdrp->sh_entsize = 0;
704 listAdd (sections, shdrp);
706 /* Initialize the ELF header */
707 for (i=0; i<EI_NIDENT; i++)
708 ehdr.e_ident[i] = 0;
709 ehdr.e_ident[EI_MAG0] = ELFMAG0;
710 ehdr.e_ident[EI_MAG1] = ELFMAG1;
711 ehdr.e_ident[EI_MAG2] = ELFMAG2;
712 ehdr.e_ident[EI_MAG3] = ELFMAG3;
713 ehdr.e_ident[EI_CLASS] = ELFCLASS32;
714 if (hilo == 0)
715 ehdr.e_ident[EI_DATA] = ELFDATA2LSB;
716 else
717 ehdr.e_ident[EI_DATA] = ELFDATA2MSB;
718 ehdr.e_ident[EI_VERSION] = 1;
719 ehdr.e_ident[EI_PAD] = 8;
720 ehdr.e_type = ET_EXEC;
721 ehdr.e_machine = TARGET_IS_STM8 ? EM_STM8 : EM_68HC08; /* FIXME: get rid of hardcoded value - EEP */
722 ehdr.e_phentsize = sizeof (*phdrp);
723 ehdr.e_shentsize = sizeof (*shdrp);
724 ehdr.e_ehsize = sizeof (ehdr);
725 ehdr.e_phnum = 0;
726 ehdr.e_shnum = 0;
727 ehdr.e_shstrndx = 0;
728 ehdr.e_version = 1;
729 ehdr.e_entry = 0;
730 if (execStartMSBfound && execStartLSBfound)
731 ehdr.e_entry = (execStartMSB << 8) + execStartLSB;
732 else
734 struct sym *entryp_sym;
735 entryp_sym = lkpsym("s_GSINIT",0);
736 if (entryp_sym)
738 ehdr.e_entry = entryp_sym->s_addr + entryp_sym->s_axp->a_addr;
742 /* Write out the ELF header as a placeholder; we will update */
743 /* it with the final values when everything is complete */
744 fputElf32_Ehdr (&ehdr, ofp);
746 /* Iterate over the linker areas to generate */
747 /* the ELF sections and segments */
748 ap = areap;
749 while (ap)
751 if (ap->a_size)
753 if (ap->a_flag & A3_ABS)
754 elfGenerateAbs (ap, segments, sections);
755 else
756 elfGenerateRel (ap, segments, sections);
758 ap = ap->a_ap;
761 /* Create symbol table section */
762 shdrp = (Elf32_Shdr *)new (sizeof (*shdrp));
763 shdrp->sh_name = strtabFindOrAdd (&shstrtab, ".symtab");
764 shdrp->sh_type = SHT_SYMTAB;
765 shdrp->sh_flags = 0;
766 shdrp->sh_addr = 0;
767 shdrp->sh_offset = ftell (ofp);
768 shdrp->sh_link = sections->count+1;
769 shdrp->sh_info = 1;
770 shdrp->sh_addralign = 0;
771 shdrp->sh_entsize = sizeof(Elf32_Sym);
772 lep = sections->first;
773 /* Generate symbols */
774 elfGenerateSyms(headp);
775 shdrp->sh_size = ftell(ofp) - shdrp->sh_offset;
776 listAdd (sections, shdrp);
778 /* Create string table section */
779 shdrp = (Elf32_Shdr *)new (sizeof (*shdrp));
780 shdrp->sh_name = strtabFindOrAdd (&shstrtab, ".strtab");
781 shdrp->sh_type = SHT_STRTAB;
782 shdrp->sh_flags = 0;
783 shdrp->sh_addr = 0;
784 shdrp->sh_offset = ftell (ofp);
785 shdrp->sh_size = strtab.last ? (strtab.last->index + strlen (strtab.last->string) + 1) : 0;
786 shdrp->sh_link = 0;
787 shdrp->sh_info = 0;
788 shdrp->sh_addralign = 0;
789 shdrp->sh_entsize = 0;
790 listAdd (sections, shdrp);
791 fputElfStrtab (&strtab, ofp);
793 /* Create the section header string table section after the other sections */
794 shdrp = (Elf32_Shdr *)new (sizeof (*shdrp));
795 shdrp->sh_name = strtabFindOrAdd (&shstrtab, ".shstrtab");
796 shdrp->sh_type = SHT_STRTAB;
797 shdrp->sh_flags = 0;
798 shdrp->sh_addr = 0;
799 shdrp->sh_offset = ftell (ofp);
800 shdrp->sh_size = shstrtab.last->index + strlen (shstrtab.last->string) + 1;
801 shdrp->sh_link = 0;
802 shdrp->sh_info = 0;
803 shdrp->sh_addralign = 0;
804 shdrp->sh_entsize = 0;
805 listAdd (sections, shdrp);
806 fputElfStrtab (&shstrtab, ofp);
808 /* Find the index of the section string table */
809 /* header and save it in the ELF header */
810 ehdr.e_shstrndx = 0;
811 shstrtabName = shdrp->sh_name;
812 lep = sections->first;
813 while (lep)
815 shdrp = lep->item;
816 if (shdrp->sh_name == shstrtabName)
817 break;
818 ehdr.e_shstrndx++;
819 lep = lep->next;
822 /* Write out the segment headers */
823 ehdr.e_phnum = segments->count;
824 ehdr.e_phoff = ftell (ofp);
825 lep = segments->first;
826 while (lep)
828 phdrp = lep->item;
829 fputElf32_Phdr (phdrp, ofp);
830 lep = lep->next;
833 /* Write out the section headers */
834 ehdr.e_shnum = sections->count;
835 ehdr.e_shoff = ftell (ofp);
836 lep = sections->first;
837 while (lep)
839 shdrp = lep->item;
840 fputElf32_Shdr (shdrp, ofp);
841 lep = lep->next;
844 /* All the values in the ELF header have now been computed; write */
845 /* over the placeholder header with the final values */
846 fseek (ofp, 0, SEEK_SET);
847 fputElf32_Ehdr (&ehdr, ofp);
848 fseek (ofp, 0, SEEK_END);
851 /*--------------------------------------------------------------------------*/
852 /* elf - incrementally called by the linker core to generate ELF file data. */
853 /* The parameter is nonzero when there is data available and zero when */
854 /* the linker is finished. */
855 /*--------------------------------------------------------------------------*/
856 void
857 elf (int i)
859 a_uint address;
861 /* Buffer the data until we have it all */
862 if (i)
864 /* 3 bytes address */
865 if(a_bytes == 3)
867 if (hilo == 0)
868 address = rtval[0] + (rtval[1] << 8) + (rtval[2] << 16); /* little endian order */
869 else
870 address = rtval[2] + (rtval[1] << 8) + (rtval[0] << 16); /* big endian order */
872 /* 2 bytes address */
873 else
875 if (hilo == 0)
876 address = rtval[0] + (rtval[1] << 8); /* little endian order */
877 else
878 address = rtval[1] + (rtval[0] << 8); /* big endian order */
881 /* If this area doesn't have an image buffer, create one */
882 if (!ap->a_image)
884 if (ap->a_flag & A3_ABS)
885 ap->a_imagesize = ap->a_addr + ap->a_size;
886 else
887 ap->a_imagesize = ap->a_size;
888 ap->a_image = new (ap->a_imagesize);
889 if (ap->a_flag & A3_ABS)
890 ap->a_used = new (ap->a_imagesize);
893 /* Copy the data into the image buffer */
894 for (i = a_bytes; i < rtcnt ; i++)
896 if (rtflg[i])
898 if (address-ap->a_addr >= ap->a_imagesize)
900 a_uint newsize;
902 if (ap->a_flag & A3_ABS)
904 newsize = ap->a_imagesize;
905 while (address-ap->a_addr >= newsize)
906 newsize = (newsize & ~4095)+4096;
907 ap->a_image = (char *) realloc (ap->a_image, newsize);
908 ap->a_used = (char *) realloc (ap->a_used, newsize);
909 if (!ap->a_image || !ap->a_used)
911 fprintf (stderr, "Out of space!\n");
912 lkexit (ER_FATAL);
914 memset (ap->a_image+ap->a_imagesize, 0, newsize-ap->a_imagesize);
915 memset (ap->a_used+ap->a_imagesize, 0, newsize-ap->a_imagesize);
916 ap->a_imagesize = newsize;
918 else
920 fprintf (stderr, "Unexpected area %s overflow. Address = 0x%x but allocated range is 0x%x - 0x%x\n",
921 ap->a_id, address, ap->a_addr, ap->a_addr+ap->a_imagesize-1);
922 lkexit (ER_FATAL);
925 ap->a_image[address-ap->a_addr] = rtval[i];
926 if (ap->a_used)
927 ap->a_used[address-ap->a_addr] = 1;
929 /* Make note of the reset vector */
930 if (!(ap->a_flag & A_NOLOAD))
932 if (address == 0xfffe)
934 execStartMSB = rtval[i];
935 execStartMSBfound = 1;
937 if (address == 0xffff)
939 execStartLSB = rtval[i];
940 execStartLSBfound = 1;
943 address++;
947 else
948 elfGenerate();