aboutsummaryrefslogtreecommitdiff
path: root/binutils/objcopy.c
diff options
context:
space:
mode:
Diffstat (limited to 'binutils/objcopy.c')
-rw-r--r--binutils/objcopy.c107
1 files changed, 78 insertions, 29 deletions
diff --git a/binutils/objcopy.c b/binutils/objcopy.c
index f2dd5a4..01eb6c0 100644
--- a/binutils/objcopy.c
+++ b/binutils/objcopy.c
@@ -1,5 +1,5 @@
/* objcopy.c -- copy object file from input to output, optionally massaging it.
- Copyright (C) 1991 Free Software Foundation, Inc.
+ Copyright (C) 1991, 92, 93, 94 Free Software Foundation, Inc.
This file is part of GNU Binutils.
@@ -22,16 +22,21 @@
#include "bucomm.h"
#include <getopt.h>
-static void setup_sections ();
-static void copy_sections ();
-static void mangle_sections ();
+static void setup_section ();
+static void copy_section ();
+static void mangle_section ();
#define nonfatal(s) {bfd_nonfatal(s); status = 1; return;}
static asymbol **isympp = NULL; /* Input symbols */
static asymbol **osympp = NULL; /* Output symbols that survive stripping */
+
+/* If `copy_byte' >= 0, copy only that byte of every `interleave' bytes. */
+static int copy_byte = -1;
+static int interleave = 4;
+
static boolean verbose; /* Print file and target names. */
-static int status = 0;
+static int status = 0; /* Exit status. */
enum strip_action
{
@@ -58,20 +63,19 @@ static enum locals_action discard_locals;
static struct option strip_options[] =
{
- {"strip-all", no_argument, 0, 's'},
- {"strip-debug", no_argument, 0, 'S'},
{"discard-all", no_argument, 0, 'x'},
{"discard-locals", no_argument, 0, 'X'},
+ {"format", required_argument, 0, 'F'}, /* Obsolete */
{"help", no_argument, 0, 'h'},
- {"input-target", required_argument, 0, 'I'},
{"input-format", required_argument, 0, 'I'}, /* Obsolete */
- {"output-target", required_argument, 0, 'O'},
+ {"input-target", required_argument, 0, 'I'},
{"output-format", required_argument, 0, 'O'}, /* Obsolete */
+ {"output-target", required_argument, 0, 'O'},
+ {"strip-all", no_argument, 0, 's'},
+ {"strip-debug", no_argument, 0, 'S'},
{"target", required_argument, 0, 'F'},
- {"format", required_argument, 0, 'F'}, /* Obsolete */
-
- {"version", no_argument, 0, 'V'},
{"verbose", no_argument, 0, 'v'},
+ {"version", no_argument, 0, 'V'},
{0, no_argument, 0, 0}
};
@@ -79,20 +83,21 @@ static struct option strip_options[] =
static struct option copy_options[] =
{
- {"strip-all", no_argument, 0, 'S'},
- {"strip-debug", no_argument, 0, 'g'},
+ {"byte", required_argument, 0, 'b'},
{"discard-all", no_argument, 0, 'x'},
{"discard-locals", no_argument, 0, 'X'},
+ {"format", required_argument, 0, 'F'}, /* Obsolete */
{"help", no_argument, 0, 'h'},
- {"input-target", required_argument, 0, 'I'},
{"input-format", required_argument, 0, 'I'}, /* Obsolete */
- {"output-target", required_argument, 0, 'O'},
+ {"input-target", required_argument, 0, 'I'},
+ {"interleave", required_argument, 0, 'i'},
{"output-format", required_argument, 0, 'O'}, /* Obsolete */
+ {"output-target", required_argument, 0, 'O'},
+ {"strip-all", no_argument, 0, 'S'},
+ {"strip-debug", no_argument, 0, 'g'},
{"target", required_argument, 0, 'F'},
- {"format", required_argument, 0, 'F'}, /* Obsolete */
-
- {"version", no_argument, 0, 'V'},
{"verbose", no_argument, 0, 'v'},
+ {"version", no_argument, 0, 'V'},
{0, no_argument, 0, 0}
};
@@ -112,10 +117,12 @@ copy_usage (stream, status)
int status;
{
fprintf (stream, "\
-Usage: %s [-vVSgxX] [-I bfdname] [-O bfdname] [-F bfdname]\n\
+Usage: %s [-vVSgxX] [-I bfdname] [-O bfdname] [-F bfdname] [-b byte]\n\
+ [-i interleave] [--interleave=interleave] [--byte=byte]\n\
[--input-target=bfdname] [--output-target=bfdname] [--target=bfdname]\n\
[--strip-all] [--strip-debug] [--discard-all] [--discard-locals]\n\
- [--verbose] [--version] [--help] in-file [out-file]\n", program_name);
+ [--verbose] [--version] [--help] in-file [out-file]\n",
+ program_name);
exit (status);
}
@@ -200,6 +207,21 @@ filter_symbols (abfd, osyms, isyms, symcount)
return dst_count;
}
+/* Keep only every `copy_byte'th byte in MEMHUNK, which is *SIZE bytes long.
+ Adjust *SIZE. */
+
+void
+filter_bytes (memhunk, size)
+ PTR memhunk;
+ bfd_size_type *size;
+{
+ char *from = memhunk + copy_byte, *to = memhunk, *end = memhunk + *size;
+
+ for (; from < end; from += interleave)
+ *to++ = *from;
+ *size /= interleave;
+}
+
/* Copy object file IBFD onto OBFD. */
static void
@@ -266,9 +288,9 @@ copy_object (ibfd, obfd)
/* bfd mandates that all output sections be created and sizes set before
any output is done. Thus, we traverse all sections multiple times. */
- bfd_map_over_sections (ibfd, setup_sections, (void *) obfd);
- bfd_map_over_sections (ibfd, copy_sections, (void *) obfd);
- bfd_map_over_sections (ibfd, mangle_sections, (void *) obfd);
+ bfd_map_over_sections (ibfd, setup_section, (void *) obfd);
+ bfd_map_over_sections (ibfd, copy_section, (void *) obfd);
+ bfd_map_over_sections (ibfd, mangle_section, (void *) obfd);
}
static char *
@@ -419,7 +441,7 @@ copy_file (input_filename, output_filename, input_target, output_target)
as ISECTION in IBFD. */
static void
-setup_sections (ibfd, isection, obfd)
+setup_section (ibfd, isection, obfd)
bfd *ibfd;
sec_ptr isection;
bfd *obfd;
@@ -493,7 +515,7 @@ loser:
If stripping then don't copy any relocation info. */
static void
-copy_sections (ibfd, isection, obfd)
+copy_section (ibfd, isection, obfd)
bfd *ibfd;
sec_ptr isection;
bfd *obfd;
@@ -544,6 +566,9 @@ copy_sections (ibfd, isection, obfd)
nonfatal (bfd_get_filename (ibfd));
}
+ if (copy_byte >= 0)
+ filter_bytes (memhunk, &size);
+
if (!bfd_set_section_contents (obfd, osection, memhunk, (file_ptr) 0,
size))
{
@@ -559,7 +584,7 @@ copy_sections (ibfd, isection, obfd)
their new location in the output file, through some complex sums. */
static void
-mangle_sections (ibfd, p, obfd)
+mangle_section (ibfd, p, obfd)
bfd *ibfd;
asection *p;
bfd *obfd;
@@ -747,11 +772,29 @@ copy_main (argc, argv)
boolean show_version = false;
int c;
- while ((c = getopt_long (argc, argv, "I:s:O:d:F:b:SgxXVv",
+ while ((c = getopt_long (argc, argv, "b:i:I:s:O:d:F:SgxXVv",
copy_options, (int *) 0)) != EOF)
{
switch (c)
{
+ case 'b':
+ copy_byte = atoi(optarg);
+ if (copy_byte < 0)
+ {
+ fprintf (stderr, "%s: byte number must be non-negative\n",
+ program_name);
+ exit (1);
+ }
+ break;
+ case 'i':
+ interleave = atoi(optarg);
+ if (interleave < 1)
+ {
+ fprintf(stderr, "%s: interleave must be positive\n",
+ program_name);
+ exit (1);
+ }
+ break;
case 'I':
case 's': /* "source" - 'I' is preferred */
input_target = optarg;
@@ -760,7 +803,6 @@ copy_main (argc, argv)
output_target = optarg;
break;
case 'F':
- case 'b': /* "both" - 'F' is preferred */
input_target = output_target = optarg;
break;
case 'S':
@@ -796,6 +838,13 @@ copy_main (argc, argv)
exit (0);
}
+ if (copy_byte >= interleave)
+ {
+ fprintf (stderr, "%s: byte number must be less than interleave\n",
+ program_name);
+ exit (1);
+ }
+
if (optind == argc || optind + 2 < argc)
copy_usage (stderr, 1);