OSDN Git Service

Merge branch 'master' of git://github.com/monaka/binutils master
authorMasaki Muranaka <monaka@monami-software.com>
Fri, 8 Jan 2010 03:48:45 +0000 (12:48 +0900)
committerMasaki Muranaka <monaka@monami-software.com>
Fri, 8 Jan 2010 03:48:45 +0000 (12:48 +0900)
37 files changed:
bfd/ChangeLog
bfd/elflink.c
gdb/ChangeLog
gdb/symfile.c
gold/ChangeLog
gold/errors.cc
gold/gc.h
gold/gold.h
gold/layout.cc
gold/object.cc
gold/options.h
gold/testsuite/Makefile.am
gold/testsuite/Makefile.in
gold/testsuite/gc_orphan_section_test.cc [new file with mode: 0644]
gold/testsuite/gc_orphan_section_test.sh [new file with mode: 0755]
ld/testsuite/ChangeLog
ld/testsuite/ld-gc/abi-note.d [new file with mode: 0644]
ld/testsuite/ld-gc/abi-note.s [new file with mode: 0644]
ld/testsuite/ld-gc/gc.exp
opcodes/ChangeLog
opcodes/cgen-ibld.in
opcodes/fr30-ibld.c
opcodes/frv-ibld.c
opcodes/ip2k-ibld.c
opcodes/iq2000-ibld.c
opcodes/lm32-ibld.c
opcodes/m32c-ibld.c
opcodes/m32r-ibld.c
opcodes/mep-ibld.c
opcodes/mt-ibld.c
opcodes/openrisc-ibld.c
opcodes/xc16x-ibld.c
opcodes/xstormy16-ibld.c
winsup/doc/ChangeLog
winsup/doc/overview.sgml
winsup/utils/ChangeLog
winsup/utils/cygpath.cc

index 4d0db31..01950b4 100644 (file)
@@ -1,3 +1,8 @@
+2010-01-07  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR ld/11143
+       * elflink.c (elf_gc_sweep): Keep SHT_NOTE section.
+
 2010-01-04  Daniel Gutson  <dgutson@codesourcery.com>
 
        * bfd.m4 (BFD_HAVE_SYS_PROCFS_TYPE): Define _STRUCTURE_PROC
index bbdfe5e..284bff1 100644 (file)
@@ -1,6 +1,6 @@
 /* ELF linking support for BFD.
    Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-   2005, 2006, 2007, 2008, 2009
+   2005, 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -11527,9 +11527,10 @@ elf_gc_sweep (bfd *abfd, struct bfd_link_info *info)
              o->gc_mark = first->gc_mark;
            }
          else if ((o->flags & (SEC_DEBUGGING | SEC_LINKER_CREATED)) != 0
-                  || (o->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0)
+                  || (o->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0
+                  || elf_section_data (o)->this_hdr.sh_type == SHT_NOTE)
            {
-             /* Keep debug and special sections.  */
+             /* Keep debug, special and SHT_NOTE sections.  */
              o->gc_mark = 1;
            }
 
index b1dbb37..66d2b08 100644 (file)
@@ -1,3 +1,9 @@
+2010-01-07  Tristan Gingold  <gingold@adacore.com>
+
+       * symfile.c (build_section_addr_info_from_objfile): New function.
+       (symbol_file_add_separate): Don't use offsets from objfile but
+       built an addr info.
+
 2010-01-06  Stan Shebs  <stan@codesourcery.com>
 
        Support disconnected tracing.
index 91b7870..cee84db 100644 (file)
@@ -384,6 +384,29 @@ build_section_addr_info_from_section_table (const struct target_section *start,
   return sap;
 }
 
+/* Create a section_addr_info from section offsets in OBJFILE.  */
+
+static struct section_addr_info *
+build_section_addr_info_from_objfile (const struct objfile *objfile)
+{
+  struct section_addr_info *sap;
+  int i;
+  struct bfd_section *sec;
+
+  sap = alloc_section_addr_info (objfile->num_sections);
+  for (i = 0, sec = objfile->obfd->sections;
+       i < objfile->num_sections;
+       i++, sec = sec->next)
+    {
+      gdb_assert (sec != NULL);
+      sap->other[i].addr = (bfd_get_section_vma (objfile->obfd, sec)
+                            + objfile->section_offsets->offsets[i]);
+      sap->other[i].name = xstrdup (bfd_get_section_name (objfile->obfd, sec));
+      sap->other[i].sectindex = sec->index;
+    }
+  return sap;
+}
+
 
 /* Free all memory allocated by build_section_addr_info_from_section_table. */
 
@@ -1043,14 +1066,23 @@ void
 symbol_file_add_separate (bfd *bfd, int symfile_flags, struct objfile *objfile)
 {
   struct objfile *new_objfile;
+  struct section_addr_info *sap;
+  struct cleanup *my_cleanup;
+
+  /* Create section_addr_info.  We can't directly use offsets from OBJFILE
+     because sections of BFD may not match sections of OBJFILE and because
+     vma may have been modified by tools such as prelink.  */
+  sap = build_section_addr_info_from_objfile (objfile);
+  my_cleanup = make_cleanup_free_section_addr_info (sap);
 
   new_objfile = symbol_file_add_with_addrs_or_offsets
     (bfd, symfile_flags,
-     0, /* No addr table.  */
-     objfile->section_offsets, objfile->num_sections,
+     sap, NULL, 0,
      objfile->flags & (OBJF_REORDERED | OBJF_SHARED | OBJF_READNOW
                       | OBJF_USERLOADED));
 
+  do_cleanups (my_cleanup);
+
   add_separate_debug_objfile (new_objfile, objfile);
 }
 
index b52505f..ce620ce 100644 (file)
@@ -1,3 +1,34 @@
+2010-01-07  Ian Lance Taylor  <iant@google.com>
+
+       PR 10980
+       * options.h (class General_options): Add --warn-unresolved-symbols
+       and --error-unresolved-symbols.
+       * errors.cc (Errors::undefined_symbol): Implement
+       --warn-unresolved-symbols.
+
+       * options.h (class General_options): Add -z text and -z textoff.
+       * layout.cc (Layout::finish_dynamic_section): Implement -z text.
+
+2010-01-06  Sriraman Tallam  <tmsriram@google.com>
+
+       * gc.h (Garbage_collection::Cident_section_map): New typedef.
+       (Garbage_collection::cident_sections): New function.
+       (Garbage_collection::add_cident_section): New function.
+       (Garbage_collection::cident_sections_): New member.
+       (gc_process_relocs): Add references to sections whose names are C
+       identifiers.
+       * gold.h (cident_section_start_prefix): New constant.
+       (cident_section_stop_prefix): New constant.
+       (is_cident): New function.
+       * layout.cc (Layout::define_section_symbols): Replace string constants
+       with the newly defined constants.
+       * object.cc (Sized_relobj::do_layout): Track sections whose names are
+       C identifiers.
+       * testsuite/Makefile.am: Add gc_orphan_section_test.
+       * testsuite/Makefile.in: Regenerate.
+       * testsuite/gc_orphan_section_test.cc: New file.
+       * testsuite/gc_orphan_section_test.sh: New file.
+
 2010-01-06  Ian Lance Taylor  <iant@google.com>
 
        PR 10980
index 618f9cd..b8031b1 100644 (file)
@@ -1,6 +1,6 @@
 // errors.cc -- handle errors for gold
 
-// Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
 // Written by Ian Lance Taylor <iant@google.com>.
 
 // This file is part of gold.
@@ -156,21 +156,33 @@ Errors::undefined_symbol(const Symbol* sym, const std::string& location)
 {
   bool initialized = this->initialize_lock();
   gold_assert(initialized);
+
+  const char* zmsg;
   {
     Hold_lock h(*this->lock_);
     if (++this->undefined_symbols_[sym] >= max_undefined_error_report)
       return;
-    ++this->error_count_;
+    if (parameters->options().warn_unresolved_symbols())
+      {
+       ++this->warning_count_;
+       zmsg = _("warning");
+      }
+    else
+      {
+       ++this->error_count_;
+       zmsg = _("error");
+      }
   }
+
   const char* const version = sym->version();
   if (version == NULL)
-    fprintf(stderr, _("%s: %s: error: undefined reference to '%s'\n"),
-           this->program_name_, location.c_str(),
+    fprintf(stderr, _("%s: %s: %s: undefined reference to '%s'\n"),
+           this->program_name_, location.c_str(), zmsg,
            sym->demangled_name().c_str());
   else
     fprintf(stderr,
-            _("%s: %s: error: undefined reference to '%s', version '%s'\n"),
-           this->program_name_, location.c_str(),
+            _("%s: %s: %s: undefined reference to '%s', version '%s'\n"),
+           this->program_name_, location.c_str(), zmsg,
            sym->demangled_name().c_str(), version);
 }
 
index f61a2f6..838b7db 100644 (file)
--- a/gold/gc.h
+++ b/gold/gc.h
@@ -60,6 +60,10 @@ class Garbage_collection
   typedef Unordered_set<Section_id, Section_id_hash> Sections_reachable;
   typedef std::map<Section_id, Sections_reachable> Section_ref;
   typedef std::queue<Section_id> Worklist_type;
+  // This maps the name of the section which can be represented as a C
+  // identifier (cident) to the list of sections that have that name.
+  // Different object files can have cident sections with the same name.
+  typedef std::map<std::string, Sections_reachable> Cident_section_map;
 
   Garbage_collection()
   : is_worklist_ready_(false)
@@ -94,12 +98,23 @@ class Garbage_collection
   is_section_garbage(Object* obj, unsigned int shndx)
   { return (this->referenced_list().find(Section_id(obj, shndx))
             == this->referenced_list().end()); }
+
+  Cident_section_map*
+  cident_sections()
+  { return &cident_sections_; }
+
+  void
+  add_cident_section(std::string section_name,
+                    Section_id secn)
+  { this->cident_sections_[section_name].insert(secn); }
+
  private:
 
   Worklist_type work_list_;
   bool is_worklist_ready_;
   Section_ref section_reloc_map_;
   Sections_reachable referenced_list_;
+  Cident_section_map cident_sections_;
 };
 
 // Data to pass between successive invocations of do_layout
@@ -161,6 +176,7 @@ gc_process_relocs(
   std::vector<Symbol*>* symvec = NULL;
   std::vector<std::pair<long long, long long> >* addendvec = NULL;
   bool is_icf_tracked = false;
+  const char* cident_section_name = NULL;
 
   if (parameters->options().icf_enabled()
       && is_section_foldable_candidate(src_obj->section_name(src_indx).c_str()))
@@ -218,6 +234,19 @@ gc_process_relocs(
           if (!is_ordinary)
             continue;
           Section_id dst_id(dst_obj, dst_indx);
+          // If the symbol name matches '__start_XXX' then the section with
+          // the C identifier like name 'XXX' should not be garbage collected.
+          // A similar treatment to symbols with the name '__stop_XXX'.
+          if (is_prefix_of(cident_section_start_prefix, gsym->name()))
+            {
+              cident_section_name = (gsym->name() 
+                                     + strlen(cident_section_start_prefix));
+            }
+          else if (is_prefix_of(cident_section_stop_prefix, gsym->name()))
+            {
+              cident_section_name = (gsym->name() 
+                                     + strlen(cident_section_stop_prefix));
+            }
           if (is_icf_tracked)
             {
               (*secvec).push_back(dst_id);
@@ -245,6 +274,23 @@ gc_process_relocs(
               Garbage_collection::Sections_reachable& v(map_it->second);
               v.insert(dst_id);
             }
+          if (cident_section_name != NULL)
+            {
+              Garbage_collection::Cident_section_map::iterator ele =
+                symtab->gc()->cident_sections()->find(std::string(cident_section_name));
+              if (ele == symtab->gc()->cident_sections()->end())
+                continue;
+              Garbage_collection::Sections_reachable&
+                v(symtab->gc()->section_reloc_map()[src_id]);
+              Garbage_collection::Sections_reachable& cident_secn(ele->second);
+              for (Garbage_collection::Sections_reachable::iterator it_v
+                     = cident_secn.begin();
+                   it_v != cident_secn.end();
+                   ++it_v)
+                {
+                  v.insert(*it_v);
+                }
+            }
         }
     }
   return;
index dc5a1c1..5c98de0 100644 (file)
@@ -1,6 +1,6 @@
 // gold.h -- general definitions for gold   -*- C++ -*-
 
-// Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
 // Written by Ian Lance Taylor <iant@google.com>.
 
 // This file is part of gold.
@@ -349,6 +349,21 @@ is_prefix_of(const char* prefix, const char* str)
   return strncmp(prefix, str, strlen(prefix)) == 0;
 }
 
+const char* const cident_section_start_prefix = "__start_";
+const char* const cident_section_stop_prefix = "__stop_";
+
+// Returns true if the name is a valid C identifier
+inline bool
+is_cident(const char* name)
+{
+  return (name[strspn(name,
+                     ("0123456789"
+                      "ABCDEFGHIJKLMNOPWRSTUVWXYZ"
+                      "abcdefghijklmnopqrstuvwxyz"
+                      "_"))]
+         == '\0');
+}
+
 // We sometimes need to hash strings.  Ideally we should use std::tr1::hash or
 // __gnu_cxx::hash on some systems but there is no guarantee that either
 // one is available.  For portability, we define simple string hash functions.
index f3deb9a..9f51e82 100644 (file)
@@ -1,6 +1,6 @@
 // layout.cc -- lay out output file sections for gold
 
-// Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
 // Written by Ian Lance Taylor <iant@google.com>.
 
 // This file is part of gold.
@@ -1232,16 +1232,13 @@ Layout::define_section_symbols(Symbol_table* symtab)
        ++p)
     {
       const char* const name = (*p)->name();
-      if (name[strspn(name,
-                     ("0123456789"
-                      "ABCDEFGHIJKLMNOPWRSTUVWXYZ"
-                      "abcdefghijklmnopqrstuvwxyz"
-                      "_"))]
-         == '\0')
+      if (is_cident(name))
        {
          const std::string name_string(name);
-         const std::string start_name("__start_" + name_string);
-         const std::string stop_name("__stop_" + name_string);
+         const std::string start_name(cident_section_start_prefix
+                                       + name_string);
+         const std::string stop_name(cident_section_stop_prefix
+                                      + name_string);
 
          symtab->define_in_output_data(start_name.c_str(),
                                        NULL, // version
@@ -3356,8 +3353,10 @@ Layout::finish_dynamic_section(const Input_objects* input_objects,
       odyn->add_constant(elfcpp::DT_TEXTREL, 0);
       flags |= elfcpp::DF_TEXTREL;
 
-      if (parameters->options().warn_shared_textrel()
-         && parameters->options().shared())
+      if (parameters->options().text())
+       gold_error(_("read-only segment has dynamic relocations"));
+      else if (parameters->options().warn_shared_textrel()
+              && parameters->options().shared())
        gold_warning(_("shared library text segment is not shareable"));
     }
   if (parameters->options().shared() && this->has_static_tls())
index 3fedcf8..89ff34c 100644 (file)
@@ -1180,6 +1180,14 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab,
             {
               symtab->gc()->worklist().push(Section_id(this, i)); 
             }
+          // If the section name XXX can be represented as a C identifier
+          // it cannot be discarded if there are references to
+          // __start_XXX and __stop_XXX symbols.  These need to be
+          // specially handled.
+          if (is_cident(name))
+            {
+              symtab->gc()->add_cident_section(name, Section_id(this, i));
+            }
         }
 
       // When doing a relocatable link we are going to copy input
index 110b91f..b22060a 100644 (file)
@@ -972,6 +972,14 @@ class General_options
              N_("Warn if text segment is not shareable"),
              N_("Do not warn if text segment is not shareable (default)"));
 
+  DEFINE_bool(warn_unresolved_symbols, options::TWO_DASHES, '\0', false,
+             N_("Report unresolved symbols as warnings"),
+             NULL);
+  DEFINE_bool_alias(error_unresolved_symbols, warn_unresolved_symbols,
+                   options::TWO_DASHES, '\0',
+                   N_("Report unresolved symbols as errors"),
+                   NULL, true);
+
   DEFINE_bool(whole_archive, options::TWO_DASHES, '\0', false,
               N_("Include all archive contents"),
               N_("Include only needed archive contents"));
@@ -1052,6 +1060,12 @@ class General_options
   DEFINE_bool(relro, options::DASH_Z, '\0', false,
              N_("Where possible mark variables read-only after relocation"),
              N_("Don't mark variables read-only after relocation"));
+  DEFINE_bool(text, options::DASH_Z, '\0', false,
+             N_("Do not permit relocations in read-only segments"),
+             NULL);
+  DEFINE_bool_alias(textoff, text, options::DASH_Z, '\0',
+                   N_("Permit relocations in read-only segments (default)"),
+                   NULL, true);
 
  public:
   typedef options::Dir_list Dir_list;
index 7b5532e..2bf5bbe 100644 (file)
@@ -139,6 +139,16 @@ gc_tls_test:gc_tls_test.o gcctestdir/ld
 gc_tls_test.stdout: gc_tls_test
        $(TEST_NM) -C gc_tls_test > gc_tls_test.stdout
 
+check_SCRIPTS += gc_orphan_section_test.sh
+check_DATA += gc_orphan_section_test.stdout
+MOSTLYCLEANFILES += gc_orphan_section_test
+gc_orphan_section_test.o: gc_orphan_section_test.cc
+       $(CXXCOMPILE) -O0 -c -g -o $@ $<
+gc_orphan_section_test:gc_orphan_section_test.o gcctestdir/ld
+       $(CXXLINK) -Bgcctestdir/ -Wl,--gc-sections gc_orphan_section_test.o
+gc_orphan_section_test.stdout: gc_orphan_section_test
+       $(TEST_NM) gc_orphan_section_test > gc_orphan_section_test.stdout
+
 check_SCRIPTS += icf_test.sh
 check_DATA += icf_test.stdout
 MOSTLYCLEANFILES += icf_test
index 291eab7..21fca3d 100644 (file)
@@ -57,6 +57,7 @@ check_PROGRAMS = object_unittest$(EXEEXT) binary_unittest$(EXEEXT) \
 # and --dynamic-list-cpp-typeinfo
 @GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_1 = incremental_test.sh \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ gc_comdat_test.sh gc_tls_test.sh \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ gc_orphan_section_test.sh \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_test.sh \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_keep_unique_test.sh \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_safe_test.sh \
@@ -82,6 +83,7 @@ check_PROGRAMS = object_unittest$(EXEEXT) binary_unittest$(EXEEXT) \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_2 = incremental_test.stdout \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ gc_comdat_test.stdout \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ gc_tls_test.stdout \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ gc_orphan_section_test.stdout \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_test.stdout \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_keep_unique_test.stdout \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_safe_test.stdout \
@@ -103,7 +105,8 @@ check_PROGRAMS = object_unittest$(EXEEXT) binary_unittest$(EXEEXT) \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ dynamic_list.stdout
 @GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_3 = incremental_test \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ gc_comdat_test gc_tls_test \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_test icf_keep_unique_test \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ gc_orphan_section_test icf_test \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_keep_unique_test \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_safe_test \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ two_file_shared.dbg \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ alt/weak_undef_lib.so
@@ -2582,6 +2585,12 @@ uninstall-am:
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Bgcctestdir/ -Wl,--gc-sections gc_tls_test.o
 @GCC_TRUE@@NATIVE_LINKER_TRUE@gc_tls_test.stdout: gc_tls_test
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_NM) -C gc_tls_test > gc_tls_test.stdout
+@GCC_TRUE@@NATIVE_LINKER_TRUE@gc_orphan_section_test.o: gc_orphan_section_test.cc
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXCOMPILE) -O0 -c -g -o $@ $<
+@GCC_TRUE@@NATIVE_LINKER_TRUE@gc_orphan_section_test:gc_orphan_section_test.o gcctestdir/ld
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Bgcctestdir/ -Wl,--gc-sections gc_orphan_section_test.o
+@GCC_TRUE@@NATIVE_LINKER_TRUE@gc_orphan_section_test.stdout: gc_orphan_section_test
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_NM) gc_orphan_section_test > gc_orphan_section_test.stdout
 @GCC_TRUE@@NATIVE_LINKER_TRUE@icf_test.o: icf_test.cc 
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXCOMPILE) -O0 -c -ffunction-sections -g -o $@ $<
 @GCC_TRUE@@NATIVE_LINKER_TRUE@icf_test: icf_test.o gcctestdir/ld
diff --git a/gold/testsuite/gc_orphan_section_test.cc b/gold/testsuite/gc_orphan_section_test.cc
new file mode 100644 (file)
index 0000000..3443f8d
--- /dev/null
@@ -0,0 +1,36 @@
+// gc_orphan_section_test.cc -- a test case for gold
+
+// Copyright 2010 Free Software Foundation, Inc.
+// Written by Sriraman Tallam <tmsriram@google.com>.
+
+// This file is part of gold.
+
+// 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 3 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., 51 Franklin Street - Fifth Floor, Boston,
+// MA 02110-1301, USA.
+
+// The goal of this program is to verify if garbage collection does not
+// discard orphan sections when references to them through __start_XXX
+// and __stop_XXX are present.  Here section _foo must not be gc'ed but
+// _boo should be gc'ed.
+
+extern const int *__start__foo;
+int foo __attribute__((__section__("_foo"))) = 1;
+int boo __attribute__((__section__("_boo"))) = 1;
+
+int main()
+{
+  return *__start__foo;
+}
+
diff --git a/gold/testsuite/gc_orphan_section_test.sh b/gold/testsuite/gc_orphan_section_test.sh
new file mode 100755 (executable)
index 0000000..6ce524d
--- /dev/null
@@ -0,0 +1,46 @@
+#!/bin/sh
+
+# gc_orphan_section_test.sh -- test --gc-sections
+
+# Copyright 2010 Free Software Foundation, Inc.
+# Written by Sriraman Tallam <tmsriram@google.com>.
+
+# This file is part of gold.
+
+# 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 3 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., 51 Franklin Street - Fifth Floor, Boston,
+# MA 02110-1301, USA.
+
+# The goal of this program is to verify if gc-sections works as expected
+# with orphan sections.
+# File gc_orphan_sections_test.cc is in this test. This program checks if
+# the orphan sections are retained when they are referenced through
+# __start_XXX and __stop_XXX symbols.
+
+check()
+{
+    if grep -q " boo" "$1"
+    then
+        echo "Garbage collection failed to collect boo"
+       exit 1
+    fi
+    grep_foo=`grep -q " foo" $1`
+    if [ $? != 0 ];
+    then
+        echo "Garbage collection should not discard foo"
+       exit 1
+    fi
+}
+
+check gc_orphan_section_test.stdout
index 4a2a6da..3320c13 100644 (file)
@@ -1,3 +1,10 @@
+2010-01-07  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR ld/11143
+       * ld-gc/gc.exp: Run abi-note.
+
+       * ld-gc/abi-note.d: New.
+       * ld-gc/abi-note.s: Likewise.
 
 For older changes see ChangeLog-2009
 \f
diff --git a/ld/testsuite/ld-gc/abi-note.d b/ld/testsuite/ld-gc/abi-note.d
new file mode 100644 (file)
index 0000000..e802fe5
--- /dev/null
@@ -0,0 +1,8 @@
+#name: --gc-sections with note section
+#ld: --gc-sections -e _start
+#readelf: -S --wide
+#target: *-*-linux*
+
+#...
+.* .note.ABI-tag[      ]+NOTE.*
+#...
diff --git a/ld/testsuite/ld-gc/abi-note.s b/ld/testsuite/ld-gc/abi-note.s
new file mode 100644 (file)
index 0000000..22536c0
--- /dev/null
@@ -0,0 +1,15 @@
+       .text
+       .global _start
+_start:
+       .long 1
+
+       .section ".note.ABI-tag", "a"
+       .p2align 2
+       .long 1f - 0f           /* name length */
+       .long 3f - 2f           /* data length */
+       .long  1                /* note type */
+0:     .asciz "GNU"            /* vendor name */
+1:     .p2align 2
+2:     .long 1
+       .long 2
+3:     .p2align 2              /* pad out section */
index c85d4f2..36df233 100644 (file)
@@ -1,5 +1,5 @@
 # Expect script for ld-gc tests
-#   Copyright 2008, 2009
+#   Copyright 2008, 2009, 2010
 #   Free Software Foundation, Inc.
 #
 # This file is part of the GNU Binutils.
@@ -90,3 +90,4 @@ test_gc "Check --gc-section/-r/-e" "gcrel" $ld "-r --gc-sections -e main"
 test_gc "Check --gc-section/-r/-u" "gcrel" $ld "-r --gc-sections -u used_func"
 
 run_dump_test "noent"
+run_dump_test "abi-note"
index 0285a69..3013151 100644 (file)
@@ -1,3 +1,11 @@
+2010-01-07  Doug Evans  <dje@sebabeach.org>
+
+       * cgen-ibld.in (insert_normal, extract_normal): Minor cleanup.
+       * fr30-ibld.c, * frv-ibld.c, * ip2k-ibld.c, * iq2000-ibld.c,
+       * lm32-ibld.c, * m32c-ibld.c, * m32r-ibld.c, * mep-ibld.c,
+       * mt-ibld.c, * openrisc-ibld.c, * xc16x-ibld.c,
+       * xstormy16-ibld.c: Regenerate.
+
 2010-01-06  Quentin Neill  <quentin.neill@amd.com>
 
        * i386-gen.c (cpu_flag_init): Add new CPU_AMDFAM15_FLAGS.
index ea12908..a29f488 100644 (file)
@@ -138,7 +138,7 @@ insert_normal (CGEN_CPU_DESC cd,
   if (length == 0)
     return NULL;
 
-  if (word_length > 32)
+  if (word_length > 8 * sizeof (CGEN_INSN_INT))
     abort ();
 
   /* For architectures with insns smaller than the base-insn-bitsize,
@@ -442,7 +442,7 @@ extract_normal (CGEN_CPU_DESC cd,
       return 1;
     }
 
-  if (word_length > 32)
+  if (word_length > 8 * sizeof (CGEN_INSN_INT))
     abort ();
 
   /* For architectures with insns smaller than the insn-base-bitsize,
@@ -469,7 +469,7 @@ extract_normal (CGEN_CPU_DESC cd,
     {
       unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
 
-      if (word_length > 32)
+      if (word_length > 8 * sizeof (CGEN_INSN_INT))
        abort ();
 
       if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
index 077f0ac..7487470 100644 (file)
@@ -138,7 +138,7 @@ insert_normal (CGEN_CPU_DESC cd,
   if (length == 0)
     return NULL;
 
-  if (word_length > 32)
+  if (word_length > 8 * sizeof (CGEN_INSN_INT))
     abort ();
 
   /* For architectures with insns smaller than the base-insn-bitsize,
@@ -442,7 +442,7 @@ extract_normal (CGEN_CPU_DESC cd,
       return 1;
     }
 
-  if (word_length > 32)
+  if (word_length > 8 * sizeof (CGEN_INSN_INT))
     abort ();
 
   /* For architectures with insns smaller than the insn-base-bitsize,
@@ -469,7 +469,7 @@ extract_normal (CGEN_CPU_DESC cd,
     {
       unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
 
-      if (word_length > 32)
+      if (word_length > 8 * sizeof (CGEN_INSN_INT))
        abort ();
 
       if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
index d628fd4..61db1bf 100644 (file)
@@ -138,7 +138,7 @@ insert_normal (CGEN_CPU_DESC cd,
   if (length == 0)
     return NULL;
 
-  if (word_length > 32)
+  if (word_length > 8 * sizeof (CGEN_INSN_INT))
     abort ();
 
   /* For architectures with insns smaller than the base-insn-bitsize,
@@ -442,7 +442,7 @@ extract_normal (CGEN_CPU_DESC cd,
       return 1;
     }
 
-  if (word_length > 32)
+  if (word_length > 8 * sizeof (CGEN_INSN_INT))
     abort ();
 
   /* For architectures with insns smaller than the insn-base-bitsize,
@@ -469,7 +469,7 @@ extract_normal (CGEN_CPU_DESC cd,
     {
       unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
 
-      if (word_length > 32)
+      if (word_length > 8 * sizeof (CGEN_INSN_INT))
        abort ();
 
       if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
index dcc9c9a..46c159a 100644 (file)
@@ -138,7 +138,7 @@ insert_normal (CGEN_CPU_DESC cd,
   if (length == 0)
     return NULL;
 
-  if (word_length > 32)
+  if (word_length > 8 * sizeof (CGEN_INSN_INT))
     abort ();
 
   /* For architectures with insns smaller than the base-insn-bitsize,
@@ -442,7 +442,7 @@ extract_normal (CGEN_CPU_DESC cd,
       return 1;
     }
 
-  if (word_length > 32)
+  if (word_length > 8 * sizeof (CGEN_INSN_INT))
     abort ();
 
   /* For architectures with insns smaller than the insn-base-bitsize,
@@ -469,7 +469,7 @@ extract_normal (CGEN_CPU_DESC cd,
     {
       unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
 
-      if (word_length > 32)
+      if (word_length > 8 * sizeof (CGEN_INSN_INT))
        abort ();
 
       if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
index c6fa653..8f56733 100644 (file)
@@ -138,7 +138,7 @@ insert_normal (CGEN_CPU_DESC cd,
   if (length == 0)
     return NULL;
 
-  if (word_length > 32)
+  if (word_length > 8 * sizeof (CGEN_INSN_INT))
     abort ();
 
   /* For architectures with insns smaller than the base-insn-bitsize,
@@ -442,7 +442,7 @@ extract_normal (CGEN_CPU_DESC cd,
       return 1;
     }
 
-  if (word_length > 32)
+  if (word_length > 8 * sizeof (CGEN_INSN_INT))
     abort ();
 
   /* For architectures with insns smaller than the insn-base-bitsize,
@@ -469,7 +469,7 @@ extract_normal (CGEN_CPU_DESC cd,
     {
       unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
 
-      if (word_length > 32)
+      if (word_length > 8 * sizeof (CGEN_INSN_INT))
        abort ();
 
       if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
index c9f8229..9a1f8bb 100644 (file)
@@ -138,7 +138,7 @@ insert_normal (CGEN_CPU_DESC cd,
   if (length == 0)
     return NULL;
 
-  if (word_length > 32)
+  if (word_length > 8 * sizeof (CGEN_INSN_INT))
     abort ();
 
   /* For architectures with insns smaller than the base-insn-bitsize,
@@ -442,7 +442,7 @@ extract_normal (CGEN_CPU_DESC cd,
       return 1;
     }
 
-  if (word_length > 32)
+  if (word_length > 8 * sizeof (CGEN_INSN_INT))
     abort ();
 
   /* For architectures with insns smaller than the insn-base-bitsize,
@@ -469,7 +469,7 @@ extract_normal (CGEN_CPU_DESC cd,
     {
       unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
 
-      if (word_length > 32)
+      if (word_length > 8 * sizeof (CGEN_INSN_INT))
        abort ();
 
       if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
index 4d201c6..66fc999 100644 (file)
@@ -138,7 +138,7 @@ insert_normal (CGEN_CPU_DESC cd,
   if (length == 0)
     return NULL;
 
-  if (word_length > 32)
+  if (word_length > 8 * sizeof (CGEN_INSN_INT))
     abort ();
 
   /* For architectures with insns smaller than the base-insn-bitsize,
@@ -442,7 +442,7 @@ extract_normal (CGEN_CPU_DESC cd,
       return 1;
     }
 
-  if (word_length > 32)
+  if (word_length > 8 * sizeof (CGEN_INSN_INT))
     abort ();
 
   /* For architectures with insns smaller than the insn-base-bitsize,
@@ -469,7 +469,7 @@ extract_normal (CGEN_CPU_DESC cd,
     {
       unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
 
-      if (word_length > 32)
+      if (word_length > 8 * sizeof (CGEN_INSN_INT))
        abort ();
 
       if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
index 8e3319f..bb8cc07 100644 (file)
@@ -138,7 +138,7 @@ insert_normal (CGEN_CPU_DESC cd,
   if (length == 0)
     return NULL;
 
-  if (word_length > 32)
+  if (word_length > 8 * sizeof (CGEN_INSN_INT))
     abort ();
 
   /* For architectures with insns smaller than the base-insn-bitsize,
@@ -442,7 +442,7 @@ extract_normal (CGEN_CPU_DESC cd,
       return 1;
     }
 
-  if (word_length > 32)
+  if (word_length > 8 * sizeof (CGEN_INSN_INT))
     abort ();
 
   /* For architectures with insns smaller than the insn-base-bitsize,
@@ -469,7 +469,7 @@ extract_normal (CGEN_CPU_DESC cd,
     {
       unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
 
-      if (word_length > 32)
+      if (word_length > 8 * sizeof (CGEN_INSN_INT))
        abort ();
 
       if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
index f0bbab5..907cff4 100644 (file)
@@ -138,7 +138,7 @@ insert_normal (CGEN_CPU_DESC cd,
   if (length == 0)
     return NULL;
 
-  if (word_length > 32)
+  if (word_length > 8 * sizeof (CGEN_INSN_INT))
     abort ();
 
   /* For architectures with insns smaller than the base-insn-bitsize,
@@ -442,7 +442,7 @@ extract_normal (CGEN_CPU_DESC cd,
       return 1;
     }
 
-  if (word_length > 32)
+  if (word_length > 8 * sizeof (CGEN_INSN_INT))
     abort ();
 
   /* For architectures with insns smaller than the insn-base-bitsize,
@@ -469,7 +469,7 @@ extract_normal (CGEN_CPU_DESC cd,
     {
       unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
 
-      if (word_length > 32)
+      if (word_length > 8 * sizeof (CGEN_INSN_INT))
        abort ();
 
       if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
index d5cd14e..00110de 100644 (file)
@@ -138,7 +138,7 @@ insert_normal (CGEN_CPU_DESC cd,
   if (length == 0)
     return NULL;
 
-  if (word_length > 32)
+  if (word_length > 8 * sizeof (CGEN_INSN_INT))
     abort ();
 
   /* For architectures with insns smaller than the base-insn-bitsize,
@@ -442,7 +442,7 @@ extract_normal (CGEN_CPU_DESC cd,
       return 1;
     }
 
-  if (word_length > 32)
+  if (word_length > 8 * sizeof (CGEN_INSN_INT))
     abort ();
 
   /* For architectures with insns smaller than the insn-base-bitsize,
@@ -469,7 +469,7 @@ extract_normal (CGEN_CPU_DESC cd,
     {
       unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
 
-      if (word_length > 32)
+      if (word_length > 8 * sizeof (CGEN_INSN_INT))
        abort ();
 
       if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
index 29372a6..6a84f32 100644 (file)
@@ -138,7 +138,7 @@ insert_normal (CGEN_CPU_DESC cd,
   if (length == 0)
     return NULL;
 
-  if (word_length > 32)
+  if (word_length > 8 * sizeof (CGEN_INSN_INT))
     abort ();
 
   /* For architectures with insns smaller than the base-insn-bitsize,
@@ -442,7 +442,7 @@ extract_normal (CGEN_CPU_DESC cd,
       return 1;
     }
 
-  if (word_length > 32)
+  if (word_length > 8 * sizeof (CGEN_INSN_INT))
     abort ();
 
   /* For architectures with insns smaller than the insn-base-bitsize,
@@ -469,7 +469,7 @@ extract_normal (CGEN_CPU_DESC cd,
     {
       unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
 
-      if (word_length > 32)
+      if (word_length > 8 * sizeof (CGEN_INSN_INT))
        abort ();
 
       if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
index 70558cf..a5c816c 100644 (file)
@@ -138,7 +138,7 @@ insert_normal (CGEN_CPU_DESC cd,
   if (length == 0)
     return NULL;
 
-  if (word_length > 32)
+  if (word_length > 8 * sizeof (CGEN_INSN_INT))
     abort ();
 
   /* For architectures with insns smaller than the base-insn-bitsize,
@@ -442,7 +442,7 @@ extract_normal (CGEN_CPU_DESC cd,
       return 1;
     }
 
-  if (word_length > 32)
+  if (word_length > 8 * sizeof (CGEN_INSN_INT))
     abort ();
 
   /* For architectures with insns smaller than the insn-base-bitsize,
@@ -469,7 +469,7 @@ extract_normal (CGEN_CPU_DESC cd,
     {
       unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
 
-      if (word_length > 32)
+      if (word_length > 8 * sizeof (CGEN_INSN_INT))
        abort ();
 
       if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
index a734677..caae89b 100644 (file)
@@ -138,7 +138,7 @@ insert_normal (CGEN_CPU_DESC cd,
   if (length == 0)
     return NULL;
 
-  if (word_length > 32)
+  if (word_length > 8 * sizeof (CGEN_INSN_INT))
     abort ();
 
   /* For architectures with insns smaller than the base-insn-bitsize,
@@ -442,7 +442,7 @@ extract_normal (CGEN_CPU_DESC cd,
       return 1;
     }
 
-  if (word_length > 32)
+  if (word_length > 8 * sizeof (CGEN_INSN_INT))
     abort ();
 
   /* For architectures with insns smaller than the insn-base-bitsize,
@@ -469,7 +469,7 @@ extract_normal (CGEN_CPU_DESC cd,
     {
       unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
 
-      if (word_length > 32)
+      if (word_length > 8 * sizeof (CGEN_INSN_INT))
        abort ();
 
       if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
index 485fb1b..2f0cf26 100644 (file)
@@ -1,3 +1,7 @@
+2010-01-07  Corinna Vinschen  <corinna@vinschen.de>
+
+       * overview.sgml: Fix Red Hat brand name.
+
 2010-01-04  Christopher Faylor  <me+cygwin@cgf.cx>
 
        * overview.sgml: Fix Red Hat URL.
index 7b7e1d6..0d521fe 100644 (file)
@@ -48,7 +48,7 @@ library, you may want the Cygwin proprietary-use license.
 For more information about the proprietary-use license, please go to
 <ulink url="http://www.redhat.com/services/custom/cygwin/">http://www.redhat.com/services/custom/cygwin/</ulink>. 
 Customers of the native Win32 GNUPro should feel free to submit bug
-reports and ask questions through Red hat channels.  All other
+reports and ask questions through Red Hat channels.  All other
 questions should be sent to the project mailing list
 <email>cygwin@cygwin.com</email>.</para>
 
index 727817b..a8438b5 100644 (file)
@@ -1,3 +1,15 @@
+2010-01-07  Corinna Vinschen  <corinna@vinschen.de>
+
+       * cygpath.cc: Throughout, free obsolete path buffers.
+
+2010-01-07  Corinna Vinschen  <corinna@vinschen.de>
+
+       * cygpath.cc (main): Remove enforcing "en_US.UTF-8" locale.
+       Revert usage of argz functions when reading input from file and
+       simplify option usage.  Allow only one option argument and use
+       the rest as filename argument to allow spaces in filenames.  Restrict
+       processing special folder type options to one line.
+
 2009-12-17  Christopher Faylor  <me+cygwin@cgf.cx>
 
        * ps.cc (main): Return 0 if pid found.
index 83d4e3f..8790031 100644 (file)
@@ -1,6 +1,6 @@
 /* cygpath.cc -- convert pathnames between Windows and Unix format
    Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-   2006, 2007, 2008, 2009 Red Hat, Inc.
+   2006, 2007, 2008, 2009, 2010 Red Hat, Inc.
 
 This file is part of Cygwin.
 
@@ -16,7 +16,6 @@ details. */
 #include <wchar.h>
 #include <locale.h>
 #include <stdlib.h>
-#include <argz.h>
 #include <limits.h>
 #include <getopt.h>
 #include <windows.h>
@@ -30,7 +29,7 @@ details. */
 #include <ddk/ntifs.h>
 #include "wide_path.h"
 
-static const char version[] = "$Revision$";
+static const char version[] = "$Revision: 1.58 $";
 
 static char *prog_name;
 static char *file_arg, *output_arg;
@@ -227,6 +226,7 @@ get_device_name (char *path)
                 a valid DOS device name, if prepended with "\\.\".  Return that
                 valid DOS path. */
              ULONG len = RtlUnicodeStringToAnsiSize (&odi->ObjectName);
+             free (ret);
              ret = (char *) malloc (len + 4);
              strcpy (ret, "\\\\.\\");
              ans.Length = 0;
@@ -667,10 +667,18 @@ do_sysfolders (char option)
     }
   else
     {
+      char *tmp;
+
       if (shortname_flag)
-       buf = get_short_name (buf);
+       {
+         buf = get_short_name (tmp = buf);
+         free (tmp);
+       }
       if (mixed_flag)
-       buf = get_mixed_name (buf);
+       {
+         buf = get_mixed_name (tmp = buf);
+         free (tmp);
+       }
     }
   printf ("%s\n", buf);
 }
@@ -696,8 +704,8 @@ report_mode (char *filename)
 static void
 do_pathconv (char *filename)
 {
-  char *buf;
-  wchar_t *buf2;
+  char *buf = NULL, *tmp;
+  wchar_t *buf2 = NULL;
   DWORD len;
   ssize_t err;
   cygwin_conv_path_t conv_func =
@@ -738,13 +746,23 @@ do_pathconv (char *filename)
        {
          if (err)
            /* oops */;
-         buf = get_device_paths (buf);
+         buf = get_device_paths (tmp = buf);
+         free (tmp);
          if (shortname_flag)
-           buf = get_short_paths (buf);
+           {
+             buf = get_short_paths (tmp = buf);
+             free (tmp);
+           }
          if (longname_flag)
-           buf = get_long_paths (buf);
+           {
+             buf = get_long_paths (tmp = buf);
+             free (tmp);
+           }
          if (mixed_flag)
-           buf = get_mixed_name (buf);
+           {
+             buf = get_mixed_name (tmp = buf);
+             free (tmp);
+           }
        }
       if (err)
        {
@@ -766,11 +784,21 @@ do_pathconv (char *filename)
       if (!unix_flag)
        {
          my_wcstombs (buf, buf2, 32768);
-         buf = get_device_name (buf);
+         buf = get_device_name (tmp = buf);
+         free (tmp);
          if (shortname_flag)
-           buf = get_short_name (buf);
+           {
+             buf = get_short_name (tmp = buf);
+             free (tmp);
+           }
          if (longname_flag)
-           buf = get_long_name (buf, len);
+           {
+             buf = get_long_name (tmp = buf, len);
+             free (tmp);
+           }
+         /* buf gets moved into the array so we have to set tmp for later
+            freeing beforehand. */
+         tmp = buf;
          if (strncmp (buf, "\\\\?\\", 4) == 0)
            {
              len = 4;
@@ -784,11 +812,18 @@ do_pathconv (char *filename)
                }
            }
          if (mixed_flag)
-           buf = get_mixed_name (buf);
+           {
+             buf = get_mixed_name (buf);
+             free (tmp);
+           }
        }
     }
 
   puts (buf);
+  if (buf2)
+    free (buf2);
+  if (buf)
+    free (buf);
 }
 
 static void
@@ -1029,10 +1064,7 @@ main (int argc, char **argv)
 {
   int o;
 
-  /* Use locale from environment.  If not set or set to "C", use UTF-8. */
   setlocale (LC_CTYPE, "");
-  if (!strcmp (setlocale (LC_CTYPE, NULL), "C"))
-    setlocale (LC_CTYPE, "en_US.UTF-8");
   prog_name = strrchr (argv[0], '/');
   if (!prog_name)
     prog_name = strrchr (argv[0], '\\');
@@ -1070,35 +1102,33 @@ main (int argc, char **argv)
 
       while (fgets (buf, sizeof (buf), fp))
        {
-         size_t azl = 0;
-         int ac;
-         char *az, **av;
+         int ac = 0;
+         char *av[4] = { NULL, NULL, NULL, NULL };
          char *p = strchr (buf, '\n');
          if (p)
            *p = '\0';
-         if (argz_create_sep (buf, ' ', &az, &azl))
+         p = buf;
+         av[ac++] = prog_name;
+         av[ac++] = p;
+         if (options_from_file_flag && *p == '-')
            {
-             perror ("cygpath");
-             exit (1);
+             while (*p && !isspace (*p))
+               ++p;
+             if (*p)
+               {
+                 *p++ = '\0';
+                 while (*p && isspace (*p))
+                   ++p;
+                 av[ac++] = p;
+               }
+             o = do_options (ac, av, 1);
            }
-         if (!az)
-           continue;
-         ac = argz_count (az, azl) + 1;
-         av = (char **) malloc ((ac + 1) * sizeof (char *));
-         if (!av)
+         else
            {
-             perror ("cygpath");
-             exit (1);
+             output_flag = 0;
+             optind = 1;
            }
-         av[0] = prog_name;
-         argz_extract (az, azl, av + 1);
-         if (options_from_file_flag)
-           o = do_options (ac, av, 1);
-         else
-           optind = 1;
          action (ac, av, o);
-         free (az);
-         free (av);
        }
     }
   exit (0);