text: #!/usr/bin/env python3
  import sys
  import argparse
  import os
  import re
  import string
  from elf_helper import ElfHelper
  from elftools.elf.elffile import ELFFile
  
  
  # This script will create linker comands for power of two aligned MPU
  # when APP_SHARED_MEM is enabled.
  print_template = """
  		/* Auto generated code do not modify */
  		. = ALIGN( 1 << LOG2CEIL(data_smem_{0}b_end - data_smem_{0}));
  		data_smem_{0} = .;
  		KEEP(*(SORT(data_smem_{0}*)))
  		. = ALIGN(_app_data_align);
  		. = ALIGN( 1 << LOG2CEIL(data_smem_{0}b_end - data_smem_{0}));
  		data_smem_{0}b_end = .;
  """
  linker_start_seq = """
  	SECTION_PROLOGUE(_APP_SMEM_SECTION_NAME, (OPTIONAL),)
  	{
  		APP_SHARED_ALIGN;
  		_image_ram_start = .;
  		_app_smem_start = .;
  """
  
  linker_end_seq = """
  		_app_smem_end = .;
  		APP_SHARED_ALIGN;
  	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
  """
  
  size_cal_string = """
  	data_smem_{0}_size = data_smem_{0}b_end - data_smem_{0};
  """
  
  
  def find_partitions(filename, full_list_of_partitions, partitions_source_file):
      with open(filename, 'rb') as f:
          full_lib = ELFFile( f)
          if (not full_lib):
              print("Error parsing file: ",filename)
              os.exit(1)
  
          sections = [ x for x in full_lib.iter_sections()]
          for section in sections:
              if ("smem" in  section.name and not ".rel" in section.name):
                  partition_name = section.name.split("data_smem_")[1]
                  if partition_name not in full_list_of_partitions:
                      full_list_of_partitions.append(partition_name)
                      if args.verbose:
                          partitions_source_file.update({partition_name: filename})
  
      return( full_list_of_partitions, partitions_source_file)
  
  def cleanup_remove_bss_regions(full_list_of_partitions):
      for partition in full_list_of_partitions:
          if (partition+"b" in full_list_of_partitions):
              full_list_of_partitions.remove(partition+"b")
      return full_list_of_partitions
  
  def generate_final_linker(linker_file, full_list_of_partitions):
      string = linker_start_seq
      size_string = ''
      for partition in full_list_of_partitions:
          string += print_template.format(partition)
          size_string += size_cal_string.format(partition)
  
      string += linker_end_seq
      string += size_string
      with open(linker_file, "w") as fw:
          fw.write(string)
  
  
  def parse_args():
      global args
      parser = argparse.ArgumentParser(
          description=__doc__,
          formatter_class=argparse.RawDescriptionHelpFormatter)
      parser.add_argument("-d", "--directory", required=True,
                          help="Root build directory")
      parser.add_argument("-o", "--output", required=False,
                          help="Output ld file")
      parser.add_argument("-v", "--verbose", action="count", default =0,
                          help="Verbose Output")
      args = parser.parse_args()
  
  
  def main():
      parse_args()
      root_directory = args.directory
      linker_file = args.output
      full_list_of_partitions = []
      partitions_source_file= {}
  
      for dirpath, dirs, files in os.walk(root_directory):
          for filename in files:
              if re.match(".*\.obj$",filename):
                  fullname = os.path.join(dirpath, filename)
                  full_list_of_partitions, partitions_source_file = find_partitions(fullname, full_list_of_partitions, partitions_source_file)
  
      full_list_of_partitions = cleanup_remove_bss_regions(full_list_of_partitions)
      generate_final_linker(linker_file, full_list_of_partitions)
      if args.verbose:
          print("Partitions retrieved: PARTITION, FILENAME")
          print([key + " "+ partitions_source_file[key] for key in full_list_of_partitions])
  
  if __name__ == '__main__':
      main()
  