Skip to content

Fix i/o addresses and pre-decrement pointers in the AVR assembler ##arch - #27135

Merged
trufae merged 3 commits into
radareorg:masterfrom
HuzaifaChaudary:avr-asm-io-and-predecrement
Oct 26, 2026
Merged

trufae merged 3 commits into
radareorg:masterfrom
HuzaifaChaudary:avr-asm-io-and-predecrement

Conversation

@HuzaifaChaudary

@HuzaifaChaudary HuzaifaChaudary commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor
  • Mark this if you consider it ready to merge
  • I've added tests (optional)
  • I wrote some lines in the book (optional)

Description

two things in the AVR assembler produced a different instruction without an error :

input before ( decoded with llvm-mc ) after
out 1, r1 out 0, r1 11b8
sbi 12, 5 sbi 0, 5 659a
ld r10, -Z ld r10, Z+ a290
st -X, r11 st X+, r11 be92
  • assemble_general_io_operand only knows spl , sph and sreg ( and their addresses ) , the numeric branch was commented out , and assemble_operand returned success anyway , so every other i/o address in out , sbi , cbi , sbic and sbis became 0 . numbers are taken again , and checked against the width of the field , 6 bits for out and 5 for the bit instructions , so out 64, r5 and sbi 32, 0 are refused instead of wrapping
  • RegsTable mapped -x , -y and -z to OPERAND_XP , OPERAND_YP and OPERAND_ZP , the post-increment forms , the pre-decrement ones OPERAND_MX , OPERAND_MY and OPERAND_MZ were already in the instruction table

found by decoding random words with llvm-mc ( -mcpu=avr6 ) , assembling the text with rasm2 -a avr and decoding the result again . same as llvm went from 4333 to 4606 of 5470 , nothing that was right changed . what is left is rjmp .+N style relative operands , where rasm2 takes an address instead . the 11 new lines in db/asm/avr fail before the change , db/asm and db/tools/rasm2 have no failures .

Copilot AI balanced review requested due to automatic review settings October 22, 2026 21:45

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@trufae trufae left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • The -x/-y/-z fix looks good. The post-increment forms still work.
  • Please check the full I/O number before narrowing it. out 0x100000001, r1 currently becomes out 1, r1. sbi 0x10000000c, 5 becomes sbi 12, 5.
  • Please reject trailing junk too. out 1junk, r1 is accepted. out 0x, r1 silently writes to address zero. The inline suggestion covers both parsing issues.
  • Add rejection tests for those four cases and an integer overflow such as out 18446744073709551616, r1. Also cover out 63/64 and sbi 31/32, with valid bit/register operands.
  • Keep tests for spl, sph and sreg. They should still work with out. They must be rejected by the 5-bit I/O instructions.
  • One existing gap: in uses OPERAND_DATA, so the new check skips it. in r1, 64 still encodes address zero. This is not a regression and can be a separate follow-up. Either change that operand to OPERAND_IO_REGISTER and add boundary tests, or adjust the helper comment so it doesn't claim to cover in.

I checked 6,720 valid I/O and pointer encodings in a focused harness using this assembler. Those passed. The small parser suggestion was also checked against the bad inputs and the normal limits.

Comment thread libr/arch/p/avr/assemble.c Resolved
@HuzaifaChaudary
HuzaifaChaudary force-pushed the avr-asm-io-and-predecrement branch from afd094c to 7be738f Compare October 25, 2026 09:23
@HuzaifaChaudary

Copy link
Copy Markdown
Contributor Author

done in 7be738f . took your suggestion as is , so the whole token is read as a 64 bit value and anything with junk after it or above 0x3f is rejected before io_fits sees it .

in uses OPERAND_IO_REGISTER now too , so in r1, 64 is rejected and in r1, spl works . one side effect , the disassembler prints the name for in the same way it already does for out , so cdb7 reads in r28, spl . i changed that test and kept the number form as an asm only line . if you would rather keep the number there i can do the comment change instead .

tests : out and in at 63 / 64 , sbi at 31 / 32 , spl , sph and sreg with out and in , and a rasm2 test that rejects your four cases , the 2^64 overflow , and spl , sph , sreg on sbi , cbi and sbic . 3 of the new tests fail on the old head , db/asm/avr and db/tools/rasm2 all pass .

the first commit was only reworded , its diff is the same .

@trufae
trufae merged commit 7201590 into radareorg:master Oct 26, 2026
20 of 45 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants