From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.3 required=5.0 tests=BAYES_00,INVALID_MSGID autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,1140c4e8eb3fd28f X-Google-Attributes: gid103376,public From: David Brown Subject: Re: Executing machine code? Date: 1999/05/27 Message-ID: #1/1 X-Deja-AN: 482765428 Sender: davidb@opus.davidb.org References: <86u2sya7od.fsf@finch.cs.und.ac.za> X-Complaints-To: abuse@pacbell.net X-Trace: typhoon-sf.snfc21.pbi.net 927822561 216.103.8.60 (Thu, 27 May 1999 09:29:21 PDT) Organization: David Brown Services NNTP-Posting-Date: Thu, 27 May 1999 09:29:21 PDT Newsgroups: comp.lang.ada Date: 1999-05-27T00:00:00+00:00 List-Id: >>>>> On 27 May 1999 16:50:10 +0200, Ikram said: > I occasionally need to write programs that generate and execute > machine code (as in e.g. genetic programming systems). in C, the > method I've been using is to store the machine instructions in an > array of bytes, and then cast the array into a function, e.g.: > char code[MAX]; /* storage area for function's code. */ > code[0] = 0x55; /* code making up the function's preamble. */ > code[1] = ... > ... > code[x] = ... /* code making up the function's body. */ > code[x+1] = ... > ... > code[MAX-1] = 0xC3; /* return instruction. */ > /* now cast array pointer into a function pointer. assume this > function takes one int argument and returns an int result, > using C parameter passing conventions. */ > f = (int (*)(int))code; > result = f(4); /* call the function. */ Calling the code isn't very hard (see below). With modern architectures, it is often necessary to flush the data cache and/or invalidate the instruction cache. How this is done is very system specific, and will most likely be provided as a service of your operating system. > I'm trying to find out whether it is similarly possible to switch > between array and function representations in Ada (not necessarily in > a platform- or compiler-independent way). or perhaps someone would > like to suggest an alternative means of executing machine code > generated on-the-fly from within Ada programs? suggestions or > pointers to information would be welcome. This conversion is making a few assumption about how the compiler represents procedure (or function) access types, and system address. I suggest finding out from your vendor how these are implemented. ---------------------------------------------------------------------- -- -- Casting example to a special procedure pointer. -- with Ada.Unchecked_Conversion; with System; procedure Call is type Grunt_Call is access procedure (Arg : Integer); type Byte is mod 2**8; for Byte'Size use 8; type Byte_Array is array (Positive range <>) of Byte; pragma Pack (Byte_Array); Sample_Code : Byte_Array (1 .. 4); function "+" is new Ada.Unchecked_Conversion (System.Address, Grunt_Call); Perform_Grunt : Grunt_Call := "+"(Sample_Code(Sample_Code'First)'Address); begin -- This is an x86 return instruction. Sample_Code (1) := 16#C3#; -- Processors with separate instruction and data caches may have to -- perform a system specific operation to make these caches coherent. -- Now we can execute. Perform_Grunt.all (10); end Call;