Date: Sat, 24 Mar 2012 01:47:33 +0000 (UTC) From: Oleksandr Tymoshenko <gonzo@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r233407 - head/cddl/contrib/opensolaris/tools/ctf/cvt Message-ID: <201203240147.q2O1lXiL004482@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: gonzo Date: Sat Mar 24 01:47:33 2012 New Revision: 233407 URL: http://svn.freebsd.org/changeset/base/233407 Log: Maintain target's byte order for multi-byte fields in CTF structures. CTF format is not cross-platform by design, e.g. it is not guaranteed that data generated by ctfconvert/ctfmerge on one architecture will be successfuly read on another. CTF structures are saved/restored using naive approach. Roughly it looks like: write(fd, &ctf_struct, sizeof(ctf_struct)) read(fd, &ctf_struct, sizeof(ctf_struct)) By sheer luck memory layout of all type-related CTF structures is the same on amd64/i386/mips32/mips64. It's different on ARM though. sparc, ia64, powerpc, and powerpc64 were not tested. So in order to get file compatible with dtrace on ARM it should be compiled on ARM. Alternative solution would be to have "signatures" for every platform and ctfmerge should convert host's reperesentation of CTF structure to target's one using "signature" as template. This patch checks byte order of ELF files used for generating CTF record and makes sure that byte order of data written to resulting files is the same as target's byte order. Modified: head/cddl/contrib/opensolaris/tools/ctf/cvt/ctf.c head/cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.c head/cddl/contrib/opensolaris/tools/ctf/cvt/ctftools.h head/cddl/contrib/opensolaris/tools/ctf/cvt/output.c Modified: head/cddl/contrib/opensolaris/tools/ctf/cvt/ctf.c ============================================================================== --- head/cddl/contrib/opensolaris/tools/ctf/cvt/ctf.c Sat Mar 24 01:02:03 2012 (r233406) +++ head/cddl/contrib/opensolaris/tools/ctf/cvt/ctf.c Sat Mar 24 01:47:33 2012 (r233407) @@ -62,6 +62,18 @@ struct ctf_buf { 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 target_requires_swap; + /*PRINTFLIKE1*/ static void parseterminate(const char *fmt, ...) @@ -140,6 +152,11 @@ write_label(void *arg1, void *arg2) ctl.ctl_label = strtab_insert(&b->ctb_strtab, le->le_name); ctl.ctl_typeidx = le->le_idx; + if (target_requires_swap) { + SWAP_32(ctl.ctl_label); + SWAP_32(ctl.ctl_typeidx); + } + ctf_buf_write(b, &ctl, sizeof (ctl)); return (1); @@ -152,6 +169,10 @@ write_objects(iidesc_t *idp, ctf_buf_t * ctf_buf_write(b, &id, sizeof (id)); + if (target_requires_swap) { + SWAP_16(id); + } + debug(3, "Wrote object %s (%d)\n", (idp ? idp->ii_name : "(null)"), id); } @@ -180,10 +201,21 @@ write_functions(iidesc_t *idp, ctf_buf_t fdata[0] = CTF_TYPE_INFO(CTF_K_FUNCTION, 1, nargs); fdata[1] = idp->ii_dtype->t_id; + + if (target_requires_swap) { + 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 (target_requires_swap) { + SWAP_16(id); + } + ctf_buf_write(b, &id, sizeof (id)); } @@ -208,11 +240,25 @@ write_sized_type_rec(ctf_buf_t *b, ctf_t 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 (target_requires_swap) { + 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 (target_requires_swap) { + 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 @@ write_unsized_type_rec(ctf_buf_t *b, ctf { ctf_stype_t *cts = (ctf_stype_t *)ctt; + if (target_requires_swap) { + 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 @@ write_type(void *arg1, void *arg2) encoding = ip->intr_fformat; data = CTF_INT_DATA(encoding, ip->intr_offset, ip->intr_nbits); + if (target_requires_swap) { + SWAP_32(data); + } ctf_buf_write(b, &data, sizeof (data)); break; @@ -312,6 +367,11 @@ write_type(void *arg1, void *arg2) 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 (target_requires_swap) { + 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 @@ write_type(void *arg1, void *arg2) offset); ctm.ctm_type = mp->ml_type->t_id; ctm.ctm_offset = mp->ml_offset; + if (target_requires_swap) { + 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 @@ write_type(void *arg1, void *arg2) CTF_OFFSET_TO_LMEMHI(mp->ml_offset); ctlm.ctlm_offsetlo = CTF_OFFSET_TO_LMEMLO(mp->ml_offset); + + if (target_requires_swap) { + 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 @@ write_type(void *arg1, void *arg2) 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 (target_requires_swap) { + SWAP_32(cte.cte_name); + SWAP_32(cte.cte_value); + } + ctf_buf_write(b, &cte, sizeof (cte)); i--; } @@ -420,6 +499,11 @@ write_type(void *arg1, void *arg2) for (i = 0; i < (int) tp->t_fndef->fn_nargs; i++) { id = tp->t_fndef->fn_args[i]->t_id; + + if (target_requires_swap) { + SWAP_16(id); + } + ctf_buf_write(b, &id, sizeof (id)); } @@ -613,6 +697,9 @@ ctf_gen(iiburst_t *iiburst, size_t *ress int i; + target_requires_swap = 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 @@ ctf_gen(iiburst_t *iiburst, size_t *ress h.cth_stroff = ctf_buf_cur(buf); h.cth_strlen = strtab_size(&buf->ctb_strtab); + if (target_requires_swap) { + SWAP_16(h.cth_preamble.ctp_magic); + SWAP_32(h.cth_parlabel); + SWAP_32(h.cth_parname); + SWAP_32(h.cth_lbloff); + SWAP_32(h.cth_objtoff); + SWAP_32(h.cth_funcoff); + SWAP_32(h.cth_typeoff); + SWAP_32(h.cth_stroff); + SWAP_32(h.cth_strlen); + } + /* * We only do compression for ctfmerge, as ctfconvert is only * supposed to be used on intermediary build objects. This is Modified: head/cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.c ============================================================================== --- head/cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.c Sat Mar 24 01:02:03 2012 (r233406) +++ head/cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.c Sat Mar 24 01:47:33 2012 (r233407) @@ -620,7 +620,7 @@ copy_ctf_data(char *srcfile, char *destf 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 @@ main(int argc, char **argv) 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); Modified: head/cddl/contrib/opensolaris/tools/ctf/cvt/ctftools.h ============================================================================== --- head/cddl/contrib/opensolaris/tools/ctf/cvt/ctftools.h Sat Mar 24 01:02:03 2012 (r233406) +++ head/cddl/contrib/opensolaris/tools/ctf/cvt/ctftools.h Sat Mar 24 01:47:33 2012 (r233407) @@ -391,6 +391,7 @@ void merge_into_master(tdata_t *, tdata_ #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); Modified: head/cddl/contrib/opensolaris/tools/ctf/cvt/output.c ============================================================================== --- head/cddl/contrib/opensolaris/tools/ctf/cvt/output.c Sat Mar 24 01:02:03 2012 (r233406) +++ head/cddl/contrib/opensolaris/tools/ctf/cvt/output.c Sat Mar 24 01:47:33 2012 (r233407) @@ -717,7 +717,7 @@ make_ctf_data(tdata_t *td, Elf *elf, con 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 @@ write_ctf(tdata_t *td, const char *curna 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 @@ write_ctf(tdata_t *td, const char *curna 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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201203240147.q2O1lXiL004482>