Преглед изворни кода

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 пре 22 година
родитељ
комит
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*/");