Sync libiberty sources with gcc master version

This commit is contained in:
Nick Clifton 2026-01-07 11:33:07 +00:00
parent e0f0649602
commit 8872d02b0f
No known key found for this signature in database
11 changed files with 521 additions and 128 deletions

View 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,

View 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

View 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

View 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 \

View 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.

View 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])

5
libiberty/configure vendored
View file

@ -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

View 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 ");

View 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;
strtab_offset = sobj->offset + ocr->symptr
+ ocr->nsyms * sizeof (struct external_syment);
/* 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 * 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))
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;
union
{
struct external_syment_bigobj sym;
union external_auxent_bigobj aux;
} syms[2];
/* 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;
}
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
{
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_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;
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
{
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;
/* 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;
}

View 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);

View 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}})