#include "clld.h"
#include <iostream.h>
#include <set_error.h>
int resolve_references (List<InternalObjectFile> & obs, List<CodeImport> & cimports,
List<InternalObjectFileP> & shlibs ) {
AVLTree<Str> unrefs;
int result = 0;
int aktshlibnum = 1;
bool newused = true;
while ( newused ) {
newused = false;
for (ListItem<InternalObjectFile> * aktob = obs.get_head();
aktob;
aktob = aktob->get_next()
) {
if (aktob->used) {
// try to resolve all imports of aktob
for (ListItem<Import> * aktimp = aktob->imports.rem_head();
aktimp;
delete aktimp, aktimp = aktob->imports.rem_head()
) {
if (! unrefs.find(aktimp->name)) {
// search for the aktimp symbol in any object-file
ListItem<InternalObjectFile> * searchob;
for (searchob = obs.get_head();
searchob;
searchob = searchob->get_next()
) {
AVLItem<Symbol> * foundexp = searchob->exports.find(Symbol(aktimp->name));
if (foundexp) {
if (foundexp->isfloat) {
cerr << "sorry, external floating point symbols not supported, yet.\n";
searchob = (ListItem<InternalObjectFile> *)0;
break;
}
if (! searchob->used) {
if (searchob->shared) {
searchob->ShLibNumber = aktshlibnum++;
if (aktshlibnum >= 45) {
cerr << "ERROR: maximum number of shared libraries exceeded -\n"
" use '-static' on one or more of your libraries\n";
searchob = (ListItem<InternalObjectFile> *)0;
break;
}
shlibs.add_tail(searchob);
}
searchob->used = true;
newused = true;
}
if (aktob->shared) {
if (foundexp->numerical) {
cerr << "ERROR: shared-library imports must be resolved by non-numerical\n"
" symbols. Violated by symbol '" << aktimp->name << "',\n"
" imported by shared-library '" << aktob->name << "',\n"
" exported by object '" << searchob->name << "'.\n";
break;
}
ListItem<Import> * lii = new ListItem<Import>(
Import(foundexp->ivalue, searchob->ShLibNumber, aktimp->name, false)
);
aktob->shimports.add_tail(lii);
if (searchob->ShLibNumber == 0) {
// shared lib imports from main code, so an internal relocation has to be applied
searchob->intrelocs.add_tail(InternalReloc(aktob, lii));
}
break;
} else {
if (searchob->shared && (! foundexp->numerical)) {
// label reference in code resolved by shared library
ListItem<CodeImport> * lic = new ListItem<CodeImport>(
CodeImport(aktimp->offset, searchob->ShLibNumber,
aktimp->name, foundexp->ivalue)
);
cimports.add_tail(lic);
// remember internal relocation has to be applied
aktob->intrelocs.add_tail(InternalReloc(searchob, (ListItem<Import> *)lic));
break;
} else {
NibStr value(foundexp->ivalue, aktimp->nibsize);
if (foundexp->numerical == false) {
if (aktimp->nibsize < 5) {
set_error("label operand too big for import ","("+NtoStr(aktimp->nibsize)+" < 5)");
value.fail = -1;
} else {
searchob->intrelocs.add_tail(InternalReloc(aktob, aktimp->offset));
}
// test if a non-internal relocation has to be added
if (aktimp->reloc_demand) {
// cerr << "added reloc at " << aktimp->offset << "\n";
aktob->relocs.add_tail(Reloc(aktimp->offset));
}
}
if (value.fail) {
add_error("WARNING: symbol '"+aktimp->name+"', imported by\n"
" object-file '"+aktob->name+"', exported by\n"
" object-file '"+searchob->name+"' with invalid value","");
cerr << get_error();
} else {
unsigned long long tmp = aktob->body.peek(aktimp->offset, aktimp->nibsize);
tmp += foundexp->ivalue;
aktob->body.poke(aktimp->offset, tmp, aktimp->nibsize);
}
break;
}
}
}
}
if (! searchob) {
if (!shared) {
unrefs.insert(aktimp->name);
cerr << "ERROR: unable to resolve symbol '" << aktimp->name << "',\n"
" referenced by object-file '" << aktob->name << "'\n";
if (unrefs.size() > 50) {
cerr << "ABORT, too many unresolved symbols\n";
return -1;
}
result = -1;
} else {
// unreferenced symbol for shared library...
if (aktimp->nibsize < 5 || (! aktimp->reloc_demand) ) {
cerr << "ERROR: run-time imports for shared libraries must be\n"
" non-numerical and >= 5 nibbles in size. This is\n"
" not the case with symbol '" << aktimp->name << "'\n"
" referenced by object-file '" << aktob->name << "'\n";
result = -1;
} else {
// add the actual import to the list of imports for the shared library that is created
aktob->shimports.add_tail(Import(aktimp->offset, 5, aktimp->name, true));
}
}
}
}
}
}
}
}
return result;
}
syntax highlighted by Code2HTML, v. 0.9.1