1 //////////////////////////////////////////////////////////////////////////////
2 //Copyright 2008
3 // Andrew Gacek, Steven Holte, Gopalan Nadathur, Xiaochu Qi, Zach Snow
4 //////////////////////////////////////////////////////////////////////////////
5 // This file is part of Teyjus. //
6 // //
7 // Teyjus is free software: you can redistribute it and/or modify //
8 // it under the terms of the GNU General Public License as published by //
9 // the Free Software Foundation, either version 3 of the License, or //
10 // (at your option) any later version. //
11 // //
12 // Teyjus is distributed in the hope that it will be useful, //
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of //
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
15 // GNU General Public License for more details. //
16 // //
17 // You should have received a copy of the GNU General Public License //
18 // along with Teyjus. If not, see <http://www.gnu.org/licenses/>. //
19 //////////////////////////////////////////////////////////////////////////////
20 #include <stdio.h>
21 #include <string.h>
22 #include "ld_message.h"
23 #include "file.h"
24 #include "../system/memory.h"
25 #include "../simulator/mctypes.h"
26 #include "loader.h"
27 #include "kind.h"
28 #include "tyskel.h"
29 #include "const.h"
30 #include "code.h"
31 #include "strings.h"
32 #include "hashtab.h"
33 #include "bvrtab.h"
34 #include "implgoal.h"
35 #include "importtab.h"
36
37 static char* LD_LOADER_path = "./";
LD_LOADER_setPath(char * path)38 void LD_LOADER_setPath(char* path)
39 {
40 if (path) LD_LOADER_path = path;
41 }
42
LD_LOADER_makePath(char * modname)43 char* LD_LOADER_makePath(char* modname)
44 {
45 char* buf=(char *)EM_malloc(strlen(LD_LOADER_path)+strlen(modname)+1);
46 sprintf(buf,"%s%s",LD_LOADER_path,modname);
47 return buf;
48 }
49
50
51 #define LINKCODE_EXT ".lp"
52 #define BYTECODE_EXT ".lpo"
53
54 void LD_LOADER_LoadLinkcodeVer();
55
56 void LD_LOADER_LoadModuleName(char* modname);
57 MEM_GmtEnt* LD_LOADER_GetNewGMTEnt(int index);
58 WordPtr LD_LOADER_ExtendModSpace(MEM_GmtEnt* ent, int size);
59 int LD_LOADER_SetName(MEM_GmtEnt* ent,char* modname);
60 void LD_LOADER_AddGMTEnt(MEM_GmtEnt* ent);
61 void LD_LOADER_DropGMTEnt(MEM_GmtEnt* ent);
62
63
64 int LD_verbosity = 0;
65
66 //Defines the primary procedure of the loader: the load function
67
68 //Loads the module into returns it's index in the global module table
69 //Returns -1 on failure.
LD_LOADER_Load(char * modname,int index)70 int LD_LOADER_Load(char* modname, int index)
71 {
72 MEM_GmtEnt* gmtEnt;
73
74 EM_TRY{
75 LD_FILE_Open(LD_LOADER_makePath(modname),LINKCODE_EXT);
76 LD_LOADER_LoadLinkcodeVer();
77 LD_LOADER_LoadModuleName(modname);
78 }EM_CATCH{
79 EM_THROW(LD_LoadError);
80 }
81 gmtEnt=LD_LOADER_GetNewGMTEnt(index);
82 EM_TRY{
83 LD_LOADER_SetName(gmtEnt,modname);
84 LD_CODE_LoadCodeSize(gmtEnt);
85 LD_KIND_LoadKst(gmtEnt);
86 LD_TYSKEL_LoadTst(gmtEnt);
87 LD_CONST_LoadCst(gmtEnt);
88 LD_STRING_LoadStrings(gmtEnt);
89 LD_IMPLGOAL_LoadImplGoals(gmtEnt);
90 LD_HASHTAB_LoadHashTabs(gmtEnt);
91 LD_BVRTAB_LoadBvrTabs(gmtEnt);
92 LD_IMPORTTAB_LoadImportTabs(gmtEnt);
93 LD_CODE_LoadCode(gmtEnt);
94 LD_LOADER_AddGMTEnt(gmtEnt);
95 }EM_CATCH{
96 ///\todo Clean up after failed load.
97 LD_LOADER_DropGMTEnt(gmtEnt);
98 EM_THROW(LD_LoadError);
99 }
100
101 return 0;
102 }
103
104 #define LINKCODE_VER 3
LD_LOADER_LoadLinkcodeVer()105 void LD_LOADER_LoadLinkcodeVer()
106 {
107 Word tmp=LD_FILE_GETWORD();
108 if(tmp!=LINKCODE_VER){
109 LD_error("Incompatible linkcode version %ld.\n",tmp);
110 EM_THROW(LD_LoadError);
111 }
112 }
113
114 ///\note Check Purpose of module name in file
LD_LOADER_LoadModuleName(char * modname)115 void LD_LOADER_LoadModuleName(char* modname)
116 {
117 char *buf;
118 int len=LD_FILE_GET4();
119 buf = EM_malloc(len+1);
120 LD_FILE_GetString(buf,len);
121 if(0!=strcmp(buf,modname)){
122 LD_error("Unexpected module name %s in %s%s\n",buf,modname,LINKCODE_EXT);
123 free(buf);
124 EM_THROW(LD_LoadError);
125 }
126 free(buf);
127 }
128
129 /* get a module table entry of given index from the global module tables */
130 /* the index is assumed to be calculated by the system front and passed in */
131 /* as an argument upon invoking the loader -- XQ */
LD_LOADER_GetNewGMTEnt(int index)132 MEM_GmtEnt* LD_LOADER_GetNewGMTEnt(int index)
133 {
134 MEM_GmtEnt* ent;
135 ent = &(MEM_modTable[index]);
136 ent->modSpaceEnd=ent->modSpaceBeg=MEM_memTop;
137 ent->codeSpaceEnd=ent->codeSpaceBeg=MEM_memBot;
138 return ent;
139 }
140
LD_LOADER_DropGMTEnt(MEM_GmtEnt * ent)141 void LD_LOADER_DropGMTEnt(MEM_GmtEnt* ent)
142 {
143 ent->modname=NULL;
144 }
145
146 /* finalize system memory after loading modules -- XQ */
LD_LOADER_AddGMTEnt(MEM_GmtEnt * ent)147 void LD_LOADER_AddGMTEnt(MEM_GmtEnt* ent)
148 {
149 MEM_memTop=ent->modSpaceEnd;
150 MEM_memBot=(MemPtr)ent->codeSpaceBeg;
151 }
152
153 /* Asking space of given number of WORDS from the system memory -- XQ */
LD_LOADER_ExtendModSpace(MEM_GmtEnt * ent,int size)154 WordPtr LD_LOADER_ExtendModSpace(MEM_GmtEnt* ent, int size)
155 {
156 WordPtr tmp = ent -> modSpaceEnd;
157 ent -> modSpaceEnd += size;
158 if(ent->modSpaceEnd > ent->codeSpaceBeg){
159 LD_error("Out of module space.\n");
160 EM_THROW(LD_LoadError);
161 }
162 return tmp;
163 }
164
165 /* Asking space of given number of BYTES from the system memory -- XQ */
LD_LOADER_ExtendModSpaceInByte(MEM_GmtEnt * ent,int size)166 BytePtr LD_LOADER_ExtendModSpaceInByte(MEM_GmtEnt* ent, int size)
167 {
168 BytePtr tmp = (BytePtr) (ent -> modSpaceEnd);
169 ent -> modSpaceEnd = (WordPtr)(((BytePtr)ent->modSpaceEnd) + size);
170 if (ent -> modSpaceEnd > ent->codeSpaceBeg){
171 LD_error("Out of module space.\n");
172 EM_THROW(LD_LoadError);
173 }
174 return tmp;
175 }
176
177
LD_LOADER_SetName(MEM_GmtEnt * ent,char * modname)178 int LD_LOADER_SetName(MEM_GmtEnt* ent,char* modname)
179 {
180 //char* namebuf=(char*)LD_LOADER_ExtendModSpace(ent,strlen(modname)+1);--XQ
181 char* namebuf=(char*)LD_LOADER_ExtendModSpaceInByte(ent,strlen(modname)+1);
182 strcpy(namebuf,modname);
183 ent->modname=namebuf;
184 return 0;
185 }
186