This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: how to embed an arbitrary opcode


Hi John,

I'm looking for a way to embed an arbitrary opcode into an assembly file for the ARM architecture.

Is there a particular reason why you cannot just include the textual version of the opcode you want and have it assembled as normal ?


Objdump refuses to disassemble those opcodes even with the
> --disassemble-all flag.

This has now been fixed in the mainline sources.

.long 0xe320f003

Currently there is no way to achieve the effect you desire. But all is not lost, this being free software and all. So, please try out the attached patch which adds two new pseudo ops to the ARM port of GAS:


  .iword <expression>[,<expression>]*
  .ishort <expression>[,<expression>]*

which can be used to insert 32-bit and 16-bit values respectively into the output stream and mark them as instructions not data.

Cheers
  Nick



Index: gas/config/tc-arm.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-arm.c,v
retrieving revision 1.387
diff -c -3 -p -r1.387 tc-arm.c
*** gas/config/tc-arm.c	18 Jun 2009 16:36:02 -0000	1.387
--- gas/config/tc-arm.c	19 Jun 2009 13:29:42 -0000
*************** static void add_unwind_opcode (valueT, i
*** 2951,2979 ****
  static void flush_pending_unwind (void);
  
  /* Directives: Data.  */
- 
  static void
! s_arm_elf_cons (int nbytes)
  {
-   expressionS exp;
- 
- #ifdef md_flush_pending_output
-   md_flush_pending_output ();
- #endif
- 
-   if (is_it_end_of_statement ())
-     {
-       demand_empty_rest_of_line ();
-       return;
-     }
- 
- #ifdef md_cons_align
-   md_cons_align (nbytes);
- #endif
- 
-   mapping_state (MAP_DATA);
    do
      {
        int reloc;
        char *base = input_line_pointer;
  
--- 2951,2962 ----
  static void flush_pending_unwind (void);
  
  /* Directives: Data.  */
  static void
! arm_elf_cons_worker (int nbytes)
  {
    do
      {
+       expressionS exp;
        int reloc;
        char *base = input_line_pointer;
  
*************** s_arm_elf_cons (int nbytes)
*** 2984,2989 ****
--- 2967,2973 ----
        else
  	{
  	  char *before_reloc = input_line_pointer;
+ 
  	  reloc = parse_reloc (&input_line_pointer);
  	  if (reloc == -1)
  	    {
*************** s_arm_elf_cons (int nbytes)
*** 3017,3022 ****
--- 3001,3007 ----
  		  char *p = input_line_pointer;
  		  int offset;
  		  char *save_buf = alloca (input_line_pointer - base);
+ 
  		  memcpy (save_buf, base, input_line_pointer - base);
  		  memmove (base + (input_line_pointer - before_reloc),
  			   base, before_reloc - base);
*************** s_arm_elf_cons (int nbytes)
*** 3040,3045 ****
--- 3025,3060 ----
    demand_empty_rest_of_line ();
  }
  
+ static void
+ s_arm_elf_cons (int nbytes)
+ {
+   if (is_it_end_of_statement ())
+     {
+       demand_empty_rest_of_line ();
+       return;
+     }
+ 
+   md_cons_align (nbytes); /* Sets mapping state to MAPPING_DATA.  */
+ 
+   arm_elf_cons_worker (nbytes);
+ }
+ 
+ /* Like s_arm_elf_cons but do not use md_cons_align and
+    set the mapping state to MAP_ARM (if nbytes == 4) or
+    MAP_THUMB (if nbytes == 2).  */
+ 
+ static void
+ s_arm_elf_iword (int nbytes)
+ {
+   if (is_it_end_of_statement ())
+     {
+       demand_empty_rest_of_line ();
+       return;
+     }
+ 
+   mapping_state (nbytes == 4 ? MAP_ARM : MAP_THUMB);
+   arm_elf_cons_worker (nbytes);
+ }
  
  /* Parse a .rel31 directive.  */
  
*************** const pseudo_typeS md_pseudo_table[] =
*** 3958,3966 ****
    { "object_arch", s_arm_object_arch,	0 },
    { "fpu",	   s_arm_fpu,	  0 },
  #ifdef OBJ_ELF
!   { "word",	   s_arm_elf_cons, 4 },
!   { "long",	   s_arm_elf_cons, 4 },
!   { "rel31",	   s_arm_rel31,	  0 },
    { "fnstart",		s_arm_unwind_fnstart,	0 },
    { "fnend",		s_arm_unwind_fnend,	0 },
    { "cantunwind",	s_arm_unwind_cantunwind, 0 },
--- 3973,3983 ----
    { "object_arch", s_arm_object_arch,	0 },
    { "fpu",	   s_arm_fpu,	  0 },
  #ifdef OBJ_ELF
!   { "word",	        s_arm_elf_cons, 4 },
!   { "long",	        s_arm_elf_cons, 4 },
!   { "iword",            s_arm_elf_iword, 4 },
!   { "ishort",           s_arm_elf_iword, 2 },
!   { "rel31",	        s_arm_rel31,	  0 },
    { "fnstart",		s_arm_unwind_fnstart,	0 },
    { "fnend",		s_arm_unwind_fnend,	0 },
    { "cantunwind",	s_arm_unwind_cantunwind, 0 },
Index: gas/doc/c-arm.texi
===================================================================
RCS file: /cvs/src/src/gas/doc/c-arm.texi,v
retrieving revision 1.56
diff -c -3 -p -r1.56 c-arm.texi
*** gas/doc/c-arm.texi	2 Apr 2009 09:43:56 -0000	1.56
--- gas/doc/c-arm.texi	19 Jun 2009 13:29:42 -0000
*************** Must be preceded by a @code{.personality
*** 564,569 ****
--- 564,586 ----
  directive.
  
  @c IIIIIIIIIIIIIIIIIIIIIIIIII
+ 
+ @cindex @code{ishort} directive, ARM
+ @item ishort @var{expression} [, @var{expression}]*
+ Inserts one or more comma separated expressions into the output stream
+ as 16-bit values and marks them as being THUMB instructions.  This
+ directive is only supported in ELF based ARM toolchains.  Note: the
+ generic GAS directive @code{.short} does the same thing, but it marks
+ the values as being data not instructions.
+ 
+ @cindex @code{iword} directive, ARM
+ @item iword @var{expression} [, @var{expression}]*
+ Inserts one or more comma separated expressions into the output stream
+ as 32-bit values and marks them as being ARM instructions.  This
+ directive is only supported in ELF based ARM toolchains.  Note: the
+ generic GAS directive @code{.word} does the same thing, but it marks
+ the values as being data not instructions.
+ 
  @c JJJJJJJJJJJJJJJJJJJJJJJJJJ
  @c KKKKKKKKKKKKKKKKKKKKKKKKKK
  @c LLLLLLLLLLLLLLLLLLLLLLLLLL

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]