Merge commit 'cc09f10e84d5' into kernel
[kernel/swap-modules.git] / driver / patchko.sh
1 #!/bin/sh
2 opt=$1
3 patch_file=$2
4 output_file=$3
5 data_file=$4
6
7 objdump=$3
8 readelf=$4
9
10 howto()
11 {
12     echo " $0 -r <patchingfile.ko> <readelf> <objdump>"
13     echo " $0 -g <patchingfile.ko> <readelf> <objdump>"
14     echo " $0 -p <patchingfile.ko> <outputfile.ko> <patchdata>"
15 }
16
17 DEBUG_OFF=1
18
19 debug(){
20     if [ $DEBUG_OFF -eq 0 ];then
21        echo "patchko.sh) $1"
22     fi
23 }
24
25 debugmk(){
26     echo "patchko.sh) $1"
27 }
28
29 error(){
30     debugmk "[Err]$1"
31 }
32
33 #toolchain=~/Work/tools/u1_slp/toolchai
34 #cross=${toolchain}/bin/arm-none-linux-gnueabi-
35 #cross=arm-none-linux-gnueabi-
36
37 sect_name="modinfo"
38 varname="vermagic"
39 debug "patchfile <$patch_file>"
40
41 if [ -f "$patch_file" ]; then
42
43     if [ "$opt" = "-p" ];then
44     #set version (use only on target)
45         debug "Set version (patching) to <$patch_file>"
46         if [ -f "$data_file" ];then
47             cp -f "${patch_file}" "${output_file}"
48
49             #get patching adderes
50             pos=$((`cat $patch_file.addr | awk '{print \$1}'`))
51             abs_len=$((`cat $patch_file.addr | awk '{print \$2}'`))
52
53             key_before=`dd if="$patch_file" bs=1 skip=${pos}c count=${abs_len}c 2>/dev/null`
54             debug "key_before<$key_before>"
55             key_before_tail=${key_before#*\ }
56             debug "key_before_tail<$key_before_tail>"
57             echo -ne "`cat $data_file` $key_before_tail\000">$data_file
58
59             key_len="`cat $data_file`"
60             key_len=$((${#key_len}+1))
61
62             debug "POS>$pos<"
63             debug "OLDLEN>$abs_len<"
64             debug "NEWLEN>$key_len<"
65             debug "PATCH_TO>`cat $data_file`<"
66
67             debug "key_len=$key_len"
68             if [ $key_len -le ${abs_len} ];then
69                 debug "before=<$key_before>"
70                 res=`dd if="${data_file}" of="${output_file}" bs=1 seek=${pos} skip=0c count=${key_len}c conv=notrunc 2>/dev/null`
71
72                 res=`dd if="$output_file" bs=1 skip=${pos}c count=${abs_len}c 2>/dev/null`
73                 debug "patched=<$res>"
74             else
75                 error "Error on patching <${patch_file}>:data file <$data_file> NEW KEY TOO LONG"
76                 error "CHECK YOUR KERNEL USED ON COMPILE SWAP IF YOU READ IT"
77                 exit 254
78             fi
79         else
80             error "Error on patching <${patch_file}>:data file <$data_file> not found"
81             exit 255
82         fi
83     else
84     #if[ "$opt" != "-p" ];then
85         debug "+not p"
86
87         $readelf -v
88         if [ $? -ne 0 ];then
89             error "readelf not found on path <$readelf>"
90             exit 2
91         fi
92         $objdump -v
93         if [ $? -ne 0 ];then
94             error "objdump not found on path <$objdump>"
95             exit 1
96         fi
97
98         file_size=$((`ls -la "$patch_file" | awk '{print \$5}'`))
99         debugmk "file_size=$file_size"
100
101         section=`$readelf -e $patch_file | grep ${sect_name}`
102         section=${section##*${sect_name}}
103         debugmk "section=$section"
104
105         addr=$((0x`echo $section | awk '{print $2}'`))
106         offs=$((0x`echo $section | awk '{print $3}'`))
107         size=$((0x`echo $section | awk '{print $4}'`))
108         debugmk $addr:$offs:$size
109
110         abs_len=$((0x`$objdump -t -j .${sect_name} "$patch_file" | grep _${varname} | awk '{print $5}'`))
111         abs_len=$(($abs_len-${#varname}-1))
112         sect_off=$((0x`$objdump -t -j .${sect_name} "$patch_file" | grep _${varname} | awk '{print $1}'`))
113         add_off=$((${#varname}+1))
114
115         abs_addr=$((${addr}+${offs}+${sect_off}+${add_off}))
116         debugmk "abs_addr=$abs_addr;"
117         debugmk "abs_len=$abs_len"
118         if [ "$opt" = "-r" ];then
119         #read version (for patch testing)
120             debugmk "Read version in <$patch_file>"
121             res=`dd if="$patch_file" bs=1 skip=${abs_addr}c count=${abs_len}c 2>/dev/null`
122             debugmk "ver<$res>"
123         elif [ "$opt" = "-g" ];then
124         #gen file version (use only on host)
125             debugmk "Generate version data for <$patch_file>"
126             #res=`dd if="$patch_file" of="$patch_file.addr" bs=1 skip=${abs_addr}c count=${abs_len}c`
127             if [ "$abs_addr" = "" ];then
128                 debugmk "ERROR cannot get absolute addres of module info line for patching"
129                 exit 253
130             elif [ "$abs_len" = "" ];then
131                 debugmk "ERROR cannot get length of module info line for patching"
132                 exit 252
133             else
134                 echo "$abs_addr $abs_len">"$patch_file.addr"
135             fi
136             debugmk "patch_addr=`cat $patch_file.addr`"
137         else
138             error "Wrong param <$opt>"
139         fi
140     fi
141 else
142     error "file for patchig not found <$patch_file>"
143     fi