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]

[PATCH] SEGV whilst placing sections


The following C code, when compiled for an ARM target with -fexceptions
and linked using the attached linker script, causes SEGV in
lang_insert_orphan () when placing the .ARM.extab section.

int f(int *);

int g(void)
{
    int a;
    return f(&a);
}

In this case, the "after" parameter to lang_insert_orphan () corresponds
to the .rodata section, the last in the linked list of "asection"s.
The upshot is that place->section points at the "next" entry of the final
section in the list, .rodata.  This "next" pointer is NULL, so "as" ends up
NULL, and we fault when "as->prev" is computed.

The attached patch fixes this problem, and doesn't cause any test
failures -- but I'm not 100% sure this is the correct thing to do.
Perhaps someone who knows the code could tell me if they think this is
reasonable?

Thanks,
Mark

--

ld/ChangeLog:

2006-06-20 Mark Shinwell <shinwell@codesourcery.com>

	* ldlang.c (lang_insert_orphan): Correctly handle the case where
	the section is to end up after the section currently at the end
	of the list in output_bfd.
Index: ld/ldlang.c
===================================================================
RCS file: /cvs/src/src/ld/ldlang.c,v
retrieving revision 1.224
diff -U3 -p -r1.224 ldlang.c
--- ld/ldlang.c	20 Jun 2006 02:22:14 -0000	1.224
+++ ld/ldlang.c	20 Jun 2006 13:36:35 -0000
@@ -1445,7 +1445,18 @@ lang_insert_orphan (asection *s,
 	place->section = &output_bfd->sections;
 
       as = *place->section;
-      if (as != snew && as->prev != snew)
+
+      if (!as)
+        {
+          /* Put the section at the end of the list.  */
+
+	  /* Unlink the section.  */
+	  bfd_section_list_remove (output_bfd, snew);
+
+	  /* Now tack it back on in the right place.  */
+	  bfd_section_list_append (output_bfd, snew);
+        }
+      else if (as != snew && as->prev != snew)
 	{
 	  /* Unlink the section.  */
 	  bfd_section_list_remove (output_bfd, snew);
OUTPUT_ARCH(arm)
ENTRY(stext)
jiffies = jiffies_64;
SECTIONS
{
 . = (0xc0000000) + 0x00008000;
 .init : { /* Init code and data		*/
  _stext = .;
   _sinittext = .;
   *(.init.text)
   _einittext = .;
  __proc_info_begin = .;
   *(.proc.info.init)
  __proc_info_end = .;
  __arch_info_begin = .;
   *(.arch.info.init)
  __arch_info_end = .;
  __tagtable_begin = .;
   *(.taglist.init)
  __tagtable_end = .;
  . = ALIGN(16);
  __setup_start = .;
   *(.init.setup)
  __setup_end = .;
  __early_begin = .;
   *(.early_param.init)
  __early_end = .;
  __initcall_start = .;
   *(.initcall1.init)
   *(.initcall2.init)
   *(.initcall3.init)
   *(.initcall4.init)
   *(.initcall5.init)
   *(.initcall6.init)
   *(.initcall7.init)
  __initcall_end = .;
  __con_initcall_start = .;
   *(.con_initcall.init)
  __con_initcall_end = .;
  __security_initcall_start = .;
   *(.security_initcall.init)
  __security_initcall_end = .;
  . = ALIGN(32);
  __initramfs_end = .;
  . = ALIGN(64);
  __per_cpu_start = .;
   *(.data.percpu)
  __per_cpu_end = .;
  __init_begin = _stext;
  *(.init.data)
  . = ALIGN(4096);
  __init_end = .;
 }
 /DISCARD/ : { /* Exit code and data		*/
  *(.exit.text)
  *(.exit.data)
  *(.exitcall.exit)
 }
 .text : { /* Real text segment		*/
  _text = .; /* Text and read-only data	*/
   *(.text)
   . = ALIGN(8); __sched_text_start = .; *(.sched.text) __sched_text_end = .;
   . = ALIGN(8); __lock_text_start = .; *(.spinlock.text) __lock_text_end = .;
   *(.fixup)
   *(.gnu.warning)
   *(.rodata)
   *(.rodata.*)
   *(.glue_7)
   *(.glue_7t)
  *(.got) /* Global offset table		*/
 }
 . = ALIGN(4096); __start_rodata = .; .rodata : AT(ADDR(.rodata) - 0) { *(.rodata) *(.rodata.*) *(__vermagic) } .rodata1 : AT(ADDR(.rodata1) - 0) { *(.rodata1) } .pci_fixup : AT(ADDR(.pci_fixup) - 0) { __start_pci_fixups_early = .; *(.pci_fixup_early) __end_pci_fixups_early = .; __start_pci_fixups_header = .; *(.pci_fixup_header) __end_pci_fixups_header = .; __start_pci_fixups_final = .; *(.pci_fixup_final) __end_pci_fixups_final = .; __start_pci_fixups_enable = .; *(.pci_fixup_enable) __end_pci_fixups_enable = .; } .rio_route : AT(ADDR(.rio_route) - 0) { __start_rio_route_ops = .; *(.rio_route_ops) __end_rio_route_ops = .; } __ksymtab : AT(ADDR(__ksymtab) - 0) { __start___ksymtab = .; *(__ksymtab) __stop___ksymtab = .; } __ksymtab_gpl : AT(ADDR(__ksymtab_gpl) - 0) { __start___ksymtab_gpl = .; *(__ksymtab_gpl) __stop___ksymtab_gpl = .; } __ksymtab_gpl_future : AT(ADDR(__ksymtab_gpl_future) - 0) { __start___ksymtab_gpl_future = .; *(__ksymtab_gpl_future) __stop___ksymtab_gpl_future = .; } __kcrctab : AT(ADDR(__kcrctab) - 0) { __start___kcrctab = .; *(__kcrctab) __stop___kcrctab = .; } __kcrctab_gpl : AT(ADDR(__kcrctab_gpl) - 0) { __start___kcrctab_gpl = .; *(__kcrctab_gpl) __stop___kcrctab_gpl = .; } __kcrctab_gpl_future : AT(ADDR(__kcrctab_gpl_future) - 0) { __start___kcrctab_gpl_future = .; *(__kcrctab_gpl_future) __stop___kcrctab_gpl_future = .; } __ksymtab_strings : AT(ADDR(__ksymtab_strings) - 0) { *(__ksymtab_strings) } __end_rodata = .; . = ALIGN(4096); __param : AT(ADDR(__param) - 0) { __start___param = .; *(__param) __stop___param = .; }
 _etext = .; /* End of text and rodata section */
 . = ALIGN(8192);
 __data_loc = .;
 .data : AT(__data_loc) {
  __data_start = .; /* address in memory */
  /*
		 * first, the init task union, aligned
		 * to an 8192 byte boundary.
		 */
  *(.init.task)
  . = ALIGN(4096);
  __nosave_begin = .;
  *(.data.nosave)
  . = ALIGN(4096);
  __nosave_end = .;
  /*
		 * then the cacheline aligned data
		 */
  . = ALIGN(32);
  *(.data.cacheline_aligned)
  /*
		 * The exception fixup table (might need resorting at runtime)
		 */
  . = ALIGN(32);
  __start___ex_table = .;
  *(__ex_table)
  __stop___ex_table = .;
  /*
		 * and the usual data section
		 */
  *(.data)
  CONSTRUCTORS
  _edata = .;
 }
 .bss : {
  __bss_start = .; /* BSS				*/
  *(.bss)
  *(COMMON)
  _end = .;
 }
     /* Stabs debugging sections.	*/
 .stab 0 : { *(.stab) }
 .stabstr 0 : { *(.stabstr) }
 .stab.excl 0 : { *(.stab.excl) }
 .stab.exclstr 0 : { *(.stab.exclstr) }
 .stab.index 0 : { *(.stab.index) }
 .stab.indexstr 0 : { *(.stab.indexstr) }
 .comment 0 : { *(.comment) }
}
/*
 * These must never be empty
 * If you have to comment these two assert statements out, your
 * binutils is too old (for other reasons as well)
 */
ASSERT((__proc_info_end - __proc_info_begin), "missing CPU support")
ASSERT((__arch_info_end - __arch_info_begin), "no machine record defined")

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