home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / emerald / emrldsys.lha / Kernel / FileLoad / transDoto.c < prev   
Encoding:
C/C++ Source or Header  |  1990-08-17  |  7.0 KB  |  202 lines

  1.  
  2. /*  C O P Y R I G H T   N O T I C E :                                     */
  3. /* Copyright 1986 Eric Jul and Norm Hutchinson.     May not be used for any  */
  4. /* purpose without written permission from the authors.              */
  5.  
  6. #include <stdio.h>
  7. #include <a.out.h>
  8. #include <setjmp.h>
  9.  
  10. #include "Kernel/h/assert.h"
  11. #include "Kernel/h/system.h"
  12. #include "Kernel/h/emTypes.h"
  13. #include "Kernel/h/kmdTypes.h"
  14. #include "Kernel/h/consts.h"
  15.  
  16. extern int             *NlistValueOf();
  17. extern void             CodeDependency();
  18. extern GODP             CreateGODEntry();
  19. extern ODP              KernelCheatingCreate();
  20. extern AbConPtr         OIDOIDOIDToAbCon();
  21. extern RODataPtr        OIDToODAP();
  22. extern unsigned int     OpNumberToAddress();
  23. extern char            *PPSSPlace(), *PPPOID(), *PPGOID(), *PPFindLineNo(),
  24.                *PPOID(), *PPCOID(), *PPCodePtr();
  25. /*
  26.  * This routine imports:
  27.  *    ODP OIDToODP(id); OID id;
  28.  *    AbConPtr OIDOIDToAbCon(atid, rid, ctid); OID atid, ctid;
  29.  *    RODataPtr OIDToODAP(id, codeid); OID id, codeid;
  30.  *    unsigned int OpNumberToAddress(id, opNumber); OID id; int opNumber;
  31.  *    int *NlistValueOf(name); char *name;
  32.  *
  33.  *      jmp_buf errorExitPoint;
  34.  */
  35.  
  36. extern jmp_buf errorExitPoint;
  37.  
  38. #define OIDToODP    OTLookup
  39. extern ODP              OTLookup();
  40.  
  41. #define Check(condition,err) assert(condition);
  42.  
  43. /* When the translation routines are asked to return an address of a routine
  44.    which it does not know about, it returns the address of the label
  45.    BadJump in the kernel stub.
  46.    The kernel stub inturn calls BadJumpOccurred which abort with
  47.    an error message.
  48. */
  49. extern int              BadJump;
  50.  
  51. void BadJumpOccurred()
  52. {
  53.     
  54.     ErrMsg("Local invocation attempt; but code is non-resident\n");
  55.     ErrMsg("Jump from %s\n", PPSSPlace(currentSSP));
  56.     abort();
  57. }
  58.  
  59. void translateDoto(fDotoPtr)
  60. DotoFilePtr fDotoPtr;
  61. {
  62.   register int          i;
  63.   register struct nlist*nl;
  64.   register struct relocation_info
  65.                *rl;
  66.   long                  numSymbols, *relocatedAddress, symbolValue;
  67.   char                **symbolNames;
  68.   RelocationInfoPtr     riptr;
  69.   ARelocation           ar;
  70.   CodePtr               cptr;
  71.   CodeODP               theCodeODP;
  72.   ODP                   cheatingODP;
  73.   
  74.   Check(NonNULL(fDotoPtr), 40);
  75.   cptr = dotoCodePtr(fDotoPtr);
  76.   Check(cptr->tag.tag == CodeTag, 41);
  77.   numSymbols = fDotoPtr->header.a_syms / sizeof(struct nlist);
  78.   KMDTrace("Translate", 2, "Translating %s\n", PPCOID(cptr->ownOID));
  79.   if (numSymbols > 0) {
  80.     symbolNames = (char **) malloc((unsigned) (numSymbols * sizeof(char *)));
  81.     for (i = 0; i < numSymbols; i++) {
  82.       nl = dotoSymbolPtr(fDotoPtr) + i;
  83.       symbolNames[i] = dotoStringPtr(fDotoPtr)+nl->n_un.n_strx;
  84.       KMDTrace("Translate", 6, "Symbol #%3d: %s\n", i, symbolNames[i]);
  85.     }
  86.   }
  87.   
  88.   for (i = 0; i < fDotoPtr->header.a_drsize / sizeof(struct relocation_info); i++) {
  89.     rl = dotoRelocPtr(fDotoPtr) + i;
  90.     if (rl->r_pcrel) continue;
  91.     Check(rl->r_length == 2, 42);
  92.     Check(rl->r_extern, 43);
  93.     Check(rl->r_symbolnum < numSymbols, 43);
  94.     symbolValue = (unsigned int) NlistValueOf(symbolNames[rl->r_symbolnum]);
  95.     assert(-1 != symbolValue);
  96.     KMDTrace("Translate", 7, "NlistValueOf returned 0x%08x\n", symbolValue);
  97.     relocatedAddress = (long *) addOffset(cptr, rl->r_address);
  98.     *relocatedAddress = symbolValue;
  99.     KMDTrace("Translate", 6, "Addr 0x%05x set to 0x%05x\n", relocatedAddress,
  100.     symbolValue);
  101. /*  obsolete  *((long *)((char *)cptr + rl->r_address)) = symbolValue; */
  102.   }
  103.   if (numSymbols > 0) {
  104.     free((char *)symbolNames);
  105.   }
  106.   /* Now do the Emerald relocation */
  107.   if (IsNULL(cptr->relocationInfoOffset)) return;
  108.   riptr = (RelocationInfoPtr) addOffset(cptr, cptr->relocationInfoOffset);
  109.   KMDTrace("Translate", 3, "Emerald Relocation %d relocation items\n",
  110.       riptr->numEntries);
  111.   for (i = 0; i < riptr->numEntries; i++) {
  112.     ar = riptr->relocation[i];
  113.     relocatedAddress = (long *) addOffset(cptr, ar.where);
  114.     KMDTrace("Translate", 5, "%s: rel loc %d, abs 0x%05x (0x%05x, 0x%05x))\n",
  115.     ar.kind == AR_OIDToODP ? "OIDToODP" :
  116.     ar.kind == AR_OIDToODAP ? "OIDToODAP" :
  117.     ar.kind == AR_OpNumberToAddress ? "OpNumberToAddress" :
  118.     ar.kind == AR_OIDOIDToAbCon ? "OIDOIDToAbCon" :
  119.     ar.kind == AR_OIDToCheatingODP ? "OIDToCheatingODP":
  120.     ar.kind == AR_OIDToCodePtr ? "OIDToCodePtr" :
  121.     "Unknown translation",
  122.     ar.where, relocatedAddress, ar.theOID1, ar.theOID2);
  123.     switch (ar.kind) {
  124.       case AR_OIDToODP:
  125.     symbolValue = (int) OIDToODP(ar.theOID1);
  126.     if (symbolValue == NULL) {
  127.         /* It is not known here, so fake one */
  128.         symbolValue = (int) CreateGODEntry(ar.theOID1, ar.theOID2);
  129.     }
  130.     KMDTrace("Translate", 3, "AR_OIDToODP: 0x%08x to 0x%08x\n",
  131.         ar.theOID1, symbolValue);
  132.     break;
  133.       case AR_OIDToODAP:
  134.     symbolValue = (int) OIDToODAP(ar.theOID1, ar.theOID2);
  135.     KMDTrace("Translate", 3, "AR_OIDToODAP: 0x%08x to 0x%08x\n",
  136.         ar.theOID1, symbolValue);
  137.     break;
  138.       case AR_OpNumberToAddress:
  139.     symbolValue = (int) OpNumberToAddress(ar.theOID1, (int) ar.theOID2);
  140.     KMDTrace("Translate", 3, "AR_OpNumberToAddress: 0x%08x to 0x%08x\n",
  141.         ar.theOID1, symbolValue);
  142.     if (IsNULL(symbolValue)) {
  143.         CodeDependency(cptr->ownOID, ar.theOID1);
  144.         symbolValue = (int) &BadJump;
  145.     }
  146.     break;
  147.       case AR_OIDOIDToAbCon:
  148.     symbolValue = (int) OIDOIDOIDToAbCon(ar.theOID1, (OID) EMNIL,
  149.         ar.theOID2);
  150.     KMDTrace("Translate", 3,
  151.         "AR_OIDOIDToAbCon(0x%08x, 0x%08x) -> AbCon at 0x%08x\n",
  152.         ar.theOID1, ar.theOID2, symbolValue);
  153.     break;
  154.       case AR_OIDToCheatingODP:
  155.     cheatingODP = OIDToODP(ar.theOID1);
  156.     symbolValue = (int) cheatingODP;
  157.     if (IsNULL(cheatingODP) || IsNULL(cheatingODP->G.ownLoc)) {
  158.         /* We have to create it */
  159.         symbolValue =
  160.         (int) KernelCheatingCreate(ar.theOID1, ar.theOID2, 0, (AVariable *)0);
  161.         KMDTrace("Code", 2, "Cheating create of %s, one of %s\n",
  162.         PPGOID(ar.theOID1), PPCOID(ar.theOID2));
  163.     } else {
  164.         KMDTrace("Code", 4,
  165.         "Cheating object %s already exists at 0x%04x\n",
  166.         PPGOID(cheatingODP->G.ownOID), cheatingODP->G.ownLoc);
  167.     }
  168.     KMDTrace("Translate", 3, "AR_OIDToCheatingODP(%s, %s)\n",
  169.         PPGOID(ar.theOID1), PPCOID(ar.theOID2));
  170.     break;
  171.       case AR_OIDToCodePtr:
  172.     theCodeODP = (CodeODP) OIDToODP(ar.theOID1);
  173.     assert(NonNULL(theCodeODP));
  174.     symbolValue = (int) theCodeODP->dataPtr;
  175.     assert(NonNULL(symbolValue));
  176.     KMDTrace("Translate", 3, "AR_OIDToCodePtr %s\n", PPCOID(ar.theOID1));
  177.     break;
  178.       default:
  179.     Check(FALSE, 44);
  180.     break;
  181.     }
  182.     KMDTrace("Translate", 5, " (0x%08x)  <- 0x%08x\n", relocatedAddress, symbolValue);
  183.     *relocatedAddress = symbolValue;
  184.   }
  185. }
  186. /**********************************************************************/
  187. /*      retranslate                                                   */
  188. /**********************************************************************/
  189.  
  190. void retranslate(fCodeODP)
  191. CodeODP                     fCodeODP;
  192. /* A previously remote piece of code has arrived, so do the necessary
  193.    retranslates.
  194. */
  195. {
  196.     KMDTrace("Code", 3, "Retranslating %s\n", PPCOID(fCodeODP->ownOID));
  197.     KMDTrace("FixMe", 5, "Do only the necessary translations\n");
  198.  
  199.     /* For now just redo the entire translation */
  200.     translateDoto(mDotoFilePtrFromCodePtr(fCodeODP->dataPtr));
  201. }
  202.