mirror of
https://github.com/google/pebble.git
synced 2025-05-18 01:14:55 +00:00
Import of the watch repository from Pebble
This commit is contained in:
commit
3b92768480
10334 changed files with 2564465 additions and 0 deletions
136
tools/analyze_static_memory_layout.py
Normal file
136
tools/analyze_static_memory_layout.py
Normal file
|
@ -0,0 +1,136 @@
|
|||
#!/usr/bin/env python
|
||||
# Copyright 2024 Google LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
import argparse
|
||||
import re
|
||||
import sh
|
||||
|
||||
class SectionInfo(object):
|
||||
def __init__(self, name, begin, end):
|
||||
self.name = name
|
||||
self.begin = begin
|
||||
self.end = end
|
||||
|
||||
def read_section_info(elf_file):
|
||||
section_headers_output = sh.arm_none_eabi_readelf('-S', elf_file)
|
||||
|
||||
line_pattern = re.compile(r"""\[\s*\d+\]\s+ # Number
|
||||
(\S+)\s+ # Name
|
||||
\S+\s+ # Type
|
||||
([0-9a-f]+)\s+ # Virtual Address
|
||||
[0-9a-f]+\s+ # Load Address
|
||||
([0-9a-f]+)\s+ # Size
|
||||
""", flags=re.VERBOSE)
|
||||
|
||||
sections = []
|
||||
|
||||
for line in section_headers_output:
|
||||
match = line_pattern.search(line)
|
||||
|
||||
if match is None:
|
||||
continue
|
||||
|
||||
name = match.group(1)
|
||||
addr = int(match.group(2), 16)
|
||||
size = int(match.group(3), 16)
|
||||
|
||||
if (addr < 0x20000000 or addr > 0x20030000) and (addr < 0x10000000 or addr > 0x10010000):
|
||||
# We only care about stuff that goes into ram or CCM
|
||||
continue
|
||||
|
||||
if (name == 'DISCARD'):
|
||||
continue
|
||||
|
||||
sections.append(SectionInfo(name, addr, addr + size))
|
||||
|
||||
return sections
|
||||
|
||||
def find_symbol(word):
|
||||
return re.compile(r"""\b({0})$""".format(word)).search
|
||||
|
||||
def read_layout_symbols(elf_file):
|
||||
symbols_output = sh.arm_none_eabi_objdump('-t', elf_file)
|
||||
|
||||
desired_symbols = [ 'system_stm32f4xx.c',
|
||||
'_heap_start',
|
||||
'_heap_end' ]
|
||||
|
||||
symbols = {}
|
||||
|
||||
line_pattern = re.compile(r"""^(\S+)""")
|
||||
|
||||
for line in symbols_output:
|
||||
for s in desired_symbols:
|
||||
if find_symbol(s)(line):
|
||||
match = line_pattern.search(line)
|
||||
symbols[s] = int(match.group(1), 16)
|
||||
|
||||
return symbols
|
||||
|
||||
def analyze_layout(elf_file):
|
||||
sections = read_section_info(elf_file)
|
||||
symbols = read_layout_symbols(elf_file)
|
||||
|
||||
ram_start_address = 0x20000000
|
||||
ram_end_address = 0x20020000
|
||||
|
||||
if 'system_stm32f4xx.c' in symbols:
|
||||
# We have a snowy! Adjust the RAM size to be larger
|
||||
ram_end_address = 0x20030000
|
||||
|
||||
# Add a dummy section that spans where the kernel heap is
|
||||
sections.append(SectionInfo('<KERNEL HEAP>', symbols['_heap_start'], symbols['_heap_end']))
|
||||
|
||||
sections = sorted(sections, key=lambda x: x.begin)
|
||||
|
||||
last_end = 0
|
||||
padding_total = 0
|
||||
|
||||
for s in sections:
|
||||
if last_end != 0 and last_end != s.begin:
|
||||
# There's a gap between sections! Use the last section's name to identify what it is.
|
||||
|
||||
padding_end = s.begin
|
||||
|
||||
# Don't insert a padding after CCM and before RAM
|
||||
if padding_end != ram_start_address:
|
||||
if last_name == '.worker_bss' or last_name == '.workerlib_paddin':
|
||||
name = 'WORKER CODE + HEAP'
|
||||
else:
|
||||
name = 'PADDING'
|
||||
padding_total += padding_end - last_end
|
||||
|
||||
print "0x%x - 0x%x %6u bytes <%s>" % \
|
||||
(last_end, padding_end, padding_end - last_end, name)
|
||||
|
||||
print "0x%x - 0x%x %6u bytes %s" % (s.begin, s.end, s.end - s.begin, s.name)
|
||||
|
||||
last_end = s.end
|
||||
last_name = s.name
|
||||
|
||||
# The app code + heap region doesn't have a section for it, it just takes up everything at the
|
||||
# end of the address space.
|
||||
print "0x%x - 0x%x %6u bytes <APP CODE + HEAP>" % (last_end, ram_end_address, ram_end_address - last_end)
|
||||
|
||||
print 'Total padding: %u bytes' % padding_total
|
||||
|
||||
if (__name__ == '__main__'):
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('elf_file')
|
||||
args = parser.parse_args()
|
||||
|
||||
sections = analyze_layout(args.elf_file)
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue