Context sensitive function behavior

Usually C, unlike dynamic languages, considered not so easy to write context sensitive code. To demonstrate that this is feasible, at least on some systems and compilers I wrote following hack. Function foxy() behaves differently depending on who called it. This behavior could be useful in profilers, and some modularity checks (for example if you want to ensure noone calls your static functions even by pointers).
#include <elf.h>
#include <stdio.h>
#include <stdint.h>

typedef struct {
  intptr_t start;
  intptr_t end;
  char\* value;
} range_t;


static range_t ranges[2];

int compute_size(void\* start) {
  Dl_info dlip;
  Elf32_Sym\* sym = 0;
  int rv = dladdr1(start, &dlip, (void\*\*)&sym, RTLD_DL_SYMENT);
  
  return (rv && sym) ? sym->st_size : -1;
}

void init_ranges() {
  int i;

  ranges[0].start = (intptr_t)&foo;
  ranges[0].value = "foo";
  ranges[1].start = (intptr_t)&bar;
  ranges[1].value = "bar";

  for (i=0; i < sizeof(ranges)/sizeof(ranges[0]); i++) {
    int sz = compute_size((void\*)ranges[i].start);
    if (sz < 0) {
      sz = 0;
    }
    ranges[i].end = ranges[i].start + sz;
  }
}
 

char\* foxy() {
  intptr_t caller = (intptr_t)__builtin_return_address (0);
  int i, idx = -1;
  
  for (i=0; i < sizeof(ranges)/sizeof(ranges[0]); i++) {
    if (caller >= ranges[i].start && caller < ranges[i].end) {
      idx = i;
      break;
    }
  }
  

   if (idx != -1) {
    return ranges[i].value;
  }

  return "other";
}


void foo() {
  printf("foo=%s\\n", foxy());
}

void bar() {
  printf("bar=%s\\n", foxy());
}

void boo() {
  printf("boo=%s\\n", foxy());
}




int main() {
  init_ranges();
  foo();
  bar();
  boo();
  return 0;
}
Comments:

Post a Comment:
  • HTML Syntax: NOT allowed
About

nike

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today