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
|