Skip to content

Commit

Permalink
Implement DDR support for AArch64 macOS
Browse files Browse the repository at this point in the history
This commit adds support for AArch64 core files on macOS in DDR.

Signed-off-by: KONNO Kazuhiro <konno@jp.ibm.com>
  • Loading branch information
knn-k committed Apr 27, 2022
1 parent 4e80e32 commit dc9f171
Show file tree
Hide file tree
Showing 3 changed files with 184 additions and 76 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2019, 2019 IBM Corp. and others
* Copyright (c) 2019, 2022 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -116,7 +116,7 @@ public void readLcString(ImageInputStream stream) throws IOException {
long currentOffset = stream.getStreamPosition();
stream.seek(absoluteOffset + offset);
int stringSize = (int) (cmdSize - offset);
byte stringBytes[] = new byte[stringSize];
byte[] stringBytes = new byte[stringSize];
stream.readFully(stringBytes);
value = getStringFromAsciiChars(stringBytes);
stream.seek(currentOffset);
Expand Down Expand Up @@ -166,7 +166,7 @@ public LoadCommand readCommand(ImageInputStream stream, long streamSegmentOffset
return this;
}

public static LoadCommand readFullCommand(ImageInputStream stream, long streamOffset, long segmentOffset) throws IOException
public static LoadCommand readFullCommand(ImageInputStream stream, long streamOffset, long segmentOffset, int cpuType) throws IOException
{
LoadCommand command;
stream.seek(streamOffset);
Expand Down Expand Up @@ -197,7 +197,7 @@ public static LoadCommand readFullCommand(ImageInputStream stream, long streamOf
break;
case LC_THREAD:
case LC_UNIXTHREAD:
command = new ThreadCommand();
command = new ThreadCommand(cpuType);
break;
case LC_ROUTINES_64:
command = new RoutinesCommand64();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2019, 2019 IBM Corp. and others
* Copyright (c) 2019, 2022 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -130,8 +130,9 @@ public class MachoDumpReader extends AbstractCoreReader implements ILibraryDepen
private static final int MH_NO_HEAP_EXECUTION = 0x1000000;
private static final int MH_APP_EXTENSION_SAFE = 0x02000000;

private static final int CPU_TYPE_X86 = 0x7;
private static final int CPU_TYPE_X86_64 = 0x01000007;
static final int CPU_TYPE_X86 = 0x7;
static final int CPU_TYPE_X86_64 = 0x01000007;
static final int CPU_TYPE_AARCH64 = 0x0100000c;

private static final int header64Size = 32;
private static final int loadCommandSize = 8;
Expand All @@ -145,7 +146,7 @@ public class MachoDumpReader extends AbstractCoreReader implements ILibraryDepen
private IModule _executable;
private List<IModule> _modules;
private int _signalNumber = -1;

public class MachHeader64
{
public int magic;
Expand Down Expand Up @@ -200,10 +201,10 @@ public Collection<? extends IMemorySource> getMemoryRangesWithOffset(long vmAddr
}
}

public class OSXThread implements IOSThread
public abstract static class OSXThread implements IOSThread
{

private final Map<String, Number> registers;
final Map<String, Number> registers;
private final Properties properties;
private final long threadId;
private final List<IMemoryRange> memoryRanges = new LinkedList<>();
Expand All @@ -214,7 +215,7 @@ public OSXThread(long tid, ThreadCommand thread)
threadId = tid;
registers = new TreeMap<>();
// Since IOSThread doesn't have a sense of the different types of registers for a thread,
// we add all the registers to the OSXThread. The registers all have different names, so
// we add all the registers to the OSXThread. The registers all have different names, so
// there should be no conflict.
for (ThreadState state : thread.states) {
registers.putAll(state.registers);
Expand Down Expand Up @@ -249,6 +250,19 @@ public Collection<? extends IMemoryRange> getMemoryRanges()
return memoryRanges;
}

public Properties getProperties()
{
return properties;
}
}

public static final class OSXAMD64Thread extends OSXThread
{
public OSXAMD64Thread(long tid, ThreadCommand thread)
{
super(tid, thread);
}

public long getInstructionPointer()
{
return registers.get("rip").longValue();
Expand All @@ -263,10 +277,28 @@ public long getStackPointer()
{
return registers.get("rsp").longValue();
}
}

public Properties getProperties()
public static final class OSXAArch64Thread extends OSXThread
{
public OSXAArch64Thread(long tid, ThreadCommand thread)
{
return properties;
super(tid, thread);
}

public long getInstructionPointer()
{
return registers.get("pc").longValue();
}

public long getBasePointer()
{
return registers.get("fp").longValue();
}

public long getStackPointer()
{
return registers.get("sp").longValue();
}
}

Expand Down Expand Up @@ -365,16 +397,28 @@ public long getProcessId()
public List<? extends IOSThread> getThreads() throws CorruptDataException
{
List<IOSThread> threads = new ArrayList<>(dumpFile.threads.size());
int cpuType = dumpFile.header.cpuType;
for (ThreadCommand command : dumpFile.threads) {
OSXThread nativeThread = new OSXThread(0, command);
threads.add(nativeThread);
if (_signalNumber == -1) {
// will use the first thread's exception values, which should be the primary thread
if (nativeThread.registers.containsKey("err")) {
_signalNumber = nativeThread.registers.get("err").intValue();
} else {
throw new CorruptDataException("Core dump missing thread exception registers.");
}
OSXThread nativeThread;
switch (cpuType) {
case CPU_TYPE_X86_64:
nativeThread = new OSXAMD64Thread(0, command);
break;
case CPU_TYPE_AARCH64:
nativeThread = new OSXAArch64Thread(0, command);
break;
default:
throw new CorruptDataException("Unrecognized CPU type.");
}
threads.add(nativeThread);
if (_signalNumber == -1) {
// will use the first thread's exception values, which should be the primary thread
String sigNumReg = (cpuType == CPU_TYPE_X86_64) ? "err" : "esr";
if (nativeThread.registers.containsKey(sigNumReg)) {
_signalNumber = nativeThread.registers.get(sigNumReg).intValue();
} else {
throw new CorruptDataException("Core dump missing thread exception registers.");
}
}
}
return threads;
Expand Down Expand Up @@ -451,7 +495,7 @@ public MachFile64 readMachFile(long fileOffset) throws IOException, InvalidDumpF
}
long currentOffset = fileOffset + header64Size;
for (int i = 0; i < machfile.header.numCommands; i++) {
LoadCommand command = LoadCommand.readFullCommand(_fileReader, currentOffset, fileOffset);
LoadCommand command = LoadCommand.readFullCommand(_fileReader, currentOffset, fileOffset, machfile.header.cpuType);
if (command instanceof SegmentCommand64) {
SegmentCommand64 segment = (SegmentCommand64) command;
machfile.segments.add(segment);
Expand Down Expand Up @@ -512,6 +556,9 @@ private String getCpuType()
if (dumpFile.header.cpuType == CPU_TYPE_X86_64) {
return "X86_64";
}
else if (dumpFile.header.cpuType == CPU_TYPE_AARCH64) {
return "AARCH64";
}
else {
return "";
}
Expand Down
Loading

0 comments on commit dc9f171

Please sign in to comment.