aboutsummaryrefslogtreecommitdiff
path: root/cddl/contrib/opensolaris/tools/ctf
diff options
context:
space:
mode:
Diffstat (limited to 'cddl/contrib/opensolaris/tools/ctf')
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/dwarf.c70
1 files changed, 65 insertions, 5 deletions
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/dwarf.c b/cddl/contrib/opensolaris/tools/ctf/cvt/dwarf.c
index c7f785eb0446..0738dd080f83 100644
--- a/cddl/contrib/opensolaris/tools/ctf/cvt/dwarf.c
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/dwarf.c
@@ -23,8 +23,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* DWARF to tdata conversion
*
@@ -1796,6 +1794,59 @@ die_resolve(dwarf_t *dw)
} while (dw->dw_nunres != 0);
}
+/*
+ * 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_getshdr(scn, &shdr);
+
+ 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);
+}
+
/*ARGSUSED*/
int
dw_read(tdata_t *td, Elf *elf, char *filename __unused)
@@ -1820,8 +1871,12 @@ dw_read(tdata_t *td, Elf *elf, char *filename __unused)
if ((rc = dwarf_elf_init(elf, DW_DLC_READ, &dw.dw_dw,
&dw.dw_err)) == DW_DLV_NO_ENTRY) {
- errno = ENOENT;
- return (-1);
+ if (should_have_dwarf(elf)) {
+ errno = ENOENT;
+ return (-1);
+ } else {
+ return (0);
+ }
} else if (rc != DW_DLV_OK) {
if (dwarf_errno(&dw.dw_err) == DW_DLE_DEBUG_INFO_NULL) {
/*
@@ -1839,9 +1894,14 @@ dw_read(tdata_t *td, Elf *elf, char *filename __unused)
&addrsz, &nxthdr, &dw.dw_err)) != DW_DLV_OK)
terminate("rc = %d %s\n", rc, dwarf_errmsg(&dw.dw_err));
- if ((cu = die_sibling(&dw, NULL)) == NULL)
+ if ((cu = die_sibling(&dw, NULL)) == NULL ||
+ (((child = die_child(&dw, cu)) == NULL) &&
+ should_have_dwarf(elf))) {
terminate("file does not contain dwarf type data "
"(try compiling with -g)\n");
+ } else if (child == NULL) {
+ return (0);
+ }
dw.dw_maxoff = nxthdr - 1;