TinyLinker1143111006刘家豪1.实验目的完成Linker.c文件,实现小型连接器功能,编译文件2.相关知识目标模块当编译器和汇编器处理完一个模块,它们产生的目标模块,几乎是可运行的。负载模组链接器的输出被称为负载模块,因为,相对地址搬迁和外部地址解析,该模块已准备好被加载并运行。A重新定位相对地址B在解析外部引用3实验思路使用的结构体:A提取file中的wordB读取下一行C通过两次process,对符号表和定义表进行遍历并修改,再寄地址上加偏移量,进行重定位Process_one()用来建立符号表process_two()用来重定位代码表,并修改代码的地址,以及打印错误情况替换外部符号:替换相对地址:输出当前代码段以及打印相关错误(如果存在):打印警告信息(如果有):4.实验结果测试9个输入文件输出9个output文件都满足要求:5.Linker(linker.c源码)#includestdio.h#includestdlib.h#includestring.h#includelinker.hFILE*in;//forreadmoduleFILE*out;//foroutputlinkresultstructsymbolMsg{charsym[30];intaddr;intmodule;interrorCode;}symbolTable[100];structCodeStr{chartype;intopcode;interrorCode;char*symbol;};intoffset;voidlink(inttest_num,constchar*filename){charoutputfile[100];charfile[5000];memset(outputfile,0,10);sprintf(outputfile,output-%d.txt,test_num);in=fopen(filename,r);//openfileforread,thefilecontainsmodulethatyoushoulddowithout=fopen(outputfile,w);//opentheoutputfiletooutputlinkresultif(in==NULL||out==NULL){fprintf(stderr,cannotopenfileforreadorwrite\n);exit(-1);}memset(symbolTable,0,sizeof(structsymbolMsg)*100);memset(file,0,sizeof(file));fread(file,sizeof(char),sizeof(file),in);//printf(%s,file);//return;process_one(file);process_two(file);fclose(in);fclose(out);}/*提取file中的word*/char*nextWord(char*src,char*word,intwordsize){inti=0,j=0;memset(word,0,wordsize);while(src[i]=='')i++;for(j=0;src[i+j]!=''&&src[i+j]!='\0'&&jwordsize-1;j++){if(src[i+j]=='\n'){j++;break;}word[j]=src[i+j];}returnsrc+i+j;}char*nextLine(char*start){inti=0;while(start[i]!='\n')i++;return&start[i+1];}/*youmustimplementthisfunction*/voidprocess_one(char*start){charword[20];intIndex,k;intmodule=1;char*errorMsg=NULL;Index=0;while(*start!='\0'){intnum=0;start=nextWord(start,word,sizeof(word));num=atoi(word);for(k=0;knum;k++){inti=0;start=nextWord(start,word,sizeof(word));for(i=0;iIndex&&strcmp(symbolTable[i].sym,word)!=0;i++);if(iIndex){//error:symbolismultiplydefined,printanerrormessageandusethevaluegiveninthefirstdefinition.symbolTable[i].errorCode=2;continue;}strcpy(symbolTable[Index].sym,word);start=nextWord(start,word,sizeof(word));symbolTable[Index].addr=atoi(word);symbolTable[Index++].module=module;}start=nextLine(start);start=nextWord(start,word,sizeof(word));num=atoi(word);for(k=Index-1;symbolTable[k].module==module;k--){//error:Ifanaddressappearinginadefinitionexceedsthesizeofthemodule,printanerrormessageandtreattheaddressgivenas0(relative).if(symbolTable[k].addr=num){symbolTable[k].errorCode=1;symbolTable[k].addr=0;}symbolTable[k].addr+=offset;}offset+=num;start=nextLine(start);start=nextLine(start);module++;//nextmodule}fwrite(SymbolTable\n,sizeof(char),strlen(SymbolTable\n),out);errorMsg=(char*)malloc(100);for(k=0;kIndex;k++){memset(errorMsg,0,100);if(1==symbolTable[k].errorCode){sprintf(errorMsg,Error:Thevalueof%sisoutsidemodule%d;zero(relative)used,symbolTable[k].sym,symbolTable[k].module);}elseif(2==symbolTable[k].errorCode){sprintf(errorMsg,Error:Thisvariableismultiplydefined;firstvalueused.);}//outputsymbolTable&errormsgfprintf(out,%s=%d%s\n,symbolTable[k].sym,symbolTable[k].addr,errorMsg);}free(errorMsg);fwrite(\nMemoryMap\n,sizeof(char),strlen(\nMemoryMap\n),out);fflush(out);}/*youmustimplementthisfunction*/voidprocess_two(char*start){charword[20];structCodeStr*code;char*useList;//引用列表char*errorMsg=NULL;inti=0;intmemMapNumber=0;intnum=0,codeCount;//numofcodesinamoduleintcurOffset;offset=0;while(*start!='\0'){curOffset=offset;//第一行定义列表(eg:1xy2)start=nextLine(start);//第二行引用列表useList=start;start=nextLine(start);//第三行代码段(numtypeopcodetypeopcode...)start=nextWord(start,word,sizeof(word));codeCount=atoi(word);offset+=codeCount;code=(structCodeStr*)malloc(sizeof(structCodeStr)*codeCount);for(i=0;icodeCount;i++){start=nextWord(start,word,sizeof(word));code[i].type=*word;start=nextWord(start,word,sizeof(word));code[i].opcode=atoi(word);code[i].errorCode=0;}//第四行空行start=nextLine(start);//替换外部符号useList=nextWord(useList,word,sizeof(word));num=atoi(word);for(i=0;inum;i++)//替换外部符号type='E'{intlineOffset;//外部符号在该行中的偏移量useList=nextWord(useList,word,sizeof(word));//symbol//从符号表查找相应符号以获得绝对地址for(i=0;symbolTable[i].sym[0]!='\0'&&strcmp(symbolTable[i].sym,word)!=0;i++);if(symbolTable[i].sym[0]!='\0'){symbolTable[i].addr|=(18);//标记该符号已使用///////////////////////////}useList=nextWord(useList,word,sizeof(word));//offsetlineOffset=atoi(word);//替换符号while(lineOffset!=777){inttemp;temp=code[lineOffset].opcode%1000;code[lineOffset].opcode=(code[lineOffset].opcode/1000)*1000+symbolTable[i].addr%(18);if(code[lineOffset].type!='E'){//error:IfanaddressonauselistisnottypeE,printanerrormessageandtreattheaddressastypeEcode[lineOffset].errorCode=2;}elseif(symbolTable[i].sym[0]=='\0'){//error:Ifasymbolisusedbutnotdefined,printanerrormessageandusethevaluezero.code[lineOffset].errorCode=1;}elseif(temp=num){//error:Ifanddressappearinginauselistexceedsthesizeofthemodule,printanerrormessageandtreattheaddressasthesentinelendingthelist.code[lineOffset].errorCode=4;break;}elsecode[lineOffset].errorCod