44/*
55 * RDFlags: 32 bits per address.
66 *
7- * 31 27 26 22 21 20 19 17 16 9 8 7 0
7+ * 31 27 26 21 20 19 18 16 15 9 8 7 0
88 * ┌────────┬──────────────┬─────┬────────┬────────────┬─┬──────────┐
99 * │ free │ structure │class│arrival │ preserve │V│ value │
1010 * └────────┴──────────────┴─────┴────────┴────────────┴─┴──────────┘
11- * └───── cleared by clear ─────┘ └────── survives clear ─ ────────┘
12- * └────── cleared by undefine ──────────┘ └─ survives undefine ──┘
11+ * └─ cleared by clear ─┘ └──────── survives clear ────────┘
12+ * └──── cleared by undefine ────┘ └─ survives undefine ─ ──┘
1313 *
1414 * Ordering is forced by the masks: a flag survives an operation if it sits
1515 * BELOW that operation's cut. Both masks cut below the class bits, so both
1818 *
1919 * The three tiers, by who owns the truth:
2020 * preserve knowledge: users, loaders, DB rows. Class-agnostic and
21- * head-only: FL_NORET marks an instruction, a function EP or an
22- * IAT slot alike, exactly like FL_IMPORTED. Never retracted
23- * implicitly.
21+ * head-only. Never retracted implicitly.
2422 * arrival how control REACHES here (call/jump/fall-through). Owned by the
2523 * referrer, not by this cell's decode: a byte change here does not
2624 * invalidate them, so they survive clear + re-decode. Dropped by
2725 * undefine ("means nothing") or by becoming a TAIL ("cannot live
2826 * mid-item").
2927 * structure what these bytes DECODE TO. Re-derived on every decode.
28+ * FL_NORET lives here: it means "this instruction terminates
29+ * flow", derived from the callee's type (RDFunctionType.is_noret),
30+ * NOT "the symbol here never returns" - that lives in the type.
3031 *
3132 * FL_FLOW and FL_FUNC are mutually exclusive, enforced symmetrically by both
3233 * setters so the outcome does not depend on discovery order.
3536 *
3637 * FL_FLOW: set on the DESTINATION instruction:
3738 * - means "reached by fall-through from the previous instruction".
38- * - never set on function entries (FL_FUNC) or noreturn functions (FL_NORET)
39+ * - never set on function entries (FL_FUNC)
3940 * - both clear FL_FLOW automatically in their set functions.
4041 */
4142
@@ -51,23 +52,22 @@ static const RDFlags FL_XREFOUT = 1U << 12;
5152static const RDFlags FL_XREFIN = 1U << 13 ;
5253static const RDFlags FL_EXPORTED = 1U << 14 ;
5354static const RDFlags FL_IMPORTED = 1U << 15 ;
54- static const RDFlags FL_NORET = 1U << 16 ;
5555
5656// covers bits 0-15 (NOTE: always add the last flag above)
57- #define FL_UNDEFINE_MASK ((RDFlags)((FL_NORET << 1) - 1))
57+ #define FL_UNDEFINE_MASK ((RDFlags)((FL_IMPORTED << 1) - 1))
5858#define FL_HAS_INFO \
5959 ((RDFlags)(FL_UNDEFINE_MASK & ~(FL_VALUE | FL_PATCH | 0xFF)))
6060
6161// [ARRIVAL]
62- static const RDFlags FL_FLOW = 1U << 17 ;
63- static const RDFlags FL_JMPDST = 1U << 18 ;
64- static const RDFlags FL_FUNC = 1U << 19 ;
62+ static const RDFlags FL_FLOW = 1U << 16 ;
63+ static const RDFlags FL_JMPDST = 1U << 17 ;
64+ static const RDFlags FL_FUNC = 1U << 18 ;
6565
66- // covers bits 0-17 (NOTE: always add the last flag above)
66+ // covers bits 0-18 (NOTE: always add the last flag above)
6767#define FL_CLEAR_MASK ((RDFlags)((FL_FUNC << 1) - 1))
6868
69- // [CLASS]: 2-bit field, bits 20-21
70- #define FL_CLASS_SHIFT 20
69+ // [CLASS]: 2-bit field, bits 19-20
70+ #define FL_CLASS_SHIFT 19
7171#define FL_CLASS_MASK ((RDFlags)(3U << FL_CLASS_SHIFT))
7272
7373typedef enum {
@@ -78,9 +78,9 @@ typedef enum {
7878} RDFlagsClass ;
7979
8080// [STRUCTURE] CODE
81- // kind: 2-bit field, bits 22-23 .
81+ // kind: 2-bit field, bits 21-22 .
8282// JUMP/CALL are mutually exclusive.
83- #define FL_KIND_SHIFT 22
83+ #define FL_KIND_SHIFT 21
8484#define FL_KIND_MASK ((RDFlags)(3U << FL_KIND_SHIFT))
8585
8686typedef enum {
@@ -89,14 +89,15 @@ typedef enum {
8989 FL_KI_CALL ,
9090} RDFlagsKind ;
9191
92+ static const RDFlags FL_NORET = 1U << 23 ;
9293static const RDFlags FL_COND = 1U << 24 ;
9394static const RDFlags FL_DSLOT = 1U << 25 ;
9495static const RDFlags FL_OPOVER = 1U << 26 ;
9596
9697// [STRUCTURE] DATA
97- static const RDFlags FL_TYPE = 1U << 22 ;
98- static const RDFlags FL_FIELD = 1U << 23 ;
99- static const RDFlags FL_ITEM = 1U << 24 ;
98+ static const RDFlags FL_TYPE = 1U << 23 ;
99+ static const RDFlags FL_FIELD = 1U << 24 ;
100+ static const RDFlags FL_ITEM = 1U << 25 ;
100101
101102static RDFlagsClass _rd_flags_class (RDFlags self ) {
102103 return (RDFlagsClass )((self & FL_CLASS_MASK ) >> FL_CLASS_SHIFT );
@@ -145,7 +146,9 @@ bool rd_i_flags_has_call(RDFlags self) {
145146 return _rd_flags_kind (self ) == FL_KI_CALL ;
146147}
147148
148- bool rd_i_flags_has_noret (RDFlags self ) { return self & FL_NORET ; }
149+ bool rd_i_flags_has_noret (RDFlags self ) {
150+ return rd_i_flags_has_code (self ) && (self & FL_NORET );
151+ }
149152
150153bool rd_i_flags_has_cond (RDFlags self ) {
151154 return rd_i_flags_has_code (self ) && (self & FL_COND );
@@ -238,7 +241,10 @@ void rd_i_flags_set_func(RDFlags* self) {
238241 * self &= ~FL_FLOW ; // function entries break flow
239242}
240243
241- void rd_i_flags_set_noret (RDFlags * self ) { * self |= FL_NORET ; }
244+ void rd_i_flags_set_noret (RDFlags * self ) {
245+ assert (rd_i_flags_has_code (* self ));
246+ * self |= FL_NORET ;
247+ }
242248
243249void rd_i_flags_set_cond (RDFlags * self ) {
244250 assert (rd_i_flags_has_jump (* self ) || rd_i_flags_has_call (* self ));
0 commit comments