This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: how to embed an arbitrary opcode
- From: Nick Clifton <nickc at redhat dot com>
- To: John Breitenbach <breiten at lexmark dot com>
- Cc: binutils at sourceware dot org
- Date: Fri, 19 Jun 2009 14:33:52 +0100
- Subject: Re: how to embed an arbitrary opcode
- References: <4A3AA129.5090708@lpdev.prtdev.lexmark.com>
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