The main objective of the second pass of a linking loader is to complete the linking and relocation process by replacing symbolic references with their actual memory addresses.
Additional functions of a linking loader include:
1) Allocate memory space for the program in the memory.
2) Resolve symbolic references between object modules by assigning addresses to user-defined and library subroutines.
3) Perform relocation for address-dependent instructions.
4) Load machine instructions into the allocated memory.
A linking loader follows a two-pass algorithm. In Pass 1, it builds symbol tables and resolves external references. Pass 2 finalizes the loading and linking of the program.
External Symbol Table (ESTAB): Used to resolve external symbol references by storing their addresses and associated object modules.
Memory Allocation Table: Ensures the correct placement of object code within allocated memory regions.
Relocation Records: Adjust addresses in the object code based on the base addresses of modules.
Object Code Buffer: Temporarily holds object code segments before loading them into memory.
Program Header Table (Optional): Contains metadata for each module, such as size, starting address, and entry points.
begin
set CSADDR to PROGADDR
set EXECADDR to PROGADDR
while
not end of input
do
begin
read next input record {header record}
set CSLTH to control section length
while
record type ≠ ‘E’
do
begin
read next input record
if
record type = ‘T’
then
begin
{if object code is in character form,
convert into internal representation}
move object code from record to
location (CSADDR + Specified address)
end
{if ‘T’}
else if
record type = ‘M’
then
begin
search ESTAB for modifying symbol
name
if
found
then
add or subtract symbol value at
location (CSADDR + specified
address)
else
set error flag (undefined
external symbol)
end
{if ‘M’}
end
{while ≠ ‘E’}
if
an address is specified {in End record}
then
set EXECADDR to (CSADDR + specified address)
add CSLTH to CSADDR
end
{while not EOF}
Jump to location given by EXECADDR {to start execution of
loaded program}
End
{pass 2}
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct exttable
{
char cextsym[20], extsym[20];
int address,length;
}estab[20];
struct objectcode
{
unsigned char code[15];
int add;
}obcode[500];
void main()
{
char temp[10];
FILE *fp1,*fp2,*fp3;
int i,j,x,y,pstart,exeloc,start,textloc,loc,textlen,length,location,st,s;
int n=0,num=0,inc=0,count=0,record=0,mloc[30],mlen[30];
signed long int newadd;
char operation,lbl[10],input[10],label[50][10],opr[30],ch,*add1,address[10];
fp1=fopen("INPUT.DAT","r");
fp2=fopen("ESTAB.DAT","r");
fp3=fopen("OUTPUT.DAT","w");
while(!feof(fp2))
{
fscanf(fp2,"%s %s %x %x", estab[num].cextsym, estab[num].extsym, &estab[num].address,
&estab[num].length);
num++;
}
exeloc=estab[0].address;
loc=exeloc;
start=loc;
st=start;
while(!feof(fp1))
{
fscanf(fp1,"%s",input);
if(strcmp(input,"H")==0)
{
fscanf(fp1,"%s",input);
for(i=0;i<num;i++)
if(strcmp(input,estab[i].cextsym)==0)
{
pstart=estab[i].address;
break;
}
while(strcmp(input,"T")!=0)
fscanf(fp1,"%s",input);
}
do
{
if(strcmp(input,"T")==0)
{
fscanf(fp1,"%x",&textloc);
textloc=textloc+pstart;
for(i=0;i<(textloc-loc);i++)
{
strcpy(obcode[inc].code,"..");
obcode[inc++].add=start++;
}
fscanf(fp1,"%x",&textlen);
loc=textloc+textlen;
}
else if(strcmp(input,"M")==0)
{
fscanf(fp1,"%x",&mloc[record]);
mloc[record]=mloc[record]+pstart;
fscanf(fp1,"%x",&mlen[record]);
fscanf(fp1,"%s",label[record++]);
}
else
{
length=strlen(input);
x=0;
for(i=0;i<length;i++)
{
obcode[inc].code[x++]=input[i];
if(x>1)
{
obcode[inc++].add=start++;
x=0;
}
}
}
fscanf(fp1,"%s",input);
}while(strcmp(input,"E")!=0);
if(strcmp(input,"E")==0)
fscanf(fp1,"%s",input);
}
for(n=0;n<record;n++)
{
operation=label[n][0];
length=strlen(label[n]);
for(i=1;i<length;i++)
{
lbl[i-1]=label[n][i];
}
lbl[length-1]='\0';
length=0;
strcpy(address,"\0");
location=mloc[n]-exeloc;
loc=location;
count=0;
while(length<mlen[n])
{
strcat(address,obcode[location++].code);
count++;
length+=2;
}
for(i=0;i<num;i++)
{
if(strcmp(lbl,estab[i].cextsym)==0)
break;
if(strcmp(lbl,estab[i].extsym)==0)
break;
}
switch(operation)
{
case '+':
newadd=strtol(address,&add1,16)+(long int)estab[i].address;
break;
case '-':
newadd=strtol(address,&add1,16)-(long int)estab[i].address;
break;
}
ltoa(newadd,address,16);
x=0; y=0;
while(count>0)
{
obcode[loc].code[x++]=address[y++];
if(x>1)
{
x=0; loc++;
count--;
}
}
}
count=0;
n=0;
s=st-16;
fprintf(fp3,"%x\t",s);
for(i=1;i<=16;i++)
{
fprintf(fp3,"xx");
if(i==4||i==8||i==12)
{
fprintf(fp3,"\t");
}
}
fprintf(fp3,"\n\n%x\t",obcode[0].add);
for(i=0;i<inc;i++)
{
fprintf(fp3,"%s",obcode[i].code);
n++;
if(n>3)
{
fprintf(fp3,"\t");
n=0;
count++;
}
if(count>3)
{
fprintf(fp3,"\n\n%x\t",obcode[i+1].add);
count=0;
}
}
fclose(fp1);
fclose(fp2);
fclose(fp3);
printf("\n\t***** PASS TWO OF A DIRECT-LINKING LOADER *****\n");
printf("\nThe contents of the output file :");
printf("\n---------------------------------------------------------------");
printf("\nAddress\t\t\t\tContents");
printf("\n---------------------------------------------------------------\n");
fp3=fopen("OUTPUT.DAT","r");
ch=fgetc(fp3);
while(ch!=EOF)
{
printf("%c",ch);
ch=fgetc(fp3);
}
fclose(fp3);
}
H PROGD 000000 000081
D LISTX 000050
R LISTY ENDX LISTZ ENDY
T 000024 0A 04201D 88100008 060014
T 000050 0F 110014 00000C 005051 000008 120000
M 000028 05 +LISTY
M 000050 06 +LISTZ
M 000058 06 +LISTY
M 000058 06 -LISTX
E 000024
H PROGE 000000 00009F
D LISTY 000070 ENDY 000090
R LISTX LISTZ ENDZ
T 000046 0B 04100000 882037 06100000
T 000090 0F 110000 00000C 005051 000008 120070
M 000047 05 +LISTX
M 00004E 05 -LISTX
M 000090 06 -LISTX
M 000090 06 +LISTZ
M 00009C 06 +PROGE
M 00009C 06 -LISTX
E 000000
H PROGF 000000 000067
D LISTZ 000040 ENDZ 000052
R LISTX LISTY ENDY
T 000028 0C 04100000 88100008 06100000
T 000052 0F 110040 00000C 005051 000008 120000
M 00002D 05 +LISTY
M 000031 05 -LISTX
M 000052 06 -LISTX
M 000052 06 +PROGF
M 00005E 06 +LISTY
M 00005E 06 -LISTX
E
END
ESTAB:
PROGD ** 2000 81
** LISTX 2050
PROGE ** 2081 9f
** LISTY 20f1
** ENDY 2111
PROGF ** 2120 67
** LISTZ 2160
** ENDZ 2172