summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPixel <>2001-04-16 14:25:48 +0000
committerPixel <>2001-04-16 14:25:48 +0000
commit47f363829678a02111423cd5d374e6739d8ea500 (patch)
tree5c288a8902492e1a91d87ba4ab1cca658e39cbfa
parent27f796ab6a9f455bbd2a1c85088db5304cece75a (diff)
Linker + bugfixes
-rw-r--r--include/Makefile.am2
-rw-r--r--lib/Makefile.am4
-rw-r--r--lib/assembler.c146
-rw-r--r--lib/instructions.txt3
-rw-r--r--lib/linker.c314
-rw-r--r--po/ProjetArchi.pot132
-rw-r--r--po/cat-id-tbl.c120
-rw-r--r--samples/recherche.asm6
-rw-r--r--src/Makefile.am6
-rw-r--r--src/compilo.c15
-rw-r--r--src/linker.c61
11 files changed, 574 insertions, 235 deletions
diff --git a/include/Makefile.am b/include/Makefile.am
index 9bfd99d..da89ffc 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -1 +1 @@
-include_HEADERS = alu.h simulator.h assembler.h exceptions.h fpu.h hash.h interne.h memoire.h meta.h numbers.h parser.h registre.h types.h
+include_HEADERS = alu.h simulator.h assembler.h exceptions.h fpu.h hash.h interne.h memoire.h meta.h numbers.h parser.h registre.h types.h linker.h
diff --git a/lib/Makefile.am b/lib/Makefile.am
index b760f64..352f089 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -2,12 +2,14 @@ localedir = $(datadir)/locale
DEFS = -DLOCALEDIR=\"$(localedir)\" @DEFS@
AM_CFLAGS = -O3 -Wall -Wstrict-prototypes $(CFLAGS)
INCLUDES = -I. -I.. -I$(includedir) -I../include
-lib_LTLIBRARIES = libCompilo.la libSimul.la
+lib_LTLIBRARIES = libCompilo.la libSimul.la libLinker.la
libCompilo_la_SOURCES = assembler.c parser.c meta.c numbers.c hash.c exceptions.c
libSimul_la_SOURCES = alu.c simulator.c exceptions.c fpu.c interne.c memoire.c registre.c
+libLinker_la_SOURCES = linker.c exceptions.c hash.c
libCompilo_la_LDFLAGS = -version-info $(ProjetArchi_VERSION_INFO)
libSimul_la_LFDLAGS = -version-info $(ProjetArchi_VERSION_INFO)
+libLinker_la_LDFLAGS = -version-info $(ProjetArchi_VERSION_INFO)
EXTRA_DIST = instructions.txt
diff --git a/lib/assembler.c b/lib/assembler.c
index c2802da..ea8b085 100644
--- a/lib/assembler.c
+++ b/lib/assembler.c
@@ -172,8 +172,6 @@ static bytestream_t *pushdword(unsigned long int d, expression_t * e)
exception(1, _("You have to be into the .text or the .data segment to define a value."));
}
- fprintf(stderr, "On pousse %i avec %p\n", d, e);
-
s = pushuninit(1);
s->Encoded = d;
if (e) {
@@ -207,6 +205,8 @@ static void pushstring(char *s)
{
char marker = *s, tstring[6];
int valid;
+
+ s++;
while ((*s) && (marker != *s)) {
if (*s == '\\') {
@@ -1231,24 +1231,15 @@ static instruct_t *e_match_i(phon_t * phons, instruct_t * instructs, expression_
if (!instructs->strings[i]) {
if (strcasecmp(instructs->names[i], i ? t->symbol : stringtolook)) {
go_out = 1;
- } else
- fprintf(stderr, "On a reconnu le mot %s au %i eme mot\n", t->symbol, i);
+ }
} else {
switch (instructs->strings[i][0]) {
case 'P':
if (!t->pattern) {
- fprintf(stderr,
- "On a une pattern sur le mot %i, mais pas dans l'instruction...\n",
- i);
go_out = 1;
} else {
- fprintf(stderr,
- "On a la pattern %s sur le mot %i, on la compare avec %s\n",
- instructs->strings[i] + 1, i, t->pattern->name);
if (strcasecmp(instructs->strings[i] + 1, t->pattern->name))
go_out = 1;
- else
- fprintf(stderr, "Ok, on ne sort pas.\n");
}
break;
case 'C':
@@ -1280,7 +1271,6 @@ static instruct_t *e_match_i(phon_t * phons, instruct_t * instructs, expression_
if (!(t = t->next) && ((i + 1) < instructs->nbexplicit)) {
go_out = 1;
- fprintf(stderr, "On sort quand même... (t = %p et i = %i)\n", t, i);
}
}
@@ -1289,38 +1279,6 @@ static instruct_t *e_match_i(phon_t * phons, instruct_t * instructs, expression_
}
}
- if (instructs) {
- fprintf(stderr, "Nous avons reconnu une instruction:\n");
- fprintf(stderr,
- " o Instruction contenant %i champs explicites et %i champs implicites.\n",
- instructs->nbexplicit, instructs->nbimplicit);
- fprintf(stderr, " => Champs explicites.\n");
- for (i = 0; i < instructs->nbexplicit; i++) {
- fprintf(stderr, " + %s <= %s (type %s)\n", instructs->names[i],
- instructs->strings[i] ? instructs->strings[i] : "Pas de chaîne associée",
- instructs->etypes[i] ? "prédéfinit" : "direct");
- }
- fprintf(stderr, " => Champs implicites.\n");
- for (i = 0; i < instructs->nbimplicit; i++) {
- switch (instructs->itypes[i]) {
- case 0:
- fprintf(stderr, " + %s <= %s (type direct)\n", instructs->implicits[i],
- instructs->istrings[i]);
- break;
- case 1:
- fprintf(stderr, " + %s <= %s (type prédéfinit)\n",
- instructs->implicits[i], instructs->istrings[i]);
- break;
- case 2:
- fprintf(stderr, " + %s <= %i (type valeur)\n", instructs->implicits[i],
- instructs->ivalues[i]);
- break;
- }
- }
- } else {
- fprintf(stderr, "Nous n'avons pas reconnu l'instruction.\n");
- }
-
return instructs;
}
@@ -1334,24 +1292,19 @@ static void evaluate_pattern(_TableauVariable * it, expression_t * e)
exception(1, _("Pattern not matching..."));
}
- fprintf(stderr, "Evaluation de la pattern %s, index %i\n", e->pattern->name, e->index);
m = e->pattern->expr[e->index];
if (m->name) {
- fprintf(stderr, "La pattern a un nom\n");
if (m->string) {
- fprintf(stderr, "et une string associée\n");
if (m->type) {
if (strcmp(m->name, "I")) {
exception(1, _("Unknow constant type in the meta language"));
}
- fprintf(stderr, "On pousse une valeur (1)\n");
if (e->e_subtype == E_VALUE) {
pushdword(e->avalue, NULL);
} else {
pushdword(0, e);
}
} else {
- fprintf(stderr, "et n'est pas d'un type prédéfinit\n");
if (m->string) {
if (m->string[0] != 'P') {
exception(1,
@@ -1384,7 +1337,6 @@ static void evaluate_pattern(_TableauVariable * it, expression_t * e)
&& (e->child->next->child->e_subtype == E_VALUE)) {
tv = e->child->next->child->avalue;
}
- fprintf(stderr, "On pousse une valeur (2)\n");
pushdword(tv, e->child);
} else {
exception(1, _("Logical error in meta language"));
@@ -1459,18 +1411,15 @@ static int evaluate_field(_TableauVariable it, char *field, field_t * fields)
r = 0;
n = 0;
- fprintf(stderr, "Evaluation du champ %s\n", field);
for (i = 0; i < fields->nbr; i++) {
t = (expression_t *) NomVarToVar(fields->names[i], it, &trouve);
e = 0;
- fprintf(stderr, "On veut la variable %s pour le champ %i\n", fields->names[i], i);
if (trouve) {
if (t->e_subtype != E_VALUE) {
exception(1, _("Can't evaluate directly expression"));
}
e = t->avalue;
}
- fprintf(stderr, "Elle vaut %i\n", e);
n = fields->sizes[i];
if ((e & ((1 << n) - 1)) != e) {
exception(1, _("Value too large for field"));
@@ -1487,7 +1436,6 @@ void asm_eol(void)
expression_t *t;
int i;
char trouve;
- bytestream_t *pi;
_TableauVariable it;
switch (special) {
@@ -1503,9 +1451,6 @@ void asm_eol(void)
case 0: /* Cas normal */
/* C'est ici la bonne histoire... Il faut reconnaitre l'instruction */
- fprintf(stderr, "Fin de ligne sur:\n");
- debug_print_expression(e_line);
- fprintf(stderr, "-----\n");
e_current = e_line;
if (!(e_current))
break;
@@ -1547,7 +1492,6 @@ void asm_eol(void)
break;
switch (e_current->e_subtype) {
case E_VALUE:
- fprintf(stderr, "On pousse une valeur (3)\n");
pushdword(e_current->avalue, NULL);
break;
case E_STRING:
@@ -1558,7 +1502,6 @@ void asm_eol(void)
break;
case E_LABEL:
case E_OPERATION:
- fprintf(stderr, "On pousse une valeur (4)\n");
pushdword(0, e_current);
break;
default:
@@ -1620,9 +1563,8 @@ void asm_eol(void)
if (instr->strings[i]) {
switch (instr->strings[i][0]) {
case 'C':
- if (instr->etypes) {
+ if (instr->etypes[i]) {
if (!strcmp(instr->names[i], "I")) {
- fprintf(stderr, "On pousse une valeur (6)\n");
if (e_current->e_subtype == E_VALUE) {
pushdword(e_current->avalue, 0);
} else {
@@ -1639,7 +1581,6 @@ void asm_eol(void)
case 'O':
if (instr->etypes) {
if (!strcmp(instr->names[i], "I")) {
- fprintf(stderr, "On pousse une valeur (7)\n");
if (e_current->e_subtype == E_VALUE) {
pushdword(e_current->avalue, 0);
} else {
@@ -1658,8 +1599,6 @@ void asm_eol(void)
t->child = t->next = NULL;
t->pattern = NULL;
t->symbol = NULL;
- fprintf(stderr, "Insertion de la variable %s, de valeur %i.\n",
- instr->names[i], t->avalue);
InsererVarDansTab(&it, CreerElement(instr->names[i], t));
evaluate_pattern(&it, e_current);
break;
@@ -1677,7 +1616,6 @@ void asm_eol(void)
for (i = 0; i < instr->nbimplicit; i++) {
switch (instr->itypes[i]) {
case 0: /* type direct */
- fprintf(stderr, "On cherche la variable %s\n", instr->istrings[i]);
t = (expression_t *) NomVarToVar(instr->istrings[i], it, &trouve);
if (!trouve) {
t = (expression_t *) Emalloc(sizeof(expression_t));
@@ -1686,8 +1624,6 @@ void asm_eol(void)
t->child = t->next = NULL;
t->pattern = NULL;
t->symbol = NULL;
- fprintf(stderr, "Insertion de la variable %s, de valeur %i.\n",
- instr->istrings[i], t->avalue);
}
InsererVarDansTab(&it, CreerElement(instr->implicits[i], t));
break;
@@ -1715,9 +1651,6 @@ void asm_eol(void)
}
}
- fprintf(stderr, "Variables\n");
- AfficheTableau(it);
- fprintf(stderr, "On pousse une valeur (8)\n");
pushdword(evaluate_field(it, "FI", fields), NULL);
DetruitTab(&it);
break;
@@ -1754,7 +1687,6 @@ int s_text = 0, s_data = 0, s_bss = 0;
static void writeword(unsigned long int a, FILE * f, int n) {
int i;
- fprintf(stderr, "On écrit le mot %i\n", a);
if (fwrite(&a, sizeof(unsigned long int), 1, f) != 1) {
if (ferror(f)) {
pushcontext(strerror(errno));
@@ -1768,7 +1700,6 @@ static void writeword(unsigned long int a, FILE * f, int n) {
}
static void writestring(char * string, FILE * f) {
- fprintf(stderr, "On écrit la chaîne %s\n", string);
for (; *string; string++) {
writeword(*string, f, 1);
}
@@ -1815,12 +1746,10 @@ void asm_eof(FILE * f)
{
bytestream_t * t, * u;
FILE * f1, * f2;
- int nbsymbols = 0, a;
+ int nbsymbols = 0, a, nbi = 0, nbe = 0;
char errctx[BUFSIZ], trouve;
bytestream_t * ttext = text, * tdata = data, * tbss = bss;
- fprintf(stderr, "On a reçu une fin de fichier...\n");
-
pushcontext(_("Creating temporary files"));
if (!(f1 = fopen("__text__", "wb"))) {
pushcontext(strerror(errno));
@@ -1837,32 +1766,25 @@ void asm_eof(FILE * f)
pushcontext(_("Dumping text segment"));
for (ttext = ttext->next; ttext; ttext = ttext->next) {
sprintf(errctx, _("Processing word number %i coming from line %i of the file %s."), ttext->offset, ttext->line, ttext->filename);
- fprintf(stderr, "%s\n", errctx);
pushcontext(errctx);
a = 0;
if (ttext->Expr) {
- fprintf(stderr, "On a une sous-expression..\n");
switch(ttext->Expr->e_subtype) {
case E_VALUE:
- fprintf(stderr, "Type valeur.\n");
a = ttext->Expr->avalue;
break;
case E_LABEL:
- fprintf(stderr, "Type label.\n");
a = ttext->Expr->avalue;
nbsymbols++;
- writeword(0, f2, 1);
+ writeword(1, f2, 1);
writeword(ttext->offset, f2, 1);
writeword(strlen(ttext->Expr->symbol), f2, 1);
- writestring(ttext->Expr->symbol, f2);
+ writestring(ttext->Expr->symbol, f2);
+ nbe++;
break;
case E_OPERATION:
- fprintf(stderr, "Type operation.\n");
- fprintf(stderr, "Affichage de l'expression:\n");
- debug_print_expression(ttext->Expr);
- fprintf(stderr, "-----\n");
if (ttext->Expr->op == OP_DIRECT) {
if (ttext->Expr->child->e_subtype == E_VALUE) {
a = ttext->Expr->child->avalue;
@@ -1909,8 +1831,12 @@ void asm_eof(FILE * f)
nbsymbols++;
writeword(0, f2, 1);
writeword(ttext->offset, f2, 1);
+ if (ttext->Label[strlen(ttext->Label) - 1] == ':') {
+ ttext->Label[strlen(ttext->Label) - 1] = '\0';
+ }
writeword(strlen(ttext->Label), f2, 1);
writestring(ttext->Label, f2);
+ nbi++;
}
}
popcontext();
@@ -1920,35 +1846,28 @@ void asm_eof(FILE * f)
pushcontext(_("Dumping data segment"));
for (tdata = tdata->next; tdata; tdata = tdata->next) {
sprintf(errctx, _("Processing word number %i coming from line %i of the file %s."), tdata->offset, tdata->line, tdata->filename);
- fprintf(stderr, "%s\n", errctx);
pushcontext(errctx);
a = 0;
if (tdata->Expr) {
- fprintf(stderr, "On a une sous-expression..\n");
switch(tdata->Expr->e_subtype) {
case E_VALUE:
- fprintf(stderr, "Type valeur.\n");
a = tdata->Expr->avalue;
break;
case E_LABEL:
- fprintf(stderr, "Type label.\n");
a = tdata->Expr->avalue;
nbsymbols++;
- writeword(0, f2, 1);
+ writeword(3, f2, 1);
writeword(tdata->offset + s_text, f2, 1);
writeword(strlen(tdata->Expr->symbol), f2, 1);
- writestring(tdata->Expr->symbol, f2);
+ writestring(tdata->Expr->symbol, f2);
+ nbe++;
break;
case E_OPERATION:
- fprintf(stderr, "Type operation.\n");
- fprintf(stderr, "Affichage de l'expression:\n");
- debug_print_expression(tdata->Expr);
- fprintf(stderr, "-----\n");
- if (ttext->Expr->op == OP_DIRECT) {
- if (ttext->Expr->child->e_subtype == E_VALUE) {
- a = ttext->Expr->child->avalue;
+ if (tdata->Expr->op == OP_DIRECT) {
+ if (tdata->Expr->child->e_subtype == E_VALUE) {
+ a = tdata->Expr->child->avalue;
break;
}
}
@@ -1990,10 +1909,11 @@ void asm_eof(FILE * f)
} else {
if (tdata->Label) {
nbsymbols++;
- writeword(0, f2, 1);
+ writeword(2, f2, 1);
writeword(tdata->offset + s_text, f2, 1);
writeword(strlen(tdata->Label), f2, 1);
- writestring(tdata->Label, f2);
+ writestring(tdata->Label, f2);
+ nbi++;
}
}
popcontext();
@@ -2005,16 +1925,16 @@ void asm_eof(FILE * f)
pushcontext(_("Dumping bss segment"));
for (tbss = tbss->next; tbss; tbss = tbss->next) {
sprintf(errctx, _("Processing word number %i coming from line %i of the file %s."), tbss->offset, tbss->line, tbss->filename);
- fprintf(stderr, "%s\n", errctx);
pushcontext(errctx);
if (!tbss->size) {
if (tbss->Label) {
nbsymbols++;
- writeword(0, f2, 1);
+ writeword(4, f2, 1);
writeword(tbss->offset + s_text + s_data, f2, 1);
writeword(strlen(tbss->Label), f2, 1);
- writestring(tbss->Label, f2);
+ writestring(tbss->Label, f2);
+ nbi++;
}
}
popcontext();
@@ -2022,14 +1942,8 @@ void asm_eof(FILE * f)
popcontext();
popcontext();
- fclose(f1);
-
- fprintf(stderr, "------\n");
-
writeword(0x4f424e4e, f, 1);
- fprintf(stderr, "Pointeur de f2: %i taille de data: %i taille de text: %i\n", ftell(f2), s_data, s_text);
writeword(ftell(f2) + s_data + s_text + 7, f, 1);
- fclose(f2);
t = (bytestream_t *) NomVarToVar("__start__", labels, &trouve);
if (trouve) {
writeword(t->offset, f, 1);
@@ -2037,12 +1951,21 @@ void asm_eof(FILE * f)
writeword(-1, f, 1);
}
+ writeword(s_text, f, 1);
+ writeword(s_data, f, 1);
+ writeword(s_bss, f, 1);
+ writeword(ftell(f2) + 1, f, 1);
+ fclose(f2);
+
+ writeword(nbsymbols, f, 1);
appendfile(f, "__symbols__");
appendfile(f, "__text__");
fclose(f);
unlink("__symbols__");
unlink("__text__");
+
+ fprintf(stderr, _("Statistics: %i words of text, %i words of data, and %i words reserved.\n%i symbols generated with %i internal and %i external.\n"), s_text, s_data, s_bss, nbsymbols, nbi, nbe);
}
static void delete_bytestream(bytestream_t * s)
@@ -2106,6 +2029,7 @@ void assemble_file(char *iname, char *oname)
{
FILE *f;
+ fprintf(stderr, _("Assembling file %s...\n"), iname);
pushcontext(_("Opening output file"));
if (!(f = fopen(oname, "wb"))) {
pushcontext(strerror(errno));
@@ -2116,7 +2040,7 @@ void assemble_file(char *iname, char *oname)
exception(1, _("Error reading file"));
}
pushcontext(_("Writing output file"));
+ fprintf(stderr, _("Generating output file %s...\n"), oname);
asm_eof(f);
- fclose(f);
popcontext();
}
diff --git a/lib/instructions.txt b/lib/instructions.txt
index 8b04e1b..9b70685 100644
--- a/lib/instructions.txt
+++ b/lib/instructions.txt
@@ -115,3 +115,6 @@ I:JMP .I=.O;op=0x0c;e=0x2
I:HALT;op=0x7f
I:RESET;op=0x7f;e=1
+
+I:RET;op=0xc
+I:RET c1=.C;op=0xc
diff --git a/lib/linker.c b/lib/linker.c
new file mode 100644
index 0000000..5fe1162
--- /dev/null
+++ b/lib/linker.c
@@ -0,0 +1,314 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#include "config.h"
+#include "linker.h"
+#include "types.h"
+#include "exceptions.h"
+#include "hash.h"
+
+typedef struct object_t {
+ Uint32 s_text, s_data, s_bss, * text, * data, textstart, datastart, bssstart;
+} object_t;
+
+typedef struct symbol_t {
+ char * name;
+ int objindex;
+ Uint32 offset;
+ int type;
+ struct symbol_t * next;
+} symbol_t;
+
+Uint32 startpoint = -1, textsize = 0, datasize = 0, bsssize = 0;
+
+object_t ** objects;
+symbol_t * symbols, * psymbols;
+int objindex = 0, nbrsymbs = 0;
+
+_TableauVariable symbs;
+
+static FILE * openfilewriting(char * name) {
+ FILE * f;
+
+ if (!(f = fopen(name, "wb"))) {
+ pushcontext(strerror(errno));
+ exception(1, _("Error writing file"));
+ }
+ return f;
+}
+
+static FILE * openfilereading(char * name) {
+ FILE * f;
+
+ if (!(f = fopen(name, "rb"))) {
+ pushcontext(strerror(errno));
+ exception(1, _("Error reading file"));
+ }
+ return f;
+}
+
+static void writeword(Uint32 a, FILE * f) {
+ if (fwrite(&a, sizeof(unsigned long int), 1, f) != 1) {
+ if (ferror(f)) {
+ pushcontext(strerror(errno));
+ }
+ exception(1, _("Error writing file"));
+ }
+}
+
+static Uint32 readword(FILE * f) {
+ Uint32 a;
+
+ if (fread(&a, sizeof(a), 1, f) != 1) {
+ exception(1, _("premature end of file"));
+ }
+ return a;
+}
+
+static char * readstring(FILE * f) {
+ Uint32 s;
+ char * r;
+ int i;
+
+ s = readword(f);
+ r = (char *) Emalloc(s + 1);
+ for (i = 0; i < s; i++) {
+ r[i] = readword(f);
+ }
+ r[i] = '\0';
+ return r;
+}
+
+static void addsymbol(char * name, int offset, int type) {
+ symbol_t * newsymbol;
+
+ newsymbol = (symbol_t *) Emalloc(sizeof(symbol_t));
+ newsymbol->next = NULL;
+ newsymbol->type = type;
+ newsymbol->offset = offset;
+ newsymbol->objindex = objindex;
+ newsymbol->name = name;
+
+ psymbols->next = newsymbol;
+ psymbols = newsymbol;
+
+ if (newsymbol->type & 1) {
+ nbrsymbs++;
+ } else {
+ InsererVarDansTab(&symbs, CreerElement(name, newsymbol));
+ }
+}
+
+void addfile(char * nom) {
+ FILE * f;
+ Uint32 start, nbsymbols, type, offset;
+ int i;
+ char * snom, errctx[BUFSIZ];
+
+ f = openfilereading(nom);
+ sprintf(errctx, _("Processing file %s"), nom);
+ pushcontext(errctx);
+
+ if (readword(f) != 0x4f424e4e) {
+ exception(1, _("Bad signature"));
+ }
+
+ readword(f); /* Taille du fichier */
+ start = readword(f);
+ if ((startpoint != -1) && (start != -1)) {
+ exception(1, _("Startpoint already defined."));
+ }
+ startpoint = start;
+
+ objects[objindex]->s_text = readword(f);
+ objects[objindex]->s_data = readword(f);
+ objects[objindex]->s_bss = readword(f);
+ readword(f); /* Taille de la table des symboles */
+ nbsymbols = readword(f);
+
+ pushcontext(_("Reading symbols"));
+ for (i = 0; i < nbsymbols; i++) {
+ type = readword(f);
+ offset = readword(f);
+ snom = readstring(f);
+ addsymbol(snom, offset, type);
+ }
+ popcontext();
+
+ objects[objindex]->textstart = textsize;
+ objects[objindex]->datastart = datasize;
+ objects[objindex]->bssstart = bsssize;
+
+ objects[objindex]->text = (Uint32 *) Emalloc(objects[objindex]->s_text * sizeof(Uint32));
+ objects[objindex]->data = (Uint32 *) Emalloc(objects[objindex]->s_data * sizeof(Uint32));
+
+ pushcontext(_("Reading text and data segments"));
+ for (i = 0; i < objects[objindex]->s_text; i++) {
+ objects[objindex]->text[i] = readword(f);
+ }
+
+ for (i = 0; i < objects[objindex]->s_data; i++) {
+ objects[objindex]->data[i] = readword(f);
+ }
+ popcontext();
+ fclose(f);
+
+ textsize += objects[objindex]->s_text;
+ datasize += objects[objindex]->s_data;
+ bsssize += objects[objindex]->s_bss;
+
+ objindex++;
+ popcontext();
+}
+
+static void dumptab(Uint32 * tab, int s, FILE * f) {
+ int i;
+
+ for (i = 0; i < s; i++) {
+ writeword(tab[i], f);
+ }
+}
+
+static void dumptext(object_t * obj, FILE * f) {
+ dumptab(obj->text, obj->s_text, f);
+}
+
+static void dumpdata(object_t * obj, FILE * f) {
+ dumptab(obj->data, obj->s_data, f);
+}
+
+static void dumprelog(FILE * f) {
+ symbol_t * s = symbols, * t;
+ char trouve, err[BUFSIZ];
+
+ for (s = s->next; s; s = s->next) {
+ if (s->type & 1) {
+ t = (symbol_t *) NomVarToVar(s->name, symbs, &trouve);
+ if (!trouve) {
+ sprintf(err, _("Symbol %s not found"), s->name);
+ exception(1, err);
+ }
+ switch(s->type) {
+ case 1: /* text */
+ switch(t->type) {
+ case 0:
+ objects[s->objindex]->text[s->offset] += objects[t->objindex]->textstart + t->offset;
+ break;
+ case 2:
+ objects[s->objindex]->text[s->offset] += textsize + objects[t->objindex]->datastart + t->offset;
+ break;
+ case 4:
+ objects[s->objindex]->text[s->offset] += textsize + datasize + objects[t->objindex]->bssstart + t->offset;
+ break;
+ default:
+ exception(1, _("Internal error"));
+ break;
+ }
+ writeword(objects[s->objindex]->textstart + s->offset, f);
+ break;
+ case 3: /* data */
+ switch(t->type) {
+ case 0:
+ objects[s->objindex]->data[s->offset] += objects[t->objindex]->textstart + t->offset;
+ break;
+ case 2:
+ objects[s->objindex]->data[s->offset] += textsize + objects[t->objindex]->datastart + t->offset;
+ break;
+ case 4:
+ objects[s->objindex]->data[s->offset] += textsize + datasize + objects[t->objindex]->bssstart + t->offset;
+ break;
+ default:
+ exception(1, _("Internal error"));
+ break;
+ }
+ writeword(textsize + objects[s->objindex]->datastart + s->offset, f);
+ break;
+ default:
+ exception(1, _("Internal error"));
+ break;
+ }
+ }
+ }
+}
+
+void dumpfile(char * nom) {
+ FILE * f;
+ int i;
+
+ pushcontext(_("Writing output file"));
+ f = openfilewriting(nom);
+
+ if (startpoint == -1) {
+ exception(1, _("No startpoint defined."));
+ }
+
+ pushcontext(_("Writing headers"));
+ writeword(0x58454e4e, f);
+ writeword(nbrsymbs + textsize + datasize + 7, f);
+ writeword(textsize, f);
+ writeword(datasize, f);
+ writeword(bsssize, f);
+ writeword(nbrsymbs, f);
+ popcontext();
+ pushcontext(_("Writing relocating informations"));
+ dumprelog(f);
+ popcontext();
+ pushcontext(_("Writing text segments"));
+ for (i = 0; i < objindex; i++) {
+ dumptext(objects[i], f);
+ }
+ popcontext();
+ pushcontext(_("Writing data segments"));
+ for (i = 0; i < objindex; i++) {
+ dumpdata(objects[i], f);
+ }
+ popcontext();
+
+ popcontext();
+ fprintf(stderr, _("Statistics: %i words of text, %i words of data and reserving %i words\n"), textsize, datasize, bsssize);
+ fprintf(stderr, _("Output file size: %i words containing %i relocating offsets.\n"), ftell(f), nbrsymbs);
+ fclose(f);
+}
+
+void init(int n) {
+ int i;
+
+ Initialise(&symbs);
+
+ objects = (object_t **) Emalloc(n * sizeof(object_t *));
+ psymbols = symbols = (symbol_t *) Emalloc(sizeof(symbol_t));
+
+ for (i = 0; i < n; i++) {
+ objects[i] = (object_t *) Emalloc(sizeof(object_t));
+ objects[i]->s_text = objects[i]->s_data = objects[i]->s_bss = objects[i]->textstart = objects[i]->datastart = 0;
+ objects[i]->text = objects[i]->data = NULL;
+ }
+
+ symbols->next = NULL;
+}
+
+void free_symbol(symbol_t * s) {
+ if (s->next)
+ free_symbol(s);
+
+ free(s->name);
+ free(s);
+}
+
+void flush(void) {
+ int i;
+
+ DetruitTab(&symbs);
+
+ for (i = 0; i < objindex; i++) {
+ if (objects[i]->text)
+ free(objects[i]->text);
+ if (objects[i]->data);
+ free(objects[i]->data);
+ free(objects[i]);
+ }
+ free(objects);
+}
diff --git a/po/ProjetArchi.pot b/po/ProjetArchi.pot
index d23c660..5854352 100644
--- a/po/ProjetArchi.pot
+++ b/po/ProjetArchi.pot
@@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
-"POT-Creation-Date: 2001-04-16 04:31+0200\n"
+"POT-Creation-Date: 2001-04-16 16:14+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -18,7 +18,7 @@ msgstr ""
msgid "You have to be into the .text or the .data segment to define a value."
msgstr ""
-#: lib/assembler.c:198
+#: lib/assembler.c:196
msgid "Label already defined"
msgstr ""
@@ -123,167 +123,184 @@ msgstr ""
msgid "Something wrong, should never got here..."
msgstr ""
-#: lib/assembler.c:1277
+#: lib/assembler.c:1268
msgid "Unknow predefined string into the meta language"
msgstr ""
-#: lib/assembler.c:1334
+#: lib/assembler.c:1292
msgid "Pattern not matching..."
msgstr ""
-#: lib/assembler.c:1345 lib/assembler.c:1377 lib/assembler.c:1634
-#: lib/assembler.c:1651 lib/assembler.c:1667
+#: lib/assembler.c:1300 lib/assembler.c:1330 lib/assembler.c:1576
+#: lib/assembler.c:1592 lib/assembler.c:1606
msgid "Unknow constant type in the meta language"
msgstr ""
-#: lib/assembler.c:1359 lib/assembler.c:1402 lib/assembler.c:1429
+#: lib/assembler.c:1312 lib/assembler.c:1354 lib/assembler.c:1381
msgid ""
"Error in the metalanguage (pattern should be here if not a constant type)"
msgstr ""
-#: lib/assembler.c:1390 lib/assembler.c:1415 lib/assembler.c:1423
-#: lib/assembler.c:1698
+#: lib/assembler.c:1342 lib/assembler.c:1367 lib/assembler.c:1375
+#: lib/assembler.c:1634
msgid "Logical error in meta language"
msgstr ""
-#: lib/assembler.c:1457
+#: lib/assembler.c:1409
msgid "Unknow field in metalanguage"
msgstr ""
-#: lib/assembler.c:1469
+#: lib/assembler.c:1419
msgid "Can't evaluate directly expression"
msgstr ""
-#: lib/assembler.c:1476
+#: lib/assembler.c:1425
msgid "Value too large for field"
msgstr ""
-#: lib/assembler.c:1529 lib/assembler.c:1725
+#: lib/assembler.c:1474 lib/assembler.c:1658
msgid "Unknow instruction"
msgstr ""
-#: lib/assembler.c:1555
+#: lib/assembler.c:1499
msgid "Unknow constant"
msgstr ""
-#: lib/assembler.c:1565
+#: lib/assembler.c:1508
msgid "Bad constant for an immediate value"
msgstr ""
-#: lib/assembler.c:1582
+#: lib/assembler.c:1525
msgid "Bad constant for a string"
msgstr ""
-#: lib/assembler.c:1599
+#: lib/assembler.c:1542
msgid "Bad array size"
msgstr ""
-#: lib/assembler.c:1609
+#: lib/assembler.c:1552
msgid "You can only have an instruction into a .text segment"
msgstr ""
-#: lib/assembler.c:1612
+#: lib/assembler.c:1555
msgid "Unmatched instruction"
msgstr ""
-#: lib/assembler.c:1762 lib/assembler.c:1799
+#: lib/assembler.c:1694 lib/assembler.c:1730
msgid "Error writing file"
msgstr ""
-#: lib/assembler.c:1808 lib/assembler.c:2116
+#: lib/assembler.c:1739 lib/assembler.c:2040
msgid "Error reading file"
msgstr ""
-#: lib/assembler.c:1824
+#: lib/assembler.c:1753
msgid "Creating temporary files"
msgstr ""
-#: lib/assembler.c:1827
+#: lib/assembler.c:1756
msgid "Error writing file __text__"
msgstr ""
-#: lib/assembler.c:1831
+#: lib/assembler.c:1760
msgid "Error writing file __symbols__"
msgstr ""
-#: lib/assembler.c:1835
+#: lib/assembler.c:1764
msgid "Dumping memory into object file"
msgstr ""
-#: lib/assembler.c:1837
+#: lib/assembler.c:1766
msgid "Dumping text segment"
msgstr ""
-#: lib/assembler.c:1839 lib/assembler.c:1922 lib/assembler.c:2007
+#: lib/assembler.c:1768 lib/assembler.c:1848 lib/assembler.c:1927
#, c-format
msgid "Processing word number %i coming from line %i of the file %s."
msgstr ""
-#: lib/assembler.c:1873 lib/assembler.c:1876 lib/assembler.c:1956
-#: lib/assembler.c:1959
+#: lib/assembler.c:1795 lib/assembler.c:1798 lib/assembler.c:1875
+#: lib/assembler.c:1878
msgid "Can't evaluate expression for a direct value"
msgstr ""
-#: lib/assembler.c:1879 lib/assembler.c:1962
+#: lib/assembler.c:1801 lib/assembler.c:1881
msgid "Can only use the diff() function onto labels"
msgstr ""
-#: lib/assembler.c:1884 lib/assembler.c:1888 lib/assembler.c:1967
-#: lib/assembler.c:1971
+#: lib/assembler.c:1806 lib/assembler.c:1810 lib/assembler.c:1886
+#: lib/assembler.c:1890
msgid "Can only evaluate a diff on local symbols"
msgstr ""
-#: lib/assembler.c:1892 lib/assembler.c:1975
+#: lib/assembler.c:1814 lib/assembler.c:1894
msgid "Can only evaluate a diff on symbols from the same segment"
msgstr ""
-#: lib/assembler.c:1898 lib/assembler.c:1981
+#: lib/assembler.c:1820 lib/assembler.c:1900
msgid "Can't evaluate expression"
msgstr ""
-#: lib/assembler.c:1920
+#: lib/assembler.c:1846
msgid "Dumping data segment"
msgstr ""
-#: lib/assembler.c:2005
+#: lib/assembler.c:1925
msgid "Dumping bss segment"
msgstr ""
-#: lib/assembler.c:2072
+#: lib/assembler.c:1968
+#, c-format
+msgid ""
+"Statistics: %i words of text, %i words of data, and %i words reserved.\n"
+"%i symbols generated with %i internal and %i external.\n"
+msgstr ""
+
+#: lib/assembler.c:1995
msgid "Loading file"
msgstr ""
-#: lib/assembler.c:2073 lib/meta.c:516
+#: lib/assembler.c:1996 lib/meta.c:516
#, c-format
msgid "Opening file '%s'"
msgstr ""
-#: lib/assembler.c:2081 lib/meta.c:524
+#: lib/assembler.c:2004 lib/meta.c:524
msgid "Reading file"
msgstr ""
-#: lib/assembler.c:2083 lib/meta.c:526
+#: lib/assembler.c:2006 lib/meta.c:526
#, c-format
msgid "Reading line %i"
msgstr ""
-#: lib/assembler.c:2092
+#: lib/assembler.c:2015
#, c-format
msgid "Summering line %s"
msgstr ""
-#: lib/assembler.c:2109
+#: lib/assembler.c:2032
+#, c-format
+msgid "Assembling file %s...\n"
+msgstr ""
+
+#: lib/assembler.c:2033
msgid "Opening output file"
msgstr ""
-#: lib/assembler.c:2112
+#: lib/assembler.c:2036
msgid "Error writing output file"
msgstr ""
-#: lib/assembler.c:2118
+#: lib/assembler.c:2042
msgid "Writing output file"
msgstr ""
+#: lib/assembler.c:2043
+#, c-format
+msgid "Generating output file %s...\n"
+msgstr ""
+
#: lib/hash.c:14
msgid "Internal error into hashing"
msgstr ""
@@ -356,7 +373,7 @@ msgstr ""
msgid "Loading meta file"
msgstr ""
-#: lib/meta.c:558 src/compilo.c:22
+#: lib/meta.c:558 src/compilo.c:27
msgid "Meta parser init failed."
msgstr ""
@@ -435,57 +452,60 @@ msgstr ""
#: src/compilo.c:15
msgid ""
-"Assembler\n"
+"Assembler v1.0\n"
"\n"
msgstr ""
#: src/compilo.c:19
+msgid "Usage: compilo program.asm objet.out\n"
+msgstr ""
+
+#: src/compilo.c:24
msgid " o Initialising the meta engine... "
msgstr ""
-#: src/compilo.c:25
+#: src/compilo.c:30
msgid ""
" Done!\n"
" o Meta language loading... "
msgstr ""
-#: src/compilo.c:28
+#: src/compilo.c:33
msgid "Meta language loading failed."
msgstr ""
-#: src/compilo.c:31
+#: src/compilo.c:36
msgid ""
" Done!\n"
" o Initialising the assembler core..."
msgstr ""
-#: src/compilo.c:34
+#: src/compilo.c:39
msgid "Assembler core init failed."
msgstr ""
-#: src/compilo.c:37
+#: src/compilo.c:42
msgid " Done!\n"
msgstr ""
-#: src/compilo.c:46
+#: src/compilo.c:51
msgid "Signal received: segfault"
msgstr ""
-#. signal(SIGSEGV, segfaulthand);
-#: src/compilo.c:54
+#: src/compilo.c:61
msgid ""
"\n"
"Performing initialisation...\n"
"\n"
msgstr ""
-#: src/compilo.c:59
+#: src/compilo.c:66
msgid ""
"\n"
"Performing shutdown...\n"
"\n"
msgstr ""
-#: src/compilo.c:62
+#: src/compilo.c:69
msgid "Exitting, bye!\n"
msgstr ""
diff --git a/po/cat-id-tbl.c b/po/cat-id-tbl.c
index 1466fe7..b5cafca 100644
--- a/po/cat-id-tbl.c
+++ b/po/cat-id-tbl.c
@@ -65,73 +65,79 @@ Error in the metalanguage (pattern should be here if not a constant type)", 31},
{"Can't evaluate expression", 55},
{"Dumping data segment", 56},
{"Dumping bss segment", 57},
- {"Loading file", 58},
- {"Opening file '%s'", 59},
- {"Reading file", 60},
- {"Reading line %i", 61},
- {"Summering line %s", 62},
- {"Opening output file", 63},
- {"Error writing output file", 64},
- {"Writing output file", 65},
- {"Internal error into hashing", 66},
- {"Read line '%s'", 67},
- {"Analysing word '%s'", 68},
- {"Missing operator ':'", 69},
- {"Invalid number.", 70},
- {"Expecting ';' for field separator.", 71},
- {"Expecting ',' for field separator.", 72},
- {"Identifier incorrect.", 73},
- {"Error: Expecting a . after a =", 74},
- {"Extra parameters for field 'p'.", 75},
- {"Unexpected char at end of line.", 76},
- {"Expecting operator '=' for field 'p'.", 77},
- {"Error: character . expected.", 78},
- {"= expected after an implicit name", 79},
- {"Identifier incorrect", 80},
- {"expecting ; as field separator", 81},
- {"Loading meta file", 82},
- {"Meta parser init failed.", 83},
- {"Too many nested operators in expression.\n", 84},
- {"Too many nested functions calls in expression.\n", 85},
- {"Invalid unary operator", 86},
- {"Invalid binary operator", 87},
- {"Parse error: too much left parenthesis", 88},
- {"Parse error: too much right parenthesis", 89},
- {"Parse error: enclosure mismatch", 90},
- {"Invalid character", 91},
- {"Out of memory.", 92},
- {"Too much error contexts during pushcontext().", 93},
- {"Error context empty, but popcontext() called.", 94},
- {"ResetBit: Incorrect Value", 95},
- {"SetBit: Incorrect Value", 96},
- {"ValeurBit: Incorrect Value", 97},
- {"Adresse: Unmatched Addr Field", 98},
- {"FPU not implemented", 99},
- {"Invalid Memory Adress", 100},
- {"Invalid Register Descriptor", 101},
{"\
-Assembler\n\
-\n", 102},
- {" o Initialising the meta engine... ", 103},
+Statistics: %i words of text, %i words of data, and %i words reserved.\n\
+%i symbols generated with %i internal and %i external.\n", 58},
+ {"Loading file", 59},
+ {"Opening file '%s'", 60},
+ {"Reading file", 61},
+ {"Reading line %i", 62},
+ {"Summering line %s", 63},
+ {"Assembling file %s...\n", 64},
+ {"Opening output file", 65},
+ {"Error writing output file", 66},
+ {"Writing output file", 67},
+ {"Generating output file %s...\n", 68},
+ {"Internal error into hashing", 69},
+ {"Read line '%s'", 70},
+ {"Analysing word '%s'", 71},
+ {"Missing operator ':'", 72},
+ {"Invalid number.", 73},
+ {"Expecting ';' for field separator.", 74},
+ {"Expecting ',' for field separator.", 75},
+ {"Identifier incorrect.", 76},
+ {"Error: Expecting a . after a =", 77},
+ {"Extra parameters for field 'p'.", 78},
+ {"Unexpected char at end of line.", 79},
+ {"Expecting operator '=' for field 'p'.", 80},
+ {"Error: character . expected.", 81},
+ {"= expected after an implicit name", 82},
+ {"Identifier incorrect", 83},
+ {"expecting ; as field separator", 84},
+ {"Loading meta file", 85},
+ {"Meta parser init failed.", 86},
+ {"Too many nested operators in expression.\n", 87},
+ {"Too many nested functions calls in expression.\n", 88},
+ {"Invalid unary operator", 89},
+ {"Invalid binary operator", 90},
+ {"Parse error: too much left parenthesis", 91},
+ {"Parse error: too much right parenthesis", 92},
+ {"Parse error: enclosure mismatch", 93},
+ {"Invalid character", 94},
+ {"Out of memory.", 95},
+ {"Too much error contexts during pushcontext().", 96},
+ {"Error context empty, but popcontext() called.", 97},
+ {"ResetBit: Incorrect Value", 98},
+ {"SetBit: Incorrect Value", 99},
+ {"ValeurBit: Incorrect Value", 100},
+ {"Adresse: Unmatched Addr Field", 101},
+ {"FPU not implemented", 102},
+ {"Invalid Memory Adress", 103},
+ {"Invalid Register Descriptor", 104},
+ {"\
+Assembler v1.0\n\
+\n", 105},
+ {"Usage: compilo program.asm objet.out\n", 106},
+ {" o Initialising the meta engine... ", 107},
{"\
Done!\n\
- o Meta language loading... ", 104},
- {"Meta language loading failed.", 105},
+ o Meta language loading... ", 108},
+ {"Meta language loading failed.", 109},
{"\
Done!\n\
- o Initialising the assembler core...", 106},
- {"Assembler core init failed.", 107},
- {" Done!\n", 108},
- {"Signal received: segfault", 109},
+ o Initialising the assembler core...", 110},
+ {"Assembler core init failed.", 111},
+ {" Done!\n", 112},
+ {"Signal received: segfault", 113},
{"\
\n\
Performing initialisation...\n\
-\n", 110},
+\n", 114},
{"\
\n\
Performing shutdown...\n\
-\n", 111},
- {"Exitting, bye!\n", 112},
+\n", 115},
+ {"Exitting, bye!\n", 116},
};
-int _msg_tbl_length = 112;
+int _msg_tbl_length = 116;
diff --git a/samples/recherche.asm b/samples/recherche.asm
index a99e353..46b979e 100644
--- a/samples/recherche.asm
+++ b/samples/recherche.asm
@@ -1,5 +1,5 @@
.DATA
-TAB1 DS "efghijklynoparstuvzxywqbcdefghijklynoparstuvzxywqbcdefghijklynoparstuvzxywqbcdefghijklynoparstuvzxyw"
+TAB1 DS "efghijklynoparstuvzxywqbcdefghijklynoparstuvzxywqbcdefghijklynoparstuvzxywqbcdefghijklynoparstuvzxywNNEX"
TAB2 DS "aafghijklynoparstuvzxywqbcdefghijklynoparstuvzxywqbcdefghijklynoparstuvzxywqbcdefghijklynoparstuvzxy"
MSGTROUVE DS "TAB1 et TAB2 ont un élément en commun"
MSGPASTROUVE DS "TAB1 et TAB2 n'ont pas d'élément en commun"
@@ -21,4 +21,6 @@ BOUCLE: SUB R5 R5 1
MOV, [0xffffff04], MSGPASTROUVE ;il n'y a pas de d'éléments identiques a une position i => on place dans R3 le msg a afficher
JMP FIN ;jmp a l'affichage
TROUVE: MOV, [0xffffff04], MSGTROUVE ;il y a une paire d'éléments identiques => on place dans R3 le msg a afficher
-FIN: HALT \ No newline at end of file
+FIN: HALT
+ RET 4
+ \ No newline at end of file
diff --git a/src/Makefile.am b/src/Makefile.am
index f340432..5b3c985 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -3,12 +3,12 @@ DEFS = -DLOCALEDIR=\"$(localedir)\" @DEFS@
AM_CFLAGS = -O3 -Wall -Wstrict-prototypes $(CFLAGS)
INCLUDES = -I. -I.. -I$(includedir) -I../include
-bin_PROGRAMS = compilo simul
+bin_PROGRAMS = compilo simul linker
compilo_SOURCES = compilo.c
simul_SOURCES = simul.c
-
-LDADD = ../lib/libCompilo.la
+linker_SOURCES = linker.c
compilo_LDADD = ../lib/libCompilo.la
simul_LDADD = ../lib/libSimul.la
+linker_LDADD = ../lib/libLinker.la
diff --git a/src/compilo.c b/src/compilo.c
index 883bd81..61ea761 100644
--- a/src/compilo.c
+++ b/src/compilo.c
@@ -12,7 +12,12 @@
typedef void (*sighandler_t)(int);
void invite(void) {
- fprintf(stderr, _("Assembler\n\n"));
+ fprintf(stderr, _("Assembler v1.0\n\n"));
+}
+
+void usage(void) {
+ fprintf(stderr, _("Usage: compilo program.asm objet.out\n"));
+ exit(0);
}
void init_all(void) {
@@ -46,15 +51,17 @@ void segfaulthand(int i) {
exception(1, _("Signal received: segfault"));
}
-int main(void) {
+int main(int argc, char ** argv) {
invite();
/* signal(SIGSEGV, segfaulthand); */
+
+ if (argc != 3) usage();
fprintf(stderr, _("\nPerforming initialisation...\n\n"));
init_all();
-
- assemble_file("progtest.asm", "progtest.o");
+
+ assemble_file(argv[1], argv[2]);
fprintf(stderr, _("\nPerforming shutdown...\n\n"));
flush_all();
diff --git a/src/linker.c b/src/linker.c
new file mode 100644
index 0000000..61301de
--- /dev/null
+++ b/src/linker.c
@@ -0,0 +1,61 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <signal.h>
+#include "config.h"
+#include "exceptions.h"
+#include "linker.h"
+
+typedef void (*sighandler_t)(int);
+
+void invite(void) {
+ fprintf(stderr, _("Linker v1.0\n\n"));
+}
+
+void usage(void) {
+ fprintf(stderr, _("Usage: linker obj1 [obj2 [obj3 [...]]] binary\n"));
+ exit(0);
+}
+
+void init_all(int n) {
+ fprintf(stderr, _(" o Initialising the linker... "));
+
+ init(n);
+ fprintf(stderr, _(" Done!\n"));
+}
+
+void flush_all(void) {
+ flush();
+}
+
+void segfaulthand(int i) {
+ exception(1, _("Signal received: segfault"));
+}
+
+int main(int argc, char ** argv) {
+ int i;
+
+ invite();
+
+ signal(SIGSEGV, segfaulthand);
+
+ if (argc < 3) usage();
+
+ fprintf(stderr, _("\nPerforming initialisation...\n\n"));
+ init_all(argc - 2);
+
+ fprintf(stderr, _("Linking files...\n"));
+
+ for (i = 1; i < argc - 1; i++) {
+ addfile(argv[i]);
+ }
+
+ fprintf(stderr, _("Generating output file...\n"));
+ dumpfile(argv[i]);
+
+ fprintf(stderr, _("\nPerforming shutdown...\n\n"));
+ flush_all();
+
+ fprintf(stderr, _("Exitting, bye!\n"));
+ return 0;
+}