Sections now support specifying: - user IDs - file offset/size - alignment - flags - bool values for fake, encrypted and thread specific sections
242 lines
10 KiB
Python
242 lines
10 KiB
Python
import lldb
|
|
from lldbsuite.test.decorators import *
|
|
from lldbsuite.test.lldbtest import *
|
|
from lldbsuite.test import lldbutil
|
|
|
|
import json
|
|
import uuid
|
|
import os
|
|
import shutil
|
|
import time
|
|
|
|
|
|
class TestObjectFileJSON(TestBase):
|
|
TRIPLE = "arm64-apple-macosx13.0.0"
|
|
|
|
def setUp(self):
|
|
TestBase.setUp(self)
|
|
self.source = "main.c"
|
|
|
|
def emitJSON(self, data, path):
|
|
json_object = json.dumps(data, indent=4)
|
|
with open(path, "w") as outfile:
|
|
outfile.write(json_object)
|
|
|
|
def toModuleSpec(self, path):
|
|
module_spec = lldb.SBModuleSpec()
|
|
module_spec.SetFileSpec(lldb.SBFileSpec(path))
|
|
return module_spec
|
|
|
|
@no_debug_info_test
|
|
def test_target(self):
|
|
triple = "arm64-apple-macosx13.0.0"
|
|
data = {
|
|
"triple": triple,
|
|
"uuid": str(uuid.uuid4()),
|
|
"type": "executable",
|
|
}
|
|
|
|
json_object_file = self.getBuildArtifact("a.json")
|
|
self.emitJSON(data, json_object_file)
|
|
|
|
target = self.dbg.CreateTarget(json_object_file)
|
|
self.assertTrue(target.IsValid())
|
|
self.assertEqual(target.GetTriple(), triple)
|
|
|
|
@no_debug_info_test
|
|
def test_module(self):
|
|
self.build()
|
|
exe = self.getBuildArtifact("a.out")
|
|
target = self.dbg.CreateTarget(exe)
|
|
|
|
data = {
|
|
"triple": target.GetTriple(),
|
|
"uuid": str(uuid.uuid4()),
|
|
}
|
|
|
|
json_object_file_b = self.getBuildArtifact("b.json")
|
|
self.emitJSON(data, json_object_file_b)
|
|
|
|
module = target.AddModule(self.toModuleSpec(json_object_file_b))
|
|
self.assertFalse(module.IsValid())
|
|
TEXT_file_addr = 0x100000000
|
|
DATA_file_addr = 0x100001000
|
|
foo_file_addr = TEXT_file_addr + 0x100
|
|
bar_file_addr = DATA_file_addr + 0x10
|
|
TEXT_size = 0x222
|
|
text_size = 0x20
|
|
DATA_size = 0x333
|
|
foo_size = 0x11
|
|
bar_size = 0x22
|
|
slide = 0x100000000
|
|
data = {
|
|
"triple": target.GetTriple(),
|
|
"uuid": str(uuid.uuid4()),
|
|
"type": "sharedlibrary",
|
|
"sections": [
|
|
{
|
|
"user_id": 0x100,
|
|
"name": "__PAGEZERO",
|
|
"type": "container",
|
|
"address": 0,
|
|
"size": 0x100000000,
|
|
"flags": 0x101
|
|
},
|
|
{
|
|
"user_id": 0x200,
|
|
"name": "__TEXT",
|
|
"type": "container",
|
|
"address": TEXT_file_addr,
|
|
"size": TEXT_size,
|
|
"flags": 0x202,
|
|
"file_offset": 0,
|
|
"file_size": TEXT_size,
|
|
"read": True,
|
|
"write": False,
|
|
"execute": True,
|
|
"subsections": [
|
|
{
|
|
"name": "__text",
|
|
"type": "code",
|
|
"address": TEXT_file_addr,
|
|
"size": text_size,
|
|
"alignment": 2,
|
|
"read": True,
|
|
"write": False,
|
|
"execute": True,
|
|
},
|
|
{
|
|
"name": "__fake",
|
|
"address": TEXT_file_addr + 1 * text_size,
|
|
"size": text_size,
|
|
"fake": True
|
|
},
|
|
{
|
|
"name": "__encrypted",
|
|
"address": TEXT_file_addr + 2 * text_size,
|
|
"size": text_size,
|
|
"encrypted": True
|
|
},
|
|
{
|
|
"name": "__tls",
|
|
"address": TEXT_file_addr + 2 * text_size,
|
|
"size": text_size,
|
|
"thread_specific": True
|
|
}
|
|
],
|
|
},
|
|
{
|
|
"name": "__DATA",
|
|
"type": "data",
|
|
"address": DATA_file_addr,
|
|
"size": DATA_size,
|
|
"read": True,
|
|
"write": True,
|
|
"execute": False,
|
|
"flags": 0x303,
|
|
"file_offset": DATA_file_addr - TEXT_file_addr,
|
|
"file_size": DATA_size,
|
|
},
|
|
],
|
|
"symbols": [
|
|
{
|
|
"name": "foo",
|
|
"type": "code",
|
|
"address": foo_file_addr,
|
|
"size": foo_size,
|
|
},
|
|
{
|
|
"name": "bar",
|
|
"type": "data",
|
|
"address": bar_file_addr,
|
|
"size": bar_size,
|
|
},
|
|
],
|
|
}
|
|
|
|
json_object_file_c = self.getBuildArtifact("c.json")
|
|
self.emitJSON(data, json_object_file_c)
|
|
|
|
module = target.AddModule(self.toModuleSpec(json_object_file_c))
|
|
self.assertTrue(module.IsValid())
|
|
|
|
TEXT_section = module.GetSectionAtIndex(0)
|
|
self.assertTrue(TEXT_section.IsValid())
|
|
self.assertEqual(TEXT_section.GetName(), "__PAGEZERO")
|
|
self.assertEqual(TEXT_section.file_addr, 0)
|
|
self.assertEqual(TEXT_section.size, 0x100000000)
|
|
self.assertEqual(TEXT_section.GetSectionType(), lldb.eSectionTypeContainer)
|
|
self.assertEqual(TEXT_section.GetNumSubSections(), 0)
|
|
text_permissions = TEXT_section.GetPermissions()
|
|
self.assertFalse((text_permissions & lldb.ePermissionsReadable) != 0)
|
|
self.assertFalse((text_permissions & lldb.ePermissionsWritable) != 0)
|
|
self.assertFalse((text_permissions & lldb.ePermissionsExecutable) != 0)
|
|
|
|
TEXT_section = module.GetSectionAtIndex(1)
|
|
self.assertTrue(TEXT_section.IsValid())
|
|
self.assertEqual(TEXT_section.GetName(), "__TEXT")
|
|
self.assertEqual(TEXT_section.file_addr, TEXT_file_addr)
|
|
self.assertEqual(TEXT_section.size, TEXT_size)
|
|
self.assertEqual(TEXT_section.file_offset, 0)
|
|
self.assertEqual(TEXT_section.file_size, TEXT_size)
|
|
self.assertEqual(TEXT_section.GetSectionType(), lldb.eSectionTypeContainer)
|
|
self.assertEqual(TEXT_section.GetNumSubSections(), 4)
|
|
text_permissions = TEXT_section.GetPermissions()
|
|
self.assertTrue((text_permissions & lldb.ePermissionsReadable) != 0)
|
|
self.assertFalse((text_permissions & lldb.ePermissionsWritable) != 0)
|
|
self.assertTrue((text_permissions & lldb.ePermissionsExecutable) != 0)
|
|
|
|
text_section = TEXT_section.GetSubSectionAtIndex(0)
|
|
self.assertEqual(text_section.GetName(), "__text")
|
|
self.assertEqual(text_section.size, text_size)
|
|
self.assertEqual(text_section.GetAlignment(), 4)
|
|
self.assertEqual(text_section.GetSectionType(), lldb.eSectionTypeCode)
|
|
self.assertEqual(text_section.GetNumSubSections(), 0)
|
|
text_permissions = text_section.GetPermissions()
|
|
self.assertTrue((text_permissions & lldb.ePermissionsReadable) != 0)
|
|
self.assertFalse((text_permissions & lldb.ePermissionsWritable) != 0)
|
|
self.assertTrue((text_permissions & lldb.ePermissionsExecutable) != 0)
|
|
|
|
DATA_section = module.GetSectionAtIndex(2)
|
|
self.assertTrue(DATA_section.IsValid())
|
|
self.assertEqual(DATA_section.GetName(), "__DATA")
|
|
self.assertEqual(DATA_section.file_addr, DATA_file_addr)
|
|
self.assertEqual(DATA_section.size, DATA_size)
|
|
self.assertEqual(DATA_section.file_offset, DATA_file_addr - TEXT_file_addr)
|
|
self.assertEqual(DATA_section.file_size, DATA_size)
|
|
self.assertEqual(DATA_section.GetSectionType(), lldb.eSectionTypeData)
|
|
data_permissions = DATA_section.GetPermissions()
|
|
self.assertTrue((data_permissions & lldb.ePermissionsReadable) != 0)
|
|
self.assertTrue((data_permissions & lldb.ePermissionsWritable) != 0)
|
|
self.assertFalse((data_permissions & lldb.ePermissionsExecutable) != 0)
|
|
|
|
foo_symbol = module.FindSymbol("foo")
|
|
self.assertTrue(foo_symbol.IsValid())
|
|
self.assertEqual(foo_symbol.addr.GetFileAddress(), foo_file_addr)
|
|
self.assertEqual(foo_symbol.GetSize(), foo_size)
|
|
|
|
bar_symbol = module.FindSymbol("bar")
|
|
self.assertTrue(bar_symbol.IsValid())
|
|
self.assertEqual(bar_symbol.addr.GetFileAddress(), bar_file_addr)
|
|
self.assertEqual(bar_symbol.GetSize(), bar_size)
|
|
|
|
# Verify the user_ids and flags are set correctly since there is no API
|
|
# for this on lldb.SBSection
|
|
self.expect("target modules dump sections c.json",
|
|
substrs = [
|
|
"0x0000000000000100 container [0x0000000000000000-0x0000000100000000) --- 0x00000000 0x00000000 0x00000101 c.json.__PAGEZERO",
|
|
"0x0000000000000200 container [0x0000000100000000-0x0000000100000222) r-x 0x00000000 0x00000222 0x00000202 c.json.__TEXT",
|
|
"0x0000000000000001 code [0x0000000100000000-0x0000000100000020) r-x 0x00000000 0x00000000 0x00000000 c.json.__TEXT.__text",
|
|
"0x0000000000000002 code [0x0000000100000020-0x0000000100000040) --- 0x00000000 0x00000000 0x00000000 c.json.__TEXT.__fake",
|
|
"0x0000000000000003 code [0x0000000100000040-0x0000000100000060) --- 0x00000000 0x00000000 0x00000000 c.json.__TEXT.__encrypted",
|
|
"0x0000000000000004 code [0x0000000100000040-0x0000000100000060) --- 0x00000000 0x00000000 0x00000000 c.json.__TEXT.__tls",
|
|
"0x0000000000000005 data [0x0000000100001000-0x0000000100001333) rw- 0x00001000 0x00000333 0x00000303 c.json.__DATA"
|
|
])
|
|
|
|
error = target.SetSectionLoadAddress(TEXT_section, TEXT_file_addr + slide)
|
|
self.assertSuccess(error)
|
|
error = target.SetSectionLoadAddress(DATA_section, DATA_file_addr + slide)
|
|
self.assertSuccess(error)
|
|
self.assertEqual(foo_symbol.addr.GetLoadAddress(target), foo_file_addr + slide)
|
|
self.assertEqual(bar_symbol.addr.GetLoadAddress(target), bar_file_addr + slide)
|