github.com/epfl-dcsl/gotee@v0.0.0-20200909122901-014b35f5e5e9/src/cmd/compile/internal/gc/gosecure.go (about)

     1  package gc
     2  
     3  // Global variables for the  current state.
     4  
     5  // Contains the k: fndcl, v: list of call sites.
     6  var targetMap map[*Node]Nodes
     7  
     8  // Generic functions that I can instrument.
     9  
    10  // genwalker is a generic walker for the Node type thgosecure callat visits all the children.
    11  // It takes as parameter a cond func that decides whether or not to apply
    12  // the act function on the node.
    13  func genwalker(n *Node, cond func(n *Node) bool, act func(n *Node)) {
    14  	if n == nil {
    15  		return
    16  	}
    17  	if cond(n) {
    18  		act(n)
    19  	}
    20  	genwalker(n.Left, cond, act)
    21  	genwalker(n.Right, cond, act)
    22  	genwalkerlist(n.Ninit, cond, act)
    23  	genwalkerlist(n.Nbody, cond, act)
    24  	genwalkerlist(n.List, cond, act)
    25  	genwalkerlist(n.Rlist, cond, act)
    26  }
    27  
    28  // genwalkerlist is a simple helper to call genwalker on all Nodes in a slice.
    29  func genwalkerlist(ns Nodes, cond func(n *Node) bool, act func(n *Node)) {
    30  	for _, n := range ns.Slice() {
    31  		genwalker(n, cond, act)
    32  	}
    33  }
    34  
    35  // Implementation of the actually actions and conditions for gosecure.
    36  
    37  // isGosecureNode returns true if Node n is a gosecure node, i.e.,
    38  // if it has Op == OGOSECURE.
    39  func isGosecureNode(n *Node) bool {
    40  	if n == nil {
    41  		return false
    42  	}
    43  	return n.Op == OGOSECURE
    44  }
    45  
    46  // findGosecureDef finds the callee of a gosecure node n.
    47  func findGosecureDef(n *Node) {
    48  	if n == nil {
    49  		return
    50  	}
    51  
    52  	if _, ok := targetMap[n]; ok {
    53  		yyerror("OGOSECURE node already in the map.")
    54  		return
    55  	}
    56  
    57  	if n.Left == nil || n.Left.Left == nil || n.Left.Left.Name == nil {
    58  		yyerror("OCALLFUNC or ONAME or Name node is nil in gosecure.")
    59  		return
    60  	}
    61  
    62  	defn := n.Left.Left.Name.Defn
    63  	if defn == nil {
    64  		//The function is from another package.
    65  		yyerror("Target of gosecure is in another package.")
    66  	}
    67  	entry := targetMap[defn]
    68  	entry.Append(n)
    69  }
    70  
    71  // getCopy highjacks the inliner mechanism to generate a copy of the node.
    72  func getCopy(n *Node) *Node {
    73  	return inlcopy(n)
    74  }
    75  
    76  // Non generic version of the walker
    77  
    78  func gosecureWalker(n *Node) {
    79  	genwalker(n, isGosecureNode, findGosecureDef)
    80  }
    81  
    82  // findSecureNodes calls the walker on the ttop nodes.
    83  func GosecurePhase(ttop []*Node) {
    84  	if targetMap != nil {
    85  		yyerror("The target map wasn't nil before starting.")
    86  	}
    87  
    88  	targetMap = make(map[*Node]Nodes)
    89  	for _, n := range ttop {
    90  		gosecureWalker(n)
    91  	}
    92  
    93  	// At that point we need to replace the targetMap with a copy.
    94  	// TODO aghosn check memory and liveliness for code below.
    95  	replacement := make(map[*Node]Nodes)
    96  	for k, v := range targetMap {
    97  		replacement[getCopy(k)] = v
    98  	}
    99  	targetMap = replacement
   100  
   101  	// Package the code.
   102  	// /enclpkg := obj.NewPkg("go.enclave", "enclave")
   103  }