In #165604, a test was skipped on Windows, because the native PDB plugin didn't set sizes on symbols. While the test isn't compiled with debug info, it's linked with `-gdwarf`, causing a PDB to be created on Windows. This PDB will only contain the public symbols (written by the linker) and section information. The symbols themselves don't have a size, however the DIA SDK sets a size for them. It seems like, for these data symbols, the size given from DIA is the distance to the next symbol (or the section end). This PR implements the naive approach for the native plugin. The main difference is in function/code symbols. There, DIA searches for a corresponding `S_GPROC32` which have a "code size" that is sometimes slightly smaller than the difference to the next symbol.
111 lines
4.3 KiB
Python
111 lines
4.3 KiB
Python
"""
|
|
Test that a binary can be slid to different load addresses correctly
|
|
"""
|
|
|
|
|
|
import lldb
|
|
from lldbsuite.test.decorators import *
|
|
from lldbsuite.test.lldbtest import *
|
|
from lldbsuite.test import lldbutil
|
|
|
|
|
|
class MultipleSlidesTestCase(TestBase):
|
|
NO_DEBUG_INFO_TESTCASE = True
|
|
|
|
def test_mulitple_slides(self):
|
|
"""Test that a binary can be slid multiple times correctly."""
|
|
self.build()
|
|
exe = self.getBuildArtifact("a.out")
|
|
err = lldb.SBError()
|
|
load_dependent_modules = False
|
|
target = self.dbg.CreateTarget(exe, "", "", load_dependent_modules, err)
|
|
self.assertTrue(target.IsValid())
|
|
module = target.GetModuleAtIndex(0)
|
|
self.assertTrue(module.IsValid())
|
|
|
|
first_sym = target.FindSymbols("first").GetContextAtIndex(0).GetSymbol()
|
|
second_sym = target.FindSymbols("second").GetContextAtIndex(0).GetSymbol()
|
|
first_size = (
|
|
first_sym.GetEndAddress().GetOffset()
|
|
- first_sym.GetStartAddress().GetOffset()
|
|
)
|
|
int_size = target.FindFirstType("int").GetByteSize()
|
|
self.assertGreaterEqual(first_size, 2048 * int_size)
|
|
second_size = (
|
|
second_sym.GetEndAddress().GetOffset()
|
|
- second_sym.GetStartAddress().GetOffset()
|
|
)
|
|
self.assertGreaterEqual(second_size, 2048 * int_size)
|
|
|
|
# View the first element of `first` and `second` while
|
|
# they have no load address set.
|
|
self.expect("expression/d ((int*)&first)[0]", substrs=["= 5"])
|
|
self.expect("expression/d ((int*)&second)[0]", substrs=["= 6"])
|
|
self.assertEqual(
|
|
first_sym.GetStartAddress().GetLoadAddress(target),
|
|
lldb.LLDB_INVALID_ADDRESS,
|
|
)
|
|
self.assertEqual(
|
|
second_sym.GetStartAddress().GetLoadAddress(target),
|
|
lldb.LLDB_INVALID_ADDRESS,
|
|
)
|
|
|
|
# View the first element of `first` and `second` with
|
|
# no slide applied, but with load address set.
|
|
#
|
|
# In memory, we have something like
|
|
# 0x1000 - 0x17ff first[]
|
|
# 0x1800 - 0x1fff second[]
|
|
error = target.SetModuleLoadAddress(module, 0)
|
|
self.assertSuccess(error)
|
|
self.expect("expression/d ((int*)&first)[0]", substrs=["= 5"])
|
|
self.expect("expression/d ((int*)&second)[0]", substrs=["= 6"])
|
|
self.assertEqual(
|
|
first_sym.GetStartAddress().GetLoadAddress(target),
|
|
first_sym.GetStartAddress().GetFileAddress(),
|
|
)
|
|
self.assertEqual(
|
|
second_sym.GetStartAddress().GetLoadAddress(target),
|
|
second_sym.GetStartAddress().GetFileAddress(),
|
|
)
|
|
|
|
# Slide it a little bit less than the size of the first array.
|
|
#
|
|
# In memory, we have something like
|
|
# 0xfc0 - 0x17bf first[]
|
|
# 0x17c0 - 0x1fbf second[]
|
|
#
|
|
# but if the original entries are still present in lldb,
|
|
# the beginning address of second[] will get a load address
|
|
# of 0x1800, instead of 0x17c0 (0x1800-64) as we need to get.
|
|
error = target.SetModuleLoadAddress(module, first_size - 64)
|
|
self.assertSuccess(error)
|
|
self.expect("expression/d ((int*)&first)[0]", substrs=["= 5"])
|
|
self.expect("expression/d ((int*)&second)[0]", substrs=["= 6"])
|
|
self.assertNotEqual(
|
|
first_sym.GetStartAddress().GetLoadAddress(target),
|
|
first_sym.GetStartAddress().GetFileAddress(),
|
|
)
|
|
self.assertNotEqual(
|
|
second_sym.GetStartAddress().GetLoadAddress(target),
|
|
second_sym.GetStartAddress().GetFileAddress(),
|
|
)
|
|
|
|
# Slide it back to the original vmaddr.
|
|
error = target.SetModuleLoadAddress(module, 0)
|
|
self.assertSuccess(error)
|
|
self.expect("expression/d ((int*)&first)[0]", substrs=["= 5"])
|
|
self.expect("expression/d ((int*)&second)[0]", substrs=["= 6"])
|
|
self.assertEqual(
|
|
first_sym.GetStartAddress().GetLoadAddress(target),
|
|
first_sym.GetStartAddress().GetFileAddress(),
|
|
)
|
|
self.assertEqual(
|
|
second_sym.GetStartAddress().GetLoadAddress(target),
|
|
second_sym.GetStartAddress().GetFileAddress(),
|
|
)
|
|
|
|
# Make sure we can use a slide > INT64_MAX.
|
|
error = target.SetModuleLoadAddress(module, 0xFFFFFFFF12345678)
|
|
self.assertSuccess(error)
|