From fe153b5b22289ddfad811e7771828ba8c04e24c5 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 7 Jan 2022 17:56:05 +0900 Subject: [PATCH] [qfcc] Add progs version to qfo and check in linker While qfcc dealing sensibly with mixed target VMs in the object files has always been an outstanding issue, with the new instruction set it has become a priority. Most importantly, this should allow QF to continue building while I work on qfcc targeting the new IS. --- tools/qfcc/include/obj_file.h | 5 ++++- tools/qfcc/source/linker.c | 4 ++++ tools/qfcc/source/obj_file.c | 10 ++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/tools/qfcc/include/obj_file.h b/tools/qfcc/include/obj_file.h index 7fdee6030..f49688f0f 100644 --- a/tools/qfcc/include/obj_file.h +++ b/tools/qfcc/include/obj_file.h @@ -49,7 +49,7 @@ \hideinitializer */ -#define QFO_VERSION 0x00001006 +#define QFO_VERSION 0x00001007 /** Header block of QFO object files. The sections of the object file come immediately after the header, and are always in the order given by @@ -68,6 +68,8 @@ typedef struct qfo_header_s { pr_uint_t num_lines; ///< number of line records pr_uint_t num_loose_relocs; ///< number of loose relocation records ///< (included in num_relocs) + pr_uint_t progs_version; ///< version of compatible VM + pr_uint_t reserved[3]; } qfo_header_t; typedef enum qfos_type_e { @@ -260,6 +262,7 @@ typedef struct qfo_mspace_s { /** In-memory representation of a QFO object file. */ typedef struct qfo_s { + pr_uint_t progs_version; ///< version of compatible VM void *data; ///< data buffer holding qfo file when read qfo_mspace_t *spaces; unsigned num_spaces; diff --git a/tools/qfcc/source/linker.c b/tools/qfcc/source/linker.c index 4b0fb7d74..948ac084f 100644 --- a/tools/qfcc/source/linker.c +++ b/tools/qfcc/source/linker.c @@ -1148,6 +1148,10 @@ linker_add_lib (const char *libname) linker_error ("error opening"); return 1; } + if (qfo->progs_version != options.code.progsversion) { + linker_error ("qfo progs version does not match target"); + return 1; + } for (j = 0; j < qfo->num_defs; j++) { qfo_def_t *def = qfo->defs + j; diff --git a/tools/qfcc/source/obj_file.c b/tools/qfcc/source/obj_file.c index 22403f7ae..2082fe8ca 100644 --- a/tools/qfcc/source/obj_file.c +++ b/tools/qfcc/source/obj_file.c @@ -480,6 +480,7 @@ qfo_write (qfo_t *qfo, const char *filename) header->num_funcs = LittleLong (qfo->num_funcs); header->num_lines = LittleLong (qfo->num_lines); header->num_loose_relocs = LittleLong (qfo->num_loose_relocs); + header->progs_version = LittleLong (options.code.progsversion); spaces = (qfo_space_t *) &header[1]; relocs = (qfo_reloc_t *) &spaces[qfo->num_spaces]; defs = (qfo_def_t *) &relocs[qfo->num_relocs]; @@ -562,6 +563,14 @@ qfo_read (QFile *file) free (data); return 0; } + header->progs_version = LittleLong (header->progs_version); + if (header->progs_version != PROG_ID_VERSION + && header->progs_version != PROG_V6P_VERSION + && header->progs_version != PROG_VERSION) { + fprintf (stderr, "not a compatible qfo file\n"); + free (data); + return 0; + } qfo = calloc (1, sizeof (qfo_t)); qfo->num_spaces = LittleLong (header->num_spaces); @@ -570,6 +579,7 @@ qfo_read (QFile *file) qfo->num_funcs = LittleLong (header->num_funcs); qfo->num_lines = LittleLong (header->num_lines); qfo->num_loose_relocs = LittleLong (header->num_loose_relocs); + qfo->progs_version = header->progs_version; //already swapped spaces = (qfo_space_t *) &header[1]; qfo->data = data;