This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
PATCH: gas .incbin pseudo-op
- To: Binutils List <binutils at sources dot redhat dot com>
- Subject: PATCH: gas .incbin pseudo-op
- From: Anders Norlander <anorland at synergenix dot se>
- Date: 29 Jun 2001 17:52:34 +0200
Hi all,
this patch adds a .incbin directive to gas to include files
verbatim at the current location, as found in many other assemblers.
I'm a bit surprised this has not come up before, but the archives
didn't reveal anything.
Syntax:
.incbin "file"[,skip[,count]]
The same search path as .include is searched for the file,
but the local directory is tried first.
Tested on i*86-*-linux*, i*86-cygwin and arm-elf-thumb,
there is also a testcase attached.
Comments?
Regards,
Anders
gas/ChangeLog
* 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.
gas/testsuite/ChangeLog
* gas/all/gas.exp: Run incbin test.
* gas/all/incbin.s: New file.
* gas/all/incbin.d: New file.
--- gas/read.h.old Fri Jun 29 17:39:25 2001
+++ gas/read.h Fri Jun 29 17:40:09 2001
@@ -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));
--- gas/read.c.old Fri Jun 29 17:39:28 2001
+++ gas/read.c Fri Jun 29 17:40:09 2001
@@ -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},
@@ -4898,6 +4899,125 @@ equals (sym_name, reassign)
ignore_rest_of_line ();
mri_comment_end (stop, stopc);
}
+}
+
+/* .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;
+ long chunk;
+ long bytes;
+ int i;
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ SKIP_WHITESPACE ();
+ filename = demand_copy_string (&i);
+ if (filename == NULL)
+ return;
+
+ path = NULL;
+ binfile = NULL;
+
+ SKIP_WHITESPACE ();
+ skip = 0;
+ chunk = 0;
+
+ /* 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;
+ chunk = get_absolute_expression ();
+ if (chunk == 0)
+ {
+ as_warn (_(".incbin count zero, ignoring `%s'"), filename);
+ goto done;
+ }
+ SKIP_WHITESPACE ();
+ }
+ }
+ demand_empty_rest_of_line ();
+
+ /* Try opening absolute path first, then try include dirs */
+ binfile = fopen (filename, "rb");
+ if (binfile == NULL)
+ {
+ path = xmalloc ((unsigned long) i + include_dir_maxlen + 5);
+ for (i = 0; i < include_dir_count; i++)
+ {
+ strcpy (path, include_dirs[i]);
+ strcat (path, "/");
+ strcat (path, filename);
+ if (NULL != (binfile = fopen (path, "rb")))
+ break;
+ }
+ if (binfile == NULL)
+ {
+ as_bad (_("file not found: %s"), filename);
+ goto done;
+ }
+ }
+ else
+ path = xstrdup (filename);
+
+ register_dependency (path);
+
+ /* If a count was not specified use the size of the file */
+ if (chunk == 0)
+ {
+ if (fseek (binfile, 0, SEEK_END) != 0)
+ {
+ as_bad (_("seek failed `%s'"), path);
+ goto done;
+ }
+ chunk = ftell (binfile);
+ if (skip > chunk)
+ {
+ as_bad (_("skip amount (%ld) larger than file size (%ld)"),
+ skip, chunk);
+ goto done;
+ }
+ chunk -= skip;
+ }
+
+ /* Allocate frag space and store file contents in it */
+ binfrag = frag_more (chunk);
+ if (fseek (binfile, skip, SEEK_SET) != 0)
+ {
+ as_bad (_("could not skip in file `%s'"), path);
+ goto done;
+ }
+
+ bytes = fread (binfrag, 1, chunk, binfile);
+ if (bytes < chunk)
+ {
+ as_warn (_("truncated file `%s', %ld of %ld bytes read"),
+ path, bytes, chunk);
+ }
+
+done:
+ if (binfile != NULL)
+ fclose (binfile);
+ if (path)
+ free (path);
+ return;
}
/* .include -- include a file at this point. */
--- gas/doc/as.texinfo.old Fri Jun 29 17:39:38 2001
+++ gas/doc/as.texinfo Fri Jun 29 17:40:33 2001
@@ -3448,6 +3448,7 @@ Some machine configurations provide addi
* 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
@@ -4119,6 +4120,21 @@ Assembles the following section of code
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}"}
--- gas/testsuite/gas/all/gas.exp.old Fri Jun 29 17:43:40 2001
+++ gas/testsuite/gas/all/gas.exp Fri Jun 29 17:45:24 2001
@@ -156,6 +156,8 @@
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 {
--- /dev/null Tue May 5 22:32:27 1998
+++ gas/testsuite/gas/all/incbin.s Fri Jun 29 17:09:09 2001
@@ -0,0 +1,5 @@
+.data
+.incbin "incbin.s"
+.incbin "incbin.s",0,28
+.incbin "incbin.s",15,9
+.p2align 4
--- /dev/null Tue May 5 22:32:27 1998
+++ gas/testsuite/gas/all/incbin.d Fri Jun 29 17:09:09 2001
@@ -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".......