Index: lldb/trunk/lit/SymbolFile/dissassemble-entry-point.s =================================================================== --- lldb/trunk/lit/SymbolFile/dissassemble-entry-point.s +++ lldb/trunk/lit/SymbolFile/dissassemble-entry-point.s @@ -0,0 +1,13 @@ +# REQUIRES: lld, arm + +# RUN: llvm-mc -triple=thumbv7-eabi %s -filetype=obj -o %t.o +# RUN: ld.lld %t.o -o %t --section-start=.text=0x8074 -e 0x8075 -s +# RUN: %lldb -x -b -o 'dis -s 0x8074 -e 0x8080' -- %t | FileCheck %s +# CHECK: {{.*}}[0x8074] <+0>: movs r0, #0x2a +# CHECK-NEXT: {{.*}}[0x8076] <+2>: movs r7, #0x1 +# CHECK-NEXT: {{.*}}[0x8078] <+4>: svc #0x0 + +_start: + movs r0, #0x2a + movs r7, #0x1 + svc #0x0 \ No newline at end of file Index: lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp =================================================================== --- lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -2703,6 +2703,46 @@ if (m_symtab_up == nullptr) m_symtab_up.reset(new Symtab(this)); + // In the event that there's no symbol entry for the entry point we'll + // artifically create one. We delegate to the symtab object the figuring + // out of the proper size, this will usually make it span til the next + // symbol it finds in the section. This means that if there are missing + // symbols the entry point might span beyond its function definition. + // We're fine with this as it doesn't make it worse than not having a + // symbol entry at all. + ArchSpec arch = GetArchitecture(); + auto entry_point_addr = GetEntryPointAddress().GetFileAddress(); + if (entry_point_addr != LLDB_INVALID_ADDRESS) { + if (!m_symtab_up->FindSymbolContainingFileAddress(entry_point_addr)) { + uint64_t symbol_id = m_symtab_up->GetNumSymbols(); + SectionSP section_sp = + GetSectionList()->FindSectionContainingFileAddress(entry_point_addr); + Symbol symbol( + symbol_id, + GetNextSyntheticSymbolName().GetCString(), // Symbol name. + false, // Is the symbol name mangled? + 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. + 0, // Offset in section or symbol value. + 0, // Size. + false, // Size is valid. + false, // Contains linker annotations? + 0); // Symbol flags. + m_symtab_up->AddSymbol(symbol); + // When the entry point is arm thumb we need to explicitly set its + // class address to reflect that. This is important because expression + // evaluation relies on correctly setting a breakpoint at this address. + if (arch.GetMachine() == llvm::Triple::arm && (entry_point_addr & 1)) + m_address_class_map[entry_point_addr ^ 1] = AddressClass::eCodeAlternateISA; + else + m_address_class_map[entry_point_addr] = AddressClass::eCode; + } + } + m_symtab_up->CalculateSymbolSizes(); } Index: lldb/trunk/unittests/ObjectFile/ELF/TestObjectFileELF.cpp =================================================================== --- lldb/trunk/unittests/ObjectFile/ELF/TestObjectFileELF.cpp +++ lldb/trunk/unittests/ObjectFile/ELF/TestObjectFileELF.cpp @@ -172,3 +172,129 @@ Uuid.SetFromStringRef("1b8a73ac238390e32a7ff4ac8ebe4d6a41ecf5c9", 20); EXPECT_EQ(Spec.GetUUID(), Uuid); } + +TEST_F(ObjectFileELFTest, GetSymtab_NoSymEntryPointArmThumbAddressClass) { + /* + // nosym-entrypoint-arm-thumb.s + .thumb_func + _start: + mov r0, #42 + mov r7, #1 + svc #0 + // arm-linux-androideabi-as nosym-entrypoint-arm-thumb.s + // -o nosym-entrypoint-arm-thumb.o + // arm-linux-androideabi-ld nosym-entrypoint-arm-thumb.o + // -o nosym-entrypoint-arm-thumb -e 0x8075 -s + */ + auto ExpectedFile = TestFile::fromYaml(R"( +--- !ELF +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_ARM + Flags: [ EF_ARM_SOFT_FLOAT, EF_ARM_EABI_VER5 ] + Entry: 0x0000000000008075 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x0000000000008074 + AddressAlign: 0x0000000000000002 + Content: 2A20012700DF + - Name: .data + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x0000000000009000 + AddressAlign: 0x0000000000000001 + Content: '' + - Name: .bss + Type: SHT_NOBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x0000000000009000 + AddressAlign: 0x0000000000000001 + - Name: .note.gnu.gold-version + Type: SHT_NOTE + AddressAlign: 0x0000000000000004 + Content: 040000000900000004000000474E5500676F6C6420312E3131000000 + - Name: .ARM.attributes + Type: SHT_ARM_ATTRIBUTES + AddressAlign: 0x0000000000000001 + Content: '4113000000616561626900010900000006020901' +... +)"); + ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded()); + + ModuleSpec spec{FileSpec(ExpectedFile->name())}; + spec.GetSymbolFileSpec().SetFile(ExpectedFile->name(), + FileSpec::Style::native); + auto module_sp = std::make_shared(spec); + + auto entry_point_addr = module_sp->GetObjectFile()->GetEntryPointAddress(); + ASSERT_TRUE(entry_point_addr.GetOffset() & 1); + // Decrease the offsite by 1 to make it into a breakable address since this + // is Thumb. + entry_point_addr.SetOffset(entry_point_addr.GetOffset() - 1); + ASSERT_EQ(entry_point_addr.GetAddressClass(), + AddressClass::eCodeAlternateISA); +} + +TEST_F(ObjectFileELFTest, GetSymtab_NoSymEntryPointArmAddressClass) { + /* + // nosym-entrypoint-arm.s + _start: + movs r0, #42 + movs r7, #1 + svc #0 + // arm-linux-androideabi-as nosym-entrypoint-arm.s + // -o nosym-entrypoint-arm.o + // arm-linux-androideabi-ld nosym-entrypoint-arm.o + // -o nosym-entrypoint-arm -e 0x8074 -s + */ + auto ExpectedFile = TestFile::fromYaml(R"( +--- !ELF +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_ARM + Flags: [ EF_ARM_SOFT_FLOAT, EF_ARM_EABI_VER5 ] + Entry: 0x0000000000008074 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x0000000000008074 + AddressAlign: 0x0000000000000004 + Content: 2A00A0E30170A0E3000000EF + - Name: .data + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x0000000000009000 + AddressAlign: 0x0000000000000001 + Content: '' + - Name: .bss + Type: SHT_NOBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x0000000000009000 + AddressAlign: 0x0000000000000001 + - Name: .note.gnu.gold-version + Type: SHT_NOTE + AddressAlign: 0x0000000000000004 + Content: 040000000900000004000000474E5500676F6C6420312E3131000000 + - Name: .ARM.attributes + Type: SHT_ARM_ATTRIBUTES + AddressAlign: 0x0000000000000001 + Content: '4113000000616561626900010900000006010801' +... +)"); + ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded()); + + ModuleSpec spec{FileSpec(ExpectedFile->name())}; + spec.GetSymbolFileSpec().SetFile(ExpectedFile->name(), + FileSpec::Style::native); + auto module_sp = std::make_shared(spec); + + auto entry_point_addr = module_sp->GetObjectFile()->GetEntryPointAddress(); + ASSERT_EQ(entry_point_addr.GetAddressClass(), AddressClass::eCode); +} \ No newline at end of file