This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[02/11] TI C6X binutils port: opcodes/dis-buf.c


On C6X, you can never disassemble an instruction just by looking at
the instruction at the given address.  Instructions are loaded by the
processor in 32-byte "fetch packets".  Instructions themselves may be
32-bit or 16-bit.  If the last word of a fetch packet contains a
certain bit pattern that is not valid in a 32-bit instruction, then
that last word is a fetch packet header for a "header-based fetch
packet" and the instructions in the other words are 32-bit or 16-bit
according to information in that header.  Otherwise, all eight words
are 32-bit instructions.

So disassembly requires reading the last word of the fetch packet.  In
addition, instructions may be explicitly parallel.  In assembly
source, this is indicated by parallel bars "||" on an instruction
indicating that it executes in paralle with the previous instruction.
This is encoded, however, with a "p-bit", which indicates that the
instruction associated with the p-bit is in parallel with the *next*
instruction.  So to tell whether the disassembly should have parallel
bars, you need to find the p-bit of the previous instruction.  For a
32-bit instruction, this is the least significant bit; for a 16-bit
instruction, it is contained in the fetch packet header.

Thus disassembly can require reading the previous instruction or fetch
packet.  At the start of a section there is no previous instruction or
fetch packet, and this must be handled smoothly as not being in
parallel with any previous instruction.  buffer_read_memory had a bug
in this case; just before the start of memory counted as a very large
positive address, so did not appear to be *before* available memory,
while the test for being *after* available memory only checked the
*end* of the region to be read (equal to the start of memory).  This
patch adds an additional check so buffer_read_memory returns a proper
error, rather than a segfault, for this particular case.

(There is one case where disassembly can require reading back much
further from the instruction being disassembled: interpreting an
SPKERNEL instruction requires finding the matching SPLOOP up to 384
instructions earlier.)

2010-03-23  Joseph Myers  <joseph@codesourcery.com>

	* dis-buf.c (buffer_read_memory): Give error for reading just
	before the start of memory.

Index: opcodes/dis-buf.c
===================================================================
RCS file: /cvs/src/src/opcodes/dis-buf.c,v
retrieving revision 1.14
diff -u -r1.14 dis-buf.c
--- opcodes/dis-buf.c	2 Sep 2009 07:20:29 -0000	1.14
+++ opcodes/dis-buf.c	23 Mar 2010 02:41:14 -0000
@@ -1,6 +1,6 @@
 /* Disassemble from a buffer, for GNU.
    Copyright 1993, 1994, 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2005,
-   2007, 2009  Free Software Foundation, Inc.
+   2007, 2009, 2010  Free Software Foundation, Inc.
 
    This file is part of the GNU opcodes library.
 
@@ -38,6 +38,7 @@
   unsigned int octets = (memaddr - info->buffer_vma) * opb;
 
   if (memaddr < info->buffer_vma
+      || memaddr - info->buffer_vma > max_addr_offset
       || memaddr - info->buffer_vma + end_addr_offset > max_addr_offset)
     /* Out of bounds.  Use EIO because GDB uses it.  */
     return EIO;

-- 
Joseph S. Myers
joseph@codesourcery.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]