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

assembler .space gives "error: invalid number of bytes" in LLVM 19 but works in 18 #123402

Open
kernigh opened this issue Jan 17, 2025 · 0 comments

Comments

@kernigh
Copy link
Contributor

kernigh commented Jan 17, 2025

I expect LLVM to assemble this x86-64 test case. It fails in today's git f719771,

$ clang --target=amd64-openbsd -c exam.s    
exam.s:38:9: error: invalid number of bytes
        .space  (p_nop - p_1st) - (. - q_1st), 0xcc
                ^

It also fails with the OpenBSD package of llvm-19.1.7p0, but succeeds with the OpenBSD package of llvm-18.1.8p3.

	.section .p
p_1st:
0:	pause
	lfence
	jmp	0b

	.section .q
q_1st:
	addl	11,%eax
	addl	22,%eax

q_cli:
	cli
0:	pause
	lfence
	jmp	0b

	.section .p
	.space	(q_cli - q_1st) - (. - p_1st), 0xcc
	cli

	.section .q
q_sti:
	sti

	.section .p
	.space	(q_sti - q_1st) - (. - p_1st), 0xcc
	sti
	addl	33,%eax
	addl	44,%eax
p_nop:
	nop

	.section .q
0:	pause
	lfence
	jmp	0b
	.space	(p_nop - p_1st) - (. - q_1st), 0xcc
	nop

This test case has 2 sections (.p and .q). Each .space should evaluate to .space 7, 0xcc. (Then cli in .p and cli in .q will have the same offset, and same for sti and nop.) LLVM 18 emits the correct .o file, for which llvm-objdump -d -j.p -j.q exam.o shows 3 groups of 7 bytes of 0xcc = int3.

I need a jmp 0b to reproduce the error in LLVM 19 or git. If I change the 1st jmp 0b (on line 5) to incl %eax (both instructions are 2 bytes), then the error goes away, and each .space inserts the correct 7 bytes.

The wrong "error: invalid number of bytes" comes from a check if (Size < 0) in llvm/lib/MC/MCAssembler.cpp. I modified LLVM 19 to print the Size in each check. For this test case, I got

  • exam.s:19 if 7 < 0
  • exam.s:38 if -15 < 0, error
  • exam.s:27 if 7 < 0
  • exam.s:19 if 7 < 0
  • exam.s:27 if 7 < 0
  • exam.s:38 if 7 < 0

It visited the check if (Size < 0) twice for each .space line. The 1st visit to line 38 got the wrong size -15 and gave the error, though the 2nd visit got the correct size 7. The 1st visits with line 38 before 27 are in the wrong order; you can't calculate the size at line 38 unless you know the size at line 27. After I changed the 1st jmp 0b to incl %eax, it visited 27 before 38.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants