This is the mail archive of the binutils@sources.redhat.com 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]

[arm] Infrastructure for eabi unwinding tables


The attached patch adds features to binutils which are required for arm eabi 
based unwinding tables.

It adds segment relative relocations, a new arm specific section type, and 
linker support for the new sections.

Tested with cross to arm-none-elf.
Ok?

Paul

2004-08-10  Paul Brook  <paul@codesourcery.com>

bfd/
	* elf32-arm.c (elf32_arm_get_roseg_base): New function.
	(elf32_arm_get_rwseg_base): New function.
	(elf32_arm_final_link_relocate): Handle R_ARM_SBREL32 and
	R_ARM_ROSEGREL32.
	(elf32_arm_fake_sections, is_unwind_section_name): New functions.
	(elf32_arm_section_from_shdr): New function.
	(elf_backend_fake_sections, elf_backend_section_from_shdr): Define.
binutils/
	* readelf.c (get_arm_section_type_name): New function.
	(get_section_type_name): Use it.
gas/
	* config/tc-arm.c (arm_elf_change_section): Set elf_linked_to_section.
include/elf/
	* arm.h (SHT_ARM_EXIDX): Define.
	(ELF_STRING_ARM_unwind*): Define.
ld/
	* emulparams/armelf.sh: Define OTHER_READONLY_SECTIONS and
	TEXT_START_SYMBOLS.
ld/testsuite/
	* ld-arm/arm-app-abs32.d: Disassembler may output __text_start.
	* ld-arm/arm-app.d: Disassembler may output __text_start.
	* ld-arm/arm-static-app.d: Disassembler may output __text_start.
Index: bfd/elf32-arm.h
===================================================================
RCS file: /cvs/src/src/bfd/elf32-arm.h,v
retrieving revision 1.133
diff -u -p -r1.133 elf32-arm.h
--- bfd/elf32-arm.h	24 Jun 2004 04:46:18 -0000	1.133
+++ bfd/elf32-arm.h	10 Aug 2004 12:38:12 -0000
@@ -1239,6 +1239,33 @@ elf32_arm_to_thumb_stub (info, name, inp
   return TRUE;
 }
 
+
+/* Get the start of the RO segment (ie. the .text section).  */
+/* ??? This is probably wrong for anything with shared libraries.  */
+
+static bfd_vma
+elf32_arm_get_roseg_base (bfd * abfd)
+{
+  asection *sec;
+  
+  sec = bfd_get_section_by_name (abfd, ".text");
+  return sec->vma;
+}
+
+
+/* Get the start of the RW segment (ie. the .data section).  */
+/* ??? This is probably wrong for anything with shared libraries.  */
+
+static bfd_vma
+elf32_arm_get_rwseg_base (bfd * abfd)
+{
+  asection *sec;
+  
+  sec = bfd_get_section_by_name (abfd, ".data");
+  return sec->vma;
+}
+
+
 /* Perform a relocation as part of a final link.  */
 
 static bfd_reloc_status_type
@@ -1324,6 +1351,8 @@ elf32_arm_final_link_relocate (howto, in
     case R_ARM_XPC25:
 #endif
     case R_ARM_PLT32:
+    case R_ARM_ROSEGREL32:
+    case R_ARM_SBREL32:
       /* r_symndx will be zero only for relocs against symbols
 	 from removed linkonce sections, or sections discarded by
 	 a linker script.  */
@@ -1334,7 +1363,8 @@ elf32_arm_final_link_relocate (howto, in
 	 will use the symbol's value, which may point to a PLT entry, but we
 	 don't need to handle that here.  If we created a PLT entry, all
 	 branches in this object should go to it.  */
-      if ((r_type != R_ARM_ABS32 && r_type != R_ARM_REL32)
+      if ((r_type != R_ARM_ABS32 && r_type != R_ARM_REL32
+	   && r_type != R_ARM_REL32)
 	  && h != NULL
 	  && splt != NULL
 	  && h->plt.offset != (bfd_vma) -1)
@@ -1362,7 +1392,9 @@ elf32_arm_final_link_relocate (howto, in
 	      || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
 	      || h->root.type != bfd_link_hash_undefweak)
 	  && r_type != R_ARM_PC24
-	  && r_type != R_ARM_PLT32)
+	  && r_type != R_ARM_PLT32
+	  && r_type != R_ARM_ROSEGREL32
+	  && r_type != R_ARM_SBREL32)
 	{
 	  Elf_Internal_Rela outrel;
 	  bfd_byte *loc;
@@ -1555,6 +1587,18 @@ elf32_arm_final_link_relocate (howto, in
 		    + input_section->output_offset + rel->r_offset);
 	  value += addend;
 	  break;
+
+	case R_ARM_ROSEGREL32:
+	  value -= elf32_arm_get_roseg_base (output_bfd);
+	  value += addend;
+	  if (sym_flags == STT_ARM_TFUNC)
+	    value |= 1;
+	  break;
+
+	case R_ARM_SBREL32:
+	  value -= elf32_arm_get_rwseg_base (output_bfd);
+	  value += addend;
+	  break;
 	}
 
       bfd_put_32 (input_bfd, value, hit_data);
@@ -1937,9 +1981,6 @@ elf32_arm_final_link_relocate (howto, in
 				       contents, rel->r_offset, value,
 				       (bfd_vma) 0);
 
-    case R_ARM_SBREL32:
-      return bfd_reloc_notsupported;
-
     case R_ARM_AMP_VCALL9:
       return bfd_reloc_notsupported;
 
@@ -4106,6 +4147,8 @@ elf32_arm_reloc_type_class (rela)
 
 static bfd_boolean elf32_arm_section_flags           PARAMS ((flagword *, const Elf_Internal_Shdr *));
 static void        elf32_arm_final_write_processing  PARAMS ((bfd *, bfd_boolean));
+static bfd_boolean elf32_arm_fake_sections (bfd *, Elf_Internal_Shdr *,
+					    asection *);
 
 /* Set the right machine number for an Arm ELF file.  */
 
@@ -4129,6 +4172,66 @@ elf32_arm_final_write_processing (abfd, 
 }
 
 
+/* Return TRUE if this is an unwinding table entry.  */
+
+static bfd_boolean
+is_unwind_section_name (bfd * abfd ATTRIBUTE_UNUSED, const char * name)
+{
+  size_t len1, len2;
+
+  len1 = sizeof (ELF_STRING_ARM_unwind) - 1;
+  len2 = sizeof (ELF_STRING_ARM_unwind_once) - 1;
+  return (strncmp (name, ELF_STRING_ARM_unwind, len1) == 0
+	  || strncmp (name, ELF_STRING_ARM_unwind_once, len2) == 0);
+}
+
+
+/* Set the type and flags for an ARM section.  We do this by the
+   section name, which is a hack, but ought to work.  */
+
+static bfd_boolean
+elf32_arm_fake_sections (bfd * abfd, Elf_Internal_Shdr * hdr, asection * sec)
+{
+  const char * name;
+
+  name = bfd_get_section_name (abfd, sec);
+
+  if (is_unwind_section_name (abfd, name))
+    {
+      hdr->sh_type = SHT_ARM_EXIDX;
+      hdr->sh_flags |= SHF_LINK_ORDER;
+    }
+  return TRUE;
+}
+
+
+/* Handle an ARM specific section when reading an object file.  This
+   is called when elf.c finds a section with an unknown type.  */
+
+static bfd_boolean
+elf32_arm_section_from_shdr (bfd *abfd, Elf_Internal_Shdr * hdr,
+			     const char *name)
+{
+  /* There ought to be a place to keep ELF backend specific flags, but
+     at the moment there isn't one.  We just keep track of the
+     sections by their name, instead.  Fortunately, the ABI gives
+     names for all the ARM specific sections, so we will probably get
+     away with this.  */
+  switch (hdr->sh_type)
+    {
+    case SHT_ARM_EXIDX:
+      break;
+
+    default:
+      return FALSE;
+    }
+
+  if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
+    return FALSE;
+
+  return TRUE;
+}
+
 /* Called for each symbol.  Builds a section map based on mapping symbols.
    Does not alter any of the symbols.  */
 
@@ -4303,6 +4406,8 @@ elf32_arm_write_section (bfd *output_bfd
 #define elf_backend_reloc_type_class		elf32_arm_reloc_type_class
 #define elf_backend_object_p			elf32_arm_object_p
 #define elf_backend_section_flags		elf32_arm_section_flags
+#define elf_backend_fake_sections		elf32_arm_fake_sections
+#define elf_backend_section_from_shdr		elf32_arm_section_from_shdr
 #define elf_backend_final_write_processing      elf32_arm_final_write_processing
 #define elf_backend_copy_indirect_symbol        elf32_arm_copy_indirect_symbol
 
Index: binutils/readelf.c
===================================================================
RCS file: /cvs/src/src/binutils/readelf.c,v
retrieving revision 1.249
diff -u -p -r1.249 readelf.c
--- binutils/readelf.c	6 Aug 2004 13:13:30 -0000	1.249
+++ binutils/readelf.c	10 Aug 2004 12:38:14 -0000
@@ -2363,6 +2363,19 @@ get_ia64_section_type_name (unsigned int
 }
 
 static const char *
+get_arm_section_type_name (unsigned int sh_type)
+{
+  switch (sh_type)
+    {
+    case SHT_ARM_EXIDX:
+      return "ARM_EXIDX";
+    default:
+      break;
+    }
+  return NULL;
+}
+
+static const char *
 get_section_type_name (unsigned int sh_type)
 {
   static char buff[32];
@@ -2412,6 +2425,9 @@ get_section_type_name (unsigned int sh_t
 	    case EM_IA_64:
 	      result = get_ia64_section_type_name (sh_type);
 	      break;
+	    case EM_ARM:
+	      result = get_arm_section_type_name (sh_type);
+	      break;
 	    default:
 	      result = NULL;
 	      break;
Index: gas/config/tc-arm.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-arm.c,v
retrieving revision 1.171
diff -u -p -r1.171 tc-arm.c
--- gas/config/tc-arm.c	6 Aug 2004 16:18:07 -0000	1.171
+++ gas/config/tc-arm.c	10 Aug 2004 12:38:17 -0000
@@ -2901,6 +2958,11 @@ arm_elf_change_section (void)
 {
   flagword flags;
 
+  /* Link unlinked unwind index table section to the .text section.  */
+  if (elf_section_type (now_seg) == SHT_ARM_EXIDX
+      && elf_linked_to_section (now_seg) == NULL)
+    elf_linked_to_section (now_seg) = text_section;
+
   if (!SEG_NORMAL (now_seg))
     return;
 
Index: include/elf/arm.h
===================================================================
RCS file: /cvs/src/src/include/elf/arm.h,v
retrieving revision 1.14
diff -u -p -r1.14 arm.h
--- include/elf/arm.h	6 Aug 2004 16:18:11 -0000	1.14
+++ include/elf/arm.h	10 Aug 2004 12:38:23 -0000
@@ -64,6 +64,9 @@
 #define STT_ARM_TFUNC      STT_LOPROC   /* A Thumb function.  */
 #define STT_ARM_16BIT      STT_HIPROC   /* A Thumb label.  */
 
+/* Additional section types.  */
+#define SHT_ARM_EXIDX	0x70000001
+
 /* ARM-specific values for sh_flags.  */
 #define SHF_ENTRYSECT      0x10000000   /* Section contains an entry point.  */
 #define SHF_COMDEF         0x80000000   /* Section may be multiply defined in the input to a link step.  */
@@ -152,5 +155,11 @@ END_RELOC_NUMBERS (R_ARM_max)
 
 /* The name of the note section used to identify arm variants.  */
 #define ARM_NOTE_SECTION ".note.gnu.arm.ident"
-     
+
+/* Special section names.  */
+#define ELF_STRING_ARM_unwind		".ARM.exidx"
+#define ELF_STRING_ARM_unwind_info	".ARM.extab"
+#define ELF_STRING_ARM_unwind_once	".gnu.linkonce.armexidx."
+#define ELF_STRING_ARM_unwind_info_once ".gnu.linkonce.armextab."
+
 #endif /* _ELF_ARM_H */
Index: ld/emulparams/armelf.sh
===================================================================
RCS file: /cvs/src/src/ld/emulparams/armelf.sh,v
retrieving revision 1.12
diff -u -p -r1.12 armelf.sh
--- ld/emulparams/armelf.sh	9 Feb 2004 18:06:20 -0000	1.12
+++ ld/emulparams/armelf.sh	10 Aug 2004 12:38:23 -0000
@@ -10,8 +10,14 @@ OTHER_TEXT_SECTIONS='*(.glue_7t) *(.glue
 OTHER_BSS_SYMBOLS='__bss_start__ = .;'
 OTHER_BSS_END_SYMBOLS='_bss_end__ = . ; __bss_end__ = . ; __end__ = . ;'
 OTHER_SECTIONS='.note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }'
+OTHER_READONLY_SECTIONS="
+  .ARM.extab ${RELOCATING-0} : { *(.ARM.extab${RELOCATING+* .gnu.linkonce.armextab.*}) }
+  __exidx_start = .;
+  .ARM.exidx ${RELOCATING-0} : { *(.ARM.exidx${RELOCATING+* .gnu.linkonce.armexidx.*}) }
+  __exidx_end = .;"
 
 DATA_START_SYMBOLS='__data_start = . ;';
+TEXT_START_SYMBOLS='__text_start = . ;';
 
 GENERATE_SHLIB_SCRIPT=yes
 
Index: ld/testsuite/ld-arm/arm-app-abs32.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/arm-app-abs32.d,v
retrieving revision 1.1
diff -u -p -r1.1 arm-app-abs32.d
--- ld/testsuite/ld-arm/arm-app-abs32.d	23 Jan 2004 16:51:39 -0000	1.1
+++ ld/testsuite/ld-arm/arm-app-abs32.d	10 Aug 2004 12:38:23 -0000
@@ -17,7 +17,7 @@ Disassembly of section .plt:
     .*:	e5bcf.* 	ldr	pc, \[ip, #.*\]!
 Disassembly of section .text:
 
-.* <_start>:
+.* <(__text|)_start>:
     .*:	e1a0c00d 	mov	ip, sp
     .*:	e92dd800 	stmdb	sp!, {fp, ip, lr, pc}
     .*:	e59f0004 	ldr	r0, \[pc, #4\]	; .* <.text\+0x14>
Index: ld/testsuite/ld-arm/arm-app.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/arm-app.d,v
retrieving revision 1.1
diff -u -p -r1.1 arm-app.d
--- ld/testsuite/ld-arm/arm-app.d	6 Jan 2004 21:47:38 -0000	1.1
+++ ld/testsuite/ld-arm/arm-app.d	10 Aug 2004 12:38:23 -0000
@@ -17,7 +17,7 @@ Disassembly of section .plt:
  .*:	e5bcf.* 	ldr	pc, \[ip, #.*\]!
 Disassembly of section .text:
 
-.* <_start>:
+.* <(__text|)_start>:
  .*:	e1a0c00d 	mov	ip, sp
  .*:	e92dd800 	stmdb	sp!, {fp, ip, lr, pc}
  .*:	eb000001 	bl	.* <app_func>
Index: ld/testsuite/ld-arm/arm-static-app.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/arm-static-app.d,v
retrieving revision 1.1
diff -u -p -r1.1 arm-static-app.d
--- ld/testsuite/ld-arm/arm-static-app.d	13 Jan 2004 21:09:18 -0000	1.1
+++ ld/testsuite/ld-arm/arm-static-app.d	10 Aug 2004 12:38:23 -0000
@@ -6,7 +6,7 @@ start address 0x.*
 
 Disassembly of section .text:
 
-.* <_start>:
+.* <(__text|)_start>:
     .*:	e1a0c00d 	mov	ip, sp
     .*:	e92dd800 	stmdb	sp!, {fp, ip, lr, pc}
     .*:	eb000001 	bl	.* <app_func>

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