[lldb/ELF] Fix IDs of synthetic eh_frame symbols
The code used the total number of symbols to create a symbol ID for the synthetic symbols. This is not correct because the IDs of real symbols can be higher than their total number, as we do not add all symbols (and in particular, we never add symbol zero, which is not a real symbol). This meant we could have symbols with duplicate IDs, which caused problems if some relocations were referring to the duplicated IDs. This was the cause of the failure of the test D97786. This patch fixes the code to use the ID of the highest (last) symbol instead.
This commit is contained in:
@@ -2901,8 +2901,11 @@ void ObjectFileELF::ParseUnwindSymbols(Symtab *symbol_table,
|
||||
// recalculate the index first.
|
||||
std::vector<Symbol> new_symbols;
|
||||
|
||||
eh_frame->ForEachFDEEntries([this, symbol_table, section_list, &new_symbols](
|
||||
lldb::addr_t file_addr, uint32_t size, dw_offset_t) {
|
||||
size_t num_symbols = symbol_table->GetNumSymbols();
|
||||
uint64_t last_symbol_id =
|
||||
num_symbols ? symbol_table->SymbolAtIndex(num_symbols - 1)->GetID() : 0;
|
||||
eh_frame->ForEachFDEEntries([&](lldb::addr_t file_addr, uint32_t size,
|
||||
dw_offset_t) {
|
||||
Symbol *symbol = symbol_table->FindSymbolAtFileAddress(file_addr);
|
||||
if (symbol) {
|
||||
if (!symbol->GetByteSizeIsValid()) {
|
||||
@@ -2915,21 +2918,20 @@ void ObjectFileELF::ParseUnwindSymbols(Symtab *symbol_table,
|
||||
if (section_sp) {
|
||||
addr_t offset = file_addr - section_sp->GetFileAddress();
|
||||
const char *symbol_name = GetNextSyntheticSymbolName().GetCString();
|
||||
uint64_t symbol_id = symbol_table->GetNumSymbols();
|
||||
Symbol eh_symbol(
|
||||
symbol_id, // Symbol table index.
|
||||
symbol_name, // Symbol name.
|
||||
eSymbolTypeCode, // Type of this symbol.
|
||||
true, // Is this globally visible?
|
||||
false, // Is this symbol debug info?
|
||||
false, // Is this symbol a trampoline?
|
||||
true, // Is this symbol artificial?
|
||||
section_sp, // Section in which this symbol is defined or null.
|
||||
offset, // Offset in section or symbol value.
|
||||
0, // Size: Don't specify the size as an FDE can
|
||||
false, // Size is valid: cover multiple symbols.
|
||||
false, // Contains linker annotations?
|
||||
0); // Symbol flags.
|
||||
++last_symbol_id, // Symbol table index.
|
||||
symbol_name, // Symbol name.
|
||||
eSymbolTypeCode, // Type of this symbol.
|
||||
true, // Is this globally visible?
|
||||
false, // Is this symbol debug info?
|
||||
false, // Is this symbol a trampoline?
|
||||
true, // Is this symbol artificial?
|
||||
section_sp, // Section in which this symbol is defined or null.
|
||||
offset, // Offset in section or symbol value.
|
||||
0, // Size: Don't specify the size as an FDE can
|
||||
false, // Size is valid: cover multiple symbols.
|
||||
false, // Contains linker annotations?
|
||||
0); // Symbol flags.
|
||||
new_symbols.push_back(eh_symbol);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user