Add new switch to objcopy: --add-gnu-debuglink=<file>

Allows packages to be shipped in two forms, a stripped executable and debug
info file.
This commit is contained in:
Nick Clifton
2003-06-12 07:23:31 +00:00
parent 7d1ebfb2ed
commit 2593f09acc
6 changed files with 283 additions and 114 deletions

View File

@ -905,9 +905,15 @@ bfd_make_writable PARAMS ((bfd *abfd));
bfd_boolean bfd_boolean
bfd_make_readable PARAMS ((bfd *abfd)); bfd_make_readable PARAMS ((bfd *abfd));
unsigned long
bfd_calc_gnu_debuglink_crc32 PARAMS ((unsigned long crc, const unsigned char *buf, bfd_size_type len));
char * char *
bfd_follow_gnu_debuglink PARAMS ((bfd *abfd, const char *dir)); bfd_follow_gnu_debuglink PARAMS ((bfd *abfd, const char *dir));
bfd_boolean
bfd_add_gnu_debuglink PARAMS ((bfd * abfd, const char * filename));
/* Extracted from libbfd.c. */ /* Extracted from libbfd.c. */
/* Byte swapping macros for user section data. */ /* Byte swapping macros for user section data. */

View File

@ -716,28 +716,32 @@ bfd_release (abfd, block)
without debug symbols). without debug symbols).
*/ */
static unsigned long calc_crc32 PARAMS ((unsigned long, const unsigned char *, size_t));
static char * get_debug_link_info PARAMS ((bfd *, unsigned long *)); static char * get_debug_link_info PARAMS ((bfd *, unsigned long *));
static bfd_boolean separate_debug_file_exists PARAMS ((const char *, const unsigned long)); static bfd_boolean separate_debug_file_exists PARAMS ((const char *, const unsigned long));
static char * find_separate_debug_file PARAMS ((bfd *, const char *)); static char * find_separate_debug_file PARAMS ((bfd *, const char *));
#define GNU_DEBUGLINK ".gnu_debuglink"
/* /*
INTERNAL_FUNCTION FUNCTION
calc_crc32 bfd_calc_gnu_debuglink_crc32
SYNOPSIS SYNOPSIS
unsigned long calc_crc32 (unsigned long crc, const unsigned char *buf, size_t len); unsigned long bfd_calc_gnu_debuglink_crc32 (unsigned long crc, const unsigned char *buf, bfd_size_type len);
DESCRIPTION DESCRIPTION
Advance the CRC32 given by @var{crc} through @var{len} Computes a CRC value as used in the .gnu_debuglink section.
bytes of @var{buf}. Return the updated CRC32 value. Advances the previously computed @var{crc} value by computing
and adding in the crc32 for @var{len} bytes of @var{buf}.
RETURNS
Return the updated CRC32 value.
*/ */
static unsigned long unsigned long
calc_crc32 (crc, buf, len) bfd_calc_gnu_debuglink_crc32 (crc, buf, len)
unsigned long crc; unsigned long crc;
const unsigned char *buf; const unsigned char *buf;
size_t len; bfd_size_type len;
{ {
static const unsigned long crc32_table[256] = static const unsigned long crc32_table[256] =
{ {
@ -808,7 +812,7 @@ INTERNAL_FUNCTION
get_debug_link_info get_debug_link_info
SYNOPSIS SYNOPSIS
char *get_debug_link_info (bfd *abfd, unsigned long *crc32_out) char * get_debug_link_info (bfd * abfd, unsigned long * crc32_out)
DESCRIPTION DESCRIPTION
fetch the filename and CRC32 value for any separate debuginfo fetch the filename and CRC32 value for any separate debuginfo
@ -818,8 +822,8 @@ DESCRIPTION
static char * static char *
get_debug_link_info (abfd, crc32_out) get_debug_link_info (abfd, crc32_out)
bfd *abfd; bfd * abfd;
unsigned long *crc32_out; unsigned long * crc32_out;
{ {
asection * sect; asection * sect;
bfd_size_type debuglink_size; bfd_size_type debuglink_size;
@ -831,14 +835,17 @@ get_debug_link_info (abfd, crc32_out)
BFD_ASSERT (abfd); BFD_ASSERT (abfd);
BFD_ASSERT (crc32_out); BFD_ASSERT (crc32_out);
sect = bfd_get_section_by_name (abfd, ".gnu_debuglink"); sect = bfd_get_section_by_name (abfd, GNU_DEBUGLINK);
if (sect == NULL) if (sect == NULL)
return NULL; return NULL;
debuglink_size = bfd_section_size (abfd, sect); debuglink_size = bfd_section_size (abfd, sect);
contents = xmalloc (debuglink_size); contents = malloc (debuglink_size);
if (contents == NULL)
return NULL;
ret = bfd_get_section_contents (abfd, sect, contents, ret = bfd_get_section_contents (abfd, sect, contents,
(file_ptr)0, debuglink_size); (file_ptr)0, debuglink_size);
if (! ret) if (! ret)
@ -877,7 +884,7 @@ separate_debug_file_exists (name, crc)
static char buffer [8 * 1024]; static char buffer [8 * 1024];
unsigned long file_crc = 0; unsigned long file_crc = 0;
int fd; int fd;
int count; bfd_size_type count;
BFD_ASSERT (name); BFD_ASSERT (name);
@ -886,7 +893,7 @@ separate_debug_file_exists (name, crc)
return FALSE; return FALSE;
while ((count = read (fd, buffer, sizeof (buffer))) > 0) while ((count = read (fd, buffer, sizeof (buffer))) > 0)
file_crc = calc_crc32 (file_crc, buffer, count); file_crc = bfd_calc_gnu_debuglink_crc32 (file_crc, buffer, count);
close (fd); close (fd);
@ -930,16 +937,21 @@ find_separate_debug_file (abfd, debug_file_directory)
return NULL; return NULL;
basename = get_debug_link_info (abfd, & crc32); basename = get_debug_link_info (abfd, & crc32);
if (basename == NULL) if (basename == NULL)
return NULL; return NULL;
if (strlen (basename) < 1) if (strlen (basename) < 1)
{ {
free (basename); free (basename);
return NULL; return NULL;
} }
dir = xstrdup (abfd->filename); dir = strdup (abfd->filename);
if (dir == NULL)
{
free (basename);
return NULL;
}
BFD_ASSERT (strlen (dir) != 0); BFD_ASSERT (strlen (dir) != 0);
/* Strip off filename part. */ /* Strip off filename part. */
@ -950,11 +962,17 @@ find_separate_debug_file (abfd, debug_file_directory)
dir[i + 1] = '\0'; dir[i + 1] = '\0';
BFD_ASSERT (dir[i] == '/' || dir[0] == '\0') BFD_ASSERT (dir[i] == '/' || dir[0] == '\0')
debugfile = xmalloc (strlen (debug_file_directory) + 1 debugfile = malloc (strlen (debug_file_directory) + 1
+ strlen (dir) + strlen (dir)
+ strlen (".debug/") + strlen (".debug/")
+ strlen (basename) + strlen (basename)
+ 1); + 1);
if (debugfile == NULL)
{
free (basename);
free (dir);
return NULL;
}
/* First try in the same directory as the original file: */ /* First try in the same directory as the original file: */
strcpy (debugfile, dir); strcpy (debugfile, dir);
@ -1037,3 +1055,114 @@ bfd_follow_gnu_debuglink (abfd, dir)
#endif #endif
return find_separate_debug_file (abfd, dir); return find_separate_debug_file (abfd, dir);
} }
/*
FUNCTION
bfd_add_gnu_debuglink
SYNOPSIS
bfd_boolean bfd_add_gnu_debuglink (bfd * abfd, const char * filename);
DESCRIPTION
Takes a @var{BFD} and adds a .gnu_debuglink section containing a link
to the specified @var{filename}. The filename should be relative to
the current directory.
RETURNS
<<TRUE>> is returned if all is ok. Otherwise <<FALSE>> is returned
and bfd_error is set.
*/
bfd_boolean
bfd_add_gnu_debuglink (abfd, filename)
bfd *abfd;
const char * filename;
{
asection * sect;
bfd_size_type debuglink_size;
unsigned long crc32;
char * contents;
bfd_size_type crc_offset;
FILE * handle;
static char buffer[8 * 1024];
size_t count;
if (abfd == NULL || filename == NULL)
{
bfd_set_error (bfd_error_invalid_operation);
return FALSE;
}
/* Make sure that we can read the file.
XXX - Should we attempt to locate the debug info file using the same
algorithm as gdb ? At the moment, since we are creating the
.gnu_debuglink section, we insist upon the user providing us with a
correct-for-section-creation-time path, but this need not conform to
the gdb location algorithm. */
handle = fopen (filename, FOPEN_RB);
if (handle == NULL)
{
bfd_set_error (bfd_error_system_call);
return FALSE;
}
crc32 = 0;
while ((count = fread (buffer, 1, sizeof buffer, handle)) > 0)
crc32 = bfd_calc_gnu_debuglink_crc32 (crc32, buffer, count);
fclose (handle);
/* Strip off any path components in filename,
now that we no longer need them. */
filename = lbasename (filename);
sect = bfd_get_section_by_name (abfd, GNU_DEBUGLINK);
if (sect)
{
/* Section already exists. */
bfd_set_error (bfd_error_invalid_operation);
return FALSE;
}
sect = bfd_make_section (abfd, GNU_DEBUGLINK);
if (sect == NULL)
return FALSE;
if (! bfd_set_section_flags (abfd, sect,
SEC_HAS_CONTENTS | SEC_DEBUGGING))
/* XXX Should we delete the section from the bfd ? */
return FALSE;
debuglink_size = strlen (filename) + 1;
debuglink_size += 3;
debuglink_size &= ~3;
debuglink_size += 4;
if (! bfd_set_section_size (abfd, sect, debuglink_size))
/* XXX Should we delete the section from the bfd ? */
return FALSE;
contents = malloc (debuglink_size);
if (contents == NULL)
{
/* XXX Should we delete the section from the bfd ? */
bfd_set_error (bfd_error_no_memory);
return FALSE;
}
strcpy (contents, filename);
crc_offset = debuglink_size - 4;
bfd_put_32 (abfd, crc32, (bfd_byte *) (contents + crc_offset));
if (! bfd_set_section_contents (abfd, sect, contents,
(file_ptr)0, debuglink_size))
{
/* XXX Should we delete the section from the bfd ? */
free (contents);
return FALSE;
}
return TRUE;
}

View File

@ -1,3 +1,21 @@
2003-06-11 Nick Clifton <nickc@redhat.com>
* objcopy.c (gnu_debuglink_filename): New variable.
(OPTION_ADD_GNU_DEBUGLINK): New switch
(copy_options): Describe --add-gnu-debuglink switch.
Mention that --strip-debug removes sections as well.
(is_strip_section): Process the sections removed and kept
lists before checking for debugging sections.
(add_redefine_syms_file): Make function static.
(copy_object): Use is_strip_section.
Check to see if a .gnu_debuglink section should be added. If
so, call bfd_add_gnu_debuglink.
(setup_section): Use is_strip_section.
(copy_section): Use is_strip_section.
(copy_main): Handle OPTION_ADD_GNU_DEBUGLINK.
* NEWS: Mention new objcopy switch.
* doc/binutils.texi: Document new switch.
2003-06-11 H.J. Lu <hongjiu.lu@intel.com> 2003-06-11 H.J. Lu <hongjiu.lu@intel.com>
* po/Make-in (DESTDIR): New. * po/Make-in (DESTDIR): New.

View File

@ -1,5 +1,9 @@
-*- text -*- -*- text -*-
* objcopy now accepts --add-gnu-debuglink=<file> to insert a .gnu_debuglink
section into a (presumably stripped) executable. This allows the debug
information for the file to be held in a seperate file.
* BFD marks the sections .comment and .note as 'n' in the BSD/POSIX * BFD marks the sections .comment and .note as 'n' in the BSD/POSIX
single-character representation. This can be checked by running nm single-character representation. This can be checked by running nm
with the -a switch. with the -a switch.

View File

@ -932,21 +932,26 @@ objcopy [@option{-F} @var{bfdname}|@option{--target=}@var{bfdname}]
[@option{-I} @var{bfdname}|@option{--input-target=}@var{bfdname}] [@option{-I} @var{bfdname}|@option{--input-target=}@var{bfdname}]
[@option{-O} @var{bfdname}|@option{--output-target=}@var{bfdname}] [@option{-O} @var{bfdname}|@option{--output-target=}@var{bfdname}]
[@option{-B} @var{bfdarch}|@option{--binary-architecture=}@var{bfdarch}] [@option{-B} @var{bfdarch}|@option{--binary-architecture=}@var{bfdarch}]
[@option{-S}|@option{--strip-all}] [@option{-g}|@option{--strip-debug}] [@option{-S}|@option{--strip-all}]
[@option{-g}|@option{--strip-debug}]
[@option{--add-gnu-debuglink=}@var{path-to-file}]
[@option{-K} @var{symbolname}|@option{--keep-symbol=}@var{symbolname}] [@option{-K} @var{symbolname}|@option{--keep-symbol=}@var{symbolname}]
[@option{-N} @var{symbolname}|@option{--strip-symbol=}@var{symbolname}] [@option{-N} @var{symbolname}|@option{--strip-symbol=}@var{symbolname}]
[@option{-G} @var{symbolname}|@option{--keep-global-symbol=}@var{symbolname}] [@option{-G} @var{symbolname}|@option{--keep-global-symbol=}@var{symbolname}]
[@option{-L} @var{symbolname}|@option{--localize-symbol=}@var{symbolname}] [@option{-L} @var{symbolname}|@option{--localize-symbol=}@var{symbolname}]
[@option{-W} @var{symbolname}|@option{--weaken-symbol=}@var{symbolname}] [@option{-W} @var{symbolname}|@option{--weaken-symbol=}@var{symbolname}]
[@option{-x}|@option{--discard-all}] [@option{-X}|@option{--discard-locals}] [@option{-x}|@option{--discard-all}]
[@option{-X}|@option{--discard-locals}]
[@option{-b} @var{byte}|@option{--byte=}@var{byte}] [@option{-b} @var{byte}|@option{--byte=}@var{byte}]
[@option{-i} @var{interleave}|@option{--interleave=}@var{interleave}] [@option{-i} @var{interleave}|@option{--interleave=}@var{interleave}]
[@option{-j} @var{sectionname}|@option{--only-section=}@var{sectionname}] [@option{-j} @var{sectionname}|@option{--only-section=}@var{sectionname}]
[@option{-R} @var{sectionname}|@option{--remove-section=}@var{sectionname}] [@option{-R} @var{sectionname}|@option{--remove-section=}@var{sectionname}]
[@option{-p}|@option{--preserve-dates}] [@option{-p}|@option{--preserve-dates}]
[@option{--debugging}] [@option{--debugging}]
[@option{--gap-fill=}@var{val}] [@option{--pad-to=}@var{address}] [@option{--gap-fill=}@var{val}]
[@option{--set-start=}@var{val}] [@option{--adjust-start=}@var{incr}] [@option{--pad-to=}@var{address}]
[@option{--set-start=}@var{val}]
[@option{--adjust-start=}@var{incr}]
[@option{--change-addresses=}@var{incr}] [@option{--change-addresses=}@var{incr}]
[@option{--change-section-address} @var{section}@{=,+,-@}@var{val}] [@option{--change-section-address} @var{section}@{=,+,-@}@var{val}]
[@option{--change-section-lma} @var{section}@{=,+,-@}@var{val}] [@option{--change-section-lma} @var{section}@{=,+,-@}@var{val}]
@ -955,10 +960,10 @@ objcopy [@option{-F} @var{bfdname}|@option{--target=}@var{bfdname}]
[@option{--set-section-flags} @var{section}=@var{flags}] [@option{--set-section-flags} @var{section}=@var{flags}]
[@option{--add-section} @var{sectionname}=@var{filename}] [@option{--add-section} @var{sectionname}=@var{filename}]
[@option{--rename-section} @var{oldname}=@var{newname}[,@var{flags}]] [@option{--rename-section} @var{oldname}=@var{newname}[,@var{flags}]]
[@option{--change-leading-char} ] [@option{--remove-leading-char}] [@option{--change-leading-char}] [@option{--remove-leading-char}]
[@option{--srec-len=}@var{ival} ] [@option{--srec-forceS3}] [@option{--srec-len=}@var{ival}] [@option{--srec-forceS3}]
[@option{--redefine-sym} @var{old}=@var{new} ] [@option{--redefine-sym} @var{old}=@var{new}]
[@option{--redefine-syms=}@var{filename} ] [@option{--redefine-syms=}@var{filename}]
[@option{--weaken}] [@option{--weaken}]
[@option{--keep-symbols=}@var{filename}] [@option{--keep-symbols=}@var{filename}]
[@option{--strip-symbols=}@var{filename}] [@option{--strip-symbols=}@var{filename}]
@ -1069,11 +1074,15 @@ Do not copy relocation and symbol information from the source file.
@item -g @item -g
@itemx --strip-debug @itemx --strip-debug
Do not copy debugging symbols from the source file. Do not copy debugging symbols or sections from the source file.
@item --strip-unneeded @item --strip-unneeded
Strip all symbols that are not needed for relocation processing. Strip all symbols that are not needed for relocation processing.
@item --add-gnu-debuglink=@var{path-to-file}
Creates a .gnu_debuglink section which contains a reference to @var{path-to-file}
and adds it to the output file.
@item -K @var{symbolname} @item -K @var{symbolname}
@itemx --keep-symbol=@var{symbolname} @itemx --keep-symbol=@var{symbolname}
Copy only symbol @var{symbolname} from the source file. This option may Copy only symbol @var{symbolname} from the source file. This option may
@ -2054,15 +2063,16 @@ and the Info entries for @file{binutils}.
@smallexample @smallexample
@c man begin SYNOPSIS strip @c man begin SYNOPSIS strip
strip [@option{-F} @var{bfdname} |@option{--target=}@var{bfdname} ] strip [@option{-F} @var{bfdname} |@option{--target=}@var{bfdname}]
[@option{-I} @var{bfdname} |@option{--input-target=}@var{bfdname} ] [@option{-I} @var{bfdname} |@option{--input-target=}@var{bfdname}]
[@option{-O} @var{bfdname} |@option{--output-target=}@var{bfdname} ] [@option{-O} @var{bfdname} |@option{--output-target=}@var{bfdname}]
[@option{-s}|@option{--strip-all}] [@option{-S}|@option{-g}|@option{-d}|@option{--strip-debug}] [@option{-s}|@option{--strip-all}]
[@option{-K} @var{symbolname} |@option{--keep-symbol=}@var{symbolname} ] [@option{-S}|@option{-g}|@option{-d}|@option{--strip-debug}]
[@option{-N} @var{symbolname} |@option{--strip-symbol=}@var{symbolname} ] [@option{-K} @var{symbolname} |@option{--keep-symbol=}@var{symbolname}]
[@option{-x}|@option{--discard-all} ] [@option{-X} |@option{--discard-locals}] [@option{-N} @var{symbolname} |@option{--strip-symbol=}@var{symbolname}]
[@option{-R} @var{sectionname} |@option{--remove-section=}@var{sectionname} ] [@option{-x}|@option{--discard-all}] [@option{-X} |@option{--discard-locals}]
[@option{-o} @var{file} ] [@option{-p}|@option{--preserve-dates}] [@option{-R} @var{sectionname} |@option{--remove-section=}@var{sectionname}]
[@option{-o} @var{file}] [@option{-p}|@option{--preserve-dates}]
[@option{-v} |@option{--verbose}] [@option{-V}|@option{--version}] [@option{-v} |@option{--verbose}] [@option{-V}|@option{--version}]
[@option{--help}] [@option{--info}] [@option{--help}] [@option{--info}]
@var{objfile}@dots{} @var{objfile}@dots{}

View File

@ -110,6 +110,8 @@ static const char * find_section_rename
PARAMS ((bfd *, sec_ptr, flagword *)); PARAMS ((bfd *, sec_ptr, flagword *));
static void add_section_rename static void add_section_rename
PARAMS ((const char *, const char *, flagword)); PARAMS ((const char *, const char *, flagword));
static void add_redefine_syms_file
PARAMS ((const char *));
#define RETURN_NONFATAL(s) {bfd_nonfatal (s); status = 1; return;} #define RETURN_NONFATAL(s) {bfd_nonfatal (s); status = 1; return;}
@ -217,6 +219,10 @@ struct section_add
/* List of sections to add to the output BFD. */ /* List of sections to add to the output BFD. */
static struct section_add *add_sections; static struct section_add *add_sections;
/* If non-NULL the argument to --add-gnu-debuglink.
This should be the filename to store in the .gnu_debuglink section. */
static const char * gnu_debuglink_filename = NULL;
/* Whether to convert debugging information. */ /* Whether to convert debugging information. */
static bfd_boolean convert_debugging = FALSE; static bfd_boolean convert_debugging = FALSE;
@ -277,6 +283,7 @@ static char *prefix_alloc_sections_string = 0;
#define OPTION_PREFIX_SECTIONS (OPTION_PREFIX_SYMBOLS + 1) #define OPTION_PREFIX_SECTIONS (OPTION_PREFIX_SYMBOLS + 1)
#define OPTION_PREFIX_ALLOC_SECTIONS (OPTION_PREFIX_SECTIONS + 1) #define OPTION_PREFIX_ALLOC_SECTIONS (OPTION_PREFIX_SECTIONS + 1)
#define OPTION_FORMATS_INFO (OPTION_PREFIX_ALLOC_SECTIONS + 1) #define OPTION_FORMATS_INFO (OPTION_PREFIX_ALLOC_SECTIONS + 1)
#define OPTION_ADD_GNU_DEBUGLINK (OPTION_FORMATS_INFO + 1)
/* Options to handle if running as "strip". */ /* Options to handle if running as "strip". */
@ -309,6 +316,7 @@ static struct option strip_options[] =
static struct option copy_options[] = static struct option copy_options[] =
{ {
{"add-gnu-debuglink", required_argument, 0, OPTION_ADD_GNU_DEBUGLINK},
{"add-section", required_argument, 0, OPTION_ADD_SECTION}, {"add-section", required_argument, 0, OPTION_ADD_SECTION},
{"adjust-start", required_argument, 0, OPTION_CHANGE_START}, {"adjust-start", required_argument, 0, OPTION_CHANGE_START},
{"adjust-vma", required_argument, 0, OPTION_CHANGE_ADDRESSES}, {"adjust-vma", required_argument, 0, OPTION_CHANGE_ADDRESSES},
@ -410,9 +418,10 @@ copy_usage (stream, exit_status)
--debugging Convert debugging information, if possible\n\ --debugging Convert debugging information, if possible\n\
-p --preserve-dates Copy modified/access timestamps to the output\n\ -p --preserve-dates Copy modified/access timestamps to the output\n\
-j --only-section <name> Only copy section <name> into the output\n\ -j --only-section <name> Only copy section <name> into the output\n\
--add-gnu-debuglink=<file> Add section .gnu_debuglink linking to <file>\n\
-R --remove-section <name> Remove section <name> from the output\n\ -R --remove-section <name> Remove section <name> from the output\n\
-S --strip-all Remove all symbol and relocation information\n\ -S --strip-all Remove all symbol and relocation information\n\
-g --strip-debug Remove all debugging symbols\n\ -g --strip-debug Remove all debugging symbols & sections\n\
--strip-unneeded Remove all symbols not needed by relocations\n\ --strip-unneeded Remove all symbols not needed by relocations\n\
-N --strip-symbol <name> Do not copy symbol <name>\n\ -N --strip-symbol <name> Do not copy symbol <name>\n\
-K --keep-symbol <name> Only copy symbol <name>\n\ -K --keep-symbol <name> Only copy symbol <name>\n\
@ -487,7 +496,7 @@ strip_usage (stream, exit_status)
-p --preserve-dates Copy modified/access timestamps to the output\n\ -p --preserve-dates Copy modified/access timestamps to the output\n\
-R --remove-section=<name> Remove section <name> from the output\n\ -R --remove-section=<name> Remove section <name> from the output\n\
-s --strip-all Remove all symbol and relocation information\n\ -s --strip-all Remove all symbol and relocation information\n\
-g -S -d --strip-debug Remove all debugging symbols\n\ -g -S -d --strip-debug Remove all debugging symbols & sections\n\
--strip-unneeded Remove all symbols not needed by relocations\n\ --strip-unneeded Remove all symbols not needed by relocations\n\
-N --strip-symbol=<name> Do not copy symbol <name>\n\ -N --strip-symbol=<name> Do not copy symbol <name>\n\
-K --keep-symbol=<name> Only copy symbol <name>\n\ -K --keep-symbol=<name> Only copy symbol <name>\n\
@ -752,24 +761,28 @@ is_strip_section (abfd, sec)
bfd *abfd ATTRIBUTE_UNUSED; bfd *abfd ATTRIBUTE_UNUSED;
asection *sec; asection *sec;
{ {
struct section_list *p; if (sections_removed || sections_copied)
{
struct section_list *p;
if ((bfd_get_section_flags (abfd, sec) & SEC_DEBUGGING) != 0 p = find_section_list (bfd_get_section_name (abfd, sec), FALSE);
&& (strip_symbols == STRIP_DEBUG
if (sections_removed && p != NULL && p->remove)
return TRUE;
if (sections_copied && (p == NULL || ! p->copy))
return TRUE;
}
if ((bfd_get_section_flags (abfd, sec) & SEC_DEBUGGING) != 0)
{
if (strip_symbols == STRIP_DEBUG
|| strip_symbols == STRIP_UNNEEDED || strip_symbols == STRIP_UNNEEDED
|| strip_symbols == STRIP_ALL || strip_symbols == STRIP_ALL
|| discard_locals == LOCALS_ALL || discard_locals == LOCALS_ALL
|| convert_debugging)) || convert_debugging)
return TRUE; return TRUE;
}
if (! sections_removed && ! sections_copied)
return FALSE;
p = find_section_list (bfd_get_section_name (abfd, sec), FALSE);
if (sections_removed && p != NULL && p->remove)
return TRUE;
if (sections_copied && (p == NULL || ! p->copy))
return TRUE;
return FALSE; return FALSE;
} }
@ -976,7 +989,7 @@ redefine_list_append (cause, source, target)
/* Handle the --redefine-syms option. Read lines containing "old new" /* Handle the --redefine-syms option. Read lines containing "old new"
from the file, and add them to the symbol redefine list. */ from the file, and add them to the symbol redefine list. */
void static void
add_redefine_syms_file (filename) add_redefine_syms_file (filename)
const char *filename; const char *filename;
{ {
@ -1182,6 +1195,8 @@ copy_object (ibfd, obfd)
for (padd = add_sections; padd != NULL; padd = padd->next) for (padd = add_sections; padd != NULL; padd = padd->next)
{ {
flagword flags;
padd->section = bfd_make_section (obfd, padd->name); padd->section = bfd_make_section (obfd, padd->name);
if (padd->section == NULL) if (padd->section == NULL)
{ {
@ -1190,45 +1205,47 @@ copy_object (ibfd, obfd)
status = 1; status = 1;
return; return;
} }
if (! bfd_set_section_size (obfd, padd->section, padd->size))
RETURN_NONFATAL (bfd_get_filename (obfd));
pset = find_section_list (padd->name, FALSE);
if (pset != NULL)
pset->used = TRUE;
if (pset != NULL && pset->set_flags)
flags = pset->flags | SEC_HAS_CONTENTS;
else else
flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DATA;
if (! bfd_set_section_flags (obfd, padd->section, flags))
RETURN_NONFATAL (bfd_get_filename (obfd));
if (pset != NULL)
{ {
flagword flags; if (pset->change_vma != CHANGE_IGNORE)
if (! bfd_set_section_vma (obfd, padd->section, pset->vma_val))
RETURN_NONFATAL (bfd_get_filename (obfd));
if (! bfd_set_section_size (obfd, padd->section, padd->size)) if (pset->change_lma != CHANGE_IGNORE)
RETURN_NONFATAL (bfd_get_filename (obfd));
pset = find_section_list (padd->name, FALSE);
if (pset != NULL)
pset->used = TRUE;
if (pset != NULL && pset->set_flags)
flags = pset->flags | SEC_HAS_CONTENTS;
else
flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DATA;
if (! bfd_set_section_flags (obfd, padd->section, flags))
RETURN_NONFATAL (bfd_get_filename (obfd));
if (pset != NULL)
{ {
if (pset->change_vma != CHANGE_IGNORE) padd->section->lma = pset->lma_val;
if (! bfd_set_section_vma (obfd, padd->section, pset->vma_val))
RETURN_NONFATAL (bfd_get_filename (obfd)); if (! bfd_set_section_alignment
(obfd, padd->section,
if (pset->change_lma != CHANGE_IGNORE) bfd_section_alignment (obfd, padd->section)))
{ RETURN_NONFATAL (bfd_get_filename (obfd));
padd->section->lma = pset->lma_val;
if (! bfd_set_section_alignment
(obfd, padd->section,
bfd_section_alignment (obfd, padd->section)))
RETURN_NONFATAL (bfd_get_filename (obfd));
}
} }
} }
} }
} }
if (gnu_debuglink_filename != NULL)
{
if (! bfd_add_gnu_debuglink (obfd, gnu_debuglink_filename))
RETURN_NONFATAL (gnu_debuglink_filename);
}
if (gap_fill_set || pad_to_set) if (gap_fill_set || pad_to_set)
{ {
asection **set; asection **set;
@ -1761,23 +1778,13 @@ setup_section (ibfd, isection, obfdarg)
const char * name; const char * name;
char *prefix = NULL; char *prefix = NULL;
if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0 if (is_strip_section (ibfd, isection))
&& (strip_symbols == STRIP_DEBUG
|| strip_symbols == STRIP_UNNEEDED
|| strip_symbols == STRIP_ALL
|| discard_locals == LOCALS_ALL
|| convert_debugging))
return; return;
p = find_section_list (bfd_section_name (ibfd, isection), FALSE); p = find_section_list (bfd_section_name (ibfd, isection), FALSE);
if (p != NULL) if (p != NULL)
p->used = TRUE; p->used = TRUE;
if (sections_removed && p != NULL && p->remove)
return;
if (sections_copied && (p == NULL || ! p->copy))
return;
/* Get the, possibly new, name of the output section. */ /* Get the, possibly new, name of the output section. */
name = find_section_rename (ibfd, isection, & flags); name = find_section_rename (ibfd, isection, & flags);
@ -1913,31 +1920,21 @@ copy_section (ibfd, isection, obfdarg)
if (status != 0) if (status != 0)
return; return;
if (is_strip_section (ibfd, isection))
return;
flags = bfd_get_section_flags (ibfd, isection); flags = bfd_get_section_flags (ibfd, isection);
if ((flags & SEC_DEBUGGING) != 0
&& (strip_symbols == STRIP_DEBUG
|| strip_symbols == STRIP_UNNEEDED
|| strip_symbols == STRIP_ALL
|| discard_locals == LOCALS_ALL
|| convert_debugging))
return;
if ((flags & SEC_GROUP) != 0) if ((flags & SEC_GROUP) != 0)
return; return;
p = find_section_list (bfd_section_name (ibfd, isection), FALSE);
if (sections_removed && p != NULL && p->remove)
return;
if (sections_copied && (p == NULL || ! p->copy))
return;
osection = isection->output_section; osection = isection->output_section;
size = bfd_get_section_size_before_reloc (isection); size = bfd_get_section_size_before_reloc (isection);
if (size == 0 || osection == 0) if (size == 0 || osection == 0)
return; return;
p = find_section_list (bfd_get_section_name (ibfd, isection), FALSE);
/* Core files do not need to be relocated. */ /* Core files do not need to be relocated. */
if (bfd_get_format (obfd) == bfd_core) if (bfd_get_format (obfd) == bfd_core)
relsize = 0; relsize = 0;
@ -2418,6 +2415,10 @@ copy_main (argc, argv)
strip_symbols = STRIP_UNNEEDED; strip_symbols = STRIP_UNNEEDED;
break; break;
case OPTION_ADD_GNU_DEBUGLINK:
gnu_debuglink_filename = optarg;
break;
case 'K': case 'K':
add_specific_symbol (optarg, &keep_specific_list); add_specific_symbol (optarg, &keep_specific_list);
break; break;
@ -2789,7 +2790,8 @@ copy_main (argc, argv)
break; break;
case 0: case 0:
break; /* we've been given a long option */ /* We've been given a long option. */
break;
case 'H': case 'H':
case 'h': case 'h':