summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2001-07-09 08:19:18 +0000
committerNick Clifton <nickc@redhat.com>2001-07-09 08:19:18 +0000
commit3415e04cb75365ea0e8841c10ce681a90509d063 (patch)
tree63de1d6b3babc58ceab66aeb056a355369960b1a
parentd1689ec2b32bfbe46a4d51537389ff1333184da1 (diff)
downloadbinutils-redhat-3415e04cb75365ea0e8841c10ce681a90509d063.tar.gz
Add .incbin pseudo op
-rw-r--r--gas/ChangeLog8
-rw-r--r--gas/NEWS3
-rw-r--r--gas/doc/as.texinfo16
-rw-r--r--gas/read.c116
-rw-r--r--gas/read.h1
-rw-r--r--gas/testsuite/ChangeLog6
-rw-r--r--gas/testsuite/gas/all/gas.exp2
-rw-r--r--gas/testsuite/gas/all/incbin.d17
-rw-r--r--gas/testsuite/gas/all/incbin.s5
9 files changed, 174 insertions, 0 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 9944e1d590..0ebe08d861 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -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
diff --git a/gas/NEWS b/gas/NEWS
index 63dc260ace..6e6d447895 100644
--- 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.
diff --git a/gas/doc/as.texinfo b/gas/doc/as.texinfo
index 42288027d2..cef74c732e 100644
--- a/gas/doc/as.texinfo
+++ b/gas/doc/as.texinfo
@@ -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}"}
diff --git a/gas/read.c b/gas/read.c
index ca88dde9fe..ca3a496139 100644
--- a/gas/read.c
+++ b/gas/read.c
@@ -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
diff --git a/gas/read.h b/gas/read.h
index d19deec5cd..a56781cf09 100644
--- a/gas/read.h
+++ b/gas/read.h
@@ -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));
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index 22082100e9..da080f8850 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -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.
diff --git a/gas/testsuite/gas/all/gas.exp b/gas/testsuite/gas/all/gas.exp
index 84118fa099..796f105cbc 100644
--- a/gas/testsuite/gas/all/gas.exp
+++ b/gas/testsuite/gas/all/gas.exp
@@ -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
index 0000000000..096506ae0c
--- /dev/null
+++ b/gas/testsuite/gas/all/incbin.d
@@ -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
index 0000000000..850c89b67b
--- /dev/null
+++ b/gas/testsuite/gas/all/incbin.s
@@ -0,0 +1,5 @@
+.data
+.incbin "incbin.s"
+.incbin "incbin.s",0,28
+.incbin "incbin.s",15,9
+.p2align 4