-/*-------------------------------------------------------------------------
- lkelf.c - Create an executable ELF/DWARF file
+/* lkelf.c - Create an executable ELF/DWARF file
- Written By - Erik Petrich, epetrich@users.sourceforge.net (2004)
+ Copyright (C) 2004 Erik Petrich, epetrich at users dot sourceforge dot net
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the
- Free Software Foundation; either version 2, or (at your option) any
- later version.
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3, or (at your option) any
+later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
--------------------------------------------------------------------------*/
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
-#include "aslink.h"
+#include <asxxxx_config.h>
-#ifdef _WIN32
-# ifdef __MINGW32__ /* GCC MINGW32 depends on configure */
-# include "sdccconf.h"
-# else
-# include "sdcc_vc.h"
-# endif
-#else /* Assume Un*x style system */
-# include "sdccconf.h"
-#endif
+#include "aslink.h"
static int execStartMSB;
static int execStartLSB;
listAdd (listHeader * lhp, void * item)
{
listEntry * lep;
-
+
lep = new (sizeof (*lep));
lep->item = item;
lep->prev = lhp->last;
if (lep->prev)
lep->prev->next = lep;
-
+
lhp->last = lep;
if (!lhp->first)
lhp->first = lep;
-
+
lhp->count++;
}
listNew (void)
{
listHeader * lhp;
-
+
lhp = new (sizeof (*lhp));
-
+
return lhp;
}
#if 0
-static Elf32_Word
+static Elf32_Word
strtabFind (strtabList * strtab, char * str)
{
strtabString * sp;
sp = strtab->first;
-
+
while (sp)
{
if (!strcmp (str, sp->string))
return sp->index;
sp = sp->next;
}
-
+
return 0;
}
#endif
/* string if it does not already exist. Returns the offset of the */
/* string in the table. */
/*-------------------------------------------------------------------*/
-static Elf32_Word
+static Elf32_Word
strtabFindOrAdd (strtabList * strtab, char * str)
{
strtabString * sp;
return sp->index;
sp = sp->next;
}
-
+
sp = new (sizeof(*sp));
if (strtab->last)
sp->index = strtab->last->index + 1 + strlen (strtab->last->string);
sp->index = 1;
sp->string = new (1+strlen (str));
strcpy (sp->string, str);
-
+
sp->prev = strtab->last;
if (sp->prev)
sp->prev->next = sp;
strtab->last = sp;
if (!strtab->first)
strtab->first = sp;
-
+
return sp->index;
}
fputElfStrtab (strtabList *strtab, FILE *fp)
{
strtabString * sp;
-
- fputc (0, fp); /* index 0 must be the null character */
-
+
+ fputc (0, fp); /* index 0 must be the null character */
+
sp = strtab->first;
while (sp)
{
fputElf32_Ehdr (Elf32_Ehdr * ehdr, FILE * fp)
{
int i;
-
+
for (i=0; i<EI_NIDENT; i++)
fputc (ehdr->e_ident[i], fp);
-
+
fputElf32_Half (ehdr->e_type, fp);
fputElf32_Half (ehdr->e_machine, fp);
fputElf32_Word (ehdr->e_version, fp);
{
return;
}
-
+
ofs = 0;
for (;;)
{
while (ofs < ap->a_size && ap->a_used[ofs])
ofs++;
size = ap->a_addr + ofs - addr;
-
+
/* create a segment header for this region if loadable */
if (!(ap->a_flag & A_NOLOAD))
{
- phdrp = new (sizeof (*phdrp));
+ phdrp = new (sizeof (*phdrp));
phdrp->p_type = PT_LOAD;
phdrp->p_offset = ftell (ofp);
phdrp->p_vaddr = addr;
phdrp->p_align = 1;
listAdd (segments, phdrp);
}
-
+
/* create a section header for this region */
- shdrp = new (sizeof (*shdrp));
+ shdrp = new (sizeof (*shdrp));
shdrp->sh_name = strtabFindOrAdd (&shstrtab, ap->a_id);
shdrp->sh_type = SHT_PROGBITS;
shdrp->sh_flags = 0;
shdrp->sh_addralign = 0;
shdrp->sh_entsize = 0;
listAdd (sections, shdrp);
-
+
fwrite (&ap->a_image[addr-ap->a_addr], 1, size, ofp);
- }
+ }
}
/*--------------------------------------------------------------------------*/
{
Elf32_Phdr * phdrp;
Elf32_Shdr * shdrp;
-
+
if (!ap->a_image)
{
return;
/* create a segment header for this area if loadable */
if (!(ap->a_flag & A_NOLOAD))
{
- phdrp = new (sizeof (*phdrp));
+ phdrp = new (sizeof (*phdrp));
phdrp->p_type = PT_LOAD;
phdrp->p_offset = ftell (ofp);
phdrp->p_vaddr = ap->a_addr;
phdrp->p_align = 1;
listAdd (segments, phdrp);
}
-
+
/* create a section header for this area */
- shdrp = new (sizeof (*shdrp));
+ shdrp = new (sizeof (*shdrp));
shdrp->sh_name = strtabFindOrAdd (&shstrtab, ap->a_id);
shdrp->sh_type = SHT_PROGBITS;
shdrp->sh_flags = 0;
shdrp->sh_addralign = 0;
shdrp->sh_entsize = 0;
listAdd (sections, shdrp);
-
+
fwrite (ap->a_image, 1, ap->a_size, ofp);
}
listEntry * lep;
int i;
Elf32_Word shstrtabName;
-
+
/* create the null section header for index 0 */
shdrp = new (sizeof (*shdrp));
shdrp->sh_name = 0;
ehdr.e_entry = 0;
if (execStartMSBfound && execStartLSBfound)
ehdr.e_entry = (execStartMSB << 8) + execStartLSB;
-
+
/* Write out the ELF header as a placeholder; we will update */
/* it with the final values when everything is complete */
fputElf32_Ehdr (&ehdr, ofp);
-
+
/* Iterate over the linker areas to generate */
/* the ELF sections and segments */
ap = areap;
}
ap = ap->a_ap;
}
-
+
/* Create the string table section after the other sections */
shdrp = new (sizeof (*shdrp));
shdrp->sh_name = strtabFindOrAdd (&shstrtab, ".shstrtab");
shdrp->sh_entsize = 0;
listAdd (sections, shdrp);
fputElfStrtab (&shstrtab, ofp);
-
+
/* Find the index of the section string table */
/* header and save it in the ELF header */
ehdr.e_shstrndx = 0;
ehdr.e_shstrndx++;
lep = lep->next;
}
-
+
/* Write out the segment headers */
ehdr.e_phnum = segments->count;
ehdr.e_phoff = ftell (ofp);
/* over the placeholder header with the final values */
fseek (ofp, 0, SEEK_SET);
fputElf32_Ehdr (&ehdr, ofp);
- fseek (ofp, 0, SEEK_END);
+ fseek (ofp, 0, SEEK_END);
}
/*--------------------------------------------------------------------------*/
/* Buffer the data until we have it all */
if (i)
- {
+ {
if (hilo == 0)
address = rtval[0] + (rtval[1] << 8); /* little endian order */
else
ap->a_image[address-ap->a_addr] = rtval[i];
if (ap->a_used)
ap->a_used[address-ap->a_addr] = 1;
-
+
/* Make note of the reset vector */
if (!(ap->a_flag & A_NOLOAD))
{
execStartLSBfound = 1;
}
}
- address++;
+ address++;
}
}
}