PERFORCE change 127662 for review

John Birrell jb at FreeBSD.org
Wed Oct 17 22:14:32 PDT 2007


http://perforce.freebsd.org/chv.cgi?CH=127662

Change 127662 by jb at jb_freebsd1 on 2007/10/18 05:13:32

	Fix compiler warnings for WARNS=6.
	
	FreeBSD's libelf has private fields visible in the Elf_Data
	structure (unfortunately), so it can't just be copied from
	a read-only source ELF file to write to a destination
	ELF file. The individual fields need to be copied.
	
	Also, in FreeBSD's libelf, a memory buffer must be allocated
	and attached to an Elf_Data object returned by elf_getdata()
	rather than just pointing to the source buffer in another
	ELF file.
	
	The timing of when the section headers are updated is important
	too, because FreeBSD's libelf uses that stuff during calls 
	which need to determine the ELF type. Remember that in FreeBSD
	the host ELF type need not match the target ELF type.
	OpenSolaris only supports matching host and target.

Affected files ...

.. //depot/projects/dtrace/src/contrib/opensolaris/tools/ctf/cvt/output.c#9 edit

Differences ...

==== //depot/projects/dtrace/src/contrib/opensolaris/tools/ctf/cvt/output.c#9 (text) ====

@@ -79,7 +79,7 @@
 
 /*ARGSUSED1*/
 static int
-save_type_by_id(tdesc_t *tdp, tdesc_t **tdpp, void *private)
+save_type_by_id(tdesc_t *tdp, tdesc_t **tdpp __unused, void *private)
 {
 	iiburst_t *iiburst = private;
 
@@ -159,8 +159,10 @@
  * a global type description.
  */
 static int
-matching_iidesc(iidesc_t *iidesc, iidesc_match_t *match)
+matching_iidesc(void *arg1, void *arg2)
 {
+	iidesc_t *iidesc = arg1;
+	iidesc_match_t *match = arg2;
 	if (streq(iidesc->ii_name, match->iim_name) == 0)
 		return (0);
 
@@ -185,6 +187,8 @@
 			return (-1);
 		}
 		break;
+	default:
+		break;
 	}
 	return (0);
 }
@@ -194,7 +198,7 @@
 {
 	match->iim_ret = NULL;
 	iter_iidescs_by_name(td, match->iim_name,
-	    (int (*)())matching_iidesc, match);
+	    matching_iidesc, match);
 	return (match->iim_ret);
 }
 
@@ -239,10 +243,12 @@
     GElf_Sym *retsym, char **curfilep)
 {
 	char *curfile = NULL;
-	char *tmpfile;
+	char *tmpfile1 = NULL;
 	GElf_Sym tmpsym;
 	int candidate = 0;
 	int i;
+	tmpsym.st_info = 0;
+	tmpsym.st_name = 0;
 
 	if (GELF_ST_BIND(weak->st_info) != STB_WEAK)
 		return (0);
@@ -276,7 +282,7 @@
 		    (curfile == NULL || weakfile == NULL ||
 		    strcmp(curfile, weakfile) != 0)) {
 			candidate = 1;
-			tmpfile = curfile;
+			tmpfile1 = curfile;
 			tmpsym = sym;
 			continue;
 		}
@@ -287,7 +293,7 @@
 	}
 
 	if (candidate) {
-		*curfilep = tmpfile;
+		*curfilep = tmpfile1;
 		*retsym = tmpsym;
 		return (1);
 	}
@@ -496,14 +502,14 @@
 	secxlate = xmalloc(sizeof (int) * sehdr.e_shnum);
 	for (srcidx = dstidx = 0; srcidx < sehdr.e_shnum; srcidx++) {
 		Elf_Scn *scn = elf_getscn(src, srcidx);
-		GElf_Shdr shdr;
+		GElf_Shdr shdr1;
 		char *sname;
 
-		gelf_getshdr(scn, &shdr);
-		sname = elf_strptr(src, sehdr.e_shstrndx, shdr.sh_name);
+		gelf_getshdr(scn, &shdr1);
+		sname = elf_strptr(src, sehdr.e_shstrndx, shdr1.sh_name);
 		if (sname == NULL) {
 			elfterminate(srcname, "Can't find string at %u",
-			    shdr.sh_name);
+			    shdr1.sh_name);
 		}
 
 		if (strcmp(sname, CTF_ELF_SCN_NAME) == 0) {
@@ -514,7 +520,7 @@
 		    strncmp(sname, ".rel.debug", 10) == 0 ||
 		    strncmp(sname, ".rela.debug", 11) == 0)) {
 			secxlate[srcidx] = -1;
-		} else if (dynsym && shdr.sh_type == SHT_SYMTAB) {
+		} else if (dynsym && shdr1.sh_type == SHT_SYMTAB) {
 			/*
 			 * If we're building CTF against the dynsym,
 			 * we'll rip out the symtab so debuggers aren't
@@ -567,11 +573,31 @@
 			elfterminate(srcname, "Can't find string at %u",
 			    shdr.sh_name);
 		}
+
+#if !defined(sun)
+		if (gelf_update_shdr(dscn, &shdr) == 0)
+			elfterminate(dstname, "Cannot update sect %s", sname);
+#endif
+
 		if ((sdata = elf_getdata(sscn, NULL)) == NULL)
 			elfterminate(srcname, "Cannot get sect %s data", sname);
 		if ((ddata = elf_newdata(dscn)) == NULL)
 			elfterminate(dstname, "Can't make sect %s data", sname);
+#if defined(sun)
 		bcopy(sdata, ddata, sizeof (Elf_Data));
+#else
+		/*
+		 * FreeBSD's Elf_Data has private fields which the
+		 * elf_* routines manage. Simply copying the 
+		 * entire structure corrupts the data. So we need
+		 * to copy the public fields explictly.
+		 */
+		ddata->d_align = sdata->d_align;
+		ddata->d_off = sdata->d_off;
+		ddata->d_size = sdata->d_size;
+		ddata->d_type = sdata->d_type;
+		ddata->d_version = sdata->d_version;
+#endif
 
 		if (srcidx == sehdr.e_shstrndx) {
 			char seclen = strlen(CTF_ELF_SCN_NAME);
@@ -601,7 +627,8 @@
 				GElf_Sym sym;
 				short newscn;
 
-				(void) gelf_getsym(ddata, i, &sym);
+				if (gelf_getsym(ddata, i, &sym) == NULL)
+					printf("Could not get symbol %d\n",i);
 
 				if (sym.st_shndx >= SHN_LORESERVE)
 					continue;
@@ -616,6 +643,13 @@
 			}
 		}
 
+#if !defined(sun)
+		if (ddata->d_buf == NULL) {
+			ddata->d_buf = xmalloc(shdr.sh_size);
+			bcopy(sdata->d_buf, ddata->d_buf, shdr.sh_size);
+		}
+#endif
+
 		if (gelf_update_shdr(dscn, &shdr) == 0)
 			elfterminate(dstname, "Cannot update sect %s", sname);
 
@@ -651,6 +685,7 @@
 	ddata->d_buf = ctfdata;
 	ddata->d_size = ctfsize;
 	ddata->d_align = shdr.sh_addralign;
+	ddata->d_off = 0;
 
 	gelf_update_shdr(dscn, &shdr);
 


More information about the p4-projects mailing list