dwtypes + dw2elf: Plan9 type-info sidecar + a.out→ELF64 converter#131
Conversation
Replace the aborted sys/src/ape/cmd/compiler/ approach with a simpler
two-step pipeline that needs no libdwarfp in the compiler itself:
pcc -g foo.c
│
├─ 6c (unmodified, but _DWTYPES env var set by pcc)
│ → foo.o + foo.dwtypes (via new dwtypes.c hook in cc/)
├─ 6l → foo (Plan9 a.out, unchanged)
└─ dw2elf -o foo.elf foo foo.dwtypes
→ foo.elf (ELF64, executable on 9front + dwarfdump-readable)
New files:
sys/src/cmd/cc/dwtypes.c — writes per-function type-info sidecar;
activates when /env/_DWTYPES exists;
derives .dwtypes path from outfile
sys/src/cmd/cc/dwtypes.h — declaration for pgen.c hook
sys/src/ape/cmd/dw2elf/ — APE tool: reads Plan9 a.out fat header +
.dwtypes sidecar(s), emits ELF64 binary
with DW_TAG_subprogram / DW_TAG_formal_parameter
DIEs via libdwarfp
Modified:
sys/src/cmd/cc/pgen.c — call dwtypes_emit_func() at end of codgen()
sys/src/cmd/cc/mkfile — add dwtypes.$O and dwtypes.h
sys/src/ape/9src/cc.c — -g flag: set _DWTYPES, run dw2elf post-link
sys/src/ape/cmd/mkfile — add dw2elf, remove compiler
Removed:
sys/src/ape/cmd/compiler/ — obsolete (was trying to rebuild compilers
with libdwarfp; no longer needed)
https://claude.ai/code/session_01WGAwvvTwDg2yknFkmZ3qzs
There was a problem hiding this comment.
Code Review
This pull request introduces DWARF debug information support for the Plan 9 C compiler suite by adding a -g flag to the compiler driver, implementing .dwtypes sidecar emission for type information, and providing a dw2elf utility to produce ELF64 binaries. The review feedback identified several areas for improved robustness, including the need for proper error handling for memory allocations and file reads, the prevention of potential integer overflows during bounds checking, and the use of safer string formatting functions.
| static uint32_t sc_u32(void) | ||
| { | ||
| uint32_t v; | ||
| if(sc_pos + 4 > sc_len) return 0; |
| { | ||
| uint32_t n = sc_u32(); | ||
| char *s; | ||
| if(n == 0 || sc_pos + n > sc_len) return strdup("?"); |
| uint32_t n = sc_u32(); | ||
| char *s; | ||
| if(n == 0 || sc_pos + n > sc_len) return strdup("?"); | ||
| s = malloc(n + 1); |
| rewind(f); | ||
| buf = malloc(*outlen ? *outlen : 1); | ||
| if(!buf) { fprintf(stderr, "dw2elf: out of memory\n"); exit(1); } | ||
| fread(buf, 1, *outlen, f); |
| int shn_text, shn_data, shn_bss, shn_shstr; | ||
| uint8_t zero = 0; | ||
|
|
||
| sidecars = malloc(argc * sizeof(char *)); |
There was a problem hiding this comment.
| dw_sects[k].data = | ||
| malloc(blen ? blen : 1); |
There was a problem hiding this comment.
The result of malloc is not checked. If memory allocation fails for a DWARF section, the program will continue with a NULL pointer, leading to a crash later when xwrite is called.
dw_sects[k].data = malloc(blen ? blen : 1);
if(!dw_sects[k].data) { fprintf(stderr, "dw2elf: out of memory\n"); exit(1); }| p = utfrrune(buf, '.'); | ||
| if(p != nil) | ||
| *p = 0; | ||
| strncat(buf, ".dwtypes", sizeof(buf) - strlen(buf) - 1); |
There was a problem hiding this comment.
Using strncat here is safe but slightly fragile. If the path in buf is already near the limit, the extension might be truncated. Using snprint to construct the full path is generally preferred in Plan 9 code for better clarity and safety.
| p = utfrrune(buf, '.'); | |
| if(p != nil) | |
| *p = 0; | |
| strncat(buf, ".dwtypes", sizeof(buf) - strlen(buf) - 1); | |
| p = utfrrune(buf, '.'); | |
| if(p == nil) | |
| p = buf + strlen(buf); | |
| snprint(p, sizeof(buf) - (p - buf), ".dwtypes"); |
Replace the aborted sys/src/ape/cmd/compiler/ approach with a simpler two-step pipeline that needs no libdwarfp in the compiler itself:
pcc -g foo.c
│
├─ 6c (unmodified, but _DWTYPES env var set by pcc)
│ → foo.o + foo.dwtypes (via new dwtypes.c hook in cc/)
├─ 6l → foo (Plan9 a.out, unchanged)
└─ dw2elf -o foo.elf foo foo.dwtypes
→ foo.elf (ELF64, executable on 9front + dwarfdump-readable)
New files:
sys/src/cmd/cc/dwtypes.c — writes per-function type-info sidecar;
activates when /env/_DWTYPES exists;
derives .dwtypes path from outfile
sys/src/cmd/cc/dwtypes.h — declaration for pgen.c hook
sys/src/ape/cmd/dw2elf/ — APE tool: reads Plan9 a.out fat header +
.dwtypes sidecar(s), emits ELF64 binary
with DW_TAG_subprogram / DW_TAG_formal_parameter
DIEs via libdwarfp
Modified:
sys/src/cmd/cc/pgen.c — call dwtypes_emit_func() at end of codgen()
sys/src/cmd/cc/mkfile — add dwtypes.$O and dwtypes.h
sys/src/ape/9src/cc.c — -g flag: set _DWTYPES, run dw2elf post-link
sys/src/ape/cmd/mkfile — add dw2elf, remove compiler
Removed:
sys/src/ape/cmd/compiler/ — obsolete (was trying to rebuild compilers
with libdwarfp; no longer needed)
https://claude.ai/code/session_01WGAwvvTwDg2yknFkmZ3qzs