diff options
author | Jing Yu <jingyu@google.com> | 2012-02-15 15:40:16 -0800 |
---|---|---|
committer | Jing Yu <jingyu@google.com> | 2012-02-15 15:40:16 -0800 |
commit | 3f73d6ef90458b45bbbb33ef4c2b174d4662a22d (patch) | |
tree | 1b5f0d96c51b51168b3713058a1b62e92f1136eb /gcc-4.6/libiberty | |
parent | d7030123e04baab5dbff9c9ee04c0de99bd9a774 (diff) | |
download | toolchain_gcc-3f73d6ef90458b45bbbb33ef4c2b174d4662a22d.tar.gz toolchain_gcc-3f73d6ef90458b45bbbb33ef4c2b174d4662a22d.tar.bz2 toolchain_gcc-3f73d6ef90458b45bbbb33ef4c2b174d4662a22d.zip |
Sync down FSF r184235@google/gcc-4_6_2-mobile branch
1) Get mostly new patches from FSF gcc-4.6 branch
2) Fix PR52129
3) Insert GNU-stack note for all ARM targets
Change-Id: I2b9926981210e517e4021242908074319a91d6bd
Diffstat (limited to 'gcc-4.6/libiberty')
-rw-r--r-- | gcc-4.6/libiberty/ChangeLog | 38 | ||||
-rw-r--r-- | gcc-4.6/libiberty/cp-demangle.c | 57 | ||||
-rw-r--r-- | gcc-4.6/libiberty/simple-object-mach-o.c | 515 | ||||
-rw-r--r-- | gcc-4.6/libiberty/testsuite/demangle-expected | 47 | ||||
-rw-r--r-- | gcc-4.6/libiberty/testsuite/test-expandargv.c | 7 |
5 files changed, 576 insertions, 88 deletions
diff --git a/gcc-4.6/libiberty/ChangeLog b/gcc-4.6/libiberty/ChangeLog index d2ab674ea..fb2b7348c 100644 --- a/gcc-4.6/libiberty/ChangeLog +++ b/gcc-4.6/libiberty/ChangeLog @@ -1,3 +1,35 @@ +2011-11-13 Iain Sandoe <iains@gcc.gnu.org> + + PR target/48108 + Backport from mainline r180523 + * simple-object-mach-o.c (GNU_WRAPPER_SECTS, GNU_WRAPPER_INDEX, + GNU_WRAPPER_NAMES): New macros. + (simple_object_mach_o_segment): Handle wrapper scheme. + (simple_object_mach_o_write_section_header): Allow the segment name + to be supplied. + (simple_object_mach_o_write_segment): Handle wrapper scheme. Ensure + that the top-level segment name in the load command is empty. + (simple_object_mach_o_write_to_file): Determine the number of + sections during segment output, use that in writing the header. + +2011-10-26 Release Manager + + * GCC 4.6.2 released. + +2011-09-23 Cary Coutant <ccoutant@google.com> + + PR 40831 + * cp-demangle.c (d_make_comp): Add new component type. + (cplus_demangle_mangled_name): Check for clone suffixes. + (d_parmlist): Don't error out if we see '.'. + (d_clone_suffix): New function. + (d_print_comp): Print info for clone suffixes. + * testsuite/demangle-expected: Add new testcases. + +2011-08-06 Uros Bizjak <ubizjak@gmail.com> + + * testsuite/test-expandargv.c (writeout_test): Check result of fwrite. + 2011-06-27 Release Manager * GCC 4.6.1 released. @@ -514,7 +546,7 @@ 2009-04-29 Julian Brown <julian@codesourcery.com> - * pex-win32.c (pex_win32_pipe): Add _O_NOINHERIT. + * pex-win32.c (pex_win32_pipe): Add _O_NOINHERIT. (pex_win32_exec_child): Ensure each process has only one handle open on pipe endpoints. Close standard input after creating child for symmetry with standard output/standard error. @@ -532,7 +564,7 @@ section, so that the native build does detect them at configure time. * configure: Regenerated. - + 2009-04-13 Ozkan Sezer <sezeroz@gmail.com> PR target/39397 @@ -632,7 +664,7 @@ 2008-10-08 David Edelsohn <edelsohn@gnu.org> * xstrdup.c: Include <sys/types.h> after "config.h" - + 2008-10-07 Jan Kratochvil <jan.kratochvil@redhat.com> * configure.ac: Call AC_SYS_LARGEFILE. diff --git a/gcc-4.6/libiberty/cp-demangle.c b/gcc-4.6/libiberty/cp-demangle.c index 7e951cc78..179197cf1 100644 --- a/gcc-4.6/libiberty/cp-demangle.c +++ b/gcc-4.6/libiberty/cp-demangle.c @@ -419,6 +419,9 @@ static struct demangle_component *d_lambda (struct d_info *); static struct demangle_component *d_unnamed_type (struct d_info *); +static struct demangle_component * +d_clone_suffix (struct d_info *, struct demangle_component *); + static int d_add_substitution (struct d_info *, struct demangle_component *); @@ -804,6 +807,7 @@ d_make_comp (struct d_info *di, enum demangle_component_type type, case DEMANGLE_COMPONENT_LITERAL_NEG: case DEMANGLE_COMPONENT_COMPOUND_NAME: case DEMANGLE_COMPONENT_VECTOR_TYPE: + case DEMANGLE_COMPONENT_CLONE: if (left == NULL || right == NULL) return NULL; break; @@ -1036,7 +1040,7 @@ d_make_sub (struct d_info *di, const char *name, int len) return p; } -/* <mangled-name> ::= _Z <encoding> +/* <mangled-name> ::= _Z <encoding> [<clone-suffix>]* TOP_LEVEL is non-zero when called at the top level. */ @@ -1044,6 +1048,8 @@ CP_STATIC_IF_GLIBCPP_V3 struct demangle_component * cplus_demangle_mangled_name (struct d_info *di, int top_level) { + struct demangle_component *p; + if (! d_check_char (di, '_') /* Allow missing _ if not at toplevel to work around a bug in G++ abi-version=2 mangling; see the comment in @@ -1052,7 +1058,18 @@ cplus_demangle_mangled_name (struct d_info *di, int top_level) return NULL; if (! d_check_char (di, 'Z')) return NULL; - return d_encoding (di, top_level); + p = d_encoding (di, top_level); + + /* If at top level and parsing parameters, check for a clone + suffix. */ + if (top_level && (di->options & DMGL_PARAMS) != 0) + while (d_peek_char (di) == '.' + && (IS_LOWER (d_peek_next_char (di)) + || d_peek_next_char (di) == '_' + || IS_DIGIT (d_peek_next_char (di)))) + p = d_clone_suffix (di, p); + + return p; } /* Return whether a function should have a return type. The argument @@ -2346,7 +2363,7 @@ d_parmlist (struct d_info *di) struct demangle_component *type; char peek = d_peek_char (di); - if (peek == '\0' || peek == 'E') + if (peek == '\0' || peek == 'E' || peek == '.') break; type = cplus_demangle_type (di); if (type == NULL) @@ -3066,6 +3083,33 @@ d_unnamed_type (struct d_info *di) return ret; } +/* <clone-suffix> ::= [ . <clone-type-identifier> ] [ . <nonnegative number> ]* +*/ + +static struct demangle_component * +d_clone_suffix (struct d_info *di, struct demangle_component *encoding) +{ + const char *suffix = d_str (di); + const char *pend = suffix; + struct demangle_component *n; + + if (*pend == '.' && (IS_LOWER (pend[1]) || pend[1] == '_')) + { + pend += 2; + while (IS_LOWER (*pend) || *pend == '_') + ++pend; + } + while (*pend == '.' && IS_DIGIT (pend[1])) + { + pend += 2; + while (IS_DIGIT (*pend)) + ++pend; + } + d_advance (di, pend - suffix); + n = d_make_name (di, suffix, pend - suffix); + return d_make_comp (di, DEMANGLE_COMPONENT_CLONE, encoding, n); +} + /* Add a new substitution. */ static int @@ -4343,6 +4387,13 @@ d_print_comp (struct d_print_info *dpi, d_append_char (dpi, '}'); return; + case DEMANGLE_COMPONENT_CLONE: + d_print_comp (dpi, d_left (dc)); + d_append_string (dpi, " [clone "); + d_print_comp (dpi, d_right (dc)); + d_append_char (dpi, ']'); + return; + default: d_print_error (dpi); return; diff --git a/gcc-4.6/libiberty/simple-object-mach-o.c b/gcc-4.6/libiberty/simple-object-mach-o.c index bbbbd09de..af5e4f9ca 100644 --- a/gcc-4.6/libiberty/simple-object-mach-o.c +++ b/gcc-4.6/libiberty/simple-object-mach-o.c @@ -1,5 +1,5 @@ /* simple-object-mach-o.c -- routines to manipulate Mach-O object files. - Copyright 2010 Free Software Foundation, Inc. + Copyright 2010, 2011 Free Software Foundation, Inc. Written by Ian Lance Taylor, Google. This program is free software; you can redistribute it and/or modify it @@ -174,6 +174,15 @@ struct mach_o_section_64 #define GNU_SECTION_NAMES "__section_names" +/* A GNU-specific extension to wrap multiple sections using three + mach-o sections within a given segment. The section '__wrapper_sects' + is subdivided according to the index '__wrapper_index' and each sub + sect is named according to the names supplied in '__wrapper_names'. */ + +#define GNU_WRAPPER_SECTS "__wrapper_sects" +#define GNU_WRAPPER_INDEX "__wrapper_index" +#define GNU_WRAPPER_NAMES "__wrapper_names" + /* Private data for an simple_object_read. */ struct simple_object_mach_o_read @@ -214,7 +223,18 @@ struct simple_object_mach_o_attributes unsigned int reserved; }; -/* See if we have a Mach-O file. */ +/* See if we have a Mach-O MH_OBJECT file: + + A standard MH_OBJECT (from as) will have three load commands: + 0 - LC_SEGMENT/LC_SEGMENT64 + 1 - LC_SYMTAB + 2 - LC_DYSYMTAB + + The LC_SEGMENT/LC_SEGMENT64 will introduce a single anonymous segment + containing all the sections. + + Files written by simple-object will have only the segment command + (no symbol tables). */ static void * simple_object_mach_o_match ( @@ -356,8 +376,29 @@ simple_object_mach_o_section_info (int is_big_endian, int is_32, } } -/* Handle a segment in a Mach-O file. Return 1 if we should continue, - 0 if the caller should return. */ +/* Handle a segment in a Mach-O Object file. + + This will callback to the function pfn for each "section found" the meaning + of which depends on gnu extensions to mach-o: + + If we find mach-o sections (with the segment name as specified) which also + contain: a 'sects' wrapper, an index, and a name table, we expand this into + as many sections as are specified in the index. In this case, there will + be a callback for each of these. + + We will also allow an extension that permits long names (more than 16 + characters) to be used with mach-o. In this case, the section name has + a specific format embedding an index into a name table, and the file must + contain such name table. + + Return 1 if we should continue, 0 if the caller should return. */ + +#define SOMO_SECTS_PRESENT 0x01 +#define SOMO_INDEX_PRESENT 0x02 +#define SOMO_NAMES_PRESENT 0x04 +#define SOMO_LONGN_PRESENT 0x08 +#define SOMO_WRAPPING (SOMO_SECTS_PRESENT | SOMO_INDEX_PRESENT \ + | SOMO_NAMES_PRESENT) static int simple_object_mach_o_segment (simple_object_read *sobj, off_t offset, @@ -378,9 +419,20 @@ simple_object_mach_o_segment (simple_object_read *sobj, off_t offset, unsigned int nsects; unsigned char *secdata; unsigned int i; + unsigned int gnu_sections_found; unsigned int strtab_index; + unsigned int index_index; + unsigned int nametab_index; + unsigned int sections_index; char *strtab; + char *nametab; + unsigned char *index; size_t strtab_size; + size_t nametab_size; + size_t index_size; + unsigned int n_wrapped_sects; + size_t wrapper_sect_size; + off_t wrapper_sect_offset; fetch_32 = (omr->is_big_endian ? simple_object_fetch_big_32 @@ -409,6 +461,8 @@ simple_object_mach_o_segment (simple_object_read *sobj, off_t offset, nsects)); } + /* Fetch the section headers from the segment command. */ + secdata = XNEWVEC (unsigned char, nsects * sechdrsize); if (!simple_object_internal_read (sobj->descriptor, offset + seghdrsize, secdata, nsects * sechdrsize, errmsg, err)) @@ -417,9 +471,13 @@ simple_object_mach_o_segment (simple_object_read *sobj, off_t offset, return 0; } - /* Scan for a __section_names section. This is in effect a GNU - extension that permits section names longer than 16 chars. */ + /* Scan for special sections that signal GNU extensions to the format. */ + gnu_sections_found = 0; + index_index = nsects; + sections_index = nsects; + strtab_index = nsects; + nametab_index = nsects; for (i = 0; i < nsects; ++i) { size_t nameoff; @@ -427,19 +485,104 @@ simple_object_mach_o_segment (simple_object_read *sobj, off_t offset, nameoff = i * sechdrsize + segname_offset; if (strcmp ((char *) secdata + nameoff, omr->segment_name) != 0) continue; + nameoff = i * sechdrsize + sectname_offset; - if (strcmp ((char *) secdata + nameoff, GNU_SECTION_NAMES) == 0) - break; + if (strcmp ((char *) secdata + nameoff, GNU_WRAPPER_NAMES) == 0) + { + nametab_index = i; + gnu_sections_found |= SOMO_NAMES_PRESENT; + } + else if (strcmp ((char *) secdata + nameoff, GNU_WRAPPER_INDEX) == 0) + { + index_index = i; + gnu_sections_found |= SOMO_INDEX_PRESENT; + } + else if (strcmp ((char *) secdata + nameoff, GNU_WRAPPER_SECTS) == 0) + { + sections_index = i; + gnu_sections_found |= SOMO_SECTS_PRESENT; + } + else if (strcmp ((char *) secdata + nameoff, GNU_SECTION_NAMES) == 0) + { + strtab_index = i; + gnu_sections_found |= SOMO_LONGN_PRESENT; + } } - strtab_index = i; - if (strtab_index >= nsects) + /* If any of the special wrapper section components is present, then + they all should be. */ + + if ((gnu_sections_found & SOMO_WRAPPING) != 0) { - strtab = NULL; - strtab_size = 0; + off_t nametab_offset; + off_t index_offset; + + if ((gnu_sections_found & SOMO_WRAPPING) != SOMO_WRAPPING) + { + *errmsg = "GNU Mach-o section wrapper: required section missing"; + *err = 0; /* No useful errno. */ + XDELETEVEC (secdata); + return 0; + } + + /* Fetch the name table. */ + + simple_object_mach_o_section_info (omr->is_big_endian, is_32, + secdata + nametab_index * sechdrsize, + &nametab_offset, &nametab_size); + nametab = XNEWVEC (char, nametab_size); + if (!simple_object_internal_read (sobj->descriptor, + sobj->offset + nametab_offset, + (unsigned char *) nametab, nametab_size, + errmsg, err)) + { + XDELETEVEC (nametab); + XDELETEVEC (secdata); + return 0; + } + + /* Fetch the index. */ + + simple_object_mach_o_section_info (omr->is_big_endian, is_32, + secdata + index_index * sechdrsize, + &index_offset, &index_size); + index = XNEWVEC (unsigned char, index_size); + if (!simple_object_internal_read (sobj->descriptor, + sobj->offset + index_offset, + index, index_size, + errmsg, err)) + { + XDELETEVEC (index); + XDELETEVEC (nametab); + XDELETEVEC (secdata); + return 0; + } + + /* The index contains 4 unsigned ints per sub-section: + sub-section offset/length, sub-section name/length. + We fix this for both 32 and 64 bit mach-o for now, since + other fields limit the maximum size of an object to 4G. */ + n_wrapped_sects = index_size / 16; + + /* Get the parameters for the wrapper too. */ + simple_object_mach_o_section_info (omr->is_big_endian, is_32, + secdata + sections_index * sechdrsize, + &wrapper_sect_offset, + &wrapper_sect_size); } else { + index = NULL; + index_size = 0; + nametab = NULL; + nametab_size = 0; + n_wrapped_sects = 0; + } + + /* If we have a long names section, fetch it. */ + + if ((gnu_sections_found & SOMO_LONGN_PRESENT) != 0) + { off_t strtab_offset; simple_object_mach_o_section_info (omr->is_big_endian, is_32, @@ -452,52 +595,120 @@ simple_object_mach_o_segment (simple_object_read *sobj, off_t offset, errmsg, err)) { XDELETEVEC (strtab); + XDELETEVEC (index); + XDELETEVEC (nametab); XDELETEVEC (secdata); return 0; } } + else + { + strtab = NULL; + strtab_size = 0; + strtab_index = nsects; + } /* Process the sections. */ for (i = 0; i < nsects; ++i) { const unsigned char *sechdr; - char namebuf[MACH_O_NAME_LEN + 1]; + char namebuf[MACH_O_NAME_LEN * 2 + 2]; char *name; off_t secoffset; size_t secsize; + int l; - if (i == strtab_index) + sechdr = secdata + i * sechdrsize; + + /* We've already processed the long section names. */ + + if ((gnu_sections_found & SOMO_LONGN_PRESENT) != 0 + && i == strtab_index) continue; - sechdr = secdata + i * sechdrsize; + /* We only act on the segment named. */ if (strcmp ((char *) sechdr + segname_offset, omr->segment_name) != 0) continue; - memcpy (namebuf, sechdr + sectname_offset, MACH_O_NAME_LEN); - namebuf[MACH_O_NAME_LEN] = '\0'; + /* Process sections associated with the wrapper. */ - name = &namebuf[0]; - if (strtab != NULL && name[0] == '_' && name[1] == '_') + if ((gnu_sections_found & SOMO_WRAPPING) != 0) { - unsigned long stringoffset; + if (i == nametab_index || i == index_index) + continue; - if (sscanf (name + 2, "%08lX", &stringoffset) == 1) + if (i == sections_index) { - if (stringoffset >= strtab_size) + unsigned int j; + for (j = 0; j < n_wrapped_sects; ++j) { - *errmsg = "section name offset out of range"; - *err = 0; - XDELETEVEC (strtab); - XDELETEVEC (secdata); - return 0; + unsigned int subsect_offset, subsect_length, name_offset; + subsect_offset = (*fetch_32) (index + 16 * j); + subsect_length = (*fetch_32) (index + 16 * j + 4); + name_offset = (*fetch_32) (index + 16 * j + 8); + /* We don't need the name_length yet. */ + + secoffset = wrapper_sect_offset + subsect_offset; + secsize = subsect_length; + name = nametab + name_offset; + + if (!(*pfn) (data, name, secoffset, secsize)) + { + *errmsg = NULL; + *err = 0; + XDELETEVEC (index); + XDELETEVEC (nametab); + XDELETEVEC (strtab); + XDELETEVEC (secdata); + return 0; + } } - - name = strtab + stringoffset; + continue; } } + 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; + + if (sscanf (name + 2, "%08lX", &stringoffset) == 1) + { + if (stringoffset >= strtab_size) + { + *errmsg = "section name offset out of range"; + *err = 0; + XDELETEVEC (index); + XDELETEVEC (nametab); + XDELETEVEC (strtab); + XDELETEVEC (secdata); + return 0; + } + + name = strtab + stringoffset; + } + } + } + else + { + /* Otherwise, make a name like __segment,__section as per the + convention in mach-o asm. */ + name = &namebuf[0]; + memset (namebuf, 0, MACH_O_NAME_LEN * 2 + 2); + memcpy (namebuf, (char *) sechdr + segname_offset, MACH_O_NAME_LEN); + l = strlen (namebuf); + namebuf[l] = ','; + memcpy (namebuf + l + 1, (char *) sechdr + sectname_offset, + MACH_O_NAME_LEN); + } + simple_object_mach_o_section_info (omr->is_big_endian, is_32, sechdr, &secoffset, &secsize); @@ -505,12 +716,16 @@ simple_object_mach_o_segment (simple_object_read *sobj, off_t offset, { *errmsg = NULL; *err = 0; + XDELETEVEC (index); + XDELETEVEC (nametab); XDELETEVEC (strtab); XDELETEVEC (secdata); return 0; } } + XDELETEVEC (index); + XDELETEVEC (nametab); XDELETEVEC (strtab); XDELETEVEC (secdata); @@ -724,9 +939,9 @@ static int simple_object_mach_o_write_section_header (simple_object_write *sobj, int descriptor, size_t sechdr_offset, - const char *name, size_t secaddr, - size_t secsize, size_t offset, - unsigned int align, + const char *name, const char *segn, + size_t secaddr, size_t secsize, + size_t offset, unsigned int align, const char **errmsg, int *err) { struct simple_object_mach_o_attributes *attrs = @@ -748,7 +963,7 @@ simple_object_mach_o_write_section_header (simple_object_write *sobj, strncpy ((char *) hdr + offsetof (struct mach_o_section_32, sectname), name, MACH_O_NAME_LEN); strncpy ((char *) hdr + offsetof (struct mach_o_section_32, segname), - sobj->segment_name, MACH_O_NAME_LEN); + segn, MACH_O_NAME_LEN); set_32 (hdr + offsetof (struct mach_o_section_32, addr), secaddr); set_32 (hdr + offsetof (struct mach_o_section_32, size), secsize); set_32 (hdr + offsetof (struct mach_o_section_32, offset), offset); @@ -773,7 +988,7 @@ simple_object_mach_o_write_section_header (simple_object_write *sobj, strncpy ((char *) hdr + offsetof (struct mach_o_section_64, sectname), name, MACH_O_NAME_LEN); strncpy ((char *) hdr + offsetof (struct mach_o_section_64, segname), - sobj->segment_name, MACH_O_NAME_LEN); + segn, MACH_O_NAME_LEN); set_64 (hdr + offsetof (struct mach_o_section_64, addr), secaddr); set_64 (hdr + offsetof (struct mach_o_section_64, size), secsize); set_32 (hdr + offsetof (struct mach_o_section_64, offset), offset); @@ -793,11 +1008,25 @@ simple_object_mach_o_write_section_header (simple_object_write *sobj, sechdrsize, errmsg, err); } -/* Write out the single segment and the sections of a Mach-O file. */ +/* Write out the single (anonymous) segment containing the sections of a Mach-O + Object file. + + As a GNU extension to mach-o, when the caller specifies a segment name in + sobj->segment_name, all the sections passed will be output under a single + mach-o section header. The caller's sections are indexed within this + 'wrapper' section by a table stored in a second mach-o section. Finally, + arbitrary length section names are permitted by the extension and these are + stored in a table in a third mach-o section. + + Note that this is only likely to make any sense for the __GNU_LTO segment + at present. + + If the wrapper extension is not in force, we assume that the section name + is in the form __SEGMENT_NAME,__section_name as per Mach-O asm. */ static int simple_object_mach_o_write_segment (simple_object_write *sobj, int descriptor, - size_t nsects, const char **errmsg, + size_t *nsects, const char **errmsg, int *err) { struct simple_object_mach_o_attributes *attrs = @@ -814,6 +1043,10 @@ simple_object_mach_o_write_segment (simple_object_write *sobj, int descriptor, simple_object_write_section *section; unsigned char hdrbuf[sizeof (struct mach_o_segment_command_64)]; unsigned char *hdr; + size_t nsects_in; + unsigned int *index; + char *snames; + unsigned int sect; set_32 = (attrs->is_big_endian ? simple_object_set_big_32 @@ -834,19 +1067,62 @@ simple_object_mach_o_write_segment (simple_object_write *sobj, int descriptor, sechdrsize = sizeof (struct mach_o_section_64); } + name_offset = 0; + *nsects = nsects_in = 0; + + /* Count the number of sections we start with. */ + + for (section = sobj->sections; section != NULL; section = section->next) + nsects_in++; + + if (sobj->segment_name != NULL) + { + /* We will only write 3 sections: wrapped data, index and names. */ + + *nsects = 3; + + /* The index has four entries per wrapped section: + Section Offset, length, Name offset, length. + Where the offsets are based at the start of the wrapper and name + sections respectively. + The values are stored as 32 bit int for both 32 and 64 bit mach-o + since the size of a mach-o MH_OBJECT cannot exceed 4G owing to + other constraints. */ + + index = XNEWVEC (unsigned int, nsects_in * 4); + + /* We now need to figure out the size of the names section. This just + stores the names as null-terminated c strings, packed without any + alignment padding. */ + + for (section = sobj->sections, sect = 0; section != NULL; + section = section->next, sect++) + { + index[sect*4+2] = name_offset; + index[sect*4+3] = strlen (section->name) + 1; + name_offset += strlen (section->name) + 1; + } + snames = XNEWVEC (char, name_offset); + } + else + { + *nsects = nsects_in; + index = NULL; + snames = NULL; + } + sechdr_offset = hdrsize + seghdrsize; - cmdsize = seghdrsize + nsects * sechdrsize; + cmdsize = seghdrsize + *nsects * sechdrsize; offset = hdrsize + cmdsize; - name_offset = 0; secaddr = 0; - for (section = sobj->sections; section != NULL; section = section->next) + for (section = sobj->sections, sect = 0; + section != NULL; section = section->next, sect++) { size_t mask; size_t new_offset; size_t secsize; struct simple_object_write_section_buffer *buffer; - char namebuf[MACH_O_NAME_LEN + 1]; mask = (1U << section->align) - 1; new_offset = offset + mask; @@ -877,39 +1153,126 @@ simple_object_mach_o_write_segment (simple_object_write *sobj, int descriptor, secsize += buffer->size; } - snprintf (namebuf, sizeof namebuf, "__%08X", name_offset); + if (sobj->segment_name != NULL) + { + index[sect*4+0] = (unsigned int) offset; + index[sect*4+1] = secsize; + /* Stash the section name in our table. */ + memcpy (snames + index[sect * 4 + 2], section->name, + index[sect * 4 + 3]); + } + else + { + char namebuf[MACH_O_NAME_LEN + 1]; + char segnbuf[MACH_O_NAME_LEN + 1]; + char *comma; + + /* Try to extract segment,section from the input name. */ + + memset (namebuf, 0, sizeof namebuf); + memset (segnbuf, 0, sizeof segnbuf); + comma = strchr (section->name, ','); + if (comma != NULL) + { + int len = comma - section->name; + len = len > MACH_O_NAME_LEN ? MACH_O_NAME_LEN : len; + strncpy (namebuf, section->name, len); + strncpy (segnbuf, comma + 1, MACH_O_NAME_LEN); + } + else /* just try to copy the name, leave segment blank. */ + strncpy (namebuf, section->name, MACH_O_NAME_LEN); + + if (!simple_object_mach_o_write_section_header (sobj, descriptor, + sechdr_offset, + namebuf, segnbuf, + secaddr, secsize, + offset, + section->align, + errmsg, err)) + return 0; + sechdr_offset += sechdrsize; + } + + offset += secsize; + secaddr += secsize; + } + + if (sobj->segment_name != NULL) + { + size_t secsize; + unsigned int i; + + /* Write the section header for the wrapper. */ + /* Account for any initial aligment - which becomes the alignment for this + created section. */ + + secsize = (offset - index[0]); if (!simple_object_mach_o_write_section_header (sobj, descriptor, - sechdr_offset, namebuf, - secaddr, secsize, offset, - section->align, + sechdr_offset, + GNU_WRAPPER_SECTS, + sobj->segment_name, + 0 /*secaddr*/, + secsize, index[0], + sobj->sections->align, errmsg, err)) return 0; + /* Subtract the wrapper section start from the begining of each sub + section. */ + + for (i = 1; i < nsects_in; ++i) + index[4 * i] -= index[0]; + index[0] = 0; + sechdr_offset += sechdrsize; - offset += secsize; - name_offset += strlen (section->name) + 1; - secaddr += secsize; - } - /* Write out the section names. */ + /* Write out the section names. + ... the header ... + name_offset contains the length of the section. It is not aligned. */ - if (!simple_object_mach_o_write_section_header (sobj, descriptor, - sechdr_offset, - GNU_SECTION_NAMES, secaddr, - name_offset, offset, 0, - errmsg, err)) - return 0; + if (!simple_object_mach_o_write_section_header (sobj, descriptor, + sechdr_offset, + GNU_WRAPPER_NAMES, + sobj->segment_name, + 0 /*secaddr*/, + name_offset, + offset, + 0, errmsg, err)) + return 0; - for (section = sobj->sections; section != NULL; section = section->next) - { - size_t namelen; + /* ... and the content.. */ + if (!simple_object_internal_write (descriptor, offset, + (const unsigned char *) snames, + name_offset, errmsg, err)) + return 0; + + sechdr_offset += sechdrsize; + secaddr += name_offset; + offset += name_offset; + + /* Now do the index, we'll align this to 4 bytes although the read code + will handle unaligned. */ + + offset += 3; + offset &= ~0x03; + if (!simple_object_mach_o_write_section_header (sobj, descriptor, + sechdr_offset, + GNU_WRAPPER_INDEX, + sobj->segment_name, + 0 /*secaddr*/, + nsects_in * 16, + offset, + 2, errmsg, err)) + return 0; - namelen = strlen (section->name) + 1; + /* ... and the content.. */ if (!simple_object_internal_write (descriptor, offset, - (const unsigned char *) section->name, - namelen, errmsg, err)) + (const unsigned char *) index, + nsects_in*16, errmsg, err)) return 0; - offset += namelen; + + XDELETEVEC (index); + XDELETEVEC (snames); } /* Write out the segment header. */ @@ -923,9 +1286,8 @@ simple_object_mach_o_write_segment (simple_object_write *sobj, int descriptor, MACH_O_LC_SEGMENT); set_32 (hdr + offsetof (struct mach_o_segment_command_32, cmdsize), cmdsize); - strncpy (((char *) hdr - + offsetof (struct mach_o_segment_command_32, segname)), - sobj->segment_name, MACH_O_NAME_LEN); + /* MH_OBJECTS have a single, anonymous, segment - so the segment name + is left empty. */ /* vmaddr left as zero. */ /* vmsize left as zero. */ set_32 (hdr + offsetof (struct mach_o_segment_command_32, fileoff), @@ -935,7 +1297,7 @@ simple_object_mach_o_write_segment (simple_object_write *sobj, int descriptor, /* maxprot left as zero. */ /* initprot left as zero. */ set_32 (hdr + offsetof (struct mach_o_segment_command_32, nsects), - nsects); + *nsects); /* flags left as zero. */ } else @@ -951,9 +1313,8 @@ simple_object_mach_o_write_segment (simple_object_write *sobj, int descriptor, MACH_O_LC_SEGMENT); set_32 (hdr + offsetof (struct mach_o_segment_command_64, cmdsize), cmdsize); - strncpy (((char *) hdr - + offsetof (struct mach_o_segment_command_64, segname)), - sobj->segment_name, MACH_O_NAME_LEN); + /* MH_OBJECTS have a single, anonymous, segment - so the segment name + is left empty. */ /* vmaddr left as zero. */ /* vmsize left as zero. */ set_64 (hdr + offsetof (struct mach_o_segment_command_64, fileoff), @@ -963,7 +1324,7 @@ simple_object_mach_o_write_segment (simple_object_write *sobj, int descriptor, /* maxprot left as zero. */ /* initprot left as zero. */ set_32 (hdr + offsetof (struct mach_o_segment_command_64, nsects), - nsects); + *nsects); /* flags left as zero. */ #endif } @@ -978,23 +1339,17 @@ static const char * simple_object_mach_o_write_to_file (simple_object_write *sobj, int descriptor, int *err) { - size_t nsects; - simple_object_write_section *section; + size_t nsects = 0; const char *errmsg; - /* Start at 1 for symbol_names section. */ - nsects = 1; - for (section = sobj->sections; section != NULL; section = section->next) - ++nsects; + if (!simple_object_mach_o_write_segment (sobj, descriptor, &nsects, + &errmsg, err)) + return errmsg; if (!simple_object_mach_o_write_header (sobj, descriptor, nsects, &errmsg, err)) return errmsg; - if (!simple_object_mach_o_write_segment (sobj, descriptor, nsects, - &errmsg, err)) - return errmsg; - return NULL; } diff --git a/gcc-4.6/libiberty/testsuite/demangle-expected b/gcc-4.6/libiberty/testsuite/demangle-expected index 5ce0377b1..74dbe8fda 100644 --- a/gcc-4.6/libiberty/testsuite/demangle-expected +++ b/gcc-4.6/libiberty/testsuite/demangle-expected @@ -4092,3 +4092,50 @@ DFA --format=auto _ZN3Psi7VariantIIcPKcEE5visitIIRZN11VariantTest9TestVisit11test_methodEvEUlS2_E0_RZNS6_11test_methodEvEUlcE1_RZNS6_11test_methodEvEUlNS_4NoneEE_EEENS_13VariantDetail19SelectVisitorResultIIDpT_EE4typeEDpOSG_ Psi::VariantDetail::SelectVisitorResult<VariantTest::TestVisit::test_method()::{lambda(char const*)#2}&, VariantTest::TestVisit::test_method()::{lambda(char)#3}&, VariantTest::TestVisit::test_method()::{lambda(Psi::None)#1}&>::type Psi::Variant<char, char const*>::visit<VariantTest::TestVisit::test_method()::{lambda(char const*)#2}&, VariantTest::TestVisit::test_method()::{lambda(char)#3}&, VariantTest::TestVisit::test_method()::{lambda(Psi::None)#1}&>((VariantTest::TestVisit::test_method()::{lambda(Psi::None)#1}&&&)...) +# +# Clone suffix tests +# +--format=gnu-v3 --no-params +_Z3fo5n.clone.1 +fo5(__int128) [clone .clone.1] +fo5 +# +--format=gnu-v3 --no-params +_Z3fo5n.constprop.2 +fo5(__int128) [clone .constprop.2] +fo5 +# +--format=gnu-v3 --no-params +_Z3fo5n.isra.3 +fo5(__int128) [clone .isra.3] +fo5 +# +--format=gnu-v3 --no-params +_Z3fo5n.part.4 +fo5(__int128) [clone .part.4] +fo5 +# +--format=gnu-v3 --no-params +_Z12to_be_clonediPv.clone.0 +to_be_cloned(int, void*) [clone .clone.0] +to_be_cloned +# +--format=gnu-v3 --no-params +_Z3fooi.1988 +foo(int) [clone .1988] +foo +# +--format=gnu-v3 --no-params +_Z3fooi.part.9.165493.constprop.775.31805 +foo(int) [clone .part.9.165493] [clone .constprop.775.31805] +foo +# +--format=gnu-v3 --no-params +_Z2f1IiEvT_S0_S0_._omp_fn.2 +void f1<int>(int, int, int) [clone ._omp_fn.2] +f1<int> +# +--format=gnu-v3 --no-params +_Z3fooi._omp_cpyfn.6 +foo(int) [clone ._omp_cpyfn.6] +foo diff --git a/gcc-4.6/libiberty/testsuite/test-expandargv.c b/gcc-4.6/libiberty/testsuite/test-expandargv.c index c16a0322a..dc44a1750 100644 --- a/gcc-4.6/libiberty/testsuite/test-expandargv.c +++ b/gcc-4.6/libiberty/testsuite/test-expandargv.c @@ -189,7 +189,7 @@ writeout_test (int test, const char * test_data) { char filename[256]; FILE *fd; - size_t len; + size_t len, sys_fwrite; char * parse; /* Unique filename per test */ @@ -208,7 +208,10 @@ writeout_test (int test, const char * test_data) /* Run all possible replaces */ run_replaces (parse); - fwrite (parse, len, sizeof (char), fd); + sys_fwrite = fwrite (parse, sizeof (char), len, fd); + if (sys_fwrite != len) + fatal_error (__LINE__, "Failed to write to test file.", errno); + free (parse); fclose (fd); } |