Mirror of the gdb mailing list
 help / color / mirror / Atom feed
* gdb segv in arm disassembler
@ 2010-01-26  2:23 Doug Evans
  2010-01-26  2:37 ` Daniel Jacobowitz
  0 siblings, 1 reply; 7+ messages in thread
From: Doug Evans @ 2010-01-26  2:23 UTC (permalink / raw)
  To: dgutson, gdb, binutils

Hi.

I'm getting a segv in the arm disassembler when invoked from gdb,
I think due to this patch.
When invoked from gdb, info->symtab can be NULL.

I'm not sure whether the fix belongs in gdb or libopcodes.

2010-01-06  Daniel Gutson  <dgutson@codesourcery.com>

	* arm-dis.c (print_insn): Fixed search for next symbol and data
	dumping condition, and the initial mapping symbol state.

Index: arm-dis.c
===================================================================
RCS file: /cvs/src/src/opcodes/arm-dis.c,v
retrieving revision 1.120
retrieving revision 1.121
diff -u -p -u -p -r1.120 -r1.121
--- arm-dis.c	4 Jan 2010 10:18:32 -0000	1.120
+++ arm-dis.c	6 Jan 2010 15:02:44 -0000	1.121
@@ -4355,7 +4355,8 @@ print_insn (bfd_vma pc, struct disassemb
   long		given;
   int           status;
   int           is_thumb = FALSE;
-  int           is_data = FALSE;
+  int           is_data = (bfd_asymbol_flavour (*info->symtab)
+			   == bfd_target_elf_flavour) ? TRUE : FALSE;
   int           little_code;
   unsigned int	size = 4;
   void	 	(*printer) (bfd_vma, struct disassemble_info *, long);
@@ -4415,7 +4416,7 @@ print_insn (bfd_vma pc, struct disassemb
       bfd_vma addr;
       int n;
       int last_sym = -1;
-      enum map_type type = MAP_ARM;
+      enum map_type type = MAP_DATA;
 
       if (pc <= last_mapping_addr)
 	last_mapping_sym = -1;
@@ -4478,7 +4479,9 @@ print_insn (bfd_vma pc, struct disassemb
 	  for (n = last_sym + 1; n < info->symtab_size; n++)
 	    {
 	      addr = bfd_asymbol_value (info->symtab[n]);
-	      if (addr > pc)
+	      if (addr > pc
+		  && (info->section == NULL
+		      || info->section == info->symtab[n]->section))
 		{
 		  if (addr - pc < size)
 		    size = addr - pc;


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: gdb segv in arm disassembler
  2010-01-26  2:23 gdb segv in arm disassembler Doug Evans
@ 2010-01-26  2:37 ` Daniel Jacobowitz
  2010-01-28 12:48   ` Nick Clifton
  0 siblings, 1 reply; 7+ messages in thread
From: Daniel Jacobowitz @ 2010-01-26  2:37 UTC (permalink / raw)
  To: Doug Evans; +Cc: dgutson, gdb, binutils

On Mon, Jan 25, 2010 at 06:22:55PM -0800, Doug Evans wrote:
> Hi.
> 
> I'm getting a segv in the arm disassembler when invoked from gdb,
> I think due to this patch.
> When invoked from gdb, info->symtab can be NULL.

Yes.  Sorry - I have a patch for this but I have got stuck travelling
instead of finishing the patch series it's part of.

I think this is the appropriate fix:

---
 opcodes/arm-dis.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

Index: gdb-mainline/opcodes/arm-dis.c
===================================================================
--- gdb-mainline.orig/opcodes/arm-dis.c	2010-01-07 00:22:43.000000000 -0800
+++ gdb-mainline/opcodes/arm-dis.c	2010-01-11 11:18:44.000000000 -0800
@@ -4355,8 +4355,7 @@ print_insn (bfd_vma pc, struct disassemb
   long		given;
   int           status;
   int           is_thumb = FALSE;
-  int           is_data = (bfd_asymbol_flavour (*info->symtab)
-			   == bfd_target_elf_flavour) ? TRUE : FALSE;
+  int           is_data = FALSE;
   int           little_code;
   unsigned int	size = 4;
   void	 	(*printer) (bfd_vma, struct disassemble_info *, long);


-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: gdb segv in arm disassembler
  2010-01-26  2:37 ` Daniel Jacobowitz
@ 2010-01-28 12:48   ` Nick Clifton
  2010-01-28 18:27     ` Daniel Jacobowitz
  0 siblings, 1 reply; 7+ messages in thread
From: Nick Clifton @ 2010-01-28 12:48 UTC (permalink / raw)
  To: Doug Evans, dgutson, gdb, binutils

Hi Daniel,

>> On Mon, Jan 25, 2010 at 06:22:55PM -0800, Doug Evans wrote:
>> I'm getting a segv in the arm disassembler when invoked from gdb,

> Yes.  Sorry - I have a patch for this but I have got stuck travelling
> instead of finishing the patch series it's part of.
>
> I think this is the appropriate fix:
> -  int           is_data = (bfd_asymbol_flavour (*info->symtab)
> -			   == bfd_target_elf_flavour) ? TRUE : FALSE;
> +  int           is_data = FALSE;

Unfortunately this introduces a new failure into the GAS testsuite.

How about this version instead ?

Cheers
   Nick

Index: opcodes/arm-dis.c
===================================================================
RCS file: /cvs/src/src/opcodes/arm-dis.c,v
retrieving revision 1.122
diff -c -3 -p -r1.122 arm-dis.c
*** opcodes/arm-dis.c	20 Jan 2010 10:54:03 -0000	1.122
--- opcodes/arm-dis.c	28 Jan 2010 12:46:17 -0000
*************** print_insn (bfd_vma pc, struct disassemb
*** 4355,4367 ****
     long		given;
     int           status;
     int           is_thumb = FALSE;
!   int           is_data = (bfd_asymbol_flavour (*info->symtab)
! 			   == bfd_target_elf_flavour) ? TRUE : FALSE;
     int           little_code;
     unsigned int	size = 4;
     void	 	(*printer) (bfd_vma, struct disassemble_info *, long);
     bfd_boolean   found = FALSE;

     if (info->disassembler_options)
       {
         parse_disassembler_options (info->disassembler_options);
--- 4355,4373 ----
     long		given;
     int           status;
     int           is_thumb = FALSE;
!   int           is_data = FALSE;
     int           little_code;
     unsigned int	size = 4;
     void	 	(*printer) (bfd_vma, struct disassemble_info *, long);
     bfd_boolean   found = FALSE;

+   /* On ELF based systems we use special mapping symbols to tell us
+      where regions of code occur, so in the absence of such symbols
+      we default to treating the words as data.  */
+   if (info->symtab != NULL
+       && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
+     is_data = TRUE;
+
     if (info->disassembler_options)
       {
         parse_disassembler_options (info->disassembler_options);


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: gdb segv in arm disassembler
  2010-01-28 12:48   ` Nick Clifton
@ 2010-01-28 18:27     ` Daniel Jacobowitz
  2010-01-28 19:30       ` Daniel Jacobowitz
  2010-02-23 12:14       ` Paul Brook
  0 siblings, 2 replies; 7+ messages in thread
From: Daniel Jacobowitz @ 2010-01-28 18:27 UTC (permalink / raw)
  To: Nick Clifton; +Cc: Doug Evans, dgutson, gdb, binutils

On Thu, Jan 28, 2010 at 12:47:35PM +0000, Nick Clifton wrote:
> Hi Daniel,
> 
> >>On Mon, Jan 25, 2010 at 06:22:55PM -0800, Doug Evans wrote:
> >>I'm getting a segv in the arm disassembler when invoked from gdb,
> 
> >Yes.  Sorry - I have a patch for this but I have got stuck travelling
> >instead of finishing the patch series it's part of.
> >
> >I think this is the appropriate fix:
> >-  int           is_data = (bfd_asymbol_flavour (*info->symtab)
> >-			   == bfd_target_elf_flavour) ? TRUE : FALSE;
> >+  int           is_data = FALSE;
> 
> Unfortunately this introduces a new failure into the GAS testsuite.
> 
> How about this version instead ?

I looked at this a bit.  It's more complicated than I expected.

I thought our two patches would do the same thing.  It turns out that
the difference is caused by info->symtab != NULL but info->symtab_size
== 0.  In this case the test case has no symbols, but the caller does
claim to have provided the symbol table.  This gets the right result
for the gas test, but can lead to a crash depending on what happens to
be in info->symtab (I discovered that with a stripped binary).

There are a couple of cases.

* No symbols.  For instance, a stripped binary.  IMO the most useful
thing to do is to default to code; objdump will already not call the
disassembler for sections without SEC_CODE.  Unfortunately, we can not
distinguish that situation from the current gas test case.

* Symbols, but no mapping symbols.  Produced by an old assembler.
Again, I think defaulting to code is reasonable; we expect that most
of a code section / symbol will be code.  Adding a label or function
symbol to the existing gas testsuite will simulate this.  The existing
code does not behave as intended when there is a function symbol,
but no mapping symbol; the function symbol overrides.

* Mapping symbols.  If there are any mapping symbols in the section
(or object), then we should obey them.  This is the only case in which
we can detect leading data with the default-$d omitted mapping symbol.

The best compromise I've thought of is:

* If there are any mapping symbols in the symbol table, honor them.
Ignore other symbols.

* If there are no mapping symbols, default to code using the existing
legacy search.  This will mishandle recent files iff they have a code
section containing only literal pools.  Outside of test cases, this
is unlikely.

I'm working on this (it's taking me a while...).

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: gdb segv in arm disassembler
  2010-01-28 18:27     ` Daniel Jacobowitz
@ 2010-01-28 19:30       ` Daniel Jacobowitz
  2010-01-29 10:21         ` Nick Clifton
  2010-02-23 12:14       ` Paul Brook
  1 sibling, 1 reply; 7+ messages in thread
From: Daniel Jacobowitz @ 2010-01-28 19:30 UTC (permalink / raw)
  To: Nick Clifton, Doug Evans, dgutson, gdb, binutils

On Thu, Jan 28, 2010 at 01:27:39PM -0500, Daniel Jacobowitz wrote:
> The best compromise I've thought of is:
> 
> * If there are any mapping symbols in the symbol table, honor them.
> Ignore other symbols.
> 
> * If there are no mapping symbols, default to code using the existing
> legacy search.  This will mishandle recent files iff they have a code
> section containing only literal pools.  Outside of test cases, this
> is unlikely.

Here is an implementation of the above.  I've run the binutils
testsuites on arm-none-eabi and also verified that it fixes the
GDB segfault.

First we check mapping symbols.  If we find a relevant mapping symbol,
we trust it.  If not, but we find some other mapping symbol in the
file, we default to MAP_DATA.  If there are no mapping symbols in the
file, we search other symbols.  If there are no symbols at all, or
for non-ELF targets, we fall back to ARM mode code.

I've updated the testcases.  dis-data.d and dis-data2.d should,
abstractly, generate .word output; they are really proxies for testing
stripped and legacy binary compatibility.

Does this look OK?

-- 
Daniel Jacobowitz
CodeSourcery

2010-01-28  Daniel Jacobowitz  <dan@codesourcery.com>

	gas/testsuite/
	* gas/arm/dis-data.d: Update test name.  Do not expect
	.word output.
	* gas/arm/dis-data2.d, gas/arm/dis-data2.s,
	gas/arm/dis-data3.d, gas/arm/dis-data3.s: New tests.

	opcodes/
	* opcodes/arm-dis.c (struct arm_private_data): New.
	(print_insn_coprocessor, print_insn_arm): Update to use struct
	arm_private_data.
	(is_mapping_symbol, get_map_sym_type): New functions.
	(get_sym_code_type): Check the symbol's section.  Do not check
	mapping symbols.
	(print_insn): Default to disassembling ARM mode code.  Check
	for mapping symbols separately from other symbols.  Use
	struct arm_private_data.

Index: gas/testsuite/gas/arm/dis-data.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/arm/dis-data.d,v
retrieving revision 1.1
diff -u -p -r1.1 dis-data.d
--- gas/testsuite/gas/arm/dis-data.d	6 Jan 2010 15:02:45 -0000	1.1
+++ gas/testsuite/gas/arm/dis-data.d	28 Jan 2010 19:19:55 -0000
@@ -1,10 +1,10 @@
-# name: Data disassembler test
+# name: Data disassembler test (no symbols)
 # skip: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
 # objdump: -dr --prefix-addresses --show-raw-insn
 
 .*: +file format .*arm.*
 
 Disassembly of section \.text:
-0x00000000 20010000 	.word	0x20010000
-0x00000004 000000f9 	.word	0x000000f9
-0x00000008 00004cd5 	.word	0x00004cd5
+0x00000000 20010000 	andcs	r0, r1, r0
+0x00000004 000000f9 	strdeq	r0, \[r0\], -r9
+0x00000008 00004cd5 	ldrdeq	r4, \[r0\], -r5
Index: gas/testsuite/gas/arm/dis-data2.d
===================================================================
RCS file: gas/testsuite/gas/arm/dis-data2.d
diff -N gas/testsuite/gas/arm/dis-data2.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/dis-data2.d	28 Jan 2010 19:19:55 -0000
@@ -0,0 +1,10 @@
+# name: Data disassembler test (function symbol)
+# skip: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
+# objdump: -dr --prefix-addresses --show-raw-insn
+
+.*: +file format .*arm.*
+
+Disassembly of section \.text:
+00000000 <main> 20010000 	andcs	r0, r1, r0
+00000004 <main\+0x4> 000000f9 	strdeq	r0, \[r0\], -r9
+00000008 <main\+0x8> 00004cd5 	ldrdeq	r4, \[r0\], -r5
Index: gas/testsuite/gas/arm/dis-data2.s
===================================================================
RCS file: gas/testsuite/gas/arm/dis-data2.s
diff -N gas/testsuite/gas/arm/dis-data2.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/dis-data2.s	28 Jan 2010 19:19:55 -0000
@@ -0,0 +1,8 @@
+.syntax unified
+.type main, %function
+.globl main
+main:
+.word	0x20010000
+.word	0x000000f9
+.word	0x00004cd5
+
Index: gas/testsuite/gas/arm/dis-data3.d
===================================================================
RCS file: gas/testsuite/gas/arm/dis-data3.d
diff -N gas/testsuite/gas/arm/dis-data3.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/dis-data3.d	28 Jan 2010 19:19:55 -0000
@@ -0,0 +1,11 @@
+# name: Data disassembler test (with mapping symbol)
+# skip: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
+# objdump: -dr --prefix-addresses --show-raw-insn
+
+.*: +file format .*arm.*
+
+Disassembly of section \.text:
+00000000 <main> 20010000 	.word	0x20010000
+00000004 <main\+0x4> 000000f9 	.word	0x000000f9
+00000008 <main\+0x8> 00004cd5 	.word	0x00004cd5
+0000000c <main\+0xc> e1a00000 	nop			; \(mov r0, r0\)
Index: gas/testsuite/gas/arm/dis-data3.s
===================================================================
RCS file: gas/testsuite/gas/arm/dis-data3.s
diff -N gas/testsuite/gas/arm/dis-data3.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/dis-data3.s	28 Jan 2010 19:19:55 -0000
@@ -0,0 +1,8 @@
+.syntax unified
+.type main, %function
+.globl main
+main:
+.word	0x20010000
+.word	0x000000f9
+.word	0x00004cd5
+nop
Index: opcodes/arm-dis.c
===================================================================
RCS file: /cvs/src/src/opcodes/arm-dis.c,v
retrieving revision 1.122
diff -u -p -r1.122 arm-dis.c
--- opcodes/arm-dis.c	20 Jan 2010 10:54:03 -0000	1.122
+++ opcodes/arm-dis.c	28 Jan 2010 19:19:58 -0000
@@ -45,6 +45,16 @@
 #define NUM_ELEM(a)     (sizeof (a) / sizeof (a)[0])
 #endif
 
+struct arm_private_data
+{
+  /* The features to use when disassembling optional instructions.  */
+  arm_feature_set features;
+
+  /* Whether any mapping symbols are present in the provided symbol
+     table.  -1 if we do not know yet, otherwise 0 or 1.  */
+  int has_mapping_symbols;
+};
+
 struct opcode32
 {
   unsigned long arch;		/* Architecture defining this insn.  */
@@ -1750,7 +1760,8 @@ print_insn_coprocessor (bfd_vma pc,
   fprintf_ftype func = info->fprintf_func;
   unsigned long mask;
   unsigned long value = 0;
-  unsigned long allowed_arches = ((arm_feature_set *) info->private_data)->coproc;
+  struct arm_private_data *private_data = info->private_data;
+  unsigned long allowed_arches = private_data->features.coproc;
   int cond;
 
   for (insn = coprocessor_opcodes; insn->assembler; insn++)
@@ -1776,7 +1787,7 @@ print_insn_coprocessor (bfd_vma pc,
 	    continue;
 
 	  case SENTINEL_GENERIC_START:
-	    allowed_arches = ((arm_feature_set *) info->private_data)->core;
+	    allowed_arches = private_data->features.core;
 	    continue;
 
 	  default:
@@ -2843,6 +2854,7 @@ print_insn_arm (bfd_vma pc, struct disas
   const struct opcode32 *insn;
   void *stream = info->stream;
   fprintf_ftype func = info->fprintf_func;
+  struct arm_private_data *private_data = info->private_data;
 
   if (print_insn_coprocessor (pc, info, given, FALSE))
     return;
@@ -2855,7 +2867,7 @@ print_insn_arm (bfd_vma pc, struct disas
       if ((given & insn->mask) != insn->value)
 	continue;
     
-      if ((insn->arch & ((arm_feature_set *) info->private_data)->core) == 0)
+      if ((insn->arch & private_data->features.core) == 0)
 	continue;
 
       /* Special case: an instruction with all bits set in the condition field
@@ -3057,7 +3069,7 @@ print_insn_arm (bfd_vma pc, struct disas
 			  /* The p-variants of tst/cmp/cmn/teq are the pre-V6
 			     mechanism for setting PSR flag bits.  They are
 			     obsolete in V6 onwards.  */
-			  if (((((arm_feature_set *) info->private_data)->core) & ARM_EXT_V6) == 0)
+			  if ((private_data->features.core & ARM_EXT_V6) == 0)
 			    func (stream, "p");
 			}
 		      break;
@@ -4268,7 +4280,44 @@ find_ifthen_state (bfd_vma pc,
     ifthen_state = 0;
 }
 
-/* Try to infer the code type (Arm or Thumb) from a symbol.
+/* Returns nonzero and sets *MAP_TYPE if the N'th symbol is a
+   mapping symbol.  */
+
+static int
+is_mapping_symbol (struct disassemble_info *info, int n,
+		   enum map_type *map_type)
+{
+  const char *name;
+
+  name = bfd_asymbol_name (info->symtab[n]);
+  if (name[0] == '$' && (name[1] == 'a' || name[1] == 't' || name[1] == 'd')
+      && (name[2] == 0 || name[2] == '.'))
+    {
+      *map_type = ((name[1] == 'a') ? MAP_ARM
+		   : (name[1] == 't') ? MAP_THUMB
+		   : MAP_DATA);
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+/* Try to infer the code type (ARM or Thumb) from a mapping symbol.
+   Returns nonzero if *MAP_TYPE was set.  */
+
+static int
+get_map_sym_type (struct disassemble_info *info,
+		  int n,
+		  enum map_type *map_type)
+{
+  /* If the symbol is in a different section, ignore it.  */
+  if (info->section != NULL && info->section != info->symtab[n]->section)
+    return FALSE;
+
+  return is_mapping_symbol (info, n, map_type);
+}
+
+/* Try to infer the code type (ARM or Thumb) from a non-mapping symbol.
    Returns nonzero if *MAP_TYPE was set.  */
 
 static int
@@ -4278,7 +4327,10 @@ get_sym_code_type (struct disassemble_in
 {
   elf_symbol_type *es;
   unsigned int type;
-  const char *name;
+
+  /* If the symbol is in a different section, ignore it.  */
+  if (info->section != NULL && info->section != info->symtab[n]->section)
+    return FALSE;
 
   es = *(elf_symbol_type **)(info->symtab + n);
   type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
@@ -4290,17 +4342,6 @@ get_sym_code_type (struct disassemble_in
       return TRUE;
     }
 
-  /* Check for mapping symbols.  */
-  name = bfd_asymbol_name (info->symtab[n]);
-  if (name[0] == '$' && (name[1] == 'a' || name[1] == 't' || name[1] == 'd')
-      && (name[2] == 0 || name[2] == '.'))
-    {
-      *map_type = ((name[1] == 'a') ? MAP_ARM
-		   : (name[1] == 't') ? MAP_THUMB
-		   : MAP_DATA);
-      return TRUE;
-    }
-
   return FALSE;
 }
 
@@ -4355,12 +4396,12 @@ print_insn (bfd_vma pc, struct disassemb
   long		given;
   int           status;
   int           is_thumb = FALSE;
-  int           is_data = (bfd_asymbol_flavour (*info->symtab)
-			   == bfd_target_elf_flavour) ? TRUE : FALSE;
+  int           is_data = FALSE;
   int           little_code;
   unsigned int	size = 4;
   void	 	(*printer) (bfd_vma, struct disassemble_info *, long);
   bfd_boolean   found = FALSE;
+  struct arm_private_data *private_data;
 
   if (info->disassembler_options)
     {
@@ -4373,7 +4414,7 @@ print_insn (bfd_vma pc, struct disassemb
   /* PR 10288: Control which instructions will be disassembled.  */
   if (info->private_data == NULL)
     {
-      static arm_feature_set features;
+      static struct arm_private_data private;
 
       if ((info->flags & USER_SPECIFIED_MACHINE_TYPE) == 0)
 	/* If the user did not use the -m command line switch then default to
@@ -4399,67 +4440,124 @@ print_insn (bfd_vma pc, struct disassemb
       /* Compute the architecture bitmask from the machine number.
 	 Note: This assumes that the machine number will not change
 	 during disassembly....  */
-      select_arm_features (info->mach, & features);
+      select_arm_features (info->mach, & private.features);
 
-      info->private_data = & features;
+      private.has_mapping_symbols = -1;
+
+      info->private_data = & private;
     }
-  
+
+  private_data = info->private_data;
+
   /* Decide if our code is going to be little-endian, despite what the
      function argument might say.  */
   little_code = ((info->endian_code == BFD_ENDIAN_LITTLE) || little);
 
-  /* First check the full symtab for a mapping symbol, even if there
-     are no usable non-mapping symbols for this address.  */
+  /* For ELF, consult the symbol table to determine what kind of code
+     or data we have.  */
   if (info->symtab_size != 0
       && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
     {
       bfd_vma addr;
-      int n;
+      int n, start;
       int last_sym = -1;
-      enum map_type type = MAP_DATA;
+      enum map_type type = MAP_ARM;
 
-      if (pc <= last_mapping_addr)
-	last_mapping_sym = -1;
-      is_thumb = (last_type == MAP_THUMB);
-      found = FALSE;
       /* Start scanning at the start of the function, or wherever
 	 we finished last time.  */
-      n = info->symtab_pos + 1;
-      if (n < last_mapping_sym)
-	n = last_mapping_sym;
+      start = info->symtab_pos + 1;
+      if (start < last_mapping_sym)
+	start = last_mapping_sym;
+      found = FALSE;
 
-      /* Scan up to the location being disassembled.  */
-      for (; n < info->symtab_size; n++)
+      /* First, look for mapping symbols.  */
+      if (private_data->has_mapping_symbols != 0)
 	{
-	  addr = bfd_asymbol_value (info->symtab[n]);
-	  if (addr > pc)
-	    break;
-	  if ((info->section == NULL
-	       || info->section == info->symtab[n]->section)
-	      && get_sym_code_type (info, n, &type))
+	  /* Scan up to the location being disassembled.  */
+	  for (n = start; n < info->symtab_size; n++)
+	    {
+	      addr = bfd_asymbol_value (info->symtab[n]);
+	      if (addr > pc)
+		break;
+	      if (get_map_sym_type (info, n, &type))
+		{
+		  last_sym = n;
+		  found = TRUE;
+		}
+	    }
+
+	  if (!found)
 	    {
-	      last_sym = n;
+	      /* No mapping symbol found at this address.  Look backwards
+		 for a preceeding one.  */
+	      for (n = start - 1; n >= 0; n--)
+		{
+		  if (get_map_sym_type (info, n, &type))
+		    {
+		      last_sym = n;
+		      found = TRUE;
+		      break;
+		    }
+		}
+	    }
+
+	  if (found)
+	    private_data->has_mapping_symbols = 1;
+
+	  /* No mapping symbols were found.  A leading $d may be
+	     omitted for sections which start with data; but for
+	     compatibility with legacy and stripped binaries, only
+	     assume the leading $d if there is at least one mapping
+	     symbol in the file.  */
+	  if (!found && private_data->has_mapping_symbols == -1)
+	    {
+	      /* Look for mapping symbols, in any section.  */
+	      for (n = 0; n < info->symtab_size; n++)
+		if (is_mapping_symbol (info, n, &type))
+		  {
+		    private_data->has_mapping_symbols = 1;
+		    break;
+		  }
+	      if (private_data->has_mapping_symbols == -1)
+		private_data->has_mapping_symbols = 0;
+	    }
+
+	  if (!found && private_data->has_mapping_symbols == 1)
+	    {
+	      type = MAP_DATA;
 	      found = TRUE;
 	    }
 	}
 
+      /* Next search for function symbols to separate ARM from Thumb
+	 in binaries without mapping symbols.  */
       if (!found)
 	{
-	  n = info->symtab_pos;
-	  if (n < last_mapping_sym - 1)
-	    n = last_mapping_sym - 1;
-
-	  /* No mapping symbol found at this address.  Look backwards
-	     for a preceeding one.  */
-	  for (; n >= 0; n--)
+	  /* Scan up to the location being disassembled.  */
+	  for (n = start; n < info->symtab_size; n++)
 	    {
-	      if ((info->section == NULL
-		   || info->section == info->symtab[n]->section)
-		  && get_sym_code_type (info, n, &type))
+	      addr = bfd_asymbol_value (info->symtab[n]);
+	      if (addr > pc)
+		break;
+	      if (get_sym_code_type (info, n, &type))
 		{
 		  last_sym = n;
 		  found = TRUE;
-		  break;
+		}
+	    }
+
+	  if (!found)
+	    {
+	      /* No mapping symbol found at this address.  Look backwards
+		 for a preceeding one.  */
+	      for (n = start - 1; n >= 0; n--)
+		{
+		  if (get_sym_code_type (info, n, &type))
+		    {
+		      last_sym = n;
+		      found = TRUE;
+		      break;
+		    }
 		}
 	    }
 	}


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: gdb segv in arm disassembler
  2010-01-28 19:30       ` Daniel Jacobowitz
@ 2010-01-29 10:21         ` Nick Clifton
  0 siblings, 0 replies; 7+ messages in thread
From: Nick Clifton @ 2010-01-29 10:21 UTC (permalink / raw)
  To: Doug Evans, dgutson, gdb, binutils

Hi Daniel,

> Does this look OK?

Yeah - it looks good.  Thanks very much for resolving this.

Cheers
   Nick



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: gdb segv in arm disassembler
  2010-01-28 18:27     ` Daniel Jacobowitz
  2010-01-28 19:30       ` Daniel Jacobowitz
@ 2010-02-23 12:14       ` Paul Brook
  1 sibling, 0 replies; 7+ messages in thread
From: Paul Brook @ 2010-02-23 12:14 UTC (permalink / raw)
  To: binutils; +Cc: Daniel Jacobowitz, Nick Clifton, Doug Evans, dgutson, gdb

> * If there are no mapping symbols, default to code using the existing
> legacy search.  This will mishandle recent files iff they have a code
> section containing only literal pools.  Outside of test cases, this
> is unlikely.

IIRC my real-world example for this was interrupt vectors or similar jump 
tables.

Paul


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2010-02-23 12:14 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-01-26  2:23 gdb segv in arm disassembler Doug Evans
2010-01-26  2:37 ` Daniel Jacobowitz
2010-01-28 12:48   ` Nick Clifton
2010-01-28 18:27     ` Daniel Jacobowitz
2010-01-28 19:30       ` Daniel Jacobowitz
2010-01-29 10:21         ` Nick Clifton
2010-02-23 12:14       ` Paul Brook

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox