[Feature]Upload Modem source code
Change-Id: Id4294f30faced84d3e6fd6d5e61e1111bf287a37
diff --git a/mcu/tools/mertos/__init__.py b/mcu/tools/mertos/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/mcu/tools/mertos/__init__.py
diff --git a/mcu/tools/mertos/mer_codegen.py b/mcu/tools/mertos/mer_codegen.py
new file mode 100644
index 0000000..d09ecab
--- /dev/null
+++ b/mcu/tools/mertos/mer_codegen.py
@@ -0,0 +1,368 @@
+#!/usr/bin/python
+# ****************************************************************************
+# Copyright Statement:
+# --------------------
+# This software is protected by Copyright and the information contained
+# herein is confidential. The software may not be copied and the information
+# contained herein may not be used or disclosed except with the written
+# permission of MediaTek Inc. (C) 2018
+#
+# BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+# THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+# RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+# AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+# NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+# SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+# SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+# THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+# NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+# SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+#
+# BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+# LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+# AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+# OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+# MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+#
+# THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+# WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+# LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+# RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+# THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+#
+# ****************************************************************************
+#
+# ****************************************************************************
+#
+# Filename:
+# ---------
+# mer_codegen.py
+#
+# Project:
+# --------
+# MERTOS
+#
+# Description:
+# ------------
+# Generate the codes required by MERTOS.
+#
+#
+# Author:
+# -------
+# Ke-Ting Chen (mtk03141)
+#
+# ****************************************************************************
+
+import mer_utility
+
+import os
+import sys
+
+
+def extract_task_info(data_extractor):
+ """
+ Transform syscomp data to internal representation
+ """
+ # typedef struct {
+ # kal_char *comp_name_ptr;
+ # kal_char *comp_qname_ptr;
+ # kal_uint32 comp_priority;
+ # kal_uint32 comp_stack_size;
+ # kal_create_func_ptr comp_create_func;
+ # kal_bool comp_internal_ram_stack;
+ # kal_uint8 comp_ext_qsize;
+ # kal_uint8 comp_int_qsize;
+ # kal_uint8 comp_boot_mode;
+ # kal_affinity_group comp_affinity_attribute;
+ # kal_bool comp_affinity_dynamic;
+ # kal_task_group_id comp_affinity_group_id;
+ # } comptask_info_struct;
+
+ # Get structure size
+ affinity_group_size = data_extractor.unpack_symbol_data('I', 'cfg_affinity_group_size')[0]
+ if affinity_group_size == 1:
+ struct_format_string = 'IIIIIBBBBBBxxI'
+ elif affinity_group_size == 2:
+ struct_format_string = 'IIIIIBBBBHBxI'
+ else:
+ assert 0
+ field_names = ['name', 'mail_queue_name', 'priority', 'stack_size', 'create_func',
+ 'is_stack_in_internal_ram', 'mail_queue_size', 'internal_queue_size',
+ 'boot_mode', 'affinity', 'is_dynamic_affinity', 'affinity_group_id']
+
+ infos = data_extractor.unpack_symbol_data_struct_array('sys_comp_config_tbl',
+ struct_format_string, field_names)
+
+ # Get VPE number of MIPS
+ vpe_num = data_extractor.unpack_symbol_data('I', 'cfg_sys_vpe_num')[0]
+
+ # Get ILM struct size
+ mail_size = data_extractor.unpack_symbol_data('I', 'cfg_ilm_struct')[0]
+
+ # Tweak the format
+ infos = [info for info in infos if info['create_func'] != 0xF0F0F0F0]
+ for info in infos:
+ if info['name'] == 0:
+ info['name'] = 'UNKNOWN'
+ else:
+ info['name'] = data_extractor.get_string_data(info['name'])[:-1] # Remove ending 0
+
+ info['priority'] = info['priority'] >> 16
+ info['mail_size'] = mail_size
+ info['entry_func'] = 'kal_mer_task_entry_wrapper'
+ info['init_func'] = 'mer_kernel_task_default_init'
+ del info['mail_queue_name']
+ del info['create_func']
+ del info['internal_queue_size']
+ del info['boot_mode']
+ del info['is_dynamic_affinity']
+ del info['affinity_group_id']
+
+ if info['stack_size'] % 32 != 0:
+ info['stack_size'] += (32 - info['stack_size'] % 32)
+
+ assert info['stack_size'] >= 96, ('Stack size should not less than 96 bytes: task ' +
+ info['name'])
+ for idx in range(vpe_num):
+ info = dict()
+ info['name'] = 'DUMMY_IDLE_LOOP%d' % idx
+ info['priority'] = 1024+idx
+ info['mail_size'] = 0
+ info['entry_func'] = 'mer_kernel_task_dummy_loop'
+ info['init_func'] = 'mer_kernel_task_default_init'
+ info['affinity'] = 2**idx
+ info['mail_queue_size'] = 0
+ info['mail_size'] = 0
+ info['stack_size'] = 512
+ infos.append(info)
+
+ assert len(infos) <= 256, 'The current total tasks number over 256.\n'
+
+ return infos
+
+
+def write_task_config(infos, config_output_path, priority_output_path):
+ # Sort by priority
+ infos.sort(key=lambda x: (x['priority'], -x['affinity']))
+
+ # To reduce the size of TCB size required in MERTOS, we have to pack the priorities
+ # Also, we have to put the KAL priority to MERTOS priority mapping in another file
+ original_priorities = [None] * len(infos)
+ for index in xrange(len(infos)):
+ if infos[index]['priority'] < 1024:
+ original_priorities[index] = infos[index]['priority']
+ else:
+ original_priorities[index] = 0
+
+ infos[index]['priority'] = index
+
+ # Write task config file
+ output_info_list = ['name', 'affinity', 'stack_size', 'mail_queue_size', 'mail_size',
+ 'priority', 'entry_func', 'init_func']
+ write_config(infos, output_info_list, 'MER_CONFIG_TASK', config_output_path)
+
+ # Write priority mapping
+ with open(priority_output_path, 'w') as out_file:
+ out_file.write(', '.join([str(priority) for priority in original_priorities]))
+
+
+def extract_dpc_info(data_extractor):
+ """
+ Transform syscomp data to internal representation
+ """
+ # typedef struct {
+ # kal_hisr index;
+ # kal_uint8 priority;
+ # kal_uint8 options;
+ # kal_uint32 stack_size;
+ # kal_hisr_func_ptr entry_func;
+ # kal_char *hisr_name;
+ # kal_affinity_group affinity_attribute;
+ # kal_bool affinity_dynamic;
+ # } hisr_parameter_s;
+
+ # Get structure size
+ affinity_group_size = data_extractor.unpack_symbol_data('I', 'cfg_affinity_group_size')[0]
+ if affinity_group_size == 1:
+ struct_format_string = 'BBBxIIIBBxx'
+ elif affinity_group_size == 2:
+ struct_format_string = 'BBBxIIIHBx'
+ else:
+ assert 0
+ field_names = ['index', 'priority', 'options', 'stack_size', 'entry_func', 'name', 'affinity',
+ 'is_dynamic_affinity']
+ infos = data_extractor.unpack_symbol_data_struct_array('hisr_info',
+ struct_format_string, field_names)
+
+ # Tweak the format
+ for index, info in zip(xrange(len(infos)), infos):
+ if info['name'] == 0:
+ info['name'] == 'UNKNOWN'
+ else:
+ info['name'] = data_extractor.get_string_data(info['name'])[:-1] # Remove ending 0
+
+ assert info['entry_func'], ('Entry function should not be NULL: hisr ' +
+ info['name'])
+ info['entry_func'] = data_extractor.get_symbol_name(info['entry_func'])
+ assert info['entry_func'] != 'SYMBOL_NOT_FOUND'
+
+ del info['options']
+ del info['is_dynamic_affinity']
+
+ if info['stack_size'] % 32 != 0:
+ info['stack_size'] += (32 - info['stack_size'] % 32)
+
+ assert info['stack_size'] >= 96, ('Stack size should not less than 96 bytes: task ' +
+ info['name'])
+
+ return infos
+
+
+def write_dpc_config(infos, config_output_path, index_output_path):
+ # Do not sort by index
+ # infos.sort(key=lambda x: x['index'])
+
+ # Get the information to map from KAL HISR index to MERTOS DPC index
+ # Also, we have to put the KAL index to MERTOS index mapping in another file
+ max_index = max(info['index'] for info in infos)
+ kal_to_mertos_indices = [max_index] * (max_index + 1)
+ for index in xrange(len(infos)):
+ kal_to_mertos_indices[infos[index]['index']] = index
+
+ # Write dpc config file
+ output_info_list = ['name', 'affinity', 'priority', 'stack_size', 'entry_func']
+ write_config(infos, output_info_list, 'MER_CONFIG_DPC', config_output_path)
+
+ # Write index mapping
+ with open(index_output_path, 'w') as out_file:
+ out_file.write(', '.join([str(index) for index in kal_to_mertos_indices]))
+
+
+def extract_fixmem_info(data_extractor):
+ """
+ Transform syscomp data to internal representation
+ """
+ # First parse control buffer
+ # typedef struct
+ # {
+ # kal_uint32 buf_size;
+ # kal_uint16 buf_num;
+ # } buffer_size_s;
+ struct_format_string = 'IHxx'
+ field_names = ['size', 'number']
+ infos = data_extractor.unpack_symbol_data_struct_array('cfg_ctrl_buff',
+ struct_format_string, field_names)
+
+ # Get control buffer overhead for each block
+ control_buffer_total_overhead = data_extractor.unpack_symbol_data('I', 'cfg_ctrl_buff_overhead')[0]
+
+ # Get control buffer OS overhead for each block
+ control_buffer_os_overhead = data_extractor.unpack_symbol_data('I', 'cfg_os_buff_overhead')[0]
+
+ # Before KAL refactoring cfg_event_buff is controlled by MERTOS
+ # That is, we don't need to know the certain pool_id of memory buffer from header
+ # It must be evshed_pool_id
+ # However, KAL refactoring gather the porting layer from each OS
+ # and use the common level API(kal_os_allocate_buffer/kal_os_deallocate_buffer) to allocate/free memory
+
+
+ # Add the overhead to each control buffer, this buffer is for user, apply total overhead(header/footer)
+ for entry in infos:
+ entry['size'] += control_buffer_total_overhead
+ entry['type'] = 'fixmem'
+
+ # Get event scheduler buffer requirement
+ event_scheduler_infos = data_extractor.unpack_symbol_data_struct_array(
+ 'cfg_event_buff', struct_format_string, field_names)
+
+ # Add the overhead to each control buffer, this buffer is for OS, apply only the OS overhead
+ for entry in event_scheduler_infos:
+ entry['size'] += control_buffer_os_overhead
+ entry['type'] = 'event'
+
+ infos.extend(event_scheduler_infos)
+
+ return infos
+
+
+def write_fixmem_config(infos, config_output_path):
+ # Write dpc config file
+ output_info_list = ['type', 'size', 'number']
+ write_config(infos, output_info_list, 'MER_SERVICE_CONFIG_FIXMEM', config_output_path)
+
+
+def write_mutex_semaphore_config(mutex_number, semaphore_number, config_output_path):
+ output_info_list = ['name', 'count']
+ infos = list({output_info_list[0]: 'M{0}'.format(index), output_info_list[1]: 1}
+ for index in xrange(mutex_number - 1))
+ infos.append({output_info_list[0]: 'LAST_MUTEX', output_info_list[1]: 1})
+ infos.extend(list({output_info_list[0]: 'S{0}'.format(index), output_info_list[1]: 1}
+ for index in xrange(semaphore_number)))
+ write_config(infos, output_info_list, 'MER_SERVICE_CONFIG_SEMAPHORE', config_output_path)
+
+
+def write_enhmutex_config(number, config_output_path):
+ output_info_list = ['name']
+ infos = list({output_info_list[0]: index} for index in xrange(number))
+ write_config(infos, output_info_list, 'MER_SERVICE_CONFIG_SYNC_ENHMUTEX', config_output_path)
+
+
+def write_event_group_config(number, config_output_path):
+ output_info_list = ['name']
+ infos = list({output_info_list[0]: index} for index in xrange(number))
+ write_config(infos, output_info_list, 'MER_SERVICE_CONFIG_EVENT_GROUP', config_output_path)
+
+
+def write_config(infos, column_names, row_name, output_path):
+ def merge_dicts(a, b):
+ c = a.copy()
+ c.update(b)
+ return c
+
+ column_width = {}
+ for name in column_names:
+ column_width[name + '_width'] = max(len(name), max(len(str(info[name])) for info in infos))
+ output_format = ', '.join('{{{0}:{{{0}_width}}}}'.format(name) for name in column_names)
+
+ # Write config file
+ with open(output_path, 'w') as out_file:
+ #Guard header
+ out_file.write('#if !defined(__MER_CONFIG_MUST_REBUILD__)\n')
+ out_file.write(' #error "should not include this file since this module is library release or binary release"\n')
+ out_file.write('#endif\n')
+ # Write info comment line
+ column_name_dict = {name: name for name in column_names}
+ out_file.write('/*' + ' ' * (len(row_name) - 2 + 1) + output_format.format(
+ **merge_dicts(column_name_dict, column_width)) + '*/\n')
+ for info in infos:
+ out_file.write('{0}('.format(row_name) + output_format.format(
+ **merge_dicts(info, column_width)) + ')\n')
+
+
+def main(argv):
+ def get_config_output_path(filename):
+ return os.path.join(task_config_output_folder, filename)
+
+ readelf_exec = argv[1]
+ elf_path = argv[2]
+ task_config_output_folder = argv[3]
+
+ data_extractor = mer_utility.ElfDataExtractor(readelf_exec, elf_path)
+ task_infos = extract_task_info(data_extractor)
+ dpc_infos = extract_dpc_info(data_extractor)
+ fixmem_infos = extract_fixmem_info(data_extractor)
+
+ write_task_config(task_infos,
+ get_config_output_path('kal_mertos_config_task.inc'),
+ get_config_output_path('kal_mertos_config_task_priority_mapping.inc'))
+ write_dpc_config(dpc_infos,
+ get_config_output_path('kal_mertos_config_dpc.inc'),
+ get_config_output_path('kal_mertos_config_dpc_index_mapping.inc'))
+ write_fixmem_config(fixmem_infos,
+ get_config_output_path('kal_mertos_config_fixmem.inc'))
+
+
+if __name__ == '__main__':
+ main(sys.argv)
diff --git a/mcu/tools/mertos/mer_utility.py b/mcu/tools/mertos/mer_utility.py
new file mode 100644
index 0000000..3d08763
--- /dev/null
+++ b/mcu/tools/mertos/mer_utility.py
@@ -0,0 +1,218 @@
+#!/usr/bin/python
+# ****************************************************************************
+# Copyright Statement:
+# --------------------
+# This software is protected by Copyright and the information contained
+# herein is confidential. The software may not be copied and the information
+# contained herein may not be used or disclosed except with the written
+# permission of MediaTek Inc. (C) 2018
+#
+# BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+# THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+# RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+# AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+# NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+# SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+# SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+# THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+# NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+# SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+#
+# BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+# LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+# AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+# OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+# MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+#
+# THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+# WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+# LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+# RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+# THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+#
+# ****************************************************************************
+#
+# ****************************************************************************
+#
+# Filename:
+# ---------
+# mer_utility.py
+#
+# Project:
+# --------
+# MERTOS
+#
+# Description:
+# ------------
+# Provide utilities used by MERTOS code generating.
+#
+#
+# Author:
+# -------
+# Ke-Ting Chen (mtk03141)
+#
+# ****************************************************************************
+
+import struct
+import subprocess
+
+
+class ElfDataExtractor(object):
+ def __init__(self, readelf_exec, elf_path):
+ self.elf_path = elf_path
+
+ # Get symbol table
+ # Example lines:
+ # Num: Value Size Type Bind Vis Ndx Name
+ # 20: 00000b1c 5216 OBJECT GLOBAL DEFAULT 9 sys_comp_config_tbl
+ self.symbols = {}
+ symbol_text_lines = subprocess.check_output([readelf_exec, '--symbols',
+ '--wide', elf_path]).splitlines()
+ for line in symbol_text_lines:
+ if line and line.lstrip()[0].isdigit():
+ contents = line.split()
+ if len(contents) == 7:
+ contents.append(contents[0][:-1])
+ #print contents[0][:-1]
+ self.symbols[contents[7]] = {
+ 'name': contents[7],
+ 'type': contents[3],
+ 'section_number': (int(contents[6]) if contents[6].isdigit() else contents[6]),
+ 'address': int(contents[1], 16),
+ 'size': int(contents[2]),
+ 'number': int(contents[0][:-1])}
+
+ # Assumes there is no hole in the number
+ self.symbol_list = sorted(self.symbols.viewvalues(), key=lambda x: x['number'])
+
+ # Get section info
+ # Example lines:
+ # [Nr] Name Type Addr Off Size ES Flg Lk Inf Al
+ # [ 9] .rodata PROGBITS 00000000 000aa0 00231c 00 A 0 0 4
+ self.sections = {}
+ section_text_lines = subprocess.check_output([readelf_exec, '--sections',
+ '--wide', elf_path]).splitlines()
+ for line in section_text_lines:
+ line = line.translate(None, '[]').lstrip()
+ if line and line[0].isdigit():
+ contents = line.split()
+ if contents[0] == '0':
+ self.sections['NULL'] = {'name': 'NULL', 'number': 0,
+ 'address': 0, 'offset': 0, 'size': 0}
+ else:
+ self.sections[contents[1]] = {
+ 'name': contents[1], 'number': int(contents[0]),
+ 'address': int(contents[3], 16), 'offset': int(contents[4], 16),
+ 'size': int(contents[5], 16)}
+
+ # Assumes there is no hole in the section number
+ self.section_list = sorted(self.sections.viewvalues(), key=lambda x: x['number'])
+
+ # Get relocation tables
+ self.relocations = {}
+ with open(elf_path, 'rb') as elf_file:
+ for name, section in self.sections.viewitems():
+ if name.startswith('.rel.') or name.startswith('.rela.'):
+ elf_file.seek(section['offset'])
+ raw_data = elf_file.read(section['size'])
+ if name.startswith('.rel.'):
+ #print 'processing ' + name
+ relocation = self.unpack_data_struct_array(
+ raw_data, '=IxHx', ['offset', 'symbol_number'])
+ for reloc_info in relocation:
+ reloc_info['addend'] = 0
+ name = name[len('.rel'):]
+ else:
+ relocation = self.unpack_data_struct_array(
+ raw_data, '=IBHxI', ['offset', 'type', 'symbol_number', 'addend'])
+ #print 'processing ' + name
+ name = name[len('.rela'):]
+ relocation.sort(key=lambda x: x['offset'])
+ self.relocations[name] = relocation
+
+ # Read in the elf and perform relocation to simplify query
+ elf_data = list(open(elf_path, 'rb').read())
+ for section_name, relocation in self.relocations.viewitems():
+ section_offset = self.sections[section_name]['offset']
+ for reloc_info in relocation:
+ elf_address = reloc_info['offset'] + section_offset
+ symbol = self.symbol_list[reloc_info['symbol_number']]
+ #print symbol['name'], reloc_info['symbol_number'], symbol['type']
+ if symbol['type'] == 'SECTION':
+ section = self.section_list[symbol['section_number']]
+ original_value = struct.unpack_from(
+ 'I', ''.join(elf_data[elf_address:elf_address + 4]))[0]
+ fill_data = original_value + section['offset'] + reloc_info['addend']
+ #print 'SECTION', symbol['name'], elf_data[elf_address:elf_address+4], hex(fill_data), hex(original_value)
+ else:
+ fill_data = reloc_info['symbol_number'] | 0x80000000
+ #print 'OTHER', symbol['name'], elf_data[elf_address:elf_address+4], hex(fill_data)
+ elf_data[elf_address:elf_address + 4] = struct.pack('I', fill_data)
+ elf_data = ''.join(elf_data)
+
+ # Get symbol data from elf
+ for symbol in self.symbols.viewvalues():
+ if symbol['size'] != 0:
+ # Get the content address in elf
+ section = self.section_list[symbol['section_number']]
+ address_offset = symbol['address'] - section['address']
+ elf_address = address_offset + section['offset']
+ # Get content from elf file
+ symbol['data'] = elf_data[elf_address:elf_address + symbol['size']]
+
+ def get_symbol_data(self, symbol_name):
+ return self.symbols[symbol_name]['data']
+
+ def get_symbol_section_name(self, symbol_name):
+ return self.section_list[
+ self.symbols[symbol_name]['section_number']]['name']
+
+ def get_symbol_name(self, target_address):
+ if target_address | 0x80000000:
+ symbol_number = target_address & 0x7FFFFFFF
+ return self.symbol_list[symbol_number]['name']
+ else:
+ for symbol in self.symbol_list:
+ if symbol['offset'] == target_address:
+ return symbol['name']
+ else:
+ return 'SYMBOL_NOT_FOUND'
+
+ def get_string_data(self, target_address):
+ elf_address = target_address
+
+ with open(self.elf_path, 'rb') as elf_file:
+ elf_file.seek(elf_address)
+ contents = ''
+ find_begin_index = 0
+ while 1:
+ contents += elf_file.read(32)
+ string_end_index = contents.find('\x00', find_begin_index)
+ if string_end_index == -1:
+ find_begin_index = len(contents)
+ else:
+ contents = contents[:string_end_index+1]
+ break
+ return contents
+
+ def unpack_symbol_data(self, format_string, symbol_name):
+ return struct.unpack_from(format_string, self.get_symbol_data(symbol_name))
+
+ def unpack_data_struct_array(self, raw_data, struct_format_string, field_names):
+ struct_size = struct.calcsize(struct_format_string)
+ array_length = len(raw_data) / struct_size
+ array = []
+ #print len(raw_data), struct_size, struct_format_string, field_names
+
+ for index in xrange(array_length):
+ data = struct.unpack_from(struct_format_string, raw_data, struct_size * index)
+ entry = dict(zip(field_names, data))
+ array.append(entry)
+
+ return array
+
+ def unpack_symbol_data_struct_array(self, symbol_name, struct_format_string, field_names):
+ raw_data = self.get_symbol_data(symbol_name)
+ return self.unpack_data_struct_array(raw_data, struct_format_string, field_names)