38 iMutex.lock(); |
60 iMutex.lock(); |
39 iQueueFiles.push(TPlacedEntry(fileName,isExecutable)); |
61 iQueueFiles.push(TPlacedEntry(fileName,isExecutable)); |
40 iMutex.unlock(); |
62 iMutex.unlock(); |
41 iCond.notify_all(); |
63 iCond.notify_all(); |
42 } |
64 } |
43 void SymbolGenerator::ProcessExecutable( const string& fileName ){ |
65 void SymbolGenerator::SetFinished() |
44 char str[MAX_LINE]; |
66 { |
45 string outString; |
67 |
46 outString = "\nFrom "; |
68 iFinished = true; |
47 outString += fileName + "\n\n"; |
69 iCond.notify_all(); |
48 iSymFile.write(outString.c_str(),outString.length()); |
|
49 string mapFile2 = fileName+".map"; |
|
50 size_t dot = fileName.rfind('.'); |
|
51 string mapFile = fileName.substr(0,dot)+".map"; |
|
52 ifstream fMap; |
|
53 fMap.open(mapFile2.c_str()); |
|
54 if(!fMap.is_open()) { |
|
55 fMap.open(mapFile.c_str()); |
|
56 } |
70 } |
57 |
71 TPlacedEntry SymbolGenerator::GetNextPlacedEntry() |
58 if(!fMap.is_open()) { |
72 { |
59 printf("%s\nWarning: Can't open \"%s\" or \"%s\"\n",fileName.c_str(),mapFile2.c_str(),mapFile.c_str()); |
73 TPlacedEntry pe("", false); |
60 int binSize = GetSizeFromBinFile(fileName); |
74 if(1) |
61 memset(str,0,sizeof(str)); |
75 { |
62 sprintf(str,"%04x", binSize); |
76 boost::mutex::scoped_lock lock(iMutex); |
63 outString = "00000000 "; |
77 while(!iFinished && iQueueFiles.empty()) |
64 outString += str; |
78 iCond.wait(lock); |
65 outString += " "; |
79 if(!iQueueFiles.empty()) |
66 outString += fileName.substr(fileName.rfind(PATH_SEPARATOR)+1)+"\n"; |
80 { |
67 iSymFile.write(outString.c_str(),outString.length()); |
81 pe = iQueueFiles.front(); |
68 } |
82 iQueueFiles.pop(); |
69 else { |
|
70 if(!fMap.good()) fMap.clear(); |
|
71 boost::regex regARMV5("ARMV5", boost::regex::icase); |
|
72 boost::regex regGCCEoARMV4("(GCCE|ARMV4)", boost::regex::icase); |
|
73 boost::cmatch what; |
|
74 if(regex_search(fileName, what, regARMV5)) { |
|
75 ProcessArmv5File(fileName, fMap); |
|
76 } |
|
77 else if(regex_search(fileName, what, regGCCEoARMV4)) { |
|
78 ProcessGcceOrArm4File(fileName, fMap); |
|
79 } |
|
80 else { |
|
81 printf("\nWarning: cannot determine linker type used to create %s\n",fileName.c_str()); |
|
82 outString = "00000000 0000 "; |
|
83 outString += fileName.substr(fileName.rfind(PATH_SEPARATOR)+1)+"\n"; |
|
84 iSymFile.write(outString.c_str(),outString.length()); |
|
85 } |
83 } |
86 } |
84 } |
|
85 return pe; |
87 } |
86 } |
88 void SymbolGenerator::ProcessDatafile( const string& fileName ){ |
87 void SymbolGenerator::thrd_func(){ |
89 string line = "\nFrom "+fileName+"\n\n00000000 0000 "+fileName.substr(fileName.rfind(PATH_SEPARATOR)+1)+"\n"; |
88 boost::thread_group threads; |
90 iSymFile.write(line.c_str(),line.length()); |
89 SymbolWorker worker; |
91 } |
90 for(int i=0; i < gThreadNum; i++) |
92 void SymbolGenerator::ProcessArmv5File( const string& fileName, ifstream& aMap ){ |
91 { |
93 aMap.seekg (0, ios::beg); |
92 threads.create_thread(worker); |
94 char str[MAX_LINE]; |
|
95 string outString; |
|
96 aMap.getline(str,MAX_LINE); |
|
97 boost::cmatch what; |
|
98 boost::regex reg("^ARM Linker"); |
|
99 if(!regex_search(str, what, reg)) { |
|
100 printf("\nWarning: expecting %s to be generated by ARM linker\n", fileName.c_str()); |
|
101 outString = "00000000 0000 "+fileName.substr(fileName.rfind(PATH_SEPARATOR)+1)+"\n"; |
|
102 iSymFile.write(outString.c_str(),outString.length()); |
|
103 } |
93 } |
104 reg.assign("Global Symbols"); |
94 threads.join_all(); |
105 while(aMap.getline(str,MAX_LINE)) { |
|
106 if(regex_search(str, what, reg)) { |
|
107 break; |
|
108 } |
95 } |
|
96 SymbolGenerator::SymbolGenerator() : boost::thread(thrd_func),iFinished(false) { |
109 } |
97 } |
110 |
98 SymbolGenerator::~SymbolGenerator(){ |
111 reg.assign("^\\s*(.+)\\s*0x(\\S+)\\s+[^\\d]*(\\d+)\\s+(.*)$"); |
99 if(joinable()) |
112 string sSym,sTmp,sSection; |
100 join(); |
113 unsigned int addr,size,baseOffset = 0; |
101 iSymFile.flush(); |
114 map<unsigned int,string> syms; |
102 iSymFile.close(); |
115 char symString[MAX_LINE]; |
|
116 while(aMap.getline(str,MAX_LINE)) { |
|
117 if(regex_search(str, what, reg)) { |
|
118 sSym.assign(what[1].first,what[1].second-what[1].first); |
|
119 sTmp.assign(what[2].first,what[2].second-what[2].first); |
|
120 addr = strtol(sTmp.c_str(), NULL, 16); |
|
121 sTmp.assign(what[3].first,what[3].second-what[3].first); |
|
122 size = strtol(sTmp.c_str(), NULL, 10); |
|
123 sSection.assign(what[4].first,what[4].second-what[4].first); |
|
124 if(sSection.find("(StubCode)") != string::npos) |
|
125 size = 8; |
|
126 if(addr > 0) { |
|
127 memset(symString,0,sizeof(symString)); |
|
128 sprintf(symString,"%04x ",size); |
|
129 outString = symString; |
|
130 outString += sSym+" "; |
|
131 outString += sSection; |
|
132 if(baseOffset == 0) |
|
133 baseOffset = addr; |
|
134 unsigned int k = addr - baseOffset; |
|
135 if( (syms.find(k) == syms.end()) || size != 0) |
|
136 syms[k] = outString; |
|
137 } |
103 } |
138 // end of addr>0 |
104 SymbolWorker::SymbolWorker() |
139 } |
105 { |
140 // end of regex_search |
106 // end of regex_search |
141 } |
107 } |
|
108 SymbolWorker::~SymbolWorker() |
|
109 { |
|
110 } |
|
111 void SymbolWorker::operator()() |
|
112 { |
|
113 SymbolProcessUnit* aSymbolProcessUnit = new CommenSymbolProcessUnit(); |
|
114 SymbolGenerator* symbolgenerator = SymbolGenerator::GetInstance(); |
142 |
115 |
143 map<unsigned int,string>::iterator it; |
116 while(1) |
144 for(it = syms.begin(); it != syms.end(); it++) { |
117 { |
145 memset(str,0,sizeof(str)); |
118 if(symbolgenerator->HasFinished() && symbolgenerator->IsEmpty()) |
146 sprintf(str,"%08x",it->first); |
119 { |
147 outString = str; |
|
148 outString += " "; |
|
149 outString += it->second+"\n"; |
|
150 iSymFile.write(outString.c_str(),outString.length()); |
|
151 } |
|
152 } |
|
153 void SymbolGenerator::ProcessGcceOrArm4File( const string& fileName, ifstream& aMap ){ |
|
154 aMap.seekg (0, ios_base::beg); |
|
155 char str[MAX_LINE]; |
|
156 aMap.getline(str,MAX_LINE); |
|
157 boost::cmatch what; |
|
158 boost::regex reg("^\\.text\\s+"); |
|
159 while(aMap.getline(str,MAX_LINE)) { |
|
160 if(regex_search(str, what, reg)) { |
|
161 break; |
|
162 } |
|
163 } |
|
164 |
120 |
165 reg.assign("^\\.text\\s+(\\w+)\\s+\\w+"); |
121 break; |
166 if(!regex_search(str, what, reg)) { |
122 } |
167 printf("ERROR: Can't get .text section info for \"%s\"\n",fileName.c_str()); |
|
168 } |
|
169 else { |
|
170 string sTmp, sLibFile; |
|
171 sTmp.assign(what[1].first,what[1].second-what[1].first); |
|
172 unsigned int imgText = strtol(sTmp.c_str(), NULL, 16); |
|
173 |
123 |
174 reg.assign("^LONG 0x.*", boost::regex::icase); |
|
175 boost::cmatch what1; |
|
176 boost::regex reg1("^\\s(\\.text)?\\s+(0x\\w+)\\s+(0x\\w+)\\s+(.*)$", boost::regex::icase); |
|
177 boost::regex reg2("^\\s+(\\w+)\\s\\s+([a-zA-Z_].+)", boost::regex::icase); |
|
178 boost::regex reg3(".*lib\\(.*d\\d*s_?\\d{5}.o\\)$", boost::regex::icase); |
|
179 |
124 |
180 map<unsigned int,string> syms; |
|
181 unsigned int addr, len, stubhex; |
|
182 |
125 |
183 while(aMap.getline(str,MAX_LINE)) { |
|
184 if(strlen(str) == 0) |
|
185 break; |
|
186 else if(regex_search(str, what, reg1)) { |
|
187 sLibFile.assign(what[4].first,what[4].second-what[4].first); |
|
188 if(!regex_search(sLibFile, what1, reg)) { |
|
189 sTmp.assign(what[2].first,what[2].second-what[2].first); |
|
190 addr = strtol(sTmp.c_str(), NULL, 16); |
|
191 sTmp.assign(what[3].first,what[3].second-what[3].first); |
|
192 len = strtol(sTmp.c_str(), NULL, 16); |
|
193 syms[addr+len] = ""; |
|
194 if(regex_search(sLibFile, what, reg3)) { |
|
195 stubhex = addr; |
|
196 } |
|
197 } |
|
198 } |
|
199 else if(regex_search(str, what, reg2)) { |
|
200 sTmp.assign(what[1].first,what[1].second-what[1].first); |
|
201 addr = strtol(sTmp.c_str(), NULL, 16); |
|
202 sTmp.assign(what[2].first,what[2].second-what[2].first); |
|
203 syms[addr] = (addr == stubhex)? ("stub "+sTmp) : sTmp; |
|
204 } |
|
205 } |
|
206 |
126 |
207 map<unsigned int,string>::iterator it = syms.begin(); |
127 TPlacedEntry pe = symbolgenerator->GetNextPlacedEntry(); |
208 map<unsigned int,string>::iterator itp = it++; |
|
209 string outString; |
|
210 for(; it != syms.end(); itp = it++) { |
|
211 if(itp->second != "") { |
|
212 memset(str,0,sizeof(str)); |
|
213 sprintf(str,"%08x %04x ",(itp->first-imgText), (it->first-itp->first)); |
|
214 outString = str; |
|
215 outString += it->second+"\n"; |
|
216 iSymFile.write(outString.c_str(),outString.length()); |
|
217 } |
|
218 } |
|
219 } |
|
220 } |
|
221 int SymbolGenerator::GetSizeFromBinFile( const string& fileName ){ |
|
222 TInt ret = 0; |
|
223 ifstream aIf(fileName.c_str(), ios_base::binary); |
|
224 if( !aIf.is_open() ) { |
|
225 printf("Warning: Cannot open file \n"); |
|
226 } |
|
227 else { |
|
228 E32ImageFile e32Image; |
|
229 TUint32 aSz; |
|
230 |
128 |
231 aIf.seekg(0,ios_base::end); |
|
232 aSz = aIf.tellg(); |
|
233 |
|
234 e32Image.Adjust(aSz); |
|
235 e32Image.iFileSize = aSz; |
|
236 |
|
237 aIf.seekg(0,ios_base::beg); |
|
238 aIf >> e32Image; |
|
239 ret = e32Image.iOrigHdr->iCodeSize; |
|
240 } |
|
241 return ret; |
|
242 } |
|
243 void SymbolGenerator::thrd_func(){ |
|
244 SymbolGenerator* me = GetInstance(); |
|
245 |
|
246 TPlacedEntry pe("",false); |
|
247 while(1) { |
|
248 if(1) { |
|
249 //scope the code block with if(1) for lock |
129 //scope the code block with if(1) for lock |
250 boost::mutex::scoped_lock lock(me->iMutex); |
|
251 while(me->iQueueFiles.empty()) |
|
252 me->iCond.wait(lock); |
|
253 /* |
130 /* |
254 if(me->iQueueFiles.empty()) { |
131 if(me->iQueueFiles.empty()) { |
255 boost::this_thread::sleep(boost::posix_time::milliseconds(10)); |
132 boost::this_thread::sleep(boost::posix_time::milliseconds(10)); |
256 continue; |
133 continue; |
257 } |
134 } |
258 */ |
135 */ |
259 |
136 |
260 pe = me->iQueueFiles.front(); |
|
261 me->iQueueFiles.pop(); |
|
262 } |
|
263 |
137 |
264 if(pe.iFileName == "") |
138 if(pe.iFileName == "") |
265 break; |
139 continue; |
266 else if(pe.iExecutable) |
140 else if(pe.iExecutable) |
267 me->ProcessExecutable(pe.iFileName); |
141 aSymbolProcessUnit->ProcessExecutableFile(pe.iFileName); |
268 else |
142 else |
269 me->ProcessDatafile(pe.iFileName); |
143 aSymbolProcessUnit->ProcessDataFile(pe.iFileName); |
270 } |
144 symbolgenerator->LockOutput(); |
|
145 aSymbolProcessUnit->FlushStdOut(cout); |
|
146 aSymbolProcessUnit->FlushSymbolContent(symbolgenerator->GetOutputFileStream()); |
|
147 symbolgenerator->UnlockOutput(); |
271 } |
148 } |
272 SymbolGenerator::SymbolGenerator() : boost::thread(thrd_func) { |
149 delete aSymbolProcessUnit; |
273 } |
150 } |
274 SymbolGenerator::~SymbolGenerator(){ |
|
275 if(joinable()) |
|
276 join(); |
|
277 iSymFile.flush(); |
|
278 iSymFile.close(); |
|
279 } |
|