as: allow output_section() to work on strtabs

- add optional ->output() method to struct section
- make output_section() use ->output() if present
- make strtab_init() set up ->output
- change strtab_write() into a trivial wrapper for output_section()
This commit is contained in:
Mikael Pettersson 2015-04-26 22:08:37 +02:00
parent 966059fbb6
commit 70768a829c
4 changed files with 28 additions and 23 deletions

2
TODO
View File

@ -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()

View File

@ -35,18 +35,10 @@ struct strtab_entry {
};
struct strtab {
struct section section; /* first to simplify mapping &section 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;
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)

View File

@ -65,6 +65,7 @@ void section_init(struct section *section, const char *name)
section->head = NULL;
section->tailptr = &section->head;
section->dot = 0;
section->output = NULL;
section->image = NULL;
section->st_shndx = 0;
section->sh_name = 0;

View File

@ -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;