mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +00:00
getting closer to being able to link
This commit is contained in:
parent
2df43ef941
commit
bc5beea311
6 changed files with 273 additions and 18 deletions
|
@ -72,6 +72,7 @@ typedef struct qfo_def_s {
|
||||||
#define QFOD_ABSOLUTE (1u<<2)
|
#define QFOD_ABSOLUTE (1u<<2)
|
||||||
#define QFOD_GLOBAL (1u<<3)
|
#define QFOD_GLOBAL (1u<<3)
|
||||||
#define QFOD_EXTERNAL (1u<<4)
|
#define QFOD_EXTERNAL (1u<<4)
|
||||||
|
#define QFOD_LOCAL (1u<<5)
|
||||||
|
|
||||||
typedef struct qfo_function_s {
|
typedef struct qfo_function_s {
|
||||||
string_t name;
|
string_t name;
|
||||||
|
@ -133,5 +134,15 @@ typedef struct qfo_s {
|
||||||
|
|
||||||
int write_obj_file (const char *filename);
|
int write_obj_file (const char *filename);
|
||||||
qfo_t *read_obj_file (const char *filename);
|
qfo_t *read_obj_file (const char *filename);
|
||||||
|
qfo_t *qfo_new (void);
|
||||||
|
void qfo_add_code (qfo_t *qfo, dstatement_t *code, int code_size);
|
||||||
|
void qfo_add_data (qfo_t *qfo, pr_type_t *data, int data_size);
|
||||||
|
void qfo_add_far_data (qfo_t *qfo, pr_type_t *far_data, int far_data_size);
|
||||||
|
void qfo_add_strings (qfo_t *qfo, const char *strings, int strings_size);
|
||||||
|
void qfo_add_relocs (qfo_t *qfo, qfo_reloc_t *relocs, int num_relocs);
|
||||||
|
void qfo_add_defs (qfo_t *qfo, qfo_def_t *defs, int num_defs);
|
||||||
|
void qfo_add_functions (qfo_t *qfo, qfo_function_t *functions, int num_functions);
|
||||||
|
void qfo_add_types (qfo_t *qfo, const char *types, int types_size);
|
||||||
|
void qfo_delete (qfo_t *qfo);
|
||||||
|
|
||||||
#endif//__obj_file_h
|
#endif//__obj_file_h
|
||||||
|
|
|
@ -108,4 +108,6 @@ int yyparse (void);
|
||||||
memset (v, 0, sizeof (*v)); \
|
memset (v, 0, sizeof (*v)); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define RUP(x,a) (((x) + ((a) - 1)) % (a))
|
||||||
|
|
||||||
#endif//__qfcc_h
|
#endif//__qfcc_h
|
||||||
|
|
|
@ -43,6 +43,7 @@ typedef enum {
|
||||||
rel_def_op,
|
rel_def_op,
|
||||||
rel_def_def,
|
rel_def_def,
|
||||||
rel_def_func,
|
rel_def_func,
|
||||||
|
rel_def_string,
|
||||||
} reloc_type;
|
} reloc_type;
|
||||||
|
|
||||||
typedef struct reloc_s {
|
typedef struct reloc_s {
|
||||||
|
|
|
@ -49,6 +49,7 @@ static const char rcsid[] =
|
||||||
#include "immediate.h"
|
#include "immediate.h"
|
||||||
#include "obj_file.h"
|
#include "obj_file.h"
|
||||||
#include "qfcc.h"
|
#include "qfcc.h"
|
||||||
|
#include "reloc.h"
|
||||||
#include "strpool.h"
|
#include "strpool.h"
|
||||||
|
|
||||||
static hashtab_t *extern_defs;
|
static hashtab_t *extern_defs;
|
||||||
|
@ -59,9 +60,27 @@ static defspace_t *data;
|
||||||
static defspace_t *far_data;
|
static defspace_t *far_data;
|
||||||
static strpool_t *strings;
|
static strpool_t *strings;
|
||||||
static strpool_t *type_strings;
|
static strpool_t *type_strings;
|
||||||
|
static struct {
|
||||||
|
qfo_reloc_t *relocs;
|
||||||
|
int num_relocs;
|
||||||
|
int max_relocs;
|
||||||
|
} relocs;
|
||||||
|
static struct {
|
||||||
|
qfo_def_t *defs;
|
||||||
|
int num_defs;
|
||||||
|
int max_defs;
|
||||||
|
} defs;
|
||||||
|
static struct {
|
||||||
|
qfo_function_t *funcs;
|
||||||
|
int num_funcs;
|
||||||
|
int max_funcs;
|
||||||
|
} funcs;
|
||||||
static int code_base;
|
static int code_base;
|
||||||
static int data_base;
|
static int data_base;
|
||||||
static int far_data_base;
|
static int far_data_base;
|
||||||
|
static int reloc_base;
|
||||||
|
static int def_base;
|
||||||
|
static int func_base;
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
defs_get_key (void *_def, void *unused)
|
defs_get_key (void *_def, void *unused)
|
||||||
|
@ -71,20 +90,80 @@ defs_get_key (void *_def, void *unused)
|
||||||
return G_GETSTR (def->name);
|
return G_GETSTR (def->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
|
add_strings (qfo_t *qfo)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < qfo->strings_size; i += strlen (qfo->strings + i))
|
||||||
|
strpool_addstr (strings, qfo->strings + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
add_relocs (qfo_t *qfo)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (relocs.num_relocs + qfo->num_relocs > relocs.max_relocs) {
|
||||||
|
relocs.max_relocs = RUP (relocs.num_relocs + qfo->num_relocs, 16384);
|
||||||
|
relocs.relocs = realloc (relocs.relocs,
|
||||||
|
relocs.max_relocs * sizeof (qfo_reloc_t));
|
||||||
|
}
|
||||||
|
relocs.num_relocs += qfo->num_relocs;
|
||||||
|
memcpy (relocs.relocs + reloc_base, qfo->relocs,
|
||||||
|
qfo->num_relocs * sizeof (qfo_reloc_t));
|
||||||
|
for (i = reloc_base; i < relocs.num_relocs; i++) {
|
||||||
|
qfo_reloc_t *reloc = relocs.relocs + i;
|
||||||
|
switch ((reloc_type)reloc->type) {
|
||||||
|
case rel_none:
|
||||||
|
break;
|
||||||
|
case rel_op_a_def:
|
||||||
|
case rel_op_b_def:
|
||||||
|
case rel_op_c_def:
|
||||||
|
case rel_op_a_op:
|
||||||
|
case rel_op_b_op:
|
||||||
|
case rel_op_c_op:
|
||||||
|
reloc->ofs += code_base;
|
||||||
|
break;
|
||||||
|
case rel_def_op:
|
||||||
|
case rel_def_def:
|
||||||
|
case rel_def_func:
|
||||||
|
case rel_def_string:
|
||||||
|
reloc->ofs += data_base;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
add_defs (qfo_t *qfo)
|
add_defs (qfo_t *qfo)
|
||||||
{
|
{
|
||||||
qfo_def_t *def;
|
int i;
|
||||||
qfo_def_t *d;
|
|
||||||
|
if (defs.num_defs + qfo->num_defs > defs.max_defs) {
|
||||||
|
defs.max_defs = RUP (defs.num_defs + qfo->num_defs, 16384);
|
||||||
|
defs.defs = realloc (defs.defs, defs.max_defs * sizeof (qfo_def_t));
|
||||||
|
}
|
||||||
|
defs.num_defs += qfo->num_defs;
|
||||||
|
memcpy (defs.defs + def_base, qfo->defs,
|
||||||
|
qfo->num_defs * sizeof (qfo_def_t));
|
||||||
|
for (i = def_base; i < defs.num_defs; i++) {
|
||||||
|
qfo_def_t *def = defs.defs + i;
|
||||||
|
|
||||||
for (def = qfo->defs; def - qfo->defs < qfo->num_defs; def++) {
|
|
||||||
def->full_type = strpool_addstr (type_strings,
|
def->full_type = strpool_addstr (type_strings,
|
||||||
qfo->strings + def->full_type);
|
qfo->types + def->full_type);
|
||||||
def->name = strpool_addstr (strings, qfo->strings + def->name);
|
def->name = strpool_addstr (strings, qfo->strings + def->name);
|
||||||
def->file = strpool_addstr (strings, qfo->strings + def->file);
|
if (!(def->flags & (QFOD_LOCAL | QFOD_ABSOLUTE))) {
|
||||||
|
def->ofs += data_base;
|
||||||
|
}
|
||||||
|
def->relocs += reloc_base;
|
||||||
|
def->file = strpool_addstr (strings, qfo->strings + def->file);
|
||||||
|
|
||||||
if (def->flags & QFOD_EXTERNAL) {
|
if (def->flags & QFOD_EXTERNAL) {
|
||||||
Hash_Add (extern_defs, def);
|
Hash_Add (extern_defs, def);
|
||||||
} else {
|
} else {
|
||||||
|
qfo_def_t *d;
|
||||||
|
|
||||||
if (def->flags & QFOD_GLOBAL) {
|
if (def->flags & QFOD_GLOBAL) {
|
||||||
if ((d = Hash_Find (defined_defs, G_GETSTR (def->name)))) {
|
if ((d = Hash_Find (defined_defs, G_GETSTR (def->name)))) {
|
||||||
pr.source_file = def->file;
|
pr.source_file = def->file;
|
||||||
|
@ -117,17 +196,73 @@ add_defs (qfo_t *qfo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
add_functions (qfo_t *qfo)
|
add_funcs (qfo_t *qfo)
|
||||||
{
|
{
|
||||||
qfo_function_t *func;
|
int i;
|
||||||
|
|
||||||
for (func = qfo->functions; func - qfo->functions < qfo->num_functions;
|
if (funcs.num_funcs + qfo->num_functions > funcs.max_funcs) {
|
||||||
func++) {
|
funcs.max_funcs = RUP (funcs.num_funcs + qfo->num_functions, 16384);
|
||||||
|
funcs.funcs = realloc (funcs.funcs,
|
||||||
|
funcs.max_funcs * sizeof (qfo_function_t));
|
||||||
|
}
|
||||||
|
funcs.num_funcs += qfo->num_functions;
|
||||||
|
memcpy (funcs.funcs + func_base, qfo->functions,
|
||||||
|
qfo->num_functions * sizeof (qfo_function_t));
|
||||||
|
for (i = func_base; i < funcs.num_funcs; i++) {
|
||||||
|
qfo_function_t *func = funcs.funcs + i;
|
||||||
func->name = strpool_addstr (strings, qfo->strings + func->name);
|
func->name = strpool_addstr (strings, qfo->strings + func->name);
|
||||||
func->file = strpool_addstr (strings, qfo->strings + func->file);
|
func->file = strpool_addstr (strings, qfo->strings + func->file);
|
||||||
if (func->code)
|
if (func->code)
|
||||||
func->code += pr.code->size;
|
func->code += code_base;
|
||||||
|
if (func->def)
|
||||||
|
func->def += def_base;
|
||||||
|
if (func->local_defs)
|
||||||
|
func->local_defs += def_base;
|
||||||
|
func->relocs += reloc_base;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fixup_relocs (qfo_t *qfo)
|
||||||
|
{
|
||||||
|
qfo_reloc_t *reloc;
|
||||||
|
|
||||||
|
for (reloc = relocs.relocs + reloc_base;
|
||||||
|
reloc - relocs.relocs < relocs.num_relocs;
|
||||||
|
reloc++) {
|
||||||
|
switch ((reloc_type)reloc->type) {
|
||||||
|
case rel_none:
|
||||||
|
break;
|
||||||
|
case rel_op_a_def:
|
||||||
|
code->code[reloc->ofs].a += data_base;
|
||||||
|
break;
|
||||||
|
case rel_op_b_def:
|
||||||
|
code->code[reloc->ofs].b += data_base;
|
||||||
|
break;
|
||||||
|
case rel_op_c_def:
|
||||||
|
code->code[reloc->ofs].c += data_base;
|
||||||
|
break;
|
||||||
|
case rel_op_a_op:
|
||||||
|
case rel_op_b_op:
|
||||||
|
case rel_op_c_op:
|
||||||
|
break;
|
||||||
|
case rel_def_op:
|
||||||
|
data->data[reloc->ofs].integer_var += code_base;
|
||||||
|
break;
|
||||||
|
case rel_def_def:
|
||||||
|
data->data[reloc->ofs].integer_var += data_base;
|
||||||
|
break;
|
||||||
|
case rel_def_func:
|
||||||
|
data->data[reloc->ofs].integer_var += func_base;
|
||||||
|
break;
|
||||||
|
case rel_def_string:
|
||||||
|
data->data[reloc->ofs].string_var =
|
||||||
|
strpool_addstr (strings,
|
||||||
|
qfo->strings + data->data[reloc->ofs].string_var);
|
||||||
|
reloc->ofs += data_base;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,13 +292,31 @@ linker_add_object_file (const char *filename)
|
||||||
code_base = code->size;
|
code_base = code->size;
|
||||||
data_base = data->size;
|
data_base = data->size;
|
||||||
far_data_base = far_data->size;
|
far_data_base = far_data->size;
|
||||||
|
reloc_base = relocs.num_relocs;
|
||||||
|
def_base = defs.num_defs;
|
||||||
|
func_base = funcs.num_funcs;
|
||||||
|
|
||||||
add_defs (qfo);
|
|
||||||
add_functions (qfo);
|
|
||||||
codespace_addcode (code, qfo->code, qfo->code_size);
|
codespace_addcode (code, qfo->code, qfo->code_size);
|
||||||
//add_data (qfo);
|
defspace_adddata (data, qfo->data, qfo->data_size);
|
||||||
//add_far_data (qfo);
|
defspace_adddata (far_data, qfo->far_data, qfo->far_data_size);
|
||||||
//add_strings (qfo);
|
add_strings (qfo);
|
||||||
|
add_relocs (qfo);
|
||||||
|
add_defs (qfo);
|
||||||
|
add_funcs (qfo);
|
||||||
|
|
||||||
|
fixup_relocs (qfo);
|
||||||
|
|
||||||
|
qfo_delete (qfo);
|
||||||
|
|
||||||
|
qfo = qfo_new ();
|
||||||
|
qfo_add_code (qfo, code->code, code->size);
|
||||||
|
qfo_add_data (qfo, data->data, data->size);
|
||||||
|
qfo_add_far_data (qfo, far_data->data, far_data->size);
|
||||||
|
qfo_add_strings (qfo, strings->strings, strings->size);
|
||||||
|
qfo_add_relocs (qfo, relocs.relocs, relocs.num_relocs);
|
||||||
|
qfo_add_defs (qfo, defs.defs, defs.num_defs);
|
||||||
|
qfo_add_functions (qfo, funcs.funcs, funcs.num_funcs);
|
||||||
|
qfo_add_types (qfo, type_strings->strings, type_strings->size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -499,3 +499,89 @@ qfo_to_progs (qfo_t *qfo, pr_info_t *pr)
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qfo_t *
|
||||||
|
qfo_new (void)
|
||||||
|
{
|
||||||
|
return calloc (1, sizeof (qfo_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
qfo_add_code (qfo_t *qfo, dstatement_t *code, int code_size)
|
||||||
|
{
|
||||||
|
qfo->code = malloc (code_size * sizeof (dstatement_t));
|
||||||
|
memcpy (qfo->code, code, code_size * sizeof (dstatement_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
qfo_add_data (qfo_t *qfo, pr_type_t *data, int data_size)
|
||||||
|
{
|
||||||
|
qfo->data = malloc (data_size * sizeof (pr_type_t));
|
||||||
|
memcpy (qfo->data, data, data_size * sizeof (pr_type_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
qfo_add_far_data (qfo_t *qfo, pr_type_t *far_data, int far_data_size)
|
||||||
|
{
|
||||||
|
qfo->far_data = malloc (far_data_size * sizeof (pr_type_t));
|
||||||
|
memcpy (qfo->far_data, far_data, far_data_size * sizeof (pr_type_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
qfo_add_strings (qfo_t *qfo, const char *strings, int strings_size)
|
||||||
|
{
|
||||||
|
qfo->strings = malloc (strings_size);
|
||||||
|
memcpy (qfo->strings, strings, strings_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
qfo_add_relocs (qfo_t *qfo, qfo_reloc_t *relocs, int num_relocs)
|
||||||
|
{
|
||||||
|
qfo->relocs = malloc (num_relocs * sizeof (qfo_reloc_t));
|
||||||
|
memcpy (qfo->relocs, relocs, num_relocs * sizeof (qfo_reloc_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
qfo_add_defs (qfo_t *qfo, qfo_def_t *defs, int num_defs)
|
||||||
|
{
|
||||||
|
qfo->defs = malloc (num_defs * sizeof (qfo_def_t));
|
||||||
|
memcpy (qfo->defs, defs, num_defs * sizeof (qfo_def_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
qfo_add_functions (qfo_t *qfo, qfo_function_t *functions, int num_functions)
|
||||||
|
{
|
||||||
|
qfo->functions = malloc (num_functions * sizeof (qfo_function_t));
|
||||||
|
memcpy (qfo->functions, functions, num_functions * sizeof (qfo_function_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
qfo_add_types (qfo_t *qfo, const char *types, int types_size)
|
||||||
|
{
|
||||||
|
qfo->types = malloc (types_size);
|
||||||
|
memcpy (qfo->types, types, types_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
qfo_delete (qfo_t *qfo)
|
||||||
|
{
|
||||||
|
if (!qfo)
|
||||||
|
return;
|
||||||
|
if (qfo->code)
|
||||||
|
free (qfo->code);
|
||||||
|
if (qfo->data)
|
||||||
|
free (qfo->data);
|
||||||
|
if (qfo->far_data)
|
||||||
|
free (qfo->far_data);
|
||||||
|
if (qfo->strings)
|
||||||
|
free (qfo->strings);
|
||||||
|
if (qfo->relocs)
|
||||||
|
free (qfo->relocs);
|
||||||
|
if (qfo->defs)
|
||||||
|
free (qfo->defs);
|
||||||
|
if (qfo->functions)
|
||||||
|
free (qfo->functions);
|
||||||
|
if (qfo->types)
|
||||||
|
free (qfo->types);
|
||||||
|
free (qfo);
|
||||||
|
}
|
||||||
|
|
|
@ -107,6 +107,8 @@ relocate_refs (reloc_t *refs, int ofs)
|
||||||
case rel_def_func:
|
case rel_def_func:
|
||||||
G_INT (refs->ofs) = ofs;
|
G_INT (refs->ofs) = ofs;
|
||||||
break;
|
break;
|
||||||
|
case rel_def_string:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
refs = refs->next;
|
refs = refs->next;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue