Skip to content

Commit

Permalink
Resolve #968
Browse files Browse the repository at this point in the history
  • Loading branch information
romainthomas committed Oct 7, 2023
1 parent d5dc7fd commit d1c16a2
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 18 deletions.
5 changes: 3 additions & 2 deletions include/LIEF/ELF/Symbol.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ class LIEF_API Symbol : public LIEF::Symbol {
friend class Binary;

public:
Symbol(const details::Elf32_Sym& header);
Symbol(const details::Elf64_Sym& header);
Symbol(const details::Elf32_Sym& header, ARCH arch);
Symbol(const details::Elf64_Sym& header, ARCH arch);
Symbol(std::string name,
ELF_SYMBOL_TYPES type = ELF_SYMBOL_TYPES::STT_NOTYPE,
SYMBOL_BINDINGS binding = SYMBOL_BINDINGS::STB_WEAK,
Expand Down Expand Up @@ -173,6 +173,7 @@ class LIEF_API Symbol : public LIEF::Symbol {
uint16_t shndx_ = 0;
Section* section_ = nullptr;
SymbolVersion* symbol_version_ = nullptr;
ARCH arch_ = ARCH::EM_NONE;
};
}
}
Expand Down
10 changes: 7 additions & 3 deletions src/ELF/Parser.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -992,8 +992,11 @@ ok_error_t Parser::parse_static_symbols(uint64_t offset, uint32_t nb_symbols,
if (!raw_sym) {
break;
}
auto symbol = std::make_unique<Symbol>(std::move(*raw_sym));
auto symbol_name = stream_->peek_string_at(string_section.file_offset() + raw_sym->st_name);
auto symbol = std::make_unique<Symbol>(std::move(*raw_sym),
binary_->header().machine_type());

const auto name_offset = string_section.file_offset() + raw_sym->st_name;
auto symbol_name = stream_->peek_string_at(name_offset);
if (symbol_name) {
symbol->name(std::move(*symbol_name));
} else {
Expand Down Expand Up @@ -1044,7 +1047,8 @@ ok_error_t Parser::parse_dynamic_symbols(uint64_t offset) {
LIEF_DEBUG("Break on symbol #{:d}", i);
break;
}
auto symbol = std::make_unique<Symbol>(std::move(*symbol_header));
auto symbol = std::make_unique<Symbol>(std::move(*symbol_header),
binary_->header().machine_type());

if (symbol_header->st_name > 0) {
auto name = stream_->peek_string_at(string_offset + symbol_header->st_name);
Expand Down
30 changes: 17 additions & 13 deletions src/ELF/Symbol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ Symbol::Symbol(const Symbol& other) : LIEF::Symbol{other},
type_{other.type_},
binding_{other.binding_},
other_{other.other_},
shndx_{other.shndx_}
shndx_{other.shndx_},
arch_{other.arch_}
{}


Expand All @@ -57,23 +58,26 @@ void Symbol::swap(Symbol& other) {
std::swap(shndx_, other.shndx_);
std::swap(section_, other.section_);
std::swap(symbol_version_, other.symbol_version_);
std::swap(arch_, other.arch_);
}

Symbol::Symbol(const details::Elf32_Sym& header) :
Symbol::Symbol(const details::Elf32_Sym& header, ARCH arch) :
type_{static_cast<ELF_SYMBOL_TYPES>(header.st_info & 0x0f)},
binding_{static_cast<SYMBOL_BINDINGS>(header.st_info >> 4)},
other_{header.st_other},
shndx_{header.st_shndx}
shndx_{header.st_shndx},
arch_{arch}
{
value_ = header.st_value;
size_ = header.st_size;
}

Symbol::Symbol(const details::Elf64_Sym& header) :
Symbol::Symbol(const details::Elf64_Sym& header, ARCH arch) :
type_{static_cast<ELF_SYMBOL_TYPES>(header.st_info & 0x0f)},
binding_{static_cast<SYMBOL_BINDINGS>(header.st_info >> 4)},
other_{header.st_other},
shndx_{header.st_shndx}
shndx_{header.st_shndx},
arch_{arch}
{
value_ = header.st_value;
size_ = header.st_size;
Expand Down Expand Up @@ -214,8 +218,14 @@ bool Symbol::is_imported() const {
// An import must not be defined in a section
bool is_imported = shndx() == static_cast<uint16_t>(SYMBOL_SECTION_INDEX::SHN_UNDEF);

// An import must not have an address
is_imported = is_imported && value() == 0;
const bool is_mips = arch_ == ARCH::EM_MIPS || arch_ == ARCH::EM_MIPS_X ||
arch_ == ARCH::EM_MIPS_RS3_LE;
const bool is_ppc = arch_ == ARCH::EM_PPC || arch_ == ARCH::EM_PPC64;

// An import must not have an address (except for some architectures like Mips/PPC)
if (!is_mips && !is_ppc) {
is_imported = is_imported && value() == 0;
}

// its name must not be empty
is_imported = is_imported && !name().empty();
Expand All @@ -239,16 +249,10 @@ void Symbol::set_imported(bool flag) {
}
}



void Symbol::accept(Visitor& visitor) const {
visitor.visit(*this);
}





std::ostream& operator<<(std::ostream& os, const Symbol& entry) {

std::string name = entry.demangled_name();
Expand Down
4 changes: 4 additions & 0 deletions tests/elf/test_issues.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,7 @@ def test_issue_863(tmp_path: Path):
new = lief.parse(out.as_posix())
assert new.sysv_hash.nchain == 6

def test_pr_968():
elf = lief.ELF.parse(get_sample('ELF/echo.mips_r3000.bin'))
sym: lief.ELF.Symbol = elf.get_symbol("strstr")
assert sym.imported

0 comments on commit d1c16a2

Please sign in to comment.