def generate(self, regs, outpath): try: regs = filters["no_access_mechanism"].filter_exclusive(regs) regs = transforms["remove_reserved_0"].transform(regs) regs = transforms["remove_reserved_1"].transform(regs) regs = transforms["remove_preserved"].transform(regs) regs = transforms["special_to_underscore"].transform(regs) logger.info("Generating outputs to: " + str(outpath)) for reg in regs: include_guard = "PAL_" + reg.name.upper() + "_H" self.gadgets["pal.include_guard"].name = include_guard self.gadgets["pal.header_depends"].includes = [ "<stdint.h>" ] outfile_path = os.path.join(outpath, reg.name.lower() + ".h") outfile_path = os.path.abspath(outfile_path) with open(outfile_path, "w") as outfile: self.gadgets["pal.cxx.namespace"].name = "pal" self._generate_register(outfile, reg) self.gadgets["pal.cxx.namespace"].indent_contents = False except Exception as e: msg = "{g} failed to generate output {out}: {exception}".format( g=str(type(self).__name__), out=outpath, exception=e) raise PalGeneratorException(msg)
def generate_registers(self, regs, outpath): try: regs = transforms["remove_reserved_0"].transform(regs) regs = transforms["remove_reserved_1"].transform(regs) regs = transforms["remove_reserved_sign_extended"].transform(regs) regs = transforms["remove_implementation_defined"].transform(regs) regs = transforms["special_to_underscore"].transform(regs) regs = transforms["insert_valid_first_character"].transform(regs) regs = transforms["remove_redundant_am"].transform(regs) regs = transforms["remove_redundant_fields"].transform(regs) regs = transforms["unique_fieldset_names"].transform(regs) regs = filters["no_access_mechanism"].filter_exclusive(regs) logger.info("Generating C header file registers to: " + str(outpath)) for reg in regs: include_guard = "PAL_" + reg.name.upper() + "_H" self.gadgets["pal.include_guard"].name = include_guard outfile_path = os.path.join(outpath, reg.name.lower() + ".h") outfile_path = os.path.abspath(outfile_path) with open(outfile_path, "w") as outfile: self._generate_register(outfile, reg) except Exception as e: msg = "{g} failed to generate output {out}: {exception}".format( g=str(type(self).__name__), out=outpath, exception=e) raise PalGeneratorException(msg)
def filter_inclusive(self, registers): """ Filter the given registers such that registers matching the filter's criteria are included, while all others are excluded (removed) """ logger.info("Applying filter: including {d}".format(d=str(self))) result = list(itertools.filterfalse(self._do_filter, registers)) logger.debug("{count} registers remaining after {name}".format( name=str(type(self).__name__), count=str(len(result)))) return result
def filter_exclusive(self, registers): """ Filter the given registers such that registers matching the filter's criteria are excluded (removed) """ logger.info("Applying filter: excluding {d}".format(d=str(self))) result = list(filter(self._do_filter, registers)) logger.debug("{name} removed {count} registers".format( name=str(type(self).__name__), count=str(len(registers) - len(result)))) return result
def generate(self, regs, outpath): try: outfile_path = os.path.abspath(os.path.join(outpath, "pal.h")) logger.info("Generating C Header: " + str(outfile_path)) regs = transforms["remove_reserved_0"].transform(regs) regs = transforms["remove_reserved_1"].transform(regs) regs = transforms["remove_reserved_sign_extended"].transform(regs) regs = transforms["remove_implementation_defined"].transform(regs) regs = transforms["special_to_underscore"].transform(regs) regs = transforms["remove_redundant_am"].transform(regs) regs = transforms["remove_redundant_fields"].transform(regs) regs = transforms["unique_fieldset_names"].transform(regs) regs = filters["no_access_mechanism"].filter_exclusive(regs) if config.encoded_functions: msg = "Encoded accessors are only supported for aarch64 " msg += "registers (aarch32 and external not supported)" logger.warn(msg) regs = filters["aarch64"].filter_inclusive(regs) self.gadgets["pal.header_depends"].includes = [ "<stdint.h>", "aarch32_gcc_accessor_macros.h", "aarch64_gcc_accessor_macros.h" ] unique = [] for reg in regs: external_mechs = reg.access_mechanisms["ldr"] + \ reg.access_mechanisms["str"] for mech in external_mechs: if mech.component not in unique: unique.append(mech.component) self.gadgets["pal.external_component"].components = unique with open(outfile_path, "w") as outfile: self._generate(outfile, regs) except Exception as e: msg = "{g} failed to generate output {out}: {exception}".format( g=str(type(self).__name__), out=outpath, exception=e) raise PalGeneratorException(msg)
def generate_instructions(self, instructions, outpath): try: logger.info("Generating C header file instructions to: " + str(outpath)) for inst in instructions: include_guard = "PAL_EXECUTE_" + inst.name.upper() + "_H" self.gadgets["pal.include_guard"].name = include_guard outfile_path = os.path.join(outpath, inst.name.lower() + ".h") outfile_path = os.path.abspath(outfile_path) with open(outfile_path, "w") as outfile: self._generate_instruction(outfile, inst) except Exception as e: msg = "{g} failed to generate output {out}: {exception}".format( g=str(type(self).__name__), out=outpath, exception=e) raise PalGeneratorException(msg)
def parse_registers(spec_path): if not os.path.exists(spec_path): msg = "Failed to parse registers, spec not found at: " + str(spec_path) logger.error(msg) raise PalParserException(msg) logger.info("Parsing registers from: " + str(spec_path)) regs = [] # paths = glob.glob(spec_path + "/*.xml") # parser = ArmV8XmlParser() paths = glob.glob(spec_path + "/*.yml") parser = PalModelParser() for path in paths: results = parser.parse_file(path) if results: for result in results: regs.append(result) logger.debug("Registers parsed: " + str(len(regs))) return regs
def transform(self, registers): """ Transform the given list of registers """ logger.info("Applying transform: {d}".format(d=str(self))) return list(map(self.do_transform, registers))