Add .incbin pseudo op
authorNick Clifton <nickc@redhat.com>
Mon, 9 Jul 2001 08:19:18 +0000 (08:19 +0000)
committerNick Clifton <nickc@redhat.com>
Mon, 9 Jul 2001 08:19:18 +0000 (08:19 +0000)
gas/ChangeLog
gas/NEWS
gas/doc/as.texinfo
gas/read.c
gas/read.h
gas/testsuite/ChangeLog
gas/testsuite/gas/all/gas.exp
gas/testsuite/gas/all/incbin.d [new file with mode: 0644]
gas/testsuite/gas/all/incbin.s [new file with mode: 0644]

index 9944e1d590fe84ab9be4f5c16fd6929c443c02f2..0ebe08d861470b141c83ba279555dee869200755 100644 (file)
@@ -1,3 +1,11 @@
+2001-07-08  Anders Norlander <anorland@synergenix.se>
+
+       * read.c (s_incbin): New .incbin function.
+       * read.c (potable): Add "incbin" pseudo-op.
+       * read.h: Add s_incbin prototype.
+       * doc/as.texinfo (incbin): Document .incbin pseudo-op.
+       * NEWS: Mention new feature.
+
 2001-07-07  Nick Clifton  <nickc@cambridge.redhat.com>
 
        * ecoff.c (add_file): Only set debug_type to DEBUG_NONE if it is
index 63dc260ace46beda5a190bc6546ffeaac59c3715..6e6d447895b593d198507f00eb5a6451481f7e6f 100644 (file)
--- a/gas/NEWS
+++ b/gas/NEWS
@@ -1,5 +1,8 @@
 -*- text -*-
 
+New psuedo op: .incbin to include a set of binary data at a given point
+in the assembly.  Contributed by Anders Norlander.
+
 The MIPS assembler now accepts -march/-mtune. -mcpu has been deprecated
 but still works for compatability.
 
index 42288027d25074b77cc300e7405aab29435fe950..cef74c732e289e9f1c8a5e6a0794aaa15e8d0451 100644 (file)
@@ -3452,6 +3452,7 @@ Some machine configurations provide additional directives.
 * hword::                       @code{.hword @var{expressions}}
 * Ident::                       @code{.ident}
 * If::                          @code{.if @var{absolute expression}}
+* Incbin::                      @code{.incbin "@var{file}"[,@var{skip}[,@var{count}]]}
 * Include::                     @code{.include "@var{file}"}
 * Int::                         @code{.int @var{expressions}}
 @ifset ELF
@@ -4124,6 +4125,21 @@ Like @code{.ifeqs}, but the sense of the test is reversed: this assembles the
 following section of code if the two strings are not the same.
 @end table
 
+@node Incbin
+@section @code{.incbin "@var{file}"[,@var{skip}[,@var{count}]]}
+
+@cindex @code{incbin} directive
+@cindex binary files, including
+The @code{incbin} directive includes @var{file} verbatim at the current
+location. You can control the search paths used with the @samp{-I} command-line
+option (@pxref{Invoking,,Command-Line Options}).  Quotation marks are required
+around @var{file}.
+
+The @var{skip} argument skips a number of bytes from the start of the
+@var{file}.  The @var{count} argument indicates the maximum number of bytes to
+read. Note that the data from is not aligned in any way, make sure to proper
+alignment is provided before and after the @code{incbin} directive.
+
 @node Include
 @section @code{.include "@var{file}"}
 
index ca88dde9fe65b05b43134f87528073e4e912add0..ca3a4961393309efea76e67e61d191253e7ef85f 100644 (file)
@@ -349,6 +349,7 @@ static const pseudo_typeS potable[] = {
   {"ifne", s_if, (int) O_ne},
   {"ifnes", s_ifeqs, 1},
   {"ifnotdef", s_ifdef, 1},
+  {"incbin", s_incbin, 0},
   {"include", s_include, 0},
   {"int", cons, 4},
   {"irp", s_irp, 0},
@@ -4900,6 +4901,121 @@ equals (sym_name, reassign)
     }
 }
 
+/* .incbin -- include a file verbatim at the current location.  */
+
+void
+s_incbin (x)
+     int x ATTRIBUTE_UNUSED;
+{
+  FILE * binfile;
+  char * path;
+  char * filename;
+  char * binfrag;
+  long   skip = 0;
+  long   count = 0;
+  long   bytes;
+  int    len;
+
+#ifdef md_flush_pending_output
+  md_flush_pending_output ();
+#endif
+
+  SKIP_WHITESPACE ();
+  filename = demand_copy_string (& len);
+  if (filename == NULL)
+    return;
+
+  SKIP_WHITESPACE ();
+
+  /* Look for optional skip and count.  */
+  if (* input_line_pointer == ',')
+    {
+      ++ input_line_pointer;
+      skip = get_absolute_expression ();
+
+      SKIP_WHITESPACE ();
+
+      if (* input_line_pointer == ',')
+       {
+         ++ input_line_pointer;
+
+         count = get_absolute_expression ();
+         if (count == 0)
+           as_warn (_(".incbin count zero, ignoring `%s'"), filename);
+
+         SKIP_WHITESPACE ();
+       }
+    }
+
+  demand_empty_rest_of_line ();
+
+  /* Try opening absolute path first, then try include dirs.  */
+  binfile = fopen (filename, "rb");
+  if (binfile == NULL)
+    {
+      int i;
+
+      path = xmalloc ((unsigned long) len + include_dir_maxlen + 5);
+
+      for (i = 0; i < include_dir_count; i++)
+       {
+         sprintf (path, "%s/%s", include_dirs[i], filename);
+
+         binfile = fopen (path, "rb");
+         if (binfile != NULL)
+           break;
+       }
+
+      if (binfile == NULL)
+       as_bad (_("file not found: %s"), filename);
+    }
+  else
+    path = xstrdup (filename);
+
+  if (binfile)
+    {
+      register_dependency (path);
+
+      /* Compute the length of the file.  */
+      if (fseek (binfile, 0, SEEK_END) != 0)
+       {
+         as_bad (_("seek to end of .incbin file failed `%s'"), path);
+         goto done;
+       }
+      len = ftell (binfile);
+
+      /* If a count was not specified use the size of the file.  */
+      if (count == 0)
+       count = len;
+
+      if (skip + count > len)
+       {
+         as_bad (_("skip (%ld) + count (%ld) larger than file size (%ld)"),
+                 skip, count, len);
+         goto done;
+       }
+
+      if (fseek (binfile, skip, SEEK_SET) != 0)
+       {
+         as_bad (_("could not skip to %ld in file `%s'"), skip, path);
+         goto done;
+       }
+
+      /* Allocate frag space and store file contents in it.  */
+      binfrag = frag_more (count);
+
+      bytes = fread (binfrag, 1, count, binfile);
+      if (bytes < count)
+       as_warn (_("truncated file `%s', %ld of %ld bytes read"),
+                path, bytes, count);
+    }
+done:
+  if (binfile != NULL)
+    fclose (binfile);
+  if (path)
+    free (path);
+}
+
 /* .include -- include a file at this point.  */
 
 void
index d19deec5cdc780197ca756c01009a1031993dff8..a56781cf0929e7b2bf8a9812207b60721e572c80 100644 (file)
@@ -181,3 +181,4 @@ extern void s_text PARAMS ((int));
 extern void stringer PARAMS ((int append_zero));
 extern void s_xstab PARAMS ((int what));
 extern void s_rva PARAMS ((int));
+extern void s_incbin PARAMS ((int));
index 22082100e95fb32d274a2f9261028b31fa7f17cd..da080f88507865e96ee33137bc057022842c3354 100644 (file)
@@ -1,3 +1,9 @@
+2001-07-08  Anders Norlander <anorland@synergenix.se>
+
+       * gas/all/gas.exp: Run incbin test.
+       * gas/all/incbin.s: New file.
+       * gas/all/incbin.d: New file.
+
 2001-07-04  Richard Sandiford  <rsandifo@redhat.com>
 
        * gas/mips/elf-rel3.s: Add zero word to end of file.
index 84118fa0990262aad49ba0b521795b91923d0da1..796f105cbc40ad2e0a17e15521ee21073f036249 100644 (file)
@@ -156,6 +156,8 @@ if ![istarget *c54x*-*-*] then {
     test_cond
 }
 
+run_dump_test incbin
+
 # FIXME: this is here cause of a bug in DejaGnu 1.1.1. When it is no longer
 #        in use, then this can be removed.
 if [info exists errorInfo] then {
diff --git a/gas/testsuite/gas/all/incbin.d b/gas/testsuite/gas/all/incbin.d
new file mode 100644 (file)
index 0000000..096506a
--- /dev/null
@@ -0,0 +1,17 @@
+#as: -I$srcdir/$subdir
+#objdump: -s -j .data
+#name: incbin
+
+# Test the incbin pseudo-op
+
+.*: .*
+
+Contents of section .data:
+ 0000 2e646174 610a2e69 6e636269 6e202269  .data..incbin "i
+ 0010 6e636269 6e2e7322 0a2e696e 6362696e  ncbin.s"..incbin
+ 0020 2022696e 6362696e 2e73222c 302c3238   "incbin.s",0,28
+ 0030 0a2e696e 6362696e 2022696e 6362696e  ..incbin "incbin
+ 0040 2e73222c 31352c39 0a2e7032 616c6967  .s",15,9..p2alig
+ 0050 6e20340a 2e646174 610a2e69 6e636269  n 4..data..incbi
+ 0060 6e202269 6e636269 6e2e7322 0a2e696e  n "incbin.s"..in
+ 0070 696e6362 696e2e73 22000000 00000000  incbin.s".......
diff --git a/gas/testsuite/gas/all/incbin.s b/gas/testsuite/gas/all/incbin.s
new file mode 100644 (file)
index 0000000..850c89b
--- /dev/null
@@ -0,0 +1,5 @@
+.data
+.incbin "incbin.s"
+.incbin "incbin.s",0,28
+.incbin "incbin.s",15,9
+.p2align 4