Hi everyone,
I am trying to cross-compile a Zig shared library for the hexagon-linux-none target and run it on a Qualcomm device with QCS6490 SoC hexagonv68 architecture, but I’m running into a runtime exception.
Environment
- Host env: Ubuntu 22.04
- Target SoC: Qualcomm QCS6490 (Hexagon v68)
- Architecture: hexagonv68
- SDK: Hexagon SDK 4.2.0.3
- Zig target: hexagon-linux-none
- Output: .so shared library
- Execution: Hexagon simulator via run_main_on_hexagon_sim
Steps to reproduce
I linked all the required libraries and translated the required headers with the help of zig translate-c for the hexagon DSP. Here is my build.zig
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const so = b.addLibrary(.{
.name = "zig-qhmath",
.linkage = .dynamic,
.root_module = b.createModule(.{
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
}),
});
so.addObjectFile(b.path("<path-to-sdk>/libs/qhl/prebuilt/hexagon_toolv84_v68/libqhmath.a"));
so.addObjectFile(b.path("<path-to-sdk>/libs/qhl/prebuilt/hexagon_toolv84_v68/libqhblas.a"));
so.addObjectFile(b.path("<path-to-sdk>/libs/qhl/prebuilt/hexagon_toolv84_v68/libqhdsp.a"));
so.addObjectFile(b.path("<path-to-sdk>/libs/qhl/prebuilt/hexagon_toolv84_v68/libqhcomplex.a"));
so.addObjectFile(b.path("<path-to-sdk>/libs/qhl_hvx/prebuilt/hexagon_toolv84_v68/libqhdsp_hvx.a"));
so.addObjectFile(b.path("<path-to-sdk>/libs/qhl_hvx/prebuilt/hexagon_toolv84_v68/libqhmath_hvx.a"));
so.addObjectFile(b.path("<path-to-sdk>/libs/qhl_hvx/prebuilt/hexagon_toolv84_v68/libqhblas_hvx.a"));
b.installArtifact(so);
const run_step = b.step("run", "Run the app");
const run_cmd = b.addRunArtifact(so);
run_step.dependOn(&run_cmd.step);
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| {
run_cmd.addArgs(args);
}
}
My main.zig calling hvx function for vector addition
const qhblas_hvx = @import("qhblas_hvx.zig");
pub export fn main(argc: i32, argv: [*][*:0]u8) i32 {
_ = argc;
_ = argv;
const ARRAY_SIZE: usize = 128;
var in1_vb: [ARRAY_SIZE]i8 = undefined;
var in2_vb: [ARRAY_SIZE]i8 = undefined;
var out_vb: [ARRAY_SIZE]i8 = undefined;
for (0..ARRAY_SIZE) |i| {
in1_vb[i] = @intCast(i);
in2_vb[i] = @intCast(i);
out_vb[i] = 0;
}
_ = qhblas_hvx.qhblas_hvx_vector_add_ab(@ptrCast(@alignCast(&in1_vb)), @ptrCast(@alignCast(&in2_vb)), @ptrCast(@alignCast(&out_vb)), ARRAY_SIZE);
return 0;
}
Building the .so library for simulator testing.
zig build -Dtarget=hexagon-linux-none -Dcpu=hexagonv68
Now running the final shared with simulator, I got the 0x1101 QuRT error code.
$HEXAGON_TOOLS_ROOT/Tools/bin/hexagon-sim -mv68 --pmu_statsfile ./pmu_stats.txt --l2tcm_base 0xd800 --rtos $HEXAGON_SDK_ROOT/utils/sim_utils/hexagon_Debug_toolv84_v68/osam.cfg $HEXAGON_SDK_ROOT/rtos/qurt/computev68/sdksim_bin/runelf.pbn -- $HEXAGON_SDK_ROOT/libs/run_main_on_hexagon/ship/hexagon_toolv84_v68/run_main_on_hexagon_sim stack_size=0x400000 -- <path-zig-prj>/zig-out/lib/libzig-qhmath.so
hexagon-sim INFO: The rev_id used in the simulation is 0x00008d68 (v68n_1024)
hexagon-sim INFO: DRIL::PluginOSAM in dril.cpp:8834: new style init-osam not available, go back to old way.
QURT kernel started
QURT kernel init cache params
QURT root task started
QuRTOS heap init: start 1e03d0c0 size 0x80000
Init memory pools...
Found Virtual Pool in overrides. size 20, pool id 4096
Adding pages 0x00001000->0x0001e000 to Default Virtual pool.
Adding pages 0x0001e200->0x000fe000 to Default Virtual pool.
0 name DEFAULT_PHYSPOOL pool 1e044580 island 0
Found requested Pool ID in overrides. size 24, pool id 0
Using over-ride ranges for pool index 0; number of ranges 2
0: 0x500ad000-->0x50100000
1: 0x50300000-->0xa0000000
1 name DRIVER_POOL pool 1e044660 island 0
Using configured ranges for pool index 1; number of ranges 2
0: 0xb0000000-->0xf0000000
1: 0x28885000-->0x28886000
2 name TCM_PHYSPOOL pool 1e044740 island 0
Using configured ranges for pool index 2; number of ranges 2
0: 0xd8020000-->0xd8040000
1: 0xd8200000-->0xd8a00000
3 name ANGEL_POOL pool 1e044820 island 0
Using configured ranges for pool index 3; number of ranges 1
0: 0x00000000-->0x00001000
4 name 64BITS_PHYSPOOL pool 1e044900 island 0
Using configured ranges for pool index 4; number of ranges 1
0: 0xa8020000-->0xb8020000
5 name 64BITS_PHYSPOOL_36BITS pool 1e0449e0 island 0
Using configured ranges for pool index 5; number of ranges 1
0: 0xa8020000-->0xb8020000
init static mapping: ppn 0x000d8020, vpn 0x000d8020, pages 0x00000010
shmem mapping 0xd8020 returns 0
init static mapping: ppn 0x000d8030, vpn 0x000d8030, pages 0x00000010
shmem mapping 0xd8030 returns 0
init static mapping: ppn 0x001a8180, vpn 0x000a8180, pages 0x00000040
shmem mapping 0xa8180 returns 0
init static mapping: ppn 0x00aa8180, vpn 0x000b8180, pages 0x00000040
shmem mapping 0xb8180 returns 0
init static mapping: ppn 0x000d8200, vpn 0x000d8200, pages 0x00000100
shmem mapping 0xd8200 returns 0
init static mapping: ppn 0x000d8300, vpn 0x000d8300, pages 0x00000100
shmem mapping 0xd8300 returns 0
init static mapping: ppn 0x000d8400, vpn 0x000d8400, pages 0x00000400
shmem mapping 0xd8400 returns 0
init static mapping: ppn 0x000d8800, vpn 0x000d8800, pages 0x00000100
shmem mapping 0xd8800 returns 0
init static mapping: ppn 0x000d8900, vpn 0x000d8900, pages 0x00000100
shmem mapping 0xd8900 returns 0
init static mapping: ppn 0x000b0000, vpn 0x000b0000, pages 0x00000001
shmem mapping 0xb0000 returns 0
init static mapping: ppn 0x000fc000, vpn 0x000fc000, pages 0x00001000
shmem mapping 0xfc000 returns 0
init static mapping: ppn 0x000b1000, vpn 0x000b1000, pages 0x00000004
shmem mapping 0xb1000 returns 0
init static mapping: ppn 0x00028885, vpn 0x00028885, pages 0x00000001
shmem mapping 0x28885 returns 0
finished static mem
App Images Init
QURT system-clock daemon started
QURT Timer Driver client started
QURT Timer service was initialized.
Entering main() ...
Debugging can be done using debug monitor/stub
Make sure to provide the debugger cosim in the config file
Start user reaper thread for process with PID: 0x2
Entering main() ...
added path ".": HIGH:0x1E8:122:paths.c
Args from QuRT: /home/vasu/Hexagon_SDK/4.2.0.3/4.2.0.3/rtos/qurt/computev68/sdksim_bin/runelf.pbn /home/vasu/Hexagon_SDK/4.2.0.3/4.2.0.3/libs/run_main_on_hexagon/ship/hexagon_toolv84_v68/run_main_on_hexagon_sim stack_size=0x400000 -- ./zig-qhl/zig-out/lib/libzig-qhmath.so : HIGH:0x1E8:59:run_main_on_hexagon_sim.c
fs_region_create request with addr=0, size=1000
fs_region_create map region with vaddr=d8041000, paddr=500ff000, size=1000, perm=b, region_handle=1e048eb0
read headers 0x0 -> d8041000 (0x1000 B): HIGH:0x1E8:539:map_object.c
_rtld_map_object_ex: sigverify skipped for ./zig-qhl/zig-out/lib/libzig-qhmath.so, no function specified!: HIGH:0x1E8:598:map_object.c
fs_region_create request with addr=0, size=fb000
fs_region_create map region with vaddr=d8100000, paddr=50380000, size=fb000, perm=b, region_handle=1e048f10
mapped [d8100000 - d81fb000] (1028096 Bytes): HIGH:0x1E8:729:map_object.c
load 0x0 -> d8100000 (0x1AB1C B): HIGH:0x1E8:845:map_object.c
load 0x1AB20 -> d812ab20 (0xAC6A0 B): HIGH:0x1E8:845:map_object.c
zero [d81e8718 - d81e8fff] (0x8E8 B): HIGH:0x1E8:815:map_object.c
load 0xC71C0 -> d81e71c0 (0x1558 B): HIGH:0x1E8:845:map_object.c
zero [d81f87e4 - d81fa8bf] (0x20DC B): HIGH:0x1E8:815:map_object.c
load 0xC8720 -> d81f8720 (0xC4 B): HIGH:0x1E8:845:map_object.c
fs_region_delete request with VMA addr=d8041000, size=1000, region_handle=1e048eb0
fs_region_delete unmap vaddr=d8041000, padd=1343221760, size=1000
protect [d8100000 - d811afff] (0x1B000 B) r..: HIGH:0x1E8:123:reloc.c
fs_change_page_attr request with addr=d8100000, size=1b000, perm=1, region_handle=1e048f10
Flush cache of range with addr=d8100000, size=fb000
chop off head from: fs_change_page_attr unmap vaddr=d8100000, paddr=50380000, size=fb000
chop off tail from: fs_change_page_attr unmap vaddr=d8100000, paddr=50380000, size=fb000
remap tail: fs_change_page_attr map vaddr=d811b000, paddr=5039b000, size=e0000, perm=b
final list after split....
fs_change_page_attr NEW map vaddr=d8100000, paddr=50380000, size=1b000, perm=9
Finished ONE mprotect, final list ....
......Finished ONE mprotect, final list
protect [d812ab20 - d81d7b1f] (0xAD000 B) r.x: HIGH:0x1E8:123:reloc.c
fs_change_page_attr request with addr=d812a000, size=ad000, perm=5, region_handle=1e048f10
Flush cache of range with addr=d811b000, size=e0000
chop off head from: fs_change_page_attr unmap vaddr=d811b000, paddr=5039b000, size=e0000
remap head: fs_change_page_attr map vaddr=d811b000, paddr=5039b000, size=f000, perm=b
chop off tail from: fs_change_page_attr unmap vaddr=d811b000, paddr=5039b000, size=e0000
remap tail: fs_change_page_attr map vaddr=d81d7000, paddr=50457000, size=24000, perm=b
final list after split....
fs_change_page_attr NEW map vaddr=d812a000, paddr=503aa000, size=ad000, perm=d
Finished ONE mprotect, final list ....
......Finished ONE mprotect, final list
protect [d81e71c0 - d81e91bf] (0x2000 B) rw.: HIGH:0x1E8:123:reloc.c
fs_change_page_attr request with addr=d81e7000, size=2000, perm=3, region_handle=1e048f10
mprotect set permission same as before, operation ignored
protect [d81f8720 - d81fb71f] (0x3000 B) rw.: HIGH:0x1E8:123:reloc.c
fs_change_page_attr request with addr=d81f8000, size=3000, perm=3, region_handle=1e048f10
mprotect set permission same as before, operation ignored
dlopen ./zig-qhl/zig-out/lib/libzig-qhmath.so return obj 5a400628: HIGH:0x1E8:792:rtld.c
!!! Exception occurred
QuRT error code 0x1101
Thread ID 0x1e6
SP 0x5a400170
ELR 0xd81d7150
BADVA 0xd81002e0
PROCESS_KILL: asid 0 client handle 0x3 exitcode 0x1e6
Invalid PID 0x0 for process kill, client_handle = 0x3
Above exitcode is the error thread id.
runelf exception handler returns
runelf main exits.
Use the information above for root causing the exception.
Ignore the error information below if any which is due to lack of user exception handler.
Fatal Error: Cause: 0x5 Cause2: 0x20
ELR: 0x1e020f84, BADVA: 0xd81f8000, SSR: 0x1b80027, SP:0xbfbfbfbf
Done!
T0: Insns=2180327 Packets=943360
T1: Insns=68615 Packets=68395
T2: Insns=68420 Packets=68296
T3: Insns=983806 Packets=449758
T4: Insns=68420 Packets=68296
T5: Insns=68420 Packets=68296
Total: Insns=3438008 Pcycles=3956040
Analyzing the 0x1101 code with qurt_error_info.py script in Hexagon SDK
python3 qurt_error_info.py 0x1101
$HEXAGON_SDK_ROOT/utils/scripts/qurt_error_info.py:145: SyntaxWarning: "is" with a literal. Did you mean "=="?
if (ssr is '') or ('#u8' in ssr):
/$HEXAGON_SDK_ROOT/utils/scripts/qurt_error_info.py:203: SyntaxWarning: "is" with a literal. Did you mean "=="?
if row[eValue] is '':
Cause type: QURT_EXCEPT_PRECISE ( 0x1 )
Cause details: A precise exception occurred.
Cause2 details:
Exception type: Precise ( 0x11 )
Exception description: Privilege violation: User/Guest mode execute to page with no execute permissions (X=0).
I also tried for hexagon-linux-musl target but got the same error.