diff --git a/TODO b/TODO index 38fea64..d307297 100644 --- a/TODO +++ b/TODO @@ -44,7 +44,6 @@ Tools: - readelf: add support for program headers - as: * support .ident: - + move strtab to tunit + have .ident append string to .comment strtab + finalize .comment strtab before output() * add support for named sections diff --git a/as/output.c b/as/output.c index a1d34b0..2eb6c0b 100644 --- a/as/output.c +++ b/as/output.c @@ -24,59 +24,9 @@ #include "pdp10-elf36.h" #include "pdp10-stdint.h" #include "pdp10-stdio.h" -#include "assemble.h" #include "hashtab.h" #include "output.h" - -struct strtab_entry { - struct strtab_entry *next; - const char *string; - unsigned int nrbytes; /* strlen(string) + 1 */ -}; - -struct strtab { - struct section section; /* first to simplify mapping §ion to &strtab */ - struct strtab_entry *head; -}; - -static pdp10_uint36_t strtab_enter(struct tunit *tunit, struct strtab *strtab, const char *name) -{ - struct strtab_entry *prev, *here; - pdp10_uint36_t index; - - index = 1; - prev = NULL; - here = strtab->head; - while (here != NULL) { - if (strcmp(name, here->string) == 0) - return index; - index += here->nrbytes; - prev = here; - here = here->next; - } - - here = malloc(sizeof *here); - if (!here) { - fprintf(stderr, "%s: failed to allocate %zu bytes for a strtab_entry: %s\n", - tunit->progname, sizeof *here, strerror(errno)); - return 0; - } - here->next = NULL; - here->string = name; - here->nrbytes = strlen(name) + 1; - - if (prev) { - prev->next = here; - } else { - strtab->head = here; - index = 1; - strtab->section.dot = 1; - } - - strtab->section.dot += here->nrbytes; - - return index; -} +#include "tunit.h" static int output_padding(PDP10_FILE *pdp10fp, unsigned int nrbytes) { @@ -86,33 +36,6 @@ static int output_padding(PDP10_FILE *pdp10fp, unsigned int nrbytes) return 0; } -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; - - if (pdp10_elf36_write_uint9(pdp10fp, '\0') < 0) - return -1; - - for (here = strtab->head; here; here = here->next) - for (i = 0; i < here->nrbytes; ++i) - if (pdp10_elf36_write_uint9(pdp10fp, here->string[i]) < 0) - return -1; - - 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; diff --git a/as/tunit.c b/as/tunit.c index b4314cd..a150801 100644 --- a/as/tunit.c +++ b/as/tunit.c @@ -21,6 +21,7 @@ #include #include #include +#include "pdp10-elf36.h" #include "hashtab.h" #include "tunit.h" @@ -122,6 +123,75 @@ static int sections_init(struct tunit *tunit) return 0; } +/* + * String tables. + */ +pdp10_uint36_t strtab_enter(struct tunit *tunit, struct strtab *strtab, const char *name) +{ + struct strtab_entry *prev, *here; + pdp10_uint36_t index; + + index = 1; + prev = NULL; + here = strtab->head; + while (here != NULL) { + if (strcmp(name, here->string) == 0) + return index; + index += here->nrbytes; + prev = here; + here = here->next; + } + + here = malloc(sizeof *here); + if (!here) { + fprintf(stderr, "%s: failed to allocate %zu bytes for a strtab_entry: %s\n", + tunit->progname, sizeof *here, strerror(errno)); + return 0; + } + here->next = NULL; + here->string = name; + here->nrbytes = strlen(name) + 1; + + if (prev) { + prev->next = here; + } else { + strtab->head = here; + index = 1; + strtab->section.dot = 1; + } + + strtab->section.dot += here->nrbytes; + + return index; +} + +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; + + if (pdp10_elf36_write_uint9(pdp10fp, '\0') < 0) + return -1; + + for (here = strtab->head; here; here = here->next) + for (i = 0; i < here->nrbytes; ++i) + if (pdp10_elf36_write_uint9(pdp10fp, here->string[i]) < 0) + return -1; + + return 0; +} + +void strtab_init(struct strtab *strtab, const char *name) +{ + section_init(&strtab->section, name); + strtab->section.sh_type = SHT_STRTAB; + strtab->section.sh_addralign = 1; + strtab->section.output = strtab_section_output; + strtab->head = NULL; +} + /* * Symbols hash table. */ diff --git a/as/tunit.h b/as/tunit.h index 87caa62..01c7995 100644 --- a/as/tunit.h +++ b/as/tunit.h @@ -81,6 +81,17 @@ struct section { void section_init(struct section *section, const char *name); +struct strtab_entry { + struct strtab_entry *next; + const char *string; + unsigned int nrbytes; /* strlen(string) + 1 */ +}; + +struct strtab { + struct section section; /* first to simplify mapping §ion to &strtab */ + struct strtab_entry *head; +}; + struct symbol { struct hashnode hashnode; const char *name; @@ -111,4 +122,7 @@ struct section *tunit_section_enter(struct tunit *tunit, const char *name); struct symbol *tunit_symbol_lookup(struct tunit *tunit, const char *name); struct symbol *tunit_symbol_enter(struct tunit *tunit, const char *name); +pdp10_uint36_t strtab_enter(struct tunit *tunit, struct strtab *strtab, const char *name); +void strtab_init(struct strtab *strtab, const char *name); + #endif /* TUNIT_H */