Commit 9f03bcf3 authored by PoroCYon's avatar PoroCYon Committed by PoroCYon
Browse files

add --det flag for deterministic order of imports

parent 4929ec18
......@@ -33,13 +33,12 @@ def main():
parser.add_argument('-s', '--hash16', default=False, action='store_true', \
help="Use 16-bit (BSD) hashes instead of 32-bit djb2 hashes. "\
+"Must be used with -DUSE_DNLOAD_LOADER")
# parser.add_argument('-d', '--dnload', default=False, action='store_true', \
# help="Use dnload's mechanism of importing functions. Slightly larger, but usually better compressable.")
# parser.add_argument('--libsep', default=False, action='store_true', \
# help="Separete import symbols per library, instead of looking at every library when resolving a symbol.")
parser.add_argument('-n', '--nx', default=False, action='store_true', \
help="Use NX (i.e. don't use RWE pages). Costs the size of one phdr, "\
+"plus some extra bytes on i386.")
parser.add_argument('-d', '--det', default=False, action='store_true', \
help="Make the order of imports deterministic (default: just use on "+\
"whatever binutils throws at us)")
parser.add_argument('input', nargs='+', help="input object file")
parser.add_argument('output', type=argparse.FileType('w'), \
......@@ -72,7 +71,7 @@ def main():
symbols.setdefault(library, [])
symbols[library].append((symbol, reloc))
output(arch, symbols, args.nx, args.hash16, args.output)
output(arch, symbols, args.nx, args.hash16, args.output, args.det)
if __name__ == '__main__':
main()
......
import sys
from collections import OrderedDict
from smolshared import *
def output_x86(libraries, nx, h16, outf):
def sort_imports(libraries, hashfn):
#eprintf("in: " + str(libraries))
# sort libs by name length
ll = sorted(libraries.items(), key=lambda ls: len(ls[0]))
for i in range(len(ll)):
# sort symbols by hash value
ll[i] = (ll[i][0], sorted(ll[i][1], key=lambda sr: hashfn(sr[0])))
#eprintf("out:" + str(dict(ll)))
# insertion order only works with python >=3.6!
if sys.version_info < (3, 6): return OrderedDict(ll)
else: return dict(ll)
def output_x86(libraries, nx, h16, outf, det):
outf.write('; vim: set ft=nasm:\n') # be friendly
if nx: outf.write('%define USE_NX 1\n')
if h16: outf.write('%define USE_HASH16 1\n')
hashfn = hash_bsd2 if h16 else hash_djb2
if det: libraries = sort_imports(libraries, hashfn)
usedrelocs = set({})
for library, symrels in libraries.items():
for sym, reloc in symrels: usedrelocs.add(reloc)
......@@ -56,16 +76,15 @@ dynamic.end:
eprintf('Relocation type ' + reloc + ' of symbol ' + sym + ' unsupported!')
sys.exit(1)
hash = hash_bsd2(sym) if h16 else hash_djb2(sym)
if nx:
outf.write("\t\t_symbols.{lib}.{name}: dd 0x{hash:x}"\
.format(lib=shorts[library],name=sym,hash=hash).lstrip('\n'))
.format(lib=shorts[library],name=sym,hash=hashfn(sym)).lstrip('\n'))
else:
outf.write(("""\
\t\tglobal {name}
\t\t{name}:""" + ("\n\t\t\tdb 0xE9" if use_jmp_bytes else '') + """
\t\t\tdd 0x{hash:x}
""").format(name=sym, hash=hash).lstrip('\n'))
""").format(name=sym, hash=hashfn(sym)).lstrip('\n'))
outf.write('db 0\n')
outf.write('_symbols.end:\n')
......@@ -87,7 +106,7 @@ global {name}
# end output_x86
def output_amd64(libraries, nx, h16, outf):
def output_amd64(libraries, nx, h16, outf, det):
if h16:
eprintf("--hash16 not supported yet for x86_64 outputs.")
exit(1)
......@@ -95,6 +114,9 @@ def output_amd64(libraries, nx, h16, outf):
if nx: outf.write('%define USE_NX 1\n')
# if h16: outf.write('%define USE_HASH16 1\n')
hashfn = hash_djb2 #hash_bsd2 if h16 else hash_djb2
if det: libraries = sort_imports(libraries, hashfn)
outf.write('; vim: set ft=nasm:\n')
outf.write('bits 64\n')
......@@ -138,9 +160,8 @@ global {name}
{name}:
""".format(name=sym).lstrip('\n'))
hash = hash_bsd2(sym) if h16 else hash_djb2(sym)
outf.write('\t\t_symbols.{lib}.{name}: dq 0x{hash:x}\n'\
.format(lib=shorts[library],name=sym,hash=hash))
.format(lib=shorts[library],name=sym,hash=hashfn(sym)))
outf.write('db 0\n')
outf.write('_symbols.end:\n')
......@@ -161,9 +182,9 @@ global {name}
# end output_amd64
def output(arch, libraries, nx, h16, outf):
if arch == 'i386': output_x86(libraries, nx, h16, outf)
elif arch == 'x86_64': output_amd64(libraries, nx, h16, outf)
def output(arch, libraries, nx, h16, outf, det):
if arch == 'i386': output_x86(libraries, nx, h16, outf, det)
elif arch == 'x86_64': output_amd64(libraries, nx, h16, outf, det)
else:
eprintf("E: cannot emit for arch '" + str(arch) + "'")
sys.exit(1)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment