VAX: Forced decoding of function entry masks (eg. for disassembling ROM images)

Jan-Benedict Glaw jbglaw@microdata-pos.de
Mon Mar 21 16:24:00 GMT 2005


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



More information about the Binutils mailing list