diff --git a/8to9/8to9.c b/8to9/8to9.c
deleted file mode 100644
index 1fca89f..0000000
--- a/8to9/8to9.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * 8to9.c -- convert octet files to nonet files
- * Copyright (C) 2013-2015 Mikael Pettersson
- *
- * This file is part of pdp10-tools.
- *
- * pdp10-tools is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * pdp10-tools is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with pdp10-tools. If not, see .
- */
-#include
-#include
-#include
-#include
-#include "pdp10-stdio.h"
-
-#define VERSION "pdp10-tools 8to9 version 0.0, built " __DATE__ " " __TIME__ "\n"
-
-int main(int argc, char **argv)
-{
- const char *infile, *outfile;
- FILE *infp;
- PDP10_FILE *outfp;
- int ch;
-
- infile = NULL;
- outfile = NULL;
-
- for (;;) {
- ch = getopt(argc, argv, "Vi:o:");
- switch (ch) {
- case 'V':
- printf(VERSION);
- return 0;
- case 'i':
- infile = optarg;
- continue;
- case 'o':
- outfile = optarg;
- continue;
- case -1:
- break;
- default:
- fprintf(stderr, "%s -o OUTFILE [-i INFILE] [-V]\n", argv[0]);
- return 1;
- }
- break;
- }
-
- /* XXX: We currently require a named output file because pdp10-stdio.c doesn't
- support fdopen:ing non-seekable files. That should be fixed at some point. */
- if (!outfile) {
- fprintf(stderr, "%s: no OUTFILE specified\n", argv[0]);
- return 1;
- } else {
- outfp = pdp10_fopen(outfile, "wb");
- if (!outfp) {
- fprintf(stderr, "%s: %s: failed to open for writing: %s\n", argv[0], outfile, strerror(errno));
- return 1;
- }
- }
-
- if (!infile) {
- infp = stdin;
- } else {
- infp = fopen(infile, "rb");
- if (!infp) {
- fprintf(stderr, "%s: %s: failed to open for reading: %s\n", argv[0], infile, strerror(errno));
- return 1;
- }
- }
-
- while ((ch = fgetc(infp)) != EOF)
- if (pdp10_fputc(ch, outfp) == EOF) {
- fprintf(stderr, "%s: %s: failed to write: %s\n", argv[0], outfile, strerror(errno));
- return 1;
- }
-
- if (pdp10_fclose(outfp) == EOF) {
- fprintf(stderr, "%s: %s: failed to close: %s\n", argv[0], outfile, strerror(errno));
- return 1;
- }
-
- return 0;
-}
diff --git a/8to9/Makefile b/8to9/Makefile
deleted file mode 100644
index 1a02877..0000000
--- a/8to9/Makefile
+++ /dev/null
@@ -1,32 +0,0 @@
-# 8to9/Makefile
-# Copyright (C) 2013-2015 Mikael Pettersson
-#
-# This file is part of pdp10-tools.
-#
-# pdp10-tools is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# pdp10-tools is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with pdp10-tools. If not, see .
-
-CC=gcc
-CFLAGS=-O2 -g -Wall
-CPPFLAGS=-I../include
-
-8TO9OBJS=8to9.o
-LIBOBJS=../lib/pdp10-stdio.o
-
-8to9: $(8TO9OBJS) $(LIBOBJS)
- $(LINK.c) -o $@ $^
-
-8to9.o: 8to9.c ../include/pdp10-stdint.h ../include/pdp10-stdio.h
-
-clean:
- rm -f $(8TO9OBJS) 8to9 a.out core.*
diff --git a/Makefile b/Makefile
index f58b42d..1f2f3ee 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
# Makefile for pdp10-tools
-# Copyright (C) 2013-2018 Mikael Pettersson
+# Copyright (C) 2013-2023 Mikael Pettersson
#
# This file is part of pdp10-tools.
#
@@ -16,7 +16,7 @@
# You should have received a copy of the GNU General Public License
# along with pdp10-tools. If not, see .
-SUBDIRS= lib 8to9 ar as nm od readelf sim
+SUBDIRS= erlang
all:
make TARGET= subdirs
diff --git a/TODO b/TODO
index 930b5cc..dcede99 100644
--- a/TODO
+++ b/TODO
@@ -1,5 +1,5 @@
# TODO notes for pdp10-tools
-# Copyright (C) 2013-2020 Mikael Pettersson
+# Copyright (C) 2013-2023 Mikael Pettersson
#
# This file is part of pdp10-tools.
#
@@ -33,9 +33,7 @@ Tools:
- top-level Makefile: subdirs should error out on error in subdir
- size: implement it
- strip: implement it
-- as:
- * tunit_{strtab_,}section_enter() should be generalized and merged
- * what happens if user defines .comment as say text, and later enters .ident?
- * output: move section_symtab into the context
- * tunit: add symtab sections analagous to strtab sections?
- * add support for extended opcodes (emit second opcode after current .text section)
+- ranlib: add wrapper script doing 'ar s'
+- sim: improve it so it can run simple applications
+- as/ld: add support for PIC
+- as/ld: add support for shared objects
diff --git a/ar/Makefile b/ar/Makefile
deleted file mode 100644
index 4e5e89a..0000000
--- a/ar/Makefile
+++ /dev/null
@@ -1,32 +0,0 @@
-# ar/Makefile
-# Copyright (C) 2013-2015 Mikael Pettersson
-#
-# This file is part of pdp10-tools.
-#
-# pdp10-tools is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# pdp10-tools is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with pdp10-tools. If not, see .
-
-CC=gcc
-CFLAGS=-O2 -g -Wall
-CPPFLAGS=-I../include
-
-AROBJS= ar.o
-LIBOBJS=../lib/pdp10-stdio.o
-
-ar: $(AROBJS) $(LIBOBJS)
- $(LINK.c) -o $@ $^
-
-ar.o: ar.c ../include/pdp10-ar.h ../include/pdp10-inttypes.h ../include/pdp10-stdint.h ../include/pdp10-stdio.h
-
-clean:
- rm -f $(AROBJS) ar a.out core.*
diff --git a/ar/ar.c b/ar/ar.c
deleted file mode 100644
index 230be13..0000000
--- a/ar/ar.c
+++ /dev/null
@@ -1,1020 +0,0 @@
-/*
- * ar.c -- ar clone
- * Copyright (C) 2013-2015 Mikael Pettersson
- *
- * This file is part of pdp10-tools.
- *
- * pdp10-tools is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * pdp10-tools is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with pdp10-tools. If not, see .
- */
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include "pdp10-ar.h"
-#include "pdp10-inttypes.h"
-#include "pdp10-stdio.h"
-
-#define VERSION "pdp10-tools ar version 0.1, built " __DATE__ " " __TIME__ "\n"
-
-enum modifier {
- MOD_create = 1 << 0, /* 'c' */
- MOD_newer = 1 << 1, /* 'u' */
- MOD_verbose = 1 << 2, /* 'v' */
-};
-
-struct strtab {
- char *bytes;
- unsigned long len;
-};
-
-struct arhdr {
- char ar_name[16]; /* NUL-terminated unless ar_name[0] == '/' */
- time_t ar_date; /* File date, decimal seconds since Epoch. */
- unsigned int ar_uid; /* User ID. */
- unsigned int ar_gid; /* Group ID. */
- unsigned int ar_mode; /* File mode. */
- unsigned long ar_size; /* File size. */
-};
-
-struct member {
- struct member **prev_next, *next;
- char *name; /* points into ->arhdr.ar_name, params->strtab, or argv[] */
- unsigned long strtaboffset; /* >=0: offset into strtab, -1U: short name in arhdr.ar_name, -2UL: short or long name in argv[] */
- unsigned long srcoffset; /* 0: in external file, >0: in old archive */
- struct arhdr arhdr;
-};
-
-struct params {
- const char *progname; /* argv[0] */
- char operation; /* 'd', 'q', 'r', 't', 'x' */
- unsigned int modifiers; /* bitmask indexed by enum modifier */
- char *arname;
- PDP10_FILE *pdp10fp;
- struct strtab strtab;
- struct member *members_head, **members_tail;
-};
-
-static void params_init(struct params *params)
-{
- memset(params, '\0', sizeof *params);
- params->progname = NULL;
- params->arname = NULL;
- params->pdp10fp = NULL;
- params->strtab.bytes = NULL;
- params->members_head = NULL;
- params->members_tail = ¶ms->members_head;
-}
-
-static struct member *lookup_member(struct params *params, const char *name)
-{
- struct member *member;
-
- for (member = params->members_head; member; member = member->next)
- if (strcmp(member->name, name) == 0)
- return member;
-
- return NULL;
-}
-
-static void unlink_member(struct member *member)
-{
- *member->prev_next = member->next;
- if (member->next)
- member->next->prev_next = member->prev_next;
-}
-
-static void append_member(struct params *params, struct member *member)
-{
- member->next = NULL;
- member->prev_next = params->members_tail;
- *params->members_tail = member;
- params->members_tail = &member->next;
-}
-
-static int ar_fgetc(struct params *params, const char *srcname, PDP10_FILE *srcfp)
-{
- int ch;
-
- ch = pdp10_fgetc(srcfp);
- if (ch == EOF) {
- fprintf(stderr, "%s: %s: premature EOF on read\n", params->progname, srcname);
- return EOF;
- }
- return ch;
-}
-
-static int ar_fputc(struct params *params, const char *dstname, PDP10_FILE *dstfp, uint16_t ch)
-{
- if (pdp10_fputc(ch, dstfp) < 0) {
- fprintf(stderr, "%s: %s: failed to write: %s\n",
- params->progname, dstname, strerror(errno));
- return -1;
- }
- return 0;
-}
-
-static int ar_fputvec(struct params *params, const char *dstname, PDP10_FILE *dstfp, const pdp10_uint9_t *v, size_t n)
-{
- size_t i;
-
- for (i = 0; i < n; ++i)
- if (ar_fputc(params, dstname, dstfp, v[i]) < 0)
- return -1;
-
- return 0;
-}
-
-static int copy_file_data(
- struct params *params, unsigned long nrbytes, PDP10_FILE *srcfp, const char *srcname, PDP10_FILE *dstfp, const char *dstname)
-{
- unsigned int i;
-
- for (i = 0; i < nrbytes; ++i) {
- int ch = ar_fgetc(params, srcname, srcfp);
- if (ch == EOF)
- return -1;
- if (ar_fputc(params, dstname, dstfp, ch) < 0)
- return -1;
- }
- return 0;
-}
-
-static const pdp10_uint9_t armag[PDP10_SARMAG] = PDP10_ARMAG;
-
-static int read_armag(struct params *params)
-{
- unsigned int i;
-
- for (i = 0; i < PDP10_SARMAG; ++i) {
- int ch = ar_fgetc(params, params->arname, params->pdp10fp);
- if (ch == EOF)
- return -1;
- if (ch != armag[i]) {
- fprintf(stderr, "%s: %s: file format not recognized\n", params->progname, params->arname);
- return -1;
- }
- }
- return 0;
-}
-
-static int write_armag(struct params *params, const char *tmparname, PDP10_FILE *tmparfp)
-{
- return ar_fputvec(params, tmparname, tmparfp, armag, PDP10_SARMAG);
-}
-
-static const pdp10_uint9_t arfmag[2] = PDP10_ARFMAG;
-
-static int read_arhdr(struct params *params, struct arhdr *arhdr)
-{
- union {
- struct pdp10_ar_hdr arhdr;
- pdp10_uint9_t buf[PDP10_ARHDR_SIZEOF];
- } u;
- unsigned int i;
- char buf[16];
-
- for (i = 0; i < PDP10_ARHDR_SIZEOF; ++i) {
- int ch = pdp10_fgetc(params->pdp10fp);
- if (ch == EOF) {
- if (i == 0)
- return 0;
- fprintf(stderr, "%s: %s: premature EOF in ar_hdr\n", params->progname, params->arname);
- return -1;
- }
- u.buf[i] = ch;
- }
-
- if (u.arhdr.ar_fmag[0] != arfmag[0] || u.arhdr.ar_fmag[1] != arfmag[1]) {
- fprintf(stderr, "%s: %s: wrong value in ar_fmag\n", params->progname, params->arname);
- return -1;
- }
-
- for (i = 0; i < 10; ++i)
- buf[i] = (char)(unsigned char)u.arhdr.ar_size[i];
- buf[i] = '\0';
- arhdr->ar_size = strtoul(buf, NULL, 10);
-
- for (i = 0; i < 8; ++i)
- buf[i] = (char)(unsigned char)u.arhdr.ar_mode[i];
- buf[i] = '\0';
- arhdr->ar_mode = strtoul(buf, NULL, 8);
-
- for (i = 0; i < 6; ++i)
- buf[i] = (char)(unsigned char)u.arhdr.ar_gid[i];
- buf[i] = '\0';
- arhdr->ar_gid = strtoul(buf, NULL, 10);
-
- for (i = 0; i < 6; ++i)
- buf[i] = (char)(unsigned char)u.arhdr.ar_uid[i];
- buf[i] = '\0';
- arhdr->ar_uid = strtoul(buf, NULL, 10);
-
- for (i = 0; i < 12; ++i)
- buf[i] = (char)(unsigned char)u.arhdr.ar_date[i];
- buf[i] = '\0';
- arhdr->ar_date = strtoul(buf, NULL, 10);
-
- for (i = 0; i < 16; ++i)
- arhdr->ar_name[i] = (char)(unsigned char)u.arhdr.ar_name[i];
-
- if (arhdr->ar_name[0] != '/') {
- for (i = 1; i < 15; ++i)
- if (arhdr->ar_name[i] == '/')
- break;
- arhdr->ar_name[i] = '\0';
- }
-
- return 1;
-}
-
-static int write_arhdr(struct params *params, const char *tmparname, PDP10_FILE *tmparfp, const struct arhdr *arhdr)
-{
- union {
- struct pdp10_ar_hdr arhdr;
- pdp10_uint9_t buf[PDP10_ARHDR_SIZEOF];
- } u;
- unsigned int i;
- char buf[16];
-
- u.arhdr.ar_fmag[0] = arfmag[0];
- u.arhdr.ar_fmag[1] = arfmag[1];
-
- sprintf(buf, "%lu", arhdr->ar_size);
- for (i = 0; i < 10 && buf[i] != '\0'; ++i)
- u.arhdr.ar_size[i] = (unsigned char)buf[i];
- for (; i < 10; ++i)
- u.arhdr.ar_size[i] = ' ';
-
- sprintf(buf, "%o", arhdr->ar_mode);
- for (i = 0; i < 8 && buf[i] != '\0'; ++i)
- u.arhdr.ar_mode[i] = (unsigned char)buf[i];
- for (; i < 8; ++i)
- u.arhdr.ar_mode[i] = ' ';
-
- sprintf(buf, "%u", arhdr->ar_gid);
- for (i = 0; i < 6 && buf[i] != '\0'; ++i)
- u.arhdr.ar_gid[i] = (unsigned char)buf[i];
- for (; i < 6; ++i)
- u.arhdr.ar_gid[i] = ' ';
-
- sprintf(buf, "%u", arhdr->ar_uid);
- for (i = 0; i < 6 && buf[i] != '\0'; ++i)
- u.arhdr.ar_uid[i] = (unsigned char)buf[i];
- for (; i < 6; ++i)
- u.arhdr.ar_uid[i] = ' ';
-
- sprintf(buf, "%llu", (unsigned long long)arhdr->ar_date);
- for (i = 0; i < 12 && buf[i] != '\0'; ++i)
- u.arhdr.ar_date[i] = (unsigned char)buf[i];
- for (; i < 12; ++i)
- u.arhdr.ar_date[i] = ' ';
-
- if (arhdr->ar_name[0] != '/') {
- for (i = 0; i < 15 && arhdr->ar_name[i] != '\0'; ++i)
- u.arhdr.ar_name[i] = (unsigned char)arhdr->ar_name[i];
- u.arhdr.ar_name[i] = '/';
- ++i;
- } else {
- for (i = 0; i < 16 && arhdr->ar_name[i] != '\0'; ++i)
- u.arhdr.ar_name[i] = (unsigned char)arhdr->ar_name[i];
- }
- for (; i < 16; ++i)
- u.arhdr.ar_name[i] = ' ';
-
- if (ar_fputvec(params, tmparname, tmparfp, u.buf, PDP10_ARHDR_SIZEOF) < 0)
- return -1;
-
- return 0;
-}
-
-static int read_arstrtab(struct params *params, const struct arhdr *arhdr)
-{
- unsigned int i;
-
- params->strtab.len = arhdr->ar_size;
- params->strtab.bytes = malloc(params->strtab.len);
- if (!params->strtab.bytes) {
- fprintf(stderr, "%s: %s: failed to allocate %zu bytes for string table: %s\n",
- params->progname, params->arname, params->strtab.len, strerror(errno));
- return -1;
- }
-
- for (i = 0; i < params->strtab.len; ++i) {
- int ch = ar_fgetc(params, params->arname, params->pdp10fp);
- if (ch == EOF)
- return -1;
- if (ch == '/')
- ch = '\0';
- params->strtab.bytes[i] = ch;
- }
-
- if ((i & 1) && ar_fgetc(params, params->arname, params->pdp10fp) == EOF)
- return -1;
-
- return 0;
-}
-
-static int write_arstrtab(struct params *params, const char *tmparname, PDP10_FILE *tmparfp)
-{
- struct arhdr arhdr;
- unsigned int i;
-
- if (!params->strtab.len)
- return 0;
-
- memset(&arhdr, 0, sizeof arhdr);
- arhdr.ar_name[0] = '/';
- arhdr.ar_name[1] = '/';
- arhdr.ar_size = params->strtab.len;
- if (write_arhdr(params, tmparname, tmparfp, &arhdr) < 0)
- return -1;
-
- for (i = 0; i < params->strtab.len; ++i) {
- int ch = params->strtab.bytes[i];
- if (ch == '\0')
- ch = '/';
- if (ar_fputc(params, tmparname, tmparfp, ch) < 0)
- return -1;
- }
-
- if ((i & 1) && ar_fputc(params, tmparname, tmparfp, '\n') < 0)
- return -1;
-
- return 0;
-}
-
-static int skip_member(struct params *params, struct arhdr *arhdr)
-{
- if (pdp10_fseeko(params->pdp10fp, (arhdr->ar_size + 1) & ~(unsigned long)1, PDP10_SEEK_CUR) < 0) {
- fprintf(stderr, "%s: %s: failed to fseek to next member: %s\n",
- params->progname, params->arname, strerror(errno));
- return -1;
- }
- return 0;
-}
-
-static int read_arsymtab(struct params *params, struct arhdr *arhdr)
-{
- /* XXX: symtab is NYI so just seek past this member */
- fprintf(stderr, "%s: %s: Warning: skipping symbol table\n", params->progname, params->arname);
- return skip_member(params, arhdr);
-}
-
-static int read_archive(struct params *params)
-{
- struct arhdr arhdr;
- int status;
- struct member *member;
-
- if (read_armag(params) < 0)
- return -1;
-
- status = read_arhdr(params, &arhdr);
- if (status <= 0)
- return status;
-
- if (arhdr.ar_name[0] == '/' && arhdr.ar_name[1] == ' ') {
- status = read_arsymtab(params, &arhdr);
- if (status < 0)
- return -1;
- status = read_arhdr(params, &arhdr);
- if (status <= 0)
- return status;
- }
-
- if (arhdr.ar_name[0] == '/' && arhdr.ar_name[1] == '/' && arhdr.ar_name[2] == ' ') {
- status = read_arstrtab(params, &arhdr);
- if (status < 0)
- return -1;
- status = read_arhdr(params, &arhdr);
- if (status <= 0)
- return status;
- }
-
- do {
- member = malloc(sizeof *member);
- if (!member) {
- fprintf(stderr, "%s: %s: failed to allocate %zu bytes for new member\n",
- params->progname, params->arname, sizeof *member);
- return -1;
- }
- member->arhdr = arhdr;
- member->srcoffset = pdp10_ftello(params->pdp10fp);
- if (arhdr.ar_name[0] == '/') {
- char buf[16];
- unsigned int i;
-
- if (arhdr.ar_name[1] < '0' || arhdr.ar_name[1] > '9') {
- fprintf(stderr, "%s: %s: invalid member name '%.*s'\n",
- params->progname, params->arname, 16, arhdr.ar_name);
- return -1;
- }
- for (i = 0; i < 15; ++i)
- buf[i] = arhdr.ar_name[i + 1];
- buf[i] = '\0';
- member->strtaboffset = strtoul(buf, NULL, 10);
- if (!params->strtab.bytes || member->strtaboffset >= params->strtab.len) {
- fprintf(stderr, "%s: %s: ar_name '%.*s' out of bounds\n",
- params->progname, params->arname, 16, arhdr.ar_name);
- return -1;
- }
- } else {
- member->strtaboffset = -1UL;
- member->name = member->arhdr.ar_name;
- }
- append_member(params, member);
- if (skip_member(params, &arhdr) < 0)
- return -1;
- status = read_arhdr(params, &arhdr);
- } while (status > 0);
-
- return status;
-}
-
-/*
- * ar t/x code
- */
-
-static int ar_tx_should_process_member(struct params *params, struct member *member, char **files, int nrfiles)
-{
- int i;
-
- for (i = 0; i < nrfiles; ++i)
- if (files[i] && strcmp(member->name, files[i]) == 0) {
- files[i] = NULL;
- return 1;
- }
-
- return nrfiles <= 0;
-}
-
-static char *rwx_string(unsigned int m, char *buf)
-{
- buf[0] = (m & 4) ? 'r' : '-';
- buf[1] = (m & 2) ? 'w' : '-';
- buf[2] = (m & 1) ? 'x' : '-';
- buf[3] = '\0';
- return buf;
-}
-
-static char *date_string(time_t t, char *buf)
-{
- struct tm *tm;
-
- tm = gmtime(&t);
- if (!tm) {
- fprintf(stderr, "gmtime(%lu) failed: %s\n", t, strerror(errno));
- exit(1);
- }
- /* Mon Day HH:MM YYYY */
- strftime(buf, 64, "%b %e %H:%M %Y", tm);
- return buf;
-}
-
-static int ar_t_member(struct params *params, struct member *member)
-{
- char mode_u_buf[4], mode_g_buf[4], mode_o_buf[4], date_buf[64];
-
- if (params->modifiers & MOD_verbose)
- printf("%s%s%s %d/%d %10lu %s ",
- rwx_string(member->arhdr.ar_mode >> 6, mode_u_buf),
- rwx_string(member->arhdr.ar_mode >> 3, mode_g_buf),
- rwx_string(member->arhdr.ar_mode, mode_o_buf),
- member->arhdr.ar_uid,
- member->arhdr.ar_gid,
- member->arhdr.ar_size,
- date_string(member->arhdr.ar_date, date_buf));
- printf("%s\n", member->name);
- return 0;
-}
-
-static int ar_x_copy(struct params *params, struct member *member, PDP10_FILE *memberfp)
-{
- if (pdp10_fseeko(params->pdp10fp, member->srcoffset, PDP10_SEEK_SET) < 0) {
- fprintf(stderr, "%s: %s: failed to fseek to member %s: %s\n",
- params->progname, params->arname, member->name, strerror(errno));
- return -1;
- }
- return copy_file_data(params, member->arhdr.ar_size, params->pdp10fp, params->arname, memberfp, member->name);
-}
-
-static int ar_x_member(struct params *params, struct member *member)
-{
- PDP10_FILE *memberfp;
- int status;
-
- if (params->modifiers & MOD_verbose)
- printf("x - %s\n", member->name);
-
- memberfp = pdp10_fopen(member->name, "wb");
- if (!memberfp) {
- fprintf(stderr, "%s: %s: %s: failed to open: %s\n",
- params->progname, params->arname, member->name, strerror(errno));
- return -1;
- }
- status = ar_x_copy(params, member, memberfp);
- pdp10_fclose(memberfp);
- if (status < 0)
- return -1;
-
- if (chmod(member->name, member->arhdr.ar_mode & 0777) < 0) {
- fprintf(stderr, "%s: %s: %s: failed to set mode %o: %s\n",
- params->progname, params->arname, member->name, member->arhdr.ar_mode & 0777, strerror(errno));
- return -1;
- }
-
- return 0;
-}
-
-static int ar_tx(struct params *params, char **files, int nrfiles)
-{
- struct member *member;
- int status;
- int i;
-
- if (nrfiles < 1) {
- fprintf(stderr, "%s: archive name missing\n", params->progname);
- return -1;
- }
- params->arname = files[0];
- ++files;
- --nrfiles;
-
- params->pdp10fp = pdp10_fopen(params->arname, "rb");
- if (!params->pdp10fp) {
- fprintf(stderr, "%s: %s: failed to open: %s\n",
- params->progname, params->arname, strerror(errno));
- return -1;
- }
-
- if (read_archive(params) < 0)
- return -1;
-
- for (member = params->members_head; member; member = member->next)
- if (ar_tx_should_process_member(params, member, files, nrfiles)) {
- switch (params->operation) {
- case 't':
- status = ar_t_member(params, member);
- break;
- case 'x':
- status = ar_x_member(params, member);
- break;
- default:
- fprintf(stderr, "%s: %s: unexpected operation '%c'\n", params->progname, __FUNCTION__, params->operation);
- return -1;
- }
- if (status < 0)
- return -1;
- }
-
- if (status < 0)
- return status;
-
- for (i = 0; i < nrfiles; ++i)
- if (files[i]) {
- status = -1;
- fprintf(stderr, "no entry %s in archive\n", files[i]);
- }
-
- return status;
-}
-
-/*
- * ar d/q/r code
- */
-
-static int fixup_arstrtab(struct params *params)
-{
- unsigned long new_strtab_len;
- struct member *member;
- size_t namlen;
- char *new_strtab_bytes;
- unsigned long curpos;
-
- new_strtab_len = 0;
- for (member = params->members_head; member; member = member->next) {
- if (member->strtaboffset == -1UL)
- continue;
- namlen = strlen(member->name);
- if (namlen < 16) {
- strcpy(member->arhdr.ar_name, member->name);
- member->name = member->arhdr.ar_name;
- member->strtaboffset = -1UL;
- continue;
- }
- new_strtab_len += namlen + 2; /* for "\0\n" which is output as "/\n" */
- }
-
- if (new_strtab_len == 0) {
- free(params->strtab.bytes);
- params->strtab.bytes = NULL;
- params->strtab.len = 0;
- return 0;
- }
-
- new_strtab_bytes = malloc(new_strtab_len);
- if (!new_strtab_bytes) {
- fprintf(stderr, "%s: %s: failed to allocate %lu bytes for updated string table: %s\n",
- params->progname, params->arname, new_strtab_len, strerror(errno));
- return -1;
- }
-
- curpos = 0;
- for (member = params->members_head; member; member = member->next) {
- if (member->strtaboffset == -1UL)
- continue;
- namlen = strlen(member->name);
- member->strtaboffset = curpos;
- strcpy(new_strtab_bytes + curpos, member->name);
- member->name = new_strtab_bytes + curpos;
- *(new_strtab_bytes + curpos + namlen + 1) = '\n';
- curpos += namlen + 2;
- }
-
- free(params->strtab.bytes);
- params->strtab.bytes = new_strtab_bytes;
- params->strtab.len = new_strtab_len;
-
- return 0;
-}
-
-static void update_arhdr(struct arhdr *arhdr, struct stat *stbuf)
-{
- arhdr->ar_date = stbuf->st_mtime;
- arhdr->ar_uid = stbuf->st_uid;
- arhdr->ar_gid = stbuf->st_gid;
- arhdr->ar_mode = stbuf->st_mode;
-
- /* stbuf->st_size is the file size in octets, convert it to the size in nonets;
- see lib/pdp10-stdio.c:pdp10_fseeko() for the derivation of this formula */
- arhdr->ar_size = (stbuf->st_size / 9) * 8 + ((stbuf->st_size % 9) * 8) / 9;
-}
-
-static int ar_d_process_files(struct params *params, char **files, int nrfiles)
-{
- struct member *member;
- int i;
- char code;
-
- code = 0;
-
- for (i = 0; i < nrfiles; ++i) {
- member = lookup_member(params, files[i]);
- if (!member) {
- fprintf(stderr, "%s: %s: member %s not found\n",
- params->progname, params->arname, files[i]);
- return -1;
- }
- unlink_member(member);
- free(member);
- code = 'd';
- if (params->modifiers & MOD_verbose)
- printf("%c - %s\n", code, files[i]);
- }
-
- return code; /* >0 if changes, 0 if no changes, -1 if error above */
-}
-
-static int ar_qr_process_files(struct params *params, char **files, int nrfiles)
-{
- struct stat stbuf;
- struct member *member;
- int i;
- char code;
-
- code = 0;
-
- for (i = 0; i < nrfiles; ++i) {
- if (stat(files[i], &stbuf) < 0) {
- fprintf(stderr, "%s: %s: failed to stat: %s\n",
- params->progname, files[i], strerror(errno));
- return -1;
- }
- member = lookup_member(params, files[i]);
- if (member && params->operation != 'q') {
- if ((params->modifiers & MOD_newer) && stbuf.st_mtime <= member->arhdr.ar_date)
- continue;
- code = 'r';
- } else {
- member = malloc(sizeof *member);
- if (!member) {
- fprintf(stderr, "%s: %s: failed to allocate %zu bytes for new member\n",
- params->progname, params->arname, sizeof *member);
- return -1;
- }
- member->name = files[i];
- member->strtaboffset = -2UL;
- append_member(params, member);
- code = 'a';
- }
- if (params->modifiers & MOD_verbose)
- printf("%c - %s\n", code, files[i]);
- member->srcoffset = 0;
- update_arhdr(&member->arhdr, &stbuf);
- }
-
- return code; /* >0 if changes, 0 if no changes, -1 if error above */
-}
-
-static char *make_tmparname(struct params *params)
-{
- char *last_slash;
- unsigned int preflen;
- char *tmparname;
-
- if (!params->pdp10fp)
- return params->arname;
-
- last_slash = strrchr(params->arname, '/');
- if (last_slash)
- preflen = last_slash + 1 - params->arname;
- else
- preflen = 0;
-
- tmparname = malloc(preflen + 5 + 6 + 1); /* artmpXXXXXX\0 */
- if (!tmparname) {
- fprintf(stderr, "%s: %s: failed to allocate %u bytes for temporary archive name: %s\n",
- params->progname, params->arname, preflen + 5 + 6 + 1, strerror(errno));
- return NULL;
- }
-
- sprintf(tmparname, "%.*sartmpXXXXXX", preflen, params->arname);
- return tmparname;
-}
-
-static PDP10_FILE *make_tmparfp(struct params *params, char *tmparname)
-{
- int tmparfd;
- PDP10_FILE *tmparfp;
-
- if (!params->pdp10fp) {
- tmparfp = pdp10_fopen(params->arname, "wb");
- if (!tmparfp)
- fprintf(stderr, "%s: %s: failed to create: %s\n", params->progname, params->arname, strerror(errno));
- if (!(params->modifiers & MOD_create))
- printf("%s: creating %s\n", params->progname, params->arname);
- return tmparfp;
- }
-
- tmparfd = mkstemp(tmparname);
- if (tmparfd < 0) {
- fprintf(stderr, "%s: %s: failed to create temporary file: %s\n",
- params->progname, tmparname, strerror(errno));
- return NULL;
- }
-
- tmparfp = pdp10_fdopen(tmparfd, "wb");
- if (!tmparfp)
- fprintf(stderr, "%s: fdopen failed: %s\n", params->progname, strerror(errno));
-
- return tmparfp;
-}
-
-static int write_member(struct params *params, const char *tmparname, PDP10_FILE *tmparfp, struct member *member)
-{
- PDP10_FILE *srcfp;
- const char *srcname;
- int status;
-
- if (member->srcoffset == 0) {
- srcname = member->name;
- srcfp = pdp10_fopen(srcname, "rb");
- if (!srcfp) {
- fprintf(stderr, "%s: %s: failed to open: %s\n",
- params->progname, srcname, strerror(errno));
- return -1;
- }
- } else {
- srcname = params->arname;
- srcfp = params->pdp10fp;
- if (pdp10_fseeko(srcfp, member->srcoffset, PDP10_SEEK_SET) < 0) {
- fprintf(stderr, "%s: %s: failed to fseek to member %s: %s\n",
- params->progname, srcname, member->name, strerror(errno));
- return -1;
- }
- }
-
- if (member->strtaboffset != -1UL)
- sprintf(member->arhdr.ar_name, "/%lu", member->strtaboffset);
-
- status = -1;
- do {
- if (write_arhdr(params, tmparname, tmparfp, &member->arhdr) < 0)
- break;
-
- if (copy_file_data(params, member->arhdr.ar_size, srcfp, srcname, tmparfp, tmparname) < 0)
- break;
-
- if ((member->arhdr.ar_size & 1) && ar_fputc(params, tmparname, tmparfp, '\n') < 0)
- break;
-
- status = 0;
- } while (0);
-
- if (member->srcoffset == 0)
- pdp10_fclose(srcfp);
-
- return status;
-}
-
-static int write_archive(struct params *params, const char *tmparname, PDP10_FILE *tmparfp)
-{
- struct member *member;
- struct stat stbuf;
-
- if (write_armag(params, tmparname, tmparfp) < 0)
- return -1;
-
- if (write_arstrtab(params, tmparname, tmparfp) < 0)
- return -1;
-
- for (member = params->members_head; member; member = member->next)
- if (write_member(params, tmparname, tmparfp, member) < 0)
- return -1;
-
- if (!params->pdp10fp)
- return 0;
-
- if (stat(params->arname, &stbuf) < 0) {
- fprintf(stderr, "%s: %s: failed to stat: %s\n",
- params->progname, params->arname, strerror(errno));
- return -1;
- }
-
- if (chmod(tmparname, stbuf.st_mode) < 0) {
- fprintf(stderr, "%s: %s: failed to chmod 0%o: %s\n",
- params->progname, tmparname, stbuf.st_mode, strerror(errno));
- return -1;
- }
-
- if (chown(tmparname, stbuf.st_uid, stbuf.st_gid) < 0) {
- fprintf(stderr, "%s: %s: failed to chown %u/%u: %s\n",
- params->progname, tmparname, stbuf.st_uid, stbuf.st_gid, strerror(errno));
- return -1;
- }
-
- if (unlink(params->arname) < 0) {
- fprintf(stderr, "%s: %s: failed to unlink: %s\n",
- params->progname, params->arname, strerror(errno));
- return -1;
- }
-
- if (link(tmparname, params->arname) < 0) {
- fprintf(stderr, "%s: failed to link %s to %s: %s\n",
- params->progname, tmparname, params->arname, strerror(errno));
- return -1;
- }
-
- return 0;
-}
-
-static int ar_dqr(struct params *params, char **files, int nrfiles)
-{
- char *tmparname;
- PDP10_FILE *tmparfp;
- int status;
-
- if (nrfiles < 1) {
- fprintf(stderr, "%s: archive name missing\n", params->progname);
- return -1;
- }
- params->arname = files[0];
- ++files;
- --nrfiles;
-
- params->pdp10fp = pdp10_fopen(params->arname, "rb");
- if (params->pdp10fp != NULL) {
- if (read_archive(params) < 0)
- return -1;
- } else if (params->operation == 'd') {
- fprintf(stderr, "%s: %s: failed to open: %s\n",
- params->progname, params->arname, strerror(errno));
- return -1;
- }
-
- if (params->operation == 'd')
- status = ar_d_process_files(params, files, nrfiles);
- else
- status = ar_qr_process_files(params, files, nrfiles);
-
- if (status <= 0)
- return status;
-
- if (fixup_arstrtab(params) < 0)
- return -1;
-
- tmparname = make_tmparname(params);
- if (!tmparname)
- return -1;
-
- tmparfp = make_tmparfp(params, tmparname);
- if (!tmparfp)
- return -1;
-
- status = write_archive(params, tmparname, tmparfp);
-
- pdp10_fclose(tmparfp);
-
- if (params->pdp10fp) {
- unlink(tmparname);
- free(tmparname);
- }
-
- return status;
-}
-
-/*
- * ar d/q/r/t/x dispatcher
- */
-
-static int ar(struct params *params, char **files, int nrfiles)
-{
- switch (params->operation) {
- case 'd':
- case 'q':
- case 'r':
- return ar_dqr(params, files, nrfiles);
- case 't':
- case 'x':
- return ar_tx(params, files, nrfiles);
- default:
- fprintf(stderr, "%s: NYI: operation '%c'\n", params->progname, params->operation);
- return -1;
- }
-}
-
-/*
- * Command-line interface.
- */
-
-static void usage(const char *progname)
-
-{
- fprintf(stderr,
- "Usage: %s [-]{d,q,r,t,x}[cuvV] archive [member...]\n",
- progname);
-}
-
-int main(int argc, char **argv)
-{
- struct params params;
- char *opts;
-
- params_init(¶ms);
- params.progname = argv[0];
-
- if (argc < 2) {
- usage(params.progname);
- return 1;
- }
-
- opts = argv[1];
- if (*opts == '-')
- ++opts;
- for (;; ++opts) {
- switch (*opts) {
- case 'd':
- case 'q':
- case 'r':
- case 't':
- case 'x':
- params.operation = *opts;
- continue;
- case 'c':
- params.modifiers |= MOD_create;
- continue;
- case 'u':
- params.modifiers |= MOD_newer;
- continue;
- case 'v':
- params.modifiers |= MOD_verbose;
- continue;
- case 'V':
- printf(VERSION);
- return 0;
- case '\0':
- break;
- default:
- fprintf(stderr, "%s: invalid option: %c\n", params.progname, *opts);
- usage(params.progname);
- return 1;
- }
- break;
- }
-
- return ar(¶ms, &argv[2], argc - 2) == 0 ? 0 : 1;
-}
diff --git a/as/Makefile b/as/Makefile
deleted file mode 100644
index 19318b3..0000000
--- a/as/Makefile
+++ /dev/null
@@ -1,40 +0,0 @@
-# as/Makefile
-# Copyright (C) 2013-2015 Mikael Pettersson
-#
-# This file is part of pdp10-tools.
-#
-# pdp10-tools is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# pdp10-tools is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with pdp10-tools. If not, see .
-
-CC=gcc
-CFLAGS=-O2 -g -Wall
-CPPFLAGS=-I../include
-
-ASOBJS=assemble.o hashtab.o input.o main.o output.o parse.o scan.o token.o tunit.o
-LIBOBJS=../lib/pdp10-elf36.o ../lib/pdp10-extint.o ../lib/pdp10-opcodes.o ../lib/pdp10-stdio.o
-
-as: $(ASOBJS) $(LIBOBJS)
- $(LINK.c) -o $@ $^
-
-assemble.o: assemble.h tunit.h hashtab.h
-hashtab.o: hashtab.h
-input.o: hashtab.h input.h parse.h scan.h tunit.h token.h token.def
-main.o: assemble.h input.h output.h tunit.h hashtab.h
-output.o: output.h tunit.h hashtab.h
-parse.o: input.h scan.h token.h tunit.h token.def hashtab.h
-scan.o: scan.h token.h token.def
-token.o: token.h token.def
-tunit.o: hashtab.h tunit.h
-
-clean:
- rm -f $(ASOBJS) as a.out core.*
diff --git a/as/assemble.c b/as/assemble.c
deleted file mode 100644
index 35812a3..0000000
--- a/as/assemble.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * assemble.c
- * Copyright (C) 2013-2015 Mikael Pettersson
- *
- * This file is part of pdp10-tools.
- *
- * pdp10-tools is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * pdp10-tools is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with pdp10-tools. If not, see .
- */
-#include
-#include
-#include
-#include
-#include "assemble.h"
-#include "hashtab.h"
-#include "tunit.h"
-#include "pdp10-extint.h"
-
-static int assemble_section(struct hashnode *hashnode, void *data)
-{
- struct section *section = container_of(hashnode, struct section, hashnode);
- struct tunit *tunit = data;
- unsigned long dot;
- struct stmt *stmt;
-
- /* if it's not .text-like then we have nothing to do (for now) */
- if (section->sh_type != SHT_PROGBITS
- || section->sh_flags != (SHF_ALLOC | SHF_EXECINSTR))
- return 0;
-
- section->dot = (section->dot + 3) & ~(unsigned long)3;
-
- section->image = malloc(section->dot * sizeof(pdp10_uint9_t));
- if (!section->image) {
- fprintf(stderr, "%s: %s: failed to allocate %zu bytes for text image: %s\n",
- tunit->progname, __FUNCTION__, section->dot * sizeof(pdp10_uint9_t), strerror(errno));
- return -1;
- }
-
- dot = 0;
- for (stmt = section->head; stmt; stmt = stmt->next) {
- switch (stmt->tag) {
- case S_LABEL:
- {
- struct symbol *symbol;
-
- symbol = tunit_symbol_lookup(tunit, stmt->u.symbol.name);
- if (!symbol)
- return -1;
-
- if (symbol->section != section
- || !symbol->defined
- || symbol->st_value != dot)
- return -1;
-
- break;
- }
- case S_INSN:
- {
- pdp10_uint36_t word;
- struct pdp10_ext_uint36 ext36;
- unsigned int i;
-
- if (dot >= section->dot) {
- fprintf(stderr, "%s: %s: internal error: text image overflow\n", tunit->progname, __FUNCTION__);
- return -1;
- }
- word =
- ((pdp10_uint36_t)(stmt->u.insn.opcode & 0x1FF) << (36 - 9)
- | ((stmt->u.insn.accumulator & 0xF) << (36 - 13))
- | ((stmt->u.insn.at & 1) << (36 - 14))
- | ((stmt->u.insn.indexreg & 0xF) << (36 - 18))
- | (stmt->u.insn.address & PDP10_UINT18_MAX));
- pdp10_uint36_to_ext(word, &ext36);
- for (i = 0; i < 4; ++i)
- section->image[dot + i] = ext36.nonet[i];
- dot += 4;
- break;
- }
- default:
- break;
- }
- }
-
- if (dot != section->dot) {
- fprintf(stderr, "%s: %s: internal error: text image size mismatch\n", tunit->progname, __FUNCTION__);
- return -1;
- }
-
- return 0;
-}
-
-int assemble(struct tunit *tunit)
-{
- return hashtab_enumerate(&tunit->sections, assemble_section, tunit);
-}
diff --git a/as/assemble.h b/as/assemble.h
deleted file mode 100644
index 03ebae0..0000000
--- a/as/assemble.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * assemble.h
- * Copyright (C) 2013-2015 Mikael Pettersson
- *
- * This file is part of pdp10-tools.
- *
- * pdp10-tools is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * pdp10-tools is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with pdp10-tools. If not, see .
- */
-#ifndef ASSEMBLE_H
-#define ASSEMBLE_H
-
-#include "tunit.h"
-
-int assemble(struct tunit *tunit);
-
-#endif /* ASSEMBLE_H */
diff --git a/as/hashtab.c b/as/hashtab.c
deleted file mode 100644
index 1b1445a..0000000
--- a/as/hashtab.c
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * hashtab.c
- * Copyright (C) 2013-2015 Mikael Pettersson
- *
- * This file is part of pdp10-tools.
- *
- * pdp10-tools is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * pdp10-tools is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with pdp10-tools. If not, see .
- */
-#include
-#include
-#include
-#include
-#include "hashtab.h"
-
-static struct hashnode **hashtab_alloc_bucket(unsigned int nrelem)
-{
- size_t nrbytes;
- struct hashnode **bucket;
- unsigned int i;
-
- nrbytes = nrelem * sizeof(struct hashnode*);
- bucket = malloc(nrbytes);
- if (!bucket) {
- fprintf(stderr, "%s: malloc(%zu) failed: %s\n", __FUNCTION__, nrbytes, strerror(errno));
- return NULL;
- }
- for (i = 0; i < nrelem; ++i)
- bucket[i] = NULL;
- return bucket;
-}
-
-int hashtab_init(struct hashtab *hashtab, unsigned int log2size, hashtab_eq_func_t eq_func)
-{
- unsigned int size;
-
- size = 1 << log2size;
- hashtab->log2size = log2size;
- hashtab->mask = size - 1;
- hashtab->used = 0;
- hashtab->eq_func = eq_func;
- hashtab->bucket = hashtab_alloc_bucket(size);
- return hashtab->bucket ? 0 : -1;
-}
-
-struct hashnode *hashtab_lookup(const struct hashtab *hashtab, uintptr_t hashval, const void *data)
-{
- unsigned int i;
- struct hashnode *hashnode;
-
- i = hashval & hashtab->mask;
-
- hashnode = hashtab->bucket[i];
- while (hashnode != NULL) {
- if (hashnode->hashval == hashval
- && (hashtab->eq_func == NULL || (*hashtab->eq_func)(hashnode, data) != 0))
- break;
- hashnode = hashnode->next;
- }
-
- return hashnode;
-}
-
-static int hashtab_grow(struct hashtab *hashtab)
-{
- unsigned int old_size, new_size, new_mask, i;
- struct hashnode **old_bucket, **new_bucket;
-
- old_size = 1 << hashtab->log2size;
- new_size = old_size << 1;
- new_bucket = hashtab_alloc_bucket(new_size);
- if (!new_bucket)
- return -1;
-
- old_bucket = hashtab->bucket;
- hashtab->log2size += 1;
- new_mask = new_size - 1;
- hashtab->mask = new_mask;
- hashtab->bucket = new_bucket;
-
- for (i = 0; i < old_size; ++i) {
- struct hashnode *hashnode = old_bucket[i];
- while (hashnode != NULL) {
- struct hashnode *next = hashnode->next;
- unsigned int j = hashnode->hashval & new_mask;
- hashnode->next = new_bucket[j];
- new_bucket[j] = hashnode;
- hashnode = next;
- }
- }
-
- free(old_bucket);
- return 0;
-}
-
-int hashtab_insert(struct hashtab *hashtab, struct hashnode *hashnode)
-{
- unsigned int i, size;
-
- i = hashnode->hashval & hashtab->mask;
- hashnode->next = hashtab->bucket[i];
- hashtab->bucket[i] = hashnode;
- hashtab->used += 1;
- size = 1 << hashtab->log2size;
- if (hashtab->used > (4 * size) / 5) /* rehash at 80% */
- return hashtab_grow(hashtab);
- return 0;
-}
-
-struct hashnode *hashtab_reset(struct hashtab *hashtab)
-{
- unsigned int i, size;
- struct hashnode **bucket, *all_nodes, *head, *tail;
-
- all_nodes = NULL;
- bucket = hashtab->bucket;
- size = 1 << hashtab->log2size;
-
- for (i = 0; i < size; ++i) {
- head = bucket[i];
- if (head) {
- bucket[i] = NULL;
- tail = head;
- while (tail->next)
- tail = tail->next;
- tail->next = all_nodes;
- all_nodes = head;
- }
- }
-
- hashtab->used = 0;
- return all_nodes;
-}
-
-int hashtab_enumerate(const struct hashtab *hashtab,
- int (*func)(struct hashnode *hashnode, void *data),
- void *data)
-{
- unsigned int i, size;
- struct hashnode **bucket, *head;
- int status;
-
- bucket = hashtab->bucket;
- size = 1 << hashtab->log2size;
-
- for (i = 0; i < size; ++i) {
- head = bucket[i];
- while (head != NULL) {
- status = (*func)(head, data);
- if (status != 0)
- return status;
- head = head->next;
- }
- }
-
- return 0;
-}
diff --git a/as/hashtab.h b/as/hashtab.h
deleted file mode 100644
index bfad267..0000000
--- a/as/hashtab.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * hashtab.h
- * Copyright (C) 2013-2015 Mikael Pettersson
- *
- * This file is part of pdp10-tools.
- *
- * pdp10-tools is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * pdp10-tools is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with pdp10-tools. If not, see .
- */
-#ifndef HASHTAB_H
-#define HASHTAB_H
-
-#include /* uintptr_t */
-
-struct hashnode {
- uintptr_t hashval;
- struct hashnode *next;
-};
-
-typedef int (*hashtab_eq_func_t)(const struct hashnode *hashnode, const void *data);
-
-struct hashtab {
- unsigned int log2size;
- unsigned int mask; /* INV: mask == (1 << log2size) - 1 */
- unsigned int used;
- hashtab_eq_func_t eq_func;
- struct hashnode **bucket;
-};
-
-int hashtab_init(struct hashtab *hashtab, unsigned int log2size, hashtab_eq_func_t eq_func);
-
-struct hashnode *hashtab_lookup(const struct hashtab *hashtab, uintptr_t hashval, const void *data);
-
-int hashtab_insert(struct hashtab *hashtab, struct hashnode *hashnode);
-
-struct hashnode *hashtab_reset(struct hashtab *hashtab);
-
-int hashtab_enumerate(const struct hashtab *hashtab,
- int (*func)(struct hashnode *hashnode, void *data),
- void *data);
-
-#endif /* HASHTAB_H */
diff --git a/as/input.c b/as/input.c
deleted file mode 100644
index a0683a4..0000000
--- a/as/input.c
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * input.c
- * Copyright (C) 2013-2015 Mikael Pettersson
- *
- * This file is part of pdp10-tools.
- *
- * pdp10-tools is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * pdp10-tools is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with pdp10-tools. If not, see .
- */
-#include
-#include
-#include
-#include
-#include "hashtab.h"
-#include "input.h"
-#include "parse.h"
-#include "scan.h"
-#include "tunit.h"
-
-static int do_append(struct scan_state *scan_state, struct tunit *tunit, struct stmt *stmt, unsigned long dot_incr)
-{
- struct stmt *stmt2;
- struct section *section;
-
- stmt2 = malloc(sizeof *stmt2);
- if (!stmt2) {
- fprintf(stderr, "%s: %s line %u: malloc(%zu) failed: %s\n",
- scan_state->progname, scan_state->filename, scan_state->linenr, sizeof *stmt2, strerror(errno));
- return -1;
- }
-
- *stmt2 = *stmt;
- stmt2->next = NULL;
-
- section = tunit->cursect;
-
- *section->tailptr = stmt2;
- section->tailptr = &stmt2->next;
- section->dot += dot_incr;
-
- return 0;
-}
-
-static int do_dot_file(struct scan_state *scan_state, struct tunit *tunit, struct stmt *stmt)
-{
- struct symbol *symbol;
-
- symbol = tunit_symbol_enter(tunit, stmt->u.string.text);
- if (!symbol)
- return -1;
-
- symbol->section = NULL;
- symbol->defined = 1;
- symbol->st_value = 0;
- symbol->st_size = 0;
- symbol->st_info = ELF_ST_INFO(STB_LOCAL, STT_FILE);
-
- return 0;
-}
-
-static int do_dot_globl(struct scan_state *scan_state, struct tunit *tunit, struct stmt *stmt)
-{
- struct symbol *symbol;
-
- symbol = tunit_symbol_enter(tunit, stmt->u.symbol.name);
- if (!symbol)
- return -1;
-
- if (ELF_ST_BIND(symbol->st_info) != STB_LOCAL) {
- fprintf(stderr, "%s: %s line %u: symbol %s already has non-zero binding type %u\n",
- scan_state->progname, scan_state->filename, scan_state->linenr, stmt->u.symbol.name, ELF_ST_BIND(symbol->st_info));
- return -1;
- }
-
- symbol->st_info = ELF_ST_INFO(STB_GLOBAL, ELF_ST_TYPE(symbol->st_info));
-
- return 0;
-}
-
-static int do_dot_ident(struct scan_state *scan_state, struct tunit *tunit, struct stmt *stmt)
-{
- struct strtab *strtab;
-
- strtab = tunit_strtab_section_enter(tunit, ".comment");
- if (!strtab)
- return -1;
-
- if (strtab->section.sh_type == SHT_NULL) {
- /* The ELF specification doesn't specify attribute values for .comment
- * sections, apart from sh_type, but GNU binutils formats them as string
- * tables with the following attribute values.
- */
- strtab->section.sh_type = SHT_PROGBITS;
- strtab->section.sh_flags = SHF_MERGE | SHF_STRINGS;
- strtab->section.sh_entsize = 1;
- strtab->section.sh_addralign = 1;
- }
-
- (void)strtab_enter(tunit, strtab, stmt->u.string.text);
-
- return 0;
-}
-
-static int do_dot_size(struct scan_state *scan_state, struct tunit *tunit, struct stmt *stmt)
-{
- struct symbol *symbol;
-
- symbol = tunit_symbol_enter(tunit, stmt->u.symbol.name);
- if (!symbol)
- return -1;
-
- if (!symbol->section
- || !symbol->defined) {
- fprintf(stderr, "%s: %s line %u: symbol %s undefined\n",
- scan_state->progname, scan_state->filename, scan_state->linenr, stmt->u.symbol.name);
- return -1;
- }
- if (symbol->st_size) {
- fprintf(stderr, "%s: %s line %u: size of symbol %s already defined\n",
- scan_state->progname, scan_state->filename, scan_state->linenr, stmt->u.symbol.name);
- return -1;
- }
- if (symbol->section != tunit->cursect) {
- fprintf(stderr, "%s: %s line %u: symbol %s is not defined in current section\n",
- scan_state->progname, scan_state->filename, scan_state->linenr, stmt->u.symbol.name);
- return -1;
- }
-
- symbol->st_size = tunit->cursect->dot - symbol->st_value;
-
- return 0;
-}
-
-static int do_dot_text(struct scan_state *scan_state, struct tunit *tunit, struct stmt *stmt)
-{
- struct section *section;
-
- section = tunit_section_enter(tunit, ".text");
- if (!section)
- return -1;
-
- if (section->sh_type == SHT_NULL) {
- section->sh_type = SHT_PROGBITS;
- section->sh_flags = SHF_ALLOC | SHF_EXECINSTR;
- section->sh_addralign = 4; /* XXX: PDP10-specific */
- }
-
- tunit->cursect = section;
-
- return 0;
-}
-
-static int do_dot_type_function(struct scan_state *scan_state, struct tunit *tunit, struct stmt *stmt)
-{
- struct symbol *symbol;
-
- symbol = tunit_symbol_enter(tunit, stmt->u.symbol.name);
- if (!symbol)
- return -1;
-
- if (ELF_ST_TYPE(symbol->st_info) != STT_NOTYPE) {
- fprintf(stderr, "%s: %s line %u: symbol %s already has non-zero type %u\n",
- scan_state->progname, scan_state->filename, scan_state->linenr, stmt->u.symbol.name, ELF_ST_TYPE(symbol->st_info));
- return -1;
- }
-
- symbol->st_info = ELF_ST_INFO(ELF_ST_BIND(symbol->st_info), STT_FUNC);
-
- return 0;
-}
-
-static int do_label(struct scan_state *scan_state, struct tunit *tunit, struct stmt *stmt)
-{
- struct symbol *symbol;
- struct section *section;
-
- symbol = tunit_symbol_enter(tunit, stmt->u.symbol.name);
- if (!symbol)
- return -1;
-
- if (symbol->section
- || symbol->defined
- || symbol->st_value) {
- fprintf(stderr, "%s: %s line %u: symbol %s already defined\n",
- scan_state->progname, scan_state->filename, scan_state->linenr, stmt->u.symbol.name);
- return -1;
- }
-
- section = tunit->cursect;
-
- symbol->section = section;
- symbol->defined = 1;
- symbol->st_value = section->dot;
-
- return do_append(scan_state, tunit, stmt, 0);
-}
-
-static int do_insn(struct scan_state *scan_state, struct tunit *tunit, struct stmt *stmt)
-{
- if (tunit->cursect->dot & 3) { /* XXX: PDP10-specific */
- fprintf(stderr, "%s: %s line %u: misaligned instruction\n",
- scan_state->progname, scan_state->filename, scan_state->linenr);
- return -1;
- }
- return do_append(scan_state, tunit, stmt, 4); /* XXX: PDP10-specific sizeof */
-}
-
-static int interpret(struct scan_state *scan_state, struct tunit *tunit, struct stmt *stmt)
-{
- switch (stmt->tag) {
- case S_DOT_FILE:
- return do_dot_file(scan_state, tunit, stmt);
- case S_DOT_GLOBL:
- return do_dot_globl(scan_state, tunit, stmt);
- case S_DOT_IDENT:
- return do_dot_ident(scan_state, tunit, stmt);
- case S_DOT_SIZE:
- return do_dot_size(scan_state, tunit, stmt);
- case S_DOT_TEXT:
- return do_dot_text(scan_state, tunit, stmt);
- case S_DOT_TYPE_FUNCTION:
- return do_dot_type_function(scan_state, tunit, stmt);
- case S_LABEL:
- return do_label(scan_state, tunit, stmt);
- case S_INSN:
- return do_insn(scan_state, tunit, stmt);
- default:
- fprintf(stderr, "%s: %s line %u: parser returned unexpected stmt->tag %u\n",
- scan_state->progname, scan_state->filename, scan_state->linenr, stmt->tag);
- return -1;
- }
-}
-
-int input(char **files, int nrfiles, struct tunit *tunit)
-{
- char fake_file[3];
- char *fake_files[1];
- struct scan_state scan_state;
- int i;
- struct stmt stmt;
- int status;
-
- if (nrfiles <= 0) {
- fake_file[0] = '-';
- fake_file[1] = '-';
- fake_file[2] = '\0';
- fake_files[0] = fake_file;
- files = fake_files;
- nrfiles = 1;
- }
-
- scan_init(&scan_state, tunit->progname);
-
- for (i = 0; i < nrfiles; ++i) {
- if (scan_open(&scan_state, files[i]) < 0)
- return -1;
- for (;;) {
- status = parse_stmt(&scan_state, &stmt);
- if (status < 0)
- return -1;
- if (status == 0)
- break;
- if (interpret(&scan_state, tunit, &stmt) < 0)
- return -1;
- }
- }
-
- return 0;
-}
diff --git a/as/input.h b/as/input.h
deleted file mode 100644
index 16090e4..0000000
--- a/as/input.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * input.h
- * Copyright (C) 2013-2015 Mikael Pettersson
- *
- * This file is part of pdp10-tools.
- *
- * pdp10-tools is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * pdp10-tools is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with pdp10-tools. If not, see .
- */
-#ifndef INPUT_H
-#define INPUT_H
-
-#include "tunit.h"
-
-int input(char **files, int nrfiles, struct tunit *tunit);
-
-#endif /* INPUT_H */
diff --git a/as/main.c b/as/main.c
deleted file mode 100644
index 02dec70..0000000
--- a/as/main.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * main.c -- as clone for pdp10-elf
- * Copyright (C) 2013-2015 Mikael Pettersson
- *
- * This file is part of pdp10-tools.
- *
- * pdp10-tools is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * pdp10-tools is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with pdp10-tools. If not, see .
- */
-#include
-#include
-#include "assemble.h"
-#include "input.h"
-#include "output.h"
-#include "tunit.h"
-
-#define VERSION "pdp10-tools as version 0.2, built " __DATE__ " " __TIME__ "\n"
-
-int main(int argc, char **argv)
-{
- const char *outfile = "a.out";
- struct tunit tunit;
-
- for (;;) {
- int ch;
-
- ch = getopt(argc, argv, "vo:VQ:");
- switch (ch) {
- case 'Q': /* SVR4 compat, ignored */
- continue;
- case 'V': /* SVR4 compat, alias for -v */
- case 'v':
- printf(VERSION);
- continue;
- case 'o':
- outfile = optarg;
- continue;
- case -1:
- break;
- default:
- fprintf(stderr, "Usage: %s [-v] [-o outfile] [files..]\n", argv[0]);
- return 1;
- }
- break;
- }
-
- if (tunit_init(&tunit, argv[0]) < 0)
- return 1;
-
- if (input(&argv[optind], argc - optind, &tunit) < 0)
- return 1;
-
- if (assemble(&tunit) < 0)
- return 1;
-
- if (output(&tunit, outfile) < 0)
- return 1;
-
- tunit_fini(&tunit);
-
- return 0;
-}
diff --git a/as/output.c b/as/output.c
deleted file mode 100644
index 26880a2..0000000
--- a/as/output.c
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * output.c
- * Copyright (C) 2013-2015 Mikael Pettersson
- *
- * This file is part of pdp10-tools.
- *
- * pdp10-tools is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * pdp10-tools is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with pdp10-tools. If not, see .
- */
-#include
-#include
-#include
-#include
-#include "pdp10-elf36.h"
-#include "pdp10-stdint.h"
-#include "pdp10-stdio.h"
-#include "hashtab.h"
-#include "output.h"
-#include "tunit.h"
-
-static int output_padding(PDP10_FILE *pdp10fp, unsigned int nrbytes)
-{
- for (; nrbytes; --nrbytes)
- if (pdp10_elf36_write_uint9(pdp10fp, '\0') < 0)
- return -1;
- return 0;
-}
-
-struct context {
- struct tunit *tunit;
- Elf36_Word shnum;
- Elf36_Word offset;
- struct strtab shstrtab;
- Elf36_Word symnum;
- struct strtab symstrtab;
- PDP10_FILE *pdp10fp;
-};
-
-static int append_section(struct context *context, struct section *section)
-{
- if (section->dot == 0)
- return 0;
-
- /* enter name before reading ->dot to allow this to work for .shstrtab too */
- section->sh_name = strtab_enter(context->tunit, &context->shstrtab, section->name);
- if (section->sh_name == 0)
- return -1;
-
- section->st_shndx = context->shnum;
- ++context->shnum;
-
- section->sh_offset = (context->offset + (section->sh_addralign - 1)) & ~(section->sh_addralign - 1);
- context->offset = section->sh_offset + section->dot;
-
- return 0;
-}
-
-static int process_section(struct hashnode *hashnode, void *data)
-{
- struct section *section = container_of(hashnode, struct section, hashnode);
- struct context *context = data;
-
- return append_section(context, section);
-}
-
-static int output_section_prologue(struct context *context, struct section *section)
-{
- if (section->st_shndx != context->shnum)
- abort();
- ++context->shnum;
-
- if (section->sh_offset < context->offset)
- abort();
-
- if (output_padding(context->pdp10fp, section->sh_offset - context->offset) < 0)
- return -1;
-
- return 0;
-}
-
-static void output_section_epilogue(struct context *context, struct section *section)
-{
- context->offset = section->sh_offset + section->dot;
-}
-
-static int output_section(struct hashnode *hashnode, void *data)
-{
- struct section *section = container_of(hashnode, struct section, hashnode);
- struct context *context = data;
-
- 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);
-
- return 0;
-}
-
-static int output_section_header(struct context *context, const struct section *section)
-{
- Elf36_Shdr shdr;
-
- shdr.sh_name = section->sh_name;
- shdr.sh_type = section->sh_type;
- shdr.sh_flags = section->sh_flags;
- shdr.sh_addr = 0;
- shdr.sh_offset = section->sh_offset;
- shdr.sh_size = section->dot;
- shdr.sh_link = section->sh_link;
- shdr.sh_info = 0; /* XXX: for symtab, LAST_LOCAL + 1 */
- shdr.sh_addralign = section->sh_addralign;
- shdr.sh_entsize = section->sh_entsize;
-
- return pdp10_elf36_write_shdr(context->pdp10fp, &shdr);
-}
-
-static int output_shdr(struct hashnode *hashnode, void *data)
-{
- struct section *section = container_of(hashnode, struct section, hashnode);
- struct context *context = data;
-
- if (section->dot == 0)
- return 0;
-
- return output_section_header(context, section);
-}
-
-static int output_strtab(struct context *context, struct strtab *strtab)
-{
- return output_section(&strtab->section.hashnode, context);
-}
-
-static int process_symbol(struct hashnode *hashnode, void *data)
-{
- struct symbol *symbol = container_of(hashnode, struct symbol, hashnode);
- struct context *context = data;
-
- ++context->symnum;
-
- symbol->st_name = strtab_enter(context->tunit, &context->symstrtab, symbol->name);
- if (symbol->st_name == 0)
- return -1;
-
- return 0;
-}
-
-struct finalize_symbol_context {
- Elf36_Sym *symtab;
- unsigned int i;
-};
-
-static int finalize_symbol(struct hashnode *hashnode, void *data)
-{
- struct symbol *symbol = container_of(hashnode, struct symbol, hashnode);
- struct finalize_symbol_context *fsctx = data;
- Elf36_Word st_shndx;
-
- fsctx->symtab[fsctx->i].st_name = symbol->st_name;
- fsctx->symtab[fsctx->i].st_value = symbol->st_value;
- fsctx->symtab[fsctx->i].st_size = symbol->st_size;
- fsctx->symtab[fsctx->i].st_info = symbol->st_info;
- fsctx->symtab[fsctx->i].st_other = STV_DEFAULT;
-
- if (symbol->section)
- st_shndx = symbol->section->st_shndx;
- else
- st_shndx = SHN_ABS;
- fsctx->symtab[fsctx->i].st_shndx = st_shndx;
-
- ++fsctx->i;
-
- return 0;
-}
-
-int output(struct tunit *tunit, const char *outfile)
-{
- struct context context;
- Elf36_Sym *symtab;
- struct section section_symtab;
- Elf36_Ehdr ehdr;
-
- context.tunit = tunit;
- context.shnum = 1;
- context.offset = ELF36_EHDR_SIZEOF;
- strtab_init(&context.shstrtab, ".shstrtab");
- context.symnum = 0;
- strtab_init(&context.symstrtab, ".strtab");
- context.pdp10fp = NULL;
-
- if (hashtab_enumerate(&tunit->sections, process_section, &context) < 0)
- return -1;
-
- if (hashtab_enumerate(&tunit->symbols, process_symbol, &context) < 0)
- return -1;
-
- symtab = NULL;
- section_init(§ion_symtab, ".symtab");
-
- /* if we have symbols, synthesize .strtab and .symtab */
- if (context.symnum) {
- struct finalize_symbol_context fsctx;
-
- if (append_section(&context, &context.symstrtab.section) < 0)
- return -1;
-
- ++context.symnum; /* for initial stub entry */
-
- symtab = malloc(context.symnum * sizeof(Elf36_Sym));
- if (!symtab) {
- fprintf(stderr, "%s: failed to allocate %zu bytes for Elf36 symbol table: %s\n",
- tunit->progname, context.symnum * sizeof(Elf36_Sym), strerror(errno));
- return -1;
- }
-
- symtab[0].st_name = 0;
- symtab[0].st_value = 0;
- symtab[0].st_size = 0;
- symtab[0].st_info = ELF36_ST_INFO(STB_LOCAL, STT_NOTYPE);
- symtab[0].st_other = 0;
- symtab[0].st_shndx = SHN_UNDEF;
-
- fsctx.symtab = symtab;
- fsctx.i = 1;
-
- if (hashtab_enumerate(&tunit->symbols, finalize_symbol, &fsctx) < 0)
- return -1;
-
- section_symtab.sh_type = SHT_SYMTAB;
- section_symtab.sh_entsize = ELF36_SYM_SIZEOF;
- section_symtab.sh_link = context.symstrtab.section.st_shndx;
- section_symtab.sh_addralign = 4; /* XXX: PDP10-specific */
- section_symtab.dot = context.symnum * ELF36_SYM_SIZEOF;
-
- if (append_section(&context, §ion_symtab) < 0)
- return -1;
- }
-
- /* if we have sections, synthesize .shstrtab */
- if (context.shnum > 1) {
- if (append_section(&context, &context.shstrtab.section) < 0)
- return -1;
-
- /* align context.offset for the section header table, which is last in the file */
- context.offset = (context.offset + (4 - 1)) & ~(Elf36_Word)(4 - 1);
- } else {
- context.shnum = 0;
- context.offset = 0;
- }
-
- ehdr.e_ident[EI_MAG0] = ELFMAG0;
- ehdr.e_ident[EI_MAG1] = ELFMAG1;
- ehdr.e_ident[EI_MAG2] = ELFMAG2;
- ehdr.e_ident[EI_MAG3] = ELFMAG3;
- ehdr.e_ident[EI_CLASS] = ELFCLASS36;
- ehdr.e_ident[EI_DATA] = ELFDATA2MSB;
- ehdr.e_ident[EI_VERSION] = EV_CURRENT;
- ehdr.e_ident[EI_OSABI] = ELFOSABI_NONE;
- ehdr.e_ident[EI_ABIVERSION] = 0;
- {
- int i;
-
- for (i = EI_PAD; i < EI_NIDENT; ++i)
- ehdr.e_ident[i] = 0;
- }
- ehdr.e_type = ET_REL;
- ehdr.e_machine = EM_PDP10;
- ehdr.e_version = EV_CURRENT;
- ehdr.e_entry = 0;
- ehdr.e_phoff = 0;
- ehdr.e_shoff = context.offset;
- ehdr.e_flags = 0;
- ehdr.e_ehsize = ELF36_EHDR_SIZEOF;
- ehdr.e_phentsize = 0;
- ehdr.e_phnum = 0;
- ehdr.e_shentsize = ELF36_SHDR_SIZEOF;
- ehdr.e_shnum = context.shnum;
- ehdr.e_shstrndx = context.shstrtab.section.st_shndx;
-
- context.pdp10fp = pdp10_fopen(outfile, "wb");
- if (!context.pdp10fp) {
- fprintf(stderr, "%s: failed to open %s: %s\n", tunit->progname, outfile, strerror(errno));
- return -1;
- }
-
- if (pdp10_elf36_write_ehdr(context.pdp10fp, &ehdr) < 0)
- return -1;
-
- context.shnum = 1;
- context.offset = ELF36_EHDR_SIZEOF;
-
- if (hashtab_enumerate(&tunit->sections, output_section, &context) < 0)
- return -1;
-
- if (context.symnum) {
- unsigned int i;
-
- if (output_strtab(&context, &context.symstrtab) < 0)
- return -1;
-
- if (output_section_prologue(&context, §ion_symtab) < 0)
- return -1;
-
- for (i = 0; i < context.symnum; ++i)
- if (pdp10_elf36_write_sym(context.pdp10fp, &symtab[i]) < 0)
- return -1;
-
- output_section_epilogue(&context, §ion_symtab);
- }
-
- if (context.shnum > 1) {
- struct section section0;
-
- if (output_strtab(&context, &context.shstrtab) < 0)
- return -1;
-
- if (ehdr.e_shoff < context.offset)
- abort();
- if (output_padding(context.pdp10fp, ehdr.e_shoff - context.offset) < 0)
- return -1;
- section_init(§ion0, "");
- section0.sh_addralign = 0;
- if (output_section_header(&context, §ion0) < 0)
- return -1;
- if (hashtab_enumerate(&tunit->sections, output_shdr, &context) < 0)
- return -1;
- if (context.symnum) {
- if (output_section_header(&context, &context.symstrtab.section) < 0)
- return -1;
- if (output_section_header(&context, §ion_symtab) < 0)
- return -1;
- }
- if (output_section_header(&context, &context.shstrtab.section) < 0)
- return -1;
- }
-
- pdp10_fclose(context.pdp10fp);
-
- return 0;
-}
diff --git a/as/output.h b/as/output.h
deleted file mode 100644
index c5b975e..0000000
--- a/as/output.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * output.h
- * Copyright (C) 2013-2015 Mikael Pettersson
- *
- * This file is part of pdp10-tools.
- *
- * pdp10-tools is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * pdp10-tools is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with pdp10-tools. If not, see .
- */
-#ifndef OUTPUT_H
-#define OUTPUT_H
-
-#include "tunit.h"
-
-int output(struct tunit *tunit, const char *outfile);
-
-#endif /* OUTPUT_H */
diff --git a/as/parse.c b/as/parse.c
deleted file mode 100644
index ba91974..0000000
--- a/as/parse.c
+++ /dev/null
@@ -1,467 +0,0 @@
-/*
- * parse.c
- * Copyright (C) 2013-2015 Mikael Pettersson
- *
- * This file is part of pdp10-tools.
- *
- * pdp10-tools is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * pdp10-tools is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with pdp10-tools. If not, see .
- */
-#include
-#include
-#include
-#include "pdp10-opcodes.h"
-#include "input.h" /* for struct stmt */
-#include "parse.h"
-#include "scan.h"
-#include "token.h"
-
-static int error(struct scan_state *scan_state, const char *msg, enum token token, const union token_attribute *token_attr)
-{
- fprintf(stderr, "%s: %s line %u: syntax error: %s; current token is ",
- scan_state->progname, scan_state->filename, scan_state->linenr, msg);
- token_print(stderr, token, token_attr);
- fprintf(stderr, "\n");
- return -1;
-}
-
-static int parse_dot_file_or_ident(struct scan_state *scan_state, struct stmt *stmt, enum stmt_tag tag, const char *errmsg)
-{
- enum token token;
- union token_attribute token_attr;
-
- token = scan_token(scan_state, &token_attr);
- if (token == T_STRING) {
- stmt->u.string.text = token_attr.text;
- token = scan_token(scan_state, &token_attr);
- if (token == T_NEWLINE) {
- stmt->tag = tag;
- return 1;
- }
- }
- return error(scan_state, errmsg, token, &token_attr);
-}
-
-static int parse_dot_file(struct scan_state *scan_state, struct stmt *stmt)
-{
- return parse_dot_file_or_ident(scan_state, stmt, S_DOT_FILE, "junk after .file directive");
-}
-
-static int parse_dot_ident(struct scan_state *scan_state, struct stmt *stmt)
-{
- return parse_dot_file_or_ident(scan_state, stmt, S_DOT_IDENT, "junk after .ident directive");
-}
-
-static int parse_dot_globl(struct scan_state *scan_state, struct stmt *stmt)
-{
- enum token token;
- union token_attribute token_attr;
-
- token = scan_token(scan_state, &token_attr);
- if (token == T_SYMBOL) {
- stmt->u.symbol.name = token_attr.text;
- token = scan_token(scan_state, &token_attr);
- if (token == T_NEWLINE) {
- stmt->tag = S_DOT_GLOBL;
- return 1;
- }
- }
- return error(scan_state, "junk after .globl directive", token, &token_attr);
-}
-
-/* for now, accepts: .size ,.- */
-static int parse_dot_size(struct scan_state *scan_state, struct stmt *stmt)
-{
- enum token token;
- union token_attribute token_attr;
-
- token = scan_token(scan_state, &token_attr);
- if (token == T_SYMBOL) {
- stmt->u.symbol.name = token_attr.text;
- token = scan_token(scan_state, &token_attr);
- if (token == T_COMMA) {
- token = scan_token(scan_state, &token_attr);
- if (token == T_DOT) {
- token = scan_token(scan_state, &token_attr);
- if (token == T_MINUS) {
- token = scan_token(scan_state, &token_attr);
- if (token == T_SYMBOL
- && strcmp(token_attr.text, stmt->u.symbol.name) == 0) {
- token = scan_token(scan_state, &token_attr);
- if (token == T_NEWLINE) {
- stmt->tag = S_DOT_SIZE;
- return 1;
- }
- }
- }
- }
- }
- }
- return error(scan_state, "junk after .size directive", token, &token_attr);
-}
-
-static int parse_dot_text(struct scan_state *scan_state, struct stmt *stmt)
-{
- enum token token;
- union token_attribute token_attr;
-
- token = scan_token(scan_state, &token_attr);
- if (token == T_NEWLINE) {
- stmt->tag = S_DOT_TEXT;
- return 1;
- }
- return error(scan_state, "junk after .text directive", token, &token_attr);
-}
-
-static int parse_dot_type(struct scan_state *scan_state, struct stmt *stmt)
-{
- enum token token;
- union token_attribute token_attr;
-
- token = scan_token(scan_state, &token_attr);
- if (token == T_SYMBOL) {
- stmt->u.symbol.name = token_attr.text;
- token = scan_token(scan_state, &token_attr);
- if (token == T_COMMA) {
- token = scan_token(scan_state, &token_attr);
- if (token == T_AT) {
- token = scan_token(scan_state, &token_attr);
- if (token == T_SYMBOL
- && strcmp(token_attr.text, "function") == 0) {
- token = scan_token(scan_state, &token_attr);
- if (token == T_NEWLINE) {
- stmt->tag = S_DOT_TYPE_FUNCTION;
- return 1;
- }
- }
- }
- }
- }
- return error(scan_state, "junk after .type directive", token, &token_attr);
-}
-
-/*
- * Recognize:
- *
- *