/* objcopy.c -- copy object file from input to output, optionally massaging it.
- Copyright (C) 1991, 92, 93, 94 Free Software Foundation, Inc.
+ Copyright (C) 1991, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
This file is part of GNU Binutils.
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
\f
#include "bfd.h"
-#include "sysdep.h"
#include "progress.h"
#include "bucomm.h"
-#include <getopt.h>
+#include "getopt.h"
#include "libiberty.h"
+#include "budbg.h"
+#include <sys/stat.h>
-static bfd_vma parse_vma PARAMS ((const char *, const char *));
static flagword parse_flags PARAMS ((const char *));
static struct section_list *find_section_list PARAMS ((const char *, boolean));
static void setup_section PARAMS ((bfd *, asection *, PTR));
static unsigned int filter_symbols
PARAMS ((bfd *, asymbol **, asymbol **, long));
static void mark_symbols_used_in_relocations PARAMS ((bfd *, asection *, PTR));
+static boolean write_debugging_info PARAMS ((bfd *, PTR, long *, asymbol ***));
#define nonfatal(s) {bfd_nonfatal(s); status = 1; return;}
static struct section_add *add_sections;
+/* Whether to convert debugging information. */
+
+static boolean convert_debugging = false;
+
/* 150 isn't special; it's just an arbitrary non-ASCII char value. */
#define OPTION_ADD_SECTION 150
#define OPTION_ADJUST_VMA (OPTION_ADJUST_START + 1)
#define OPTION_ADJUST_SECTION_VMA (OPTION_ADJUST_VMA + 1)
#define OPTION_ADJUST_WARNINGS (OPTION_ADJUST_SECTION_VMA + 1)
-#define OPTION_GAP_FILL (OPTION_ADJUST_WARNINGS + 1)
+#define OPTION_DEBUGGING (OPTION_ADJUST_WARNINGS + 1)
+#define OPTION_GAP_FILL (OPTION_DEBUGGING + 1)
#define OPTION_NO_ADJUST_WARNINGS (OPTION_GAP_FILL + 1)
#define OPTION_PAD_TO (OPTION_NO_ADJUST_WARNINGS + 1)
#define OPTION_SET_SECTION_FLAGS (OPTION_PAD_TO + 1)
{"adjust-section-vma", required_argument, 0, OPTION_ADJUST_SECTION_VMA},
{"adjust-warnings", no_argument, 0, OPTION_ADJUST_WARNINGS},
{"byte", required_argument, 0, 'b'},
+ {"debugging", no_argument, 0, OPTION_DEBUGGING},
{"discard-all", no_argument, 0, 'x'},
{"discard-locals", no_argument, 0, 'X'},
{"format", required_argument, 0, 'F'}, /* Obsolete */
[-R section] [-i interleave] [--interleave=interleave] [--byte=byte]\n\
[--input-target=bfdname] [--output-target=bfdname] [--target=bfdname]\n\
[--strip-all] [--strip-debug] [--strip-unneeded] [--discard-all]\n\
- [--discard-locals] [--remove-section=section] [--gap-fill=val]\n",
+ [--discard-locals] [--debugging] [--remove-section=section]\n",
program_name);
fprintf (stream, "\
- [--pad-to=address] [--set-start=val] [--adjust-start=incr]\n\
+ [--gap-fill=val] [--pad-to=address]\n\
+ [--set-start=val] [--adjust-start=incr]\n\
[--adjust-vma=incr] [--adjust-section-vma=section{=,+,-}val]\n\
[--adjust-warnings] [--no-adjust-warnings]\n\
[--set-section-flags=section=flags] [--add-section=sectionname=filename]\n\
exit (exit_status);
}
-/* Parse a string into a VMA, with a fatal error if it can't be
- parsed. */
-
-static bfd_vma
-parse_vma (s, arg)
- const char *s;
- const char *arg;
-{
- bfd_vma ret;
- const char *end;
-
- ret = bfd_scan_vma (s, &end, 0);
- if (*end != '\0')
- {
- fprintf (stderr, "%s: %s: bad number: %s\n", program_name, arg, s);
- exit (1);
- }
- return ret;
-}
-
/* Parse section flags into a flagword, with a fatal error if the
string can't be parsed. */
&& (strip_symbols == strip_debug
|| strip_symbols == strip_unneeded
|| strip_symbols == strip_all
- || discard_locals == locals_all))
+ || discard_locals == locals_all
+ || convert_debugging))
return true;
if (! sections_removed)
keep = strip_symbols != strip_unneeded;
else if ((flags & BSF_DEBUGGING) != 0) /* Debugging symbol. */
keep = (strip_symbols != strip_debug
- && strip_symbols != strip_unneeded);
+ && strip_symbols != strip_unneeded
+ && ! convert_debugging);
else /* Local symbol. */
keep = (strip_symbols != strip_unneeded
&& (discard_locals != locals_all
else
{
long symsize;
+ PTR dhandle = NULL;
symsize = bfd_get_symtab_upper_bound (ibfd);
if (symsize < 0)
nonfatal (bfd_get_filename (ibfd));
}
+ if (convert_debugging)
+ dhandle = read_debugging_info (ibfd, isympp, symcount);
+
if (strip_symbols == strip_debug
|| strip_symbols == strip_unneeded
|| discard_locals != locals_undef
|| strip_specific_list != NULL
- || sections_removed)
+ || sections_removed
+ || convert_debugging)
{
/* Mark symbols used in output relocations so that they
are kept, even if they are local labels or static symbols.
osympp = (asymbol **) xmalloc (symcount * sizeof (asymbol *));
symcount = filter_symbols (ibfd, osympp, isympp, symcount);
}
+
+ if (convert_debugging && dhandle != NULL)
+ {
+ if (! write_debugging_info (obfd, dhandle, &symcount, &osympp))
+ {
+ status = 1;
+ return;
+ }
+ }
}
bfd_set_symtab (obfd, osympp, symcount);
struct section_list *p;
sec_ptr osection;
bfd_vma vma;
+ bfd_vma lma;
flagword flags;
char *err;
&& (strip_symbols == strip_debug
|| strip_symbols == strip_unneeded
|| strip_symbols == strip_all
- || discard_locals == locals_all))
+ || discard_locals == locals_all
+ || convert_debugging))
return;
p = find_section_list (bfd_section_name (ibfd, isection), false);
goto loser;
}
+ lma = isection->lma;
+ if (p != NULL && p->adjust == adjust_vma)
+ lma += p->val;
+ else if (p != NULL && p->adjust == set_vma)
+ lma = p->val;
+ else
+ lma += adjust_section_vma;
+ osection->lma = lma;
+
if (bfd_set_section_alignment (obfd,
osection,
bfd_section_alignment (ibfd, isection))
&& (strip_symbols == strip_debug
|| strip_symbols == strip_unneeded
|| strip_symbols == strip_all
- || discard_locals == locals_all))
+ || discard_locals == locals_all
+ || convert_debugging))
{
return;
}
bfd_fatal (bfd_get_filename (ibfd));
if (relsize == 0)
- return 0;
+ return;
relpp = (arelent **) xmalloc (relsize);
relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, symbols);
free (relpp);
}
+/* Write out debugging information. */
+
+static boolean
+write_debugging_info (obfd, dhandle, symcountp, symppp)
+ bfd *obfd;
+ PTR dhandle;
+ long *symcountp;
+ asymbol ***symppp;
+{
+ if (bfd_get_flavour (obfd) == bfd_target_ieee_flavour)
+ return write_ieee_debugging_info (obfd, dhandle);
+
+ fprintf (stderr,
+ "%s: don't know how to write debugging information for %s\n",
+ bfd_get_filename (obfd), bfd_get_target (obfd));
+ return false;
+}
+
/* The number of bytes to copy at once. */
#define COPY_BUF 8192
fromfd = open (from, O_RDONLY);
if (fromfd < 0)
return -1;
- tofd = open (to, O_WRONLY | O_CREAT | O_TRUNC);
+ tofd = creat (to, 0777);
if (tofd < 0)
{
saved = errno;
case OPTION_ADJUST_WARNINGS:
adjust_warn = true;
break;
+ case OPTION_DEBUGGING:
+ convert_debugging = true;
+ break;
case OPTION_GAP_FILL:
{
bfd_vma gap_fill_vma;