Compare commits

..

5 Commits

Author SHA1 Message Date
e1ae369d17 CI: Fix Cargo.toml version check 2024-09-04 23:51:42 -06:00
ce05d6d6c0 Version v2.0.0-beta.6 2024-09-04 23:36:41 -06:00
c16a926d9b objdiff-cli: Build static binary & for more arches 2024-09-04 23:33:52 -06:00
Robin Lambertz
a32d99923c Coff line number (#100)
* Update object to 0.36

* Add COFF line number support
2024-09-04 18:36:09 -06:00
68606dfdcb Add config.schema.json & update README.md 2024-09-03 20:48:45 -06:00
9 changed files with 490 additions and 63 deletions

View File

@@ -25,6 +25,21 @@ jobs:
sudo apt-get -y install libgtk-3-dev
- name: Checkout
uses: actions/checkout@v4
- name: Check git tag against Cargo version
if: startsWith(github.ref, 'refs/tags/')
shell: bash
run: |
set -eou pipefail
tag='${{github.ref}}'
tag="${tag#refs/tags/}"
for file in */Cargo.toml; do
version=$(grep '^version' $file | head -1 | awk -F' = ' '{print $2}' | tr -d '"')
version="v$version"
if [ "$tag" != "$version" ]; then
echo "::error::Git tag doesn't match the Cargo version! ($tag != $version)"
exit 1
fi
done
- name: Setup Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
@@ -100,8 +115,82 @@ jobs:
SCCACHE_GHA_ENABLED: "true"
run: cargo test --release
build:
name: Build
build-cli:
name: Build objdiff-cli
env:
CARGO_BIN_NAME: objdiff-cli
strategy:
matrix:
include:
- platform: ubuntu-latest
target: x86_64-unknown-linux-musl
name: linux-x86_64
build: zigbuild
features: default
- platform: ubuntu-latest
target: i686-unknown-linux-musl
name: linux-i686
build: zigbuild
features: default
- platform: ubuntu-latest
target: aarch64-unknown-linux-musl
name: linux-aarch64
build: zigbuild
features: default
- platform: ubuntu-latest
target: armv7-unknown-linux-musleabi
name: linux-armv7l
build: zigbuild
features: default
- platform: windows-latest
target: x86_64-pc-windows-msvc
name: windows-x86_64
build: build
features: default
- platform: windows-latest
target: aarch64-pc-windows-msvc
name: windows-arm64
build: build
features: default
- platform: macos-latest
target: x86_64-apple-darwin
name: macos-x86_64
build: build
features: default
- platform: macos-latest
target: aarch64-apple-darwin
name: macos-arm64
build: build
features: default
fail-fast: false
runs-on: ${{ matrix.platform }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install cargo-zigbuild
if: matrix.build == 'zigbuild'
run: pip install ziglang==0.13.0 cargo-zigbuild==0.19.1
- name: Setup Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Cargo build
run: >
cargo ${{ matrix.build }} --profile ${{ env.BUILD_PROFILE }} --target ${{ matrix.target }}
--bin ${{ env.CARGO_BIN_NAME }} --features ${{ matrix.features }}
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: ${{ env.CARGO_BIN_NAME }}-${{ matrix.name }}
path: |
${{ env.CARGO_TARGET_DIR }}/${{ matrix.target }}/${{ env.BUILD_PROFILE }}/${{ env.CARGO_BIN_NAME }}
${{ env.CARGO_TARGET_DIR }}/${{ matrix.target }}/${{ env.BUILD_PROFILE }}/${{ env.CARGO_BIN_NAME }}.exe
if-no-files-found: error
build-gui:
name: Build objdiff-gui
env:
CARGO_BIN_NAME: objdiff
strategy:
matrix:
include:
@@ -144,23 +233,21 @@ jobs:
SCCACHE_GHA_ENABLED: "true"
run: >
cargo build --profile ${{ env.BUILD_PROFILE }} --target ${{ matrix.target }}
--bin objdiff-cli --bin objdiff --features ${{ matrix.features }}
--bin ${{ env.CARGO_BIN_NAME }} --features ${{ matrix.features }}
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.name }}
name: ${{ env.CARGO_BIN_NAME }}-${{ matrix.name }}
path: |
${{ env.CARGO_TARGET_DIR }}/${{ matrix.target }}/${{ env.BUILD_PROFILE }}/objdiff-cli
${{ env.CARGO_TARGET_DIR }}/${{ matrix.target }}/${{ env.BUILD_PROFILE }}/objdiff-cli.exe
${{ env.CARGO_TARGET_DIR }}/${{ matrix.target }}/${{ env.BUILD_PROFILE }}/objdiff
${{ env.CARGO_TARGET_DIR }}/${{ matrix.target }}/${{ env.BUILD_PROFILE }}/objdiff.exe
${{ env.CARGO_TARGET_DIR }}/${{ matrix.target }}/${{ env.BUILD_PROFILE }}/${{ env.CARGO_BIN_NAME }}
${{ env.CARGO_TARGET_DIR }}/${{ matrix.target }}/${{ env.BUILD_PROFILE }}/${{ env.CARGO_BIN_NAME }}.exe
if-no-files-found: error
release:
name: Release
if: startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
needs: [ build ]
needs: [ check, build-cli, build-gui ]
permissions:
contents: write
steps:
@@ -183,7 +270,9 @@ jobs:
else
ext=".$ext"
fi
dst="../out/${name}-${dir%/}${ext}"
arch="${dir%/}" # remove trailing slash
arch="${arch##"$name-"}" # remove bin name
dst="../out/${name}-${arch}${ext}"
mv "$file" "$dst"
done
done

12
Cargo.lock generated
View File

@@ -2835,7 +2835,7 @@ dependencies = [
[[package]]
name = "objdiff-cli"
version = "2.0.0-beta.5"
version = "2.0.0-beta.6"
dependencies = [
"anyhow",
"argp",
@@ -2856,7 +2856,7 @@ dependencies = [
[[package]]
name = "objdiff-core"
version = "2.0.0-beta.5"
version = "2.0.0-beta.6"
dependencies = [
"anyhow",
"arm-attr",
@@ -2875,7 +2875,7 @@ dependencies = [
"memmap2",
"msvc-demangler",
"num-traits",
"object 0.35.0",
"object 0.36.4",
"pbjson",
"pbjson-build",
"ppc750cl",
@@ -2895,7 +2895,7 @@ dependencies = [
[[package]]
name = "objdiff-gui"
version = "2.0.0-beta.5"
version = "2.0.0-beta.6"
dependencies = [
"anyhow",
"bytes",
@@ -2950,9 +2950,9 @@ dependencies = [
[[package]]
name = "object"
version = "0.35.0"
version = "0.36.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8ec7ab813848ba4522158d5517a6093db1ded27575b070f4177b8d12b41db5e"
checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a"
dependencies = [
"memchr",
]

View File

@@ -49,91 +49,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.
```json5
// objdiff.json
```json
{
"$schema": "https://raw.githubusercontent.com/encounter/objdiff/main/config.schema.json",
"custom_make": "ninja",
"custom_args": [
"-d",
"keeprsp"
],
// Only required if objects use "path" instead of "target_path" and "base_path".
"target_dir": "build/asm",
"base_dir": "build/src",
"build_target": true,
"build_target": false,
"build_base": true,
"watch_patterns": [
"*.c",
"*.cp",
"*.cpp",
"*.cxx",
"*.h",
"*.hp",
"*.hpp",
"*.py"
"*.hxx",
"*.s",
"*.S",
"*.asm",
"*.inc",
"*.py",
"*.yml",
"*.txt",
"*.json"
],
"objects": [
"units": [
{
"name": "main/MetroTRK/mslsupp",
// Option 1: Relative to target_dir and base_dir
"path": "MetroTRK/mslsupp.o",
// Option 2: Explicit paths from project root
// Useful for more complex directory layouts
"target_path": "build/asm/MetroTRK/mslsupp.o",
"base_path": "build/src/MetroTRK/mslsupp.o",
"reverse_fn_order": false
},
// ...
"metadata": {}
}
]
}
```
### Schema
View [config.schema.json](config.schema.json) for all available options. The below list is a summary of the most important options.
`custom_make` _(optional)_: By default, objdiff will use `make` to build the project.
If the project uses a different build system (e.g. `ninja`), specify it here.
The build command will be `[custom_make] [custom_args] path/to/object.o`.
`custom_args` _(optional)_: Additional arguments to pass to the build command prior to the object path.
`target_dir` _(optional)_: Relative from the root of the project, this where the "target" or "expected" objects are located.
These are the **intended result** of the match.
`base_dir` _(optional)_: Relative from the root of the project, this is where the "base" or "actual" objects are located.
These are objects built from the **current source code**.
`build_target`: If true, objdiff will tell the build system to build the target objects before diffing (e.g.
`make path/to/target.o`).
This is useful if the target objects are not built by default or can change based on project configuration or edits
to assembly files.
Requires the build system to be configured properly.
`build_base`: If true, objdiff will tell the build system to build the base objects before diffing (e.g. `make path/to/base.o`).
It's unlikely you'll want to disable this, unless you're using an external tool to rebuild the base object on source file changes.
`watch_patterns` _(optional)_: A list of glob patterns to watch for changes.
([Supported syntax](https://docs.rs/globset/latest/globset/#syntax))
If any of these files change, objdiff will automatically rebuild the objects and re-compare them.
If not specified, objdiff will use the default patterns listed above.
`objects` _(optional)_: If specified, objdiff will display a list of objects in the sidebar for easy navigation.
`units` _(optional)_: If specified, objdiff will display a list of objects in the sidebar for easy navigation.
> `name` _(optional)_: The name of the object in the UI. If not specified, the object's `path` will be used.
>
> `path`: Relative path to the object from the `target_dir` and `base_dir`.
> Requires `target_dir` and `base_dir` to be specified.
> `target_path`: Path to the "target" or "expected" object from the project root.
> This object is the **intended result** of the match.
>
> `target_path`: Path to the target object from the project root.
> Required if `path` is not specified.
> `base_path`: Path to the "base" or "actual" object from the project root.
> This object is built from the **current source code**.
>
> `base_path`: Path to the base object from the project root.
> Required if `path` is not specified.
> `metadata.auto_generated` _(optional)_: Hides the object from the object list, but still includes it in reports.
>
> `reverse_fn_order` _(optional)_: Displays function symbols in reversed order.
Used to support MWCC's `-inline deferred` option, which reverses the order of functions in the object file.
> `metadata.complete` _(optional)_: Marks the object as "complete" (or "linked") in the object list.
> This is useful for marking objects that are fully decompiled. A value of `false` will mark the object as "incomplete".
## Building

221
config.schema.json Normal file
View File

@@ -0,0 +1,221 @@
{
"$schema": "https://json-schema.org/draft-07/schema",
"$id": "https://raw.githubusercontent.com/encounter/objdiff/main/config.schema.json",
"title": "objdiff configuration",
"description": "Configuration file for objdiff",
"type": "object",
"properties": {
"min_version": {
"type": "string",
"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"
}
}
},
"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."
}
}
}
}
}

View File

@@ -1,6 +1,6 @@
[package]
name = "objdiff-cli"
version = "2.0.0-beta.5"
version = "2.0.0-beta.6"
edition = "2021"
rust-version = "1.70"
authors = ["Luke Street <luke@street.dev>"]

View File

@@ -87,9 +87,10 @@ fn generate(args: GenerateArgs) -> Result<()> {
let project_dir = args.project.as_deref().unwrap_or_else(|| Path::new("."));
info!("Loading project {}", project_dir.display());
let config = objdiff_core::config::try_project_config(project_dir);
let Some((Ok(mut project), _)) = config else {
bail!("No project configuration found");
let mut project = match objdiff_core::config::try_project_config(project_dir) {
Some((Ok(config), _)) => config,
Some((Err(err), _)) => bail!("Failed to load project configuration: {}", err),
None => bail!("No project configuration found"),
};
info!(
"Generating report for {} units (using {} threads)",

View File

@@ -1,6 +1,6 @@
[package]
name = "objdiff-core"
version = "2.0.0-beta.5"
version = "2.0.0-beta.6"
edition = "2021"
rust-version = "1.70"
authors = ["Luke Street <luke@street.dev>"]
@@ -34,7 +34,7 @@ flagset = "0.4.5"
log = "0.4.21"
memmap2 = "0.9.4"
num-traits = "0.2.18"
object = { version = "0.35.0", features = ["read_core", "std", "elf", "pe"], default-features = false }
object = { version = "0.36.0", features = ["read_core", "std", "elf", "pe"], default-features = false }
pbjson = { version = "0.7.0", optional = true }
prost = { version = "0.13.1", optional = true }
serde = { version = "1", features = ["derive"] }

View File

@@ -1,12 +1,15 @@
use std::{collections::HashSet, fs, io::Cursor, path::Path};
use std::{collections::HashSet, fs, io::Cursor, mem::size_of, path::Path};
use anyhow::{anyhow, bail, ensure, Context, Result};
use cwextab::decode_extab;
use filetime::FileTime;
use flagset::Flags;
use object::{
endian::LittleEndian as LE,
pe::{ImageAuxSymbolFunctionBeginEnd, ImageLinenumber},
read::coff::{CoffFile, CoffHeader, ImageSymbol},
Architecture, BinaryFormat, File, Object, ObjectSection, ObjectSymbol, RelocationTarget,
SectionIndex, SectionKind, Symbol, SymbolKind, SymbolScope, SymbolSection,
SectionIndex, SectionKind, Symbol, SymbolIndex, SymbolKind, SymbolScope, SymbolSection,
};
use crate::{
@@ -401,7 +404,7 @@ fn relocations_by_section(
Ok(relocations)
}
fn line_info(obj_file: &File<'_>, sections: &mut [ObjSection]) -> Result<()> {
fn line_info(obj_file: &File<'_>, sections: &mut [ObjSection], obj_data: &[u8]) -> Result<()> {
// DWARF 1.1
if let Some(section) = obj_file.section_by_name(".line") {
let data = section.uncompressed_data()?;
@@ -490,6 +493,121 @@ fn line_info(obj_file: &File<'_>, sections: &mut [ObjSection]) -> Result<()> {
}
}
// COFF
if let File::Coff(coff) = obj_file {
line_info_coff(coff, sections, obj_data)?;
}
Ok(())
}
fn line_info_coff(coff: &CoffFile, sections: &mut [ObjSection], obj_data: &[u8]) -> Result<()> {
let symbol_table = coff.coff_header().symbols(obj_data)?;
// Enumerate over all sections.
for sect in coff.sections() {
let ptr_linenums = sect.coff_section().pointer_to_linenumbers.get(LE) as usize;
let num_linenums = sect.coff_section().number_of_linenumbers.get(LE) as usize;
// If we have no line number, skip this section.
if num_linenums == 0 {
continue;
}
// Find this section in our out_section. If it's not in out_section,
// skip it.
let Some(out_section) = sections.iter_mut().find(|s| s.orig_index == sect.index().0) else {
continue;
};
// Turn the line numbers into an ImageLinenumber slice.
let Some(linenums) =
&obj_data.get(ptr_linenums..ptr_linenums + num_linenums * size_of::<ImageLinenumber>())
else {
continue;
};
let Ok(linenums) = object::pod::slice_from_all_bytes::<ImageLinenumber>(linenums) else {
continue;
};
// In COFF, the line numbers are stored relative to the start of the
// function. Because of this, we need to know the line number where the
// function starts, so we can sum the two and get the line number
// relative to the start of the file.
//
// This variable stores the line number where the function currently
// being processed starts. It is set to None when we failed to find the
// line number of the start of the function.
let mut cur_fun_start_linenumber = None;
for linenum in linenums {
let line_number = linenum.linenumber.get(LE);
if line_number == 0 {
// Starting a new function. We need to find the line where that
// function is located in the file. To do this, we need to find
// the `.bf` symbol "associated" with this function. The .bf
// symbol will have a Function Begin/End Auxillary Record, which
// contains the line number of the start of the function.
// First, set cur_fun_start_linenumber to None. If we fail to
// find the start of the function, this will make sure the
// subsequent line numbers will be ignored until the next start
// of function.
cur_fun_start_linenumber = None;
// Get the symbol associated with this function. We'll need it
// for logging purposes, but also to acquire its Function
// Auxillary Record, which tells us where to find our .bf symbol.
let symtable_entry = linenum.symbol_table_index_or_virtual_address.get(LE);
let Ok(symbol) = symbol_table.symbol(SymbolIndex(symtable_entry as usize)) else {
continue;
};
let Ok(aux_fun) = symbol_table.aux_function(SymbolIndex(symtable_entry as usize))
else {
continue;
};
// Get the .bf symbol associated with this symbol. To do so, we
// look at the Function Auxillary Record's tag_index, which is
// an index in the symbol table pointing to our .bf symbol.
if aux_fun.tag_index.get(LE) == 0 {
continue;
}
let Ok(bf_symbol) =
symbol_table.symbol(SymbolIndex(aux_fun.tag_index.get(LE) as usize))
else {
continue;
};
// Do some sanity checks that we are, indeed, looking at a .bf
// symbol.
if bf_symbol.name(symbol_table.strings()) != Ok(b".bf") {
continue;
}
// Get the Function Begin/End Auxillary Record associated with
// our .bf symbol, where we'll fine the linenumber of the start
// of our function.
let Ok(bf_aux) = symbol_table.get::<ImageAuxSymbolFunctionBeginEnd>(
SymbolIndex(aux_fun.tag_index.get(LE) as usize),
1,
) else {
continue;
};
// Set cur_fun_start_linenumber so the following linenumber
// records will know at what line the current function start.
cur_fun_start_linenumber = Some(bf_aux.linenumber.get(LE) as u32);
// Let's also synthesize a line number record from the start of
// the function, as the linenumber records don't always cover it.
out_section.line_info.insert(
sect.address() + symbol.value() as u64,
bf_aux.linenumber.get(LE) as u32,
);
} else if let Some(cur_linenumber) = cur_fun_start_linenumber {
let vaddr = linenum.symbol_table_index_or_virtual_address.get(LE);
out_section
.line_info
.insert(sect.address() + vaddr as u64, cur_linenumber + line_number as u32);
}
}
}
Ok(())
}
@@ -620,7 +738,7 @@ pub fn parse(data: &[u8], config: &DiffObjConfig) -> Result<ObjInfo> {
if config.combine_data_sections {
combine_data_sections(&mut sections)?;
}
line_info(&obj_file, &mut sections)?;
line_info(&obj_file, &mut sections, data)?;
let common = common_symbols(arch.as_ref(), &obj_file, split_meta.as_ref())?;
let extab = exception_tables(&mut sections, &obj_file)?;
Ok(ObjInfo { arch, path: None, timestamp: None, sections, common, extab, split_meta })

View File

@@ -1,6 +1,6 @@
[package]
name = "objdiff-gui"
version = "2.0.0-beta.5"
version = "2.0.0-beta.6"
edition = "2021"
rust-version = "1.70"
authors = ["Luke Street <luke@street.dev>"]