VirtualBox

Ignore:
Timestamp:
Jul 15, 2011 11:12:48 AM (13 years ago)
Author:
vboxsync
Message:

Runtime/r0drv/solaris/vbi: CTF support for probing offsets into kernel structures.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r0drv/solaris/vbi/i86pc/os/vbi.c

    r37949 r37976  
    5757#include <sys/machparam.h>
    5858#include <sys/utsname.h>
     59#include <sys/ctf_api.h>
    5960
    6061#include <iprt/assert.h>
     
    144145static int vbi_is_initialized = 0;
    145146
    146 /* Introduced in v6 */
    147 static int vbi_is_nevada = 0;
    148 
    149 #ifdef _LP64
    150 /* 64-bit Solaris 10 offsets */
    151 /* CPU */
    152 static int off_s10_cpu_runrun   = 232;
    153 static int off_s10_cpu_kprunrun = 233;
    154 /* kthread_t */
    155 static int off_s10_t_preempt    = 42;
    156 
    157 /* 64-bit Solaris 11 (Nevada/OpenSolaris) offsets */
    158 /* CPU */
    159 static int off_s11_cpu_runrun   = 216;
    160 static int off_s11_cpu_kprunrun = 217;
    161 /* kthread_t */
    162 static int off_s11_t_preempt    = 42;
    163 
    164 /* 64-bit Solaris 11 snv_166+ offsets (CR 7037143) */
    165 static int off_s11_t_preempt_new = 48;
    166 #else
    167 /* 32-bit Solaris 10 offsets */
    168 /* CPU */
    169 static int off_s10_cpu_runrun   = 124;
    170 static int off_s10_cpu_kprunrun = 125;
    171 /* kthread_t */
    172 static int off_s10_t_preempt    = 26;
    173 
    174 /* 32-bit Solaris 11 (Nevada/OpenSolaris) offsets */
    175 /* CPU */
    176 static int off_s11_cpu_runrun   = 112;
    177 static int off_s11_cpu_kprunrun = 113;
    178 /* kthread_t */
    179 static int off_s11_t_preempt    = 26;
    180 #endif
    181 
    182 
    183147/* Which offsets will be used */
    184148static int off_cpu_runrun       = -1;
     
    218182}
    219183#endif
     184
     185static int
     186vbi_get_ctf_member_offset(ctf_file_t *ctfp, const char *structname, const char *membername, int *offset)
     187{
     188        AssertReturn(ctfp, CTF_ERR);
     189        AssertReturn(structname, CTF_ERR);
     190        AssertReturn(membername, CTF_ERR);
     191        AssertReturn(offset, CTF_ERR);
     192
     193        ctf_id_t typeident = ctf_lookup_by_name(ctfp, structname);
     194        if (typeident != CTF_ERR)
     195        {
     196                ctf_membinfo_t memberinfo;
     197                bzero(&memberinfo, sizeof(memberinfo));
     198                if (ctf_member_info(ctfp, typeident, membername, &memberinfo) != CTF_ERR)
     199                {
     200                        *offset = (memberinfo.ctm_offset >> 3);
     201                        cmn_err(CE_NOTE, "%s::%s at %d\n", structname, membername, *offset);
     202                        return (0);
     203                }
     204                else
     205                        cmn_err(CE_NOTE, "ctf_member_info failed for struct %s member %s\n", structname, membername);
     206        }
     207        else
     208                cmn_err(CE_NOTE, "ctf_lookup_by_name failed for struct %s\n", structname);
     209
     210        return (CTF_ERR);
     211}
     212
    220213
    221214int
     
    253246                        kobj_getsymvalue("contig_free", 1);
    254247                if (p_contig_free == NULL) {
    255                         cmn_err(CE_NOTE, " contig_free() not found in kernel\n");
     248                        cmn_err(CE_NOTE, "contig_free() not found in kernel\n");
    256249                        return (EINVAL);
    257250                }
     
    272265        }
    273266
    274 
    275267        /*
    276          * Check if this is S10 or Nevada
     268         * CTF probing for fluid, private members.
    277269         */
    278         if (!strncmp(utsname.release, "5.11", sizeof("5.11") - 1)) {
    279                 /* Nevada detected... */
    280                 vbi_is_nevada = 1;
    281 
    282                 off_cpu_runrun = off_s11_cpu_runrun;
    283                 off_cpu_kprunrun = off_s11_cpu_kprunrun;
    284                 off_t_preempt = off_s11_t_preempt;
    285 
    286 #ifdef _LP64
    287                 /* Only 64-bit kernels */
    288                 long snv_version = 0;
    289                 if (  !strncmp(utsname.version, "snv_", 4)
    290                         && strlen(utsname.version) > 4)
     270        int err = 0;
     271        modctl_t *genunix_modctl = mod_hold_by_name("genunix");
     272        if (genunix_modctl)
     273        {
     274                ctf_file_t *ctfp = ctf_modopen(genunix_modctl->mod_mp, &err);
     275                if (ctfp)
    291276                {
    292                         int err = ddi_strtol(utsname.version + 4, NULL /* endptr */, 0, &snv_version);
    293                         if (!err)
    294                         {
    295                                 if (snv_version >= 166)
    296                                         off_t_preempt = off_s11_t_preempt_new;
    297                                 cmn_err(CE_NOTE, "Detected S11 version %ld: Preemption offset=%d\n", snv_version, off_t_preempt);
    298                         }
    299                         else
    300                                 snv_version = 0;
     277                        do {
     278                                err = vbi_get_ctf_member_offset(ctfp, "kthread_t", "t_preempt", &off_t_preempt); AssertBreak(!err);
     279                                err = vbi_get_ctf_member_offset(ctfp, "cpu_t", "cpu_runrun", &off_cpu_runrun); AssertBreak(!err);
     280                                err = vbi_get_ctf_member_offset(ctfp, "cpu_t", "cpu_kprunrun", &off_cpu_kprunrun); AssertBreak(!err);
     281                        } while (0);
    301282                }
    302283
    303                 if (snv_version == 0)
    304                 {
    305                         cmn_err(CE_NOTE, "WARNING(2)!! Cannot determine version. Assuming pre snv_166, name=%s Preemption offset=%ld may be busted!\n",
    306                                 utsname.version, off_t_preempt);
    307                 }
    308 #endif
    309         } else {
    310                 /* Solaris 10 detected... */
    311                 vbi_is_nevada = 0;
    312 
    313                 off_cpu_runrun = off_s10_cpu_runrun;
    314                 off_cpu_kprunrun = off_s10_cpu_kprunrun;
    315                 off_t_preempt = off_s10_t_preempt;
    316         }
    317 
    318         /*
    319          * Sanity checking...
    320          */
    321         /* CPU */
    322         char crr = VBI_CPU_RUNRUN;
    323         char krr = VBI_CPU_KPRUNRUN;
    324         if (   (crr < 0 || crr > 1)
    325                 || (krr < 0 || krr > 1)) {
    326                 cmn_err(CE_NOTE, ":CPU structure sanity check failed! OS version mismatch.\n");
    327                 return EINVAL;
    328         }
    329 
    330         /* Thread */
    331         char t_preempt = VBI_T_PREEMPT;
    332         if (t_preempt < 0 || t_preempt > 32) {
    333                 cmn_err(CE_NOTE, ":Thread structure sanity check failed! OS version mismatch.\n");
    334                 return EINVAL;
    335         }
     284                mod_release_mod(genunix_modctl);
     285        }
     286        else
     287        {
     288                cmn_err(CE_NOTE, "failed to open module genunix.\n");
     289                err = EINVAL;
     290        }
     291
     292        if (err)
     293                return (EINVAL);
    336294
    337295        vbi_is_initialized = 1;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette