OSDN Git Service

Add toppers-jsp/ in nxtOSEK_v205b0.zip. They are licensed under TOPPERS license.
[nxt-jsp/etrobo-atk.git] / nxtOSEK / toppers_jsp / cfg / base / fc_binutils.cpp
1 /*
2  *  TOPPERS/JSP Kernel
3  *      Toyohashi Open Platform for Embedded Real-Time Systems/
4  *      Just Standard Profile Kernel
5  * 
6  *  Copyright (C) 2003 by Embedded and Real-Time Systems Laboratory
7  *                              Toyohashi Univ. of Technology, JAPAN
8  * 
9  *  ¾åµ­Ãøºî¸¢¼Ô¤Ï¡¤°Ê²¼¤Î (1)¡Á(4) ¤Î¾ò·ï¤«¡¤Free Software Foundation 
10  *  ¤Ë¤è¤Ã¤Æ¸øɽ¤µ¤ì¤Æ¤¤¤ë GNU General Public License ¤Î Version 2 ¤Ëµ­
11  *  ½Ò¤µ¤ì¤Æ¤¤¤ë¾ò·ï¤òËþ¤¿¤¹¾ì¹ç¤Ë¸Â¤ê¡¤ËÜ¥½¥Õ¥È¥¦¥§¥¢¡ÊËÜ¥½¥Õ¥È¥¦¥§¥¢
12  *  ¤ò²þÊѤ·¤¿¤â¤Î¤ò´Þ¤à¡¥°Ê²¼Æ±¤¸¡Ë¤ò»ÈÍÑ¡¦Ê£À½¡¦²þÊÑ¡¦ºÆÇÛÉۡʰʲ¼¡¤
13  *  ÍøÍѤȸƤ֡ˤ¹¤ë¤³¤È¤ò̵½þ¤ÇµöÂú¤¹¤ë¡¥
14  *  (1) ËÜ¥½¥Õ¥È¥¦¥§¥¢¤ò¥½¡¼¥¹¥³¡¼¥É¤Î·Á¤ÇÍøÍѤ¹¤ë¾ì¹ç¤Ë¤Ï¡¤¾åµ­¤ÎÃøºî
15  *      ¸¢É½¼¨¡¤¤³¤ÎÍøÍѾò·ï¤ª¤è¤Ó²¼µ­¤Î̵Êݾڵ¬Ä꤬¡¤¤½¤Î¤Þ¤Þ¤Î·Á¤Ç¥½¡¼
16  *      ¥¹¥³¡¼¥ÉÃæ¤Ë´Þ¤Þ¤ì¤Æ¤¤¤ë¤³¤È¡¥
17  *  (2) ËÜ¥½¥Õ¥È¥¦¥§¥¢¤ò¡¤¥é¥¤¥Ö¥é¥ê·Á¼°¤Ê¤É¡¤Â¾¤Î¥½¥Õ¥È¥¦¥§¥¢³«È¯¤Ë»È
18  *      ÍѤǤ­¤ë·Á¤ÇºÆÇÛÉÛ¤¹¤ë¾ì¹ç¤Ë¤Ï¡¤ºÆÇÛÉÛ¤Ëȼ¤¦¥É¥­¥å¥á¥ó¥È¡ÊÍøÍÑ
19  *      ¼Ô¥Þ¥Ë¥å¥¢¥ë¤Ê¤É¡Ë¤Ë¡¤¾åµ­¤ÎÃøºî¸¢É½¼¨¡¤¤³¤ÎÍøÍѾò·ï¤ª¤è¤Ó²¼µ­
20  *      ¤Î̵Êݾڵ¬Äê¤ò·ÇºÜ¤¹¤ë¤³¤È¡¥
21  *  (3) ËÜ¥½¥Õ¥È¥¦¥§¥¢¤ò¡¤µ¡´ï¤ËÁȤ߹þ¤à¤Ê¤É¡¤Â¾¤Î¥½¥Õ¥È¥¦¥§¥¢³«È¯¤Ë»È
22  *      ÍѤǤ­¤Ê¤¤·Á¤ÇºÆÇÛÉÛ¤¹¤ë¾ì¹ç¤Ë¤Ï¡¤¼¡¤Î¤¤¤º¤ì¤«¤Î¾ò·ï¤òËþ¤¿¤¹¤³
23  *      ¤È¡¥
24  *    (a) ºÆÇÛÉÛ¤Ëȼ¤¦¥É¥­¥å¥á¥ó¥È¡ÊÍøÍѼԥޥ˥奢¥ë¤Ê¤É¡Ë¤Ë¡¤¾åµ­¤ÎÃø
25  *        ºî¸¢É½¼¨¡¤¤³¤ÎÍøÍѾò·ï¤ª¤è¤Ó²¼µ­¤Î̵Êݾڵ¬Äê¤ò·ÇºÜ¤¹¤ë¤³¤È¡¥
26  *    (b) ºÆÇÛÉۤηÁÂÖ¤ò¡¤Ê̤ËÄê¤á¤ëÊýË¡¤Ë¤è¤Ã¤Æ¡¤TOPPERS¥×¥í¥¸¥§¥¯¥È¤Ë
27  *        Êó¹ð¤¹¤ë¤³¤È¡¥
28  *  (4) ËÜ¥½¥Õ¥È¥¦¥§¥¢¤ÎÍøÍѤˤè¤êľÀÜŪ¤Þ¤¿¤Ï´ÖÀÜŪ¤ËÀ¸¤¸¤ë¤¤¤«¤Ê¤ë»
29  *      ³²¤«¤é¤â¡¤¾åµ­Ãøºî¸¢¼Ô¤ª¤è¤ÓTOPPERS¥×¥í¥¸¥§¥¯¥È¤òÌÈÀÕ¤¹¤ë¤³¤È¡¥
30  * 
31  *  ËÜ¥½¥Õ¥È¥¦¥§¥¢¤Ï¡¤ÌµÊݾڤÇÄ󶡤µ¤ì¤Æ¤¤¤ë¤â¤Î¤Ç¤¢¤ë¡¥¾åµ­Ãøºî¸¢¼Ô¤ª
32  *  ¤è¤ÓTOPPERS¥×¥í¥¸¥§¥¯¥È¤Ï¡¤ËÜ¥½¥Õ¥È¥¦¥§¥¢¤Ë´Ø¤·¤Æ¡¤¤½¤ÎŬÍѲÄǽÀ­¤â
33  *  ´Þ¤á¤Æ¡¤¤¤¤«¤Ê¤ëÊݾڤâ¹Ô¤ï¤Ê¤¤¡¥¤Þ¤¿¡¤ËÜ¥½¥Õ¥È¥¦¥§¥¢¤ÎÍøÍѤˤè¤êľ
34  *  ÀÜŪ¤Þ¤¿¤Ï´ÖÀÜŪ¤ËÀ¸¤¸¤¿¤¤¤«¤Ê¤ë»³²¤Ë´Ø¤·¤Æ¤â¡¤¤½¤ÎÀÕǤ¤òÉé¤ï¤Ê¤¤¡¥
35  * 
36  *  @(#) $Id: fc_binutils.cpp,v 1.21 2004/09/04 15:50:13 honda Exp $
37  */
38
39 #if defined(FILECONTAINER_BINUTILS) || defined(TESTSUITE)
40
41 #ifdef _MSC_VER
42 #pragma warning(disable:4786) //¥Ç¥Ð¥Ã¥°Ê¸»úÎó¤ò255ʸ»ú¤ËÀÚ¤êµÍ¤á¤¿
43 #endif
44
45 #include "base/filecontainer.h"
46 #include <string>
47 #include <map>
48 #include <fstream>
49 #include <cassert>
50 #include <cctype>
51 #include <cstdio>
52 #include <cstdlib>
53
54 #define _isspace(x)  isspace(x)
55 #define _isprint(x)  isprint(x)
56
57 #define SIZE_LOADPAGE 65536         //¥Ð¥¤¥Ê¥ê¥Ç¡¼¥¿¤ò³ÊǼ¤¹¤ë¥Ú¡¼¥¸Ã±°Ì
58
59 #define SIZE_TO_CONFIRM_BINARYFILE 128  //¥Õ¥¡¥¤¥ë¤¬¥Ð¥¤¥Ê¥ê¤ò´Þ¤à¤«¤É¤¦¤«¤ò³Îǧ¤¹¤ë¤Î¤ËÆɤ߽Ф¹¥Ç¡¼¥¿¤ÎŤµ (¥Ð¥Ã¥Õ¥¡¤ò¼è¤ë¤Î¤Ç¤¢¤Þ¤êÂ礭¤¯¤·¤Ê¤¤¤³¤È)
60
61 #define MAGIC_SYMBOL "_checker_magic_number"
62 #define MAGIC_NUMBER 0x01234567                         //4¥Ð¥¤¥È¤ÎÀ°¿ô
63
64 #define CMD_GNUNM      "nm"
65 #define CMD_GNUOBJCOPY "objcopy"
66
67 #define MAKE_BASEADDRESS(x)   ((x) & ~(SIZE_LOADPAGE-1))
68 #define MAKE_OFFSETADDRESS(x) ((x) &  (SIZE_LOADPAGE-1))
69
70 using namespace std;
71
72 namespace {
73
74     class FileContainerBinutilsImpl : public FileContainer
75     {
76     public:
77         typedef void (interceptor_func_t)(fstream &, const string &);      //ÉÔ°Õ¤Ëˬ¤ì¤¿¥Ð¥¤¥Ê¥ê¥Õ¥¡¥¤¥ë¤Î½±·â¤ËÂбþ¤¹¤ë´Ø¿ô¤Î·¿
78
79     protected:
80         string                 symbol_prefix;
81         map<string, address_t> symbol_table;
82         map<address_t, char *> contents;
83
84         address_t last_address;     //¥­¥ã¥Ã¥·¥å¤â¤É¤­
85         char *    last_page;
86
87             //¥Ç¡¼¥¿¼è¤ê¹þ¤ß
88         void loadSymbols(fstream & file)  throw(Exception);
89         void loadDataContents(fstream & file) throw(Exception);
90
91             //contents¤Ø1¥Ð¥¤¥È½ñ¤­¹þ¤ß
92         void writeByte(address_t address, unsigned int) throw(Exception);
93
94             //¼«Æ°½èÍý
95         void searchSymbolPrefix(void) throw();
96         void searchByteOrder(void)    throw();
97
98     public:
99         FileContainerBinutilsImpl(void) throw();
100         virtual ~FileContainerBinutilsImpl(void) throw();
101
102             /* ¥¤¥ó¥¿¥Õ¥§¡¼¥¹Éô */
103         virtual void        attachModule(const string & filename) throw(Exception);
104         virtual void        loadContents(void * dest, address_t address, size_t size) throw(Exception);
105         virtual address_t   getSymbolAddress(const string & symbol) throw(Exception);
106         virtual std::string getArchitecture(void) throw();
107
108         TESTSUITE_PROTOTYPE(main)
109     };
110
111     namespace {
112         FileContainerBinutilsImpl instance_of_FileContainerBinutilsImpl;
113     }
114
115         /* ¥³¥ó¥¹¥È¥é¥¯¥¿ */
116     FileContainerBinutilsImpl::FileContainerBinutilsImpl(void) throw()
117         : symbol_prefix(""), symbol_table(), contents(), last_address(0), last_page(0)
118     {}
119
120         /* ¥Ç¥¹¥È¥é¥¯¥¿ : ¥Ç¡¼¥¿¥Ð¥Ã¥Õ¥¡¤Î²òÊü */
121     FileContainerBinutilsImpl::~FileContainerBinutilsImpl(void) throw()
122     {
123         map<address_t, char *>::iterator scope;
124
125         scope = contents.begin();
126         while(scope != contents.end()) {
127             delete [] scope->second;
128             ++ scope;
129         }
130         symbol_table.clear();
131         contents.clear();
132     }
133
134         /* ¥Õ¥¡¥¤¥ë̾¤ò¥«¥ó¥Þ¤ÇÆó¤Ä¤Ëʬ¤±¤ë */
135     void splitFilename(const string & src, string & first, string & second) throw(Exception)
136     {
137         if(!src.empty()) {
138             string::size_type pos;
139
140             pos = src.find_first_of(',');
141             if(pos != string::npos) {
142                 first  = src.substr(0, pos);
143                 second = src.substr(pos + 1);
144             }
145             else {
146                     //¥Õ¥¡¥¤¥ë̾¤¬°ì¤Ä¤·¤«»ØÄꤵ¤ì¤Æ¤¤¤Ê¤¤
147                 first  = src;
148                 second = src;
149             }
150         }
151         else
152             ExceptionMessage("[FCBI] Empty filename could not be accepted.","[FCBI] ¥Õ¥¡¥¤¥ë̾¤¬¤¢¤ê¤Þ¤»¤ó").throwException();
153     }
154
155         /* ¥Õ¥¡¥¤¥ë¤¬¥Ð¥¤¥Ê¥ê¥Ç¡¼¥¿¤ò»ý¤Ã¤Æ¤¤¤ë¤«¤É¤¦¤«¤òȽÄê */
156     bool hasBinaryContents(fstream & file) throw()
157     {
158         assert(file.is_open());
159
160         bool        result = false;
161         char        buffer[SIZE_TO_CONFIRM_BINARYFILE];
162         streamsize  length;
163
164         file.read(buffer, SIZE_TO_CONFIRM_BINARYFILE);
165         length = file.gcount();
166
167         for(streamsize i = 0; i < length; ++ i) {
168             if(buffer[i] < 0 || !(_isprint(buffer[i]) || _isspace(buffer[i]))){
169                 result = true;
170                 break;
171             }
172         }
173
174                 if(!result) {
175                 file.clear();
176             file.seekg(0, ios::beg);    //ÀèƬ¤ËÌᤷ¤Æ¤ª¤¯
177                 }
178
179         return result;
180     }
181
182         /* ¥Æ¥­¥¹¥È¥Õ¥¡¥¤¥ë¤ò³«¤¯ (¥Ð¥¤¥Ê¥ê¤À¤Ã¤¿¾ì¹ç¤Ë¤ÏÂнè) */
183     void openTextFile(fstream & file, const string & filename, FileContainerBinutilsImpl::interceptor_func_t * interceptor) throw(Exception)
184     {
185         assert(!filename.empty());
186         assert(!file.is_open());
187
188         file.open(filename.c_str(), ios::in|ios::binary);
189         if(!file.is_open()) {
190             ExceptionMessage("File '%' could not be opened.","¥Õ¥¡¥¤¥ë '%' ¤Ï³«¤±¤Þ¤»¤ó") << filename << throwException;
191             return;
192         }
193
194             /* ¥Ð¥¤¥Ê¥ê¥Õ¥¡¥¤¥ë¤À¤Ã¤¿¤é... */
195         while(hasBinaryContents(file)) {
196             file.close();
197             
198             if(interceptor != 0) {
199                 (*interceptor)(file, filename);
200                 interceptor = 0;    //Âнè¤Ï°ì²ó¤Î¤ß
201             }
202
203             if(!file.is_open()) {
204                 break;
205             }
206         }
207
208             /* ¥Õ¥¡¥¤¥ë¤¬³«¤±¤Ê¤«¤Ã¤¿¤éÎã³° */
209         if(!file.is_open())
210             ExceptionMessage("Program failed to convert the binary '%' into suitable style. Please specify a suitable TEXT file.",
211                             "¥×¥í¥°¥é¥à¤Ï¥Ð¥¤¥Ê¥ê¥Õ¥¡¥¤¥ë'%'¤ÎÊÑ´¹¤Ë¼ºÇÔ¤·¤Þ¤·¤¿¡£Àµ¤·¤¤¥Æ¥­¥¹¥È¥Õ¥¡¥¤¥ë¤ò»ØÄꤷľ¤·¤Æ¤¯¤À¤µ¤¤¡£")
212                                 << filename << throwException;
213     }
214
215         /* °ì»þŪ¤Ê¥Õ¥¡¥¤¥ë̾¤ÎÀ¸À® */
216     const char * makeTemporaryFilename(void) throw()
217     {
218         static char filename[10];
219
220         sprintf(filename, "cfg%06x", (int)(rand() & 0xffffffl));
221
222         return filename;
223     }
224
225
226         /* ¥Ð¥¤¥Ê¥ê¤òGNU-NM¤ò»È¤Ã¤ÆÊÑ´¹¤¹¤ë */
227     void interceptWithGnuNM(fstream & file, const string & filename) throw(Exception)
228     {
229         assert(!file.is_open());
230
231         string cmdline;
232         string symfile;
233
234         symfile.assign(makeTemporaryFilename());
235         cmdline = string(CMD_GNUNM) + " " + filename + " > " + symfile;
236         VerboseMessage("[EXEC] %\n") << cmdline;
237
238                 system(cmdline.c_str());
239
240             /* Àµ¤·¤¯³«¤±¤¿¤é¥Õ¥¡¥¤¥ë¤òºï½ü */
241         file.open(symfile.c_str(), ios::in);
242         if(file.is_open()) {
243             remove(symfile.c_str());
244         }
245     }
246
247         /* ¥Ð¥¤¥Ê¥ê¤òGNU-OBJCOPY¤ò»È¤Ã¤ÆÊÑ´¹¤¹¤ë */
248     void interceptWithGnuObjcopy(fstream & file, const string & filename) throw(Exception)
249     {
250         assert(!file.is_open());
251
252         string cmdline;
253         string srecfile;
254
255         srecfile.assign(makeTemporaryFilename());
256         cmdline = string(CMD_GNUOBJCOPY) + " -F srec " + filename + " " + srecfile;
257         VerboseMessage("[EXEC] %\n") << cmdline;
258
259                 system(cmdline.c_str());
260
261             /* Àµ¤·¤¯³«¤±¤¿¤é¥Õ¥¡¥¤¥ë¤òºï½ü */
262         file.open(srecfile.c_str(), ios::in);
263         if(file.is_open()) {
264             remove(srecfile.c_str());
265         }
266     }
267
268         /* 16¿Ê¤«¤é10¿Ê¤Ø¤ÎÊÑ´¹ (¥Ý¥¤¥ó¥¿°ÜÆ°, Ä¹¤µ»ØÄêÉÕ¤­) */
269     unsigned int hextodec(const char * & src, size_t length) throw()
270     {
271         assert(length <= sizeof(unsigned int) * 2);
272
273         unsigned int result = 0;
274         unsigned int digit;
275
276         while(length-- > 0) {
277             if(*src >= '0' && *src <= '9')
278                 digit = *src - '0';
279             else if(*src >= 'A' && *src <='F')
280                 digit = *src - 'A' + 10;
281             else if(*src >= 'a' && *src <='f')
282                 digit = *src - 'a' + 10;
283             else
284                 break;
285
286             ++ src;
287             result = (result << 4) | (digit & 0xf);
288         }
289
290         return result;
291     }
292
293         /* NM¤¬½ÐÎϤ·¤¿¹Ô¤ò¥Ñ¡¼¥¹ */
294     bool readGnuNmLine(fstream & file, FileContainer::address_t & address, string & attribute, string & symbolname) throw()
295     {
296         assert(file.is_open());
297
298         string src;
299         string addr;
300         string::size_type pos1;
301         string::size_type pos2;
302
303             /* Ãæ¿È¤ò¶õ¤Ë¤·¤Æ¤ª¤¯ */
304         address = 0;
305         if(!attribute.empty())
306             attribute.erase();
307         if(!symbolname.empty())
308             symbolname.erase();
309
310             //¼¡¤Î¹Ô¤ò¼èÆÀ (¶õ¹Ô, Ì¤ÄêµÁ¥·¥ó¥Ü¥ë¤ÏÆɤßÈô¤Ð¤¹)
311         do {
312             if(file.eof())
313                 return false;
314
315             getline(file, src, '\n');
316         } while(src.empty() || src.at(0) == ' ');
317
318             //¹Ô¤òʬ²ò
319         pos1 = src.find_first_of(' ');
320         addr = src.substr(0, pos1);
321
322         pos2 = src.find_first_of(' ', pos1 + 1);
323         attribute  = src.substr(pos1 + 1, pos2 - pos1 - 1);
324         symbolname = src.substr(pos2 + 1);
325
326             //¥¢¥É¥ì¥¹¤Î¥Ñ¡¼¥¹  (Ãí : ¤Ê¤ó¤Ç¤³¤ó¤Ê¤Á¤Þ¤Á¤Þ¤ä¤Ã¤Æ¤ë¤«¤È¤¤¤¦¤È¡¢¥¢¥É¥ì¥¹¤¬32bit¤òĶ¤¨¤ë¥¿¡¼¥²¥Ã¥È¤¬¤¤¤ë¤«¤é)
327         while(!addr.empty()) {
328             size_t length = addr.size();
329             const char * src = addr.c_str();
330             if(length > sizeof(unsigned int) * 2)
331                 length = sizeof(unsigned int) * 2;
332             address = (address << (length * 2)) | (hextodec(src, length));
333             addr.erase(0, length);
334         }
335
336         return true;
337     }
338
339         /* ¥·¥ó¥Ü¥ë¤ÎÆɤ߹þ¤ß */
340     void FileContainerBinutilsImpl::loadSymbols(fstream & file) throw(Exception)
341     {
342         assert(file.is_open());
343
344         address_t address;
345         string    attribute;
346         string    symbolname;
347
348         while(readGnuNmLine(file, address, attribute, symbolname)) {
349             symbol_table.insert(map<string, address_t>::value_type(symbolname, address));
350         }
351
352                 VerboseMessage("% symbols loaded\n") << symbol_table.size() << &throwException;
353
354         file.close();
355     }
356
357         /* contents¤Ë1¥Ð¥¤¥È½ñ¤­¹þ¤ß */
358     void FileContainerBinutilsImpl::writeByte(address_t address, unsigned int value) throw(Exception)
359     {
360         address_t & base = last_address;
361         char *    & page = last_page;
362
363             /* ¥­¥ã¥Ã¥·¥å¤â¤É¤­¤¬»È¤¨¤Ê¤¤¤Ê¤é¡¢¥Ú¡¼¥¸¤òõ¤¹ */
364         if(MAKE_BASEADDRESS(address) != last_address || last_page == 0) {
365             map<address_t, char *>::iterator scope;
366
367             base  = MAKE_BASEADDRESS(address);
368             scope = contents.find(base);
369             if(scope == contents.end()) {
370                 page = new(nothrow) char [SIZE_LOADPAGE];
371                 if(page == 0) {
372                     ExceptionMessage("Not enough memory available to store the contents","¶õ¤­¥á¥â¥êÉÔ­¤Î¤¿¤á¡¢¥Ç¡¼¥¿¤Î³ÊǼ¤Ë¼ºÇÔ¤·¤Þ¤·¤¿").throwException();
373                     return;
374                 }
375                 contents.insert(map<address_t,char*>::value_type(base, page));
376             }
377             else
378                 page = scope->second;
379         }
380
381         *(page + (address - base)) = static_cast<char>(value & 0xff);
382     }
383
384         /* ËöÈø¤Î¶õÇòʸ»ú¤òÀÚ¤ê¼è¤ë */
385     void trimString(string & src) throw()
386     {
387         string::size_type pos;
388
389         pos = src.find_last_not_of(" \t\r\n");
390         if(pos != string::npos && pos != src.size())
391             src.erase(pos + 1);
392     }
393
394         /* ¥â¥È¥í¡¼¥éS¥ì¥³¡¼¥É¤ò°ì¹ÔÆɤ߹þ¤à */
395         /*
396                 The general format of an S-record follows: 
397                 +-------------------//------------------//-----------------------+
398                 | type | count | address  |            data           | checksum |
399                 +-------------------//------------------//-----------------------+
400         */
401     bool readRecord(fstream & file, string & dest) throw(Exception)
402     {
403         unsigned int sum;
404         unsigned int count;
405         unsigned int i;
406         const char * pos;
407
408             /* ¼¡¤Î¹Ô¤òÆɤ߹þ¤à */
409         do {
410                 //getline¤¬ReadFile¤ò¸Æ¤ó¤Ç¥Ö¥í¥Ã¥¯¤¹¤ë¤Î¤Ç¡¢³Î¼Â¤ËEOF¤òÈ¿±þ¤µ¤»¤ë¤¿¤á¤Ë¤³¤¦¤¹¤ë
411             int ch = file.get();
412             if(ch == EOF)
413                 return false;
414
415             file.putback(static_cast<char>(ch));
416             getline(file, dest);
417         } while(dest.empty());
418
419         trimString(dest);
420
421             /* ÀµÅöÀ­¤ÎȽÄê */
422
423         if(dest[0] != 'S')      //¹ÔƬ¤¬'S'¤Ç»Ï¤Þ¤é¤Ê¤¤
424             ExceptionMessage("The file is not a Motorola S-Record file.","¥â¥È¥í¡¼¥éS¥Õ¥©¡¼¥Þ¥Ã¥È¤Ç̵¤¤¹Ô¤¬¸«¤Ä¤«¤ê¤Þ¤·¤¿") << throwException;
425
426         pos = dest.c_str() + 2;
427         count = hextodec(pos, 2);
428         if(dest.size() != (count + 2)*2)
429             ExceptionMessage("Illegal S-Record found (count unmatched).","ÉÔÀµ¤ÊS¥ì¥³¡¼¥É¤¬¤¢¤ê¤Þ¤¹ (¥µ¥¤¥ºÉÔ°ìÃ×)") << throwException;
430
431         sum = count;
432         for(i = 0; i < count; ++ i)
433             sum += hextodec(pos, 2);
434
435         if((sum & 0xff) != 0xff)
436             ExceptionMessage("Illegal S-Record found (check-sum unmatched).","ÉÔÀµ¤ÊS¥ì¥³¡¼¥É¤¬¤¢¤ê¤Þ¤¹ (¥Á¥§¥Ã¥¯¥µ¥àÉÔ°ìÃ×)") << throwException;
437
438         return true;
439     }
440
441         /* ¼¡¤Î³«»Ï¥¢¥É¥ì¥¹¤òÆÀ¤ë */
442     FileContainer::address_t parseRecordAddress(const string & src, FileContainer::address_t base) throw()
443     {
444         const char * record = src.c_str();
445         FileContainer::address_t result = 0;
446
447         record += 4;
448         switch(*(record - 3)) {
449             case '1':
450                 result = hextodec(record, 4);
451                 break;
452             case '2':
453                 result = hextodec(record, 6);
454                 break;
455             case '3':
456                 result = hextodec(record, 8);
457                 break;
458             case '5':
459                 result = base;
460                 break;
461             default:
462                 break;
463         }
464
465         return result;
466     }
467
468         /* ¥Ç¡¼¥¿Éôʬ¤À¤±¤ò»Ä¤·¤Æ¥Á¥ç¥Ã¥× */
469     void chopRecord(string & src) throw()
470     {
471         string::size_type start;
472
473         switch(src[1]) {
474             case '1':  start = 4 + 4;  break;
475             case '2':  start = 4 + 6;  break;
476             case '3':  start = 4 + 8;  break;
477             default:   start = 4;      break;
478         }
479
480             //ÀèƬ4¥Ð¥¤¥È + ¥¢¥É¥ì¥¹Éô + ºÇ¸å¤Î¥µ¥à¤ò¼è¤ê½ü¤¯
481         src = src.substr(start, src.size() - start - 2);
482     }
483
484         /* ¥×¥í¥°¥é¥à¥Ç¡¼¥¿¤ÎÆɤ߹þ¤ß */
485     void FileContainerBinutilsImpl::loadDataContents(fstream & file) throw(Exception)
486     {
487         assert(file.is_open());
488
489         address_t address;
490         string    line;
491
492         address = 0;
493         while(readRecord(file, line)) {
494
495             address = parseRecordAddress(line, address);
496
497             chopRecord(line);
498
499                 /* ¥Ç¡¼¥¿¤Î³ÊǼ */
500             const char * pos = line.c_str();
501             while(*pos != '\x0') {
502                 unsigned int data = hextodec(pos, 2);
503                 writeByte(address, data);
504                 ++ address;
505             }
506         }
507
508         file.close();
509     }
510
511         /* ¥·¥ó¥Ü¥ë¥×¥ì¥Õ¥£¥¯¥¹¤Î¼«Æ°È½Äê */
512     void FileContainerBinutilsImpl::searchSymbolPrefix(void) throw()
513     {
514         const char *  candidate_list[] = {"", "_", NULL};
515         const char ** candidate;
516
517         for(candidate = candidate_list; *candidate != NULL; ++ candidate) {
518             map<string, address_t>::const_iterator scope;
519             string symbol;
520             
521             symbol = string(*candidate) + MAGIC_SYMBOL;
522             scope  = symbol_table.find(symbol);
523
524             if(scope != symbol_table.end())
525                 break;
526         }
527
528         if(*candidate != NULL)
529             symbol_prefix.assign(*candidate);
530     }
531
532         /* ¥¨¥ó¥Ç¥£¥¢¥ó¤Î¼«Æ°È½Äê */
533     void FileContainerBinutilsImpl::searchByteOrder(void) throw()
534     {
535         address_t address;
536         union {
537             char         buffer[4];
538             unsigned int value;
539         };
540
541         try {
542             value   = 0;
543             address = getSymbolAddress(MAGIC_SYMBOL);
544             loadContents(buffer, address, 4);
545
546             if(value == MAGIC_NUMBER) {
547                 byteorder = HOSTORDER;
548             }
549             else {
550                 buffer[0] ^= buffer[3], buffer[3] ^= buffer[0], buffer[0] ^= buffer[3]; // swap(buffer[0], buffer[3])
551                 buffer[1] ^= buffer[2], buffer[2] ^= buffer[1], buffer[1] ^= buffer[2]; // swap(buffer[1], buffer[2])
552
553                 if(value == MAGIC_NUMBER)
554                     byteorder = HOSTORDER == LITTLE ? BIG : LITTLE;
555                 else
556                     throw false;
557             }
558         }
559         catch(...) {}
560     }
561
562         /* ¥â¥¸¥å¡¼¥ë¤Î¥¢¥¿¥Ã¥Á -> ¥·¥ó¥Ü¥ëÆɽФ·, ¥Ç¡¼¥¿³ÊǼ */
563     void FileContainerBinutilsImpl::attachModule(const string & filename) throw(Exception)
564     {
565         fstream file;
566         string  symbol_filename;
567         string  contents_filename;
568
569         splitFilename(filename, symbol_filename, contents_filename);
570
571         openTextFile(file, symbol_filename, interceptWithGnuNM);
572         loadSymbols(file);
573
574         openTextFile(file, contents_filename, interceptWithGnuObjcopy);
575         loadDataContents(file);
576
577         searchSymbolPrefix();
578         searchByteOrder();
579     }
580
581         /* ³ÊǼ¤·¤Æ¤¤¤ëÆâÍƤμèÆÀ */
582     void FileContainerBinutilsImpl::loadContents(void * _dest, address_t address, size_t size) throw(Exception)
583     {
584         char * dest = static_cast<char *>(_dest);
585
586         while(size > 0) {
587             map<address_t, char *>::const_iterator scope;
588
589             address_t  base   = MAKE_BASEADDRESS(address);
590             address_t  offset = MAKE_OFFSETADDRESS(address);
591             size_t     transfer_size = size;
592
593             if(transfer_size > SIZE_LOADPAGE - offset)
594                 transfer_size = SIZE_LOADPAGE - offset;
595
596             scope = contents.find(base);
597             if(scope == contents.end())
598                 ExceptionMessage("[Internel error] Memory read with unmapped address","[ÆâÉô¥¨¥é¡¼] ¥Þ¥Ã¥×¤µ¤ì¤Æ¤Ê¤¤¥¢¥É¥ì¥¹¤ò»È¤Ã¤Æ¥á¥â¥ê¥ê¡¼¥É¤¬¹Ô¤ï¤ì¤Þ¤·¤¿").throwException();
599
600             memcpy(dest, scope->second + offset, transfer_size);
601
602             dest += transfer_size;
603             size -= transfer_size;
604         }
605     }
606
607         /* ¥·¥ó¥Ü¥ë¤Î¥¢¥É¥ì¥¹¤Î¼èÆÀ */
608     FileContainer::address_t FileContainerBinutilsImpl::getSymbolAddress(const string & symbol) throw(Exception)
609     {
610         string symbolname;
611         map<string, address_t>::const_iterator scope;
612
613         symbolname = symbol_prefix + symbol;
614
615         scope = symbol_table.find(symbolname);
616         if(scope == symbol_table.end())
617             ExceptionMessage("Unknown symbol '%'","ÉÔÌÀ¤Ê¥·¥ó¥Ü¥ë̾ '%'") << symbol << throwException;
618
619         return scope->second;
620     }
621
622         /* ¥¢¡¼¥­¥Æ¥¯¥Á¥ã̾¤Î¼èÆÀ */
623     string FileContainerBinutilsImpl::getArchitecture(void) throw()
624     {
625         if(byteorder == LITTLE)
626             return "Little endian target (with GNU/Binutils)";
627         else
628             return "Big endian target (with GNU/Binutils)";
629     }
630
631 }
632
633 //---------------------------------------------
634
635 #ifdef TESTSUITE
636 #include "base/coverage_undefs.h"
637
638 namespace {
639     fstream * interceptor_file;
640     string    interceptor_filename;
641     void interceptor(fstream & file, const string & filename)
642     {
643         CHECKPOINT("interceptor");
644         interceptor_file = &file;
645         interceptor_filename = filename;
646
647         if(filename.compare("textfile") == 0) {
648             remove(filename.c_str());
649             file.open(filename.c_str(), ios::out);
650             file << "text";
651             file.close();
652
653             file.open(filename.c_str(), ios::in|ios::binary);
654         }
655         else if(filename.compare("binaryfile") == 0) {
656             remove(filename.c_str());
657             file.open(filename.c_str(), ios::out|ios::binary);
658             file.write("\x1",1);
659             file.close();
660
661             file.open(filename.c_str(), ios::in|ios::binary);
662         }
663     }
664 }
665
666 TESTSUITE(main, FileContainerBinutilsImpl)
667 {
668     PREDECESSOR("TFileContainer");
669
670     SingletonBase::ContextChain chain;
671     chain.saveContext<RuntimeObjectTable>();
672
673     BEGIN_CASE("splitFilename","splitFilename") {
674         BEGIN_CASE("1","¥«¥ó¥Þ¤ÎÁ°¸å¤ÇÀÚ¤ì¤ë") {
675             string first, second;
676             
677             splitFilename("a,b", first, second);
678             TEST_CASE("1","first¤ÎÃæ¿È¤ÏÀµ¤·¤¤", first.compare("a") == 0);
679             TEST_CASE("2","second¤ÎÃæ¿È¤ÏÀµ¤·¤¤", second.compare("b") == 0);
680         } END_CASE;
681
682         BEGIN_CASE("2","¥«¥ó¥Þ¤Î̵¤¤°ú¿ô¤òÍ¿¤¨¤ë¤È¡¢Î¾Êý¤ËƱ¤¸Ãæ¿È¤¬Æþ¤ë") {
683             string first, second;
684
685             splitFilename("abc", first, second);
686             TEST_CASE("1","first¤ÎÃæ¿È¤ÏÀµ¤·¤¤", first.compare("abc") == 0);
687             TEST_CASE("2","second¤ÎÃæ¿È¤ÏÀµ¤·¤¤", second.compare("abc") == 0);
688         } END_CASE;
689
690         BEGIN_CASE("3","¶õʸ»ú¤òÍ¿¤¨¤ë¤ÈÎã³°") {
691             bool result = false;
692             string first, second;
693             try { splitFilename("", first, second); } catch(Exception &) { result = true; }
694             if(!result)
695                 TEST_FAIL;
696         } END_CASE;
697     } END_CASE;
698
699     BEGIN_CASE("hasBinaryContents","hasBinaryContents") {
700         BEGIN_CASE("1","¥Æ¥­¥¹¥È¥Õ¥¡¥¤¥ë¤ò¿©¤ï¤»¤ë") {
701             fstream file("test", ios::out);
702             file << "This is a sample text file.";
703             file.close();
704
705             file.open("test",ios::in|ios::binary);
706             TEST_CASE("1","´Ø¿ô¤Ïfalse¤òÊÖ¤¹", !hasBinaryContents(file));
707             TEST_CASE("2","file¤Ïeof¤Ë㤷¤Æ¤¤¤Ê¤¤", !file.eof());
708             file.close();
709
710             remove("test");
711         } END_CASE;
712
713         BEGIN_CASE("2","¥Ð¥¤¥Ê¥ê¥Ç¡¼¥¿¤ò¿©¤ï¤»¤ë") {
714             fstream file("test", ios::out|ios::binary);
715             file << "This is a sample text file.";
716             file.write("\x0\x1\x2\x3", 4);
717             file.close();
718
719             file.open("test",ios::in|ios::binary);
720             TEST_CASE("1","´Ø¿ô¤Ïtrue¤òÊÖ¤¹", hasBinaryContents(file));
721             TEST_CASE("2","file¤Ïeof¤Ë㤷¤Æ¤¤¤Ê¤¤", !file.eof());
722             file.close();
723
724             remove("test");
725         } END_CASE;
726     } END_CASE;
727
728     BEGIN_CASE("openTextFile","openTextFile") {
729         BEGIN_CASE("1","¥Æ¥­¥¹¥È¥Õ¥¡¥¤¥ë¤ò»ØÄꤹ¤ë") {
730             TestSuite::clearCheckpoints();
731             fstream file("test", ios::out);
732             file << "This is a sample text file.";
733             file.close();
734
735             bool result = true;
736             try { openTextFile(file, "test", interceptor); } catch(Exception &) { result = false; }
737
738             TEST_CASE("1","Îã³°¤Ïµ¯¤­¤Ê¤¤", result);
739             TEST_CASE("2","¥Õ¥¡¥¤¥ë¤¬³«¤«¤ì¤Æ¤¤¤ë", file.is_open());
740             TEST_CASE("3","interceptor¤Ï¥³¡¼¥ë¤µ¤ì¤Æ¤¤¤Ê¤¤", !TestSuite::isReached("interceptor"));
741
742             string work;
743             getline(file, work, '\n');
744             TEST_CASE("4","Æɤ߽Фµ¤ì¤¿ÆâÍƤ¬Àµ¤·¤¤", work.compare("This is a sample text file.") == 0);
745
746             file.close();
747             remove("test");
748         } END_CASE;
749
750         BEGIN_CASE("2","¥Ð¥¤¥Ê¥ê¥Õ¥¡¥¤¥ë¤ò»ØÄꤹ¤ë (interceptor¤Ï¥Õ¥¡¥¤¥ë¤ò³«¤«¤Ê¤¤)") {
751             TestSuite::clearCheckpoints();
752             fstream file("test", ios::out|ios::binary);
753             file.write("\x1", 1);
754             file.close();
755
756             bool result = false;
757             try { openTextFile(file, "test", interceptor); } catch(Exception &) { result = true; }
758
759             TEST_CASE("1","Îã³°¤¬µ¯¤­¤ë", result);
760             TEST_CASE("2","¥Õ¥¡¥¤¥ë¤¬³«¤«¤ì¤Æ¤¤¤ë", !file.is_open());
761             TEST_CASE("3","interceptor¤¬¥³¡¼¥ë¤µ¤ì¤Æ¤¤¤ë", TestSuite::isReached("interceptor"));
762             TEST_CASE("4","interceptor¤Î°ú¿ô¤¬Àµ¤·¤¤ (file)", interceptor_file == &file);
763             TEST_CASE("5","interceptor¤Î°ú¿ô¤¬Àµ¤·¤¤", interceptor_filename.compare("test") == 0);
764
765             file.close();
766             remove("test");
767         } END_CASE;
768
769         BEGIN_CASE("3","¸ºß¤·¤Ê¤¤¥Õ¥¡¥¤¥ë¤ò»ØÄꤹ¤ë") {
770             TestSuite::clearCheckpoints();
771             fstream file;
772             bool result = false;
773             try { openTextFile(file, "___unknown___", interceptor); } catch(Exception &) { result = true; }
774
775             TEST_CASE("1","Îã³°¤¬µ¯¤­¤ë", result);
776             TEST_CASE("2","¥Õ¥¡¥¤¥ë¤¬³«¤«¤ì¤Æ¤¤¤Ê¤¤", !file.is_open());
777             TEST_CASE("3","interceptor¤¬¥³¡¼¥ë¤µ¤ì¤Æ¤¤¤Ê¤¤", !TestSuite::isReached("interceptor"));
778         } END_CASE;
779
780         BEGIN_CASE("4","interceptor¤¬¥Æ¥­¥¹¥È¥Õ¥¡¥¤¥ë¤òÀ¸À®¤¹¤ë") {
781             TestSuite::clearCheckpoints();
782             fstream file("textfile", ios::out|ios::binary);
783             file.write("\x1", 1);
784             file.close();
785
786             bool result = true;
787             try { openTextFile(file, "textfile", interceptor); } catch(Exception &) { result = false; }
788
789             TEST_CASE("1","Îã³°¤Ïµ¯¤­¤Ê¤¤", result);
790             TEST_CASE("2","¥Õ¥¡¥¤¥ë¤¬³«¤«¤ì¤Æ¤¤¤ë", file.is_open());
791             TEST_CASE("3","interceptor¤¬¥³¡¼¥ë¤µ¤ì¤Æ¤¤¤ë", TestSuite::isReached("interceptor"));
792             TEST_CASE("4","interceptor¤Î°ú¿ô¤¬Àµ¤·¤¤ (file)", interceptor_file == &file);
793             TEST_CASE("5","interceptor¤Î°ú¿ô¤¬Àµ¤·¤¤", interceptor_filename.compare("textfile") == 0);
794
795             string work;
796             getline(file, work, '\n');
797             TEST_CASE("4","Æɤ߽Фµ¤ì¤¿ÆâÍƤ¬Àµ¤·¤¤", work.compare("text") == 0);
798
799             file.close();
800             remove("textfile");
801         } END_CASE;
802
803         BEGIN_CASE("5","interceptor¤¬¥Ð¥¤¥Ê¥ê¥Õ¥¡¥¤¥ë¤òÀ¸À®¤¹¤ë") {
804             TestSuite::clearCheckpoints();
805             fstream file("binaryfile", ios::out|ios::binary);
806             file.write("\x1", 1);
807             file.close();
808
809             bool result = false;
810             try { openTextFile(file, "binaryfile", interceptor); } catch(Exception &) { result = true; }
811
812             TEST_CASE("1","Îã³°¤Ïµ¯¤­¤ë", result);
813             TEST_CASE("2","¥Õ¥¡¥¤¥ë¤¬³«¤«¤ì¤Æ¤¤¤Ê¤¤", !file.is_open());
814             TEST_CASE("3","interceptor¤¬¥³¡¼¥ë¤µ¤ì¤Æ¤¤¤ë", TestSuite::isReached("interceptor"));
815             TEST_CASE("4","interceptor¤Î°ú¿ô¤¬Àµ¤·¤¤ (file)", interceptor_file == &file);
816             TEST_CASE("5","interceptor¤Î°ú¿ô¤¬Àµ¤·¤¤", interceptor_filename.compare("binaryfile") == 0);
817
818             file.close();
819             remove("binaryfile");
820         } END_CASE;
821     } END_CASE;
822
823     BEGIN_CASE("hextodec","hextodec") {
824         const char * letter = "0123456789abcdEFg";
825         const char * work = letter;
826
827         TEST_CASE("1", "ÀÚ¤ê½Ð¤µ¤ì¤¿Ãͤ¬Àµ¤·¤¤", hextodec(work, 2) == 1);
828         TEST_CASE("2", "work¤¬¿Ê¤ó¤Ç¤¤¤ë", work == letter + 2);
829         TEST_CASE("3", "ÀÚ¤ê½Ð¤µ¤ì¤¿Ãͤ¬Àµ¤·¤¤", hextodec(work, 4) == 0x2345);
830         TEST_CASE("4", "work¤¬¿Ê¤ó¤Ç¤¤¤ë", work == letter + 6);
831         TEST_CASE("5", "ÀÚ¤ê½Ð¤µ¤ì¤¿Ãͤ¬Àµ¤·¤¤", hextodec(work, 8) == 0x6789abcd);
832         TEST_CASE("6", "work¤¬¿Ê¤ó¤Ç¤¤¤ë", work == letter + 14);
833         TEST_CASE("7", "ÀÚ¤ê½Ð¤µ¤ì¤¿Ãͤ¬Àµ¤·¤¤", hextodec(work, 8) == 0xef);
834         TEST_CASE("8", "work¤¬'g'¤Î°ÌÃ֤ǤȤޤë", *work == 'g');
835         TEST_CASE("9", "ÀÚ¤ê½Ð¤µ¤ì¤¿Ãͤ¬Àµ¤·¤¤", hextodec(work, 8) == 0);
836         TEST_CASE("10", "work¤¬'g'¤Î°ÌÃ֤ǤȤޤë", *work == 'g');
837     } END_CASE;
838
839     BEGIN_CASE("readGnuNmLine","readGnuNmLine") {
840         fstream file("test", ios::out);
841         file << "0804aab0 T _kernel_task_initialize\n0805d8a0 B _kernel_tcb_table\n\n0804e560 R _kernel_tinib_table\n         U getpid@@GLIBC_2.0\n";
842         file.close();
843
844         address_t address;
845         string    attribute;
846         string    symbolname;
847
848         file.open("test", ios::in);
849         BEGIN_CASE("1","ÉáÄ̤Υ¨¥ó¥È¥ê¤¬Æɤá¤ë") {
850             TEST_CASE("1","´Ø¿ô¤ÏÀ®¸ù¤¹¤ë", readGnuNmLine(file, address, attribute, symbolname));
851             TEST_CASE("2","address¤ÏÀµ¤·¤¤", address == 0x0804aab0);
852             TEST_CASE("3","attribute¤ÏÀµ¤·¤¤", attribute.compare("T") == 0);
853             TEST_CASE("4","symbolname¤ÏÀµ¤·¤¤", symbolname.compare("_kernel_task_initialize") == 0);
854         } END_CASE;
855
856         BEGIN_CASE("2","ÉáÄ̤Υ¨¥ó¥È¥ê¤¬Æɤá¤ë (2)") {
857             TEST_CASE("1","´Ø¿ô¤ÏÀ®¸ù¤¹¤ë", readGnuNmLine(file, address, attribute, symbolname));
858             TEST_CASE("2","address¤ÏÀµ¤·¤¤", address == 0x0805d8a0);
859             TEST_CASE("3","attribute¤ÏÀµ¤·¤¤", attribute.compare("B") == 0);
860             TEST_CASE("4","symbolname¤ÏÀµ¤·¤¤", symbolname.compare("_kernel_tcb_table") == 0);
861         } END_CASE;
862
863         BEGIN_CASE("3","¶õ¹Ô¤òÆɤßÈô¤Ð¤·¤Æ¼¡¤¬Æɤá¤ë") {
864             TEST_CASE("1","´Ø¿ô¤ÏÀ®¸ù¤¹¤ë", readGnuNmLine(file, address, attribute, symbolname));
865             TEST_CASE("2","address¤ÏÀµ¤·¤¤", address == 0x0804e560);
866             TEST_CASE("3","attribute¤ÏÀµ¤·¤¤", attribute.compare("R") == 0);
867             TEST_CASE("4","symbolname¤ÏÀµ¤·¤¤", symbolname.compare("_kernel_tinib_table") == 0);
868         } END_CASE;
869
870         BEGIN_CASE("4","¥¢¥É¥ì¥¹¤Î̵¤¤¥¨¥ó¥È¥ê¤Ï̵»ë¤¹¤ë") {
871             TEST_CASE("1","´Ø¿ô¤Ï¼ºÇÔ¤¹¤ë", !readGnuNmLine(file, address, attribute, symbolname));
872         } END_CASE;
873
874         file.close();
875         remove("test");
876     } END_CASE;
877
878     BEGIN_CASE("loadSymbols","loadSymbols") {
879         fstream file("test", ios::out);
880         file << "0804aab0 T _kernel_task_initialize\n0805d8a0 B _kernel_tcb_table\n\n0804e560 R _kernel_tinib_table\n         U getpid@@GLIBC_2.0\n";
881         file.close();
882
883         file.open("test",ios::in);
884
885         FileContainerBinutilsImpl fcbi;
886         fcbi.loadSymbols(file);
887
888         TEST_CASE("1","Æɤ߹þ¤Þ¤ì¤¿¥¨¥ó¥È¥ê¤Î¿ô¤¬Àµ¤·¤¤", fcbi.symbol_table.size() == 3);
889         TEST_CASE("2","¥Õ¥¡¥¤¥ë¤ÏÊĤ¸¤é¤ì¤Æ¤¤¤ë", !file.is_open());
890
891         remove("test");
892     } END_CASE;
893
894     BEGIN_CASE("writeByte","writeByte") {
895         FileContainerBinutilsImpl fcbi;
896
897         BEGIN_CASE("1","¸ºß¤·¤Ê¤¤¥Ú¡¼¥¸¤Ø¤Î½ñ¤­¹þ¤ß") {
898             TEST_CASE("0", "[Á°Äó] contents¤ÎÍ×ÁÇ¿ô¤Ï0", fcbi.contents.size() == 0);
899             fcbi.writeByte(0x100, 0);
900
901             TEST_CASE("1","contents¤ÎÍ×ÁǤ¬Áý¤¨¤Æ¤¤¤ë", fcbi.contents.size() == 1);
902
903             const char * scope = fcbi.contents.find(MAKE_BASEADDRESS(0x100))->second + MAKE_OFFSETADDRESS(0x100);
904             TEST_CASE("2","½ñ¤­¹þ¤Þ¤ì¤Æ¤¤¤ëÆâÍƤ¬Àµ¤·¤¤", *scope == 0);
905         } END_CASE;
906
907         BEGIN_CASE("2","¸ºß¤¹¤ë¥Ú¡¼¥¸¤Ø¤Î½ñ¤­¹þ¤ß (Ϣ³¥¢¥¯¥»¥¹)") {
908             fcbi.writeByte(0x100, 0xff);
909
910             TEST_CASE("1","contents¤ÎÍ×ÁǤ¬Áý¤¨¤Æ¤¤¤Ê¤¤", fcbi.contents.size() == 1);
911
912             const char * scope = fcbi.contents.find(MAKE_BASEADDRESS(0x100))->second + MAKE_OFFSETADDRESS(0x100);
913             TEST_CASE("2","½ñ¤­¹þ¤Þ¤ì¤Æ¤¤¤ëÆâÍƤ¬Àµ¤·¤¤", *scope == 0xff);
914         } END_CASE;
915
916         BEGIN_CASE("3","¿·¤·¤¤¥Ú¡¼¥¸¤Ø¤Î½ñ¤­¹þ¤ß") {
917             fcbi.writeByte(0x10000000, 0xff);
918
919             TEST_CASE("1","contents¤ÎÍ×ÁǤ¬Áý¤¨¤Æ¤¤¤ë", fcbi.contents.size() == 2);
920
921             const char * scope = fcbi.contents.find(MAKE_BASEADDRESS(0x10000000))->second + MAKE_OFFSETADDRESS(0x10000000);
922             TEST_CASE("2","½ñ¤­¹þ¤Þ¤ì¤Æ¤¤¤ëÆâÍƤ¬Àµ¤·¤¤", *scope == 0xff);
923         } END_CASE;
924
925         BEGIN_CASE("4","´û¸¤Î¥Ú¡¼¥¸¤Ø¤Î¥¢¥¯¥»¥¹") {
926             fcbi.writeByte(0x100, 0x0);
927
928             TEST_CASE("1","contents¤ÎÍ×ÁǤ¬Áý¤¨¤Æ¤¤¤Ê¤¤", fcbi.contents.size() == 2);
929
930             const char * scope = fcbi.contents.find(MAKE_BASEADDRESS(0x100))->second + MAKE_OFFSETADDRESS(0x100);
931             TEST_CASE("2","½ñ¤­¹þ¤Þ¤ì¤Æ¤¤¤ëÆâÍƤ¬Àµ¤·¤¤", *scope == 0x0);
932         } END_CASE;
933     } END_CASE;
934
935     BEGIN_CASE("readRecord","readRecord") {
936         fstream file("test",ios::out);
937         file << "S315080480F42F6C69622F6C642D6C696E75782E736F98\n\nS315080480F42F6C69622F6C642D6C696E75782E736F98\nS308080481042E320005\nDUMMY\nS31808048108040000001000000001000000474E550056\nS31008048108040000001000000001000000474E550056\n";
938         file.close();
939
940         file.open("test",ios::in);
941         BEGIN_CASE("1","Àµ¾ï¥±¡¼¥¹") {
942             string work;
943             bool result;
944             bool exception = false;
945             try { result = readRecord(file, work); } catch(Exception &) { exception = true; }
946             TEST_CASE("1","Îã³°¤Ïµ¯¤³¤é¤Ê¤¤", !exception);
947             TEST_CASE("2","´Ø¿ô¤Ïtrue¤òÊÖ¤¹", result);
948             TEST_CASE("3","Æɤ߽Фµ¤ì¤¿ÆâÍƤ¬Àµ¤·¤¤", work.compare("S315080480F42F6C69622F6C642D6C696E75782E736F98") == 0);
949         } END_CASE;
950
951         BEGIN_CASE("2","Àµ¾ï¥±¡¼¥¹ (¶õ¹Ô¤ÎÆɤßÈô¤Ð¤·)") {
952             string work;
953             bool result;
954             bool exception = false;
955             try { result = readRecord(file, work); } catch(Exception &) { exception = true; }
956             TEST_CASE("1","Îã³°¤Ïµ¯¤³¤é¤Ê¤¤", !exception);
957             TEST_CASE("2","´Ø¿ô¤Ïtrue¤òÊÖ¤¹", result);
958             TEST_CASE("3","Æɤ߽Фµ¤ì¤¿ÆâÍƤ¬Àµ¤·¤¤", work.compare("S315080480F42F6C69622F6C642D6C696E75782E736F98") == 0);
959         } END_CASE;
960
961         BEGIN_CASE("3","¥Á¥§¥Ã¥¯¥µ¥à¤¬¸í¤Ã¤Æ¤¤¤ë¥¨¥ó¥È¥ê") {
962             string work;
963             bool result;
964             bool exception = false;
965             try { result = readRecord(file, work); } catch(Exception &) { exception = true; }
966             TEST_CASE("1","Îã³°¤ò¤ª¤³¤¹", exception);
967         } END_CASE;
968
969         BEGIN_CASE("4","ÀèƬ¤¬S¤Ç»Ï¤Þ¤é¤Ê¤¤¥¨¥ó¥È¥ê") {
970             string work;
971             bool result;
972             bool exception = false;
973             try { result = readRecord(file, work); } catch(Exception &) { exception = true; }
974             TEST_CASE("1","Îã³°¤ò¤ª¤³¤¹", exception);
975         } END_CASE;
976
977         BEGIN_CASE("5","»ØÄꤵ¤ì¤¿Ä¹¤µ¤è¤ê¤âŤ¤¥¨¥ó¥È¥ê") {
978             string work;
979             bool result;
980             bool exception = false;
981             try { result = readRecord(file, work); } catch(Exception &) { exception = true; }
982             TEST_CASE("1","Îã³°¤ò¤ª¤³¤¹", exception);
983         } END_CASE;
984
985         BEGIN_CASE("6","»ØÄꤵ¤ì¤¿Ä¹¤µ¤è¤ê¤âû¤¤¥¨¥ó¥È¥ê") {
986             string work;
987             bool result;
988             bool exception = false;
989             try { result = readRecord(file, work); } catch(Exception &) { exception = true; }
990             TEST_CASE("1","Îã³°¤ò¤ª¤³¤¹", exception);
991         } END_CASE;
992
993         BEGIN_CASE("7","¥Õ¥¡¥¤¥ë½ªÃ¼") {
994             string work;
995             bool result;
996             bool exception = false;
997             try { result = readRecord(file, work); } catch(Exception &) { exception = true; }
998             TEST_CASE("1","Îã³°¤ò¤ª¤³¤µ¤Ê¤¤", !exception);
999             TEST_CASE("2","´Ø¿ô¤Ïfalse¤òÊÖ¤¹", !result);
1000         } END_CASE;
1001
1002         remove("test");
1003     } END_CASE;
1004
1005     BEGIN_CASE("chopRecord","chopRecord") {
1006         BEGIN_CASE("1","S1¥ì¥³¡¼¥É") {
1007             string src("S106080480F42F4A");
1008
1009             chopRecord(src);
1010             TEST_CASE("1","Ãͤ¬Àµ¤·¤¤", src.compare("80F42F") == 0);
1011         } END_CASE;
1012
1013         BEGIN_CASE("2","S2¥ì¥³¡¼¥É") {
1014             string src("S206080480F42F4A");
1015
1016             chopRecord(src);
1017             TEST_CASE("1","Ãͤ¬Àµ¤·¤¤", src.compare("F42F") == 0);
1018         } END_CASE;
1019
1020         BEGIN_CASE("3","S3¥ì¥³¡¼¥É") {
1021             string src("S306080480F42F4A");
1022
1023             chopRecord(src);
1024             TEST_CASE("1","Ãͤ¬Àµ¤·¤¤", src.compare("2F") == 0);
1025         } END_CASE;
1026
1027         BEGIN_CASE("4","S4¥ì¥³¡¼¥É") {
1028             string src("S406080480F42F4A");
1029
1030             chopRecord(src);
1031             TEST_CASE("1","Ãͤ¬Àµ¤·¤¤", src.compare("080480F42F") == 0);
1032         } END_CASE;
1033
1034         BEGIN_CASE("5","S5¥ì¥³¡¼¥É") {
1035             string src("S506080480F42F4A");
1036
1037             chopRecord(src);
1038             TEST_CASE("1","Ãͤ¬Àµ¤·¤¤", src.compare("080480F42F") == 0);
1039         } END_CASE;
1040
1041     } END_CASE;
1042
1043     BEGIN_CASE("loadDataContents/loadContents","loadDataContents/loadContents") {
1044         fstream file("test", ios::out);
1045         file << "S30D000000000123456789ABCDEF32\nS509FEDCBA9876543210BE";
1046         file.close();
1047
1048         BEGIN_CASE("1","Àµ¾ï¥±¡¼¥¹") {
1049             FileContainerBinutilsImpl fcbi;
1050
1051             file.open("test",ios::in);
1052             bool exception = false;
1053             try { fcbi.loadDataContents(file); } catch(...) { exception = true; }
1054
1055             TEST_CASE("1","Îã³°¤Ïµ¯¤³¤é¤Ê¤¤", !exception);
1056             TEST_CASE("2","¥Ç¡¼¥¿¤¬³ÎÊݤµ¤ì¤Æ¤¤¤ë", fcbi.contents.size() == 1);
1057             TEST_CASE("3","¥Õ¥¡¥¤¥ë¤ÏÊĤ¸¤é¤ì¤Æ¤¤¤ë", !file.is_open());
1058             BEGIN_CASE("4","³ÊǼ¤·¤¿Ãͤ¬Àµ¤·¤¯Æɤá¤ë") {
1059                 unsigned int i;
1060
1061                 assert(sizeof(unsigned int) >= 4);
1062                 i = 0;
1063                 
1064                 fcbi.loadContents(&i, 0, 4);
1065                 TEST_CASE("1","1-4¥Ð¥¤¥ÈÌÜ", i == 0x67452301);
1066                 fcbi.loadContents(&i, 4, 4);
1067                 TEST_CASE("1","5-8¥Ð¥¤¥ÈÌÜ", i == 0xefcdab89);
1068                 fcbi.loadContents(&i, 8, 4);
1069                 TEST_CASE("1","9-12¥Ð¥¤¥ÈÌÜ", i == 0x98badcfe);
1070                 fcbi.loadContents(&i,12, 4);
1071                 TEST_CASE("1","13-16¥Ð¥¤¥ÈÌÜ", i == 0x10325476);
1072             } END_CASE;
1073         } END_CASE;
1074         remove("test");
1075
1076         BEGIN_CASE("2","loadContents¤Ç°ìÅ٤˥ڡ¼¥¸¥µ¥¤¥º¤òĶ¤¨¤ëÎ̤òÍ׵᤹¤ë") {
1077             FileContainerBinutilsImpl fcbi;
1078             unsigned int i;
1079
1080             for(i=0;i<SIZE_LOADPAGE*2;++i)
1081                 fcbi.writeByte(i, i);
1082
1083             unsigned char * buffer = new unsigned char [SIZE_LOADPAGE * 2];
1084             fcbi.loadContents(buffer, 0, SIZE_LOADPAGE * 2);
1085
1086             for(i=0;i<SIZE_LOADPAGE*2;++i)
1087                 if(*(buffer + i) != (i & 0xff))
1088                     TEST_FAIL;
1089
1090             delete [] buffer;
1091         } END_CASE;
1092
1093     } END_CASE;
1094
1095     BEGIN_CASE("searchSymbolPrefix","searchSymbolPrefix") {
1096
1097         BEGIN_CASE("1","¥×¥ì¥Õ¥£¥¯¥¹¤¬¤Ê¤¤") {
1098             FileContainerBinutilsImpl fcbi;
1099             fcbi.symbol_table.insert(pair<string, address_t>(MAGIC_SYMBOL, 0x100));
1100
1101             fcbi.searchSymbolPrefix();
1102             if(!fcbi.symbol_prefix.empty())
1103                 TEST_FAIL;
1104         } END_CASE;
1105
1106         BEGIN_CASE("2","ÊÑ¿ô̾¤Ë\"_\"¤¬¤Ä¤¯¥¿¥¤¥×") {
1107             FileContainerBinutilsImpl fcbi;
1108             fcbi.symbol_table.insert(pair<string, address_t>("_" MAGIC_SYMBOL, 0x100));
1109
1110             fcbi.searchSymbolPrefix();
1111             if(fcbi.symbol_prefix.compare("_") != 0)
1112                 TEST_FAIL;
1113         } END_CASE;
1114
1115         BEGIN_CASE("3","\"__\"¤Ë¤ÏÈ¿±þ¤·¤Ê¤¤") {
1116             FileContainerBinutilsImpl fcbi;
1117             fcbi.symbol_table.insert(pair<string, address_t>("__" MAGIC_SYMBOL, 0x100));
1118
1119             fcbi.searchSymbolPrefix();
1120             if(!fcbi.symbol_prefix.empty())
1121                 TEST_FAIL;
1122         } END_CASE;
1123             
1124         BEGIN_CASE("4","ȯ¸«¤Ç¤­¤Ê¤¤¾ì¹ç¡¢Êѹ¹¤·¤Ê¤¤") {
1125             FileContainerBinutilsImpl fcbi;
1126             fcbi.symbol_prefix.assign("test");
1127
1128             fcbi.searchSymbolPrefix();
1129             if(fcbi.symbol_prefix.compare("test") != 0)
1130                 TEST_FAIL;
1131         } END_CASE;
1132     } END_CASE;
1133
1134     BEGIN_CASE("searchByteOrder","searchByteOrder") {
1135         BEGIN_CASE("1","¥Û¥¹¥È¤ÈƱ¤¸¥¨¥ó¥Ç¥£¥¢¥ó") {
1136             FileContainerBinutilsImpl fcbi;
1137             unsigned int value = MAGIC_NUMBER;
1138             fcbi.symbol_table.insert(pair<string, address_t>(MAGIC_SYMBOL, 0x100));
1139
1140             for(int i=0;i<4;i++)
1141                 fcbi.writeByte(0x100 + i, *((char *)&value + i));
1142
1143             fcbi.byteorder = UNKNOWN;
1144             fcbi.searchByteOrder();
1145
1146             if(fcbi.byteorder != HOSTORDER)
1147                 TEST_FAIL;
1148         } END_CASE;
1149
1150         BEGIN_CASE("2","¥Û¥¹¥È¤È°ã¤¦¥¨¥ó¥Ç¥£¥¢¥ó") {
1151             FileContainerBinutilsImpl fcbi;
1152             unsigned int value = MAGIC_NUMBER;
1153             fcbi.symbol_table.insert(pair<string, address_t>(MAGIC_SYMBOL, 0x100));
1154
1155             for(int i=0;i<4;i++)
1156                 fcbi.writeByte(0x100 + i, *((char *)&value + (3 - i)));
1157
1158             fcbi.byteorder = UNKNOWN;
1159             fcbi.searchByteOrder();
1160
1161             if(fcbi.byteorder == HOSTORDER)
1162                 TEST_FAIL;
1163         } END_CASE;
1164
1165         BEGIN_CASE("3","¥·¥ó¥Ü¥ë¤¬Ìµ¤¤") {
1166             FileContainerBinutilsImpl fcbi;
1167             unsigned int value = MAGIC_NUMBER;
1168
1169             for(int i=0;i<4;i++)
1170                 fcbi.writeByte(0x100 + i, *((char *)&value + (3 - i)));
1171
1172             fcbi.byteorder = UNKNOWN;
1173             fcbi.searchByteOrder();
1174
1175             if(fcbi.byteorder != UNKNOWN)
1176                 TEST_FAIL;
1177         } END_CASE;
1178
1179         BEGIN_CASE("4","¥Ç¡¼¥¿¤¬Ìµ¤¤") {
1180             FileContainerBinutilsImpl fcbi;
1181             unsigned int value = MAGIC_NUMBER;
1182             fcbi.symbol_table.insert(pair<string, address_t>(MAGIC_SYMBOL, 0x100));
1183
1184             fcbi.byteorder = UNKNOWN;
1185             fcbi.searchByteOrder();
1186
1187             if(fcbi.byteorder != UNKNOWN)
1188                 TEST_FAIL;
1189         } END_CASE;
1190     } END_CASE;
1191
1192     chain.restoreContext();
1193 }
1194
1195 #endif /* TESTSUITE */
1196
1197 #endif /* FILECONTAINER_BINUTILS || TESTSUITE */
1198