aboutsummaryrefslogtreecommitdiff
path: root/gas/read.c
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
commit7e005732aa09aad97c790cab88d294aeed06eada (patch)
tree9411e3103de35962825513144f9ba3b719ddaeda /gas/read.c
parent46712191470afb32ce078cfa49550f84a774973c (diff)
downloadfsf-binutils-gdb-7e005732aa09aad97c790cab88d294aeed06eada.zip
fsf-binutils-gdb-7e005732aa09aad97c790cab88d294aeed06eada.tar.gz
fsf-binutils-gdb-7e005732aa09aad97c790cab88d294aeed06eada.tar.bz2
Add .incbin pseudo op
Diffstat (limited to 'gas/read.c')
-rw-r--r--gas/read.c116
1 files changed, 116 insertions, 0 deletions
diff --git a/gas/read.c b/gas/read.c
index ca88dde..ca3a496 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