Skip to content

[lldb][ELF] Return address class map changes from symbol table parsing methods #91585

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 49 additions & 28 deletions lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2060,13 +2060,17 @@ static char FindArmAarch64MappingSymbol(const char *symbol_name) {
#define IS_MICROMIPS(ST_OTHER) (((ST_OTHER)&STO_MIPS_ISA) == STO_MICROMIPS)

// private
unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
SectionList *section_list,
const size_t num_symbols,
const DataExtractor &symtab_data,
const DataExtractor &strtab_data) {
std::pair<unsigned, ObjectFileELF::FileAddressToAddressClassMap>
ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
SectionList *section_list, const size_t num_symbols,
const DataExtractor &symtab_data,
const DataExtractor &strtab_data) {
ELFSymbol symbol;
lldb::offset_t offset = 0;
// The changes these symbols would make to the class map. We will also update
// m_address_class_map but need to tell the caller what changed because the
// caller may be another object file.
FileAddressToAddressClassMap address_class_map;

static ConstString text_section_name(".text");
static ConstString init_section_name(".init");
Expand Down Expand Up @@ -2213,18 +2217,18 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
switch (mapping_symbol) {
case 'a':
// $a[.<any>]* - marks an ARM instruction sequence
m_address_class_map[symbol.st_value] = AddressClass::eCode;
address_class_map[symbol.st_value] = AddressClass::eCode;
break;
case 'b':
case 't':
// $b[.<any>]* - marks a THUMB BL instruction sequence
// $t[.<any>]* - marks a THUMB instruction sequence
m_address_class_map[symbol.st_value] =
address_class_map[symbol.st_value] =
AddressClass::eCodeAlternateISA;
break;
case 'd':
// $d[.<any>]* - marks a data item sequence (e.g. lit pool)
m_address_class_map[symbol.st_value] = AddressClass::eData;
address_class_map[symbol.st_value] = AddressClass::eData;
break;
}
}
Expand All @@ -2238,11 +2242,11 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
switch (mapping_symbol) {
case 'x':
// $x[.<any>]* - marks an A64 instruction sequence
m_address_class_map[symbol.st_value] = AddressClass::eCode;
address_class_map[symbol.st_value] = AddressClass::eCode;
break;
case 'd':
// $d[.<any>]* - marks a data item sequence (e.g. lit pool)
m_address_class_map[symbol.st_value] = AddressClass::eData;
address_class_map[symbol.st_value] = AddressClass::eData;
break;
}
}
Expand All @@ -2260,11 +2264,11 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
// conjunction with symbol.st_value to produce the final
// symbol_value that we store in the symtab.
symbol_value_offset = -1;
m_address_class_map[symbol.st_value ^ 1] =
address_class_map[symbol.st_value ^ 1] =
AddressClass::eCodeAlternateISA;
} else {
// This address is ARM
m_address_class_map[symbol.st_value] = AddressClass::eCode;
address_class_map[symbol.st_value] = AddressClass::eCode;
}
}
}
Expand All @@ -2285,17 +2289,17 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
*/
if (arch.IsMIPS()) {
if (IS_MICROMIPS(symbol.st_other))
m_address_class_map[symbol.st_value] = AddressClass::eCodeAlternateISA;
address_class_map[symbol.st_value] = AddressClass::eCodeAlternateISA;
else if ((symbol.st_value & 1) && (symbol_type == eSymbolTypeCode)) {
symbol.st_value = symbol.st_value & (~1ull);
m_address_class_map[symbol.st_value] = AddressClass::eCodeAlternateISA;
address_class_map[symbol.st_value] = AddressClass::eCodeAlternateISA;
} else {
if (symbol_type == eSymbolTypeCode)
m_address_class_map[symbol.st_value] = AddressClass::eCode;
address_class_map[symbol.st_value] = AddressClass::eCode;
else if (symbol_type == eSymbolTypeData)
m_address_class_map[symbol.st_value] = AddressClass::eData;
address_class_map[symbol.st_value] = AddressClass::eData;
else
m_address_class_map[symbol.st_value] = AddressClass::eUnknown;
address_class_map[symbol.st_value] = AddressClass::eUnknown;
}
}
}
Expand Down Expand Up @@ -2392,24 +2396,33 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
dc_symbol.SetIsWeak(true);
symtab->AddSymbol(dc_symbol);
}
return i;

m_address_class_map.merge(address_class_map);
return {i, address_class_map};
}

unsigned ObjectFileELF::ParseSymbolTable(Symtab *symbol_table,
user_id_t start_id,
lldb_private::Section *symtab) {
std::pair<unsigned, ObjectFileELF::FileAddressToAddressClassMap>
ObjectFileELF::ParseSymbolTable(Symtab *symbol_table, user_id_t start_id,
lldb_private::Section *symtab) {
if (symtab->GetObjectFile() != this) {
// If the symbol table section is owned by a different object file, have it
// do the parsing.
ObjectFileELF *obj_file_elf =
static_cast<ObjectFileELF *>(symtab->GetObjectFile());
return obj_file_elf->ParseSymbolTable(symbol_table, start_id, symtab);
auto [num_symbols, address_class_map] =
obj_file_elf->ParseSymbolTable(symbol_table, start_id, symtab);

// The other object file returned the changes it made to its address
// class map, make the same changes to ours.
m_address_class_map.merge(address_class_map);

return {num_symbols, address_class_map};
}

// Get section list for this object file.
SectionList *section_list = m_sections_up.get();
if (!section_list)
return 0;
return {};

user_id_t symtab_id = symtab->GetID();
const ELFSectionHeaderInfo *symtab_hdr = GetSectionHeaderByIndex(symtab_id);
Expand All @@ -2435,7 +2448,7 @@ unsigned ObjectFileELF::ParseSymbolTable(Symtab *symbol_table,
}
}

return 0;
return {0, {}};
}

size_t ObjectFileELF::ParseDynamicSymbols() {
Expand Down Expand Up @@ -2972,8 +2985,12 @@ void ObjectFileELF::ParseSymtab(Symtab &lldb_symtab) {
// while the reverse is not necessarily true.
Section *symtab =
section_list->FindSectionByType(eSectionTypeELFSymbolTable, true).get();
if (symtab)
symbol_id += ParseSymbolTable(&lldb_symtab, symbol_id, symtab);
if (symtab) {
auto [num_symbols, address_class_map] =
ParseSymbolTable(&lldb_symtab, symbol_id, symtab);
m_address_class_map.merge(address_class_map);
symbol_id += num_symbols;
}

// The symtab section is non-allocable and can be stripped, while the
// .dynsym section which should always be always be there. To support the
Expand All @@ -2986,8 +3003,12 @@ void ObjectFileELF::ParseSymtab(Symtab &lldb_symtab) {
Section *dynsym =
section_list->FindSectionByType(eSectionTypeELFDynamicSymbols, true)
.get();
if (dynsym)
symbol_id += ParseSymbolTable(&lldb_symtab, symbol_id, dynsym);
if (dynsym) {
auto [num_symbols, address_class_map] =
ParseSymbolTable(&lldb_symtab, symbol_id, dynsym);
symbol_id += num_symbols;
m_address_class_map.merge(address_class_map);
}
}

// DT_JMPREL
Expand Down
21 changes: 11 additions & 10 deletions lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
Original file line number Diff line number Diff line change
Expand Up @@ -285,18 +285,19 @@ class ObjectFileELF : public lldb_private::ObjectFile {

/// Populates the symbol table with all non-dynamic linker symbols. This
/// method will parse the symbols only once. Returns the number of symbols
/// parsed.
unsigned ParseSymbolTable(lldb_private::Symtab *symbol_table,
lldb::user_id_t start_id,
lldb_private::Section *symtab);
/// parsed and a map of address types (used by targets like Arm that have
/// an alternative ISA mode like Thumb).
std::pair<unsigned, FileAddressToAddressClassMap>
ParseSymbolTable(lldb_private::Symtab *symbol_table, lldb::user_id_t start_id,
lldb_private::Section *symtab);

/// Helper routine for ParseSymbolTable().
unsigned ParseSymbols(lldb_private::Symtab *symbol_table,
lldb::user_id_t start_id,
lldb_private::SectionList *section_list,
const size_t num_symbols,
const lldb_private::DataExtractor &symtab_data,
const lldb_private::DataExtractor &strtab_data);
std::pair<unsigned, FileAddressToAddressClassMap>
ParseSymbols(lldb_private::Symtab *symbol_table, lldb::user_id_t start_id,
lldb_private::SectionList *section_list,
const size_t num_symbols,
const lldb_private::DataExtractor &symtab_data,
const lldb_private::DataExtractor &strtab_data);

/// Scans the relocation entries and adds a set of artificial symbols to the
/// given symbol table for each PLT slot. Returns the number of symbols
Expand Down