Skip site navigation (1)Skip section navigation (2)
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>