1) Resolve external symbol definitions and references between object modules.
2) Allocate memory and calculate starting addresses for each object module.
3) Process relocation records to identify addresses that need to be adjusted.
4) Validate external symbols to check for undefined or duplicate definitions.
5) Prepare data structures to enable efficient loading and linking of object code in Pass 2.
The primary data structure used in the first pass of a linking loader is the External Symbol Table (ESTAB). This table stores the names and addresses of all external symbols in the control sections being loaded. The ESTAB is typically organized as a hash table to allow for efficient lookups and storage of external symbol information.
begin
get PROOADDR from operating system
set CSADDR to PROOADDR {for first control section}
while not end of input do
begin
read next input record {Header record for control section}
set CSLTH to control section length
search ESTAB for control section name
if found then
set error flag {duplicate external symbol}
else
enter control section name into ESTAB with value CSADDR
while record type ~ 'E' do
begin
read next input record
if record type = 'D' then
for each symbol in the record do
begin
search ESTAB for symbol name
if found then
set error flag (duplicate external symbol)
else
enter symbol into ESTAB with value(CSADDR + indicated address)
end {for}
end {while ~ 'E'}
add CSLTH to CSADDR {starting address for next control section}
end {while not EOF}
end {Pass 1}
#include<stdio.h>
#include<string.h>
struct estab
{
Β Β char csname[10];
Β Β char extsym[10];
Β Β int address;
Β Β int length;
}es[20];
void main()
{
char input[10],name[10],symbol[10],ch;Β int count=0,progaddr,csaddr,add,len;
FILE *fp1,*fp2;
fp1=fopen("INPUT.DAT","r");
fp2=fopen("ESTAB.DAT","w");
printf("\n\nEnter the address where the program has to be loaded : ");
scanf("%x",&progaddr); // TAKING THE PROGRAM ADDRESS FROM THE USER,GENERALLY IT IS DONE BY THE OS
csaddr=progaddr;
fscanf(fp1,"%s",input);
while(strcmp(input,"END")!=0)
{
if(strcmp(input,"H")==0)
{
fscanf(fp1,"%s",name);
strcpy(es[count].csname,name);
strcpy(es[count].extsym,"Β ");
fscanf(fp1,"%x",&add);
es[count].address=add+csaddr;
fscanf(fp1,"%x",&len);
es[count].length=len;
fprintf(fp2,"%s ** %x %x\n",es[count].csname,es[count].address,es[count].length);
count++;
}
else if(strcmp(input,"D")==0)
{
fscanf(fp1,"%s",input);
while(strcmp(input,"R")!=0)
{
strcpy(es[count].csname,"Β ");
strcpy(es[count].extsym,input);
fscanf(fp1,"%x",&add);
es[count].address=add+csaddr;
es[count].length=0;
fprintf(fp2,"** %s %x\n",es[count].extsym,es[count].address);
count++;
fscanf(fp1,"%s",input);
}
csaddr=csaddr+len;
}
else if(strcmp(input,"T")==0)
{
while(strcmp(input,"E")!=0)
fscanf(fp1,"%s",input);
}
fscanf(fp1,"%s",input);
}
Β Β fclose(fp1);
Β Β fclose(fp2);
Β Β fp2=fopen("ESTAB.DAT","r");
Β Β ch=fgetc(fp2);
Β Β while(ch!=EOF)
Β Β {
Β Β Β printf("%c",ch);
Β Β Β ch=fgetc(fp2);
Β Β }
Β Β fclose(fp2);
}
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