blob: e0b5e0cdb5fecb7ddeafcac9ed0e937c806b50b4 [file] [log] [blame]
/* %%%%%%%%%%%%%%%%%%%% (c) William Landi 1991 %%%%%%%%%%%%%%%%%%%%%%%%%%%% */
/* Permission to use this code is granted as long as the copyright */
/* notice remains in place. */
/* =============================== pass2.h ================================= */
/* Process Text, Modify, and Reference records of one object file. Also */
/* does minimal recomputation of the number of bytes needs to be shifted to */
/* accomidate the relocation. */
#include <string.h>
#include <stdio.h>
#include "boolean.h"
#include "constants.h"
#include "sym_tab.h"
#include "stringI.h"
#include "memory.h"
#include "convert.h"
#include "load.h"
/* --------------------------------- pass2 --------------------------------- */
/* Process Text, Modify, and Reference records of one object file. Also */
/* does minimal recomputation of the number of bytes needs to be shifted to */
/* accomidate the relocation. */
void PASS2(MEM_SPACE MEMORY,SYMBOL_TABLE *SYM_TAB,int *LOCATION,int *ERROR,
FILE *INPUT)
{
char MODULE_NAME[LABEL_SIZE_1+1]; /* Name of (program) module currently */
/* assembling. */
char *RECORD; /* One record from the input stream */
int UNREL_LOCATION; /* Where in the unrelocated memory is it */
/* located. */
int UNREL_TO_REL_SHIFT = 0; /* signed number of bytes to shift the */
/* object code due to relocation */
int LENGTH; /* Used to store length of blocks of */
/* memory affected by text and modification*/
/* records */
MODULE_NAME[LABEL_SIZE_1] = '\0';
while (!feof(INPUT) && ((*LOCATION) <= MEM_SIZE_1)) {
BOOLEAN LOCAL_ERROR;
LOCAL_ERROR = FALSE_1;
GET_LINE(&RECORD,INPUT);
switch (RECORD[0]) {
case 'T':
/* ---------------------------- TEXT RECORD -------------------------------- */
if (strlen(RECORD) < 9)
LOCAL_ERROR = TRUE_1;
else {
STR_TO_NUM(&(RECORD[1]),6,16,&UNREL_LOCATION,&LOCAL_ERROR);
STR_TO_NUM(&(RECORD[7]),2,16,&LENGTH,&LOCAL_ERROR);
if (strlen(RECORD) != 9+LENGTH*2) LOCAL_ERROR = TRUE_1;
else STORE_AT(&(RECORD[9]), LENGTH, UNREL_LOCATION+UNREL_TO_REL_SHIFT,
MEMORY,&LOCAL_ERROR);
}
if (LOCAL_ERROR)
(void) printf("ERROR: Illegal text record = %s\n",RECORD);
break;
case 'H':
/* ---------------------------- HEADER RECORD ------------------------------ */
/* ----- Just calcution of UNREL_TO_REL_SHIFT */
if (strlen(RECORD) != (13 + LABEL_SIZE_1))
LOCAL_ERROR = TRUE_1;
else {
int TEMP_LOC;
(void) strncpy(MODULE_NAME,&(RECORD[1]),LABEL_SIZE_1);
STR_TO_NUM(&(RECORD[9]),6,16,&TEMP_LOC,&LOCAL_ERROR);
UNREL_TO_REL_SHIFT = (*LOCATION) - TEMP_LOC;
STR_TO_NUM(&(RECORD[15]),6,16,&TEMP_LOC,&LOCAL_ERROR);
(*LOCATION) += TEMP_LOC;
if ((*LOCATION) > MEM_SIZE_1)
(void) printf("ERROR: Program does not fit in memory. Aborting.\n");
}
break;
/* ---------------------------- MODIFICATION RECORD ------------------------ */
case 'M':
if (strlen(RECORD) < 9) LOCAL_ERROR = TRUE_1;
else if (strlen(RECORD) == 9) {
/* -------------------------- Type 1 Modification record. ------------------ */
STR_TO_NUM(&(RECORD[1]),6,16,&UNREL_LOCATION,&LOCAL_ERROR);
STR_TO_NUM(&(RECORD[7]),2,16,&LENGTH,&LOCAL_ERROR);
ADD_INT_TO_LOC(UNREL_TO_REL_SHIFT, UNREL_LOCATION + UNREL_TO_REL_SHIFT,
LENGTH, MEMORY, &LOCAL_ERROR);
} else
/* -------------------------- Type 2 Modification record. ------------------ */
if (strlen(RECORD) != 18) LOCAL_ERROR = TRUE_1;
else {
struct SYMBOL_TABLE_ENTRY *SYMBOL;
int SIGN;
STR_TO_NUM(&(RECORD[1]),6,16,&UNREL_LOCATION,&LOCAL_ERROR);
STR_TO_NUM(&(RECORD[7]),2,16,&LENGTH,&LOCAL_ERROR);
switch (RECORD[9]) {
case '-':
SIGN = -1;
break;
case '+':
SIGN = 1;
break;
default:
SIGN = 0;
LOCAL_ERROR = TRUE_1;
break;
}
SYMBOL = LOOK_UP_SYMBOL(GLOBAL_1,&(RECORD[10]),SYM_TAB);
if (SYMBOL == NULL) LOCAL_ERROR = TRUE_1;
else ADD_INT_TO_LOC((*SYMBOL).LOCATION * SIGN,
UNREL_LOCATION + UNREL_TO_REL_SHIFT,
LENGTH, MEMORY, &LOCAL_ERROR);
}
if (LOCAL_ERROR)
(void) printf("ERROR: Illegal text record = %s\n",RECORD);
break;
case 'R':
/* ------------------------------- REFERENCE RECORD ------------------------ */
if (strlen(RECORD) > 73) LOCAL_ERROR = TRUE_1;
else {
int NEXT = 1;
char TEMP_NAME[LABEL_SIZE_1+1];
TEMP_NAME[LABEL_SIZE_1] = '\0';
while (NEXT + LABEL_SIZE_1 <= strlen(RECORD)) {
(void) strncpy(TEMP_NAME,&(RECORD[NEXT]),LABEL_SIZE_1);
if (LOOK_UP_SYMBOL(GLOBAL_1,TEMP_NAME, SYM_TAB) == NULL) {
int I;
(void) INSERT_IN_SYM_TAB(GLOBAL_1,TEMP_NAME,0,UNDEFINED,SYM_TAB);
for (I=LABEL_SIZE_1-1; ( (I<1) || (TEMP_NAME[I] == ' ')); I--);
TEMP_NAME[I+1] = '\0';
(void) printf(
"ERROR: Undefined global %s. Program not loaded.\n"
,TEMP_NAME);
(*ERROR) = TRUE_1;
}
NEXT += LABEL_SIZE_1;
}
if (NEXT != strlen(RECORD)) LOCAL_ERROR = TRUE_1;
}
if (LOCAL_ERROR)
(void) printf("ERROR: Illegal define record = %s\n",RECORD);
break;
case 'E':
case 'D':
case '\0':
default:
break;
}
(*ERROR) = (*ERROR) || LOCAL_ERROR;
}
}