home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2000 #4 / Amiga Plus CD - 2000 - No. 4.iso / PowerPC / Dev / PPCRelease / LoadSegPatch / ELFLoadSeg.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-06-21  |  30.6 KB  |  921 lines

  1. /**********************************************************
  2.  *
  3.  * The standard PowerUP ELFLoadSeg patch and API Definition.
  4.  * The initial PPC function is called as
  5.  *
  6.  *                    init(Argument,WBMsg)
  7.  *
  8.  * where Argument is NULL for a Workbench start and WBMsg is
  9.  * NULL for a CLI start.
  10.  * Argument is a concatination of the "ProgramName"+"Argument"
  11.  * and NP_Argument is also set for ReadArgs on a CLI start
  12.  *
  13.  * Ralph Schmidt, Phase5 1998
  14.  *
  15.  * Thanks to
  16.  * Steve Krueger for initial runelf source and concept input.
  17.  * Volker Barthelsmann for the VBCC runppc sources
  18.  *
  19.  **********************************************************/
  20. #include <exec/execbase.h>
  21. #include <exec/memory.h>
  22. #include <exec/libraries.h>
  23. #include <dos/dos.h>
  24. #include <dos/dosextens.h>
  25. #include <dos/dostags.h>
  26. #include <utility/tagitem.h>
  27. #include <workbench/startup.h>
  28. #include <workbench/workbench.h>
  29. #include <workbench/icon.h>
  30. #include <powerup/ppclib/object.h>
  31. #include <powerup/proto/ppc.h>
  32. #include <powerup/ppclib/tasks.h>
  33. #include <proto/exec.h>
  34. #include <proto/dos.h>
  35. #include <string.h>
  36. #include "compiler.h"
  37. #include "ELFLoadSeg_VERSION.h"
  38.  
  39. #define    D(x)        ;
  40.  
  41. #define    INTERNALFUNC    FALSE
  42.  
  43. #define    LVO_LoadSeg        (-150)
  44. #define    LVO_UnLoadSeg        (-156)
  45. #define    LVO_InternalLoadSeg    (-756)
  46. #define    LVO_InternalUnLoadSeg    (-762)
  47. #define    LVO_NewLoadSeg        (-768)
  48.  
  49. #define MSGID_EXIT        0x44584954
  50. #define    DEFAULTPPCSTACK        0x10000
  51. #define    PATCHNAME        "ELFLoadSeg-Patch"
  52.  
  53.  
  54. void    SegmentCode(void);
  55. void    SegmentCode_Object(void);
  56. void    SegmentCode_ID(void);
  57. void    SegmentCode_End(void);
  58. void    kprintf(UBYTE *fmt,...);
  59.  
  60. BPTR    ASM    NEW_LoadSeg(REG_D1 char            *MyName,
  61.                             REG_A6 struct Library    *DosBase);
  62. BPTR    ASM    NEW_NewLoadSeg(REG_D1 char        *MyName,
  63.                                REG_D2 struct TagItem    *MyTags,
  64.                                REG_A6 struct Library    *DosBase);
  65. BOOL    ASM    NEW_UnLoadSeg(REG_D1 BPTR            MySegList,
  66.                               REG_A6 struct Library        *DosBase);
  67.  
  68. BPTR    ASM    NEW_InternalLoadSeg(REG_D0 BPTR            MyFile,
  69.                                     REG_A0 BPTR            Table,
  70.                                     REG_A1 ULONG        *FuncArray,
  71.                                     REG_A2 ULONG        *Stack,
  72.                                     REG_A6 struct Library    *DosBase);
  73. BOOL    ASM    NEW_InternalUnLoadSeg(REG_D1 BPTR            MySegList,
  74.                                       REG_A1 void             (*FreeFunc)(STRPTR,ULONG),
  75.                                       REG_A6 struct Library        *DosBase);
  76.  
  77. struct HunkSegment
  78. {
  79.     ULONG            Size;
  80.     struct HunkSegment    *Next;
  81. };
  82.  
  83. /* VBCC compatibility
  84.  * extension
  85.  * The CTRL-D feature of the
  86.  * runppc should be put into
  87.  * PPCTool as i think it`s too
  88.  * dangerous for normal usage.
  89.  * The signal handling in the old
  90.  * runppc was also not 100% as
  91.  * some shell(s) set the last
  92.  * DosPacket`s Task as the receiver
  93.  * of the signal.
  94.  * Don`t remember now if it was
  95.  * WShell or Shell.
  96.  * With the PPCTASKTAG_BREAKSIGNAL
  97.  * parameter the ppclib waits on
  98.  * both tasks.
  99.  * The creator task and the PPC 68k
  100.  * msg task.
  101.  */
  102.  
  103. struct StartupData
  104. {
  105.     void    *M68kPort;    /* the PowerPC task can send messages to this port */
  106.     BPTR    std_in;        /* standard input handle */
  107.     BPTR    std_out;    /* standard output handle */
  108.     BPTR    std_err;    /* standard error handle */
  109.     LONG    ReturnCode;    /* here we will find the return code from the PPC task */
  110.     ULONG    Flags;        /* additional flags (currently unused) */
  111. };
  112.  
  113. #define STARTUPF_ELFLOADSEG    0x1
  114.  
  115.  
  116. struct Library        *SysBase;
  117. struct DosLibrary    *DOSBase;
  118. struct Library        *PPCLibBase;
  119. APTR            OldNewLoadSeg;
  120. APTR            OldLoadSeg;
  121. APTR            OldUnLoadSeg;
  122. APTR            OldInternalLoadSeg;
  123. APTR            OldInternalUnLoadSeg;
  124. static const UBYTE    vers[] = VERSTAG;
  125.  
  126. ULONG    main(void)
  127. {
  128. struct SignalSemaphore    *MySemaphore;
  129.   SysBase = *(struct Library **)4;
  130.  
  131.   if (DOSBase=(struct DosLibrary*) OpenLibrary("dos.library",0))
  132.   {
  133.     if (PPCLibBase=OpenLibrary("ppc.library",42))
  134.     {
  135.       if ((PPCLibBase->lib_Version > 45) ||
  136.           ((PPCLibBase->lib_Version == 45) && (PPCLibBase->lib_Revision >= 11)))
  137.       {
  138.         if (FindSemaphore(PATCHNAME)==NULL)
  139.         {
  140.           if (MySemaphore=(struct SignalSemaphore*) AllocVec(sizeof(struct SignalSemaphore) + sizeof(PATCHNAME) + 1,
  141.                                                              MEMF_ANY|MEMF_CLEAR))
  142.           {
  143.             MySemaphore->ss_Link.ln_Name    =    (char*) &MySemaphore[1];
  144.             MySemaphore->ss_Link.ln_Pri    =    -127;
  145.             strcpy((char*) &MySemaphore[1],
  146.                    PATCHNAME);
  147.             InitSemaphore(MySemaphore);
  148.             AddSemaphore(MySemaphore);
  149.  
  150.             OldNewLoadSeg=SetFunction((struct Library*) DOSBase,  
  151.                                    LVO_NewLoadSeg,  
  152.                                    (ULONG (*)(void)) NEW_NewLoadSeg);
  153.       
  154.             D(kprintf("OldNewLoadSeg=0x%08lx NewNewLoadSeg=0x%08lx\n",  
  155.                       OldNewLoadSeg,  
  156.                       NEW_NewLoadSeg));
  157.       
  158.             OldLoadSeg=SetFunction((struct Library*) DOSBase,  
  159.                                    LVO_LoadSeg,  
  160.                                    (ULONG (*)(void)) NEW_LoadSeg);
  161.       
  162.             D(kprintf("OldLoadSeg=0x%08lx NewLoadSeg=0x%08lx\n",  
  163.                       OldLoadSeg,  
  164.                       NEW_LoadSeg));
  165.       
  166.             OldUnLoadSeg=SetFunction((struct Library*) DOSBase,  
  167.                                      LVO_UnLoadSeg,  
  168.                                      (ULONG (*)(void)) NEW_UnLoadSeg);
  169.       
  170.             D(kprintf("OldUnLoadSeg=0x%08lx NewUnLoadSeg=0x%08lx\n",  
  171.                       OldUnLoadSeg,  
  172.                       NEW_UnLoadSeg));
  173.       
  174. #if INTERNALFUNC
  175.             OldInternalLoadSeg=SetFunction((struct Library*) DOSBase,  
  176.                                            LVO_InternalLoadSeg,  
  177.                                            (ULONG (*)(void)) NEW_InternalLoadSeg);
  178.       
  179.             D(kprintf("OldInternalLoadSeg=0x%08lx NewInternalLoadSeg=0x%08lx\  n",
  180.                       OldInternalLoadSeg,  
  181.                       NEW_InternalLoadSeg));
  182.       
  183.             OldInternalUnLoadSeg=SetFunction((struct Library*) DOSBase,  
  184.                                              LVO_InternalUnLoadSeg,  
  185.                                              (ULONG (*)(void)) NEW_InternalUnLoadSeg);
  186.       
  187.             D(kprintf("OldInternalUnLoadSeg=0x%08lx NewInternalUnLoadSeg=0x%0  8lx\n",
  188.                       OldInternalUnLoadSeg,  
  189.                       NEW_InternalUnLoadSeg));
  190. #endif
  191.  
  192.             ((struct CommandLineInterface*) BADDR((((struct Process*) FindTask(NULL))->pr_CLI)))->cli_Module    =    NULL;
  193.             return(0);
  194.           }
  195.           else
  196.           {
  197.             SetIoErr(ERROR_NO_FREE_STORE);
  198.           }
  199.         }
  200.         else
  201.         {
  202.           Printf("ElfLoadSeg is already installed.\n");
  203.         }
  204.       }
  205.       else
  206.       {
  207.         Printf("You need at least ppc.library V45.11\n");
  208.       }
  209.       CloseLibrary(PPCLibBase);
  210.     }
  211.     else
  212.     {
  213.       Printf("Can`t open ppc.library\n");
  214.     }
  215.   }
  216.   return(RETURN_FAIL);
  217. }
  218.  
  219.  
  220. /*****************************************************************************************/
  221. /*****************************************************************************************/
  222. /*****************************************************************************************/
  223. /*****************************************************************************************/
  224. /*****************************************************************************************/
  225. /*****************************************************************************************/
  226. /*****************************************************************************************/
  227.  
  228.  
  229. BPTR    ASM    NEW_NewLoadSeg(REG_D1 char        *MyName,
  230.                                REG_D2 struct TagItem    *MyTags,
  231.                                REG_A6 struct Library    *DosBase)
  232. {
  233. BPTR    SegList;
  234.  
  235. BPTR ASM (*MyFunc)(REG_D1 char*,
  236.                    REG_D2 struct TagItem*,
  237.                    REG_A6 struct Library*);
  238.  
  239.   MyFunc=(BPTR ASM (*) (char*,
  240.                         struct TagItem*,
  241.                         struct Library*))
  242.           OldNewLoadSeg;
  243.  
  244.   SegList=(*MyFunc)(MyName,
  245.                     MyTags,
  246.                     DosBase);
  247.  
  248.   D(kprintf("NEW_NewLoadSeg: MyName %s MyTags 0x%08lx\n",
  249.              MyName,
  250.              MyTags));
  251.  
  252.   if (SegList==NULL)
  253.   {
  254.     struct TagItem    MyTagItem[2];
  255.     void        *MyObject;
  256.     struct HunkSegment    *MySegment;
  257.     ULONG        AllocSize;
  258.     ULONG        CodeSize;
  259.     ULONG        *ObjectPtr;
  260.  
  261.     MyTagItem[0].ti_Tag        =    PPCELFLOADTAG_ELFNAME;
  262.     MyTagItem[0].ti_Data    =    (ULONG) MyName,
  263.     MyTagItem[1].ti_Tag        =    TAG_END;
  264. //__builtin_emit(0x4afc);
  265.     if (MyObject=PPCLoadObjectTagList(&MyTagItem[0]))
  266.     {
  267.       D(kprintf("NEW_NewLoadSeg: MyObject 0x%08lx\n",
  268.                 MyObject));
  269.  
  270.       CodeSize    =    (ULONG) &SegmentCode_End - (ULONG) &SegmentCode;
  271.       AllocSize    =    CodeSize + sizeof(struct HunkSegment);
  272.       if (MySegment=(struct HunkSegment*) AllocMem(AllocSize,
  273.                                                    MEMF_PUBLIC))
  274.       {
  275.         D(kprintf("NEW_NewLoadSeg: MySegMent 0x%08lx AllocSize 0x%08lx\n",
  276.                   MySegment,
  277.                   AllocSize));
  278.  
  279.         MySegment->Size    =    AllocSize;
  280.         MySegment->Next    =    NULL;
  281.         CopyMemQuick((void*) &SegmentCode,
  282.                      &MySegment[1],
  283.                      CodeSize);
  284.  
  285.         ObjectPtr    =(ULONG*) ((ULONG) &MySegment[1] + ((ULONG) &SegmentCode_Object - (ULONG) &SegmentCode + 2));
  286.         *ObjectPtr     =(ULONG) MyObject;
  287.         SegList    =    MKBADDR(&MySegment->Next);
  288.         CacheClearE(MySegment,
  289.                     AllocSize,
  290.                     CACRF_ClearI|CACRF_ClearD);
  291.                     
  292.         SetIoErr(RETURN_OK);
  293.       }
  294.       else
  295.       {
  296.         D(kprintf("NEW_NewLoadSeg: MySegment alloc failed\n"));
  297.         PPCUnLoadObject(MyObject);
  298.         SetIoErr(ERROR_NO_FREE_STORE);
  299.       }
  300.     }
  301.     else
  302.     {
  303.       SetIoErr(ERROR_OBJECT_WRONG_TYPE);
  304.       D(kprintf("NEW_NewLoadSeg: no elf object\n"));
  305.     }
  306.   }
  307.   D(kprintf("NEW_NewLoadSeg: SegList 0x%08lx\n",
  308.             SegList));
  309.  
  310.   return(SegList);
  311. }
  312.  
  313. /*****************************************************************************************/
  314. /*****************************************************************************************/
  315. /*****************************************************************************************/
  316. /*****************************************************************************************/
  317. /*****************************************************************************************/
  318. /*****************************************************************************************/
  319. /*****************************************************************************************/
  320.  
  321.  
  322. BPTR    ASM    NEW_LoadSeg(REG_D1 char            *MyName,
  323.                             REG_A6 struct Library    *DosBase)
  324. {
  325. BPTR    SegList;
  326.  
  327. BPTR ASM (*MyFunc)(REG_D1 char*,
  328.                    REG_A6 struct Library*);
  329.  
  330.   MyFunc=(BPTR ASM (*) (char*,
  331.                         struct Library*))
  332.           OldLoadSeg;
  333.  
  334.   SegList=(*MyFunc)(MyName,
  335.                     DosBase);
  336.  
  337.   D(kprintf("NEW_LoadSeg: MyName %s\n",
  338.              MyName));
  339.  
  340.   if (SegList==NULL)
  341.   {
  342.     struct TagItem    MyTagItem[2];
  343.     void        *MyObject;
  344.     struct HunkSegment    *MySegment;
  345.     ULONG        AllocSize;
  346.     ULONG        CodeSize;
  347.     ULONG        *ObjectPtr;
  348.  
  349.     MyTagItem[0].ti_Tag        =    PPCELFLOADTAG_ELFNAME;
  350.     MyTagItem[0].ti_Data    =    (ULONG) MyName,
  351.     MyTagItem[1].ti_Tag        =    TAG_END;
  352. //__builtin_emit(0x4afc);
  353.     if (MyObject=PPCLoadObjectTagList(&MyTagItem[0]))
  354.     {
  355.       D(kprintf("NEW_LoadSeg: MyObject 0x%08lx\n",
  356.                 MyObject));
  357.  
  358.       CodeSize    =    (ULONG) &SegmentCode_End - (ULONG) &SegmentCode;
  359.       AllocSize    =    CodeSize + sizeof(struct HunkSegment);
  360.       if (MySegment=(struct HunkSegment*) AllocMem(AllocSize,
  361.                                                    MEMF_PUBLIC))
  362.       {
  363.         D(kprintf("NEW_LoadSeg: MySegMent 0x%08lx AllocSize 0x%08lx\n",
  364.                   MySegment,
  365.                   AllocSize));
  366.  
  367.         MySegment->Size    =    AllocSize;
  368.         MySegment->Next    =    NULL;
  369.         CopyMemQuick((void*) &SegmentCode,
  370.                      &MySegment[1],
  371.                      CodeSize);
  372.  
  373.         ObjectPtr    =(ULONG*) ((ULONG) &MySegment[1] + ((ULONG) &SegmentCode_Object - (ULONG) &SegmentCode + 2));
  374.         *ObjectPtr     =(ULONG) MyObject;
  375.         SegList    =    MKBADDR(&MySegment->Next);
  376.         CacheClearE(MySegment,
  377.                     AllocSize,
  378.                     CACRF_ClearI|CACRF_ClearD);
  379.                     
  380.         SetIoErr(RETURN_OK);
  381.       }
  382.       else
  383.       {
  384.         D(kprintf("NEW_LoadSeg: MySegment alloc failed\n"));
  385.         PPCUnLoadObject(MyObject);
  386.         SetIoErr(ERROR_NO_FREE_STORE);
  387.       }
  388.     }
  389.     else
  390.     {
  391.       D(kprintf("NEW_LoadSeg: no elf object\n"));
  392.       SetIoErr(ERROR_OBJECT_WRONG_TYPE);
  393.     }
  394.   }
  395.   D(kprintf("NEW_LoadSeg: SegList 0x%08lx\n",
  396.             SegList));
  397.  
  398.   return(SegList);
  399. }
  400.  
  401.  
  402. /*****************************************************************************************/
  403. /*****************************************************************************************/
  404. /*****************************************************************************************/
  405. /*****************************************************************************************/
  406. /*****************************************************************************************/
  407. /*****************************************************************************************/
  408. /*****************************************************************************************/
  409. #if INTERNALFUNC
  410. /* Really dumb...DOS doesn`t call these through the library
  411.  * removed because of a certain program..authors know which i meant:-)
  412.  */
  413. BPTR    ASM    NEW_InternalLoadSeg(REG_D0 BPTR            MyFile,
  414.                                     REG_A0 BPTR            Table,
  415.                                     REG_A1 ULONG        *FuncArray,
  416.                                     REG_A2 ULONG        *Stack,
  417.                                     REG_A6 struct Library    *DosBase)
  418. {
  419. BPTR    SegList;
  420.  
  421. BPTR ASM (*MyFunc)(REG_D0 BPTR,
  422.                    REG_A0 BPTR,
  423.                    REG_A1 ULONG*,
  424.                    REG_A2 ULONG*,
  425.                    REG_A6 struct Library*);
  426.  
  427.   MyFunc=(BPTR ASM (*) (BPTR,
  428.                         BPTR,
  429.                         ULONG*,
  430.                         ULONG*,
  431.                         struct Library*))
  432.           OldInternalLoadSeg;
  433.  
  434.   SegList=(*MyFunc)(MyFile,
  435.                     Table,
  436.                     FuncArray,
  437.                     Stack,
  438.                     DosBase);
  439.  
  440.   D(kprintf("NEW_InternalLoadSeg: File 0x%08lx Table 0x%08lx FuncArray 0x%08lx Stack 0x%08lx\n",
  441.              MyFile,
  442.              Table,
  443.              FuncArray,
  444.              Stack));
  445.  
  446.   if (SegList==NULL)
  447.   {
  448.     struct TagItem    MyTagItem[4];
  449.     void        *MyObject;
  450.     struct HunkSegment    *MySegment;
  451.     ULONG        AllocSize;
  452.     ULONG        CodeSize;
  453.     ULONG        *ObjectPtr;
  454.  
  455.     MyTagItem[0].ti_Tag        =    PPCELFLOADTAG_FILE;
  456.     MyTagItem[0].ti_Data    =    (ULONG) MyFile;
  457.     MyTagItem[1].ti_Tag        =    PPCELFLOADTAG_ELFNAME;
  458.     MyTagItem[1].ti_Data    =    (ULONG) "ElfPatch";
  459.     MyTagItem[2].ti_Tag        =    TAG_END;
  460.     if (MyObject=PPCLoadObjectTagList(&MyTagItem[0]))
  461.     {
  462.       D(kprintf("NEW_InternalLoadSeg: MyObject 0x%08lx\n",
  463.                 MyObject));
  464.  
  465.       CodeSize    =    (ULONG) &SegmentCode_End - (ULONG) &SegmentCode;
  466.       AllocSize    =    CodeSize + sizeof(struct HunkSegment);
  467.       if (MySegment=(struct HunkSegment*) AllocMem(AllocSize,
  468.                                                    MEMF_PUBLIC))
  469.       {
  470.         D(kprintf("NEW_InternalLoadSeg: MySegment 0x%08lx AllocSize 0x%08lx\n",
  471.                   MySegment,
  472.                   AllocSize));
  473.  
  474.         MySegment->Size    =    AllocSize;
  475.         MySegment->Next    =    NULL;
  476.         CopyMemQuick((void*) &SegmentCode,
  477.                      &MySegment[1],
  478.                      CodeSize);
  479.  
  480.         ObjectPtr    =(ULONG*) ((ULONG) &MySegment[1] + ((ULONG) &SegmentCode_Object - (ULONG) &SegmentCode + 2));
  481.         *ObjectPtr     =(ULONG) MyObject;
  482.         SegList    =    MKBADDR(&MySegment->Next);
  483.         CacheClearE(MySegment,
  484.                     AllocSize,
  485.                     CACRF_ClearI|CACRF_ClearD);
  486.                     
  487.         SetIoErr(RETURN_OK);
  488.       }
  489.       else
  490.       {
  491.         D(kprintf("NEW_InternalLoadSeg: MySegment alloc failed\n"));
  492.         PPCUnLoadObject(MyObject);
  493.         SetIoErr(ERROR_NO_FREE_STORE);
  494.       }
  495.     }
  496.     else
  497.     {
  498.       D(kprintf("NEW_InternalLoadSeg: no elf object\n"));
  499.       SetIoErr(ERROR_OBJECT_WRONG_TYPE);
  500.     }
  501.   }
  502.   D(kprintf("NEW_InternalLoadSeg: SegList 0x%08lx\n",
  503.             SegList));
  504.  
  505.   return(SegList);
  506. }
  507. #endif
  508.  
  509. /*****************************************************************************************/
  510. /*****************************************************************************************/
  511. /*****************************************************************************************/
  512. /*****************************************************************************************/
  513. /*****************************************************************************************/
  514. /*****************************************************************************************/
  515. /*****************************************************************************************/
  516.  
  517. BOOL    ASM    NEW_UnLoadSeg(REG_D1 BPTR            MySegList,
  518.                               REG_A6 struct Library        *DosBase)
  519. {
  520. char    *IDPtr;
  521. UBYTE    *SegmentAddress;
  522. void    *MyObject;
  523.  
  524. BOOL ASM (*MyFunc)(REG_D1 BPTR,
  525.                    REG_A6 struct Library*);
  526.  
  527.   D(kprintf("NEW_UnLoadSeg: SegList 0x%08lx\n",
  528.              MySegList));
  529.  
  530.   if (MySegList)
  531.   {
  532.     SegmentAddress    =(UBYTE*) BADDR(MySegList) + sizeof(ULONG);
  533.     IDPtr        =(char*) &SegmentAddress[(ULONG) &SegmentCode_ID - (ULONG) &SegmentCode];
  534.  
  535.     D(kprintf("NEW_UnLoadSeg: IDPtr 0x%08lx\n",
  536.               IDPtr));
  537.  
  538. //__builtin_emit(0x4afc);
  539.     if (strcmp(IDPtr,
  540.                (char*) &SegmentCode_ID)==0)
  541.     {
  542.  
  543.       MyObject    =(void*)    *((ULONG*) (&SegmentAddress[(ULONG) &SegmentCode_Object - (ULONG) &SegmentCode + 2]));
  544.  
  545.       D(kprintf("NEW_UnLoadSeg: ELF 0x%08lx\n",
  546.                 MyObject));
  547.  
  548.       if (MyObject)
  549.       {
  550.         PPCUnLoadObject(MyObject);
  551.       }
  552.     }
  553.   }
  554.  
  555.   MyFunc=(BOOL ASM (*) (BPTR,
  556.                         struct Library*))
  557.          OldUnLoadSeg;
  558.  
  559.   return((*MyFunc)(MySegList,
  560.                    DosBase));
  561.  
  562. }
  563.  
  564. /*****************************************************************************************/
  565. /*****************************************************************************************/
  566. /*****************************************************************************************/
  567. /*****************************************************************************************/
  568. /*****************************************************************************************/
  569. /*****************************************************************************************/
  570. /*****************************************************************************************/
  571. /* Really dumb...DOS doesn`t call these through the library
  572.  */
  573. #if INTERNALFUNC
  574.  * removed because of a certain program..authors know which i meant:-)
  575. BOOL    ASM    NEW_InternalUnLoadSeg(REG_D1 BPTR            MySegList,
  576.                                       REG_A1 void             (*FreeFunc)(STRPTR,ULONG),
  577.                                       REG_A6 struct Library        *DosBase)
  578. {
  579. char    *IDPtr;
  580. UBYTE    *SegmentAddress;
  581. void    *MyObject;
  582.  
  583. BOOL ASM (*MyFunc)(REG_D1 BPTR,
  584.                    REG_A1 void (*)(STRPTR,ULONG),
  585.                    REG_A6 struct Library*);
  586.  
  587.   D(kprintf("NEW_InternalUnLoadSeg: SegList 0x%08lx FreeFunc 0x%08lx\n",
  588.              MySegList,
  589.              FreeFunc));
  590.  
  591.   if (MySegList)
  592.   {
  593.     SegmentAddress    =(UBYTE*) BADDR(MySegList) + sizeof(ULONG);
  594.     IDPtr        =(char*) &SegmentAddress[sizeof(ULONG) + (ULONG) &SegmentCode_ID - (ULONG) &SegmentCode];
  595.  
  596.     D(kprintf("NEW_InternalUnLoadSeg: IDPtr 0x%08lx\n",
  597.               IDPtr));
  598.  
  599.     if (strcmp(IDPtr,
  600.                (char*) &SegmentCode_ID)==0)
  601.     {
  602.       MyObject    =(void*)    *((ULONG*) (&SegmentAddress[(ULONG) &SegmentCode_Object - (ULONG) &SegmentCode + 2]));
  603.  
  604.       D(kprintf("NEW_InternalUnLoadSeg: ELF 0x%08lx\n",
  605.                 MyObject));
  606.  
  607.       if (MyObject)
  608.       {
  609.         PPCUnLoadObject(MyObject);
  610.       }
  611.     }
  612.   }
  613.  
  614.   MyFunc=(BOOL ASM (*) (BPTR,
  615.                         void (*)(STRPTR,ULONG),
  616.                         struct Library*))
  617.          OldInternalUnLoadSeg;
  618.  
  619.   return((*MyFunc)(MySegList,
  620.                    FreeFunc,
  621.                    DosBase));
  622.  
  623. }
  624. #endif
  625.  
  626. /*****************************************************************************************/
  627. /*****************************************************************************************/
  628. /*****************************************************************************************/
  629. /*****************************************************************************************/
  630. /*****************************************************************************************/
  631. /*****************************************************************************************/
  632. /*****************************************************************************************/
  633.  
  634. ULONG    ASM RunElf(REG_A0 char    *MyCommandLine,
  635.                    REG_A1 void    *MyObject)
  636. {
  637. char                *p;
  638. char                *MyArgument;
  639. const char            *MyCommandName;
  640. char                *MyTaskName;
  641. ULONG                MyCommandLen;
  642. ULONG                MyStackSize;
  643. ULONG                My68kStackSize;
  644. struct Process            *MyProcess;
  645. struct CommandLineInterface    *MyCLI;
  646. char                *rdargs_line;
  647. int                MyCommandLinelength;
  648. struct TagItem            MyTags[20];
  649. ULONG                Result;
  650. ULONG                Index;
  651. struct WBStartup        *WBMsg;
  652. struct WBArg            *MyWBArg;
  653. BPTR                NewCurrentDir;
  654. BPTR                OldCurrentDir;
  655. void                *M68kPort;
  656. void                *MyStartupMsg;
  657. struct StartupData        *MyStartupData;
  658. struct FileHandle        *CurrentInput;
  659. BPTR                CurrentInputBPTR;
  660. ULONG                OldBuffer;
  661. ULONG                OldPosition;
  662. ULONG                OldEnd;
  663. struct TagItem            MyInfoTags[1];
  664. struct PPCObjectInfo        MyInfo;
  665. BOOL                CTRL_C_CHECK;
  666.  
  667.   MyProcess    = (struct Process*) FindTask(NULL);
  668.   MyCLI        = (struct CommandLineInterface*) BADDR(MyProcess->pr_CLI);
  669.   NewCurrentDir    =    NULL;
  670.   OldCurrentDir    =    NULL;
  671.   Result    =    ERROR_NO_FREE_STORE;
  672.   if (MyCLI)
  673.   {
  674.     MyCommandName    =    BADDR(MyCLI->cli_CommandName);
  675.     MyCommandLen    =    MyCommandName[0];
  676.     if (MyTaskName=(char*) PPCAllocVec(MyCommandLen + 2,
  677.                                        MEMF_PUBLIC))
  678.     {
  679.       memcpy(MyTaskName,
  680.              &MyCommandName[1],
  681.              MyCommandLen);
  682.       MyTaskName[MyCommandLen]    =    '\0';
  683.       MyStackSize        =    My68kStackSize    =    MyCLI->cli_DefaultStack * sizeof(ULONG);
  684.       if (MyStackSize < DEFAULTPPCSTACK)
  685.       {
  686.         MyStackSize = DEFAULTPPCSTACK;
  687.       }
  688.       /* strip off the /n the end */
  689.       MyCommandLinelength    =    strlen(MyCommandLine);
  690.       p            =    MyCommandLine + MyCommandLinelength;
  691.       p--;
  692.       if (*p == '\n')
  693.       {
  694.         *p = 0;
  695.       }
  696.       D(kprintf("RunElf: MyCommandLine '%s' Object 0x%08lx\n",
  697.                 MyCommandLine,
  698.                 MyObject));
  699.  
  700.       if (MyArgument=(char*) PPCAllocVec(MyCommandLinelength + (MyCommandName ? MyCommandLen + 6 : 0),
  701.                                          MEMF_PUBLIC))
  702.       {
  703.         if (MyCommandName)
  704.         {
  705.           MyArgument[0]            =    '"';
  706.           memcpy(&MyArgument[1],
  707.                  &MyCommandName[1],
  708.                  MyCommandLen);
  709.           MyArgument[1+MyCommandLen]    =    '"';
  710.           MyArgument[1+1+MyCommandLen]    =    ' ';
  711.           Index                =    1+1+1+MyCommandLen;
  712.         }
  713.         else
  714.         {
  715.           Index                =    0;
  716.         }
  717.         memcpy(&MyArgument[Index],
  718.                MyCommandLine,
  719.                MyCommandLinelength);
  720.       
  721.         if (rdargs_line=PPCAllocVec(MyCommandLinelength + 2, MEMF_ANY))
  722.         {
  723.           memcpy(rdargs_line,
  724.                  MyCommandLine,
  725.                  MyCommandLinelength-1);
  726.           rdargs_line[MyCommandLinelength-1]    =    '\n';
  727.           rdargs_line[MyCommandLinelength]    =    '\0';
  728.  
  729.           if (M68kPort=PPCCreatePortTags(TAG_END))
  730.           {
  731.             if (MyStartupMsg=PPCCreateMessage(M68kPort,sizeof(struct StartupData)))
  732.             {
  733.               if (MyStartupData=(struct StartupData*)
  734.                                 PPCAllocVec(sizeof(struct StartupData),MEMF_CLEAR|MEMF_PUBLIC))
  735.               {
  736.                 MyStartupData->M68kPort    =    M68kPort;
  737.                 MyStartupData->std_in    =    Input();
  738.                 MyStartupData->std_out    =    Output();
  739.                 MyStartupData->std_err    =    MyProcess->pr_CES;
  740.                 MyStartupData->Flags    =    STARTUPF_ELFLOADSEG;
  741.  
  742.                 CurrentInput        =(struct FileHandle*) BADDR(MyStartupData->std_in);
  743.                 CurrentInputBPTR        =    MyStartupData->std_in;
  744.                 OldBuffer            =    CurrentInput->fh_Buf;
  745.                 OldPosition        =    CurrentInput->fh_Pos;
  746.                 OldEnd            =    CurrentInput->fh_End;
  747.  
  748.  
  749.                 if (PPCGetObjectAttrs(MyObject,
  750.                                       &MyInfo,
  751.                                       MyInfoTags))
  752.                 {
  753.                   CTRL_C_CHECK        =    FALSE;
  754.                 }
  755.                 else
  756.                 {
  757.                   CTRL_C_CHECK        =    TRUE;
  758.                 }
  759.  
  760.                 MyTags[0].ti_Tag        =    PPCTASKTAG_STOPTASK;
  761.                 MyTags[0].ti_Data        =    FALSE;
  762.                 MyTags[1].ti_Tag        =    PPCTASKTAG_WAITFINISH;
  763.                 MyTags[1].ti_Data        =    TRUE;
  764.                 MyTags[2].ti_Tag        =    PPCTASKTAG_INPUTHANDLE;
  765.                 MyTags[2].ti_Data        =    (ULONG) MyStartupData->std_in;
  766.                 MyTags[3].ti_Tag        =    PPCTASKTAG_OUTPUTHANDLE;
  767.                 MyTags[3].ti_Data        =    (ULONG) MyStartupData->std_out;
  768.                 MyTags[4].ti_Tag        =    PPCTASKTAG_ARG1;
  769.                 MyTags[4].ti_Data        =    (ULONG) MyArgument;
  770.                 MyTags[5].ti_Tag        =    PPCTASKTAG_STACKSIZE;
  771.                 MyTags[5].ti_Data        =    MyStackSize;
  772.                 MyTags[6].ti_Tag        =    NP_CloseInput;
  773.                 MyTags[6].ti_Data        =    FALSE;
  774.                 MyTags[7].ti_Tag        =    NP_CloseOutput;
  775.                 MyTags[7].ti_Data        =    FALSE;
  776.                 MyTags[8].ti_Tag        =    NP_Cli;
  777.                 MyTags[8].ti_Data        =    TRUE;
  778.                 MyTags[9].ti_Tag        =    PPCTASKTAG_BREAKSIGNAL;
  779.                 MyTags[9].ti_Data        =    CTRL_C_CHECK;
  780.                 MyTags[10].ti_Tag        =    NP_Arguments;
  781.                 MyTags[10].ti_Data    =    (ULONG)rdargs_line;
  782.                 MyTags[11].ti_Tag        =    NP_Name;
  783.                 MyTags[11].ti_Data    =    (ULONG) MyCommandName,
  784.                 MyTags[12].ti_Tag        =    NP_CommandName;
  785.                 MyTags[12].ti_Data    =    (ULONG) MyCommandName,
  786.                 MyTags[13].ti_Tag        =    PPCTASKTAG_STARTUP_MSG;
  787.                 MyTags[13].ti_Data    =(ULONG)MyStartupMsg;
  788.                 MyTags[14].ti_Tag        =    PPCTASKTAG_STARTUP_MSGDATA;
  789.                 MyTags[14].ti_Data    =(ULONG)MyStartupData;
  790.                 MyTags[15].ti_Tag        =    PPCTASKTAG_STARTUP_MSGLENGTH;
  791.                 MyTags[15].ti_Data    =    sizeof(struct StartupData);
  792.                 MyTags[16].ti_Tag        =    PPCTASKTAG_STARTUP_MSGID;
  793.                 MyTags[16].ti_Data    =    MSGID_EXIT;
  794.                 MyTags[17].ti_Tag        =    NP_StackSize;
  795.                 MyTags[17].ti_Data    =    My68kStackSize;
  796.                 MyTags[18].ti_Tag        =    TAG_END;
  797.  
  798.                 Result=(ULONG) PPCCreateTask(MyObject,
  799.                                              &MyTags[0]);
  800.  
  801.                 /* The startupmsg MUST be replied when PPCCreateTask
  802.                  * returns so this is safe.
  803.                  * Trust me...:-)
  804.                  */
  805.                 while (PPCGetMessage(M68kPort));
  806.  
  807.                 UnGetC(CurrentInputBPTR,-1);
  808.                 CurrentInput->fh_Buf    =    OldBuffer;
  809.                 CurrentInput->fh_Pos    =    OldPosition;
  810.                 if (CurrentInput->fh_End)
  811.                 {
  812.                   CurrentInput->fh_End    =    OldEnd;
  813.                 }
  814.                 PPCFreeVec(MyStartupData);
  815.               }
  816.               PPCDeleteMessage(MyStartupMsg);
  817.             }
  818.             PPCDeletePort(M68kPort);
  819.           }
  820.           PPCFreeVec(rdargs_line);
  821.         }
  822.         PPCFreeVec(MyArgument);
  823.       }
  824.       PPCFreeVec(MyTaskName);
  825.     }
  826.   }
  827.   else
  828.   {
  829.     /* WBStartup */
  830.     MyCommandName    =    NULL;
  831.     MyStackSize        =    DEFAULTPPCSTACK;
  832.  
  833.  
  834.     MyStackSize        =    My68kStackSize    =    MyProcess->pr_StackSize;
  835.     if (MyStackSize < DEFAULTPPCSTACK)
  836.     {
  837.       MyStackSize = DEFAULTPPCSTACK;
  838.     }
  839.  
  840.     WaitPort(&MyProcess->pr_MsgPort);
  841.     if (WBMsg=(struct WBStartup*) GetMsg(&MyProcess->pr_MsgPort))
  842.     {
  843.       if (MyWBArg=WBMsg->sm_ArgList)
  844.       {
  845.         if (NewCurrentDir=DupLock(MyWBArg->wa_Lock))
  846.         {
  847.           OldCurrentDir        =    CurrentDir(NewCurrentDir);
  848.         }
  849.         MyCommandName        =    MyWBArg->wa_Name;
  850.       }
  851.       D(kprintf("RunElf: WBMsg 0x%08lx Object 0x%08lx\n",
  852.                 WBMsg,
  853.                 MyObject));
  854.  
  855.       if (M68kPort=PPCCreatePortTags(TAG_END))
  856.       {
  857.         if (MyStartupMsg=PPCCreateMessage(M68kPort,sizeof(struct StartupData)))
  858.         {
  859.           if (MyStartupData=(struct StartupData*)
  860.                             PPCAllocVec(sizeof(struct StartupData),MEMF_CLEAR|MEMF_PUBLIC))
  861.           {
  862.             MyStartupData->M68kPort    =    M68kPort;
  863.             MyStartupData->std_in    =    Input();
  864.             MyStartupData->std_out    =    Output();
  865.             MyStartupData->std_err    =    MyStartupData->std_out;
  866.             MyStartupData->Flags    =    STARTUPF_ELFLOADSEG;
  867.  
  868.             MyTags[0].ti_Tag        =    PPCTASKTAG_STOPTASK;
  869.             MyTags[0].ti_Data        =    FALSE;
  870.             MyTags[1].ti_Tag        =    PPCTASKTAG_WAITFINISH;
  871.             MyTags[1].ti_Data        =    TRUE;
  872.             MyTags[2].ti_Tag        =    PPCTASKTAG_ARG1;
  873.             MyTags[2].ti_Data        =    (ULONG) NULL;        /* NULL Argument means WBMsg */
  874.             MyTags[3].ti_Tag        =    PPCTASKTAG_ARG2;
  875.             MyTags[3].ti_Data        =    (ULONG) WBMsg;
  876.             MyTags[4].ti_Tag        =    PPCTASKTAG_STACKSIZE;
  877.             MyTags[4].ti_Data        =    MyStackSize;
  878.             MyTags[5].ti_Tag        =    PPCTASKTAG_BREAKSIGNAL;
  879.             MyTags[5].ti_Data        =    TRUE;
  880.             MyTags[6].ti_Tag        =    NP_Name;
  881.             MyTags[6].ti_Data        =    (ULONG) MyCommandName;
  882.             MyTags[7].ti_Tag        =    PPCTASKTAG_STARTUP_MSG;
  883.             MyTags[7].ti_Data        =(ULONG) MyStartupMsg;
  884.             MyTags[8].ti_Tag        =    PPCTASKTAG_STARTUP_MSGDATA;
  885.             MyTags[8].ti_Data        =(ULONG) MyStartupData;
  886.             MyTags[9].ti_Tag        =    PPCTASKTAG_STARTUP_MSGLENGTH;
  887.             MyTags[9].ti_Data        =    sizeof(struct StartupData);
  888.             MyTags[10].ti_Tag        =    PPCTASKTAG_STARTUP_MSGID;
  889.             MyTags[10].ti_Data        =    MSGID_EXIT;
  890.             MyTags[11].ti_Tag        =    NP_StackSize;
  891.             MyTags[11].ti_Data        =    My68kStackSize;
  892.             MyTags[12].ti_Tag        =    TAG_END;
  893.  
  894.             Result=(ULONG) PPCCreateTask(MyObject,
  895.                                          &MyTags[0]);
  896.  
  897.  
  898.             /* The startupmsg MUST be replied when PPCCreateTask
  899.              * returns so this is safe.
  900.              * Trust me...:-)
  901.              */
  902.             while (PPCGetMessage(M68kPort));
  903.  
  904.             PPCFreeVec(MyStartupData);
  905.           }
  906.           PPCDeleteMessage(MyStartupMsg);
  907.         }
  908.         PPCDeletePort(M68kPort);
  909.       }
  910.       if (NewCurrentDir)
  911.       {
  912.         CurrentDir(OldCurrentDir);
  913.         UnLock(NewCurrentDir);
  914.       }
  915.       Forbid();
  916.       ReplyMsg(&WBMsg->sm_Message);
  917.     }
  918.   }
  919.   return(Result);
  920. }
  921.