This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Decode function entry mask on VAXen
- From: Jan-Benedict Glaw <jbglaw at microdata-pos dot de>
- To: binutils at sources dot redhat dot com
- Date: Tue, 8 Mar 2005 03:14:30 +0100
- Subject: Decode function entry mask on VAXen
Hi!
An entry point of a function on a VAX is a bit different compared to
those of other CPUs: at the address of the entry point the CPU won't
find the first instruction to execute, but a 2 byte long bit mask
indicating the registers to be pushed onto the stack prior function
execution (basically, this is all registers used in that function,
except registers 0+1, which are used for the return value, as well
as stack/frame/argument pointer and PC).
Unfortunately, objdump didn't honor the entry mask, disassembling it
as regular instructions. In some cases, the first (two) bytes won't
make one two-byte (or two one-byte) instructions, thus mixing up the
remaining functional part of the function.
I'd like to see a patch like this installed, please comment on it.
(A changelog entry is however missing...):
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 02:53:26.000000000 +0100
@@ -1379,7 +1379,11 @@ disassemble_bytes (struct disassemble_in
info->stream = (FILE *) &sfile;
info->bytes_per_line = 0;
info->bytes_per_chunk = 0;
- info->flags = 0;
+ info->last_symbol_address = section->vma + start_offset;
+ if (disassemble && disassemble_all)
+ info->flags = FORCE_DISASSEMBLE;
+ else
+ info->flags = 0;
#ifdef DISASSEMBLER_NEEDS_RELOCS
if (*relppp < relppend)
diff -Nurp ../cvs-repos/binutils/binutils-upstream-HEAD/include/dis-asm.h src/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 01:26:23.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;
/* 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 */
+ bfd_vma last_symbol_address; /* Address of last symbol or section start */
/* Command line options specific to the target disassembler. */
char * disassembler_options;
diff -Nurp ../cvs-repos/binutils/binutils-upstream-HEAD/opcodes/vax-dis.c src/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 03:01:48.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>
This program is free software; you can redistribute it and/or modify
@@ -34,6 +34,21 @@ static char *reg_names[] =
"r8", "r9", "r10", "r11", "ap", "fp", "sp", "pc"
};
+/* Definitions for the function entry mask bits. */
+static char *entry_mask_bit[] =
+{
+ /* 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__ == 1
#define COERCE_SIGNED_CHAR(ch) ((signed char)(ch))
@@ -140,6 +155,26 @@ print_insn_vax (memaddr, info)
buffer[1] = 0;
}
+ /* Decode function entry mask. */
+ if (memaddr - info->last_symbol_address < 2 &&
+ !(info->flags & FORCE_DISASSEMBLE))
+ {
+ int i = 0;
+ int register_mask = buffer[1] << 8 | buffer[0];
+
+ (*info->fprintf_func) (info->stream, "Entry mask 0x%04x = <",
+ register_mask);
+
+ for (i = 15; i >= 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 = &votstrs[0]; votp->name[0]; votp++)
{
register vax_opcodeT opcode = votp->detail.code;
My goal is to do further cleanups of the VAX code (starting with the
simple parts like converting K&R-style function heads, ...).
MfG, JBG
--
Look hard: my ~/.signature is well hidden! You won't find it :-)