
/* Copyright William Schelter. All rights reserved.  This file does
the low level relocation which tends to be very system dependent.
It is included by the file sfasl.c
*/

relocate()
{
    unsigned int new_value;
    char *where = the_start + relocation_info.r_address;

    if (relocation_info.r_extern) {
	struct syment *sym = &symbol_table[relocation_info.r_symbolnum];
	if (N_SECTION(sym) == N_UNDEF)
	    handle_missing_symbol(SYM_NAME(sym), where,
				  relocation_info.r_length);
	new_value= sym->n_value;
	if (relocation_info.r_pcrel)
	    new_value -= (int)start_address;
    }
    else {
	switch(relocation_info.r_symbolnum){
	  case N_DATA: case N_BSS: case N_TEXT:
	    new_value = (int)start_address;
	    break;
	  default:
	    dprintf(relocation_info.r_extern = %d, relocation_info.r_extern);
	    printf("\nrelocation_info {r_symbolnum= %d, r_address = %d, r_extern=0 Ignored:",relocation_info.r_address,
		   relocation_info.r_symbolnum);fflush(stdout);
	    goto DONT;
	}
    };
    switch(relocation_info.r_length) {
      case 0: *( char *)where += new_value; break;
      case 1: *( short *)where += new_value; break;
      case 2: *( long *)where += new_value; break;
    }
  DONT:;
}



