From 87a15686e48b2d4ea9a43d63d161cf639f4c55de Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Thu, 17 Nov 1994 20:12:51 +0000 Subject: [PATCH] * objcopy.c (main): Fix is_strip test. From pirker@eiunix.tuwien.ac.at (Martin Pirker). --- binutils/ChangeLog | 9 +++ binutils/objcopy.c | 186 ++++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 142 insertions(+), 53 deletions(-) diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 2ac4af6..0ab1fa2 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,5 +1,14 @@ +Thu Nov 17 15:00:13 1994 Ian Lance Taylor + + * objcopy.c (main): Fix is_strip test. From + pirker@eiunix.tuwien.ac.at (Martin Pirker). + Tue Nov 8 13:12:54 1994 Ian Lance Taylor + * objdump.c (display_target_list, display_info_table): Pass an + array to tmparg, rather than NULL, since some systems can't handle + NULL. + * objcopy.c (copy_archive): Keep a list of the names of the temporary files we created. Close each input BFD after we open its successor. diff --git a/binutils/objcopy.c b/binutils/objcopy.c index 3308b51..e752f4b 100644 --- a/binutils/objcopy.c +++ b/binutils/objcopy.c @@ -95,7 +95,11 @@ static struct section_list *adjust_sections; /* Filling gaps between sections. */ static boolean gap_fill_set = false; -static bfd_byte gap_fill; +static bfd_byte gap_fill = 0; + +/* Pad to a given address. */ +static boolean pad_to_set = false; +static bfd_vma pad_to; /* Options to handle if running as "strip". */ @@ -128,7 +132,8 @@ static struct option strip_options[] = #define OPTION_ADJUST_WARNINGS (OPTION_ADJUST_SECTION_VMA + 1) #define OPTION_GAP_FILL (OPTION_ADJUST_WARNINGS + 1) #define OPTION_NO_ADJUST_WARNINGS (OPTION_GAP_FILL + 1) -#define OPTION_SET_START (OPTION_NO_ADJUST_WARNINGS + 1) +#define OPTION_PAD_TO (OPTION_NO_ADJUST_WARNINGS + 1) +#define OPTION_SET_START (OPTION_PAD_TO + 1) static struct option copy_options[] = { @@ -148,6 +153,7 @@ static struct option copy_options[] = {"no-adjust-warnings", no_argument, 0, OPTION_NO_ADJUST_WARNINGS}, {"output-format", required_argument, 0, 'O'}, /* Obsolete */ {"output-target", required_argument, 0, 'O'}, + {"pad-to", required_argument, 0, OPTION_PAD_TO}, {"remove-section", required_argument, 0, 'R'}, {"set-start", required_argument, 0, OPTION_SET_START}, {"strip-all", no_argument, 0, 'S'}, @@ -178,8 +184,8 @@ Usage: %s [-vVSgxX] [-I bfdname] [-O bfdname] [-F bfdname] [-b byte]\n\ [-R section] [-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\ - [--remove-section=section] [--gap-fill=val] [--set-start=val]\n\ - [--adjust-start=incr] [--adjust-vma=incr]\n\ + [--remove-section=section] [--gap-fill=val] [--pad-to=address]\n\ + [--set-start=val] [--adjust-start=incr] [--adjust-vma=incr]\n\ [--adjust-section-vma=section{=,+,-}val] [--adjust-warnings]\n\ [--no-adjust-warnings] [--verbose] [--version] [--help]\n\ in-file [out-file]\n", @@ -361,14 +367,16 @@ copy_object (ibfd, obfd) any output is done. Thus, we traverse all sections multiple times. */ bfd_map_over_sections (ibfd, setup_section, (void *) obfd); - if (gap_fill_set) + if (gap_fill_set || pad_to_set) { asection **set; unsigned int c, i; - /* We must fill in gaps between the sections. We do this by + /* We must fill in gaps between the sections and/or we must pad + the last section to a specified address. We do this by grabbing a list of the sections, sorting them by VMA, and - adding new sections to occupy any gaps. */ + increasing the section sizes as required to fill the gaps. + We write out the gap contents below. */ c = bfd_count_sections (obfd); osections = (asection **) xmalloc (c * sizeof (asection *)); @@ -378,39 +386,69 @@ copy_object (ibfd, obfd) qsort (osections, c, sizeof (asection *), compare_section_vma); gaps = (bfd_size_type *) xmalloc (c * sizeof (bfd_size_type)); - for (i = 0; i < c - 1; i++) + memset (gaps, 0, c * sizeof (bfd_size_type)); + + if (gap_fill_set) + { + for (i = 0; i < c - 1; i++) + { + flagword flags; + bfd_size_type size; + bfd_vma gap_start, gap_stop; + + flags = bfd_get_section_flags (obfd, osections[i]); + if ((flags & SEC_HAS_CONTENTS) == 0 + || (flags & SEC_LOAD) == 0) + continue; + + size = bfd_section_size (obfd, osections[i]); + gap_start = bfd_section_vma (obfd, osections[i]) + size; + gap_stop = bfd_section_vma (obfd, osections[i + 1]); + if (gap_start < gap_stop) + { + if (! bfd_set_section_size (obfd, osections[i], + size + (gap_stop - gap_start))) + { + fprintf (stderr, "%s: Can't fill gap after %s: %s\n", + program_name, + bfd_get_section_name (obfd, osections[i]), + bfd_errmsg (bfd_get_error())); + status = 1; + break; + } + gaps[i] = gap_stop - gap_start; + if (max_gap < gap_stop - gap_start) + max_gap = gap_stop - gap_start; + } + } + } + + if (pad_to_set) { - flagword flags; + bfd_vma vma; bfd_size_type size; - bfd_vma gap_start, gap_stop; - - flags = bfd_get_section_flags (obfd, osections[i]); - if ((flags & SEC_HAS_CONTENTS) == 0 - || (flags & SEC_LOAD) == 0) - continue; - - size = bfd_section_size (obfd, osections[i]); - gap_start = bfd_section_vma (obfd, osections[i]) + size; - gap_stop = bfd_section_vma (obfd, osections[i + 1]); - if (gap_start >= gap_stop) - gaps[i] = 0; - else + + vma = bfd_section_vma (obfd, osections[c - 1]); + size = bfd_section_size (obfd, osections[c - 1]); + if (vma + size < pad_to) { - if (! bfd_set_section_size (obfd, osections[i], - size + (gap_stop - gap_start))) + if (! bfd_set_section_size (obfd, osections[c - 1], + pad_to - vma)) { - fprintf (stderr, "%s: Can't fill gap after %s: %s\n", + fprintf (stderr, "%s: Can't add padding to %s: %s\n", program_name, - bfd_get_section_name (obfd, osections[i]), - bfd_errmsg (bfd_get_error())); + bfd_get_section_name (obfd, osections[c - 1]), + bfd_errmsg (bfd_get_error ())); status = 1; - break; } - gaps[i] = gap_stop - gap_start; - if (max_gap < gap_stop - gap_start) - max_gap = gap_stop - gap_start; + else + { + gaps[c - 1] = pad_to - (vma + size); + if (max_gap < pad_to - (vma + size)) + max_gap = pad_to - (vma + size); + } } - } + } } /* Symbol filtering must happen after the output sections have @@ -460,7 +498,7 @@ copy_object (ibfd, obfd) /* This has to happen after the symbol table has been set. */ bfd_map_over_sections (ibfd, copy_section, (void *) obfd); - if (gap_fill_set) + if (gap_fill_set || pad_to_set) { bfd_byte *buf; int c, i; @@ -473,7 +511,7 @@ copy_object (ibfd, obfd) memset (buf, gap_fill, max_gap); c = bfd_count_sections (obfd); - for (i = 0; i < c - 1; i++) + for (i = 0; i < c; i++) { if (gaps[i] != 0) { @@ -541,6 +579,11 @@ copy_archive (ibfd, obfd, output_target) bfd *obfd; char *output_target; { + struct name_list + { + struct name_list *next; + char *name; + } *list, *l; bfd **ptr = &obfd->archive_head; bfd *this_element; char *dir = make_tempname (bfd_get_filename (obfd)); @@ -549,13 +592,20 @@ copy_archive (ibfd, obfd, output_target) mkdir (dir, 0700); obfd->has_armap = ibfd->has_armap; + list = NULL; + 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, "/", bfd_get_filename(this_element)); bfd *output_bfd = bfd_openw (output_name, output_target); + bfd *last_element; + + l = (struct name_list *) xmalloc (sizeof (struct name_list)); + l->name = output_name; + l->next = list; + list = l; if (output_bfd == (bfd *) NULL) { @@ -572,14 +622,18 @@ copy_archive (ibfd, obfd, output_target) } bfd_close (output_bfd); - /* Open the newly output file and attatch to our list. */ + + /* Open the newly output file and attach 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; + + last_element = this_element; + + this_element = bfd_openr_next_archived_file (ibfd, last_element); + + bfd_close (last_element); } *ptr = (bfd *) NULL; @@ -588,16 +642,11 @@ copy_archive (ibfd, obfd, output_target) nonfatal (bfd_get_filename (obfd)); } - /* Delete all the files that we opened. - Construct their names again, unfortunately, but - we're about to exit anyway. */ - for (this_element = ibfd->archive_head; - this_element != (bfd *) NULL; - this_element = this_element->next) - { - unlink (cat (dir, "/", bfd_get_filename (this_element))); - } + /* Delete all the files that we opened. */ + for (l = list; l != NULL; l = l->next) + unlink (l->name); rmdir (dir); + if (!bfd_close (ibfd)) { nonfatal (bfd_get_filename (ibfd)); @@ -878,7 +927,8 @@ copy_section (ibfd, isection, obfdarg) } } -/* Get all the sections. This is used when --gap-fill is used. */ +/* Get all the sections. This is used when --gap-fill or --pad-to is + used. */ static void get_sections (obfd, osection, secppparg) @@ -893,7 +943,8 @@ get_sections (obfd, osection, secppparg) } /* Sort sections by VMA. This is called via qsort, and is used when - --gap-fill is used. */ + --gap-fill or --pad-to is used. We force non loadable or empty + sections to the front, where they are easier to ignore. */ static int compare_section_vma (arg1, arg2) @@ -902,13 +953,38 @@ compare_section_vma (arg1, arg2) { const asection **sec1 = (const asection **) arg1; const asection **sec2 = (const asection **) arg2; + flagword flags1, flags2; + + /* Sort non loadable sections to the front. */ + flags1 = (*sec1)->flags; + flags2 = (*sec2)->flags; + if ((flags1 & SEC_HAS_CONTENTS) == 0 + || (flags1 & SEC_LOAD) == 0) + { + if ((flags2 & SEC_HAS_CONTENTS) != 0 + && (flags2 & SEC_LOAD) != 0) + return -1; + } + else + { + if ((flags2 & SEC_HAS_CONTENTS) == 0 + || (flags2 & SEC_LOAD) == 0) + return 1; + } + /* Sort sections by VMA. */ if ((*sec1)->vma > (*sec2)->vma) return 1; else if ((*sec1)->vma < (*sec2)->vma) return -1; - else - return 0; + + /* Sort sections with the same VMA by size. */ + if ((*sec1)->_raw_size > (*sec2)->_raw_size) + return 1; + else if ((*sec1)->_raw_size < (*sec2)->_raw_size) + return -1; + + return 0; } /* Mark all the symbols which will be used in output relocations with @@ -1280,6 +1356,10 @@ copy_main (argc, argv) case OPTION_NO_ADJUST_WARNINGS: adjust_warn = false; break; + case OPTION_PAD_TO: + pad_to = parse_vma (optarg, "--pad-to"); + pad_to_set = true; + break; case OPTION_SET_START: set_start = parse_vma (optarg, "--set-start"); set_start_set = true; @@ -1373,7 +1453,7 @@ main (argc, argv) if (is_strip < 0) { int i = strlen (program_name); - is_strip = (i >= 5 && strcmp (program_name + i - 5, "strip")); + is_strip = (i >= 5 && strcmp (program_name + i - 5, "strip") == 0); } if (is_strip) -- 2.7.4