Skip to content

Commit a76518c

Browse files
[lldb][ELF] Return address class map changes from symbol table parsing methods (#91585)
Instead of updating the member of the ObjectFileELF instance. This means that if one object file asks another to parse the symbol table, that first object's can update its address class map with the same changes that the other object did. (I'm not returning a reference to the other object's m_address_class_map member because there may be other things in there not related to the symbol table being parsed) This will fix the code added in #90622 which broke the test `Expr/TestStringLiteralExpr.test` on 32 bit Arm Linux. This happened because we had the program file, then asked for a better object file, which returned the same program file again. This creates a second ObjectFileELF for the same file, so when we tell the second instance to parse the symbol table it actually calls into the first instance, leaving the address class map of the second instance empty. Which caused us to put an Arm breakpoint instuction at a Thumb return address and broke the ability to call mmap.
1 parent 5d24217 commit a76518c

File tree

2 files changed

+60
-38
lines changed

2 files changed

+60
-38
lines changed

lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp

Lines changed: 49 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2060,13 +2060,17 @@ static char FindArmAarch64MappingSymbol(const char *symbol_name) {
20602060
#define IS_MICROMIPS(ST_OTHER) (((ST_OTHER)&STO_MIPS_ISA) == STO_MICROMIPS)
20612061

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

20712075
static ConstString text_section_name(".text");
20722076
static ConstString init_section_name(".init");
@@ -2213,18 +2217,18 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
22132217
switch (mapping_symbol) {
22142218
case 'a':
22152219
// $a[.<any>]* - marks an ARM instruction sequence
2216-
m_address_class_map[symbol.st_value] = AddressClass::eCode;
2220+
address_class_map[symbol.st_value] = AddressClass::eCode;
22172221
break;
22182222
case 'b':
22192223
case 't':
22202224
// $b[.<any>]* - marks a THUMB BL instruction sequence
22212225
// $t[.<any>]* - marks a THUMB instruction sequence
2222-
m_address_class_map[symbol.st_value] =
2226+
address_class_map[symbol.st_value] =
22232227
AddressClass::eCodeAlternateISA;
22242228
break;
22252229
case 'd':
22262230
// $d[.<any>]* - marks a data item sequence (e.g. lit pool)
2227-
m_address_class_map[symbol.st_value] = AddressClass::eData;
2231+
address_class_map[symbol.st_value] = AddressClass::eData;
22282232
break;
22292233
}
22302234
}
@@ -2238,11 +2242,11 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
22382242
switch (mapping_symbol) {
22392243
case 'x':
22402244
// $x[.<any>]* - marks an A64 instruction sequence
2241-
m_address_class_map[symbol.st_value] = AddressClass::eCode;
2245+
address_class_map[symbol.st_value] = AddressClass::eCode;
22422246
break;
22432247
case 'd':
22442248
// $d[.<any>]* - marks a data item sequence (e.g. lit pool)
2245-
m_address_class_map[symbol.st_value] = AddressClass::eData;
2249+
address_class_map[symbol.st_value] = AddressClass::eData;
22462250
break;
22472251
}
22482252
}
@@ -2260,11 +2264,11 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
22602264
// conjunction with symbol.st_value to produce the final
22612265
// symbol_value that we store in the symtab.
22622266
symbol_value_offset = -1;
2263-
m_address_class_map[symbol.st_value ^ 1] =
2267+
address_class_map[symbol.st_value ^ 1] =
22642268
AddressClass::eCodeAlternateISA;
22652269
} else {
22662270
// This address is ARM
2267-
m_address_class_map[symbol.st_value] = AddressClass::eCode;
2271+
address_class_map[symbol.st_value] = AddressClass::eCode;
22682272
}
22692273
}
22702274
}
@@ -2285,17 +2289,17 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
22852289
*/
22862290
if (arch.IsMIPS()) {
22872291
if (IS_MICROMIPS(symbol.st_other))
2288-
m_address_class_map[symbol.st_value] = AddressClass::eCodeAlternateISA;
2292+
address_class_map[symbol.st_value] = AddressClass::eCodeAlternateISA;
22892293
else if ((symbol.st_value & 1) && (symbol_type == eSymbolTypeCode)) {
22902294
symbol.st_value = symbol.st_value & (~1ull);
2291-
m_address_class_map[symbol.st_value] = AddressClass::eCodeAlternateISA;
2295+
address_class_map[symbol.st_value] = AddressClass::eCodeAlternateISA;
22922296
} else {
22932297
if (symbol_type == eSymbolTypeCode)
2294-
m_address_class_map[symbol.st_value] = AddressClass::eCode;
2298+
address_class_map[symbol.st_value] = AddressClass::eCode;
22952299
else if (symbol_type == eSymbolTypeData)
2296-
m_address_class_map[symbol.st_value] = AddressClass::eData;
2300+
address_class_map[symbol.st_value] = AddressClass::eData;
22972301
else
2298-
m_address_class_map[symbol.st_value] = AddressClass::eUnknown;
2302+
address_class_map[symbol.st_value] = AddressClass::eUnknown;
22992303
}
23002304
}
23012305
}
@@ -2392,24 +2396,33 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
23922396
dc_symbol.SetIsWeak(true);
23932397
symtab->AddSymbol(dc_symbol);
23942398
}
2395-
return i;
2399+
2400+
m_address_class_map.merge(address_class_map);
2401+
return {i, address_class_map};
23962402
}
23972403

2398-
unsigned ObjectFileELF::ParseSymbolTable(Symtab *symbol_table,
2399-
user_id_t start_id,
2400-
lldb_private::Section *symtab) {
2404+
std::pair<unsigned, ObjectFileELF::FileAddressToAddressClassMap>
2405+
ObjectFileELF::ParseSymbolTable(Symtab *symbol_table, user_id_t start_id,
2406+
lldb_private::Section *symtab) {
24012407
if (symtab->GetObjectFile() != this) {
24022408
// If the symbol table section is owned by a different object file, have it
24032409
// do the parsing.
24042410
ObjectFileELF *obj_file_elf =
24052411
static_cast<ObjectFileELF *>(symtab->GetObjectFile());
2406-
return obj_file_elf->ParseSymbolTable(symbol_table, start_id, symtab);
2412+
auto [num_symbols, address_class_map] =
2413+
obj_file_elf->ParseSymbolTable(symbol_table, start_id, symtab);
2414+
2415+
// The other object file returned the changes it made to its address
2416+
// class map, make the same changes to ours.
2417+
m_address_class_map.merge(address_class_map);
2418+
2419+
return {num_symbols, address_class_map};
24072420
}
24082421

24092422
// Get section list for this object file.
24102423
SectionList *section_list = m_sections_up.get();
24112424
if (!section_list)
2412-
return 0;
2425+
return {};
24132426

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

2438-
return 0;
2451+
return {0, {}};
24392452
}
24402453

24412454
size_t ObjectFileELF::ParseDynamicSymbols() {
@@ -2972,8 +2985,12 @@ void ObjectFileELF::ParseSymtab(Symtab &lldb_symtab) {
29722985
// while the reverse is not necessarily true.
29732986
Section *symtab =
29742987
section_list->FindSectionByType(eSectionTypeELFSymbolTable, true).get();
2975-
if (symtab)
2976-
symbol_id += ParseSymbolTable(&lldb_symtab, symbol_id, symtab);
2988+
if (symtab) {
2989+
auto [num_symbols, address_class_map] =
2990+
ParseSymbolTable(&lldb_symtab, symbol_id, symtab);
2991+
m_address_class_map.merge(address_class_map);
2992+
symbol_id += num_symbols;
2993+
}
29772994

29782995
// The symtab section is non-allocable and can be stripped, while the
29792996
// .dynsym section which should always be always be there. To support the
@@ -2986,8 +3003,12 @@ void ObjectFileELF::ParseSymtab(Symtab &lldb_symtab) {
29863003
Section *dynsym =
29873004
section_list->FindSectionByType(eSectionTypeELFDynamicSymbols, true)
29883005
.get();
2989-
if (dynsym)
2990-
symbol_id += ParseSymbolTable(&lldb_symtab, symbol_id, dynsym);
3006+
if (dynsym) {
3007+
auto [num_symbols, address_class_map] =
3008+
ParseSymbolTable(&lldb_symtab, symbol_id, dynsym);
3009+
symbol_id += num_symbols;
3010+
m_address_class_map.merge(address_class_map);
3011+
}
29913012
}
29923013

29933014
// DT_JMPREL

lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -285,18 +285,19 @@ class ObjectFileELF : public lldb_private::ObjectFile {
285285

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

293294
/// Helper routine for ParseSymbolTable().
294-
unsigned ParseSymbols(lldb_private::Symtab *symbol_table,
295-
lldb::user_id_t start_id,
296-
lldb_private::SectionList *section_list,
297-
const size_t num_symbols,
298-
const lldb_private::DataExtractor &symtab_data,
299-
const lldb_private::DataExtractor &strtab_data);
295+
std::pair<unsigned, FileAddressToAddressClassMap>
296+
ParseSymbols(lldb_private::Symtab *symbol_table, lldb::user_id_t start_id,
297+
lldb_private::SectionList *section_list,
298+
const size_t num_symbols,
299+
const lldb_private::DataExtractor &symtab_data,
300+
const lldb_private::DataExtractor &strtab_data);
300301

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

0 commit comments

Comments
 (0)