Skip to content

Commit a059afa

Browse files
authored
[lldb] Fix reading 32-bit signed integers (llvm#169150)
Both `Target::ReadSignedIntegerFromMemory()` and `Process::ReadSignedIntegerFromMemory()` internally created an unsigned scalar, so extending the value later did not duplicate the sign bit.
1 parent bf43b95 commit a059afa

File tree

3 files changed

+77
-6
lines changed

3 files changed

+77
-6
lines changed

lldb/source/Target/Process.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2452,8 +2452,10 @@ size_t Process::ReadScalarIntegerFromMemory(addr_t addr, uint32_t byte_size,
24522452
scalar = data.GetMaxU32(&offset, byte_size);
24532453
else
24542454
scalar = data.GetMaxU64(&offset, byte_size);
2455-
if (is_signed)
2455+
if (is_signed) {
2456+
scalar.MakeSigned();
24562457
scalar.SignExtend(byte_size * 8);
2458+
}
24572459
return bytes_read;
24582460
}
24592461
} else {

lldb/source/Target/Target.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2283,8 +2283,10 @@ size_t Target::ReadScalarIntegerFromMemory(const Address &addr, uint32_t byte_si
22832283
else
22842284
scalar = data.GetMaxU64(&offset, byte_size);
22852285

2286-
if (is_signed)
2286+
if (is_signed) {
2287+
scalar.MakeSigned();
22872288
scalar.SignExtend(byte_size * 8);
2289+
}
22882290
return bytes_read;
22892291
}
22902292
} else {
@@ -2299,7 +2301,7 @@ int64_t Target::ReadSignedIntegerFromMemory(const Address &addr,
22992301
int64_t fail_value, Status &error,
23002302
bool force_live_memory) {
23012303
Scalar scalar;
2302-
if (ReadScalarIntegerFromMemory(addr, integer_byte_size, false, scalar, error,
2304+
if (ReadScalarIntegerFromMemory(addr, integer_byte_size, true, scalar, error,
23032305
force_live_memory))
23042306
return scalar.SLongLong(fail_value);
23052307
return fail_value;

lldb/unittests/Target/MemoryTest.cpp

Lines changed: 70 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ class DummyProcess : public Process {
4848
}
4949
Status DoDestroy() override { return {}; }
5050
void RefreshStateAfterStop() override {}
51+
// Required by Target::ReadMemory() to call Process::ReadMemory()
52+
bool IsAlive() override { return true; }
5153
size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
5254
Status &error) override {
5355
if (m_bytes_left == 0)
@@ -61,7 +63,7 @@ class DummyProcess : public Process {
6163
m_bytes_left -= size;
6264
}
6365

64-
memset(buf, 'B', num_bytes_to_write);
66+
memset(buf, m_filler, num_bytes_to_write);
6567
return num_bytes_to_write;
6668
}
6769
bool DoUpdateThreadList(ThreadList &old_thread_list,
@@ -72,8 +74,10 @@ class DummyProcess : public Process {
7274

7375
// Test-specific additions
7476
size_t m_bytes_left;
77+
int m_filler = 'B';
7578
MemoryCache &GetMemoryCache() { return m_memory_cache; }
7679
void SetMaxReadSize(size_t size) { m_bytes_left = size; }
80+
void SetFiller(int filler) { m_filler = filler; }
7781
};
7882
} // namespace
7983

@@ -85,6 +89,18 @@ TargetSP CreateTarget(DebuggerSP &debugger_sp, ArchSpec &arch) {
8589
return target_sp;
8690
}
8791

92+
static ProcessSP CreateProcess(lldb::TargetSP target_sp) {
93+
ListenerSP listener_sp(Listener::MakeListener("dummy"));
94+
ProcessSP process_sp = std::make_shared<DummyProcess>(target_sp, listener_sp);
95+
96+
struct TargetHack : public Target {
97+
void SetProcess(ProcessSP process) { m_process_sp = process; }
98+
};
99+
static_cast<TargetHack *>(target_sp.get())->SetProcess(process_sp);
100+
101+
return process_sp;
102+
}
103+
88104
TEST_F(MemoryTest, TesetMemoryCacheRead) {
89105
ArchSpec arch("x86_64-apple-macosx-");
90106

@@ -96,8 +112,7 @@ TEST_F(MemoryTest, TesetMemoryCacheRead) {
96112
TargetSP target_sp = CreateTarget(debugger_sp, arch);
97113
ASSERT_TRUE(target_sp);
98114

99-
ListenerSP listener_sp(Listener::MakeListener("dummy"));
100-
ProcessSP process_sp = std::make_shared<DummyProcess>(target_sp, listener_sp);
115+
ProcessSP process_sp = CreateProcess(target_sp);
101116
ASSERT_TRUE(process_sp);
102117

103118
DummyProcess *process = static_cast<DummyProcess *>(process_sp.get());
@@ -227,6 +242,58 @@ TEST_F(MemoryTest, TesetMemoryCacheRead) {
227242
// old cache
228243
}
229244

245+
TEST_F(MemoryTest, TestReadInteger) {
246+
ArchSpec arch("x86_64-apple-macosx-");
247+
248+
Platform::SetHostPlatform(PlatformRemoteMacOSX::CreateInstance(true, &arch));
249+
250+
DebuggerSP debugger_sp = Debugger::CreateInstance();
251+
ASSERT_TRUE(debugger_sp);
252+
253+
TargetSP target_sp = CreateTarget(debugger_sp, arch);
254+
ASSERT_TRUE(target_sp);
255+
256+
ProcessSP process_sp = CreateProcess(target_sp);
257+
ASSERT_TRUE(process_sp);
258+
259+
DummyProcess *process = static_cast<DummyProcess *>(process_sp.get());
260+
Status error;
261+
262+
process->SetFiller(0xff);
263+
process->SetMaxReadSize(256);
264+
// The ReadSignedIntegerFromMemory() methods return int64_t. Check that they
265+
// extend the sign correctly when reading 32-bit values.
266+
EXPECT_EQ(-1,
267+
target_sp->ReadSignedIntegerFromMemory(Address(0), 4, 0, error));
268+
EXPECT_EQ(-1, process->ReadSignedIntegerFromMemory(0, 4, 0, error));
269+
// Check reading 64-bit values as well.
270+
EXPECT_EQ(-1,
271+
target_sp->ReadSignedIntegerFromMemory(Address(0), 8, 0, error));
272+
EXPECT_EQ(-1, process->ReadSignedIntegerFromMemory(0, 8, 0, error));
273+
274+
// ReadUnsignedIntegerFromMemory() should not extend the sign.
275+
EXPECT_EQ(0xffffffffULL,
276+
target_sp->ReadUnsignedIntegerFromMemory(Address(0), 4, 0, error));
277+
EXPECT_EQ(0xffffffffULL,
278+
process->ReadUnsignedIntegerFromMemory(0, 4, 0, error));
279+
EXPECT_EQ(0xffffffffffffffffULL,
280+
target_sp->ReadUnsignedIntegerFromMemory(Address(0), 8, 0, error));
281+
EXPECT_EQ(0xffffffffffffffffULL,
282+
process->ReadUnsignedIntegerFromMemory(0, 8, 0, error));
283+
284+
// Check reading positive values.
285+
process->GetMemoryCache().Clear();
286+
process->SetFiller(0x7f);
287+
process->SetMaxReadSize(256);
288+
EXPECT_EQ(0x7f7f7f7fLL,
289+
target_sp->ReadSignedIntegerFromMemory(Address(0), 4, 0, error));
290+
EXPECT_EQ(0x7f7f7f7fLL, process->ReadSignedIntegerFromMemory(0, 4, 0, error));
291+
EXPECT_EQ(0x7f7f7f7f7f7f7f7fLL,
292+
target_sp->ReadSignedIntegerFromMemory(Address(0), 8, 0, error));
293+
EXPECT_EQ(0x7f7f7f7f7f7f7f7fLL,
294+
process->ReadSignedIntegerFromMemory(0, 8, 0, error));
295+
}
296+
230297
/// A process class that, when asked to read memory from some address X, returns
231298
/// the least significant byte of X.
232299
class DummyReaderProcess : public Process {

0 commit comments

Comments
 (0)