~pixelherodev/knightos

plan9 linker: correctly handle symbol types v1 PROPOSED

Jacob G-W: 1
 plan9 linker: correctly handle symbol types

 2 files changed, 45 insertions(+), 18 deletions(-)
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~pixelherodev/knightos/patches/23797/mbox | git am -3
Learn more about email & git

[PATCH] plan9 linker: correctly handle symbol types Export this patch

Also add comments to some potentially confusing places
---
 include/linker.h |  2 +-
 linker/plan9.c   | 61 ++++++++++++++++++++++++++++++++++--------------
 2 files changed, 45 insertions(+), 18 deletions(-)

diff --git a/include/linker.h b/include/linker.h
index dfc4bfb..ac4270d 100644
--- a/include/linker.h
+++ b/include/linker.h
@@ -9,5 +9,5 @@ struct linker_settings {
    format_writer write_output;
};

list_t *symbols_gather(list_t *areas, list_t *errors);
symbol_t * find_symbol(list_t *symbols, char *name);
void link_objects(FILE *output, list_t *objects, linker_settings_t *settings);
diff --git a/linker/plan9.c b/linker/plan9.c
index 6a14171..d19d83d 100644
--- a/linker/plan9.c
+++ b/linker/plan9.c
@@ -3,6 +3,7 @@
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <ctype.h>
#include "list.h"
#include "stack.h"
#include "expression.h"
@@ -12,6 +13,8 @@
#include "instructions.h"
#include "runtime.h"
#include "log.h"
#include "errors.h"
#include "merge.h"

#define HDR_MAGIC	0x00008000		/* header expansion */

@@ -57,6 +60,16 @@ uint32_t get_magic(char* arch) {
	}
	return 1;
}
uint8_t get_symtype_from_area(area_t* area) {
	if (strcmp(area->name, "_CODE") == 0) {
		return 't';
	} else if (strcmp(area->name, "_DATA") == 0) {
		return 'd';
	} else {
		scas_log(L_ERROR, "unknown area type for plan9 %s", area->name);
		return 0;
	}
}

int output_plan9(FILE *f, object_t *object, linker_settings_t *settings) {
	area_t* data = 0;
@@ -98,6 +111,7 @@ int output_plan9(FILE *f, object_t *object, linker_settings_t *settings) {
	write_be32(f, entry);
	write_be32(f, 0); // size of pc/sp offset table
	write_be32(f, 0); // size of pc/line number table
	// fat header
	if (is64)
		write_be64(f, entry);

@@ -106,32 +120,45 @@ int output_plan9(FILE *f, object_t *object, linker_settings_t *settings) {
	// write the data (if there is any)
	if (data != 0)
		fwrite(data->data, 1, data->data_length, f);
	// write the symbols
	uint32_t symseclen = 0;
	list_t* symbols = symbols_gather(object->areas, settings->errors);
	for (unsigned int i = 0; i < symbols->length; i++){
		symbol_t* s = symbols->items[i];
		if (is64)
			write_be64(f, s->value);
		else
			write_be32(f, s->value);
		fputc('T' | 0x80, f); // TODO actual type not just text
		int namelen = strlen(s->name) + 1;
		fwrite(s->name, sizeof(char), namelen, f);
		if (strcmp("start", s->name) == 0)
			entry = s->value;
		symseclen += 8 + 1 + namelen;

	list_t *symbols = create_list();
	char type;
	for(unsigned int i = 0; i < object->areas->length; i += 1) {
		area_t* area = object->areas->items[i];
		type = get_symtype_from_area(area);
		for(unsigned int i = 0; i < area->symbols->length; ++i){
			symbol_t *s = area->symbols->items[i];
			if(find_symbol(symbols, s->name))
				add_error_from_map(settings->errors, ERROR_DUPLICATE_SYMBOL,
								   area->source_map, s->defined_address, s->name);
			else {
				if (is64)
					write_be64(f, s->value);
				else
					write_be32(f, s->value);
				uint8_t type_toput = (s->exported ? toupper(type) : type) | 0x80;
				fputc(type_toput, f);
				int namelen = strlen(s->name) + 1;
				fwrite(s->name, sizeof(char), namelen, f);
				if (strcmp("start", s->name) == 0)
					entry = s->value;
				syms_len += 8 + 1 + namelen;
			}
		}
	}

	// write back into the header
	// write the symbol table len
	fseek(f, 4 * 4, SEEK_SET);
	write_be32(f, symseclen);
	write_be32(f, syms_len);
	// entry point
	fseek(f, 5 * 4, SEEK_SET);
	write_be32(f, entry);
	// fat entry point
	if (is64) {
		fseek(f, 8 * 4, SEEK_SET);
		write_be64(f, entry);
	}
	fseek(f, 0, SEEK_END);

	return 0;
}
-- 
2.29.3