Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disable rodata start suggestion #419

Merged
merged 6 commits into from
Nov 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

### 0.28.2

* New global option and per-segment option: `suggestion_rodata_section_start`
* Allows to toggle the rodata section start suggestion that is emitted by inspecting the data section
* Avoid running spimdisasm on auto segments.
* Should improve runtime performance and avoid giving redundant filesplit suggestions.
* A zero-sized bin segment is considered a hard error.
* A zero-sized bin segment is now considered a hard error.

### 0.28.1

Expand Down
12 changes: 12 additions & 0 deletions docs/Configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,18 @@ Does the same as `use_gp_rel_macro_nonmatching`, except it is only applied to `a

Defaults to `True`

### suggestion_rodata_section_start

splat is able to suggest where the rodata section may start by inspecting a corresponding data section (as long as the rodata section follows rodata and not the other way around).
Don't trust this suggestion blindly since it may be incorrect, either because the rodata section may start a lot before than what splat suggests or splat even may be completely wrong and suggest something that
actually is data as if it were rodata.

This option allows turning off the suggestion in case you have checked it is not correct.

This can be turned off [per segment](Segments.md#suggestion_rodata_section_start), which is recommended if you are still on the exploration stage of the decompilation project.

Defaults to `True`.

## N64-specific options

### header_encoding
Expand Down
22 changes: 22 additions & 0 deletions docs/Segments.md
Original file line number Diff line number Diff line change
Expand Up @@ -537,3 +537,25 @@ Only works on top-level segments
```

Defaults to the global `subalign` option.

### `suggestion_rodata_section_start`

splat is able to suggest where the rodata section may start by inspecting a corresponding data section (as long as the rodata section follows rodata and not the other way around).
Don't trust this suggestion blindly since it may be incorrect, either because the rodata section may start a lot before than what splat suggests or splat even may be completely wrong and suggest something that
actually is data as if it were rodata.

This option allows turning off the suggestion for this segment in case you have checked the suggestion is not correct. This option is inherited from the parent segment if a subsegment does not specify it.

This can be turned off [globally](Configuration.md#suggestion_rodata_section_start), but it is not recommended to globally turn it off unless you are confident you have mapped every data/rodata section of every segment.

Defaults to the global option.

**Example:**

```yaml
- name: boot
type: code
start: 0x001060
vram: 0x80000460
suggestion_rodata_section_start: False
```
6 changes: 5 additions & 1 deletion src/splat/segtypes/common/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,11 @@ def disassemble_data(self, rom_bytes):
)

# Hint to the user that we are now in the .rodata section and no longer in the .data section (assuming rodata follows data)
if not rodata_encountered and self.get_most_parent().rodata_follows_data:
if (
self.suggestion_rodata_section_start
and not rodata_encountered
and self.get_most_parent().rodata_follows_data
):
if symbol.contextSym.isJumpTable():
rodata_encountered = True
print(
Expand Down
25 changes: 25 additions & 0 deletions src/splat/segtypes/segment.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,19 @@ def parse_ld_align_segment_start(yaml: Union[dict, list]) -> Optional[int]:
return yaml["ld_align_segment_start"]
return options.opts.ld_align_segment_start

@staticmethod
def parse_suggestion_rodata_section_start(
yaml: Union[dict, list]
) -> Optional[bool]:
if isinstance(yaml, dict):
suggestion_rodata_section_start = yaml.get(
"suggestion_rodata_section_start"
)
if suggestion_rodata_section_start is not None:
assert isinstance(suggestion_rodata_section_start, bool)
return suggestion_rodata_section_start
return None

def __init__(
self,
rom_start: Optional[int],
Expand Down Expand Up @@ -301,6 +314,10 @@ def __init__(
# True if this segment was generated based on auto_link_sections
self.is_generated: bool = False

self.given_suggestion_rodata_section_start: Optional[bool] = (
self.parse_suggestion_rodata_section_start(yaml)
)

# Is an automatic segment, generated automatically or declared on the yaml by the user
self.is_auto_segment: bool = False

Expand Down Expand Up @@ -512,6 +529,14 @@ def rodata_follows_data(self) -> bool:
self.section_order.index(".rodata") - self.section_order.index(".data") == 1
)

@property
def suggestion_rodata_section_start(self) -> bool:
if self.given_suggestion_rodata_section_start is not None:
return self.given_suggestion_rodata_section_start
if self.parent is not None:
return self.parent.suggestion_rodata_section_start
return options.opts.suggestion_rodata_section_start

def get_cname(self) -> str:
name = self.name
if self.parent:
Expand Down
5 changes: 5 additions & 0 deletions src/splat/util/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,8 @@ class SplatOpts:
use_gp_rel_macro_nonmatching: bool
# Does the same as `use_gp_rel_macro_nonmatching`, except it is only applied to `asm` and `hasm` segments.
use_gp_rel_macro: bool
# Allows emitting suggestions for where the rodata may start by examining the data section.
suggestion_rodata_section_start: bool

################################################################################
# N64-specific options
Expand Down Expand Up @@ -558,6 +560,9 @@ def parse_endianness() -> Literal["big", "little"]:
"use_gp_rel_macro_nonmatching", bool, True
),
use_gp_rel_macro=p.parse_opt("use_gp_rel_macro", bool, True),
suggestion_rodata_section_start=p.parse_opt(
"suggestion_rodata_section_start", bool, True
),
)
p.check_no_unread_opts()
return ret
Expand Down