2978 ctfconvert still needs to ignore legitimately dataless files on SPARC
authorRichard Lowe <richlowe@richlowe.net>
Mon, 09 Jul 2012 21:10:26 +0100
changeset 13754 7231b684c18b
parent 13753 2aba784c276b
child 13755 80fe82480d1e
2978 ctfconvert still needs to ignore legitimately dataless files on SPARC Reviewed by: Keith Wesolowski <[email protected]> Reviewed by: Jason King <[email protected]> Approved by: Garrett D'Amore <[email protected]>
usr/src/tools/ctf/cvt/dwarf.c
--- a/usr/src/tools/ctf/cvt/dwarf.c	Thu Jul 19 04:58:27 2012 -0700
+++ b/usr/src/tools/ctf/cvt/dwarf.c	Mon Jul 09 21:10:26 2012 +0100
@@ -1839,21 +1839,53 @@
 }
 
 /*
- * Any object containing at least one allocatable section of non-0 size is
- * taken to be a file which should contain DWARF type information
+ * Any object containing a function or object symbol at any scope should also
+ * contain DWARF data.
  */
 static boolean_t
 should_have_dwarf(Elf *elf)
 {
 	Elf_Scn *scn = NULL;
+	Elf_Data *data = NULL;
+	GElf_Shdr shdr;
+	GElf_Sym sym;
+	uint32_t symdx = 0;
+	size_t nsyms = 0;
+	boolean_t found = B_FALSE;
 
 	while ((scn = elf_nextscn(elf, scn)) != NULL) {
-		GElf_Shdr shdr;
 		gelf_getshdr(scn, &shdr);
 
-		if ((shdr.sh_flags & SHF_ALLOC) &&
-		    (shdr.sh_size != 0))
-			return (B_TRUE);
+		if (shdr.sh_type == SHT_SYMTAB) {
+			found = B_TRUE;
+			break;
+		}
+	}
+
+	if (!found)
+		terminate("cannot convert stripped objects\n");
+
+	data = elf_getdata(scn, NULL);
+	nsyms = shdr.sh_size / shdr.sh_entsize;
+
+	for (symdx = 0; symdx < nsyms; symdx++) {
+		gelf_getsym(data, symdx, &sym);
+
+		if ((GELF_ST_TYPE(sym.st_info) == STT_FUNC) ||
+		    (GELF_ST_TYPE(sym.st_info) == STT_TLS) ||
+		    (GELF_ST_TYPE(sym.st_info) == STT_OBJECT)) {
+			char *name;
+
+			name = elf_strptr(elf, shdr.sh_link, sym.st_name);
+
+			/* Studio emits these local symbols regardless */
+			if ((strcmp(name, "Bbss.bss") != 0) &&
+			    (strcmp(name, "Ttbss.bss") != 0) &&
+			    (strcmp(name, "Ddata.data") != 0) &&
+			    (strcmp(name, "Ttdata.data") != 0) &&
+			    (strcmp(name, "Drodata.rodata") != 0))
+				return (B_TRUE);
+		}
 	}
 
 	return (B_FALSE);