diff options
Diffstat (limited to 'utils/hwpatcher/lib.lua')
-rw-r--r-- | utils/hwpatcher/lib.lua | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/utils/hwpatcher/lib.lua b/utils/hwpatcher/lib.lua new file mode 100644 index 0000000000..7a3e4a4115 --- /dev/null +++ b/utils/hwpatcher/lib.lua | |||
@@ -0,0 +1,107 @@ | |||
1 | --[[ | ||
2 | hwpatcher library | ||
3 | |||
4 | The C code provides the following functions. | ||
5 | |||
6 | At global level: | ||
7 | - quit() Quit the interactive mode | ||
8 | - exit() Same as quit() | ||
9 | |||
10 | In the hwp table: | ||
11 | - load_file(filename) Load a firmware and guess type | ||
12 | - load_elf_file(filename) Load a firmware as ELF | ||
13 | - load_sb_file(filename) Load a firmware as SB | ||
14 | - load_sb1_file(filename) Load a firmware as SB1 | ||
15 | - load_bin_file(filename) Load a firmware as binary | ||
16 | - save_file(obj, filename) Save a firmware to a file | ||
17 | - read(obj, addr, len) Read data from a firmware | ||
18 | - write(obj, addr, data) Write data to a firmware | ||
19 | - section_info(obj, sec) Return information about a section in a table (or nil) | ||
20 | - md5sum(filename) Compute the MD5 sum of a file | ||
21 | |||
22 | Data read/written from/to a firmware must must be an array of bytes. | ||
23 | The address must be a table of the following fields: | ||
24 | - address: contain the address | ||
25 | - section: optional section name | ||
26 | Data section information is a table with the following fields: | ||
27 | - address: first address if the section | ||
28 | - size: size of the section | ||
29 | We provide the following functions to help dealing with addresses: | ||
30 | - make_addr | ||
31 | |||
32 | ]]-- | ||
33 | |||
34 | function hwp.deepcopy(o, seen) | ||
35 | seen = seen or {} | ||
36 | if o == nil then return nil end | ||
37 | if seen[o] then return seen[o] end | ||
38 | |||
39 | local no | ||
40 | if type(o) == 'table' then | ||
41 | no = {} | ||
42 | seen[o] = no | ||
43 | |||
44 | for k, v in next, o, nil do | ||
45 | no[hwp.deepcopy(k, seen)] = hwp.deepcopy(v, seen) | ||
46 | end | ||
47 | setmetatable(no, hwp.deepcopy(getmetatable(o), seen)) | ||
48 | else -- number, string, boolean, etc | ||
49 | no = o | ||
50 | end | ||
51 | return no | ||
52 | end | ||
53 | |||
54 | function hwp.make_addr(addr, section) | ||
55 | local t = {addr = addr, section = section} | ||
56 | local addr_to_string = function(self) | ||
57 | if self.section == nil then | ||
58 | return string.format("%#x", self.addr) | ||
59 | else | ||
60 | return string.format("%#x@%s", self.addr, self.section) | ||
61 | end | ||
62 | end | ||
63 | setmetatable(t, {__tostring = addr_to_string}) | ||
64 | return t | ||
65 | end | ||
66 | |||
67 | function hwp.inc_addr(addr, amount) | ||
68 | return hwp.make_addr(addr.addr + amount, addr.section) | ||
69 | end | ||
70 | |||
71 | -- pack an array of bytes in a integer (little-endian) | ||
72 | function hwp.pack(arr) | ||
73 | local v = 0 | ||
74 | for i = #arr, 1, -1 do | ||
75 | v = bit32.bor(bit32.lshift(v, 8),bit32.band(arr[i], 0xff)) | ||
76 | end | ||
77 | return v | ||
78 | end | ||
79 | |||
80 | -- do the converse | ||
81 | function hwp.unpack(v, n) | ||
82 | local t = {} | ||
83 | for i = 1, n do | ||
84 | t[i] = bit32.band(v, 0xff) | ||
85 | v = bit32.rshift(v, 8) | ||
86 | end | ||
87 | return t | ||
88 | end | ||
89 | |||
90 | -- read a 32-bit value | ||
91 | function hwp.read32(obj, addr) | ||
92 | return hwp.pack(hwp.read(obj, addr, 4)) | ||
93 | end | ||
94 | |||
95 | -- write a 32-bit value | ||
96 | function hwp.write32(obj, addr, v) | ||
97 | return hwp.write(obj, addr, hwp.unpack(v, 4)) | ||
98 | end | ||
99 | |||
100 | -- convert a MD5 hash to a string | ||
101 | function hwp.md5str(md5) | ||
102 | local s = "" | ||
103 | for i = 1, #md5 do | ||
104 | s = s .. string.format("%02x", md5[i]) | ||
105 | end | ||
106 | return s | ||
107 | end | ||