blob: 3f39188d4139d8d619f1adf34708e6514ed3d118 [file] [log] [blame]
rjw6c1fd8f2022-11-30 14:33:01 +08001#!/usr/bin/perl
2#
3# Copyright Statement:
4# --------------------
5# This software is protected by Copyright and the information contained
6# herein is confidential. The software may not be copied and the information
7# contained herein may not be used or disclosed except with the written
8# permission of MediaTek Inc. (C) 2018
9#
10# BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
11# THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
12# RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
13# AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
14# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
15# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
16# NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
17# SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
18# SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
19# THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
20# NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
21# SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
22#
23# BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
24# LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
25# AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
26# OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
27# MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
28#
29# THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
30# WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
31# LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
32# RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
33# THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
34#
35#*****************************************************************************
36#*
37#* Filename:
38#* ---------
39#* update_dump_table.pl
40#*
41#* Project:
42#* --------
43#*
44#*
45#* Description:
46#* ------------
47#* This script is to update the value of dump table.
48#*
49#* Author:
50#* -------
51#* Yao Liu (mtk15073)
52#*
53#****************************************************************************/
54
55use strict;
56use warnings;
57BEGIN { push @INC, './tools/', './tools/MemoryUtility/' }
58use FileInfoParser;
59use constant {
60 Section_Size =>0,
61 Section_VMA =>1,
62 Section_LMA =>2,
63 Section_Fileoffset =>3,
64 Symbol_VMA =>0,
65 Symbol_Section =>1,
66 Symbol_Size =>2,
67};
68#****************************************************************************
69# Input
70#****************************************************************************
71my $debug = 1;
72&msg_handler("Fatal", "Wrong Parameters, Usage: update_drdi_table.pl <ELF_FILE> <SYM_FILE> <DUMP_FILE> <MAKEFILE>", __LINE__) if($#ARGV != 3);
73
74my ($elf_file, $sym_file, $dump_file, $makefile) = @ARGV;
75
76my $templog = "Input: ELF is $elf_file\nSYM is $sym_file\nDUMP_TABLE is $dump_file\nmakefile is $makefile\n\n";
77&msg_handler("Log", $templog, __LINE__);
78
79my %g_MAKEFILE_OPTIONS;
80&msg_handler("Fatal", "Failed to parse makefile!!!\n", __LINE__) if(1!=&FileInfo::Parse_MAKEFILE($makefile, \%g_MAKEFILE_OPTIONS));
81&msg_handler("Log", "This load do not support DHL!!!\n", __LINE__) if(FileInfo::is("DHL_SUPPORT", "FALSE"));
82exit 0 if(FileInfo::is("DHL_SUPPORT", "FALSE"));
83
84my @symbol_array = qw/dhl_dump_profile/;
85
86my %sym_file_hash;
87map{ $sym_file_hash{'symbol_info'}->{$_} = 0 } (@symbol_array);
88&parse_sym_file();
89
90my @CRC32_Table;
91&Init_CRC32_Table();
92
93my $init = 0x1A424650;
94my $constant = 1; #If the value of $init is not 0xFFFFFFFF, please set $constant to 1.
95my $update_content = &get_table_info();
96
97&dump_update_elf();
98
99exit 0;
100
101sub parse_sym_file
102{
103 my ($bBegin, $sum_hit_sym) = (undef, 0);
104 open SYM, "< $sym_file" or &msg_handler("Fatal", "fail to open $sym_file", __LINE__);
105 while(my $line = <SYM>) {
106 $bBegin = 1 if($line =~ /^Sections:$/);
107 $bBegin = 2 if($line =~ /^SYMBOL TABLE:$/);
108 next unless(defined $bBegin);
109
110 #Idx Name Size VMA LMA File off Algn
111 # 0 ROM_GFH 0000084c 00000000 00000000 00000fd4 2**2
112 if($bBegin == 1 and $line =~ /\s*(\d+)\s+(\S+)\s+(\w+)\s+(\w+)\s+(\w+)\s+(\w+)\s+(\S+)/) {
113 my $section_name = $2;
114 $sym_file_hash{'section_info'}->{$section_name} = [$3, $4, $5, $6];
115 }
116 #91437ed0 g O ROM 00000180 DRDI_RCUCS_Array
117 elsif($bBegin == 2 and $line =~ /^([0-9a-fA-F]{8})\s+g\s+O\s+(\S+)\s+(\S+)\s+(?:\S+\s+)?(\S+)$/) {
118 my $symbol_name = $4;
119 next unless(exists $sym_file_hash{'symbol_info'}->{$symbol_name});
120 $sym_file_hash{'symbol_info'}->{$symbol_name} = [$1, $2, hex($3)];
121 &msg_handler("Log", "[Symbol]:$symbol_name [VMA]:0x$1 [Section]:$2 [Size]:0x$3\n", __LINE__) if($debug);
122 last if(($sum_hit_sym ++) == $#symbol_array);
123 }
124 }
125 close SYM;
126 map {&msg_handler("Fatal", "can't find symbol: $_!!!", __LINE__) if ($sym_file_hash{'symbol_info'}->{$_} == 0)} (@symbol_array);
127}
128
129 sub get_table_info
130{
131 my @temp = stat($dump_file);
132 #Check total size
133 &msg_handler("Fatal", "The sie of $dump_file is biffer than symbol size!!!\n", __LINE__) if($temp[7] > $sym_file_hash{'symbol_info'}->{"dhl_dump_profile"}->[Symbol_Size]);
134
135 my $header = unpack("V", read_memory_from_file($dump_file, 0, 4,__LINE__));
136 my $table_value = read_memory_from_file($dump_file, 0, ($temp[7] - 4),__LINE__);
137 my $check_sum = unpack("V", read_memory_from_file($dump_file, ($temp[7] - 4), 4,__LINE__));
138 my $content = read_memory_from_file($dump_file, 0, $temp[7],__LINE__);
139
140 #Check header
141 &msg_handler("Fatal", "The magic pattern mismatch!!!\n", __LINE__) if($header != 0x1A424650);
142 #Check CRC32 checksum
143 my $check_value = CRC32_CheckSum($table_value);
144 &msg_handler("Log", "[File Size]:$temp[7] [Old CHecksum]:$check_sum [New Checksum]:$check_value\n", __LINE__) if($debug);
145
146 &msg_handler("Fatal", "The checksum mismatch!!!\n", __LINE__) if($check_value != $check_sum);
147 return $content;
148}
149
150sub dump_update_elf
151{
152 open (ELF_FILE, "+< $elf_file") or &msg_handler("Fatal", "Open $elf_file file failed!!!\n", __LINE__);
153 binmode ELF_FILE;
154 foreach my $symbol (@symbol_array) {
155 if($sym_file_hash{'symbol_info'}->{$symbol} == 0) {
156 &msg_handler("Fatal", "can't find symbol: $symbol", __LINE__);
157 next;
158 }
159 my $sym_region = $sym_file_hash{'symbol_info'}->{$symbol}->[Symbol_Section];
160 my $offset = (hex($sym_file_hash{'symbol_info'}->{$symbol}->[Symbol_VMA]) - hex($sym_file_hash{'section_info'}->{$sym_region}->[Section_VMA])) +
161 hex($sym_file_hash{'section_info'}->{$sym_region}->[Section_Fileoffset]);
162 &msg_handler("Log", "The addr of symbol in ELF is $offset.\n", __LINE__);
163
164 seek ELF_FILE, $offset, 0;
165 print ELF_FILE $update_content;
166 }
167 close ELF_FILE;
168 &msg_handler("Log", "\n\nUpdate Elf succeed ^O^", __LINE__);
169}
170
171sub read_memory_from_file
172{
173 &msg_handler("Fatal", "[Error]: argument of $0 is insufficient\n", __LINE__) if(@_ != 4);
174 my ($file,$off,$len,$file_line_no) = @_;
175
176 my $content;
177 open(FH, $file) or &msg_handler("Fatal", "Fail to open $file: $!\n", __LINE__);
178 binmode FH;
179 &msg_handler("Fatal", "Can not seek to $off\n", __LINE__) if not seek FH, $off, 0;
180 &msg_handler("Fatal", "At line $file_line_no! Can't read offset $off, length $len from file $file\n", __LINE__) if read(FH, $content, $len) != $len;
181 close FH;
182 return $content;
183}
184
185sub Init_CRC32_Table
186{
187 foreach my $index (0..255){
188 my $crc = $index;
189 foreach (0..7){
190 $crc = ($crc >> 1) ^ ($crc & 1 && 0xEDB88320);
191 }
192 my $value = $crc & 2 ** 32 - 1;
193 push @CRC32_Table, $value;
194 }
195}
196
197sub CRC32_CheckSum
198{
199 my ($data) = @_;
200 $init ^= 0xFFFFFFFF if ($constant);
201 my $check_sum = $init;
202 my $len = length $data;
203 foreach my $pos (0..$len-1){
204 my $temp = ($check_sum ^ ord(substr($data, $pos, 1))) & 0xFF;
205 $check_sum = ($check_sum >> 8) ^ $CRC32_Table[$temp];
206 }
207 $check_sum ^= 0xFFFFFFFF;
208 return ($check_sum & 0xFFFFFFFF);
209}
210
211sub msg_handler
212{
213 my ($type, $msg, $line_no) = (@_);
214 my $prompt_prefix;
215 if($type eq "Log") {
216 print $msg . "\n";
217 }
218 elsif($type eq "Warning") {
219 $prompt_prefix = ">> Warning : ";
220 print "\n" . $prompt_prefix . "[at line $line_no] " . $msg . "\n";
221 }
222 elsif($type eq "Fatal") {
223 $prompt_prefix = ">> Fatal : ";
224 die $prompt_prefix . "[at line $line_no] " . "$msg" . "\n";
225 }
226}
227
228