smol.py 2.34 KB
Newer Older
PoroCYon's avatar
PoroCYon committed
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
31
#!/usr/bin/env python3

import argparse
import glob
import itertools
import os.path
import shutil
import subprocess
import sys

from smolshared import *
from smolparse  import *
from smolemit   import *

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-m', '--target', default='', \
        help='architecture to generate asm code for (default: auto)')
    parser.add_argument('-l', '--library', metavar='LIB', action='append', \
        help='libraries to link against')
    parser.add_argument('-L', '--libdir', metavar='DIR', action='append', \
        help="directories to search libraries in")

    parser.add_argument('--nasm', default=shutil.which('nasm'), \
        help="which nasm binary to use")
    parser.add_argument('--cc', default=shutil.which('cc'), \
        help="which cc binary to use")
    parser.add_argument('--scanelf', default=shutil.which('scanelf'), \
        help="which scanelf binary to use")
    parser.add_argument('--readelf', default=shutil.which('readelf'), \
        help="which readelf binary to use")
32

33
34
#   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.")
35

PoroCYon's avatar
PoroCYon committed
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
    parser.add_argument('input', nargs='+', help="input object file")
    parser.add_argument('output', type=argparse.FileType('w'), \
        help="output nasm file", default=sys.stdout)

    args = parser.parse_args()

    if args.libdir is None: args.libdir = []
    arch = args.target.tolower() if len(args.target)!=0 \
                                 else decide_arch(args.input)
    if arch not in archmagic:
        eprintf("Unknown architecture '" + str(arch) + "'")
        sys.exit(1)

    syms = get_needed_syms(args.readelf, args.input)

    paths = get_cc_paths(args.cc)

    spaths = args.libdir + paths['libraries']
    libraries=paths['libraries']
    libnames = args.library
    libs = list(find_libs(spaths, libnames))
    symbols = {}

59
    for symbol, reloc in syms:
PoroCYon's avatar
PoroCYon committed
60
61
62
63
64
        library = find_symbol(args.scanelf, libs, libnames, symbol)
        if not library:
            eprintf("could not find symbol: {}".format(symbol))
            sys.exit(1)
        symbols.setdefault(library, [])
65
        symbols[library].append((symbol, reloc))
PoroCYon's avatar
PoroCYon committed
66

67
    output(arch, symbols, args.output)
PoroCYon's avatar
PoroCYon committed
68
69
70
71

if __name__ == '__main__':
    main()