25 lines
847 B
C
25 lines
847 B
C
|
// the spec macro chooses between alternatives depending on the "class"
|
||
|
// possible "classes": armv6 pre 4.3, armv7 pre 4.3, 4.3.x, 5.0.x
|
||
|
|
||
|
static unsigned int _armv6 = 0;
|
||
|
static unsigned int _armv7 = 1;
|
||
|
static unsigned int _43 = 2;
|
||
|
static unsigned int _50 = 3;
|
||
|
|
||
|
#define spec_(c1, v1, c2, v2, c3, v3, c4, v4, ...) \
|
||
|
(class >= (c1) ? (v1) : \
|
||
|
class >= (c2) ? (v2) : \
|
||
|
class >= (c3) ? (v3) : \
|
||
|
class >= (c4) ? (v4) : \
|
||
|
(die("no valid alternative"), (typeof(v1+0)) 0))
|
||
|
#define spec(args...) spec_(args, 10, 0, 10, 0, 10, 0)
|
||
|
|
||
|
#define is_armv7(binary) (binary->cpusubtype == 9)
|
||
|
|
||
|
static unsigned int classify(const struct binary *binary) {
|
||
|
if(!is_armv7(binary)) return _armv6;
|
||
|
else if(b_sym(binary, "_mach_gss_hold_cred", 0)) return _50;
|
||
|
else if(b_sym(binary, "_vfs_getattr", 0)) return _43;
|
||
|
else return _armv7;
|
||
|
}
|