1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
--!A cross-platform build utility based on Lua
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-- Copyright (C) 2015-present, Xmake Open Source Community.
--
-- @author ruki
-- @file bin2c.lua
--
-- imports
import("core.base.bytes")
import("core.base.option")
import("core.base.binutils")
local options = {
{'w', "linewidth", "kv", nil, "Set the line width"},
{nil, "nozeroend", "k", false, "Disable to patch zero terminating character"},
{'i', "binarypath", "kv", nil, "Set the binary file path."},
{'o', "outputpath", "kv", nil, "Set the output file path."}
}
function _do_dump(binarydata, outputfile, opt)
local i = 0
local n = 147
local p = 0
local e = binarydata:size()
local line = nil
local linewidth = opt.linewidth or 32
local first = true
while p < e do
line = ""
if p + linewidth <= e then
for i = 0, linewidth - 1 do
if first then
first = false
line = line .. " "
else
line = line .. ","
end
line = line .. string.format(" 0x%02X", binarydata[p + i + 1])
end
outputfile:print(line)
p = p + linewidth
elseif p < e then
local left = e - p
for i = 0, left - 1 do
if first then
first = false
line = line .. " "
else
line = line .. ","
end
line = line .. string.format(" 0x%02X", binarydata[p + i + 1])
end
outputfile:print(line)
p = p + left
else
break
end
end
end
function _do_bin2c(binarypath, outputpath, opt)
-- init source directory and options
opt = opt or {}
binarypath = path.absolute(binarypath)
outputpath = path.absolute(outputpath)
assert(os.isfile(binarypath), "%s not found!", binarypath)
-- trace
print("generating code data file from %s ..", binarypath)
-- optimize the default linewidth for reading large file
if not opt.linewidth then
local filesize = os.filesize(binarypath)
if filesize > 1024 * 1024 * 1024 then
opt.linewidth = 512
elseif filesize > 100 * 1024 * 1024 then
opt.linewidth = 256
elseif filesize > 10 * 1024 * 1024 then
opt.linewidth = 128
elseif filesize > 1024 * 1024 then
opt.linewidth = 64
else
opt.linewidth = 32
end
end
-- do dump
if binutils.bin2c then
binutils.bin2c(binarypath, outputpath, opt)
else
local binarydata = bytes(io.readfile(binarypath, {encoding = "binary"}))
local outputfile = io.open(outputpath, 'w')
if outputfile then
if not opt.nozeroend then
binarydata = binarydata .. bytes('\0')
end
_do_dump(binarydata, outputfile, opt)
outputfile:close()
end
end
-- trace
cprint("${bright}%s generated!", outputpath)
end
function main(...)
-- parse arguments
local argv = {...}
local opt = option.parse(argv, options, "Print c/c++ code files from the given binary file."
, ""
, "Usage: xmake l utils.binary.bin2c [options]")
-- do bin2c
_do_bin2c(opt.binarypath, opt.outputpath, opt)
end
|