Trace external pointers through function returns (#1821)

* Trace external pointers through function returns

Surprisingly, the rewriter wasn't able to trace external pointers
returned by inlined functions until now.  This commit fixes it by
adding functions that return an external pointer to ProbeVisitor's
set of external pointers, along with the levels of indirection.

This change requires reversing a few traversals to visit called
functions before they are called.  Then, we check the presence of an
external pointer on return statements and retrieve that information
at the call expression.

* Tests dereferences of ext ptrs returned by inlined func

* tcpdrop: remove unnecessary bpf_probe_read calls

e783567a makes these calls unnecessary.
diff --git a/tools/tcpdrop.py b/tools/tcpdrop.py
index 77ad752..9667868 100755
--- a/tools/tcpdrop.py
+++ b/tools/tcpdrop.py
@@ -107,16 +107,16 @@
     u8 tcpflags = 0;
     struct tcphdr *tcp = skb_to_tcphdr(skb);
     struct iphdr *ip = skb_to_iphdr(skb);
-    bpf_probe_read(&sport, sizeof(sport), &tcp->source);
-    bpf_probe_read(&dport, sizeof(dport), &tcp->dest);
+    sport = tcp->source;
+    dport = tcp->dest;
     bpf_probe_read(&tcpflags, sizeof(tcpflags), &tcp_flag_byte(tcp));
     sport = ntohs(sport);
     dport = ntohs(dport);
 
     if (family == AF_INET) {
         struct ipv4_data_t data4 = {.pid = pid, .ip = 4};
-        bpf_probe_read(&data4.saddr, sizeof(u32), &ip->saddr);
-        bpf_probe_read(&data4.daddr, sizeof(u32), &ip->daddr);
+        data4.saddr = ip->saddr;
+        data4.daddr = ip->daddr;
         data4.dport = dport;
         data4.sport = sport;
         data4.state = state;