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]

Objcopy and binary files


Hello!
I made some changes to the objcopy tool and to the bfd library and want
to hear your opinion on it !!!

I attached the patch files to this mail!

Here is a little text which explains what I did and why I did it:


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

a) binary.c:

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 this directly in front of the (last) return in this function:

  if (bfd_external_binary_architecture != bfd_arch_unknown)
    bfd_set_arch_info(abfd,
bfd_lookup_arch(bfd_external_binary_architecture,
                            0));

b) objcopy.c:

Insert the new option to the structure

  static struct option copy_options[]

. Add 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[];

make now 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, prove (also in this function) behind the case instruction, if
input target is "binary" and if -B (--binary-architecture) is set. Set
the global variable from binary.c.

I have placed the test

  if (strcmp(input_target, "binary") == 0)
  {
    if (binary_architecture != NULL)
    {
      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
        non_fatal (_("warning: architecture %s unknown"),
                  binary_architecture);
    }
  }

behind this:

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




Stefan Geuken
15.12.2000
292a293
>   {"binary-architecture", required_argument, 0, 'B'},
331a333
>   -B --binary-architecture <arch>  Force output file to have architecture <arch> if input file is binary\n\
1784a1787,1788
> extern enum bfd_architecture bfd_external_binary_architecture;
> 
1789a1794
>   char* binary_architecture = NULL;
1798c1803
<   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:",
1891a1897,1900
> 	
>         case 'B':
>           binary_architecture = optarg;
>           break;
2156a2166,2179
> 
>   if (strcmp(input_target, "binary") == 0)
>   {
>     if (binary_architecture != NULL)
>     {
>       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
>         non_fatal (_("warning: architecture %s unknown"),
> 	                 binary_architecture);
> 	  }
>   }
69a70,71
> enum bfd_architecture bfd_external_binary_architecture = bfd_arch_unknown;
> 
101a104,106
> 
>   if (bfd_external_binary_architecture != bfd_arch_unknown)
>     bfd_set_arch_info(abfd, bfd_lookup_arch(bfd_external_binary_architecture, 0));

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