2020-08-07 16:11:04 +08:00
|
|
|
From d71913d38475f5b4f0dc753074337ba29d5c0789 Mon Sep 17 00:00:00 2001
|
|
|
|
|
From: Guy Harris <gharris@sonic.net>
|
|
|
|
|
Date: Thu, 21 May 2020 22:37:19 -0700
|
|
|
|
|
Subject: [PATCH 875/977] optimize: make some variables unsigned.
|
|
|
|
|
|
|
|
|
|
That should avoid some overflow failure modes, and allow saner overflow
|
|
|
|
|
checking.
|
|
|
|
|
---
|
2021-08-09 17:29:44 +08:00
|
|
|
optimize.c | 92 +++++++++++++++++++++++++++++++++---------------------
|
2020-08-07 16:11:04 +08:00
|
|
|
1 file changed, 57 insertions(+), 35 deletions(-)
|
|
|
|
|
|
|
|
|
|
diff --git a/optimize.c b/optimize.c
|
2021-08-09 17:29:44 +08:00
|
|
|
index a70dfc5..d90b463 100644
|
2020-08-07 16:11:04 +08:00
|
|
|
--- a/optimize.c
|
|
|
|
|
+++ b/optimize.c
|
|
|
|
|
@@ -115,7 +115,7 @@ pcap_set_print_dot_graph(int value)
|
|
|
|
|
/*
|
|
|
|
|
* GCC 3.4 and later; we have __builtin_ctz().
|
|
|
|
|
*/
|
|
|
|
|
- #define lowest_set_bit(mask) __builtin_ctz(mask)
|
|
|
|
|
+ #define lowest_set_bit(mask) ((u_int)__builtin_ctz(mask))
|
|
|
|
|
#elif defined(_MSC_VER)
|
|
|
|
|
/*
|
|
|
|
|
* Visual Studio; we support only 2005 and later, so use
|
|
|
|
|
@@ -127,7 +127,7 @@ pcap_set_print_dot_graph(int value)
|
|
|
|
|
#pragma intrinsic(_BitScanForward)
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
-static __forceinline int
|
|
|
|
|
+static __forceinline u_int
|
|
|
|
|
lowest_set_bit(int mask)
|
|
|
|
|
{
|
|
|
|
|
unsigned long bit;
|
|
|
|
|
@@ -138,14 +138,14 @@ lowest_set_bit(int mask)
|
|
|
|
|
*/
|
|
|
|
|
if (_BitScanForward(&bit, (unsigned int)mask) == 0)
|
|
|
|
|
abort(); /* mask is zero */
|
|
|
|
|
- return (int)bit;
|
|
|
|
|
+ return (u_int)bit;
|
|
|
|
|
}
|
|
|
|
|
#elif defined(MSDOS) && defined(__DJGPP__)
|
|
|
|
|
/*
|
|
|
|
|
* MS-DOS with DJGPP, which declares ffs() in <string.h>, which
|
|
|
|
|
* we've already included.
|
|
|
|
|
*/
|
|
|
|
|
- #define lowest_set_bit(mask) (ffs((mask)) - 1)
|
|
|
|
|
+ #define lowest_set_bit(mask) ((u_int)(ffs((mask)) - 1))
|
|
|
|
|
#elif (defined(MSDOS) && defined(__WATCOMC__)) || defined(STRINGS_H_DECLARES_FFS)
|
|
|
|
|
/*
|
|
|
|
|
* MS-DOS with Watcom C, which has <strings.h> and declares ffs() there,
|
|
|
|
|
@@ -153,18 +153,18 @@ lowest_set_bit(int mask)
|
|
|
|
|
* of the Single UNIX Specification).
|
|
|
|
|
*/
|
|
|
|
|
#include <strings.h>
|
|
|
|
|
- #define lowest_set_bit(mask) (ffs((mask)) - 1)
|
|
|
|
|
+ #define lowest_set_bit(mask) (u_int)((ffs((mask)) - 1))
|
|
|
|
|
#else
|
|
|
|
|
/*
|
|
|
|
|
* None of the above.
|
|
|
|
|
* Use a perfect-hash-function-based function.
|
|
|
|
|
*/
|
|
|
|
|
-static int
|
|
|
|
|
+static u_int
|
|
|
|
|
lowest_set_bit(int mask)
|
|
|
|
|
{
|
|
|
|
|
unsigned int v = (unsigned int)mask;
|
|
|
|
|
|
|
|
|
|
- static const int MultiplyDeBruijnBitPosition[32] = {
|
|
|
|
|
+ static const u_int MultiplyDeBruijnBitPosition[32] = {
|
|
|
|
|
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
|
|
|
|
|
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
|
|
|
|
|
};
|
2021-08-09 17:29:44 +08:00
|
|
|
@@ -244,17 +244,17 @@ typedef struct {
|
2020-08-07 16:11:04 +08:00
|
|
|
*/
|
|
|
|
|
int done;
|
|
|
|
|
|
|
|
|
|
- int n_blocks;
|
|
|
|
|
+ u_int n_blocks; /* number of blocks in the CFG; guaranteed to be > 0, as it's a RET instruction at a minimum */
|
|
|
|
|
struct block **blocks;
|
|
|
|
|
- int n_edges;
|
|
|
|
|
+ u_int n_edges; /* twice n_blocks, so guaranteed to be > 0 */
|
|
|
|
|
struct edge **edges;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* A bit vector set representation of the dominators.
|
|
|
|
|
* We round up the set size to the next power of two.
|
|
|
|
|
*/
|
|
|
|
|
- int nodewords;
|
|
|
|
|
- int edgewords;
|
|
|
|
|
+ u_int nodewords; /* number of 32-bit words for a bit vector of "number of nodes" bits; guaranteed to be > 0 */
|
|
|
|
|
+ u_int edgewords; /* number of 32-bit words for a bit vector of "number of edges" bits; guaranteed to be > 0 */
|
|
|
|
|
struct block **levels;
|
|
|
|
|
bpf_u_int32 *space;
|
|
|
|
|
|
2021-08-09 17:29:44 +08:00
|
|
|
@@ -279,32 +279,35 @@ typedef struct {
|
2020-08-07 16:11:04 +08:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* a := a intersect b
|
|
|
|
|
+ * n must be guaranteed to be > 0
|
|
|
|
|
*/
|
|
|
|
|
#define SET_INTERSECT(a, b, n)\
|
|
|
|
|
{\
|
|
|
|
|
register bpf_u_int32 *_x = a, *_y = b;\
|
|
|
|
|
- register int _n = n;\
|
|
|
|
|
- while (--_n >= 0) *_x++ &= *_y++;\
|
|
|
|
|
+ register u_int _n = n;\
|
|
|
|
|
+ do *_x++ &= *_y++; while (--_n != 0);\
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* a := a - b
|
|
|
|
|
+ * n must be guaranteed to be > 0
|
|
|
|
|
*/
|
|
|
|
|
#define SET_SUBTRACT(a, b, n)\
|
|
|
|
|
{\
|
|
|
|
|
register bpf_u_int32 *_x = a, *_y = b;\
|
|
|
|
|
- register int _n = n;\
|
|
|
|
|
- while (--_n >= 0) *_x++ &=~ *_y++;\
|
|
|
|
|
+ register u_int _n = n;\
|
|
|
|
|
+ do *_x++ &=~ *_y++; while (--_n != 0);\
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* a := a union b
|
|
|
|
|
+ * n must be guaranteed to be > 0
|
|
|
|
|
*/
|
|
|
|
|
#define SET_UNION(a, b, n)\
|
|
|
|
|
{\
|
|
|
|
|
register bpf_u_int32 *_x = a, *_y = b;\
|
|
|
|
|
- register int _n = n;\
|
|
|
|
|
- while (--_n >= 0) *_x++ |= *_y++;\
|
|
|
|
|
+ register u_int _n = n;\
|
|
|
|
|
+ do *_x++ |= *_y++; while (--_n != 0);\
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uset all_dom_sets;
|
2021-08-09 17:29:44 +08:00
|
|
|
@@ -401,7 +404,8 @@ find_levels(opt_state_t *opt_state, struct icode *ic)
|
2020-08-07 16:11:04 +08:00
|
|
|
static void
|
|
|
|
|
find_dom(opt_state_t *opt_state, struct block *root)
|
|
|
|
|
{
|
|
|
|
|
- int i;
|
|
|
|
|
+ u_int i;
|
|
|
|
|
+ int level;
|
|
|
|
|
struct block *b;
|
|
|
|
|
bpf_u_int32 *x;
|
|
|
|
|
|
2021-08-09 17:29:44 +08:00
|
|
|
@@ -409,16 +413,25 @@ find_dom(opt_state_t *opt_state, struct block *root)
|
2020-08-07 16:11:04 +08:00
|
|
|
* Initialize sets to contain all nodes.
|
|
|
|
|
*/
|
|
|
|
|
x = opt_state->all_dom_sets;
|
|
|
|
|
+ /*
|
|
|
|
|
+ * These are both guaranteed to be > 0, so the product is
|
|
|
|
|
+ * guaranteed to be > 0.
|
|
|
|
|
+ *
|
|
|
|
|
+ * XXX - but what if it overflows?
|
|
|
|
|
+ */
|
|
|
|
|
i = opt_state->n_blocks * opt_state->nodewords;
|
|
|
|
|
- while (--i >= 0)
|
|
|
|
|
+ do
|
|
|
|
|
*x++ = 0xFFFFFFFFU;
|
|
|
|
|
+ while (--i != 0);
|
|
|
|
|
/* Root starts off empty. */
|
|
|
|
|
- for (i = opt_state->nodewords; --i >= 0;)
|
|
|
|
|
+ i = opt_state->nodewords;
|
|
|
|
|
+ do
|
|
|
|
|
root->dom[i] = 0;
|
|
|
|
|
+ while (--i != 0);
|
|
|
|
|
|
|
|
|
|
/* root->level is the highest level no found. */
|
|
|
|
|
- for (i = root->level; i >= 0; --i) {
|
|
|
|
|
- for (b = opt_state->levels[i]; b; b = b->link) {
|
|
|
|
|
+ for (level = root->level; level >= 0; --level) {
|
|
|
|
|
+ for (b = opt_state->levels[level]; b; b = b->link) {
|
|
|
|
|
SET_INSERT(b->dom, b->id);
|
|
|
|
|
if (JT(b) == 0)
|
|
|
|
|
continue;
|
2021-08-09 17:29:44 +08:00
|
|
|
@@ -445,19 +458,28 @@ propedom(opt_state_t *opt_state, struct edge *ep)
|
2020-08-07 16:11:04 +08:00
|
|
|
static void
|
|
|
|
|
find_edom(opt_state_t *opt_state, struct block *root)
|
|
|
|
|
{
|
|
|
|
|
- int i;
|
|
|
|
|
+ u_int i;
|
|
|
|
|
uset x;
|
|
|
|
|
+ int level;
|
|
|
|
|
struct block *b;
|
|
|
|
|
|
|
|
|
|
x = opt_state->all_edge_sets;
|
|
|
|
|
- for (i = opt_state->n_edges * opt_state->edgewords; --i >= 0; )
|
|
|
|
|
+ /*
|
|
|
|
|
+ * These are both guaranteed to be > 0, so the product is
|
|
|
|
|
+ * guaranteed to be > 0.
|
|
|
|
|
+ *
|
|
|
|
|
+ * XXX - but what if it overflows?
|
|
|
|
|
+ */
|
|
|
|
|
+ i = opt_state->n_edges * opt_state->edgewords;
|
|
|
|
|
+ do
|
|
|
|
|
x[i] = 0xFFFFFFFFU;
|
|
|
|
|
+ while (--i != 0);
|
|
|
|
|
|
|
|
|
|
/* root->level is the highest level no found. */
|
|
|
|
|
memset(root->et.edom, 0, opt_state->edgewords * sizeof(*(uset)0));
|
|
|
|
|
memset(root->ef.edom, 0, opt_state->edgewords * sizeof(*(uset)0));
|
|
|
|
|
- for (i = root->level; i >= 0; --i) {
|
|
|
|
|
- for (b = opt_state->levels[i]; b != 0; b = b->link) {
|
|
|
|
|
+ for (level = root->level; level >= 0; --level) {
|
|
|
|
|
+ for (b = opt_state->levels[level]; b != 0; b = b->link) {
|
|
|
|
|
propedom(opt_state, &b->et);
|
|
|
|
|
propedom(opt_state, &b->ef);
|
|
|
|
|
}
|
2021-08-09 17:29:44 +08:00
|
|
|
@@ -474,7 +496,7 @@ find_edom(opt_state_t *opt_state, struct block *root)
|
2020-08-07 16:11:04 +08:00
|
|
|
static void
|
|
|
|
|
find_closure(opt_state_t *opt_state, struct block *root)
|
|
|
|
|
{
|
|
|
|
|
- int i;
|
|
|
|
|
+ int level;
|
|
|
|
|
struct block *b;
|
|
|
|
|
|
|
|
|
|
/*
|
2021-08-09 17:29:44 +08:00
|
|
|
@@ -484,8 +506,8 @@ find_closure(opt_state_t *opt_state, struct block *root)
|
2020-08-07 16:11:04 +08:00
|
|
|
opt_state->n_blocks * opt_state->nodewords * sizeof(*opt_state->all_closure_sets));
|
|
|
|
|
|
|
|
|
|
/* root->level is the highest level no found. */
|
|
|
|
|
- for (i = root->level; i >= 0; --i) {
|
|
|
|
|
- for (b = opt_state->levels[i]; b; b = b->link) {
|
|
|
|
|
+ for (level = root->level; level >= 0; --level) {
|
|
|
|
|
+ for (b = opt_state->levels[level]; b; b = b->link) {
|
|
|
|
|
SET_INSERT(b->closure, b->id);
|
|
|
|
|
if (JT(b) == 0)
|
|
|
|
|
continue;
|
2021-08-09 17:29:44 +08:00
|
|
|
@@ -1555,7 +1577,7 @@ fold_edge(struct block *child, struct edge *ep)
|
2020-08-07 16:11:04 +08:00
|
|
|
static void
|
|
|
|
|
opt_j(opt_state_t *opt_state, struct edge *ep)
|
|
|
|
|
{
|
|
|
|
|
- register int i, k;
|
|
|
|
|
+ register u_int i, k;
|
|
|
|
|
register struct block *target;
|
|
|
|
|
|
2021-08-09 17:29:44 +08:00
|
|
|
if (JT(ep->succ) == 0)
|
|
|
|
|
@@ -1839,17 +1861,16 @@ link_inedge(struct edge *parent, struct block *child)
|
2020-08-07 16:11:04 +08:00
|
|
|
static void
|
|
|
|
|
find_inedges(opt_state_t *opt_state, struct block *root)
|
|
|
|
|
{
|
|
|
|
|
- int i;
|
|
|
|
|
struct block *b;
|
|
|
|
|
|
|
|
|
|
- for (i = 0; i < opt_state->n_blocks; ++i)
|
|
|
|
|
+ for (u_int i = 0; i < opt_state->n_blocks; ++i)
|
|
|
|
|
opt_state->blocks[i]->in_edges = 0;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Traverse the graph, adding each edge to the predecessor
|
|
|
|
|
* list of its successors. Skip the leaves (i.e. level 0).
|
|
|
|
|
*/
|
|
|
|
|
- for (i = root->level; i > 0; --i) {
|
|
|
|
|
+ for (int i = root->level; i > 0; --i) {
|
|
|
|
|
for (b = opt_state->levels[i]; b != 0; b = b->link) {
|
|
|
|
|
link_inedge(&b->et, JT(b));
|
|
|
|
|
link_inedge(&b->ef, JF(b));
|
2021-08-09 17:29:44 +08:00
|
|
|
@@ -2005,7 +2026,7 @@ static void
|
2020-08-07 16:11:04 +08:00
|
|
|
intern_blocks(opt_state_t *opt_state, struct icode *ic)
|
|
|
|
|
{
|
|
|
|
|
struct block *p;
|
|
|
|
|
- int i, j;
|
|
|
|
|
+ u_int i, j;
|
|
|
|
|
int done1; /* don't shadow global */
|
|
|
|
|
top:
|
|
|
|
|
done1 = 1;
|
2021-08-09 17:29:44 +08:00
|
|
|
@@ -2014,7 +2035,8 @@ intern_blocks(opt_state_t *opt_state, struct icode *ic)
|
2020-08-07 16:11:04 +08:00
|
|
|
|
|
|
|
|
mark_code(ic);
|
|
|
|
|
|
|
|
|
|
- for (i = opt_state->n_blocks - 1; --i >= 0; ) {
|
|
|
|
|
+ for (i = opt_state->n_blocks - 1; i != 0; ) {
|
|
|
|
|
+ --i;
|
|
|
|
|
if (!isMarked(ic, opt_state->blocks[i]))
|
|
|
|
|
continue;
|
|
|
|
|
for (j = i + 1; j < opt_state->n_blocks; ++j) {
|
|
|
|
|
--
|
2021-08-09 17:29:44 +08:00
|
|
|
2.27.0
|
2020-08-07 16:11:04 +08:00
|
|
|
|