Jacob G-W: 1 plan9 linker: correctly handle symbol types 2 files changed, 45 insertions(+), 18 deletions(-)
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 -3Learn more about email & git
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