Authentication-Results: mail-b.sr.ht; dkim=pass header.d=gmail.com header.i=@gmail.com Received: from mail-qv1-f41.google.com (mail-qv1-f41.google.com [209.85.219.41]) by mail-b.sr.ht (Postfix) with ESMTPS id 65D1411EF28 for <~pixelherodev/knightos@lists.sr.ht>; Mon, 12 Jul 2021 03:48:52 +0000 (UTC) Received: by mail-qv1-f41.google.com with SMTP id i4so7408997qvq.10 for <~pixelherodev/knightos@lists.sr.ht>; Sun, 11 Jul 2021 20:48:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=2Wa7ucuYgunGwROGNDb3hJHpjw/OvI0hpCpz+ZZous8=; b=Czlv2093N2VOrqWNT5bV2e1H8aFW2ijCyYG3lGflqlQyP08Qj9og5VDo1Yo27h4rsp JAQAviu9whyabc634/kFUg1UwWQWX2Dl01u9a0pC+pTC/hmJLmM90n8ArAysopQA6/g8 R1352aNgWsqa+Qa3dP/qzqdbU5UBazP/fD1xtA4BRIe5PkXiu6cx44tG0nyCgpq1kB/J UMSlCkbIW3QrQintwCNPjxlXmS7XMpUAqOiwICJ0KMZ1BodtFEBVrl8qpDajcEIYbYKM 23/hcZtsJZHWC+9Xgxmlp2DOIbdlL1KsVv4LVI45WPaarSOsQWx+06MLTEI5e2bPK3f/ eSXQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=2Wa7ucuYgunGwROGNDb3hJHpjw/OvI0hpCpz+ZZous8=; b=ZtnYr47UUi7QJyxs7Ys4L1r/PX9I6J+FBxPn3r8xSme0CrYLujCe+k8+pj2Ek5nE86 hmWuV2FdJtIy6iIkROE4npEtdFt29FuN1najvp5f2Yg6J2GUxBgveZLTD9YTUxBZ6Yn1 KRoGvt9H8cEDQH7GLfE4Ndh/yB9CXSjQ85ZsjZJYiroxQhCY8eP3A47J6vKr3h+QWuqt Dd+SABdtLZeGxfIx9iFRRYwE/jP/bjzUPPaRKvPgEFO9TT5dpUqulMoERwD7jvV7AdIb EYKSTgSORINwY+TXhzAaJAMtyskbWVruWfef4vj7mIepZj3S6MYCpvmOtdwB+49NuRPK gyow== X-Gm-Message-State: AOAM532Vt7sg+ctZOt7Erm8DCcMviuKcpPpKBj90nMGSpwTSTS41UL5y 1M7L3o9zHOo/ULHTaLT2wPmr6BxogVQ= X-Google-Smtp-Source: ABdhPJxcjlyXvl8XLRJKg9z+Jy40dKm8l1NiDd6+MEq+CXCi88uE36zCmTW2SJPVnUpPIT4k7fjJCg== X-Received: by 2002:a0c:df85:: with SMTP id w5mr31571151qvl.24.1626061731753; Sun, 11 Jul 2021 20:48:51 -0700 (PDT) Received: from dell.myfiosgateway.com (pool-96-232-174-225.nycmny.fios.verizon.net. [96.232.174.225]) by smtp.gmail.com with ESMTPSA id v5sm5319535qtp.25.2021.07.11.20.48.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 11 Jul 2021 20:48:51 -0700 (PDT) From: Jacob G-W To: ~pixelherodev/knightos@lists.sr.ht Cc: Jacob G-W Subject: [PATCH] scas: add plan9 object file support Date: Sun, 11 Jul 2021 23:48:24 -0400 Message-Id: <20210712034823.32663-1-jacoblevgw@gmail.com> X-Mailer: git-send-email 2.29.3 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + Makefile | 4 +- include/linker.h | 1 + include/plan9.h | 2 + linker/plan9.c | 137 +++++++++++++++++++++++++++++++++++++++++++++++ scas.c | 3 ++ 6 files changed, 146 insertions(+), 2 deletions(-) create mode 100644 include/plan9.h create mode 100644 linker/plan9.c diff --git a/.gitignore b/.gitignore index 00ae34f..e5850b3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ *.swp *.o +*.6 bin/ *.rom test/ diff --git a/Makefile b/Makefile index fd28234..142739f 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ CFLAGS=-Iinclude/ -O2 -Ibin/ -Wall -Wextra -pedantic -std=c99 -D_XOPEN_SOURCE=70 ASSEMBLER=assembler/privatize.c assembler/directives.c assembler/assembler.c COMMON=bin/amd64.c bin/z80.c bin/arm64.c common/functions.c common/hashtable.c common/expression.c common/list.c common/operators.c common/runtime.c common/stringop.c common/errors.c common/stack.c common/format.c common/instructions.c common/log.c common/match.c common/md5.c common/objects.c common/readline.c -LINKER=linker/8xp.c linker/bin.c linker/linker.c linker/merge.c +LINKER=linker/8xp.c linker/plan9.c linker/bin.c linker/linker.c linker/merge.c SOURCES=$(ASSEMBLER) $(COMMON) $(LINKER) all:bin/scas bin/scdump bin/scwrap @@ -70,7 +70,7 @@ bin/generate_tables: tables/generate.c mkdir -p bin/ $(CC) $(CFLAGS) $< -o $@ -$(SOURCES:.c=.o) scas.o: bin/z80.h bin/amd64.h bin/arm64.h include/linker.h include/match.h include/format.h include/merge.h include/list.h include/assembler.h include/md5.h include/objects.h include/8xp.h include/stack.h include/bin.h include/directives.h include/errors.h include/instructions.h include/readline.h include/runtime.h include/stringop.h include/hashtable.h include/functions.h include/log.h include/expression.h include/privatize.h include/operators.h +$(SOURCES:.c=.o) scas.o: bin/z80.h bin/amd64.h bin/arm64.h include/linker.h include/match.h include/format.h include/merge.h include/list.h include/assembler.h include/md5.h include/objects.h include/8xp.h include/plan9.h include/stack.h include/bin.h include/directives.h include/errors.h include/instructions.h include/readline.h include/runtime.h include/stringop.h include/hashtable.h include/functions.h include/log.h include/expression.h include/privatize.h include/operators.h .c.o: $(CC) $(CFLAGS) -c $< -o $@ diff --git a/include/linker.h b/include/linker.h index e6fa184..dfc4bfb 100644 --- a/include/linker.h +++ b/include/linker.h @@ -9,4 +9,5 @@ struct linker_settings { format_writer write_output; }; +list_t *symbols_gather(list_t *areas, list_t *errors); void link_objects(FILE *output, list_t *objects, linker_settings_t *settings); diff --git a/include/plan9.h b/include/plan9.h new file mode 100644 index 0000000..7686da8 --- /dev/null +++ b/include/plan9.h @@ -0,0 +1,2 @@ +int output_plan9(FILE *f, object_t *object, linker_settings_t *settings); + diff --git a/linker/plan9.c b/linker/plan9.c new file mode 100644 index 0000000..6a14171 --- /dev/null +++ b/linker/plan9.c @@ -0,0 +1,137 @@ +#include +#include +#include +#include +#include +#include "list.h" +#include "stack.h" +#include "expression.h" +#include "objects.h" +#include "linker.h" +#include "plan9.h" +#include "instructions.h" +#include "runtime.h" +#include "log.h" + +#define HDR_MAGIC 0x00008000 /* header expansion */ + +#define _MAGIC(f, b) ((f)|((((4*(b))+0)*(b))+7)) +#define A_MAGIC _MAGIC(0, 8) /* 68020 */ +#define I_MAGIC _MAGIC(0, 11) /* intel 386 */ +#define J_MAGIC _MAGIC(0, 12) /* intel 960 (retired) */ +#define K_MAGIC _MAGIC(0, 13) /* sparc */ +#define V_MAGIC _MAGIC(0, 16) /* mips 3000 BE */ +#define X_MAGIC _MAGIC(0, 17) /* att dsp 3210 (retired) */ +#define M_MAGIC _MAGIC(0, 18) /* mips 4000 BE */ +#define D_MAGIC _MAGIC(0, 19) /* amd 29000 (retired) */ +#define E_MAGIC _MAGIC(0, 20) /* arm */ +#define Q_MAGIC _MAGIC(0, 21) /* powerpc */ +#define N_MAGIC _MAGIC(0, 22) /* mips 4000 LE */ +#define L_MAGIC _MAGIC(0, 23) /* dec alpha (retired) */ +#define P_MAGIC _MAGIC(0, 24) /* mips 3000 LE */ +#define U_MAGIC _MAGIC(0, 25) /* sparc64 */ +#define S_MAGIC _MAGIC(HDR_MAGIC, 26) /* amd64 */ +#define T_MAGIC _MAGIC(HDR_MAGIC, 27) /* powerpc64 */ +#define R_MAGIC _MAGIC(HDR_MAGIC, 28) /* arm64 */ + +void write_be32(FILE *f, uint32_t value) { + uint8_t bytes[4]; + bytes[0] = (value >> 24) & 0xff; + bytes[1] = (value >> 16) & 0xff; + bytes[2] = (value >> 8) & 0xff; + bytes[3] = (value) & 0xff; + fwrite(bytes, 4, 1, f); +} +void write_be64(FILE *f, uint64_t value) { + write_be32(f, (value >> 32) & 0xffffffff); + write_be32(f, (value) & 0xffffffff); +} + +// returns 1 on failure +uint32_t get_magic(char* arch) { + if (strcmp(arch, "amd64")) { + return S_MAGIC; + } + if (strcmp(arch, "arm64")) { + return R_MAGIC; + } + return 1; +} + +int output_plan9(FILE *f, object_t *object, linker_settings_t *settings) { + area_t* data = 0; + area_t* text = 0; + uint32_t bss_len = 0; + uint32_t syms_len = 0; + uint64_t entry = 0; + + for (unsigned int i = 0; i < object->areas->length; i++){ + area_t* area = object->areas->items[i]; + if (strcmp("_CODE", area->name) == 0) { + text = area; + relocate_area(text, 0x200028, true); + } else if (strcmp("_DATA", area->name) == 0) { + data = area; + relocate_area(data, 0x400000, true); + } else { + scas_log(L_ERROR, "unknown section name for plan9 a.out format: %s", area->name); + return 1; + } + } + if (text == 0) { + scas_log(L_ERROR, "plan9 a.out format needs text section"); + return 1; + } + + // the header + uint32_t magic = get_magic(scas_runtime.arch); + bool is64 = (magic & HDR_MAGIC) >> 15 == 1; + if (magic == 1) return 1; + write_be32(f, magic); + write_be32(f, text->data_length); + if (data != 0) + write_be32(f, data->data_length); + else + write_be32(f, 0); + write_be32(f, bss_len); + write_be32(f, syms_len); + write_be32(f, entry); + write_be32(f, 0); // size of pc/sp offset table + write_be32(f, 0); // size of pc/line number table + if (is64) + write_be64(f, entry); + + // write the text + fwrite(text->data, 1, text->data_length, f); + // 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; + } + // write back into the header + fseek(f, 4 * 4, SEEK_SET); + write_be32(f, symseclen); + fseek(f, 5 * 4, SEEK_SET); + write_be32(f, entry); + if (is64) { + fseek(f, 8 * 4, SEEK_SET); + write_be64(f, entry); + } + fseek(f, 0, SEEK_END); + + return 0; +} diff --git a/scas.c b/scas.c index b97a488..b55fd3c 100644 --- a/scas.c +++ b/scas.c @@ -18,6 +18,7 @@ #include "linker.h" #include "assembler.h" #include "8xp.h" +#include "plan9.h" #include "bin.h" #include "merge.h" #include "runtime.h" @@ -164,6 +165,8 @@ bool parse_flag(const char *flag) { scas_runtime.options.output_format = output_bin; } else if (strcmp(value, "8xp") == 0){ scas_runtime.options.output_format = output_8xp; + } else if (strcmp(value, "plan9") == 0){ + scas_runtime.options.output_format = output_plan9; } else { scas_log(L_ERROR, "Unknown output format %s", value); return false; -- 2.29.3