Assembler as shared library

Philip Herron redbrain@gcc.gnu.org
Wed Feb 19 14:07:00 GMT 2014


Yeah i can implement this api i am playing around with trying to load
the assembled code into memory an example from comp.compilers:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <errno.h>
#include <sys/mman.h>

int main( int argc, char *argv[] )
{
  int (*fnptr)(void); int retval= 0; size_t c_len= 1024;

  char *c_buffer = mmap( NULL, c_len, PROT_EXEC | PROT_READ | PROT_WRITE,
             MAP_ANONYMOUS | MAP_PRIVATE , -1, 0 );

  *(c_buffer) = 0xB8;                /* mov eax,1234h */
  *(c_buffer+1) = 0x34;
  *(c_buffer+2) = 0x12;
  *(c_buffer+3) = 0;
  *(c_buffer+4) = 0;
  *(c_buffer+5) = 0xC3;                /* ret */

  fnptr = (int (*)(void)) c_buffer;
  retval = fnptr( );                      /* call the code */

  printf("Result = %X\n", retval );        /* show result */
  munmap( c_buffer, c_len );

  return 0;
}

To load stuff into memory am hoping it would be possible to take
output from gas and just dump it into memory and pray lol. But no
success so far i think i need to learn more about object files and elf
before i can move forward at the moment.

On 18 February 2014 21:57, David Malcolm <dmalcolm@redhat.com> wrote:
> [existing thread uses top-posting, so am going with that]
>
> Philip: thanks for working on this.
>
> Some context for binutils people: I've been working on an experimental
> branch of gcc that can be built as a shared library for just-in-time
> compilation:
> http://gcc.gnu.org/wiki/JIT
> The GCC JIT codebase can take client API calls and give assembler,
> rather than machine code.  Right now I have an ugly hack that calls out
> to (another) gcc to use gcc's harness logic to invoke programs to turn
> the .s file into a .so (via a .o), then links it into memory.  IIRC,
> this hack takes about half the wallclock, though I don't know to what
> extent it's the expense of execing subprocesses vs the inherent work of
> the .s to machine code, and ELF manipulation.  So it would be nice to
> have the existing binutils code be available as a library that can turn
> either a .s file (or even an in-memory string) into machine code.  Hence
> my interest in the GNU Assembler as a shared library (although as I
> understand it that's only half the battle - turning it into a DSO would
> be further effort, and ideally we could skip much of this, since it's
> all in-process).
>
> From the JIT's point of view, what I need is something that can
> repeatedly be invoked within one process (perhaps from different
> threads), so I think state management is going to be an issue here.
> Last time I looked at the gas source code, my recollection is that there
> are quite a few global variables.
>
> One way to tackle this is to get rid of all globals, moving them all
> into some kind of "context" struct.  Another way is to put a big mutex
> around the library, and to purge all state when done.  I'm using a
> similar approach in gcc, and the latter especially within my "jit"
> branch.
>
> An approach to take might be an outside-in one: what should the API look
> like?   From the libgccjit perspective, perhaps something like this
> would be good:
>
>   extern gas_context *
>   gas_context_acquire (void);
>
>   extern void
>   gas_context_release (gas_context *ctxt);
>
>   extern void
>   gas_context_set_input_file (gas_context *ctxt,
>                               const char *path);
>
>   extern void
>   gas_context_set_output_file (gas_context *ctxt,
>                                const char *path);
>
>   extern int
>   gas_context_assemble (gas_context *ctxt);
>
> ??? (caveat: very much a first iteration, no idea if the above is sane,
> though there's a stylistic resemblance to the libgccjit.h API)
>
> Hope this is helpful
> Dave
>
> On Mon, 2014-02-17 at 16:54 +0000, Philip Herron wrote:
>> Hey all
>>
>> This is my initial patch it creates a shared library out of gas and
>> installs the necessary headers along side it. I am trying to work out
>> how to use it so far need more time tracing through the code to figure
>> it out but so far i am been copying and pasting bits and pieces to get
>> this so far as a client program:
>>
>> #include <stdio.h>
>> #include <stdlib.h>
>> #include <string.h>
>>
>> #include <as.h>
>> #include <subsegs.h>
>> #include <output-file.h>
>>
>> char * out_file_name;
>>
>> int main (int argc, char **argv)
>> {
>>     printf ("trying...\n");
>>     out_file_name = strdup ("./ninja");
>>
>>     bfd_init ();
>>     md_begin ();
>>
>>     symbol_begin ();
>>     frag_init ();
>>     subsegs_begin ();
>>     read_begin ();
>>     input_scrub_begin ();
>>     expr_begin ();
>>
>>     output_file_create (out_file_name);
>>
>>     dot_symbol_init ();
>>
>>     text_section = subseg_new (TEXT_SECTION_NAME, 0);
>>     data_section = subseg_new (DATA_SECTION_NAME, 0);
>>     bss_section = subseg_new (BSS_SECTION_NAME, 0);
>>
>>     subseg_new (BFD_ABS_SECTION_NAME, 0);
>>     subseg_new (BFD_UND_SECTION_NAME, 0);
>>     reg_section = subseg_new ("*GAS `reg' section*", 0);
>>     expr_section = subseg_new ("*GAS `expr' section*", 0);
>>     subseg_set (text_section, 0);
>>
>>     read_a_source_file ("./t.s");
>>     write_object_file ();
>>
>>     free (out_file_name);
>>
>>     return 0;
>> }
>>
>> $ gcc -g -O2 -Wall test.c -o test -I/opt/binutils/include
>> -L/opt/binutils/lib -lgas -lbfd
>>
>> Its definitely not right but demonstrates i am calling into normal gas
>> things. Hope to get more working soon and i will probably need to make
>> some wrapper code as this although i am doing it completely wrong is
>> fairly involved. I would great if i could get some feedback i reckon
>> this patch is probably going to break some stuff.
>>
>> Thanks i hope i can get something more use-able soon.
>>
>> --Phil
>>
>> On 14 February 2014 17:06, Philip Herron <redbrain@gcc.gnu.org> wrote:
>> > Ah thanks! I have a github repo:
>> >
>> > https://github.com/redbrain/binutils-gdb/tree/libasm
>> >
>> > It now builds libasm.la which as is built off now and as seems to
>> > work. So i think i have the first stages of this working. I am
>> > #ifdefing out the main so far and need to make a libgas.h so we can
>> > use this in David Malcoms jit.
>> >
>> > On 14 February 2014 15:13, nick clifton <nickc@redhat.com> wrote:
>> >> Hi Philip,
>> >>
>> >>
>> >>> But i can find any where to start to make a little mini assembler
>> >>> using libopcodes.
>> >>
>> >>
>> >> Take a look at gas/doc/internals.texi, especially the section on GAS
>> >> processing.
>> >>
>> >> Essentially you will need to provide library routines that emulate what is
>> >> done in gas/as.c:main().
>> >>
>> >> Cheers
>> >>   Nick
>> >>
>> >>
>
>



More information about the Binutils mailing list