Merge various CTF fixes from illumos

2942 CTF tools need to handle files which legitimately lack data
2978 ctfconvert still needs to ignore legitimately dataless files on SPARC

Illumos Revisions:	13745:6b3106b4250f
			13754:7231b684c18b

Reference:

https://www.illumos.org/issues/2942
https://www.illumos.org/issues/2978

MFC after:	3 weeks
This commit is contained in:
Pedro F. Giffuni 2013-08-26 22:29:42 +00:00
parent acb3b5d2fe
commit d69c286983
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=254941

View File

@ -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;