This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: Objcopy and binary files
- To: Nick Clifton <nickc at redhat dot com>
- Subject: Re: Objcopy and binary files
- From: Stefan Geuken <mail at stefan-geuken dot de>
- Date: Thu, 01 Mar 2001 19:10:58 +0100
- CC: binutils at sources dot redhat dot com
- References: <200102161845.KAA09028@elmo.cygnus.com>
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)
{