[Feature][Modem]Update MTK MODEM V1.6 baseline version: MOLY.NR15.R3.MD700.IVT.MP1MR3.MP.V1.6

MTK modem version: MT2735_IVT_MOLY.NR15.R3.MD700.IVT.MP1MR3.MP.V1.6.tar.gz
RF  modem version: NA

Change-Id: I45a4c2752fa9d1a618beacd5d40737fb39ab64fb
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)