From 341662991a028df33e0f47f16006225906f0b72e Mon Sep 17 00:00:00 2001 From: Tim Besard Date: Tue, 7 Jul 2026 14:48:14 -0400 Subject: [PATCH] Fix ELF symbol indexing for explicit sections ELFSymbols can be constructed directly from a section, such as .dynsym, but the generic Symbols.getindex path read entries from symtab_entry_offset(handle(syms)). For ELF that re-runs Symbols(oh) and usually selects .symtab, leaving explicit .dynsym objects with entries read from .symtab and names resolved through .dynstr. Add an ELF-specific getindex method that reads from Section(syms), preserving the symbol table selected by Symbols(section). This fixes explicit .dynsym indexing semantics and also avoids repeatedly rediscovering the object-level preferred table on large binaries. Cover the regression with bundled ELF fixtures by checking a known .dynsym entry. --- Project.toml | 2 +- src/ELF/ELFSymbol.jl | 11 +++++++++++ test/runtests.jl | 14 +++++++++++++- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/Project.toml b/Project.toml index a02bf28..02c36b7 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "ObjectFile" uuid = "d8793406-e978-5875-9003-1fc021f44a92" authors = ["Elliot Saba "] -version = "0.5.0" +version = "0.5.1" [deps] Reexport = "189a3867-3050-52da-a836-e630ba90ab69" diff --git a/src/ELF/ELFSymbol.jl b/src/ELF/ELFSymbol.jl index 291c5ed..b90eea1 100644 --- a/src/ELF/ELFSymbol.jl +++ b/src/ELF/ELFSymbol.jl @@ -50,6 +50,17 @@ function lastindex(syms::ELFSymbols{H}) where {H <: ELFHandle} return div(sect_size, sym_size) end +function Base.getindex(syms::ELFSymbols{H}, idx) where {H <: ELFHandle} + return getindex_ref( + syms, + section_offset(Section(syms)), + sizeof(symtab_entry_type(syms)), + symtab_entry_type(syms), + SymbolRef, + idx, + ) +end + # Add an StrTab() override to be able to load the symbol string table """ diff --git a/test/runtests.jl b/test/runtests.jl index ba88082..c5b1146 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -145,6 +145,19 @@ function test_libfoo_and_fooifier(fooifier_path, libfoo_path) @test isglobal(syms_exe[main_idx_exe]) @test isglobal(syms_lib[foo_idx_lib]) end + + if isa(oh_exe, ELFHandle) + sections = Sections(oh_exe) + dynsym = Symbols(only(findall(sections, ".dynsym"))) + symtab = Symbols(only(findall(sections, ".symtab"))) + + @test section_name(Section(dynsym)) == ".dynsym" + @test section_number(Section(dynsym)) != section_number(Section(symtab)) + @test section_number(Section(dynsym)) == section_number(Section(Symbols(dynsym[2]))) + @test symbol_number(dynsym[2]) == 2 + @test length(dynsym) <= length(symtab) + @test symbol_name(dynsym[2]) == "_ITM_deregisterTMCloneTable" + end end @testset "Printing" begin @@ -324,4 +337,3 @@ using Mmap find_dep_libs(joinpath("./libjulias", file)) end end -