1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-10-19 02:29:40 +00:00

Handle ELF symbols better. This fixes "vmstat -i" for the case

where "/var/db/kvm_kernel.db" exists.

Note, kvm_mkdb tries to be clever, and skips rebuilding the database
if it thinks it's already up to date.  To see the effects of this
fix, you may need to manually delete "/var/db/kvm_kernel.db" and
then run "kvm_mkdb".
This commit is contained in:
John Polstra 1998-10-28 06:39:41 +00:00
parent 76a2643efb
commit a150a878d5
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=40689

View File

@ -29,6 +29,8 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef lint
@ -36,7 +38,7 @@
static char sccsid[] = "@(#)from: nlist.c 8.1 (Berkeley) 6/6/93";
#endif
static const char rcsid[] =
"$Id: nlist.c,v 1.8 1997/09/24 06:44:10 charnier Exp $";
"$Id: nlist.c,v 1.9 1998/08/17 08:46:46 dfr Exp $";
#endif /* not lint */
#include <sys/param.h>
@ -180,14 +182,16 @@ __aout_knlist(name, db)
#ifdef DO_ELF
static void elf_sym_to_nlist __P((struct nlist *, Elf_Sym *, Elf_Shdr *, int));
int
__elf_knlist(name, db)
char *name;
DB *db;
{
register caddr_t strtab;
register off_t symstroff, symoff;
register u_long symsize;
register off_t symstroff = 0, symoff = 0;
register u_long symsize = 0;
register u_long kernvma, kernoffs;
register int i;
Elf_Sym *sbuf;
@ -241,6 +245,8 @@ __elf_knlist(name, db)
kernoffs = sh[i].sh_offset;
}
}
if (symsize == 0)
badfmt("stripped");
strtab = (char *)&filep[symstroff];
@ -253,24 +259,7 @@ __elf_knlist(name, db)
sbuf = (Elf_Sym *)&filep[symoff + i * sizeof(*sbuf)];
if (!sbuf->st_name)
continue;
nbuf.n_value = sbuf->st_value;
/*XXX type conversion is pretty rude... */
switch (ELF_ST_TYPE(sbuf->st_info)) {
case STT_NOTYPE:
nbuf.n_type = N_UNDF;
break;
case STT_FUNC:
nbuf.n_type = N_TEXT;
break;
case STT_OBJECT:
nbuf.n_type = N_DATA;
break;
}
if (ELF_ST_BIND(sbuf->st_info) == STB_LOCAL)
nbuf.n_type = N_EXT;
elf_sym_to_nlist(&nbuf, sbuf, sh, eh->e_shnum);
key.data = (u_char *)(strtab + sbuf->st_name);
key.size = strlen((char *)key.data);
if (db->put(db, &key, &data, 0))
@ -311,6 +300,46 @@ __elf_knlist(name, db)
(void)close(fd);
return(0);
}
/*
* Convert an Elf_Sym into an nlist structure. This fills in only the
* n_value and n_type members.
*/
static void
elf_sym_to_nlist(nl, s, shdr, shnum)
struct nlist *nl;
Elf_Sym *s;
Elf_Shdr *shdr;
int shnum;
{
nl->n_value = s->st_value;
switch (s->st_shndx) {
case SHN_UNDEF:
case SHN_COMMON:
nl->n_type = N_UNDF;
break;
case SHN_ABS:
nl->n_type = ELF_ST_TYPE(s->st_info) == STT_FILE ?
N_FN : N_ABS;
break;
default:
if (s->st_shndx >= shnum)
nl->n_type = N_UNDF;
else {
Elf_Shdr *sh = shdr + s->st_shndx;
nl->n_type = sh->sh_type == SHT_PROGBITS ?
(sh->sh_flags & SHF_WRITE ? N_DATA : N_TEXT) :
(sh->sh_type == SHT_NOBITS ? N_BSS : N_UNDF);
}
break;
}
if (ELF_ST_BIND(s->st_info) == STB_GLOBAL ||
ELF_ST_BIND(s->st_info) == STB_WEAK)
nl->n_type |= N_EXT;
}
#endif /* DO_ELF */
static struct knlist_handlers {