diff -uNr gcc-5.1.0.orig/gcc/config/darwin-c.c gcc-5.1.0/gcc/config/darwin-c.c --- gcc-5.1.0.orig/gcc/config/darwin-c.c 2015-01-09 15:18:42.000000000 -0500 +++ gcc-5.1.0/gcc/config/darwin-c.c 2015-04-28 18:51:01.000000000 -0400 @@ -599,42 +599,180 @@ return 0; } -/* Return the value of darwin_macosx_version_min suitable for the - __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ macro, so '10.4.2' - becomes 1040 and '10.10.0' becomes 101000. The lowest digit is - always zero, as is the second lowest for '10.10.x' and above. - Print a warning if the version number can't be understood. */ +/* Given a version string, return the version as a statically-allocated + array of three non-negative integers. If the version string is + invalid, return null. + + Version strings must consist of one, two, or three tokens, each + separated by a single period. Each token must contain only the + characters '0' through '9' and is converted to an equivalent + integer. Omitted tokens are treated as zeros. For example: + + "10" becomes {10,0,0} + "10.10" becomes {10,10,0} + "10.10.1" becomes {10,10,1} + "10.000010.1" becomes {10,10,1} + "10.010.001" becomes {10,10,1} + "000010.10.00001" becomes {10,10,1} */ + +enum version_components { MAJOR, MINOR, TINY }; + +static const unsigned long * +parse_version (const char *version_str) +{ + size_t version_len; + char *end; + static unsigned long version_array[3]; + + if (! version_str) + return NULL; + + version_len = strlen (version_str); + if (version_len < 1) + return NULL; + + /* Version string must consist of digits and periods only. */ + if (strspn (version_str, "0123456789.") != version_len) + return NULL; + + if (! ISDIGIT (version_str[0]) || ! ISDIGIT (version_str[version_len - 1])) + return NULL; + + version_array[MAJOR] = strtoul (version_str, &end, 10); + version_str = end + ((*end == '.') ? 1 : 0); + + /* Version string must not contain adjacent periods. */ + if (*version_str == '.') + return NULL; + + version_array[MINOR] = strtoul (version_str, &end, 10); + version_str = end + ((*end == '.') ? 1 : 0); + + version_array[TINY] = strtoul (version_str, &end, 10); + + /* Version string must contain no more than three tokens. */ + if (*end != '\0') + return NULL; + + return version_array; +} + +/* Given a three-component version represented as an array of + non-negative integers, return a statically-allocated string suitable + for the legacy __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ macro. + If the version is invalid and cannot be coerced into a valid form, + return null. + + The legacy format is a four-character string -- two chars for the + major number and one each for the minor and tiny numbers. Major + numbers are zero-padded if necessary. Minor and tiny numbers from + 10 through 99 are permitted but are clamped to 9 (for example, + {10,9,10} produces "1099"). Versions containing numbers greater + than 99 are rejected. */ + static const char * -version_as_macro (void) +version_as_legacy_macro (const unsigned long *version) { - static char result[7] = "1000"; - int minorDigitIdx; + unsigned long major, minor, tiny; + static char result[sizeof "9999"]; + + if (! version) + return NULL; + + major = version[MAJOR]; + minor = version[MINOR]; + tiny = version[TINY]; + + if (major > 99 || minor > 99 || tiny > 99) + return NULL; + + minor = ((minor > 9) ? 9 : minor); + tiny = ((tiny > 9) ? 9 : tiny); + + /* NOTE: Cast result of sizeof so that result of sprintf is not + converted to an unsigned type. */ + if (sprintf (result, "%02lu%lu%lu", major, minor, tiny) + != (int) sizeof "9999" - 1) + return NULL; - if (strncmp (darwin_macosx_version_min, "10.", 3) != 0) + return result; +} + +/* Given a three-component version represented as an array of + non-negative integers, return a statically-allocated string suitable + for the modern __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ macro + or the __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ macro. If the + version is invalid, return null. + + The modern format is a five- or six-character string -- one or two + chars for the major number and two each for the minor and tiny + numbers, which are zero-padded if necessary (for example, {8,1,0} + produces "80100", and {10,10,1} produces "101001"). Versions + containing numbers greater than 99 are rejected. */ + +static const char * +version_as_modern_macro (const unsigned long *version) +{ + unsigned long major, minor, tiny; + static char result[sizeof "999999"]; + + if (! version) + return NULL; + + major = version[MAJOR]; + minor = version[MINOR]; + tiny = version[TINY]; + + if (major > 99 || minor > 99 || tiny > 99) + return NULL; + + /* NOTE: 'sizeof ((x > y) ? "foo" : "bar")' returns size of char + pointer instead of char array, so use + '(x > y) ? sizeof "foo" : sizeof "bar"' instead. */ + /* NOTE: Cast result of sizeof so that result of sprintf is not + converted to an unsigned type. */ + if (sprintf (result, "%lu%02lu%02lu", major, minor, tiny) + != (int) ((major > 9) ? sizeof "999999" : sizeof "99999") - 1) + return NULL; + + return result; +} + +/* Return the value of darwin_macosx_version_min, suitably formatted + for the __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ macro. Values + representing OS X 10.9 and earlier are encoded using the legacy + four-character format, while 10.10 and later use a modern + six-character format. (For example, "10.9" produces "1090", and + "10.10.1" produces "101001".) If the value is invalid and cannot be + coerced into a valid form, print a warning and return "1000". */ + +static const char * +macosx_version_as_macro (void) +{ + const unsigned long *version_array; + const char *version_macro; + + version_array = parse_version (darwin_macosx_version_min); + if (! version_array) goto fail; - if (! ISDIGIT (darwin_macosx_version_min[3])) + + /* Do not assume that the major number will always be exactly 10. */ + if (version_array[MAJOR] < 10 || version_array[MAJOR] > 10) goto fail; - minorDigitIdx = 3; - result[2] = darwin_macosx_version_min[minorDigitIdx++]; - if (ISDIGIT (darwin_macosx_version_min[minorDigitIdx])) - { - /* Starting with OS X 10.10, the macro ends '00' rather than '0', - i.e. 10.10.x becomes 101000 rather than 10100. */ - result[3] = darwin_macosx_version_min[minorDigitIdx++]; - result[4] = '0'; - result[5] = '0'; - result[6] = '\0'; - } - if (darwin_macosx_version_min[minorDigitIdx] != '\0' - && darwin_macosx_version_min[minorDigitIdx] != '.') + if (version_array[MAJOR] == 10 && version_array[MINOR] < 10) + version_macro = version_as_legacy_macro (version_array); + else + version_macro = version_as_modern_macro (version_array); + + if (! version_macro) goto fail; - return result; + return version_macro; fail: error ("unknown value %qs of -mmacosx-version-min", - darwin_macosx_version_min); + darwin_macosx_version_min); return "1000"; } @@ -656,7 +794,7 @@ builtin_define ("__CONSTANT_CFSTRINGS__"); builtin_define_with_value ("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", - version_as_macro(), false); + macosx_version_as_macro(), false); /* Since we do not (at 4.6) support ObjC gc for the NeXT runtime, the following will cause a syntax error if one tries to compile gc attributed diff -uNr gcc-5.1.0.orig/gcc/config/darwin.h gcc-5.1.0/gcc/config/darwin.h --- gcc-5.1.0.orig/gcc/config/darwin.h 2015-01-15 15:11:12.000000000 -0500 +++ gcc-5.1.0/gcc/config/darwin.h 2015-04-28 18:51:01.000000000 -0400 @@ -911,9 +911,8 @@ darwin_driver_init (&decoded_options_count, &decoded_options) #endif -/* The Apple assembler and linker do not support constructor priorities. */ -#undef SUPPORTS_INIT_PRIORITY -#define SUPPORTS_INIT_PRIORITY 0 +/* While the Apple assembler and linker do not support constructor priorities, + intra-module priority support is available through sort_cdtor_records. */ /* When building cross-compilers (and native crosses) we shall default to providing an osx-version-min of this unless overridden by the User. */ diff -uNr gcc-5.1.0.orig/gcc/config/darwin.opt gcc-5.1.0/gcc/config/darwin.opt --- gcc-5.1.0.orig/gcc/config/darwin.opt 2015-01-05 07:33:28.000000000 -0500 +++ gcc-5.1.0/gcc/config/darwin.opt 2015-04-28 18:51:29.000000000 -0400 @@ -155,6 +155,9 @@ pthread Driver +rdynamic +Driver + seg_addr_table Driver Separate Alias(Zseg_addr_table) diff -uNr gcc-5.1.0.orig/gcc/config/darwin12.h gcc-5.1.0/gcc/config/darwin12.h --- gcc-5.1.0.orig/gcc/config/darwin12.h 1969-12-31 19:00:00.000000000 -0500 +++ gcc-5.1.0/gcc/config/darwin12.h 2015-04-28 18:51:29.000000000 -0400 @@ -0,0 +1,27 @@ +/* Target definitions for Darwin (Mac OS X) systems. + Copyright (C) 2009-2015 Free Software Foundation, Inc. + Contributed by Jack Howarth . + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#undef LINK_GCC_C_SEQUENCE_SPEC +#define LINK_GCC_C_SEQUENCE_SPEC \ +"%:version-compare(>= 10.6 mmacosx-version-min= -no_compact_unwind) \ + %{rdynamic:-export_dynamic} %{!static:%{!static-libgcc: \ + %:version-compare(>= 10.6 mmacosx-version-min= -lSystem) } } \ + %{fno-pic|fno-PIC|fno-pie|fno-PIE|fapple-kext|mkernel|static|mdynamic-no-pic: \ + %:version-compare(>= 10.7 mmacosx-version-min= -no_pie) } %G %L" diff -uNr gcc-5.1.0.orig/gcc/config.gcc gcc-5.1.0/gcc/config.gcc --- gcc-5.1.0.orig/gcc/config.gcc 2015-03-10 05:50:41.000000000 -0400 +++ gcc-5.1.0/gcc/config.gcc 2015-04-28 18:51:29.000000000 -0400 @@ -605,9 +605,12 @@ *-*-darwin9*) tm_file="${tm_file} darwin9.h" ;; - *-*-darwin[12][0-9]*) + *-*-darwin[1][01]*) tm_file="${tm_file} darwin9.h darwin10.h" ;; + *-*-darwin[1][2-9]* | *-*-darwin[2][0-9]*) + tm_file="${tm_file} darwin9.h darwin10.h darwin12.h" + ;; esac tm_file="${tm_file} ${cpu_type}/darwin.h" tm_p_file="${tm_p_file} darwin-protos.h" diff -uNr gcc-5.1.0.orig/gcc/testsuite/g++.dg/special/conpr-3.C gcc-5.1.0/gcc/testsuite/g++.dg/special/conpr-3.C --- gcc-5.1.0.orig/gcc/testsuite/g++.dg/special/conpr-3.C 2007-02-25 13:47:05.000000000 -0500 +++ gcc-5.1.0/gcc/testsuite/g++.dg/special/conpr-3.C 2015-04-28 18:51:01.000000000 -0400 @@ -1,5 +1,6 @@ /* { dg-do run { target init_priority } } */ /* { dg-additional-sources "conpr-3a.cc conpr-3b.cc" } */ +/* { dg-shouldfail "No inter-module priority support" { *-apple-darwin* } } */ #include diff -uNr gcc-5.1.0.orig/gcc/testsuite/gcc.dg/darwin-minversion-10.c gcc-5.1.0/gcc/testsuite/gcc.dg/darwin-minversion-10.c --- gcc-5.1.0.orig/gcc/testsuite/gcc.dg/darwin-minversion-10.c 1969-12-31 19:00:00.000000000 -0500 +++ gcc-5.1.0/gcc/testsuite/gcc.dg/darwin-minversion-10.c 2015-04-28 18:51:01.000000000 -0400 @@ -0,0 +1,16 @@ +/* PR target/63810: Test that a version with a zero-padded minor + number < 10 and a zero-padded tiny number < 10 produces the correct + four-character macro. */ +/* Added by Lawrence Velázquez . */ + +/* { dg-options "-mmacosx-version-min=10.07.02" } */ +/* { dg-do compile { target *-*-darwin* } } */ + +int +main () +{ +#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ != 1072 + fail me; +#endif + return 0; +} diff -uNr gcc-5.1.0.orig/gcc/testsuite/gcc.dg/darwin-minversion-11.c gcc-5.1.0/gcc/testsuite/gcc.dg/darwin-minversion-11.c --- gcc-5.1.0.orig/gcc/testsuite/gcc.dg/darwin-minversion-11.c 1969-12-31 19:00:00.000000000 -0500 +++ gcc-5.1.0/gcc/testsuite/gcc.dg/darwin-minversion-11.c 2015-04-28 18:51:01.000000000 -0400 @@ -0,0 +1,15 @@ +/* PR target/63810: Test that a version with outrageous zero-padding and + a minor number > 9 still produces a six-character macro. */ +/* Added by Lawrence Velázquez . */ + +/* { dg-options "-mmacosx-version-min=00010.010.0000098" } */ +/* { dg-do compile { target *-*-darwin* } } */ + +int +main () +{ +#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ != 101098 + fail me; +#endif + return 0; +} diff -uNr gcc-5.1.0.orig/gcc/testsuite/gcc.dg/darwin-minversion-12.c gcc-5.1.0/gcc/testsuite/gcc.dg/darwin-minversion-12.c --- gcc-5.1.0.orig/gcc/testsuite/gcc.dg/darwin-minversion-12.c 1969-12-31 19:00:00.000000000 -0500 +++ gcc-5.1.0/gcc/testsuite/gcc.dg/darwin-minversion-12.c 2015-04-28 18:51:01.000000000 -0400 @@ -0,0 +1,15 @@ +/* PR target/63810: Test that a version with outrageous zero-padding and + a minor number < 10 still produces a four-character macro. */ +/* Added by Lawrence Velázquez . */ + +/* { dg-options "-mmacosx-version-min=010.008.000031" } */ +/* { dg-do compile { target *-*-darwin* } } */ + +int +main () +{ +#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ != 1089 + fail me; +#endif + return 0; +} diff -uNr gcc-5.1.0.orig/gcc/testsuite/gcc.dg/darwin-minversion-3.c gcc-5.1.0/gcc/testsuite/gcc.dg/darwin-minversion-3.c --- gcc-5.1.0.orig/gcc/testsuite/gcc.dg/darwin-minversion-3.c 2014-09-14 04:05:43.000000000 -0400 +++ gcc-5.1.0/gcc/testsuite/gcc.dg/darwin-minversion-3.c 2015-04-28 18:51:01.000000000 -0400 @@ -1,11 +1,11 @@ -/* Test that most-minor versions greater than 9 work. */ -/* { dg-options "-mmacosx-version-min=10.4.10" } */ +/* Test that most minor versions < 10 work. */ +/* { dg-options "-mmacosx-version-min=10.4.1" } */ /* { dg-do compile { target *-*-darwin* } } */ int main () { -#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ != 1040 +#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ != 1041 fail me; #endif return 0; diff -uNr gcc-5.1.0.orig/gcc/testsuite/gcc.dg/darwin-minversion-4.c gcc-5.1.0/gcc/testsuite/gcc.dg/darwin-minversion-4.c --- gcc-5.1.0.orig/gcc/testsuite/gcc.dg/darwin-minversion-4.c 2014-09-14 04:05:43.000000000 -0400 +++ gcc-5.1.0/gcc/testsuite/gcc.dg/darwin-minversion-4.c 2015-04-28 18:51:01.000000000 -0400 @@ -1,11 +1,11 @@ -/* Test that major versions greater than 9 work and have the additional 0. */ -/* { dg-options "-mmacosx-version-min=10.10.0" } */ +/* Test that minor versions > 9 produce a six-character macro. */ +/* { dg-options "-mmacosx-version-min=10.10.1" } */ /* { dg-do compile { target *-*-darwin* } } */ int main () { -#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ != 101000 +#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ != 101001 fail me; #endif return 0; diff -uNr gcc-5.1.0.orig/gcc/testsuite/gcc.dg/darwin-minversion-5.c gcc-5.1.0/gcc/testsuite/gcc.dg/darwin-minversion-5.c --- gcc-5.1.0.orig/gcc/testsuite/gcc.dg/darwin-minversion-5.c 1969-12-31 19:00:00.000000000 -0500 +++ gcc-5.1.0/gcc/testsuite/gcc.dg/darwin-minversion-5.c 2015-04-28 18:51:01.000000000 -0400 @@ -0,0 +1,16 @@ +/* PR target/63810: Test that a version with minor number < 10 and tiny + number > 9 produces a four-character macro with the tiny number + clamped to 9. */ +/* Added by Lawrence Velázquez . */ + +/* { dg-options "-mmacosx-version-min=10.9.10" } */ +/* { dg-do compile { target *-*-darwin* } } */ + +int +main () +{ +#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ != 1099 + fail me; +#endif + return 0; +} diff -uNr gcc-5.1.0.orig/gcc/testsuite/gcc.dg/darwin-minversion-6.c gcc-5.1.0/gcc/testsuite/gcc.dg/darwin-minversion-6.c --- gcc-5.1.0.orig/gcc/testsuite/gcc.dg/darwin-minversion-6.c 1969-12-31 19:00:00.000000000 -0500 +++ gcc-5.1.0/gcc/testsuite/gcc.dg/darwin-minversion-6.c 2015-04-28 18:51:01.000000000 -0400 @@ -0,0 +1,15 @@ +/* PR target/63810: Test that tiny numbers are preserved in + six-character macros. */ +/* Added by Lawrence Velázquez . */ + +/* { dg-options "-mmacosx-version-min=10.10.11" } */ +/* { dg-do compile { target *-*-darwin* } } */ + +int +main () +{ +#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ != 101011 + fail me; +#endif + return 0; +} diff -uNr gcc-5.1.0.orig/gcc/testsuite/gcc.dg/darwin-minversion-7.c gcc-5.1.0/gcc/testsuite/gcc.dg/darwin-minversion-7.c --- gcc-5.1.0.orig/gcc/testsuite/gcc.dg/darwin-minversion-7.c 1969-12-31 19:00:00.000000000 -0500 +++ gcc-5.1.0/gcc/testsuite/gcc.dg/darwin-minversion-7.c 2015-04-28 18:51:01.000000000 -0400 @@ -0,0 +1,15 @@ +/* PR target/63810: Test that tiny numbers < 10 are preserved in + four-character macros. */ +/* Added by Lawrence Velázquez . */ + +/* { dg-options "-mmacosx-version-min=10.9.1" } */ +/* { dg-do compile { target *-*-darwin* } } */ + +int +main () +{ +#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ != 1091 + fail me; +#endif + return 0; +} diff -uNr gcc-5.1.0.orig/gcc/testsuite/gcc.dg/darwin-minversion-8.c gcc-5.1.0/gcc/testsuite/gcc.dg/darwin-minversion-8.c --- gcc-5.1.0.orig/gcc/testsuite/gcc.dg/darwin-minversion-8.c 1969-12-31 19:00:00.000000000 -0500 +++ gcc-5.1.0/gcc/testsuite/gcc.dg/darwin-minversion-8.c 2015-04-28 18:51:01.000000000 -0400 @@ -0,0 +1,15 @@ +/* PR target/63810: Test that a version with minor number > 9 and no + tiny number produces a six-character macro ending in "00". */ +/* Added by Lawrence Velázquez . */ + +/* { dg-options "-mmacosx-version-min=10.11" } */ +/* { dg-do compile { target *-*-darwin* } } */ + +int +main () +{ +#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ != 101100 + fail me; +#endif + return 0; +} diff -uNr gcc-5.1.0.orig/gcc/testsuite/gcc.dg/darwin-minversion-9.c gcc-5.1.0/gcc/testsuite/gcc.dg/darwin-minversion-9.c --- gcc-5.1.0.orig/gcc/testsuite/gcc.dg/darwin-minversion-9.c 1969-12-31 19:00:00.000000000 -0500 +++ gcc-5.1.0/gcc/testsuite/gcc.dg/darwin-minversion-9.c 2015-04-28 18:51:01.000000000 -0400 @@ -0,0 +1,15 @@ +/* PR target/63810: Test that a version with a zero-padded minor + number < 10 produces a four-character macro. */ +/* Added by Lawrence Velázquez . */ + +/* { dg-options "-mmacosx-version-min=10.08.4" } */ +/* { dg-do compile { target *-*-darwin* } } */ + +int +main () +{ +#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ != 1084 + fail me; +#endif + return 0; +} diff -uNr gcc-5.1.0.orig/libatomic/config/darwin/host-config.h gcc-5.1.0/libatomic/config/darwin/host-config.h --- gcc-5.1.0.orig/libatomic/config/darwin/host-config.h 1969-12-31 19:00:00.000000000 -0500 +++ gcc-5.1.0/libatomic/config/darwin/host-config.h 2015-04-28 18:51:01.000000000 -0400 @@ -0,0 +1,55 @@ +/* Copyright (C) 2012-2014 Free Software Foundation, Inc. + Contributed by Richard Henderson . + + This file is part of the GNU Atomic Library (libatomic). + + Libatomic is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Libatomic is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + . */ + +/* Included after all more target-specific host-config.h. */ + + +#ifndef protect_start_end +# ifdef HAVE_ATTRIBUTE_VISIBILITY +# pragma GCC visibility push(hidden) +# endif + +void libat_lock_1 (void *ptr); +void libat_unlock_1 (void *ptr); + +static inline UWORD +protect_start (void *ptr) +{ + libat_lock_1 (ptr); + return 0; +} + +static inline void +protect_end (void *ptr, UWORD dummy UNUSED) +{ + libat_unlock_1 (ptr); +} + +# define protect_start_end 1 +# ifdef HAVE_ATTRIBUTE_VISIBILITY +# pragma GCC visibility pop +# endif +#endif /* protect_start_end */ + +#include_next diff -uNr gcc-5.1.0.orig/libatomic/config/darwin/lock.c gcc-5.1.0/libatomic/config/darwin/lock.c --- gcc-5.1.0.orig/libatomic/config/darwin/lock.c 1969-12-31 19:00:00.000000000 -0500 +++ gcc-5.1.0/libatomic/config/darwin/lock.c 2015-04-28 18:51:01.000000000 -0400 @@ -0,0 +1,248 @@ +/* Copyright (C) 2014 Free Software Foundation, Inc. + Contributed by Iain Sandoe . + + This file is part of the GNU Atomic Library (libatomic). + + Libatomic is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Libatomic is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + . */ + +#include +#include "libatomic_i.h" + +#include +#include + +/* For items that must be guarded by a lock, we use the following strategy: + If atomic support is available for a unit32_t we use that. + If not, we use the Darwin OSSpinLock implementation. */ + +/* Algorithm motivations. + +Layout Assumptions: + o Darwin has a number of sub-targets with common atomic types that have no + 'native' in-line handling, but are smaller than a cache-line. + E.G. PPC32 needs locking for >= 8byte quantities, X86/m32 for >=16. + + o The _Atomic alignment of a "natural type" is no greater than the type size. + + o There are no special guarantees about the alignment of _Atomic aggregates + other than those determined by the psABI. + + o There are no guarantees that placement of an entity won't cause it to + straddle a cache-line boundary. + + o Realistic User code will likely place several _Atomic qualified types in + close proximity (such that they fall within the same cache-line). + Similarly, arrays of _Atomic qualified items. + +Performance Assumptions: + o Collisions of address hashes for items (which make up the lock keys) + constitute the largest performance issue. + + o We want to avoid unnecessary flushing of [lock table] cache-line(s) when + items are accessed. + +Implementation: + We maintain a table of locks, each lock being 4 bytes (at present). + This choice of lock size gives some measure of equality in hash-collision + statistics between the 'atomic' and 'OSSpinLock' implementations, since the + lock size is fixed at 4 bytes for the latter. + + The table occupies one physical page, and we attempt to align it to a + page boundary, appropriately. + + For entities that need a lock, with sizes < one cache line: + Each entity that requires a lock, chooses the lock to use from the table on + the basis of a hash determined by its size and address. The lower log2(size) + address bits are discarded on the assumption that the alignment of entities + will not be smaller than their size. + CHECKME: this is not verified for aggregates; it might be something that + could/should be enforced from the front ends (since _Atomic types are + allowed to have increased alignment c.f. 'normal'). + + For entities that need a lock, with sizes >= one cacheline_size: + We assume that the entity alignment >= log2(cacheline_size) and discard + log2(cacheline_size) bits from the address. + We then apply size/cacheline_size locks to cover the entity. + + The idea is that this will typically result in distinct hash keys for items + placed close together. The keys are mangled further such that the size is + included in the hash. + + Finally, to attempt to make it such that the lock table entries are accessed + in a scattered manner,to avoid repeated cacheline flushes, the hash is + rearranged to attempt to maximise the most noise in the upper bits. +*/ + +/* The target page size. Must be no larger than the runtime page size, + lest locking fail with virtual address aliasing (i.e. a page mmaped + at two locations). */ +#ifndef PAGE_SIZE +# define PAGE_SIZE 4096 +#endif + +/* The target cacheline size. */ +#ifndef CACHLINE_SIZE +# define CACHLINE_SIZE 64 +#endif + +/* The granularity at which locks are applied when n > CACHLINE_SIZE. + We follow the posix pthreads implementation here. */ +#ifndef WATCH_SIZE +# define WATCH_SIZE CACHLINE_SIZE +#endif + +/* This is a number the number of tries we will make to acquire the lock + before giving up our time-slice (on the basis that we are guarding small + sections of code here and, therefore if we don't acquire the lock quickly, + that implies that the current holder is not active). */ +#define NSPINS 4 + +#if HAVE_ATOMIC_EXCHANGE_4 && HAVE_ATOMIC_LDST_4 + +# define LOCK_TYPE volatile uint32_t + +/* So that we work with gcc-4.8 we don't try to use _Atomic. + If _Atomic(uint32_t) ever gets greater alignment than 4 we'll need to + revise this. */ + +inline static void LockUnlock(LOCK_TYPE *l) +{ + __atomic_store_4((LOCK_TYPE *)l, 0, __ATOMIC_RELEASE); +} + +inline static void LockLock(LOCK_TYPE *l) +{ + uint32_t old = 0; + unsigned n = NSPINS; + while (!__atomic_compare_exchange_4((LOCK_TYPE *)l, &old, + 1, true, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) + { + old = 0; + if (--n == 0) + { + /* Give up this time-slice, no hint to the scheduler about what to + pick. + TODO: maybe see if it's worth preserving some info about presence + of waiting processes - to allow a similar "give up" time-slice + scheme on the unlock end. */ + thread_switch((mach_port_name_t)0, SWITCH_OPTION_NONE, + MACH_MSG_TIMEOUT_NONE); + n = NSPINS; + } + } +} + +#else + +# include +# define LOCK_TYPE OSSpinLock + +#define LockUnlock(L) OSSpinLockUnlock(L) + +inline static void LockLock(LOCK_TYPE *l) +{ + while (!OSSpinLockTry(l)) + { + unsigned n = NSPINS; + if (--n == 0) + { + /* Give up this time-slice, no hint to the scheduler about what to + pick. (see comment above) */ + thread_switch((mach_port_name_t)0, SWITCH_OPTION_NONE, + MACH_MSG_TIMEOUT_NONE); + n = NSPINS; + } + } +} + +#endif + +#define LOCK_SIZE sizeof(LOCK_TYPE) +#define NLOCKS (PAGE_SIZE / LOCK_SIZE) +/* An array of locks, that should fill one physical page. */ +static LOCK_TYPE locks[NLOCKS] __attribute__((aligned(PAGE_SIZE))); + +/* A hash function that assumes that entities of a given size are at least + aligned to that size, and tries to minimise the probability that adjacent + objects will end up using the same cache line in the locks. */ +static inline uintptr_t +addr_hash (void *ptr, size_t n) +{ + if (n <= CACHLINE_SIZE && n > 0) + n = sizeof(unsigned int)*8 - __builtin_clz((unsigned int) n) -1; + else + n = 7; + + uint16_t x = (((uintptr_t)ptr) >> n); + x ^= n; + x = ((x >> 8) & 0xff) | ((x << 8) & 0xff00); + return x % NLOCKS; +} + +void +libat_lock_1 (void *ptr) +{ + LockLock (&locks[addr_hash (ptr, 1)]); +} + +void +libat_unlock_1 (void *ptr) +{ + LockUnlock (&locks[addr_hash (ptr, 1)]); +} + +void +libat_lock_n (void *ptr, size_t n) +{ + uintptr_t h = addr_hash (ptr, n); + + /* Don't lock more than all the locks we have. */ + if (n > PAGE_SIZE) + n = PAGE_SIZE; + + size_t i = 0; + do + { + LockLock (&locks[h]); + if (++h == NLOCKS) + h = 0; + i += WATCH_SIZE; + } + while (i < n); +} + +void +libat_unlock_n (void *ptr, size_t n) +{ + uintptr_t h = addr_hash (ptr, n); + + if (n > PAGE_SIZE) + n = PAGE_SIZE; + + size_t i = 0; + do + { + LockUnlock (&locks[h]); + if (++h == NLOCKS) + h = 0; + i += WATCH_SIZE; + } + while (i < n); +} diff -uNr gcc-5.1.0.orig/libatomic/configure.tgt gcc-5.1.0/libatomic/configure.tgt --- gcc-5.1.0.orig/libatomic/configure.tgt 2015-01-09 09:06:02.000000000 -0500 +++ gcc-5.1.0/libatomic/configure.tgt 2015-04-28 18:51:01.000000000 -0400 @@ -26,6 +26,16 @@ # Map the target cpu to an ARCH sub-directory. At the same time, # work out any special compilation flags as necessary. +case "${target}" in + *-*-darwin*) + # Use the same default as GCC. + DEFAULT_X86_CPU=core2 + ;; + *) + DEFAULT_X86_CPU=i486 + ;; +esac + case "${target_cpu}" in alpha*) # fenv.c needs this option to generate inexact exceptions. @@ -72,7 +82,7 @@ ;; *) if test -z "$with_arch"; then - XCFLAGS="${XCFLAGS} -march=i486 -mtune=${target_cpu}" + XCFLAGS="${XCFLAGS} -march=$DEFAULT_X86_CPU -mtune=${target_cpu}" XCFLAGS="${XCFLAGS} -fomit-frame-pointer" fi esac @@ -83,7 +93,7 @@ x86_64) case " ${CC} ${CFLAGS} " in *" -m32 "*) - XCFLAGS="${XCFLAGS} -march=i486 -mtune=generic" + XCFLAGS="${XCFLAGS} -march=$DEFAULT_X86_CPU -mtune=generic" XCFLAGS="${XCFLAGS} -fomit-frame-pointer" ;; *) @@ -112,11 +122,16 @@ *-*-linux* | *-*-gnu* | *-*-k*bsd*-gnu \ | *-*-netbsd* | *-*-freebsd* | *-*-openbsd* \ | *-*-solaris2* | *-*-sysv4* | *-*-irix6* | *-*-osf* | *-*-hpux11* \ - | *-*-darwin* | *-*-aix* | *-*-cygwin*) + | *-*-aix* | *-*-cygwin*) # POSIX system. The OS is supported. config_path="${config_path} posix" ;; + *-*-darwin*) + # Darwin system. The OS is supported. + config_path="${config_path} darwin" + ;; + *-*-mingw*) # OS support for atomic primitives. case ${target_thread_file} in diff -uNr gcc-5.1.0.orig/libjava/Makefile.am gcc-5.1.0/libjava/Makefile.am --- gcc-5.1.0.orig/libjava/Makefile.am 2015-01-13 03:23:31.000000000 -0500 +++ gcc-5.1.0/libjava/Makefile.am 2015-04-28 18:51:01.000000000 -0400 @@ -494,7 +494,7 @@ libgcj_la_LDFLAGS = -rpath $(toolexeclibdir) $(THREADLDFLAGS) $(extra_ldflags) $(THREADLIBS) \ $(LIBLTDL) $(SYS_ZLIBS) $(LIBJAVA_LDFLAGS_NOUNDEF) \ -version-info `grep -v '^\#' $(srcdir)/libtool-version` \ - $(LIBGCJ_LD_SYMBOLIC_FUNCTIONS) $(LIBGCJ_LD_EXPORT_ALL) + $(LIBGCJ_LD_SYMBOLIC_FUNCTIONS) $(LIBGCJ_LD_EXPORT_ALL) $(LDLIBICONV) libgcj_la_LIBADD = \ classpath/native/fdlibm/libfdlibm.la \ java/lang/Object.lo \ diff -uNr gcc-5.1.0.orig/libjava/Makefile.in gcc-5.1.0/libjava/Makefile.in --- gcc-5.1.0.orig/libjava/Makefile.in 2015-04-22 04:45:05.000000000 -0400 +++ gcc-5.1.0/libjava/Makefile.in 2015-04-28 18:51:01.000000000 -0400 @@ -1080,7 +1080,7 @@ libgcj_la_LDFLAGS = -rpath $(toolexeclibdir) $(THREADLDFLAGS) $(extra_ldflags) $(THREADLIBS) \ $(LIBLTDL) $(SYS_ZLIBS) $(LIBJAVA_LDFLAGS_NOUNDEF) \ -version-info `grep -v '^\#' $(srcdir)/libtool-version` \ - $(LIBGCJ_LD_SYMBOLIC_FUNCTIONS) $(LIBGCJ_LD_EXPORT_ALL) + $(LIBGCJ_LD_SYMBOLIC_FUNCTIONS) $(LIBGCJ_LD_EXPORT_ALL) $(LDLIBICONV) libgcj_la_LIBADD = \ classpath/native/fdlibm/libfdlibm.la \