Skip to content

Commit 34c5ac8

Browse files
committed
[lldb][ELF] Return address class map from symbol table parsing methods
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 address class map is not left empty, which would break Arm and MIPS targets that need this information. This will fix the code added in llvm#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 58a94b1 commit 34c5ac8

File tree

2 files changed

+51
-38
lines changed

2 files changed

+51
-38
lines changed

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

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2060,13 +2060,14 @@ 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+
FileAddressToAddressClassMap address_class_map;
20702071

20712072
static ConstString text_section_name(".text");
20722073
static ConstString init_section_name(".init");
@@ -2213,18 +2214,18 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
22132214
switch (mapping_symbol) {
22142215
case 'a':
22152216
// $a[.<any>]* - marks an ARM instruction sequence
2216-
m_address_class_map[symbol.st_value] = AddressClass::eCode;
2217+
address_class_map[symbol.st_value] = AddressClass::eCode;
22172218
break;
22182219
case 'b':
22192220
case 't':
22202221
// $b[.<any>]* - marks a THUMB BL instruction sequence
22212222
// $t[.<any>]* - marks a THUMB instruction sequence
2222-
m_address_class_map[symbol.st_value] =
2223+
address_class_map[symbol.st_value] =
22232224
AddressClass::eCodeAlternateISA;
22242225
break;
22252226
case 'd':
22262227
// $d[.<any>]* - marks a data item sequence (e.g. lit pool)
2227-
m_address_class_map[symbol.st_value] = AddressClass::eData;
2228+
address_class_map[symbol.st_value] = AddressClass::eData;
22282229
break;
22292230
}
22302231
}
@@ -2238,11 +2239,11 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
22382239
switch (mapping_symbol) {
22392240
case 'x':
22402241
// $x[.<any>]* - marks an A64 instruction sequence
2241-
m_address_class_map[symbol.st_value] = AddressClass::eCode;
2242+
address_class_map[symbol.st_value] = AddressClass::eCode;
22422243
break;
22432244
case 'd':
22442245
// $d[.<any>]* - marks a data item sequence (e.g. lit pool)
2245-
m_address_class_map[symbol.st_value] = AddressClass::eData;
2246+
address_class_map[symbol.st_value] = AddressClass::eData;
22462247
break;
22472248
}
22482249
}
@@ -2260,11 +2261,11 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
22602261
// conjunction with symbol.st_value to produce the final
22612262
// symbol_value that we store in the symtab.
22622263
symbol_value_offset = -1;
2263-
m_address_class_map[symbol.st_value ^ 1] =
2264+
address_class_map[symbol.st_value ^ 1] =
22642265
AddressClass::eCodeAlternateISA;
22652266
} else {
22662267
// This address is ARM
2267-
m_address_class_map[symbol.st_value] = AddressClass::eCode;
2268+
address_class_map[symbol.st_value] = AddressClass::eCode;
22682269
}
22692270
}
22702271
}
@@ -2285,17 +2286,17 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
22852286
*/
22862287
if (arch.IsMIPS()) {
22872288
if (IS_MICROMIPS(symbol.st_other))
2288-
m_address_class_map[symbol.st_value] = AddressClass::eCodeAlternateISA;
2289+
address_class_map[symbol.st_value] = AddressClass::eCodeAlternateISA;
22892290
else if ((symbol.st_value & 1) && (symbol_type == eSymbolTypeCode)) {
22902291
symbol.st_value = symbol.st_value & (~1ull);
2291-
m_address_class_map[symbol.st_value] = AddressClass::eCodeAlternateISA;
2292+
address_class_map[symbol.st_value] = AddressClass::eCodeAlternateISA;
22922293
} else {
22932294
if (symbol_type == eSymbolTypeCode)
2294-
m_address_class_map[symbol.st_value] = AddressClass::eCode;
2295+
address_class_map[symbol.st_value] = AddressClass::eCode;
22952296
else if (symbol_type == eSymbolTypeData)
2296-
m_address_class_map[symbol.st_value] = AddressClass::eData;
2297+
address_class_map[symbol.st_value] = AddressClass::eData;
22972298
else
2298-
m_address_class_map[symbol.st_value] = AddressClass::eUnknown;
2299+
address_class_map[symbol.st_value] = AddressClass::eUnknown;
22992300
}
23002301
}
23012302
}
@@ -2392,24 +2393,27 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
23922393
dc_symbol.SetIsWeak(true);
23932394
symtab->AddSymbol(dc_symbol);
23942395
}
2395-
return i;
2396+
return {i, address_class_map};
23962397
}
23972398

2398-
unsigned ObjectFileELF::ParseSymbolTable(Symtab *symbol_table,
2399-
user_id_t start_id,
2400-
lldb_private::Section *symtab) {
2399+
std::pair<unsigned, ObjectFileELF::FileAddressToAddressClassMap>
2400+
ObjectFileELF::ParseSymbolTable(Symtab *symbol_table, user_id_t start_id,
2401+
lldb_private::Section *symtab) {
24012402
if (symtab->GetObjectFile() != this) {
24022403
// If the symbol table section is owned by a different object file, have it
24032404
// do the parsing.
24042405
ObjectFileELF *obj_file_elf =
24052406
static_cast<ObjectFileELF *>(symtab->GetObjectFile());
2406-
return obj_file_elf->ParseSymbolTable(symbol_table, start_id, symtab);
2407+
auto [num_symbols, address_class_map] =
2408+
obj_file_elf->ParseSymbolTable(symbol_table, start_id, symtab);
2409+
m_address_class_map.merge(address_class_map);
2410+
return {num_symbols, address_class_map};
24072411
}
24082412

24092413
// Get section list for this object file.
24102414
SectionList *section_list = m_sections_up.get();
24112415
if (!section_list)
2412-
return 0;
2416+
return {};
24132417

24142418
user_id_t symtab_id = symtab->GetID();
24152419
const ELFSectionHeaderInfo *symtab_hdr = GetSectionHeaderByIndex(symtab_id);
@@ -2435,7 +2439,7 @@ unsigned ObjectFileELF::ParseSymbolTable(Symtab *symbol_table,
24352439
}
24362440
}
24372441

2438-
return 0;
2442+
return {0, {}};
24392443
}
24402444

24412445
size_t ObjectFileELF::ParseDynamicSymbols() {
@@ -2972,8 +2976,12 @@ void ObjectFileELF::ParseSymtab(Symtab &lldb_symtab) {
29722976
// while the reverse is not necessarily true.
29732977
Section *symtab =
29742978
section_list->FindSectionByType(eSectionTypeELFSymbolTable, true).get();
2975-
if (symtab)
2976-
symbol_id += ParseSymbolTable(&lldb_symtab, symbol_id, symtab);
2979+
if (symtab) {
2980+
auto [num_symbols, address_class_map] =
2981+
ParseSymbolTable(&lldb_symtab, symbol_id, symtab);
2982+
m_address_class_map.merge(address_class_map);
2983+
symbol_id += num_symbols;
2984+
}
29772985

29782986
// The symtab section is non-allocable and can be stripped, while the
29792987
// .dynsym section which should always be always be there. To support the
@@ -2986,8 +2994,12 @@ void ObjectFileELF::ParseSymtab(Symtab &lldb_symtab) {
29862994
Section *dynsym =
29872995
section_list->FindSectionByType(eSectionTypeELFDynamicSymbols, true)
29882996
.get();
2989-
if (dynsym)
2990-
symbol_id += ParseSymbolTable(&lldb_symtab, symbol_id, dynsym);
2997+
if (dynsym) {
2998+
auto [num_symbols, address_class_map] =
2999+
ParseSymbolTable(&lldb_symtab, symbol_id, dynsym);
3000+
symbol_id += num_symbols;
3001+
m_address_class_map.merge(address_class_map);
3002+
}
29913003
}
29923004

29933005
// 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)