Skip to content
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
41 changes: 40 additions & 1 deletion lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2037,6 +2037,19 @@ static char FindArmAarch64MappingSymbol(const char *symbol_name) {
return '\0';
}

static char FindRISCVMappingSymbol(const char *symbol_name) {
if (!symbol_name)
return '\0';

if (strcmp(symbol_name, "$d") == 0) {
return 'd';
}
if (strcmp(symbol_name, "$x") == 0) {
return 'x';
}
return '\0';
}

#define STO_MIPS_ISA (3 << 6)
#define STO_MICROMIPS (2 << 6)
#define IS_MICROMIPS(ST_OTHER) (((ST_OTHER)&STO_MIPS_ISA) == STO_MICROMIPS)
Expand Down Expand Up @@ -2102,6 +2115,12 @@ ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
if (!symbol_name)
symbol_name = "";

// Skip local symbols starting with ".L" because these are compiler
// generated local labels used for internal purposes (e.g. debugging,
// optimization) and are not relevant for symbol resolution or external
// linkage.
if (llvm::StringRef(symbol_name).starts_with(".L"))
continue;
// No need to add non-section symbols that have no names
if (symbol.getType() != STT_SECTION &&
(symbol_name == nullptr || symbol_name[0] == '\0'))
Expand Down Expand Up @@ -2190,7 +2209,6 @@ ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,

int64_t symbol_value_offset = 0;
uint32_t additional_flags = 0;

if (arch.IsValid()) {
if (arch.GetMachine() == llvm::Triple::arm) {
if (symbol.getBinding() == STB_LOCAL) {
Expand Down Expand Up @@ -2235,6 +2253,27 @@ ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
if (mapping_symbol)
continue;
}
} else if (arch.GetTriple().isRISCV()) {
if (symbol.getBinding() == STB_LOCAL) {
char mapping_symbol = FindRISCVMappingSymbol(symbol_name);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure the FindRISCVMappingSymbol is making the code cleaner here since we have to switch on the result anyway.

I think it would look cleaner to just check the symbol directly.

  if (strcmp(symbol_name, "$d") == 0) {
    address_class_map[symbol.st_value] = AddressClass::eCode;
    continue;
  }
  if (strcmp(symbol_name, "$x") == 0) {
    address_class_map[symbol.st_value] = AddressClass::eData;
    continue;
  }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We discussed offline and decided to keep it the way I did before to follow same style as existing code.

if (symbol_type == eSymbolTypeCode) {
// Only handle $d and $x mapping symbols.
// Other mapping symbols are ignored as they don't affect address
// classification.
switch (mapping_symbol) {
case 'x':
// $x - marks a RISCV instruction sequence
address_class_map[symbol.st_value] = AddressClass::eCode;
break;
case 'd':
// $d - marks a RISCV data item sequence
address_class_map[symbol.st_value] = AddressClass::eData;
break;
}
}
if (mapping_symbol)
continue;
}
}

if (arch.GetMachine() == llvm::Triple::arm) {
Expand Down
81 changes: 81 additions & 0 deletions lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -308,3 +308,84 @@ TEST_F(ObjectFileELFTest, GetSymtab_NoSymEntryPointArmAddressClass) {
auto entry_point_addr = module_sp->GetObjectFile()->GetEntryPointAddress();
ASSERT_EQ(entry_point_addr.GetAddressClass(), AddressClass::eCode);
}

TEST_F(ObjectFileELFTest, SkipsLocalMappingAndDotLSymbols) {
auto ExpectedFile = TestFile::fromYaml(R"(
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_EXEC
Machine: EM_RISCV
Flags: [ EF_RISCV_RVC, EF_RISCV_FLOAT_ABI_SINGLE ]
Entry: 0xC0A1B010
Sections:
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
Address: 0x0000000000400180
AddressAlign: 0x0000000000000010
Content: 554889E5
- Name: .data
Type: SHT_PROGBITS
Flags: [ SHF_WRITE, SHF_ALLOC ]
Address: 0x0000000000601000
AddressAlign: 0x0000000000000004
Content: 2F000000
- Name: .riscv.attributes
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC ]
Address: 0x0000000000610000
AddressAlign: 0x0000000000000004
Content: "00"
Symbols:
- Name: $d
Type: STT_NOTYPE
Section: .riscv.attributes
Value: 0x0000000000400180
Size: 0x10
Binding: STB_LOCAL
- Name: $x
Type: STT_NOTYPE
Section: .text
Value: 0xC0A1B010
Size: 0x10
Binding: STB_LOCAL
- Name: .Lfoo
Type: STT_OBJECT
Section: .data
Value: 0x0000000000601000
Size: 0x4
Binding: STB_LOCAL
- Name: global_func
Type: STT_FUNC
Section: .text
Value: 0x00000000004001A0
Size: 0x10
Binding: STB_GLOBAL
- Name: global_obj
Type: STT_OBJECT
Section: .data
Value: 0x0000000000601004
Size: 0x4
Binding: STB_GLOBAL
...
)");
ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());
auto module_sp = std::make_shared<Module>(ExpectedFile->moduleSpec());
auto *symtab = module_sp->GetSymtab();
ASSERT_NE(nullptr, symtab);
EXPECT_EQ(nullptr, module_sp->FindFirstSymbolWithNameAndType(
ConstString("$d"), eSymbolTypeAny));
EXPECT_EQ(nullptr, module_sp->FindFirstSymbolWithNameAndType(
ConstString("$x"), eSymbolTypeAny));
EXPECT_EQ(nullptr, module_sp->FindFirstSymbolWithNameAndType(
ConstString(".Lfoo"), eSymbolTypeAny));
// assert that other symbols are present
const Symbol *global_func = module_sp->FindFirstSymbolWithNameAndType(
ConstString("global_func"), eSymbolTypeAny);
ASSERT_NE(nullptr, global_func);
const Symbol *global_obj = module_sp->FindFirstSymbolWithNameAndType(
ConstString("global_obj"), eSymbolTypeAny);
ASSERT_NE(nullptr, global_obj);
}
Loading