This is the mail archive of the gas2@sourceware.cygnus.com mailing list for the gas2 project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

More gas/bfd patches



OK, here are three more patches, based on the gas-950208 snapshot.
I've verified that they merge cleanly into gas-950219.

The first is just another minor bug fix to the 16-bit i386 support:

diff -ur gas-950208/include/opcode/i386.h gas-new/include/opcode/i386.h
--- gas-950208/include/opcode/i386.h	Mon Feb  6 12:00:43 1995
+++ gas-new/include/opcode/i386.h	Sun Feb 19 10:06:03 1995
@@ -101,6 +101,8 @@
 {"sahf", 0, 0x9e, _, NoModrm, { 0, 0, 0} },
 {"pushf", 0, 0x9c, _, NoModrm|Data32, { 0, 0, 0} },
 {"popf", 0, 0x9d, _, NoModrm|Data32, { 0, 0, 0} },
+{"pushfl", 0, 0x9c, _, NoModrm|Data32, { 0, 0, 0} },
+{"popfl", 0, 0x9d, _, NoModrm|Data32, { 0, 0, 0} },
 {"pushfw", 0, 0x9c, _, NoModrm|Data16, { 0, 0, 0} },
 {"popfw", 0, 0x9d, _, NoModrm|Data16, { 0, 0, 0} },
 {"stc", 0, 0xf9, _, NoModrm, { 0, 0, 0} },
@@ -280,8 +282,10 @@
 {"lret", 1, 0xca, _, NoModrm|Data32, { Imm16, 0, 0} },
 {"lretw", 0, 0xcb, _, NoModrm|Data16, { 0, 0, 0} },
 {"lretw", 1, 0xca, _, NoModrm|Data16, { Imm16, 0, 0} },
-{"enter", 2, 0xc8, _, NoModrm, { Imm16, Imm8, 0} },
-{"leave", 0, 0xc9, _, NoModrm, { 0, 0, 0} },
+{"enter", 2, 0xc8, _, NoModrm|Data32, { Imm16, Imm8, 0} },
+{"leave", 0, 0xc9, _, NoModrm|Data32, { 0, 0, 0} },
+{"enterw", 2, 0xc8, _, NoModrm|Data16, { Imm16, Imm8, 0} },
+{"leavew", 0, 0xc9, _, NoModrm|Data16, { 0, 0, 0} },
 
 /* conditional jumps */
 {"jo", 1, 0x70, _, Jump, { Disp, 0, 0} },


The second is a minor fix to bfd/libaout.h that I needed 
in order to get bfd to compile here:

diff -cr gas-950208/bfd/libaout.h gas-950208-new/bfd/libaout.h
*** gas-950208/bfd/libaout.h	Thu Feb  9 08:04:33 1995
--- gas-950208-new/bfd/libaout.h	Thu Feb  9 08:08:55 1995
***************
*** 442,448 ****
  NAME(aout,swap_std_reloc_in) PARAMS ((bfd *, struct reloc_std_external *,
  				      arelent *, asymbol **));
  
! CONST struct reloc_howto_struct *
  NAME(aout,reloc_type_lookup) PARAMS ((bfd *abfd,
  				      bfd_reloc_code_real_type code));
  
--- 442,448 ----
  NAME(aout,swap_std_reloc_in) PARAMS ((bfd *, struct reloc_std_external *,
  				      arelent *, asymbol **));
  
! reloc_howto_type *
  NAME(aout,reloc_type_lookup) PARAMS ((bfd *abfd,
  				      bfd_reloc_code_real_type code));
  

The third is a little more interesting - it adds read support
to the "binary" BFD backend.  Basically, if you specify "binary"
as the format of an input file to ld or objcopy or whatever,
the input file will be read into a data section as raw, uninterpreted bytes,
and some symbols will be produced, based on the filename of the input file,
marking the start and end of the data chunk.  Basically, it allows you
to link arbitrary files into a program without all the machine-dependent,
format-dependent "wrap-a-file-in-a-.o" kludgery that's usually needed.
(e.g. see the Linux boot image creation mechanism. :-) )

The binary BFD reader will only be enabled when it is specifically
requested by name; it will never "match" when an automatic BFD format
search is being done.

I didn't find any documentation on the binary BFD backend (or on any
other BFD backends for that matter); if there is some, point me to it
and I'll add appropriate documentation for the reader.

BTW, this code requires a horrible kludge to find the size of the
input file, because bfd_seek doesn't support SEEK_END, and by definition
there's no way to find the length of an uninterpreted binary input file
based only its contents.  (I just read through the file once and count
the number of bytes before EOF.)  I noticed that the srec reader also
needs to detect EOF.  Maybe it would be a good idea to enable SEEK_END
in bfd_seek(), and simply make it known that certain file formats
cannot be placed in archives.  Perhaps modify the ASSERT in bfd_seek()
to die only if someone tries to bfd_seek in an archive...?

				Bryan

diff -ur gas-950208/bfd/binary.c gas-new/bfd/binary.c
--- gas-950208/bfd/binary.c	Wed Oct 19 12:08:55 1994
+++ gas-new/bfd/binary.c	Sat Feb 18 13:48:50 1995
@@ -31,10 +31,16 @@
    the file.  objcopy cooperates by specially setting the start
    address to zero by default.  */
 
+#include <ctype.h>
+
 #include "bfd.h"
 #include "sysdep.h"
 #include "libbfd.h"
 
+/* Any bfd we create by reading a binary file has three symbols:
+   a start symbol, an end symbol, and an absolute length symbol.  */
+#define BIN_SYMS 2
+
 static boolean binary_mkobject PARAMS ((bfd *));
 static asymbol *binary_make_empty_symbol PARAMS ((bfd *));
 static boolean binary_set_section_contents
@@ -50,15 +56,29 @@
 }
 
 /* Most of the symbol routines can just return an error.  */
-#define binary_get_symtab_upper_bound _bfd_nosymbols_get_symtab_upper_bound
-#define binary_get_symtab _bfd_nosymbols_get_symtab
+#define	binary_close_and_cleanup _bfd_generic_close_and_cleanup
+#define binary_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
+#define binary_new_section_hook _bfd_generic_new_section_hook
+
 #define binary_print_symbol _bfd_nosymbols_print_symbol
-#define binary_get_symbol_info _bfd_nosymbols_get_symbol_info
-#define binary_bfd_is_local_label _bfd_nosymbols_bfd_is_local_label
+#define binary_bfd_is_local_label bfd_generic_is_local_label
 #define binary_get_lineno _bfd_nosymbols_get_lineno
 #define binary_find_nearest_line _bfd_nosymbols_find_nearest_line
 #define binary_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
 
+#define binary_get_reloc_upper_bound \
+  ((long (*) PARAMS ((bfd *, asection *))) bfd_0l)
+#define binary_canonicalize_reloc \
+  ((long (*) PARAMS ((bfd *, asection *, arelent **, asymbol **))) bfd_0l)
+#define binary_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
+
+#define binary_bfd_get_relocated_section_contents \
+  bfd_generic_get_relocated_section_contents
+#define binary_bfd_relax_section bfd_generic_relax_section
+#define binary_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
+#define binary_bfd_link_add_symbols _bfd_generic_link_add_symbols
+#define binary_bfd_final_link _bfd_generic_final_link
+
 /* We do have to provide a routine to make an empty symbol.  */
 
 static asymbol *
@@ -108,6 +128,176 @@
   return _bfd_generic_set_section_contents (abfd, sec, data, offset, size);
 }
 
+/* Check whether an existing file is a binary file.
+   Pretty easy - _every_ file is as far as we're concerned. :-)
+   However, only "recognize" the file
+   if the input target was explicitly set to "binary",
+   not if we're doing an automatic target search.  */
+
+static const bfd_target *
+binary_object_p (abfd)
+     bfd *abfd;
+{
+  long bytes;
+
+  if (abfd->target_defaulted)
+    return NULL;
+
+  abfd->symcount = BIN_SYMS;
+
+  /* Find the file size.  XXX big kludge,
+     because bfd_seek doesn't like SEEK_END.  */
+  {
+    bfd_byte c;
+
+    if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
+      return NULL;
+
+    bytes = 0;
+    while (bfd_read (&c, 1, 1, abfd) == 1)
+      bytes++;
+
+    if (bfd_get_error () != bfd_error_file_truncated)
+      return NULL;
+  }
+
+  /* One data section.  */
+  {
+    asection *sec;
+    char *secname;
+
+    secname = (char *) bfd_alloc (abfd, strlen (".data") + 1);
+    strcpy (secname, ".data");
+    sec = bfd_make_section (abfd, secname);
+    if (sec == NULL)
+      return NULL;
+    sec->flags = SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS;
+    sec->vma = 0;
+    sec->_raw_size = bytes;
+    sec->filepos = 0;
+
+    abfd->tdata.any = (PTR)sec;
+  }
+
+  return abfd->xvec;
+}
+
+/* Get the contents of "the" section.  */
+
+static boolean
+binary_get_section_contents (abfd, section, location, offset, count)
+     bfd *abfd;
+     asection *section;
+     PTR location;
+     file_ptr offset;
+     bfd_size_type count;
+{
+  if ((bfd_seek (abfd, offset, SEEK_SET) != 0)
+      || (bfd_read (location, 1, count, abfd) != count))
+    return false;
+  return true;
+}
+
+/* Return the amount of memory needed to read the symbol table.  */
+
+static long
+binary_get_symtab_upper_bound (abfd)
+     bfd *abfd;
+{
+  return (BIN_SYMS + 1) * sizeof (asymbol *);
+}
+
+void
+binary_get_symbol_info (ignore_abfd, symbol, ret)
+     bfd *ignore_abfd;
+     asymbol *symbol;
+     symbol_info *ret;
+{
+  bfd_symbol_info (symbol, ret);
+}
+
+/* Create a symbol name based on the bfd's filename.  */
+static char *mangle_name(abfd, suffix)
+     bfd *abfd;
+     char *suffix;
+{
+  int size = strlen(bfd_get_filename(abfd)) + strlen(suffix) + 10;
+  char *buf = (char*) bfd_alloc (abfd, size);
+  char *p;
+
+  if (buf == NULL)
+    {
+      bfd_set_error (bfd_error_no_memory);
+      return false;
+    }
+
+  sprintf(buf, "_binary_%s_%s", bfd_get_filename(abfd), suffix);
+
+  /* Change any non-alphanumeric characters to underscores.  */
+  for (p = buf; *p; p++)
+    if (!isalnum(*p))
+      *p = '_';
+
+  return buf;
+}
+
+/* Return the symbol table.  */
+
+static long
+binary_get_symtab (abfd, alocation)
+     bfd *abfd;
+     asymbol **alocation;
+{
+  asection *sec = (asection*)abfd->tdata.any;
+  asymbol *syms;
+  unsigned int i;
+
+  syms = (asymbol *) bfd_alloc (abfd, BIN_SYMS * sizeof (asymbol));
+  if (syms == NULL)
+    {
+      bfd_set_error (bfd_error_no_memory);
+      return false;
+    }
+
+  /* Start symbol.  */
+  syms[0].the_bfd = abfd;
+  syms[0].name = mangle_name(abfd, "start");
+  syms[0].value = 0;
+  syms[0].flags = BSF_GLOBAL;
+  syms[0].section = sec;
+  syms[0].udata.p = NULL;
+
+  /* End symbol.  */
+  syms[1].the_bfd = abfd;
+  syms[1].name = mangle_name(abfd, "end");
+  syms[1].value = sec->_raw_size;
+  syms[1].flags = BSF_GLOBAL;
+  syms[1].section = sec;
+  syms[1].udata.p = NULL;
+
+  /* End symbol.  */
+  syms[2].the_bfd = abfd;
+  syms[2].name = mangle_name(abfd, "size");
+  syms[2].value = sec->_raw_size;
+  syms[2].flags = BSF_GLOBAL;
+  syms[2].section = bfd_abs_section_ptr;
+  syms[2].udata.p = NULL;
+
+  for (i = 0; i < BIN_SYMS; i++)
+    *alocation++ = syms++;
+  *alocation = NULL;
+
+  return BIN_SYMS;
+}
+
+static int
+binary_sizeof_headers (abfd, exec)
+     bfd *abfd;
+     boolean exec;
+{
+  return 0;
+}
+
 const bfd_target binary_vec =
 {
   "binary",			/* name */
@@ -129,7 +319,7 @@
   bfd_getb16, bfd_getb_signed_16, bfd_putb16,	/* hdrs */
   {				/* bfd_check_format */
     _bfd_dummy_target,
-    _bfd_dummy_target,
+    binary_object_p,		/* bfd_check_format */
     _bfd_dummy_target,
     _bfd_dummy_target,
   },
@@ -146,14 +336,14 @@
     bfd_false,
   },
 
-  BFD_JUMP_TABLE_GENERIC (_bfd_generic),
+  BFD_JUMP_TABLE_GENERIC (binary),
   BFD_JUMP_TABLE_COPY (_bfd_generic),
   BFD_JUMP_TABLE_CORE (_bfd_nocore),
   BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
   BFD_JUMP_TABLE_SYMBOLS (binary),
-  BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
+  BFD_JUMP_TABLE_RELOCS (binary),
   BFD_JUMP_TABLE_WRITE (binary),
-  BFD_JUMP_TABLE_LINK (_bfd_nolink),
+  BFD_JUMP_TABLE_LINK (binary),
   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
 
   NULL