152 lines
4.3 KiB
Python
152 lines
4.3 KiB
Python
#!/usr/bin/env python3
|
|
#
|
|
# Copyright (c) 2018 Intel Corporation
|
|
#
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
|
|
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 sections and linker variables to place the
|
|
# application shared memory partitions.
|
|
# these are later read by the macros defined in app_memdomain.h for
|
|
# initialization purpose when APP_SHARED_MEM is enabled.
|
|
data_template = """
|
|
/* Auto generated code do not modify */
|
|
SMEM_PARTITION_ALIGN(data_smem_{0}_bss_end - data_smem_{0}_start);
|
|
data_smem_{0}_start = .;
|
|
KEEP(*(data_smem_{0}_data))
|
|
"""
|
|
|
|
library_data_template = """
|
|
*{0}:*(.data .data.*)
|
|
"""
|
|
|
|
bss_template = """
|
|
data_smem_{0}_bss_start = .;
|
|
KEEP(*(data_smem_{0}_bss))
|
|
"""
|
|
|
|
library_bss_template = """
|
|
*{0}:*(.bss .bss.* COMMON COMMON.*)
|
|
"""
|
|
|
|
footer_template = """
|
|
SMEM_PARTITION_ALIGN(data_smem_{0}_bss_end - data_smem_{0}_start);
|
|
data_smem_{0}_bss_end = .;
|
|
data_smem_{0}_end = .;
|
|
"""
|
|
|
|
linker_start_seq = """
|
|
SECTION_PROLOGUE(_APP_SMEM_SECTION_NAME, (OPTIONAL),)
|
|
{
|
|
APP_SHARED_ALIGN;
|
|
_app_smem_start = .;
|
|
"""
|
|
|
|
linker_end_seq = """
|
|
APP_SHARED_ALIGN;
|
|
_app_smem_end = .;
|
|
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
|
|
"""
|
|
|
|
size_cal_string = """
|
|
data_smem_{0}_size = data_smem_{0}_end - data_smem_{0}_start;
|
|
data_smem_{0}_bss_size = data_smem_{0}_bss_end - data_smem_{0}_bss_start;
|
|
"""
|
|
|
|
section_regex = re.compile(r'data_smem_([A-Za-z0-9_]*)_(data|bss)')
|
|
|
|
def find_partitions(filename, partitions, sources):
|
|
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:
|
|
m = section_regex.match(section.name)
|
|
if not m:
|
|
continue
|
|
|
|
partition_name = m.groups()[0]
|
|
if partition_name not in partitions:
|
|
partitions[partition_name] = []
|
|
if args.verbose:
|
|
sources.update({partition_name: filename})
|
|
|
|
return (partitions, sources)
|
|
|
|
|
|
def generate_final_linker(linker_file, partitions):
|
|
string = linker_start_seq
|
|
size_string = ''
|
|
for partition, libs in partitions.items():
|
|
string += data_template.format(partition)
|
|
for lib in libs:
|
|
string += library_data_template.format(lib)
|
|
string += bss_template.format(partition)
|
|
for lib in libs:
|
|
string += library_bss_template.format(lib)
|
|
string += footer_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")
|
|
parser.add_argument("-l", "--library", nargs=2, action="append", default=[],
|
|
metavar=("LIBRARY", "PARTITION"),
|
|
help="Include globals for a particular library or object filename into a designated partition")
|
|
|
|
args = parser.parse_args()
|
|
|
|
|
|
def main():
|
|
parse_args()
|
|
linker_file = args.output
|
|
partitions = {}
|
|
sources = {}
|
|
|
|
for dirpath, dirs, files in os.walk(args.directory):
|
|
for filename in files:
|
|
if re.match(".*\.obj$",filename):
|
|
fullname = os.path.join(dirpath, filename)
|
|
find_partitions(fullname, partitions,
|
|
sources)
|
|
|
|
for lib, ptn in args.library:
|
|
if ptn not in partitions:
|
|
partitions[ptn] = [lib]
|
|
else:
|
|
partitions[ptn].append(lib)
|
|
|
|
generate_final_linker(args.output, partitions)
|
|
if args.verbose:
|
|
print("Partitions retrieved:")
|
|
for key in partitions:
|
|
print(" %s: %s\n", key, sources[key])
|
|
|
|
if __name__ == '__main__':
|
|
main()
|