[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v9 11/27] xsplice: Implement payload loading
On 04/25/2016 04:34 PM, Konrad Rzeszutek Wilk wrote: snip +static int move_payload(struct payload *payload, struct xsplice_elf *elf) +{ + uint8_t *text_buf, *ro_buf, *rw_buf; + unsigned int i; + size_t size = 0; + unsigned int *offset; + int rc = 0; + + offset = xzalloc_array(unsigned int, elf->hdr->e_shnum); + if ( !offset ) + return -ENOMEM; + + /* Compute size of different regions. */ + for ( i = 1; i < elf->hdr->e_shnum; i++ ) + { + if ( (elf->sec[i].sec->sh_flags & (SHF_ALLOC|SHF_EXECINSTR)) == + (SHF_ALLOC|SHF_EXECINSTR) ) + calc_section(&elf->sec[i], &payload->text_size, &offset[i]); + else if ( (elf->sec[i].sec->sh_flags & SHF_ALLOC) && + !(elf->sec[i].sec->sh_flags & SHF_EXECINSTR) && + (elf->sec[i].sec->sh_flags & SHF_WRITE) ) + calc_section(&elf->sec[i], &payload->rw_size, &offset[i]); + else if ( (elf->sec[i].sec->sh_flags & SHF_ALLOC) && + !(elf->sec[i].sec->sh_flags & SHF_EXECINSTR) && + !(elf->sec[i].sec->sh_flags & SHF_WRITE) ) + calc_section(&elf->sec[i], &payload->ro_size, &offset[i]); + else if ( !elf->sec[i].sec->sh_flags || + (elf->sec[i].sec->sh_flags & SHF_EXECINSTR) || + (elf->sec[i].sec->sh_flags & SHF_MASKPROC) ) + /* Do nothing.*/; + else if ( (elf->sec[i].sec->sh_flags & SHF_ALLOC) && + (elf->sec[i].sec->sh_type == SHT_NOBITS) ) + { + dprintk(XENLOG_DEBUG, XSPLICE "%s: Not supporting %s section!\n", + elf->name, elf->sec[i].name); + rc = -EOPNOTSUPP; + goto out; + } + else /* Such as .comment. */ + dprintk(XENLOG_DEBUG, XSPLICE "%s: Ignoring %s section!\n", + elf->name, elf->sec[i].name); + } + + /* + * Total of all three regions - RX, RW, and RO. We have to have + * keep them in seperate pages so we PAGE_ALIGN the RX and RW to have + * them on seperate pages. The last one will by default fall on its + * own page. + */ + size = PAGE_ALIGN(payload->text_size) + PAGE_ALIGN(payload->rw_size) + + payload->ro_size; + + size = PFN_UP(size); /* Nr of pages. */ + text_buf = vzalloc_xen(size * PAGE_SIZE); + if ( !text_buf ) + { + dprintk(XENLOG_ERR, XSPLICE "%s: Could not allocate memory for payload!\n", + elf->name); + rc = -ENOMEM; + goto out; + } + rw_buf = text_buf + + PAGE_ALIGN(payload->text_size); ??? The rarely used unary plus operator :-) + ro_buf = rw_buf + PAGE_ALIGN(payload->rw_size); + + payload->pages = size; + payload->text_addr = text_buf; + payload->rw_addr = rw_buf; + payload->ro_addr = ro_buf; + + for ( i = 1; i < elf->hdr->e_shnum; i++ ) + { + if ( elf->sec[i].sec->sh_flags & SHF_ALLOC ) + { + uint8_t *buf; + if ( (elf->sec[i].sec->sh_flags & SHF_EXECINSTR) ) + buf = text_buf; + else if ( (elf->sec[i].sec->sh_flags & SHF_WRITE) ) + buf = rw_buf; + else + buf = ro_buf; + + elf->sec[i].load_addr = buf + offset[i]; + + /* + * Don't copy NOBITS - such as BSS. We don't memset BSS as + * arch_xsplice_alloc_payload has zeroed it out for us. + */ + if ( elf->sec[i].sec->sh_type != SHT_NOBITS ) + { + memcpy(elf->sec[i].load_addr, elf->sec[i].data, + elf->sec[i].sec->sh_size); + dprintk(XENLOG_DEBUG, XSPLICE "%s: Loaded %s at %p\n", + elf->name, elf->sec[i].name, elf->sec[i].load_addr); -- Ross Lagerwall _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |