--- cddl/contrib/opensolaris/tools/ctf/cvt/ctf.c.orig +++ cddl/contrib/opensolaris/tools/ctf/cvt/ctf.c @@ -62,6 +62,18 @@ int ntholes; /* number of type holes */ }; +/* + * Macros to reverse byte order + */ +#define BSWAP_8(x) ((x) & 0xff) +#define BSWAP_16(x) ((BSWAP_8(x) << 8) | BSWAP_8((x) >> 8)) +#define BSWAP_32(x) ((BSWAP_16(x) << 16) | BSWAP_16((x) >> 16)) + +#define SWAP_16(x) (x) = BSWAP_16(x) +#define SWAP_32(x) (x) = BSWAP_32(x) + +static int needSwap; + /*PRINTFLIKE1*/ static void parseterminate(const char *fmt, ...) @@ -140,6 +152,11 @@ ctl.ctl_label = strtab_insert(&b->ctb_strtab, le->le_name); ctl.ctl_typeidx = le->le_idx; + if (needSwap) { + SWAP_32(ctl.ctl_label); + SWAP_32(ctl.ctl_typeidx); + } + ctf_buf_write(b, &ctl, sizeof (ctl)); return (1); @@ -152,6 +169,10 @@ ctf_buf_write(b, &id, sizeof (id)); + if (needSwap) { + SWAP_16(id); + } + debug(3, "Wrote object %s (%d)\n", (idp ? idp->ii_name : "(null)"), id); } @@ -180,10 +201,21 @@ fdata[0] = CTF_TYPE_INFO(CTF_K_FUNCTION, 1, nargs); fdata[1] = idp->ii_dtype->t_id; + + if (needSwap) { + SWAP_16(fdata[0]); + SWAP_16(fdata[1]); + } + ctf_buf_write(b, fdata, sizeof (fdata)); for (i = 0; i < idp->ii_nargs; i++) { id = idp->ii_args[i]->t_id; + + if (needSwap) { + SWAP_16(id); + } + ctf_buf_write(b, &id, sizeof (id)); } @@ -208,11 +240,25 @@ ctt->ctt_size = CTF_LSIZE_SENT; ctt->ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(size); ctt->ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(size); + if (needSwap) { + SWAP_32(ctt->ctt_name); + SWAP_16(ctt->ctt_info); + SWAP_16(ctt->ctt_size); + SWAP_32(ctt->ctt_lsizehi); + SWAP_32(ctt->ctt_lsizelo); + } ctf_buf_write(b, ctt, sizeof (*ctt)); } else { ctf_stype_t *cts = (ctf_stype_t *)ctt; cts->ctt_size = (ushort_t)size; + + if (needSwap) { + SWAP_32(cts->ctt_name); + SWAP_16(cts->ctt_info); + SWAP_16(cts->ctt_size); + } + ctf_buf_write(b, cts, sizeof (*cts)); } } @@ -222,6 +268,12 @@ { ctf_stype_t *cts = (ctf_stype_t *)ctt; + if (needSwap) { + SWAP_32(cts->ctt_name); + SWAP_16(cts->ctt_info); + SWAP_16(cts->ctt_size); + } + ctf_buf_write(b, cts, sizeof (*cts)); } @@ -296,6 +348,9 @@ encoding = ip->intr_fformat; data = CTF_INT_DATA(encoding, ip->intr_offset, ip->intr_nbits); + if (needSwap) { + SWAP_32(data); + } ctf_buf_write(b, &data, sizeof (data)); break; @@ -312,6 +367,11 @@ cta.cta_contents = tp->t_ardef->ad_contents->t_id; cta.cta_index = tp->t_ardef->ad_idxtype->t_id; cta.cta_nelems = tp->t_ardef->ad_nelems; + if (needSwap) { + SWAP_16(cta.cta_contents); + SWAP_16(cta.cta_index); + SWAP_32(cta.cta_nelems); + } ctf_buf_write(b, &cta, sizeof (cta)); break; @@ -341,6 +401,11 @@ offset); ctm.ctm_type = mp->ml_type->t_id; ctm.ctm_offset = mp->ml_offset; + if (needSwap) { + SWAP_32(ctm.ctm_name); + SWAP_16(ctm.ctm_type); + SWAP_16(ctm.ctm_offset); + } ctf_buf_write(b, &ctm, sizeof (ctm)); } } else { @@ -355,6 +420,14 @@ CTF_OFFSET_TO_LMEMHI(mp->ml_offset); ctlm.ctlm_offsetlo = CTF_OFFSET_TO_LMEMLO(mp->ml_offset); + + if (needSwap) { + SWAP_32(ctlm.ctlm_name); + SWAP_16(ctlm.ctlm_type); + SWAP_32(ctlm.ctlm_offsethi); + SWAP_32(ctlm.ctlm_offsetlo); + } + ctf_buf_write(b, &ctlm, sizeof (ctlm)); } } @@ -377,6 +450,12 @@ offset = strtab_insert(&b->ctb_strtab, ep->el_name); cte.cte_name = CTF_TYPE_NAME(CTF_STRTAB_0, offset); cte.cte_value = ep->el_number; + + if (needSwap) { + SWAP_32(cte.cte_name); + SWAP_32(cte.cte_value); + } + ctf_buf_write(b, &cte, sizeof (cte)); i--; } @@ -420,6 +499,11 @@ for (i = 0; i < (int) tp->t_fndef->fn_nargs; i++) { id = tp->t_fndef->fn_args[i]->t_id; + + if (needSwap) { + SWAP_16(id); + } + ctf_buf_write(b, &id, sizeof (id)); } @@ -613,6 +697,9 @@ int i; + needSwap = do_compress & CTF_SWAP_BYTES; + do_compress &= ~CTF_SWAP_BYTES; + /* * Prepare the header, and create the CTF output buffers. The data * object section and function section are both lists of 2-byte @@ -649,6 +736,18 @@ h.cth_stroff = ctf_buf_cur(buf); h.cth_strlen = strtab_size(&buf->ctb_strtab); + if (needSwap) { + SWAP_16(h.cth_preamble.ctp_magic); + SWAP_32(h.cth_parlabel); /* ref to name of parent lbl uniq'd against */ + SWAP_32(h.cth_parname); /* ref to basename of parent */ + SWAP_32(h.cth_lbloff); /* offset of label section */ + SWAP_32(h.cth_objtoff); /* offset of object section */ + SWAP_32(h.cth_funcoff); /* offset of function section */ + SWAP_32(h.cth_typeoff); /* offset of type section */ + SWAP_32(h.cth_stroff); /* offset of string section */ + SWAP_32(h.cth_strlen); /* length of string section in bytes */ + } + /* * We only do compression for ctfmerge, as ctfconvert is only * supposed to be used on intermediary build objects. This is --- cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.c.orig +++ cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.c @@ -620,7 +620,7 @@ terminate("No CTF data found in source file %s\n", srcfile); tmpname = mktmpname(destfile, ".ctf"); - write_ctf(srctd, destfile, tmpname, CTF_COMPRESS | keep_stabs); + write_ctf(srctd, destfile, tmpname, CTF_COMPRESS | CTF_SWAP_BYTES | keep_stabs); if (rename(tmpname, destfile) != 0) { terminate("Couldn't rename temp file %s to %s", tmpname, destfile); @@ -1015,7 +1015,7 @@ tmpname = mktmpname(outfile, ".ctf"); write_ctf(savetd, outfile, tmpname, - CTF_COMPRESS | write_fuzzy_match | dynsym | keep_stabs); + CTF_COMPRESS | CTF_SWAP_BYTES | write_fuzzy_match | dynsym | keep_stabs); if (rename(tmpname, outfile) != 0) terminate("Couldn't rename output temp file %s", tmpname); free(tmpname); --- cddl/contrib/opensolaris/tools/ctf/cvt/ctftools.h.orig +++ cddl/contrib/opensolaris/tools/ctf/cvt/ctftools.h @@ -391,6 +391,7 @@ #define CTF_USE_DYNSYM 0x2 /* use .dynsym not .symtab */ #define CTF_COMPRESS 0x4 /* compress CTF output */ #define CTF_KEEP_STABS 0x8 /* keep .stabs sections */ +#define CTF_SWAP_BYTES 0x10 /* target byte order is different from host */ void write_ctf(tdata_t *, const char *, const char *, int); --- cddl/contrib/opensolaris/tools/ctf/cvt/output.c.orig +++ cddl/contrib/opensolaris/tools/ctf/cvt/output.c @@ -717,7 +717,7 @@ iiburst = sort_iidescs(elf, file, td, flags & CTF_FUZZY_MATCH, flags & CTF_USE_DYNSYM); - data = ctf_gen(iiburst, lenp, flags & CTF_COMPRESS); + data = ctf_gen(iiburst, lenp, flags & (CTF_COMPRESS | CTF_SWAP_BYTES)); iiburst_free(iiburst); @@ -730,10 +730,12 @@ struct stat st; Elf *elf = NULL; Elf *telf = NULL; + GElf_Ehdr ehdr; caddr_t data; size_t len; int fd = -1; int tfd = -1; + int byteorder; (void) elf_version(EV_CURRENT); if ((fd = open(curname, O_RDONLY)) < 0 || fstat(fd, &st) < 0) @@ -746,6 +748,22 @@ if ((telf = elf_begin(tfd, ELF_C_WRITE, NULL)) == NULL) elfterminate(curname, "Cannot write"); + if (gelf_getehdr(elf, &ehdr)) { +#if BYTE_ORDER == _BIG_ENDIAN + byteorder = ELFDATA2MSB; +#else + byteorder = ELFDATA2LSB; +#endif + /* + * If target and host has the same byte order + * clear byte swapping request + */ + if (ehdr.e_ident[EI_DATA] == byteorder) + flags &= ~CTF_SWAP_BYTES; + } + else + elfterminate(curname, "Failed to get EHDR"); + data = make_ctf_data(td, elf, curname, &len, flags); write_file(elf, curname, telf, newname, data, len, flags); free(data);