i) Introduction:
Purpose of Two-Pass Linking Loader: Combines multiple object modules and resolves external references.
Function of Pass 1:
Establishes memory layout by processing external symbols and definitions.
Ensures modules are linked without overlapping memory addresses.
Key Output: Generates an external symbol table (ESTAB) mapping symbols to tentative addresses.
Objective: Prepares for actual address resolution and linking in Pass 2.
ii) Problem Description:
Primary Goal:
Scans input object modules to populate ESTAB.
Records control sections and external symbols with their names, addresses, and lengths.
Error Detection: Identifies and flags issues like duplicate symbol definitions.
Symbol References: Records unresolved external symbol references for resolution in Pass 2.
Outcome: Creates a foundation for accurate address resolution and linking in the subsequent pass.
Pass 1 of two pass linking loader:
Code
Pass 1 of two pass linking loader:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_SYMBOLS 100
#define MAX_NAME_LENGTH 20
#define MAX_REFERENCES 100
typedef struct
{
char name[MAX_NAME_LENGTH];
int address;
int length;
} ESTABEntry;
typedef struct
{
char name[MAX_NAME_LENGTH];
char cname[MAX_NAME_LENGTH];
int resolvedAddress;
} ReferenceEntry;
ESTABEntry ESTAB[MAX_SYMBOLS];
ReferenceEntry references[MAX_REFERENCES];
int estabCount = 0;
int referenceCount = 0;
int PROGADDR = 0;
int CSADDR = 0;
// Function to search ESTAB for a given name
int searchESTAB(const char *name)
{
for (int i = 0; i < estabCount; i++)
{
if (strcmp(ESTAB[i].name, name) == 0)
{
return i;
}
}
return -1;
}
// Function to add an entry to ESTAB
void addToESTAB(const char *name, int address, int length)
{
strcpy(ESTAB[estabCount].name, name);
ESTAB[estabCount].address = address;
ESTAB[estabCount].length = length;
estabCount++;
}
void addReference(const char *name, const char *cname)
{
strcpy(references[referenceCount].name, name);
strcpy(references[referenceCount].cname, cname);
references[referenceCount].resolvedAddress = -1;
referenceCount++;
}
int main()
{
char line[100];
FILE *inputFile = fopen("MDLL_input.txt", "r");
FILE *outputFile = fopen("MDESTAB.txt", "w");
if (!inputFile || !outputFile)
{
printf("Error opening file.\n");
return 1;
}
PROGADDR = 0x7000;
CSADDR = PROGADDR;
printf("\n******* Control Sections and References *******\n");
while (fgets(line, sizeof(line), inputFile))
{
if (line[0] == 'H')
{
char controlSectionName[MAX_NAME_LENGTH];
int CSLTH;
sscanf(line, "H%6s%*6x%6x", controlSectionName, &CSLTH);
if (searchESTAB(controlSectionName) != -1)
{
printf("Error: Duplicate external symbol '%s'.\n", controlSectionName);
continue;
}
// Add control section to ESTAB
addToESTAB(controlSectionName, CSADDR, CSLTH);
printf("\nControl Section: %s\n", controlSectionName);
while (fgets(line, sizeof(line), inputFile) && line[0] != 'E')
{
if (line[0] == 'D') // Define record
{
char symbolName[MAX_NAME_LENGTH];
int symbolAddress, offset = 1;
while (sscanf(&line[offset], "%6s%6x", symbolName, &symbolAddress) == 2)
{
offset += 12;
if (searchESTAB(symbolName) != -1)
{
printf("Error: Duplicate external symbol '%s'.\n", symbolName);
}
else
{
addToESTAB(symbolName, CSADDR + symbolAddress, 0);
}
}
}
else if (line[0] == 'R') // Reference record
{
char symbolName[MAX_NAME_LENGTH];
int offset = 1;
printf("References:\n");
while (sscanf(&line[offset], "%6s", symbolName) == 1)
{
offset += 6;
addReference(symbolName, controlSectionName);
printf(" %s\n", symbolName);
}
}
}
CSADDR += CSLTH;
}
}
for (int i = 0; i < referenceCount; i++)
{
int idx = searchESTAB(references[i].name);
if (idx != -1)
{
references[i].resolvedAddress = ESTAB[idx].address;
}
}
printf("******* ESTAB Entries *******\n");
printf("CSection SName\tAddress\tLength\n");
for (int i = 0; i < estabCount; i++)
{
if (ESTAB[i].length > 0)
{
fprintf(outputFile, "%s\t\t%04X\t%04X\n", ESTAB[i].name, ESTAB[i].address, ESTAB[i].length);
printf("%s\t\t%04X\t%04X\n", ESTAB[i].name, ESTAB[i].address, ESTAB[i].length);
}
else
{
fprintf(outputFile, "\t%s\t%04X\n", ESTAB[i].name, ESTAB[i].address);
printf("\t%s\t%04X\n", ESTAB[i].name, ESTAB[i].address);
}
}
printf("\n******* Resolved References Grouped by Control Section *******\n");
for (int i = 0; i < estabCount; i++)
{
if (ESTAB[i].length > 0)
{
printf("\nControl Section: %s\n", ESTAB[i].name);
printf("Symbol\t\tAddress\n");
for (int j = 0; j < referenceCount; j++)
{
if (references[j].resolvedAddress != -1 && (strcmp(ESTAB[i].name, references[j].cname) == 0))
{
printf("%s\t\t%04X\n", references[j].name, references[j].resolvedAddress);
}
/* else
{
printf("%s\t\tUNDEFINED\n", references[j].name);
}*/
}
}
}
fclose(inputFile);
fclose(outputFile);
return 0;
}