[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] dom0cut script patches


  • To: xen-devel@xxxxxxxxxxxxxxxxxxx
  • From: "Kazuo Moriwaka" <moriwaka@xxxxxxxxxxxxx>
  • Date: Mon, 22 May 2006 22:05:37 +0900
  • Delivery-date: Mon, 22 May 2006 06:06:02 -0700
  • Domainkey-signature: a=rsa-sha1; q=dns; c=nofws; s=beta; d=gmail.com; h=received:message-id:date:from:sender:to:subject:mime-version:content-type:content-transfer-encoding:content-disposition:x-google-sender-auth; b=MftKTtfB4GVNpSHGJjv9Dm0q0TZpXd3jHivVyNhDVD4cjAiyaMp9tidOHPLmMb9DOCjugtrCLYI9GwV5FplUOIUBf6YDzc7oXa5V2EasGj3u4EdG4mK23Pgyr2GbFTf9B38N/igFTlJKAVM+l+wOhSppgel1BhQYNNCScsKKoc4=
  • List-id: Xen developer discussion <xen-devel.lists.xensource.com>

Hi,

I fix some bugs about dom0cut script's ELF Core output.

- It was assumed that phys_to_machine mapping and pagetables have same state,
 and it is wrong.  Now the script uses pagetable information only
 to create ELF core image.
- ElfCoreReader._get_pages() returned wrong pages.
- some measures against slowness.
- some cleanups.

Index: ElfCore.py
===================================================================
RCS file: /cvsroot/xen_ia64/people/moriwaka/dom0cut/ElfCore.py,v
retrieving revision 1.9
retrieving revision 1.11
diff -u -r1.9 -r1.11
--- ElfCore.py  19 May 2006 08:49:44 -0000      1.9
+++ ElfCore.py  22 May 2006 12:49:54 -0000      1.11
@@ -4,6 +4,7 @@
and their abstruct class ElfCore
'''

+import sys
import os
import re
import CoreDump
@@ -23,9 +24,12 @@

    currentrange = [start, start + 1]
    oldoffset = start - m2v[start]
+    count = 0

    for mfn in mfns:
        if not mfn in m2v:
+            count += 1
+            print 'mfn %d cannot found in m2v mapping' % mfn, count
            continue                    # this page is not mapped
        offset = mfn - m2v[mfn]
        if oldoffset == offset and currentrange[1] == mfn:
@@ -56,7 +60,7 @@
    Elf Section header class.
    '''

-    def __init__(self, typename, offset, vaddr, maddr, filesize,
memsize, flag, align):
+    def __init__(self, typename, offset, vaddr, maddr, filesize,
memsize, flag, align, arch):
        self.typename = typename
        self.offset = offset
        self.vaddr = vaddr
@@ -65,13 +69,27 @@
        self.memsize = memsize
        self.flag = flag
        self.align = align
+        self.arch = arch

+        firstmfn = self.maddr / self.arch.page_size
+
+        self.pages = range(firstmfn, firstmfn + (self.memsize) /
self.arch.page_size)
+        self.pageoffset = dict([(mfn, (mfn - firstmfn) *
self.arch.page_size + self.offset) for mfn in self.pages])
+
    def has_maddr(self, maddr):
        return self.maddr <= maddr < self.maddr + self.memsize

    def maddr_to_offset(self, maddr):
-        return maddr - self.maddr + self.offset
+        if self.has_maddr(maddr):
+            return maddr - self.maddr + self.offset
+        else:
+            return None

+    def mfn_to_offset(self, mfn):
+        if mfn in self.pageoffset:
+            return self.pageoffset[mfn]
+        else:
+            return None

class ElfCore(CoreDump.CoreDump):
    '''
@@ -83,19 +101,18 @@
        self.pages = []
        self.file = None
        self.m2v = None
-        self.p2m = None
+        self.p2m = None                 # not used
        self.note = ''

    def mfn2offset(self, mfn):
        offset = None
-        for sec in self.sections:
-            if sec.has_maddr(self.arch.mfn_to_maddr(mfn)):
-                offset = sec.maddr_to_offset(self.arch.mfn_to_maddr(mfn))
-                break
-        if offset == None:
-            raise KeyError, '%s not found' % mfn
-        return offset

+        for sec in self.sections:
+            offset = sec.mfn_to_offset(mfn)
+            if offset != None:
+                return offset
+        raise KeyError('%s doesn\'t have mfn 0x%x' % (self.corefilename, mfn))
+
    def read_page(self, mfn):
        '''return a page data'''
        offset = self.mfn2offset(mfn)
@@ -103,9 +120,18 @@
        data = self.file.read(self.arch.page_size)
        return data

+    def write_page(self, mfn, data):
+        '''put a page into index and write data into file. header is
not updated by this.'''
+        offset = self.mfn2offset(mfn)
+        self.file.seek(offset)
+        self.file.write(data)
+
    def has_page(self, mfn):
        '''return a page is there or not'''
-        return mfn in self.pages
+        if self.m2v:
+            return mfn in self.m2v
+        else:
+            return mfn in self.pages

    def get_pagelist(self):
        '''return a list of all available mfn'''
@@ -138,20 +164,19 @@
    def set_m2v(self, m2v):
        '''set machine to virtual mapping'''
        self.m2v = m2v
-        if self.p2m:
-            self._update_sections()
-
+        self._update_sections()
+
    def set_p2m(self, p2m):
        '''set pfn2mfn for this dump image'''
-        self.p2m = p2m
-        if self.m2v:
-            self._update_sections()
-
-
+        # not used in elf
+
    def _update_sections(self):
-        '''update section info from p2m & m2v'''
+        '''update section info from m2v'''
+
+        self.pages = self.m2v.keys()
+        self.pages.sort()

-        pagemap = m2v_to_sections(self.m2v, self.p2m.values())
+        pagemap = m2v_to_sections(self.m2v, self.pages)
        dataoffset = self.arch.round_pgup(
            # ELF heaer
            libelf.sizeof_elf32_ehdr +
@@ -168,10 +193,10 @@
                                    self.arch.page_size *
s['nr_pages'], # memsize
                                    'RWE',
                                    self.arch.page_size, # page align
+                                    self.arch,
                                    )
                         for s in pagemap]

-
class ElfCoreReader(ElfCore):
    '''
    ELF core image file reader class.
@@ -199,7 +224,7 @@
            if sec.typename == 'LOAD':
                start_mfn = self.arch.maddr_to_mfn(sec.maddr)
                end_mfn = self.arch.maddr_to_mfn(sec.maddr + sec.memsize)
-                pages = pages + range(start_mfn, end_mfn+1)
+                pages = pages + range(start_mfn, end_mfn)
        return pages

    def _read_sections(self):
@@ -225,7 +250,7 @@
                memsize = int(memsize, 16)
                align = int(align, 16)

-                sections.append( ElfSection(typename, offset, vaddr,
paddr, filesize, memsize, flag, align) )
+                sections.append( ElfSection(typename, offset, vaddr,
paddr, filesize, memsize, flag, align, self.arch) )

        return sections

@@ -237,12 +262,17 @@
    def __init__(self, corefilename, arch):
        ElfCore.__init__(self, corefilename, arch)
        self.file = file(corefilename, 'r+')
-
+        self.elf = None
+        self.phdr = []
+        self._header_size = 0
+        self.note = ''

    def set_note(self, note):
+        '''set note header\'s contents by string'''
        self.note = note

    def _elf_init(self):
+        '''make elf struct, elf header, and phdr'''
        libelf.format(self.arch.elf_format)
        libelf.version(libelf.EV_CURRENT)
        self.elf = libelf.begin(self.file, libelf.ELF_C_WRITE, None)
@@ -258,6 +288,7 @@

    def _fill_note_hdr(self):
        '''make PT_NOTE header'''
+
        self.note_offset = (libelf.sizeof_elf32_ehdr +
                            (1 + len(self.sections)) *
libelf.sizeof_elf32_phdr)
        phdr = self.phdrs[0]
@@ -273,6 +304,7 @@

    def _fill_load_hdr(self):
        '''make PT_LOAD header'''
+
        for i, sec in enumerate(self.sections):
            phdr = self.phdrs[1 + i]
            phdr.p_type = libelf.PT_LOAD
@@ -286,10 +318,13 @@

    def _elf_write_notes(self):
        '''make ELF notes'''
+
        self.file.seek(self.note_offset)
        self.file.write(self.note)

    def _elf_end(self):
+        '''write elf headers.'''
+
        self.elf.update(libelf.ELF_C_WRITE)
        self._header_size = self.elf.end()

@@ -299,34 +334,30 @@
        self._elf_init()

        # make program headers
-        note = self._fill_note_hdr()
-        loads = self._fill_load_hdr()
+        self._fill_note_hdr()
+        self._fill_load_hdr()

        self._elf_write_notes()
        # write headers, set self.page_offset
-        offset = self._elf_end()
+        self._elf_end()


    def fetch_pages(self, other):
        '''copy pages from other dump'''
        count = 0
        pagebuf = {}
+        nullpage = '\0' * self.arch.page_size
+
+        for mfn in self.pages:
+            try:
+                pagebuf[mfn] = other.read_page(mfn)
+            except:
+                pagebuf[mfn] = nullpage
+                sys.stderr.write("%s doesn't have mfn 0x%x, the page
is filled with '\\0'\n" % (other.corefilename, mfn))

-        pages = self.p2m.values()
-        pages.sort()
-
-        for mfn in pages:
-            pagebuf[mfn] = other.read_page(mfn)
            count += 1
-            if count % 1024 == 0 or count == len(pages):
+            if count % 1024 == 0 or count == len(self.pages):
                for mfn in pagebuf:
                    self.write_page(mfn, pagebuf[mfn]) # write mfn
                pagebuf = {}
-
-    def write_page(self, mfn, data):
-        '''put a page into index and write data into file. header is
not updated by this.'''
-        # data on disk
-        self.file.seek(self.mfn2offset(mfn))
-        self.file.write(data)
-
-
+
Index: PageTable.py
===================================================================
RCS file: /cvsroot/xen_ia64/people/moriwaka/dom0cut/PageTable.py,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- PageTable.py        18 May 2006 13:05:36 -0000      1.3
+++ PageTable.py        22 May 2006 11:44:05 -0000      1.4
@@ -47,14 +47,14 @@
            pte = self.l1[page]
            if pte & FLAGPRESENT:
                if pte & FLAG4MB:
-                    ranges.append((page, 1024))
+                    ranges.append((page, pte & BASE_L1, 1024))
                else:
                    mfn = self.arch.maddr_to_mfn(pte)
                    l2 = self.read_l2(mfn)
                    for subpage in l2:
                        pte = l2[subpage]
                        if pte & FLAGPRESENT:
-                            ranges.append((page|subpage, 1))
+                            ranges.append((page|subpage, pte & BASE_L2, 1))
        return ranges

    def get_machine_to_virt(self):
@@ -62,10 +62,11 @@
        pages = self.get_present_virt()
        mach2virt = {}
        shift = 12
-        for base, nr in pages:
+        for base, mbase, nr in pages:
            for i in range(nr):
-                page = base + i * self.arch.page_size
-                mach2virt[self.v2m(page) >> shift] = page >> shift
+                page = (base >> shift) + i
+                mpage = (mbase >> shift) + i
+                mach2virt[mpage] = page
        return mach2virt

    def read_l1(self, mfn):


--
Kazuo Moriwaka

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.