Skip to content

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

Closed
@kernigh

Description

@kernigh

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.

Metadata

Metadata

Assignees

Labels

mcMachine (object) code

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions