symSyncLib.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:51k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* symSyncLib.c - host/target symbol table synchronization */
  2. /* Copyright 1996-2002 Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 01t,03may02,jhw  Added VX_FP_TASK task option to tSymSync. (SPR 66307)
  7. 01s,03apr02,j_s  correct the miscalculation of length limit of symbol name
  8.  in syncSymAddHook/syncSymRemoveHook (SPR 75036).
  9. 01r,30oct01,jn   use symFindSymbol for symbol lookup (SPR #7453)
  10. 01q,01oct01,c_c  Fixed SPR 62583.
  11. 01p,02apr99,jdi  corrected spelling of NOMANUAL in syncTgtSafeModCheck()
  12. 01o,14mar99,jdi  doc: removed refs to config.h and/or configAll.h (SPR 25663).
  13. 01n,01sep98,pcn  Added wtxObjModuleUndefSymAdd definition.
  14. 01m,27jul98,elp  fixed stack size for SIMSPARCSOLARIS (SPR #20150).
  15. 01l,07jul98,pcn  Added include for wtxObjModuleUndefSymAdd.
  16. 01k,24apr98,dbt  fixed WTX timeout error message (SPR #20852).
  17. 01j,14jul97,dgp  doc: edit new additions
  18. 01i,21feb96,elp  improved timeout managements (added warning message).
  19. 01h,13feb97,elp  managed timeout errors on wtxEventGet() (SPR# 7959)
  20.  + network doc enhancements (SPR# 7852).
  21. 01g,06jan97,elp  fixed a typo.
  22. 01f,18dec96,jdi  doc: more enhancements and cleanup; changed title line to
  23.     reflect new name of module.
  24. 01e,12dec96,elp  moved hooks initialization into tSymSync
  25.  + added global symSyncHWtx to enable timeout modifications.
  26.  + added symSyncTimeout()
  27.  + name revision.
  28. 01d,10dec96,jdi  doc: cleanup.
  29. 01c,13nov96,elp  doc generation.
  30. 01b,24oct96,elp  added event notification when synchronization is done
  31.  + synchronize usual target commands (ld(), symAdd(), ...).
  32. 01a,04oct96,elp  written.
  33. */
  34. /*
  35. DESCRIPTION
  36. This module provides host/target symbol table synchronization.
  37. With synchronization, every module or symbol added to the run-time
  38. system from either the target or host side can be seen by facilities
  39. on both the target and the host. Symbol table synchronization makes it 
  40. possible to use host tools to debug application modules loaded with the 
  41. target loader or from a target file system.  To enable synchronization, 
  42. two actions must be performed: 
  43. .iP 1 6
  44. The module is initialized by symSyncLibInit(), which is called automatically 
  45. when the configuration macro INCLUDE_SYM_TBL_SYNC is defined.
  46. .iP 2
  47. The target server is launched with the `-s' option.
  48. .LP
  49. If synchronization is enabled, `symSyncLib' spawns a synchronization task 
  50. on the target, `tSymSync'. This task behaves as a WTX tool and attaches 
  51. itself to the target server.  When the task starts, it synchronizes target 
  52. and host symbol tables so that every module loaded on the target before the 
  53. target server was started can be seen by the host tools.  This feature is 
  54. particularly useful if VxWorks is started with a target-based startup script 
  55. before the target server has been launched.
  56. The `tSymSync' task synchronizes new symbols that are added
  57. by either the target or the host tools.  The task waits for synchronization 
  58. events on two channels:  a WTX event from the host or a message queue additon
  59. from the target.
  60. The `tSymSync' task, like all WTX tools, must be able to connect to the WTX
  61. registry. To make the WTX registry accessible from the target, do one of
  62. the following:
  63. .iP 1 6
  64. Boot the target from a host on the same subnet as the registry.
  65. .iP 2
  66. Start the registry on the same host the target boots from.
  67. .iP 3
  68. Add the needed routes with routeAdd() calls, possibly in a startup script.
  69. .LP
  70. Neither the host tools nor the target loader wait for synchronization
  71. completion to return.  To know when the synchronization is complete, you
  72. can wait for the corresponding event sent by the target server, or,
  73. if your target server was started with the `-V' option, it prints a
  74. message indicating synchronization has completed.
  75. The event sent by the target server is of the following format:
  76. .tS
  77.     SYNC_DONE <syncType> <syncObj> <syncStatus>
  78. .tE
  79. The following are examples of messages displayed by the target server
  80. indicating synchronization is complete:
  81. .CS
  82.     Added target_modules         to target-server.....done
  83.     Added ttTest.o.68k           to target............done
  84. .CE
  85. If synchronization fails, the following message is displayed:
  86. .CS
  87.     Added gopher.o               to target............failed
  88. .CE
  89. This error generally means that synchronization of the corresponding module
  90. or symbol is no longer possible because it no longer exists in the original
  91. symbol table.  If so, it will be followed by:
  92. .CS
  93.     Removed gopher.o             from target..........failed
  94. .CE
  95. Failure can also occur if a timeout is reached.  
  96. Call symSyncTimeoutSet() to modify the WTX timeout between the target
  97. synchronization task and the target server.
  98. LIMITATIONS
  99. Hardware:  Because the synchronization task uses the WTX protocol to
  100. communicate with the target server, the target must include network
  101. facilities.  Depending on how much synchronization is to be done (number
  102. of symbols to transfer), a reasonable throughput between the target server
  103. and target agent is required (the wdbrpc backend is recommended when large
  104. modules are to be loaded).
  105. Performance:  The synchronization task requires some minor overhead in
  106. target routines msgQSend(), loadModule(), symAdd(), and symRemove(); 
  107. however, if an application sends more than 15 synchronization events,
  108. it will fill the message queue and then need to wait for a synchronization
  109. event to be processed by `tSymSync'. Also, waiting for host synchronization 
  110. events is done by polling; thus there may be some impact on performance if 
  111. there are lower-priority tasks than `tSymSync'.  If no more synchronization 
  112. is needed, `tSymSync' can be suspended.
  113. Known problem:  Modules with undefined symbols that are loaded from the target
  114. are not synchronized; however, they are synchronized if they are loaded
  115. from the host.
  116. SEE ALSO
  117. `tgtsvr'
  118. */
  119. /* includes */
  120. #include "symSyncLib.h"
  121. #include "rpcLib.h"
  122. #include "loadLib.h"
  123. #include "unldLib.h"
  124. #include "symLib.h"
  125. #include "msgQLib.h"
  126. #include "sysLib.h"
  127. #include "a_out.h" /* XXX ELP to get N_TYPE definition */
  128. #include "usrLib.h"
  129. #include "logLib.h"
  130. /* typedefs */
  131. typedef struct
  132.     {
  133.     DL_NODE  node;
  134.     UINT16 tgtGroup;
  135.     UINT32 hostGroup;
  136.     } GROUP_NODE;
  137. /* 
  138.  * dummy type that concatenates arguments as only one can be passed to
  139.  * routines called by symEach().
  140.  */
  141. typedef struct 
  142. {
  143. HWTX hWtx;
  144. UINT16 tgtGroup;
  145. UINT32 hostGroup;
  146. } BY_GROUP_ARG_T;
  147. /* defines */
  148. /* #define DEBUG */
  149. #define H_STR_TO_L(str) (strtoul (str, NULL, 16))
  150. #define SYNC_TGT_EVT_MAX 15 /* max number of sync rqsts */
  151. #define OBJ_NAME_MAX 30
  152. #define SYNC_TGT_EVT_LGTH 60 /* max event string length */
  153. #define OBJ_LOADED_EVT "OBJ_LOADED"
  154. #define OBJ_UNLOADED_EVT "OBJ_UNLOADED"
  155. #define SYM_ADDED_EVT "SYM_ADDED"
  156. #define SYM_REMOVED_EVT "SYM_REMOVED"
  157. #define SYM_ADDED_EVT_MSG_NON_NAME_LGTH 34
  158. #define USR_RQST_EVT "USR_RQST"
  159. #define TIMEOUT  sysClkRateGet()
  160. /* for sending/receiving events */
  161. #define SYNC_PRIORITY 90
  162. /* XXX - jhw 
  163.  * The VX_FP_TASK option is needed to prevent corruption of 
  164.  * the floating point registers. All tasks that call
  165.  * (directly or indirectly) C++ code that is compiled without 
  166.  * '-fnoexceptions' with gnu 2.96 are affected.
  167.  * See SPR 66307,70995 for additional info.
  168.  * This module calls unldByModuleId() which calls C++ destructors.
  169.  */
  170. #define SYNC_OPTIONS VX_FP_TASK
  171. #if (CPU_FAMILY == MC680X0) 
  172. #define SYNC_STACK_SIZE 8000
  173. #elif (CPU_FAMILY == I960)
  174. #define SYNC_STACK_SIZE 5000
  175. #elif ((CPU_FAMILY == SIMSPARCSOLARIS) || (CPU_FAMILY == SPARC) || 
  176.        (CPU_FAMILY == SIMSPARCSUNOS))
  177. #define SYNC_STACK_SIZE 15000
  178. #else
  179. #define SYNC_STACK_SIZE 5000
  180. #endif
  181. /* globals */
  182. MSG_Q_ID symSyncMsgQId; /* target synchro event container */
  183. HWTX symSyncHWtx; /* symbol synchro WTX handle */
  184. /* locals */
  185. LOCAL const char SYM_SYNC_TOOL_NAME[] =  "symTblsSync";
  186. LOCAL DL_LIST symSyncLst; /* sync modules list */
  187. LOCAL DL_LIST symSyncTmpLst; /* tmp buffer */
  188. LOCAL BOOL symSyncKill; /* to exit tSymSync loop */
  189. LOCAL UINT32 symSyncWtxTimeout = 5000; /* wtx timeout */
  190. IMPORT CLASS_ID symTblClassId;
  191. IMPORT CLASS_ID moduleClassId;
  192. IMPORT SYMTAB_ID sysSymTbl;
  193. IMPORT struct opaque_auth authCred;
  194. /* forward declarations */
  195. extern  STATUS wtxObjModuleUndefSymAdd (HWTX, char *, UINT32 );
  196. STATUS symSRemove (SYMTAB_ID, char *, SYM_TYPE);
  197. /* group list processing */
  198. LOCAL STATUS groupAdd (DL_LIST *, UINT16, UINT32);
  199. LOCAL GROUP_NODE * groupFind (DL_LIST *, UINT32, FUNCPTR);
  200. LOCAL GROUP_NODE * groupRemove (DL_LIST *, UINT32, FUNCPTR);
  201. LOCAL BOOL isInHostGroupList (DL_NODE *, int);
  202. LOCAL BOOL isInTgtGroupList (DL_NODE *, int);
  203. LOCAL void syncGroupUpdate ();
  204. LOCAL STATUS symSyncMain (HWTX);
  205. LOCAL STATUS symSyncTaskInit (char *);
  206. /* host -> target synchronization */
  207. LOCAL STATUS symSyncTgtUpdate (HWTX, char *, char *);
  208. LOCAL STATUS syncModCTgtUpdate (HWTX, UINT32);
  209. LOCAL STATUS syncModDTgtUpdate (HWTX, UINT32);
  210. LOCAL STATUS syncSymAddTgtUpdate (HWTX, char *);
  211. LOCAL MODULE_ID syncTgtModInfoFill (WTX_MODULE_INFO *);
  212. /* target -> host synchronization */
  213. LOCAL STATUS symSyncHostUpdate (HWTX, char *, char *);
  214. LOCAL STATUS syncModCHostUpdate (HWTX, DL_LIST *, MODULE_ID, BOOL *,BOOL);
  215. LOCAL STATUS syncModDHostUpdate (HWTX, char *, UINT16);
  216. LOCAL STATUS syncSymAddHostUpdate (HWTX, char *, char *, SYM_TYPE, UINT16);
  217. LOCAL STATUS syncSymRemHostUpdate (HWTX, char *, SYM_TYPE);
  218. LOCAL STATUS syncHostModInfoFill (WTX_LD_M_FILE_DESC *, MODULE_ID, BOOL);
  219. LOCAL STATUS syncUsrUpdate (HWTX, int, int);
  220. LOCAL BOOL syncTgtSafeModCheck (MODULE_ID , int);
  221. LOCAL BOOL syncEachSymToHost (char *, int, SYM_TYPE, int, UINT16);
  222. LOCAL BOOL syncSymByGrpToHost (char *, int, SYM_TYPE, int, UINT16);
  223. LOCAL void syncLoadHook (MODULE_ID);
  224. LOCAL void syncUnldHook (MODULE_ID);
  225. LOCAL void syncSymAddHook (char *, char *, SYM_TYPE, UINT16);
  226. LOCAL void syncSymRemoveHook (char *, SYM_TYPE);
  227. /******************************************************************************
  228. * symSyncLibInit - initialize host/target symbol table synchronization
  229. *
  230. * This routine initializes host/target symbol table synchronization. 
  231. * To enable synchronization, it must be called before a target server
  232. * is started.  It is called automatically if the configuration macro
  233. * INCLUDE_SYM_TBL_SYNC is defined.
  234. *
  235. * RETURNS: N/A
  236. */
  237. void symSyncLibInit ()
  238.     {
  239.     /* create the target synchronization event folder */
  240.     symSyncMsgQId = msgQCreate (SYNC_TGT_EVT_MAX, SYNC_TGT_EVT_LGTH,
  241. MSG_Q_FIFO);
  242.     return;
  243.     }
  244. /******************************************************************************
  245. *
  246. * symSyncTimeoutSet - set WTX timeout 
  247. *
  248. * This routine sets the WTX timeout between target server and synchronization
  249. * task.
  250. *
  251. * RETURNS: If <timeout> is 0, the current timeout, otherwise the new timeout
  252. * value in milliseconds.
  253. */
  254. UINT32 symSyncTimeoutSet
  255.     (
  256.     UINT32 timeout /* WTX timeout in milliseconds */
  257.     )
  258.     {
  259.     UINT32 curTimeout;
  260.     if (wtxToolConnected (symSyncHWtx))
  261. {
  262. if (timeout == 0)
  263.     {
  264.     if (wtxTimeoutGet (symSyncHWtx, &curTimeout) == WTX_OK)
  265. return (curTimeout);
  266.     return (symSyncWtxTimeout);
  267.     }
  268. else
  269.     {
  270.     symSyncWtxTimeout = timeout;
  271.     wtxTimeoutSet (symSyncHWtx, symSyncWtxTimeout);
  272.     return (symSyncWtxTimeout);
  273.     }
  274. }
  275.     
  276.     if (timeout == 0)
  277. return (symSyncWtxTimeout);
  278.     symSyncWtxTimeout = timeout;
  279.     return (symSyncWtxTimeout);
  280.     }
  281. /******************************************************************************
  282. *
  283. * syncErrHandler - synchronization error handler
  284. * Some WTX errors may happen in an unpredictable way (because information of
  285. * the synchronization task are not up to date). So these errors should be 
  286. * ignored.
  287. *
  288. * RETURNS: FALSE to prevent from calling other error handler. 
  289. *
  290. * NOMANUAL
  291. */
  292. BOOL32 syncErrHandler
  293.     (
  294.     HWTX hWtx, /* WTX API handle */
  295.     void * pClientData,
  296.     void * errCode
  297.     )
  298.     {
  299.     if (((WTX_ERROR_T)errCode == WTX_OK) ||
  300. ((WTX_ERROR_T)errCode == WTX_ERR_LOADER_OBJ_MODULE_NOT_FOUND) || 
  301. ((WTX_ERROR_T)errCode == WTX_ERR_SYMTBL_SYMBOL_NOT_FOUND) ||
  302. ((WTX_ERROR_T)errCode == WTX_ERR_SYMTBL_NO_SUCH_MODULE))
  303. {
  304. #ifdef DEBUG 
  305. logMsg ("%#x ignoredn", (WTX_ERROR_T)errCode, 0, 0, 0, 0, 0);
  306. #endif
  307. }
  308.     else if (((WTX_ERROR_T)errCode == WTX_ERR_API_NOT_CONNECTED) ||
  309.      ((WTX_ERROR_T)errCode == WTX_ERR_API_TOOL_DISCONNECTED) ||
  310.      ((WTX_ERROR_T)errCode == WTX_ERR_API_REGISTRY_UNREACHABLE) ||
  311.      ((WTX_ERROR_T)errCode == WTX_ERROR))
  312. {
  313. if (!symSyncKill)
  314.     fprintf (stderr,
  315.      "Fatal WTX error (%#x), synchronization stoppedn",
  316.      (int)errCode);
  317. symSyncKill = TRUE;  /* end the task */
  318. }
  319.     else if ((WTX_ERROR_T)errCode == WTX_ERR_API_REQUEST_TIMED_OUT)
  320. {
  321. fprintf (stderr, "Warning: tSymSync WTX timeoutn");
  322. }
  323.     else
  324. {
  325. #ifdef DEBUG
  326. fprintf (stderr, "Unexpected WTX error %#x during synchronizationn",
  327.  (WTX_ERROR_T)errCode);
  328.         taskSuspend (0);
  329. #endif
  330. }
  331.     return (FALSE);
  332.     }
  333. /******************************************************************************
  334. *
  335. * syncSymStart - start the synchronization task
  336. *
  337. * This routine is the entry point that is called by target server.
  338. * It initializes registry inet and RPC credentials and then starts <tSymSync>
  339. * task.
  340. * Once the synchronization task is started, it sends a request to synchronize
  341. * the symbol tables.
  342. *
  343. * RETURNS: tid of <tSymSync> or WTX_ERROR.
  344. *
  345. * NOMANUAL
  346. */
  347. STATUS syncSymStart
  348.     (
  349.     char * tgtSvrName, /* target server name */
  350.     UINT32 registryInet, /* registry address */
  351.     int pCredFlavor, /* RPC credentials information */
  352.     void * pCredBase,
  353.     UINT32 pCredLength
  354.     )
  355.     {
  356.     int tid;
  357.     char startSyncEvt[SYNC_TGT_EVT_LGTH];
  358.     if (OBJ_VERIFY (sysSymTbl, symTblClassId) != OK)
  359. return (WTX_ERROR);
  360.     /* store the registry internet address */
  361.     syncRegistry = registryInet;
  362.     /* store RPC credentials */
  363.     authCred.oa_flavor = pCredFlavor;
  364.     authCred.oa_base = pCredBase;
  365.     authCred.oa_length = pCredLength;
  366.     /*
  367.      * Initialize hooks so that module loads and symbol additions send a
  368.      * message in the synchronization message queue.
  369.      */
  370.     taskLock ();
  371.     syncLoadRtn = (FUNCPTR) syncLoadHook;
  372.     syncUnldRtn = (FUNCPTR) syncUnldHook;
  373.     syncSymAddRtn = (FUNCPTR) syncSymAddHook;
  374.     syncSymRemoveRtn = (FUNCPTR) syncSymRemoveHook;
  375.     taskUnlock ();
  376.     tid = taskSpawn ("tSymSync", SYNC_PRIORITY, SYNC_OPTIONS, SYNC_STACK_SIZE,
  377.      symSyncTaskInit, (int)tgtSvrName, 0,0,0,0,0,0,0,0,0);
  378.     /* bring unknown target symbols to host symbol table */
  379.     sprintf (startSyncEvt, "%s 0x1 0x1", USR_RQST_EVT);
  380.     msgQSend (symSyncMsgQId, startSyncEvt, strlen(startSyncEvt)+1, TIMEOUT, 
  381.       MSG_PRI_NORMAL);
  382.     
  383.     return (tid);
  384.     }
  385. /******************************************************************************
  386. *
  387. * symSyncTaskInit - WTX initializations
  388. *
  389. * This routine initializes RPC then WTX, attaches to target server and 
  390. * registers for concerned events.
  391. * RETURNS: OK or ERROR.
  392. *
  393. * NOMANUAL
  394. */
  395. STATUS symSyncTaskInit
  396.     (
  397.     char * tgtSvrName /* target server name */
  398.     )
  399.     {
  400.     char  regEvtStr[50]; /* registered events */
  401.     WTX_HANDLER_T wtxErrHId;  /* error handler id */
  402.     strcpy (regEvtStr, "(OBJ_(LOAD|UNLOAD)|SYM_(ADD|REMOV))ED|SYNC_STOP");
  403.     /*
  404.      * initialize the synchronized group list : vxWorks symbols are always
  405.      * synchronized (group is 1 on target side and 1 on host side).
  406.      */
  407.     dllInit (&symSyncLst);
  408.     dllInit (&symSyncTmpLst);
  409.     groupAdd (&symSyncLst, 1, 1);
  410.     /* initialize the task access to the RPC package */
  411.     rpcTaskInit ();
  412.     /* initialize WTX session handle */
  413.     if (wtxInitialize (&symSyncHWtx) != WTX_OK)
  414. return (ERROR);
  415.     
  416.     wtxErrHId = wtxErrHandlerAdd (symSyncHWtx,
  417.   (WTX_HANDLER_FUNC)&syncErrHandler, 0);
  418.     if (wtxErrHId == NULL)
  419. {
  420. fprintf (stderr,
  421.  "Unable to initialize synchronization task. Giving up.n");
  422. wtxTerminate (symSyncHWtx);
  423. return (ERROR);
  424. }
  425.     /* attach to Target Server */
  426.     wtxToolAttach (symSyncHWtx, tgtSvrName, SYM_SYNC_TOOL_NAME);
  427.     /* set WTX timeout if necessary */
  428.     if (symSyncWtxTimeout != 0)
  429. wtxTimeoutSet (symSyncHWtx, symSyncWtxTimeout);
  430.     /* register for events */
  431.     wtxRegisterForEvent (symSyncHWtx, regEvtStr);
  432.     /* synchronize symbol tables */
  433.     symSyncMain (symSyncHWtx);
  434.     /* detach from target server */
  435.     wtxToolDetach (symSyncHWtx);
  436.     /* remove error handler */
  437.     wtxErrHandlerRemove (symSyncHWtx, wtxErrHId);
  438.     wtxTerminate (symSyncHWtx);
  439.     return (OK);
  440.     }
  441. /******************************************************************************
  442. *
  443. * symSyncMain - main routine
  444. *
  445. * This routine waits for target or host synchronization events and does the
  446. * corresponding job.
  447. *
  448. * RETURNS: OK or ERROR.
  449. *
  450. * NOMANUAL
  451. */
  452. STATUS symSyncMain 
  453.     (
  454.     HWTX hWtx
  455.     )
  456.     {
  457.     WTX_EVENT_DESC * pEvtDesc; /* event descriptor */
  458.     char  tgtEvtBuffer[SYNC_TGT_EVT_LGTH];
  459.     char  doneEvtBuffer[SYNC_TGT_EVT_LGTH];
  460.     symSyncKill = FALSE;
  461.     while (!symSyncKill)
  462. {
  463. if (msgQReceive (symSyncMsgQId, tgtEvtBuffer, SYNC_TGT_EVT_LGTH,
  464.  TIMEOUT) != ERROR)
  465.     {
  466. #ifdef DEBUG
  467.          logMsg ("tgt evt: %sn", (int)tgtEvtBuffer, 0, 0, 0, 0, 0);
  468. #endif
  469.     symSyncHostUpdate (hWtx, tgtEvtBuffer, doneEvtBuffer);
  470.     }
  471. else
  472.     {
  473.     if ((pEvtDesc = wtxEventGet (hWtx)) == NULL)
  474. continue; /* we got a timeout, may be better next time */
  475.     while (strcmp (pEvtDesc->event, "") != 0) /* no event received */
  476. {
  477. if (strcmp (pEvtDesc->event, "SYNC_STOP") == 0)
  478.          {
  479. #ifdef DEBUG
  480.     logMsg ("stop event receivedn", 0, 0, 0, 0, 0, 0);
  481. #endif
  482.     symSyncKill = TRUE;
  483.     break;
  484.     }
  485. else /* split event string and process it */
  486.     {
  487. #ifdef DEBUG 
  488.     logMsg ("tgtsvr evt: %sn", (int)pEvtDesc->event,0,0,0,0,0);
  489. #endif
  490.     symSyncTgtUpdate (hWtx, pEvtDesc->event, doneEvtBuffer);
  491.     wtxEventAdd (hWtx, doneEvtBuffer, 0, NULL);
  492.     }
  493. wtxResultFree (hWtx, pEvtDesc);
  494. if ((pEvtDesc = wtxEventGet (hWtx)) == NULL)
  495.     break; /* we got a timeout, giving up */
  496. }
  497.     if (pEvtDesc != NULL)
  498. wtxResultFree (hWtx, pEvtDesc);
  499.     }
  500. }
  501.     return (OK);
  502.     }
  503. /******************************************************************************
  504. *
  505. * groupAdd - add a group to a group list.
  506. *
  507. * RETURNS: OK if addition is possible, ERROR otherwise.
  508. *
  509. * NOMANUAL
  510. */
  511. STATUS groupAdd
  512.     (
  513.     DL_LIST * pList,
  514.     UINT16 tgtGroup,
  515.     UINT32 hostGroup
  516.     )
  517.     {
  518.     GROUP_NODE * pToAdd = (GROUP_NODE *) malloc (sizeof (GROUP_NODE));
  519.     if (pToAdd)
  520. {
  521. pToAdd->tgtGroup = tgtGroup;
  522. pToAdd->hostGroup = hostGroup;
  523. dllAdd (pList, (DL_NODE *)pToAdd);
  524. return (OK);
  525. }
  526.     return (ERROR);
  527.     }
  528. /******************************************************************************
  529. *
  530. * groupFind - find if a given group is in a group list
  531. *
  532. * This routine is used to know if a module is already synchronized. If its
  533. * target or host module's group is in the synchronized group list there is
  534. * nothing to do.
  535. *
  536. * RETURNS: a pointer on the GROUP_NODE found or NULL.
  537. *
  538. * NOMANUAL
  539. */
  540. GROUP_NODE * groupFind
  541.     (
  542.     DL_LIST * pList,
  543.     UINT32 group, /* module's group on host or target side */
  544.     FUNCPTR findRtn
  545.     )
  546.     {
  547.     GROUP_NODE * pGroup;
  548.     pGroup = (GROUP_NODE *) dllEach (pList, findRtn, (int)group);
  549.     return (pGroup);
  550.     }
  551. /******************************************************************************
  552. *
  553. * groupRemove - remove a group from a list
  554. *
  555. * RETURNS: a pointer on the group node removed or NULL.
  556. *
  557. * NOMANUAL
  558. */
  559. GROUP_NODE * groupRemove
  560.     (
  561.     DL_LIST * pList,
  562.     UINT32 group,
  563.     FUNCPTR findRtn
  564.     )
  565.     {
  566.     GROUP_NODE * pGroup = groupFind (pList, group, findRtn);
  567.     if (pGroup)
  568. dllRemove (pList, (DL_NODE *)pGroup);
  569.     return (pGroup);
  570.     }
  571. /******************************************************************************
  572. *
  573. * syncGroupUpdate - update <symSyncLst> with elements of <symSyncTmpLst>
  574. *
  575. * <symSyncTmpLst> is used as a buffer to indicate when we are bringing
  576. * target symbols to host, that target module info were already synchronized
  577. * while symbols are not. When every symbols are synchronized then modules 
  578. * of <symSyncTmpLst> can be considered as synchronized.
  579. *
  580. * RETURNS: N/A.
  581. *
  582. * NOMANUAL
  583. */
  584. void syncGroupUpdate ()
  585.     {
  586.     GROUP_NODE * pToAdd = (GROUP_NODE *) dllGet (&symSyncTmpLst);
  587.     while (pToAdd != NULL)
  588. {
  589. if (groupFind (&symSyncLst, pToAdd->tgtGroup, 
  590. (FUNCPTR)isInTgtGroupList) == NULL)
  591.     dllAdd (&symSyncLst, (DL_NODE *)pToAdd);
  592. else 
  593.     free (pToAdd);
  594. pToAdd = (GROUP_NODE *) DLL_NEXT (pToAdd);
  595. }
  596.     }
  597. /******************************************************************************
  598. *
  599. * isInHostGroupList - check a given host group is in the list.
  600. *
  601. * RETURNS: TRUE if we should examine next element, FALSE otherwise.
  602. *
  603. * NOMANUAL
  604. */
  605. BOOL isInHostGroupList
  606.     (
  607.     DL_NODE * pNode,
  608.     int arg
  609.     )
  610.     {
  611.     if (((GROUP_NODE *)pNode)->hostGroup == (UINT32)arg)
  612. return (FALSE);
  613.     return (TRUE);
  614.     }
  615. /******************************************************************************
  616. *
  617. * isInTgtGroupList - check a given target group is in the list.
  618. *
  619. * RETURNS: TRUE if we should examine next element, FALSE otherwise.
  620. *
  621. * NOMANUAL
  622. */
  623. BOOL isInTgtGroupList
  624.     (
  625.     DL_NODE * pNode,
  626.     int arg
  627.     )
  628.     {
  629.     if (((GROUP_NODE *)pNode)->tgtGroup == arg)
  630. return (FALSE);
  631.     return (TRUE);
  632.     }
  633. /* HOST ----> TARGET */
  634. /******************************************************************************
  635. *
  636. * symSyncTgtUpdate - update target symbol table
  637. *
  638. * This routine parses and dispatches the target events received.
  639. *
  640. * RETURNS: OK or ERROR.
  641. *
  642. * NOMANUAL
  643. */
  644. STATUS symSyncTgtUpdate
  645.     (
  646.     HWTX hWtx, /* WTX API handle */
  647.     char * evtString, /* event received */
  648.     char * doneEvt  /* event sent when sync is done */
  649.     )
  650.     {
  651.     char * evtType;
  652.     char * info[3];
  653.     char * pLast = NULL;
  654.     STATUS status = OK;
  655.     evtType = strtok_r (evtString, " ", &pLast);
  656.     if (strcmp (evtType, OBJ_LOADED_EVT) == 0)
  657. {
  658. /* get the host module Id from the event string */
  659. info[0] = strtok_r (NULL, " ", &pLast); /* module Id */
  660. info[1] = strtok_r (NULL, " ", &pLast); /* module name */
  661. status = syncModCTgtUpdate (hWtx, H_STR_TO_L(info[0]));
  662. }
  663.     else if (strcmp (evtType, OBJ_UNLOADED_EVT) == 0)
  664. {
  665. /* get the host module group from the event string */
  666. info[0] = strtok_r (NULL, " ", &pLast); /* module id */
  667. info[1] = strtok_r (NULL, " ", &pLast); /* module name */
  668. info[2] = strtok_r (NULL, " ", &pLast); /* module group */
  669. status = syncModDTgtUpdate (hWtx, H_STR_TO_L(info[2]));
  670. }
  671.     else if (strcmp (evtType, SYM_ADDED_EVT) == 0)
  672. {
  673. info[1] = strtok_r (NULL, " ", &pLast); /* symbol name */
  674. status = syncSymAddTgtUpdate (hWtx, info[1]);
  675. }
  676.     else if (strcmp (evtType, SYM_REMOVED_EVT) == 0)
  677. {
  678. info[1] = strtok_r (NULL, " ", &pLast); /* symbol name */
  679. info[0] = strtok_r (NULL, " ", &pLast); /* symbol type */
  680. status = symSRemove (sysSymTbl, info[1], H_STR_TO_L(info[0]));
  681. }
  682.     else 
  683. return (OK);
  684.     if (strlen (info[1]) > OBJ_NAME_MAX)
  685. info[1][OBJ_NAME_MAX - 1] = '';
  686.     sprintf (doneEvt, "SYNC_DONE t %s %s %d", evtType, info[1], status);
  687.     return (status);
  688.     }
  689. /******************************************************************************
  690. *
  691. * syncModCTgtUpdate - update target info when a module is created on host
  692. *
  693. * RETURNS: OK or ERROR
  694. *
  695. * NOMANUAL
  696. */
  697. STATUS syncModCTgtUpdate
  698.     (
  699.     HWTX hWtx, /* WTX API handle */
  700.     UINT32 id /* host module id */
  701.     )
  702.     {
  703.     WTX_MODULE_INFO * pModInfo; /* host module informations */
  704.     MODULE_ID modId; /* target module Id */
  705.     WTX_SYM_LIST * pSymList; /* symbols of the module */
  706.     WTX_SYMBOL * pSymInfo;
  707.     STATUS status = OK;
  708.     /* Get the module info from the host and update target side */
  709.     if ((pModInfo = wtxObjModuleInfoGet (hWtx, id)) == NULL)
  710. return (ERROR);
  711.     /* check if the module was previously synchronized */
  712.     if (groupFind (&symSyncLst, pModInfo->group, isInHostGroupList) != NULL)
  713. {
  714. wtxResultFree (hWtx, pModInfo);
  715. return (OK);
  716. }
  717.     
  718.     /* create the new target module */
  719.     if ((modId = syncTgtModInfoFill (pModInfo)) == NULL)
  720. {
  721. wtxResultFree (hWtx, pModInfo);
  722. return (ERROR);
  723. }
  724.     /* get symbols from the tgtsvr and add them in target symTbl */
  725.     if ((pSymList = wtxSymListGet (hWtx, NULL, pModInfo->moduleName,
  726.    0, FALSE)) == NULL)
  727. {
  728. /* the module no longer exists on target */
  729. moduleDelete (modId);
  730. wtxResultFree (hWtx, pModInfo);
  731. return (ERROR);
  732. }
  733.     pSymInfo = pSymList->pSymbol;
  734.     while ((pSymInfo != NULL) && (status == OK))
  735. {
  736. status = symSAdd (sysSymTbl, pSymInfo->name, (char *)pSymInfo->value,
  737.   pSymInfo->type, modId->group);
  738. pSymInfo = pSymInfo->next;
  739. }
  740.     /* update synchronized group list */
  741.     groupAdd (&symSyncLst, modId->group, pModInfo->group);
  742.     wtxResultFree (hWtx, pSymList);
  743.     wtxResultFree (hWtx, pModInfo);
  744.     return (status);
  745.     }
  746. /******************************************************************************
  747. *
  748. * syncModDTgtUpdate - update target info when a module is deleted on host
  749. *
  750. * RETURNS: OK or ERROR
  751. *
  752. * NOMANUAL
  753. */
  754. STATUS syncModDTgtUpdate
  755.     (
  756.     HWTX hWtx,  /* WTX API handler */
  757.     UINT32 group /* group (on host) of the deleted module */
  758.     )
  759.     {
  760.     STATUS status = OK;
  761.     MODULE_ID modId; /* target module Id */
  762.     GROUP_NODE * pGroup; /* group node of the module */
  763.     /* remove the module from the synchronized group list */
  764.     if ((pGroup = groupRemove (&symSyncLst, group, 
  765.        (FUNCPTR)isInHostGroupList)) == NULL)
  766. return (ERROR);
  767.     /* unload the module on target side */
  768.     if ((modId = moduleFindByGroup (pGroup->tgtGroup)) != NULL)
  769. status = unldByModuleId (modId, UNLD_SYNC);
  770.     free (pGroup);
  771. #ifdef DEBUG
  772.     if (status == ERROR)
  773. fprintf (stderr, "unload pbn");
  774. #endif
  775.     return (status);
  776.     }
  777. /******************************************************************************
  778. *
  779. * syncSymAddTgtUpdate - update target symbol table when a symbol is added
  780. *
  781. * RETURNS: OK or ERROR
  782. *
  783. * NOMANUAL
  784. */
  785. STATUS syncSymAddTgtUpdate
  786.     (
  787.     HWTX hWtx, /* WTX API handle */
  788.     char * symName /* symbol name */
  789.     )
  790.     {
  791.     GROUP_NODE * pGroup; /* group node of the module */
  792.     WTX_SYMBOL * pSymInfo;
  793.     UINT16  tgtGroup;
  794.     STATUS  status = OK;
  795.     if ((pSymInfo = wtxSymFind (hWtx, symName, 0, TRUE, 0, 0)) == NULL)
  796. return (ERROR);
  797.     /* 
  798.      * get the corresponding target group 
  799.      * the default group number (0) is the same on host and target
  800.      */
  801.     if ((tgtGroup = pSymInfo->group) != 0)
  802. {
  803. if ((pGroup = groupFind (&symSyncLst, pSymInfo->group,
  804.  (FUNCPTR)isInHostGroupList)) == NULL)
  805.     /* XXX ELP inexistant group set to 0 */
  806.     tgtGroup = 0;
  807. tgtGroup = pGroup->tgtGroup;
  808. }
  809.     status = symSAdd (sysSymTbl, pSymInfo->name, (char *)pSymInfo->value,
  810.       pSymInfo->type, tgtGroup);
  811.     wtxResultFree (hWtx, pSymInfo);
  812.     return (status);
  813.     }
  814. /******************************************************************************
  815. *
  816. * syncTgtModInfoFill - fill target module information
  817. *
  818. * From a host module descriptor we get the information to store on the target
  819. * side.
  820. *
  821. * note: flag LOAD_LOADED_BY_TGTSVR is set in order we know that if the
  822. * target-server restarts these modules become obsolete.
  823. * note: To prevent from displaying 0xffffffff on target moduleShow(), segment
  824. * address is set to 0 when the segment does not exist.
  825. * note: The segment flag SEG_FREE_MEMORY is removed to prevent the memory from
  826. * being freed twice when unloading (1 by host and 1 by target).
  827. *
  828. * RETURNS: target module Id or NULL.
  829. *
  830. * NOMANUAL
  831. */
  832. MODULE_ID syncTgtModInfoFill
  833.     (
  834.     WTX_MODULE_INFO *   pModInfo
  835.     )
  836.     {
  837.     MODULE_ID modId;
  838.     int format = -1;
  839.     int flags = 0;
  840.     int segType;
  841.     int segAddr;
  842.     int ix;
  843.     STATUS status = OK;
  844.     /* tarnslate host format into target format */
  845.     
  846.     if (strcmp (pModInfo->format, "a.out") == 0)
  847. format = MODULE_A_OUT;
  848.     else if (strcmp (pModInfo->format, "coff") == 0)
  849. format = MODULE_ECOFF;
  850.     else if (strcmp (pModInfo->format, "elf") == 0)
  851. format = MODULE_ELF;
  852.     /* translate host load flags into target host flags */
  853.     if (pModInfo->loadFlag & 0x1)
  854. flags |= LOAD_NO_SYMBOLS;
  855.     if (pModInfo->loadFlag & 0x2)
  856. flags |= LOAD_LOCAL_SYMBOLS;
  857.     if (pModInfo->loadFlag & 0x4)
  858. flags |= LOAD_GLOBAL_SYMBOLS;
  859.     flags |= (pModInfo->loadFlag & 0x00fffff0);
  860.     flags |= LOAD_LOADED_BY_TGTSVR;
  861.     /* create the module on the target */
  862.     if ((modId = moduleCreate (pModInfo->moduleName, format, flags)) == NULL)
  863. return (NULL);
  864.     /* add the segments */
  865.     
  866.     for (ix = 0; (ix < pModInfo->nSegments) && (status == OK); ix++)
  867. {
  868. switch (ix)
  869.     {
  870.     case 0: segType = SEGMENT_TEXT; break;
  871.     case 1: segType = SEGMENT_DATA; break; 
  872.     case 2: segType = SEGMENT_BSS; break;
  873. #ifdef INCLUDE_SDA
  874.     case 3: segType = SEGMENT_SDATA; break;
  875.     case 4: segType = SEGMENT_SBSS; break;
  876.     case 5: segType = SEGMENT_SDATA2; break;
  877.     case 6: segType = SEGMENT_SBSS2; break;
  878. #endif
  879.     default: segType = -1; break;
  880.     }
  881. segAddr = ((int)pModInfo->segment[ix].addr != -1) ?
  882.   (int)pModInfo->segment[ix].addr : 0;
  883. status = moduleSegAdd (modId, segType, (void *)segAddr,
  884.        pModInfo->segment[ix].length,
  885.       (pModInfo->segment[ix].flags & ~SEG_FREE_MEMORY));
  886. }
  887.     if (status == OK)
  888. return (modId);
  889.     else 
  890. {
  891. moduleDelete (modId);
  892. return (NULL);
  893. }
  894.     }
  895. /* TARGET ----> HOST  */
  896. /******************************************************************************
  897. *
  898. * symSyncHostUpdate -  update host side depending on <evtString>
  899. *
  900. * This routine dispatch the WTX events received from the target server
  901. *
  902. * RETURNS:
  903. *
  904. * NOMANUAL
  905. */
  906. STATUS symSyncHostUpdate
  907.     (
  908.     HWTX hWtx, /* WTX API handle */
  909.     char * evtString, /* event received */
  910.     char * doneEvt /* event sent when sync is done */
  911.     )
  912.     {
  913.     char * pLast = NULL;
  914.     STATUS status = OK;
  915.     char * evtType; /* synchronization event type */
  916.     char * info[4]; /* store event tokens */
  917.     BOOL eventSend = TRUE;
  918.     evtType = strtok_r (evtString, " ", &pLast);
  919.     if (strcmp (evtType, OBJ_LOADED_EVT) == 0)
  920. {
  921. info[1] = strtok_r (NULL, " ", &pLast);  /* module id */
  922. info[0] = strtok_r (NULL, " ", &pLast);  /* module name */
  923. status = syncModCHostUpdate (hWtx, &symSyncLst,
  924.      (MODULE_ID)H_STR_TO_L(info[1]),
  925.      &eventSend, TRUE);
  926. }
  927.     else if (strcmp (evtType, OBJ_UNLOADED_EVT) == 0)
  928. {
  929. info[0] = strtok_r (NULL, " ", &pLast); /* mod name */
  930. info[1] = strtok_r (NULL, " ", &pLast); /* mod group */
  931. status = syncModDHostUpdate (hWtx, info[0], H_STR_TO_L(info[1]));
  932. }
  933.     else if (strcmp (evtType, SYM_ADDED_EVT) == 0)
  934. {
  935. info[0] = strtok_r (NULL, " ", &pLast); /* sym name */
  936. info[1] = strtok_r (NULL, " ", &pLast); /* sym val */
  937. info[2] = strtok_r (NULL, " ", &pLast); /* sym type */
  938. info[3] = strtok_r (NULL, " ", &pLast); /* sym group */
  939. status = syncSymAddHostUpdate (hWtx, info[0],
  940.    (char *)H_STR_TO_L(info[1]),
  941.    H_STR_TO_L(info[2]), H_STR_TO_L(info[3]));
  942. }
  943.     else if (strcmp (evtType, SYM_REMOVED_EVT) == 0)
  944. {
  945. info[0] = strtok_r (NULL, " ", &pLast); /* sym name */
  946. info[1] = strtok_r (NULL, " ", &pLast); /* sym type */
  947. status = syncSymRemHostUpdate (hWtx, info[0], H_STR_TO_L(info[1]));
  948. }
  949.     else if (strcmp (evtType, USR_RQST_EVT) == 0)
  950. {
  951. info[0] = "target_modules";
  952. info[1] = strtok_r (NULL, " ", &pLast); /* sense */
  953. info[2] = strtok_r (NULL, " ", &pLast); /* starting tgtsvr? */
  954. status = syncUsrUpdate (hWtx, H_STR_TO_L(info[1]), H_STR_TO_L(info[2]));
  955. }
  956.     else 
  957. {
  958. #ifdef DEBUG
  959. logMsg ("unknown target eventn", 0, 0, 0, 0, 0, 0);
  960. #endif
  961. return (OK);
  962. }
  963.     if (eventSend)
  964. {
  965. if (strlen (info[0]) > OBJ_NAME_MAX)
  966.     info[0][OBJ_NAME_MAX - 1] = '';
  967. sprintf (doneEvt, "SYNC_DONE h %s %s %d", evtType, info[0], status);
  968. wtxEventAdd (hWtx, doneEvt, 0, NULL);
  969. }
  970.     return (status);
  971.     }
  972. /******************************************************************************
  973. *
  974. * syncModCHostUpdate - update host side when a module is created on target
  975. *
  976. * This routine creates a module on the host with the same information than on
  977. * the target (except group number). If <addSym> is TRUE the routine looks for
  978. * the symbol of that module and add them in the host symbol table, otherwise
  979. * symbols are not added here.
  980. *
  981. * RETURNS:
  982. *
  983. * NOMANUAL
  984. */
  985. STATUS syncModCHostUpdate
  986.     (
  987.     HWTX hWtx, /* WTX API handle */
  988.     DL_LIST * pList, /* where to add the synchronized module */
  989.     MODULE_ID modId, /* target module Id */
  990.     BOOL * pEventSend, /* send back an event when synchro is done */
  991.     BOOL addSym /* add module's symbol or not */
  992.     )
  993.     {
  994.     STATUS status = OK; /* synchro status */
  995.     WTX_LD_M_FILE_DESC in; /* host mod creation input */
  996.     WTX_LD_M_FILE_DESC * pObjInfo; /* object file info */
  997.     WTX_MODULE_INFO * pModInfo; /* host module info */
  998.     BY_GROUP_ARG_T  modFind;
  999.     MODULE sMod; /* stored module */
  1000.     /* store module information to get them safely later */
  1001.     taskLock();
  1002.     if (OBJ_VERIFY (modId, moduleClassId) == OK)
  1003. memcpy (&sMod, modId, sizeof(MODULE));
  1004.     else 
  1005. {
  1006. taskUnlock ();
  1007. return (ERROR);
  1008. }
  1009.     taskUnlock();
  1010.     /* check if the module was previously synchronized */
  1011.     
  1012.     if (groupFind (&symSyncLst, sMod.group, isInTgtGroupList) != NULL)
  1013. {
  1014. /* we do not send an event to tgtsvr because no work is performed */
  1015. *pEventSend = FALSE;
  1016. return (OK);
  1017. }
  1018.     /* prepare host module creation */
  1019.     if (syncHostModInfoFill (&in, &sMod, TRUE) == ERROR)
  1020. return (ERROR);
  1021.     /* create the host module (flag LOAD_MODULE_INFO_ONLY is set) */
  1022.     if ((pObjInfo = wtxObjModuleLoad (hWtx, &in)) == NULL)
  1023. {
  1024. free (in.filename);
  1025. free (in.section);
  1026. return (ERROR);
  1027. }
  1028.     free (in.filename);
  1029.     free (in.section);
  1030.     /* get newly created host module information */
  1031.     
  1032.     if ((pModInfo = wtxObjModuleInfoGet (hWtx, pObjInfo->moduleId)) == NULL)
  1033. {
  1034. wtxResultFree (hWtx, pObjInfo);
  1035. return (ERROR);
  1036. }
  1037.     
  1038.     /* add the module in the synchronized group list */
  1039.     
  1040.     groupAdd (pList, sMod.group, pModInfo->group);
  1041.     if (addSym)
  1042. {
  1043. /* add the symbols of the new module */
  1044.     /* 
  1045.      * XXX ELP there is no routine that returns a symbol list as tgtsvr does.
  1046.      * The solution is to go through the whole symTbl and add the concerned 
  1047.      * symbols one by one. Building a list and sending it once should be faster.
  1048.      */
  1049.      modFind.hWtx = hWtx;
  1050. modFind.tgtGroup = sMod.group;
  1051. modFind.hostGroup = pModInfo->group;
  1052. if (symEach (sysSymTbl, (FUNCPTR)syncSymByGrpToHost, (int)&modFind)
  1053.     != NULL)
  1054.     /* because of an error we did not go through the all list */
  1055.     status = ERROR;
  1056. }
  1057.     wtxResultFree (hWtx, pObjInfo);
  1058.     wtxResultFree (hWtx, pModInfo);
  1059.     return (status);
  1060.     }
  1061. /******************************************************************************
  1062. *
  1063. * syncModDHostUpdate - upadte host side when a module is deleted on target
  1064. *
  1065. * RETURNS:
  1066. *
  1067. * NOMANUAL
  1068. */
  1069. STATUS syncModDHostUpdate
  1070.     (
  1071.     HWTX hWtx, /* WTX API handle */
  1072.     char * modName, /* name of the deleted module */
  1073.     UINT16 modGroup /* group of the deleted module */
  1074.     )
  1075.     {
  1076.     GROUP_NODE * pGroup;
  1077.     UINT32 moduleId = 0;
  1078.     /* remove the module from the synchronized group list */
  1079.     if ((pGroup = groupRemove (&symSyncLst, modGroup , isInTgtGroupList))
  1080. == NULL)
  1081. return (OK);
  1082.     free (pGroup);
  1083.     /* check to see if the module should be unloaded on host side */
  1084.     moduleId = wtxObjModuleFindId (hWtx, modName);
  1085.     if (moduleId)
  1086. wtxObjModuleUnload (hWtx, moduleId);
  1087.     
  1088.     return (OK);
  1089.     }
  1090. /******************************************************************************
  1091. *
  1092. * syncSymAddHostUpdate - update host symTbl when a symbol is added on target
  1093. *
  1094. * RETURNS: 
  1095. *
  1096. * NOMANUAL
  1097. */
  1098. STATUS syncSymAddHostUpdate
  1099.     (
  1100.     HWTX hWtx, /* WTX API handle */
  1101.     char * name, /* symbol name */
  1102.     char * val, /* symbol value */
  1103.     SYM_TYPE type, /* symbol type */
  1104.     UINT16 group /* symbol group */
  1105.     )
  1106.     {
  1107.     GROUP_NODE * pGroup;
  1108.     UINT32 hGroup;
  1109.     MODULE_ID modId;
  1110.     STATUS status = OK;
  1111.     BOOL  eventSend = TRUE;
  1112.     char  buf[SYNC_TGT_EVT_LGTH];
  1113.     char  doneEvt[SYNC_TGT_EVT_LGTH];
  1114.     /* find the corresponding host group */
  1115.     if (group == symGroupDefault)
  1116. hGroup = 0; 
  1117.     else if ((pGroup = groupFind (&symSyncLst, group,
  1118.   (FUNCPTR)isInTgtGroupList)) != NULL)
  1119. hGroup = pGroup->hostGroup;
  1120.     else
  1121. {
  1122. /* symbol's group is unknown on host side */
  1123. if ((modId = moduleFindByGroup (group)) == NULL)
  1124.     hGroup = 0; /* XXX ELP */
  1125. else 
  1126.     {
  1127.     /*
  1128.      * it seems very hard to come here but... we answer we failed
  1129.      * and try to load the unsynchronized module.
  1130.      */
  1131.      
  1132.     memset (buf, 0, SYNC_TGT_EVT_LGTH);
  1133.     taskLock();
  1134.     if (OBJ_VERIFY (modId, moduleClassId) == OK)
  1135. {
  1136. strncpy (buf, modId->name, SYNC_TGT_EVT_LGTH - 1);
  1137. buf[SYNC_TGT_EVT_LGTH - 1] = EOS;
  1138. }
  1139.     taskUnlock();
  1140.     status = syncModCHostUpdate (hWtx, &symSyncLst, modId, &eventSend,
  1141.  FALSE);
  1142.     if (eventSend)
  1143. {
  1144. if (strlen (buf) > OBJ_NAME_MAX)
  1145.     buf [OBJ_NAME_MAX - 1] = '';
  1146. sprintf (doneEvt, "SYNC_DONE h OBJ_LOADED %s %d", buf,
  1147.  status);
  1148. wtxEventAdd (hWtx, doneEvt, 0, NULL);
  1149. }
  1150.     return (status);
  1151.     }
  1152. }
  1153.     if (wtxSymAddWithGroup (hWtx, name, (TGT_ADDR_T)val, type, hGroup)
  1154. == WTX_ERROR)
  1155. status = ERROR;
  1156.     return (status);
  1157.     }
  1158. /******************************************************************************
  1159. *
  1160. * syncSymRemHostUpdate - update host symTbl when a target symbol is removed
  1161. * This routine is called if the target remove a symbol.
  1162. *
  1163. * RETURNS: OK or ERROR.
  1164. *
  1165. * NOMANUAL
  1166. */
  1167. STATUS syncSymRemHostUpdate
  1168.     (
  1169.     HWTX hWtx, /* WTX API handle */
  1170.     char * symName, /* symbol name */
  1171.     SYM_TYPE symType /* symbol type */
  1172.     )
  1173.     {
  1174.     STATUS status = OK;
  1175.     if (wtxSymRemove (hWtx, symName, symType) == WTX_ERROR)
  1176. status = ERROR;
  1177.     return (status);
  1178.     }
  1179. /******************************************************************************
  1180. *
  1181. * syncUsrUpdate - update target from host and host from target
  1182. *
  1183. * This routine is called when the user asks for it.
  1184. * if <sense> is 1 then synchronization is done from target to host.
  1185. *
  1186. * the following is unused
  1187. * if <sense> is 2 then synchronization is done from host to target. 
  1188. * if <sense> is 0 then both synchronization are performed. 
  1189. * <toolId> is used to identify the tool that requested for synchronization
  1190. *
  1191. * note: host symbols that don't belong to a module are not synchronized.
  1192. *
  1193. * RETURNS: OK or ERROR.
  1194. *
  1195. * NOMANUAL
  1196. */
  1197. STATUS syncUsrUpdate
  1198.     (
  1199.     HWTX hWtx, /* WTX API handle */
  1200.     int sense, /* synchronization sense */
  1201.     int start /* TRUE if the target server is starting */
  1202.     )
  1203.     {
  1204.     WTX_MODULE_LIST * pModList;
  1205.     STATUS status = OK;
  1206.     int ix;
  1207.     char evtBuf[60];
  1208.     if ((sense == 0) || (sense == 1))
  1209.      {
  1210. /*
  1211.  * Check every modules that will be synchronized are target modules.
  1212.  * Otherwise the target server may have restarted, thus it considers
  1213.  * segments are no more allocated!
  1214.  */
  1215. if (start)
  1216.     {
  1217.     moduleEach (syncTgtSafeModCheck, (int) hWtx);
  1218.     }
  1219. /* process each symbol of the target symbol table */
  1220. if (OBJ_VERIFY (sysSymTbl, symTblClassId) == OK)
  1221.     {
  1222.     if (symEach (sysSymTbl, (FUNCPTR)syncEachSymToHost,
  1223.  (int)hWtx) != NULL)
  1224. return (ERROR);
  1225.     /* add modules that was not yet in the sync group list */
  1226.     syncGroupUpdate ();
  1227.     }
  1228. }
  1229.     if ((sense == 0) || (sense == 2))
  1230. {
  1231. pModList = wtxObjModuleList (hWtx);
  1232. for (ix = 0;
  1233.      (pModList != NULL) && (status == OK) && (ix < pModList->numObjMod);
  1234.      ix++)
  1235.     status = syncModCTgtUpdate (hWtx, pModList->modIdList[ix]);
  1236. wtxResultFree (hWtx, pModList);
  1237. sprintf (evtBuf, "SYNC_DONE t USR_RQST target_modules %d", status);
  1238. wtxEventAdd (hWtx, evtBuf, 0, NULL);
  1239. }
  1240.     return (status);
  1241.     }
  1242. /******************************************************************************
  1243. *
  1244. * syncTgtSafeModCheck - check if a target module can be safely used
  1245. *
  1246. * If synchronization is running, modules loaded by the target-server are added
  1247. * to the target side. Then, if the target-server restarts (without rebooting)
  1248. * these modules seem to be loaded on target side while memory is no more 
  1249. * allocated. This routine unloads such modules (it is not possible to
  1250. * automatically reload them because we do not have the path of the file). 
  1251. *
  1252. * RETURNS: TRUE to go through the whole module list, FALSE if an error occured.
  1253. *
  1254. * NOMANUAL
  1255. */
  1256. BOOL syncTgtSafeModCheck
  1257.     (
  1258.     MODULE_ID moduleId,
  1259.     int arg /* WTX API handle */
  1260.     )
  1261.     {
  1262.     /*
  1263.      * if the module is loaded by target server and it is no more in
  1264.      * synchronization list then it is a "zombie" module.
  1265.      */
  1266.     if ((moduleId->flags & LOAD_LOADED_BY_TGTSVR) &&
  1267. (groupFind (&symSyncLst, moduleId->group, isInTgtGroupList) == NULL))
  1268. unldByModuleId (moduleId, UNLD_SYNC);
  1269.     return (TRUE);
  1270.     }
  1271. /******************************************************************************
  1272. *
  1273. * syncEachSymToHost - update the host symbol table if needed
  1274. *
  1275. * This routine examine a symbol to know if it should be added in host symTbl.
  1276. *
  1277. * RETURNS: TRUE if we should go to next symbol, FALSE otherwise.
  1278. *
  1279. * NOMANUAL
  1280. */
  1281. BOOL syncEachSymToHost
  1282.     (
  1283.     char *      name,   /* entry name */
  1284.     int         val,    /* value associated with entry */
  1285.     SYM_TYPE    type,   /* entry type */
  1286.     int         arg,    /* wtx API handle */
  1287.     UINT16      group   /* group number (on target side) */
  1288.     )
  1289.     {
  1290.     HWTX                        hWtx = (HWTX)arg; /* wtx API handle */
  1291.     MODULE_ID                   modId; /* target module Id */
  1292.     GROUP_NODE *                pGroup;
  1293.     UINT32 hGroup;
  1294.     WTX_SYMBOL * pSymbol;
  1295.     BOOL dummy;
  1296.     if (groupFind (&symSyncLst, group, (FUNCPTR)isInTgtGroupList) != NULL)
  1297. /* this module is already synchronized */
  1298. return TRUE;
  1299.     if (group == symGroupDefault)
  1300. {
  1301. /* XXX ELP, 2 possibilities 
  1302.  * 1. we do not synchronize these symbols in forced mode since we do
  1303.  *    not know if it was already done before. 
  1304.  * 2. we examine host symbol table to see if the symbol is already
  1305.  *    existing. if so we return, otherwise we add it.
  1306.  * choose 2
  1307.  */
  1308. hGroup = 0;
  1309. if ((pSymbol = wtxSymFind (hWtx, name, 0, TRUE, type, N_TYPE))
  1310.     != NULL)
  1311.     {
  1312.     if ((pSymbol->value == val) && (pSymbol->group == hGroup))
  1313. {
  1314. wtxResultFree (hWtx, pSymbol);
  1315. return (TRUE);
  1316. }
  1317.     wtxResultFree (hWtx, pSymbol);
  1318.     }
  1319. }
  1320.     else if ((pGroup = groupFind (&symSyncTmpLst, group, 
  1321.   (FUNCPTR)isInTgtGroupList)) == NULL)
  1322. {
  1323. /* this module is unknown on host, we must add it */
  1324. if ((modId = moduleFindByGroup (group)) == NULL)
  1325.     return (FALSE);
  1326. if (syncModCHostUpdate (hWtx, &symSyncTmpLst, modId, &dummy, FALSE)
  1327.     == ERROR)
  1328.     return (FALSE);
  1329. if ((pGroup = groupFind (&symSyncTmpLst, group,
  1330.  (FUNCPTR)isInTgtGroupList)) == NULL)
  1331.     return (FALSE);
  1332. hGroup = pGroup->hostGroup;
  1333. }
  1334.     else
  1335. hGroup = pGroup->hostGroup;
  1336.     /* add the symbol */
  1337.     
  1338.     if (wtxSymAddWithGroup (hWtx, name, (TGT_ADDR_T)val, type, hGroup)
  1339. != WTX_OK)
  1340. return (FALSE);
  1341.    
  1342.     /* if it is an undefined symbol, update the corresponding module info */
  1343.     if (type == N_UNDF)
  1344. {
  1345. if (wtxObjModuleUndefSymAdd (hWtx, name, hGroup) != WTX_OK)
  1346.     return (FALSE);
  1347. }
  1348.     
  1349.     return (TRUE);
  1350.     }
  1351. /******************************************************************************
  1352. *
  1353. * syncSymByGrpToHost - update host symbol table with symbols of a given group
  1354. *
  1355. * This routine examine each symbol of a given group to know if it should be
  1356. * added in host symTbl.
  1357. *
  1358. * RETURNS: TRUE if we should examine the next symbol, FALSE otherwise.
  1359. *
  1360. * NOMANUAL
  1361. */
  1362. BOOL syncSymByGrpToHost
  1363.     (
  1364.     char *      name,   /* entry name */
  1365.     int         val,    /* value associated with entry */
  1366.     SYM_TYPE    type,   /* entry type */
  1367.     int         arg,    /* wtx API handle, host and target groups */
  1368.     UINT16      group   /* group number (on target side) */
  1369.     )
  1370.     {
  1371.     BY_GROUP_ARG_T * pArg = (BY_GROUP_ARG_T *)arg;
  1372.     if (group != pArg->tgtGroup)
  1373. return (TRUE);
  1374.     if (wtxSymAddWithGroup (pArg->hWtx, name, (TGT_ADDR_T)val, type,
  1375.     pArg->hostGroup) == WTX_ERROR)
  1376. return (FALSE);
  1377.     /* if it is an undefined symbol, update the corresponding module info */
  1378.     if (type == N_UNDF)
  1379. {
  1380. if (wtxObjModuleUndefSymAdd (pArg->hWtx, name, pArg->hostGroup)
  1381.     == WTX_ERROR)
  1382.     return (FALSE);
  1383. }
  1384.     
  1385.     return (TRUE);
  1386.     }
  1387. /******************************************************************************
  1388. *
  1389. * syncHostModInfoFill - fill a host module descriptor from a target MODULE_ID
  1390. * This routine creates a module on host side with the information provided by 
  1391. * the target module identifier.
  1392. * note: if <synchro> is TRUE, loadFlag LOAD_MODULE_INFO_ONLY is set to indicate
  1393. * that the module is already loaded so wtxObjModuleLoad() will not do it
  1394. * again.
  1395. * note: segment flag is always unset to prevent segment memory from being freed
  1396. * twice when unloading module (1 on target and 1 on host).
  1397. *
  1398. * RETURNS: OK or ERROR
  1399. *
  1400. * NOMANUAL
  1401. */
  1402. STATUS syncHostModInfoFill
  1403.     (
  1404.     WTX_LD_M_FILE_DESC * pFileDesc,
  1405.     MODULE_ID modId,
  1406.     BOOL synchro
  1407.     )
  1408.     {
  1409.     char * fileNameBuf = NULL;
  1410.     SEGMENT_ID segId;
  1411.     int ix;
  1412.     memset (pFileDesc, 0, sizeof(WTX_LD_M_FILE_DESC));
  1413.     
  1414.     if ((fileNameBuf = malloc (PATH_MAX + NAME_MAX)) == NULL)
  1415. return (ERROR);
  1416.     sprintf (fileNameBuf, "%s/%s", modId->path, modId->name);
  1417.     pFileDesc->filename = fileNameBuf;
  1418.     pFileDesc->moduleId = 0;
  1419.     /*
  1420.      * undefined symbol list is initialized empty at first,
  1421.      * if undefined symbol are found when going through symbol table they are
  1422.      * added in this list
  1423.      */
  1424.     
  1425.     pFileDesc->undefSymList.pSymbol = NULL;
  1426.     /* translate target module flags into host module flag */
  1427.     if (modId->flags & LOAD_NO_SYMBOLS)
  1428. pFileDesc->loadFlag |= 0x1;
  1429.     if (modId->flags & LOAD_LOCAL_SYMBOLS)
  1430. pFileDesc->loadFlag |= 0x2;
  1431.     if (modId->flags & LOAD_GLOBAL_SYMBOLS)
  1432. pFileDesc->loadFlag |= 0x4;
  1433.     pFileDesc->loadFlag |= (modId->flags & HIDDEN_MODULE);
  1434.     if (!synchro)
  1435. {
  1436. /* we want to load the file, letting target-server decide where */
  1437. pFileDesc->nSections = 0;
  1438. return (OK);
  1439. }
  1440.     pFileDesc->loadFlag |= LOAD_MODULE_INFO_ONLY;
  1441.     pFileDesc->nSections = dllCount (&modId->segmentList);
  1442.     if ((pFileDesc->section = (LD_M_SECTION *)
  1443.  malloc (pFileDesc->nSections * sizeof (LD_M_SECTION))) == NULL)
  1444. {
  1445. free (fileNameBuf);
  1446. return (ERROR);
  1447. }
  1448.     for (segId = (SEGMENT *)DLL_FIRST (&modId->segmentList);
  1449.  segId != NULL; segId = (SEGMENT *)DLL_NEXT (segId))
  1450. {
  1451. switch (segId->type)
  1452.     {
  1453.     case SEGMENT_TEXT: ix = 0; break;
  1454.     case SEGMENT_DATA: ix = 1; break;
  1455.     case SEGMENT_BSS: ix = 2; break;
  1456. #ifdef INCLUDE_SDA
  1457.     /*
  1458.      * XXX ELP every segments are put in the list even if SDA segments
  1459.      * are currently useless. (it will be necessary to add the
  1460.      * memPartId info in the LD_M_SECTION structure)
  1461.      */
  1462.     case SEGMENT_SDATA: ix = 3; break;
  1463.     case SEGMENT_SBSS: ix = 4; break;
  1464.     case SEGMENT_SDATA2: ix = 5; break;
  1465.     case SEGMENT_SBSS2: ix = 6; break;
  1466. #endif /* INCLUDE_SDA */
  1467.     default: ix = -1; break;
  1468.     }
  1469. if (ix < 0)
  1470.     continue;
  1471. pFileDesc->section[ix].flags = segId->flags & ~SEG_FREE_MEMORY;
  1472. pFileDesc->section[ix].addr = (segId->size == 0) ? (TGT_ADDR_T) -1 :
  1473.       (TGT_ADDR_T)segId->address;
  1474. pFileDesc->section[ix].length = segId->size;
  1475. }
  1476.     return (OK);
  1477.     }
  1478. /******************************************************************************
  1479. *
  1480. * syncLoadHook - load module hook
  1481. *
  1482. * RETURNS: N/A
  1483. * NOMANUAL
  1484. */
  1485. void syncLoadHook
  1486.     (
  1487.     MODULE_ID modId
  1488.     )
  1489.     {
  1490.     char buf[SYNC_TGT_EVT_LGTH];
  1491.     char  name[SYNC_TGT_EVT_LGTH - 25];
  1492.     strncpy (name, modId->name, SYNC_TGT_EVT_LGTH - 26);
  1493.     name[SYNC_TGT_EVT_LGTH - 26] = EOS;
  1494.     sprintf (buf, "%s %#x %s", OBJ_LOADED_EVT, (UINT32)modId, name);
  1495.     if (msgQSend (symSyncMsgQId, buf, SYNC_TGT_EVT_LGTH, WAIT_FOREVER, 0)
  1496. == ERROR)
  1497. {
  1498. #ifdef DEBUG
  1499. logMsg ("module 0x%x sync failedn", (int)modId, 0,0,0,0,0);
  1500. #endif
  1501. return;
  1502. }
  1503.     return;
  1504.     }
  1505. /******************************************************************************
  1506. *
  1507. * syncUnldHook - unload module hook
  1508. *
  1509. * RETURNS: N/A
  1510. * NOMANUAL
  1511. */
  1512. void syncUnldHook
  1513.     (
  1514.     MODULE_ID modId
  1515.     )
  1516.     {
  1517.     char buf[SYNC_TGT_EVT_LGTH];
  1518.     char  name[SYNC_TGT_EVT_LGTH - 25];
  1519.     strncpy (name, modId->name, SYNC_TGT_EVT_LGTH - 26);
  1520.     name[SYNC_TGT_EVT_LGTH - 26] = EOS;
  1521.     sprintf (buf, "%s %s %#x", OBJ_UNLOADED_EVT, name, modId->group);
  1522.     if (msgQSend (symSyncMsgQId, buf, SYNC_TGT_EVT_LGTH, WAIT_FOREVER, 0)
  1523. == ERROR)
  1524. {
  1525. #ifdef DEBUG
  1526. logMsg ("module 0x%x deletion sync failedn", (int)modId,
  1527. 0, 0, 0, 0, 0);
  1528. #endif
  1529. return ;
  1530. }
  1531.     }
  1532. /******************************************************************************
  1533. *
  1534. * syncSymAddHook - symbol addition hook
  1535. *
  1536. * RETURNS: N/A
  1537. *
  1538. * NOMANUAL
  1539. */
  1540. void syncSymAddHook
  1541.     (
  1542.     char * name,
  1543.     char * value,
  1544.     SYM_TYPE type,
  1545.     UINT16 group
  1546.     )
  1547.     {
  1548.     char buf[SYNC_TGT_EVT_LGTH];
  1549.     char  symName[SYNC_TGT_EVT_LGTH - SYM_ADDED_EVT_MSG_NON_NAME_LGTH];
  1550.     if (group == 1) /* symbol table group */
  1551. return ;
  1552.     strncpy (symName, name, 
  1553.      SYNC_TGT_EVT_LGTH - SYM_ADDED_EVT_MSG_NON_NAME_LGTH - 1);
  1554.     symName[SYNC_TGT_EVT_LGTH - SYM_ADDED_EVT_MSG_NON_NAME_LGTH -1] = EOS;
  1555.     
  1556.     /*
  1557.      * The message for SYM_ADDED event will look as follows:
  1558.      *
  1559.      *  "SYM_ADDED <name> 0x<value> 0x<type> 0x<group>"
  1560.      *   |   9   | |    | |  10   | |  4   | |   6   |
  1561.      *
  1562.      * <value>: char*, takes 8 bytes at maximum in the output of sprintf;
  1563.      * <type> : SYM_TYPE, takes 2 bytes at maximum in the output of sprintf;
  1564.      * <group>: UINT16, takes 4 bytes at maximum in the output of sprintf;
  1565.      *
  1566.      * Totally, the non-name information(including white spaces and EOS) takes
  1567.      * at maximum 9+1+1+10+1+4+1+6+1 = 34. So define macro
  1568.      * SYM_ADDED_EVT_MSG_NON_NAME_LGTH to 34
  1569.      */
  1570.     sprintf (buf, "%s %s 0x%x 0x%x 0x%x", SYM_ADDED_EVT, symName, (int)value,
  1571.      type, group);
  1572.     if (msgQSend (symSyncMsgQId, buf, SYNC_TGT_EVT_LGTH, WAIT_FOREVER, 0)
  1573. == ERROR)
  1574. {
  1575. #ifdef DEBUG
  1576. logMsg ("sym %s addition sync failedn", (int)name, 0, 0, 0, 0, 0);
  1577. #endif
  1578. return ;
  1579. }
  1580.     }
  1581. /******************************************************************************
  1582. *
  1583. * syncSymRemoveHook - symbol removing hook
  1584. *
  1585. * RETURNS: N/A
  1586. *
  1587. * NOMANUAL
  1588. */
  1589. void syncSymRemoveHook
  1590.     (
  1591.     char * name,
  1592.     SYM_TYPE type
  1593.     )
  1594.     {
  1595.     /* SYM_ADDED_EVT_MSG_NON_NAME_LGTH is used to calculate space for
  1596.      * symbol name so syncSymRemoveHook and syncSymAdd Hook agree on
  1597.      * acceptable length of symbol name
  1598.      */
  1599.     char buf[SYNC_TGT_EVT_LGTH];
  1600.     char  symName[SYNC_TGT_EVT_LGTH - SYM_ADDED_EVT_MSG_NON_NAME_LGTH];
  1601.     strncpy (symName, name, 
  1602.      SYNC_TGT_EVT_LGTH - SYM_ADDED_EVT_MSG_NON_NAME_LGTH - 1);
  1603.     symName[SYNC_TGT_EVT_LGTH - SYM_ADDED_EVT_MSG_NON_NAME_LGTH -1] = EOS;
  1604.     sprintf (buf, "%s %s 0x%x", SYM_REMOVED_EVT, symName, type);
  1605.     if (msgQSend (symSyncMsgQId, buf, SYNC_TGT_EVT_LGTH, WAIT_FOREVER, 0)
  1606. == ERROR)
  1607. {
  1608. #ifdef DEBUG
  1609. logMsg ("sym %s removing sync failedn", (int)name, 0, 0, 0, 0, 0);
  1610. #endif
  1611. return ;
  1612. }
  1613.     }
  1614. /*******************************************************************************
  1615. *
  1616. * symSRemove - remove a symbol from a symbol table
  1617. *
  1618. * This routine behaves like symRemove() except it does not test syncRemoveRtn
  1619. * function pointer. Thus it enables to "silently" remove a symbol.
  1620. *
  1621. * RETURNS: OK, or ERROR if the symbol is not found
  1622. * or could not be deallocated.
  1623. *
  1624. * NOMANUAL
  1625. */
  1626. STATUS symSRemove
  1627.     (
  1628.     SYMTAB_ID symTblId,         /* symbol tbl to remove symbol from */
  1629.     char      *name,            /* name of symbol to remove */
  1630.     SYM_TYPE  type              /* type of symbol to remove */
  1631.     )
  1632.     {
  1633.     SYMBOL *pSymbol;
  1634.     if (symFindSymbol (symTblId, name, 0, type, SYM_MASK_ALL, 
  1635.        (SYMBOL_ID *) &pSymbol) != OK)
  1636. return (ERROR);
  1637.     /* XXX JLN symTblRemove should really take a SYMBOL_ID */
  1638.     if (symTblRemove (symTblId, pSymbol) != OK)
  1639. return (ERROR);
  1640.     return (symFree (symTblId, pSymbol));
  1641.     }