mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-11-29 23:10:26 +00:00
* objcopy.c: Renamed from copy.c, updated comments accordingly.
* Makefile.in, binutils.texi: Renamed copy to objcopy. * is-strip.c, maybe-strip.c, not-strip.c: Updated comments for rename of copy to objcopy.
This commit is contained in:
parent
261d3247f9
commit
df14d9573c
@ -43,7 +43,6 @@ bucomm.h
|
||||
configure.bat
|
||||
configure.in
|
||||
config
|
||||
copy.c
|
||||
filemode.c
|
||||
gmalloc.c
|
||||
is-ranlib.c
|
||||
@ -54,6 +53,7 @@ nm.1
|
||||
nm.c
|
||||
not-ranlib.c
|
||||
not-strip.c
|
||||
objcopy.c
|
||||
objdump.1
|
||||
objdump.c
|
||||
objdump.h
|
||||
|
@ -1,3 +1,14 @@
|
||||
Wed May 12 12:05:36 1993 Ian Lance Taylor (ian@cygnus.com)
|
||||
|
||||
* objcopy.c: Renamed from copy.c, updated comments accordingly.
|
||||
* Makefile.in, binutils.texi: Renamed copy to objcopy.
|
||||
* is-strip.c, maybe-strip.c, not-strip.c: Updated comments for
|
||||
rename of copy to objcopy.
|
||||
|
||||
Mon May 10 17:20:18 1993 Per Bothner (bothner@cygnus.com)
|
||||
|
||||
* binutils.texi (strip, -v option): Fix typo.
|
||||
|
||||
Fri May 7 13:57:50 1993 Ian Lance Taylor (ian@cygnus.com)
|
||||
|
||||
* Makefile.in (RUNTEST): Define.
|
||||
|
@ -81,8 +81,8 @@ MANPAGES= ar nm objdump ranlib size strip
|
||||
AR_PROG=ar
|
||||
RANLIB_PROG=ranlib
|
||||
|
||||
# copy and strip should be the same program
|
||||
COPY_PROG=copy
|
||||
# objcopy and strip should be the same program
|
||||
OBJCOPY_PROG=objcopy
|
||||
STRIP_PROG=strip
|
||||
|
||||
# These should all be the same program too.
|
||||
@ -91,9 +91,9 @@ NM_PROG=nm
|
||||
OBJDUMP_PROG=objdump
|
||||
|
||||
# This is the demangler, as a standalone program.
|
||||
DEMANGLER_PROG=demangle
|
||||
DEMANGLER_PROG=c++filt
|
||||
|
||||
PROGS = $(SIZE_PROG) $(OBJDUMP_PROG) $(NM_PROG) $(AR_PROG) $(STRIP_PROG) $(RANLIB_PROG) $(DEMANGLER_PROG)
|
||||
PROGS = $(SIZE_PROG) $(OBJDUMP_PROG) $(NM_PROG) $(AR_PROG) $(STRIP_PROG) $(RANLIB_PROG) $(DEMANGLER_PROG) $(OBJCOPY_PROG)
|
||||
STAGESTUFF = $(PROGS) *.o
|
||||
# Files that can be generated, but should be in the distribution.
|
||||
DISTSTUFF=arparse.c arlex.c binutils.mm
|
||||
@ -138,11 +138,13 @@ ADDL_LIBS = $(MALLOC) $(BULIBS) $(BFD) $(LIBIBERTY)
|
||||
BFD = $(LIBDIR)/libbfd.a
|
||||
OPCODES = $(OPCODEDIR)/libopcodes.a
|
||||
|
||||
RUNTEST = runtest
|
||||
RUNTESTFLAGS =
|
||||
FLAGS_TO_PASS = \
|
||||
"RUNTEST=$(RUNTEST)" \
|
||||
"RUNTESTFLAGS=$(RUNTESTFLAGS) \
|
||||
SIZE=`if [ -f $$rootme/$(SIZE_PROG) ] ; then echo $$rootme/$(SIZE_PROG) ; else echo $(SIZE_PROG); fi` \
|
||||
COPY=`if [ -f $$rootme/$(COPY_PROG) ] ; then echo $$rootme/$(COPY_PROG) ; else echo $(COPY_PROG); fi` \
|
||||
OBJCOPY=`if [ -f $$rootme/$(OBJCOPY_PROG) ] ; then echo $$rootme/$(OBJCOPY_PROG) ; else echo $(OBJCOPY_PROG); fi` \
|
||||
NM=`if [ -f $$rootme/$(NM_PROG) ] ; then echo $$rootme/$(NM_PROG) ; else echo $(NM_PROG); fi` \
|
||||
AR=`if [ -f $$rootme/$(AR_PROG) ] ; then echo $$rootme/$(AR_PROG) ; else echo $(AR_PROG); fi` \
|
||||
OBJDUMP=`if [ -f $$rootme/$(OBJDUMP_PROG) ] ; then echo $$rootme/$(OBJDUMP_PROG) ; else echo $(OBJDUMP_PROG); fi` \
|
||||
@ -180,11 +182,11 @@ dvi: binutils.dvi
|
||||
$(SIZE_PROG): $(ADDL_LIBS) size.o $(BFD)
|
||||
$(CC) $(LDFLAGS) $(CFLAGS) -o $(SIZE_PROG) size.o $(ADDL_LIBS) $(LOADLIBES)
|
||||
|
||||
$(COPY_PROG): $(ADDL_LIBS) copy.o not-strip.o $(BFD)
|
||||
$(CC) $(LDFLAGS) $(CFLAGS) -o $(COPY_PROG) copy.o not-strip.o $(ADDL_LIBS) $(LOADLIBES)
|
||||
$(OBJCOPY_PROG): $(ADDL_LIBS) objcopy.o not-strip.o $(BFD)
|
||||
$(CC) $(LDFLAGS) $(CFLAGS) -o $(OBJCOPY_PROG) objcopy.o not-strip.o $(ADDL_LIBS) $(LOADLIBES)
|
||||
|
||||
$(STRIP_PROG): $(ADDL_LIBS) copy.o is-strip.o $(BFD)
|
||||
$(CC) $(LDFLAGS) $(CFLAGS) -o $(STRIP_PROG) copy.o is-strip.o $(ADDL_LIBS) $(LOADLIBES)
|
||||
$(STRIP_PROG): $(ADDL_LIBS) objcopy.o is-strip.o $(BFD)
|
||||
$(CC) $(LDFLAGS) $(CFLAGS) -o $(STRIP_PROG) objcopy.o is-strip.o $(ADDL_LIBS) $(LOADLIBES)
|
||||
|
||||
$(NM_PROG): $(ADDL_LIBS) nm.o $(BFD)
|
||||
$(CC) $(LDFLAGS) $(CFLAGS) -o $(NM_PROG) nm.o $(ADDL_LIBS) $(LOADLIBES)
|
||||
@ -223,12 +225,12 @@ ar_with_ranlib: $(ADDL_LIBS) ar.o maybe-ranlib.o $(BFD)
|
||||
-rm -f $(RANLIB_PROG)
|
||||
-ln $(AR_PROG) $(RANLIB_PROG)
|
||||
|
||||
# copy and strip in one binary that uses argv[0] to decide its action.
|
||||
# objcopy and strip in one binary that uses argv[0] to decide its action.
|
||||
|
||||
copy_with_strip: $(ADDL_LIBS) copy.o maybe-strip.o $(BFD)
|
||||
$(CC) $(LDFLAGS) $(CFLAGS) -o $(COPY_PROG) copy.o maybe-strip.o $(ADDL_LIBS) $(LOADLIBES)
|
||||
objcopy_with_strip: $(ADDL_LIBS) objcopy.o maybe-strip.o $(BFD)
|
||||
$(CC) $(LDFLAGS) $(CFLAGS) -o $(OBJCOPY_PROG) objcopy.o maybe-strip.o $(ADDL_LIBS) $(LOADLIBES)
|
||||
-rm -f $(STRIP_PROG)
|
||||
-ln $(COPY_PROG) $(STRIP_PROG)
|
||||
-ln $(OBJCOPY_PROG) $(STRIP_PROG)
|
||||
|
||||
stage1: force
|
||||
- mkdir stage1
|
||||
@ -406,7 +408,7 @@ alloca.o:alloca.c
|
||||
ar.o: ar.c
|
||||
arsup.o: arsup.c
|
||||
bucomm.o: bucomm.c
|
||||
copy.o: copy.c
|
||||
objcopy.o: objcopy.c
|
||||
filemode.o:filemode.c
|
||||
getopt.o:getopt.c
|
||||
getopt1.o:getopt1.c
|
||||
|
@ -4,7 +4,7 @@
|
||||
@ifinfo
|
||||
@format
|
||||
START-INFO-DIR-ENTRY
|
||||
* Binutils: (binutils). The GNU binary utilities "ar", "ld", "copy",
|
||||
* Binutils: (binutils). The GNU binary utilities "ar", "ld", "objcopy",
|
||||
"objdump", "nm", "size", "strip", and "ranlib".
|
||||
END-INFO-DIR-ENTRY
|
||||
@end format
|
||||
@ -36,8 +36,8 @@ into another language, under the above conditions for modified versions.
|
||||
|
||||
@synindex ky cp
|
||||
@c
|
||||
@c This file documents the GNU binary utilities "ar", "ld", "copy", "objdump",
|
||||
@c "nm", "size", "strip", and "ranlib".
|
||||
@c This file documents the GNU binary utilities "ar", "ld", "objcopy",
|
||||
@c "objdump", "nm", "size", "strip", and "ranlib".
|
||||
@c
|
||||
@c Copyright (C) 1991 Free Software Foundation, Inc.
|
||||
@c
|
||||
@ -94,7 +94,7 @@ utilities (collectively version 2.1):
|
||||
@item ar
|
||||
Create, modify, and extract from archives
|
||||
|
||||
@item copy
|
||||
@item objcopy
|
||||
Copy and translate object files
|
||||
|
||||
@item nm
|
||||
@ -116,7 +116,7 @@ Discard symbols
|
||||
|
||||
@menu
|
||||
* ar:: Create, modify, and extract from archives
|
||||
* copy:: Copy and translate object files
|
||||
* objcopy:: Copy and translate object files
|
||||
* ld:(ld)Overview. Combine object and archive files
|
||||
* nm:: List symbols from object files
|
||||
* objdump:: Display information from object files
|
||||
@ -126,7 +126,7 @@ Discard symbols
|
||||
* Index::
|
||||
@end menu
|
||||
|
||||
@node ar, copy, Top, Top
|
||||
@node ar, objcopy, Top, Top
|
||||
@chapter ar
|
||||
|
||||
@kindex ar
|
||||
@ -540,27 +540,27 @@ Requires prior use of @code{OPEN} or @code{CREATE}.
|
||||
|
||||
@end table
|
||||
|
||||
@node copy, nm, ar, Top
|
||||
@chapter copy
|
||||
@node objcopy, nm, ar, Top
|
||||
@chapter objcopy
|
||||
|
||||
@smallexample
|
||||
copy [ -F @var{format} | --format=@var{format} ]
|
||||
[ -I @var{format} | --input-format=@var{format} ]
|
||||
[ -O @var{format} | --output-format=@var{format} ]
|
||||
[ -S | --strip-all ] [ -g | --strip-debug ]
|
||||
[ -x | --discard-all ] [ -X | --discard-locals ]
|
||||
[ -v | --verbose ] [ -V | --version ]
|
||||
@var{infile} [@var{outfile}]
|
||||
objcopy [ -F @var{format} | --format=@var{format} ]
|
||||
[ -I @var{format} | --input-format=@var{format} ]
|
||||
[ -O @var{format} | --output-format=@var{format} ]
|
||||
[ -S | --strip-all ] [ -g | --strip-debug ]
|
||||
[ -x | --discard-all ] [ -X | --discard-locals ]
|
||||
[ -v | --verbose ] [ -V | --version ]
|
||||
@var{infile} [@var{outfile}]
|
||||
@end smallexample
|
||||
|
||||
The GNU @code{copy} utility copies the contents of an object file to
|
||||
another. @code{copy} uses the GNU BFD Library to read and write the
|
||||
The GNU @code{objcopy} utility copies the contents of an object file to
|
||||
another. @code{objcopy} uses the GNU BFD Library to read and write the
|
||||
object files. It can write the destination object file in a format
|
||||
different from that of the source object file. The exact behavior of
|
||||
@code{copy} is controlled by command-line options.
|
||||
@code{objcopy} is controlled by command-line options.
|
||||
|
||||
@code{copy} creates temporary files to do its translations and
|
||||
deletes them afterward. @code{copy} uses BFD to do all its
|
||||
@code{objcopy} creates temporary files to do its translations and
|
||||
deletes them afterward. @code{objcopy} uses BFD to do all its
|
||||
translation work; it knows about all the formats BFD knows about, and
|
||||
thus is able to recognize most formats without being told explicitly.
|
||||
@xref{BFD,,BFD,ld.info,Using LD, the GNU linker}.
|
||||
@ -569,7 +569,7 @@ thus is able to recognize most formats without being told explicitly.
|
||||
@item @var{infile}
|
||||
@itemx @var{outfile}
|
||||
The source and output files respectively.
|
||||
If you do not specify @var{outfile}, @code{copy} creates a
|
||||
If you do not specify @var{outfile}, @code{objcopy} creates a
|
||||
temporary file and destructively renames the result with
|
||||
the name of the input file.
|
||||
|
||||
@ -608,12 +608,12 @@ Do not copy compiler-generated local symbols.
|
||||
|
||||
@item -V
|
||||
@itemx --version
|
||||
Show the version number of @code{copy}.
|
||||
Show the version number of @code{objcopy}.
|
||||
|
||||
@item -v
|
||||
@itemx --verbose
|
||||
Verbose output: list all object files modified. In the case of
|
||||
archives, @samp{copy -V} lists all members of the archive.
|
||||
archives, @samp{objcopy -V} lists all members of the archive.
|
||||
@end table
|
||||
|
||||
@iftex
|
||||
@ -625,7 +625,7 @@ The GNU linker @code{ld} is now described in a separate manual.
|
||||
@xref{Top,, Overview,, Using LD: the GNU linker}.
|
||||
@end iftex
|
||||
|
||||
@node nm, objdump, copy, Top
|
||||
@node nm, objdump, objcopy, Top
|
||||
@chapter nm
|
||||
@cindex symbols
|
||||
@kindex nm
|
||||
|
665
binutils/copy.c
665
binutils/copy.c
@ -1,665 +0,0 @@
|
||||
/* copy.c -- copy object file from input to output, optionally massaging it.
|
||||
Copyright (C) 1991 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Binutils.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include "bfd.h"
|
||||
#include "sysdep.h"
|
||||
#include "bucomm.h"
|
||||
#include <getopt.h>
|
||||
|
||||
asymbol **sympp;
|
||||
char *input_target = NULL;
|
||||
char *output_target = NULL;
|
||||
char *input_filename = NULL;
|
||||
char *output_filename = NULL;
|
||||
|
||||
|
||||
static void setup_sections();
|
||||
static void copy_sections();
|
||||
static boolean verbose;
|
||||
|
||||
/* This flag distinguishes between strip and copy:
|
||||
1 means this is 'strip'; 0 means this is 'copy'.
|
||||
-1 means if we should use argv[0] to decide. */
|
||||
extern int is_strip;
|
||||
|
||||
int show_version = 0;
|
||||
|
||||
enum strip_action
|
||||
{
|
||||
strip_undef,
|
||||
strip_none, /* don't strip */
|
||||
strip_debug, /* strip all debugger symbols */
|
||||
strip_all /* strip all symbols */
|
||||
};
|
||||
|
||||
/* Which symbols to remove. */
|
||||
enum strip_action strip_symbols;
|
||||
|
||||
enum locals_action
|
||||
{
|
||||
locals_undef,
|
||||
locals_start_L, /* discard locals starting with L */
|
||||
locals_all /* discard all locals */
|
||||
};
|
||||
|
||||
/* Which local symbols to remove. */
|
||||
enum locals_action discard_locals;
|
||||
|
||||
/* Options to handle if running as "strip". */
|
||||
|
||||
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'},
|
||||
{"input-format", required_argument, 0, 'I'},
|
||||
{"output-format", required_argument, 0, 'O'},
|
||||
{"format", required_argument, 0, 'F'},
|
||||
{"target", required_argument, 0, 'F'},
|
||||
|
||||
{"version", no_argument, 0, 'V'},
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
{0, no_argument, 0, 0}
|
||||
};
|
||||
|
||||
/* Options to handle if running as "copy". */
|
||||
|
||||
struct option copy_options[] = {
|
||||
{"strip-all", no_argument, 0, 'S'},
|
||||
{"strip-debug", no_argument, 0, 'g'},
|
||||
{"discard-all", no_argument, 0, 'x'},
|
||||
{"discard-locals", no_argument, 0, 'X'},
|
||||
{"input-format", required_argument, 0, 'I'},
|
||||
{"output-format", required_argument, 0, 'O'},
|
||||
{"format", required_argument, 0, 'F'},
|
||||
{"target", required_argument, 0, 'F'},
|
||||
|
||||
{"version", no_argument, 0, 'V'},
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
{0, no_argument, 0, 0}
|
||||
};
|
||||
|
||||
/* IMPORTS */
|
||||
extern char *program_name;
|
||||
extern char *program_version;
|
||||
|
||||
|
||||
static
|
||||
void
|
||||
copy_usage()
|
||||
{
|
||||
fprintf(stderr, "\
|
||||
Usage: %s [-vVSgxX] [-I format] [-O format] [-F format]\n\
|
||||
[--format=format] [--target=format] [--input-format=format]\n\
|
||||
[--output-format=format] [--strip-all] [--strip-debug]\n\
|
||||
[--discard-all] [--discard-locals] [--verbose] [--version]\n\
|
||||
in-file [out-file]\n", program_name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
strip_usage()
|
||||
{
|
||||
fprintf(stderr, "strip %s\n\
|
||||
Usage: %s [-vVsSgxX] [-I format] [-O format] [-F format]\n\
|
||||
[--format=format] [--target=format] [--input-format=format]\n\
|
||||
[--output-format=format] [--strip-all] [--strip-debug]\n\
|
||||
[--discard-all] [--discard-locals] [--verbose] [--version] file...\n",
|
||||
program_version, program_name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
/* Create a temp file in the same directory as supplied */
|
||||
static
|
||||
char *
|
||||
make_tempname(filename)
|
||||
char *filename;
|
||||
{
|
||||
static char template[] = "stXXXXXX";
|
||||
char *tmpname;
|
||||
char * slash = strrchr( filename, '/' );
|
||||
if (slash != (char *)NULL){
|
||||
*slash = 0;
|
||||
tmpname = xmalloc(strlen(filename) + sizeof(template) + 1 );
|
||||
strcpy(tmpname, filename);
|
||||
strcat(tmpname, "/" );
|
||||
strcat(tmpname, template);
|
||||
mktemp(tmpname );
|
||||
*slash = '/';
|
||||
} else {
|
||||
tmpname = xmalloc(sizeof(template));
|
||||
strcpy(tmpname, template);
|
||||
mktemp(tmpname);
|
||||
}
|
||||
return tmpname;
|
||||
}
|
||||
|
||||
/*
|
||||
All the symbols have been read in and point to their owning input section.
|
||||
They have been relocated to that they are all relative to the base of
|
||||
their owning section. On the way out, all the symbols will be relocated to
|
||||
their new location in the output file, through some complex sums.
|
||||
|
||||
*/
|
||||
static void
|
||||
mangle_sections(ibfd, obfd)
|
||||
bfd *ibfd;
|
||||
bfd *obfd;
|
||||
{
|
||||
asection *current = ibfd->sections;
|
||||
for (; current != NULL; current = current->next) {
|
||||
current->output_section = bfd_get_section_by_name(obfd, current->name);
|
||||
current->output_offset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Choose which symbol entries to copy;
|
||||
compact them downward to get rid of the rest.
|
||||
Return the number of symbols to be printed. */
|
||||
static unsigned int
|
||||
filter_symbols (abfd, syms, symcount)
|
||||
bfd *abfd;
|
||||
asymbol **syms;
|
||||
unsigned long symcount;
|
||||
{
|
||||
asymbol **from, **to;
|
||||
unsigned int dst_count = 0;
|
||||
asymbol *sym;
|
||||
char locals_prefix = bfd_get_symbol_leading_char(abfd) == '_' ? 'L' : '.';
|
||||
|
||||
unsigned int src_count;
|
||||
for (from = to = syms, src_count = 0; src_count <symcount; src_count++) {
|
||||
int keep = 0;
|
||||
|
||||
flagword flags = (from[src_count])->flags;
|
||||
sym = from[src_count];
|
||||
if ((flags & BSF_GLOBAL) /* Keep if external */
|
||||
|| (sym->section == &bfd_und_section)
|
||||
|| (bfd_is_com_section (sym->section)))
|
||||
keep = 1;
|
||||
else if ((flags & BSF_DEBUGGING) != 0) /* debugging symbol */
|
||||
keep = strip_symbols != strip_debug;
|
||||
else /* local symbol */
|
||||
keep = (discard_locals != locals_all)
|
||||
&& !(discard_locals == locals_start_L &&
|
||||
sym->name[0] == locals_prefix);
|
||||
|
||||
|
||||
if (keep) {
|
||||
to[dst_count++] = from[src_count];
|
||||
}
|
||||
}
|
||||
|
||||
return dst_count;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
copy_object(ibfd, obfd)
|
||||
bfd *ibfd;
|
||||
bfd *obfd;
|
||||
{
|
||||
|
||||
unsigned int symcount;
|
||||
|
||||
|
||||
if (!bfd_set_format(obfd, bfd_get_format(ibfd)))
|
||||
bfd_fatal(output_filename);
|
||||
|
||||
|
||||
if (verbose)
|
||||
printf("copy from %s(%s) to %s(%s)\n",
|
||||
ibfd->filename, ibfd->xvec->name,
|
||||
obfd->filename, obfd->xvec->name);
|
||||
|
||||
if ((bfd_set_start_address(obfd, bfd_get_start_address(ibfd)) == false)
|
||||
||
|
||||
(bfd_set_file_flags(obfd, (bfd_get_file_flags(ibfd) &
|
||||
(HAS_LINENO | HAS_DEBUG |
|
||||
HAS_RELOC | HAS_SYMS | D_PAGED |
|
||||
HAS_LOCALS))) == false)) {
|
||||
bfd_fatal(bfd_get_filename(ibfd));
|
||||
}
|
||||
|
||||
/* Copy architecture of input file to output file */
|
||||
if (!bfd_set_arch_mach(obfd, bfd_get_arch(ibfd),
|
||||
bfd_get_mach(ibfd))) {
|
||||
fprintf(stderr, "Output file cannot represent architecture %s\n",
|
||||
bfd_printable_arch_mach(bfd_get_arch(ibfd),
|
||||
bfd_get_mach(ibfd)));
|
||||
}
|
||||
if (!bfd_set_format(obfd, bfd_get_format(ibfd)))
|
||||
{
|
||||
bfd_fatal(ibfd->filename);
|
||||
}
|
||||
|
||||
sympp = (asymbol **) xmalloc(get_symtab_upper_bound(ibfd));
|
||||
symcount = bfd_canonicalize_symtab(ibfd, sympp);
|
||||
|
||||
if (strip_symbols == strip_debug || discard_locals != locals_undef)
|
||||
symcount = filter_symbols (ibfd, sympp, symcount);
|
||||
|
||||
|
||||
bfd_set_symtab(obfd, sympp,
|
||||
strip_symbols == strip_all ? 0 : symcount);
|
||||
|
||||
/*
|
||||
bfd mandates that all output sections be created and sizes set before
|
||||
any output is done. Thus, we traverse all sections twice.
|
||||
*/
|
||||
bfd_map_over_sections(ibfd, setup_sections, (void *) obfd);
|
||||
bfd_map_over_sections(ibfd, copy_sections, (void *) obfd);
|
||||
mangle_sections(ibfd, obfd);
|
||||
}
|
||||
static
|
||||
char *
|
||||
cat(a,b,c)
|
||||
char *a;
|
||||
char *b;
|
||||
char *c;
|
||||
{
|
||||
int size = strlen(a) + strlen(b) + strlen(c);
|
||||
char *r = xmalloc(size+1);
|
||||
strcpy(r,a);
|
||||
strcat(r,b);
|
||||
strcat(r,c);
|
||||
return r;
|
||||
}
|
||||
|
||||
static void
|
||||
copy_archive(ibfd, obfd)
|
||||
bfd *ibfd;
|
||||
bfd *obfd;
|
||||
{
|
||||
bfd **ptr = &obfd->archive_head;
|
||||
bfd *this_element;
|
||||
/* Read each archive element in turn from the input, copy the
|
||||
contents to a temp file, and keep the temp file handle */
|
||||
char *dir = cat("./#",make_tempname(""),"cd");
|
||||
|
||||
/* Make a temp directory to hold the contents */
|
||||
mkdir(dir,0777);
|
||||
obfd->has_armap = ibfd->has_armap;
|
||||
this_element = bfd_openr_next_archived_file(ibfd, NULL);
|
||||
ibfd->archive_head = this_element;
|
||||
while (this_element != (bfd *)NULL) {
|
||||
|
||||
/* Create an output file for this member */
|
||||
char *output_name = cat(dir, "/",this_element->filename);
|
||||
bfd *output_bfd = bfd_openw(output_name, output_target);
|
||||
|
||||
if (!bfd_set_format(obfd, bfd_get_format(ibfd)))
|
||||
bfd_fatal(output_filename);
|
||||
|
||||
if (output_bfd == (bfd *)NULL) {
|
||||
bfd_fatal(output_name);
|
||||
}
|
||||
if (bfd_check_format(this_element, bfd_object) == true) {
|
||||
copy_object(this_element, output_bfd);
|
||||
}
|
||||
|
||||
bfd_close(output_bfd);
|
||||
/* Now open the newly output file and attatch to our list */
|
||||
output_bfd = bfd_openr(output_name, output_target);
|
||||
/* Mark it for deletion */
|
||||
|
||||
*ptr = output_bfd;
|
||||
|
||||
ptr = &output_bfd->next;
|
||||
this_element->next = bfd_openr_next_archived_file(ibfd, this_element);
|
||||
this_element = this_element->next;
|
||||
|
||||
}
|
||||
*ptr = (bfd *)NULL;
|
||||
|
||||
if (!bfd_close(obfd))
|
||||
bfd_fatal(output_filename);
|
||||
|
||||
/* Now delete all the files that we opened.
|
||||
Construct their names again, unfortunately, but so what;
|
||||
we're about to exit anyway. */
|
||||
for (this_element = ibfd->archive_head;
|
||||
this_element != (bfd *)NULL;
|
||||
this_element = this_element->next)
|
||||
{
|
||||
unlink(cat(dir,"/",this_element->filename));
|
||||
}
|
||||
rmdir(dir);
|
||||
if (!bfd_close(ibfd))
|
||||
bfd_fatal(input_filename);
|
||||
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
copy_file(input_filename, output_filename)
|
||||
char *input_filename;
|
||||
char *output_filename;
|
||||
{
|
||||
bfd *ibfd;
|
||||
|
||||
ibfd = bfd_openr(input_filename, input_target);
|
||||
if (ibfd == NULL)
|
||||
bfd_fatal(input_filename);
|
||||
|
||||
if (bfd_check_format(ibfd, bfd_object)) {
|
||||
bfd * obfd = bfd_openw(output_filename, output_target);
|
||||
if (obfd == NULL)
|
||||
bfd_fatal(output_filename);
|
||||
|
||||
copy_object(ibfd, obfd);
|
||||
|
||||
if (ibfd->flags & EXEC_P)
|
||||
obfd->flags |= EXEC_P;
|
||||
if (!bfd_close(obfd))
|
||||
bfd_fatal(output_filename);
|
||||
|
||||
if (!bfd_close(ibfd))
|
||||
bfd_fatal(input_filename);
|
||||
}
|
||||
else if (bfd_check_format(ibfd, bfd_archive)) {
|
||||
bfd * obfd = bfd_openw(output_filename, output_target);
|
||||
if (obfd == NULL)
|
||||
bfd_fatal(output_filename);
|
||||
copy_archive(ibfd, obfd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Actually do the work */
|
||||
static void
|
||||
setup_sections(ibfd, isection, obfd)
|
||||
bfd *ibfd;
|
||||
sec_ptr isection;
|
||||
bfd *obfd;
|
||||
{
|
||||
sec_ptr osection;
|
||||
char *err;
|
||||
|
||||
osection = bfd_get_section_by_name(obfd, bfd_section_name(ibfd, isection));
|
||||
if (osection == NULL) {
|
||||
osection = bfd_make_section(obfd, bfd_section_name(ibfd, isection));
|
||||
if (osection == NULL) {
|
||||
err = "making";
|
||||
goto loser;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bfd_set_section_size(obfd,
|
||||
osection,
|
||||
bfd_section_size(ibfd, isection))) {
|
||||
err = "size";
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (bfd_set_section_vma(obfd,
|
||||
osection,
|
||||
bfd_section_vma(ibfd, isection))
|
||||
== false) {
|
||||
err = "vma";
|
||||
goto loser;
|
||||
} /* on error */
|
||||
|
||||
if (bfd_set_section_alignment(obfd,
|
||||
osection,
|
||||
bfd_section_alignment(ibfd, isection))
|
||||
== false) {
|
||||
err = "alignment";
|
||||
goto loser;
|
||||
} /* on error */
|
||||
|
||||
if (!bfd_set_section_flags(obfd, osection,
|
||||
bfd_get_section_flags(ibfd, isection))) {
|
||||
err = "flags";
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* All went well */
|
||||
return;
|
||||
|
||||
loser:
|
||||
fprintf(stderr, "%s: file \"%s\", section \"%s\": error in %s: %s\n",
|
||||
program_name,
|
||||
bfd_get_filename(ibfd), bfd_section_name(ibfd, isection),
|
||||
err, bfd_errmsg(bfd_error));
|
||||
exit(1);
|
||||
} /* setup_sections() */
|
||||
|
||||
/*
|
||||
Copy all the section related data from an input section
|
||||
to an output section
|
||||
|
||||
If stripping then don't copy any relocation info
|
||||
*/
|
||||
static void
|
||||
copy_sections(ibfd, isection, obfd)
|
||||
bfd *ibfd;
|
||||
sec_ptr isection;
|
||||
bfd *obfd;
|
||||
{
|
||||
|
||||
arelent **relpp;
|
||||
int relcount;
|
||||
sec_ptr osection;
|
||||
bfd_size_type size;
|
||||
osection = bfd_get_section_by_name(obfd,
|
||||
bfd_section_name(ibfd, isection));
|
||||
|
||||
size = bfd_get_section_size_before_reloc(isection);
|
||||
|
||||
if (size == 0)
|
||||
return;
|
||||
|
||||
if (strip_symbols == strip_all
|
||||
|| bfd_get_reloc_upper_bound(ibfd, isection) == 0)
|
||||
{
|
||||
bfd_set_reloc(obfd, osection, (arelent **)NULL, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
relpp = (arelent **) xmalloc(bfd_get_reloc_upper_bound(ibfd, isection));
|
||||
relcount = bfd_canonicalize_reloc(ibfd, isection, relpp, sympp);
|
||||
bfd_set_reloc(obfd, osection, relpp, relcount);
|
||||
}
|
||||
|
||||
isection->_cooked_size = isection->_raw_size;
|
||||
isection->reloc_done =true;
|
||||
|
||||
|
||||
if (bfd_get_section_flags(ibfd, isection) & SEC_HAS_CONTENTS)
|
||||
{
|
||||
PTR memhunk = (PTR) xmalloc((unsigned)size);
|
||||
|
||||
if (!bfd_get_section_contents(ibfd, isection, memhunk, (file_ptr) 0, size))
|
||||
bfd_fatal(bfd_get_filename(ibfd));
|
||||
|
||||
if (!bfd_set_section_contents(obfd, osection, memhunk, (file_ptr)0, size))
|
||||
bfd_fatal(bfd_get_filename(obfd));
|
||||
free(memhunk);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int i;
|
||||
int c; /* sez which option char */
|
||||
|
||||
program_name = argv[0];
|
||||
|
||||
strip_symbols = strip_undef; /* default is to strip everything. */
|
||||
discard_locals = locals_undef;
|
||||
|
||||
bfd_init();
|
||||
|
||||
if (is_strip < 0) {
|
||||
i = strlen (program_name);
|
||||
is_strip = (i >= 5 && strcmp(program_name+i-5,"strip"));
|
||||
}
|
||||
|
||||
if (is_strip) {
|
||||
|
||||
while ((c = getopt_long(argc, argv, "I:O:F:sSgxXVv",
|
||||
strip_options, (int *) 0))
|
||||
!= EOF) {
|
||||
switch (c) {
|
||||
case 'I':
|
||||
input_target = optarg;
|
||||
case 'O':
|
||||
output_target = optarg;
|
||||
break;
|
||||
case 'F':
|
||||
input_target = output_target = optarg;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
strip_symbols = strip_all;
|
||||
break;
|
||||
case 'S':
|
||||
case 'g':
|
||||
strip_symbols = strip_debug;
|
||||
break;
|
||||
case 'x':
|
||||
discard_locals = locals_all;
|
||||
break;
|
||||
case 'X':
|
||||
discard_locals = locals_start_L;
|
||||
break;
|
||||
case 'v':
|
||||
verbose = true;
|
||||
show_version = true;
|
||||
break;
|
||||
case 'V':
|
||||
show_version = true;
|
||||
break;
|
||||
case 0:
|
||||
break; /* we've been given a long option */
|
||||
default:
|
||||
strip_usage ();
|
||||
}
|
||||
}
|
||||
|
||||
i = optind;
|
||||
|
||||
/* Default is to strip all symbols. */
|
||||
if (strip_symbols == strip_undef && discard_locals == locals_undef)
|
||||
strip_symbols = strip_all;
|
||||
|
||||
if (output_target == (char *) NULL)
|
||||
output_target = input_target;
|
||||
|
||||
if (show_version)
|
||||
printf ("%s version %s\n", program_name, program_version);
|
||||
else if (i == argc)
|
||||
strip_usage();
|
||||
for ( ; i < argc; i++) {
|
||||
char *tmpname = make_tempname(argv[i]);
|
||||
copy_file(argv[i], tmpname);
|
||||
rename(tmpname, argv[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Invoked as "copy", not "strip" */
|
||||
|
||||
while ((c = getopt_long(argc, argv, "I:s:O:d:F:b:SgxXVv",
|
||||
strip_options, (int *) 0))
|
||||
!= EOF) {
|
||||
switch (c) {
|
||||
case 'I':
|
||||
case 's': /* "source" - 'I' is preferred */
|
||||
input_target = optarg;
|
||||
case 'O':
|
||||
case 'd': /* "destination" - 'O' is preferred */
|
||||
output_target = optarg;
|
||||
break;
|
||||
case 'F':
|
||||
case 'b': /* "both" - 'F' is preferred */
|
||||
input_target = output_target = optarg;
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
strip_symbols = strip_all;
|
||||
break;
|
||||
case 'g':
|
||||
strip_symbols = strip_debug;
|
||||
break;
|
||||
case 'x':
|
||||
discard_locals = locals_all;
|
||||
break;
|
||||
case 'X':
|
||||
discard_locals = locals_start_L;
|
||||
break;
|
||||
case 'v':
|
||||
verbose = true;
|
||||
show_version = true;
|
||||
break;
|
||||
case 'V':
|
||||
show_version = true;
|
||||
break;
|
||||
case 0:
|
||||
break; /* we've been given a long option */
|
||||
default:
|
||||
copy_usage ();
|
||||
}
|
||||
}
|
||||
|
||||
if (show_version)
|
||||
printf ("%s version %s\n", program_name, program_version);
|
||||
|
||||
if (optind == argc)
|
||||
if (show_version)
|
||||
exit(0);
|
||||
else
|
||||
copy_usage();
|
||||
|
||||
input_filename = argv[optind];
|
||||
if (optind + 1 < argc)
|
||||
output_filename = argv[optind+1];
|
||||
|
||||
/* Default is to strip no symbols. */
|
||||
if (strip_symbols == strip_undef && discard_locals == locals_undef)
|
||||
strip_symbols = strip_none;
|
||||
|
||||
if (input_filename == (char *) NULL)
|
||||
copy_usage();
|
||||
|
||||
if (output_target == (char *) NULL)
|
||||
output_target = input_target;
|
||||
|
||||
/* If there is no destination file then create a temp and rename
|
||||
the result into the input */
|
||||
|
||||
if (output_filename == (char *)NULL) {
|
||||
char * tmpname = make_tempname(input_filename);
|
||||
copy_file(input_filename, tmpname);
|
||||
output_filename = input_filename;
|
||||
rename(tmpname, input_filename);
|
||||
}
|
||||
else {
|
||||
copy_file(input_filename, output_filename);
|
||||
}
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user