Esempio n. 1
0
ELF_HANDLE_DECL(elf_phdr) elf_phdr_by_index(struct elf_binary *elf, unsigned index)
{
    uint64_t count = elf_uval(elf, elf->ehdr, e_phnum);
    elf_ptrval ptr;

    if ( index >= count )
        return ELF_INVALID_HANDLE(elf_phdr);

    ptr = (ELF_IMAGE_BASE(elf)
           + elf_uval(elf, elf->ehdr, e_phoff)
           + elf_uval(elf, elf->ehdr, e_phentsize) * index);
    return ELF_MAKE_HANDLE(elf_phdr, ptr);
}
Esempio n. 2
0
static char *xc_dom_guest_type(struct xc_dom_image *dom,
                               struct elf_binary *elf)
{
    uint64_t machine = elf_uval(elf, elf->ehdr, e_machine);

    if ( dom->container_type == XC_DOM_HVM_CONTAINER &&
         dom->parms.phys_entry != UNSET_ADDR32 )
        return "hvm-3.0-x86_32";

    switch ( machine )
    {
    case EM_386:
        switch ( dom->parms.pae )
        {
        case XEN_PAE_BIMODAL:
            if ( strstr(dom->xen_caps, "xen-3.0-x86_32p") )
                return "xen-3.0-x86_32p";
            return "xen-3.0-x86_32";
        case XEN_PAE_EXTCR3:
        case XEN_PAE_YES:
            return "xen-3.0-x86_32p";
        case XEN_PAE_NO:
        default:
            return "xen-3.0-x86_32";
        }
    case EM_X86_64:
        return "xen-3.0-x86_64";
    default:
        return "xen-3.0-unknown";
    }
}
static char *xc_dom_guest_type(struct xc_dom_image *dom,
                               struct elf_binary *elf)
{
    uint64_t machine = elf_uval(elf, elf->ehdr, e_machine);

    switch ( machine )
    {
    case EM_386:
        switch ( dom->parms.pae )
        {
        case 3 /* PAEKERN_bimodal */:
            if ( strstr(dom->xen_caps, "xen-3.0-x86_32p") )
                return "xen-3.0-x86_32p";
            return "xen-3.0-x86_32";
        case PAEKERN_extended_cr3:
        case PAEKERN_yes:
            return "xen-3.0-x86_32p";
        case PAEKERN_no:
        default:
            return "xen-3.0-x86_32";
        }
    case EM_X86_64:
        return "xen-3.0-x86_64";
    case EM_IA_64:
        return elf_msb(elf) ? "xen-3.0-ia64be" : "xen-3.0-ia64";
    case EM_PPC64:
        return "xen-3.0-powerpc64";
    default:
        return "xen-3.0-unknown";
    }
}
Esempio n. 4
0
static char *xc_dom_guest_type(struct xc_dom_image *dom,
                               struct elf_binary *elf)
{
    uint64_t machine = elf_uval(elf, elf->ehdr, e_machine);

    switch ( machine )
    {
    case EM_386:
        switch ( dom->parms.pae )
        {
        case XEN_PAE_BIMODAL:
            if ( strstr(dom->xen_caps, "xen-3.0-x86_32p") )
                return "xen-3.0-x86_32p";
            return "xen-3.0-x86_32";
        case XEN_PAE_EXTCR3:
        case XEN_PAE_YES:
            return "xen-3.0-x86_32p";
        case XEN_PAE_NO:
        default:
            return "xen-3.0-x86_32";
        }
    case EM_X86_64:
        return "xen-3.0-x86_64";
    default:
        return "xen-3.0-unknown";
    }
}
Esempio n. 5
0
static void print_numeric_note(const char *prefix, struct elf_binary *elf,
			       const elf_note *note)
{
	uint64_t value = elf_note_numeric(elf, note);
	int descsz = elf_uval(elf, note, descsz);

	printf("%s: %#*" PRIx64 " (%d bytes)\n",
	       prefix, 2+2*descsz, value, descsz);
}
Esempio n. 6
0
unsigned elf_shdr_count(struct elf_binary *elf)
{
    unsigned count = elf_uval(elf, elf->ehdr, e_shnum);
    uint64_t max = elf->size / sizeof(Elf32_Shdr);
    if (max > ~(unsigned)0)
        max = ~(unsigned)0; /* Xen doesn't have limits.h :-/ */
    if (count > max)
    {
        elf_mark_broken(elf, "far too many section headers");
        count = max;
    }
    return count;
}
Esempio n. 7
0
static void print_l1_mfn_valid_note(const char *prefix, struct elf_binary *elf,
				    const elf_note *note)
{
	int descsz = elf_uval(elf, note, descsz);
	const uint32_t *desc32 = elf_note_desc(elf, note);
	const uint64_t *desc64 = elf_note_desc(elf, note);

	/* XXX should be able to cope with a list of values. */
	switch ( descsz / 2 )
	{
	case 8:
		printf("%s: mask=%#"PRIx64" value=%#"PRIx64"\n", prefix,
		       desc64[0], desc64[1]);
		break;
	case 4:
		printf("%s: mask=%#"PRIx32" value=%#"PRIx32"\n", prefix,
		       desc32[0],desc32[1]);
		break;
	}

}
Esempio n. 8
0
int __init construct_dom0(
    struct domain *d,
    unsigned long _image_start, unsigned long image_len, 
    unsigned long _initrd_start, unsigned long initrd_len,
    char *cmdline)
{
    int i, rc, compatible, compat32, order, machine;
    struct cpu_user_regs *regs;
    unsigned long pfn, mfn;
    unsigned long nr_pages;
    unsigned long nr_pt_pages;
    unsigned long alloc_spfn;
    unsigned long alloc_epfn;
    unsigned long count;
    struct page_info *page = NULL;
    start_info_t *si;
    struct vcpu *v = d->vcpu[0];
    unsigned long long value;
#if defined(__i386__)
    char *image_start  = (char *)_image_start;  /* use lowmem mappings */
    char *initrd_start = (char *)_initrd_start; /* use lowmem mappings */
#elif defined(__x86_64__)
    char *image_start  = __va(_image_start);
    char *initrd_start = __va(_initrd_start);
#endif
#if CONFIG_PAGING_LEVELS >= 4
    l4_pgentry_t *l4tab = NULL, *l4start = NULL;
#endif
    l3_pgentry_t *l3tab = NULL, *l3start = NULL;
    l2_pgentry_t *l2tab = NULL, *l2start = NULL;
    l1_pgentry_t *l1tab = NULL, *l1start = NULL;

    /*
     * This fully describes the memory layout of the initial domain. All 
     * *_start address are page-aligned, except v_start (and v_end) which are 
     * superpage-aligned.
     */
    struct elf_binary elf;
    struct elf_dom_parms parms;
    unsigned long vkern_start;
    unsigned long vkern_end;
    unsigned long vinitrd_start;
    unsigned long vinitrd_end;
    unsigned long vphysmap_start;
    unsigned long vphysmap_end;
    unsigned long vstartinfo_start;
    unsigned long vstartinfo_end;
    unsigned long vstack_start;
    unsigned long vstack_end;
    unsigned long vpt_start;
    unsigned long vpt_end;
    unsigned long v_start;
    unsigned long v_end;

    /* Machine address of next candidate page-table page. */
    unsigned long mpt_alloc;

    /* Sanity! */
    BUG_ON(d->domain_id != 0);
    BUG_ON(d->vcpu[0] == NULL);
    BUG_ON(v->is_initialised);

    printk("*** LOADING DOMAIN 0 ***\n");

    d->max_pages = ~0U;

    nr_pages = compute_dom0_nr_pages();

    if ( (rc = elf_init(&elf, image_start, image_len)) != 0 )
        return rc;
#ifdef VERBOSE
    elf_set_verbose(&elf);
#endif
    elf_parse_binary(&elf);
    if ( (rc = elf_xen_parse(&elf, &parms)) != 0 )
        return rc;

    /* compatibility check */
    compatible = 0;
    compat32   = 0;
    machine = elf_uval(&elf, elf.ehdr, e_machine);
    switch (CONFIG_PAGING_LEVELS) {
    case 3: /* x86_32p */
        if (parms.pae == PAEKERN_bimodal)
            parms.pae = PAEKERN_extended_cr3;
        printk(" Xen  kernel: 32-bit, PAE, lsb\n");
        if (elf_32bit(&elf) && parms.pae && machine == EM_386)
            compatible = 1;
        break;
    case 4: /* x86_64 */
        printk(" Xen  kernel: 64-bit, lsb, compat32\n");
        if (elf_32bit(&elf) && parms.pae == PAEKERN_bimodal)
            parms.pae = PAEKERN_extended_cr3;
        if (elf_32bit(&elf) && parms.pae && machine == EM_386)
        {
            compat32 = 1;
            compatible = 1;
        }
        if (elf_64bit(&elf) && machine == EM_X86_64)
            compatible = 1;
        break;
    }
    printk(" Dom0 kernel: %s%s, %s, paddr 0x%" PRIx64 " -> 0x%" PRIx64 "\n",
           elf_64bit(&elf) ? "64-bit" : "32-bit",
           parms.pae       ? ", PAE"  : "",
           elf_msb(&elf)   ? "msb"    : "lsb",
           elf.pstart, elf.pend);
    if ( elf.bsd_symtab_pstart )
        printk(" Dom0 symbol map 0x%" PRIx64 " -> 0x%" PRIx64 "\n",
               elf.bsd_symtab_pstart, elf.bsd_symtab_pend);

    if ( !compatible )
    {
        printk("Mismatch between Xen and DOM0 kernel\n");
        return -EINVAL;
    }

#if defined(__x86_64__)
    if ( compat32 )
    {
        l1_pgentry_t gdt_l1e;

        d->arch.is_32bit_pv = d->arch.has_32bit_shinfo = 1;
        v->vcpu_info = (void *)&d->shared_info->compat.vcpu_info[0];

        if ( nr_pages != (unsigned int)nr_pages )
            nr_pages = UINT_MAX;

        /*
         * Map compatibility Xen segments into every VCPU's GDT. See
         * arch_domain_create() for further comments.
         */
        gdt_l1e = l1e_from_page(virt_to_page(compat_gdt_table),
                                PAGE_HYPERVISOR);
        for ( i = 0; i < MAX_VIRT_CPUS; i++ )
            d->arch.mm_perdomain_pt[((i << GDT_LDT_VCPU_SHIFT) +
                                     FIRST_RESERVED_GDT_PAGE)] = gdt_l1e;
        flush_tlb_one_local(GDT_LDT_VIRT_START + FIRST_RESERVED_GDT_BYTE);
    }
#endif

    if ( parms.pae == PAEKERN_extended_cr3 )
            set_bit(VMASST_TYPE_pae_extended_cr3, &d->vm_assist);

    if ( (parms.virt_hv_start_low != UNSET_ADDR) && elf_32bit(&elf) )
    {
        unsigned long mask = (1UL << L2_PAGETABLE_SHIFT) - 1;
        value = (parms.virt_hv_start_low + mask) & ~mask;
        BUG_ON(!is_pv_32bit_domain(d));
#if defined(__i386__)
        if ( value > HYPERVISOR_VIRT_START )
            panic("Domain 0 expects too high a hypervisor start address.\n");
#else
        if ( value > __HYPERVISOR_COMPAT_VIRT_START )
            panic("Domain 0 expects too high a hypervisor start address.\n");
        HYPERVISOR_COMPAT_VIRT_START(d) =
            max_t(unsigned int, m2p_compat_vstart, value);
#endif
    }
Esempio n. 9
0
unsigned elf_phdr_count(struct elf_binary *elf)
{
    return elf_uval(elf, elf->ehdr, e_phnum);
}
Esempio n. 10
0
int __init construct_dom0(
    struct domain *d,
    const module_t *image, unsigned long image_headroom,
    module_t *initrd,
    void *(*bootstrap_map)(const module_t *),
    char *cmdline)
{
    int i, cpu, rc, compatible, compat32, order, machine;
    struct cpu_user_regs *regs;
    unsigned long pfn, mfn;
    unsigned long nr_pages;
    unsigned long nr_pt_pages;
    unsigned long alloc_spfn;
    unsigned long alloc_epfn;
    unsigned long initrd_pfn = -1, initrd_mfn = 0;
    unsigned long count;
    struct page_info *page = NULL;
    start_info_t *si;
    struct vcpu *v = d->vcpu[0];
    unsigned long long value;
    char *image_base = bootstrap_map(image);
    unsigned long image_len = image->mod_end;
    char *image_start = image_base + image_headroom;
    unsigned long initrd_len = initrd ? initrd->mod_end : 0;
#if CONFIG_PAGING_LEVELS < 4
    module_t mpt;
    void *mpt_ptr;
#else
    l4_pgentry_t *l4tab = NULL, *l4start = NULL;
#endif
    l3_pgentry_t *l3tab = NULL, *l3start = NULL;
    l2_pgentry_t *l2tab = NULL, *l2start = NULL;
    l1_pgentry_t *l1tab = NULL, *l1start = NULL;

    /*
     * This fully describes the memory layout of the initial domain. All 
     * *_start address are page-aligned, except v_start (and v_end) which are 
     * superpage-aligned.
     */
    struct elf_binary elf;
    struct elf_dom_parms parms;
    unsigned long vkern_start;
    unsigned long vkern_end;
    unsigned long vinitrd_start;
    unsigned long vinitrd_end;
    unsigned long vphysmap_start;
    unsigned long vphysmap_end;
    unsigned long vstartinfo_start;
    unsigned long vstartinfo_end;
    unsigned long vstack_start;
    unsigned long vstack_end;
    unsigned long vpt_start;
    unsigned long vpt_end;
    unsigned long v_start;
    unsigned long v_end;

    /* Machine address of next candidate page-table page. */
    paddr_t mpt_alloc;

    /* Sanity! */
    BUG_ON(d->domain_id != 0);
    BUG_ON(d->vcpu[0] == NULL);
    BUG_ON(v->is_initialised);

    printk("*** LOADING DOMAIN 0 ***\n");

    d->max_pages = ~0U;

    if ( (rc = bzimage_parse(image_base, &image_start, &image_len)) != 0 )
        return rc;

    if ( (rc = elf_init(&elf, image_start, image_len)) != 0 )
        return rc;
#ifdef VERBOSE
    elf_set_verbose(&elf);
#endif
    elf_parse_binary(&elf);
    if ( (rc = elf_xen_parse(&elf, &parms)) != 0 )
        return rc;

    /* compatibility check */
    compatible = compat32 = 0;
    machine = elf_uval(&elf, elf.ehdr, e_machine);
    switch (CONFIG_PAGING_LEVELS) {
    case 3: /* x86_32p */
        if (parms.pae == PAEKERN_bimodal)
            parms.pae = PAEKERN_extended_cr3;
        printk(" Xen  kernel: 32-bit, PAE, lsb\n");
        if (elf_32bit(&elf) && parms.pae && machine == EM_386)
            compatible = 1;
        break;
    case 4: /* x86_64 */
        printk(" Xen  kernel: 64-bit, lsb, compat32\n");
        if (elf_32bit(&elf) && parms.pae == PAEKERN_bimodal)
            parms.pae = PAEKERN_extended_cr3;
        if (elf_32bit(&elf) && parms.pae && machine == EM_386)
        {
            compat32 = 1;
            compatible = 1;
        }
        if (elf_64bit(&elf) && machine == EM_X86_64)
            compatible = 1;
        break;
    }
    printk(" Dom0 kernel: %s%s, %s, paddr 0x%" PRIx64 " -> 0x%" PRIx64 "\n",
           elf_64bit(&elf) ? "64-bit" : "32-bit",
           parms.pae       ? ", PAE"  : "",
           elf_msb(&elf)   ? "msb"    : "lsb",
           elf.pstart, elf.pend);
    if ( elf.bsd_symtab_pstart )
        printk(" Dom0 symbol map 0x%" PRIx64 " -> 0x%" PRIx64 "\n",
               elf.bsd_symtab_pstart, elf.bsd_symtab_pend);

    if ( !compatible )
    {
        printk("Mismatch between Xen and DOM0 kernel\n");
        return -EINVAL;
    }

    if ( parms.elf_notes[XEN_ELFNOTE_SUPPORTED_FEATURES].type != XEN_ENT_NONE &&
         !test_bit(XENFEAT_dom0, parms.f_supported) )
    {
        printk("Kernel does not support Dom0 operation\n");
        return -EINVAL;
    }

#if defined(__x86_64__)
    if ( compat32 )
    {
        d->arch.is_32bit_pv = d->arch.has_32bit_shinfo = 1;
        v->vcpu_info = (void *)&d->shared_info->compat.vcpu_info[0];
        if ( setup_compat_arg_xlat(v) != 0 )
            BUG();
    }
#endif

    nr_pages = compute_dom0_nr_pages(d, &parms, initrd_len);

    if ( parms.pae == PAEKERN_extended_cr3 )
            set_bit(VMASST_TYPE_pae_extended_cr3, &d->vm_assist);

    if ( (parms.virt_hv_start_low != UNSET_ADDR) && elf_32bit(&elf) )
    {
        unsigned long mask = (1UL << L2_PAGETABLE_SHIFT) - 1;
        value = (parms.virt_hv_start_low + mask) & ~mask;
        BUG_ON(!is_pv_32bit_domain(d));
#if defined(__i386__)
        if ( value > HYPERVISOR_VIRT_START )
            panic("Domain 0 expects too high a hypervisor start address.\n");
#else
        if ( value > __HYPERVISOR_COMPAT_VIRT_START )
            panic("Domain 0 expects too high a hypervisor start address.\n");
        HYPERVISOR_COMPAT_VIRT_START(d) =
            max_t(unsigned int, m2p_compat_vstart, value);
#endif
    }
static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
                                  struct elf_binary *elf, int load)
{
    struct elf_binary syms;
    const elf_shdr *shdr, *shdr2;
    xen_vaddr_t symtab, maxaddr;
    char *hdr;
    size_t size;
    int h, count, type, i, tables = 0;

    if ( elf_swap(elf) )
    {
        xc_dom_printf("%s: non-native byte order, bsd symtab not supported\n",
                      __FUNCTION__);
        return 0;
    }

    if ( load )
    {
        if ( !dom->bsd_symtab_start )
            return 0;
        size = dom->kernel_seg.vend - dom->bsd_symtab_start;
        hdr  = xc_dom_vaddr_to_ptr(dom, dom->bsd_symtab_start);
        *(int *)hdr = size - sizeof(int);
    }
    else
    {
        size = sizeof(int) + elf_size(elf, elf->ehdr) +
            elf_shdr_count(elf) * elf_size(elf, shdr);
        hdr = xc_dom_malloc(dom, size);
        if ( hdr == NULL )
            return 0;
        dom->bsd_symtab_start = elf_round_up(&syms, dom->kernel_seg.vend);
    }

    memcpy(hdr + sizeof(int),
           elf->image,
           elf_size(elf, elf->ehdr));
    memcpy(hdr + sizeof(int) + elf_size(elf, elf->ehdr),
           elf->image + elf_uval(elf, elf->ehdr, e_shoff),
           elf_shdr_count(elf) * elf_size(elf, shdr));
    if ( elf_64bit(elf) )
    {
        Elf64_Ehdr *ehdr = (Elf64_Ehdr *)(hdr + sizeof(int));
        ehdr->e_phoff = 0;
        ehdr->e_phentsize = 0;
        ehdr->e_phnum = 0;
        ehdr->e_shoff = elf_size(elf, elf->ehdr);
        ehdr->e_shstrndx = SHN_UNDEF;
    }
    else
    {
        Elf32_Ehdr *ehdr = (Elf32_Ehdr *)(hdr + sizeof(int));
        ehdr->e_phoff = 0;
        ehdr->e_phentsize = 0;
        ehdr->e_phnum = 0;
        ehdr->e_shoff = elf_size(elf, elf->ehdr);
        ehdr->e_shstrndx = SHN_UNDEF;
    }
    if ( elf_init(&syms, hdr + sizeof(int), size - sizeof(int)) )
        return -1;
    if ( xc_dom_logfile )
        elf_set_logfile(&syms, xc_dom_logfile, 1);

    symtab = dom->bsd_symtab_start + sizeof(int);
    maxaddr = elf_round_up(&syms, symtab + elf_size(&syms, syms.ehdr) +
                           elf_shdr_count(&syms) * elf_size(&syms, shdr));

    xc_dom_printf("%s/%s: bsd_symtab_start=%" PRIx64 ", kernel.end=0x%" PRIx64
                  " -- symtab=0x%" PRIx64 ", maxaddr=0x%" PRIx64 "\n",
                  __FUNCTION__, load ? "load" : "parse",
                  dom->bsd_symtab_start, dom->kernel_seg.vend,
                  symtab, maxaddr);

    count = elf_shdr_count(&syms);
    for ( h = 0; h < count; h++ )
    {
        shdr = elf_shdr_by_index(&syms, h);
        type = elf_uval(&syms, shdr, sh_type);
        if ( type == SHT_STRTAB )
        {
            /* Look for a strtab @i linked to symtab @h. */
            for ( i = 0; i < count; i++ )
            {
                shdr2 = elf_shdr_by_index(&syms, i);
                if ( (elf_uval(&syms, shdr2, sh_type) == SHT_SYMTAB) &&
                     (elf_uval(&syms, shdr2, sh_link) == h) )
                    break;
            }
            /* Skip symtab @h if we found no corresponding strtab @i. */
            if ( i == count )
            {
                if ( elf_64bit(&syms) )
                    *(Elf64_Off*)(&shdr->e64.sh_offset) = 0;
                else
                    *(Elf32_Off*)(&shdr->e32.sh_offset) = 0;
                continue;
            }
        }

        if ( (type == SHT_STRTAB) || (type == SHT_SYMTAB) )
        {
            /* Mangled to be based on ELF header location. */
            if ( elf_64bit(&syms) )
                *(Elf64_Off*)(&shdr->e64.sh_offset) = maxaddr - symtab;
            else
                *(Elf32_Off*)(&shdr->e32.sh_offset) = maxaddr - symtab;
            size = elf_uval(&syms, shdr, sh_size);
            maxaddr = elf_round_up(&syms, maxaddr + size);
            tables++;
            xc_dom_printf("%s: h=%d %s, size=0x%zx, maxaddr=0x%" PRIx64 "\n",
                          __FUNCTION__, h,
                          type == SHT_SYMTAB ? "symtab" : "strtab",
                          size, maxaddr);

            if ( load )
            {
                shdr2 = elf_shdr_by_index(elf, h);
                memcpy((void*)elf_section_start(&syms, shdr),
                       elf_section_start(elf, shdr2),
                       size);
            }
        }

        /* Name is NULL. */
        if ( elf_64bit(&syms) )
            *(Elf64_Half*)(&shdr->e64.sh_name) = 0;
        else
            *(Elf32_Word*)(&shdr->e32.sh_name) = 0;
    }

    if ( tables == 0 )
    {
        xc_dom_printf("%s: no symbol table present\n", __FUNCTION__);
        dom->bsd_symtab_start = 0;
        return 0;
    }
    if ( !load )
        dom->kernel_seg.vend = maxaddr;
    return 0;
}
Esempio n. 12
0
        [XEN_ELFNOTE_PADDR_OFFSET] = { "PADDR_OFFSET", 0},
        [XEN_ELFNOTE_HV_START_LOW] = { "HV_START_LOW", 0},
        [XEN_ELFNOTE_XEN_VERSION] = { "XEN_VERSION", 1},
        [XEN_ELFNOTE_GUEST_OS] = { "GUEST_OS", 1},
        [XEN_ELFNOTE_GUEST_VERSION] = { "GUEST_VERSION", 1},
        [XEN_ELFNOTE_LOADER] = { "LOADER", 1},
        [XEN_ELFNOTE_PAE_MODE] = { "PAE_MODE", 1},
        [XEN_ELFNOTE_FEATURES] = { "FEATURES", 1},
        [XEN_ELFNOTE_BSD_SYMTAB] = { "BSD_SYMTAB", 1},
        [XEN_ELFNOTE_SUSPEND_CANCEL] = { "SUSPEND_CANCEL", 0 },
    };
/* *INDENT-ON* */

    const char *str = NULL;
    uint64_t val = 0;
    int type = elf_uval(elf, note, type);

    if ( (type >= sizeof(note_desc) / sizeof(note_desc[0])) ||
         (note_desc[type].name == NULL) )
    {
        elf_msg(elf, "%s: unknown xen elf note (0x%x)\n",
                __FUNCTION__, type);
        return 0;
    }

    if ( note_desc[type].str )
    {
        str = elf_note_desc(elf, note);
        elf_msg(elf, "%s: %s = \"%s\"\n", __FUNCTION__,
                note_desc[type].name, str);
        parms->elf_notes[type].type = XEN_ENT_STR;
Esempio n. 13
0
        [XEN_ELFNOTE_GUEST_OS] = { "GUEST_OS", 1},
        [XEN_ELFNOTE_GUEST_VERSION] = { "GUEST_VERSION", 1},
        [XEN_ELFNOTE_LOADER] = { "LOADER", 1},
        [XEN_ELFNOTE_PAE_MODE] = { "PAE_MODE", 1},
        [XEN_ELFNOTE_FEATURES] = { "FEATURES", 1},
        [XEN_ELFNOTE_SUPPORTED_FEATURES] = { "SUPPORTED_FEATURES", 0},
        [XEN_ELFNOTE_BSD_SYMTAB] = { "BSD_SYMTAB", 1},
        [XEN_ELFNOTE_SUSPEND_CANCEL] = { "SUSPEND_CANCEL", 0 },
        [XEN_ELFNOTE_MOD_START_PFN] = { "MOD_START_PFN", 0 },
    };
/* *INDENT-ON* */

    const char *str = NULL;
    uint64_t val = 0;
    unsigned int i;
    unsigned type = elf_uval(elf, note, type);

    if ( (type >= sizeof(note_desc) / sizeof(note_desc[0])) ||
         (note_desc[type].name == NULL) )
    {
        elf_msg(elf, "%s: unknown xen elf note (0x%x)\n",
                __FUNCTION__, type);
        return 0;
    }

    if ( note_desc[type].str )
    {
        str = elf_strval(elf, elf_note_desc(elf, note));
        if (str == NULL)
            /* elf_strval will mark elf broken if it fails so no need to log */
            return 0;
Esempio n. 14
0
static int print_notes(struct elf_binary *elf, const elf_note *start, const elf_note *end)
{
	const elf_note *note;
	int notes_found = 0;

	for ( note = start; note < end; note = elf_note_next(elf, note) )
	{
		if (0 != strcmp(elf_note_name(elf, note), "Xen"))
			continue;

		notes_found++;

		switch(elf_uval(elf, note, type))
		{
		case XEN_ELFNOTE_INFO:
			print_string_note("INFO", elf , note);
			break;
		case XEN_ELFNOTE_ENTRY:
			print_numeric_note("ENTRY", elf , note);
			break;
		case XEN_ELFNOTE_HYPERCALL_PAGE:
			print_numeric_note("HYPERCALL_PAGE", elf , note);
			break;
		case XEN_ELFNOTE_VIRT_BASE:
			print_numeric_note("VIRT_BASE", elf , note);
			break;
		case XEN_ELFNOTE_PADDR_OFFSET:
			print_numeric_note("PADDR_OFFSET", elf , note);
			break;
		case XEN_ELFNOTE_XEN_VERSION:
			print_string_note("XEN_VERSION", elf , note);
			break;
		case XEN_ELFNOTE_GUEST_OS:
			print_string_note("GUEST_OS", elf , note);
			break;
		case XEN_ELFNOTE_GUEST_VERSION:
			print_string_note("GUEST_VERSION", elf , note);
			break;
		case XEN_ELFNOTE_LOADER:
			print_string_note("LOADER", elf , note);
			break;
		case XEN_ELFNOTE_PAE_MODE:
			print_string_note("PAE_MODE", elf , note);
			break;
		case XEN_ELFNOTE_FEATURES:
			print_string_note("FEATURES", elf , note);
			break;
		case XEN_ELFNOTE_HV_START_LOW:
			print_numeric_note("HV_START_LOW", elf , note);
			break;
		case XEN_ELFNOTE_SUSPEND_CANCEL:
			print_numeric_note("SUSPEND_CANCEL", elf, note);
			break;
		case XEN_ELFNOTE_L1_MFN_VALID:
			print_l1_mfn_valid_note("L1_MFN_VALID", elf , note);
			break;
		default:
			printf("unknown note type %#x\n",
			       (int)elf_uval(elf, note, type));
			break;
		}
	}
	return notes_found;
}
Esempio n. 15
0
int main(int argc, char **argv)
{
	const char *f;
	int fd,h,size,usize,count;
	void *image,*tmp;
	struct stat st;
	struct elf_binary elf;
	const elf_shdr *shdr;
	int notes_found = 0;

	if (argc != 2)
	{
		fprintf(stderr, "Usage: readnotes <elfimage>\n");
		return 1;
	}
	f = argv[1];

	fd = open(f, O_RDONLY);
	if (fd == -1)
	{
		fprintf(stderr, "Unable to open %s: %s\n", f, strerror(errno));
		return 1;
	}
	if (fstat(fd, &st) == -1)
	{
		fprintf(stderr, "Unable to determine size of %s: %s\n",
			f, strerror(errno));
		return 1;
	}

	image = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
	if (image == MAP_FAILED)
	{
		fprintf(stderr, "Unable to map %s: %s\n", f, strerror(errno));
		return 1;
	}
	size = st.st_size;

	usize = xc_dom_check_gzip(image, st.st_size);
	if (usize)
	{
		tmp = malloc(usize);
		xc_dom_do_gunzip(image, st.st_size, tmp, usize);
		image = tmp;
		size = usize;
	}

	if (0 != elf_init(&elf, image, size))
	{
		fprintf(stderr, "File %s is not an ELF image\n", f);
		return 1;
	}
	elf_set_logfile(&elf, stderr, 0);

	count = elf_phdr_count(&elf);
	for ( h=0; h < count; h++)
	{
		const elf_phdr *phdr;
		phdr = elf_phdr_by_index(&elf, h);
		if (elf_uval(&elf, phdr, p_type) != PT_NOTE)
			continue;

		/* Some versions of binutils do not correctly set
		 * p_offset for note segments.
		 */
		if (elf_uval(&elf, phdr, p_offset) == 0)
			continue;

		notes_found = print_notes(&elf,
					  elf_segment_start(&elf, phdr),
					  elf_segment_end(&elf, phdr));
	}

	if ( notes_found == 0 )
	{
		count = elf_shdr_count(&elf);
		for ( h=0; h < count; h++)
		{
			const elf_shdr *shdr;
			shdr = elf_shdr_by_index(&elf, h);
			if (elf_uval(&elf, shdr, sh_type) != SHT_NOTE)
				continue;
			notes_found = print_notes(&elf,
						  elf_section_start(&elf, shdr),
						  elf_section_end(&elf, shdr));
			if ( notes_found )
				fprintf(stderr, "using notes from SHT_NOTE section\n");

		}
	}

	shdr = elf_shdr_by_name(&elf, "__xen_guest");
	if (shdr)
		printf("__xen_guest: %s\n", (char*)elf_section_start(&elf, shdr));

	return 0;
}