diff --git a/TODO b/TODO index 98f4e87..38fea64 100644 --- a/TODO +++ b/TODO @@ -44,8 +44,6 @@ Tools: - readelf: add support for program headers - as: * support .ident: - + change strtab to have a finalizer which returns an image array, - + use standard output_section for strtab + move strtab to tunit + have .ident append string to .comment strtab + finalize .comment strtab before output() diff --git a/as/output.c b/as/output.c index 9190f0c..a1d34b0 100644 --- a/as/output.c +++ b/as/output.c @@ -35,18 +35,10 @@ struct strtab_entry { }; struct strtab { + struct section section; /* first to simplify mapping §ion to &strtab */ struct strtab_entry *head; - struct section section; }; -static void strtab_init(struct strtab *strtab, const char *name) -{ - strtab->head = NULL; - section_init(&strtab->section, name); - strtab->section.sh_type = SHT_STRTAB; - strtab->section.sh_addralign = 1; -} - static pdp10_uint36_t strtab_enter(struct tunit *tunit, struct strtab *strtab, const char *name) { struct strtab_entry *prev, *here; @@ -94,8 +86,10 @@ static int output_padding(PDP10_FILE *pdp10fp, unsigned int nrbytes) return 0; } -static int strtab_write(PDP10_FILE *pdp10fp, const struct strtab *strtab) +static int strtab_section_output(PDP10_FILE *pdp10fp, const struct section *section) { + /* section is first in strtab, so no need to mess with offsetof */ + const struct strtab *strtab = (const struct strtab*)section; struct strtab_entry *here; unsigned int i; @@ -110,6 +104,15 @@ static int strtab_write(PDP10_FILE *pdp10fp, const struct strtab *strtab) return 0; } +static void strtab_init(struct strtab *strtab, const char *name) +{ + strtab->head = NULL; + section_init(&strtab->section, name); + strtab->section.sh_type = SHT_STRTAB; + strtab->section.sh_addralign = 1; + strtab->section.output = strtab_section_output; +} + struct context { struct tunit *tunit; Elf36_Word shnum; @@ -171,17 +174,23 @@ static int output_section(struct hashnode *hashnode, void *data) { struct section *section = (struct section*)hashnode; struct context *context = data; - unsigned int i; - if (section->dot == 0 || section->image == NULL) + if (section->dot == 0 || (section->image == NULL && section->output == NULL)) return 0; if (output_section_prologue(context, section) < 0) return -1; - for (i = 0; i < section->dot; ++i) - if (pdp10_elf36_write_uint9(context->pdp10fp, section->image[i]) < 0) + if (section->output) { + if (section->output(context->pdp10fp, section) < 0) return -1; + } else { + unsigned int i; + + for (i = 0; i < section->dot; ++i) + if (pdp10_elf36_write_uint9(context->pdp10fp, section->image[i]) < 0) + return -1; + } output_section_epilogue(context, section); @@ -219,12 +228,7 @@ static int output_shdr(struct hashnode *hashnode, void *data) static int output_strtab(struct context *context, struct strtab *strtab) { - if (output_section_prologue(context, &strtab->section) < 0) - return -1; - if (strtab_write(context->pdp10fp, strtab) < 0) - return -1; - output_section_epilogue(context, &strtab->section); - return 0; + return output_section(&strtab->section.hashnode, context); } static int process_symbol(struct hashnode *hashnode, void *data) diff --git a/as/tunit.c b/as/tunit.c index 313ab96..b4314cd 100644 --- a/as/tunit.c +++ b/as/tunit.c @@ -65,6 +65,7 @@ void section_init(struct section *section, const char *name) section->head = NULL; section->tailptr = §ion->head; section->dot = 0; + section->output = NULL; section->image = NULL; section->st_shndx = 0; section->sh_name = 0; diff --git a/as/tunit.h b/as/tunit.h index 0c32e45..87caa62 100644 --- a/as/tunit.h +++ b/as/tunit.h @@ -21,6 +21,7 @@ #define TUNIT_H #include "pdp10-elf36.h" +#include "pdp10-stdio.h" #include "hashtab.h" /* @@ -66,7 +67,8 @@ struct section { const char *name; struct stmt *head, **tailptr; unsigned long dot; - pdp10_uint9_t *image; /* assigned during assembly */ + int (*output)(PDP10_FILE*, const struct section*); /* must be present if ->image is NULL */ + pdp10_uint9_t *image; /* assigned during assembly, must be present if ->output is NULL */ Elf36_Word st_shndx; /* assigned during output */ Elf36_Word sh_name; /* assigned during output */ Elf36_Word sh_type;