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]

Re: [ARM] fix handling of "merge strings" sections


Paul,

On 28.11.2007 16:16, Paul Brook wrote:

This is still going to break valid code. At minimum it needs to be controlled by a commandline option. I'm strongly opposed to breaking valid code just to workaround bugs in old, broken, proprietary toolchains.

Paul


I agree with you, but unfortunately we have to cope with code generated by RVCT-2.2.


Here is another patch proposal, essentially the same as the previous one, but controlled with a command line option, as you suggested.

In case anyone has the same kind of issue, at least they can find a patch, if it is not integrated in the mainstream.

Christophe.


Index: ld/emultempl/armelf.em
===================================================================
--- ld/emultempl/armelf.em	(revision 457)
+++ ld/emultempl/armelf.em	(working copy)
@@ -35,6 +35,7 @@ static int target1_is_rel = 0${TARGET1_I
 static char *target2_type = "${TARGET2_TYPE}";
 static int fix_v4bx = 0;
 static int use_blx = 0;
+static int rvct22_conststring = 0;
 
 static void
 gld${EMULATION_NAME}_before_parse (void)
@@ -213,7 +214,7 @@ static void
 arm_elf_create_output_section_statements (void)
 {
   bfd_elf32_arm_set_target_relocs (&link_info, target1_is_rel, target2_type,
-                                   fix_v4bx, use_blx);
+                                   fix_v4bx, use_blx, rvct22_conststring);
 }
 
 EOF
@@ -229,6 +230,7 @@ PARSE_AND_LIST_PROLOGUE='
 #define OPTION_TARGET2			305
 #define OPTION_FIX_V4BX			306
 #define OPTION_USE_BLX			307
+#define OPTION_RVCT22_CONSTSTRING	308
 '
 
 PARSE_AND_LIST_SHORTOPTS=p
@@ -242,6 +244,7 @@ PARSE_AND_LIST_LONGOPTS='
   { "target2", required_argument, NULL, OPTION_TARGET2},
   { "fix-v4bx", no_argument, NULL, OPTION_FIX_V4BX},
   { "use-blx", no_argument, NULL, OPTION_USE_BLX},
+  { "rvct22-conststring", no_argument, NULL, OPTION_RVCT22_CONSTSTRING},
 '
 
 PARSE_AND_LIST_OPTIONS='
@@ -252,6 +255,7 @@ PARSE_AND_LIST_OPTIONS='
   fprintf (file, _("     --target2=<type>         Specify definition of R_ARM_TARGET2\n"));
   fprintf (file, _("     --fix-v4bx               Rewrite BX rn as MOV pc, rn for ARMv4\n"));
   fprintf (file, _("     --use-blx                Enable use of BLX instructions\n"));
+  fprintf (file, _("     --rvct22_conststring     Workaround RVCT2.2 .conststring section merging\n"));
 '
 
 PARSE_AND_LIST_ARGS_CASES='
@@ -286,6 +290,10 @@ PARSE_AND_LIST_ARGS_CASES='
     case OPTION_USE_BLX:
       use_blx = 1;
       break;
+
+    case OPTION_RVCT22_CONSTSTRING:
+      rvct22_conststring = 1;
+      break;
 '
 
 # We have our own after_open and before_allocation functions, but they call
Index: ld/ld.info
===================================================================
--- ld/ld.info	(revision 457)
+++ ld/ld.info	(working copy)
@@ -4362,11 +4350,31 @@ entry. This should lead to such calls ex
    This option is enabled implicitly for SymbianOS, so there is no need
 to specify it if you are using that target.
 
+   When linking with object files generated by RVCT-2.2, which define
+and reference symbols in the `.conststring' section, the
+`--rvct22-conststring' switch instructs the linker to resolve the
+involved relocations in the way expected by RVCT-2.2.
+
+   A symbol value is actually an offset from the beginning of a section.
+
+   ARM's RVCT-2.2 compiler assumes that the addend of a relocation to a
+symbol in the `.conststring' section is an offset, while GCC assumes
+such an offset is an absolute value.
+
+   In other words, RVCT-2.2 assumes that the addend will be updated by
+the linker after merging the section contents, while GCC assumes it
+will be kept unmodified, unless the referenced symbol is the section
+base symbol.
+
+   If you mix code produced by RVCT-2.2 and GCC, and both object files
+define and reference symbols in the `.conststring' section, there is
+propably no solution to the conflict.
+
 
 File: ld.info,  Node: HPPA ELF32,  Next: MMIX,  Prev: ARM,  Up: Machine Dependent
 
Index: ld/ld.texinfo
===================================================================
--- ld/ld.texinfo	(revision 457)
+++ ld/ld.texinfo	(working copy)
@@ -5397,6 +5397,28 @@ each PLT entry. This should lead to such
 This option is enabled implicitly for SymbianOS, so there is no need to
 specify it if you are using that target.
 
+@cindex RVCT22_CONSTSTRING
+@kindex --rvct22-conststring
+When linking with object files generated by RVCT-2.2, which define and
+reference symbols in the @code{.conststring} section, the
+@option{--rvct22-conststring} switch instructs the linker to resolve
+the involved relocations in the way expected by RVCT-2.2.
+
+A symbol value is actually an offset from the beginning of a section.
+
+ARM's RVCT-2.2 compiler assumes that the addend of a relocation to a
+symbol in the @code{.conststring} section is an offset, while GCC
+assumes such an offset is an absolute value.
+
+In other words, RVCT-2.2 assumes that the addend will be updated by
+the linker after merging the section contents, while GCC assumes it
+will be kept unmodified, unless the referenced symbol is the section
+base symbol.
+
+If you mix code produced by RVCT-2.2 and GCC, and both object files
+define and reference symbols in the @code{.conststring} section, there
+is propably no solution to the conflict.
+
 @ifclear GENERIC
 @lowersections
 @end ifclear
Index: bfd/bfd-in.h
===================================================================
--- bfd/bfd-in.h	(revision 457)
+++ bfd/bfd-in.h	(working copy)
@@ -839,7 +839,7 @@ extern bfd_boolean bfd_elf32_arm_process
   (bfd *, struct bfd_link_info *, int);
 
 void bfd_elf32_arm_set_target_relocs
-  (struct bfd_link_info *, int, char *, int, int);
+(struct bfd_link_info *, int, char *, int, int, int);
 
 extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking
   (bfd *, struct bfd_link_info *);
Index: bfd/bfd-in2.h
===================================================================
--- bfd/bfd-in2.h	(revision 457)
+++ bfd/bfd-in2.h	(working copy)
@@ -846,7 +846,7 @@ extern bfd_boolean bfd_elf32_arm_process
   (bfd *, struct bfd_link_info *, int);
 
 void bfd_elf32_arm_set_target_relocs
-  (struct bfd_link_info *, int, char *, int, int);
+(struct bfd_link_info *, int, char *, int, int, int);
 
 extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking
   (bfd *, struct bfd_link_info *);
Index: bfd/elf32-arm.c
===================================================================
--- bfd/elf32-arm.c	(revision 457)
+++ bfd/elf32-arm.c	(working copy)
@@ -2136,6 +2136,10 @@ struct elf32_arm_link_hash_table
     /* Nonzero if the ARM/Thumb BLX instructions are available for use.  */
     int use_blx;
 
+    /* Nonzero if relocations to .conststring should be patched in the
+       way expected by ARMs' RVCT-2.2 */
+    int rvct22_conststring;
+
     /* The number of bytes in the initial entry in the PLT.  */
     bfd_size_type plt_header_size;
 
@@ -2409,6 +2413,7 @@ elf32_arm_link_hash_table_create (bfd *a
 #endif
   ret->fix_v4bx = 0;
   ret->use_blx = 0;
+  ret->rvct22_conststring = 0;
   ret->vxworks_p = 0;
   ret->symbian_p = 0;
   ret->use_rel = 1;
@@ -2985,7 +2990,8 @@ bfd_elf32_arm_set_target_relocs (struct 
 				 int target1_is_rel,
 				 char * target2_type,
                                  int fix_v4bx,
-				 int use_blx)
+				 int use_blx,
+				 int rvct22_conststring)
 {
   struct elf32_arm_link_hash_table *globals;
 
@@ -3005,6 +3011,7 @@ bfd_elf32_arm_set_target_relocs (struct 
     }
   globals->fix_v4bx = fix_v4bx;
   globals->use_blx |= use_blx;
+  globals->rvct22_conststring = rvct22_conststring;
 }
 
 /* The thumb form of a long branch is a bit finicky, because the offset
@@ -5660,7 +5667,14 @@ elf32_arm_relocate_section (bfd *       
 			    + sec->output_offset
 			    + sym->st_value);
 	      if ((sec->flags & SEC_MERGE)
-		       && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+		  && (
+		      (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+		      ||
+		      ( globals->rvct22_conststring
+			&& (sec->flags & SEC_STRINGS)
+			&& strcmp(sec->name, ".conststring")==0 )
+		      )
+		  )
 		{
 		  asection *msec;
 		  bfd_vma addend, value;
2007-11-28  Christophe Lyon  <christophe.lyon@st.com>

	bfd/
	* bfd-in.h (bfd_elf32_arm_set_target_relocs): Update prototype.
	* bfd-in2.h: Regenerate.
	* elf32-arm.c (elf32_arm_link_hash_table): New field, 'rvct22_conststring'.
	(elf32_arm_link_hash_table_create): Initialise rvct22_conststring.
	(bfd_elf32_arm_set_target_relocs): Handle rvct22_conststring.
	(elf32_arm_relocate_section): Update addend for relocations to
	symbols in .conststring section of non-STT_SECTION type if
	rvct22_conststring is in effect.

	ld/
	* emultempl/armelf.em (rvct22_conststring): New variable.
	(arm_elf_create_output_section_statements): Communicate
	rvct22_conststring flag value to bfd.
	(PARSE_AND_LIST_PROLOGUE): Add option token OPTION_RVCT22_CONSTSTRING.
	(PARSE_AND_LIST_LONGOPTS): Add option --rvct22-conststring.
	(PARSE_AND_LIST_OPTIONS): Add option --rvct22-conststring.
	(PARSE_AND_LIST_ARGS_CASES): Add option OPTION_RVCT22_CONSTSTRING.
	* ld.texinfo: Document --rvct22-conststring.

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