* Add data info for superh
* fmt
* Fetch symbol data dynamically from resolved.section
* Remove unused var
---------
Co-authored-by: Luke Street <luke@street.dev>
* Combine data/text sections: Pad all sections to 4-byte minimum alignment
* Update x86 test snapshot
* Read and store object section alignment
* Combine data/text sections: Pad sections to more than 4-byte alignment if they have alignment specified
* Limit left-panel scrollview to the file tree
Removes the redundant build button
* Expand ScrollArea to full side panel width
* Use auto_shrink(false) instead of set_width
---------
Co-authored-by: Luke Street <luke@street.dev>
* Reimplement colorized data relocation hover diffs
* Fix objdiff-wasm build
Data diffing doesn't seem to be fully implemented in objdiff-wasm yet, so just putting placeholders in so it compiles.
* Reloc hover: Add separators, override special color too
Before, this was comparing, for example, `.text-2`
with `.text-10` with standard string comparison,
yielding `.text-10` before `.text-2`.
Instead, this simply uses a stable sort by name,
which preserves the relative ordering of sections.
* PPC: Calculate pooled relocations
Reimplements #140
The relocations are now generated when the object is first read in `parse`, right after the real relocations are read.
`resolve_relocation` was changed to take `obj.symbols` instead of `obj` as an argument, because `obj` itself doesn't exist yet at the time the relocations are being read.
* Improve readability of PPC pool relocs code
* Fix regression causing extern pool relocs to be ignored
* Fix showing incorrect diff when diffing weak stripped symbol with an addend
This is a regression that was introduced by #158 diffing addends in addition to symbol names. But it's not really a bug in that PR, rather it seems like I simply never added the offset into the addend when creating a fake pool relocation for an extern symbol. So this commit fixes that root issue instead.
* Add PPC "Calculate pooled data references" option
* Fix objdiff-wasm compilation errors
* Update PPC test snapshots
* Show data literal values on instruction hover
Reimplements #108
* Show reloc diffs in func view when data's content differs
Reimplements #153
* Data diff view: Show relocs on hover and in context menu
This reimplements #154
Note that colorizing the text depending on the kind of diff has still not been reimplemented yet
* Fix up some comments
Implements MIPS relocation pairing logic.
New option for "Register '$' prefix", off by default.
Fixes various regressions introduced by refactoring.
Resolves#122Resolves#156
* Data view: Show data bytes with differing relocations as a diff
* Data view: Show differing relocations on hover
* Symbol list view: Adjust symbol/section match %s when relocations differ
* Improve data reloc diffing logic
* Don't make reloc diffs cause bytes to show as red or green
* Properly detect byte size of each relocation
* Data view: Add context menu for copying relocation target symbols
* Also show already-matching relocations on hover/right click
* Change font color for nonmatching relocs on hover
* Show reloc diff in func view when data content differs
* Add "Relax shifted data diffs" option
* Display fake pool relocations at end of line
* Diff reloc data by display string instead of raw bytes
This is to handle data symbols that contain multiple values in them at once, such as stringBase. If you compare the target symbol's bytes directly, then any part of the symbol having different bytes will cause *all* relocations to that symbol to show as a diff, even if the specific string being accessed is the same.
* Fix weak stripped symbols showing as a false diff
Fixed this by showing extern symbols correctly instead of skipping them.
* Add "Relax shifted data diffs" option to objdiff-cli
Includes both a command line argument and a keyboard shortcut (S).
* Remove addi string data hack and ... pool name hack
* Clippy fix
* PPC: Clear relocs from GPRs when overwritten
* PPC: Follow branches to improve pool detection accuracy
* PPC: Handle following bctr jump table control flow
* Clippy fixes
* PPC: Fix extern relocations not having their addend copied
* Add option to disable func data value diffing
* PPC: Handle lmw when clearing GPRs
* PPC: Handle moving reloc address with `add` inst
* Combine "relax reloc diffs" with other reloc diff options
* Add v3 config and migrate from v2
---------
Co-authored-by: Luke Street <luke@street.dev>
* Fix missing dependency feature for objdiff-gui
* Update .gitignore
* PPC: Display data values on hover for pools as well
* Tooltip data display: Format floats and doubles better
Floats and doubles will now always be displayed with a decimal point and one digit after it, even if they are whole numbers. Floats will also have the f suffix. This is so you can tell the data type just by glancing at the value.
* Move big functions to bottom ppc.rs
* Clear pool relocs in volatile registers on function call
This fixes some false positives.
* Revert ObjArch API changes, add fake target symbol hack
Because we no longer have access to the actual symbol name via sections, guess_data_type can no longer detect the String data type for pooled references.
* Add hack to detect strings via the addi opcode
* Move hack to resolve placeholder symbol into process_code_symbol
* Merge reloc and fake_pool_reloc fields of ObjIns
* Fix missing dependency feature for objdiff-gui
* Update .gitignore
* Add enter and back hotkeys
* Add scroll hotkeys
* Add hotkeys to select the next symbol above/below the current one in the listing
* Do not clear highlighted symbol when backing out of diff view
* Do not clear highlighted symbol when hovering mouse over an unpaired symbol
* Auto-scroll the keyboard-selected symbols into view if offscreen
* Fix some hotkeys stealing input from focused widgets
e.g. The symbol list was stealing the W/S key presses when typing into the symbol filter text edit.
If the user actually wants to use these shortcuts while a widget is focused, they can simply press the escape key to unfocus all widgets and then press the shortcut.
* Add Ctrl+F/S shortcuts for focusing the object and symbol filter text edits
* Add space as alternative to enter hotkey
This is for consistency with egui's builtint enter/space hotkey for interacting with the focused widget.
* Add hotkeys to change target and base functions
* Split function diff view: Enable PageUp/PageDown/Home/End for scrolling
* Add escape as an alternative to back hotkey
* Fix auto-scrolling to highlighted symbol only working for the left side
The flag is cleared after one scroll to avoid doing it continuously, but this breaks when we need to scroll to both the left and the right symbol at the same time. So now each side has its own flag to keep track of this state independently.
* Simplify clearing of the autoscroll flag, remove &mut State
* Found a better place to clear the autoscroll flag
DiffViewState::post_update is where the flag gets set, so clearing it right before that at the start of the function seems to make the most sense, instead of doing it in App::update.
* Fix missing dependency feature for objdiff-gui
* Update .gitignore
* Display decoded rlwinm info to hover tooltip
* Remove trailing newline when displaying decoded rlwinm info
* Change variable name
* Also update variable name in rlwinm.rs
The Ghidra delinker plugin emits functions with type STT_OBJECT,
rather than STT_FUNC. The current logic was preventing these from
being compared based on their symbol type. Relax this condition
for now.
* Reduce dependencies for no features
* Add missing deps to every feature
* Add missing `dep:`s
* Gate even more deps behind features
Removes dependency on tsify-next / wasm-bindgen unless
compiling with the wasm feature by using `#[cfg_attr]`
* Fix wasm
---------
Co-authored-by: Luke Street <luke@street.dev>
* Fix panic when parsing DWARF 2 line info for empty section
* Fix panic when parsing DWARF 2 line info for empty section
May as well remove both unwraps :p
* Fix data tooltip panic
Prevents panicing when attempting to display the data tooltip for a symbol that is too large by just using as many bytes as needed from the begging of the symbol.
* Don't attempt to interpret wrongly sized data
* Reference data display improvment issue
* Log failure to display a symbol's value
This allows users to "map" (or "link") symbols with different names so that they can be compared without having to update either the target or base objects. Symbol mappings are persisted in objdiff.json, so generators will need to ensure that they're preserved when updating. (Example: https://github.com/encounter/dtk-template/commit/d1334bb79e71af1a7b3b090bffda4adc483f722c)
Resolves#117
Job status is now shown in the top menu bar,
with a new Jobs window that can be toggled.
Build and diff errors are now handled more
gracefully.
Fixes#40
Before, this was running 2 fs::metadata
calls every frame. We don't need to do it
nearly that often, so now it only checks
once every 500ms.
This required refactoring AppConfig into
a separate AppState that holds transient
runtime state along with the loaded
AppConfig.
* Guess reloc data type based on the instruction.
Adds an entry to the reloc tooltip to show the inferred data type
and value.
* Fix clippy warning
* Match on Opcode rather than mnemonic string
With filter option to display them,
if desired. decomp-toolkit will
start writing auto-generated objects
in objdiff.json for reporting
purposes, so this maintains the
existing behavior.
This migrates to using protobuf to
define the "report" and "changes"
formats in objdiff-cli.
The JSON output now uses the Proto3
"JSON Mapping", which is slightly
incompatible with the existing JSON
format. Mainly, 64-bit numbers are
represented as strings, and addresses
are decimal strings instead of hex.
However, the older JSON format is
still accepted by "report changes"
to ease migration.
This re-implements the older algorithm
used for data and BSS section match
percentages. We perform both and
choose the highest match percent
between the two options.
Resolves#84, #85
This attempts the following in order:
- wgpu with user-selected backend
- wgpu with automatic backend
- glow (fallback OpenGL backend)
This should eliminate most issues
where objdiff fails to launch.
* Support R_MIPS_GPREL16 relocations correctly
symbols defined in the same file require adding a
special ri_gp_value from the .reginfo section to
their relocation calculations.
* Run nightly rustfmt
* Prevent potential panic when slicing .reginfo
* Basic integration
* Implement basic right click option
Needs lotsa work
* nothing to worry about
* Convert extab diff to separate view
* Make clippy and fmt shut up
* Make clippy fmt shut up for real this time
* Print extab/extabindex symbol names in extab view
* I hate fmt
* Basic integration
* Implement basic right click option
Needs lotsa work
* nothing to worry about
* Convert extab diff to separate view
* Make clippy and fmt shut up
* Make clippy fmt shut up for real this time
* Print extab/extabindex symbol names in extab view
* I hate fmt
* Fix scroll position not being maintained from extab view
* Silly me
* Add rlwinm decoder window
* Remove extra files
* Create Cargo.lock
* Show extab symbol names in hover window
* Appease fmt
* Update symbol_diff.rs
* Update symbol_diff.rs
* Get extab symbol from extabindex relocations instead
* Update Cargo.lock
* Update Cargo.lock
* Initial ARM support
* Disassemble const pool reloc
* Disasm ARM/Thumb/data based on mapping symbols
* Fallback to mapping symbol `$a`
* Support multiple DWARF sequences
* Update line info
* Rework DWARF line info parsing
- Properly handles multiple sections
in DWARF 1
- line_info moved into ObjSection
- DWARF 2 parser no longer errors with
no .text section
- Both parsers properly skip empty
sections
* Simplify line_info (no Option)
* Get line info from section; output formatted ins string
* Unwrap code section in `arm.rs`
* Handle reloc `R_ARM_SBREL32`
* Update ARM disassembler
* Update README.md
* Format
* Revert "Update README.md"
This reverts commit 8bbfcc6f45.
* Update README.md
* Detect ARM version; support ARMv4T and v6K
* Combobox to force ARM version
* Clear LSB in ARM symbol addresses
* Support big-endian ARM ELF files
* Bump `unarm`, `arm-attr`
* Handle ARM implicit addends
* Update README.md
* Explicitly handle all ARM argument types
* Format
* Display more ARM relocs
* Mask LSB on ARM code symbols only
* Read ARM implicit addends
* Format
---------
Co-authored-by: Luke Street <luke.street@encounterpc.com>
* Fix read error on objects with no .text section
* Fix read error on DWARF 1.1 objects
* Revert DWARF 1 changes
---------
Co-authored-by: Luke Street <luke@street.dev>
* Initial ARM support
* Disassemble const pool reloc
* Disasm ARM/Thumb/data based on mapping symbols
* Fallback to mapping symbol `$a`
* Support multiple DWARF sequences
* Update line info
* Rework DWARF line info parsing
- Properly handles multiple sections
in DWARF 1
- line_info moved into ObjSection
- DWARF 2 parser no longer errors with
no .text section
- Both parsers properly skip empty
sections
* Simplify line_info (no Option)
* Get line info from section; output formatted ins string
* Unwrap code section in `arm.rs`
* Handle reloc `R_ARM_SBREL32`
* Update ARM disassembler
* Update README.md
* Format
* Revert "Update README.md"
This reverts commit 8bbfcc6f45.
* Update README.md
---------
Co-authored-by: Luke Street <luke.street@encounterpc.com>
A local diffing tool for decompilation projects. Inspired by [decomp.me](https://decomp.me) and [asm-differ](https://github.com/simonlindholm/asm-differ).
Features:
- Compare entire object files: functions and data.
- Built-in symbol demangling for C++. (CodeWarrior, Itanium & MSVC)
- Automatic rebuild on source file changes.
@@ -14,12 +15,34 @@ Features:
- Click to highlight all instances of values and registers.
For Linux and macOS, run `chmod +x objdiff-*` to make the binary executable.
### CLI
CLI binaries can be found on the [releases page](https://github.com/encounter/objdiff/releases).
## Screenshots


@@ -48,91 +71,89 @@ See [Configuration](#configuration) for more information.
## Configuration
While **not required** (most settings can be specified in the UI), projects can add an `objdiff.json`(or
`objdiff.yaml`, `objdiff.yml`) file to configure the tool automatically. The configuration file must be located in
While **not required** (most settings can be specified in the UI), projects can add an `objdiff.json`file to configure the tool automatically. The configuration file must be located in
the root project directory.
If your project has a generator script (e.g. `configure.py`), it's recommended to generate the objdiff configuration
file as well. You can then add `objdiff.json` to your `.gitignore` to prevent it from being committed.
"description":"Minimum version of objdiff required to load this configuration file.",
"examples":[
"1.0.0",
"2.0.0-beta.1"
]
},
"custom_make":{
"type":"string",
"description":"By default, objdiff will use make to build the project.\nIf the project uses a different build system (e.g. ninja), specify it here.\nThe build command will be `[custom_make] [custom_args] path/to/object.o`.",
"examples":[
"make",
"ninja"
],
"default":"make"
},
"custom_args":{
"type":"array",
"description":"Additional arguments to pass to the build command prior to the object path.",
"items":{
"type":"string"
}
},
"target_dir":{
"type":"string",
"description":"Relative from the root of the project, this where the \"target\" or \"expected\" objects are located.\nThese are the intended result of the match.",
"deprecated":true
},
"base_dir":{
"type":"string",
"description":"Relative from the root of the project, this is where the \"base\" or \"actual\" objects are located.\nThese are objects built from the current source code.",
"deprecated":true
},
"build_target":{
"type":"boolean",
"description":"If true, objdiff will tell the build system to build the target objects before diffing (e.g. `make path/to/target.o`).\nThis is useful if the target objects are not built by default or can change based on project configuration or edits to assembly files.\nRequires the build system to be configured properly.",
"default":false
},
"build_base":{
"type":"boolean",
"description":"If true, objdiff will tell the build system to build the base objects before diffing (e.g. `make path/to/base.o`).\nIt's unlikely you'll want to disable this, unless you're using an external tool to rebuild the base object on source file changes.",
"default":true
},
"watch_patterns":{
"type":"array",
"description":"List of glob patterns to watch for changes in the project.\nIf any of these files change, objdiff will automatically rebuild the objects and re-compare them.\nSupported syntax: https://docs.rs/globset/latest/globset/#syntax",
"items":{
"type":"string"
},
"default":[
"*.c",
"*.cp",
"*.cpp",
"*.cxx",
"*.h",
"*.hp",
"*.hpp",
"*.hxx",
"*.s",
"*.S",
"*.asm",
"*.inc",
"*.py",
"*.yml",
"*.txt",
"*.json"
]
},
"objects":{
"type":"array",
"description":"Use units instead.",
"deprecated":true,
"items":{
"$ref":"#/$defs/unit"
}
},
"units":{
"type":"array",
"description":"If specified, objdiff will display a list of objects in the sidebar for easy navigation.",
"items":{
"$ref":"#/$defs/unit"
}
},
"progress_categories":{
"type":"array",
"description":"Progress categories used for objdiff-cli report.",
"items":{
"$ref":"#/$defs/progress_category"
}
}
},
"$defs":{
"unit":{
"type":"object",
"properties":{
"name":{
"type":"string",
"description":"The name of the object in the UI. If not specified, the object's path will be used."
},
"path":{
"type":"string",
"description":"Relative path to the object from the target_dir and base_dir.\nRequires target_dir and base_dir to be specified.",
"deprecated":true
},
"target_path":{
"type":"string",
"description":"Path to the target object from the project root.\nRequired if path is not specified."
},
"base_path":{
"type":"string",
"description":"Path to the base object from the project root.\nRequired if path is not specified."
},
"reverse_fn_order":{
"type":"boolean",
"description":"Displays function symbols in reversed order.\nUsed to support MWCC's -inline deferred option, which reverses the order of functions in the object file.",
"deprecated":true
},
"complete":{
"type":"boolean",
"description":"Marks the object as \"complete\" (or \"linked\") in the object list.\nThis is useful for marking objects that are fully decompiled. A value of `false` will mark the object as \"incomplete\".",
"deprecated":true
},
"scratch":{
"ref":"#/$defs/scratch"
},
"metadata":{
"ref":"#/$defs/metadata"
},
"symbol_mappings":{
"type":"object",
"description":"Manual symbol mappings from target to base.",
"additionalProperties":{
"type":"string"
}
}
}
},
"scratch":{
"type":"object",
"description":"If present, objdiff will display a button to create a decomp.me scratch.",
"properties":{
"platform":{
"type":"string",
"description":"The decomp.me platform ID to use for the scratch.",
"examples":[
"gc_wii",
"n64"
]
},
"compiler":{
"type":"string",
"description":"The decomp.me compiler ID to use for the scratch.",
"examples":[
"mwcc_242_81",
"ido7.1"
]
},
"c_flags":{
"type":"string",
"description":"C flags to use for the scratch. Exclude any include paths."
},
"ctx_path":{
"type":"string",
"description":"Path to the context file to use for the scratch."
},
"build_ctx":{
"type":"boolean",
"description":"If true, objdiff will run the build command with the context file as an argument to generate it.",
"default":false
}
},
"required":[
"platform",
"compiler"
]
},
"metadata":{
"type":"object",
"properties":{
"complete":{
"type":"boolean",
"description":"Marks the object as \"complete\" (or \"linked\") in the object list.\nThis is useful for marking objects that are fully decompiled. A value of `false` will mark the object as \"incomplete\"."
},
"reverse_fn_order":{
"type":"boolean",
"description":"Displays function symbols in reversed order.\nUsed to support MWCC's -inline deferred option, which reverses the order of functions in the object file."
},
"source_path":{
"type":"string",
"description":"Path to the source file that generated the object."
},
"progress_categories":{
"type":"array",
"description":"Progress categories used for objdiff-cli report.",
"items":{
"type":"string",
"description":"Unique identifier for the category. (See progress_categories)"
}
},
"auto_generated":{
"type":"boolean",
"description":"Hides the object from the object list by default, but still includes it in reports."
}
}
},
"progress_category":{
"type":"object",
"properties":{
"id":{
"type":"string",
"description":"Unique identifier for the category."
},
"name":{
"type":"string",
"description":"Human-readable name of the category."
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.