This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
VAX: Forced decoding of function entry masks (eg. for disassembling ROM images)
- From: Jan-Benedict Glaw <jbglaw at microdata-pos dot de>
- To: binutils at sources dot redhat dot com
- Date: Mon, 21 Mar 2005 15:10:14 +0100
- Subject: VAX: Forced decoding of function entry masks (eg. for disassembling ROM images)
Hi!
I introduced a way to supply function entry addresses through the -M
option of objdump. This aids me in disassembling raw binary files
(currently, I'm working on ROM images and a MOP image that is capable of
writing to VAXens flash chips).
This was very useful for me and I'd like to get a comment if you think
it's worth importing into the binutils tree. (I'll then resubmit with a
changelog text). Basically, this patch shifts a bit of code around,
introduces a new function to decide wether an address is an entry mask
and another new function that sets up the disassembler-private array of
(up to 30) forced entry mask addresses.
Thanks, JBG
diff -Nurp src-fresh/binutils/doc/binutils.texi src-hacked/binutils/doc/binutils.texi
--- src-fresh/binutils/doc/binutils.texi 2005-03-21 13:26:04.000000000 +0100
+++ src-hacked/binutils/doc/binutils.texi 2005-03-21 14:16:59.000000000 +0100
@@ -1793,6 +1793,13 @@ rather than names, for the selected type
You can list the available values of @var{ABI} and @var{ARCH} using
the @option{--help} option.
+For VAX, you can specify up to 30 function entry addresses with
+@option{-M entry:0xf00ba}. You can use this to properly disassemble
+VAX binary files that don't contain symbol tables (like ROM dumps).
+In these cases, the function entry mask would otherwise be decoded
+as VAX instructions, which would probably lead the the rest of the
+function being wrongly disassembled.
+
@item -p
@itemx --private-headers
Print information that is specific to the object file format. The exact
diff -Nurp src-fresh/opcodes/vax-dis.c src-hacked/opcodes/vax-dis.c
--- src-fresh/opcodes/vax-dis.c 2005-03-14 14:07:03.000000000 +0100
+++ src-hacked/opcodes/vax-dis.c 2005-03-21 13:53:40.000000000 +0100
@@ -17,17 +17,39 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+#include <setjmp.h>
+#include <string.h>
#include "sysdep.h"
#include "opcode/vax.h"
#include "dis-asm.h"
+/* Maximum length of an instruction. */
+#define MAXLEN 25
+
+/* Maximum number of forced function entry points */
+#define MAX_ENTRY_ADDR 30
+
+struct private
+{
+ /* Points to first byte not fetched. */
+ bfd_byte *max_fetched;
+ bfd_byte the_buffer[MAXLEN];
+ bfd_vma insn_start;
+ jmp_buf bailout;
+ int num_entry_addr;
+ bfd_vma entry_addr[MAX_ENTRY_ADDR];
+};
+
/* Local function prototypes */
static int fetch_data PARAMS ((struct disassemble_info *, bfd_byte *));
static int print_insn_arg
PARAMS ((const char *, unsigned char *, bfd_vma, disassemble_info *));
static int print_insn_mode
PARAMS ((const char *, int, unsigned char *, bfd_vma, disassemble_info *));
-
+static void init_private_data
+ PARAMS ((struct disassemble_info *, struct private *));
+static bfd_boolean is_function_entry
+ PARAMS ((struct disassemble_info *, bfd_vma addr));
static char *reg_names[] =
{
@@ -74,20 +96,6 @@ static char *entry_mask_bit[] =
(p += 4, FETCH_DATA (info, p), \
(COERCE32 ((((((p[-1] << 8) + p[-2]) << 8) + p[-3]) << 8) + p[-4])))
-/* Maximum length of an instruction. */
-#define MAXLEN 25
-
-#include <setjmp.h>
-
-struct private
-{
- /* Points to first byte not fetched. */
- bfd_byte *max_fetched;
- bfd_byte the_buffer[MAXLEN];
- bfd_vma insn_start;
- jmp_buf bailout;
-};
-
/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
to ADDR (exclusive) are valid. Returns 1 for success, longjmps
on error. */
@@ -95,6 +103,58 @@ struct private
((addr) <= ((struct private *)(info->private_data))->max_fetched \
? 1 : fetch_data ((info), (addr)))
+
+/* Init our private data. This decodes supplied entry addresses, which can
+ be useful to disassemble ROM images, since there's no symbol table. */
+static void
+init_private_data (info, priv)
+ struct disassemble_info *info;
+ struct private *priv;
+{
+ char *tmp;
+ priv->num_entry_addr = 0;
+
+ if (info->disassembler_options)
+ {
+ tmp = info->disassembler_options;
+ while ((tmp = strstr (tmp, "entry:"))
+ && !(priv->num_entry_addr == MAX_ENTRY_ADDR))
+ {
+ tmp += strlen ("entry:");
+ priv->entry_addr[priv->num_entry_addr++] = bfd_scan_vma (tmp, NULL,
+ 0);
+ }
+ }
+}
+
+/* Check if the given address is a known function entry. Either there must
+ be a symbol of function type at this address, or the address must be
+ a forced entry point. The later helps in disassembling ROM images, because
+ there's no symbol table at all. Forced entry points can be given by
+ supplying several -M options to objdump: -M entry:0xffbb7730 . */
+static bfd_boolean
+is_function_entry (info, addr)
+ struct disassemble_info *info;
+ bfd_vma addr;
+{
+ int i;
+ struct private *priv = info->private_data;
+
+ /* Check if there's a BSF_FUNCTION symbol at our address. */
+ if (info->symbols
+ && info->symbols[0]
+ && (info->symbols[0]->flags & BSF_FUNCTION)
+ && addr == bfd_asymbol_value (info->symbols[0]))
+ return TRUE;
+
+ /* Check for forced function entry address. */
+ for (i = 0; i < priv->num_entry_addr; i++)
+ if (priv->entry_addr[i] == addr)
+ return TRUE;
+
+ return FALSE;
+}
+
static int
fetch_data (info, addr)
struct disassemble_info *info;
@@ -133,6 +193,7 @@ print_insn_vax (memaddr, info)
struct private priv;
bfd_byte *buffer = priv.the_buffer;
+ init_private_data (info, &priv);
info->private_data = (PTR) &priv;
priv.max_fetched = priv.the_buffer;
priv.insn_start = memaddr;
@@ -157,10 +218,7 @@ print_insn_vax (memaddr, info)
}
/* Decode function entry mask. */
- if (info->symbols
- && info->symbols[0]
- && (info->symbols[0]->flags & BSF_FUNCTION)
- && memaddr == bfd_asymbol_value (info->symbols[0]))
+ if (is_function_entry (info, memaddr))
{
int i = 0;
int register_mask = buffer[1] << 8 | buffer[0];
--
AWEK microdata GmbH -- Am Wellbach 4 -- 33609 Bielefeld