This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Objcopy and binary files
- To: binutils at sources dot redhat dot com
- Subject: Objcopy and binary files
- From: Stefan Geuken <mail at stefan-geuken dot de>
- Date: Fri, 16 Feb 2001 00:14:42 +0100
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));