/* * 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 * */