On 1/14/2009 at 10:08 PM, Isaku Yamahata <yamahata@xxxxxxxxxxxxx> wrote:
> On Wed, Jan 14, 2009 at 09:00:38PM -0700, Bruce Rogers wrote:
>> The "change" to the format is as follows: Now the file format for a
> cross-bit configuration will be the same as would have been produced by a
> same-bitness configuration, which crash of course already handles. So crash
> should be fine with this change. In fact that was part of how I determined
> that it was working right.
>> I consider that the cross-bitness format was simply not valid as there is no
> reason for there to be a different format for the file simply because the
> host was a different bitsize than the guest (and it didn't work with crash &
> gdb-xenserver as it was).
>>
>
> Yes, I agree with you. However for FV case, e_ident[EI_DATA] is set
> according to the host configuration because XEN_DOMCTL_[sg]et_address_bits
> doesn't make sense. And there is no easy way to determine the guest OS mode.
> The following patch looks okay?
>
Right - thanks for pointing that out. The doc change looks good to me.
Bruce
> dump-core: update the documentation
>
> This patch updates the document on dump-core file format.
>
> Signed-off-by: Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
>
> diff --git a/docs/misc/dump-core-format.txt b/docs/misc/dump-core-format.txt
> --- a/docs/misc/dump-core-format.txt
> +++ b/docs/misc/dump-core-format.txt
> @@ -30,8 +30,13 @@ The elf header members are set as follow
> e_ident[EI_OSABI] = ELFOSABI_SYSV = 0
> e_type = ET_CORE = 4
> ELFCLASS64 is always used independent of architecture.
> -e_ident[EI_DATA] and e_flags are set according to the dumping system's
> -architecture. Other members are set as usual.
> +e_ident[EI_DATA] is set as follows
> + For x86 PV domain case, it is set according to the guest configuration
> + (i.e. if guest is 32bit it is set to EM_386 even when the dom0 is 64
> bit.)
> + For other domain case (x86 HVM domain case and ia64 domain case),
> + it is set according to the dumping system's architecture.
> +e_flags is set according to the dumping system's architecture.
> +Other members are set as usual.
>
> Sections
> --------
> @@ -241,3 +246,7 @@ Currently only (major, minor) = (0, 1) i
> The format version isn't bumped because analysis tools can distinguish
> it.
> - .xen_ia64_mapped_regs section was made only for ia64 PV domain.
> In case of IA64 HVM domain, this section doesn't exist.
> +- elf header e_ident[EI_DATA]
> + On x86 PV domain case, it is set according to the guest configuration.
> + I.e. 32-on-64 case, the file will be set EM_386 instead of EM_X86_64.
> + This is the same as 32-on-32 case, so there is no impact on analysis tools.
>
>
>> - Bruce
>>
>> >>> Isaku Yamahata <yamahata@xxxxxxxxxxxxx> 01/14/09 8:17 PM >>>
>> [CCed to Anderson, Oda and crash-utility ml]
>> Hi Bruce. Nice patch.
>>
>> Could you please update the documentation about its format too?
>> docs/misc/dump-core-format.txt
>> - Elf header section, and
>> - revision history at the end of the file.
>>
>> And what is the impact on the crash utility?
>>
>> thanks,
>>
>> On Wed, Jan 14, 2009 at 04:47:41PM -0700, Bruce Rogers wrote:
>> > This patch allows core-dumping to work on a cross-bit host/guest
> configuration, whereas previously that was not supported. It supports both
> PV and FV guests. The core file format generated by the host, needs to match
> that of the guest, so an alignment issue is addressed, along with the p2m
> frame list handling being done according to the guest size.
>> >
>> > Signed-off-by: Bruce Rogers <brogers@xxxxxxxxxx>
>> >
>>
>> > diff -r 77476eeb8c42 tools/libxc/xc_core.c
>> > --- a/tools/libxc/xc_core.c Wed Jan 14 11:39:01 2009 +0000
>> > +++ b/tools/libxc/xc_core.c Wed Jan 14 16:40:17 2009 -0700
>> > @@ -57,9 +57,6 @@
>> >
>> > /* number of pages to write at a time */
>> > #define DUMP_INCREMENT (4 * 1024)
>> > -
>> > -/* Don't yet support cross-address-size core dump */
>> > -#define guest_width (sizeof (unsigned long))
>> >
>> > /* string table */
>> > struct xc_core_strtab {
>> > @@ -240,7 +237,7 @@ xc_core_ehdr_init(Elf64_Ehdr *ehdr)
>> > ehdr->e_ident[EI_ABIVERSION] = EV_CURRENT;
>> >
>> > ehdr->e_type = ET_CORE;
>> > - ehdr->e_machine = ELF_ARCH_MACHINE;
>> > + /* e_machine will be filled in later */
>> > ehdr->e_version = EV_CURRENT;
>> > ehdr->e_entry = 0;
>> > ehdr->e_phoff = 0;
>> > @@ -359,7 +356,8 @@ elfnote_dump_core_header(
>> > }
>> >
>> > static int
>> > -elfnote_dump_xen_version(void *args, dumpcore_rtn_t dump_rtn, int
> xc_handle)
>> > +elfnote_dump_xen_version(void *args, dumpcore_rtn_t dump_rtn, int
> xc_handle,
>> > + unsigned int guest_width)
>> > {
>> > int sts;
>> > struct elfnote elfnote;
>> > @@ -371,6 +369,12 @@ elfnote_dump_xen_version(void *args, dum
>> > elfnote.descsz = sizeof(xen_version);
>> > elfnote.type = XEN_ELFNOTE_DUMPCORE_XEN_VERSION;
>> > elfnote_fill_xen_version(xc_handle, &xen_version);
>> > + if (guest_width < sizeof(unsigned long))
>> > + {
>> > + // 32 bit elf file format differs in pagesize's alignment
>> > + char *p = (char *)&xen_version.pagesize;
>> > + memmove(p - 4, p, sizeof(xen_version.pagesize));
>> > + }
>> > sts = dump_rtn(args, (char*)&elfnote, sizeof(elfnote));
>> > if ( sts != 0 )
>> > return sts;
>> > @@ -396,6 +400,24 @@ elfnote_dump_format_version(void *args,
>> > return dump_rtn(args, (char*)&format_version, sizeof(format_version));
>> > }
>> >
>> > +static int
>> > +get_guest_width(int xc_handle,
>> > + uint32_t domid,
>> > + unsigned int *guest_width)
>> > +{
>> > + DECLARE_DOMCTL;
>> > +
>> > + memset(&domctl, 0, sizeof(domctl));
>> > + domctl.domain = domid;
>> > + domctl.cmd = XEN_DOMCTL_get_address_size;
>> > +
>> > + if ( do_domctl(xc_handle, &domctl) != 0 )
>> > + return 1;
>> > +
>> > + *guest_width = domctl.u.address_size.size / 8;
>> > + return 0;
>> > +}
>> > +
>> > int
>> > xc_domain_dumpcore_via_callback(int xc_handle,
>> > uint32_t domid,
>> > @@ -403,7 +425,8 @@ xc_domain_dumpcore_via_callback(int xc_h
>> > dumpcore_rtn_t dump_rtn)
>> > {
>> > xc_dominfo_t info;
>> > - shared_info_t *live_shinfo = NULL;
>> > + shared_info_any_t *live_shinfo = NULL;
>> > + unsigned int guest_width;
>> >
>> > int nr_vcpus = 0;
>> > char *dump_mem, *dump_mem_start = NULL;
>> > @@ -437,6 +460,12 @@ xc_domain_dumpcore_via_callback(int xc_h
>> > uint16_t strtab_idx;
>> > struct xc_core_section_headers *sheaders = NULL;
>> > Elf64_Shdr *shdr;
>> > +
>> > + if ( get_guest_width(xc_handle, domid, &guest_width) != 0 )
>> > + {
>> > + PERROR("Could not get address size for domain");
>> > + return sts;
>> > + }
>> >
>> > xc_core_arch_context_init(&arch_ctxt);
>> > if ( (dump_mem_start = malloc(DUMP_INCREMENT*PAGE_SIZE)) == NULL )
>> > @@ -500,7 +529,7 @@ xc_domain_dumpcore_via_callback(int xc_h
>> > goto out;
>> > }
>> >
>> > - sts = xc_core_arch_map_p2m(xc_handle, &info, live_shinfo,
>> > + sts = xc_core_arch_map_p2m(xc_handle, guest_width, &info,
> live_shinfo,
>> > &p2m, &p2m_size);
>> > if ( sts != 0 )
>> > goto out;
>> > @@ -676,6 +705,7 @@ xc_domain_dumpcore_via_callback(int xc_h
>> > /* write out elf header */
>> > ehdr.e_shnum = sheaders->num;
>> > ehdr.e_shstrndx = strtab_idx;
>> > + ehdr.e_machine = ELF_ARCH_MACHINE;
>> > sts = dump_rtn(args, (char*)&ehdr, sizeof(ehdr));
>> > if ( sts != 0 )
>> > goto out;
>> > @@ -697,7 +727,7 @@ xc_domain_dumpcore_via_callback(int xc_h
>> > goto out;
>> >
>> > /* elf note section: xen version */
>> > - sts = elfnote_dump_xen_version(args, dump_rtn, xc_handle);
>> > + sts = elfnote_dump_xen_version(args, dump_rtn, xc_handle,
> guest_width);
>> > if ( sts != 0 )
>> > goto out;
>> >
>> > @@ -757,9 +787,21 @@ xc_domain_dumpcore_via_callback(int xc_h
>> >
>> > if ( !auto_translated_physmap )
>> > {
>> > - gmfn = p2m[i];
>> > - if ( gmfn == INVALID_P2M_ENTRY )
>> > - continue;
>> > + if ( guest_width >= sizeof(unsigned long) )
>> > + {
>> > + if ( guest_width == sizeof(unsigned long) )
>> > + gmfn = p2m[i];
>> > + else
>> > + gmfn = ((uint64_t *)p2m)[i];
>> > + if ( gmfn == INVALID_P2M_ENTRY )
>> > + continue;
>> > + }
>> > + else
>> > + {
>> > + gmfn = ((uint32_t *)p2m)[i];
>> > + if ( gmfn == (uint32_t)INVALID_P2M_ENTRY )
>> > + continue;
>> > + }
>> >
>> > p2m_array[j].pfn = i;
>> > p2m_array[j].gmfn = gmfn;
>> > @@ -802,7 +844,7 @@ copy_done:
>> > /* When live dump-mode (-L option) is specified,
>> > * guest domain may reduce memory. pad with zero pages.
>> > */
>> > - IPRINTF("j (%ld) != nr_pages (%ld)", j , nr_pages);
>> > + IPRINTF("j (%ld) != nr_pages (%ld)", j, nr_pages);
>> > memset(dump_mem_start, 0, PAGE_SIZE);
>> > for (; j < nr_pages; j++) {
>> > sts = dump_rtn(args, dump_mem_start, PAGE_SIZE);
>> > @@ -891,7 +933,7 @@ xc_domain_dumpcore(int xc_handle,
>> > struct dump_args da;
>> > int sts;
>> >
>> > - if ( (da.fd = open(corename, O_CREAT|O_RDWR, S_IWUSR|S_IRUSR)) < 0 )
>> > + if ( (da.fd = open(corename, O_CREAT|O_RDWR|O_TRUNC,
>> > S_IWUSR|S_IRUSR))
> < 0 )
>> > {
>> > PERROR("Could not open corefile %s", corename);
>> > return -errno;
>> > diff -r 77476eeb8c42 tools/libxc/xc_core.h
>> > --- a/tools/libxc/xc_core.h Wed Jan 14 11:39:01 2009 +0000
>> > +++ b/tools/libxc/xc_core.h Wed Jan 14 16:40:17 2009 -0700
>> > @@ -136,12 +136,12 @@ struct xc_core_arch_context;
>> > struct xc_core_arch_context;
>> > int xc_core_arch_memory_map_get(int xc_handle,
>> > struct xc_core_arch_context *arch_ctxt,
>> > - xc_dominfo_t *info, shared_info_t
> *live_shinfo,
>> > + xc_dominfo_t *info, shared_info_any_t
> *live_shinfo,
>> > xc_core_memory_map_t **mapp,
>> > unsigned int *nr_entries);
>> > -int xc_core_arch_map_p2m(int xc_handle, xc_dominfo_t *info,
>> > - shared_info_t *live_shinfo, xen_pfn_t **live_p2m,
>> > - unsigned long *pfnp);
>> > +int xc_core_arch_map_p2m(int xc_handle, unsigned int guest_width,
>> > + xc_dominfo_t *info, shared_info_any_t
> *live_shinfo,
>> > + xen_pfn_t **live_p2m, unsigned long *pfnp);
>> >
>> >
>> > #if defined (__i386__) || defined (__x86_64__)
>> > diff -r 77476eeb8c42 tools/libxc/xc_core_ia64.c
>> > --- a/tools/libxc/xc_core_ia64.c Wed Jan 14 11:39:01 2009 +0000
>> > +++ b/tools/libxc/xc_core_ia64.c Wed Jan 14 16:40:17 2009 -0700
>> > @@ -235,7 +235,7 @@ old:
>> > }
>> >
>> > int
>> > -xc_core_arch_map_p2m(int xc_handle, xc_dominfo_t *info,
>> > +xc_core_arch_map_p2m(int xc_handle, unsigned int guest_width,
>> > xc_dominfo_t
> *info,
>> > shared_info_t *live_shinfo, xen_pfn_t **live_p2m,
>> > unsigned long *pfnp)
>> > {
>> > diff -r 77476eeb8c42 tools/libxc/xc_core_x86.c
>> > --- a/tools/libxc/xc_core_x86.c Wed Jan 14 11:39:01 2009 +0000
>> > +++ b/tools/libxc/xc_core_x86.c Wed Jan 14 16:40:17 2009 -0700
>> > @@ -20,9 +20,25 @@
>> >
>> > #include "xg_private.h"
>> > #include "xc_core.h"
>> > +#include "xc_e820.h"
>> >
>> > -/* Don't yet support cross-address-size core dump */
>> > -#define guest_width (sizeof (unsigned long))
>> > +#define GET_FIELD(_p, _f) ((guest_width==8) ? ((_p)->x64._f) :
>> > ((_p)->x32._f))
>> > +
>> > +#ifndef MAX
>> > +#define MAX(_a, _b) ((_a) >= (_b) ? (_a) : (_b))
>> > +#endif
>> > +
>> > +int
>> > +xc_core_arch_gpfn_may_present(struct xc_core_arch_context *arch_ctxt,
>> > + unsigned long pfn)
>> > +{
>> > + if ((pfn >= 0xa0 && pfn < 0xc0) /* VGA hole */
>> > + || (pfn >= (HVM_BELOW_4G_MMIO_START >> PAGE_SHIFT)
>> > + && pfn < (1ULL<<32) >> PAGE_SHIFT)) /* MMIO */
>> > + return 0;
>> > + return 1;
>> > +}
>> > +
>> >
>> > static int nr_gpfns(int xc_handle, domid_t domid)
>> > {
>> > @@ -37,7 +53,7 @@ xc_core_arch_auto_translated_physmap(con
>> >
>> > int
>> > xc_core_arch_memory_map_get(int xc_handle, struct xc_core_arch_context
> *unused,
>> > - xc_dominfo_t *info, shared_info_t
>> > *live_shinfo,
>> > + xc_dominfo_t *info, shared_info_any_t
> *live_shinfo,
>> > xc_core_memory_map_t **mapp,
>> > unsigned int *nr_entries)
>> > {
>> > @@ -60,17 +76,22 @@ xc_core_arch_memory_map_get(int xc_handl
>> > }
>> >
>> > int
>> > -xc_core_arch_map_p2m(int xc_handle, xc_dominfo_t *info,
>> > - shared_info_t *live_shinfo, xen_pfn_t **live_p2m,
>> > +xc_core_arch_map_p2m(int xc_handle, unsigned int guest_width,
>> > xc_dominfo_t
> *info,
>> > + shared_info_any_t *live_shinfo, xen_pfn_t **live_p2m,
>> > unsigned long *pfnp)
>> > {
>> > /* Double and single indirect references to the live P2M table */
>> > xen_pfn_t *live_p2m_frame_list_list = NULL;
>> > xen_pfn_t *live_p2m_frame_list = NULL;
>> > + /* Copies of the above. */
>> > + xen_pfn_t *p2m_frame_list_list = NULL;
>> > + xen_pfn_t *p2m_frame_list = NULL;
>> > +
>> > uint32_t dom = info->domid;
>> > unsigned long p2m_size = nr_gpfns(xc_handle, info->domid);
>> > int ret = -1;
>> > int err;
>> > + int i;
>> >
>> > if ( p2m_size < info->nr_pages )
>> > {
>> > @@ -80,7 +101,7 @@ xc_core_arch_map_p2m(int xc_handle, xc_d
>> >
>> > live_p2m_frame_list_list =
>> > xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, PROT_READ,
>> > -
>> > live_shinfo->arch.pfn_to_mfn_frame_list_list);
>> > + GET_FIELD(live_shinfo,
> arch.pfn_to_mfn_frame_list_list));
>> >
>> > if ( !live_p2m_frame_list_list )
>> > {
>> > @@ -88,9 +109,28 @@ xc_core_arch_map_p2m(int xc_handle, xc_d
>> > goto out;
>> > }
>> >
>> > + /* Get a local copy of the live_P2M_frame_list_list */
>> > + if ( !(p2m_frame_list_list = malloc(PAGE_SIZE)) )
>> > + {
>> > + ERROR("Couldn't allocate p2m_frame_list_list array");
>> > + goto out;
>> > + }
>> > + memcpy(p2m_frame_list_list, live_p2m_frame_list_list, PAGE_SIZE);
>> > +
>> > + /* Canonicalize guest's unsigned long vs ours */
>> > + if ( guest_width > sizeof(unsigned long) )
>> > + for ( i = 0; i < PAGE_SIZE/sizeof(unsigned long); i++ )
>> > + if ( i < PAGE_SIZE/guest_width )
>> > + p2m_frame_list_list[i] = ((uint64_t
> *)p2m_frame_list_list)[i];
>> > + else
>> > + p2m_frame_list_list[i] = 0;
>> > + else if ( guest_width < sizeof(unsigned long) )
>> > + for ( i = PAGE_SIZE/sizeof(unsigned long) - 1; i >= 0; i-- )
>> > + p2m_frame_list_list[i] = ((uint32_t *)p2m_frame_list_list)[i];
>> > +
>> > live_p2m_frame_list =
>> > xc_map_foreign_pages(xc_handle, dom, PROT_READ,
>> > - live_p2m_frame_list_list,
>> > + p2m_frame_list_list,
>> > P2M_FLL_ENTRIES);
>> >
>> > if ( !live_p2m_frame_list )
>> > @@ -99,8 +139,25 @@ xc_core_arch_map_p2m(int xc_handle, xc_d
>> > goto out;
>> > }
>> >
>> > + /* Get a local copy of the live_P2M_frame_list */
>> > + if ( !(p2m_frame_list = malloc(P2M_TOOLS_FL_SIZE)) )
>> > + {
>> > + ERROR("Couldn't allocate p2m_frame_list array");
>> > + goto out;
>> > + }
>> > + memset(p2m_frame_list, 0, P2M_TOOLS_FL_SIZE);
>> > + memcpy(p2m_frame_list, live_p2m_frame_list, P2M_GUEST_FL_SIZE);
>> > +
>> > + /* Canonicalize guest's unsigned long vs ours */
>> > + if ( guest_width > sizeof(unsigned long) )
>> > + for ( i = 0; i < P2M_FL_ENTRIES; i++ )
>> > + p2m_frame_list[i] = ((uint64_t *)p2m_frame_list)[i];
>> > + else if ( guest_width < sizeof(unsigned long) )
>> > + for ( i = P2M_FL_ENTRIES - 1; i >= 0; i-- )
>> > + p2m_frame_list[i] = ((uint32_t *)p2m_frame_list)[i];
>> > +
>> > *live_p2m = xc_map_foreign_pages(xc_handle, dom, PROT_READ,
>> > - live_p2m_frame_list,
>> > + p2m_frame_list,
>> > P2M_FL_ENTRIES);
>> >
>> > if ( !*live_p2m )
>> > @@ -122,6 +179,12 @@ out:
>> > if ( live_p2m_frame_list )
>> > munmap(live_p2m_frame_list, P2M_FLL_ENTRIES * PAGE_SIZE);
>> >
>> > + if ( p2m_frame_list_list )
>> > + free(p2m_frame_list_list);
>> > +
>> > + if ( p2m_frame_list )
>> > + free(p2m_frame_list);
>> > +
>> > errno = err;
>> > return ret;
>> > }
>> > diff -r 77476eeb8c42 tools/libxc/xc_core_x86.h
>> > --- a/tools/libxc/xc_core_x86.h Wed Jan 14 11:39:01 2009 +0000
>> > +++ b/tools/libxc/xc_core_x86.h Wed Jan 14 16:40:17 2009 -0700
>> > @@ -21,15 +21,8 @@
>> > #ifndef XC_CORE_X86_H
>> > #define XC_CORE_X86_H
>> >
>> > -#if defined(__i386__) || defined(__x86_64__)
>> > #define ELF_ARCH_DATA ELFDATA2LSB
>> > -#if defined (__i386__)
>> > -# define ELF_ARCH_MACHINE EM_386
>> > -#else
>> > -# define ELF_ARCH_MACHINE EM_X86_64
>> > -#endif
>> > -#endif /* __i386__ or __x86_64__ */
>> > -
>> > +#define ELF_ARCH_MACHINE (guest_width == 8 ? EM_X86_64 : EM_386)
>> >
>> > struct xc_core_arch_context {
>> > /* nothing */
>> > @@ -40,8 +33,10 @@ struct xc_core_arch_context {
>> > #define xc_core_arch_context_get(arch_ctxt, ctxt, xc_handle, domid) \
>> > (0)
>> > #define xc_core_arch_context_dump(arch_ctxt, args, dump_rtn) (0)
>> > -#define xc_core_arch_gpfn_may_present(arch_ctxt, i) (1)
>> >
>> > +int
>> > +xc_core_arch_gpfn_may_present(struct xc_core_arch_context *arch_ctxt,
>> > + unsigned long pfn);
>> > static inline int
>> > xc_core_arch_context_get_shdr(struct xc_core_arch_context *arch_ctxt,
>> > struct xc_core_section_headers *sheaders,
>>
>> > _______________________________________________
>> > Xen-devel mailing list
>> > Xen-devel@xxxxxxxxxxxxxxxxxxx
>> > http://lists.xensource.com/xen-devel
>>
>>
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|