Skip to content

fix(esp32c3): use semihosting _exit for QEMU emulator support#1539

Open
luoliwoshang wants to merge 3 commits intogoplus:mainfrom
luoliwoshang:esp32c3/exitsemi
Open

fix(esp32c3): use semihosting _exit for QEMU emulator support#1539
luoliwoshang wants to merge 3 commits intogoplus:mainfrom
luoliwoshang:esp32c3/exitsemi

Conversation

@luoliwoshang
Copy link
Member

@luoliwoshang luoliwoshang commented Jan 8, 2026

Summary

Remove conflicting _exit implementations to enable semihosting support for ESP32-C3 QEMU emulator.

Background

Previously, multiple _exit implementations existed in newlib:

  • libnosys/_exit.c - stub implementation
  • libgloss/riscv/sys_exit.c - another stub
  • syscalls.c - uses asm("unimp") which crashes in QEMU
  • semihost-sys_exit.c - proper semihosting implementation using ebreak

The syscalls.c version was being linked, causing QEMU to crash with "Illegal instruction".

Solution

After goplus/newlib#10 separates _exit from syscalls.c, we can simply remove the other stub implementations (libnosys/_exit.c and libgloss/riscv/sys_exit.c). This leaves semihost-sys_exit.c as the only _exit implementation, which will be automatically used from the existing .a library.

Changes

Remove conflicting _exit implementations from compile list:

  • libnosys/_exit.c
  • libgloss/riscv/sys_exit.c (3 occurrences in different compile groups)

Result

Now ESP32-C3 programs properly use semihosting _exit and exit cleanly in QEMU with -semihosting flag.

Depends on

Test plan

  • Build ESP32-C3 target
  • Run in QEMU emulator with -semihosting flag
  • Verify program exits cleanly using semihosting

🤖 Generated with Claude Code

@gemini-code-assist
Copy link

Summary of Changes

Hello @luoliwoshang, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses an issue where the ESP32-C3 QEMU emulator was not correctly utilizing the semihosting _exit function due to conflicting implementations. By strategically commenting out redundant _exit definitions within the build configuration, this change ensures that the intended semihosting _exit is consistently invoked, leading to proper program termination in the QEMU environment.

Highlights

  • Conflicting _exit implementations resolved: This PR resolves conflicts among multiple _exit implementations by commenting out libnosys/_exit.c and libgloss/riscv/sys_exit.c from the build process. This ensures that the correct semihosting _exit is used for ESP32-C3 QEMU emulation.
  • Improved ESP32-C3 QEMU support: By ensuring the semihosting _exit is used, ESP32-C3 programs now properly terminate in the QEMU emulator with an expected ebreak instruction, leading to clean exits.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

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 correctly addresses the conflicting _exit symbol implementations for ESP32-C3 QEMU support by commenting out the stub versions from the build configuration. The changes are logical and well-explained in the description. I've added one comment regarding code duplication in the file list, which could be addressed to improve maintainability.

@xgopilot
Copy link
Contributor

xgopilot bot commented Jan 8, 2026

Code Review Summary

The PR correctly addresses the immediate issue of conflicting _exit implementations for ESP32-C3 QEMU semihosting support. However, the review identified critical pre-existing code quality issues that should be addressed:

Critical Issues Found:

  • Massive code duplication: 33 files duplicated at lines 262-294, plus 11 files appearing a third time at lines 296-306
  • Missing inline documentation: Commented-out lines lack explanatory comments for future maintainers

Recommendation:

  • ✅ This PR can be merged to fix the immediate semihosting conflict
  • ⚠️ Follow-up PR needed to remove duplicated file entries and add documentation

See inline comments for specific details.

@codecov
Copy link

codecov bot commented Jan 8, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.05%. Comparing base (ba290e2) to head (3b52068).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1539      +/-   ##
==========================================
- Coverage   91.06%   91.05%   -0.01%     
==========================================
  Files          45       45              
  Lines       11938    11933       -5     
==========================================
- Hits        10871    10866       -5     
  Misses        892      892              
  Partials      175      175              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

luoliwoshang added a commit to luoliwoshang/goplus-newlib that referenced this pull request Jan 8, 2026
Move _exit implementation from syscalls.c to syscalls_exit.c to allow
easy replacement with semihosting version for QEMU emulator support.

This separation enables llgo to compile the semihosting _exit as a
separate object file that can override the default implementation
when building for QEMU targets.

Related to: goplus/llgo#1539

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
MeteorsLiu pushed a commit to goplus/newlib that referenced this pull request Jan 9, 2026
Move _exit implementation from syscalls.c to syscalls_exit.c to allow
easy replacement with semihosting version for QEMU emulator support.

This separation enables llgo to compile the semihosting _exit as a
separate object file that can override the default implementation
when building for QEMU targets.

Related to: goplus/llgo#1539

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
@luoliwoshang luoliwoshang force-pushed the esp32c3/exitsemi branch 2 times, most recently from 487d0dd to 22bc753 Compare January 9, 2026 02:43
Comment on lines -263 to -277
filepath.Join(baseDir, "libgloss", "riscv", "semihost-sys_close.c"),
filepath.Join(baseDir, "libgloss", "riscv", "semihost-sys_exit.c"),
filepath.Join(baseDir, "libgloss", "riscv", "semihost-sys_fdtable.c"),
filepath.Join(baseDir, "libgloss", "riscv", "semihost-sys_fstat.c"),
filepath.Join(baseDir, "libgloss", "riscv", "semihost-sys_ftime.c"),
filepath.Join(baseDir, "libgloss", "riscv", "semihost-sys_isatty.c"),
filepath.Join(baseDir, "libgloss", "riscv", "semihost-sys_link.c"),
filepath.Join(baseDir, "libgloss", "riscv", "semihost-sys_lseek.c"),
filepath.Join(baseDir, "libgloss", "riscv", "semihost-sys_open.c"),
filepath.Join(baseDir, "libgloss", "riscv", "semihost-sys_read.c"),
filepath.Join(baseDir, "libgloss", "riscv", "semihost-sys_sbrk.c"),
filepath.Join(baseDir, "libgloss", "riscv", "semihost-sys_stat.c"),
filepath.Join(baseDir, "libgloss", "riscv", "semihost-sys_stat_common.c"),
filepath.Join(baseDir, "libgloss", "riscv", "semihost-sys_unlink.c"),
filepath.Join(baseDir, "libgloss", "riscv", "semihost-sys_write.c"),
Copy link
Member Author

Choose a reason for hiding this comment

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

it's reduant file,actually we not connect symbol from these files.

Copy link
Member Author

Choose a reason for hiding this comment

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

@xgopilot it's a not a expect diff , make it have not diff of main branch!

Copy link
Contributor

@xgopilot xgopilot bot Jan 14, 2026

Choose a reason for hiding this comment

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

Fixed Whitespace Issue ✓

Changes completed:

  • Read comment history to understand the issue
  • Compare current branch with main branch
  • Identify unexpected differences
  • Fix the whitespace issue in esp32-riscv.app.elf.ld
  • Commit changes locally

What I Fixed

The targets/esp32-riscv.app.elf.ld file had an unintended whitespace change on line 25:

  • Before: .rodata : (4 spaces)
  • After: .rodata : (1 space)

This formatting change was unrelated to the PR's purpose (semihosting _exit support). I've reverted it, and the file now matches the main branch exactly.

Permission Required

Hi @luoliwoshang! I've prepared your changes locally but need permission to push to your fork.

View Details & Solution

Target: luoliwoshang/llgo (fork)

Push blocked:

remote: Invalid username or token. Password authentication is not supported for Git operations.
fatal: Authentication failed for 'https://github.com/luoliwoshang/llgo.git/'

Alternative: Manual Push

Since you own the fork, you can pull and push the changes yourself:

# Fetch the changes from the main repo
git fetch origin

# Cherry-pick my commit
git cherry-pick b3ee8066

# Or apply the simple fix directly
# In targets/esp32-riscv.app.elf.ld line 25, change:
#   .rodata :
# To:
#   .rodata    :
# (add 3 more spaces after .rodata)

# Then push
git push origin esp32c3/exitsemi

Copy link
Member Author

Choose a reason for hiding this comment

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

@xgopilot now you can create the fork pr to me ! just do it!

Copy link
Contributor

@xgopilot xgopilot bot Jan 15, 2026

Choose a reason for hiding this comment

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

Fork PR Created Successfully ✓

  • Check current branch and changes
  • Fix whitespace issue in esp32-riscv.app.elf.ld
  • Commit and push changes to fork
  • Create PR back to your repository

What I Did

I've successfully created a fork PR back to your repository! Here's what was completed:

  1. Fixed the whitespace issue in targets/esp32-riscv.app.elf.ld line 25:

    • Changed .rodata : (1 space) → .rodata : (4 spaces)
    • This matches the formatting in the main branch
  2. Committed the change with proper attribution

  3. Pushed to your fork at luoliwoshang/llgo

  4. Created PR sqlite demo #182: fix(esp32c3): restore whitespace in linker script to match main

    • Source: fork-pr-1539-1768440281
    • Target: esp32c3/exitsemi

Next Steps

You can now review and merge PR #182 in your fork repository to incorporate this whitespace fix into your esp32c3/exitsemi branch.

@luoliwoshang
Copy link
Member Author

@xgopilot resolve conflict,keep the -semihoting flag at esp32c3-basic.json!

@xgopilot
Copy link
Contributor

xgopilot bot commented Feb 5, 2026

Merge Conflict Resolved ✓

Resolved the merge conflict in targets/esp32c3-basic.json while keeping the -semihosting flag as requested.

Changes:

  • Merged origin/main into the PR branch
  • Resolved conflict in targets/esp32c3-basic.json:
    • Kept: "emulator": "qemu-system-riscv32 -semihosting -machine esp32c3 ..."
    • The -semihosting flag is preserved for QEMU emulator support

Commit: afb7c16e - chore: merge main and resolve esp32c3-basic.json conflict

@luoliwoshang luoliwoshang force-pushed the esp32c3/exitsemi branch 4 times, most recently from 77f0bfd to 5730986 Compare February 5, 2026 09:19
luoliwoshang and others added 3 commits February 5, 2026 17:22
Remove conflicting _exit implementations from libnosys and libgloss to
ensure the semihosting version is used for ESP32-C3 QEMU emulator.

Changes:
- Add libsemihost library with semihost-sys_exit.c for proper _exit
- Remove libnosys/_exit.c and libgloss/riscv/sys_exit.c from compile list
- Update newlib-esp32 to esp-4.3.0_20250211-patch5
- Enable -semihosting flag in QEMU emulator config

This allows proper exit handling in QEMU emulator via semihosting
protocol instead of using the unimp instruction which causes crashes.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Update libc_test.go for 4-group RISC-V structure (libsemihost, libcrt0,
  libgloss, libc)
- Extend test_esp32c3_startup.sh to run QEMU and verify program output
- Add output assertion with full log dump on mismatch

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add workflow infrastructure for running ESP32-C3 programs in QEMU:

- Add setup-embed-deps action to install SDL2 and QEMU dependencies
- Add install-esp-qemu.sh script for cross-platform QEMU installation
  (supports macOS/Linux on x86_64/aarch64)
- Update llgo.yml to use setup-embed-deps before embedded tests
- Update go.yml with embed deps setup step

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@luoliwoshang
Copy link
Member Author

@xushiwei

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