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_windows.cpp
1 /*
2  *  TOPPERS/JSP Kernel
3  *      Toyohashi Open Platform for Embedded Real-Time Systems/
4  *      Just Standard Profile Kernel
5  * 
6  *  Copyright (C) 2000-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_windows.cpp,v 1.12 2003/12/20 06:51:58 takayuki Exp $
37  */
38
39 #if (defined(FILECONTAINER_WINDOWS) || defined(TESTSUITE)) && defined(_MSC_VER)
40
41 #pragma warning(disable:4786)
42
43 #include "base/filecontainer.h"
44 #include <windows.h>
45 #include <imagehlp.h>
46 #include <string>
47
48 using namespace std;
49
50 namespace {
51
52     class FileContainerWindowsImpl : public FileContainer
53     {
54     protected:
55         HANDLE          process;
56         LOADED_IMAGE    image;
57         DWORD           base;
58
59         inline bool isLoaded(void) const
60         {   return base != 0;   }
61
62     public:
63         FileContainerWindowsImpl(void) throw();
64         virtual ~FileContainerWindowsImpl(void) throw();
65
66             /* ¥¤¥ó¥¿¥Õ¥§¡¼¥¹Éô */
67         virtual void        attachModule(const string & filename) throw(Exception);
68         virtual void        loadContents(void * dest, address_t address, size_t size) throw(Exception);
69         virtual address_t   getSymbolAddress(const string & symbol) throw(Exception);
70         virtual std::string getArchitecture(void) throw();
71
72         TESTSUITE_PROTOTYPE(main)
73     };
74
75     FileContainerWindowsImpl instance_of_FileContaienrWindowsImpl;
76
77         /* ¥³¥ó¥¹¥È¥é¥¯¥¿ */
78     FileContainerWindowsImpl::FileContainerWindowsImpl(void) throw()
79         : process(NULL), image(), base(0)
80     {}
81
82         /* ¥Ç¥¹¥È¥é¥¯¥¿ */
83     FileContainerWindowsImpl::~FileContainerWindowsImpl(void) throw()
84     {
85         if(isLoaded()) {
86             ::UnMapAndLoad(&image);
87             ::SymUnloadModule(process, base);
88             process = NULL;
89             base    = 0;
90         }
91     }
92
93         /* Âоݥ⥸¥å¡¼¥ë¤Î³äÉÕ */
94     void FileContainerWindowsImpl::attachModule(const std::string & _filename) throw(Exception)
95     {
96         string filename(_filename);
97
98         process = ::GetCurrentProcess();
99         if(::SymInitialize( process , NULL, FALSE) == FALSE)
100             ExceptionMessage("[Internal Error] ImageHelper API initialization failure","[ÆâÉô¥¨¥é¡¼] ½é´ü²½¤Ë¼ºÇÔ¤·¤Þ¤·¤¿ (ImageHlp)").throwException();
101
102         base = ::SymLoadModule(process, NULL, (PSTR)filename.c_str(), NULL, 0, 0);
103
104         image.SizeOfImage = sizeof(LOADED_IMAGE);
105         if(::MapAndLoad((PSTR)filename.c_str(), NULL, &image, FALSE, TRUE) == FALSE)
106             ExceptionMessage("[Internel error] Module loading failure [%]","[ÆâÉô¥¨¥é¡¼] ¥â¥¸¥å¡¼¥ë¤ÎÆɤ߹þ¤ß¤Ë¼ºÇÔ¤·¤Þ¤·¤¿ [%]") << filename << throwException;
107     }
108
109         /* ÆâÍƤμèÆÀ */
110     void FileContainerWindowsImpl::loadContents(void * dest, address_t address, size_t size) throw(Exception)
111     {
112         PIMAGE_SECTION_HEADER header;
113         unsigned int i;
114
115         address -= base;
116         for(i=0;i<image.NumberOfSections;i++) {
117             header = image.Sections+i;
118             if(address >= header->VirtualAddress && address < header->VirtualAddress + header->SizeOfRawData) {
119                 address -= header->VirtualAddress - header->PointerToRawData;
120                 ::CopyMemory(dest,image.MappedAddress + address,size);
121                 break;
122             }
123         }
124
125         if(i == image.NumberOfSections)
126             ExceptionMessage("[Internel error] Memory read with unmapped address","[ÆâÉô¥¨¥é¡¼] ¥Þ¥Ã¥×¤µ¤ì¤Æ¤Ê¤¤¥¢¥É¥ì¥¹¤ò»È¤Ã¤Æ¥á¥â¥ê¥ê¡¼¥É¤¬¹Ô¤ï¤ì¤Þ¤·¤¿").throwException();
127     }
128
129         /* ¥·¥ó¥Ü¥ë¥¢¥É¥ì¥¹¤Î²ò·è */
130     FileContainer::address_t FileContainerWindowsImpl::getSymbolAddress(const string & _symbol) throw(Exception)
131     {
132         FileContainer::address_t result = 0;
133         string symbol(_symbol);
134         IMAGEHLP_SYMBOL sym;
135
136         if(process == NULL || base == 0)
137             ExceptionMessage("Not initialized","½é´ü²½¤µ¤ì¤Æ¤Þ¤»¤ó").throwException();
138
139         sym.SizeOfStruct = sizeof(sym);
140         sym.MaxNameLength = 0;
141
142         if(::SymGetSymFromName(process, (PSTR)symbol.c_str(), &sym) == TRUE)
143             result = static_cast<FileContainer::address_t>(sym.Address);
144      
145         if(result == 0)
146             ExceptionMessage("Unknown symbol [%]","ÉÔÀµ¤Ê¥·¥ó¥Ü¥ë̾ [%]") << symbol << throwException;
147
148         return static_cast<FileContainer::address_t>(sym.Address);
149     }
150
151     string FileContainerWindowsImpl::getArchitecture(void) throw()
152     {   return "Windows (Win32)";   }
153
154 }
155
156 //---------------------------------------------
157
158 #ifdef TESTSUITE
159 #include "base/coverage_undefs.h"
160
161 #pragma warning(disable:4311) //'reinterpret_cast' : ¥Ý¥¤¥ó¥¿¤ò 'const int *__w64 ' ¤«¤é 'FileContainer::address_t' ¤ØÀÚ¤êµÍ¤á¤Þ¤¹¡£
162
163 extern "C" const int FileContainerWindowsImplTestVariable = 0x01234567;
164 extern "C" const int _FileContainerWindowsImplTestVariableWithUnderbar = 0x89abcdef;
165
166 TESTSUITE(main, FileContainerWindowsImpl)
167 {
168     PREDECESSOR("TFileContainer");
169
170     SingletonBase::ContextChain chain;
171     chain.saveContext<RuntimeObjectTable>();
172     chain.renewInstance();
173
174     BEGIN_CASE("attachModule","attachModule") {
175         BEGIN_CASE("1","¼Â¹Ô¤·¤Æ¤¤¤ë¥×¥í¥°¥é¥à¤¬³«¤±¤ë¤«") {
176             FileContainerWindowsImpl fcwi;
177             bool result = true;
178             try { fcwi.attachModule(TestSuite::getProgName()); } catch(...) { result = false; }
179             
180             TEST_CASE("1", "Îã³°¤Ïµ¯¤­¤Ê¤¤", result);
181         } END_CASE;
182
183         BEGIN_CASE("2","¸ºß¤·¤Ê¤¤¥Õ¥¡¥¤¥ë̾¤ÇÎã³°") {
184             FileContainerWindowsImpl fcwi;
185             bool result = false;
186             try { fcwi.attachModule("..."); } catch(...) { result = true; }
187             
188             TEST_CASE("1", "Îã³°¤¬µ¯¤­¤ë", result);
189         } END_CASE;
190     } END_CASE;
191
192     BEGIN_CASE("getSymbolAddress","getSymbolAddress") {
193         FileContainerWindowsImpl fcwi;
194
195         BEGIN_CASE("1","½é´ü²½¤·¤Æ¤¤¤Ê¤¤¾õÂ֤Ǹ¡º÷¤¹¤ë") {
196             bool result = false;
197             try { fcwi.getSymbolAddress("FileContainerWindowsImplTestVariable"); } catch(...) { result = true; }
198             TEST_CASE("1","Îã³°¤¬¤ª¤­¤ë", result);
199         } END_CASE;
200
201         fcwi.attachModule(TestSuite::getProgName());
202
203         BEGIN_CASE("2","¸ºß¤¹¤ë¥·¥ó¥Ü¥ë¤ò¸¡º÷¤¹¤ë") {
204             FileContainer::address_t addr = 0;
205             bool result = true;
206
207             try { addr = fcwi.getSymbolAddress("FileContainerWindowsImplTestVariable"); } catch(...) { result = false; }
208
209             TEST_CASE("1","Îã³°¤Ïµ¯¤­¤Ê¤¤", result);
210             TEST_CASE("2","¥¢¥É¥ì¥¹¤¬Àµ¤·¤¤", addr == reinterpret_cast<FileContainer::address_t>(&FileContainerWindowsImplTestVariable));
211         } END_CASE;
212
213         BEGIN_CASE("3",";·×¤Ê_¤ò¾¡¼ê¤ËÉղ䷤ʤ¤") {
214             FileContainer::address_t addr = 0;
215             bool result = false;
216
217             try { addr = fcwi.getSymbolAddress("FileContainerWindowsImplTestVariableWithUnderbar"); } catch(...) { result = true; }
218
219             TEST_CASE("1","Îã³°¤¬µ¯¤­¤ë", result);
220             TEST_CASE("2","¥¢¥É¥ì¥¹¤Ï0¤Î¤Þ¤Þ", addr == 0);
221         } END_CASE;
222
223         BEGIN_CASE("4","¸ºß¤·¤Ê¤¤¥·¥ó¥Ü¥ë¤ò¸¡º÷¤¹¤ë") {
224             FileContainer::address_t addr = 0;
225             bool result = false;
226
227             try { addr = fcwi.getSymbolAddress("____unknown____"); } catch(...) { result = true; }
228
229             TEST_CASE("1","Îã³°¤¬¤ª¤­¤ë", result);
230         } END_CASE;
231     } END_CASE;
232
233     BEGIN_CASE("loadContents","loadContents") {
234         FileContainerWindowsImpl fcwi;
235         fcwi.attachModule(TestSuite::getProgName());
236
237         BEGIN_CASE("1","¸ºß¤¹¤ëÊÑ¿ô¤òÆɤ߽Ф¹") {
238             FileContainer::address_t addr;
239             int i;
240
241             addr = fcwi.getSymbolAddress("FileContainerWindowsImplTestVariable");
242             bool result = true;
243             try { fcwi.loadContents(&i, addr, sizeof(i)); } catch(...) { result = false; }
244
245             TEST_CASE("1","Îã³°¤Ïµ¯¤­¤Ê¤¤", result);
246             TEST_CASE("2","Æɤ߽Фµ¤ì¤¿ÆâÍƤÏÀµ¤·¤¤", i == FileContainerWindowsImplTestVariable);
247         } END_CASE;
248
249         BEGIN_CASE("2","¸ºß¤·¤Ê¤¤ÊÑ¿ô¤òÆɤ߽Ф¹") {
250             FileContainer::address_t addr;
251             int i;
252
253             addr = ~0;
254             bool result = false;
255             try { fcwi.loadContents(&i, addr, sizeof(i)); } catch(Exception &) { result = true; }
256
257             TEST_CASE("1","Îã³°¤¬µ¯¤³¤ë", result);
258         } END_CASE;
259
260     } END_CASE;
261
262     chain.restoreContext();
263 }
264
265 #endif /* TESTSUITE */
266
267 #endif /* FILECONTAINER_WINDOWS || TESTSUITE */
268