This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


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

Re: Objcopy and binary files


Hello,

I have updated my patch that I posted on February, 2nd. Here is the new patch
file and an explanation about the patch!

Stefan

PS: Nick, I also send the copyright assignment to the fsf.
Changing the bfd-library (libbfd):

1. Versions
2. Problem
3. Solution
4. Modifications


1. Versions

Underlying versons are:

  a) libbfd    Version GNU binutils 2.10.1
  b) objcopy   Version GNU objcopy 2.10.1


2. Problem

The aim is to convert a binary file to an object file using the binutils program objcopy and to set the architecture of the output file. I want to do this, because I want to be able to convert a picture (e.g. a bitmap, ...) into an object file and link it with C++ code to have an executable with the picture data in it. I do not want to read the picture from the file system.
Objcopy does not set the architecture of an object file if the input file is binary, but some linkers want all object files to have an architecture.

Example:

Following call

  objcopy --input-target=binary --output-target=elf32-i386 pic.bmp pic.o

causes a warning:

  objcopy: Warning: Output file cannot represent architecture UNKNOWN!

The created file pic.o has no architecture information which one can prove with objdump:

  objdump -f Bild.o

  pic.o:     file format elf32-little
  architecture: UNKNOWN!, flags 0x00000010:
  HAS_SYMS
  start address 0x00000000

3. Solution

To be able to determine the architecture of the output file, I extended the program objcopy with another parameter. With this parameter you can set the architecture external for a binary input file.

I called the new parameter --binary-architecture=arg respectively -B, where arg is the architecture for the output file (e.g. i386, powerpc, ...).

Example:

  objcopy -I binary -O elf32-i386 -B i386 pic.bmp pic.bmp.o
  objdump -f pic.o

  pic.o:     file format elf32-i386
  architecture: i386, flags 0x00000010:
  HAS_SYMS
  start address 0x00000000

4. Modifications

Two files have to be changed:

  a) binary.c in directory bfd
  b) objcopy.c in directory binutils

and additionally the documentation in

  c) binutils.texi in directory binutils
  d) NEWS in directory binutils


a) binary.c in directory bfd

Insert a global variable, that stores the desired architecture. The best is to add the line

  enum bfd_architecture bfd_external_binary_architecture = bfd_arch_unknown;

directly in front of the function

  static const bfd_target *
  binary_object_p (abfd)
       bfd *abfd;

Copy these lines directly in front of the (last) return in this function:

    if (bfd_get_arch_info (abfd) != NULL)
    {
      if ((bfd_get_arch_info (abfd)->arch == bfd_arch_unknown)
          && (bfd_external_binary_architecture != bfd_arch_unknown))
        bfd_set_arch_info (abfd, bfd_lookup_arch (bfd_external_binary_architecture, 0));
    }


b) objcopy.c in directory binutils

Insert the new option to the structure

  static struct option copy_options[]

by adding the line

 {"binary-architecture", required_argument, 0, 'B'},

Expand the help, do this by adding

  -B --binary-architecture <arch>  Force output file to have architecture
  <arch> if input file is binary\n\

to the function

  static void
  copy_usage (stream, exit_status)
       FILE *stream;
       int exit_status;

The new option has to be processed: in front of function

  static int
  copy_main (argc, argv)
       int argc;
       char *argv[];

insert the external variable from binary.c:

  extern enum bfd_architecture bfd_external_binary_architecture;

Insert a local variable that stores the argument of -B (--binary-architecture) in this function:

  char* binary_architecture = NULL;

Insert the option (-B) (insert B: (in this line at the end)):

  while ((c = getopt_long (argc, argv, "b:i:I:j:K:N:s:O:d:F:L:R:SpgxXVvW:B:",
         copy_options, (int *) 0)) != EOF)

In the case instruction beneath, respond to this parameter:

  case 'B':
    binary_architecture = optarg;
    break;

Finally, set (also in this function) the global variable from binary.c:

I have placed the test

  if (binary_architecture != (char *) NULL)
    {
      if (strcmp (input_target, "binary") == 0)
        {
          const bfd_arch_info_type* temp_arch_info = bfd_scan_arch (binary_architecture);

          if (temp_arch_info != NULL)
            bfd_external_binary_architecture = temp_arch_info->arch;
          else
            fatal (_("architecture %s unknown"), binary_architecture);
        }
      else
        {
          non_fatal (_("Warning: input target 'binary' required for binary architecture parameter."
                       " Argument %s ignored"), binary_architecture);
        }
    }

behind this:

  if (output_target == (char *) NULL)
    output_target = input_target;

Updating the documentation:

c) binutils.texi in directory binutils

Insert help on the new command line switch of objcopy under section objcopy:

  [ -B @var{bfdarch} | --binary-architecture=@var{bfdarch} ]

and the detailed description:

  @item -B @var{bfdarch}
  @itemx --binary-architecture=@var{bfdarch}
  Useful when transforming a raw binary input file into an object file.
  In this case the output architecture can be set to @var{bfdarch}. This
  option will be ignored if the input file has a known @var{bfdarch}. You
  have access to this binary data by the start, stop and size symbols
  within your @var{objfile}, e.g. you can transform a picture file
  into an object file and accessing it in your code using these symbols.

d) NEWS in directory binutils

Insert information about new commandline switch:

* New command line switch to objcopy -B (or --binary-architecture) which sets
  the archiceture of the output file to the given argument. This option only
  makes sense, if the input target is binary. Otherwise it is ignored.


Stefan Geuken
01.03.2001
diff -u -r binutils-2.10.1/bfd/binary.c binutils-2.10.1_modified/bfd/binary.c
--- binutils-2.10.1/bfd/binary.c	Mon Jul 19 16:55:15 1999
+++ binutils-2.10.1_modified/bfd/binary.c	Mon Feb 19 19:15:42 2001
@@ -67,6 +67,8 @@
    was not defaulted.  That is, it must be explicitly specified as
    being binary.  */
 
+enum bfd_architecture bfd_external_binary_architecture = bfd_arch_unknown;
+
 static const bfd_target *
 binary_object_p (abfd)
      bfd *abfd;
@@ -100,6 +102,13 @@
 
   abfd->tdata.any = (PTR) sec;
 
+  if (bfd_get_arch_info (abfd) != NULL)
+    {
+      if ((bfd_get_arch_info (abfd)->arch == bfd_arch_unknown)
+          && (bfd_external_binary_architecture != bfd_arch_unknown))
+        bfd_set_arch_info (abfd, bfd_lookup_arch (bfd_external_binary_architecture, 0));
+    }
+  
   return abfd->xvec;
 }
 
diff -u -r binutils-2.10.1/binutils/NEWS binutils-2.10.1_modified/binutils/NEWS
--- binutils-2.10.1/binutils/NEWS	Wed Apr  5 07:36:40 2000
+++ binutils-2.10.1_modified/binutils/NEWS	Thu Mar  1 11:37:08 2001
@@ -2,6 +2,10 @@
 
 Changes in binutils 2.10:
 
+* New command line switch to objcopy -B (or --binary-architecture) which sets
+  the archiceture of the output file to the given argument. This option only
+  makes sense, if the input target is binary. Otherwise it is ignored.
+
 * New command line switch to objdump --file-start-context which shows the
   entire file contents up to the source line first encountered for a given
   file. 
diff -u -r binutils-2.10.1/binutils/binutils.texi binutils-2.10.1_modified/binutils/binutils.texi
--- binutils-2.10.1/binutils/binutils.texi	Sat Oct 14 20:42:22 2000
+++ binutils-2.10.1_modified/binutils/binutils.texi	Thu Mar  1 12:27:48 2001
@@ -875,6 +875,7 @@
         [ -j @var{sectionname} | --only-section=@var{sectionname} ]
         [ -R @var{sectionname} | --remove-section=@var{sectionname} ]
         [ -p | --preserve-dates ] [ --debugging ]
+        [ -B @var{bfdarch} | --binary-architecture=@var{bfdarch} ]
         [ --gap-fill=@var{val} ] [ --pad-to=@var{address} ]
         [ --set-start=@var{val} ] [ --adjust-start=@var{incr} ]
         [ --change-addresses=@var{incr} ]
@@ -1014,6 +1015,15 @@
 Set the access and modification dates of the output file to be the same
 as those of the input file.
 
+@item -B @var{bfdarch}
+@itemx --binary-architecture=@var{bfdarch}
+Useful when transforming a raw binary input file into an object file.
+In this case the output architecture can be set to @var{bfdarch}. This
+option will be ignored if the input file has a known @var{bfdarch}. You
+have access to this binary data by the start, stop and size symbols
+within your @var{objfile}, e.g. you can transform a picture file
+into an object file and accessing it in your code using these symbols.
+
 @item --debugging
 Convert debugging information, if possible.  This is not the default
 because only certain debugging formats are supported, and the
diff -u -r binutils-2.10.1/binutils/objcopy.c binutils-2.10.1_modified/binutils/objcopy.c
--- binutils-2.10.1/binutils/objcopy.c	Tue Sep  5 10:56:22 2000
+++ binutils-2.10.1_modified/binutils/objcopy.c	Thu Mar  1 11:26:17 2001
@@ -275,6 +275,7 @@
   {"output-target", required_argument, 0, 'O'},
   {"pad-to", required_argument, 0, OPTION_PAD_TO},
   {"preserve-dates", no_argument, 0, 'p'},
+  {"binary-architecture", required_argument, 0, 'B'},
   {"localize-symbol", required_argument, 0, 'L'},
   {"remove-leading-char", no_argument, 0, OPTION_REMOVE_LEADING_CHAR},
   {"remove-section", required_argument, 0, 'R'},
@@ -315,6 +316,7 @@
   -F --target <bfdname>            Set both input and output format to <bfdname>\n\
      --debugging                   Convert debugging information, if possible\n\
   -p --preserve-dates              Copy modified/access timestamps to the output\n\
+  -B --binary-architecture <arch>  Force output file to have architecture <arch> if input file is binary\n\
   -j --only-section <name>         Only copy section <name> into the output\n\
   -R --remove-section <name>       Remove section <name> from the output\n\
   -S --strip-all                   Remove all symbol and relocation information\n\
@@ -1782,11 +1784,14 @@
   return 0;
 }
 
+extern enum bfd_architecture bfd_external_binary_architecture;
+
 static int
 copy_main (argc, argv)
      int argc;
      char *argv[];
 {
+  char* binary_architecture = NULL;
   char *input_filename = NULL, *output_filename = NULL;
   char *input_target = NULL, *output_target = NULL;
   boolean show_version = false;
@@ -1795,7 +1800,7 @@
   struct section_list *p;
   struct stat statbuf;
 
-  while ((c = getopt_long (argc, argv, "b:i:I:j:K:N:s:O:d:F:L:R:SpgxXVvW:",
+  while ((c = getopt_long (argc, argv, "b:i:I:j:K:N:s:O:d:F:L:R:SpgxXVvW:B:",
 			   copy_options, (int *) 0)) != EOF)
     {
       switch (c)
@@ -1890,6 +1895,10 @@
 	  show_version = true;
 	  break;
 
+        case 'B':
+          binary_architecture = optarg;
+          break;
+
 	case OPTION_WEAKEN:
 	  weaken = true;
 	  break;
@@ -2154,6 +2163,24 @@
 
   if (output_target == (char *) NULL)
     output_target = input_target;
+
+  if (binary_architecture != (char *) NULL)
+    {
+      if (strcmp (input_target, "binary") == 0)
+        {
+          const bfd_arch_info_type* temp_arch_info = bfd_scan_arch (binary_architecture);
+
+          if (temp_arch_info != NULL)
+            bfd_external_binary_architecture = temp_arch_info->arch;
+          else
+            fatal (_("architecture %s unknown"), binary_architecture);
+        }
+      else
+        {
+          non_fatal (_("Warning: input target 'binary' required for binary architecture parameter."
+                       " Argument %s ignored"), binary_architecture);
+        }
+    }
 
   if (preserve_dates)
     {

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