143 lines
4.1 KiB
Python
143 lines
4.1 KiB
Python
|
#!/usr/bin/env python3
|
||
|
import sys
|
||
|
import argparse
|
||
|
import os
|
||
|
import re
|
||
|
import string
|
||
|
from elftools.elf.elffile import ELFFile
|
||
|
|
||
|
partitions=[]
|
||
|
variables=[]
|
||
|
|
||
|
app_smem = "/*\n * The following is a dynamically created linker section.\n" \
|
||
|
" * Please do not modify or delete.\n */\n"
|
||
|
dRegion_size = { "0x20":32 , \
|
||
|
"0x40":64, \
|
||
|
"0x80":128, \
|
||
|
"0x100":256, \
|
||
|
"0x200":512, \
|
||
|
"0x400":1024, \
|
||
|
"0x800":2048, \
|
||
|
"0x1000":4096, \
|
||
|
"0x2000":8192, \
|
||
|
"0x4000":16384, \
|
||
|
"0x8000":32768, \
|
||
|
"0x10000":65536, \
|
||
|
"0x20000":131072, \
|
||
|
"0x40000":262144, \
|
||
|
"0x80000":524288, \
|
||
|
"0x100000":1048576, \
|
||
|
"0x200000":2097152, \
|
||
|
"0x400000":4194304, \
|
||
|
"0x800000":8388608, \
|
||
|
"0x1000000":16777216, \
|
||
|
"0x2000000":33554432, \
|
||
|
"0x4000000":67108864, \
|
||
|
"0x8000000":134217728, \
|
||
|
"0x10000000":268435456, \
|
||
|
"0x20000000":536870912, \
|
||
|
"0x40000000":1073741824, \
|
||
|
"0x80000000":2147483648, \
|
||
|
"0x100000000":4294967296}
|
||
|
|
||
|
def build_linker_section(filename, regionSizes):
|
||
|
with open(filename, 'w') as f:
|
||
|
f.write(app_smem)
|
||
|
for part in partitions:
|
||
|
psize = "0"
|
||
|
if (part.endswith("b")):
|
||
|
continue
|
||
|
for partition, size in regionSizes:
|
||
|
if (partition == str(part).strip("b'")):
|
||
|
f.write("\t\t. = ALIGN(" + size + ");\n");
|
||
|
psize = size
|
||
|
f.write("\t\t" + str(part).strip("b'") + " = .;\n")
|
||
|
f.write("\t\t*(SORT(" + str(part).strip("b'") + "*))\n")
|
||
|
f.write("\t\t. = ALIGN(_app_data_align);\n")
|
||
|
f.write("\t\t" + str(part).strip("b'") + "b_end = .;\n")
|
||
|
f.write("\t\t. = ALIGN(" + psize + ");\n")
|
||
|
|
||
|
|
||
|
def find_variables(filename):
|
||
|
flag = 0
|
||
|
with open(filename, 'rb') as f:
|
||
|
objF = ELFFile( f)
|
||
|
if (not objF):
|
||
|
print("Error parsing file: ",filename)
|
||
|
os.exit(1)
|
||
|
sec = [ x for x in objF.iter_sections()]
|
||
|
for s in sec:
|
||
|
if ("smem" in s.name and not ".rel" in s.name):
|
||
|
variables.append( s)
|
||
|
|
||
|
|
||
|
def build_partitions():
|
||
|
global partitions
|
||
|
s = set()
|
||
|
for var in variables:
|
||
|
s.add(var.name)
|
||
|
for sec in sorted(s):
|
||
|
partitions.append(sec)
|
||
|
|
||
|
def calc_sec_size():
|
||
|
d = dict()
|
||
|
if not variables:
|
||
|
return None
|
||
|
for v in variables:
|
||
|
if( v.name in d):
|
||
|
d[v.name] += v.header.sh_size
|
||
|
else:
|
||
|
d[v.name] = v.header.sh_size
|
||
|
return d
|
||
|
|
||
|
def genRegionDef():
|
||
|
res = []
|
||
|
dSecs = calc_sec_size()
|
||
|
if(dSecs is None):
|
||
|
print("\n***\nError: Failed to identify smem regions in the object files\n***\n")
|
||
|
sys.exit(1)
|
||
|
ordered_defs = []
|
||
|
for key, value in sorted(dRegion_size.items(), key=lambda o: (o[1],o[0]) ):
|
||
|
ordered_defs.append( ( value, key))
|
||
|
|
||
|
ltSecs = sorted(dSecs.items())
|
||
|
szltSecs = len(ltSecs)
|
||
|
if( szltSecs % 2 == 1):
|
||
|
szltSecs += 1
|
||
|
for r in range(int(szltSecs /2 )):
|
||
|
i = r*2
|
||
|
sz = ltSecs[i][1] + ltSecs[1+i][1]
|
||
|
for d in ordered_defs:
|
||
|
if( sz < d[0]):
|
||
|
res.append( ( ltSecs[i][0], d[1]))
|
||
|
break
|
||
|
return res
|
||
|
|
||
|
|
||
|
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=True,
|
||
|
help="Output ld file")
|
||
|
args = parser.parse_args()
|
||
|
|
||
|
|
||
|
def main():
|
||
|
parse_args()
|
||
|
startIndex = args.directory
|
||
|
fileOutput = args.output
|
||
|
for dirpath, dirs, files in os.walk(startIndex):
|
||
|
for filename in files:
|
||
|
if (filename.endswith(".obj") or filename.endswith(".OBJ")):
|
||
|
fullname = os.path.join(dirpath, filename)
|
||
|
find_variables(fullname)
|
||
|
build_partitions()
|
||
|
build_linker_section(fileOutput, genRegionDef())
|
||
|
|
||
|
if __name__ == '__main__':
|
||
|
main()
|