def main(argv): # {{{ hexagon_path = None elf_path = None i = 0 while i < len(argv): arg = argv[i] if arg.lower() == '--hexagon-path': if not (i + 1 < len(argv)): return print_err(file_name, 'Expecting argument after --hexagon-path') hexagon_path = argv[i + 1] i += 2 continue elif arg.lower().startswith('--hexagon-path='): path = '='.join(arg.split('=')[1:]) if len(path) < 1: return print_err(file_name, 'Expecting argument after --hexagon-path=') hexagon_path = path i += 1 continue elif arg.lower() == '-v' or arg.lower() == '--verbose': global verbose verbose = True else: elf_path = arg i += 1 if not elf_path: return print_err(file_name, 'No ELF path given') if not os.path.exists(elf_path): return print_err(file_name, 'ELF does not exist: %s' % elf_path) print '%s\n' % (ps(ap(elf_path))[-1], ) # get elf data mc = MemoryChecker(elf_path, hexagon_path=hexagon_path) mc.pull_info() dp('') # separate verbose data from regular data ok = mc.print_info() if not ok: return 1 else: return 0
def read_txt(ddir): """ Read all .txt files in dir into a list(dict) w/ Id (from filename) and text keys """ comments = [] files = os.listdir(ddir) # sort files in ascending numeric order files = sorted(files, key=lambda x: int(x.split('.')[0])) for filename in files: with open(pj(ddir, filename), 'rb') as f: d = {'text': f.read().decode('utf-8').replace('\n', '')} Id = filename.split('.')[0] d['Id'] = ps(Id)[-1] comments.append(d) return comments
def main(): args = parse_args() infile = args.infile copy_dir = args.linkdir glob_suffix = '-rgb*.tif' with open(infile, 'r') as f: ids = [line.strip() for line in f] # Look for any permutations of each im ID if not os.path.exists(copy_dir): os.mkdir(copy_dir) for i in ids: for im in glob(i + glob_suffix): src = os.path.abspath(im) dst = pj(ps(src)[0], copy_dir, im) e = force_symlink(src, dst) if e: print('Overwrote prexisting symlinks!') print('Symlinked IDs in %s to %s' % (args.infile, args.linkdir))
def main(): # Use optparse to set up usage use = "Usage: python %prog [options] <Input ELF> <Output ELF>" use += "\n python %prog -s symbolName <ELF>" parser = optparse.OptionParser(usage=use, version="%prog 1.11") parser.add_option("-d", action="store_true", dest="debug", help="enable debug") parser.add_option("-r", action="store", dest="removeSection", type="str", help="Section to remove") parser.add_option("-t", action="store_true", dest="timing", help="print program execution time") parser.add_option("-V", action="store_true", dest="verification", help="enable ELF verification (currently none)") parser.add_option("-R", action="store_true", dest="ro_fatal", help="Enable ro fatal section removal/compression") parser.add_option("-M", action="store_true", dest="overlay_mem_dump", help="Enable memory dump overlay") parser.add_option("-c", action="store", dest="compressorRoot", help="Specify the root folder of the Q6Zip compressor") parser.add_option("-s", action="store", dest="coprocMerge", type="str", help="Path of coprocessor (silver) ELF") options, arguments = parser.parse_args() # Check arguments if len(arguments) != 2: parser.error("Unexpected argument length") exit(const.RC_ERROR) baseELF = arguments[0] modifiedELF = arguments[1] if not pe(baseELF): parser.error("Specified ELF file does not exist.") exit(const.RC_ERROR) # Print configuration if not options.debug: print "================================================================" print " elfManipulator.py - Generic manipulator for ELF files" print "----------------------------------------------------------------" print " Base ELF: ".ljust(20) + baseELF print " Modified ELF: ".ljust(20) + modifiedELF print " Debug: ".ljust(20) + str(options.debug) print " Verification: ".ljust(20) + str(options.verification) print "================================================================" # Record the starting time if options.timing: start_time = time.time() # Get the elf file as an elfFile object if not options.debug: print "----------------------------------------------------------------" print " Getting ELF data from input ELF..." print "----------------------------------------------------------------" elf = elfFileClass.elfFile(baseELF) # If debug is enabled, show ELF contents similarly to readelf -a if options.debug: elf.printInfo() if not options.debug: print "----------------------------------------------------------------" print " Applying requested ELF modifications..." print "----------------------------------------------------------------" """ HERE IS WHERE ALL THE ELF MODIFICATIONS SHOULD HAPPEN """ # -r option: Remove specified section if options.removeSection: if not options.debug: print "Attempting to remove section '" + options.removeSection + "'" elf.removeSectionByName(options.removeSection) symbolDict = {} # -M option: Remove BSS section for 'overlay_mem_dump' feature overlay_mem_dumpSize = -1 if options.overlay_mem_dump: print "OVERLAY_MEM_DUMP" overlay_mem_dumpSh = elf.getSectionByName("overlay_mem_dump") ro_fatalSh = elf.getSectionByName("ro_fatal") if overlay_mem_dumpSh != const.RC_ERROR and ro_fatalSh != const.RC_ERROR: # If an overlay_mem_dump section is found print "\t'overlay_mem_dump' section found" print "\tAttempting to remove 'overlay_mem_dump' BSS section." overlay_mem_dumpSize = overlay_mem_dumpSh.sh_size elf.removeBssOverlaySectionByName("overlay_mem_dump") if overlay_mem_dumpSize > ro_fatalSh.sh_size: # It is expected that size of ro_fatal section matches the # program segment size in subsequent steps. elfManipulator is # currently written to manipulate single section segments, # with the EXCEPTION of removing BSS sections. print "\t'overlay_mem_dump' exceeded 'ro_fatal' size. Re-sizing." elf.resizeSectionByName("ro_fatal", len(ro_fatalSh.contents)) else: if overlay_mem_dumpSh == const.RC_ERROR: print "\tNo 'overlay_mem_dump' section found. No-op." if ro_fatalSh == const.RC_ERROR: print "\tNo 'ro_fatal' section found. No-op." # -R option: Remove or compress 'ro_fatal' section if options.ro_fatal: print print "RO_FATAL COMPRESSION" # Get the section in question sh = elf.getSectionByName("ro_fatal") if sh != const.RC_ERROR: # If an ro_fatal section is found print "\t'ro_fatal' section found" if sh.sh_size == 0: # If 0 size section is found, remove the section for mbn print "\tZero-sized 'ro_fatal' section. Attempting removal." elf.removeSectionByName("ro_fatal") else: # Move up the ro_fatal section and then compress it print "\tMoving up 'ro_fatal' to closest section" symbolDict["__ro_fatal_old_start"] = sh.sh_addr oldSize = sh.sh_size elf.moveupSectionByName("ro_fatal") print "\tCompressing 'ro_fatal' contents using zlib" sh = elf.compressSectionByName("ro_fatal") if (sh != const.RC_ERROR): # If compression is successful, update symbols accordingly symbolDict["__ro_fatal_new_start"] = sh.sh_addr symbolDict["__ro_fatal_new_end"] = sh.sh_addr + len( sh.contents) else: utils.raiseElfManipulatorError( "Failed to compress ro_fatal") # Print out statistics print "\tOld Size: " + str(oldSize) print "\tNew Size: " + str(sh.sh_size) else: # The last segment is still created due to linker script print "\tNo 'ro_fatal' section found, checking for zero-sized segment" if ((elf.programHeaderTable[-1].p_memsz == 0) and (elf.programHeaderTable[-1].p_vaddr == 0)): print "\tRemoving zero-sized segment" elf.elfHeader.e_phnum -= 1 elf.programHeaderTable.pop() #============================================= # START: Q6_ZIP CHANGES #============================================= q6_roSection = ".candidate_compress_section" q6_rwSection = ".rw_candidate_compress_section" pageSize = 4096 # determine where the compressors reside my_d = ps(inspect.getframeinfo(inspect.currentframe()).filename)[0] compressorDirs = [ ap(pj(my_d, "../../core/kernel/dlpager/compressor")), ap(pj(my_d, "../../../core/kernel/dlpager/compressor")), ap(pj(my_d, "./include")), ] if options.compressorRoot: compressorDirs.insert(0, options.compressorRoot) for d in compressorDirs: if os.path.isdir(d) and 'q6zip_compress.py' in os.listdir(d): sys.path.insert(0, d) break print print "Q6ZIP FEATURE (RO)" # Get the ELF section containing the code to compress sh = elf.getSectionByName(q6_roSection) # Check if the section exists if (sh != const.RC_ERROR): # Save the old VA before ANY modifications to the section/segment oldVA = sh.sh_addr # Save old size oldSize = sh.sh_size print "oldVA = " + hex(oldVA) print "Size of " + q6_roSection + " is " + str(sh.sh_size) symbolDict["start_va_uncompressed_text"] = sh.sh_addr symbolDict["end_va_uncompressed_text"] = sh.sh_addr + sh.sh_size # Move up the vaddr of the section, corresponding segment and mark all # its symbols as SHN_UNDEF. Will fail if q6_roSection is part of multi- # section segment in the ELF. # Save the new VA after moving up the section/segment print "Moving up " + q6_roSection + " to closest segment" elf.moveupSectionByName(q6_roSection) newVA = sh.sh_addr print "newVA = " + hex(newVA) print "Compress " + q6_roSection import q6zip_compress try: text_nonpartial_start = elf.getSymbolByName( "__swapped_range_text_partial_end__").st_value if text_nonpartial_start != 0: size_partial = text_nonpartial_start - oldVA print "text nonpartial start = " + hex(text_nonpartial_start) print "text partial size = " + str(size_partial) sh.contents = q6zip_compress.compress(pageSize, newVA, sh.contents, size_partial) except: sh.contents = q6zip_compress.compress(pageSize, newVA, sh.contents) # Alignment needed for Q6ZIP RW in the next section alignedSize = pageSize * (len(sh.contents) / pageSize + 1) for i in xrange(alignedSize - len(sh.contents)): sh.contents += '\0' elf.resizeSectionByName(q6_roSection, alignedSize) print "Size of " + q6_roSection + " after compression " + str( sh.sh_size) print("Memory Savings Report: Q6Zip RO: Gross Memory Saved: %u\n" % (oldSize - sh.sh_size)) symbolDict["start_va_compressed_text"] = newVA symbolDict["end_va_compressed_text"] = sh.sh_addr + sh.sh_size # Change permissions (remove execute) print "\tRemoving X from " + q6_roSection sh.sh_flags = sh.sh_flags & ~const.sectionFlags.SHF_EXECINSTR ph = elf.getProgramHeaderBySectionName(q6_roSection) if ph != const.RC_ERROR: ph.p_flags &= ~const.segmentFlags.PF_X else: utils.raiseElfManipulatorError( "Unexpected error while changing permissions for " + q6_roSection) if (sh != const.RC_ERROR): print "Success compressing " + q6_roSection else: utils.raiseElfManipulatorError("Failed to compress " + q6_roSection) else: # Like ro_fatal, need to check for zero-sized segment print "No " + q6_roSection + " section found, checking for zero-sized segment" if ((elf.programHeaderTable[-1].p_memsz == 0) and (elf.programHeaderTable[-1].p_vaddr == 0)): print "Removing zero-sized segment" elf.elfHeader.e_phnum -= 1 elf.programHeaderTable.pop() print print "Q6ZIP FEATURE (RW)" # Get the ELF section containing the code to compress sh = elf.getSectionByName(q6_rwSection) # Check if the section exists if (sh != const.RC_ERROR): print "\t'" + q6_rwSection + " section found" print "Size of " + q6_rwSection + " is " + str(sh.sh_size) # Save the old VA before ANY modifications to the section/segment oldSize = sh.sh_size bss_common_start = elf.getSymbolByName( "__swapped_segments_bss_start__").st_value print "\bss_common_start = " + hex(bss_common_start) symbolDict["start_va_uncompressed_rw"] = sh.sh_addr symbolDict["end_va_uncompressed_rw"] = sh.sh_addr + sh.sh_size rw_contents = bss_common_start - sh.sh_addr print "\t rw_contents = " + hex(rw_contents) # Move up the section print "\tMoving up " + q6_rwSection + " to closest section" elf.moveupSectionByName(q6_rwSection) newVA = sh.sh_addr print "\tCompressing " + q6_rwSection + " contents using q6 compressor" import rw_py_compress sh.contents = rw_py_compress.rw_py_compress(pageSize, newVA, sh.contents[0:rw_contents]) #pad with 0s till pageSize rem = len(sh.contents) % pageSize if rem != 0: sh.contents = sh.contents.ljust( len(sh.contents) + pageSize - rem, '0') # Resize the section elf.resizeSectionByName(q6_rwSection, len(sh.contents)) symbolDict["start_va_compressed_rw"] = newVA symbolDict["end_va_compressed_rw"] = sh.sh_addr + sh.sh_size # Change permissions (remove execute) print "\tRemoving X from " + q6_rwSection sh.sh_flags = sh.sh_flags & ~const.sectionFlags.SHF_EXECINSTR ph = elf.getProgramHeaderBySectionName(q6_rwSection) if ph != const.RC_ERROR: ph.p_flags &= ~const.segmentFlags.PF_X else: utils.raiseElfManipulatorError( "Unexpected error while changing permissions for " + q6_rwSection) # Print out statistics print "Size of " + q6_rwSection + " after compression " + str( sh.sh_size) print("Memory Savings Report: Q6Zip RW: Gross Memory Saved: %u" % (oldSize - sh.sh_size)) # Moving up sections elf.moveupElfOffsetSectionByName(q6_roSection) elf.moveupElfOffsetSectionByName(q6_rwSection) # moving this part to pplkcmd.py for prototyping. #elf.moveupElfOffsetSectionByName(dynrec_section) #elf.moveupElfOffsetSectionByName("QSR_STRING") else: # Like ro_fatal, need to check for zero-sized segment print "\tNo " + q6_rwSection + " section found, checking for zero-sized segment" if ((elf.programHeaderTable[-1].p_memsz == 0) and (elf.programHeaderTable[-1].p_vaddr == 0)): print "\tRemoving zero-sized segment" elf.elfHeader.e_phnum -= 1 elf.programHeaderTable.pop() #============================================= # END: Q6_ZIP CHANGES #============================================= # -M option: Remove BSS section for 'overlay_mem_dump' feature if options.overlay_mem_dump and overlay_mem_dumpSize >= 0: # Need to check that the overlay_memdump does not exceed ro_fatal + # candidate_compress_section AFTER manipulations. roFatalSh = elf.getSectionByName("ro_fatal") roCompressSh = elf.getSectionByName(q6_roSection) rwCompressSh = elf.getSectionByName(q6_rwSection) roFatalSz = 0 roCompressSz = 0 rwCompressSz = 0 if roFatalSh != const.RC_ERROR: roFatalSz = roFatalSh.sh_size if roCompressSh != const.RC_ERROR: roCompressSz = roCompressSh.sh_size if rwCompressSh != const.RC_ERROR: rwCompressSz = rwCompressSh.sh_size if overlay_mem_dumpSize > (roFatalSz + roCompressSz + rwCompressSz): print "FATAL ERROR: memdump exceeds ro_fatal + ro/rw candidate_compress_sections." print "ro_fatal size: %s bytes" % str(roFatalSz) print "ro candidate_compress_section size: %s bytes" % str( roCompressSz) print "rw candidate_compress_section size: %s bytes" % str( rwCompressSz) print "FW memdump overlay size: %s bytes" % str( overlay_mem_dumpSize) print "Short by: %s bytes" % ( (roFatalSz + roCompressSz + rwCompressSz) - overlay_mem_dumpSize) print "Aborting" exit(const.RC_ERROR) # After all modifications, update image_vend pointing to the end of the # last program segment, aligned using integer division lastPh = elf.programHeaderTable[-1] for ph in elf.programHeaderTable: if ph.p_vaddr > lastPh.p_vaddr: lastPh = ph endAddress = lastPh.p_vaddr + lastPh.p_align * ( lastPh.p_memsz / lastPh.p_align + 1) symbolDict["image_vend"] = endAddress #=========================================================================== # Option: -s <COPROC_ELF> # Description: Combine silver coprocessor image with primary ELF. No debug # information will be preserved. # Requirements: # [1] Coprocessor image only has a single segment # [2] Primary image has a single section segment (COPROC_IMAGE) # [3] Coprocessor segment does not exceed the original size of COPROC_IMAGE # [4] Coprocessor segment contents becomes the contents of COPROC_IMAGE # [5] __coproc_image_start__ must point to the start of the section #=========================================================================== if options.coprocMerge: print "Combining coprocessor image with primary image..." # Ensure that coprocessor segment does not exceed COPROC_IMAGE size coproc_imageSh = elf.getSectionByName("COPROC_IMAGE") coproc_imagePh = elf.getProgramHeaderBySectionName("COPROC_IMAGE") coproc_align = 256 * (1 << 10) print "\tLooking for COPROC_IMAGE section in primary image" if coproc_imageSh != const.RC_ERROR and coproc_imagePh != const.RC_ERROR: print "\tCOPROC_IMAGE section found in primary image" print "\tValidating coprocessor ELF" coprocELF = options.coprocMerge # Read in the coprocessor ELF and verify [1] coproc = elfFileClass.elfFile(coprocELF) if len(coproc.programHeaderTable) != 1: utils.raiseElfManipulatorError( "Coproc image has more than 1 segment") print "\tComparing size of coprocessor image with reserved COPROC_IMAGE" if coproc_imagePh.p_filesz >= coproc.programHeaderTable[0].p_filesz: # Move up COPROC_IMAGE, if required (both VA/PA and ELF offsets) print "\tMoving up COPROC_IMAGE (address and ELF offset)" elf.moveupSectionByName("COPROC_IMAGE", align=coproc_align) elf.moveupElfOffsetSectionByName("COPROC_IMAGE") # Read in the coprocessor image coprocImage = utils.getDataFromELF( coprocELF, coproc.programHeaderTable[0].p_offset, coproc.programHeaderTable[0].p_filesz) # Replace the contents of COPROC_IMAGE print "\tReplacing contents of COPROC_IMAGE and resizing" coproc_imageSh.contents = coprocImage coprocFinalSize = coproc_imagePh.p_align * ( len(coproc_imageSh.contents) / coproc_imagePh.p_align + 1) for i in xrange(coprocFinalSize - len(coproc_imageSh.contents)): coproc_imageSh.contents += '\0' elf.resizeSectionByName("COPROC_IMAGE", len(coproc_imageSh.contents)) print "\tUpdating __coproc_image_start__" symbolDict["__coproc_image_start__"] = coproc_imagePh.p_vaddr symbolDict["fw_coproc_image_start"] = coproc_imagePh.p_vaddr print "\tUpdating MMU entries surrounding the coprocessor" symbolDict[ "__MMU_region_unmapped_align_padding_start_coproc"] = coproc_imagePh.p_vaddr coproc_end = coproc_imagePh.p_vaddr + len( coproc_imageSh.contents) coproc_end = (coproc_end + coproc_imagePh.p_align - 1) & ~(coproc_imagePh.p_align - 1) symbolDict[ "__MMU_region_start_name_qsr_A0_1_R_1_W_1_X_0_lock_1"] = coproc_end # move this step to pplkcmd.py for CR800980. #print "\tMoving up QSR_STRING" #elf.moveupElfOffsetSectionByName("QSR_STRING") else: # If coprocessor segment exists but is larger than reserved size, need to catch this immediately utils.raiseElfManipulatorError( "Coprocessor segment > COPROC_IMAGE") else: print "\tPrimary image does not have COPROC_IMAGE (no-op)" # Update all symbols if symbolDict: print "----------------------------------------------------------------" print " Updating symbol values from all ELF modifications..." print "----------------------------------------------------------------" elf.updateSymbolValuesByDict(symbolDict) # If verification is enabled, enable verification on if options.verification: print "----------------------------------------------------------------" print " Verifying modified ELF data..." print "----------------------------------------------------------------" elf.verify() # Write out the ELF file based on the elfFile object if not options.debug: print "----------------------------------------------------------------" print " Writing out modified ELF..." print "----------------------------------------------------------------" elf.writeOutELF(modifiedELF) # Record the starting time if options.timing: print("Execution time: %.2f seconds" % (time.time() - start_time)) # elfManipulator ran to completed, exit with return code 0 exit(const.RC_SUCCESS)
def mc( # {{{ self, inpath, outpath=None, do_print=True, store_dyn=False, print_dyn=False ): t1 = timer() retcode = 0 self.p('\nRunning memory checker') objdump = self.objcopy objdump = ps(objdump) objdump = (objdump[0], objdump[1].lower().replace('objcopy', 'objdump')) objdump = pj(*objdump) if print_dyn: try: extra = self.load('mc_extra') except (NameError, KeyError): extra = [] else: extra = [] retcode, stdout, stderr = self.call([ self.python, '-O', pj(self.mypspath, 'mc.py'), '--hexagon-path', objdump, inpath]) if retcode != 0: self.p('Memory checker failed. Logs below:') self.p('stdout: %s' % stdout) self.p('stderr: %s' % stderr) elif do_print: # {{{ if len(extra) > 0: # splice in extra values {{{ extra_lines = [] extra_sizes = 0 sys.path.insert(0, pj(self.mypspath)) import mc # append extra lines for l in extra: m = re.search(r'^([^:]+):\s+([0-9.]{4,}) .iB', l) if not m: continue k, v = m.groups() v = float(v) * (1 << 20) if ('%.2f' % (mc.meg(v),)) != '0.00': extra_lines.append( '%s (dynamic)' % (mc.MemoryChecker.format(k, v),) ) extra_sizes += v stdout = stdout.split('\n') total_offset = [ i for i, s in enumerate(stdout) if s.startswith('Total:') ][0] for i, s in enumerate(extra_lines): stdout.insert(total_offset - 1 + i, s) # update Total total_offset = [ i for i, s in enumerate(stdout) if s.startswith('Total:') ][0] total_val = float(stdout[total_offset].split()[1]) * (1 << 20) total_val += extra_sizes stdout[total_offset] = mc.MemoryChecker.format('Total', total_val) # update Available, if it exists if stdout[total_offset + 1].startswith('Available:'): avail_val = float(stdout[total_offset + 1].split()[1]) * (1 << 20) avail_val -= extra_sizes stdout[total_offset + 1] = mc.MemoryChecker.format( 'Available', avail_val ) stdout = '\n'.join(stdout) # }}} self.p() self.p('=' * 80) self.p() self.p('%s' % stdout) self.p('=' * 80) self.p() self.subtract_savings_costs(stdout) # }}} if store_dyn: try: extra = self.load('mc_extra') except (NameError, KeyError): extra = [] extra.extend([i for i in stdout.split('\n') if 'dynamic' in i]) self.save('mc_extra', extra) t2 = timer() t_diff = t2 - t1 self.p(' Memory checker execution time: %s' % t_str(t_diff)) return retcode
def tlbupdt(self, inpath, outpath): # {{{ t1 = timer() retcode = 0 self.p('\nRunning TLB update') # note the trailing slash tempdir = pj(*[ self.outdir, ''.join(['tlbupdt-', self.short_buildpath]), '']) shutil.rmtree(tempdir, ignore_errors=True) os.makedirs(tempdir) retcode, stdout, stderr = self.call([ self.python, '-O', pj(self.mypspath, 'tlbupdt.py'), inpath, '-t', tempdir, '-q']) if retcode != 0: self.p('TLB update failed. Logs below:') self.p('stdout: %s' % stdout) self.p('stderr: %s' % stderr) return retcode else: self.log('TLB update logs:') self.log('stdout: %s' % stdout) self.log('stderr: %s' % stderr) locked_tlb_entries = '(unknown)' m = re.search(r'(\d+) locked entries', stdout) if m: locked_tlb_entries = m.groups()[0] self.p(' %s locked TLB entries' % locked_tlb_entries) _elfpath = ps(inpath) _elfpath = pj(_elfpath[0], ''.join(['_', _elfpath[1]])) shutil.move(_elfpath, outpath) if retcode != 0: self.p('Post-TLB update objcopy failed. Logs below:') self.p('stdout: %s' % stdout) self.p('stderr: %s' % stderr) else: self.log('Post-TLB update objcopy logs:') self.log('stdout: %s' % stdout) self.log('stderr: %s' % stderr) shutil.rmtree(tempdir, ignore_errors=True) t2 = timer() t_diff = t2 - t1 self.p(' TLB update execution time: %s' % t_str(t_diff)) return retcode
def __init__(self, target, source, env, debug=False, keeplog=True): # {{{ '''Take everything we need from 'env' and prep it for our subroutines. Note: to find env items: print [i for i in env._dict.keys() if 'search_string' in i.lower()] ''' self.elfpath = ap(str(source[0])) self.outdir = ap(ps(self.elfpath)[0]) if target is not None: self.outpath = ap(str(target[0])) if len(target) == 1: self.qdbpath = "" elif len(target) == 2: self.qdbpath = ap(str(target[1])) else: self.outpath = None self.qdbpath = None self.buildms = ap(env.subst('${BUILD_MS_ROOT}')) self.buildpath = ap(env.subst('${BUILD_ROOT}')) self.memreport = (env.subst('${MEMREPORT}') == '1' or ('USES_INTERNAL_BUILD' in env and # last dir of $TARGET_ROOT is 'b' ps(env.subst('${TARGET_ROOT}'))[-1] == 'b')) self.buildroot = env.subst('${TARGET_ROOT}') self.objcopy = env.subst('${OBJCOPY}') self.threads = [] self.python = env.subst('${PYTHONCMD}') self.short_buildpath = env.subst('${SHORT_BUILDPATH}') self.cust_config = env.FindConfigFiles('cust_config.xml')[0] self.core_root = env.subst('${COREBSP_ROOT}') self.debug = debug if len(source) > 1 and source[1] is not None: self.coproc_path = ap(str(source[1])) else: self.coproc_path = None # BYO OrderedDict implementation: [0]: order list, [1]: dict self.savings_report = [[], {}] self.mypspath = ap(file_dir) if env.subst('${FAKE_ENV}') == '1': self.replay = True else: self.replay = False self.executed_manips = [] self.finalized = False if keeplog: self.log_handle = open( ap(pj(self.buildms, 'pplk-%s.log' % self.short_buildpath)), 'wb', ) else: self.log_handle = tempfile.TemporaryFile( prefix='pplk-tmp-%s-' % (self.short_buildpath,), suffix='.log', dir=self.buildms, ) self.log('pplkcmd log version: %i' % (self.log_version,)) self.log('pplkcmd __dict__: %s' % (base64.b64encode(repr(self.__dict__)),))