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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
|
--!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 binutils.lua
--
-- define module
local binutils = binutils or {}
-- load modules
local os = require("base/os")
-- save original interfaces
binutils._bin2c = binutils._bin2c or binutils.bin2c
binutils._bin2coff = binutils._bin2coff or binutils.bin2coff
binutils._bin2macho = binutils._bin2macho or binutils.bin2macho
binutils._bin2elf = binutils._bin2elf or binutils.bin2elf
binutils._readsyms = binutils._readsyms or binutils.readsyms
binutils._deplibs = binutils._deplibs or binutils.deplibs
binutils._rpath_list = binutils._rpath_list or binutils.rpath_list
binutils._rpath_clean = binutils._rpath_clean or binutils.rpath_clean
binutils._extractlib = binutils._extractlib or binutils.extractlib
binutils._format = binutils._format or binutils.format
-- generate c/c++ header with binary data from the binary file
--
-- @param binaryfile the input binary file path
-- @param outputfile the output header file path
-- @param opt the options, e.g. {nozeroend = true}
--
function binutils.bin2c(binaryfile, outputfile, opt)
opt = opt or {}
if binutils._bin2c then
return binutils._bin2c(binaryfile, outputfile, opt.linewidth or 32, opt.nozeroend or false)
else
-- fallback to old implementation if C implementation not available
return nil, "C implementation not available"
end
end
-- generate object file from the binary file
-- @param binaryfile the binary file path
-- @param outputfile the output object file path
-- @param opt the options
-- - format: the object file format (coff, elf, macho), required
-- - symbol_prefix: the symbol prefix (default: _binary_)
-- - arch: the target architecture (default: x86_64)
-- - plat: the target platform (default: macosx, only for macho)
-- - basename: the base name for symbols
-- - target_minver: the target minimum version (only for macho)
-- - xcode_sdkver: the Xcode SDK version (only for macho)
-- - zeroend: append null terminator (default: false)
function binutils.bin2obj(binaryfile, outputfile, opt)
opt = opt or {}
local format = opt.format
if not format then
-- auto-detect format based on host platform
local host = os.host()
if host == "windows" or host == "mingw" or host == "msys" or host == "cygwin" then
format = "coff"
elseif host == "macosx" or host == "iphoneos" or host == "watchos" or host == "appletvos" then
format = "macho"
else
format = "elf"
end
end
format = format:lower()
if format == "coff" then
if not binutils._bin2coff then
return nil, "binutils._bin2coff not available (C implementation not compiled)"
end
return binutils._bin2coff(binaryfile, outputfile, opt.symbol_prefix or "_binary_", opt.arch or "x86_64", opt.basename, opt.zeroend or false)
elseif format == "macho" then
if not binutils._bin2macho then
return nil, "binutils._bin2macho not available (C implementation not compiled)"
end
return binutils._bin2macho(binaryfile, outputfile, opt.symbol_prefix or "_binary_", opt.plat or "macosx", opt.arch or "x86_64", opt.basename, opt.target_minver, opt.xcode_sdkver, opt.zeroend or false)
elseif format == "elf" then
if not binutils._bin2elf then
return nil, "binutils._bin2elf not available (C implementation not compiled)"
end
return binutils._bin2elf(binaryfile, outputfile, opt.symbol_prefix or "_binary_", opt.arch or "x86_64", opt.basename, opt.zeroend or false)
else
return nil, string.format("unsupported format '%s' (supported: coff, elf, macho)", format)
end
end
-- get binary file format (auto-detect: coff, elf, macho, ar, pe, unknown)
--
-- @param binaryfile the binary file path
-- @return the format string
--
function binutils.format(binaryfile)
if binutils._format then
return binutils._format(binaryfile)
else
return nil, "C implementation not available"
end
end
-- read symbols from object file (auto-detect: COFF, ELF, or Mach-O)
--
-- @param binaryfile the binary file path
-- @return the symbols table, or nil and error info
--
function binutils.readsyms(binaryfile)
if binutils._readsyms then
return binutils._readsyms(binaryfile)
else
return nil, "C implementation not available"
end
end
-- get dependent libraries from binary file (auto-detect: COFF, ELF, or Mach-O)
--
-- @param binaryfile the binary file path
-- @return the dependent libraries table, or nil and error info
--
function binutils.deplibs(binaryfile)
if binutils._deplibs then
return binutils._deplibs(binaryfile)
else
return nil, "C implementation not available"
end
end
-- get rpath list from binary file (auto-detect: ELF or Mach-O)
--
-- @param binaryfile the binary file path
-- @return the rpath list table, or nil and error info
--
function binutils.rpath_list(binaryfile)
if binutils._rpath_list then
return binutils._rpath_list(binaryfile)
else
return nil, "internal rpath_list not supported!"
end
end
-- insert rpath to binary file (auto-detect format: ELF or Mach-O)
-- clean rpaths from binary file (auto-detect: ELF or Mach-O)
--
-- @param binaryfile the binary file path
-- @return true on success, or false and error info
--
function binutils.rpath_clean(binaryfile)
if binutils._rpath_clean then
return binutils._rpath_clean(binaryfile)
else
return false, "internal rpath_clean not supported!"
end
end
-- extract static library to directory
-- Supports AR format (.a) and MSVC lib format (.lib)
-- @param libraryfile the static library file path (.a or .lib)
-- @param outputdir the output directory to extract object files
-- @param opt the options (optional)
-- - plain: extract all object files to the same directory (default: true)
-- @return true on success, false and error message on failure
function binutils.extractlib(libraryfile, outputdir, opt)
if binutils._extractlib then
local ok, errors = binutils._extractlib(libraryfile, outputdir, opt and opt.plain)
if ok then
return true
else
return false, errors or "unknown error"
end
else
return false, "C implementation not available"
end
end
-- return module
return binutils
|