]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Sync libiberty sources with gcc master version
authorNick Clifton <nickc@redhat.com>
Wed, 7 Jan 2026 11:33:07 +0000 (11:33 +0000)
committerNick Clifton <nickc@redhat.com>
Wed, 7 Jan 2026 11:33:07 +0000 (11:33 +0000)
include/demangle.h
include/libiberty.h
libiberty/ChangeLog
libiberty/Makefile.in
libiberty/acinclude.m4
libiberty/aclocal.m4
libiberty/configure
libiberty/cp-demangle.c
libiberty/simple-object-coff.c
libiberty/simple-object-mach-o.c
libiberty/testsuite/demangle-expected

index 7e01a116f9145304d0046f057f625b4831bfabac..e9165d6b0833ba744499b0a8f0fc66186b02ad8e 100644 (file)
@@ -64,14 +64,14 @@ extern "C" {
 /* Disable a limit on the depth of recursion in mangled strings.
    Note if this limit is disabled then stack exhaustion is possible when
    demangling pathologically complicated strings.  Bug reports about stack
-   exhaustion when the option is enabled will be rejected.  */  
-#define DMGL_NO_RECURSE_LIMIT (1 << 18)        
+   exhaustion when the option is enabled will be rejected.  */
+#define DMGL_NO_RECURSE_LIMIT (1 << 18)
 
 /* If DMGL_NO_RECURSE_LIMIT is not enabled, then this is the value used as
    the maximum depth of recursion allowed.  It should be enough for any
    real-world mangled name.  */
 #define DEMANGLE_RECURSION_LIMIT 2048
-  
+
 /* Enumeration of possible demangling styles.
 
    Lucid and ARM styles are still kept logically distinct, even though
@@ -435,6 +435,8 @@ enum demangle_component_type
   DEMANGLE_COMPONENT_DEFAULT_ARG,
   /* An unnamed type.  */
   DEMANGLE_COMPONENT_UNNAMED_TYPE,
+  /* An unnamed enum.  */
+  DEMANGLE_COMPONENT_UNNAMED_ENUM,
   /* A transactional clone.  This has one subtree, the encoding for
      which it is providing alternative linkage.  */
   DEMANGLE_COMPONENT_TRANSACTION_CLONE,
index 7960d802b667f64bf06fccf1dd9f16b8847507a2..1af4fa861017f19e5e82c51bab34b42d92072d91 100644 (file)
@@ -1,7 +1,7 @@
 /* Function declarations for libiberty.
 
    Copyright (C) 1997-2026 Free Software Foundation, Inc.
-   
+
    Note - certain prototypes declared in this header file are for
    functions whoes implementation copyright does not belong to the
    FSF.  Those prototypes are present in this file for reference
@@ -23,7 +23,7 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street - Fifth Floor,
    Boston, MA 02110-1301, USA.
-   
+
    Written by Cygnus Support, 1994.
 
    The libiberty library provides a number of functions which are
@@ -108,7 +108,7 @@ extern int countargv (char * const *);
 #if defined (__GNU_LIBRARY__ ) || defined (__linux__) \
  || defined (__FreeBSD__) || defined (__OpenBSD__) || defined (__NetBSD__) \
  || defined (__CYGWIN__) || defined (__CYGWIN32__) || defined (__MINGW32__) \
- || defined (__DragonFly__) || defined (HAVE_DECL_BASENAME) 
+ || defined (__DragonFly__) || defined (HAVE_DECL_BASENAME)
 extern char *basename (const char *) ATTRIBUTE_RETURNS_NONNULL ATTRIBUTE_NONNULL(1);
 #else
 /* Do not allow basename to be used if there is no prototype seen.  We
@@ -232,7 +232,7 @@ extern char * getpwd (void);
 #ifdef __MINGW32__
 /* Forward declaration to avoid #include <sys/time.h>.   */
 struct timeval;
-extern int gettimeofday (struct timeval *, void *); 
+extern int gettimeofday (struct timeval *, void *);
 #endif
 
 /* Get the amount of time the process has run, in microseconds.  */
@@ -482,7 +482,7 @@ extern struct pex_obj *pex_init (int flags, const char *pname,
 /* Capture stderr to a pipe.  The output can be read by
    calling pex_read_err and reading from the returned
    FILE object.  This flag may be specified only for
-   the last program in a pipeline.  
+   the last program in a pipeline.
 
    This flag is supported only on Unix and Windows.  */
 #define PEX_STDERR_TO_PIPE     0x40
index b072d0bed5289dcb416da4f6645f3a89370df35b..37c351d33f5f14d28c94723df7af1212274929c4 100644 (file)
@@ -1,3 +1,57 @@
+2025-11-30  Jose E. Marchesi  <jose.marchesi@oracle.com>
+
+       * simple-object-mach-o.c
+       (simple_object_mach_o_segment): Handle non-LTO sections.
+
+2025-11-06  Peter Damianov  <peter0x44@disroot.org>
+
+       PR target/122472
+       * simple-object-coff.c (struct external_filehdr_bigobj): New
+       structure for BigObj file header.
+       (bigobj_magic): New constant for BigObj magic bytes.
+       (struct external_syment_bigobj): New structure for BigObj
+       20-byte symbol table entries.
+       (union external_auxent_bigobj): New union for BigObj 20-byte
+       auxiliary symbol entries.
+       (struct simple_object_coff_read): Add is_bigobj flag and make
+       nscns 32-bit to support both formats.
+       (struct simple_object_coff_attributes): Add is_bigobj flag.
+       (simple_object_coff_match): Add BigObj format detection.
+       (simple_object_coff_read_strtab): Use format-specific symbol
+       size when calculating string table offset.
+       (simple_object_coff_attributes_merge): Check is_bigobj flag.
+       (simple_object_coff_write_filehdr_bigobj): New function.
+       (simple_object_coff_write_to_file): Add logic for writing
+       BigObj vs regular COFF format with appropriate symbol
+       and auxiliary entry structures.
+
+2025-11-03  Sam James  <sam@gentoo.org>
+
+       * configure: Regenerate.
+
+2025-10-02  H.J. Lu  <hjl.tools@gmail.com>
+
+       * aclocal.m4: Regenerated.
+       * configure: Likewise.
+       * configure.ac: Synced from binutils-gdb.
+
+2025-08-17  Nathaniel Shead  <nathanieloshead@gmail.com>
+
+       PR c++/120503
+       PR c++/120824
+       * cp-demangle.c (d_unnamed_enum): New function.
+       (d_unqualified_name): Call it.
+       (cplus_demangle_type): Handle unscoped unnamed types
+       (Ue, Ul, etc.)
+       (d_count_templates_scopes): Handle unnamed enums.
+       (d_find_pack): Likewise.
+       (d_print_comp_inner): Print unnamed enums.
+       * testsuite/demangle-expected: Add tests.
+
+2025-08-13  Jakub Jelinek  <jakub@redhat.com>
+
+       * cp-demangle.c (d_encoding): Fix a comment typo, whaever -> whatever.
+
 2025-08-06  Matthieu Longo  <matthieu.longo@arm.com>
 
        * testsuite/test-doubly-linked-list.c: disable debug logging on
index 6d8c88ebfe77b22d505d5993f4c87fb56f32d74c..00af4acca66e0356a05133aa55ec74ed9c71fdec 100644 (file)
@@ -510,7 +510,6 @@ aclocal_deps = \
        $(srcdir)/../config/cet.m4 \
        $(srcdir)/../config/enable.m4 \
        $(srcdir)/../config/gcc-plugin.m4 \
-       $(srcdir)/../config/mmap.m4 \
        $(srcdir)/../config/no-executables.m4 \
        $(srcdir)/../config/override.m4 \
        $(srcdir)/../config/picflag.m4 \
index 49f621bf6297fdc6e004730b3e08ccffa39eb737..a8f2146b0f56790abe2612c9aa74867c8df67cce 100644 (file)
@@ -19,7 +19,7 @@ dnl On some versions of SunOS4 at least, strncmp reads a word at a time
 dnl but erroneously reads past the end of strings.  This can cause
 dnl a SEGV in some cases.
 AC_DEFUN([libiberty_AC_FUNC_STRNCMP],
-[AC_REQUIRE([GCC_AC_FUNC_MMAP])
+[AC_REQUIRE([AC_FUNC_MMAP])
 AC_CACHE_CHECK([for working strncmp], ac_cv_func_strncmp_works,
 [AC_TRY_RUN([
 /* Test by Jim Wilson and Kaveh Ghazi.
index 46cefc36edc6c1d52b0dbf7acbc19130f4eb70d2..5151f5fee189df5232e611a04775b2c3fc5c6b07 100644 (file)
@@ -18,7 +18,6 @@ m4_include([../config/clang-plugin.m4])
 m4_include([../config/enable.m4])
 m4_include([../config/gcc-plugin.m4])
 m4_include([../config/hwcaps.m4])
-m4_include([../config/mmap.m4])
 m4_include([../config/no-executables.m4])
 m4_include([../config/override.m4])
 m4_include([../config/picflag.m4])
index 4c72b5a92831da97f11562143fe5a8845d521b93..359f19ac0379a46ea92f9183a8e23aaad1eb6f60 100755 (executable)
@@ -7997,9 +7997,6 @@ if test x$gcc_no_link = xyes; then
   fi
 fi
 if test "x${ac_cv_func_mmap_fixed_mapped}" != xno; then
-  save_ASAN_OPTIONS="$ASAN_OPTIONS"
-  ASAN_OPTIONS=detect_leaks=0
-  export ASAN_OPTIONS
 
 for ac_func in getpagesize
 do :
@@ -8178,8 +8175,6 @@ $as_echo "#define HAVE_MMAP 1" >>confdefs.h
 fi
 rm -f conftest.mmap conftest.txt
 
-  ASAN_OPTIONS="$save_ASAN_OPTIONS"
-
 fi
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working strncmp" >&5
index e3c9ca104345b7abf091734dce7fd5c176e5c45e..5e6571d419b469a5572548052e90b69d68bdc601 100644 (file)
@@ -499,6 +499,8 @@ static struct demangle_component *d_lambda (struct d_info *);
 
 static struct demangle_component *d_unnamed_type (struct d_info *);
 
+static struct demangle_component *d_unnamed_enum (struct d_info *);
+
 static struct demangle_component *
 d_clone_suffix (struct d_info *, struct demangle_component *);
 
@@ -1424,7 +1426,7 @@ d_encoding (struct d_info *di, int top_level)
 
              /* If this is a non-top-level local-name, clear the
                 return type, so it doesn't confuse the user by
-                being confused with the return type of whaever
+                being confused with the return type of whatever
                 this is nested within.  */
              if (!top_level && dc->type == DEMANGLE_COMPONENT_LOCAL_NAME
                  && ftype->type == DEMANGLE_COMPONENT_FUNCTION_TYPE)
@@ -1799,6 +1801,9 @@ d_unqualified_name (struct d_info *di, struct demangle_component *scope,
     {
       switch (d_peek_next_char (di))
        {
+       case 'e':
+         ret = d_unnamed_enum (di);
+         break;
        case 'l':
          ret = d_lambda (di);
          break;
@@ -2728,13 +2733,20 @@ cplus_demangle_type (struct d_info *di)
       break;
 
     case 'U':
-      d_advance (di, 1);
-      ret = d_source_name (di);
-      if (d_peek_char (di) == 'I')
-       ret = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, ret,
-                          d_template_args (di));
-      ret = d_make_comp (di, DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL,
-                        cplus_demangle_type (di), ret);
+      peek = d_peek_next_char (di);
+      if (IS_DIGIT (peek))
+       {
+         d_advance (di, 1);
+         ret = d_source_name (di);
+         if (d_peek_char (di) == 'I')
+           ret = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, ret,
+                              d_template_args (di));
+         ret = d_make_comp (di, DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL,
+                            cplus_demangle_type (di), ret);
+       }
+      else
+       /* Could be a closure type or an unnamed enum.  */
+       ret = d_unqualified_name (di, NULL, NULL);
       break;
 
     case 'D':
@@ -4090,6 +4102,33 @@ d_unnamed_type (struct d_info *di)
   return ret;
 }
 
+/* <unnamed-enum-name> ::= Ue <underlying type> <enumerator source-name> */
+
+static struct demangle_component *
+d_unnamed_enum (struct d_info *di)
+{
+  if (! d_check_char (di, 'U'))
+    return NULL;
+  if (! d_check_char (di, 'e'))
+    return NULL;
+
+  struct demangle_component *underlying = cplus_demangle_type (di);
+  struct demangle_component *name = d_source_name (di);
+
+  struct demangle_component *ret = d_make_empty (di);
+  if (ret)
+    {
+      ret->type = DEMANGLE_COMPONENT_UNNAMED_ENUM;
+      d_left (ret) = underlying;
+      d_right (ret) = name;
+    }
+
+  if (! d_add_substitution (di, ret))
+    return NULL;
+
+  return ret;
+}
+
 /* <clone-suffix> ::= [ . <clone-type-identifier> ] [ . <nonnegative number> ]*
 */
 
@@ -4396,6 +4435,7 @@ d_count_templates_scopes (struct d_print_info *dpi,
     case DEMANGLE_COMPONENT_CHARACTER:
     case DEMANGLE_COMPONENT_NUMBER:
     case DEMANGLE_COMPONENT_UNNAMED_TYPE:
+    case DEMANGLE_COMPONENT_UNNAMED_ENUM:
     case DEMANGLE_COMPONENT_STRUCTURED_BINDING:
     case DEMANGLE_COMPONENT_MODULE_NAME:
     case DEMANGLE_COMPONENT_MODULE_PARTITION:
@@ -4780,6 +4820,7 @@ d_find_pack (struct d_print_info *dpi,
     case DEMANGLE_COMPONENT_CHARACTER:
     case DEMANGLE_COMPONENT_FUNCTION_PARAM:
     case DEMANGLE_COMPONENT_UNNAMED_TYPE:
+    case DEMANGLE_COMPONENT_UNNAMED_ENUM:
     case DEMANGLE_COMPONENT_DEFAULT_ARG:
     case DEMANGLE_COMPONENT_NUMBER:
       return NULL;
@@ -6258,6 +6299,14 @@ d_print_comp_inner (struct d_print_info *dpi, int options,
       d_append_char (dpi, '}');
       return;
 
+    case DEMANGLE_COMPONENT_UNNAMED_ENUM:
+      d_append_string (dpi, "{enum:");
+      d_print_comp (dpi, options, d_left (dc));
+      d_append_string (dpi, "{");
+      d_print_comp (dpi, options, d_right (dc));
+      d_append_string (dpi, "}}");
+      return;
+
     case DEMANGLE_COMPONENT_CLONE:
       d_print_comp (dpi, options, d_left (dc));
       d_append_string (dpi, " [clone ");
index 2cc94495a133b190d93366e8ea9850b746a5b23f..648036921acfaf632ab622636195d4e7a8a277fd 100644 (file)
@@ -57,6 +57,32 @@ struct external_filehdr
   unsigned char f_flags[2];    /* flags                        */
 };
 
+/* BigObj COFF file header.  */
+
+struct external_filehdr_bigobj
+{
+  unsigned char sig1[2];       /* Must be 0x0000 */
+  unsigned char sig2[2];       /* Must be 0xFFFF */
+  unsigned char version[2];    /* Version, currently 2 */
+  unsigned char machine[2];    /* Machine type */
+  unsigned char timdat[4];     /* time & date stamp */
+  unsigned char classid[16];   /* Magic GUID that identifies BigObj format */
+  unsigned char sizeofdata[4]; /* Size of data (unused, set to 0) */
+  unsigned char flags[4];      /* Flags (unused, set to 0) */
+  unsigned char metadatasize[4];       /* Metadata size (unused, set to 0) */
+  unsigned char metadataoffset[4];     /* Metadata offset (unused, set to 0) */
+  unsigned char nscns[4];      /* number of sections (32-bit!) */
+  unsigned char symptr[4];     /* file pointer to symtab */
+  unsigned char nsyms[4];      /* number of symtab entries */
+};
+
+/* The BigObj magic GUID (ClassID).  */
+static const unsigned char bigobj_magic[16] =
+{
+  0xC7, 0xA1, 0xBA, 0xD1, 0xEE, 0xBA, 0xA9, 0x4B,
+  0xAF, 0x20, 0xFA, 0xF6, 0x6A, 0xA4, 0xDC, 0xB8
+};
+
 /* Bits for filehdr f_flags field.  */
 
 #define F_EXEC                 (0x0002)
@@ -119,6 +145,28 @@ struct external_syment
   unsigned char e_numaux[1];
 };
 
+/* BigObj COFF symbol table entry (20 bytes instead of 18).  */
+
+struct external_syment_bigobj
+{
+  union
+  {
+    unsigned char e_name[E_SYMNMLEN];
+
+    struct
+    {
+      unsigned char e_zeroes[4];
+      unsigned char e_offset[4];
+    } e;
+  } e;
+
+  unsigned char e_value[4];
+  unsigned char e_scnum[4];    /* 32-bit section number! */
+  unsigned char e_type[2];
+  unsigned char e_sclass[1];
+  unsigned char e_numaux[1];
+};
+
 /* Length allowed for filename in aux sym format 4.  */
 
 #define E_FILNMLEN     18
@@ -149,6 +197,33 @@ union external_auxent
   } x_scn;
 };
 
+/* BigObj auxiliary symbol (20 bytes to match symbol size).  */
+
+union external_auxent_bigobj
+{
+  /* Aux sym format 4: file.  */
+  union
+  {
+    char x_fname[E_FILNMLEN];
+    struct
+    {
+      unsigned char x_zeroes[4];
+      unsigned char x_offset[4];
+    } x_n;
+  } x_file;
+  /* Aux sym format 5: section.  */
+  struct
+  {
+    unsigned char x_scnlen[4];         /* section length               */
+    unsigned char x_nreloc[2];         /* # relocation entries         */
+    unsigned char x_nlinno[2];         /* # line numbers               */
+    unsigned char x_checksum[4];       /* section COMDAT checksum      */
+    unsigned char x_associated[2];     /* COMDAT assoc section index   */
+    unsigned char x_comdat[1];         /* COMDAT selection number      */
+    unsigned char x_pad[3];            /* Padding to 20 bytes          */
+  } x_scn;
+};
+
 /* Symbol-related constants.  */
 
 #define IMAGE_SYM_DEBUG                (-2)
@@ -168,8 +243,10 @@ struct simple_object_coff_read
   unsigned short magic;
   /* Whether the file is big-endian.  */
   unsigned char is_big_endian;
+  /* Whether this is BigObj format.  */
+  unsigned char is_bigobj;
   /* Number of sections.  */
-  unsigned short nscns;
+  unsigned int nscns;
   /* File offset of symbol table.  */
   off_t symptr;
   /* Number of symbol table entries.  */
@@ -188,6 +265,8 @@ struct simple_object_coff_attributes
   unsigned short magic;
   /* Whether the file is big-endian.  */
   unsigned char is_big_endian;
+  /* Whether this is BigObj format.  */
+  unsigned char is_bigobj;
   /* Flags.  */
   unsigned short flags;
 };
@@ -240,10 +319,12 @@ simple_object_coff_match (unsigned char header[SIMPLE_OBJECT_MATCH_HEADER_LEN],
   int is_big_endian;
   unsigned short (*fetch_16) (const unsigned char *);
   unsigned int (*fetch_32) (const unsigned char *);
-  unsigned char hdrbuf[sizeof (struct external_filehdr)];
+  unsigned char hdrbuf[sizeof (struct external_filehdr_bigobj)];
   unsigned short flags;
   struct simple_object_coff_read *ocr;
+  unsigned short sig1, sig2;
 
+  /* Try regular COFF first.  */
   c = sizeof (coff_magic) / sizeof (coff_magic[0]);
   magic_big = simple_object_fetch_big_16 (header);
   magic_little = simple_object_fetch_little_16 (header);
@@ -254,12 +335,64 @@ simple_object_coff_match (unsigned char header[SIMPLE_OBJECT_MATCH_HEADER_LEN],
          : coff_magic[i].magic == magic_little)
        break;
     }
-  if (i >= c)
+
+  /* Check for BigObj if regular COFF didn't match.  */
+  sig1 = simple_object_fetch_little_16 (header);
+  sig2 = simple_object_fetch_little_16 (header + 2);
+
+  if (i >= c && (sig1 != 0 || sig2 != 0xFFFF))
     {
+      /* Not regular COFF and not BigObj.  */
       *errmsg = NULL;
       *err = 0;
       return NULL;
     }
+
+  if (sig1 == 0 && sig2 == 0xFFFF)
+    {
+      /* This looks like BigObj.  Verify the ClassID.  */
+      unsigned char bigobj_hdrbuf[sizeof (struct external_filehdr_bigobj)];
+
+      if (!simple_object_internal_read (descriptor, offset, bigobj_hdrbuf,
+                                       sizeof bigobj_hdrbuf, errmsg, err))
+       return NULL;
+
+      if (memcmp (bigobj_hdrbuf + offsetof (struct external_filehdr_bigobj,
+                                           classid),
+                 bigobj_magic, 16) != 0)
+       {
+         *errmsg = NULL;
+         *err = 0;
+         return NULL;
+       }
+
+      /* BigObj is always little-endian.  */
+      is_big_endian = 0;
+
+      ocr = XNEW (struct simple_object_coff_read);
+      ocr->magic = simple_object_fetch_little_16
+                    (bigobj_hdrbuf
+                     + offsetof (struct external_filehdr_bigobj, machine));
+      ocr->is_big_endian = 0;
+      ocr->is_bigobj = 1;
+      ocr->nscns = simple_object_fetch_little_32
+                    (bigobj_hdrbuf
+                     + offsetof (struct external_filehdr_bigobj, nscns));
+      ocr->symptr = simple_object_fetch_little_32
+                     (bigobj_hdrbuf
+                      + offsetof (struct external_filehdr_bigobj, symptr));
+      ocr->nsyms = simple_object_fetch_little_32
+                    (bigobj_hdrbuf
+                     + offsetof (struct external_filehdr_bigobj, nsyms));
+      ocr->flags = simple_object_fetch_little_32
+                    (bigobj_hdrbuf
+                     + offsetof (struct external_filehdr_bigobj, flags));
+      ocr->scnhdr_offset = sizeof (struct external_filehdr_bigobj);
+
+      return (void *) ocr;
+    }
+
+  /* Regular COFF.  */
   is_big_endian = coff_magic[i].is_big_endian;
 
   magic = is_big_endian ? magic_big : magic_little;
@@ -270,7 +403,7 @@ simple_object_coff_match (unsigned char header[SIMPLE_OBJECT_MATCH_HEADER_LEN],
              ? simple_object_fetch_big_32
              : simple_object_fetch_little_32);
 
-  if (!simple_object_internal_read (descriptor, offset, hdrbuf, sizeof hdrbuf,
+  if (!simple_object_internal_read (descriptor, offset, hdrbuf, sizeof (struct external_filehdr),
                                    errmsg, err))
     return NULL;
 
@@ -285,6 +418,7 @@ simple_object_coff_match (unsigned char header[SIMPLE_OBJECT_MATCH_HEADER_LEN],
   ocr = XNEW (struct simple_object_coff_read);
   ocr->magic = magic;
   ocr->is_big_endian = is_big_endian;
+  ocr->is_bigobj = 0;
   ocr->nscns = fetch_16 (hdrbuf + offsetof (struct external_filehdr, f_nscns));
   ocr->symptr = fetch_32 (hdrbuf
                          + offsetof (struct external_filehdr, f_symptr));
@@ -309,9 +443,13 @@ simple_object_coff_read_strtab (simple_object_read *sobj, size_t *strtab_size,
   unsigned char strsizebuf[4];
   size_t strsize;
   char *strtab;
+  size_t sym_size;
+
+  /* Symbol size depends on format.  */
+  sym_size = ocr->is_bigobj ? sizeof (struct external_syment_bigobj)
+                           : sizeof (struct external_syment);
 
-  strtab_offset = sobj->offset + ocr->symptr
-                 + ocr->nsyms * sizeof (struct external_syment);
+  strtab_offset = sobj->offset + ocr->symptr + ocr->nsyms * sym_size;
   if (!simple_object_internal_read (sobj->descriptor, strtab_offset,
                                    strsizebuf, 4, errmsg, err))
     return NULL;
@@ -444,6 +582,7 @@ simple_object_coff_fetch_attributes (simple_object_read *sobj,
   ret = XNEW (struct simple_object_coff_attributes);
   ret->magic = ocr->magic;
   ret->is_big_endian = ocr->is_big_endian;
+  ret->is_bigobj = ocr->is_bigobj;
   ret->flags = ocr->flags;
   return ret;
 }
@@ -466,7 +605,9 @@ simple_object_coff_attributes_merge (void *todata, void *fromdata, int *err)
   struct simple_object_coff_attributes *from =
     (struct simple_object_coff_attributes *) fromdata;
 
-  if (to->magic != from->magic || to->is_big_endian != from->is_big_endian)
+  if (to->magic != from->magic
+      || to->is_big_endian != from->is_big_endian
+      || to->is_bigobj != from->is_bigobj)
     {
       *err = 0;
       return "COFF object format mismatch";
@@ -500,6 +641,52 @@ simple_object_coff_start_write (void *attributes_data,
   return ret;
 }
 
+/* Write out a BigObj COFF filehdr.  */
+
+static int
+simple_object_coff_write_filehdr_bigobj (simple_object_write *sobj,
+                                        int descriptor,
+                                        unsigned int nscns,
+                                        size_t symtab_offset,
+                                        unsigned int nsyms,
+                                        const char **errmsg, int *err)
+{
+  struct simple_object_coff_attributes *attrs =
+    (struct simple_object_coff_attributes *) sobj->data;
+  unsigned char hdrbuf[sizeof (struct external_filehdr_bigobj)];
+  unsigned char *hdr;
+  void (*set_16) (unsigned char *, unsigned short);
+  void (*set_32) (unsigned char *, unsigned int);
+
+  hdr = &hdrbuf[0];
+
+  /* BigObj is always little-endian.  */
+  set_16 = simple_object_set_little_16;
+  set_32 = simple_object_set_little_32;
+
+  memset (hdr, 0, sizeof (struct external_filehdr_bigobj));
+
+  /* Set BigObj signatures.  */
+  set_16 (hdr + offsetof (struct external_filehdr_bigobj, sig1), 0);
+  set_16 (hdr + offsetof (struct external_filehdr_bigobj, sig2), 0xFFFF);
+  set_16 (hdr + offsetof (struct external_filehdr_bigobj, version), 2);
+  set_16 (hdr + offsetof (struct external_filehdr_bigobj, machine),
+         attrs->magic);
+  /* timdat left as zero.  */
+  /* Copy ClassID.  */
+  memcpy (hdr + offsetof (struct external_filehdr_bigobj, classid),
+         bigobj_magic, 16);
+  /* sizeofdata, flags, metadatasize, metadataoffset left as zero.  */
+  set_32 (hdr + offsetof (struct external_filehdr_bigobj, nscns), nscns);
+  set_32 (hdr + offsetof (struct external_filehdr_bigobj, symptr),
+         symtab_offset);
+  set_32 (hdr + offsetof (struct external_filehdr_bigobj, nsyms), nsyms);
+
+  return simple_object_internal_write (descriptor, 0, hdrbuf,
+                                      sizeof (struct external_filehdr_bigobj),
+                                      errmsg, err);
+}
+
 /* Write out a COFF filehdr.  */
 
 static int
@@ -618,14 +805,16 @@ simple_object_coff_write_to_file (simple_object_write *sobj, int descriptor,
      what 'gas' uses when told to assemble from stdin.  */
   const char *source_filename = "fake";
   size_t sflen;
-  union
-  {
-    struct external_syment sym;
-    union external_auxent aux;
-  } syms[2];
+  size_t symsize;
   void (*set_16) (unsigned char *, unsigned short);
   void (*set_32) (unsigned char *, unsigned int);
 
+  /* Determine symbol size based on format.  */
+  if (attrs->is_bigobj)
+    symsize = sizeof (struct external_syment_bigobj);
+  else
+    symsize = sizeof (struct external_syment);
+
   set_16 = (attrs->is_big_endian
            ? simple_object_set_big_16
            : simple_object_set_little_16);
@@ -637,7 +826,10 @@ simple_object_coff_write_to_file (simple_object_write *sobj, int descriptor,
   for (section = sobj->sections; section != NULL; section = section->next)
     ++nscns;
 
-  scnhdr_offset = sizeof (struct external_filehdr);
+  if (attrs->is_bigobj)
+    scnhdr_offset = sizeof (struct external_filehdr_bigobj);
+  else
+    scnhdr_offset = sizeof (struct external_filehdr);
   offset = scnhdr_offset + nscns * sizeof (struct external_scnhdr);
   name_offset = 4;
   for (section = sobj->sections; section != NULL; section = section->next)
@@ -693,91 +885,198 @@ simple_object_coff_write_to_file (simple_object_write *sobj, int descriptor,
   symtab_offset = offset;
   /* Advance across space reserved for symbol table to locate
      start of string table.  */
-  offset += nsyms * sizeof (struct external_syment);
+  offset += nsyms * symsize;
 
   /* Write out file symbol.  */
-  memset (&syms[0], 0, sizeof (syms));
-  strcpy ((char *)&syms[0].sym.e.e_name[0], ".file");
-  set_16 (&syms[0].sym.e_scnum[0], IMAGE_SYM_DEBUG);
-  set_16 (&syms[0].sym.e_type[0], IMAGE_SYM_TYPE);
-  syms[0].sym.e_sclass[0] = IMAGE_SYM_CLASS_FILE;
-  syms[0].sym.e_numaux[0] = 1;
-  /* The name need not be nul-terminated if it fits into the x_fname field
-     directly, but must be if it has to be placed into the string table.  */
-  sflen = strlen (source_filename);
-  if (sflen <= E_FILNMLEN)
-    memcpy (&syms[1].aux.x_file.x_fname[0], source_filename, sflen);
-  else
+  if (attrs->is_bigobj)
     {
-      set_32 (&syms[1].aux.x_file.x_n.x_offset[0], name_offset);
-      if (!simple_object_internal_write (descriptor, offset + name_offset,
-                                        ((const unsigned char *)
-                                         source_filename),
-                                        sflen + 1, &errmsg, err))
+      union
+      {
+       struct external_syment_bigobj sym;
+       union external_auxent_bigobj aux;
+      } syms[2];
+
+      memset (&syms[0], 0, sizeof (syms));
+      strcpy ((char *)&syms[0].sym.e.e_name[0], ".file");
+      set_32 (&syms[0].sym.e_scnum[0], IMAGE_SYM_DEBUG);
+      set_16 (&syms[0].sym.e_type[0], IMAGE_SYM_TYPE);
+      syms[0].sym.e_sclass[0] = IMAGE_SYM_CLASS_FILE;
+      syms[0].sym.e_numaux[0] = 1;
+      /* The name need not be nul-terminated if it fits into the x_fname field
+        directly, but must be if it has to be placed into the string table.  */
+      sflen = strlen (source_filename);
+      if (sflen <= E_FILNMLEN)
+       memcpy (&syms[1].aux.x_file.x_fname[0], source_filename, sflen);
+      else
+       {
+         set_32 (&syms[1].aux.x_file.x_n.x_offset[0], name_offset);
+         if (!simple_object_internal_write (descriptor, offset + name_offset,
+                                            ((const unsigned char *)
+                                             source_filename),
+                                            sflen + 1, &errmsg, err))
+           return errmsg;
+         name_offset += strlen (source_filename) + 1;
+       }
+      if (!simple_object_internal_write (descriptor, symtab_offset,
+                                        (const unsigned char *) &syms[0],
+                                        sizeof (syms), &errmsg, err))
        return errmsg;
-      name_offset += strlen (source_filename) + 1;
-    }
-  if (!simple_object_internal_write (descriptor, symtab_offset,
-                                    (const unsigned char *) &syms[0],
-                                    sizeof (syms), &errmsg, err))
-    return errmsg;
-
-  /* Write the string table length, followed by the strings and section
-     symbols in step with each other.  */
-  set_32 (strsizebuf, name_offset);
-  if (!simple_object_internal_write (descriptor, offset, strsizebuf, 4,
-                                    &errmsg, err))
-    return errmsg;
 
-  name_offset = 4;
-  secsym_offset = symtab_offset + sizeof (syms);
-  memset (&syms[0], 0, sizeof (syms));
-  set_16 (&syms[0].sym.e_type[0], IMAGE_SYM_TYPE);
-  syms[0].sym.e_sclass[0] = IMAGE_SYM_CLASS_STATIC;
-  syms[0].sym.e_numaux[0] = 1;
-  secnum = 1;
+      /* Write the string table length, followed by the strings and section
+        symbols in step with each other.  */
+      set_32 (strsizebuf, name_offset);
+      if (!simple_object_internal_write (descriptor, offset, strsizebuf, 4,
+                                        &errmsg, err))
+       return errmsg;
 
-  for (section = sobj->sections; section != NULL; section = section->next)
-    {
-      size_t namelen;
-      size_t scnsize;
-      struct simple_object_write_section_buffer *buffer;
+      name_offset = 4;
+      secsym_offset = symtab_offset + sizeof (syms);
+      memset (&syms[0], 0, sizeof (syms));
+      set_16 (&syms[0].sym.e_type[0], IMAGE_SYM_TYPE);
+      syms[0].sym.e_sclass[0] = IMAGE_SYM_CLASS_STATIC;
+      syms[0].sym.e_numaux[0] = 1;
+      secnum = 1;
 
-      namelen = strlen (section->name);
-      set_16 (&syms[0].sym.e_scnum[0], secnum++);
-      scnsize = 0;
-      for (buffer = section->buffers; buffer != NULL; buffer = buffer->next)
-       scnsize += buffer->size;
-      set_32 (&syms[1].aux.x_scn.x_scnlen[0], scnsize);
-      if (namelen > SCNNMLEN)
+      for (section = sobj->sections; section != NULL; section = section->next)
        {
-         set_32 (&syms[0].sym.e.e.e_zeroes[0], 0);
-         set_32 (&syms[0].sym.e.e.e_offset[0], name_offset);
-         if (!simple_object_internal_write (descriptor, offset + name_offset,
-                                            ((const unsigned char *)
-                                             section->name),
-                                            namelen + 1, &errmsg, err))
+         size_t namelen;
+         size_t scnsize;
+         struct simple_object_write_section_buffer *buffer;
+
+         namelen = strlen (section->name);
+         set_32 (&syms[0].sym.e_scnum[0], secnum++);
+         scnsize = 0;
+         for (buffer = section->buffers; buffer != NULL; buffer = buffer->next)
+           scnsize += buffer->size;
+         set_32 (&syms[1].aux.x_scn.x_scnlen[0], scnsize);
+         if (namelen > SCNNMLEN)
+           {
+             set_32 (&syms[0].sym.e.e.e_zeroes[0], 0);
+             set_32 (&syms[0].sym.e.e.e_offset[0], name_offset);
+             if (!simple_object_internal_write (descriptor, offset + name_offset,
+                                                ((const unsigned char *)
+                                                 section->name),
+                                                namelen + 1, &errmsg, err))
+               return errmsg;
+             name_offset += namelen + 1;
+           }
+         else
+           {
+             memcpy (&syms[0].sym.e.e_name[0], section->name,
+                     strlen (section->name));
+             memset (&syms[0].sym.e.e_name[strlen (section->name)], 0,
+                     E_SYMNMLEN - strlen (section->name));
+           }
+
+         if (!simple_object_internal_write (descriptor, secsym_offset,
+                                            (const unsigned char *) &syms[0],
+                                            sizeof (syms), &errmsg, err))
            return errmsg;
-         name_offset += namelen + 1;
+         secsym_offset += sizeof (syms);
        }
+    }
+  else
+    {
+      /* Regular COFF.  */
+      union
+      {
+       struct external_syment sym;
+       union external_auxent aux;
+      } syms[2];
+
+      memset (&syms[0], 0, sizeof (syms));
+      strcpy ((char *)&syms[0].sym.e.e_name[0], ".file");
+      set_16 (&syms[0].sym.e_scnum[0], IMAGE_SYM_DEBUG);
+      set_16 (&syms[0].sym.e_type[0], IMAGE_SYM_TYPE);
+      syms[0].sym.e_sclass[0] = IMAGE_SYM_CLASS_FILE;
+      syms[0].sym.e_numaux[0] = 1;
+      /* The name need not be nul-terminated if it fits into the x_fname field
+        directly, but must be if it has to be placed into the string table.  */
+      sflen = strlen (source_filename);
+      if (sflen <= E_FILNMLEN)
+       memcpy (&syms[1].aux.x_file.x_fname[0], source_filename, sflen);
       else
        {
-         memcpy (&syms[0].sym.e.e_name[0], section->name,
-                 strlen (section->name));
-         memset (&syms[0].sym.e.e_name[strlen (section->name)], 0,
-                 E_SYMNMLEN - strlen (section->name));
+         set_32 (&syms[1].aux.x_file.x_n.x_offset[0], name_offset);
+         if (!simple_object_internal_write (descriptor, offset + name_offset,
+                                            ((const unsigned char *)
+                                             source_filename),
+                                            sflen + 1, &errmsg, err))
+           return errmsg;
+         name_offset += strlen (source_filename) + 1;
        }
-
-      if (!simple_object_internal_write (descriptor, secsym_offset,
+      if (!simple_object_internal_write (descriptor, symtab_offset,
                                         (const unsigned char *) &syms[0],
                                         sizeof (syms), &errmsg, err))
        return errmsg;
-      secsym_offset += sizeof (syms);
+
+      /* Write the string table length, followed by the strings and section
+        symbols in step with each other.  */
+      set_32 (strsizebuf, name_offset);
+      if (!simple_object_internal_write (descriptor, offset, strsizebuf, 4,
+                                        &errmsg, err))
+       return errmsg;
+
+      name_offset = 4;
+      secsym_offset = symtab_offset + sizeof (syms);
+      memset (&syms[0], 0, sizeof (syms));
+      set_16 (&syms[0].sym.e_type[0], IMAGE_SYM_TYPE);
+      syms[0].sym.e_sclass[0] = IMAGE_SYM_CLASS_STATIC;
+      syms[0].sym.e_numaux[0] = 1;
+      secnum = 1;
+
+      for (section = sobj->sections; section != NULL; section = section->next)
+       {
+         size_t namelen;
+         size_t scnsize;
+         struct simple_object_write_section_buffer *buffer;
+
+         namelen = strlen (section->name);
+         set_16 (&syms[0].sym.e_scnum[0], secnum++);
+         scnsize = 0;
+         for (buffer = section->buffers; buffer != NULL; buffer = buffer->next)
+           scnsize += buffer->size;
+         set_32 (&syms[1].aux.x_scn.x_scnlen[0], scnsize);
+         if (namelen > SCNNMLEN)
+           {
+             set_32 (&syms[0].sym.e.e.e_zeroes[0], 0);
+             set_32 (&syms[0].sym.e.e.e_offset[0], name_offset);
+             if (!simple_object_internal_write (descriptor, offset + name_offset,
+                                                ((const unsigned char *)
+                                                 section->name),
+                                                namelen + 1, &errmsg, err))
+               return errmsg;
+             name_offset += namelen + 1;
+           }
+         else
+           {
+             memcpy (&syms[0].sym.e.e_name[0], section->name,
+                     strlen (section->name));
+             memset (&syms[0].sym.e.e_name[strlen (section->name)], 0,
+                     E_SYMNMLEN - strlen (section->name));
+           }
+
+         if (!simple_object_internal_write (descriptor, secsym_offset,
+                                            (const unsigned char *) &syms[0],
+                                            sizeof (syms), &errmsg, err))
+           return errmsg;
+         secsym_offset += sizeof (syms);
+       }
     }
 
-  if (!simple_object_coff_write_filehdr (sobj, descriptor, nscns,
-                                        symtab_offset, nsyms, &errmsg, err))
-    return errmsg;
+  if (attrs->is_bigobj)
+    {
+      if (!simple_object_coff_write_filehdr_bigobj (sobj, descriptor, nscns,
+                                                    symtab_offset, nsyms,
+                                                    &errmsg, err))
+       return errmsg;
+    }
+  else
+    {
+      if (!simple_object_coff_write_filehdr (sobj, descriptor, nscns,
+                                            symtab_offset, nsyms, &errmsg, err))
+       return errmsg;
+    }
 
   return NULL;
 }
index 3e98c7c778688b453647086e9bc33a3f8371c7e7..3e81d6f908a0a2596ec807a029df208429661650 100644 (file)
@@ -617,7 +617,6 @@ simple_object_mach_o_segment (simple_object_read *sobj, off_t offset,
       char *name;
       off_t secoffset;
       size_t secsize;
-      int l;
 
       sechdr = secdata + i * sechdrsize;
 
@@ -669,12 +668,15 @@ simple_object_mach_o_segment (simple_object_read *sobj, off_t offset,
            }
        }
 
+      memset (namebuf, 0, sizeof (namebuf));
+      /* Copy the section name so we can append a null to make it into a
+        c-string (Mach-o section names are not terminated).  */
+      memcpy (namebuf, sechdr + sectname_offset, MACH_O_NAME_LEN);
+      namebuf[MACH_O_NAME_LEN] = '\0';
+      name = &namebuf[0];
+      /* Maybe override this if we have long section name extension.  */
       if ((gnu_sections_found & SOMO_LONGN_PRESENT) != 0)
        {
-         memcpy (namebuf, sechdr + sectname_offset, MACH_O_NAME_LEN);
-         namebuf[MACH_O_NAME_LEN] = '\0';
-
-         name = &namebuf[0];
          if (strtab != NULL && name[0] == '_' && name[1] == '_')
            {
              unsigned long stringoffset;
@@ -696,19 +698,6 @@ simple_object_mach_o_segment (simple_object_read *sobj, off_t offset,
                }
          }
        }
-      else
-       {
-          /* Otherwise, make a name like __segment,__section as per the
-             convention in mach-o asm.  */
-         name = &namebuf[0];
-         memcpy (namebuf, (char *) sechdr + segname_offset, MACH_O_NAME_LEN);
-         namebuf[MACH_O_NAME_LEN] = '\0';
-         l = strlen (namebuf);
-         namebuf[l] = ',';
-         memcpy (namebuf + l + 1, (char *) sechdr + sectname_offset,
-                 MACH_O_NAME_LEN);
-         namebuf[l + 1 + MACH_O_NAME_LEN] = '\0';
-       }
 
       simple_object_mach_o_section_info (omr->is_big_endian, is_32, sechdr,
                                         &secoffset, &secsize);
index 0f7b97a6d0ad414ac59f74cc7a6407ca47c5c31a..e5cd8ec8a7764e84ef1d4ae7ff3b2e58a5525e65 100644 (file)
@@ -1709,3 +1709,10 @@ void S::bar<5, int>(this S, int)
 
 _ZNH1S3bazERKS_
 S::baz(this S const&)
+
+_Z3fooUlvE_
+foo({lambda()#1})
+
+# P2115R0 unnamed enums
+_Z3fooUei1ES_
+foo({enum:int{E}}, {enum:int{E}})