Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 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
43 changes: 39 additions & 4 deletions lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2037,6 +2037,18 @@ static char FindArmAarch64MappingSymbol(const char *symbol_name) {
return '\0';
}

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

if (symbol_name[0] == '$' &&
(symbol_name[1] == 'd' || symbol_name[1] == 'x') &&
symbol_name[2] == '\0') {
return symbol_name[1];
}
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 +2114,8 @@ ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
if (!symbol_name)
symbol_name = "";

if (symbol_name[0] == '.' && symbol_name[1] == '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,9 +2204,9 @@ ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,

int64_t symbol_value_offset = 0;
uint32_t additional_flags = 0;

llvm::Triple::ArchType arch_machine = arch.GetMachine();
if (arch.IsValid()) {
if (arch.GetMachine() == llvm::Triple::arm) {
if (arch_machine == llvm::Triple::arm) {
if (symbol.getBinding() == STB_LOCAL) {
char mapping_symbol = FindArmAarch64MappingSymbol(symbol_name);
if (symbol_type == eSymbolTypeCode) {
Expand All @@ -2217,7 +2231,7 @@ ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
if (mapping_symbol)
continue;
}
} else if (arch.GetMachine() == llvm::Triple::aarch64) {
} else if (arch_machine == llvm::Triple::aarch64) {
if (symbol.getBinding() == STB_LOCAL) {
char mapping_symbol = FindArmAarch64MappingSymbol(symbol_name);
if (symbol_type == eSymbolTypeCode) {
Expand All @@ -2235,9 +2249,30 @@ ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
if (mapping_symbol)
continue;
}
} else if (arch_machine == llvm::Triple::riscv32 ||
arch_machine == llvm::Triple::riscv64 ||
arch_machine == llvm::Triple::riscv32be ||
arch_machine == llvm::Triple::riscv64be) {
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) {
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) {
if (arch_machine == llvm::Triple::arm) {
if (symbol_type == eSymbolTypeCode) {
if (symbol.st_value & 1) {
// Subtracting 1 from the address effectively unsets the low order
Expand Down
75 changes: 75 additions & 0 deletions lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -308,3 +308,78 @@ 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
Symbols:
- Name: $d
Type: STT_FUNC
Copy link
Contributor

Choose a reason for hiding this comment

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

$d and $x are not STT_FUNC type. They are unknown type, i.e. Type is empty.

Section: .text
Value: 0x0000000000400180
Size: 0x10
Binding: STB_LOCAL
- Name: $x
Type: STT_FUNC
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