From: Nick Clifton Date: Wed, 7 Jan 2026 11:33:07 +0000 (+0000) Subject: Sync libiberty sources with gcc master version X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8872d02b0f1216d12bdc34a4b5e71157b4e1aa25;p=thirdparty%2Fbinutils-gdb.git Sync libiberty sources with gcc master version --- diff --git a/include/demangle.h b/include/demangle.h index 7e01a116f91..e9165d6b083 100644 --- a/include/demangle.h +++ b/include/demangle.h @@ -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, diff --git a/include/libiberty.h b/include/libiberty.h index 7960d802b66..1af4fa86101 100644 --- a/include/libiberty.h +++ b/include/libiberty.h @@ -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 . */ 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 diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index b072d0bed52..37c351d33f5 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -1,3 +1,57 @@ +2025-11-30 Jose E. Marchesi + + * simple-object-mach-o.c + (simple_object_mach_o_segment): Handle non-LTO sections. + +2025-11-06 Peter Damianov + + 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 + + * configure: Regenerate. + +2025-10-02 H.J. Lu + + * aclocal.m4: Regenerated. + * configure: Likewise. + * configure.ac: Synced from binutils-gdb. + +2025-08-17 Nathaniel Shead + + 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 + + * cp-demangle.c (d_encoding): Fix a comment typo, whaever -> whatever. + 2025-08-06 Matthieu Longo * testsuite/test-doubly-linked-list.c: disable debug logging on diff --git a/libiberty/Makefile.in b/libiberty/Makefile.in index 6d8c88ebfe7..00af4acca66 100644 --- a/libiberty/Makefile.in +++ b/libiberty/Makefile.in @@ -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 \ diff --git a/libiberty/acinclude.m4 b/libiberty/acinclude.m4 index 49f621bf629..a8f2146b0f5 100644 --- a/libiberty/acinclude.m4 +++ b/libiberty/acinclude.m4 @@ -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. diff --git a/libiberty/aclocal.m4 b/libiberty/aclocal.m4 index 46cefc36edc..5151f5fee18 100644 --- a/libiberty/aclocal.m4 +++ b/libiberty/aclocal.m4 @@ -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]) diff --git a/libiberty/configure b/libiberty/configure index 4c72b5a9283..359f19ac037 100755 --- a/libiberty/configure +++ b/libiberty/configure @@ -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 diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c index e3c9ca10434..5e6571d419b 100644 --- a/libiberty/cp-demangle.c +++ b/libiberty/cp-demangle.c @@ -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; } +/* ::= Ue */ + +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; +} + /* ::= [ . ] [ . ]* */ @@ -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 "); diff --git a/libiberty/simple-object-coff.c b/libiberty/simple-object-coff.c index 2cc94495a13..648036921ac 100644 --- a/libiberty/simple-object-coff.c +++ b/libiberty/simple-object-coff.c @@ -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; } diff --git a/libiberty/simple-object-mach-o.c b/libiberty/simple-object-mach-o.c index 3e98c7c7786..3e81d6f908a 100644 --- a/libiberty/simple-object-mach-o.c +++ b/libiberty/simple-object-mach-o.c @@ -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); diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected index 0f7b97a6d0a..e5cd8ec8a77 100644 --- a/libiberty/testsuite/demangle-expected +++ b/libiberty/testsuite/demangle-expected @@ -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}})