mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-03-22 02:11:19 +00:00
more linking fixes, including seting up relocations. not quite working yet
This commit is contained in:
parent
34fa421638
commit
e550ad670a
12 changed files with 134 additions and 84 deletions
|
@ -94,8 +94,8 @@ struct def_s *protocol_def (protocol_t *protocol);
|
|||
protocollist_t *new_protocollist (void);
|
||||
void add_protocol (protocollist_t *protocollist, protocol_t *protocol);
|
||||
|
||||
int emit_protocol (protocol_t *protocol);
|
||||
int emit_protocol_list (protocollist_t *protocols, const char *name);
|
||||
struct def_s *emit_protocol (protocol_t *protocol);
|
||||
struct def_s *emit_protocol_list (protocollist_t *protocols, const char *name);
|
||||
|
||||
void clear_classes (void);
|
||||
|
||||
|
|
|
@ -49,4 +49,18 @@ struct def_s *emit_statement (struct expr_s *e, opcode_t *op, struct def_s *var_
|
|||
struct def_s *emit_sub_expr (struct expr_s*e, struct def_s *dest);
|
||||
void emit_expr (struct expr_s *e);
|
||||
|
||||
#define EMIT_STRING(dest,str) \
|
||||
do { \
|
||||
(dest) = ReuseString (str); \
|
||||
reloc_def_string (POINTER_OFS (&(dest))); \
|
||||
} while (0)
|
||||
|
||||
#define EMIT_DEF(dest,def) \
|
||||
do { \
|
||||
def_t *d = (def); \
|
||||
(dest) = d ? d->ofs : 0; \
|
||||
if (d) \
|
||||
reloc_def_def (d, POINTER_OFS (&(dest))); \
|
||||
} while (0)
|
||||
|
||||
#endif//__emit_h
|
||||
|
|
|
@ -80,7 +80,8 @@ void selector_name (struct dstring_s *sel_id, keywordarg_t *selector);
|
|||
void selector_types (struct dstring_s *sel_types, keywordarg_t *selector);
|
||||
struct def_s *selector_def (const char *sel_id, const char *sel_types);
|
||||
|
||||
int emit_methods (methodlist_t *methods, const char *name, int instance);
|
||||
struct def_s *emit_methods (methodlist_t *methods, const char *name,
|
||||
int instance);
|
||||
|
||||
void clear_selectors (void);
|
||||
|
||||
|
|
|
@ -56,5 +56,8 @@ struct statement_s;
|
|||
|
||||
reloc_t *new_reloc (int ofs, reloc_type type);
|
||||
void relocate_refs (reloc_t *refs, int ofs);
|
||||
void reloc_def_def (struct def_s *def, int ofs);
|
||||
void reloc_def_func (struct function_s *func, int ofs);
|
||||
void reloc_def_string (int ofs);
|
||||
|
||||
#endif//__reloc_h
|
||||
|
|
|
@ -55,7 +55,7 @@ struct type_s *new_union (const char *name);
|
|||
struct type_s *find_struct (const char *name);
|
||||
void copy_struct_fields (struct type_s *dst, struct type_s *src);
|
||||
|
||||
int emit_struct (struct type_s *strct, const char *name);
|
||||
struct def_s *emit_struct (struct type_s *strct, const char *name);
|
||||
|
||||
void process_enum (struct expr_s *enm);
|
||||
struct expr_s *get_enum (const char *name);
|
||||
|
|
|
@ -176,12 +176,13 @@ class_begin (class_t *class)
|
|||
|
||||
class->def->initialized = class->def->constant = 1;
|
||||
category = &G_STRUCT (pr_category_t, class->def->ofs);
|
||||
category->category_name = ReuseString (class->category_name);
|
||||
category->class_name = ReuseString (class->class_name);
|
||||
category->protocols = emit_protocol_list (class->protocols,
|
||||
va ("%s_%s",
|
||||
class->class_name,
|
||||
class->category_name));
|
||||
EMIT_STRING (category->category_name, class->category_name);
|
||||
EMIT_STRING (category->class_name, class->class_name);
|
||||
EMIT_DEF (category->protocols,
|
||||
emit_protocol_list (class->protocols,
|
||||
va ("%s_%s",
|
||||
class->class_name,
|
||||
class->category_name)));
|
||||
} else if (class->class_name) {
|
||||
def_t *meta_def;
|
||||
pr_class_t *meta;
|
||||
|
@ -192,19 +193,19 @@ class_begin (class_t *class)
|
|||
pr.scope, st_static);
|
||||
meta_def->initialized = meta_def->constant = 1;
|
||||
meta = &G_STRUCT (pr_class_t, meta_def->ofs);
|
||||
meta->class_pointer = ReuseString (class->class_name);
|
||||
EMIT_STRING (meta->class_pointer, class->class_name);
|
||||
if (class->super_class)
|
||||
meta->super_class = ReuseString (class->super_class->class_name);
|
||||
meta->name = meta->class_pointer;
|
||||
EMIT_STRING (meta->super_class, class->super_class->class_name);
|
||||
EMIT_STRING (meta->name, class->class_name);
|
||||
meta->info = _PR_CLS_META;
|
||||
meta->instance_size = type_size (type_Class.aux_type);
|
||||
meta->ivars = emit_struct (type_Class.aux_type, "Class");
|
||||
meta->protocols = emit_protocol_list (class->protocols,
|
||||
class->class_name);
|
||||
EMIT_DEF (meta->ivars, emit_struct (type_Class.aux_type, "Class"));
|
||||
EMIT_DEF (meta->protocols, emit_protocol_list (class->protocols,
|
||||
class->class_name));
|
||||
|
||||
class->def->initialized = class->def->constant = 1;
|
||||
cls = &G_STRUCT (pr_class_t, class->def->ofs);
|
||||
cls->class_pointer = meta_def->ofs;
|
||||
EMIT_DEF (cls->class_pointer, meta_def);
|
||||
cls->super_class = meta->super_class;
|
||||
cls->name = meta->name;
|
||||
meta->info = _PR_CLS_CLASS;
|
||||
|
@ -219,16 +220,14 @@ class_finish (class_t *class)
|
|||
pr_category_t *category;
|
||||
|
||||
category = &G_STRUCT (pr_category_t, class->def->ofs);
|
||||
category->instance_methods = emit_methods (class->methods,
|
||||
va ("%s_%s",
|
||||
class->class_name,
|
||||
class->category_name),
|
||||
1);
|
||||
category->class_methods = emit_methods (class->methods,
|
||||
va ("%s_%s",
|
||||
EMIT_DEF (category->instance_methods,
|
||||
emit_methods (class->methods, va ("%s_%s",
|
||||
class->class_name,
|
||||
class->category_name),
|
||||
0);
|
||||
class->category_name), 1));
|
||||
EMIT_DEF (category->class_methods,
|
||||
emit_methods (class->methods, va ("%s_%s",
|
||||
class->class_name,
|
||||
class->category_name), 0));
|
||||
} else if (class->class_name) {
|
||||
pr_class_t *meta;
|
||||
pr_class_t *cls;
|
||||
|
@ -237,11 +236,13 @@ class_finish (class_t *class)
|
|||
|
||||
meta = &G_STRUCT (pr_class_t, cls->class_pointer);
|
||||
|
||||
meta->methods = emit_methods (class->methods, class->class_name, 0);
|
||||
EMIT_DEF (meta->methods, emit_methods (class->methods,
|
||||
class->class_name, 0));
|
||||
|
||||
cls->instance_size = type_size (class->ivars);
|
||||
cls->ivars = emit_struct (class->ivars, class->class_name);
|
||||
cls->methods = emit_methods (class->methods, class->class_name, 1);
|
||||
EMIT_DEF (cls->ivars, emit_struct (class->ivars, class->class_name));
|
||||
EMIT_DEF (cls->methods, emit_methods (class->methods,
|
||||
class->class_name, 1));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -417,7 +418,7 @@ class_pointer_def (class_t *class)
|
|||
class->def = class_def (class, 1);
|
||||
if (!class->def->external)
|
||||
G_INT (def->ofs) = class->def->ofs;
|
||||
//FIXME need reloc
|
||||
reloc_def_def (class->def, def->ofs);
|
||||
return def;
|
||||
}
|
||||
|
||||
|
@ -445,13 +446,13 @@ class_finish_module (void)
|
|||
if (class_hash) {
|
||||
classes = (class_t **) Hash_GetList (class_hash);
|
||||
for (t = classes; *t; t++)
|
||||
if ((*t)->def)
|
||||
if ((*t)->def && !(*t)->def->external)
|
||||
num_classes++;
|
||||
}
|
||||
if (category_hash) {
|
||||
categories = (class_t **) Hash_GetList (category_hash);
|
||||
for (t = categories; *t; t++)
|
||||
if ((*t)->def)
|
||||
if ((*t)->def && !(*t)->def->external)
|
||||
num_categories++;
|
||||
}
|
||||
if (!num_classes && !num_categories)
|
||||
|
@ -468,33 +469,39 @@ class_finish_module (void)
|
|||
symtab->cls_def_cnt = num_classes;
|
||||
symtab->cat_def_cnt = num_categories;
|
||||
def_ptr = symtab->defs;
|
||||
for (i = 0, t = classes; i < num_classes; i++, t++)
|
||||
if ((*t)->def)
|
||||
for (i = 0, t = classes; i < num_classes; i++, t++) {
|
||||
if ((*t)->def && !(*t)->def->external) {
|
||||
reloc_def_def ((*t)->def, POINTER_OFS (def_ptr));
|
||||
*def_ptr++ = (*t)->def->ofs;
|
||||
for (i = 0, t = categories; i < num_categories; i++, t++)
|
||||
if ((*t)->def)
|
||||
}
|
||||
}
|
||||
for (i = 0, t = categories; i < num_categories; i++, t++) {
|
||||
if ((*t)->def && !(*t)->def->external) {
|
||||
reloc_def_def ((*t)->def, POINTER_OFS (def_ptr));
|
||||
*def_ptr++ = (*t)->def->ofs;
|
||||
}
|
||||
}
|
||||
|
||||
module_def = get_def (type_module, "_OBJ_MODULE", pr.scope, st_static);
|
||||
module_def->initialized = module_def->constant = 1;
|
||||
module = &G_STRUCT (pr_module_t, module_def->ofs);
|
||||
module->size = type_size (type_module);
|
||||
module->name = ReuseString (options.output_file);
|
||||
module->symtab = symtab_def->ofs;
|
||||
EMIT_STRING (module->name, options.output_file);
|
||||
EMIT_DEF (module->symtab, symtab_def);
|
||||
|
||||
exec_class_def = get_def (&type_obj_exec_class, "__obj_exec_class",
|
||||
pr.scope, st_static);
|
||||
exec_class_func = new_function ("__obj_exec_class");
|
||||
exec_class_func->builtin = 0;
|
||||
exec_class_func->def = exec_class_def;
|
||||
exec_class_func->refs = new_reloc (exec_class_def->ofs, rel_def_func);
|
||||
reloc_def_func (exec_class_func, exec_class_def->ofs);
|
||||
build_function (exec_class_func);
|
||||
finish_function (exec_class_func);
|
||||
|
||||
init_def = get_def (&type_function, ".ctor", pr.scope, st_static);
|
||||
init_func = new_function (".ctor");
|
||||
init_func->def = init_def;
|
||||
init_func->refs = new_reloc (init_def->ofs, rel_def_func);
|
||||
reloc_def_func (init_func, init_def->ofs);
|
||||
init_func->code = pr.code->size;
|
||||
build_scope (init_func, init_def, 0);
|
||||
build_function (init_func);
|
||||
|
@ -579,7 +586,7 @@ add_protocol (protocollist_t *protocollist, protocol_t *protocol)
|
|||
protocollist->list[protocollist->count++] = protocol;
|
||||
}
|
||||
|
||||
int
|
||||
def_t *
|
||||
emit_protocol (protocol_t *protocol)
|
||||
{
|
||||
def_t *proto_def;
|
||||
|
@ -591,17 +598,18 @@ emit_protocol (protocol_t *protocol)
|
|||
proto_def->initialized = proto_def->constant = 1;
|
||||
proto = &G_STRUCT (pr_protocol_t, proto_def->ofs);
|
||||
proto->class_pointer = 0;
|
||||
proto->protocol_name = ReuseString (protocol->name);
|
||||
proto->protocol_list =
|
||||
emit_protocol_list (protocol->protocols,
|
||||
va ("PROTOCOL_%s", protocol->name));
|
||||
proto->instance_methods = emit_methods (protocol->methods,
|
||||
protocol->name, 1);
|
||||
proto->class_methods = emit_methods (protocol->methods, protocol->name, 0);
|
||||
return proto_def->ofs;
|
||||
EMIT_STRING (proto->protocol_name, protocol->name);
|
||||
EMIT_DEF (proto->protocol_list,
|
||||
emit_protocol_list (protocol->protocols,
|
||||
va ("PROTOCOLo_%s", protocol->name)));
|
||||
EMIT_DEF (proto->instance_methods,
|
||||
emit_methods (protocol->methods, protocol->name, 1));
|
||||
EMIT_DEF (proto->class_methods,
|
||||
emit_methods (protocol->methods, protocol->name, 0));
|
||||
return proto_def;
|
||||
}
|
||||
|
||||
int
|
||||
def_t *
|
||||
emit_protocol_list (protocollist_t *protocols, const char *name)
|
||||
{
|
||||
def_t *proto_list_def;
|
||||
|
@ -624,8 +632,8 @@ emit_protocol_list (protocollist_t *protocols, const char *name)
|
|||
proto_list->next = 0;
|
||||
proto_list->count = protocols->count;
|
||||
for (i = 0; i < protocols->count; i++)
|
||||
proto_list->list[i] = emit_protocol (protocols->list[i]);
|
||||
return proto_list_def->ofs;
|
||||
EMIT_DEF (proto_list->list[i], emit_protocol (protocols->list[i]));
|
||||
return proto_list_def;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -204,7 +204,7 @@ build_builtin_function (def_t *def, expr_t *bi_val)
|
|||
f->builtin = bi_val->type == ex_integer ? bi_val->e.integer_val
|
||||
: (int)bi_val->e.float_val;
|
||||
f->def = def;
|
||||
f->refs = new_reloc (def->ofs, rel_def_func);
|
||||
reloc_def_func (f, def->ofs);
|
||||
build_function (f);
|
||||
finish_function (f);
|
||||
return f;
|
||||
|
|
|
@ -51,6 +51,7 @@ static const char rcsid[] =
|
|||
#include "expr.h"
|
||||
#include "class.h"
|
||||
#include "def.h"
|
||||
#include "emit.h"
|
||||
#include "immediate.h"
|
||||
#include "method.h"
|
||||
#include "reloc.h"
|
||||
|
@ -245,11 +246,9 @@ sel_def_compare (void *_sd1, void *_sd2, void *unused)
|
|||
}
|
||||
|
||||
def_t *
|
||||
selector_def (const char *_sel_id, const char *_sel_types)
|
||||
selector_def (const char *sel_id, const char *sel_types)
|
||||
{
|
||||
string_t sel_id = ReuseString (_sel_id);
|
||||
string_t sel_types = ReuseString (_sel_types);
|
||||
sel_def_t _sel_def = {sel_id, sel_types, 0};
|
||||
sel_def_t _sel_def = {ReuseString (sel_id), ReuseString (sel_types), 0};
|
||||
sel_def_t *sel_def = &_sel_def;
|
||||
|
||||
if (!sel_def_hash) {
|
||||
|
@ -260,18 +259,18 @@ selector_def (const char *_sel_id, const char *_sel_types)
|
|||
if (sel_def)
|
||||
return sel_def->def;
|
||||
sel_def = malloc (sizeof (sel_def_t));
|
||||
sel_def->sel_id = sel_id;
|
||||
sel_def->sel_types = sel_types;
|
||||
sel_def->def = new_def (type_SEL.aux_type, ".imm", pr.scope);
|
||||
sel_def->def->initialized = sel_def->def->constant = 1;
|
||||
sel_def->def->ofs = new_location (type_SEL.aux_type, pr.near_data);
|
||||
G_INT (sel_def->def->ofs) = sel_id;
|
||||
G_INT (sel_def->def->ofs + 1) = sel_types;
|
||||
EMIT_STRING (G_INT (sel_def->def->ofs), sel_id);
|
||||
EMIT_STRING (G_INT (sel_def->def->ofs + 1), sel_types);
|
||||
sel_def->sel_id = G_INT (sel_def->def->ofs);
|
||||
sel_def->sel_types = G_INT (sel_def->def->ofs + 1);
|
||||
Hash_AddElement (sel_def_hash, sel_def);
|
||||
return sel_def->def;
|
||||
}
|
||||
|
||||
int
|
||||
def_t *
|
||||
emit_methods (methodlist_t *_methods, const char *name, int instance)
|
||||
{
|
||||
const char *type = instance ? "INSTANCE" : "CLASS";
|
||||
|
@ -304,24 +303,19 @@ emit_methods (methodlist_t *_methods, const char *name, int instance)
|
|||
methods->method_next = 0;
|
||||
methods->method_count = count;
|
||||
for (i = 0, method = _methods->head; method; method = method->next) {
|
||||
reloc_t *ref;
|
||||
if (!method->instance != !instance || !method->def)
|
||||
continue;
|
||||
methods->method_list[i].method_name.sel_id = ReuseString (method->name);
|
||||
methods->method_list[i].method_name.sel_types =
|
||||
ReuseString (method->types);
|
||||
methods->method_list[i].method_types =
|
||||
methods->method_list[i].method_name.sel_types;
|
||||
EMIT_STRING (methods->method_list[i].method_name.sel_id, method->name);
|
||||
EMIT_STRING (methods->method_list[i].method_name.sel_types, method->types);
|
||||
EMIT_STRING (methods->method_list[i].method_types, method->types);
|
||||
methods->method_list[i].method_imp = G_FUNCTION (method->def->ofs);
|
||||
if (method->func) {
|
||||
ref = new_reloc (POINTER_OFS (&methods->method_list[i].method_imp),
|
||||
rel_def_func);
|
||||
ref->next = method->func->refs;
|
||||
method->func->refs = ref;
|
||||
reloc_def_func (method->func,
|
||||
POINTER_OFS (&methods->method_list[i].method_imp));
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return methods_def->ofs;
|
||||
return methods_def;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -492,11 +492,11 @@ qfo_to_progs (qfo_t *qfo, pr_info_t *pr)
|
|||
pd->line = qd->line;
|
||||
}
|
||||
|
||||
pr->num_functions = qfo->num_functions;
|
||||
pr->func_head = calloc (pr->num_functions, sizeof (function_t));
|
||||
pr->num_functions = qfo->num_functions + 1;
|
||||
pr->func_head = calloc (qfo->num_functions, sizeof (function_t));
|
||||
pr->func_tail = &pr->func_head;
|
||||
for (i = 0, pf = pr->func_head, qf = qfo->functions;
|
||||
i < pr->num_functions; i++, pf++, qf++) {
|
||||
i < qfo->num_functions; i++, pf++, qf++) {
|
||||
*pr->func_tail = pf;
|
||||
pr->func_tail = &pf->next;
|
||||
pf->aux = new_auxfunction ();
|
||||
|
|
|
@ -170,7 +170,7 @@ WriteData (int crc)
|
|||
fields = calloc (pr.scope->num_defs + 1, sizeof (ddef_t));
|
||||
|
||||
for (def = pr.scope->head; def; def = def->def_next) {
|
||||
if (!def->global || !def->name)
|
||||
if (def->local || !def->name)
|
||||
continue;
|
||||
if (def->type->type == ev_func) {
|
||||
} else if (def->type->type == ev_field) {
|
||||
|
@ -351,7 +351,6 @@ finish_compilation (void)
|
|||
ex_label_t *l;
|
||||
dfunction_t *df;
|
||||
|
||||
class_finish_module ();
|
||||
// check to make sure all functions prototyped have code
|
||||
if (options.warnings.undefined_function)
|
||||
for (d = pr.scope->head; d; d = d->def_next) {
|
||||
|
@ -489,7 +488,10 @@ compile_to_obj (const char *file, const char *obj)
|
|||
}
|
||||
}
|
||||
if (!err) {
|
||||
qfo_t *qfo = qfo_from_progs (&pr);
|
||||
qfo_t *qfo;
|
||||
|
||||
class_finish_module ();
|
||||
qfo = qfo_from_progs (&pr);
|
||||
err = qfo_write (qfo, obj);
|
||||
qfo_delete (qfo);
|
||||
}
|
||||
|
@ -633,6 +635,7 @@ progs_src_compile (void)
|
|||
qfo_write (qfo, options.output_file);
|
||||
qfo_delete (qfo);
|
||||
} else {
|
||||
class_finish_module ();
|
||||
if (!finish_compilation ()) {
|
||||
fprintf (stderr, "compilation errors\n");
|
||||
return 1;
|
||||
|
|
|
@ -44,6 +44,7 @@ static const char rcsid[] =
|
|||
#include "def.h"
|
||||
#include "emit.h"
|
||||
#include "expr.h"
|
||||
#include "function.h"
|
||||
#include "qfcc.h"
|
||||
#include "reloc.h"
|
||||
|
||||
|
@ -124,3 +125,27 @@ new_reloc (int ofs, reloc_type type)
|
|||
ref->type = type;
|
||||
return ref;
|
||||
}
|
||||
|
||||
void
|
||||
reloc_def_def (def_t *def, int ofs)
|
||||
{
|
||||
reloc_t *ref = new_reloc (ofs, rel_def_def);
|
||||
ref->next = def->refs;
|
||||
def->refs = ref;
|
||||
}
|
||||
|
||||
void
|
||||
reloc_def_func (function_t *func, int ofs)
|
||||
{
|
||||
reloc_t *ref = new_reloc (ofs, rel_def_func);
|
||||
ref->next = func->refs;
|
||||
func->refs = ref;
|
||||
}
|
||||
|
||||
void
|
||||
reloc_def_string (int ofs)
|
||||
{
|
||||
reloc_t *ref = new_reloc (ofs, rel_def_string);
|
||||
ref->next = pr.relocs;
|
||||
pr.relocs = ref;
|
||||
}
|
||||
|
|
|
@ -47,10 +47,12 @@ static const char rcsid[] =
|
|||
#include <QF/sys.h>
|
||||
#include <QF/va.h>
|
||||
|
||||
#include "qfcc.h"
|
||||
#include "def.h"
|
||||
#include "emit.h"
|
||||
#include "expr.h"
|
||||
#include "immediate.h"
|
||||
#include "qfcc.h"
|
||||
#include "reloc.h"
|
||||
#include "struct.h"
|
||||
#include "type.h"
|
||||
|
||||
|
@ -202,7 +204,7 @@ struct_compare_fields (struct type_s *s1, struct type_s *s2)
|
|||
return !((!f1) ^ !(f2));
|
||||
}
|
||||
|
||||
int
|
||||
def_t *
|
||||
emit_struct(type_t *strct, const char *name)
|
||||
{
|
||||
struct_field_t *field;
|
||||
|
@ -234,8 +236,8 @@ emit_struct(type_t *strct, const char *name)
|
|||
if (!field->name)
|
||||
continue;
|
||||
encode_type (encoding, field->type);
|
||||
ivars->ivar_list[i].ivar_name = ReuseString (field->name);
|
||||
ivars->ivar_list[i].ivar_type = ReuseString (encoding->str);
|
||||
EMIT_STRING (ivars->ivar_list[i].ivar_name, field->name);
|
||||
EMIT_STRING (ivars->ivar_list[i].ivar_type, encoding->str);
|
||||
ivars->ivar_list[i].ivar_offset = field->offset;
|
||||
dstring_clearstr (encoding);
|
||||
i++;
|
||||
|
@ -243,7 +245,7 @@ emit_struct(type_t *strct, const char *name)
|
|||
done:
|
||||
dstring_delete (encoding);
|
||||
dstring_delete (ivars_name);
|
||||
return ivars_def->ofs;
|
||||
return ivars_def;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Reference in a new issue