summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2025-12-09 22:41:52 +0800
committerruki <[email protected]>2025-12-09 22:41:52 +0800
commit9bcc8fdd4eecb665ea98a38e3fa03b889663922a (patch)
treedc44938688fb32c59d87031b8bf1cce5fdfd4c75
parent4840a395c687cb90c0821f7ce9b075eaa9160465 (diff)
improve readsyms
-rw-r--r--xmake/modules/utils/binary/readsyms.lua25
-rw-r--r--xmake/rules/utils/symbols/export_all/export_all.lua56
2 files changed, 52 insertions, 29 deletions
diff --git a/xmake/modules/utils/binary/readsyms.lua b/xmake/modules/utils/binary/readsyms.lua
index 6aaa414d0..e5954e92a 100644
--- a/xmake/modules/utils/binary/readsyms.lua
+++ b/xmake/modules/utils/binary/readsyms.lua
@@ -81,11 +81,28 @@ function dump(binaryfile)
end
end
--- read symbols from object file (auto-detect format: ELF, COFF, Mach-O)
+-- read symbols from object file(s) (auto-detect format: ELF, COFF, Mach-O)
--
--- @param binaryfile the object file path (required)
--- @return the symbols table
+-- @param binaryfile the object file path or table of object files (required)
+-- @return the symbols table (all symbols from all files if table is provided)
function main(binaryfile)
- return _get_symbols(binaryfile)
+ assert(binaryfile, "usage: xmake l utils.binary.readsyms <binaryfile> or readsyms(binaryfiles)")
+
+ local all_symbols = {}
+ if type(binaryfile) == "string" then
+ -- single file
+ return _get_symbols(binaryfile)
+ else
+ -- multiple files
+ for _, objectfile in ipairs(binaryfile) do
+ local symbols = _get_symbols(objectfile)
+ if symbols then
+ for _, sym in ipairs(symbols) do
+ table.insert(all_symbols, sym)
+ end
+ end
+ end
+ return all_symbols
+ end
end
diff --git a/xmake/rules/utils/symbols/export_all/export_all.lua b/xmake/rules/utils/symbols/export_all/export_all.lua
index 8c93fc555..6e077aaf3 100644
--- a/xmake/rules/utils/symbols/export_all/export_all.lua
+++ b/xmake/rules/utils/symbols/export_all/export_all.lua
@@ -23,9 +23,9 @@ import("lib.detect.find_tool")
import("core.tool.toolchain")
import("core.base.option")
import("core.base.hashset")
-import("core.base.binutils")
import("core.project.depend")
import("utils.progress")
+import("utils.binary.readsyms")
-- It is not very accurate because some rules automatically
-- generate objectfiles and do not save the corresponding sourcefiles.
@@ -157,33 +157,39 @@ function _get_allsymbols_by_readsyms(target, opt)
if export_filter then
_get_sourcefiles_map(target, sourcefiles_map)
end
- for _, objectfile in ipairs(target:objectfiles()) do
- local symbols, errors = binutils.readsyms(objectfile)
- if symbols then
- local sourcefile = sourcefiles_map[objectfile]
- for _, sym in ipairs(symbols) do
- if sym.name and sym.type then
- -- only export function symbols (T/t) for DLL exports
- -- skip data (D/d), bss (B/b), other sections (S/s), and undefined (U) symbols
- if sym.type == "T" or sym.type == "t" then
- local symbol = sym.name
- -- we need ignore DllMain, https://github.com/xmake-io/xmake/issues/3992
- if target:is_arch("x86") and symbol:startswith("_") and not symbol:startswith("__") and not symbol:startswith("_DllMain@") then
- symbol = symbol:sub(2)
- end
- if export_filter then
- if export_filter(symbol, {objectfile = objectfile, sourcefile = sourcefile}) then
- allsymbols:insert(symbol)
+ local objectfiles = target:objectfiles()
+ local symbols = readsyms(objectfiles)
+ if symbols then
+ for _, sym in ipairs(symbols) do
+ if sym.name and sym.type then
+ -- only export function symbols (T/t) for DLL exports
+ -- skip data (D/d), bss (B/b), other sections (S/s), and undefined (U) symbols
+ if sym.type == "T" or sym.type == "t" then
+ local symbol = sym.name
+ -- we need ignore DllMain, https://github.com/xmake-io/xmake/issues/3992
+ if target:is_arch("x86") and symbol:startswith("_") and not symbol:startswith("__") and not symbol:startswith("_DllMain@") then
+ symbol = symbol:sub(2)
+ end
+ if export_filter then
+ -- find sourcefile for this symbol (approximate match)
+ local sourcefile = nil
+ for objfile, srcfile in pairs(sourcefiles_map) do
+ if objfile:find(path.basename(symbol), 1, true) then
+ sourcefile = srcfile
+ break
end
- elseif not symbol:startswith("__") then
- if export_classes or not symbol:startswith("?") then
- if export_classes then
- if not symbol:startswith("??_G") and not symbol:startswith("??_E") then
- allsymbols:insert(symbol)
- end
- else
+ end
+ if export_filter(symbol, {sourcefile = sourcefile}) then
+ allsymbols:insert(symbol)
+ end
+ elseif not symbol:startswith("__") then
+ if export_classes or not symbol:startswith("?") then
+ if export_classes then
+ if not symbol:startswith("??_G") and not symbol:startswith("??_E") then
allsymbols:insert(symbol)
end
+ else
+ allsymbols:insert(symbol)
end
end
end