mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-10 06:02:09 +00:00
Merge tag 'Ghidra_11.1.2_build' into stable
This commit is contained in:
commit
75f08aa0b4
@ -22,6 +22,35 @@
|
||||
|
||||
<BODY>
|
||||
|
||||
<H1 align="center">Ghidra 11.1.2 Change History (July 2024)</H1>
|
||||
<blockquote><p><u><B>New Features</B></u></p>
|
||||
<ul>
|
||||
<li><I>Basic Infrastructure</I>. Ghidra native components (Decompiler, GNU Demangler, etc.) now run properly on Windows ARM using x86 emulation. Building natively for Windows ARM is not yet supported (Gradle limitation). (GP-4738)</li>
|
||||
</ul>
|
||||
</blockquote>
|
||||
<blockquote><p><u><B>Improvements</B></u></p>
|
||||
<ul>
|
||||
<li><I>Data Types</I>. Corrected resolution of typedefs whose name matches the underlying type name. (GP-4751, Issue #6493)</li>
|
||||
<li><I>Processors</I>. Made minor semantic changes to the X86 processor specification for several AVX instructions as well as changes to UDF undefined instructions. (GP-4724)</li>
|
||||
</ul>
|
||||
</blockquote>
|
||||
<blockquote><p><u><B>Bugs</B></u></p>
|
||||
<ul>
|
||||
<li><I>Data Types</I>. Fixed Structure bug where DB may not be updated properly with length change induced by certain operations (e.g., <span class="gcode">insertBitFieldAt</span>). (GP-4756)</li>
|
||||
<li><I>Data Types</I>. Fixed formatting of float value <span class="gcode">-0.0</span> within assembly Listing view. (GP-4759, Issue #6677)</li>
|
||||
<li><I>Debugger</I>. Added <span class="gcode">.bat</span> launchers for GDB and LLDB on Windows. (GP-4677)</li>
|
||||
<li><I>Debugger</I>. Fixed GDB <span class="gcode">show version</span> parse error. (GP-4698, Issue #6646)</li>
|
||||
<li><I>Debugger</I>. Fixed an issue with handling of memory read errors in GDB TraceRMI connector. (GP-4701, Issue #6647)</li>
|
||||
<li><I>Debugger</I>. Fixed GDB endianness calculation. (GP-4704, Issue #6656)</li>
|
||||
<li><I>Debugger:GDB</I>. Provided fall-back to refresh all registers when <span class="gcode">general</span> is not recognized by GDB as a register group. (GP-4710, Issue #6635)</li>
|
||||
<li><I>Importer:ELF</I>. Fixed ELF X86-64 GOT allocation bug which could cause exception during import. Also added unverified ELF relocation support for <span class="gcode">R_X86_64_GOT64</span> and <span class="gcode">R_X86_64_PLTOFF64</span>. (GP-4758, Issue #6691)</li>
|
||||
<li><I>Importer:Mach-O</I>. Fixed an issue with importing Mach-O binaries that have an empty <span class="gcode">__chain_starts</span> section. (GP-4695)</li>
|
||||
<li><I>Importer:Mach-O</I>. Fixed a regression in the MachoLoader that prevented some KDK binaries from being loaded. (GP-4699)</li>
|
||||
<li><I>Multi-User:Merge</I>. Fixed assertion error which occured for multi-user merge of register context within overlay memory blocks. (GP-4508, Issue #6403)</li>
|
||||
<li><I>Processors</I>. Fixed AARCH64 Windows stack alignment. (GP-4752, Issue #6680)</li>
|
||||
</ul>
|
||||
</blockquote>
|
||||
|
||||
<H1 align="center">Ghidra 11.1.1 Change History (June 2024)</H1>
|
||||
<blockquote><p><u><B>Bugs</B></u></p>
|
||||
<ul>
|
||||
|
@ -18,9 +18,8 @@ apply from: "$rootProject.projectDir/gradle/jacocoProject.gradle"
|
||||
apply from: "$rootProject.projectDir/gradle/javaTestProject.gradle"
|
||||
apply from: "$rootProject.projectDir/gradle/nativeProject.gradle"
|
||||
apply from: "$rootProject.projectDir/gradle/distributableGhidraModule.gradle"
|
||||
|
||||
apply from: "$rootProject.projectDir/gradle/hasPythonPackage.gradle"
|
||||
apply from: "$rootProject.projectDir/gradle/debugger/hasNodepJar.gradle"
|
||||
apply from: "$rootProject.projectDir/gradle/debugger/hasPythonPackage.gradle"
|
||||
|
||||
apply plugin: 'eclipse'
|
||||
eclipse.project.name = 'Debug Debugger-agent-dbgeng'
|
||||
|
@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "ghidradbg"
|
||||
version = "11.1"
|
||||
version = "11.1.2"
|
||||
authors = [
|
||||
{ name="Ghidra Development Team" },
|
||||
]
|
||||
@ -17,7 +17,7 @@ classifiers = [
|
||||
"Operating System :: OS Independent",
|
||||
]
|
||||
dependencies = [
|
||||
"ghidratrace==11.1",
|
||||
"ghidratrace==11.1.2",
|
||||
"pybag>=2.2.10"
|
||||
]
|
||||
|
||||
|
@ -18,9 +18,8 @@ apply from: "$rootProject.projectDir/gradle/jacocoProject.gradle"
|
||||
apply from: "$rootProject.projectDir/gradle/javaTestProject.gradle"
|
||||
apply from: "$rootProject.projectDir/gradle/nativeProject.gradle"
|
||||
apply from: "$rootProject.projectDir/gradle/distributableGhidraModule.gradle"
|
||||
|
||||
apply from: "$rootProject.projectDir/gradle/hasPythonPackage.gradle"
|
||||
apply from: "$rootProject.projectDir/gradle/debugger/hasExecutableJar.gradle"
|
||||
apply from: "$rootProject.projectDir/gradle/debugger/hasPythonPackage.gradle"
|
||||
|
||||
apply plugin: 'eclipse'
|
||||
eclipse.project.name = 'Debug Debugger-agent-gdb'
|
||||
|
@ -1,11 +1,13 @@
|
||||
##VERSION: 2.0
|
||||
##MODULE IP: JSch License
|
||||
Module.manifest||GHIDRA||||END|
|
||||
data/debugger-launchers/local-gdb.bat||GHIDRA||||END|
|
||||
data/scripts/fallback_info_proc_mappings.gdb||GHIDRA||||END|
|
||||
data/scripts/fallback_maintenance_info_sections.gdb||GHIDRA||||END|
|
||||
data/scripts/getpid-linux-i386.gdb||GHIDRA||||END|
|
||||
data/scripts/wine32_info_proc_mappings.gdb||GHIDRA||||END|
|
||||
src/main/py/LICENSE||GHIDRA||||END|
|
||||
src/main/py/MANIFEST.in||GHIDRA||||END|
|
||||
src/main/py/README.md||GHIDRA||||END|
|
||||
src/main/py/pyproject.toml||GHIDRA||||END|
|
||||
src/main/py/src/ghidragdb/schema.xml||GHIDRA||||END|
|
||||
|
@ -0,0 +1,53 @@
|
||||
::@title gdb
|
||||
::@desc <html><body width="300px">
|
||||
::@desc <h3>Launch with <tt>gdb</tt></h3>
|
||||
::@desc <p>
|
||||
::@desc This will launch the target on the local machine using <tt>gdb</tt>.
|
||||
::@desc For setup instructions, press <b>F1</b>.
|
||||
::@desc </p>
|
||||
::@desc </body></html>
|
||||
::@menu-group local
|
||||
::@icon icon.debugger
|
||||
::@help TraceRmiLauncherServicePlugin#gdb
|
||||
::@enum StartCmd:str run start starti
|
||||
::@arg :file "Image" "The target binary executable image"
|
||||
::@args "Arguments" "Command-line arguments to pass to the target"
|
||||
::@env OPT_GDB_PATH:file="gdb" "gdb command" "The path to gdb. Omit the full path to resolve using the system PATH."
|
||||
::@env OPT_START_CMD:StartCmd="starti" "Run command" "The gdb command to actually run the target."
|
||||
::@env OPT_EXTRA_TTY:bool=false "Inferior TTY" "Provide a separate terminal emulator for the target."
|
||||
::@tty TTY_TARGET if env:OPT_EXTRA_TTY
|
||||
|
||||
@echo off
|
||||
set PYTHONPATH0=%GHIDRA_HOME%\Ghidra\Debug\Debugger-agent-gdb\pypkg\src
|
||||
set PYTHONPATH1=%GHIDRA_HOME%\Ghidra\Debug\Debugger-rmi-trace\pypkg\src
|
||||
IF EXIST %GHIDRA_HOME%\.git (
|
||||
set PYTHONPATH0=%GHIDRA_HOME%\Ghidra\Debug\Debugger-agent-gdb\build\pypkg\src
|
||||
set PYTHONPATH1=%GHIDRA_HOME%\Ghidra\Debug\Debugger-rmi-trace\build\pypkg\src
|
||||
)
|
||||
IF EXIST %GHIDRA_HOME%\ghidra\.git (
|
||||
set PYTHONPATH0=%GHIDRA_HOME%\ghidra\Ghidra\Debug\Debugger-agent-gdb\build\pypkg\src
|
||||
set PYTHONPATH1=%GHIDRA_HOME%\ghidra\Ghidra\Debug\Debugger-rmi-trace\build\pypkg\src
|
||||
)
|
||||
set PYTHONPATH=%PYTHONPATH1%;%PYTHONPATH0%;%PYTHONPATH%
|
||||
|
||||
set target_image=%1
|
||||
shift
|
||||
set target_args=%*
|
||||
|
||||
"%OPT_GDB_PATH%" ^
|
||||
-q ^
|
||||
-ex "set pagination off" ^
|
||||
-ex "set confirm off" ^
|
||||
-ex "show version" ^
|
||||
-ex "python import ghidragdb" ^
|
||||
-ex "target exec %target_image%" ^
|
||||
-ex "set args %target_args%" ^
|
||||
-ex "set inferior-tty %TTY_TARGET%" ^
|
||||
-ex "ghidra trace connect '%GHIDRA_TRACE_RMI_ADDR%'" ^
|
||||
-ex "ghidra trace start" ^
|
||||
-ex "ghidra trace sync-enable" ^
|
||||
-ex "%OPT_START_CMD%" ^
|
||||
-ex "set confirm on" ^
|
||||
-ex "set pagination on" ^
|
||||
|
||||
|
1
Ghidra/Debug/Debugger-agent-gdb/src/main/py/MANIFEST.in
Normal file
1
Ghidra/Debug/Debugger-agent-gdb/src/main/py/MANIFEST.in
Normal file
@ -0,0 +1 @@
|
||||
include src/ghidragdb/schema.xml
|
@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "ghidragdb"
|
||||
version = "11.1"
|
||||
version = "11.1.2"
|
||||
authors = [
|
||||
{ name="Ghidra Development Team" },
|
||||
]
|
||||
@ -17,7 +17,7 @@ classifiers = [
|
||||
"Operating System :: OS Independent",
|
||||
]
|
||||
dependencies = [
|
||||
"ghidratrace==11.1",
|
||||
"ghidratrace==11.1.2",
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
|
@ -85,9 +85,9 @@ data64_compiler_map = {
|
||||
|
||||
x86_compiler_map = {
|
||||
'GNU/Linux': 'gcc',
|
||||
'Windows': 'Visual Studio',
|
||||
'Windows': 'windows',
|
||||
# This may seem wrong, but Ghidra cspecs really describe the ABI
|
||||
'Cygwin': 'Visual Studio',
|
||||
'Cygwin': 'windows',
|
||||
}
|
||||
|
||||
compiler_map = {
|
||||
@ -104,7 +104,7 @@ def get_arch():
|
||||
|
||||
def get_endian():
|
||||
parm = gdb.parameter('endian')
|
||||
if parm != 'auto':
|
||||
if not parm in ['', 'auto', 'default']:
|
||||
return parm
|
||||
# Once again, we have to hack using the human-readable 'show'
|
||||
show = gdb.execute('show endian', to_string=True)
|
||||
@ -132,7 +132,7 @@ def get_osabi():
|
||||
def compute_ghidra_language():
|
||||
# First, check if the parameter is set
|
||||
lang = gdb.parameter('ghidra-language')
|
||||
if lang != 'auto':
|
||||
if not lang in ['', 'auto', 'default']:
|
||||
return lang
|
||||
|
||||
# Get the list of possible languages for the arch. We'll need to sift
|
||||
@ -157,7 +157,7 @@ def compute_ghidra_language():
|
||||
def compute_ghidra_compiler(lang):
|
||||
# First, check if the parameter is set
|
||||
comp = gdb.parameter('ghidra-compiler')
|
||||
if comp != 'auto':
|
||||
if not comp in ['', 'auto', 'default']:
|
||||
return comp
|
||||
|
||||
# Check if the selected lang has specific compiler recommendations
|
||||
|
@ -19,9 +19,13 @@ import os.path
|
||||
import socket
|
||||
import time
|
||||
|
||||
try:
|
||||
import psutil
|
||||
except ImportError:
|
||||
print(f"Unable to import 'psutil' - check that it has been installed")
|
||||
|
||||
from ghidratrace import sch
|
||||
from ghidratrace.client import Client, Address, AddressRange, TraceObject
|
||||
import psutil
|
||||
|
||||
import gdb
|
||||
|
||||
|
@ -93,8 +93,14 @@ class InferiorState(object):
|
||||
if first or hashable_frame not in self.visited:
|
||||
commands.putreg(
|
||||
frame, util.get_register_descs(frame.architecture(), 'general'))
|
||||
commands.putmem("$pc", "1", from_tty=False)
|
||||
commands.putmem("$sp", "1", from_tty=False)
|
||||
try:
|
||||
commands.putmem("$pc", "1", from_tty=False)
|
||||
except MemoryError as e:
|
||||
print(f"Couldn't record page with PC: {e}")
|
||||
try:
|
||||
commands.putmem("$sp", "1", from_tty=False)
|
||||
except MemoryError as e:
|
||||
print(f"Couldn't record page with SP: {e}")
|
||||
self.visited.add(hashable_frame)
|
||||
if first or self.regions or self.threads or self.modules:
|
||||
# Sections, memory syscalls, or stack allocations
|
||||
|
@ -28,6 +28,8 @@ def _compute_gdb_ver():
|
||||
top = blurb.split('\n')[0]
|
||||
full = top.split(' ')[-1]
|
||||
major, minor = full.split('.')[:2]
|
||||
if '-' in minor:
|
||||
minor = minor[:minor.find('-')]
|
||||
return GdbVersion(full, int(major), int(minor))
|
||||
|
||||
|
||||
@ -379,7 +381,10 @@ class RegisterDesc(namedtuple('BaseRegisterDesc', ['name'])):
|
||||
|
||||
def get_register_descs(arch, group='all'):
|
||||
if hasattr(arch, "registers"):
|
||||
return arch.registers(group)
|
||||
try:
|
||||
return arch.registers(group)
|
||||
except ValueError: # No such group, or version too old
|
||||
return arch.registers()
|
||||
else:
|
||||
descs = []
|
||||
regset = gdb.execute(
|
||||
|
@ -18,9 +18,8 @@ apply from: "$rootProject.projectDir/gradle/jacocoProject.gradle"
|
||||
apply from: "$rootProject.projectDir/gradle/javaTestProject.gradle"
|
||||
apply from: "$rootProject.projectDir/gradle/nativeProject.gradle"
|
||||
apply from: "$rootProject.projectDir/gradle/distributableGhidraModule.gradle"
|
||||
|
||||
apply from: "$rootProject.projectDir/gradle/hasPythonPackage.gradle"
|
||||
apply from: "$rootProject.projectDir/gradle/debugger/hasExecutableJar.gradle"
|
||||
apply from: "$rootProject.projectDir/gradle/debugger/hasPythonPackage.gradle"
|
||||
|
||||
apply plugin: 'eclipse'
|
||||
eclipse.project.name = 'Debug Debugger-agent-lldb'
|
||||
|
@ -3,9 +3,11 @@
|
||||
##MODULE IP: Apache License 2.0 with LLVM Exceptions
|
||||
Module.manifest||GHIDRA||||END|
|
||||
build.gradle||GHIDRA||||END|
|
||||
data/debugger-launchers/local-lldb.bat||GHIDRA||||END|
|
||||
src/llvm-project/lldb/bindings/java/java-typemaps.swig||Apache License 2.0 with LLVM Exceptions||||END|
|
||||
src/llvm-project/lldb/bindings/java/java.swig||Apache License 2.0 with LLVM Exceptions||||END|
|
||||
src/main/py/LICENSE||GHIDRA||||END|
|
||||
src/main/py/MANIFEST.in||GHIDRA||||END|
|
||||
src/main/py/README.md||GHIDRA||||END|
|
||||
src/main/py/pyproject.toml||GHIDRA||||END|
|
||||
src/main/py/src/ghidralldb/schema.xml||GHIDRA||||END|
|
||||
|
@ -0,0 +1,54 @@
|
||||
::@title lldb
|
||||
::@desc <html><body width="300px">
|
||||
::@desc <h3>Launch with <tt>lldb</tt></h3>
|
||||
::@desc <p>
|
||||
::@desc This will launch the target on the local machine using <tt>lldb</tt>.
|
||||
::@desc For setup instructions, press <b>F1</b>.
|
||||
::@desc </p>
|
||||
::@desc </body></html>
|
||||
::@menu-group local
|
||||
::@icon icon.debugger
|
||||
::@help TraceRmiLauncherServicePlugin#lldb
|
||||
::@enum StartCmd:str "process launch" "process launch --stop-at-entry"
|
||||
::@arg :file "Image" "The target binary executable image"
|
||||
::@args "Arguments" "Command-line arguments to pass to the target"
|
||||
::@env OPT_LLDB_PATH:file="lldb" "lldb command" "The path to lldb. Omit the full path to resolve using the system PATH."
|
||||
::@env OPT_START_CMD:StartCmd="process launch" "Run command" "The lldb command to actually run the target."
|
||||
::@env OPT_EXTRA_TTY:bool=false "Target TTY" "Provide a separate terminal emulator for the target."
|
||||
::@tty TTY_TARGET if env:OPT_EXTRA_TTY
|
||||
|
||||
@echo off
|
||||
set PYTHONPATH0=%GHIDRA_HOME%\Ghidra\Debug\Debugger-agent-gdb\pypkg\src
|
||||
set PYTHONPATH1=%GHIDRA_HOME%\Ghidra\Debug\Debugger-rmi-trace\pypkg\src
|
||||
IF EXIST %GHIDRA_HOME%\.git (
|
||||
set PYTHONPATH0=%GHIDRA_HOME%\Ghidra\Debug\Debugger-agent-gdb\build\pypkg\src
|
||||
set PYTHONPATH1=%GHIDRA_HOME%\Ghidra\Debug\Debugger-rmi-trace\build\pypkg\src
|
||||
)
|
||||
IF EXIST %GHIDRA_HOME%\ghidra\.git (
|
||||
set PYTHONPATH0=%GHIDRA_HOME%\ghidra\Ghidra\Debug\Debugger-agent-gdb\build\pypkg\src
|
||||
set PYTHONPATH1=%GHIDRA_HOME%\ghidra\Ghidra\Debug\Debugger-rmi-trace\build\pypkg\src
|
||||
)
|
||||
set PYTHONPATH=%PYTHONPATH1%;%PYTHONPATH0%;%PYTHONPATH%
|
||||
|
||||
set target_image=%1
|
||||
shift
|
||||
set target_args=%*
|
||||
|
||||
IF DEFINED target_args (
|
||||
argspart=-o "settings set target.run-args %target_args%"
|
||||
)
|
||||
|
||||
IF DEFINED TARGET_TTY (
|
||||
ttypart=-o "settings set target.output-path %TTY_TARGET%" -o "settings set target.input-path $TTY_TARGET"
|
||||
)
|
||||
|
||||
"%OPT_LLDB_PATH%" ^
|
||||
-o "version" ^
|
||||
-o "script import ghidralldb" ^
|
||||
-o "target create %target_image%" ^
|
||||
%argspart% ^
|
||||
%ttypart% ^
|
||||
-o "ghidra trace connect %GHIDRA_TRACE_RMI_ADDR%" ^
|
||||
-o "ghidra trace start" ^
|
||||
-o "ghidra trace sync-enable" ^
|
||||
-o "%OPT_START_CMD%"
|
1
Ghidra/Debug/Debugger-agent-lldb/src/main/py/MANIFEST.in
Normal file
1
Ghidra/Debug/Debugger-agent-lldb/src/main/py/MANIFEST.in
Normal file
@ -0,0 +1 @@
|
||||
include src/ghidragdb/schema.xml
|
@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "ghidralldb"
|
||||
version = "11.1"
|
||||
version = "11.1.2"
|
||||
authors = [
|
||||
{ name="Ghidra Development Team" },
|
||||
]
|
||||
@ -17,7 +17,7 @@ classifiers = [
|
||||
"Operating System :: OS Independent",
|
||||
]
|
||||
dependencies = [
|
||||
"ghidratrace==11.1",
|
||||
"ghidratrace==11.1.2",
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
|
@ -23,7 +23,10 @@ import socket
|
||||
import sys
|
||||
import time
|
||||
|
||||
import psutil
|
||||
try:
|
||||
import psutil
|
||||
except ImportError:
|
||||
print(f"Unable to import 'psutil' - check that it has been installed")
|
||||
|
||||
from ghidratrace import sch
|
||||
from ghidratrace.client import Client, Address, AddressRange, TraceObject
|
||||
|
@ -18,7 +18,7 @@ apply from: "${rootProject.projectDir}/gradle/javaProject.gradle"
|
||||
apply from: "${rootProject.projectDir}/gradle/jacocoProject.gradle"
|
||||
apply from: "${rootProject.projectDir}/gradle/javaTestProject.gradle"
|
||||
apply from: "${rootProject.projectDir}/gradle/distributableGhidraModule.gradle"
|
||||
apply from: "${rootProject.projectDir}/gradle/debugger/hasProtobuf.gradle"
|
||||
apply from: "${rootProject.projectDir}/gradle/hasProtobuf.gradle"
|
||||
|
||||
apply plugin: 'eclipse'
|
||||
eclipse.project.name = 'Debug Debugger-gadp'
|
||||
|
@ -18,7 +18,7 @@ apply from: "${rootProject.projectDir}/gradle/javaProject.gradle"
|
||||
apply from: "${rootProject.projectDir}/gradle/jacocoProject.gradle"
|
||||
apply from: "${rootProject.projectDir}/gradle/javaTestProject.gradle"
|
||||
apply from: "${rootProject.projectDir}/gradle/distributableGhidraModule.gradle"
|
||||
apply from: "${rootProject.projectDir}/gradle/debugger/hasProtobuf.gradle"
|
||||
apply from: "${rootProject.projectDir}/gradle/hasProtobuf.gradle"
|
||||
|
||||
apply plugin: 'eclipse'
|
||||
eclipse.project.name = 'Debug Debugger-isf'
|
||||
|
@ -19,8 +19,8 @@ apply from: "${rootProject.projectDir}/gradle/helpProject.gradle"
|
||||
apply from: "${rootProject.projectDir}/gradle/jacocoProject.gradle"
|
||||
apply from: "${rootProject.projectDir}/gradle/javaTestProject.gradle"
|
||||
apply from: "${rootProject.projectDir}/gradle/distributableGhidraModule.gradle"
|
||||
apply from: "${rootProject.projectDir}/gradle/debugger/hasProtobuf.gradle"
|
||||
apply from: "${rootProject.projectDir}/gradle/debugger/hasPythonPackage.gradle"
|
||||
apply from: "${rootProject.projectDir}/gradle/hasProtobuf.gradle"
|
||||
apply from: "${rootProject.projectDir}/gradle/hasPythonPackage.gradle"
|
||||
|
||||
apply plugin: 'eclipse'
|
||||
eclipse.project.name = 'Debug Debugger-rmi-trace'
|
||||
|
@ -16,11 +16,13 @@
|
||||
package ghidra.app.plugin.core.debug.gui.tracermi.launcher;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import generic.jar.ResourceFile;
|
||||
import ghidra.debug.api.tracermi.TraceRmiLaunchOffer;
|
||||
import ghidra.framework.OperatingSystem;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.util.Msg;
|
||||
|
||||
@ -29,10 +31,13 @@ public class BatchScriptTraceRmiLaunchOpinion extends AbstractTraceRmiLaunchOpin
|
||||
@Override
|
||||
public Collection<TraceRmiLaunchOffer> getOffers(TraceRmiLauncherServicePlugin plugin,
|
||||
Program program) {
|
||||
return getScriptPaths(plugin.getTool())
|
||||
.flatMap(rf -> Stream.of(rf.listFiles(crf -> crf.getName().endsWith(".bat"))))
|
||||
.flatMap(sf -> createOffer(plugin, program, sf))
|
||||
.collect(Collectors.toList());
|
||||
if (OperatingSystem.CURRENT_OPERATING_SYSTEM == OperatingSystem.WINDOWS) {
|
||||
return getScriptPaths(plugin.getTool())
|
||||
.flatMap(rf -> Stream.of(rf.listFiles(crf -> crf.getName().endsWith(".bat"))))
|
||||
.flatMap(sf -> createOffer(plugin, program, sf))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
return List.of();
|
||||
}
|
||||
|
||||
protected Stream<TraceRmiLaunchOffer> createOffer(TraceRmiLauncherServicePlugin plugin,
|
||||
|
@ -16,11 +16,13 @@
|
||||
package ghidra.app.plugin.core.debug.gui.tracermi.launcher;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import generic.jar.ResourceFile;
|
||||
import ghidra.debug.api.tracermi.TraceRmiLaunchOffer;
|
||||
import ghidra.framework.OperatingSystem;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.util.Msg;
|
||||
|
||||
@ -29,10 +31,13 @@ public class UnixShellScriptTraceRmiLaunchOpinion extends AbstractTraceRmiLaunch
|
||||
@Override
|
||||
public Collection<TraceRmiLaunchOffer> getOffers(TraceRmiLauncherServicePlugin plugin,
|
||||
Program program) {
|
||||
return getScriptPaths(plugin.getTool())
|
||||
.flatMap(rf -> Stream.of(rf.listFiles(crf -> crf.getName().endsWith(".sh"))))
|
||||
.flatMap(sf -> createOffer(plugin, program, sf))
|
||||
.collect(Collectors.toList());
|
||||
if (OperatingSystem.CURRENT_OPERATING_SYSTEM != OperatingSystem.WINDOWS) {
|
||||
return getScriptPaths(plugin.getTool())
|
||||
.flatMap(rf -> Stream.of(rf.listFiles(crf -> crf.getName().endsWith(".sh"))))
|
||||
.flatMap(sf -> createOffer(plugin, program, sf))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
return List.of();
|
||||
}
|
||||
|
||||
protected Stream<TraceRmiLaunchOffer> createOffer(TraceRmiLauncherServicePlugin plugin,
|
||||
|
@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "ghidratrace"
|
||||
version = "11.1"
|
||||
version = "11.1.2"
|
||||
authors = [
|
||||
{ name="Ghidra Development Team" },
|
||||
]
|
||||
|
@ -1,3 +1,8 @@
|
||||
######################################################################################
|
||||
## PLEASE NOTE: This version of the lldb-based debugger is being deprecated. ##
|
||||
## Please try the Python-based traceRMI versions documented in the Debugger help. ##
|
||||
######################################################################################
|
||||
|
||||
To use the LLDB agent in Ghidra, you will need to build the JNI interface to the LLDB Scripting Bridge.
|
||||
|
||||
If you are using the distribution (vs. source) and wish to use the default swig files included (LLDB v17), you can use the
|
||||
|
@ -44,10 +44,11 @@ task generateSwig {
|
||||
"-outdir", "$outdir_java/SWIG", "-o", "$outdir_cpp/LLDBWrapJava.cpp"
|
||||
args "$srcdir/java.swig"
|
||||
}
|
||||
} else if (llvmRequired) {
|
||||
throw new GradleException("Debugger-swig-lldb:generateSwig requires LLVM_HOME to be defined")
|
||||
} else {
|
||||
println "Debugger-swig-lldb:generateSwig skipped - LLVM_HOME not defined"
|
||||
//throw new GradleException("Debugger-swig-lldb:generateSwig requires LLVM_HOME to be defined")
|
||||
println "OPTIONAL dependency Debugger-swig-lldb:generateSwig skipped - LLVM_HOME not defined"
|
||||
println "NOTE: The JNI/swig interface for recorder-style lldb debugging is being deprecated."
|
||||
println " Please try the new traceRMI python-based versions of the debugger."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,14 @@
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
##
|
||||
|
||||
######################################################################################
|
||||
## PLEASE NOTE: This version of the lldb-based debugger is being deprecated. ##
|
||||
## Please try the Python-based traceRMI versions documented in the Debugger help. ##
|
||||
######################################################################################
|
||||
|
||||
|
||||
##
|
||||
# This script will download lldb from homebrew and
|
||||
# build the Ghidra JNI bindings for this version of
|
||||
|
@ -244,22 +244,25 @@ public class MachoPrelinkUtils {
|
||||
* @param offset The offset within the provider to check.
|
||||
* @return True A valid {@link LoadSpec} for the Mach-O at the given provider's offset, or null
|
||||
* if it is not a Mach-O or a valid {@link LoadSpec} could not be found.
|
||||
* @throws IOException if there was an IO-related problem.
|
||||
*/
|
||||
private static LoadSpec getMachoLoadSpec(ByteProvider provider, long offset)
|
||||
throws IOException {
|
||||
Collection<LoadSpec> loadSpecs = new MachoLoader().findSupportedLoadSpecs(
|
||||
new ByteProviderWrapper(provider, offset, provider.length() - offset));
|
||||
private static LoadSpec getMachoLoadSpec(ByteProvider provider, long offset) {
|
||||
try {
|
||||
Collection<LoadSpec> loadSpecs = new MachoLoader().findSupportedLoadSpecs(
|
||||
new ByteProviderWrapper(provider, offset, provider.length() - offset));
|
||||
|
||||
// Getting a LoadSpec back means it's a Mach-O we can load. We also need to make sure
|
||||
// the LoadSpec has a language/compiler spec defined to know we support the processor the
|
||||
// loader detected.
|
||||
if (!loadSpecs.isEmpty()) {
|
||||
LoadSpec loadSpec = loadSpecs.iterator().next();
|
||||
if (loadSpec.getLanguageCompilerSpec() != null) {
|
||||
return loadSpec;
|
||||
// Getting a LoadSpec back means it's a Mach-O we can load. We also need to make sure
|
||||
// the LoadSpec has a language/compiler spec defined to know we support the processor the
|
||||
// loader detected.
|
||||
if (!loadSpecs.isEmpty()) {
|
||||
LoadSpec loadSpec = loadSpecs.iterator().next();
|
||||
if (loadSpec.getLanguageCompilerSpec() != null) {
|
||||
return loadSpec;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -412,7 +412,9 @@ public class MachoProgramBuilder {
|
||||
}
|
||||
}
|
||||
if (segmentFragment == null) {
|
||||
log.appendMsg("Could not find/fixup segment in Program Tree: " + segmentName);
|
||||
if (segment.getVMsize() != 0 || segment.getFileSize() != 0) {
|
||||
log.appendMsg("Could not find/fixup segment in Program Tree: " + segmentName);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
ProgramModule segmentModule = rootModule.createModule(segmentName + suffix);
|
||||
@ -830,8 +832,10 @@ public class MachoProgramBuilder {
|
||||
List<DyldChainedFixupsCommand> loadCommands =
|
||||
machoHeader.getLoadCommands(DyldChainedFixupsCommand.class);
|
||||
if (!loadCommands.isEmpty()) {
|
||||
BinaryReader memReader = new BinaryReader(new MemoryByteProvider(memory, imagebase),
|
||||
!memory.isBigEndian());
|
||||
for (DyldChainedFixupsCommand loadCommand : loadCommands) {
|
||||
fixups.addAll(loadCommand.getChainedFixups(reader, imagebase.getOffset(),
|
||||
fixups.addAll(loadCommand.getChainedFixups(memReader, imagebase.getOffset(),
|
||||
symbolTable, log, monitor));
|
||||
}
|
||||
}
|
||||
@ -842,7 +846,8 @@ public class MachoProgramBuilder {
|
||||
Section threadStartsSection =
|
||||
machoHeader.getSection(SegmentNames.SEG_TEXT, SectionNames.THREAD_STARTS);
|
||||
|
||||
if (chainStartsSection != null) {
|
||||
if (chainStartsSection != null && chainStartsSection.getAddress() != 0 &&
|
||||
chainStartsSection.getSize() != 0) {
|
||||
reader.setPointerIndex(chainStartsSection.getOffset());
|
||||
DyldChainedStartsOffsets chainedStartsOffsets =
|
||||
new DyldChainedStartsOffsets(reader);
|
||||
@ -852,7 +857,8 @@ public class MachoProgramBuilder {
|
||||
imagebase.getOffset(), symbolTable, log, monitor));
|
||||
}
|
||||
}
|
||||
else if (threadStartsSection != null) {
|
||||
else if (threadStartsSection != null && threadStartsSection.getAddress() != 0 &&
|
||||
threadStartsSection.getSize() != 0) {
|
||||
Address threadSectionStart = space.getAddress(threadStartsSection.getAddress());
|
||||
Address threadSectionEnd =
|
||||
threadSectionStart.add(threadStartsSection.getSize() - 1);
|
||||
|
@ -22,8 +22,7 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||
import docking.widgets.OptionDialog;
|
||||
import ghidra.app.plugin.core.progmgr.ProgramLocator;
|
||||
import ghidra.app.util.dialog.CheckoutDialog;
|
||||
import ghidra.framework.client.ClientUtil;
|
||||
import ghidra.framework.client.RepositoryAdapter;
|
||||
import ghidra.framework.client.*;
|
||||
import ghidra.framework.main.AppInfo;
|
||||
import ghidra.framework.model.DomainFile;
|
||||
import ghidra.framework.protocol.ghidra.GhidraURLQuery;
|
||||
@ -93,33 +92,28 @@ public class ProgramOpener {
|
||||
*/
|
||||
public Program openProgram(ProgramLocator locator, TaskMonitor monitor) {
|
||||
if (locator.isURL()) {
|
||||
try {
|
||||
return openURL(locator, monitor);
|
||||
}
|
||||
catch (CancelledException e) {
|
||||
return null;
|
||||
}
|
||||
catch (IOException e) {
|
||||
Msg.showError(this, null, "Program Open Failed",
|
||||
"Failed to open Ghidra URL: " + locator.getURL(), e);
|
||||
}
|
||||
return openURL(locator, monitor);
|
||||
}
|
||||
return openProgram(locator, locator.getDomainFile(), monitor);
|
||||
}
|
||||
|
||||
private Program openURL(ProgramLocator locator, TaskMonitor monitor)
|
||||
throws CancelledException, IOException {
|
||||
private Program openURL(ProgramLocator locator, TaskMonitor monitor) {
|
||||
URL ghidraUrl = locator.getURL();
|
||||
|
||||
AtomicReference<Program> openedProgram = new AtomicReference<>();
|
||||
GhidraURLQuery.queryUrl(ghidraUrl, new GhidraURLResultHandlerAdapter() {
|
||||
@Override
|
||||
public void processResult(DomainFile domainFile, URL url, TaskMonitor m) {
|
||||
Program p = openProgram(locator, domainFile, m); // may return null
|
||||
openedProgram.set(p);
|
||||
}
|
||||
}, monitor);
|
||||
|
||||
try {
|
||||
GhidraURLQuery.queryUrl(ghidraUrl, new GhidraURLResultHandlerAdapter() {
|
||||
@Override
|
||||
public void processResult(DomainFile domainFile, URL url, TaskMonitor m) {
|
||||
Program p = openProgram(locator, domainFile, m); // may return null
|
||||
openedProgram.set(p);
|
||||
}
|
||||
}, monitor);
|
||||
}
|
||||
catch (IOException | CancelledException e) {
|
||||
// IOException reported to user by GhidraURLResultHandlerAdapter
|
||||
return null;
|
||||
}
|
||||
return openedProgram.get();
|
||||
}
|
||||
|
||||
|
@ -36,10 +36,6 @@ public class CParserTest extends AbstractGhidraHeadlessIntegrationTest {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method just tries to parse a bunch o'
|
||||
* data types just checking for stack traces.
|
||||
*/
|
||||
@Test
|
||||
public void testSimple() throws Exception {
|
||||
CParser parser = new CParser();
|
||||
@ -68,10 +64,6 @@ public class CParserTest extends AbstractGhidraHeadlessIntegrationTest {
|
||||
assertEquals(comp.getDataType().getName(),"char");
|
||||
}
|
||||
|
||||
/**
|
||||
* This method just tries to parse a bunch o'
|
||||
* data types just checking for stack traces.
|
||||
*/
|
||||
@Test
|
||||
public void testLongLong() throws Exception {
|
||||
CParser parser;
|
||||
@ -96,6 +88,27 @@ public class CParserTest extends AbstractGhidraHeadlessIntegrationTest {
|
||||
assertEquals(8, pdt32.getLength());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTypedef() throws Exception {
|
||||
CParser parser;
|
||||
|
||||
parser = new CParser();
|
||||
DataType tdDt = parser.parse("typedef struct foo * foo;");
|
||||
|
||||
assertTrue(tdDt != null);
|
||||
assertTrue(tdDt instanceof TypeDef);
|
||||
System.out.println(tdDt.getPathName());
|
||||
System.out.println(((TypeDef)tdDt).getDataType().getPathName());
|
||||
assertEquals("foo", tdDt.getName());
|
||||
assertEquals("foo.conflict *", ((TypeDef)tdDt).getDataType().getName());
|
||||
assertEquals(4, tdDt.getLength());
|
||||
|
||||
DataType dt = parser.getDataTypeManager().getDataType("/foo");
|
||||
assertTrue(dt != null);
|
||||
assertTrue(dt instanceof TypeDef);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWcharT() throws Exception {
|
||||
|
||||
|
@ -465,12 +465,6 @@ public class FakeSharedProject {
|
||||
|
||||
void refresh() {
|
||||
DefaultProjectData projectData = getProjectData();
|
||||
try {
|
||||
projectData.refresh(true);
|
||||
}
|
||||
catch (IOException e) {
|
||||
// shouldn't happen
|
||||
throw new AssertionFailedError("Unable to refresh project " + this);
|
||||
}
|
||||
projectData.refresh(true);
|
||||
}
|
||||
}
|
||||
|
@ -474,13 +474,13 @@ public class Application {
|
||||
exactFilename);
|
||||
}
|
||||
|
||||
// Allow win_x86_32 to be used for win_x86_64 as fallback
|
||||
if (file == null && Platform.CURRENT_PLATFORM == Platform.WIN_X86_64) {
|
||||
file = getModuleFile(module, "build/os/" + Platform.WIN_X86_32.getDirectoryName(),
|
||||
// Allow win_x86_64 to be used for win_arm_64 as fallback (requires Windows emulation)
|
||||
if (file == null && Platform.CURRENT_PLATFORM == Platform.WIN_ARM_64) {
|
||||
file = getModuleFile(module, "build/os/" + Platform.WIN_X86_64.getDirectoryName(),
|
||||
exactFilename);
|
||||
}
|
||||
if (file == null && Platform.CURRENT_PLATFORM == Platform.WIN_X86_64) {
|
||||
file = getModuleFile(module, "os/" + Platform.WIN_X86_32.getDirectoryName(),
|
||||
if (file == null && Platform.CURRENT_PLATFORM == Platform.WIN_ARM_64) {
|
||||
file = getModuleFile(module, "os/" + Platform.WIN_X86_64.getDirectoryName(),
|
||||
exactFilename);
|
||||
}
|
||||
|
||||
@ -520,12 +520,12 @@ public class Application {
|
||||
file = findModuleFile("os/" + Platform.CURRENT_PLATFORM.getDirectoryName(), path);
|
||||
}
|
||||
|
||||
// Allow win_x86_32 to be used for win_x86_64 as fallback
|
||||
if (file == null && Platform.CURRENT_PLATFORM == Platform.WIN_X86_64) {
|
||||
file = findModuleFile("build/os/" + Platform.WIN_X86_32.getDirectoryName(), path);
|
||||
// Allow win_x86_64 to be used for win_arm_64 as fallback (requires Windows emulation)
|
||||
if (file == null && Platform.CURRENT_PLATFORM == Platform.WIN_ARM_64) {
|
||||
file = findModuleFile("build/os/" + Platform.WIN_X86_64.getDirectoryName(), path);
|
||||
}
|
||||
if (file == null && Platform.CURRENT_PLATFORM == Platform.WIN_X86_64) {
|
||||
file = findModuleFile("os/" + Platform.WIN_X86_32.getDirectoryName(), path);
|
||||
if (file == null && Platform.CURRENT_PLATFORM == Platform.WIN_ARM_64) {
|
||||
file = findModuleFile("os/" + Platform.WIN_X86_64.getDirectoryName(), path);
|
||||
}
|
||||
|
||||
// Allow mac_x86_64 to be used for mac_arm_64 as fallback (requires macOS Rosetta 2)
|
||||
|
@ -35,6 +35,11 @@ public enum Platform {
|
||||
*/
|
||||
WIN_X86_64(OperatingSystem.WINDOWS, Architecture.X86_64, "win_x86_64", ".dll", ".exe"),
|
||||
|
||||
/**
|
||||
* Identifies a Windows ARM 64-bit OS.
|
||||
*/
|
||||
WIN_ARM_64(OperatingSystem.WINDOWS, Architecture.ARM_64, "win_arm_64", ".dll", ".exe"),
|
||||
|
||||
/**
|
||||
* Identifies a Linux x86 32-bit OS.
|
||||
*/
|
||||
|
@ -734,7 +734,7 @@ public class DefaultProjectData implements ProjectData {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh(boolean force) throws IOException {
|
||||
public void refresh(boolean force) {
|
||||
try {
|
||||
rootFolderData.refresh(true, true, projectDisposalMonitor);
|
||||
}
|
||||
|
@ -17,14 +17,12 @@ package ghidra.framework.main.projectdata.actions;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.swing.Icon;
|
||||
|
||||
import docking.action.*;
|
||||
import ghidra.framework.client.ClientUtil;
|
||||
import ghidra.framework.main.datatable.ProjectDataContext;
|
||||
import ghidra.framework.main.datatable.FrontendProjectTreeAction;
|
||||
import ghidra.framework.main.datatable.ProjectDataContext;
|
||||
import ghidra.framework.model.ProjectData;
|
||||
import ghidra.util.HelpLocation;
|
||||
import ghidra.util.task.*;
|
||||
@ -53,13 +51,7 @@ public class ProjectDataRefreshAction extends FrontendProjectTreeAction {
|
||||
TaskLauncher.launch(new Task("Refresh folders and files", false, false, true) {
|
||||
@Override
|
||||
public void run(TaskMonitor monitor) {
|
||||
try {
|
||||
projectData.refresh(false);
|
||||
}
|
||||
catch (IOException e) {
|
||||
ClientUtil.handleException(projectData.getRepository(), e,
|
||||
"Refresh Project Data", false, comp);
|
||||
}
|
||||
projectData.refresh(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -143,9 +143,8 @@ public interface ProjectData {
|
||||
* Sync the Domain folder/file structure with the underlying file structure.
|
||||
* @param force if true all folders will be be visited and refreshed, if false
|
||||
* only those folders previously visited will be refreshed.
|
||||
* @throws IOException if an IO error occurs
|
||||
*/
|
||||
public void refresh(boolean force) throws IOException;
|
||||
public void refresh(boolean force);
|
||||
|
||||
/**
|
||||
* Returns User object associated with remote repository or null if a remote repository
|
||||
|
@ -119,7 +119,7 @@ public class TestDummyProjectData implements ProjectData {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh(boolean force) throws IOException {
|
||||
public void refresh(boolean force) {
|
||||
// stub
|
||||
}
|
||||
|
||||
|
@ -1042,6 +1042,9 @@ public class BigFloat implements Comparable<BigFloat> {
|
||||
if (isInfinite()) {
|
||||
return sign < 0 ? NEGATIVE_INFINITY : POSITIVE_INFINITY;
|
||||
}
|
||||
if (isZero()) {
|
||||
return sign < 0 ? "-0.0" : "0.0";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -1445,6 +1445,8 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
|
||||
* <br>
|
||||
* NOTE: The original datatype name will be returned unchanged for pointers and arrays since
|
||||
* they cannot be renamed.
|
||||
* <br>
|
||||
* NOTE: Otherwise, if category does not exist the non-conflict name will be returned.
|
||||
*
|
||||
* @param path the category path of the category where the new data type live in
|
||||
* the data type manager.
|
||||
@ -1452,16 +1454,39 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
|
||||
* @return the unused conflict name
|
||||
*/
|
||||
public String getUnusedConflictName(CategoryPath path, DataType dt) {
|
||||
String name = dt.getName();
|
||||
if ((dt instanceof Array) || (dt instanceof Pointer) || (dt instanceof BuiltInDataType)) {
|
||||
// name not used - anything will do
|
||||
return name;
|
||||
return dt.getName();
|
||||
}
|
||||
return getUnusedConflictName(getCategory(path), dt);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method gets a ".conflict" name that is not currently used by any data
|
||||
* types in the indicated category within this data type manager. If the baseName without
|
||||
* conflict suffix is not used that name will be returned.
|
||||
* <br>
|
||||
* NOTE: The original datatype name will be returned unchanged for pointers and arrays since
|
||||
* they cannot be renamed.
|
||||
* <br>
|
||||
* NOTE: Otherwise, if category does not exist the non-conflict name will be returned.
|
||||
*
|
||||
* @param cat the existing category to check.
|
||||
* @param dt datatype who name is used to establish non-conflict base name
|
||||
* @return the unused conflict name
|
||||
*/
|
||||
private String getUnusedConflictName(Category cat, DataType dt) {
|
||||
if ((dt instanceof Array) || (dt instanceof Pointer) || (dt instanceof BuiltInDataType)) {
|
||||
// name not used - anything will do
|
||||
return dt.getName();
|
||||
}
|
||||
String baseName = DataTypeUtilities.getNameWithoutConflict(dt);
|
||||
if (cat == null) {
|
||||
return baseName;
|
||||
}
|
||||
String testName = baseName;
|
||||
int count = 0;
|
||||
while (getDataType(path, testName) != null) {
|
||||
while (cat.getDataType(testName) != null) {
|
||||
testName = baseName + DataType.CONFLICT_SUFFIX;
|
||||
if (count > 0) {
|
||||
testName += Integer.toString(count);
|
||||
@ -3116,6 +3141,10 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
|
||||
flags = (short) TypedefDBAdapter.TYPEDEF_FLAG_AUTONAME;
|
||||
cat = getCategory(dataType.getCategoryPath()); // force category
|
||||
}
|
||||
else if (cat.getDataType(name) != null) {
|
||||
// force use of conflict name if needed
|
||||
name = getUnusedConflictName(cat, typedef);
|
||||
}
|
||||
DBRecord record = typedefAdapter.createRecord(getID(dataType), name, flags, cat.getID(),
|
||||
sourceArchiveIdValue, universalIdValue, typedef.getLastChangeTime());
|
||||
TypedefDB typedefDB = new TypedefDB(this, dtCache, typedefAdapter, record);
|
||||
|
@ -215,7 +215,7 @@ class StructureDB extends CompositeDB implements StructureInternal {
|
||||
++numComponents;
|
||||
structLength += structureGrowth;
|
||||
|
||||
if (validatePackAndNotify) {
|
||||
if (validatePackAndNotify) { // else caller responsible for record updates
|
||||
if (isPackingEnabled()) {
|
||||
repack(false, false); // may not recognize length change
|
||||
}
|
||||
@ -1684,6 +1684,9 @@ class StructureDB extends CompositeDB implements StructureInternal {
|
||||
|
||||
private void doReplaceWithNonPacked(Structure struct, DataType[] resolvedDts)
|
||||
throws IOException {
|
||||
|
||||
// caller responsible for record updates
|
||||
|
||||
// assumes components is clear and that alignment characteristics have been set.
|
||||
if (struct.isNotYetDefined()) {
|
||||
return;
|
||||
@ -1728,7 +1731,7 @@ class StructureDB extends CompositeDB implements StructureInternal {
|
||||
private void doCopy(Structure struct, DataTypeComponent[] definedComponents,
|
||||
DataType[] resolvedDts) throws IOException {
|
||||
|
||||
// simple replication of struct
|
||||
// simple replication of struct - caller must perform record updates
|
||||
structLength = struct.isZeroLength() ? 0 : struct.getLength();
|
||||
numComponents = struct.getNumComponents();
|
||||
structAlignment = struct.getAlignment();
|
||||
@ -2469,18 +2472,23 @@ class StructureDB extends CompositeDB implements StructureInternal {
|
||||
private boolean updateComposite(int currentNumComponents, int currentLength,
|
||||
int currentAlignment, boolean setLastChangeTime) {
|
||||
boolean compositeChanged = false;
|
||||
if (currentNumComponents >= 0 && numComponents != currentNumComponents) {
|
||||
if (currentNumComponents >= 0 &&
|
||||
(currentNumComponents != numComponents || currentNumComponents != record
|
||||
.getIntValue(CompositeDBAdapter.COMPOSITE_NUM_COMPONENTS_COL))) {
|
||||
numComponents = currentNumComponents;
|
||||
record.setIntValue(CompositeDBAdapter.COMPOSITE_NUM_COMPONENTS_COL, numComponents);
|
||||
setLastChangeTime = true;
|
||||
compositeChanged = true;
|
||||
}
|
||||
if (currentLength >= 0 && structLength != currentLength) {
|
||||
if (currentLength >= 0 && (currentLength != structLength ||
|
||||
currentLength != record.getIntValue(CompositeDBAdapter.COMPOSITE_LENGTH_COL))) {
|
||||
structLength = currentLength;
|
||||
record.setIntValue(CompositeDBAdapter.COMPOSITE_LENGTH_COL, structLength);
|
||||
compositeChanged = true;
|
||||
}
|
||||
if (currentAlignment >= 0 && structAlignment != currentAlignment) {
|
||||
if (currentAlignment >= 0 &&
|
||||
(currentAlignment != structAlignment || currentAlignment != record
|
||||
.getIntValue(CompositeDBAdapter.COMPOSITE_ALIGNMENT_COL))) {
|
||||
structAlignment = currentAlignment;
|
||||
record.setIntValue(CompositeDBAdapter.COMPOSITE_ALIGNMENT_COL, structAlignment);
|
||||
compositeChanged = true;
|
||||
|
@ -22,7 +22,6 @@ import ghidra.program.database.register.InMemoryRangeMapAdapter;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.lang.*;
|
||||
import ghidra.program.model.listing.ContextChangeException;
|
||||
import ghidra.util.exception.AssertException;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
@ -248,8 +247,9 @@ abstract public class AbstractStoredProgramContext extends AbstractProgramContex
|
||||
@Override
|
||||
public void remove(Address start, Address end, Register register)
|
||||
throws ContextChangeException {
|
||||
if (start.getAddressSpace() != end.getAddressSpace()) {
|
||||
throw new AssertException("start and end address must be in the same address space");
|
||||
if (!start.getAddressSpace().equals(end.getAddressSpace())) {
|
||||
throw new IllegalArgumentException(
|
||||
"start and end address must be within the same address space");
|
||||
}
|
||||
RegisterValueStore values = registerValueMap.get(register.getBaseRegister());
|
||||
if (values != null) {
|
||||
@ -259,8 +259,9 @@ abstract public class AbstractStoredProgramContext extends AbstractProgramContex
|
||||
}
|
||||
|
||||
// public void removeDefault(Address start, Address end, Register register) {
|
||||
// if (start.getAddressSpace() != end.getAddressSpace()) {
|
||||
// throw new AssertException("start and end address must be in the same address space");
|
||||
// if (!start.getAddressSpace().equals(end.getAddressSpace())) {
|
||||
// throw new IllegalArgumentException(
|
||||
// "start and end address must be within the same address space");
|
||||
// }
|
||||
// invalidateCache();
|
||||
// RegisterValueStore values = defaultRegisterValueMap.get(register.getBaseRegister());
|
||||
@ -272,8 +273,9 @@ abstract public class AbstractStoredProgramContext extends AbstractProgramContex
|
||||
@Override
|
||||
public void setValue(Register register, Address start, Address end, BigInteger value)
|
||||
throws ContextChangeException {
|
||||
if (start.getAddressSpace() != end.getAddressSpace()) {
|
||||
throw new AssertException("start and end address must be in the same address space");
|
||||
if (!start.getAddressSpace().equals(end.getAddressSpace())) {
|
||||
throw new IllegalArgumentException(
|
||||
"start and end address must be within the same address space");
|
||||
}
|
||||
if (value == null) {
|
||||
remove(start, end, register);
|
||||
@ -284,8 +286,9 @@ abstract public class AbstractStoredProgramContext extends AbstractProgramContex
|
||||
|
||||
@Override
|
||||
public void setDefaultValue(RegisterValue registerValue, Address start, Address end) {
|
||||
if (start.getAddressSpace() != end.getAddressSpace()) {
|
||||
throw new AssertException("start and end address must be in the same address space");
|
||||
if (!start.getAddressSpace().equals(end.getAddressSpace())) {
|
||||
throw new IllegalArgumentException(
|
||||
"start and end address must be within the same address space");
|
||||
}
|
||||
Register baseRegister = registerValue.getRegister().getBaseRegister();
|
||||
RegisterValueStore store = defaultRegisterValueMap.get(baseRegister);
|
||||
|
@ -1480,7 +1480,11 @@ public class FloatFormatTest extends AbstractGenericTest {
|
||||
@Test
|
||||
public void testValueOfBigInteger() {
|
||||
FloatFormat ff = FloatFormatFactory.getFloatFormat(8);
|
||||
assertEquals("0.0", ff.toDecimalString(ff.getBigFloat(BigInteger.ZERO)));
|
||||
|
||||
assertFalse(ff.getBigZero(true).equals(ff.getBigZero(false)));
|
||||
|
||||
assertEquals("-0.0", ff.toDecimalString(ff.getBigZero(true)));
|
||||
assertEquals("0.0", ff.toDecimalString(ff.getBigZero(false)));
|
||||
assertEquals("1.0", ff.toDecimalString(ff.getBigFloat(BigInteger.ONE)));
|
||||
assertEquals("2.0", ff.toDecimalString(ff.getBigFloat(BigInteger.TWO)));
|
||||
assertEquals("-1.0", ff.toDecimalString(ff.getBigFloat(BigInteger.ONE.negate())));
|
||||
|
@ -0,0 +1,69 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.program.database.data;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.*;
|
||||
|
||||
import generic.test.AbstractGenericTest;
|
||||
import ghidra.program.model.data.*;
|
||||
|
||||
public class TypedefDBTest extends AbstractGenericTest {
|
||||
|
||||
private final String NAME = "Test";
|
||||
|
||||
private DataTypeManagerDB dataMgr;
|
||||
private int txId;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
dataMgr = new StandAloneDataTypeManager("dummyDTM");
|
||||
txId = dataMgr.startTransaction("Test");
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
if (txId > 0) {
|
||||
dataMgr.endTransaction(txId, true);
|
||||
dataMgr.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDuplicateNameResolve() throws Exception {
|
||||
|
||||
Structure struct = new StructureDataType(NAME, 0);
|
||||
struct.add(new ByteDataType(), "field1", "Comment1");
|
||||
struct.add(new WordDataType(), null, "Comment2");
|
||||
struct.add(new DWordDataType(), "field3", null);
|
||||
struct.add(new ByteDataType(), "field4", "Comment4");
|
||||
|
||||
Pointer structPtr = new PointerDataType(struct);
|
||||
|
||||
TypeDef typeDef = new TypedefDataType(NAME, structPtr);
|
||||
|
||||
TypeDef td = (TypeDef) dataMgr.resolve(typeDef, null);
|
||||
assertNotNull(td);
|
||||
assertEquals(NAME + ".conflict", td.getName());
|
||||
|
||||
assertTrue(td.isEquivalent(typeDef));
|
||||
|
||||
assertEquals("typedef Test.conflict Test *", td.toString());
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -122,7 +122,7 @@
|
||||
<pentry minsize="1" maxsize="8" extension="zero">
|
||||
<register name="x7"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="500" align="4">
|
||||
<pentry minsize="1" maxsize="500" align="8">
|
||||
<addr offset="0" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
|
@ -18,33 +18,44 @@ define pcodeop vaddpd_avx ;
|
||||
}
|
||||
|
||||
# ADDPS 3-36 PAGE 606 LINE 33558
|
||||
define pcodeop vaddps_avx ;
|
||||
:VADDPS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x58; (XmmReg1 & ZmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vaddps_avx( vexVVVV_XmmReg, XmmReg2_m128 );
|
||||
ZmmReg1 = zext(tmp);
|
||||
local tmp:16 = XmmReg2_m128;
|
||||
XmmReg1[0,32] = vexVVVV_XmmReg[0,32] f+ tmp[0,32];
|
||||
XmmReg1[32,32] = vexVVVV_XmmReg[32,32] f+ tmp[32,32];
|
||||
XmmReg1[64,32] = vexVVVV_XmmReg[64,32] f+ tmp[64,32];
|
||||
XmmReg1[96,32] = vexVVVV_XmmReg[96,32] f+ tmp[96,32];
|
||||
ZmmReg1 = zext(XmmReg1);
|
||||
}
|
||||
|
||||
|
||||
# ADDPS 3-36 PAGE 606 LINE 33560
|
||||
:VADDPS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x58; (YmmReg1 & ZmmReg1) ... & YmmReg2_m256
|
||||
{
|
||||
local tmp:32 = vaddps_avx( vexVVVV_YmmReg, YmmReg2_m256 );
|
||||
ZmmReg1 = zext(tmp);
|
||||
local tmp:32 = YmmReg2_m256;
|
||||
YmmReg1[0,32] = vexVVVV_YmmReg[0,32] f+ tmp[0,32];
|
||||
YmmReg1[32,32] = vexVVVV_YmmReg[32,32] f+ tmp[32,32];
|
||||
YmmReg1[64,32] = vexVVVV_YmmReg[64,32] f+ tmp[64,32];
|
||||
YmmReg1[96,32] = vexVVVV_YmmReg[96,32] f+ tmp[96,32];
|
||||
YmmReg1[128,32] = vexVVVV_YmmReg[128,32] f+ tmp[128,32];
|
||||
YmmReg1[160,32] = vexVVVV_YmmReg[160,32] f+ tmp[160,32];
|
||||
YmmReg1[192,32] = vexVVVV_YmmReg[192,32] f+ tmp[192,32];
|
||||
YmmReg1[224,32] = vexVVVV_YmmReg[224,32] f+ tmp[224,32];
|
||||
|
||||
ZmmReg1 = zext(YmmReg1);
|
||||
}
|
||||
|
||||
# ADDSD 3-39 PAGE 609 LINE 33718
|
||||
define pcodeop vaddsd_avx ;
|
||||
:VADDSD XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x58; (XmmReg1 & ZmmReg1) ... & XmmReg2_m64
|
||||
{
|
||||
local tmp:16 = vaddsd_avx( vexVVVV_XmmReg, XmmReg2_m64 );
|
||||
local tmp:8 = vexVVVV_XmmReg[0,64] f+ XmmReg2_m64[0,64];
|
||||
ZmmReg1 = zext(tmp);
|
||||
}
|
||||
|
||||
# ADDSS 3-41 PAGE 611 LINE 33812
|
||||
define pcodeop vaddss_avx ;
|
||||
:VADDSS XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x58; (XmmReg1 & ZmmReg1) ... & XmmReg2_m32
|
||||
{
|
||||
local tmp:16 = vaddss_avx( vexVVVV_XmmReg, XmmReg2_m32 );
|
||||
local tmp:4 = vexVVVV_XmmReg[0,32] f+ XmmReg2_m32[0,32];
|
||||
ZmmReg1 = zext(tmp);
|
||||
}
|
||||
|
||||
@ -509,19 +520,15 @@ define pcodeop vcmpss_avx ;
|
||||
}
|
||||
|
||||
# COMISD 3-186 PAGE 756 LINE 40860
|
||||
define pcodeop vcomisd_avx ;
|
||||
:VCOMISD XmmReg1, XmmReg2_m64 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x2F; (XmmReg1 & ZmmReg1) ... & XmmReg2_m64
|
||||
{
|
||||
local tmp:16 = vcomisd_avx( XmmReg2_m64 );
|
||||
ZmmReg1 = zext(tmp);
|
||||
fucompe(XmmReg1[0,64], XmmReg2_m64[0,64]);
|
||||
}
|
||||
|
||||
# COMISS 3-188 PAGE 758 LINE 40938
|
||||
define pcodeop vcomiss_avx ;
|
||||
:VCOMISS XmmReg1, XmmReg2_m32 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x2F; (XmmReg1 & ZmmReg1) ... & XmmReg2_m32
|
||||
{
|
||||
local tmp:16 = vcomiss_avx( XmmReg2_m32 );
|
||||
ZmmReg1 = zext(tmp);
|
||||
fucompe(XmmReg1[0,32], XmmReg2_m32[0,32]);
|
||||
}
|
||||
|
||||
# CVTDQ2PD 3-228 PAGE 798 LINE 43074
|
||||
@ -615,10 +622,9 @@ define pcodeop vcvtps2pd_avx ;
|
||||
}
|
||||
|
||||
# CVTSD2SI 3-253 PAGE 823 LINE 44315
|
||||
define pcodeop vcvtsd2si_avx ;
|
||||
:VCVTSD2SI Reg32, XmmReg2_m64 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_W0); byte=0x2D; Reg32 ... & XmmReg2_m64
|
||||
{
|
||||
Reg32 = vcvtsd2si_avx( XmmReg2_m64 );
|
||||
Reg32 = trunc(round(XmmReg2_m64[0,64]));
|
||||
# TODO Reg64 = zext(Reg32)
|
||||
}
|
||||
|
||||
@ -626,49 +632,56 @@ define pcodeop vcvtsd2si_avx ;
|
||||
@ifdef IA64
|
||||
:VCVTSD2SI Reg64, XmmReg2_m64 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_W1); byte=0x2D; Reg64 ... & XmmReg2_m64
|
||||
{
|
||||
Reg64 = vcvtsd2si_avx( XmmReg2_m64 );
|
||||
Reg64 = round(XmmReg2_m64[0,64]);
|
||||
}
|
||||
@endif
|
||||
|
||||
# CVTSD2SS 3-255 PAGE 825 LINE 44414
|
||||
define pcodeop vcvtsd2ss_avx ;
|
||||
:VCVTSD2SS XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x5A; (XmmReg1 & ZmmReg1) ... & XmmReg2_m64
|
||||
{
|
||||
local tmp:16 = vcvtsd2ss_avx( vexVVVV_XmmReg, XmmReg2_m64 );
|
||||
ZmmReg1 = zext(tmp);
|
||||
local tmp:4 = float2float(XmmReg2_m64[0,64]);
|
||||
XmmReg1[0,32] = tmp;
|
||||
XmmReg1[32,96] = vexVVVV_XmmReg[32,96];
|
||||
ZmmReg1 = zext(XmmReg1);
|
||||
}
|
||||
|
||||
# CVTSI2SD 3-257 PAGE 827 LINE 44516
|
||||
define pcodeop vcvtsi2sd_avx ;
|
||||
:VCVTSI2SD XmmReg1, vexVVVV_XmmReg, rm32 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x2A; (XmmReg1 & ZmmReg1) ... & rm32
|
||||
{
|
||||
local tmp:16 = vcvtsi2sd_avx( vexVVVV_XmmReg, rm32 );
|
||||
ZmmReg1 = zext(tmp);
|
||||
local tmp:8 = int2float(rm32);
|
||||
XmmReg1[0,64] = tmp;
|
||||
XmmReg1[64,64] = vexVVVV_XmmReg[64,64];
|
||||
ZmmReg1 = zext(XmmReg1);
|
||||
}
|
||||
|
||||
# CVTSI2SD 3-257 PAGE 827 LINE 44519
|
||||
@ifdef IA64
|
||||
:VCVTSI2SD XmmReg1, vexVVVV_XmmReg, rm64 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x2A; (XmmReg1 & ZmmReg1) ... & rm64
|
||||
{
|
||||
local tmp:16 = vcvtsi2sd_avx( vexVVVV_XmmReg, rm64 );
|
||||
ZmmReg1 = zext(tmp);
|
||||
local tmp:8 = int2float(rm64);
|
||||
XmmReg1[0,64] = tmp;
|
||||
XmmReg1[64,64] = vexVVVV_XmmReg[64,64];
|
||||
ZmmReg1 = zext(XmmReg1);
|
||||
}
|
||||
@endif
|
||||
|
||||
# CVTSI2SS 3-259 PAGE 829 LINE 44632
|
||||
define pcodeop vcvtsi2ss_avx ;
|
||||
:VCVTSI2SS XmmReg1, vexVVVV_XmmReg, rm32 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x2A; (XmmReg1 & ZmmReg1) ... & rm32
|
||||
{
|
||||
local tmp:16 = vcvtsi2ss_avx( vexVVVV_XmmReg, rm32 );
|
||||
ZmmReg1 = zext(tmp);
|
||||
local tmp:4 = int2float( rm32 );
|
||||
XmmReg1[0,32] = tmp;
|
||||
XmmReg1[32,96] = vexVVVV_XmmReg[32,96];
|
||||
ZmmReg1 = zext(XmmReg1);
|
||||
}
|
||||
|
||||
# CVTSI2SS 3-259 PAGE 829 LINE 44634
|
||||
@ifdef IA64
|
||||
:VCVTSI2SS XmmReg1, vexVVVV_XmmReg, rm64 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x2A; (XmmReg1 & ZmmReg1) ... & rm64
|
||||
{
|
||||
local tmp:16 = vcvtsi2ss_avx( vexVVVV_XmmReg, rm64 );
|
||||
ZmmReg1 = zext(tmp);
|
||||
local tmp:4 = int2float( rm64 );
|
||||
XmmReg1[0,32] = tmp;
|
||||
XmmReg1[32,96] = vexVVVV_XmmReg[32,96];
|
||||
ZmmReg1 = zext(XmmReg1);
|
||||
}
|
||||
@endif
|
||||
|
||||
@ -1026,77 +1039,90 @@ define pcodeop vminss_avx ;
|
||||
}
|
||||
|
||||
# MOVD/MOVQ 4-55 PAGE 1175 LINE 61358
|
||||
define pcodeop vmovd_avx ;
|
||||
:VMOVD XmmReg1, rm32 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_W0); byte=0x6E; (XmmReg1 & ZmmReg1) ... & rm32
|
||||
{
|
||||
local tmp:16 = vmovd_avx( rm32 );
|
||||
ZmmReg1 = zext(tmp);
|
||||
ZmmReg1 = zext( rm32 );
|
||||
}
|
||||
|
||||
# MOVD/MOVQ 4-55 PAGE 1175 LINE 61360
|
||||
define pcodeop vmovq_avx ;
|
||||
@ifdef IA64
|
||||
:VMOVQ XmmReg1, rm64 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_W1); byte=0x6E; (XmmReg1 & ZmmReg1) ... & rm64
|
||||
{
|
||||
local tmp:16 = vmovq_avx( rm64 );
|
||||
ZmmReg1 = zext(tmp);
|
||||
ZmmReg1 = zext( rm64 );
|
||||
}
|
||||
@endif
|
||||
|
||||
# MOVD/MOVQ 4-55 PAGE 1175 LINE 61362
|
||||
:VMOVD rm32, XmmReg1 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_W0); byte=0x7E; XmmReg1 ... & rm32
|
||||
{
|
||||
rm32 = vmovd_avx( XmmReg1 );
|
||||
rm32 = XmmReg1 [0,32];
|
||||
}
|
||||
|
||||
# MOVD/MOVQ 4-55 PAGE 1175 LINE 61364
|
||||
@ifdef IA64
|
||||
:VMOVQ rm64, XmmReg1 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_W1); byte=0x7E; XmmReg1 ... & rm64
|
||||
{
|
||||
rm64 = vmovq_avx( XmmReg1 );
|
||||
rm64 = XmmReg1 [0,64];
|
||||
}
|
||||
@endif
|
||||
|
||||
# MOVDDUP 4-59 PAGE 1179 LINE 61521
|
||||
define pcodeop vmovddup_avx ;
|
||||
:VMOVDDUP XmmReg1, XmmReg2_m64 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_WIG); byte=0x12; (XmmReg1 & ZmmReg1) ... & XmmReg2_m64
|
||||
{
|
||||
local tmp:16 = vmovddup_avx( XmmReg2_m64 );
|
||||
ZmmReg1 = zext(tmp);
|
||||
local tmp:8 = XmmReg2_m64[0,64];
|
||||
XmmReg1[0,64] = tmp;
|
||||
XmmReg1[64,64] = tmp;
|
||||
ZmmReg1 = zext(XmmReg1);
|
||||
}
|
||||
|
||||
# MOVDDUP 4-59 PAGE 1179 LINE 61523
|
||||
:VMOVDDUP YmmReg1, YmmReg2_m256 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_WIG); byte=0x12; (YmmReg1 & ZmmReg1) ... & YmmReg2_m256
|
||||
{
|
||||
local tmp:32 = vmovddup_avx( YmmReg2_m256 );
|
||||
ZmmReg1 = zext(tmp);
|
||||
local tmp:32 = YmmReg2_m256;
|
||||
local tmp1:8 = tmp[0,64];
|
||||
local tmp2:8 = tmp[128,64];
|
||||
YmmReg1[0,64] = tmp1;
|
||||
YmmReg1[64,64] = tmp1;
|
||||
YmmReg1[128,64] = tmp2;
|
||||
YmmReg1[192,64] = tmp2;
|
||||
ZmmReg1 = zext(YmmReg1);
|
||||
}
|
||||
|
||||
# MOVDQU,VMOVDQU8/16/32/64 4-67 PAGE 1187 LINE 61930
|
||||
define pcodeop vmovdqu_avx ;
|
||||
:VMOVDQU XmmReg1, XmmReg2_m128 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG); byte=0x6F; (XmmReg1 & ZmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vmovdqu_avx( XmmReg2_m128 );
|
||||
local tmp:16 = XmmReg2_m128;
|
||||
ZmmReg1 = zext(tmp);
|
||||
}
|
||||
|
||||
# MOVDQU,VMOVDQU8/16/32/64 4-67 PAGE 1187 LINE 61932
|
||||
:VMOVDQU XmmReg2_m128, XmmReg1 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG); byte=0x7F; XmmReg1 ... & XmmReg2_m128
|
||||
:VMOVDQU m128, XmmReg1 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG); byte=0x7F; XmmReg1 ... & m128
|
||||
{
|
||||
XmmReg2_m128 = vmovdqu_avx( XmmReg1 );
|
||||
m128 = XmmReg1;
|
||||
}
|
||||
|
||||
:VMOVDQU XmmReg2, XmmReg1 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG); byte=0x7F; XmmReg1 & (mod=3 & XmmReg2 & ZmmReg2)
|
||||
{
|
||||
ZmmReg2 = zext( XmmReg1 );
|
||||
}
|
||||
|
||||
|
||||
# MOVDQU,VMOVDQU8/16/32/64 4-67 PAGE 1187 LINE 61934
|
||||
:VMOVDQU YmmReg1, YmmReg2_m256 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG); byte=0x6F; (YmmReg1 & ZmmReg1) ... & YmmReg2_m256
|
||||
{
|
||||
local tmp:32 = vmovdqu_avx( YmmReg2_m256 );
|
||||
local tmp:32 = YmmReg2_m256;
|
||||
ZmmReg1 = zext(tmp);
|
||||
}
|
||||
|
||||
# MOVDQU,VMOVDQU8/16/32/64 4-67 PAGE 1187 LINE 61936
|
||||
:VMOVDQU YmmReg2_m256, YmmReg1 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG); byte=0x7F; YmmReg1 ... & YmmReg2_m256
|
||||
:VMOVDQU m256, YmmReg1 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG); byte=0x7F; YmmReg1 ... & m256
|
||||
{
|
||||
YmmReg2_m256 = vmovdqu_avx( YmmReg1 );
|
||||
m256 = YmmReg1;
|
||||
}
|
||||
|
||||
:VMOVDQU YmmReg2, YmmReg1 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG); byte=0x7F; YmmReg1 & (mod=3 & ZmmReg2 & YmmReg2)
|
||||
{
|
||||
ZmmReg2 = zext( YmmReg1 );
|
||||
}
|
||||
|
||||
# MOVHLPS 4-76 PAGE 1196 LINE 62410
|
||||
@ -1251,14 +1277,18 @@ define pcodeop vmovntps_avx ;
|
||||
# MOVQ 4-103 PAGE 1223 LINE 63579
|
||||
:VMOVQ XmmReg1, XmmReg2_m64 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG); byte=0x7E; (XmmReg1 & ZmmReg1) ... & XmmReg2_m64
|
||||
{
|
||||
local tmp:16 = vmovq_avx( XmmReg2_m64 );
|
||||
ZmmReg1 = zext(tmp);
|
||||
ZmmReg1 = zext(XmmReg2_m64[0,64]);
|
||||
}
|
||||
|
||||
# MOVQ 4-103 PAGE 1223 LINE 63585
|
||||
:VMOVQ XmmReg2_m64, XmmReg1 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0xD6; XmmReg1 ... & XmmReg2_m64
|
||||
:VMOVQ m64, XmmReg1 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0xD6; XmmReg1 ... & m64
|
||||
{
|
||||
XmmReg2_m64 = vmovq_avx( XmmReg1 );
|
||||
m64 = XmmReg1[0,64];
|
||||
}
|
||||
|
||||
:VMOVQ XmmReg2, XmmReg1 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0xD6; XmmReg1 & (mod=3 & XmmReg2 & ZmmReg2 )
|
||||
{
|
||||
ZmmReg2 = zext( XmmReg1[0,64] );
|
||||
}
|
||||
|
||||
# MOVSHDUP 4-114 PAGE 1234 LINE 64126
|
||||
@ -1292,58 +1322,69 @@ define pcodeop vmovsldup_avx ;
|
||||
}
|
||||
|
||||
# MOVSS 4-120 PAGE 1240 LINE 64433
|
||||
define pcodeop vmovss_avx ;
|
||||
|
||||
:VMOVSS XmmReg1, vexVVVV_XmmReg, XmmReg2 is $(VEX_NDS) & $(VEX_LIG) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x10; (XmmReg1 & ZmmReg1) & (mod=0x3 & XmmReg2)
|
||||
{
|
||||
local tmp:16 = vmovss_avx( vexVVVV_XmmReg, XmmReg2 );
|
||||
ZmmReg1 = zext(tmp);
|
||||
XmmReg1[0,32] = XmmReg2[0,32];
|
||||
XmmReg1[32,96] = vexVVVV_XmmReg[32,96];
|
||||
ZmmReg1 = zext(XmmReg1);
|
||||
}
|
||||
|
||||
# MOVSS 4-120 PAGE 1240 LINE 64435
|
||||
:VMOVSS XmmReg1, m32 is $(VEX_NONE) & $(VEX_LIG) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG); byte=0x10; (XmmReg1 & ZmmReg1) ... & m32
|
||||
{
|
||||
local tmp:16 = vmovss_avx( m32 );
|
||||
ZmmReg1 = zext(tmp);
|
||||
ZmmReg1 = zext( m32 );
|
||||
}
|
||||
|
||||
# MOVSS 4-120 PAGE 1240 LINE 64439
|
||||
:VMOVSS XmmReg2, vexVVVV_XmmReg, XmmReg1 is $(VEX_NDS) & $(VEX_LIG) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x11; XmmReg1 & (mod=0x3 & (XmmReg2 & ZmmReg2))
|
||||
{
|
||||
local tmp:16 = vmovss_avx( vexVVVV_XmmReg, XmmReg1 );
|
||||
ZmmReg2 = zext(tmp);
|
||||
XmmReg2[0,32] = XmmReg1[0,32];
|
||||
XmmReg2[32,96] = vexVVVV_XmmReg[32,96];
|
||||
ZmmReg2 = zext(XmmReg2);
|
||||
}
|
||||
|
||||
# MOVSS 4-120 PAGE 1240 LINE 64441
|
||||
:VMOVSS m32, XmmReg1 is $(VEX_NONE) & $(VEX_LIG) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG); byte=0x11; XmmReg1 ... & m32
|
||||
{
|
||||
m32 = vmovss_avx( XmmReg1 );
|
||||
m32 = XmmReg1[0,32];
|
||||
}
|
||||
|
||||
# MOVUPD 4-126 PAGE 1246 LINE 64687
|
||||
define pcodeop vmovupd_avx ;
|
||||
:VMOVUPD XmmReg1, XmmReg2_m128 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x10; (XmmReg1 & ZmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vmovupd_avx( XmmReg2_m128 );
|
||||
local tmp:16 = XmmReg2_m128;
|
||||
ZmmReg1 = zext(tmp);
|
||||
}
|
||||
|
||||
# MOVUPD 4-126 PAGE 1246 LINE 64689
|
||||
:VMOVUPD XmmReg2_m128, XmmReg1 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x11; XmmReg1 ... & XmmReg2_m128
|
||||
:VMOVUPD m128, XmmReg1 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x11; XmmReg1 ... & m128
|
||||
{
|
||||
XmmReg2_m128 = vmovupd_avx( XmmReg1 );
|
||||
m128 = XmmReg1;
|
||||
}
|
||||
|
||||
:VMOVUPD XmmReg2, XmmReg1 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x11; XmmReg1 & ( mod=3 & XmmReg2 & ZmmReg2 )
|
||||
{
|
||||
ZmmReg2 = zext( XmmReg1 );
|
||||
}
|
||||
|
||||
# MOVUPD 4-126 PAGE 1246 LINE 64691
|
||||
:VMOVUPD YmmReg1, YmmReg2_m256 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x10; (YmmReg1 & ZmmReg1) ... & YmmReg2_m256
|
||||
{
|
||||
local tmp:32 = vmovupd_avx( YmmReg2_m256 );
|
||||
local tmp:32 = YmmReg2_m256;
|
||||
ZmmReg1 = zext(tmp);
|
||||
}
|
||||
|
||||
# MOVUPD 4-126 PAGE 1246 LINE 64693
|
||||
:VMOVUPD YmmReg2_m256, YmmReg1 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x11; YmmReg1 ... & YmmReg2_m256
|
||||
:VMOVUPD m256, YmmReg1 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x11; YmmReg1 ... & m256
|
||||
{
|
||||
YmmReg2_m256 = vmovupd_avx( YmmReg1 );
|
||||
m256 = YmmReg1;
|
||||
}
|
||||
|
||||
:VMOVUPD YmmReg2, YmmReg1 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x11; YmmReg1 & ( mod=3 & YmmReg2 & ZmmReg2 )
|
||||
{
|
||||
local tmp:32 = YmmReg1;
|
||||
ZmmReg2 = zext(tmp);
|
||||
}
|
||||
|
||||
# MPSADBW 4-136 PAGE 1256 LINE 65135
|
||||
@ -1385,18 +1426,16 @@ define pcodeop vmulps_avx ;
|
||||
}
|
||||
|
||||
# MULSD 4-152 PAGE 1272 LINE 65956
|
||||
define pcodeop vmulsd_avx ;
|
||||
:VMULSD XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x59; (XmmReg1 & ZmmReg1) ... & XmmReg2_m64
|
||||
{
|
||||
local tmp:16 = vmulsd_avx( vexVVVV_XmmReg, XmmReg2_m64 );
|
||||
local tmp:8 = vexVVVV_XmmReg[0,64] f* XmmReg2_m64[0,64];
|
||||
ZmmReg1 = zext(tmp);
|
||||
}
|
||||
|
||||
# MULSS 4-154 PAGE 1274 LINE 66052
|
||||
define pcodeop vmulss_avx ;
|
||||
:VMULSS XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x59; (XmmReg1 & ZmmReg1) ... & XmmReg2_m32
|
||||
{
|
||||
local tmp:16 = vmulss_avx( vexVVVV_XmmReg, XmmReg2_m32 );
|
||||
local tmp:4 = vexVVVV_XmmReg[0,32] f* XmmReg2_m32[0,32];
|
||||
ZmmReg1 = zext(tmp);
|
||||
}
|
||||
|
||||
@ -2429,10 +2468,9 @@ define pcodeop vpunpcklqdq_avx ;
|
||||
}
|
||||
|
||||
# PXOR 4-518 PAGE 1638 LINE 85495
|
||||
define pcodeop vpxor_avx ;
|
||||
:VPXOR XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xEF; (XmmReg1 & ZmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vpxor_avx( vexVVVV_XmmReg, XmmReg2_m128 );
|
||||
local tmp:16 = vexVVVV_XmmReg ^ XmmReg2_m128;
|
||||
ZmmReg1 = zext(tmp);
|
||||
}
|
||||
|
||||
@ -2642,35 +2680,33 @@ define pcodeop vsubps_avx ;
|
||||
}
|
||||
|
||||
# SUBSD 4-662 PAGE 1782 LINE 92419
|
||||
define pcodeop vsubsd_avx ;
|
||||
:VSUBSD XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x5C; (XmmReg1 & ZmmReg1) ... & XmmReg2_m64
|
||||
{
|
||||
local tmp:16 = vsubsd_avx( vexVVVV_XmmReg, XmmReg2_m64 );
|
||||
local tmp:8 = vexVVVV_XmmReg[0,64] f- XmmReg2_m64[0,64];
|
||||
ZmmReg1 = zext(tmp);
|
||||
}
|
||||
|
||||
# SUBSS 4-664 PAGE 1784 LINE 92512
|
||||
define pcodeop vsubss_avx ;
|
||||
:VSUBSS XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x5C; (XmmReg1 & ZmmReg1) ... & XmmReg2_m32
|
||||
{
|
||||
local tmp:16 = vsubss_avx( vexVVVV_XmmReg, XmmReg2_m32 );
|
||||
local tmp:4 = vexVVVV_XmmReg[0,32] f- XmmReg2_m32[0,32];
|
||||
ZmmReg1 = zext(tmp);
|
||||
}
|
||||
|
||||
# UCOMISD 4-683 PAGE 1803 LINE 93421
|
||||
define pcodeop vucomisd_avx ;
|
||||
:VUCOMISD XmmReg1, XmmReg2_m64 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x2E; XmmReg1 ... & XmmReg2_m64
|
||||
{
|
||||
vucomisd_avx( XmmReg1, XmmReg2_m64 );
|
||||
# TODO set flags AF, CF, OF, PF, SF, ZF
|
||||
val1:8 = XmmReg1[0,64];
|
||||
val2:8 = XmmReg2_m64[0,64];
|
||||
fucompe(val1, val2);
|
||||
}
|
||||
|
||||
# UCOMISS 4-685 PAGE 1805 LINE 93504
|
||||
define pcodeop vucomiss_avx ;
|
||||
:VUCOMISS XmmReg1, XmmReg2_m32 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x2E; XmmReg1 ... & XmmReg2_m32
|
||||
{
|
||||
vucomiss_avx( XmmReg1, XmmReg2_m32 );
|
||||
# TODO set flags AF, CF, OF, PF, SF, ZF
|
||||
val1:4 = XmmReg1[0,32];
|
||||
val2:4 = XmmReg2_m32[0,32];
|
||||
fucompe(val1, val2);
|
||||
}
|
||||
|
||||
# UNPCKHPD 4-688 PAGE 1808 LINE 93623
|
||||
@ -2930,33 +2966,49 @@ define pcodeop vtestpd_avx ;
|
||||
}
|
||||
|
||||
# XORPD 5-596 PAGE 2420 LINE 123828
|
||||
define pcodeop vxorpd_avx ;
|
||||
:VXORPD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x57; (XmmReg1 & ZmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vxorpd_avx( vexVVVV_XmmReg, XmmReg2_m128 );
|
||||
ZmmReg1 = zext(tmp);
|
||||
tmp:16 = XmmReg2_m128;
|
||||
XmmReg1[0,64] = ( vexVVVV_XmmReg[0,64] ^ tmp[0,64] );
|
||||
XmmReg1[64,64] = ( vexVVVV_XmmReg[64,64] ^ tmp[64,64] );
|
||||
ZmmReg1 = zext(XmmReg1);
|
||||
}
|
||||
|
||||
# XORPD 5-596 PAGE 2420 LINE 123831
|
||||
:VXORPD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x57; (YmmReg1 & ZmmReg1) ... & YmmReg2_m256
|
||||
{
|
||||
local tmp:32 = vxorpd_avx( vexVVVV_YmmReg, YmmReg2_m256 );
|
||||
ZmmReg1 = zext(tmp);
|
||||
tmp:32 = YmmReg2_m256;
|
||||
YmmReg1[0,64] = ( vexVVVV_YmmReg[0,64] ^ tmp[0,64] );
|
||||
YmmReg1[64,64] = ( vexVVVV_YmmReg[64,64] ^ tmp[64,64] );
|
||||
YmmReg1[128,64] = ( vexVVVV_YmmReg[128,64] ^ tmp[128,64] );
|
||||
YmmReg1[192,64] = ( vexVVVV_YmmReg[192,64] ^ tmp[192,64] );
|
||||
ZmmReg1 = zext(YmmReg1);
|
||||
}
|
||||
|
||||
# XORPS 5-599 PAGE 2423 LINE 123953
|
||||
define pcodeop vxorps_avx ;
|
||||
:VXORPS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x57; (XmmReg1 & ZmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vxorps_avx( vexVVVV_XmmReg, XmmReg2_m128 );
|
||||
ZmmReg1 = zext(tmp);
|
||||
tmp:16 = XmmReg2_m128;
|
||||
XmmReg1[0,32] = ( vexVVVV_XmmReg[0,32] ^ tmp[0,32] );
|
||||
XmmReg1[32,32] = ( vexVVVV_XmmReg[32,32] ^ tmp[32,32] );
|
||||
XmmReg1[64,32] = ( vexVVVV_XmmReg[64,32] ^ tmp[64,32] );
|
||||
XmmReg1[96,32] = ( vexVVVV_XmmReg[96,32] ^ tmp[96,32] );
|
||||
ZmmReg1 = zext(XmmReg1);
|
||||
}
|
||||
|
||||
# XORPS 5-599 PAGE 2423 LINE 123956
|
||||
:VXORPS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x57; (YmmReg1 & ZmmReg1) ... & YmmReg2_m256
|
||||
{
|
||||
local tmp:32 = vxorps_avx( vexVVVV_YmmReg, YmmReg2_m256 );
|
||||
ZmmReg1 = zext(tmp);
|
||||
tmp:32 = YmmReg2_m256;
|
||||
YmmReg1[0,32] = ( vexVVVV_YmmReg[0,32] ^ tmp[0,32] );
|
||||
YmmReg1[32,32] = ( vexVVVV_YmmReg[32,32] ^ tmp[32,32] );
|
||||
YmmReg1[64,32] = ( vexVVVV_YmmReg[64,32] ^ tmp[64,32] );
|
||||
YmmReg1[96,32] = ( vexVVVV_YmmReg[96,32] ^ tmp[96,32] );
|
||||
YmmReg1[128,32] = ( vexVVVV_YmmReg[128,32] ^ tmp[128,32] );
|
||||
YmmReg1[160,32] = ( vexVVVV_YmmReg[160,32] ^ tmp[160,32] );
|
||||
YmmReg1[192,32] = ( vexVVVV_YmmReg[192,32] ^ tmp[192,32] );
|
||||
YmmReg1[224,32] = ( vexVVVV_YmmReg[224,32] ^ tmp[224,32] );
|
||||
ZmmReg1 = zext(YmmReg1);
|
||||
}
|
||||
|
||||
# INFO This file automatically generated by andre on Tue Apr 30 16:08:43 2024
|
||||
|
@ -889,18 +889,17 @@ define pcodeop vpunpcklqdq_avx2 ;
|
||||
}
|
||||
|
||||
# PXOR 4-518 PAGE 1638 LINE 85497
|
||||
define pcodeop vpxor_avx2 ;
|
||||
:VPXOR YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xEF; (YmmReg1 & ZmmReg1) ... & YmmReg2_m256
|
||||
{
|
||||
local tmp:32 = vpxor_avx2( vexVVVV_YmmReg, YmmReg2_m256 );
|
||||
local tmp:32 = vexVVVV_YmmReg ^ YmmReg2_m256;
|
||||
ZmmReg1 = zext(tmp);
|
||||
}
|
||||
|
||||
# VEXTRACTI128/VEXTRACTI32x4/VEXTRACTI64x2/VEXTRACTI32x8/VEXTRACTI64x4 5-106 PAGE 1930 LINE 99432
|
||||
define pcodeop vextracti128_avx2 ;
|
||||
:VEXTRACTI128 XmmReg2_m128, YmmReg1, imm8 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W0); byte=0x39; YmmReg1 ... & XmmReg2_m128; imm8
|
||||
{
|
||||
XmmReg2_m128 = vextracti128_avx2( YmmReg1, imm8:1 );
|
||||
local ext:1 = imm8:1 == 1;
|
||||
XmmReg2_m128 = (YmmReg1[0,128] * zext(ext==0)) | (YmmReg1[128,128] * zext(ext==1));
|
||||
}
|
||||
|
||||
# VPBLENDD 5-321 PAGE 2145 LINE 110309
|
||||
|
@ -4362,9 +4362,9 @@ define pcodeop skinit;
|
||||
@endif
|
||||
|
||||
define pcodeop invalidInstructionException;
|
||||
:UD0 Reg32, rm32 is vexMode=0 & byte=0x0f; byte=0xff; rm32 & Reg32 ... { invalidInstructionException(); goto inst_start; }
|
||||
:UD1 Reg32, rm32 is vexMode=0 & byte=0x0f; byte=0xb9; rm32 & Reg32 ... { invalidInstructionException(); goto inst_start; }
|
||||
:UD2 is vexMode=0 & byte=0xf; byte=0xb { invalidInstructionException(); goto inst_start; }
|
||||
:UD0 Reg32, rm32 is vexMode=0 & byte=0x0f; byte=0xff; rm32 & Reg32 ... { local target:$(SIZE) = invalidInstructionException(); goto [target]; }
|
||||
:UD1 Reg32, rm32 is vexMode=0 & byte=0x0f; byte=0xb9; rm32 & Reg32 ... { local target:$(SIZE) = invalidInstructionException(); goto [target]; }
|
||||
:UD2 is vexMode=0 & byte=0xf; byte=0xb { local target:$(SIZE) = invalidInstructionException(); goto [target]; }
|
||||
|
||||
define pcodeop verr;
|
||||
define pcodeop verw;
|
||||
|
@ -5,7 +5,7 @@
|
||||
endian="little"
|
||||
size="32"
|
||||
variant="default"
|
||||
version="4.0"
|
||||
version="4.1"
|
||||
slafile="x86.sla"
|
||||
processorspec="x86.pspec"
|
||||
manualindexfile="../manuals/x86.idx"
|
||||
@ -36,7 +36,7 @@
|
||||
endian="little"
|
||||
size="32"
|
||||
variant="System Management Mode"
|
||||
version="4.0"
|
||||
version="4.1"
|
||||
slafile="x86.sla"
|
||||
processorspec="x86-16.pspec"
|
||||
manualindexfile="../manuals/x86.idx"
|
||||
@ -49,7 +49,7 @@
|
||||
endian="little"
|
||||
size="16"
|
||||
variant="Real Mode"
|
||||
version="4.0"
|
||||
version="4.1"
|
||||
slafile="x86.sla"
|
||||
processorspec="x86-16-real.pspec"
|
||||
manualindexfile="../manuals/x86.idx"
|
||||
@ -69,7 +69,7 @@
|
||||
endian="little"
|
||||
size="16"
|
||||
variant="Protected Mode"
|
||||
version="4.0"
|
||||
version="4.1"
|
||||
slafile="x86.sla"
|
||||
processorspec="x86-16.pspec"
|
||||
manualindexfile="../manuals/x86.idx"
|
||||
@ -84,7 +84,7 @@
|
||||
endian="little"
|
||||
size="64"
|
||||
variant="default"
|
||||
version="4.0"
|
||||
version="4.1"
|
||||
slafile="x86-64.sla"
|
||||
processorspec="x86-64.pspec"
|
||||
manualindexfile="../manuals/x86.idx"
|
||||
@ -106,7 +106,7 @@
|
||||
endian="little"
|
||||
size="64"
|
||||
variant="compat32"
|
||||
version="4.0"
|
||||
version="4.1"
|
||||
slafile="x86-64.sla"
|
||||
processorspec="x86-64-compat32.pspec"
|
||||
manualindexfile="../manuals/x86.idx"
|
||||
|
@ -141,6 +141,13 @@ class X86_64_ElfRelocationContext extends ElfRelocationContext<X86_64_ElfRelocat
|
||||
|
||||
private Address allocateGot() {
|
||||
|
||||
if (allocatedGotAddress != null) {
|
||||
if (allocatedGotAddress == Address.NO_ADDRESS) {
|
||||
return null;
|
||||
}
|
||||
return allocatedGotAddress;
|
||||
}
|
||||
|
||||
allocatedGotAddress = Address.NO_ADDRESS;
|
||||
nextAllocatedGotEntryAddress = Address.NO_ADDRESS;
|
||||
|
||||
@ -193,7 +200,9 @@ class X86_64_ElfRelocationContext extends ElfRelocationContext<X86_64_ElfRelocat
|
||||
*/
|
||||
private Address getNextAllocatedGotEntryAddress() {
|
||||
if (nextAllocatedGotEntryAddress == null) {
|
||||
allocateGot();
|
||||
if (allocateGot() == null) {
|
||||
return Address.NO_ADDRESS; // failed to allocate got
|
||||
}
|
||||
}
|
||||
|
||||
Address addr = nextAllocatedGotEntryAddress;
|
||||
|
@ -134,7 +134,7 @@ public class X86_64_ElfRelocationHandler extends
|
||||
}
|
||||
catch (NotFoundException e) {
|
||||
markAsError(program, relocationAddress, type, symbolName, symbolIndex,
|
||||
e.getMessage(), elfRelocationContext.getLog());
|
||||
"GOT allocation failure", elfRelocationContext.getLog());
|
||||
return RelocationResult.FAILURE;
|
||||
}
|
||||
break;
|
||||
@ -257,6 +257,32 @@ public class X86_64_ElfRelocationHandler extends
|
||||
}
|
||||
value = symbolGotAddress.getOffset() + addend - offset;
|
||||
memory.setLong(relocationAddress, value);
|
||||
break;
|
||||
|
||||
case R_X86_64_GOT64: // 64 bit GOT entry offset (UNVERIFIED)
|
||||
symbolGotAddress = elfRelocationContext.getGotEntryAddress(sym);
|
||||
if (symbolGotAddress == null) {
|
||||
markAsError(program, relocationAddress, type, symbolName, symbolIndex,
|
||||
"GOT allocation failure", elfRelocationContext.getLog());
|
||||
return RelocationResult.FAILURE;
|
||||
}
|
||||
value = symbolGotAddress.getOffset() + addend;
|
||||
memory.setLong(relocationAddress, value);
|
||||
break;
|
||||
|
||||
case R_X86_64_PLTOFF64: // 64 bit GOT relative offset to PLT entry (UNVERIFIED)
|
||||
long dotgot;
|
||||
try {
|
||||
dotgot = elfRelocationContext.getGOTValue();
|
||||
}
|
||||
catch (NotFoundException e) {
|
||||
markAsError(program, relocationAddress, type, symbolName, symbolIndex,
|
||||
"GOT allocation failure", elfRelocationContext.getLog());
|
||||
return RelocationResult.FAILURE;
|
||||
}
|
||||
value = symbolValue - dotgot + addend;
|
||||
memory.setLong(relocationAddress, value);
|
||||
break;
|
||||
|
||||
case R_X86_64_RELATIVE:
|
||||
// word64 for LP64 and specifies word32 for ILP32,
|
||||
|
@ -23,11 +23,11 @@ import java.net.*;
|
||||
import java.nio.file.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.function.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
import org.junit.Before;
|
||||
@ -157,16 +157,22 @@ public abstract class AbstractGdbTraceRmiTest extends AbstractGhidraHeadedDebugg
|
||||
}
|
||||
|
||||
protected record GdbResult(boolean timedOut, int exitCode, String stdout, String stderr) {
|
||||
String filterLines(String in, Predicate<String> lineTest) {
|
||||
return Stream.of(in.split("\n")).filter(lineTest).collect(Collectors.joining("\n"));
|
||||
}
|
||||
|
||||
protected String handle() {
|
||||
if (!"".equals(stderr) | 0 != exitCode) {
|
||||
String filtErr = filterLines(stderr, line -> {
|
||||
return !line.contains("warning: could not find '.gnu_debugaltlink' file");
|
||||
});
|
||||
if (!filtErr.isBlank() | 0 != exitCode) {
|
||||
throw new GdbError(exitCode, stdout, stderr);
|
||||
}
|
||||
return stdout;
|
||||
}
|
||||
}
|
||||
|
||||
protected record ExecInGdb(Process gdb, CompletableFuture<GdbResult> future) {
|
||||
}
|
||||
protected record ExecInGdb(Process gdb, CompletableFuture<GdbResult> future) {}
|
||||
|
||||
@SuppressWarnings("resource") // Do not close stdin
|
||||
protected ExecInGdb execInGdb(String script) throws IOException {
|
||||
@ -345,8 +351,7 @@ public abstract class AbstractGdbTraceRmiTest extends AbstractGhidraHeadedDebugg
|
||||
return out.split(head)[1].split("---")[0].replace("(gdb)", "").trim();
|
||||
}
|
||||
|
||||
record MemDump(long address, byte[] data) {
|
||||
}
|
||||
record MemDump(long address, byte[] data) {}
|
||||
|
||||
protected MemDump parseHexDump(String dump) throws IOException {
|
||||
// First, get the address. Assume contiguous, so only need top line.
|
||||
|
@ -1020,7 +1020,7 @@ public class GdbCommandsTest extends AbstractGdbTraceRmiTest {
|
||||
starti
|
||||
ghidra trace start
|
||||
ghidra trace tx-start "Tx"
|
||||
break main
|
||||
break *main
|
||||
hbreak *main+10
|
||||
watch -l *((char*)(&main+20))
|
||||
rwatch -l *((char(*)[8])(&main+30))
|
||||
@ -1046,7 +1046,7 @@ public class GdbCommandsTest extends AbstractGdbTraceRmiTest {
|
||||
// NB. starti avoid use of temporary main breakpoint
|
||||
assertBreakLoc(infBreakLocVals.get(0), "[1.1]", main, 1,
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE),
|
||||
"main");
|
||||
"*main");
|
||||
assertBreakLoc(infBreakLocVals.get(1), "[2.1]", main.add(10), 1,
|
||||
Set.of(TraceBreakpointKind.HW_EXECUTE),
|
||||
"*main+10");
|
||||
|
@ -116,7 +116,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
waitStopped();
|
||||
|
||||
conn.execute("""
|
||||
break main
|
||||
break *main
|
||||
hbreak *main+10
|
||||
watch -l *((char*)(&main+20))
|
||||
rwatch -l *((char(*)[8])(&main+30))
|
||||
@ -138,7 +138,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
// NB. starti avoid use of temporary main breakpoint
|
||||
assertBreakLoc(infBreakLocVals.get(0), "[1.1]", main, 1,
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE),
|
||||
"main");
|
||||
"*main");
|
||||
assertBreakLoc(infBreakLocVals.get(1), "[2.1]", main.add(10), 1,
|
||||
Set.of(TraceBreakpointKind.HW_EXECUTE),
|
||||
"*main+10");
|
||||
@ -172,7 +172,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
TraceObject locations = Objects.requireNonNull(tb.obj("Inferiors[1].Breakpoints"));
|
||||
conn.execute("""
|
||||
break main
|
||||
break *main
|
||||
hbreak *main+10
|
||||
watch -l *((char*)(&main+20))
|
||||
rwatch -l *((char(*)[8])(&main+30))
|
||||
@ -193,7 +193,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
// NB. starti avoid use of temporary main breakpoint
|
||||
assertBreakLoc(infBreakLocVals.get(0), "[1.1]", main, 1,
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE),
|
||||
"main");
|
||||
"*main");
|
||||
assertBreakLoc(infBreakLocVals.get(1), "[2.1]", main.add(10), 1,
|
||||
Set.of(TraceBreakpointKind.HW_EXECUTE),
|
||||
"*main+10");
|
||||
@ -935,7 +935,8 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
tb = new ToyDBTraceBuilder((Trace) mdo.get());
|
||||
waitStopped();
|
||||
|
||||
breakSwExecuteExpression.invoke(Map.of("expression", "main"));
|
||||
// Use *main instead of main, because some gdb will instead do <main+8>
|
||||
breakSwExecuteExpression.invoke(Map.of("expression", "*main"));
|
||||
|
||||
String out = conn.executeCapture("info break");
|
||||
assertThat(out, containsString("<main>"));
|
||||
@ -982,7 +983,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
tb = new ToyDBTraceBuilder((Trace) mdo.get());
|
||||
waitStopped();
|
||||
|
||||
breakHwExecuteExpression.invoke(Map.of("expression", "main"));
|
||||
breakHwExecuteExpression.invoke(Map.of("expression", "*main"));
|
||||
|
||||
String out = conn.executeCapture("info break");
|
||||
assertThat(out, containsString("<main>"));
|
||||
|
@ -1,5 +1,5 @@
|
||||
application.name=Ghidra
|
||||
application.version=11.1.1
|
||||
application.version=11.1.2
|
||||
application.release.name=DEV
|
||||
application.layout.version=2
|
||||
application.gradle.min=7.3
|
||||
|
@ -22,9 +22,9 @@ Require-Bundle: org.eclipse.ant.core;bundle-version="3.6.200",
|
||||
org.eclipse.ui;bundle-version="3.200.0",
|
||||
org.eclipse.ui.ide;bundle-version="3.18.400",
|
||||
com.python.pydev.debug;bundle-version="6.3.1";resolution:=optional,
|
||||
org.python.pydev;bundle-version="6.3.1";resolution:=optional,
|
||||
org.python.pydev.core;bundle-version="6.3.1";resolution:=optional,
|
||||
org.python.pydev.ast;bundle-version="6.3.1";resolution:=optional,
|
||||
org.python.pydev;bundle-version="[6.3.1,10.0.0)";resolution:=optional,
|
||||
org.python.pydev.core;bundle-version="[6.3.1,10.0.0)";resolution:=optional,
|
||||
org.python.pydev.ast;bundle-version="[6.3.1,10.0.0)";resolution:=optional,
|
||||
org.eclipse.cdt.core;bundle-version="5.9.1";resolution:=optional,
|
||||
org.eclipse.cdt.ui;bundle-version="5.9.0";resolution:=optional
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-17
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
<h1>Ghidra Installation Guide</h1>
|
||||
<p>
|
||||
The installation information provided is effective as of Ghidra 11.1 and is subject to change with
|
||||
The installation information provided is effective as of Ghidra 11.1.2 and is subject to change with
|
||||
future releases.
|
||||
</p>
|
||||
|
||||
@ -68,7 +68,7 @@ future releases.
|
||||
|
||||
<h2><a name="Platforms"></a>Platforms Supported</h2>
|
||||
<ul>
|
||||
<li>Windows 10 or later (x86 64-bit)</li>
|
||||
<li>Windows 10 or later (64-bit)</li>
|
||||
<li>Linux (64-bit)</li>
|
||||
<li>macOS 10.13 or later</li>
|
||||
</ul>
|
||||
@ -318,6 +318,7 @@ public Ghidra release includes native binaries for the following platforms.
|
||||
<p>NOTE: For some non-public Ghidra releases macOS natives may be omitted.</p>
|
||||
<ul>
|
||||
<li>Windows 10 or later, x86 64-bit</li>
|
||||
<li>Windows 10 or later, ARM 64-bit (using x86 emulation)</li>
|
||||
<li>Linux x86 64-bit</li>
|
||||
<li>macOS x86 64-bit</li>
|
||||
<li>macOS ARM 64-bit</li>
|
||||
@ -330,7 +331,7 @@ public Ghidra release includes native binaries for the following platforms.
|
||||
<li>FreeBSD ARM 64-bit (no debugger support)</li>
|
||||
</ul>
|
||||
<p>For supported systems where native binaries have not been supplied, or those that are supplied
|
||||
fail to run properly, it may be neccessary to build the native Ghidra binaries.
|
||||
fail to run properly, it may be necessary to build the native Ghidra binaries.
|
||||
In order to build native binaries for your platform, you will need the following installed on your
|
||||
system:</p>
|
||||
<ul>
|
||||
|
Loading…
Reference in New Issue
Block a user