[lldb][NFC] Fix all formatting errors in .cpp file headers
Summary:
A *.cpp file header in LLDB (and in LLDB) should like this:
```
//===-- TestUtilities.cpp -------------------------------------------------===//
```
However in LLDB most of our source files have arbitrary changes to this format and
these changes are spreading through LLDB as folks usually just use the existing
source files as templates for their new files (most notably the unnecessary
editor language indicator `-*- C++ -*-` is spreading and in every review
someone is pointing out that this is wrong, resulting in people pointing out that this
is done in the same way in other files).
This patch removes most of these inconsistencies including the editor language indicators,
all the different missing/additional '-' characters, files that center the file name, missing
trailing `===//` (mostly caused by clang-format breaking the line).
Reviewers: aprantl, espindola, jfb, shafik, JDevlieghere
Reviewed By: JDevlieghere
Subscribers: dexonsmith, wuzish, emaste, sdardis, nemanjai, kbarton, MaskRay, atanasyan, arphaman, jfb, abidh, jsji, JDevlieghere, usaxena95, lldb-commits
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D73258
2020-01-24 15:23:27 +08:00
|
|
|
//===-- TestObjectFileELF.cpp ---------------------------------------------===//
|
2017-05-02 20:40:31 +08:00
|
|
|
//
|
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2017-05-02 20:40:31 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
|
2019-07-26 15:03:28 +08:00
|
|
|
#include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h"
|
2019-12-23 17:38:12 +08:00
|
|
|
#include "TestingSupport/SubsystemRAII.h"
|
2017-12-15 22:23:58 +08:00
|
|
|
#include "TestingSupport/TestUtilities.h"
|
2017-05-02 20:40:31 +08:00
|
|
|
#include "lldb/Core/Module.h"
|
|
|
|
#include "lldb/Core/ModuleSpec.h"
|
|
|
|
#include "lldb/Core/Section.h"
|
2018-11-01 05:49:27 +08:00
|
|
|
#include "lldb/Host/FileSystem.h"
|
2017-05-02 20:40:31 +08:00
|
|
|
#include "lldb/Host/HostInfo.h"
|
2018-11-06 06:18:00 +08:00
|
|
|
#include "lldb/Utility/DataBufferHeap.h"
|
2017-09-14 04:02:24 +08:00
|
|
|
#include "llvm/ADT/Optional.h"
|
2017-12-15 22:23:58 +08:00
|
|
|
#include "llvm/Support/Compression.h"
|
2017-05-02 20:40:31 +08:00
|
|
|
#include "llvm/Support/FileUtilities.h"
|
|
|
|
#include "llvm/Support/Path.h"
|
|
|
|
#include "llvm/Support/Program.h"
|
|
|
|
#include "llvm/Support/raw_ostream.h"
|
2019-05-07 04:01:21 +08:00
|
|
|
#include "llvm/Testing/Support/Error.h"
|
2017-05-02 20:40:31 +08:00
|
|
|
#include "gtest/gtest.h"
|
|
|
|
|
|
|
|
using namespace lldb_private;
|
|
|
|
using namespace lldb;
|
|
|
|
|
|
|
|
class ObjectFileELFTest : public testing::Test {
|
2019-12-23 17:38:12 +08:00
|
|
|
SubsystemRAII<FileSystem, HostInfo, ObjectFileELF, SymbolFileSymtab>
|
|
|
|
subsystems;
|
2017-05-02 20:40:31 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
TEST_F(ObjectFileELFTest, SectionsResolveConsistently) {
|
unittests: Use yaml2obj as a library instead of an external process
Summary:
Recently, yaml2obj has been turned into a library. This means we can use
it from our unit tests directly, instead of shelling out to an external
process. This patch does just that.
Reviewers: JDevlieghere, aadsm, espindola, jdoerfert
Subscribers: emaste, mgorny, arichardson, MaskRay, jhenderson, abrachet, lldb-commits
Differential Revision: https://reviews.llvm.org/D65949
llvm-svn: 369374
2019-08-20 20:28:36 +08:00
|
|
|
auto ExpectedFile = TestFile::fromYaml(R"(
|
|
|
|
--- !ELF
|
|
|
|
FileHeader:
|
|
|
|
Class: ELFCLASS64
|
|
|
|
Data: ELFDATA2LSB
|
|
|
|
Type: ET_EXEC
|
|
|
|
Machine: EM_X86_64
|
|
|
|
Entry: 0x0000000000400180
|
|
|
|
Sections:
|
|
|
|
- Name: .note.gnu.build-id
|
|
|
|
Type: SHT_NOTE
|
|
|
|
Flags: [ SHF_ALLOC ]
|
|
|
|
Address: 0x0000000000400158
|
|
|
|
AddressAlign: 0x0000000000000004
|
|
|
|
Content: 040000001400000003000000474E55003F3EC29E3FD83E49D18C4D49CD8A730CC13117B6
|
|
|
|
- Name: .text
|
|
|
|
Type: SHT_PROGBITS
|
|
|
|
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
|
|
|
Address: 0x0000000000400180
|
|
|
|
AddressAlign: 0x0000000000000010
|
|
|
|
Content: 554889E58B042500106000890425041060005DC3
|
|
|
|
- Name: .data
|
|
|
|
Type: SHT_PROGBITS
|
|
|
|
Flags: [ SHF_WRITE, SHF_ALLOC ]
|
|
|
|
Address: 0x0000000000601000
|
|
|
|
AddressAlign: 0x0000000000000004
|
|
|
|
Content: 2F000000
|
|
|
|
- Name: .bss
|
|
|
|
Type: SHT_NOBITS
|
|
|
|
Flags: [ SHF_WRITE, SHF_ALLOC ]
|
|
|
|
Address: 0x0000000000601004
|
|
|
|
AddressAlign: 0x0000000000000004
|
|
|
|
Size: 0x0000000000000004
|
|
|
|
Symbols:
|
|
|
|
- Name: Y
|
|
|
|
Type: STT_OBJECT
|
|
|
|
Section: .data
|
|
|
|
Value: 0x0000000000601000
|
|
|
|
Size: 0x0000000000000004
|
|
|
|
Binding: STB_GLOBAL
|
|
|
|
- Name: _start
|
|
|
|
Type: STT_FUNC
|
|
|
|
Section: .text
|
|
|
|
Value: 0x0000000000400180
|
|
|
|
Size: 0x0000000000000014
|
|
|
|
Binding: STB_GLOBAL
|
|
|
|
- Name: X
|
|
|
|
Type: STT_OBJECT
|
|
|
|
Section: .bss
|
|
|
|
Value: 0x0000000000601004
|
|
|
|
Size: 0x0000000000000004
|
|
|
|
Binding: STB_GLOBAL
|
|
|
|
...
|
|
|
|
)");
|
|
|
|
ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());
|
2017-05-02 20:40:31 +08:00
|
|
|
|
2020-07-10 05:14:36 +08:00
|
|
|
auto module_sp = std::make_shared<Module>(ExpectedFile->moduleSpec());
|
2017-05-02 20:40:31 +08:00
|
|
|
SectionList *list = module_sp->GetSectionList();
|
|
|
|
ASSERT_NE(nullptr, list);
|
|
|
|
|
|
|
|
auto bss_sp = list->FindSectionByName(ConstString(".bss"));
|
|
|
|
ASSERT_NE(nullptr, bss_sp);
|
|
|
|
auto data_sp = list->FindSectionByName(ConstString(".data"));
|
|
|
|
ASSERT_NE(nullptr, data_sp);
|
|
|
|
auto text_sp = list->FindSectionByName(ConstString(".text"));
|
|
|
|
ASSERT_NE(nullptr, text_sp);
|
|
|
|
|
|
|
|
const Symbol *X = module_sp->FindFirstSymbolWithNameAndType(ConstString("X"),
|
|
|
|
eSymbolTypeAny);
|
|
|
|
ASSERT_NE(nullptr, X);
|
|
|
|
EXPECT_EQ(bss_sp, X->GetAddress().GetSection());
|
|
|
|
|
|
|
|
const Symbol *Y = module_sp->FindFirstSymbolWithNameAndType(ConstString("Y"),
|
|
|
|
eSymbolTypeAny);
|
|
|
|
ASSERT_NE(nullptr, Y);
|
|
|
|
EXPECT_EQ(data_sp, Y->GetAddress().GetSection());
|
|
|
|
|
|
|
|
const Symbol *start = module_sp->FindFirstSymbolWithNameAndType(
|
|
|
|
ConstString("_start"), eSymbolTypeAny);
|
|
|
|
ASSERT_NE(nullptr, start);
|
|
|
|
EXPECT_EQ(text_sp, start->GetAddress().GetSection());
|
|
|
|
}
|
Fix parsing of object files with "early" section headers
ObjectFileELF::GetModuleSpecifications contained a lot of tip-toing code
which was trying to avoid loading the full object file into memory. It
did this by trying to load data only up to the offset if was accessing.
However, in practice this was useless, as 99% of object files we
encounter have section headers at the end, so we would load the whole
file as soon as we start parsing the section headers.
In fact, this would break as soon as we encounter a file which does
*not* have section headers at the end (yaml2obj produces these), as the
access to .strtab (which we need to get the section names) was not
guarded by this offset check.
As this strategy was completely ineffective anyway, I do not attempt to
proliferate it further by guarding the .strtab accesses. Instead I just
lead the full file as soon as we are reasonably sure that we are indeed
processing an elf file.
If we really care about the load size here, we would need to reimplement
this to just load the bits of the object file we need, instead of
loading everything from the start of the object file to the given
offset. However, given that the OS will do this for us for free when
using mmap, I think think this is really necessary.
For testing this I check a (tiny) SO file instead of yaml2obj-ing it
because the fact that they come out first is an implementation detail of
yaml2obj that can change in the future.
llvm-svn: 324254
2018-02-06 01:25:40 +08:00
|
|
|
|
|
|
|
// Test that GetModuleSpecifications works on an "atypical" object file which
|
|
|
|
// has section headers right after the ELF header (instead of the more common
|
|
|
|
// layout where the section headers are at the very end of the object file).
|
2018-02-06 02:03:02 +08:00
|
|
|
//
|
|
|
|
// Test file generated with yaml2obj (@svn rev 324254) from the following input:
|
|
|
|
/*
|
|
|
|
--- !ELF
|
|
|
|
FileHeader:
|
|
|
|
Class: ELFCLASS64
|
|
|
|
Data: ELFDATA2LSB
|
|
|
|
Type: ET_EXEC
|
|
|
|
Machine: EM_X86_64
|
|
|
|
Entry: 0x00000000004003D0
|
|
|
|
Sections:
|
|
|
|
- Name: .note.gnu.build-id
|
|
|
|
Type: SHT_NOTE
|
|
|
|
Flags: [ SHF_ALLOC ]
|
|
|
|
Address: 0x0000000000400274
|
|
|
|
AddressAlign: 0x0000000000000004
|
|
|
|
Content: 040000001400000003000000474E55001B8A73AC238390E32A7FF4AC8EBE4D6A41ECF5C9
|
|
|
|
- Name: .text
|
|
|
|
Type: SHT_PROGBITS
|
|
|
|
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
|
|
|
Address: 0x00000000004003D0
|
|
|
|
AddressAlign: 0x0000000000000010
|
|
|
|
Content: DEADBEEFBAADF00D
|
|
|
|
...
|
|
|
|
*/
|
Fix parsing of object files with "early" section headers
ObjectFileELF::GetModuleSpecifications contained a lot of tip-toing code
which was trying to avoid loading the full object file into memory. It
did this by trying to load data only up to the offset if was accessing.
However, in practice this was useless, as 99% of object files we
encounter have section headers at the end, so we would load the whole
file as soon as we start parsing the section headers.
In fact, this would break as soon as we encounter a file which does
*not* have section headers at the end (yaml2obj produces these), as the
access to .strtab (which we need to get the section names) was not
guarded by this offset check.
As this strategy was completely ineffective anyway, I do not attempt to
proliferate it further by guarding the .strtab accesses. Instead I just
lead the full file as soon as we are reasonably sure that we are indeed
processing an elf file.
If we really care about the load size here, we would need to reimplement
this to just load the bits of the object file we need, instead of
loading everything from the start of the object file to the given
offset. However, given that the OS will do this for us for free when
using mmap, I think think this is really necessary.
For testing this I check a (tiny) SO file instead of yaml2obj-ing it
because the fact that they come out first is an implementation detail of
yaml2obj that can change in the future.
llvm-svn: 324254
2018-02-06 01:25:40 +08:00
|
|
|
TEST_F(ObjectFileELFTest, GetModuleSpecifications_EarlySectionHeaders) {
|
|
|
|
std::string SO = GetInputFilePath("early-section-headers.so");
|
|
|
|
ModuleSpecList Specs;
|
2018-11-02 05:05:36 +08:00
|
|
|
ASSERT_EQ(1u, ObjectFile::GetModuleSpecifications(FileSpec(SO), 0, 0, Specs));
|
Fix parsing of object files with "early" section headers
ObjectFileELF::GetModuleSpecifications contained a lot of tip-toing code
which was trying to avoid loading the full object file into memory. It
did this by trying to load data only up to the offset if was accessing.
However, in practice this was useless, as 99% of object files we
encounter have section headers at the end, so we would load the whole
file as soon as we start parsing the section headers.
In fact, this would break as soon as we encounter a file which does
*not* have section headers at the end (yaml2obj produces these), as the
access to .strtab (which we need to get the section names) was not
guarded by this offset check.
As this strategy was completely ineffective anyway, I do not attempt to
proliferate it further by guarding the .strtab accesses. Instead I just
lead the full file as soon as we are reasonably sure that we are indeed
processing an elf file.
If we really care about the load size here, we would need to reimplement
this to just load the bits of the object file we need, instead of
loading everything from the start of the object file to the given
offset. However, given that the OS will do this for us for free when
using mmap, I think think this is really necessary.
For testing this I check a (tiny) SO file instead of yaml2obj-ing it
because the fact that they come out first is an implementation detail of
yaml2obj that can change in the future.
llvm-svn: 324254
2018-02-06 01:25:40 +08:00
|
|
|
ModuleSpec Spec;
|
|
|
|
ASSERT_TRUE(Specs.GetModuleSpecAtIndex(0, Spec)) ;
|
|
|
|
UUID Uuid;
|
2020-06-02 04:43:18 +08:00
|
|
|
Uuid.SetFromStringRef("1b8a73ac238390e32a7ff4ac8ebe4d6a41ecf5c9");
|
Fix parsing of object files with "early" section headers
ObjectFileELF::GetModuleSpecifications contained a lot of tip-toing code
which was trying to avoid loading the full object file into memory. It
did this by trying to load data only up to the offset if was accessing.
However, in practice this was useless, as 99% of object files we
encounter have section headers at the end, so we would load the whole
file as soon as we start parsing the section headers.
In fact, this would break as soon as we encounter a file which does
*not* have section headers at the end (yaml2obj produces these), as the
access to .strtab (which we need to get the section names) was not
guarded by this offset check.
As this strategy was completely ineffective anyway, I do not attempt to
proliferate it further by guarding the .strtab accesses. Instead I just
lead the full file as soon as we are reasonably sure that we are indeed
processing an elf file.
If we really care about the load size here, we would need to reimplement
this to just load the bits of the object file we need, instead of
loading everything from the start of the object file to the given
offset. However, given that the OS will do this for us for free when
using mmap, I think think this is really necessary.
For testing this I check a (tiny) SO file instead of yaml2obj-ing it
because the fact that they come out first is an implementation detail of
yaml2obj that can change in the future.
llvm-svn: 324254
2018-02-06 01:25:40 +08:00
|
|
|
EXPECT_EQ(Spec.GetUUID(), Uuid);
|
|
|
|
}
|
Explicitly set entry point arch when it's thumb [Second Try]
Summary:
This is a redo of D68069 because I reverted it due to some concerns that were now addressed along with the new comments that @labath added.
I found a case where the main android binary (app_process32) had thumb code at its entry point but no entry in the symbol table indicating this. This made lldb set a 4 byte breakpoint at that address (we default to arm code) instead of a 2 byte one (like we should for thumb).
The big deal with this is that the expression evaluator uses the entry point as a way to know when a JITed expression has finished executing by putting a breakpoint there. Because of this, evaluating expressions on certain android devices (Google Pixel something) made the process crash.
This was fixed by checking this specific situation when we parse the symbol table and add an artificial symbol for this 2 byte range and indicating that it's arm thumb.
I created 2 unit tests for this, one to check that now we know that the entry point is arm thumb, and the other to make sure we didn't change the behaviour for arm code.
I also run the following on the command line with the `app_process32` where I found the issue:
**Before:**
```
(lldb) dis -s 0x1640 -e 0x1644
app_process32[0x1640]: .long 0xf0004668 ; unknown opcode
```
**After:**
```
(lldb) dis -s 0x1640 -e 0x1644
app_process32`:
app_process32[0x1640] <+0>: mov r0, sp
app_process32[0x1642]: andeq r0, r0, r0
```
Reviewers: clayborg, labath, wallace, espindola
Reviewed By: labath
Subscribers: labath, lldb-commits, MaskRay, kristof.beyls, arichardson, emaste, srhines
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D68533
llvm-svn: 374132
2019-10-09 07:44:49 +08:00
|
|
|
|
|
|
|
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());
|
|
|
|
|
2020-07-10 05:14:36 +08:00
|
|
|
auto module_sp = std::make_shared<Module>(ExpectedFile->moduleSpec());
|
Explicitly set entry point arch when it's thumb [Second Try]
Summary:
This is a redo of D68069 because I reverted it due to some concerns that were now addressed along with the new comments that @labath added.
I found a case where the main android binary (app_process32) had thumb code at its entry point but no entry in the symbol table indicating this. This made lldb set a 4 byte breakpoint at that address (we default to arm code) instead of a 2 byte one (like we should for thumb).
The big deal with this is that the expression evaluator uses the entry point as a way to know when a JITed expression has finished executing by putting a breakpoint there. Because of this, evaluating expressions on certain android devices (Google Pixel something) made the process crash.
This was fixed by checking this specific situation when we parse the symbol table and add an artificial symbol for this 2 byte range and indicating that it's arm thumb.
I created 2 unit tests for this, one to check that now we know that the entry point is arm thumb, and the other to make sure we didn't change the behaviour for arm code.
I also run the following on the command line with the `app_process32` where I found the issue:
**Before:**
```
(lldb) dis -s 0x1640 -e 0x1644
app_process32[0x1640]: .long 0xf0004668 ; unknown opcode
```
**After:**
```
(lldb) dis -s 0x1640 -e 0x1644
app_process32`:
app_process32[0x1640] <+0>: mov r0, sp
app_process32[0x1642]: andeq r0, r0, r0
```
Reviewers: clayborg, labath, wallace, espindola
Reviewed By: labath
Subscribers: labath, lldb-commits, MaskRay, kristof.beyls, arichardson, emaste, srhines
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D68533
llvm-svn: 374132
2019-10-09 07:44:49 +08:00
|
|
|
|
|
|
|
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());
|
|
|
|
|
2020-07-10 05:14:36 +08:00
|
|
|
auto module_sp = std::make_shared<Module>(ExpectedFile->moduleSpec());
|
Explicitly set entry point arch when it's thumb [Second Try]
Summary:
This is a redo of D68069 because I reverted it due to some concerns that were now addressed along with the new comments that @labath added.
I found a case where the main android binary (app_process32) had thumb code at its entry point but no entry in the symbol table indicating this. This made lldb set a 4 byte breakpoint at that address (we default to arm code) instead of a 2 byte one (like we should for thumb).
The big deal with this is that the expression evaluator uses the entry point as a way to know when a JITed expression has finished executing by putting a breakpoint there. Because of this, evaluating expressions on certain android devices (Google Pixel something) made the process crash.
This was fixed by checking this specific situation when we parse the symbol table and add an artificial symbol for this 2 byte range and indicating that it's arm thumb.
I created 2 unit tests for this, one to check that now we know that the entry point is arm thumb, and the other to make sure we didn't change the behaviour for arm code.
I also run the following on the command line with the `app_process32` where I found the issue:
**Before:**
```
(lldb) dis -s 0x1640 -e 0x1644
app_process32[0x1640]: .long 0xf0004668 ; unknown opcode
```
**After:**
```
(lldb) dis -s 0x1640 -e 0x1644
app_process32`:
app_process32[0x1640] <+0>: mov r0, sp
app_process32[0x1642]: andeq r0, r0, r0
```
Reviewers: clayborg, labath, wallace, espindola
Reviewed By: labath
Subscribers: labath, lldb-commits, MaskRay, kristof.beyls, arichardson, emaste, srhines
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D68533
llvm-svn: 374132
2019-10-09 07:44:49 +08:00
|
|
|
|
|
|
|
auto entry_point_addr = module_sp->GetObjectFile()->GetEntryPointAddress();
|
|
|
|
ASSERT_EQ(entry_point_addr.GetAddressClass(), AddressClass::eCode);
|
2020-06-02 04:43:18 +08:00
|
|
|
}
|