/* read.c - read a source file -
Copyright 1986, 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
- 1998, 1999, 2000 Free Software Foundation, Inc.
+ 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
{"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},
memset (p, 0, (unsigned int) size);
/* The magic number BSD_FILL_SIZE_CROCK_4 is from BSD 4.2 VAX
- flavoured AS. The following bizzare behaviour is to be
+ flavoured AS. The following bizarre behaviour is to be
compatible with above. I guess they tried to take up to 8
bytes from a 4-byte expression and they forgot to sign
- extend. Un*x Sux. */
+ extend. */
#define BSD_FILL_SIZE_CROCK_4 (4)
md_number_to_chars (p, (valueT) fill,
(size > BSD_FILL_SIZE_CROCK_4
int sign;
{
operatorT op = exp->X_op;
+ int nbytes;
if (op == O_absent || op == O_illegal)
{
op = O_constant;
}
+ /* Let check_eh_frame know that data is being emitted. nbytes == -1 is
+ a signal that this is leb128 data. It shouldn't optimize this away. */
+ nbytes = -1;
+ if (check_eh_frame (exp, &nbytes))
+ abort ();
+
+ /* Let the backend know that subsequent data may be byte aligned. */
+#ifdef md_cons_align
+ md_cons_align (1);
+#endif
+
if (op == O_constant)
{
/* If we've got a constant, emit the thing directly right now. */
}
else
{
+#ifdef OBJ_COFF
+ int local;
+
+ symbolP = symbol_find (sym_name);
+ local = symbolP == NULL;
+ if (local)
+#endif /* OBJ_COFF */
symbolP = symbol_find_or_make (sym_name);
/* Permit register names to be redefined. */
if (!reassign
#ifdef OBJ_COFF
/* "set" symbols are local unless otherwise specified. */
- SF_SET_LOCAL (symbolP);
+ if (local)
+ SF_SET_LOCAL (symbolP);
#endif /* OBJ_COFF */
pseudo_set (symbolP);
}
}
+/* .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, FOPEN_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, FOPEN_RB);
+ if (binfile != NULL)
+ break;
+ }
+
+ if (binfile == NULL)
+ as_bad (_("file not found: %s"), filename);
+ }
+ else
+ path = xstrdup (filename);
+
+ if (binfile)
+ {
+ long file_len;
+
+ 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;
+ }
+ file_len = ftell (binfile);
+
+ /* If a count was not specified use the size of the file. */
+ if (count == 0)
+ count = file_len;
+
+ if (skip + count > file_len)
+ {
+ as_bad (_("skip (%ld) + count (%ld) larger than file size (%ld)"),
+ skip, count, file_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
strcpy (path, include_dirs[i]);
strcat (path, "/");
strcat (path, filename);
- if (0 != (try = fopen (path, "r")))
+ if (0 != (try = fopen (path, FOPEN_RT)))
{
fclose (try);
goto gotit;