mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 03:50:02 +02:00
GP-1005: Added new agent for lldb on macOS and Linux
This commit is contained in:
parent
a79d2578a9
commit
51cd51d658
469 changed files with 87645 additions and 8 deletions
|
@ -50,11 +50,15 @@ task testSpecimenLinux_x86_64 {
|
|||
//dependsOn 'expCloneSpinExecutable'//Linux_x86_64Executable'
|
||||
dependsOn 'expForkExecutable'//Linux_x86_64Executable'
|
||||
dependsOn 'expPrintLinux_x86_64Executable'
|
||||
dependsOn 'expSpinLinux_x86_64Executable'
|
||||
//dependsOn 'expTypesExecutable'//Linux_x86_64Executable'
|
||||
dependsOn 'expRegistersLinux_x86_64Executable'
|
||||
dependsOn 'expStackLinux_x86_64Executable'
|
||||
}
|
||||
|
||||
// TODO: testSpecimenMac_x86_64 (Intel)
|
||||
// will likely need to codesign them to grant debugee-entitlement
|
||||
|
||||
model {
|
||||
components {
|
||||
expCreateProcess(NativeExecutableSpec) {
|
||||
|
@ -92,6 +96,7 @@ model {
|
|||
targetPlatform "win_x86_32" // TODO: Test on these
|
||||
}
|
||||
expSpin(NativeExecutableSpec) {
|
||||
targetPlatform "linux_x86_64"
|
||||
targetPlatform "win_x86_64"
|
||||
targetPlatform "win_x86_32" // TODO: Test on these
|
||||
}
|
||||
|
|
|
@ -13,10 +13,20 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifdef WIN32
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow) {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
Sleep(1000);
|
||||
}
|
||||
}
|
||||
#else
|
||||
int main(int argc, char** argv) {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -114,6 +114,15 @@ public abstract class AbstractDebuggerModelRegistersTest extends AbstractDebugge
|
|||
return m.findWithIndex(TargetRegisterBank.class, "0", seedPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param seedPath the path to the target or thread
|
||||
* @return the set of banks
|
||||
* @throws Throwable if anything goes wrong
|
||||
*/
|
||||
protected Map<List<String>, TargetRegisterBank> findRegisterBanks(List<String> seedPath) throws Throwable {
|
||||
return m.findAll(TargetRegisterBank.class, seedPath, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegisterBankIsWhereExpected() throws Throwable {
|
||||
m.build();
|
||||
|
|
|
@ -75,6 +75,25 @@ public abstract class AbstractDebuggerModelScenarioRegistersTest extends Abstrac
|
|||
*/
|
||||
protected abstract Map<String, byte[]> getRegisterWrites();
|
||||
|
||||
/**
|
||||
* Perform the register writing portion of the test
|
||||
*
|
||||
* <p>
|
||||
* TODO: It is necessary to override this for LLDB, since it presents its registers in various
|
||||
* "sub" banks. For it, we need to search the banks for each register to write, and delegate to
|
||||
* the appropriate bank.
|
||||
*
|
||||
* @param toWrite
|
||||
*
|
||||
* @param the trapped thread
|
||||
*/
|
||||
protected void performRegisterWrites(TargetObject target, Map<String, byte[]> toWrite)
|
||||
throws Throwable {
|
||||
TargetRegisterBank bank = Objects
|
||||
.requireNonNull(m.findWithIndex(TargetRegisterBank.class, "0", target.getPath()));
|
||||
waitOn(bank.writeRegistersNamed(toWrite));
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify, using {@link Assert}, that the target exhibited the effect of the register write
|
||||
*
|
||||
|
@ -165,10 +184,8 @@ public abstract class AbstractDebuggerModelScenarioRegistersTest extends Abstrac
|
|||
TargetObject target = waitOn(bpMonitor.trapped);
|
||||
|
||||
Map<String, byte[]> toWrite = getRegisterWrites();
|
||||
TargetRegisterBank bank = Objects
|
||||
.requireNonNull(m.findWithIndex(TargetRegisterBank.class, "0", target.getPath()));
|
||||
Msg.debug(this, "Writing registers: " + toWrite.keySet());
|
||||
waitOn(bank.writeRegistersNamed(toWrite));
|
||||
performRegisterWrites(target, toWrite);
|
||||
Msg.debug(this, " Done");
|
||||
|
||||
assertTrue(DebugModelConventions.isProcessAlive(process));
|
||||
|
|
|
@ -17,6 +17,7 @@ package ghidra.dbg.test;
|
|||
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.function.Function;
|
||||
|
||||
import ghidra.dbg.DebuggerModelFactory;
|
||||
import ghidra.dbg.DebuggerObjectModel;
|
||||
|
@ -231,8 +232,16 @@ public abstract class AbstractModelHost implements ModelHost, DebuggerModelTestU
|
|||
@Override
|
||||
public <T extends TargetObject> NavigableMap<List<String>, T> findAll(Class<T> cls,
|
||||
List<String> seedPath, boolean atLeastOne) throws Throwable {
|
||||
PathMatcher matcher =
|
||||
model.getRootSchema().getSuccessorSchema(seedPath).searchFor(cls, seedPath, false);
|
||||
return findAll(cls, seedPath, pred -> pred, atLeastOne);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends TargetObject> NavigableMap<List<String>, T> findAll(Class<T> cls,
|
||||
List<String> seedPath, Function<PathPredicates, PathPredicates> adjustPredicates,
|
||||
boolean atLeastOne) throws Throwable {
|
||||
PathPredicates matcher = adjustPredicates.apply(model.getRootSchema()
|
||||
.getSuccessorSchema(seedPath)
|
||||
.searchFor(cls, seedPath, false));
|
||||
if (matcher.isEmpty()) {
|
||||
return new TreeMap<>();
|
||||
}
|
||||
|
@ -244,7 +253,10 @@ public abstract class AbstractModelHost implements ModelHost, DebuggerModelTestU
|
|||
// During testing, we should expend the energy to verify the heap.
|
||||
NavigableMap<List<String>, T> result = new TreeMap<>(PathComparator.KEYED);
|
||||
for (Entry<List<String>, ?> ent : found.entrySet()) {
|
||||
result.put(ent.getKey(), cls.cast(ent.getValue()));
|
||||
//TODO GP-1301
|
||||
if (cls.isInstance(ent.getValue())) {
|
||||
result.put(ent.getKey(), cls.cast(ent.getValue()));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -17,9 +17,11 @@ package ghidra.dbg.testutil;
|
|||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
import ghidra.dbg.DebuggerObjectModel;
|
||||
import ghidra.dbg.target.TargetObject;
|
||||
import ghidra.dbg.util.PathPredicates;
|
||||
|
||||
public interface TestDebuggerModelProvider {
|
||||
interface ModelHost extends AutoCloseable {
|
||||
|
@ -83,6 +85,10 @@ public interface TestDebuggerModelProvider {
|
|||
<T extends TargetObject> Map<List<String>, T> findAll(Class<T> cls, List<String> seedPath,
|
||||
boolean atLeastOne) throws Throwable;
|
||||
|
||||
<T extends TargetObject> Map<List<String>, T> findAll(Class<T> cls, List<String> seedPath,
|
||||
Function<PathPredicates, PathPredicates> adjustPredicates, boolean atLeastOne)
|
||||
throws Throwable;
|
||||
|
||||
TargetObject findContainer(Class<? extends TargetObject> cls, List<String> seedPath)
|
||||
throws Throwable;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue