ソースを参照

Another update to initfini.awk and initfini.c from Stefan Allius
to hopefully address SH wierdness. Now works on other architecture
properly as well.

Eric Andersen 21 年 前
コミット
c6e5fdc8e9
2 ファイル変更34 行追加13 行削除
  1. 15 13
      extra/scripts/initfini.awk
  2. 19 0
      libc/sysdeps/linux/common/initfini.c

+ 15 - 13
extra/scripts/initfini.awk

@@ -18,23 +18,29 @@ BEGIN \
     if(/\.end/) {end=1}
     if(/\.align/) {alignval=$2}
 # here comes some special stuff for the SuperH targets
-# Search for all labels
-#    if(/_GLOBAL_OFFSET_TABLE_/) {
-#      sub (":","",last);
-#      glb_label[glb_idx] = last;
-#      glb_idx += 1;
-#      glb = $0;
-#    }
+#  We search for all labels, which uses the _GLOBAL_OFFSET_TABLE_
+#  definition, and store them in the glb_label array.
+    if(/_GLOBAL_OFFSET_TABLE_/) {
+      glb_label[glb_idx] = last;
+      glb_idx += 1;
+      glb = $0;
+    }
     last = $1;
   }
   close("initfini.s");
 }
+# special rules for the SuperH targets (They do nothing on other targets)
+/SH_GLB_BEGINS/ && glb_idx==0 {omitcrti +=1}
+/_init_SH_GLB/  && glb_idx>=1 {print glb_label[0] glb >> "crti.S"}
+/_fini_SH_GLB/  && glb_idx>=2 {print glb_label[1] glb >> "crti.S"}
+/SH_GLB_ENDS/   && glb_idx==0 {omitcrti -=1}
+/SH_GLB/ || /_GLOBAL_OFFSET_TABLE_/{getline}
 
-/^_init:/{omitcrtn=1;if (glb_idx>0) print glb_label[0] ":" glb >> "crti.S";}
-/^_fini:/{omitcrtn=1;if (glb_idx>1) print glb_label[1] ":" glb >> "crti.S";}
+# rules for all targets
 /HEADER_ENDS/{omitcrti=1;omitcrtn=1;getline}
 /PROLOG_BEGINS/{omitcrti=0;omitcrtn=0;getline}
 /i_am_not_a_leaf/{getline}
+/_init:/||/_fini:/{omitcrtn=1}
 /PROLOG_PAUSES/{omitcrti=1;getline}
 /PROLOG_UNPAUSES/{omitcrti=0;getline}
 /PROLOG_ENDS/{omitcrti=1;getline}
@@ -78,10 +84,6 @@ BEGIN \
   { gsub("ALIGN","",$0)
   }
 }
-# substitude all label references of the _GLOBAL_OFFSET_TABLE_
-# .L10  ==> .L10b etc.
-glb_idx>0 { gsub (glb_label[0],sprintf("%sb",glb_label[0]),$0)}
-glb_idx>1 { gsub (glb_label[1],sprintf("%sb",glb_label[1]),$0)}
 
 omitcrti==0 {print >> "crti.S"}
 omitcrtn==0 {print >> "crtn.S"}

+ 19 - 0
libc/sysdeps/linux/common/initfini.c

@@ -52,6 +52,23 @@
 #  define HIDDEN(func)
 #endif
 
+#if defined(__sh__)
+  /* The macro insert this sh specific stuff:
+     @_SH_GLB_BEGINS
+          bra     1f
+	  nop
+	  ALIGN
+     @func_SH_GLB_LABEL
+     1:
+     @_SH_GLB_ENDS
+   */
+#define GLB_STUFF(func)  asm ("\n/*@_SH_GLB_BEGINS*/"); \
+  asm ("\n\tbra\t1f\n\tnop\n\tALIGN\n/*@" #func"_SH_GLB_LABEL*/\n1:"); \
+  asm ("\n/*@_SH_GLB_ENDS*/");
+#else
+#define GLB_STUFF(func)
+#endif
+
 /* The initial common code ends here. */
 asm ("\n/*@HEADER_ENDS*/");
 
@@ -107,6 +124,7 @@ void _init (void)
   asm ("\n/*@_init_PROLOG_UNPAUSES*/");
 #endif
 
+  GLB_STUFF(_init)
   asm ("ALIGN");
   asm("END_INIT");
   /* Now the epilog. */
@@ -127,6 +145,7 @@ void _fini (void)
 {
 
   /* End of the _fini prolog. */
+  GLB_STUFF(_fini)
   asm ("ALIGN");
   asm ("END_FINI");
   asm ("\n/*@_fini_PROLOG_ENDS*/");