summaryrefslogtreecommitdiff
path: root/2.6.32
diff options
context:
space:
mode:
authorAnthony G. Basile <blueness@gentoo.org>2012-08-23 05:21:35 -0400
committerAnthony G. Basile <blueness@gentoo.org>2012-08-23 05:21:35 -0400
commita89caf05a86e0a5b4b1e4995e935988d7ccb52a2 (patch)
tree5ae270da647938e5fed57a27685ef0e1e2978a3c /2.6.32
parentGrsec/PaX: 2.9.1-{2.6.32.59,3.2.27,3.5.2}-201208151951 (diff)
downloadhardened-patchset-a89caf05a86e0a5b4b1e4995e935988d7ccb52a2.tar.gz
hardened-patchset-a89caf05a86e0a5b4b1e4995e935988d7ccb52a2.tar.bz2
hardened-patchset-a89caf05a86e0a5b4b1e4995e935988d7ccb52a2.zip
Grsec/PaX: 2.9.1-{2.6.32.59,3.2.27,3.5.2}-201208201521
Diffstat (limited to '2.6.32')
-rw-r--r--2.6.32/0000_README2
-rw-r--r--2.6.32/4420_grsecurity-2.9.1-2.6.32.59-201208201521.patch (renamed from 2.6.32/4420_grsecurity-2.9.1-2.6.32.59-201208151950.patch)417
2 files changed, 226 insertions, 193 deletions
diff --git a/2.6.32/0000_README b/2.6.32/0000_README
index 1250ead..0ba8a80 100644
--- a/2.6.32/0000_README
+++ b/2.6.32/0000_README
@@ -30,7 +30,7 @@ Patch: 1058_linux-2.6.32.59.patch
From: http://www.kernel.org
Desc: Linux 2.6.32.59
-Patch: 4420_grsecurity-2.9.1-2.6.32.59-201208151950.patch
+Patch: 4420_grsecurity-2.9.1-2.6.32.59-201208201521.patch
From: http://www.grsecurity.net
Desc: hardened-sources base patch from upstream grsecurity
diff --git a/2.6.32/4420_grsecurity-2.9.1-2.6.32.59-201208151950.patch b/2.6.32/4420_grsecurity-2.9.1-2.6.32.59-201208201521.patch
index ad50ae4..c356bad 100644
--- a/2.6.32/4420_grsecurity-2.9.1-2.6.32.59-201208151950.patch
+++ b/2.6.32/4420_grsecurity-2.9.1-2.6.32.59-201208201521.patch
@@ -110277,7 +110277,7 @@ index 0000000..048d4ff
+}
diff --git a/tools/gcc/generate_size_overflow_hash.sh b/tools/gcc/generate_size_overflow_hash.sh
new file mode 100644
-index 0000000..a0fe8b2
+index 0000000..68b646e
--- /dev/null
+++ b/tools/gcc/generate_size_overflow_hash.sh
@@ -0,0 +1,94 @@
@@ -110334,7 +110334,7 @@ index 0000000..a0fe8b2
+ params="${data_array[2]}"
+ next="${data_array[5]}"
+
-+ echo "struct size_overflow_hash $struct_hash_name = {" >> "$header1"
++ echo "const struct size_overflow_hash $struct_hash_name = {" >> "$header1"
+
+ echo -e "\t.next\t= $next,\n\t.name\t= \"$funcn\"," >> "$header1"
+ echo -en "\t.param\t= " >> "$header1"
@@ -110349,7 +110349,7 @@ index 0000000..a0fe8b2
+}
+
+create_headers () {
-+ echo "struct size_overflow_hash *size_overflow_hash[$n] = {" >> "$header1"
++ echo "const struct size_overflow_hash * const size_overflow_hash[$n] = {" >> "$header1"
+}
+
+create_array_elements () {
@@ -113560,10 +113560,10 @@ index 0000000..42bbc4f
+_002415_hash acl_alloc_num 1-2 60778 _002415_hash NULL
diff --git a/tools/gcc/size_overflow_plugin.c b/tools/gcc/size_overflow_plugin.c
new file mode 100644
-index 0000000..41e11e1
+index 0000000..e9310fa
--- /dev/null
+++ b/tools/gcc/size_overflow_plugin.c
-@@ -0,0 +1,1579 @@
+@@ -0,0 +1,1612 @@
+/*
+ * Copyright 2011, 2012 by Emese Revfy <re.emese@gmail.com>
+ * Licensed under the GPL v2, or (at your option) v3
@@ -113599,9 +113599,9 @@ index 0000000..41e11e1
+#include "cfgloop.h"
+
+struct size_overflow_hash {
-+ struct size_overflow_hash *next;
-+ const char *name;
-+ unsigned int param;
++ const struct size_overflow_hash * const next;
++ const char * const name;
++ const unsigned int param;
+};
+
+#include "size_overflow_hash.h"
@@ -113624,15 +113624,16 @@ index 0000000..41e11e1
+int plugin_is_GPL_compatible;
+void debug_gimple_stmt(gimple gs);
+
-+static tree expand(struct pointer_set_t *visited, bool *potentionally_overflowed, tree var);
++static tree expand(struct pointer_set_t *visited, bool *potentionally_overflowed, tree lhs);
+static tree report_size_overflow_decl;
-+static tree const_char_ptr_type_node;
++static const_tree const_char_ptr_type_node;
+static unsigned int handle_function(void);
+static void check_size_overflow(gimple stmt, tree size_overflow_type, tree cast_rhs, tree rhs, bool *potentionally_overflowed, bool before);
+static tree get_size_overflow_type(gimple stmt, tree node);
++static tree dup_assign(struct pointer_set_t *visited, bool *potentionally_overflowed, gimple oldstmt, tree size_overflow_type, tree rhs1, tree rhs2, tree __unused rhs3);
+
+static struct plugin_info size_overflow_plugin_info = {
-+ .version = "20120815beta",
++ .version = "20120820beta",
+ .help = "no-size-overflow\tturn off size overflow checking\n",
+};
+
@@ -113685,8 +113686,8 @@ index 0000000..41e11e1
+#define cwmixa( in ) { cwfold( in, m, k, h ); }
+#define cwmixb( in ) { cwfold( in, n, h, k ); }
+
-+ const unsigned int m = 0x57559429;
-+ const unsigned int n = 0x5052acdb;
++ unsigned int m = 0x57559429;
++ unsigned int n = 0x5052acdb;
+ const unsigned int *key4 = (const unsigned int *)key;
+ unsigned int h = len;
+ unsigned int k = len + seed + n;
@@ -113717,14 +113718,14 @@ index 0000000..41e11e1
+ return fn ^ codes;
+}
+
-+static inline tree get_original_function_decl(tree fndecl)
++static inline const_tree get_original_function_decl(const_tree fndecl)
+{
+ if (DECL_ABSTRACT_ORIGIN(fndecl))
+ return DECL_ABSTRACT_ORIGIN(fndecl);
+ return fndecl;
+}
+
-+static inline gimple get_def_stmt(tree node)
++static inline gimple get_def_stmt(const_tree node)
+{
+ gcc_assert(node != NULL_TREE);
+ gcc_assert(TREE_CODE(node) == SSA_NAME);
@@ -113776,9 +113777,10 @@ index 0000000..41e11e1
+ return len;
+}
+
-+static unsigned int get_function_decl(tree fndecl, unsigned char *tree_codes)
++static unsigned int get_function_decl(const_tree fndecl, unsigned char *tree_codes)
+{
-+ tree arg, result, type = TREE_TYPE(fndecl);
++ tree arg;
++ const_tree result, type = TREE_TYPE(fndecl);
+ enum tree_code code = TREE_CODE(type);
+ size_t len = 0;
+
@@ -113807,10 +113809,10 @@ index 0000000..41e11e1
+ return len;
+}
+
-+static struct size_overflow_hash *get_function_hash(tree fndecl)
++static const struct size_overflow_hash *get_function_hash(const_tree fndecl)
+{
+ unsigned int hash;
-+ struct size_overflow_hash *entry;
++ const struct size_overflow_hash *entry;
+ unsigned char tree_codes[CODES_LIMIT];
+ size_t len;
+ const char *func_name = NAME(fndecl);
@@ -113831,9 +113833,9 @@ index 0000000..41e11e1
+ return NULL;
+}
+
-+static void check_arg_type(tree var)
++static void check_arg_type(const_tree arg)
+{
-+ tree type = TREE_TYPE(var);
++ const_tree type = TREE_TYPE(arg);
+ enum tree_code code = TREE_CODE(type);
+
+ gcc_assert(code == INTEGER_TYPE || code == ENUMERAL_TYPE ||
@@ -113841,7 +113843,7 @@ index 0000000..41e11e1
+ (code == POINTER_TYPE && TREE_CODE(TREE_TYPE(type)) == INTEGER_TYPE));
+}
+
-+static int find_arg_number(tree arg, tree func)
++static int find_arg_number(const_tree arg, const_tree func)
+{
+ tree var;
+ bool match = false;
@@ -113867,7 +113869,7 @@ index 0000000..41e11e1
+ return argnum;
+}
+
-+static void print_missing_msg(tree func, unsigned int argnum)
++static void print_missing_msg(const_tree func, unsigned int argnum)
+{
+ unsigned int new_hash;
+ size_t len;
@@ -113880,16 +113882,15 @@ index 0000000..41e11e1
+ inform(loc, "Function %s is missing from the size_overflow hash table +%s+%d+%u+", curfunc, curfunc, argnum, new_hash);
+}
+
-+static void check_missing_attribute(tree arg)
++static void check_missing_attribute(const_tree arg)
+{
-+ tree type, func = get_original_function_decl(current_function_decl);
++ const_tree type = TREE_TYPE(arg);
++ const_tree func = get_original_function_decl(current_function_decl);
+ unsigned int argnum;
-+ struct size_overflow_hash *hash;
++ const struct size_overflow_hash *hash;
+
+ gcc_assert(TREE_CODE(arg) != COMPONENT_REF);
+
-+ type = TREE_TYPE(arg);
-+
+ if (TREE_CODE(type) == POINTER_TYPE)
+ return;
+
@@ -113930,9 +113931,9 @@ index 0000000..41e11e1
+ return assign;
+}
+
-+static bool is_bool(tree node)
++static bool is_bool(const_tree node)
+{
-+ tree type;
++ const_tree type;
+
+ if (node == NULL_TREE)
+ return false;
@@ -113956,26 +113957,25 @@ index 0000000..41e11e1
+ return fold_convert(type, var);
+}
+
-+static gimple build_cast_stmt(tree type, tree var, tree new_var, gimple_stmt_iterator *gsi, bool before)
++static gimple build_cast_stmt(tree dst_type, tree rhs, tree lhs, gimple_stmt_iterator *gsi, bool before)
+{
+ gimple assign;
-+ location_t loc;
+
-+ gcc_assert(type != NULL_TREE && var != NULL_TREE);
++ gcc_assert(dst_type != NULL_TREE && rhs != NULL_TREE);
+ if (gsi_end_p(*gsi) && before == BEFORE_STMT)
+ gcc_unreachable();
+
-+ if (new_var == CREATE_NEW_VAR)
-+ new_var = create_new_var(type);
++ if (lhs == CREATE_NEW_VAR)
++ lhs = create_new_var(dst_type);
+
-+ assign = gimple_build_assign(new_var, cast_a_tree(type, var));
++ assign = gimple_build_assign(lhs, cast_a_tree(dst_type, rhs));
+
+ if (!gsi_end_p(*gsi)) {
-+ loc = gimple_location(gsi_stmt(*gsi));
++ location_t loc = gimple_location(gsi_stmt(*gsi));
+ gimple_set_location(assign, loc);
+ }
+
-+ gimple_set_lhs(assign, make_ssa_name(new_var, assign));
++ gimple_set_lhs(assign, make_ssa_name(lhs, assign));
+
+ if (before)
+ gsi_insert_before(gsi, assign, GSI_NEW_STMT);
@@ -113989,7 +113989,7 @@ index 0000000..41e11e1
+
+static tree cast_to_new_size_overflow_type(gimple stmt, tree new_rhs1, tree size_overflow_type, bool before)
+{
-+ gimple assign;
++ const_gimple assign;
+ gimple_stmt_iterator gsi;
+
+ if (new_rhs1 == NULL_TREE)
@@ -114003,9 +114003,25 @@ index 0000000..41e11e1
+ return new_rhs1;
+}
+
++static tree follow_overflow_type_and_dup(struct pointer_set_t *visited, bool *potentionally_overflowed, gimple stmt, tree node, tree new_rhs1, tree new_rhs2, tree new_rhs3)
++{
++ tree size_overflow_type = get_size_overflow_type(stmt, node);
++
++ new_rhs1 = cast_to_new_size_overflow_type(stmt, new_rhs1, size_overflow_type, BEFORE_STMT);
++
++ if (new_rhs2 != NULL_TREE)
++ new_rhs2 = cast_to_new_size_overflow_type(stmt, new_rhs2, size_overflow_type, BEFORE_STMT);
++
++ if (new_rhs3 != NULL_TREE)
++ new_rhs3 = cast_to_new_size_overflow_type(stmt, new_rhs3, size_overflow_type, BEFORE_STMT);
++
++ return dup_assign(visited, potentionally_overflowed, stmt, size_overflow_type, new_rhs1, new_rhs2, new_rhs3);
++}
++
+static tree create_assign(struct pointer_set_t *visited, bool *potentionally_overflowed, gimple oldstmt, tree rhs1, bool before)
+{
-+ tree oldstmt_rhs1, size_overflow_type, lhs;
++ const_tree oldstmt_rhs1;
++ tree size_overflow_type, lhs;
+ enum tree_code code;
+ gimple stmt;
+ gimple_stmt_iterator gsi;
@@ -114033,7 +114049,7 @@ index 0000000..41e11e1
+ pointer_set_insert(visited, oldstmt);
+ if (lookup_stmt_eh_lp(oldstmt) != 0) {
+ basic_block next_bb, cur_bb;
-+ edge e;
++ const_edge e;
+
+ gcc_assert(before == false);
+ gcc_assert(stmt_can_throw_internal(oldstmt));
@@ -114063,9 +114079,9 @@ index 0000000..41e11e1
+
+static tree dup_assign(struct pointer_set_t *visited, bool *potentionally_overflowed, gimple oldstmt, tree size_overflow_type, tree rhs1, tree rhs2, tree __unused rhs3)
+{
-+ tree new_var, lhs = gimple_get_lhs(oldstmt);
+ gimple stmt;
+ gimple_stmt_iterator gsi;
++ tree new_var, lhs = gimple_get_lhs(oldstmt);
+
+ if (!*potentionally_overflowed)
+ return NULL_TREE;
@@ -114118,7 +114134,7 @@ index 0000000..41e11e1
+ return gimple_get_lhs(stmt);
+}
+
-+static gimple overflow_create_phi_node(gimple oldstmt, tree var)
++static gimple overflow_create_phi_node(gimple oldstmt, tree result)
+{
+ basic_block bb;
+ gimple phi;
@@ -114126,7 +114142,7 @@ index 0000000..41e11e1
+
+ bb = gsi_bb(gsi);
+
-+ phi = create_phi_node(var, bb);
++ phi = create_phi_node(result, bb);
+ gsi = gsi_last(phi_nodes(bb));
+ gsi_remove(&gsi, false);
+
@@ -114150,7 +114166,7 @@ index 0000000..41e11e1
+static tree cast_old_phi_arg(gimple oldstmt, tree size_overflow_type, tree arg, tree new_var, unsigned int i)
+{
+ basic_block bb;
-+ gimple newstmt;
++ const_gimple newstmt;
+ gimple_stmt_iterator gsi;
+ bool before = BEFORE_STMT;
+
@@ -114172,7 +114188,7 @@ index 0000000..41e11e1
+ return gimple_get_lhs(newstmt);
+}
+
-+static gimple handle_new_phi_arg(tree arg, tree new_var, tree new_rhs)
++static const_gimple handle_new_phi_arg(const_tree arg, tree new_var, tree new_rhs)
+{
+ gimple newstmt;
+ gimple_stmt_iterator gsi;
@@ -114209,7 +114225,7 @@ index 0000000..41e11e1
+
+static tree build_new_phi_arg(struct pointer_set_t *visited, bool *potentionally_overflowed, tree size_overflow_type, tree arg, tree new_var)
+{
-+ gimple newstmt;
++ const_gimple newstmt;
+ tree new_rhs;
+
+ new_rhs = expand(visited, potentionally_overflowed, arg);
@@ -114222,27 +114238,28 @@ index 0000000..41e11e1
+ return gimple_get_lhs(newstmt);
+}
+
-+static tree build_new_phi(struct pointer_set_t *visited, bool *potentionally_overflowed, tree var)
++static tree build_new_phi(struct pointer_set_t *visited, bool *potentionally_overflowed, tree orig_result)
+{
-+ gimple phi, oldstmt = get_def_stmt(var);
-+ tree new_var, size_overflow_type;
-+ unsigned int i, n = gimple_phi_num_args(oldstmt);
++ gimple phi, oldstmt = get_def_stmt(orig_result);
++ tree new_result, size_overflow_type;
++ unsigned int i;
++ unsigned int n = gimple_phi_num_args(oldstmt);
+
-+ size_overflow_type = get_size_overflow_type(oldstmt, var);
++ size_overflow_type = get_size_overflow_type(oldstmt, orig_result);
+
-+ new_var = create_new_var(size_overflow_type);
++ new_result = create_new_var(size_overflow_type);
+
+ pointer_set_insert(visited, oldstmt);
-+ phi = overflow_create_phi_node(oldstmt, new_var);
++ phi = overflow_create_phi_node(oldstmt, new_result);
+ for (i = 0; i < n; i++) {
+ tree arg, lhs;
+
+ arg = gimple_phi_arg_def(oldstmt, i);
+ if (is_gimple_constant(arg))
+ arg = cast_a_tree(size_overflow_type, arg);
-+ lhs = build_new_phi_arg(visited, potentionally_overflowed, size_overflow_type, arg, new_var);
++ lhs = build_new_phi_arg(visited, potentionally_overflowed, size_overflow_type, arg, new_result);
+ if (lhs == NULL_TREE)
-+ lhs = cast_old_phi_arg(oldstmt, size_overflow_type, arg, new_var, i);
++ lhs = cast_old_phi_arg(oldstmt, size_overflow_type, arg, new_result, i);
+ add_phi_arg(phi, lhs, gimple_phi_arg_edge(oldstmt, i), gimple_location(oldstmt));
+ }
+
@@ -114250,9 +114267,9 @@ index 0000000..41e11e1
+ return gimple_phi_result(phi);
+}
+
-+static tree change_assign_rhs(gimple stmt, tree orig_rhs, tree new_rhs)
++static tree change_assign_rhs(gimple stmt, const_tree orig_rhs, tree new_rhs)
+{
-+ gimple assign;
++ const_gimple assign;
+ gimple_stmt_iterator gsi = gsi_for_stmt(stmt);
+ tree origtype = TREE_TYPE(orig_rhs);
+
@@ -114265,18 +114282,18 @@ index 0000000..41e11e1
+static void change_rhs1(gimple stmt, tree new_rhs1)
+{
+ tree assign_rhs;
-+ tree rhs = gimple_assign_rhs1(stmt);
++ const_tree rhs = gimple_assign_rhs1(stmt);
+
+ assign_rhs = change_assign_rhs(stmt, rhs, new_rhs1);
+ gimple_assign_set_rhs1(stmt, assign_rhs);
+ update_stmt(stmt);
+}
+
-+static bool check_mode_type(gimple stmt)
++static bool check_mode_type(const_gimple stmt)
+{
-+ tree lhs = gimple_get_lhs(stmt);
-+ tree lhs_type = TREE_TYPE(lhs);
-+ tree rhs_type = TREE_TYPE(gimple_assign_rhs1(stmt));
++ const_tree lhs = gimple_get_lhs(stmt);
++ const_tree lhs_type = TREE_TYPE(lhs);
++ const_tree rhs_type = TREE_TYPE(gimple_assign_rhs1(stmt));
+ enum machine_mode lhs_mode = TYPE_MODE(lhs_type);
+ enum machine_mode rhs_mode = TYPE_MODE(rhs_type);
+
@@ -114289,13 +114306,13 @@ index 0000000..41e11e1
+ return true;
+}
+
-+static bool check_undefined_integer_operation(gimple stmt)
++static bool check_undefined_integer_operation(const_gimple stmt)
+{
-+ gimple def_stmt;
-+ tree lhs = gimple_get_lhs(stmt);
-+ tree rhs1 = gimple_assign_rhs1(stmt);
-+ tree rhs1_type = TREE_TYPE(rhs1);
-+ tree lhs_type = TREE_TYPE(lhs);
++ const_gimple def_stmt;
++ const_tree lhs = gimple_get_lhs(stmt);
++ const_tree rhs1 = gimple_assign_rhs1(stmt);
++ const_tree rhs1_type = TREE_TYPE(rhs1);
++ const_tree lhs_type = TREE_TYPE(lhs);
+
+ if (TYPE_MODE(rhs1_type) != TYPE_MODE(lhs_type) || TYPE_UNSIGNED(rhs1_type) == TYPE_UNSIGNED(lhs_type))
+ return false;
@@ -114309,9 +114326,9 @@ index 0000000..41e11e1
+ return true;
+}
+
-+static bool is_a_cast_and_const_overflow(tree no_const_rhs)
++static bool is_a_cast_and_const_overflow(const_tree no_const_rhs)
+{
-+ tree rhs1, lhs, rhs1_type, lhs_type;
++ const_tree rhs1, lhs, rhs1_type, lhs_type;
+ enum machine_mode lhs_mode, rhs_mode;
+ gimple def_stmt = get_def_stmt(no_const_rhs);
+
@@ -114334,8 +114351,8 @@ index 0000000..41e11e1
+{
+ tree size_overflow_type, lhs = gimple_get_lhs(stmt);
+ tree new_rhs1, rhs1 = gimple_assign_rhs1(stmt);
-+ tree rhs1_type = TREE_TYPE(rhs1);
-+ tree lhs_type = TREE_TYPE(lhs);
++ const_tree rhs1_type = TREE_TYPE(rhs1);
++ const_tree lhs_type = TREE_TYPE(lhs);
+
+ *potentionally_overflowed = true;
+
@@ -114347,23 +114364,18 @@ index 0000000..41e11e1
+ if (gimple_plf(stmt, MY_STMT))
+ return lhs;
+
-+ if (gimple_plf(stmt, NO_CAST_CHECK)) {
-+ size_overflow_type = get_size_overflow_type(stmt, rhs1);
-+ new_rhs1 = cast_to_new_size_overflow_type(stmt, new_rhs1, size_overflow_type, BEFORE_STMT);
-+ return dup_assign(visited, potentionally_overflowed, stmt, size_overflow_type, new_rhs1, NULL_TREE, NULL_TREE);
-+ }
++ if (gimple_plf(stmt, NO_CAST_CHECK))
++ return follow_overflow_type_and_dup(visited, potentionally_overflowed, stmt, rhs1, new_rhs1, NULL_TREE, NULL_TREE);
+
-+ if (!gimple_assign_cast_p(stmt)) {
-+ size_overflow_type = get_size_overflow_type(stmt, lhs);
++ if (gimple_assign_rhs_code(stmt) == BIT_NOT_EXPR) {
++ size_overflow_type = get_size_overflow_type(stmt, rhs1);
+ new_rhs1 = cast_to_new_size_overflow_type(stmt, new_rhs1, size_overflow_type, BEFORE_STMT);
-+ return dup_assign(visited, potentionally_overflowed, stmt, size_overflow_type, new_rhs1, NULL_TREE, NULL_TREE);
++ check_size_overflow(stmt, size_overflow_type, new_rhs1, rhs1, potentionally_overflowed, BEFORE_STMT);
++ return create_assign(visited, potentionally_overflowed, stmt, lhs, AFTER_STMT);
+ }
+
-+ if (check_undefined_integer_operation(stmt)) {
-+ size_overflow_type = get_size_overflow_type(stmt, lhs);
-+ new_rhs1 = cast_to_new_size_overflow_type(stmt, new_rhs1, size_overflow_type, BEFORE_STMT);
-+ return dup_assign(visited, potentionally_overflowed, stmt, size_overflow_type, new_rhs1, NULL_TREE, NULL_TREE);
-+ }
++ if (!gimple_assign_cast_p(stmt) || check_undefined_integer_operation(stmt))
++ return follow_overflow_type_and_dup(visited, potentionally_overflowed, stmt, lhs, new_rhs1, NULL_TREE, NULL_TREE);
+
+ size_overflow_type = get_size_overflow_type(stmt, rhs1);
+ new_rhs1 = cast_to_new_size_overflow_type(stmt, new_rhs1, size_overflow_type, BEFORE_STMT);
@@ -114432,7 +114444,7 @@ index 0000000..41e11e1
+static tree create_string_param(tree string)
+{
+ tree i_type, a_type;
-+ int length = TREE_STRING_LENGTH(string);
++ const int length = TREE_STRING_LENGTH(string);
+
+ gcc_assert(length > 0);
+
@@ -114446,12 +114458,14 @@ index 0000000..41e11e1
+ return build1(ADDR_EXPR, ptr_type_node, string);
+}
+
-+static void insert_cond_result(basic_block bb_true, gimple stmt, tree arg, bool min)
++static void insert_cond_result(basic_block bb_true, const_gimple stmt, const_tree arg, bool min)
+{
-+ gimple func_stmt, def_stmt;
-+ tree current_func, loc_file, loc_line, ssa_name;
++ gimple func_stmt;
++ const_gimple def_stmt;
++ const_tree loc_line;
++ tree loc_file, ssa_name, current_func;
+ expanded_location xloc;
-+ char ssa_name_buf[100];
++ char ssa_name_buf[256];
+ gimple_stmt_iterator gsi = gsi_start_bb(bb_true);
+
+ def_stmt = get_def_stmt(arg);
@@ -114471,8 +114485,8 @@ index 0000000..41e11e1
+ current_func = build_string(NAME_LEN(current_function_decl) + 1, NAME(current_function_decl));
+ current_func = create_string_param(current_func);
+
-+ snprintf(ssa_name_buf, sizeof(ssa_name_buf), "%s_%u (%s)\n", NAME(SSA_NAME_VAR(arg)), SSA_NAME_VERSION(arg), min ? "min" : "max");
-+ ssa_name = build_string(sizeof(ssa_name_buf), ssa_name_buf);
++ snprintf(ssa_name_buf, 256, "%s_%u (%s)\n", NAME(SSA_NAME_VAR(arg)), SSA_NAME_VERSION(arg), min ? "min" : "max");
++ ssa_name = build_string(256, ssa_name_buf);
+ ssa_name = create_string_param(ssa_name);
+
+ // void report_size_overflow(const char *file, unsigned int line, const char *func, const char *ssa_name)
@@ -114481,7 +114495,7 @@ index 0000000..41e11e1
+ gsi_insert_after(&gsi, func_stmt, GSI_CONTINUE_LINKING);
+}
+
-+static void __unused print_the_code_insertions(gimple stmt)
++static void __unused print_the_code_insertions(const_gimple stmt)
+{
+ location_t loc = gimple_location(stmt);
+
@@ -114529,7 +114543,9 @@ index 0000000..41e11e1
+
+static void check_size_overflow(gimple stmt, tree size_overflow_type, tree cast_rhs, tree rhs, bool *potentionally_overflowed, bool before)
+{
-+ tree cast_rhs_type, type_max_type, type_min_type, type_max, type_min, rhs_type = TREE_TYPE(rhs);
++ const_tree rhs_type = TREE_TYPE(rhs);
++ tree cast_rhs_type, type_max_type, type_min_type, type_max, type_min;
++
+ gcc_assert(rhs_type != NULL_TREE);
+ gcc_assert(TREE_CODE(rhs_type) == INTEGER_TYPE || TREE_CODE(rhs_type) == BOOLEAN_TYPE || TREE_CODE(rhs_type) == ENUMERAL_TYPE);
+
@@ -114551,27 +114567,27 @@ index 0000000..41e11e1
+ insert_check_size_overflow(stmt, LT_EXPR, cast_rhs, type_min, before, true);
+}
+
-+static tree get_handle_const_assign_size_overflow_type(gimple def_stmt, tree var_rhs)
++static tree get_size_overflow_type_for_intentional_overflow(gimple def_stmt, tree change_rhs)
+{
-+ gimple var_rhs_def_stmt;
++ gimple change_rhs_def_stmt;
+ tree lhs = gimple_get_lhs(def_stmt);
+ tree lhs_type = TREE_TYPE(lhs);
+ tree rhs1_type = TREE_TYPE(gimple_assign_rhs1(def_stmt));
+ tree rhs2_type = TREE_TYPE(gimple_assign_rhs2(def_stmt));
+
-+ if (var_rhs == NULL_TREE)
++ if (change_rhs == NULL_TREE)
+ return get_size_overflow_type(def_stmt, lhs);
+
-+ var_rhs_def_stmt = get_def_stmt(var_rhs);
++ change_rhs_def_stmt = get_def_stmt(change_rhs);
+
+ if (TREE_CODE_CLASS(gimple_assign_rhs_code(def_stmt)) == tcc_comparison)
-+ return get_size_overflow_type(var_rhs_def_stmt, var_rhs);
++ return get_size_overflow_type(change_rhs_def_stmt, change_rhs);
+
+ if (gimple_assign_rhs_code(def_stmt) == LSHIFT_EXPR)
-+ return get_size_overflow_type(var_rhs_def_stmt, var_rhs);
++ return get_size_overflow_type(change_rhs_def_stmt, change_rhs);
+
+ if (gimple_assign_rhs_code(def_stmt) == RSHIFT_EXPR)
-+ return get_size_overflow_type(var_rhs_def_stmt, var_rhs);
++ return get_size_overflow_type(change_rhs_def_stmt, change_rhs);
+
+ if (!useless_type_conversion_p(lhs_type, rhs1_type) || !useless_type_conversion_p(rhs1_type, rhs2_type)) {
+ debug_gimple_stmt(def_stmt);
@@ -114581,45 +114597,16 @@ index 0000000..41e11e1
+ return get_size_overflow_type(def_stmt, lhs);
+}
+
-+static tree handle_const_assign(struct pointer_set_t *visited, bool *potentionally_overflowed, gimple def_stmt, tree var_rhs, tree new_rhs1, tree new_rhs2)
++static bool is_a_constant_overflow(const_gimple stmt, const_tree rhs)
+{
-+ tree new_rhs, size_overflow_type, orig_rhs;
-+ void (*gimple_assign_set_rhs)(gimple, tree);
-+ tree rhs1 = gimple_assign_rhs1(def_stmt);
-+ tree rhs2 = gimple_assign_rhs2(def_stmt);
-+ tree lhs = gimple_get_lhs(def_stmt);
-+
-+ if (var_rhs == NULL_TREE)
-+ return create_assign(visited, potentionally_overflowed, def_stmt, lhs, AFTER_STMT);
-+
-+ if (new_rhs2 == NULL_TREE) {
-+ size_overflow_type = get_handle_const_assign_size_overflow_type(def_stmt, new_rhs1);
-+ new_rhs2 = cast_a_tree(size_overflow_type, rhs2);
-+ orig_rhs = rhs1;
-+ gimple_assign_set_rhs = &gimple_assign_set_rhs1;
-+ } else {
-+ size_overflow_type = get_handle_const_assign_size_overflow_type(def_stmt, new_rhs2);
-+ new_rhs1 = cast_a_tree(size_overflow_type, rhs1);
-+ orig_rhs = rhs2;
-+ gimple_assign_set_rhs = &gimple_assign_set_rhs2;
-+ }
-+
-+ var_rhs = cast_to_new_size_overflow_type(def_stmt, var_rhs, size_overflow_type, BEFORE_STMT);
-+
-+ if (gimple_assign_rhs_code(def_stmt) == MIN_EXPR)
-+ return dup_assign(visited, potentionally_overflowed, def_stmt, size_overflow_type, new_rhs1, new_rhs2, NULL_TREE);
-+
-+ if (!is_a_cast_and_const_overflow(orig_rhs))
-+ check_size_overflow(def_stmt, size_overflow_type, var_rhs, orig_rhs, potentionally_overflowed, BEFORE_STMT);
-+
-+ new_rhs = change_assign_rhs(def_stmt, orig_rhs, var_rhs);
-+ gimple_assign_set_rhs(def_stmt, new_rhs);
-+ update_stmt(def_stmt);
-+
-+ return create_assign(visited, potentionally_overflowed, def_stmt, lhs, AFTER_STMT);
++ if (gimple_assign_rhs_code(stmt) == MIN_EXPR)
++ return false;
++ if (!is_gimple_constant(rhs))
++ return false;
++ return true;
+}
+
-+static tree get_cast_def_stmt_rhs(tree new_rhs)
++static tree get_cast_def_stmt_rhs(const_tree new_rhs)
+{
+ gimple def_stmt;
+
@@ -114633,7 +114620,8 @@ index 0000000..41e11e1
+static tree cast_to_int_TI_type_and_check(bool *potentionally_overflowed, gimple stmt, tree new_rhs)
+{
+ gimple_stmt_iterator gsi;
-+ gimple cast_stmt, def_stmt;
++ const_gimple cast_stmt;
++ gimple def_stmt;
+ enum machine_mode mode = TYPE_MODE(TREE_TYPE(new_rhs));
+
+ if (mode != TImode && mode != DImode) {
@@ -114660,13 +114648,13 @@ index 0000000..41e11e1
+ return new_rhs;
+}
+
-+static bool is_an_integer_trunction(gimple stmt)
++static bool is_an_integer_trunction(const_gimple stmt)
+{
+ gimple rhs1_def_stmt, rhs2_def_stmt;
-+ tree rhs1_def_stmt_rhs1, rhs2_def_stmt_rhs1;
++ const_tree rhs1_def_stmt_rhs1, rhs2_def_stmt_rhs1;
+ enum machine_mode rhs1_def_stmt_rhs1_mode, rhs2_def_stmt_rhs1_mode;
-+ tree rhs1 = gimple_assign_rhs1(stmt);
-+ tree rhs2 = gimple_assign_rhs2(stmt);
++ const_tree rhs1 = gimple_assign_rhs1(stmt);
++ const_tree rhs2 = gimple_assign_rhs2(stmt);
+ enum machine_mode rhs1_mode = TYPE_MODE(TREE_TYPE(rhs1));
+ enum machine_mode rhs2_mode = TYPE_MODE(TREE_TYPE(rhs2));
+
@@ -114697,7 +114685,7 @@ index 0000000..41e11e1
+
+static tree handle_integer_truncation(struct pointer_set_t *visited, bool *potentionally_overflowed, tree lhs)
+{
-+ tree new_rhs1, new_rhs2, size_overflow_type;
++ tree new_rhs1, new_rhs2;
+ tree new_rhs1_def_stmt_rhs1, new_rhs2_def_stmt_rhs1, new_lhs;
+ tree new_rhs1_def_stmt_rhs1_type, new_rhs2_def_stmt_rhs1_type;
+ gimple assign, stmt = get_def_stmt(lhs);
@@ -114725,15 +114713,64 @@ index 0000000..41e11e1
+ new_lhs = gimple_get_lhs(assign);
+ check_size_overflow(assign, TREE_TYPE(new_lhs), new_lhs, rhs1, potentionally_overflowed, AFTER_STMT);
+
-+ size_overflow_type = get_size_overflow_type(stmt, lhs);
-+ new_rhs1 = cast_to_new_size_overflow_type(stmt, new_rhs1, size_overflow_type, BEFORE_STMT);
-+ new_rhs2 = cast_to_new_size_overflow_type(stmt, new_rhs2, size_overflow_type, BEFORE_STMT);
-+ return dup_assign(visited, potentionally_overflowed, stmt, size_overflow_type, new_rhs1, new_rhs2, NULL_TREE);
++ return follow_overflow_type_and_dup(visited, potentionally_overflowed, stmt, lhs, new_rhs1, new_rhs2, NULL_TREE);
++}
++
++static bool is_a_neg_overflow(const_gimple stmt, const_tree rhs)
++{
++ const_gimple def_stmt;
++
++ if (TREE_CODE(rhs) != SSA_NAME)
++ return false;
++
++ if (gimple_assign_rhs_code(stmt) != PLUS_EXPR)
++ return false;
++
++ def_stmt = get_def_stmt(rhs);
++ if (gimple_code(def_stmt) != GIMPLE_ASSIGN || gimple_assign_rhs_code(def_stmt) != BIT_NOT_EXPR)
++ return false;
++
++ return true;
++}
++
++static tree handle_intentional_overflow(struct pointer_set_t *visited, bool *potentionally_overflowed, bool check_overflow, gimple stmt, tree change_rhs, tree new_rhs1, tree new_rhs2)
++{
++ tree new_rhs, size_overflow_type, orig_rhs;
++ void (*gimple_assign_set_rhs)(gimple, tree);
++ tree rhs1 = gimple_assign_rhs1(stmt);
++ tree rhs2 = gimple_assign_rhs2(stmt);
++ tree lhs = gimple_get_lhs(stmt);
++
++ if (change_rhs == NULL_TREE)
++ return create_assign(visited, potentionally_overflowed, stmt, lhs, AFTER_STMT);
++
++ if (new_rhs2 == NULL_TREE) {
++ size_overflow_type = get_size_overflow_type_for_intentional_overflow(stmt, new_rhs1);
++ new_rhs2 = cast_a_tree(size_overflow_type, rhs2);
++ orig_rhs = rhs1;
++ gimple_assign_set_rhs = &gimple_assign_set_rhs1;
++ } else {
++ size_overflow_type = get_size_overflow_type_for_intentional_overflow(stmt, new_rhs2);
++ new_rhs1 = cast_a_tree(size_overflow_type, rhs1);
++ orig_rhs = rhs2;
++ gimple_assign_set_rhs = &gimple_assign_set_rhs2;
++ }
++
++ change_rhs = cast_to_new_size_overflow_type(stmt, change_rhs, size_overflow_type, BEFORE_STMT);
++
++ if (check_overflow)
++ check_size_overflow(stmt, size_overflow_type, change_rhs, orig_rhs, potentionally_overflowed, BEFORE_STMT);
++
++ new_rhs = change_assign_rhs(stmt, orig_rhs, change_rhs);
++ gimple_assign_set_rhs(stmt, new_rhs);
++ update_stmt(stmt);
++
++ return create_assign(visited, potentionally_overflowed, stmt, lhs, AFTER_STMT);
+}
+
+static tree handle_binary_ops(struct pointer_set_t *visited, bool *potentionally_overflowed, tree lhs)
+{
-+ tree rhs1, rhs2, size_overflow_type, new_lhs;
++ tree rhs1, rhs2, new_lhs;
+ gimple def_stmt = get_def_stmt(lhs);
+ tree new_rhs1 = NULL_TREE;
+ tree new_rhs2 = NULL_TREE;
@@ -114771,18 +114808,17 @@ index 0000000..41e11e1
+ if (TREE_CODE(rhs2) == SSA_NAME)
+ new_rhs2 = expand(visited, potentionally_overflowed, rhs2);
+
-+ if (is_gimple_constant(rhs2))
-+ return handle_const_assign(visited, potentionally_overflowed, def_stmt, new_rhs1, new_rhs1, NULL_TREE);
-+
-+ if (is_gimple_constant(rhs1))
-+ return handle_const_assign(visited, potentionally_overflowed, def_stmt, new_rhs2, NULL_TREE, new_rhs2);
-+
-+ size_overflow_type = get_size_overflow_type(def_stmt, lhs);
++ if (is_a_neg_overflow(def_stmt, rhs2))
++ return handle_intentional_overflow(visited, potentionally_overflowed, true, def_stmt, new_rhs1, new_rhs1, NULL_TREE);
++ if (is_a_neg_overflow(def_stmt, rhs1))
++ return handle_intentional_overflow(visited, potentionally_overflowed, true, def_stmt, new_rhs2, NULL_TREE, new_rhs2);
+
-+ new_rhs1 = cast_to_new_size_overflow_type(def_stmt, new_rhs1, size_overflow_type, BEFORE_STMT);
-+ new_rhs2 = cast_to_new_size_overflow_type(def_stmt, new_rhs2, size_overflow_type, BEFORE_STMT);
++ if (is_a_constant_overflow(def_stmt, rhs2))
++ return handle_intentional_overflow(visited, potentionally_overflowed, !is_a_cast_and_const_overflow(rhs1), def_stmt, new_rhs1, new_rhs1, NULL_TREE);
++ if (is_a_constant_overflow(def_stmt, rhs1))
++ return handle_intentional_overflow(visited, potentionally_overflowed, !is_a_cast_and_const_overflow(rhs2), def_stmt, new_rhs2, NULL_TREE, new_rhs2);
+
-+ return dup_assign(visited, potentionally_overflowed, def_stmt, size_overflow_type, new_rhs1, new_rhs2, NULL_TREE);
++ return follow_overflow_type_and_dup(visited, potentionally_overflowed, def_stmt, lhs, new_rhs1, new_rhs2, NULL_TREE);
+}
+
+#if BUILDING_GCC_VERSION >= 4007
@@ -114795,14 +114831,14 @@ index 0000000..41e11e1
+ return expand(visited, potentionally_overflowed, rhs);
+}
+
-+static tree handle_ternary_ops(struct pointer_set_t *visited, bool *potentionally_overflowed, tree var)
++static tree handle_ternary_ops(struct pointer_set_t *visited, bool *potentionally_overflowed, tree lhs)
+{
+ tree rhs1, rhs2, rhs3, new_rhs1, new_rhs2, new_rhs3, size_overflow_type;
-+ gimple def_stmt = get_def_stmt(var);
++ gimple def_stmt = get_def_stmt(lhs);
+
+ *potentionally_overflowed = true;
+
-+ size_overflow_type = get_size_overflow_type(def_stmt, var);
++ size_overflow_type = get_size_overflow_type(def_stmt, lhs);
+
+ rhs1 = gimple_assign_rhs1(def_stmt);
+ rhs2 = gimple_assign_rhs2(def_stmt);
@@ -114811,11 +114847,7 @@ index 0000000..41e11e1
+ new_rhs2 = get_new_rhs(visited, potentionally_overflowed, size_overflow_type, rhs2);
+ new_rhs3 = get_new_rhs(visited, potentionally_overflowed, size_overflow_type, rhs3);
+
-+ new_rhs1 = cast_to_new_size_overflow_type(def_stmt, new_rhs1, size_overflow_type, BEFORE_STMT);
-+ new_rhs2 = cast_to_new_size_overflow_type(def_stmt, new_rhs2, size_overflow_type, BEFORE_STMT);
-+ new_rhs3 = cast_to_new_size_overflow_type(def_stmt, new_rhs3, size_overflow_type, BEFORE_STMT);
-+
-+ return dup_assign(visited, potentionally_overflowed, def_stmt, size_overflow_type, new_rhs1, new_rhs2, new_rhs3);
++ return follow_overflow_type_and_dup(visited, potentionally_overflowed, def_stmt, lhs, new_rhs1, new_rhs2, new_rhs3);
+}
+#endif
+
@@ -114850,7 +114882,7 @@ index 0000000..41e11e1
+
+static tree expand_visited(gimple def_stmt)
+{
-+ gimple next_stmt;
++ const_gimple next_stmt;
+ gimple_stmt_iterator gsi = gsi_for_stmt(def_stmt);
+
+ gsi_next(&gsi);
@@ -114868,51 +114900,51 @@ index 0000000..41e11e1
+ }
+}
+
-+static tree expand(struct pointer_set_t *visited, bool *potentionally_overflowed, tree var)
++static tree expand(struct pointer_set_t *visited, bool *potentionally_overflowed, tree lhs)
+{
+ gimple def_stmt;
-+ enum tree_code code = TREE_CODE(TREE_TYPE(var));
++ enum tree_code code = TREE_CODE(TREE_TYPE(lhs));
+
-+ if (is_gimple_constant(var))
++ if (is_gimple_constant(lhs))
+ return NULL_TREE;
+
-+ if (TREE_CODE(var) == ADDR_EXPR)
++ if (TREE_CODE(lhs) == ADDR_EXPR)
+ return NULL_TREE;
+
+ gcc_assert(code == INTEGER_TYPE || code == POINTER_TYPE || code == BOOLEAN_TYPE || code == ENUMERAL_TYPE);
+
-+ if (TREE_CODE(SSA_NAME_VAR(var)) == PARM_DECL)
-+ check_missing_attribute(var);
++ if (TREE_CODE(SSA_NAME_VAR(lhs)) == PARM_DECL)
++ check_missing_attribute(lhs);
+
-+ def_stmt = get_def_stmt(var);
++ def_stmt = get_def_stmt(lhs);
+
+ if (!def_stmt)
+ return NULL_TREE;
+
+ if (gimple_plf(def_stmt, MY_STMT))
-+ return var;
++ return lhs;
+
+ if (pointer_set_contains(visited, def_stmt))
+ return expand_visited(def_stmt);
+
+ switch (gimple_code(def_stmt)) {
+ case GIMPLE_NOP:
-+ check_missing_attribute(var);
++ check_missing_attribute(lhs);
+ return NULL_TREE;
+ case GIMPLE_PHI:
-+ return build_new_phi(visited, potentionally_overflowed, var);
++ return build_new_phi(visited, potentionally_overflowed, lhs);
+ case GIMPLE_CALL:
+ case GIMPLE_ASM:
-+ return create_assign(visited, potentionally_overflowed, def_stmt, var, AFTER_STMT);
++ return create_assign(visited, potentionally_overflowed, def_stmt, lhs, AFTER_STMT);
+ case GIMPLE_ASSIGN:
+ switch (gimple_num_ops(def_stmt)) {
+ case 2:
-+ return handle_unary_ops(visited, potentionally_overflowed, var);
++ return handle_unary_ops(visited, potentionally_overflowed, lhs);
+ case 3:
-+ return handle_binary_ops(visited, potentionally_overflowed, var);
++ return handle_binary_ops(visited, potentionally_overflowed, lhs);
+#if BUILDING_GCC_VERSION >= 4007
+ case 4:
-+ return handle_ternary_ops(visited, potentionally_overflowed, var);
++ return handle_ternary_ops(visited, potentionally_overflowed, lhs);
+#endif
+ }
+ default:
@@ -114922,9 +114954,9 @@ index 0000000..41e11e1
+ }
+}
+
-+static void change_function_arg(gimple stmt, tree origarg, unsigned int argnum, tree newarg)
++static void change_function_arg(gimple stmt, const_tree origarg, unsigned int argnum, tree newarg)
+{
-+ gimple assign;
++ const_gimple assign;
+ gimple_stmt_iterator gsi = gsi_for_stmt(stmt);
+ tree origtype = TREE_TYPE(origarg);
+
@@ -114936,10 +114968,11 @@ index 0000000..41e11e1
+ update_stmt(stmt);
+}
+
-+static tree get_function_arg(unsigned int argnum, gimple stmt, tree fndecl)
++static tree get_function_arg(unsigned int argnum, const_gimple stmt, const_tree fndecl)
+{
+ const char *origid;
-+ tree arg, origarg;
++ tree arg;
++ const_tree origarg;
+
+ if (!DECL_ABSTRACT_ORIGIN(fndecl)) {
+ gcc_assert(gimple_call_num_args(stmt) > argnum);
@@ -114963,7 +114996,7 @@ index 0000000..41e11e1
+ return NULL_TREE;
+}
+
-+static void handle_function_arg(gimple stmt, tree fndecl, unsigned int argnum)
++static void handle_function_arg(gimple stmt, const_tree fndecl, unsigned int argnum)
+{
+ struct pointer_set_t *visited;
+ tree arg, newarg;
@@ -114993,7 +115026,7 @@ index 0000000..41e11e1
+ check_size_overflow(stmt, TREE_TYPE(newarg), newarg, arg, &potentionally_overflowed, BEFORE_STMT);
+}
+
-+static void handle_function_by_attribute(gimple stmt, tree attr, tree fndecl)
++static void handle_function_by_attribute(gimple stmt, const_tree attr, const_tree fndecl)
+{
+ tree p = TREE_VALUE(attr);
+ do {
@@ -115002,11 +115035,11 @@ index 0000000..41e11e1
+ } while (p);
+}
+
-+static void handle_function_by_hash(gimple stmt, tree fndecl)
++static void handle_function_by_hash(gimple stmt, const_tree fndecl)
+{
-+ tree orig_fndecl;
++ const_tree orig_fndecl;
+ unsigned int num;
-+ struct size_overflow_hash *hash;
++ const struct size_overflow_hash *hash;
+
+ orig_fndecl = get_original_function_decl(fndecl);
+ hash = get_function_hash(orig_fndecl);
@@ -115043,7 +115076,7 @@ index 0000000..41e11e1
+ next = bb->next_bb;
+
+ for (gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) {
-+ tree fndecl, attr;
++ const_tree fndecl, attr;
+ gimple stmt = gsi_stmt(gsi);
+
+ if (!(is_gimple_call(stmt)))