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--