The bootobj macro


The bootobj macro

The bootobj macro is a three-line macro and, reading it, appears to show information about a file system. Here is the macro.

Example 12-3 The bootobj macro
 Hiya...  cd /usr/kvm/lib/adb  Hiya...  cat bootobj  ./"fstype"16t16C  +/"name"16t128C  +/"flags"16t"size"16t"vp"n3X  Hiya... 

Unfortunately, unlike the utsname macro, execution of the bootobj macro starts at location " . ", which means the current location. This is an example of a macro that we must call by specifying a symbol name or a new current address where the macro would start its work. The question is: For which file system or file systems was this macro designed to display data? We'll see if we can figure that out shortly. First, let's discuss what this macro does step by step.

The first line displays "fstype" for readability, tabs out to the display position that is a multiple of 16, then displays 16 characters . Note, unlike in the utsname macro, we are using an uppercase C modifier instead of the lowercase c . The difference is that the uppercase C says to show the contents of all 128 character positions whether or not they contain printable ASCII characters. When the value stored in memory is not printable, a "control character" representation (such as ^@ for a null byte) is printed instead.

The second line advances the current address and displays 128 characters, apparently a name of some sort , judging from the fact that we print "name" before the characters.

The last macro command line will generate two lines of output. The first line will have the words "flags" , "size" , and "vp" separated by tabs. The n says to print a newline. The 3X modifier says to display the contents of three full-word addresses in hexadecimal.

By default, adb allows for 16 character positions for each full-word hexadecimal value displayed, with a maximum of four full words displayed per line, or 4X if we were speaking in terms of adb modifiers. Knowing this about adb, the macro's author has the "flags" , "size" , and "vp" identifiers similarly tabbed out, using the 16t modifier.

So, we now know what the macro does. Next , let's see if we can figure out with which kernel variables this macro was designed to be used. The first place we might look would be the namelist , which we can examine via the UNIX nm command. In this case, we will pipe the output of nm into the UNIX grep command, searching for bootobj or something similar. We are only interested in objects, such as variables and structures, instead of kernel routines and other symbols, so we use grep a second time to print out the nm OBJT matches only.

 Hiya...  nm /dev/ksyms  grep -i bootobj  grep OBJT  Hiya...  nm /dev/ksyms  grep -i boot  grep OBJT  [469]   4027923924      52OBJT LOCL 0    ABS    bootcode  [5034]  4232978432      12OBJT LOCL 0    ABS    bootparam_addr  [6815]  4027926848       4OBJT GLOB 0    ABS    path_to_inst_bootstrap  [7229]  4028089244     256OBJT GLOB 0    ABS    kern_bootargs  [7402]  4028089636       4OBJT GLOB 0    ABS    boothowto  [7482]  4027920040       4OBJT GLOB 0    ABS    bootops  [7501]  4028092332       4OBJT GLOB 0    ABS    kmacctboot  [8707]  4028112416       4OBJT GLOB 0    ABS    netboot  Hiya... 

Well, that wasn't very helpful. Next, we will dig through the /usr/include header files. It is probably safe to assume that bootobj has something to do with the booting sequence, so we will dig through the sys subdirectory as a starting point. If that fails to find what we are looking for, we can start the search at /usr/include next time.

In this example, we will use the UNIX find command to grep through all of the sys header files. If you aren't familiar with the find or grep commands, please refer to the man pages.

 Hiya...  cd /usr/include/sys  Hiya...  find . -exec grep -i bootobj {} /dev/null \;  ./bootconf.h:struct bootobj { ./bootconf.h:extern struct bootobj rootfs;  ./bootconf.h:extern struct bootobj dumpfile;  ./bootconf.h:extern struct bootobj swapfile;  Hiya... 

Note

The use of /dev/null in the grep command exec 'ed within the find command may have you wondering a bit. If only one filename is given for grep to search, we will not see the name of the file along with the matching strings. We are using /dev/null as nothing more than a second file name. Actually, any filename would have done. Try the same command with and without /dev/null specified, and you'll understand the significance of using it.


So, we have found that /usr/include/sys/bootconf.h defines a bootobj structure. We need to read this header file to learn more about this structure. Here is the portion of /usr/include/sys/bootconf.h that talks about the bootobj structure.

Example 12-4 Excerpts from /usr/include/sys/bootconf.h
 /*   * Boot configuration information   */  #define BO_MAXFSNAME    16  #define BO_MAXOBJNAME   128  struct bootobj {         char  bo_fstype[BO_MAXFSNAME];        /* vfs type name (e.g. nfs) */          char  bo_name[BO_MAXOBJNAME];         /* name of object */          int   bo_flags;                       /* flags, see below */          int   bo_size;                        /* number of blocks */          struct vnode *bo_vp;                  /* vnode of object */  };  /*   * flags   */  #define BO_VALID        0x01    /* all information in object is valid */  #define BO_BUSY         0x02    /* object is busy */  extern struct bootobj rootfs;  extern struct bootobj dumpfile;  extern struct bootobj swapfile; 

As defined here, bootobj structures consist of 16 characters reflecting a virtual file system type, 128 characters representing an object name, a full-word integer flags value, another integer showing the size in blocks, and finally, a pointer (a full-word value) to a vnode structure declared as *bo_vp . So far, this is right in line with what the bootobj macro will be displaying.

Only three structures of type bootobj are declared for use. These are dumpfile, which we have seen earlier, rootfs , and swapfile . These three variables will be in the symbol table. To confirm this, we will quickly grep through nm 's output.

 Hiya...  nm /dev/ksyms  grep rootfs  [8662]  4027916920     156OBJT GLOB 0    ABS    rootfs  Hiya...  nm /dev/ksyms  grep swapfile  [1285]  4028028788       4OBJT LOCL 0    ABS    nswapfiles  [8378]  4027917076     156OBJT GLOB 0    ABS    swapfile  Hiya...  nm /dev/ksyms  grep dumpfile  [6059]  4027917232     156OBJT GLOB 0    ABS    dumpfile  Hiya... 

Note that the sizes of rootfs , swapfile, and dumpfile are each listed as 156. This decimal value represents the size in bytes. Does it fit what we found in the bootobj structure? Absolutely!

16 chars + 128 chars + 3 full words = 16 bytes + 128 bytes + 12 bytes = 156 bytes

We are now fairly confident what the bootobj macro was designed to examine. Let's use adb to look at all three variables on a live system Remember, since the bootobj macro starts at the current address, we need to feed the macro a valid starting point.

Figure 12-2 Using the bootobj macro against three kernel variables
 #  adb -k /dev/ksyms /dev/mem  physmem 1e15  rootfs$<bootobj  rootfs:  rootfs:         fstype          ufs^@^@^@^@^@^@^@^@^@^@^@^@^@  rootfs+0x10:    name            /iommu@f,e0000000/sbus@f,e0001000/espdma@f,40000                  0/esp@f,800000/sd@3,0:a^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@                  ^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@                  ^@^@^@^@  rootfs+0x90:    flags           size            vp                  0               0               0  swapfile$<bootobj  swapfile:  swapfile:       fstype          ^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@  swapfile+0x10:  name            ^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@                  ^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@                  ^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@                  ^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@                  ^@^@^@^@^@^@^@^@  swapfile+0x90:  flags           size            vp                  0               0               0  dumpfile$<bootobj  dumpfile:  dumpfile:       fstype          ^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@  dumpfile+0x10:  name            /dev/dsk/c0t1d0s1^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@                  ^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@                  ^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@                  ^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@  dumpfile+0x90:  flags           size            vp                  0               30200           fc2d7604  $q  

To find out how these structures are initialized and later used, we would have to look at the source code.

We have learned a few new concepts by examining the bootobj macro, most importantly, how to attempt to establish what variables the macro was designed to be used with when its execution starts at the current location, " . ".



PANIC. UNIX System Crash Dump Analysis Handbook
PANIC! UNIX System Crash Dump Analysis Handbook (Bk/CD-ROM)
ISBN: 0131493868
EAN: 2147483647
Year: 1994
Pages: 289
Authors: Chris Drake

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net