elf2ecoff endianness bugs
Steve Rumble <[email protected]> Fri, 5 Dec 2025 10:33:10 -0800
| Newsgroups | gmane.os.netbsd.ports.mips.devel |
|---|---|
| Message-ID | <CAL4_dAQFm=uJf+bB0j1hScizDaSOT9f0bbF4JEgsX6X3Tv9B1g@mail.gmail.com> |
Hello, elf2ecoff isn't generating valid symbol tables. It's both byte swapping when it shouldn't (same host and target endianness) and not swapping when it should. For example, my crosstool objdump doesn't like an elf2ecoff'd sgimips kernel generated on amd64: $ mipseb--netbsd-objdump -x netbsd.ecoff > /dev/null mipseb--netbsd-objdump: failed to read symbol table from: netbsd.ecoff mipseb--netbsd-objdump: error message was: file truncated Same goes for an hpcmips (mipsel) kernel generated on amd64: $ mipsel--netbsd-objdump -x netbsd.ecoff > /dev/null mipsel--netbsd-objdump: netbsd.ecoff: bad value The attached patch makes objdump able to read the ecoff symbol tables again. Steve
elf2ecoff.c.diff
(application/octet-stream, 2.6 KB)
Index: elf2ecoff.c
===================================================================
RCS file: /cvsroot/src/usr.bin/elf2ecoff/elf2ecoff.c,v
retrieving revision 1.38
diff -u -r1.38 elf2ecoff.c
--- elf2ecoff.c 13 Sep 2025 17:08:47 -0000 1.38
+++ elf2ecoff.c 5 Dec 2025 17:19:37 -0000
@@ -425,9 +425,12 @@
}
- if (debug)
- fprintf(stderr, "writing syms at offset %#x\n",
- (uint32_t)(ep.f.f_symptr + sizeof(symhdr)));
+ if (debug) {
+ uint32_t symptr = needswap ? bswap32(ep.f.f_symptr) : ep.f.f_symptr;
+ fprintf(stderr, "writing symhdr at offset %#x, "
+ "syms at offset %#x\n", symptr,
+ (uint32_t)(symptr + sizeof(symhdr)));
+ }
/* Copy and translate the symbol table... */
elf_symbol_table_to_ecoff(outfile, infile, &ep,
@@ -591,10 +594,12 @@
int32_t extsymoff, int32_t extstroff, int32_t strsize)
{
- if (debug)
+ if (debug) {
+ uint32_t symptr = needswap ? bswap32(ep->f.f_symptr) : ep->f.f_symptr;
fprintf(stderr,
"writing symhdr for %d entries at offset %#x\n",
- nesyms, ep->f.f_symptr);
+ nesyms, symptr);
+ }
ep->f.f_nsyms = sizeof(struct ecoff32_symhdr);
@@ -614,9 +619,9 @@
if (needswap) {
bswap32_region(&symhdrp->ilineMax,
sizeof(*symhdrp) - sizeof(symhdrp->magic) -
- sizeof(symhdrp->ilineMax));
+ sizeof(symhdrp->vstamp));
symhdrp->magic = bswap16(symhdrp->magic);
- symhdrp->ilineMax = bswap16(symhdrp->ilineMax);
+ symhdrp->vstamp = bswap16(symhdrp->vstamp);
}
safewrite(out, symhdrp, sizeof(*symhdrp),
@@ -675,7 +680,7 @@
nsyms = ecoffsymtab.nsymbols;
/* Compute output ECOFF symbol- and string-table offsets. */
- ecoff_symhdr_off = ep->f.f_symptr;
+ ecoff_symhdr_off = needswap ? bswap32(ep->f.f_symptr) : ep->f.f_symptr;
nextoff = ecoff_symhdr_off + sizeof(struct ecoff_symhdr);
stringtaboff = nextoff;
@@ -703,12 +708,15 @@
/* Write out the symbol table... */
padding = symtabsize - (nsyms * sizeof(struct ecoff_extsym));
- for (i = 0; i < nsyms; i++) {
- struct ecoff_extsym *es = &ecoffsymtab.ecoff_syms[i];
- es->es_flags = bswap16(es->es_flags);
- es->es_ifd = bswap16(es->es_ifd);
- bswap32_region(&es->es_strindex,
- sizeof(*es) - sizeof(es->es_flags) - sizeof(es->es_ifd));
+ if (needswap) {
+ for (i = 0; i < nsyms; i++) {
+ struct ecoff_extsym *es = &ecoffsymtab.ecoff_syms[i];
+ es->es_flags = bswap16(es->es_flags);
+ es->es_ifd = bswap16(es->es_ifd);
+ bswap32_region(&es->es_strindex,
+ sizeof(*es) - sizeof(es->es_flags) -
+ sizeof(es->es_ifd));
+ }
}
safewrite(out, ecoffsymtab.ecoff_syms,
nsyms * sizeof(struct ecoff_extsym),