Add support for kvm.h in RTEMS terms

The implementation uses an array of strings and variable names. The
names are weak symbolic references to the items we have seen calls
to kvm services with.
This commit is contained in:
Joel Sherrill 2012-10-24 15:38:22 -05:00
parent 5e93bed562
commit 34e1fb2c5a
5 changed files with 236 additions and 1 deletions

1
.gitignore vendored
View File

@ -66,3 +66,4 @@ rtemsbsd/v850/include/freebsd/machine/pci_cfgreg.h
freebsd-userspace/lib/libc/net/nslexer.c
freebsd-userspace/lib/libc/net/nsparser.c
freebsd-userspace/lib/libc/net/nsparser.i
freebsd-userspace/rtems/rtems-kvm-symbols.c

View File

@ -163,6 +163,8 @@ C_FILES += lib/libipsec/policy_parse.c
# RTEMS Specific Files
# C_FILES += rtems/rtems-net-setup.c
C_FILES += rtems/syslog.c
C_FILES += rtems/rtems-kvm.c
C_FILES += rtems/rtems-kvm-symbols.c
C_FILES += rtems/rtems-syslog-initialize.c
C_FILES += rtems/rtems-getprogname.c
C_FILES += rtems/rtems-uthread_main_np.c
@ -270,7 +272,8 @@ NETSTAT = commands/usr.bin/netstat/netstat.rel
COMMAND_RELS = $(NETSTAT) $(IFCONFIG)
GEN_FILES = include/rpc/rpcb_prot.h
GEN_FILES = rtems/rtems-kvm-symbols.c
GEN_FILES += include/rpc/rpcb_prot.h
GEN_FILES += commands/sbin/route/keywords.h
# lib/libc/net
GEN_FILES += lib/libc/net/nslexer.c
@ -295,6 +298,9 @@ $(IFCONFIG): $(IFCONFIG_C_O_FILES)
$(NETSTAT): $(NETSTAT_C_O_FILES)
$(LD) -r -o $@ $^
rtems/rtems-kvm-symbols.c: rtems/generate_kvm_symbols
./rtems/generate_kvm_symbols >rtems/rtems-kvm-symbols.c
include/rpc/rpcb_prot.h: include/rpc/rpcb_prot.x
rm -f include/rpc/rpcb_prot.h
rpcgen -h -o include/rpc/rpcb_prot.h include/rpc/rpcb_prot.x

View File

@ -0,0 +1,108 @@
#! /bin/sh
#
# This file generates the symbol table for the kvm subsystem. The
# table is limited to the ones we believe are needed.
symbols=""
while read sym
do
symbols="${symbols} ${sym}"
done <<EOF
_ifnet
_rtstat
_rt_tables
_mrtstat
_mfchashtbl
_viftable
_ipxpcb_list
_ipxstat
_spx_istat
_ddpstat
_ddpcb
_ngsocklist
_ip6stat
_icmp6stat
_ipsec4stat
_ipsec6stat
_pim6stat
_mrt6stat
_mf6ctable
_mif6table
_pfkeystat
_mbstat
_mbtypes
_nmbclusters
_nmbufs
_mbuf_hiwm
_clust_hiwm
_smp_cpus
_pagesize
_mb_statpcpu
_rttrash
_mbuf_lowm
_clust_lowm
_carpstats
_pfsyncstats
_ahstat
_espstat
_ipcompstat
_tcpstat
_udpstat
_ipstat
_icmpstat
_igmpstat
_pimstat
_tcbinfo
_udbinfo
_divcbinfo
_ripcbinfo
_unp_count
_unp_gencnt
_unp_dhead
_unp_shead
_rip6stat
_sctpstat
_mfctablesize
_arpstat
EOF
cat <<EOF
/**** THIS FILE IS GENERATED BY A SCRIPT ****/
/*
* This file contains the known list of symbols for the kvm subsystem.
*/
#include "kvm_private.h"
#include "stdio.h"
/*
* The following is the known list of symbols that may be passed
* to the kvm family of calls.
*/
EOF
for sym in ${symbols}
do
no_underscore=`echo $sym | sed -e 's/^_//' `
echo "extern int ${no_underscore} __attribute((weak));"
done
cat <<EOF
/*
* The following is the known list of symbols that may be passed
* to the kvm family of calls.
*/
kvm_symval_t rtems_kvm_symbols[] = {
EOF
for sym in ${symbols}
do
no_underscore=`echo $sym | sed -e 's/^_//' `
echo " { \"${sym}\", &${no_underscore} },"
done
cat <<EOF
{ "", NULL }
};
EOF

View File

@ -0,0 +1,13 @@
#ifndef __KVM_PRIVATE_h
#define __KVM_PRIVATE_h
#include <stdint.h>
typedef struct {
const char *symbol;
uintptr_t value;
} kvm_symval_t;
kvm_symval_t rtems_kvm_symbols[];
#endif

View File

@ -0,0 +1,107 @@
#include "port_before.h"
#include <sys/cdefs.h>
#include <kvm.h>
#include <nlist.h>
#include <assert.h>
#include "kvm_private.h"
char *
kvm_geterr(
kvm_t *kd
)
{
return "KVM error";
// return (kd->errbuf);
}
kvm_t *
kvm_openfiles(
const char *uf,
const char *mf,
const char *sf __unused,
int flag,
char *errout
)
{
return (kvm_t *)kvm_openfiles;
}
int
kvm_nlist(kvm_t *kd, struct nlist *nl)
{
struct nlist *p;
int nvalid;
int error;
kvm_symval_t *kvm;
assert( kd != NULL );
assert( nl != NULL );
nvalid = 0;
again:
for (p = nl; p->n_name && p->n_name[0]; ++p) {
if (p->n_type != N_UNDF)
continue;
if (p->n_name[0] != '_')
continue;
for (kvm=rtems_kvm_symbols; kvm->symbol[0]; ++kvm) {
if (!strcmp(p->n_name, kvm->symbol)) {
p->n_type = N_TEXT;
p->n_other = 0;
p->n_desc = 0;
p->n_value = kvm->value;
if (kvm->value) {
++nvalid;
printf("kvm: %s = %p\n", p->n_name, (void*)kvm->value);
}
break;
}
}
if (! kvm->symbol[0]) {
printf("kvm: did not know about %s\n", p->n_name);
}
}
error = ((p - nl) - nvalid);
return (error);
}
ssize_t
kvm_read(kd, kva, buf, len)
kvm_t *kd;
u_long kva;
void *buf;
size_t len;
{
assert( kd != NULL );
assert( buf != NULL );
if ( kva == 0 )
return (-1);
#ifdef __rtems__
// printf( "%d from %p to %p\n", len, (void*)kva, buf);
#endif
#if 0
/*
* Use a byte-wide copy to avoid alignment issues.
*/
{
unsigned char *s;
unsigned char *d;
size_t c;
s = (void *)kva;
d = buf;
for (c=0; c<len ; c++)
*d++ = *s++;
}
#else
memcpy(buf, (void *)kva, len);
#endif
return len;
}