From 3415e04cb75365ea0e8841c10ce681a90509d063 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Mon, 9 Jul 2001 08:19:18 +0000 Subject: [PATCH] Add .incbin pseudo op --- gas/ChangeLog | 8 +++ gas/NEWS | 3 ++ gas/doc/as.texinfo | 16 ++++++ gas/read.c | 116 +++++++++++++++++++++++++++++++++++++++++ gas/read.h | 1 + gas/testsuite/ChangeLog | 6 +++ gas/testsuite/gas/all/gas.exp | 2 + gas/testsuite/gas/all/incbin.d | 17 ++++++ gas/testsuite/gas/all/incbin.s | 5 ++ 9 files changed, 174 insertions(+) create mode 100644 gas/testsuite/gas/all/incbin.d create mode 100644 gas/testsuite/gas/all/incbin.s 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 + + * 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 * 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 + + * gas/all/gas.exp: Run incbin test. + * gas/all/incbin.s: New file. + * gas/all/incbin.d: New file. + 2001-07-04 Richard Sandiford * 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 -- 2.11.0