/*
* Code to manipulate the relocation table during the link
*/
#include "../include/genutil.h"
#include "../include/bacicnty.h"
#include "ld.h"
#include "ldutils.h"
#include "ldreloc.h"
/*
*>>>>>>>>>>>> Change this to your login id <<<<<<<<<<<<
*>>>>>>>>>>>> (code won't run until you do) <<<<<<<<<<<<
*/
char loginid[] = {"rcthom"};
void append_reloc(ALL_TABLES* tfinal, ALL_TABLES *t1, ALL_TABLES* t2)
/* appends t2->reloc[] to tfinal->reloc[],
updating the code addresses of the reloc items to the
value required in tfinal->reloc[], and editing
tfinal->code[] as necessary,
*/
{
int t2_coffset = t1->last_code+1 - t2->first_code;
int t2_doffset = t1->last_dseg+1 - t2->first_dseg;
int tix;
int tixf;
reloc_fields r;
int i;
for(i = 0; i <= t2->last_reloc; i++){
r = t2->reloc[i];
if(r.r.ref == CODEREF){
r.r.adr += t2_coffset;
tfinal->code[r.r.adr].u.y += t2_coffset;
}
if(r.r.ref == EXTDSEGREF){
r.r.adr += t2_coffset;
if(tfinal->code[r.r.adr].u.y != 0xffff)
tfinal->code[r.r.adr].u.y += t2_doffset;
}
if(r.r.ref == DSEGREF){
if(r.r.tabix == NO_MOD){
r.r.tabix = 0;
}else{
r.r.adr += t2_coffset;
tfinal->code[r.r.adr].u.y += t2_doffset;
}
}
if(r.r.ref == MARKSTACKREF)
{
tix = t2->code[r.r.adr].u.y;
tixf = search_tab(tfinal, t2->tab[tix].name);
r.r.adr += t2_coffset;
tfinal->code[r.r.adr].u.y = tixf;
}
t2->reloc[i] = r;
tfinal->last_reloc += 1;
tfinal->reloc[tfinal->last_reloc] = t2->reloc[i];
}
//printf("DONE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
}/*end append_reloc */
void update_ext_reloc(ALL_TABLES* tfinal, ALL_TABLES* t, int ex_tabix,
int new_ref, int new_tabix, int modify_code , int t_code_offset,
int new_dseg_adr)
/* Called when new information shows up about an external dseg reference.
* Search the relocation table t->reloc[] for an extdsegref ref field
* having a tabix field == ex_tabix
* When found at t->reloc[i],
* update the ref field of t->reloc[i] to new_ref
* update the tabix field of t->reloc[i] to new_tabix
* If (modify_code),
* modify tfinal->code[adr+t_code_offset].u.y to new_dseg_adr
* If new_tabix == NO_MOD, then the adr field of the relocation
* item must be modified now (append_reloc will zero the tabix
* field when it sees such an item and leave the adr field
* unmolested)
*/
{
int i;
for(i = 0; i<= t->last_reloc; i++){
if((t->reloc[i].r.ref == EXTDSEGREF) && (t->reloc[i].r.tabix == ex_tabix)){
t->reloc[i].r.ref = new_ref;
t->reloc[i].r.tabix = new_tabix;
if(modify_code){
tfinal->code[t->reloc[i].r.adr + t_code_offset].u.y = new_dseg_adr;
if(new_tabix == NO_MOD)
t->reloc[i].r.adr += t_code_offset;
}
}
}
} /* update_ext_reloc */
void perform_reloc(ALL_TABLES* t, int first_code, int first_dseg)
/* user has requested relocation of the final link file
* so that t->first_code = first_code and t->first_dseg = first_dseg.
* Move code & dseg tables, then
* Use reloc table to update the code array
* Change code addresses in the tab and dbg tables
*/
{
int code_delta = first_code - t->first_code;
int dseg_delta = first_dseg - t->first_dseg;
move_code(t, first_code);
move_dseg(t, first_dseg);
int ix = t->btab[0].last;
reloc_fields r;
int i;
for(i = 0; i <= t->last_reloc; i++){
r = t->reloc[i];
r.r.adr += code_delta;
if(r.r.ref == CODEREF)
t->code[r.r.adr].u.y += code_delta;
if(r.r.ref == DSEGREF)
t->code[r.r.adr].u.y += dseg_delta;
if(r.r.ref == EXTDSEGREF && t->code[r.r.adr].u.y != 0xffff)
t->code[r.r.adr].u.y += dseg_delta;
t->reloc[i] = r;
}
while (ix) {
if(t->tab[ix].obj == variable){
t->tab[ix].adr += dseg_delta;
}else{
t->tab[ix].adr += code_delta;
}
ix = t->tab[ix].link;
}
update_dbg(t, code_delta);
} /* perform_reloc */
/*
* $Log: ldreloc-handout.c,v $
* Revision 1.2 2005/04/13 18:59:36 bynum
* Fall 2004 version
*
* Revision 1.1 2002/11/27 13:26:01 bynum
* Initial revision
*
*/