Subject: binutils/objdump: decode function entry mask
To: None <linux-vax@mithra.physics.montana.edu, port-vax@NetBSD.org>
From: Jan-Benedict Glaw <jbglaw@lug-owl.de>
List: port-vax
Date: 03/08/2005 21:53:13
--4LwthZj+AV2mq5CX
Content-Type: text/plain; charset=utf-8
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

Hi!

Once again, I'm (trying to) work on the toolchain. First of all, here's
a patch that adds entry mask decoding to objdump. This is somewhat
useful since it happens that, decoded as instructions, the two bytes
make up a longer insn so that the remaining (real) part of the function
is totally mis-disassembled.

To the Linux folks: with this patch, the checkstack.pl script should now
work.

To the NetBSD folks: could you please try this patch and look at gdb?
gdb could use a patch like that for objdump to correctly disassemble the
entry mask, but I've not yet got a proper NetBSD installation around :-)
Preferrably this could be done by someone who also already has FSF
copyright assignments in place.

MfG, JBG

diff -Nurp ../cvs-repos/binutils/binutils-upstream-HEAD/binutils/objdump.c =
src/binutils/objdump.c
--- ../cvs-repos/binutils/binutils-upstream-HEAD/binutils/objdump.c	2005-03=
-01 16:18:42.000000000 +0100
+++ src/binutils/objdump.c	2005-03-08 19:40:46.000000000 +0100
@@ -1379,7 +1379,12 @@ disassemble_bytes (struct disassemble_in
 	      info->stream =3D (FILE *) &sfile;
 	      info->bytes_per_line =3D 0;
 	      info->bytes_per_chunk =3D 0;
-	      info->flags =3D 0;
+	      info->last_symbol =3D find_symbol_for_address (section->vma +
+			      start_offset, info, NULL);
+	      if (disassemble && disassemble_all)
+		info->flags =3D FORCE_DISASSEMBLE;
+	      else
+		info->flags =3D 0;
=20
 #ifdef DISASSEMBLER_NEEDS_RELOCS
 	      if (*relppp < relppend)
diff -Nurp ../cvs-repos/binutils/binutils-upstream-HEAD/include/dis-asm.h s=
rc/include/dis-asm.h
--- ../cvs-repos/binutils/binutils-upstream-HEAD/include/dis-asm.h	2005-03-=
03 12:58:01.000000000 +0100
+++ src/include/dis-asm.h	2005-03-08 19:39:36.000000000 +0100
@@ -98,7 +98,11 @@ typedef struct disassemble_info {
      The top 16 bits are reserved for public use (and are documented here).
      The bottom 16 bits are for the internal use of the disassembler.  */
   unsigned long flags;
-#define INSN_HAS_RELOC	0x80000000
+#define INSN_HAS_RELOC		0x80000000
+#define FORCE_DISASSEMBLE	0x40000000	/* Force disassembly of the
+						   address, even if it was
+						   probably better handled in
+						   a different way  */
   void *private_data;
=20
   /* Function used to get bytes to disassemble.  MEMADDR is the
@@ -187,6 +191,7 @@ typedef struct disassemble_info {
   bfd_vma target;		/* Target address of branch or dref, if known;
 				   zero if unknown.  */
   bfd_vma target2;		/* Second target address for dref2 */
+  asymbol *last_symbol;		/* Address of last symbol or section start  */
=20
   /* Command line options specific to the target disassembler.  */
   char * disassembler_options;
diff -Nurp ../cvs-repos/binutils/binutils-upstream-HEAD/opcodes/vax-dis.c s=
rc/opcodes/vax-dis.c
--- ../cvs-repos/binutils/binutils-upstream-HEAD/opcodes/vax-dis.c	2002-05-=
10 01:11:30.000000000 +0200
+++ src/opcodes/vax-dis.c	2005-03-08 19:51:47.000000000 +0100
@@ -1,5 +1,5 @@
 /* Print VAX instructions.
-   Copyright 1995, 1998, 2000, 2001, 2002 Free Software Foundation, Inc.
+   Copyright 1995, 1998, 2000-2002, 2005 Free Software Foundation, Inc.
    Contributed by Pauline Middelink <middelin@polyware.iaf.nl>
=20
 This program is free software; you can redistribute it and/or modify
@@ -34,6 +34,21 @@ static char *reg_names[] =3D
   "r8", "r9", "r10", "r11", "ap", "fp", "sp", "pc"
 };
=20
+/* Definitions for the function entry mask bits.  */
+static char *entry_mask_bit[] =3D
+{
+  /* Registers 0 and 1 shall not be saved, since they're used to pass back
+     a function's result to it's caller...  */
+  "~r0~", "~r1~",
+  /* Registers 2 .. 11 are normal registers.  */
+  "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
+  /* Registers 12 and 13 are argument and frame pointer and must not
+     be saved by using the entry mask.  */
+  "~ap~", "~fp~",
+  /* Bits 14 and 15 control integer and decimal overflow.  */
+  "IntOvfl", "DecOvfl",
+};
+
 /* Sign-extend an (unsigned char). */
 #if __STDC__ =3D=3D 1
 #define COERCE_SIGNED_CHAR(ch) ((signed char)(ch))
@@ -140,6 +155,28 @@ print_insn_vax (memaddr, info)
       buffer[1] =3D 0;
     }
=20
+  /* Decode function entry mask.  */
+  if (info->last_symbol
+		  && (info->last_symbol->flags & BSF_FUNCTION)
+		  && !(info->flags & FORCE_DISASSEMBLE)
+		  && memaddr =3D=3D bfd_asymbol_value (info->last_symbol))
+    {
+      int i =3D 0;
+      int register_mask =3D buffer[1] << 8 | buffer[0];
+
+      (*info->fprintf_func) (info->stream, "Entry mask 0x%04x =3D <",
+			     register_mask);
+
+      for (i =3D 15; i >=3D 0; i--)
+	if (register_mask & (1 << i))
+          (*info->fprintf_func) (info->stream, " %s",
+			entry_mask_bit[i]);
+
+      (*info->fprintf_func) (info->stream, " >");
+
+      return 2;
+    }
+
   for (votp =3D &votstrs[0]; votp->name[0]; votp++)
     {
       register vax_opcodeT opcode =3D votp->detail.code;
--=20
Jan-Benedict Glaw       jbglaw@lug-owl.de    . +49-172-7608481             =
_ O _
"Eine Freie Meinung in  einem Freien Kopf    | Gegen Zensur | Gegen Krieg  =
_ _ O
 fuer einen Freien Staat voll Freier B=C3=BCrger" | im Internet! |   im Ira=
k!   O O O
ret =3D do_actions((curr | FREE_SPEECH) & ~(NEW_COPYRIGHT_LAW | DRM | TCPA)=
);

--4LwthZj+AV2mq5CX
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: Digital signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (GNU/Linux)

iD8DBQFCLhC5Hb1edYOZ4bsRAj4dAJ9S0JW6QITJVNT77wWuGDpvbZhv1wCeJfh4
56psrm7mEMZ5MNdLFMRn3DY=
=Cheb
-----END PGP SIGNATURE-----

--4LwthZj+AV2mq5CX--