Skip to content

dw2elf: fix ELF alignment, add DW_DLC_SYMBOLIC_RELOCATIONS for DWARF#137

Merged
staalmannen merged 1 commit into
mainfrom
claude/upgrade-ape-c-library-mmZGd
May 22, 2026
Merged

dw2elf: fix ELF alignment, add DW_DLC_SYMBOLIC_RELOCATIONS for DWARF#137
staalmannen merged 1 commit into
mainfrom
claude/upgrade-ape-c-library-mmZGd

Conversation

@staalmannen

Copy link
Copy Markdown
Owner

ELF alignment fix:
The ELF spec requires p_offset ≡ p_vaddr (mod p_align). With
p_align=AOUT_INITRND=0x200000 the constraint was violated (text_foff=176
vs text_vaddr=0x200028, 176≠40 mod 0x200000), causing the kernel to
reject the binary and fall back to shell execution (the '(' in
"Syntax error: ( unexpected" is byte 0x28 = low byte of entry 0x200028).
Fix: use p_align=PAGE_SIZE=0x1000 and pad text/data file offsets so
text_foff ≡ text_vaddr and data_foff ≡ data_vaddr (mod PAGE_SIZE).

DWARF fix:
libdwarfp comment: "Non-MIPS Non IA64 should use DW_DLC_SYMBOLIC_RELOCATIONS".
Without it the library uses binary ELF stream relocations which silently
produce no sections for x86_64, so n_dw_sects stayed 0.
Also add error reporting when dwarf_producer_init fails.

https://claude.ai/code/session_01WGAwvvTwDg2yknFkmZ3qzs

ELF alignment fix:
  The ELF spec requires p_offset ≡ p_vaddr (mod p_align). With
  p_align=AOUT_INITRND=0x200000 the constraint was violated (text_foff=176
  vs text_vaddr=0x200028, 176≠40 mod 0x200000), causing the kernel to
  reject the binary and fall back to shell execution (the '(' in
  "Syntax error: ( unexpected" is byte 0x28 = low byte of entry 0x200028).
  Fix: use p_align=PAGE_SIZE=0x1000 and pad text/data file offsets so
  text_foff ≡ text_vaddr and data_foff ≡ data_vaddr (mod PAGE_SIZE).

DWARF fix:
  libdwarfp comment: "Non-MIPS Non IA64 should use DW_DLC_SYMBOLIC_RELOCATIONS".
  Without it the library uses binary ELF stream relocations which silently
  produce no sections for x86_64, so n_dw_sects stayed 0.
  Also add error reporting when dwarf_producer_init fails.

https://claude.ai/code/session_01WGAwvvTwDg2yknFkmZ3qzs
@staalmannen staalmannen merged commit 7b8f4f1 into main May 22, 2026
1 check passed

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request updates dw2elf.c to ensure ELF file offsets align with virtual addresses modulo PAGE_SIZE, satisfying ELF alignment requirements. This is achieved by calculating necessary padding after headers and between sections and writing it to the output file. The dwarf_producer_init call was also updated to include symbolic relocations. Feedback suggests optimizing the padding implementation by using a single xwrite call with a zeroed buffer instead of writing byte-by-byte, and improving error reporting for DWARF initialization by including descriptive error messages from libdwarf.

Comment on lines +439 to +441
if(res != DW_DLV_OK) {
fprintf(stderr, "dw2elf: dwarf_producer_init failed\n");
} else {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

When dwarf_producer_init fails, it's helpful to include the error details provided by libdwarf. You can use dwarf_errmsg(derr) to get a human-readable description of the error.

		if(res != DW_DLV_OK) {
			fprintf(stderr, "dw2elf: dwarf_producer_init failed: %s\n", dwarf_errmsg(derr));
		} else {

/* ── text and data ── */
/* ── padding + text + padding + data ── */
cur = (long)(EHDR_SIZE + 2 * PHDR_SIZE);
while(cur < text_foff) { xwrite(ofd, &zero, 1); cur++; }

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Writing padding byte-by-byte using xwrite is inefficient as it results in a system call for every single byte. Since the maximum padding is PAGE_SIZE, it's better to write the padding in a single call using a zeroed buffer.

	if(cur < text_foff) {
		static char zeros[PAGE_SIZE];
		xwrite(ofd, zeros, text_foff - cur);
		cur = text_foff;
	}

while(cur < text_foff) { xwrite(ofd, &zero, 1); cur++; }
xwrite(ofd, aout_buf + AOUT_HEADR, textsize);
cur += (long)textsize;
while(cur < data_foff) { xwrite(ofd, &zero, 1); cur++; }

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Similar to the text section padding, writing the data section padding byte-by-byte is inefficient. Consider using a single xwrite call with a zeroed buffer.

	if(cur < data_foff) {
		static char zeros[PAGE_SIZE];
		xwrite(ofd, zeros, data_foff - cur);
		cur = data_foff;
	}

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.

2 participants