offsetof is resolved very early in gcc, only INTEGER_CST is left but no type information in gimple -> define __builtin_offsetof as __spslr_offsetof("type", "member", __builtin_offsetof(type, member)) -> gcc does not know what to do with __spslr_offsetof so it remains in tree during gimple -> plugin can extract type and member name and then replace the call with just the INTEGER_CST precise per-instruction labels are required at RTL level single gimple statement can cause multiple RTL instructions only out-of-the-box mapping is location (line, file, ...) multiple gimple statements can share single location gimple optimizations can merge statements from different locations -> build logic tree at gimple but after gimple optimizations (right before conversion to RTL) -> at RTL, pattern match sets of RTL instructions with same location to pattern of gimple statements -> attach notes to any RTL instruction that accesses relevant structs -> notes are propagated throughout RTL optimizations -> at the very end of RTL handling, discover notes and add assembly labels Constant foldable expressions, e.g. "size_t myOffset = ((size_t)&((struct task_struct*)0)->tasks);", are invisible -> gcc folds those expressions before PLUGIN_FINISH_PARSE_FUNCTION -> any recoverability of COMPONENT_REF is impossible -> requires gcc patch (fairly small one though) -> fold_offsetof in the C frontend is responsible -> can not universally be disabled (loss of const-ness, static assertions fail) -> would be okay for randomized structs (semantically not constant at compile time any more) -> PROBLEM for structs that are NOT targets! -> static assertions happen before plugin could restore const-ness -> plugin callback in build_component_ref (0 miss rate) -> must be type compatible for fold_offsetof CONSTRUCTORs are only turned into COMPONENT_REF at gimplification -> early gimple pass (before cfg) to replace offsets with calls