diff --git a/Project.toml b/Project.toml index 65a0b13..7a22cac 100644 --- a/Project.toml +++ b/Project.toml @@ -7,7 +7,6 @@ version = "0.4.4" Reexport = "189a3867-3050-52da-a836-e630ba90ab69" StructIO = "53d494c1-5632-5724-8f4c-31dff12d585f" - [compat] Reexport = "0.2, 1.0" StructIO = "0.3" @@ -15,6 +14,7 @@ julia = "1.6" [extras] Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +Mmap = "a63ad114-7e13-5084-954f-fe012c677804" [targets] -test = ["Test"] +test = ["Test", "Mmap"] diff --git a/src/Abstract/Symbol.jl b/src/Abstract/Symbol.jl index eb51b87..68b03c4 100644 --- a/src/Abstract/Symbol.jl +++ b/src/Abstract/Symbol.jl @@ -10,7 +10,7 @@ export Symbols, # Export SymtabEntry API export SymtabEntry, - deref, symbol_name, symbol_value, isundef, isglobal, islocal, isweak + deref, symbol_name, symbol_value, isundef, isglobal, islocal, isweak, symbol_section, symbol_offset # Export SymbolRef API export SymbolRef, @@ -161,6 +161,19 @@ Return the value of the given symbol """ @mustimplement symbol_value(sym::SymtabEntry) +""" + symbol_section(sym::SymtabEntry) +Return the section that this symbol refers to +""" +@mustimplement symbol_section(sym::SymtabEntry) + +""" + symbol_offset(sym::SymtabEntry) +Return the offset into the file that this symbol refers to. +""" +@mustimplement symbol_offset(sym::SymtabEntry) + + """ isundef(sym::SymtabEntry) diff --git a/src/COFF/COFF.jl b/src/COFF/COFF.jl index 68221d9..ec1e2a9 100644 --- a/src/COFF/COFF.jl +++ b/src/COFF/COFF.jl @@ -17,7 +17,7 @@ import ObjectFile: DynamicLink, DynamicLinks, RPath, ObjectHandle, Section, Sect findfirst, deref, section_name, section_size, section_offset, section_address, section_number, segment_name, segment_offset, segment_file_size, segment_memory_size, segment_address, strtab_lookup, - symbol_name, symbol_value, isundef, isglobal, islocal, isweak, symbol_number + symbol_name, symbol_value, isundef, isglobal, islocal, isweak, symbol_number, symbol_section, symbol_offset # Load in imported C #define constants include("constants.jl") diff --git a/src/COFF/COFFSymbol.jl b/src/COFF/COFFSymbol.jl index e8aa028..2d7d938 100644 --- a/src/COFF/COFFSymbol.jl +++ b/src/COFF/COFFSymbol.jl @@ -80,7 +80,6 @@ function symbol_name(sym::COFFSymtabEntry) end symbol_value(sym::COFFSymtabEntry) = sym.Value -symbol_section(sym::COFFSymtabEntry) = sym.SectionNumber symbol_type(sym::COFFSymtabEntry) = sym.Type function isundef(sym::COFFSymtabEntry) sym.StorageClass in ( @@ -112,6 +111,7 @@ end deref(sym::COFFSymbolRef) = sym.entry Symbols(sym::COFFSymbolRef) = sym.syms symbol_number(sym::COFFSymbolRef) = sym.idx +symbol_section(sym::COFFSymbolRef) = Sections(handle(sym))[deref(sym).SectionNumber] @derefmethod symbol_type(sym::COFFSymbolRef) function symbol_name(sym::COFFSymbolRef) # COFF Symbols set the first four bytes of the name to zero to signify a @@ -127,6 +127,10 @@ function symbol_name(sym::COFFSymbolRef) return unsafe_string(name) end +function symbol_offset(sym::COFFSymbolRef) + # Return the offset into the file that this symbol refers to + return symbol_value(sym) + section_offset(symbol_section(sym)) +end # Symbol printing stuff """ @@ -161,7 +165,7 @@ function symbol_type_string(sym::COFFSymtabEntry) if isempty(type_string) string("Unknown Symbol Type (0x", string(sym.Type, base=16), ")") end - + return type_string end @derefmethod symbol_type_string(s::COFFSymbolRef) diff --git a/src/ELF/ELF.jl b/src/ELF/ELF.jl index 200998a..61f0979 100644 --- a/src/ELF/ELF.jl +++ b/src/ELF/ELF.jl @@ -17,7 +17,7 @@ import ObjectFile: DynamicLink, DynamicLinks, RPath, ObjectHandle, Section, Sect findfirst, deref, section_name, section_size, section_offset, section_address, section_number, segment_name, segment_offset, segment_file_size, segment_memory_size, segment_address, strtab_lookup, - symbol_name, symbol_value, isundef, isglobal, islocal, isweak, symbol_number + symbol_name, symbol_value, isundef, isglobal, islocal, isweak, symbol_number, symbol_section, symbol_offset # Load in imported C #define constants include("constants.jl") diff --git a/src/ELF/ELFSymbol.jl b/src/ELF/ELFSymbol.jl index 3922544..291c5ed 100644 --- a/src/ELF/ELFSymbol.jl +++ b/src/ELF/ELFSymbol.jl @@ -27,7 +27,7 @@ function Symbols(oh::H) where {H <: ELFHandle} if !isempty(dyn_sections) return ELFSymbols(first(dyn_sections)) end - + dyn_sections = findall(sections, ".dynsym") if !isempty(dyn_sections) return ELFSymbols(first(dyn_sections)) @@ -176,3 +176,10 @@ function symbol_value(sym::ELFSymbolRef) # Return our ill-gotten goods return value end + +function symbol_offset(sym::ELFSymbolRef) + addr = symbol_value(sym) + sect = symbol_section(sym) + virtual_offset = section_address(sect) - section_offset(sect) + return addr - virtual_offset +end diff --git a/src/MachO/MachO.jl b/src/MachO/MachO.jl index 92c9280..2ef277f 100644 --- a/src/MachO/MachO.jl +++ b/src/MachO/MachO.jl @@ -17,7 +17,7 @@ import ObjectFile: DynamicLink, DynamicLinks, RPath, ObjectHandle, Section, Sect findfirst, deref, section_name, section_size, section_offset, section_address, section_number, segment_name, segment_offset, segment_file_size, segment_memory_size, segment_address, strtab_lookup, - symbol_name, symbol_value, isundef, isglobal, islocal, isweak, symbol_number + symbol_name, symbol_value, isundef, isglobal, islocal, isweak, symbol_number, symbol_section, symbol_offset # Load in imported C #define constants include("constants.jl") diff --git a/src/MachO/MachOSymbol.jl b/src/MachO/MachOSymbol.jl index 0416798..123a5ca 100644 --- a/src/MachO/MachOSymbol.jl +++ b/src/MachO/MachOSymbol.jl @@ -25,7 +25,6 @@ end symbol_name(sym::MachOSymtabEntry) = string("strtab@", sym.n_strx) symbol_value(sym::MachOSymtabEntry) = sym.n_value symbol_type(sym::MachOSymtabEntry) = sym.n_type -symbol_section(sym::MachOSymtabEntry) = sym.n_sect symbol_description(sym::MachOSymtabEntry) = sym.n_desc function isglobal(sym::MachOSymtabEntry) @@ -39,7 +38,7 @@ function isweak(sym::MachOSymtabEntry) end function isundef(sym::MachOSymtabEntry) return (symbol_type(sym) == N_UNDF) || - (isglobal(sym) && symbol_section(sym) == NO_SECT) + (isglobal(sym) && sym.n_sect == NO_SECT) end @@ -115,6 +114,23 @@ end deref(sym::MachOSymbolRef) = sym.entry Symbols(sym::MachOSymbolRef) = sym.syms symbol_number(sym::MachOSymbolRef) = sym.idx + +function symbol_section(sym::MachOSymbolRef) + # MachO uses 0 to indicate no section, so we use NO_SECT + if deref(sym).n_sect == 0 + return NO_SECT + end + return Sections(handle(sym))[deref(sym).n_sect] +end + function symbol_name(sym::MachOSymbolRef) return strtab_lookup(StrTab(Symbols(sym)), sym.entry.n_strx) -end \ No newline at end of file +end + +function symbol_offset(sym::MachOSymbolRef) + addr = symbol_value(sym) + sect = symbol_section(sym) + virtual_offset = section_address(sect) - section_offset(sect) + return addr - virtual_offset +end + diff --git a/test/libjulias/libjulia.1.10.10.dylib b/test/libjulias/libjulia.1.10.10.dylib new file mode 100755 index 0000000..63485a0 Binary files /dev/null and b/test/libjulias/libjulia.1.10.10.dylib differ diff --git a/test/libjulias/libjulia.dll b/test/libjulias/libjulia.dll new file mode 100644 index 0000000..8e89cb9 Binary files /dev/null and b/test/libjulias/libjulia.dll differ diff --git a/test/libjulias/libjulia.so b/test/libjulias/libjulia.so new file mode 100755 index 0000000..b2bf727 Binary files /dev/null and b/test/libjulias/libjulia.so differ diff --git a/test/runtests.jl b/test/runtests.jl index 447bcc7..7f22b2d 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -278,3 +278,23 @@ end @test "KERNEL32.dll" in dynamic_links @test "libstdc++-6.dll" in dynamic_links end + +using Mmap +@testset "Finding dep_libs" begin + function find_dep_libs(file) + obj = only(readmeta(open(file, "r"))) + syms = collect(Symbols(obj)) + syms_names = symbol_name.(syms) + sym = syms[findfirst(syms_names .== mangle_symbol_name(obj, "dep_libs"))] + offset = symbol_offset(sym) + filem = Mmap.mmap(file) + data = String(filem[offset: (offset + 255)]) + @test contains(data, "libjulia-internal") + @test contains(data, "libjulia-codegen") + @test contains(data, "libopenlibm") + end + for file in readdir("./libjulias") + find_dep_libs(joinpath("./libjulias", file)) + end +end +