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@lists.xensource.com
http://lists.xensource.com/xen-devel