[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [MiNT] Should Setting Stack be added to Binutils?



Keith Scroggins wrote:
> What I was wondering was if we could/should add stack functionality to
> Binutils so you could pass a linking flag of something like --stack=512k
> to have it set?  Any input?

Here is a quick and dirty patch for enabling the --stack option in the linker. It must be applied to binutils 2.19 already patched for MiNT.

This is just a test for verifying if the concept is good. When we agree to what is good or not, I will take the time to clean it ant to merge it to my "official" binutils patch.

Current limitations are :
- The "ld" produced with this patch seems to be good, but I'm pretty sure that the "strip" would reset the stack settings. So use only the "ld" produced by this patch and keep your old "strip". - The stack value is a number of bytes, the suffixes "K", etc. are not yet supported. - When the --stack option is not used, the value "0" is put into the executable, which means "mysterious default stack size" (actually 64K if I remember well). The MiNTLib has been recently patched for setting an explicit stack value, this linker breaks that behavior.

Usage :
See ld --target-help for the new option :-)

Typical usage is by using the "gcc" command.
Beware, if you want to replace only the "ld" executable for test purposes. On my cross-environment, gcc uses the linker located at this location :
/usr/local/cross-mint/m68k-atari-mint/bin/ld
The "normal" linker command /usr/local/m68k-atari-mint-ld is not used.
Is is probably the same for a native compiler.

So the typical usage is :
gcc hello.c -o hello -Wl,--stack,512000
It just works.

When compiling a GNU package, you can use :
configure ... LDFLAGS=-Wl,--stack,512000
So the stack size will be written in all the makefiles :-)

Another option is so specify the LDFLAGS on the make command line.
make LDFLAGS=-Wl,--stack,512000

If this behavior seems good for you, and it it works as expected, I will clean the patch and get rid of the current limitations.

--
Vincent Rivière
diff -aurN binutils-2.19.1-mint-20090214/bfd/bfd-in.h binutils-2.19.1-mint-stack/bfd/bfd-in.h
--- binutils-2.19.1-mint-20090214/bfd/bfd-in.h	2009-03-09 21:43:14.265625000 +0100
+++ binutils-2.19.1-mint-stack/bfd/bfd-in.h	2009-03-09 20:59:50.234375000 +0100
@@ -734,7 +734,7 @@
 
 /* MiNT executable support routines for the linker.  */
 extern bfd_boolean bfd_m68kmint_set_extended_flags
-  (bfd *, flagword);
+  (bfd *, flagword, unsigned long);
 extern bfd_boolean bfd_m68kmint_add_tpa_relocation_entry
   (bfd *abfd, bfd_vma address);
 
diff -aurN binutils-2.19.1-mint-20090214/bfd/bfd-in2.h binutils-2.19.1-mint-stack/bfd/bfd-in2.h
--- binutils-2.19.1-mint-20090214/bfd/bfd-in2.h	2009-03-09 21:43:14.406250000 +0100
+++ binutils-2.19.1-mint-stack/bfd/bfd-in2.h	2009-03-09 20:59:02.015625000 +0100
@@ -741,7 +741,7 @@
 
 /* MiNT executable support routines for the linker.  */
 extern bfd_boolean bfd_m68kmint_set_extended_flags
-  (bfd *, flagword);
+  (bfd *, flagword, unsigned long);
 extern bfd_boolean bfd_m68kmint_add_tpa_relocation_entry
   (bfd *abfd, bfd_vma address);
 
diff -aurN binutils-2.19.1-mint-20090214/bfd/prg-mint.c binutils-2.19.1-mint-stack/bfd/prg-mint.c
--- binutils-2.19.1-mint-20090214/bfd/prg-mint.c	2009-03-09 21:43:15.218750000 +0100
+++ binutils-2.19.1-mint-stack/bfd/prg-mint.c	2009-03-09 21:17:19.531250000 +0100
@@ -168,6 +168,8 @@
 
   flagword	prg_flags;	     /* Standard GEMDOS flags.	*/
 
+  unsigned long	stacksize;	     /* Stack size.	*/
+
   bfd_boolean	reloc_error;	     /* True if an unhandled error during
 					relocation occured.  */
 };
@@ -1548,6 +1550,20 @@
   PUT_WORD (abfd, myinfo->symbol_format, exec_bytes->g_symbol_format);
 
   memset (&exec_bytes->g_pad0, 0, sizeof (exec_bytes->g_pad0));
+
+  /* Ajust the stack size.  */
+  if (myinfo->stkpos)
+  {
+    bfd_byte big_endian_stacksize[4];
+
+    bfd_h_put_32 (abfd, myinfo->stacksize, &big_endian_stacksize);
+
+    if (bfd_seek (abfd, (file_ptr) myinfo->stkpos, SEEK_SET) != 0)
+      return FALSE;
+
+    if (bfd_bwrite (big_endian_stacksize, 4, abfd) != 4)
+      return FALSE;
+  }
 
   /* The standard stuff.  */
   NAME(aout,swap_exec_header_out) (abfd, execp, exec_bytes);
@@ -1631,7 +1647,7 @@
    It is called by the linker emulation script.  */
 
 bfd_boolean
-bfd_m68kmint_set_extended_flags (bfd *abfd, flagword prg_flags)
+bfd_m68kmint_set_extended_flags (bfd *abfd, flagword prg_flags, unsigned long stacksize)
 {
   struct mint_internal_info *myinfo = obj_aout_ext (abfd);
 
@@ -1650,6 +1666,7 @@
   obj_aout_ext (abfd) = myinfo;
 
   myinfo->prg_flags = prg_flags;
+  myinfo->stacksize = stacksize;
 
   return TRUE;
 }
diff -aurN binutils-2.19.1-mint-20090214/ld/emultempl/mint.em binutils-2.19.1-mint-stack/ld/emultempl/mint.em
--- binutils-2.19.1-mint-20090214/ld/emultempl/mint.em	2009-03-09 21:43:17.468750000 +0100
+++ binutils-2.19.1-mint-stack/ld/emultempl/mint.em	2009-03-09 20:49:46.390625000 +0100
@@ -41,6 +41,9 @@
 /* Option flags.  */
 static flagword prg_flags = (_MINT_F_FASTLOAD | _MINT_F_ALTLOAD
 			     | _MINT_F_ALTALLOC | _MINT_F_MEMPRIVATE);
+
+/* Stack size.  */
+static unsigned long stacksize = 0;
 
 /* MiNT format extra command line options.  */
 
@@ -60,6 +63,7 @@
 #define OPTION_MEM_SUPER (OPTION_MEM_GLOBAL + 1)
 #define OPTION_MEM_READONLY (OPTION_MEM_SUPER + 1)
 #define OPTION_PRG_FLAGS (OPTION_MEM_READONLY + 1)
+#define OPTION_STACK (OPTION_PRG_FLAGS + 1)
 
 static void
 gld${EMULATION_NAME}_add_options
@@ -93,6 +97,7 @@
     {"mreadable-memory", no_argument, NULL, OPTION_MEM_READONLY},
     {"mreadonly-memory", no_argument, NULL, OPTION_MEM_READONLY},
     {"mprg-flags", required_argument, NULL, OPTION_PRG_FLAGS},
+    {"stack", required_argument, NULL, OPTION_STACK},
     {NULL, no_argument, NULL, 0}
   };
 
@@ -182,6 +187,20 @@
 	  }
 	  break;
       }
+    case OPTION_STACK:
+      {
+	char* tail;
+	unsigned long flag_value = strtoul (optarg, &tail, 0);
+	if (*tail != '\0')
+	  {
+	    einfo (_("%P: warning: ignoring invalid stack size %s\n"), optarg);
+	  }
+	else
+	  {
+	    stacksize = flag_value;
+	  }
+	  break;
+      }
     }
   return TRUE;
 }
@@ -209,6 +228,7 @@
   fprintf (file, _("                              Process memory is readable but not writable\n"));
   fprintf (file, "\n");
   fprintf (file, _("  --mprg-flags <value>        Set all the flags with an integer raw value\n"));
+  fprintf (file, _("  --stack <size>              Set size of the initial stack\n"));
 }
 
 /* This callback is called by lang_for_each_statement. It checks that the
@@ -277,7 +297,7 @@
   lang_for_each_statement (gld${EMULATION_NAME}_check_output_sections);
 
   /* Set the MiNT executable header flags.  */
-  if (!bfd_m68kmint_set_extended_flags (link_info.output_bfd, prg_flags))
+  if (!bfd_m68kmint_set_extended_flags (link_info.output_bfd, prg_flags, stacksize))
     einfo (_("%F%P:%B: unable to set the header flags\n"), link_info.output_bfd);
 
   /* Generate TPA relocation entries for the data statements.  */