Skip to content

Commit

Permalink
go all the way
Browse files Browse the repository at this point in the history
  • Loading branch information
comex committed Jun 23, 2011
1 parent 08142f0 commit 3ce1883
Show file tree
Hide file tree
Showing 11 changed files with 183 additions and 164 deletions.
66 changes: 10 additions & 56 deletions catalog/catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@

mode, version, cachefile, kernfile, patchfile, kcode, outfile = sys.argv[1:8]
four_dot_three = '4.3' in version
cachefiles = [cachefile] + sys.argv[8:]
polyglot = len(cachefiles) > 1

assert mode in ['dejavu', 'untether']
patchfp = open(patchfile)
Expand Down Expand Up @@ -121,10 +119,11 @@ def set_cache(cachefile):
if mode == 'dejavu':
add_lib(conn, 'ft', '/System/Library/Frameworks/CoreGraphics.framework/Resources/libCGFreetype.A.dylib')
add_lib(conn, 'libz', '/usr/lib/libz.dylib')
add_lib(conn, 'c++', '/usr/lib/libstdc++.6.0.9.dylib')
add_lib(conn, 'iokit', '/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit')
return conn
if not polyglot: dmini.cur = set_cache(cachefile)
targets = [None]

dmini.cur = set_cache(cachefile)

if four_dot_three:
def wrap(self, num):
Expand Down Expand Up @@ -167,7 +166,7 @@ def do_main_thing():

if mode == 'untether':
# XXX is this necessary? it's from star
funcall('iokit._IOKitWaitQuiet', 0, 0)#ptrI(0, 0, 0))
pass #funcall('iokit._IOKitWaitQuiet', 0, 0)#ptrI(0, 0, 0))

funcall('iokit._IOServiceMatching', AppleRGBOUT)
store_r0_to(matchingp)
Expand Down Expand Up @@ -235,54 +234,9 @@ def do_main_thing():
dest_len_p = ptrI(reloc(0xa, 0))
locutus_str = ptr('/tmp/locutus', True)

if not polyglot:
make_r7_avail()
set_sp_to_sp()
do_main_thing()
else:
cases = {}
idy = {}

old_fwds = goo.fwds

for cachefile in cachefiles:
print cachefile
dmini.cur = set_cache(cachefile)
old_heap, goo.heap = goo.heap, troll_string()
come_from_load_sp_r0('')
do_main_thing()
new_heap, goo.heap = goo.heap, old_heap
stderrp = dmini.cur.sym('___stderrp')
print cachefile, stderrp
if cases.has_key(stderrp):
print cases.keys()
raise Exception("Well, that's weird. I'm %s but %s was taken by %s" % (cachefile, stderrp, idy[stderrp]))
cases[stderrp] = new_heap
idy[stderrp] = cachefile

old_fa = dmini.data.b_find_anywhere
def new_fa(binary, pattern, align, flags):
print '>>', pattern

result = dmini.data.find_data(dmini.data.b_macho_segrange(dmini.cur.binaries['ft'], '__TEXT'), pattern, align, flags)
return result

dmini.data.b_find_anywhere = new_fa

goo.fwds = old_fwds

make_r7_avail()
set_sp_to_sp()

make_avail()
switch_ptr = dmini.cur.sym('ft.___stderrp', 'imported')

crap = map_switch(switch_ptr, cases)
load_sp_r0()
heapadd(crap)

dmini.data.b_find_anywhere = old_fa

make_r7_avail()
set_sp_to_sp()
do_main_thing()

goo.sheap.append(weirdfile)

Expand All @@ -297,12 +251,12 @@ def new_fa(binary, pattern, align, flags):
# add sp, #392; pop {r2, r5, r6, pc}
parse_callback = reloc_value(dmini.cur.find('+ 50 b0 30 bd'))
actual_parse_callback = reloc_value(dmini.cur.sym('ft._T1_Parse_Glyph', 'private'))
parse_callback = 0xdeadbeef
print dmini.cur.path, hex(parse_callback), parse_callback - actual_parse_callback
personality = reloc_value(dmini.cur.sym('c++.___gxx_personality_sj0'))
#parse_callback = 0xdeadbeef

final = final.unpack()

open(outfile, 'w').write(pickle.dumps({'parse_callback': parse_callback, 'actual_parse_callback': actual_parse_callback, 'final': final}))
open(outfile, 'w').write(pickle.dumps({'parse_callback': parse_callback, 'actual_parse_callback': actual_parse_callback, 'personality': personality, 'final': final}))
else:
# for two.py
initializer = dmini.cur.find('+ 5f 13 77 47') # asrs r7, r3, #13; bx lr
Expand Down
154 changes: 87 additions & 67 deletions dejavu/gen_dejavu.raw.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
# later, parse_callback - expected
# 2: buildchar (used for buildchar offset, duh!)
# 3: idx
# 4: personality - parse_callback
# 31000: [start of data]

import struct, sys
Expand Down Expand Up @@ -112,7 +113,61 @@ def encode_unknown(s):
return
'''

subrs['main'] = \
subrno = max(subrs.keys()) + 1

le_chain = '0\n'

diffs_seen = set()

for data in sorted(stuff, key=lambda d: d['personality'] - d['actual_parse_callback']):
diff = data['personality'] - data['actual_parse_callback']
if diff in diffs_seen:
raise Exception('duplicate')
diffs_seen.add(diff)

assert data['parse_callback'] > 32000
assert data['actual_parse_callback'] > 32000

le_chain += str(subrno) + ' 1 1 25 callothersubr ' + xrepr_plus_small(diff, False, [4, 27]) + ' callothersubr\n'

subr = '''1 1 25 callothersubr % get parse_callback
{actual_pc} 2 21 callothersubr % subtract the real one
1 2 24 callothersubr % store back
0 {pc}
1 1 25 callothersubr
2 20 callothersubr
setcurrentpoint
'''.format(actual_pc=xrepr_to_small(data['actual_parse_callback'], False), pc=xrepr_to_small(data['parse_callback'], False))

for number in data['final']:
if hasattr(number, 'key'):
key = number.key
number = number.value
else:
key = 0
if key == 0xa: # locutus length
number += locutus_len
elif key == 0xb: # compressed locutus length
number += zlocutus_len
elif key == 0xd: # code offset
subr += xrepr_plus_small(number + 31000*4, False, [7]) + ' callsubr '
continue
elif key == 0xe: # decoder offset
subr += xrepr_plus_small(number - 0x70 - 257*4, False, [6]) + ' callsubr '
continue
elif key == 3: # dyld cache
subr += xrepr_plus_small(number, False, [5]) + ' callsubr '
continue
else:
assert key == 0
subr += xrepr_plus_small(number, False, [4]) + ' callsubr '

subr += 'return'
subrs[subrno] = subr

subrno += 1

main = \
'''3 0 setcurrentpoint
3 callsubr % prepare for the first run up
-347 42 callothersubr
Expand All @@ -129,39 +184,49 @@ def encode_unknown(s):
3 callsubr % start flex so we can get x and y
0 0 0 3 0 callothersubr
1 2 24 callothersubr % parse_callback -> bca[1]
0 2 24 callothersubr % top -> bca[0]
1 2 24 callothersubr % parse_callback -> bca[1]
0 2 24 callothersubr % top -> bca[0]
-101 42 callothersubr % back up to get buildchar
setcurrentpoint % now at 343
hstem3 hstem3 hstem3 hstem3
hstem3 hstem3 hstem3 hstem3
hstem3 hstem3 hstem3 hstem3
hstem3 hstem3 hstem3
253 42 callothersubr
hstem3 hstem3 hstem3 hstem3
3 callsubr % flex again
0 0 0 3 0 callothersubr
2 2 24 callothersubr % buildchar -> bca[2]
{twenty} 42 callothersubr % go up to 20
-150 42 callothersubr % back up to 398 get gxx_personality_sj0
setcurrentpoint
hstem3 hstem3 hstem3 hstem3
hstem3 hstem3 hstem3 hstem3
hstem3 hstem3 hstem3 hstem3
hstem3 hstem3 hstem3 hstem3
hstem3 hstem3 hstem3 hstem3
hstem3 hstem3 hstem3 hstem3
252 42 callothersubr % this had better get us to 20 (or actually 0!) down when it does 31000 stuff
31000 3 2 24 callothersubr % idx = 31000
3 callsubr % flex again
0 0 0 3 0 callothersubr % personality
1 1 25 callothersubr % parse_callback
2 21 callothersubr % subtract
4 2 24 callothersubr % store to 4
hmoveto % ignore x
1 1 25 callothersubr % first
1 1 25 callothersubr % second
2 div % / 2
2 2 22 callothersubr % * 2
2 21 callothersubr % x - ((x / 2) * 2)
{le_chain}
2 2 20 callothersubr % + 2, so it's 1 or 2
callsubr % call 1 or 2 to:
% - add data to BCA;
% - set y to an appropriate parse_callback
% be lazy - take first items from BCA and stick them at 20
callsubr % call the subr to:
% - add data to BCA;
% - set y to an appropriate parse_callback
% be lazy - take first items from BCA and stick them at 20
31000 1 25 callothersubr
31001 1 25 callothersubr
31002 1 25 callothersubr
Expand All @@ -181,62 +246,17 @@ def encode_unknown(s):
0 0 0 64 64 seac % 64 = @
endchar % unnecessary if it worked''' \
.format(twenty=-(0 - 1), go_up_amount = -(344 - 7 - 0))

subrs[1] = 'return'
subrs[2] = 'return'

for data in stuff:
subrno = 1 if (data['actual_parse_callback'] & 1) else 2
assert data['parse_callback'] > 32000
assert data['actual_parse_callback'] > 32000

subr = '''1 1 25 callothersubr % get parse_callback
{actual_pc} 2 21 callothersubr % subtract the real one
1 2 24 callothersubr % store back
0 {pc}
1 1 25 callothersubr
2 20 callothersubr
setcurrentpoint
'''.format(actual_pc=xrepr_to_small(data['actual_parse_callback'], False), pc=xrepr_to_small(data['parse_callback'], False))

for number in data['final']:
if hasattr(number, 'key'):
key = number.key
number = number.value
else:
key = 0
if key == 0xa: # locutus length
number += locutus_len
elif key == 0xb: # compressed locutus length
number += zlocutus_len
elif key == 0xd: # code offset
subr += xrepr_plus_small(number + 31000*4, False, [7]) + ' callsubr '
continue
elif key == 0xe: # decoder offset
subr += xrepr_plus_small(number - 0x70 - 257*4, False, [6]) + ' callsubr '
continue
elif key == 3: # dyld cache
subr += xrepr_plus_small(number, False, [5]) + ' callsubr '
continue
else:
assert key == 0
subr += xrepr_plus_small(number, False, [4]) + ' callsubr '

subr += 'return'
assert subrs[subrno] == 'return'
subrs[subrno] = subr
.format(go_up_amount = -(344 - 7 - 0), le_chain=le_chain)

num_bca = 3 << 16

template = open('dejavu.raw.template').read()
subrtext = ''
for num, subr in subrs.iteritems():
if num == 'main': continue
subrtext += 'dup %d {\n\t%s\n\t} put\n' % (num, subr)
template = template.replace('%BCA%', ' '.join(['0'] * num_bca))
template = template.replace('%MAIN%', subrs['main'])
template = template.replace('%NUMSUBRS%', '%d' % (len(subrs) - 1))
template = template.replace('%MAIN%', main)
template = template.replace('%NUMSUBRS%', str(max(subrs.keys()) + 1))
template = template.replace('%SUBRS%', subrtext)
template = template.replace('%TERMFUN%', '\x1b[2t\x1b[5t'*1000)

Expand Down
5 changes: 5 additions & 0 deletions fabricate.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@
import tempfile
import time

try:
WindowsError
except:
class WindowsError(Exception): pass

# so you can do "from fabricate import *" to simplify your build script
__all__ = ['setup', 'run', 'run_multiple', 'autoclean', 'main', 'shell', 'fabricate_version',
'memoize', 'outofdate',
Expand Down
2 changes: 1 addition & 1 deletion fs/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,5 +164,5 @@ extern struct vnodeop_desc *vfs_op_descs[];
extern void *union_dircheckp asm("$ldr_$_T_4d_4b_1b_68_73_b1_0d_f5_92_60");

extern void IOLog(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
//#define printf(args...) ((void) (args))
#define printf(args...) ((void) (args))

12 changes: 12 additions & 0 deletions fs/kpi_vfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -4267,3 +4267,15 @@ vn_checkunionwait(vnode_t vp)
msleep((caddr_t)&vp->v_flag, &vp->v_lock, 0, 0, 0);
vnode_unlock(vp);
}

void
vfs_unbusy(mount_t mp)
{
lck_rw_done(&mp->mnt_rwlock);
}
int
vnode_isdir(vnode_t vp)
{
return ((vp->v_type == VDIR)? 1 : 0);
}

2 changes: 2 additions & 0 deletions fs/union/union_subr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1057,6 +1057,7 @@ union_mkwhiteout(um, dvp, cnp, path)
struct componentname *cnp;
char *path;
{
return ENOENT;
int error;
struct vnode *wvp;
struct componentname cn;
Expand Down Expand Up @@ -1265,6 +1266,7 @@ union_lowervp(vp)
int
union_dowhiteout(struct union_node *un, vfs_context_t ctx)
{
return 0;
struct vnode_attr va;

if (UNNODE_FAULTIN(un))
Expand Down
Loading

0 comments on commit 3ce1883

Please sign in to comment.