def perform_diff(): """Perform graphical diff.""" (modified, rightrev) = get_pred_revision_and_modified() ltf = None leftname = None if flag_prev_revision: rightrev = flag_prev_revision if flag_revision_pair: if modified: u.warning("warning: working copy of %s is " "modified" % flag_target_file) leftrev = flag_revision_pair[0] rightrev = flag_revision_pair[1] ltf = tempfile.NamedTemporaryFile(mode="w", prefix="svnpreddifftmp_REV%s_" % leftrev, delete=True) leftname = ltf.name u.verbose(1, "left temp file is: %s" % leftname) u.docmdout("svn cat -r%d %s" % (leftrev, flag_target_file), leftname) if flag_save_temps: save_temps(ltf, leftrev) else: u.verbose(1, "left file is: %s" % flag_target_file) leftname = flag_target_file rtf = tempfile.NamedTemporaryFile(mode="w", prefix="svnpreddifftmp_REV%s_" % rightrev, delete=True) rightname = rtf.name u.verbose(1, "right temp file is: %s" % rightname) u.docmdout("svn cat -r%d %s" % (rightrev, flag_target_file), rightname) if flag_save_temps: save_temps(rtf, rightrev) # Perform diff u.docmd("%s %s %s" % (flag_diff_cmd, leftname, rightname))
def grabaddrsize(line, func): """Grab address and size from objdump line if sym matches.""" # # ELF symtab examples: # # 000000000052b410 l F .text 0000000000000010 .hidden stat64 # 000000000000e990 g F .text 0000000000000008 _Unwind_SetIP # # Dynamic table examples: # # 000000000000e990 g DF .text 0000000000000008 GCC_3.0 _Unwind_SetIP # 0000000000520c70 g DF .text 0000000000000043 Base sinl # regexes = [ re.compile(r"^(\S+)\s.+\.text\s+(\S+)\s+(\S+)$"), re.compile(r"^(\S+)\s.+\.text\s+(\S+)\s+\S+\s+(\S+)$") ] hexstaddr = None hexsize = None for r in regexes: m = r.match(line) if m: name = m.group(3) u.verbose(2, "=-= name is %s" % name) if name == func: # Found hexstaddr = m.group(1) hexsize = m.group(2) break if hexstaddr and hexsize == "00000000": u.warning("warning -- malformed hexsize for func %s" % func) hexsize = "4" return (hexstaddr, hexsize)
def collect_all_loadmodules(): """Collect names of all interesting loadmodules.""" locations = None if flag_filemode == "target": locations = "%s/symbols/system" % apo else: locations = "%s/bin %s/lib64" % (aho, aho) u.verbose(1, "collecting loadmodules from %s" % locations) cmd = "find %s -type f -print" % locations u.verbose(1, "find cmd: %s" % cmd) cargs = shlex.split(cmd) mypipe = subprocess.Popen(cargs, stdout=subprocess.PIPE) pout, _ = mypipe.communicate() if mypipe.returncode != 0: u.error("command failed (rc=%d): cmd was %s" % (mypipe.returncode, cmd)) encoding = locale.getdefaultlocale()[1] decoded = pout.decode(encoding) lines = decoded.strip().split("\n") u.verbose(1, "found a total of %d load modules" % len(lines)) for line in lines: path = line.strip() u.verbose(2, "adding LM %s" % path) all_loadmodules[path] = 0 bn = os.path.basename(path) pdict = base_to_paths[bn] pdict[path] = 1 if flag_backward_slice: for filearg in flag_input_files: bn = os.path.basename(filearg) if bn not in all_loadmodules: u.warning("argument %s not found in all_loadmodules " "-- unable to compute slice" % filearg)
def annotate(func, tag, fn, ppo, perf_work): """Run 'perf annotate' on a specified function.""" # Check to see if function present in perf report repfile = "rep.%s.txt" % tag if not flag_dryrun: try: # 0.16% compile compile [.] runtime.mapdelete regex_fn = re.compile(r"^\s*(\S+)%\s+\S+.+\]\s+(\S+)$") found = False with open(repfile, "r") as rf: lines = rf.readlines() for line in lines: fm = regex_fn.match(line) if fm and fm.group(2) == func: found = True except IOError: u.warning("open failed for %s" % repfile) return if not found: u.warning("skipping annotate for %s, could not " "find in %s" % (func, repfile)) return report_file = "%s/ann%d.%s.txt" % (perf_work, fn, tag) ppo_append(ppo, "%s annotate -i perf.data.%s " "-s %s" % (flag_perf, tag, func), report_file) generated_reports[report_file] = 1
def examinefile(filename): """Perform symbol analysis on specified file.""" u.verbose(2, "examinefile(%s)" % filename) if filename not in all_loadmodules: fullpath = os.path.join(os.getcwd(), filename) if fullpath in all_loadmodules: filename = fullpath else: u.warning("unable to visit %s (not " "in %s out)" % (filename, flag_filemode)) return if all_loadmodules[filename] == 1: return if not in_symbols_dir(filename): u.warning("%s: does not appear to be in " "%s/symbols directory? skipping" % (filename, apo)) return soname = examine_deps(filename) if not soname: all_loadmodules[filename] = 1 return worklist = [] ddict = depends[soname] for dep in ddict: pdict = base_to_paths[dep] for path in pdict: if path in all_loadmodules and all_loadmodules[path] == 0: all_loadmodules[path] = 1 worklist.append(path) for item in worklist: examine_deps(item)
def grabaddrsize(line, func): """Grab address and size from objdump line if sym matches.""" # # ELF symtab examples: # # 000000000052b410 l F .text 0000000000000010 .hidden stat64 # 000000000000e990 g F .text 0000000000000008 _Unwind_SetIP # # Dynamic table examples: # # 000000000000e990 g DF .text 0000000000000008 GCC_3.0 _Unwind_SetIP # 0000000000520c70 g DF .text 0000000000000043 Base sinl # regexes = [re.compile(r"^(\S+)\s.+\.text\s+(\S+)\s+(\S+)$"), re.compile(r"^(\S+)\s.+\.text\s+(\S+)\s+\S+\s+(\S+)$")] hexstaddr = None hexsize = None for r in regexes: m = r.match(line) if m: name = m.group(3) u.verbose(2, "=-= name is %s" % name) if name == func: # Found hexstaddr = m.group(1) hexsize = m.group(2) break if hexstaddr and hexsize == "00000000": u.warning("warning -- malformed hexsize for func %s" % func) hexsize = "4" return (hexstaddr, hexsize)
def examine_file(f): """Examine and copy a file if it needs copying.""" rval = 0 sfile = os.path.join(flag_source_dir, f) if not os.path.exists(sfile): u.warning("file %s does not exist in src dir -- skipping" % f) return 0 dfile = os.path.join(flag_dest_dir, f) docopy = False if not os.path.exists(dfile): u.verbose(1, "file %s does not exist in dest dir" % f) docopy = True else: scksum = checksum_file(sfile) dcksum = checksum_file(dfile) if scksum != dcksum: u.verbose(1, "checksum mismatch (%s vs %s) " "on file %s" % (scksum, dcksum, f)) docopy = True if docopy: if flag_dryrun: u.verbose(0, "dryrun: cp %s %s" % (sfile, dfile)) else: u.verbose(0, "cp %s %s" % (sfile, dfile)) u.docmd("cp %s %s" % (sfile, dfile)) u.docmd("chmod 0755 %s" % dfile) rval = 1 return rval
def parse_args(): """Command line argument parsing.""" global flag_infiles try: optlist, args = getopt.getopt(sys.argv[1:], "d") except getopt.GetoptError as err: # unrecognized option usage(str(err)) if not args: usage("supply one or more link paths as arguments") for opt, _ in optlist: if opt == "-d": u.increment_verbosity() for a in args: if not os.path.exists(a): u.warning("failed to open/access '%s' -- skipping" % a) else: try: p = os.readlink(a) except OSError as ose: u.warning("unable to process '%s' -- %s" % (a, ose)) continue flag_infiles.append(a)
def perform(): """Create links in a gcc trunk repo for gofrontend development.""" msg = "" islink = True try: _ = os.readlink("gcc/go/gofrontend") except OSError as ose: msg = "%s" % ose islink = False if flag_reverse: if not islink: u.warning("warning: gcc/go/gofrontend not a link (%s), " "continuing anyway" % msg) return else: undolink("gcc/go/gofrontend") for item in os.listdir("libgo"): undolink("libgo/%s" % item) docmd("git checkout libgo") else: if islink: u.warning("warning: gcc/go/gofrontend is already a link, " "unable to proceed") return docmd("rm -rf gcc/go/gofrontend") docmd("ln -s ../../../gofrontend/go gcc/go/gofrontend") docmd("rm -rf libgo") docmd("mkdir libgo") libgo = "../gofrontend/libgo" for item in os.listdir(libgo): docmd("ln -s ../../gofrontend/libgo/%s libgo/%s" % (item, item))
def perform(): """Create links in a gcc trunk repo for gofrontend development.""" msg = "" islink = True try: _ = os.readlink("gcc/go/gofrontend") except OSError as ose: msg = "%s" % ose islink = False if flag_reverse: if not islink: u.warning("warning: gcc/go/gofrontend not a link (%s), " "continuing anyway" % msg) return else: undolink("gcc/go/gofrontend") for item in os.listdir("libgo"): undolink("libgo/%s" % item) docmd("git checkout libgo") else: if islink: u.warning("warning: gcc/go/gofrontend is already a link, " "unable to proceed") return docmd("rm -rf gcc/go/gofrontend") docmd("ln -s ../../../gofrontend/go gcc/go/gofrontend") docmd("rm -rf libgo") docmd("mkdir libgo") libgo = "../gofrontend/libgo" for item in os.listdir(libgo): docmd("ln -s ../../gofrontend/libgo/%s libgo/%s" % (item, item))
def examine_file(filename): """Perform symbol analysis on specified file.""" if not in_symbols_dir(filename): u.warning("%s: does not appear to be in " "%s/symbols directory? skipping" % (filename, apo)) return u.verbose(1, "visiting file %s" % filename) examine_sections(filename)
def examine_file(filename): """Perform symbol analysis on specified file.""" if not in_symbols_dir(filename): u.warning("%s: does not appear to be in " "%s/symbols directory? skipping" % (filename, apo)) return u.verbose(1, "visiting file %s" % filename) examine_sections(filename)
def parse_args(): """Command line argument parsing.""" global flag_echo, flag_dryrun, flag_dwarf_cu, flag_dumpdwarf try: optlist, args = getopt.getopt(sys.argv[1:], "deDa:f:m:W:Z") except getopt.GetoptError as err: # unrecognized option usage(str(err)) if args: usage("unknown extra args") for opt, arg in optlist: if opt == "-d": u.increment_verbosity() elif opt == "-D": u.verbose(0, "+++ dry run mode") flag_dryrun = True flag_echo = True elif opt == "-e": flag_echo = True elif opt == "-f": flag_functions[arg] = 1 elif opt == "-a": are = re.compile(r"^0x(\S+)$") m = are.match(arg) if not m: u.warning("ignore -a arg '%s' -- not in form 0x<hexdigits>" % arg) else: hd = m.group(1) good = True v = "bad" try: v = int(hd, 16) except ValueError: good = False u.warning("ignore -a arg '%s' -- not in form 0x<hexdigits>" % arg) if good: u.verbose(1, "looking for addr %s dec %d" % (arg, v)) flag_addresses[v] = 1 elif opt == "-m": flag_loadmodules[arg] = 1 elif opt == "-W": flag_dwarf_cu = arg elif opt == "-Z": flag_dumpdwarf = True # Make sure at least one function, loadmodule, or addr if not flag_functions and not flag_addresses: usage("specify function name with -f or address with -a") if not flag_loadmodules: usage("specify loadmodule with -m") if len(flag_loadmodules) > 1 and flag_dwarf_cu: usage("use only single loadmodule with -W option")
def shell_is_bash(): """Return TRUE if the shell being used is bash.""" if "SHELL" not in os.environ: u.warning("no definition for SHELL in environment (?)") return False shell = os.environ["SHELL"] u.verbose(1, "SHELL set to: %s" % shell) matcher = re.compile(r"^.*/bash$") m = matcher.match(shell) if m is not None: return True return False
def shell_is_bash(): """Return TRUE if the shell being used is bash.""" if "SHELL" not in os.environ: u.warning("no definition for SHELL in environment (?)") return False shell = os.environ["SHELL"] u.verbose(1, "SHELL set to: %s" % shell) matcher = re.compile(r"^.*/bash$") m = matcher.match(shell) if m is not None: return True return False
def run_cmake(builddir, cmake_cmd): """Cmake run helper.""" try: os.chdir(builddir) except OSError as err: u.warning("chdir failed: %s" % err) return 1 rv = u.doscmd(cmake_cmd, True) if not rv: u.warning("cmd command returned bad status: %s" % cmake_cmd) return 1 return 0
def perform(): """Main driver routine.""" # Step 1: dump only compilation unit info. cmd = ("%s --dwarf=info " "--dwarf-depth=0 %s" % (flag_objdump, flag_loadmodule)) u.verbose(1, "running: %s" % cmd) lines = u.docmdlines(cmd) cre = re.compile(r"^\s*Compilation Unit \@ offset 0x(\S+)\:\s*$") units = 0 lo = -1 hi = -1 maxoff = -1 selectoff = -1 for line in lines: m = cre.match(line) if m: binoff = int(m.group(1), 16) if binoff <= flag_offset_to_find: lo = units selectoff = binoff if binoff > flag_offset_to_find: hi = units break maxoff = binoff units += 1 if units == 0 or lo == -1: u.warning("no DWARF compile units in %s, dump aborted" % flag_loadmodule) return if hi == -1: u.warning("could not find CU with offset higher than %x; " "dumping last CU at offset %x" % (flag_offset_to_find, maxoff)) # Step 2: issue the dump cmd = ("%s --dwarf=info " "--dwarf-start=%d %s" % (flag_objdump, selectoff, flag_loadmodule)) u.verbose(1, "dump cmd is: %s" % cmd) args = shlex.split(cmd) mypipe = subprocess.Popen(args, stdout=subprocess.PIPE) cure = re.compile(r"^.+\(DW_TAG_compile_unit\).*") ncomps = 0 while True: line = mypipe.stdout.readline() if not line: break m = cure.match(line) if m: ncomps += 1 if ncomps > 1: break sys.stdout.write(line)
def perform_install(): """Install all blobs for a specific device.""" # Check for device subdir in archive dir devdir = "%s/cur/%s" % (flag_archive_dir, flag_device) if not os.path.exists(devdir): u.warning("error: unable to locate %s subdir in " "%s/cur" % (flag_device, flag_archive_dir)) u.warning("consider running download-aosp-blobs.py") exit(1) # Pick up all blobs in dir for afile in os.listdir(devdir): install_blob(afile, devdir)
def perform_install(): """Install all blobs for a specific device.""" # Check for device subdir in archive dir devdir = "%s/cur/%s" % (flag_archive_dir, flag_device) if not os.path.exists(devdir): u.warning("error: unable to locate %s subdir in " "%s/cur" % (flag_device, flag_archive_dir)) u.warning("consider running download-aosp-blobs.py") exit(1) # Pick up all blobs in dir for afile in os.listdir(devdir): install_blob(afile, devdir)
def parse_args(): """Command line argument parsing.""" global flag_dryrun, flag_destdir global flag_oldsha, flag_newsha, flag_branch_to_diff try: optlist, _ = getopt.getopt(sys.argv[1:], "hdo:DS:B:") except getopt.GetoptError as err: # unrecognized option usage(str(err)) for opt, arg in optlist: if opt == "-d": u.increment_verbosity() elif opt == "-h": usage() elif opt == "-D": flag_dryrun = True elif opt == "-B": flag_branch_to_diff = arg elif opt == "-S": r1 = re.compile(r"^(\S+):(\S+)$") m1 = r1.match(arg) if m1: flag_oldsha = m1.group(1) flag_newsha = m1.group(2) u.verbose(1, "old sha: %s" % flag_oldsha) u.verbose(1, "new sha: %s" % flag_newsha) else: u.usage("malformed -S argument %s (should be of form X:Y)" % arg) elif opt == "-o": if flag_destdir: usage("specify a single dest dir with -o") if not os.path.exists(arg): usage("dest dir %s does not exist" % arg) if not os.path.isdir(arg): usage("dest dir %s is not a directory" % arg) not_empty = False for _ in os.listdir(arg): not_empty = True break if not_empty: u.warning("warning: dest dir %s is not empty" % arg) flag_destdir = arg if not flag_destdir: usage("supply dest dir with -o option") if flag_branch_to_diff and flag_oldsha: usage("supply either -B or -S but not both") u.verbose(1, "dst dir: %s" % flag_destdir)
def install_shim(scriptpath): """Install shim into gccgo install dir.""" # Make sure we're in the right place (gccgo install dir) if not os.path.exists("bin"): usage("expected to find bin subdir") if not os.path.exists("lib64/libgo.so"): usage("expected to find lib64/libgo.so") if not os.path.exists("bin/gccgo"): usage("expected to find bin/gccgo") # Copy script, or update if already in place. docmd("cp %s bin" % scriptpath) sdir = os.path.dirname(scriptpath) docmd("cp %s/script_utils.py bin" % sdir) # Test to see if script installed already cmd = "file bin/gccgo" lines = u.docmdlines(cmd) if not lines: u.error("no output from %s -- bad gccgo install dir?" % cmd) else: reg = re.compile(r"^.+ ELF .+$") m = reg.match(lines[0]) if not m: u.warning("wrapper appears to be installed already in this dir") return # Move aside the real gccgo binary docmd("mv bin/gccgo bin/gccgo.real") # Emit a script into gccgo sys.stderr.write("emitting wrapper script into bin/gccgo\n") if not flag_dryrun: try: with open("./bin/gccgo", "w") as wf: here = os.getcwd() wf.write("#!/bin/sh\n") wf.write("P=%s/bin/gollvm-wrap.py\n" % here) wf.write("exec python ${P} \"$@\"\n") except IOError: u.error("open/write failed for bin/gccgo wrapper") docmd("chmod 0755 bin/gccgo") # Success u.verbose(0, "wrapper installed successfully") # Done return 0
def parse_args(): """Command line argument parsing.""" global flag_dryrun, flag_destdir global flag_oldsha, flag_newsha, flag_branch_to_diff try: optlist, _ = getopt.getopt(sys.argv[1:], "hdo:DS:B:") except getopt.GetoptError as err: # unrecognized option usage(str(err)) for opt, arg in optlist: if opt == "-d": u.increment_verbosity() elif opt == "-h": usage() elif opt == "-D": flag_dryrun = True elif opt == "-B": flag_branch_to_diff = arg elif opt == "-S": r1 = re.compile(r"^(\S+):(\S+)$") m1 = r1.match(arg) if m1: flag_oldsha = m1.group(1) flag_newsha = m1.group(2) u.verbose(1, "old sha: %s" % flag_oldsha) u.verbose(1, "new sha: %s" % flag_newsha) else: u.usage("malformed -S argument %s (should be of form X:Y)" % arg) elif opt == "-o": if flag_destdir: usage("specify a single dest dir with -o") if not os.path.exists(arg): usage("dest dir %s does not exist" % arg) if not os.path.isdir(arg): usage("dest dir %s is not a directory" % arg) not_empty = False for _ in os.listdir(arg): not_empty = True break if not_empty: u.warning("warning: dest dir %s is not empty" % arg) flag_destdir = arg if not flag_destdir: usage("supply dest dir with -o option") if flag_branch_to_diff and flag_oldsha: usage("supply either -B or -S but not both") u.verbose(1, "dst dir: %s" % flag_destdir)
def visit_branch(b): """Work on specified branch.""" docmd("git checkout %s" % b) # Query upstream branch for this branch. If not set, then don't # try to work on it. lines = u.docmdlines( "git rev-parse --symbolic-full-name --abbrev-ref @{u}", True) if not lines: u.warning("no upstream branch set for branch %s, skipping" % b) return docmd("git rebase") docmd("git checkout master") doscmd("git branch -d %s" % b, True)
def get_device_tag_from_build(abuild): """Map build name (ex: aosp_hammerhead-userdebug) to tag (ex: N5).""" regex = re.compile(r"aosp_(\S+)\-\S+$") m = regex.match(abuild) if not m: u.warning("unable to flash build %s (can't derive " "device codename" % abuild) return None codename = m.group(1) if codename not in codename_to_tag: u.warning("unable to flash build %s (no entry in " "codename->tag mapping)" % abuild) return None tag = codename_to_tag[codename] return tag
def locate_binaries(clangcmd): """Locate executables of interest.""" global toolpaths # Figure out what to invoke u.verbose(1, "clangcmd is %s" % clangcmd) toolpaths["clang"] = clangcmd reg = re.compile("(^.*)/(.*)$") m = reg.match(clangcmd) bindir = None clcmd = None if m: bindir = m.group(1) clcmd = m.group(2) else: if not flag_dryrun: lines = u.docmdlines("which %s" % clangcmd) if not lines: u.error("which %s returned empty result" % clangcmd) clangbin = lines[0].strip() bindir = os.path.dirname(clangbin) + "/" clcmd = os.path.basename(clangbin) u.verbose(1, "clang bindir is %s" % bindir) else: bindir = "" toolpaths["clang"] = os.path.join(bindir, clcmd) toolpaths["opt"] = os.path.join(bindir, "opt") toolpaths["llc"] = os.path.join(bindir, "llc") toolpaths["llvm-dis"] = os.path.join(bindir, "llvm-dis") if flag_dryrun: return # If clang is versioned, then version llvm-dis reg2 = re.compile("^.+(\-\d\.\d)$") m2 = reg2.match(clangcmd) if m2: toolpaths["llvm-dis"] = os.path.join(bindir, "llvm-dis%s" % m2.group(1)) # Check for existence and executability tocheck = ["clang", "opt", "llc", "llvm-dis"] for tc in tocheck: path = toolpaths[tc] if not os.path.exists(path): u.warning("can't access binary %s at path %s" % (tc, path)) if not os.access(path, os.X_OK): u.warning("no execute permission on binary %s" % path)
def find_ssdroots(): """Return a list of all BTRFS filesystems mounted.""" btrfsmounts = u.docmdlines("mount -l -t btrfs") matcher = re.compile(r"^\S+ on (\S+) ") rootlist = [] for line in btrfsmounts: m = matcher.match(line) if m is None: u.warning("warning: pattern match failed for " "output of mount -l: %s" % line) else: rootlist.append(m.group(1)) if not rootlist: u.error("unable to locate any BTRFS mounts " "from 'mount -l -t btrfs' -- aborting") return rootlist
def find_ssdroots(): """Return a list of all BTRFS filesystems mounted.""" btrfsmounts = u.docmdlines("mount -l -t btrfs") matcher = re.compile(r"^\S+ on (\S+) ") rootlist = [] for line in btrfsmounts: m = matcher.match(line) if m is None: u.warning("warning: pattern match failed for " "output of mount -l: %s" % line) else: rootlist.append(m.group(1)) if not rootlist: u.error("unable to locate any BTRFS mounts " "from 'mount -l -t btrfs' -- aborting") return rootlist
def examinefile(filename): """Perform symbol analysis on specified file.""" if not in_symbols_dir(filename): u.warning("%s: does not appear to be in " "%s/symbols directory? skipping" % (filename, apo)) return secsizes = examine_sections(filename) if not secsizes: u.verbose(1, "skipping file %s, no contents" % filename) return if file_is_stripped(secsizes): u.verbose(1, "skipping file %s, already stripped" % filename) return for secname, secsize in secsizes.iteritems(): allsecsizes[secname] += secsize examine_symbols(filename, secsizes)
def locate_binaries(clangcmd): """Locate executables of interest.""" global toolpaths # Figure out what to invoke u.verbose(1, "clangcmd is %s" % clangcmd) toolpaths["clang"] = clangcmd reg = re.compile("(^.*)/(.*)$") m = reg.match(clangcmd) bindir = None clcmd = None if m: bindir = m.group(1) clcmd = m.group(2) else: if not flag_dryrun: lines = u.docmdlines("which %s" % clangcmd) if not lines: u.error("which %s returned empty result" % clangcmd) clangbin = lines[0].strip() bindir = os.path.dirname(clangbin) + "/" clcmd = os.path.basename(clangbin) u.verbose(1, "clang bindir is %s" % bindir) else: bindir = "" toolpaths["clang"] = os.path.join(bindir, clcmd) toolpaths["opt"] = os.path.join(bindir, "opt") toolpaths["llc"] = os.path.join(bindir, "llc") toolpaths["llvm-dis"] = os.path.join(bindir, "llvm-dis") if flag_dryrun: return # If clang is versioned, then version llvm-dis reg2 = re.compile("^.+(\-\d\.\d)$") m2 = reg2.match(clangcmd) if m2: toolpaths["llvm-dis"] = os.path.join(bindir, "llvm-dis%s" % m2.group(1)) # Check for existence and executability tocheck = ["clang", "opt", "llc", "llvm-dis"] for tc in tocheck: path = toolpaths[tc] if not os.path.exists(path): u.warning("can't access binary %s at path %s" % (tc, path)) if not os.access(path, os.X_OK): u.warning("no execute permission on binary %s" % path)
def read_devtags(): """Read and post-process DEVTAGS environment var.""" dt = os.getenv("DEVTAGS") chunks = dt.split(" ") sertotag = {} tagtoser = {} for chunk in chunks: (tag, ser) = chunk.split(":") if ser in sertotag: u.error("malformed DEVTAGS (more than one " "entry for serial number %s" % ser) if tag in tagtoser: u.warning("malformed DEVTAGS (more than one " "serial number for tag %s" % tag) sertotag[ser] = tag tagtoser[tag] = ser return (sertotag, tagtoser)
def run_objdump_cmd(cargs, filename): """Run objdump with specified args, returning list of lines.""" objdump_cmd = determine_objdump(filename) cmd = "%s %s %s" % (objdump_cmd, cargs, filename) u.verbose(1, "objdump cmd: %s" % cmd) splargs = shlex.split(cmd) mypipe = subprocess.Popen(splargs, stdout=subprocess.PIPE) encoding = locale.getdefaultlocale()[1] pout, perr = mypipe.communicate() if mypipe.returncode != 0: decoded_err = perr.decode(encoding) u.warning(decoded_err) u.error("command failed (rc=%d): cmd was %s" % (mypipe.returncode, cmd)) decoded = pout.decode(encoding) return decoded.strip().split("\n")
def visit(filename): """Examine specified file.""" if not os.path.exists(filename): u.warning("unable to access file '%s', skipping" % filename) return u.verbose(1, "about to invoke readelf") lines = u.docmdlines("readelf -p .comment %s" % filename, True) if not lines: u.warning("unable to extract comment from %s, skipping" % filename) return matcher1 = re.compile(r"^\s*\[\s*\d+\]\s+(\S.+)$") matcher2 = re.compile(r"^GCC\:.+$") matcher3 = re.compile(r"^clang version \d.*$") res = "" sep = "" found = False comms = {} for line in lines: u.verbose(2, "line is %s" % line) m = matcher1.match(line) if not m: continue found = True comm = m.group(1).strip() u.verbose(1, "comm is %s" % comm) if comm in comms: continue comms[comm] = 1 m2 = matcher2.match(comm) if m2: versioncount[comm] += 1 res += sep + comm sep = ", " m3 = matcher3.match(comm) if m3: versioncount[comm] += 1 res += sep + comm sep = ", " if not found: res = "<comment not found>" versioncount[res] += 1 elif not res: res = "<unknown>" versioncount[res] += 1 print "%s: %s" % (filename, res)
def visit(filename): """Examine specified file.""" if not os.path.exists(filename): u.warning("unable to access file '%s', skipping" % filename) return u.verbose(1, "about to invoke readelf") lines = u.docmdlines("readelf -p .comment %s" % filename, True) if not lines: u.warning("unable to extract comment from %s, skipping" % filename) return matcher1 = re.compile(r"^\s*\[\s*\d+\]\s+(\S.+)$") matcher2 = re.compile(r"^GCC\:.+$") matcher3 = re.compile(r"^clang version \d.*$") res = "" sep = "" found = False comms = {} for line in lines: u.verbose(2, "line is %s" % line) m = matcher1.match(line) if not m: continue found = True comm = m.group(1).strip() u.verbose(1, "comm is %s" % comm) if comm in comms: continue comms[comm] = 1 m2 = matcher2.match(comm) if m2: versioncount[comm] += 1 res += sep + comm sep = ", " m3 = matcher3.match(comm) if m3: versioncount[comm] += 1 res += sep + comm sep = ", " if not found: res = "<comment not found>" versioncount[res] += 1 elif not res: res = "<unknown>" versioncount[res] += 1 print "%s: %s" % (filename, res)
def run_objdump_cmd(cargs, filename): """Run objdump with specified args, returning list of lines.""" objdump_cmd = determine_objdump(filename) cmd = "%s %s %s" % (objdump_cmd, cargs, filename) u.verbose(1, "objdump cmd: %s" % cmd) splargs = shlex.split(cmd) mypipe = subprocess.Popen(splargs, stdout=subprocess.PIPE) encoding = locale.getdefaultlocale()[1] pout, perr = mypipe.communicate() if mypipe.returncode != 0: decoded_err = perr.decode(encoding) u.warning(decoded_err) u.error("command failed (rc=%d): cmd was %s" % (mypipe.returncode, cmd)) decoded = pout.decode(encoding) return decoded.strip().split("\n")
def parse_args(): """Command line argument parsing.""" try: optlist, args = getopt.getopt(sys.argv[1:], "d") except getopt.GetoptError as err: # unrecognized option usage(str(err)) if not args: usage("supply one or more object files or archives as arguments") for opt, _ in optlist: if opt == "-d": u.increment_verbosity() for a in args: if not os.path.exists(a): u.warning("failed to open/access '%s' -- skipping" % a) else: flag_infiles.append(a)
def parse_args(): """Command line argument parsing.""" try: optlist, args = getopt.getopt(sys.argv[1:], "d") except getopt.GetoptError as err: # unrecognized option usage(str(err)) if not args: usage("supply one or more object files or archives as arguments") for opt, _ in optlist: if opt == "-d": u.increment_verbosity() for a in args: if not os.path.exists(a): u.warning("failed to open/access '%s' -- skipping" % a) else: flag_infiles.append(a)
def setup(): """Sort through args, derive basename.""" global basename # Last arg is expected to be src file filepath = flag_clang_opts[-1] u.verbose(1, "srcfile path is %s" % filepath) if not os.path.exists(filepath): u.warning("srcpath %s doesn't exist" % filepath) # Derive basename basename = None reg = re.compile(r"^(\S+)\.(\S+)$") m = reg.match(filepath) if m: ext = m.group(2) if ext == "c" or ext == "cpp" or ext == "cc": basename = m.group(1) if not basename: u.error("expected {.c,.cc,.cpp} input argument (got %s)" % filepath)
def setup(): """Sort through args, derive basename.""" global basename # Last arg is expected to be src file filepath = flag_clang_opts[-1] u.verbose(1, "srcfile path is %s" % filepath) if not os.path.exists(filepath): u.warning("srcpath %s doesn't exist" % filepath) # Derive basename basename = None reg = re.compile(r"^(\S+)\.(\S+)$") m = reg.match(filepath) if m: ext = m.group(2) if ext == "c" or ext == "cpp" or ext == "cc": basename = m.group(1) if not basename: u.error("expected {.c,.cc,.cpp} input argument (got %s)" % filepath)
def undolink(link): """Undo a symbolic link.""" try: _ = os.readlink(link) except OSError as ose: u.warning("warning: %s not a link (%s), " "skipping" % (link, ose)) return docmd("rm %s" % link) # Hack: sometimes gofrontend can get ahead of gcc trunk, in which case # we may try to check out something that does not exist. Check for this # case and work around it. # rev = "HEAD~1" rev = "HEAD" st = u.docmderrout("git show %s:%s" % (rev, link), "/dev/null", True) if st != 0: u.warning("skipping %s, does not exist in trunk yet" % link) else: docmd("git checkout %s" % link)
def undolink(link): """Undo a symbolic link.""" try: _ = os.readlink(link) except OSError as ose: u.warning("warning: %s not a link (%s), " "skipping" % (link, ose)) return docmd("rm %s" % link) # Hack: sometimes gofrontend can get ahead of gcc trunk, in which case # we may try to check out something that does not exist. Check for this # case and work around it. # rev = "HEAD~1" rev = "HEAD" st = u.docmderrout("git show %s:%s" % (rev, link), "/dev/null", True) if st != 0: u.warning("skipping %s, does not exist in trunk yet" % link) else: docmd("git checkout %s" % link)
def collect_subvolumes_and_snapshots(volumes, snapshots, voldict): """Collect info on volumes and snapshots.""" lines = u.docmdlines("showsnapshots.py -m") volm = re.compile(r"^subvolume (\S+)\s*$") snapm = re.compile(r"^\s+snapshot (\S+)\s+\->\s+(\S+)\s*$") for line in lines: m1 = volm.match(line) if m1: pv = m1.group(1) volumes[pv] = 1 continue m2 = snapm.match(line) if m2: pv = m2.group(1) sv = m2.group(2) snapshots[sv] = 1 voldict[pv][sv] = 1 continue u.warning("unmatchable line from %s " "output: %s" % ("showsnapshots -m", line))
def perform_flash(abuild): """Flash build to device if available.""" # Determine device tag tag = get_device_tag_from_build(abuild) if not tag: return None # Device online? serial = device_is_online(tag) if not serial: u.warning("device '%s' is not online, can't flash" % tag) return None u.verbose(0, "waiting for device '%s'" % tag) docmd("adb -s %s wait-for-device" % serial) docmd("adb -s %s reboot bootloader" % serial) t1 = int(time.time()) u.verbose(0, "flashing device '%s'" % tag) docmd("fastboot -s %s flashall" % serial) t2 = int(time.time()) u.verbose(1, "took %d seconds to flash device '%s'" % (t2 - t1, tag)) return serial
def examine(afile): """Dump go exports for specified file.""" objfile = afile arcmd = "ar t %s" % afile # Run 'ar' command, suppressing error output. If # if succeeds, then continue on the ar path, otherwise # treat input as an object. if u.doscmd(arcmd, True, True): # Handle archives lines = u.docmdlines(arcmd, True) if not lines: u.warning("skipping %s, can't index archive %s", afile) return # Extract elem from archive elem = lines[0].strip() u.verbose(1, "%s contains %s" % (afile, elem)) rc = u.docmdnf("ar x %s %s" % (afile, elem)) if rc: u.warning("skipping %s, can't extract object" % afile) return objfile = elem gexptemp = tempfile.NamedTemporaryFile(mode="w", prefix="go_export", delete=True) # Handle objects cmd = ("objcopy -O binary --only-section=.go_export " "--set-section-flags .go_export=alloc %s " "%s" % (objfile, gexptemp.name)) rc = u.docmdnf(cmd) if rc: u.warning("skipping %s, can't extract export " "data (cmd failed: %s)" % (objfile, cmd)) return try: inf = open(gexptemp.name, "rb") except IOError as e: u.error("unable to open tempfile %s: " "%s" % (gexptemp.name, e.strerror)) print "== %s ==" % afile lines = inf.readlines() if not lines: u.warning("skipping %s, no .go_export section present" % objfile) for line in lines: print line.strip() inf.close() if objfile != afile: os.unlink(objfile)
def examine(afile): """Dump go exports for specified file.""" objfile = afile arcmd = "ar t %s" % afile # Run 'ar' command, suppressing error output. If # if succeeds, then continue on the ar path, otherwise # treat input as an object. if u.doscmd(arcmd, True, True): # Handle archives lines = u.docmdlines(arcmd, True) if not lines: u.warning("skipping %s, can't index archive %s", afile) return # Extract elem from archive elem = lines[0].strip() u.verbose(1, "%s contains %s" % (afile, elem)) rc = u.docmdnf("ar x %s %s" % (afile, elem)) if rc: u.warning("skipping %s, can't extract object" % afile) return objfile = elem gexptemp = tempfile.NamedTemporaryFile(mode="w", prefix="go_export", delete=True) # Handle objects cmd = ("objcopy -O binary --only-section=.go_export " "--set-section-flags .go_export=alloc %s " "%s" % (objfile, gexptemp.name)) rc = u.docmdnf(cmd) if rc: u.warning("skipping %s, can't extract export " "data (cmd failed: %s)" % (objfile, cmd)) return try: inf = open(gexptemp.name, "rb") except IOError as e: u.error("unable to open tempfile %s: " "%s" % (gexptemp.name, e.strerror)) print "== %s ==" % afile lines = inf.readlines() if not lines: u.warning("skipping %s, no .go_export section present" % objfile) for line in lines: print line.strip() inf.close() if objfile != afile: os.unlink(objfile)
def read_env_cachefile(cachefile): """Read environment from cache file into dict.""" # Read results u.verbose(1, "reading results from %s" % cachefile) env_dict = {} try: with open(cachefile, "r") as rf: regex = re.compile(r"^([^=]+)\=(.*)$") lines = rf.readlines() for line in lines: m = regex.match(line) if not m: u.warning("unable to parse environment line %s" % line) continue varname = m.group(1) setting = m.group(2) u.verbose(2, "caching %s=%s" % (varname, setting)) env_dict[varname] = setting except IOError: u.error("unable to open/read from %s" % cachefile) return env_dict
def perform(): """Main driver routine.""" andser = os.getenv("ANDROID_SERIAL") if andser: andser = andser.strip() else: andser = "" (serial_to_tag, tag_to_serial) = read_devtags() lines = u.docmdlines("adb devices") rxd1 = re.compile(r"^\* daemon not running.+$") rxd2 = re.compile(r"^\* daemon started.+$") rx1 = re.compile(r"^\s*(\S+)\s+(\S+)\s*$") devices_found = {} for line in lines[1:]: if rxd1.match(line) or rxd2.match(line): continue m = rx1.match(line) if not m: u.warning("unable to match adb output line: %s" % line) continue ser = m.group(1) disp = m.group(2) if disp not in valid_dispositions: u.warning("unknown device disposition %s in adb " "output line: %s" % (disp, line)) sel = "" if ser == andser: sel = ">>" if ser not in serial_to_tag: tag = "???" else: tag = serial_to_tag[ser] devices_found[tag] = 1 print "%2s %8s %16s %s" % (sel, tag, ser, disp) if flag_showall: for tag, ser in tag_to_serial.iteritems(): if tag in devices_found: continue print "%2s %8s %16s %s" % ("", tag, ser, "<unconnected>")
def capture_env_from_cmds(cmds, cachefile, errfile): """Capture the environment resulting from executing bash cmds.""" # Emit small bash script to execute cmdfile = ".bashcmd" with open(cmdfile, "w") as wf: first = True for c in cmds: if first: first = False wf.write("%s 1> %s 2>&1\n" % (c, errfile)) else: wf.write("%s 1>> %s 2>&1\n" % (c, errfile)) wf.write("if [ $? != 0 ]; then\n") wf.write(" exit 1\n") wf.write("fi\n") wf.write("printenv > %s\n" % cachefile) wf.write("exit 0\n") wf.close() rc = u.docmdnf("bash %s" % cmdfile) if rc != 0: u.warning("bash cmd failed") u.warning("cmd script was:") u.docmd("cat %s" % cmdfile) u.warning("bash error output was:") u.docmd("cat %s" % errfile) raise Exception("command failed")
def perform_diff(): """Perform graphical diff.""" (modified, rightrev) = get_pred_revision_and_modified() ltf = None leftname = None if flag_prev_revision: rightrev = flag_prev_revision if flag_revision_pair: if modified: u.warning("warning: working copy of %s is " "modified" % flag_target_file) leftrev = flag_revision_pair[0] rightrev = flag_revision_pair[1] ltf = tempfile.NamedTemporaryFile(mode="w", prefix="svnpreddifftmp_REV%s_" % leftrev, delete=True) leftname = ltf.name u.verbose(1, "left temp file is: %s" % leftname) u.docmdout("svn cat -r%d %s" % (leftrev, flag_target_file), leftname) if flag_save_temps: save_temps(ltf, leftrev) else: u.verbose(1, "left file is: %s" % flag_target_file) leftname = flag_target_file rtf = tempfile.NamedTemporaryFile(mode="w", prefix="svnpreddifftmp_REV%s_" % rightrev, delete=True) rightname = rtf.name u.verbose(1, "right temp file is: %s" % rightname) u.docmdout("svn cat -r%d %s" % (rightrev, flag_target_file), rightname) if flag_save_temps: save_temps(rtf, rightrev) # Perform diff u.docmd("%s %s %s" % (flag_diff_cmd, leftname, rightname))
def rmvolsnap(volsnapname, which): """Remove an existing btrfs snapshot or subvolume.""" # Determine /ssd root ssdroot = u.determine_btrfs_ssdroot(os.getcwd()) u.verbose(1, "ssdroot=%s" % ssdroot) # Normalize snap name volsnapname = normalize(ssdroot, volsnapname) # Check for existence oldvolsnap = "%s/%s" % (ssdroot, volsnapname) if not os.path.exists(oldvolsnap): u.error("unable to locate existing %s %s" % (which, oldvolsnap)) # Determine whether there is a parent uuid isvol = -1 showlines = u.docmdlines("sudo btrfs subvolume show %s" % oldvolsnap) if not showlines: u.error("unable to get subvolume info for %s" % oldvolsnap) matcher = re.compile(r"^\s*Parent uuid\:\s+(\S+).*$") for line in showlines: m = matcher.match(line) if m: puid = m.group(1) if puid == "-": isvol = 1 else: isvol = 0 u.verbose(2, "isvol=%d for %s" % (isvol, oldvolsnap)) if isvol == -1: u.warning("unable to determine snapshot/subvolume status for %s" % oldvolsnap) elif isvol == 0: if which == "volume": u.warning("%s appears to be snapshot, not subvolume" % oldvolsnap) else: if which == "snapshot": u.warning("%s appears to be subvolume, not snapshot" % oldvolsnap) # Here goes rc = u.docmdnf("sudo btrfs subvolume delete %s" % oldvolsnap) if rc != 0: # Couldn't delete the subvolume. Suggest running lsof sys.stderr.write( "** deletion failed -- trying to determine open file:\n") sys.stderr.write(" lsof +D %s\n" % oldvolsnap) u.docmdnf("lsof +D %s\n" % oldvolsnap) exit(1) sys.stderr.write("... %s %s deleted\n" % (which, oldvolsnap))
def rmvolsnap(volsnapname, which): """Remove an existing btrfs snapshot or subvolume.""" # Determine /ssd root ssdroot = u.determine_btrfs_ssdroot(os.getcwd()) u.verbose(1, "ssdroot=%s" % ssdroot) # Normalize snap name volsnapname = normalize(ssdroot, volsnapname) # Check for existence oldvolsnap = "%s/%s" % (ssdroot, volsnapname) if not os.path.exists(oldvolsnap): u.error("unable to locate existing %s %s" % (which, oldvolsnap)) # Determine whether there is a parent uuid isvol = -1 showlines = u.docmdlines("sudo btrfs subvolume show %s" % oldvolsnap) if not showlines: u.error("unable to get subvolume info for %s" % oldvolsnap) matcher = re.compile(r"^\s*Parent uuid\:\s+(\S+).*$") for line in showlines: m = matcher.match(line) if m: puid = m.group(1) if puid == "-": isvol = 1 else: isvol = 0 u.verbose(2, "isvol=%d for %s" % (isvol, oldvolsnap)) if isvol == -1: u.warning("unable to determine snapshot/subvolume status for %s" % oldvolsnap) elif isvol == 0: if which == "volume": u.warning("%s appears to be snapshot, not subvolume" % oldvolsnap) else: if which == "snapshot": u.warning("%s appears to be subvolume, not snapshot" % oldvolsnap) # Here goes rc = u.docmdnf("sudo btrfs subvolume delete %s" % oldvolsnap) if rc != 0: # Couldn't delete the subvolume. Suggest running lsof sys.stderr.write("** deletion failed -- trying to determine open file:\n") sys.stderr.write(" lsof +D %s\n"% oldvolsnap) u.docmdnf("lsof +D %s\n" % oldvolsnap) exit(1) sys.stderr.write("... %s %s deleted\n" % (which, oldvolsnap))
def dodwarf(asmlines, lm): """Annotate disassembly with DWARF info.""" u.verbose(1, "inspecting DWARF for %s" % lm) # Initial pass to collect load modules lines = u.docmdlines("objdump --dwarf=info --dwarf-depth=1 %s" % lm) dies = read_die_chain(lines) cu_offset = None if flag_dwarf_cu != ".": # Try to find correct DWARF CU for off, lines in dies.items(): abbrev, tag, attrs = expand_die(lines) if tag != "DW_TAG_compile_unit": continue if "DW_AT_name" not in attrs: continue cuname = attrs["DW_AT_name"] if cuname == flag_dwarf_cu: u.verbose(1, "found DWARF %s cu at offset %s" % (flag_dwarf_cu, off)) cu_offset = "--dwarf-start=%d" % off # Bail if not match ranged_items = [] if not cu_offset: u.warning("could not locate DWARF compilation unit %s" % flag_dwarf_cu) else: # Redo dwarf dump with selected unit lines2 = u.docmdlines("objdump %s --dwarf=info %s" % (cu_offset, lm)) dies = read_die_chain(lines2) # Dump if flag_dumpdwarf: for off in sorted(dies): dlines = dies[off] abbrev, tag, attrs = expand_die(dlines) u.verbose(2, "DIE at offset %s: abbrev %s " "tag %s" % (off, abbrev, tag)) for attr, val in attrs.items(): u.verbose(2, " %s => %s" % (attr, val)) # Collect ranged items ranged_items = collect_ranged_items(lm, dies) # Debugging for ri in ranged_items: name, lo, hi = ri u.verbose(1, "ranged item: %s [%x,%x)" % (name, lo, hi)) # ASM re asmre = re.compile(r"(^\s*)(\S+)(\:\s*\S.*)$") # Output for line in asmlines: m1 = asmre.match(line) if not m1: sys.stdout.write(line) sys.stdout.write("\n") continue sp = m1.group(1) addr = m1.group(2) rem = m1.group(3) try: decaddr = int(addr, 16) except ValueError: sys.stdout.write(line) sys.stdout.write("\n") continue suffixes = [] # Assumes smallish functions -- replace with something more # efficient if this assumption doesn't hold. for tup in ranged_items: name, lo, hi = tup if lo == decaddr: suffixes.append(" begin %s" % name) if hi == decaddr: suffixes.append(" end %s" % name) sys.stdout.write("%s%s%s" % (sp, addr, rem)) if suffixes: sys.stdout.write(" // ") sys.stdout.write(",".join(suffixes)) sys.stdout.write("\n")
5M 1KB 2GB will be sorted as 1,2,5. """ import sys import script_utils as u #...................................................................... lines = sys.stdin.readlines() tups = [] for line in lines: chunks = line.split() if chunks[0]: nbytes = u.hr_size_to_bytes(chunks[0]) if not nbytes: continue tup = (nbytes, chunks[0], " ".join(chunks[1:])) tups.append(tup) else: u.warning("malformed 'du' output line %s" % line) stups = sorted(tups) for t in stups: print "%-10s %s" % (t[1], t[2])
def perform(): """Main driver routine.""" u.verbose(1, "argv: %s" % " ".join(sys.argv)) # llvm-goparse should be available somewhere in PATH, error if not lines = u.docmdlines("which llvm-goparse", True) if not lines: u.error("no 'llvm-goparse' in PATH -- can't proceed") # Perform a walk of the command line arguments looking for Go files. reg = re.compile(r"^\S+\.go$") foundgo = False for clarg in sys.argv[1:]: m = reg.match(clarg) if m: foundgo = True break if not foundgo or flag_nollvm: # No go files. Invoke real gccgo. bd = os.path.dirname(sys.argv[0]) driver = "%s/gccgo.real" % bd u.verbose(1, "driver path is %s" % driver) args = [sys.argv[0]] + sys.argv[1:] u.verbose(1, "args: '%s'" % " ".join(args)) if not os.path.exists(driver): u.warning("internal error: %s does not exist" % driver) u.warning("[most likely this script was not installed correctly]") usage() os.execv(driver, args) u.error("exec failed: %s" % driver) # Create a set of massaged args. nargs = [] skipc = 0 outfile = None asmfile = None for ii in range(1, len(sys.argv)): clarg = sys.argv[ii] if skipc != 0: skipc -= 1 continue if clarg == "-o": skipc = 1 outfile = sys.argv[ii+1] asmfile = "%s.s" % outfile nargs.append("-o") nargs.append(asmfile) continue nargs.append(clarg) if not asmfile or not outfile: u.error("fatal error: unable to find -o " "option in clargs: %s" % " ".join(sys.argv)) golibargs = form_golibargs(sys.argv[0]) nargs += golibargs u.verbose(1, "revised args: %s" % " ".join(nargs)) # Invoke gollvm. driver = "llvm-goparse" u.verbose(1, "driver path is %s" % driver) nargs = ["llvm-goparse"] + nargs if flag_trace_llinvoc: u.verbose(0, "+ %s" % " ".join(nargs)) rc = subprocess.call(nargs) if rc != 0: u.verbose(1, "return code %d from %s" % (rc, " ".join(nargs))) return 1 # Invoke the assembler ascmd = "as %s -o %s" % (asmfile, outfile) u.verbose(1, "asm command is: %s" % ascmd) rc = u.docmdnf(ascmd) if rc != 0: u.verbose(1, "return code %d from %s" % (rc, ascmd)) return 1 return 0
def setup_gccgo_gdb(): """Set up for gccgo debugging.""" if not gccgo_location: u.warning("failed to locate gccgo compilation " "of %s" % flag_gccgo_gdb) return outfile = ".gccgo.err.txt" here = os.getcwd() gloc = gccgo_location if here != gloc: u.warning("gccgo compile takes place in %s, " "not here (%s)" % (gccgo_location, here)) regloc = re.compile(r"\$WORK/(\S+)$") m = regloc.match(gccgo_location) if m: if flag_relocate: gloc = os.path.join(flag_relocate, m.group(1)) else: gloc = os.path.join(workdir, m.group(1)) u.verbose(1, "revised gloc dir is %s" % gloc) os.chdir(gloc) driver = gccgo_invocation[0] args = gccgo_invocation[1:] for idx in range(0, len(args)): if args[idx] == "$WORK": if flag_relocate: args[idx] = flag_relocate else: args[idx] = workdir cmd = ("%s -v %s" % (driver, " ".join(args))) u.verbose(1, "in %s, executing gdb setup cmd: %s" % (os.getcwd(), cmd)) rc = u.docmderrout(cmd, outfile, True) if rc != 0: u.warning("cmd failed: %s" % cmd) try: inf = open(outfile, "rb") except IOError as e: u.error("internal error: unable to consume tmp " "file %s? error %s" % (outfile, e.strerror)) lines = inf.readlines() inf.close() found = False reg1 = re.compile(r"^\s*(\S+/go1)\s+(\S.+)$") for line in lines: u.verbose(2, "gccgo -v line is %s" % line.strip()) m = reg1.match(line) if m: go1exe = m.group(1) u.verbose(1, "go1 driver is %s" % go1exe) go1args = m.group(2) u.verbose(1, "go1 args: %s" % go1args) # Create symlink if not os.path.exists("go1"): u.verbose(0, "symlinking to %s" % go1exe) os.symlink(go1exe, "go1") # Dump args u.verbose(0, "writing args to .gdbinit") try: outf = open(".gdbinit", "w") except IOError as e: u.error("unable to open %s: " "%s" % (".gdbinit", e.strerror)) outf.write("# gud-gdb --fullname ./go1\n") outf.write("set args %s" % go1args) outf.close() u.verbose(0, "starting emacs") subprocess.Popen(["emacs", ".gdbinit"]) return if not found: u.error("unable to locate go1 invocation in gccgo -v output") os.chdir(here)
def parse_args(): """Command line argument parsing.""" global flag_preserve_bitcode, flag_dryrun, flag_echo, arghash global flag_ptag, flag_pass_olevel, flag_explicitly_invoke_opt try: optlist, _ = getopt.getopt(sys.argv[1:], "depxDTL:O:P:") except getopt.GetoptError as err: # unrecognized option usage(str(err)) for opt, arg in optlist: if opt == "-d": u.increment_verbosity() elif opt == "-e": flag_echo = True elif opt == "-D": flag_dryrun = True elif opt == "-T": flag_pass_olevel = True elif opt == "-L": flag_llc_opts.append(arg) elif opt == "-O": flag_opt_opts.append(arg) elif opt == "-P": flag_ptag = arg elif opt == "-p": flag_preserve_bitcode = True elif opt == "-x": flag_explicitly_invoke_opt = True # Walk through command line and locate -- nargs = len(sys.argv) clangbin = None foundc = False for ii in range(0, nargs): arg = sys.argv[ii] if arg == "--": clangbin = sys.argv[ii+1] skipnext = False for clarg in sys.argv[ii+2:]: if skipnext: skipnext = False continue if clarg == "-o" or clarg == "-MT" or clarg == "-MF": skipnext = True continue if clarg == "-MD": continue flag_clang_opts.append(clarg) if clarg == "-c": foundc = True translated = False for rex, tr in transargs.iteritems(): u.verbose(3, "=-= tmatching clarg %s against %s" % (clarg, rex)) r = re.compile(rex) m = r.match(clarg) if m: transarg = tr % m.group(1) flag_opt_opts.append(transarg) flag_llc_opts.append(transarg) u.verbose(3, "=-= => translated %s to %s" % (clarg, transarg)) translated = True break if translated: continue if flag_pass_olevel: for rex in passargs: u.verbose(3, "=-= matching clarg %s against %s" % (clarg, rex)) r = re.compile(rex) m = r.match(clarg) if m: flag_opt_opts.append(clarg) flag_llc_opts.append(clarg) u.verbose(3, "=-= => matched") break if not clangbin: usage("malformed command line, no -- arg or no clang mentioned") if not foundc: u.warning("adding -c to clang invocation") flag_clang_opts.append("-c") locate_binaries(clangbin) u.verbose(1, "clangbin: %s" % toolpaths["clang"]) u.verbose(1, "llvm-dis: %s" % toolpaths["llvm-dis"]) u.verbose(1, "llc options: %s" % " ".join(flag_llc_opts)) u.verbose(1, "opt options: %s" % " ".join(flag_opt_opts)) u.verbose(1, "clang args: %s" % " ".join(flag_clang_opts)) # compute arghash for later use m = hashlib.md5() for a in sys.argv: m.update(a) arghash = m.hexdigest()
import sys import script_utils as u #...................................................................... me = sys.argv[0] mebase = os.path.basename(me) if len(sys.argv) != 2: u.error("%s: supply exactly one argument" % mebase) arg = sys.argv[1] if not re.compile(r"extract\-.+\.sh$").match(arg): u.warning("arg '%s' does not match template extract*.sh" % arg) if not os.path.exists(arg): u.error("unable to access file arg '%s'" % arg) u.verbose(0, "... examining '%s'" % arg) matcher = re.compile(r"tail \-n \+\d+ .+ tar zxv") cmd = "" encoding = locale.getdefaultlocale()[1] with open(arg, "rb") as fin: for line in fin: decoded = line.decode(encoding) if matcher.match(decoded): # found cmd = re.sub(r"\$0", arg, decoded.rstrip()) break
def perform(): """Main driver routine.""" u.verbose(1, "argv: %s" % " ".join(sys.argv)) # llvm-goparse should be available somewhere in PATH, error if not lines = u.docmdlines("which llvm-goparse", True) if not lines: u.error("no 'llvm-goparse' in PATH -- can't proceed") # Perform a walk of the command line arguments looking for Go files. reg = re.compile(r"^\S+\.go$") foundgo = False for clarg in sys.argv[1:]: m = reg.match(clarg) if m: foundgo = True break if not foundgo or flag_nollvm: # No go files. Invoke real gccgo. bd = os.path.dirname(sys.argv[0]) driver = "%s/gccgo.real" % bd u.verbose(1, "driver path is %s" % driver) args = [sys.argv[0]] + sys.argv[1:] u.verbose(1, "args: '%s'" % " ".join(args)) if not os.path.exists(driver): u.warning("internal error: %s does not exist" % driver) u.warning("[most likely this script was not installed correctly]") usage() os.execv(driver, args) u.error("exec failed: %s" % driver) # Create a set of massaged args. nargs = [] skipc = 0 outfile = None asmfile = None for ii in range(1, len(sys.argv)): clarg = sys.argv[ii] if skipc != 0: skipc -= 1 continue if clarg == "-o": skipc = 1 outfile = sys.argv[ii + 1] asmfile = "%s.s" % outfile nargs.append("-o") nargs.append(asmfile) continue nargs.append(clarg) if not asmfile or not outfile: u.error("fatal error: unable to find -o " "option in clargs: %s" % " ".join(sys.argv)) golibargs = form_golibargs(sys.argv[0]) nargs += golibargs u.verbose(1, "revised args: %s" % " ".join(nargs)) # Invoke gollvm. driver = "llvm-goparse" u.verbose(1, "driver path is %s" % driver) nargs = ["llvm-goparse"] + nargs if flag_trace_llinvoc: u.verbose(0, "+ %s" % " ".join(nargs)) rc = subprocess.call(nargs) if rc != 0: u.verbose(1, "return code %d from %s" % (rc, " ".join(nargs))) return 1 # Invoke the assembler ascmd = "as %s -o %s" % (asmfile, outfile) u.verbose(1, "asm command is: %s" % ascmd) rc = u.docmdnf(ascmd) if rc != 0: u.verbose(1, "return code %d from %s" % (rc, ascmd)) return 1 return 0