Beispiel #1
0
void *Pool_malloc(Pool *self, size_t size)
#endif
{
	BlockHeader *p;
	BlockHeader *s;
#ifdef POOL_DEBUG
	size_t i;
	size_t alloc_block_size = ALIGN_UP(HEADER_SIZE + size + WALL_SIZE * 2);
#else
	size_t alloc_block_size = ALIGN_UP(HEADER_SIZE + size);
#endif

	if (self->init_flag != self) {
		DEBUGLOG(("Pool_malloc: pool is not initialized: %s(%d)\n", file, line));
		assert(0);
		return 0;
	}
#ifdef POOL_DEBUG
	if (!size) {
		DEBUGLOG(("Pool_malloc: alloc 0 bytes: %s(%d)\n", file, line));
	}
	if (self->fail_count >= 0) {
		if (self->fail_count > 0) {
			self->fail_count--;
		} else {
			DEBUGLOG(("Pool_malloc: return NULL by fail_count: %s(%d)\n", file, line));
			return 0;
		}
	}
#endif
	for (p = self->loop_p->next; p != self->loop_p; p = p->next) {
		if (!p->occupied && p->size >= alloc_block_size) {
			if (p->size >= alloc_block_size + HEADER_SIZE + SPLIT_MIN) {
				s = (BlockHeader *) ((char *) p + alloc_block_size);
				s->size = p->size - alloc_block_size;
				s->occupied = 0;
				s->magic = MAGIC_NO;
				p->size = alloc_block_size;
				s->next = p->next;
#ifndef POOL_SLIST
				s->prev = p;
				p->next->prev = s;
#endif
				p->next = s;
			}
			p->occupied = 1;
#ifdef POOL_DEBUG
			p->file = file;
			p->line = line;
			p->alloc_size = size;
			for (i = 0; i < WALL_SIZE; i++) {
				((char *) p)[HEADER_SIZE + i] = WALL_CHAR;
				((char *) p)[HEADER_SIZE + WALL_SIZE + size + i] = WALL_CHAR;
			}
#endif
			self->loop_p = p;
#ifdef POOL_DEBUG
			return (char *) p + HEADER_SIZE + WALL_SIZE;
#else
			return (char *) p + HEADER_SIZE;
#endif
		}
	}
	DEBUGLOG(("Pool_malloc: return NULL: %s(%d)\n", file, line));
	return 0;
}
Beispiel #2
0
void PackArmPe::rebuildImports(upx_byte *& extrainfo)
{
    if (ODADDR(PEDIR_IMPORT) == 0
        || ODSIZE(PEDIR_IMPORT) <= sizeof(import_desc))
        return;

//    const upx_byte * const idata = obuf + get_le32(extrainfo);
    OPTR_C(const upx_byte, idata, obuf + get_le32(extrainfo));
    const unsigned inamespos = get_le32(extrainfo + 4);
    extrainfo += 8;

    unsigned sdllnames = 0;

//    const upx_byte *import = ibuf + IDADDR(PEDIR_IMPORT) - isection[2].vaddr;
//    const upx_byte *p;
    IPTR_I(const upx_byte, import, ibuf + IDADDR(PEDIR_IMPORT) - isection[2].vaddr);
    OPTR(const upx_byte, p);

    for (p = idata; get_le32(p) != 0; ++p)
    {
        const upx_byte *dname = get_le32(p) + import;
        ICHECK(dname, 1);
        const unsigned dlen = strlen(dname);
        ICHECK(dname, dlen + 1);

        sdllnames += dlen + 1;
        for (p += 8; *p;)
            if (*p == 1)
                p += strlen(++p) + 1;
            else if (*p == 0xff)
                p += 3; // ordinal
            else
                p += 5;
    }
    sdllnames = ALIGN_UP(sdllnames,2u);

    upx_byte * const Obuf = obuf - rvamin;
    import_desc * const im0 = (import_desc*) (Obuf + ODADDR(PEDIR_IMPORT));
    import_desc *im = im0;
    upx_byte *dllnames = Obuf + inamespos;
    upx_byte *importednames = dllnames + sdllnames;
    upx_byte * const importednames_start = importednames;

    for (p = idata; get_le32(p) != 0; ++p)
    {
        // restore the name of the dll
        const upx_byte *dname = get_le32(p) + import;
        ICHECK(dname, 1);
        const unsigned dlen = strlen(dname);
        ICHECK(dname, dlen + 1);

        const unsigned iatoffs = get_le32(p + 4) + rvamin;
        if (inamespos)
        {
            // now I rebuild the dll names
            OCHECK(dllnames, dlen + 1);
            strcpy(dllnames, dname);
            im->dllname = ptr_diff(dllnames,Obuf);
            //;;;printf("\ndll: %s:",dllnames);
            dllnames += dlen + 1;
        }
        else
        {
            OCHECK(Obuf + im->dllname, dlen + 1);
            strcpy(Obuf + im->dllname, dname);
        }
        im->oft = im->iat = iatoffs;

//        LE32 *newiat = (LE32 *) (Obuf + iatoffs);
        OPTR_I(LE32, newiat, (LE32 *) (Obuf + iatoffs));

        // restore the imported names+ordinals
        for (p += 8; *p; ++newiat)
            if (*p == 1)
            {
                const unsigned ilen = strlen(++p) + 1;
                if (inamespos)
                {
                    if (ptr_diff(importednames, importednames_start) & 1)
                        importednames -= 1;
                    omemcpy(importednames + 2, p, ilen);
                    //;;;printf(" %s",importednames+2);
                    *newiat = ptr_diff(importednames, Obuf);
                    importednames += 2 + ilen;
                }
                else
                {
                    OCHECK(Obuf + *newiat + 2, ilen + 1);
                    strcpy(Obuf + *newiat + 2, p);
                }
                p += ilen;
            }
            else if (*p == 0xff)
            {
                *newiat = get_le16(p + 1) + 0x80000000;
                //;;;printf(" %x",(unsigned)*newiat);
                p += 3;
            }
            else
            {
                *newiat = get_le32(get_le32(p + 1) + import);
                assert(*newiat & 0x80000000);
                p += 5;
            }
        *newiat = 0;
        im++;
    }
    //memset(idata,0,p - idata);
}
Beispiel #3
0
void bootstrap(void)
{
	version_print();
	ofw_memmap(&bootinfo.memmap);
	
	void *bootinfo_pa = ofw_translate(&bootinfo);
	void *real_mode_pa = ofw_translate(&real_mode);
	void *loader_address_pa = ofw_translate((void *) LOADER_ADDRESS);
	
	printf("\nMemory statistics (total %llu MB)\n", bootinfo.memmap.total >> 20);
	printf(" %p|%p: real mode trampoline\n", &real_mode, real_mode_pa);
	printf(" %p|%p: boot info structure\n", &bootinfo, bootinfo_pa);
	printf(" %p|%p: kernel entry point\n",
	    (void *) PA2KA(BOOT_OFFSET), (void *) BOOT_OFFSET);
	printf(" %p|%p: loader entry point\n",
	    (void *) LOADER_ADDRESS, loader_address_pa);
	
	size_t i;
	for (i = 0; i < COMPONENTS; i++)
		printf(" %p|%p: %s image (%zu/%zu bytes)\n", components[i].start,
		    ofw_translate(components[i].start), components[i].name,
		    components[i].inflated, components[i].size);
	
	size_t dest[COMPONENTS];
	size_t top = 0;
	size_t cnt = 0;
	bootinfo.taskmap.cnt = 0;
	for (i = 0; i < min(COMPONENTS, TASKMAP_MAX_RECORDS); i++) {
		top = ALIGN_UP(top, PAGE_SIZE);
		
		if (i > 0) {
			bootinfo.taskmap.tasks[bootinfo.taskmap.cnt].addr =
			    (void *) PA2KA(top);
			bootinfo.taskmap.tasks[bootinfo.taskmap.cnt].size =
			    components[i].inflated;
			
			str_cpy(bootinfo.taskmap.tasks[bootinfo.taskmap.cnt].name,
			    BOOTINFO_TASK_NAME_BUFLEN, components[i].name);
			
			bootinfo.taskmap.cnt++;
		}
		
		dest[i] = top;
		top += components[i].inflated;
		cnt++;
	}
	
	void *balloc_base;
	void *balloc_base_pa;
	ofw_alloc("boot allocator area", &balloc_base, &balloc_base_pa,
	    BALLOC_MAX_SIZE, loader_address_pa);
	printf(" %p|%p: boot allocator area\n", balloc_base, balloc_base_pa);
	
	void *inflate_base;
	void *inflate_base_pa;
	ofw_alloc("inflate area", &inflate_base, &inflate_base_pa, top,
	    loader_address_pa);
	printf(" %p|%p: inflate area\n", inflate_base, inflate_base_pa);
	
	uintptr_t balloc_start = ALIGN_UP(top, PAGE_SIZE);
	size_t pages = (balloc_start + ALIGN_UP(BALLOC_MAX_SIZE, PAGE_SIZE))
	    >> PAGE_WIDTH;
	void *transtable;
	void *transtable_pa;
	ofw_alloc("translate table", &transtable, &transtable_pa,
	    pages * sizeof(void *), loader_address_pa);
	printf(" %p|%p: translate table\n", transtable, transtable_pa);
	
	check_overlap("boot allocator area", balloc_base_pa, pages);
	check_overlap("inflate area", inflate_base_pa, pages);
	check_overlap("translate table", transtable_pa, pages);
	
	printf("\nInflating components ... ");
	
	for (i = cnt; i > 0; i--) {
		printf("%s ", components[i - 1].name);
		
		int err = inflate(components[i - 1].start, components[i - 1].size,
		    inflate_base + dest[i - 1], components[i - 1].inflated);
		
		if (err != EOK) {
			printf("\n%s: Inflating error %d, halting.\n",
			    components[i - 1].name, err);
			halt();
		}
	}
	
	printf(".\n");
	
	printf("Setting up boot allocator ...\n");
	balloc_init(&bootinfo.ballocs, balloc_base, PA2KA(balloc_start),
	    BALLOC_MAX_SIZE);
	
	printf("Setting up screens ...\n");
	ofw_setup_screens();
	
	printf("Canonizing OpenFirmware device tree ...\n");
	bootinfo.ofw_root = ofw_tree_build();
	
	printf("Setting up translate table ...\n");
	for (i = 0; i < pages; i++) {
		uintptr_t off = i << PAGE_WIDTH;
		void *phys;
		
		if (off < balloc_start)
			phys = ofw_translate(inflate_base + off);
		else
			phys = ofw_translate(balloc_base + off - balloc_start);
		
		((void **) transtable)[i] = phys;
	}
	
	printf("Booting the kernel...\n");
	jump_to_kernel(bootinfo_pa, transtable_pa, pages, real_mode_pa);
}
static ssize_t relocate_fvh(uintptr_t new_addr, void *fsp, size_t fsp_size,
				size_t fvh_offset, size_t *fih_offset)
{
	EFI_FIRMWARE_VOLUME_HEADER *fvh;
	EFI_FFS_FILE_HEADER *ffsfh;
	EFI_COMMON_SECTION_HEADER *csh;
	size_t offset;
	size_t file_offset;
	size_t size;
	size_t fv_length;

	offset = fvh_offset;
	fvh = relative_offset(fsp, offset);

	if (read_le32(&fvh->Signature) != EFI_FVH_SIGNATURE)
		return -1;

	fv_length = read_le64(&fvh->FvLength);

	printk(FSP_DBG_LVL, "FVH length: %zx Offset: %zx Mapping length: %zx\n",
		fv_length, offset, fsp_size);

	if (fv_length + offset > fsp_size)
		return -1;

	/* Parse only this FV. However, the algorithm uses offsets into the
	 * entire FSP region so make size include the starting offset. */
	size = fv_length + offset;

	if (guid_compare(&fvh->FileSystemGuid, &ffs2_guid)) {
		printk(BIOS_ERR, "FVH not an FFS2 type.\n");
		return -1;
	}

	if (read_le16(&fvh->ExtHeaderOffset) != 0) {
		EFI_FIRMWARE_VOLUME_EXT_HEADER *fveh;

		offset += read_le16(&fvh->ExtHeaderOffset);
		fveh = relative_offset(fsp, offset);
		printk(FSP_DBG_LVL, "Extended Header Offset: %zx Size: %zx\n",
			(size_t)read_le16(&fvh->ExtHeaderOffset),
			(size_t)read_le32(&fveh->ExtHeaderSize));
		offset += read_le32(&fveh->ExtHeaderSize);
		/* FFS files are 8 byte aligned after extended header. */
		offset = ALIGN_UP(offset, 8);
	} else {
		offset += read_le16(&fvh->HeaderLength);
	}

	file_offset = offset;
	while (file_offset + sizeof(*ffsfh) < size) {
		offset = file_offset;
		printk(FSP_DBG_LVL, "file offset: %zx\n", file_offset);

		/* First file and section should be FSP info header. */
		if (fih_offset != NULL && *fih_offset == 0)
			*fih_offset = file_offset;

		ffsfh = relative_offset(fsp, file_offset);

		printk(FSP_DBG_LVL, "file type = %x\n", read_le8(&ffsfh->Type));
		printk(FSP_DBG_LVL, "file attribs = %x\n",
			read_le8(&ffsfh->Attributes));

		/* Exit FV relocation when empty space found */
		if (read_le8(&ffsfh->Type) == EFI_FV_FILETYPE_FFS_MAX)
			break;

		/* Next file on 8 byte alignment. */
		file_offset += ffs_file_size(ffsfh);
		file_offset = ALIGN_UP(file_offset, 8);

		/* Padding files have no section information. */
		if (read_le8(&ffsfh->Type) == EFI_FV_FILETYPE_FFS_PAD)
			continue;

		offset += file_section_offset(ffsfh);

		while (offset + sizeof(*csh) < file_offset) {
			size_t data_size;
			size_t data_offset;

			csh = relative_offset(fsp, offset);

			printk(FSP_DBG_LVL, "section offset: %zx\n", offset);
			printk(FSP_DBG_LVL, "section type: %x\n",
				read_le8(&csh->Type));

			data_size = section_data_size(csh);
			data_offset = section_data_offset(csh);

			if (data_size + data_offset + offset > file_offset) {
				printk(BIOS_ERR, "Section exceeds FV size.\n");
				return -1;
			}

			/*
			 * The entire FSP 1.1 image can be thought of as one
			 * program with a single link address even though there
			 * are multiple TEs linked separately. The reason is
			 * that each TE is linked for XIP. So in order to
			 * relocate the TE properly we need to form the
			 * relocated address based on the TE offset within
			 * FSP proper.
			 */
			if (read_le8(&csh->Type) == EFI_SECTION_TE) {
				void *te;
				size_t te_offset = offset + data_offset;
				uintptr_t te_addr = new_addr + te_offset;

				printk(FSP_DBG_LVL, "TE image at offset %zx\n",
					te_offset);
				te = relative_offset(fsp, te_offset);
				te_relocate(te_addr, te);
			}

			offset += data_size + data_offset;
			/* Sections are aligned to 4 bytes. */
			offset = ALIGN_UP(offset, 4);
		}
	}

	/* Return amount of buffer parsed: FV size. */
	return fv_length;
}
Beispiel #5
0
static int __INIT__ flash_parse_part(struct flash_chip *host,
						struct part_attr *part,	const char *part_def)
{
	int i, ret = -EINVAL, index = 0;
	__u32 curr_base = 0;
	char buff[128];
	const char *p;

	p = strchr(part_def, ':');
	if (!p)
		goto error;

	p++;

	while (*p && *p != ';') {
		if (curr_base >= host->chip_size)
			goto error;

		while (' ' == *p) p++;

		// part size
		if (*p == '-') {
			part->size = host->chip_size - curr_base;
			p++;
		} else {
			for (i = 0; *p; i++, p++) {
				if (*p == '@' || *p == '(' || *p == 'r' || *p == ',')
					break;
				buff[i] = *p;
			}
			buff[i] = '\0';

			ret = hr_str_to_val(buff, (unsigned long *)&part->size);
			if (ret < 0)
				goto error;

			ALIGN_UP(part->size, host->erase_size);
		}

		// part base
		if (*p == '@') {
			for (i = 0, p++; *p; i++, p++) {
				if (*p == '(' || *p == 'r' || *p == ',')
					break;
				buff[i] = *p;
			}
			buff[i] = '\0';

			ret = hr_str_to_val(buff, (unsigned long *)&part->base);
			if (ret < 0)
				goto error;

			ALIGN_UP(part->base, host->erase_size);

			curr_base = part->base;
		} else {
			part->base = curr_base;
		}

		// part label and image
		i = 0;
		if (*p == '(') {
			for (p++; *p && *p != ')'; i++, p++)
				part->label[i] = *p;

			p++;
		}

		if (*p == 'r') {
			p++;
			if (*p != 'o') {
				return -EINVAL;
			}

			part->flags |= BDF_RDONLY;
			p++;
		}

		if (',' == *p)
			p++;

		part->label[i] = '\0';

		curr_base += part->size;

		index++;
		part++;
	}

	return index;

error:
	printf("%s(): invalid part definition \"%s\"\n", __func__, part_def);
	return ret;
}
Beispiel #6
0
grub_err_t
SUFFIX (grub_freebsd_load_elfmodule_obj) (grub_file_t file, int argc,
					  char *argv[], grub_addr_t *kern_end)
{
  Elf_Ehdr e;
  Elf_Shdr *s;
  char *shdr;
  grub_addr_t curload, module;
  grub_err_t err;

  err = read_headers (file, &e, &shdr);
  if (err)
    return err;

  curload = module = ALIGN_PAGE (*kern_end);

  for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) ((char *) shdr
						+ e.e_shnum * e.e_shentsize);
       s = (Elf_Shdr *) ((char *) s + e.e_shentsize))
    {
      if (s->sh_size == 0)
	continue;

      if (s->sh_addralign)
	curload = ALIGN_UP (curload, s->sh_addralign);
      s->sh_addr = curload;

      grub_dprintf ("bsd", "loading section to %x, size %d, align %d\n",
		    (unsigned) curload, (int) s->sh_size,
		    (int) s->sh_addralign);

      switch (s->sh_type)
	{
	default:
	case SHT_PROGBITS:
	  err = load (file, UINT_TO_PTR (curload), s->sh_offset, s->sh_size);
	  if (err)
	    return err;
	  break;
	case SHT_NOBITS:
	  if (curload + s->sh_size > grub_os_area_addr + grub_os_area_size)
	    return grub_error (GRUB_ERR_OUT_OF_RANGE,
			       "not enough memory for the module");
	  grub_memset (UINT_TO_PTR (curload), 0, s->sh_size);
	  break;
	}
      curload += s->sh_size;
    }

  *kern_end = ALIGN_PAGE (curload);

  err = grub_freebsd_add_meta_module (argv[0], FREEBSD_MODTYPE_ELF_MODULE_OBJ,
				      argc - 1, argv + 1, module,
				      curload - module);
  if (! err)
    err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA
				 | FREEBSD_MODINFOMD_ELFHDR,
				 &e, sizeof (e));
  if (! err)
    err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA
				 | FREEBSD_MODINFOMD_SHDR,
				 shdr, e.e_shnum * e.e_shentsize);

  return err;
}
Beispiel #7
0
static u32 alloc_mem(u32 bytes)
{
    return alloc -= ALIGN_UP(bytes, 16);
}
Beispiel #8
0
static grub_err_t
grub_cbfs_find_file (struct grub_archelp_data *data, char **name,
		     grub_int32_t *mtime,
		     grub_uint32_t *mode)
{
  grub_size_t offset;
  for (;;
       data->dofs = data->hofs + offset,
	 data->next_hofs = ALIGN_UP (data->dofs + data->size, data->cbfs_align))
    {
      struct cbfs_file hd;
      grub_size_t namesize;

      data->hofs = data->next_hofs;

      if (data->hofs >= data->cbfs_end)
	{
	  *mode = GRUB_ARCHELP_ATTR_END;
	  return GRUB_ERR_NONE;
	}

      if (grub_disk_read (data->disk, 0, data->hofs, sizeof (hd), &hd))
	return grub_errno;

      if (grub_memcmp (hd.magic, CBFS_FILE_MAGIC, sizeof (hd.magic)) != 0)
	{
	  *mode = GRUB_ARCHELP_ATTR_END;
	  return GRUB_ERR_NONE;
	}
      data->size = grub_be_to_cpu32 (hd.len);
      (void) mtime;
      offset = grub_be_to_cpu32 (hd.offset);

      *mode = GRUB_ARCHELP_ATTR_FILE | GRUB_ARCHELP_ATTR_NOTIME;

      namesize = offset;
      if (namesize >= sizeof (hd))
	namesize -= sizeof (hd);
      if (namesize == 0)
	continue;
      *name = grub_malloc (namesize + 1);
      if (*name == NULL)
	return grub_errno;

      if (grub_disk_read (data->disk, 0, data->hofs + sizeof (hd),
			  namesize, *name))
	{
	  grub_free (*name);
	  return grub_errno;
	}

      if ((*name)[0] == '\0')
	{
	  grub_free (*name);
	  *name = NULL;
	  continue;
	}

      (*name)[namesize] = 0;

      data->dofs = data->hofs + offset;
      data->next_hofs = ALIGN_UP (data->dofs + data->size, data->cbfs_align);
      return GRUB_ERR_NONE;
    }
}
Beispiel #9
0
static int
load_of(uval64 rmo_start, uval64 rmo_size)
{
	uval32 stub_addr = rmo_size - (1 << 20);
	char mem_node[64];
	uval64 prop[2];
	int ret;
	char *dum = NULL;

      retry:
	snprintf(mem_node, sizeof(mem_node), "/memory@0x%x", 0);
	prop[0] = 0;
	prop[1] = stub_addr;
	of_set_prop(mem_node, "available", prop, sizeof (prop));

	char oftree[512];
	char ofstub[512];
	char ofdimg[512];

	snprintf(oftree, sizeof(oftree), HYPE_ROOT "/%s/of_tree", oh_pname);
	snprintf(ofstub, sizeof(ofstub), HYPE_ROOT "/%s/of_image", oh_pname);
	snprintf(ofdimg, sizeof(ofdimg), HYPE_ROOT "/%s/of_tree.ofd", oh_pname);

	const char *const args[] = { "ofdfs", "pack", oftree, ofdimg, NULL };
	run_command(args);

	uval32 stub_size;
	struct stat buf;

	ret = stat(ofstub, &buf);
	ASSERT(ret == 0, "Stat failure %s\n", ofstub);
	stub_size = buf.st_size + 4 * PGSIZE;

	uval32 data_size;

	ret = stat(ofdimg, &buf);
	ASSERT(ret == 0, "Stat failure %s\n", ofdimg);
	data_size = buf.st_size;

	uval32 bottom = ALIGN_DOWN(rmo_size - data_size - stub_size, 1 << 20);

	if (stub_addr > bottom) {
		stub_addr = bottom;
		goto retry;
	}

	uval32 data_addr = ALIGN_UP(stub_addr + stub_size, PGSIZE);

	int fd = open(ofstub, O_RDWR);

	ASSERT(fd >= 0, "bad fd for %s\n", ofstub);

	off_t offset = lseek(fd, 0x10, SEEK_SET);

	ASSERT(offset != ((off_t) - 1), "seek failure on %s\n", ofstub);

	write(fd, &data_addr, sizeof (data_addr));

	close(fd);

	msg("Loading OF stub: 0x%x[0x%x]\n", stub_addr, stub_size);
	msg("Loading OF data: 0x%x[0x%x]\n", data_addr, data_size);
	laddr_load(ofstub, rmo_start + stub_addr, &dum);
	laddr_load(ofdimg, rmo_start + data_addr, &dum);

	set_file_printf("r5", "0x%lx", stub_addr);
	set_file_printf("r1", "0x%lx", stub_addr - PGSIZE);
	return 0;
}
Beispiel #10
0
int
main(int argc, char **argv)
{
	char scratch[128];

	hcall_fd = hcall_init();
	int ret = parse_args(argc, argv);

	if (ret < 0)
		return ret;
	uval total = 0;

	ASSERT(num_ranges > 0, "No memory ranges specified\n");

	ret = get_file("state", scratch, sizeof(scratch));
	if (ret <= 0 || strncmp(scratch, "READY", ret) != 0) {
		bailout("Partition not ready\n");
	}

	uval rmo_start = lranges[0].lr_base;
	uval rmo_size = lranges[0].lr_size;
	uval laddr = 0;
	uval img_base = 0;
	uval img_offset = 0;
	int count = 0;

	while (count < 255) {
		char image[256];
		char image_laddr[256];
		char data[64];
		struct stat sbuf;
		uval base;

		snprintf(image, sizeof(image), HYPE_ROOT "/%s/image%02x",
			 oh_pname, count);
		snprintf(image_laddr, sizeof(image_laddr), "image%02x_load", count);
		++count;

		ret = stat(image, &sbuf);
		if (ret < 0)
			continue;

		ret = get_file(image_laddr, data, sizeof(data));
		if (ret >= 0) {
			uval64 l = strtoull(data, NULL, 0);

			ASSERT(errno != ERANGE, "Corrupted data %s\n",
			       image_laddr);

			laddr = l;
		}

		int size = laddr_load(image, rmo_start + laddr, &base);

		if (0 == img_base) {
			img_base = base;
			img_offset = laddr;
		}

		laddr = ALIGN_UP(laddr + size, PGSIZE);
	}

	char pinfo_buf[64];
	uval64 pinfo;

	ret = get_file("pinfo", pinfo_buf, sizeof(pinfo_buf));

	if (ret <= 0 || (pinfo = strtoull(pinfo_buf, NULL, 0)) <= 0) {
		pinfo = (uval64)-1;
	}

	uval lpid;



	hargs.opcode = H_CREATE_PARTITION;
	hargs.args[0] = rmo_start;
	hargs.args[1] = rmo_size;
	hargs.args[2] = pinfo;

	ret = hcall(&hargs);
	ASSERT(ret >= 0 && hargs.retval == 0,
	       "hcall failure: %d " UVAL_CHOOSE("0x%x", "0x%lx") "\n", ret,
	       hargs.retval);

	lpid = hargs.args[0];

	set_file_printf("of_tree/ibm,partition-no", "0x%llx", lpid);
	set_file_printf("lpid", "0x%llx", lpid);
	set_file("state", "CREATED", -1);

	clean_vdevices();


	of_add_memory(0, rmo_size);
	total += rmo_size;

	int i = 1;

	while (i < num_ranges) {
		uval64 base = lranges[i].lr_base;
		uval64 size = lranges[i].lr_size;

		add_memory(lpid, base, size);
		total += size;
		++i;
	}

#ifdef __PPC__
	add_htab(lpid, total);
#endif

	if (get_file_numeric("res_console_srv", &console_ua) < 0) {
		console_ua = 0;
	} else {
		vtys = 1;
	}

	uval64 vty0 = 0;

	if (vtys == 0 && console_ua == 0) {
		add_vty(0);
	} else {
		if (vtys > 0) {
			/* add vty and force it to be vty@0 */
			vty0 = add_vterm(0, lpid);
			--vtys;
		}

		while (vtys > 0) {
			/* add vty and let it be the proper liobn */
			add_vterm(-1, lpid);
		}

	}

	if (crq > 0) {
		ret = add_vdev(lpid, crq);
		if (ret == -1) {
			fprintf(stderr, "vdev failed : 0x%lx\n", crq);
			return 1;
		}
	}

	if (console_ua) {
		printf("Registering console vterm: "
		       UVAL_CHOOSE("0x%lx","0x%llx")" -> 0x%lx:0x%llx\n",
		       console_ua, lpid, vty0);
		hargs.opcode = H_REGISTER_VTERM;
		hargs.args[0] = console_ua;
		hargs.args[1] = lpid;
		hargs.args[2] = vty0;
		ret = hcall(&hargs);
		ASSERT(ret >= 0 && hargs.retval == 0,
		       "hcall failure: %d " UVAL_CHOOSE("0x%x", "0x%lx") "\n",
		       ret, hargs.retval);
	}

	add_llan(lpid);

#ifdef __PPC__
	load_of(lranges[0].lr_base, lranges[0].lr_size);
#endif
#ifdef __i386__
	if (0 != img_base) {
		static struct partition_info part_info[2];
		fill_pinfo(&part_info[1], lpid, rmo_size);
		if (inject_pinfo(part_info, sizeof(part_info), 
		                img_base, img_offset)) {
			add_cmdlineargs(img_base, 
			                0x1000, /* offset in image for data */ 
			                lpid);
		}
	}
#endif

	hargs.opcode = H_SET_SCHED_PARAMS;
	hargs.args[0] = lpid;
	hargs.args[1] = 0;
	hargs.args[2] = 1;
	hargs.args[3] = 0;
	ret = hcall(&hargs);
	ASSERT(ret >= 0 && hargs.retval == 0,
	       "hcall failure: %d " UVAL_CHOOSE("0x%x", "0x%lx") "\n", ret,
	       hargs.retval);

	hargs.opcode = H_START;
	hargs.args[0] = lpid;

	char buf[64];

	ret = get_file("pc", buf, sizeof(buf));
	if (ret >= 0) {
		buf[ret] = 0;
		hargs.args[1] = strtoull(buf, NULL, 0);
	} else {
		hargs.args[1] = 0;
	}

	int x = 2;

	while (x < 8) {
		int y = 0;

		snprintf(buf, sizeof(buf), "r%d", x);
		y = get_file(buf, buf, sizeof(buf));
		if (y >= 0) {
			buf[y] = 0;
			hargs.args[x] = strtoull(buf, NULL, 0);
		} else {
			hargs.args[x] = 0;
		}
		++x;
	}

	if (wait_for_key) {
		printf("waiting for keypress:");
		(void)fgetc(stdin);
	}

	printf("Starting...\n");
	hcall(&hargs);
	ASSERT(ret >= 0 && hargs.retval == 0,
	       "hcall failure: %d " UVAL_CHOOSE("0x%x", "0x%lx") "\n", ret,
	       hargs.retval);

	set_file("state", "RUNNING", -1);
	return 0;
}
Beispiel #11
0
/* static */ SysStatusUval
SysVSharedMem::MakeRegion(sval32 key, uval size, uval flags)
{
    SysStatus rc = 0;
    uval addr;
    ObjectHandle frOH;
    RegionInfo *ri;
    uval perm;
    uval accMode;


    if (flags & SHM_HUGETLB) {
	rc = StubFRComputation::_CreateLargePage(frOH, LARGE_PAGES_SIZE);
	size = ALIGN_UP(size, LARGE_PAGES_SIZE);
    } else {
	rc = StubFRComputation::_Create(frOH);
    }
    if (_FAILURE(rc)) return rc;

    perm = (flags & (S_IRWXU|S_IRWXG|S_IRWXO));
    if (!(perm & (S_IWUSR | S_IRUSR))) {
	tassertWrn(0,"Region perms are neither read or write.\n");
	perm |= S_IWUSR;
    }
    // FIXME: this is wrong
    if (perm & S_IWUSR) {
	accMode = AccessMode::writeUserWriteSup;
    } else {
	accMode = AccessMode::readUserReadSup;
    }

    // FIXME: The only reason to bind the region in the servers
    // address space is to "reserve" at least one region somewhere
    // since the shamt cannot fail due to absence of memory resources.

    /*
     * Note: We cannot assume that all processes have the reion mapped
     * at the same address, so keeping track of this by our address
     * value is stupid.
     */

    rc = StubRegionDefault::_CreateFixedLenExt(
	addr, size, 0, frOH, 0, accMode, 0, RegionType::K42Region);

    if (_FAILURE(rc)) {
	Obj::ReleaseAccess(frOH);
	return rc;
    }
    ri = new RegionInfo;
    if (ri == NULL) {
	Obj::ReleaseAccess(frOH);
	rc = DREFGOBJ(TheProcessRef)->regionDestroy(addr);
	tassert(_SUCCESS(rc), err_printf("region destroy @ 0x%lx: failed.\n",
					 addr));
	return _SERROR(2520, 0, ENOMEM);
    }
    ri->frOH = frOH;
    ri->addr = addr;
    // FIXME: need some sort of reuse policy!!
    ri->shmID = FetchAndAddSynced(&(obj->shmID), 1);
    tassert(ri->shmID > 0,
	    err_printf("Blew the max shmget(2) id values\n"));

    ri->shmInfo.shm_perm.__key	= key;
    ri->shmInfo.shm_perm.uid	= 0;	// uid of owner
    ri->shmInfo.shm_perm.gid	= 0;	// gid of owner
    ri->shmInfo.shm_perm.cuid	= 0;	// uid of creator
    ri->shmInfo.shm_perm.cgid	= 0;	// gid of creator
    ri->shmInfo.shm_perm.mode	= perm;	// perms
    ri->shmInfo.shm_perm.__seq	= ri->shmID; // FIXME: I THINK

    ri->shmInfo.shm_segsz	= size;	// size of segment (bytes)
    ri->shmInfo.shm_atime	= 0;	// last attach time
    ri->shmInfo.shm_dtime	= 0;	// last dettach time
    // Should be time now
    ri->shmInfo.shm_ctime	= 2;	// last change time by shmctl()
    ri->shmInfo.shm_cpid	= 1;	// pid of creator
    ri->shmInfo.shm_lpid	= 1;	// pid of last shm operation
    ri->shmInfo.shm_nattch	= 0;	// number of current attaches

    AutoLock<BLock> al(&obj->lock);
    if(key != IPC_PRIVATE) {
	obj->regionsByKey.add(key, ri);
    }
    obj->regionsByShmID.add(ri->shmID, ri);
    obj->regionsByAddr.add(addr, ri);

    return _SRETUVAL(ri->shmID);
}
Beispiel #12
0
mspace create_contiguous_mspace_with_base(size_t starting_capacity,
    size_t max_capacity, int locked, void *base) {
  struct mspace_contig_state *cs;
  unsigned int pagesize;
  mstate m;

  init_mparams();
  pagesize = PAGESIZE;
  assert(starting_capacity <= max_capacity);
  assert(((uintptr_t)base & (pagesize-1)) == 0);
  assert(((uintptr_t)max_capacity & (pagesize-1)) == 0);
  starting_capacity = (size_t)ALIGN_UP(starting_capacity, pagesize);

  /* Make the first page read/write. dlmalloc needs to use that page.
   */
  if (mprotect(base, starting_capacity, PROT_READ | PROT_WRITE) < 0) {
    goto error;
  }

  /* Create the mspace, pointing to the memory given.
   */
  m = create_mspace_with_base((char *)base + sizeof(*cs), starting_capacity,
                              locked);
  if (m == (mspace)0) {
    goto error;
  }
  /* Make sure that m is in the same page as base.
   */
  assert(((uintptr_t)m & (uintptr_t)~(pagesize-1)) == (uintptr_t)base);
  /* Use some space for the information that our MORECORE needs.
   */
  cs = (struct mspace_contig_state *)base;

  /* Find out exactly how much of the memory the mspace
   * is using.
   */
  cs->brk = m->seg.base + m->seg.size;
  cs->top = (char *)base + max_capacity;

  assert((char *)base <= cs->brk);
  assert(cs->brk <= cs->top);
  /* Prevent access to the memory we haven't handed out yet.
   */
  if (cs->brk != cs->top) {
    /* mprotect() requires page-aligned arguments, but it's possible
     * for cs->brk not to be page-aligned at this point.
     */
    char *prot_brk = (char *)ALIGN_UP(cs->brk, pagesize);
    if ((mprotect(base, prot_brk - (char *)base, PROT_READ | PROT_WRITE) < 0) ||
        (mprotect(prot_brk, cs->top - prot_brk, PROT_NONE) < 0)) {
      goto error;
    }
  }

  cs->m = m;
  cs->magic = CONTIG_STATE_MAGIC;

  return (mspace)m;

error:
  return (mspace)0;
}
Beispiel #13
0
void *Pool_realloc(Pool *self, void *ptr, size_t newsize)
#endif
{
	size_t i;
	BlockHeader *p;
	BlockHeader *s;
	size_t new_alloc_block_size;
	if (self->init_flag != self) {
		DEBUGLOG(("Pool_realloc: pool is not initialized: %s(%d)\n", file, line));
		assert(0);
		return 0;
	}
	if (!ptr) {
#ifdef POOL_DEBUG
		return Pool_malloc_debug(self, newsize, file, line);
#else
		return Pool_malloc(self, newsize);
#endif
	}
	if (!newsize) {
#ifdef POOL_DEBUG
		Pool_free_debug(self, ptr, file, line);
#else
		Pool_free(self, ptr);
#endif
		return 0;
	}
#ifdef POOL_DEBUG
	p = (BlockHeader *) ((char *) ptr - (HEADER_SIZE + WALL_SIZE));
#else
	p = (BlockHeader *) ((char *) ptr - HEADER_SIZE);
#endif
	if (p->magic != MAGIC_NO || !p->occupied) {
		DEBUGLOG(("Pool_realloc: NG pointer: %s(%d)\n", file, line));
		assert(0);
		return 0;
	}
#ifdef POOL_DEBUG
	new_alloc_block_size = ALIGN_UP(HEADER_SIZE + newsize + WALL_SIZE * 2);
#else
	new_alloc_block_size = ALIGN_UP(HEADER_SIZE + newsize);
#endif
	if (p->size >= new_alloc_block_size) {
		if (p->size >= 2 * new_alloc_block_size && new_alloc_block_size >= HEADER_SIZE + SPLIT_MIN) {
			/* 縮んだ分を空き領域として回収 */
			s = (BlockHeader *) ((char *) p + new_alloc_block_size);
			s->occupied = 0;
			s->magic = MAGIC_NO;
#ifndef POOL_SLIST
			s->prev = p;
#endif
			if (p->next->occupied) {
				s->size = p->size - new_alloc_block_size;
				s->next = p->next;
#ifndef POOL_SLIST
				p->next->prev = s;
#endif
			} else {
				if (self->loop_p == p->next) {
					self->loop_p = p->next->next;
				}
				s->size = p->size - new_alloc_block_size + p->next->size;
				s->next = p->next->next;
#ifndef POOL_SLIST
				p->next->next->prev = s;
#endif
			}
			p->size = new_alloc_block_size;
			p->next = s;
		}
#ifdef POOL_DEBUG
		p->alloc_size = newsize;
		for (i = 0; i < WALL_SIZE; i++) {
			((char *) ptr)[newsize + i] = WALL_CHAR;
		}
#endif
		return ptr;
	}
	/* 以下、拡張 */
	if (p->next->occupied || p->size + p->next->size < new_alloc_block_size) {
#ifdef POOL_DEBUG
		void *newptr = Pool_malloc_debug(self, newsize, file, line);
#else
		void *newptr = Pool_malloc(self, newsize);
#endif
		if (!newptr) {
			DEBUGLOG(("Pool_realloc: return NULL: %s(%d)\n", file, line));
			return 0;
		}
		for (i = 0;
#ifdef POOL_DEBUG
				i < p->alloc_size;
#else
				i < p->size - HEADER_SIZE;
#endif
				i++) {
			((char *) newptr)[i] = ((char *) ptr)[i];
		}
#ifdef POOL_DEBUG
		Pool_free_debug(self, ptr, file, line);
#else
		Pool_free(self, ptr);
#endif
		return newptr;
	}
Beispiel #14
0
unsigned PackArmPe::processImports() // pass 1
{
    static const unsigned char kernel32dll[] = "COREDLL.dll";
    static const char llgpa[] = "\x0\x0""LoadLibraryW\x0\x0"
                                "GetProcAddressA\x0\x0\x0"
                                "CacheSync";
    //static const char exitp[] = "ExitProcess\x0\x0\x0";

    unsigned dllnum = 0;
    import_desc *im = (import_desc*) (ibuf + IDADDR(PEDIR_IMPORT));
    import_desc * const im_save = im;
    if (IDADDR(PEDIR_IMPORT))
    {
        while (im->dllname)
            dllnum++, im++;
        im = im_save;
    }

    struct udll
    {
        const upx_byte *name;
        const upx_byte *shname;
        unsigned   ordinal;
        unsigned   iat;
        LE32       *lookupt;
        unsigned   npos;
        unsigned   original_position;
        bool       isk32;

        static int __acc_cdecl_qsort compare(const void *p1, const void *p2)
        {
            const udll *u1 = * (const udll * const *) p1;
            const udll *u2 = * (const udll * const *) p2;
            if (u1->isk32) return -1;
            if (u2->isk32) return 1;
            if (!*u1->lookupt) return 1;
            if (!*u2->lookupt) return -1;
            int rc = strcasecmp(u1->name,u2->name);
            if (rc) return rc;
            if (u1->ordinal) return -1;
            if (u2->ordinal) return 1;
            if (!u1->shname) return 1;
            if (!u2->shname) return -1;
            return strlen(u1->shname) - strlen(u2->shname);
        }
    };

    // +1 for dllnum=0
    Array(struct udll, dlls, dllnum+1);
    Array(struct udll *, idlls, dllnum+1);

    soimport = 1024; // safety

    unsigned ic,k32o;
    for (ic = k32o = 0; dllnum && im->dllname; ic++, im++)
    {
        idlls[ic] = dlls + ic;
        dlls[ic].name = ibuf + im->dllname;
        dlls[ic].shname = NULL;
        dlls[ic].ordinal = 0;
        dlls[ic].iat = im->iat;
        dlls[ic].lookupt = (LE32*) (ibuf + (im->oft ? im->oft : im->iat));
        dlls[ic].npos = 0;
        dlls[ic].original_position = ic;
        dlls[ic].isk32 = strcasecmp(kernel32dll,dlls[ic].name) == 0;

        soimport += strlen(dlls[ic].name) + 1 + 4;

        for (IPTR_I(LE32, tarr, dlls[ic].lookupt); *tarr; tarr += 1)
        {
            if (*tarr & 0x80000000)
            {
                importbyordinal = true;
                soimport += 2; // ordinal num: 2 bytes
                dlls[ic].ordinal = *tarr & 0xffff;
                //if (dlls[ic].isk32)
                //    kernel32ordinal = true,k32o++;
            }
            else
            {
                IPTR_I(const upx_byte, n, ibuf + *tarr + 2);
                unsigned len = strlen(n);
                soimport += len + 1;
                if (dlls[ic].shname == NULL || len < strlen (dlls[ic].shname))
                    dlls[ic].shname = n;
            }
            soimport++; // separator
        }
    }
    oimport = new upx_byte[soimport];
    memset(oimport,0,soimport);
    oimpdlls = new upx_byte[soimport];
    memset(oimpdlls,0,soimport);

    qsort(idlls,dllnum,sizeof (udll*),udll::compare);

    unsigned dllnamelen = sizeof (kernel32dll);
    unsigned dllnum2 = 1;
    for (ic = 0; ic < dllnum; ic++)
        if (!idlls[ic]->isk32 && (ic == 0 || strcasecmp(idlls[ic - 1]->name,idlls[ic]->name)))
        {
            dllnum2++;
            dllnamelen += strlen(idlls[ic]->name) + 1;
        }
    //fprintf(stderr,"dllnum=%d dllnum2=%d soimport=%d\n",dllnum,dllnum2,soimport); //

    info("Processing imports: %d DLLs", dllnum);

    // create the new import table
    im = (import_desc*) oimpdlls;

    LE32 *ordinals = (LE32*) (oimpdlls + (dllnum2 + 1) * sizeof(import_desc));
    LE32 *lookuptable = ordinals + 4;// + k32o + (isdll ? 0 : 1);
    upx_byte *dllnames = ((upx_byte*) lookuptable) + (dllnum2 - 1) * 8;
    upx_byte *importednames = dllnames + (dllnamelen &~ 1);

    unsigned k32namepos = ptr_diff(dllnames,oimpdlls);

    memcpy(importednames, llgpa, ALIGN_UP((unsigned) sizeof(llgpa), 2u));
    strcpy(dllnames,kernel32dll);
    im->dllname = k32namepos;
    im->iat = ptr_diff(ordinals,oimpdlls);
    *ordinals++ = ptr_diff(importednames,oimpdlls);             // LoadLibraryW
    *ordinals++ = ptr_diff(importednames,oimpdlls) + 14;        // GetProcAddressA
    *ordinals++ = ptr_diff(importednames,oimpdlls) + 14 + 18;   // CacheSync
    dllnames += sizeof(kernel32dll);
    importednames += sizeof(llgpa);

    im++;
    for (ic = 0; ic < dllnum; ic++)
        if (idlls[ic]->isk32)
        {
            idlls[ic]->npos = k32namepos;
            /*
            if (idlls[ic]->ordinal)
                for (LE32 *tarr = idlls[ic]->lookupt; *tarr; tarr++)
                    if (*tarr & 0x80000000)
                        *ordinals++ = *tarr;
            */
        }
        else if (ic && strcasecmp(idlls[ic-1]->name,idlls[ic]->name) == 0)
            idlls[ic]->npos = idlls[ic-1]->npos;
        else
        {
            im->dllname = idlls[ic]->npos = ptr_diff(dllnames,oimpdlls);
            im->iat = ptr_diff(lookuptable,oimpdlls);

            strcpy(dllnames,idlls[ic]->name);
            dllnames += strlen(idlls[ic]->name)+1;
            if (idlls[ic]->ordinal)
                *lookuptable = idlls[ic]->ordinal + 0x80000000;
            else if (idlls[ic]->shname)
            {
                if (ptr_diff(importednames,oimpdlls) & 1)
                    importednames--;
                *lookuptable = ptr_diff(importednames,oimpdlls);
                importednames += 2;
                strcpy(importednames,idlls[ic]->shname);
                importednames += strlen(idlls[ic]->shname) + 1;
            }
            lookuptable += 2;
            im++;
        }
    soimpdlls = ALIGN_UP(ptr_diff(importednames,oimpdlls),4);

    Interval names(ibuf),iats(ibuf),lookups(ibuf);
    // create the preprocessed data
    //ordinals -= k32o;
    upx_byte *ppi = oimport;  // preprocessed imports
    for (ic = 0; ic < dllnum; ic++)
    {
        LE32 *tarr = idlls[ic]->lookupt;
#if 0 && ENABLE_THIS_AND_UNCOMPRESSION_WILL_BREAK
        if (!*tarr)  // no imports from this dll
            continue;
#endif
        set_le32(ppi,idlls[ic]->npos);
        set_le32(ppi+4,idlls[ic]->iat - rvamin);
        ppi += 8;
        for (; *tarr; tarr++)
            if (*tarr & 0x80000000)
            {
                /*if (idlls[ic]->isk32)
                {
                    *ppi++ = 0xfe; // signed + odd parity
                    set_le32(ppi,ptr_diff(ordinals,oimpdlls));
                    ordinals++;
                    ppi += 4;
                }
                else*/
                {
                    *ppi++ = 0xff;
                    set_le16(ppi,*tarr & 0xffff);
                    ppi += 2;
                }
            }
            else
            {
                *ppi++ = 1;
                unsigned len = strlen(ibuf + *tarr + 2) + 1;
                memcpy(ppi,ibuf + *tarr + 2,len);
                ppi += len;
                names.add(*tarr,len + 2 + 1);
            }
        ppi++;

        unsigned esize = ptr_diff((char *)tarr, (char *)idlls[ic]->lookupt);
        lookups.add(idlls[ic]->lookupt,esize);
        if (ptr_diff(ibuf + idlls[ic]->iat, (char *)idlls[ic]->lookupt))
        {
            memcpy(ibuf + idlls[ic]->iat, idlls[ic]->lookupt, esize);
            iats.add(idlls[ic]->iat,esize);
        }
        names.add(idlls[ic]->name,strlen(idlls[ic]->name) + 1 + 1);
    }
    ppi += 4;
    assert(ppi < oimport+soimport);
    soimport = ptr_diff(ppi,oimport);

    if (soimport == 4)
        soimport = 0;

    //OutputFile::dump("x0.imp", oimport, soimport);
    //OutputFile::dump("x1.imp", oimpdlls, soimpdlls);

    unsigned ilen = 0;
    names.flatten();
    if (names.ivnum > 1)
    {
        // The area occupied by the dll and imported names is not continuous
        // so to still support uncompression, I can't zero the iat area.
        // This decreases compression ratio, so FIXME somehow.
        infoWarning("can't remove unneeded imports");
        ilen += sizeof(import_desc) * dllnum;
#if defined(DEBUG)
        if (opt->verbose > 3)
            names.dump();
#endif
        // do some work for the unpacker
        im = im_save;
        for (ic = 0; ic < dllnum; ic++, im++)
        {
            memset(im,FILLVAL,sizeof(*im));
            im->dllname = ptr_diff(dlls[idlls[ic]->original_position].name,ibuf);
        }
    }
    else
    {
        iats.add(im_save,sizeof(import_desc) * dllnum);
        // zero unneeded data
        iats.clear();
        lookups.clear();
    }
    names.clear();

    iats.add(&names);
    iats.add(&lookups);
    iats.flatten();
    for (ic = 0; ic < iats.ivnum; ic++)
        ilen += iats.ivarr[ic].len;

    info("Imports: original size: %u bytes, preprocessed size: %u bytes",ilen,soimport);
    return names.ivnum == 1 ? names.ivarr[0].start : 0;
}
Beispiel #15
0
static void* reserve_code(struct jit* jit, lua_State* L, size_t sz)
{
    struct page* page;
    size_t off = (jit->pagenum > 0) ? jit->pages[jit->pagenum-1]->off : 0;
    size_t size = (jit->pagenum > 0) ? jit->pages[jit->pagenum-1]->size : 0;

    if (off + sz >= size) {
        int i;
        uint8_t* pdata;
        cfunction func;

        /* need to create a new page */
        jit->pages = (struct page**) realloc(jit->pages, (++jit->pagenum) * sizeof(jit->pages[0]));

        size = ALIGN_UP(sz + LINKTABLE_MAX_SIZE + sizeof(struct page), jit->align_page_size);

        page = (struct page*) AllocPage(size);
        jit->pages[jit->pagenum-1] = page;
        pdata = (uint8_t*) page;
        page->size = size;
        page->off = sizeof(struct page);

        lua_newtable(L);

#define ADDFUNC(DLL, NAME) \
        lua_pushliteral(L, #NAME); \
        func = DLL ? (cfunction) GetProcAddressA(DLL, #NAME) : NULL; \
        func = func ? func : (cfunction) &NAME; \
        lua_pushcfunction(L, (lua_CFunction) func); \
        lua_rawset(L, -3)

        ADDFUNC(NULL, check_double);
        ADDFUNC(NULL, check_float);
        ADDFUNC(NULL, check_uint64);
        ADDFUNC(NULL, check_int64);
        ADDFUNC(NULL, check_int32);
        ADDFUNC(NULL, check_uint32);
        ADDFUNC(NULL, check_uintptr);
        ADDFUNC(NULL, check_enum);
        ADDFUNC(NULL, check_typed_pointer);
        ADDFUNC(NULL, check_typed_cfunction);
        ADDFUNC(NULL, check_complex_double);
        ADDFUNC(NULL, check_complex_float);
        ADDFUNC(NULL, unpack_varargs_stack);
        ADDFUNC(NULL, unpack_varargs_stack_skip);
        ADDFUNC(NULL, unpack_varargs_reg);
        ADDFUNC(NULL, unpack_varargs_float);
        ADDFUNC(NULL, unpack_varargs_int);
        ADDFUNC(NULL, push_cdata);
        ADDFUNC(NULL, push_int);
        ADDFUNC(NULL, push_uint);
        ADDFUNC(NULL, push_float);
        ADDFUNC(jit->kernel32_dll, SetLastError);
        ADDFUNC(jit->kernel32_dll, GetLastError);
        ADDFUNC(jit->lua_dll, luaL_error);
        ADDFUNC(jit->lua_dll, lua_pushnumber);
        ADDFUNC(jit->lua_dll, lua_pushboolean);
        ADDFUNC(jit->lua_dll, lua_gettop);
        ADDFUNC(jit->lua_dll, lua_rawgeti);
        ADDFUNC(jit->lua_dll, lua_pushnil);
        ADDFUNC(jit->lua_dll, lua_callk);
        ADDFUNC(jit->lua_dll, lua_settop);
        lua_pushliteral(L, "lua_remove");
        lua_pushcfunction(L, (lua_CFunction) lua_removef);
        lua_rawset(L, -3);
#undef ADDFUNC

        for (i = 0; extnames[i] != NULL; i++) {

            if (strcmp(extnames[i], "FUNCTION") == 0) {
                shred(pdata + page->off, 0, JUMP_SIZE);
                jit->function_extern = i;

            } else {
                lua_getfield(L, -1, extnames[i]);
                func = (cfunction) lua_tocfunction(L, -1);

                if (func == NULL) {
                    luaL_error(L, "internal error: missing link for %s", extnames[i]);
                }

                compile_extern_jump(jit, L, func, pdata + page->off);
                lua_pop(L, 1);
            }

            page->off += JUMP_SIZE;
        }

        page->freed = page->off;
        lua_pop(L, 1);

    } else {
        page = jit->pages[jit->pagenum-1];
        EnableWrite(page, page->size);
    }

    return (uint8_t*) page + page->off;
}
Beispiel #16
0
void PackArmPe::pack(OutputFile *fo)
{
    // FIXME: we need to think about better support for --exact
    if (opt->exact)
        throwCantPackExact();

    const unsigned objs = ih.objects;
    isection = new pe_section_t[objs];
    fi->seek(pe_offset+sizeof(ih),SEEK_SET);
    fi->readx(isection,sizeof(pe_section_t)*objs);

    rvamin = isection[0].vaddr;

    infoHeader("[Processing %s, format %s, %d sections]", fn_basename(fi->getName()), getName(), objs);

    // check the PE header
    // FIXME: add more checks
    if (!opt->force && (
           (ih.cpu != 0x1c0 && ih.cpu != 0x1c2)
        || (ih.opthdrsize != 0xe0)
        || ((ih.flags & EXECUTABLE) == 0)
        || (ih.subsystem != 9)
        || (ih.entry == 0 /*&& !isdll*/)
        || (ih.ddirsentries != 16)
//        || IDSIZE(PEDIR_EXCEPTION) // is this used on arm?
//        || IDSIZE(PEDIR_COPYRIGHT)
       ))
        throwCantPack("unexpected value in PE header (try --force)");

    if (IDSIZE(PEDIR_SEC))
        IDSIZE(PEDIR_SEC) = IDADDR(PEDIR_SEC) = 0;
    //    throwCantPack("compressing certificate info is not supported");

    if (IDSIZE(PEDIR_COMRT))
        throwCantPack(".NET files (win32/net) are not yet supported");

    if (isdll)
        opt->win32_pe.strip_relocs = false;
    else if (opt->win32_pe.strip_relocs < 0)
        opt->win32_pe.strip_relocs = (ih.imagebase >= 0x10000);
    if (opt->win32_pe.strip_relocs)
    {
        if (ih.imagebase < 0x10000)
            throwCantPack("--strip-relocs is not allowed when imagebase < 0x10000");
        else
            ih.flags |= RELOCS_STRIPPED;
    }

    if (memcmp(isection[0].name,"UPX",3) == 0)
        throwAlreadyPackedByUPX();
    if (!opt->force && IDSIZE(15))
        throwCantPack("file is possibly packed/protected (try --force)");
    if (ih.entry && ih.entry < rvamin)
        throwCantPack("run a virus scanner on this file!");
    if (!opt->force && ih.subsystem == 1)
        throwCantPack("subsystem 'native' is not supported (try --force)");
    if (ih.filealign < 0x200)
        throwCantPack("filealign < 0x200 is not yet supported");

    handleStub(fi,fo,pe_offset);
    const unsigned usize = ih.imagesize;
    const unsigned xtrasize = UPX_MAX(ih.datasize, 65536u) + IDSIZE(PEDIR_IMPORT) + IDSIZE(PEDIR_BOUNDIM) + IDSIZE(PEDIR_IAT) + IDSIZE(PEDIR_DELAYIMP) + IDSIZE(PEDIR_RELOC);
    ibuf.alloc(usize + xtrasize);

    // BOUND IMPORT support. FIXME: is this ok?
    fi->seek(0,SEEK_SET);
    fi->readx(ibuf,isection[0].rawdataptr);

    Interval holes(ibuf);

    unsigned ic,jc,overlaystart = 0;
    ibuf.clear(0, usize);
    for (ic = jc = 0; ic < objs; ic++)
    {
        if (isection[ic].rawdataptr && overlaystart < isection[ic].rawdataptr + isection[ic].size)
            overlaystart = ALIGN_UP(isection[ic].rawdataptr + isection[ic].size,ih.filealign);
        if (isection[ic].vsize == 0)
            isection[ic].vsize = isection[ic].size;
        if ((isection[ic].flags & PEFL_BSS) || isection[ic].rawdataptr == 0
            || (isection[ic].flags & PEFL_INFO))
        {
            holes.add(isection[ic].vaddr,isection[ic].vsize);
            continue;
        }
        if (isection[ic].vaddr + isection[ic].size > usize)
            throwCantPack("section size problem");
        if (((isection[ic].flags & (PEFL_WRITE|PEFL_SHARED))
            == (PEFL_WRITE|PEFL_SHARED)))
            if (!opt->force)
                throwCantPack("writable shared sections not supported (try --force)");
        if (jc && isection[ic].rawdataptr - jc > ih.filealign)
            throwCantPack("superfluous data between sections");
        fi->seek(isection[ic].rawdataptr,SEEK_SET);
        jc = isection[ic].size;
        if (jc > isection[ic].vsize)
            jc = isection[ic].vsize;
        if (isection[ic].vsize == 0) // hack for some tricky programs - may this break other progs?
            jc = isection[ic].vsize = isection[ic].size;
        if (isection[ic].vaddr + jc > ibuf.getSize())
            throwInternalError("buffer too small 1");
        fi->readx(ibuf + isection[ic].vaddr,jc);
        jc += isection[ic].rawdataptr;
    }

    // check for NeoLite
    if (find(ibuf + ih.entry, 64+7, "NeoLite", 7) >= 0)
        throwCantPack("file is already compressed with another packer");

    unsigned overlay = file_size - stripDebug(overlaystart);
    if (overlay >= (unsigned) file_size)
    {
#if 0
        if (overlay < file_size + ih.filealign)
            overlay = 0;
        else if (!opt->force)
            throwNotCompressible("overlay problem (try --force)");
#endif
        overlay = 0;
    }
    checkOverlay(overlay);

    Resource res;
    Interval tlsiv(ibuf);
    Export xport((char*)(unsigned char*)ibuf);

    const unsigned dllstrings = processImports();
    processTls(&tlsiv); // call before processRelocs!!
    processResources(&res);
    processExports(&xport);
    processRelocs();

    //OutputFile::dump("x1", ibuf, usize);

    // some checks for broken linkers - disable filter if necessary
    bool allow_filter = true;
    if (ih.codebase == ih.database
        || ih.codebase + ih.codesize > ih.imagesize
        || (isection[virta2objnum(ih.codebase,isection,objs)].flags & PEFL_CODE) == 0)
        allow_filter = false;

    const unsigned oam1 = ih.objectalign - 1;

    // FIXME: disabled: the uncompressor would not allocate enough memory
    //objs = tryremove(IDADDR(PEDIR_RELOC),objs);

    // FIXME: if the last object has a bss then this won't work
    // newvsize = (isection[objs-1].vaddr + isection[objs-1].size + oam1) &~ oam1;
    // temporary solution:
    unsigned newvsize = (isection[objs-1].vaddr + isection[objs-1].vsize + oam1) &~ oam1;

    //fprintf(stderr,"newvsize=%x objs=%d\n",newvsize,objs);
    if (newvsize + soimport + sorelocs > ibuf.getSize())
         throwInternalError("buffer too small 2");
    memcpy(ibuf+newvsize,oimport,soimport);
    memcpy(ibuf+newvsize+soimport,orelocs,sorelocs);

    cimports = newvsize - rvamin;   // rva of preprocessed imports
    crelocs = cimports + soimport;  // rva of preprocessed fixups

    ph.u_len = newvsize + soimport + sorelocs;

    // some extra data for uncompression support
    unsigned s = 0;
    upx_byte * const p1 = ibuf + ph.u_len;
    memcpy(p1 + s,&ih,sizeof (ih));
    s += sizeof (ih);
    memcpy(p1 + s,isection,ih.objects * sizeof(*isection));
    s += ih.objects * sizeof(*isection);
    if (soimport)
    {
        set_le32(p1 + s,cimports);
        set_le32(p1 + s + 4,dllstrings);
        s += 8;
    }
    if (sorelocs)
    {
        set_le32(p1 + s,crelocs);
        p1[s + 4] = (unsigned char) (big_relocs & 6);
        s += 5;
    }
    if (soresources)
    {
        set_le16(p1 + s,icondir_count);
        s += 2;
    }
    // end of extra data
    set_le32(p1 + s,ptr_diff(p1,ibuf) - rvamin);
    s += 4;
    ph.u_len += s;
    obuf.allocForCompression(ph.u_len);

    // prepare packheader
    ph.u_len -= rvamin;
    // prepare filter
    Filter ft(ph.level);
    ft.buf_len = ih.codesize;
    ft.addvalue = ih.codebase - rvamin;
    // compress
    int filter_strategy = allow_filter ? 0 : -3;

    // disable filters for files with broken headers
    if (ih.codebase + ih.codesize > ph.u_len)
    {
        ft.buf_len = 1;
        filter_strategy = -3;
    }

    // limit stack size needed for runtime decompression
    upx_compress_config_t cconf; cconf.reset();
    cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28 KiB stack
    compressWithFilters(&ft, 2048, &cconf, filter_strategy,
                        ih.codebase, rvamin, 0, NULL, 0);
// info: see buildLoader()
    newvsize = (ph.u_len + rvamin + ph.overlap_overhead + oam1) &~ oam1;
    /*
    if (tlsindex && ((newvsize - ph.c_len - 1024 + oam1) &~ oam1) > tlsindex + 4)
    tlsindex = 0;
    */

    const unsigned lsize = getLoaderSize();

    int identsize = 0;
    const unsigned codesize = getLoaderSection("IDENTSTR",&identsize);
    assert(identsize > 0);
    getLoaderSection("UPX1HEAD",(int*)&ic);
    identsize += ic;

    pe_section_t osection[4];
    // section 0 : bss
    //         1 : [ident + header] + packed_data + unpacker + tls
    //         2 : not compressed data
    //         3 : resource data -- wince 5 needs a new section for this

    // identsplit - number of ident + (upx header) bytes to put into the PE header
    int identsplit = pe_offset + sizeof(osection) + sizeof(oh);
    if ((identsplit & 0x1ff) == 0)
        identsplit = 0;
    else if (((identsplit + identsize) ^ identsplit) < 0x200)
        identsplit = identsize;
    else
        identsplit = ALIGN_GAP(identsplit, 0x200);
    ic = identsize - identsplit;

    const unsigned c_len = ((ph.c_len + ic) & 15) == 0 ? ph.c_len : ph.c_len + 16 - ((ph.c_len + ic) & 15);
    obuf.clear(ph.c_len, c_len - ph.c_len);

    const unsigned s1size = ALIGN_UP(ic + c_len + codesize,4u) + sotls;
    const unsigned s1addr = (newvsize - (ic + c_len) + oam1) &~ oam1;

    const unsigned ncsection = (s1addr + s1size + oam1) &~ oam1;
    const unsigned upxsection = s1addr + ic + c_len;

    Reloc rel(1024); // new relocations are put here
    static const char* symbols_to_relocate[] = {
        "ONAM", "BIMP", "BREL", "FIBE", "FIBS", "ENTR", "DST0", "SRC0"
    };
    for (unsigned s2r = 0; s2r < TABLESIZE(symbols_to_relocate); s2r++)
    {
        unsigned off = linker->getSymbolOffset(symbols_to_relocate[s2r]);
        if (off != 0xdeaddead)
            rel.add(off + upxsection, 3);
    }

    // new PE header
    memcpy(&oh,&ih,sizeof(oh));
    oh.filealign = 0x200; // identsplit depends on this
    memset(osection,0,sizeof(osection));

    oh.entry = upxsection;
    oh.objects = 4;
    oh.chksum = 0;

    // fill the data directory
    ODADDR(PEDIR_DEBUG) = 0;
    ODSIZE(PEDIR_DEBUG) = 0;
    ODADDR(PEDIR_IAT) = 0;
    ODSIZE(PEDIR_IAT) = 0;
    ODADDR(PEDIR_BOUNDIM) = 0;
    ODSIZE(PEDIR_BOUNDIM) = 0;


    // tls is put into section 1
    ic = s1addr + s1size - sotls;
    super::processTls(&rel,&tlsiv,ic);
    ODADDR(PEDIR_TLS) = sotls ? ic : 0;
    ODSIZE(PEDIR_TLS) = sotls ? 0x18 : 0;
    ic += sotls;

    // these are put into section 2

    ic = ncsection;

    // wince wants relocation data at the beginning of a section
    processRelocs(&rel);
    ODADDR(PEDIR_RELOC) = soxrelocs ? ic : 0;
    ODSIZE(PEDIR_RELOC) = soxrelocs;
    ic += soxrelocs;

    processImports(ic, linker->getSymbolOffset("IATT") + upxsection);
    ODADDR(PEDIR_IMPORT) = ic;
    ODSIZE(PEDIR_IMPORT) = soimpdlls;
    ic += soimpdlls;

    processExports(&xport,ic);
    ODADDR(PEDIR_EXPORT) = soexport ? ic : 0;
    ODSIZE(PEDIR_EXPORT) = soexport;
    if (!isdll && opt->win32_pe.compress_exports)
    {
        ODADDR(PEDIR_EXPORT) = IDADDR(PEDIR_EXPORT);
        ODSIZE(PEDIR_EXPORT) = IDSIZE(PEDIR_EXPORT);
    }
    ic += soexport;

    ic = (ic + oam1) &~ oam1;
    const unsigned res_start = ic;
    if (soresources)
        processResources(&res,ic);
    ODADDR(PEDIR_RESOURCE) = soresources ? ic : 0;
    ODSIZE(PEDIR_RESOURCE) = soresources;
    ic += soresources;

    const unsigned onam = ncsection + soxrelocs + ih.imagebase;
    linker->defineSymbol("start_of_dll_names", onam);
    linker->defineSymbol("start_of_imports", ih.imagebase + rvamin + cimports);
    linker->defineSymbol("start_of_relocs", crelocs + rvamin + ih.imagebase);
    linker->defineSymbol("filter_buffer_end", ih.imagebase + ih.codebase + ih.codesize);
    linker->defineSymbol("filter_buffer_start", ih.imagebase + ih.codebase);
    linker->defineSymbol("original_entry", ih.entry + ih.imagebase);
    linker->defineSymbol("uncompressed_length", ph.u_len);
    linker->defineSymbol("start_of_uncompressed", ih.imagebase + rvamin);
    linker->defineSymbol("compressed_length", ph.c_len);
    linker->defineSymbol("start_of_compressed", ih.imagebase + s1addr + identsize - identsplit);
    defineDecompressorSymbols();
    relocateLoader();

    MemBuffer loader(lsize);
    memcpy(loader, getLoader(), lsize);
    patchPackHeader(loader, lsize);

    // this is computed here, because soxrelocs changes some lines above
    const unsigned ncsize = soxrelocs + soimpdlls + soexport;
    const unsigned fam1 = oh.filealign - 1;

    // fill the sections
    strcpy(osection[0].name,"UPX0");
    strcpy(osection[1].name,"UPX1");
    strcpy(osection[2].name, "UPX2");
    strcpy(osection[3].name, ".rsrc");

    osection[0].vaddr = rvamin;
    osection[1].vaddr = s1addr;
    osection[2].vaddr = ncsection;
    osection[3].vaddr = res_start;

    osection[0].size = 0;
    osection[1].size = (s1size + fam1) &~ fam1;
    osection[2].size = (ncsize + fam1) &~ fam1;
    osection[3].size = (soresources + fam1) &~ fam1;

    osection[0].vsize = osection[1].vaddr - osection[0].vaddr;
    //osection[1].vsize = (osection[1].size + oam1) &~ oam1;
    //osection[2].vsize = (osection[2].size + oam1) &~ oam1;
    osection[1].vsize = osection[1].size;
    osection[2].vsize = osection[2].size;
    osection[3].vsize = osection[3].size;

    osection[0].rawdataptr = 0;
    osection[1].rawdataptr = (pe_offset + sizeof(oh) + sizeof(osection) + fam1) &~ fam1;
    osection[2].rawdataptr = osection[1].rawdataptr + osection[1].size;
    osection[3].rawdataptr = osection[2].rawdataptr + osection[2].size;

    osection[0].flags = (unsigned) (PEFL_BSS|PEFL_EXEC|PEFL_WRITE|PEFL_READ);
    osection[1].flags = (unsigned) (PEFL_DATA|PEFL_EXEC|PEFL_WRITE|PEFL_READ);
    osection[2].flags = (unsigned) (PEFL_DATA|PEFL_READ);
    osection[3].flags = (unsigned) (PEFL_DATA|PEFL_READ);

    oh.imagesize = (osection[3].vaddr + osection[3].vsize + oam1) &~ oam1;
    oh.bsssize  = osection[0].vsize;
    oh.datasize = osection[2].vsize + osection[3].vsize;
    oh.database = osection[2].vaddr;
    oh.codesize = osection[1].vsize;
    oh.codebase = osection[1].vaddr;
    oh.headersize = osection[1].rawdataptr;
    if (rvamin < osection[0].rawdataptr)
        throwCantPack("object alignment too small");

    if (opt->win32_pe.strip_relocs && !isdll)
        oh.flags |= RELOCS_STRIPPED;

    //for (ic = 0; ic < oh.filealign; ic += 4)
    //    set_le32(ibuf + ic,get_le32("UPX "));
    ibuf.clear(0, oh.filealign);

    info("Image size change: %u -> %u KiB",
         ih.imagesize / 1024, oh.imagesize / 1024);

    infoHeader("[Writing compressed file]");

    if (soresources == 0)
    {
        oh.objects = 3;
        memset(&osection[3], 0, sizeof(osection[3]));
    }
    // write loader + compressed file
    fo->write(&oh,sizeof(oh));
    fo->write(osection,sizeof(osection));
    // some alignment
    if (identsplit == identsize)
    {
        unsigned n = osection[1].rawdataptr - fo->getBytesWritten() - identsize;
        assert(n <= oh.filealign);
        fo->write(ibuf, n);
    }
    fo->write(loader + codesize,identsize);
    infoWriting("loader", fo->getBytesWritten());
    fo->write(obuf,c_len);
    infoWriting("compressed data", c_len);
    fo->write(loader,codesize);
    if (opt->debug.dump_stub_loader)
        OutputFile::dump(opt->debug.dump_stub_loader, loader, codesize);
    if ((ic = fo->getBytesWritten() & 3) != 0)
        fo->write(ibuf,4 - ic);
    fo->write(otls,sotls);
    if ((ic = fo->getBytesWritten() & fam1) != 0)
        fo->write(ibuf,oh.filealign - ic);
    fo->write(oxrelocs,soxrelocs);
    fo->write(oimpdlls,soimpdlls);
    fo->write(oexport,soexport);

    if ((ic = fo->getBytesWritten() & fam1) != 0)
        fo->write(ibuf,oh.filealign - ic);

    fo->write(oresources,soresources);
    if ((ic = fo->getBytesWritten() & fam1) != 0)
        fo->write(ibuf,oh.filealign - ic);

#if 0
    printf("%-13s: program hdr  : %8ld bytes\n", getName(), (long) sizeof(oh));
    printf("%-13s: sections     : %8ld bytes\n", getName(), (long) sizeof(osection));
    printf("%-13s: ident        : %8ld bytes\n", getName(), (long) identsize);
    printf("%-13s: compressed   : %8ld bytes\n", getName(), (long) c_len);
    printf("%-13s: decompressor : %8ld bytes\n", getName(), (long) codesize);
    printf("%-13s: tls          : %8ld bytes\n", getName(), (long) sotls);
    printf("%-13s: resources    : %8ld bytes\n", getName(), (long) soresources);
    printf("%-13s: imports      : %8ld bytes\n", getName(), (long) soimpdlls);
    printf("%-13s: exports      : %8ld bytes\n", getName(), (long) soexport);
    printf("%-13s: relocs       : %8ld bytes\n", getName(), (long) soxrelocs);
#endif

    // verify
    verifyOverlappingDecompression();

    // copy the overlay
    copyOverlay(fo, overlay, &obuf);

    // finally check the compression ratio
    if (!checkFinalCompressionRatio(fo))
        throwNotCompressible();
}
Beispiel #17
0
/*
 * Provide a variant that takes just the vtable for small fixed-size objects.
 * The aligned size is already computed and stored in vt->gc_descr.
 * Note: every SGEN_SCAN_START_SIZE or so we are given the chance to do some special
 * processing. We can keep track of where objects start, for example,
 * so when we scan the thread stacks for pinned objects, we can start
 * a search for the pinned object in SGEN_SCAN_START_SIZE chunks.
 */
GCObject*
sgen_alloc_obj_nolock (GCVTable vtable, size_t size)
{
	/* FIXME: handle OOM */
	void **p;
	char *new_next;
	size_t real_size = size;
	TLAB_ACCESS_INIT;
	
	CANARIFY_SIZE(size);

	HEAVY_STAT (++stat_objects_alloced);
	if (real_size <= SGEN_MAX_SMALL_OBJ_SIZE)
		HEAVY_STAT (stat_bytes_alloced += size);
	else
		HEAVY_STAT (stat_bytes_alloced_los += size);

	size = ALIGN_UP (size);

	SGEN_ASSERT (6, sgen_vtable_get_descriptor (vtable), "VTable without descriptor");

	if (G_UNLIKELY (has_per_allocation_action)) {
		static int alloc_count;
		int current_alloc = InterlockedIncrement (&alloc_count);

		if (collect_before_allocs) {
			if (((current_alloc % collect_before_allocs) == 0) && nursery_section) {
				sgen_perform_collection (0, GENERATION_NURSERY, "collect-before-alloc-triggered", TRUE);
				if (!degraded_mode && sgen_can_alloc_size (size) && real_size <= SGEN_MAX_SMALL_OBJ_SIZE) {
					// FIXME:
					g_assert_not_reached ();
				}
			}
		} else if (verify_before_allocs) {
			if ((current_alloc % verify_before_allocs) == 0)
				sgen_check_whole_heap_stw ();
		}
	}

	/*
	 * We must already have the lock here instead of after the
	 * fast path because we might be interrupted in the fast path
	 * (after confirming that new_next < TLAB_TEMP_END) by the GC,
	 * and we'll end up allocating an object in a fragment which
	 * no longer belongs to us.
	 *
	 * The managed allocator does not do this, but it's treated
	 * specially by the world-stopping code.
	 */

	if (real_size > SGEN_MAX_SMALL_OBJ_SIZE) {
		p = (void **)sgen_los_alloc_large_inner (vtable, ALIGN_UP (real_size));
	} else {
		/* tlab_next and tlab_temp_end are TLS vars so accessing them might be expensive */

		p = (void**)TLAB_NEXT;
		/* FIXME: handle overflow */
		new_next = (char*)p + size;
		TLAB_NEXT = new_next;

		if (G_LIKELY (new_next < TLAB_TEMP_END)) {
			/* Fast path */

			/* 
			 * FIXME: We might need a memory barrier here so the change to tlab_next is 
			 * visible before the vtable store.
			 */

			CANARIFY_ALLOC(p,real_size);
			SGEN_LOG (6, "Allocated object %p, vtable: %p (%s), size: %zd", p, vtable, sgen_client_vtable_get_name (vtable), size);
			binary_protocol_alloc (p , vtable, size, sgen_client_get_provenance ());
			g_assert (*p == NULL);
			mono_atomic_store_seq (p, vtable);

			return (GCObject*)p;
		}

		/* Slow path */

		/* there are two cases: the object is too big or we run out of space in the TLAB */
		/* we also reach here when the thread does its first allocation after a minor 
		 * collection, since the tlab_ variables are initialized to NULL.
		 * there can be another case (from ORP), if we cooperate with the runtime a bit:
		 * objects that need finalizers can have the high bit set in their size
		 * so the above check fails and we can readily add the object to the queue.
		 * This avoids taking again the GC lock when registering, but this is moot when
		 * doing thread-local allocation, so it may not be a good idea.
		 */
		if (TLAB_NEXT >= TLAB_REAL_END) {
			int available_in_tlab;
			/* 
			 * Run out of space in the TLAB. When this happens, some amount of space
			 * remains in the TLAB, but not enough to satisfy the current allocation
			 * request. Currently, we retire the TLAB in all cases, later we could
			 * keep it if the remaining space is above a treshold, and satisfy the
			 * allocation directly from the nursery.
			 */
			TLAB_NEXT -= size;
			/* when running in degraded mode, we continue allocing that way
			 * for a while, to decrease the number of useless nursery collections.
			 */
			if (degraded_mode && degraded_mode < DEFAULT_NURSERY_SIZE)
				return alloc_degraded (vtable, size, FALSE);

			available_in_tlab = (int)(TLAB_REAL_END - TLAB_NEXT);//We'll never have tlabs > 2Gb
			if (size > tlab_size || available_in_tlab > SGEN_MAX_NURSERY_WASTE) {
				/* Allocate directly from the nursery */
				p = (void **)sgen_nursery_alloc (size);
				if (!p) {
					/*
					 * We couldn't allocate from the nursery, so we try
					 * collecting.  Even after the collection, we might
					 * still not have enough memory to allocate the
					 * object.  The reason will most likely be that we've
					 * run out of memory, but there is the theoretical
					 * possibility that other threads might have consumed
					 * the freed up memory ahead of us.
					 *
					 * What we do in this case is allocate degraded, i.e.,
					 * from the major heap.
					 *
					 * Ideally we'd like to detect the case of other
					 * threads allocating ahead of us and loop (if we
					 * always loop we will loop endlessly in the case of
					 * OOM).
					 */
					sgen_ensure_free_space (real_size, GENERATION_NURSERY);
					if (!degraded_mode)
						p = (void **)sgen_nursery_alloc (size);
				}
				if (!p)
					return alloc_degraded (vtable, size, FALSE);

				zero_tlab_if_necessary (p, size);
			} else {
				size_t alloc_size = 0;
				if (TLAB_START)
					SGEN_LOG (3, "Retire TLAB: %p-%p [%ld]", TLAB_START, TLAB_REAL_END, (long)(TLAB_REAL_END - TLAB_NEXT - size));
				sgen_nursery_retire_region (p, available_in_tlab);

				p = (void **)sgen_nursery_alloc_range (tlab_size, size, &alloc_size);
				if (!p) {
					/* See comment above in similar case. */
					sgen_ensure_free_space (tlab_size, GENERATION_NURSERY);
					if (!degraded_mode)
						p = (void **)sgen_nursery_alloc_range (tlab_size, size, &alloc_size);
				}
				if (!p)
					return alloc_degraded (vtable, size, FALSE);

				/* Allocate a new TLAB from the current nursery fragment */
				TLAB_START = (char*)p;
				TLAB_NEXT = TLAB_START;
				TLAB_REAL_END = TLAB_START + alloc_size;
				TLAB_TEMP_END = TLAB_START + MIN (SGEN_SCAN_START_SIZE, alloc_size);

				zero_tlab_if_necessary (TLAB_START, alloc_size);

				/* Allocate from the TLAB */
				p = (void **)TLAB_NEXT;
				TLAB_NEXT += size;
				sgen_set_nursery_scan_start ((char*)p);
			}
		} else {
			/* Reached tlab_temp_end */

			/* record the scan start so we can find pinned objects more easily */
			sgen_set_nursery_scan_start ((char*)p);
			/* we just bump tlab_temp_end as well */
			TLAB_TEMP_END = MIN (TLAB_REAL_END, TLAB_NEXT + SGEN_SCAN_START_SIZE);
			SGEN_LOG (5, "Expanding local alloc: %p-%p", TLAB_NEXT, TLAB_TEMP_END);
		}
		CANARIFY_ALLOC(p,real_size);
	}

	if (G_LIKELY (p)) {
		SGEN_LOG (6, "Allocated object %p, vtable: %p (%s), size: %zd", p, vtable, sgen_client_vtable_get_name (vtable), size);
		binary_protocol_alloc (p, vtable, size, sgen_client_get_provenance ());
		mono_atomic_store_seq (p, vtable);
	}

	return (GCObject*)p;
}
Beispiel #18
0
bool CMMALRenderer::Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_format, unsigned int orientation)
{
  ReleaseBuffers();

  m_sourceWidth  = width;
  m_sourceHeight = height;
  m_renderOrientation = orientation;

  m_fps = fps;
  m_iFlags = flags;
  m_format = format;

  CLog::Log(LOGDEBUG, "%s::%s - %dx%d->%dx%d@%.2f flags:%x format:%d ext:%x orient:%d", CLASSNAME, __func__, width, height, d_width, d_height, fps, flags, format, extended_format, orientation);

  m_RenderUpdateCallBackFn = NULL;
  m_RenderUpdateCallBackCtx = NULL;
  if ((m_format == RENDER_FMT_BYPASS) && g_application.GetCurrentPlayer())
  {
    m_renderFeatures.clear();
    m_scalingMethods.clear();
    m_deinterlaceModes.clear();
    m_deinterlaceMethods.clear();

    if (m_RenderFeaturesCallBackFn)
    {
      (*m_RenderFeaturesCallBackFn)(m_RenderFeaturesCallBackCtx, m_renderFeatures);
      // after setting up m_renderFeatures, we are done with the callback
      m_RenderFeaturesCallBackFn = NULL;
      m_RenderFeaturesCallBackCtx = NULL;
    }
    g_application.m_pPlayer->GetRenderFeatures(m_renderFeatures);
    g_application.m_pPlayer->GetDeinterlaceMethods(m_deinterlaceMethods);
    g_application.m_pPlayer->GetDeinterlaceModes(m_deinterlaceModes);
    g_application.m_pPlayer->GetScalingMethods(m_scalingMethods);
  }

  // calculate the input frame aspect ratio
  CalculateFrameAspectRatio(d_width, d_height);
  ChooseBestResolution(fps);
  m_destWidth = g_graphicsContext.GetResInfo(m_resolution).iWidth;
  m_destHeight = g_graphicsContext.GetResInfo(m_resolution).iHeight;
  SetViewMode(CMediaSettings::Get().GetCurrentVideoSettings().m_ViewMode);
  ManageDisplay();

  if (m_format == RENDER_FMT_MMAL|| m_format == RENDER_FMT_YUV420P)
  {
    MMAL_ES_FORMAT_T *es_format = mmal_format_alloc();
    es_format->type = MMAL_ES_TYPE_VIDEO;
    es_format->es->video.crop.width = m_sourceWidth;
    es_format->es->video.crop.height = m_sourceHeight;

    if (m_format == RENDER_FMT_MMAL)
    {
      es_format->encoding = MMAL_ENCODING_OPAQUE;
      es_format->es->video.width = m_sourceWidth;
      es_format->es->video.height = m_sourceHeight;
    }
    else if (m_format == RENDER_FMT_YUV420P)
    {
      const int pitch = ALIGN_UP(m_sourceWidth, 32);
      const int aligned_height = ALIGN_UP(m_sourceHeight, 16);

      es_format->encoding = MMAL_ENCODING_I420;
      es_format->es->video.width = pitch;
      es_format->es->video.height = aligned_height;

      if (CONF_FLAGS_YUVCOEF_MASK(m_iFlags) == CONF_FLAGS_YUVCOEF_BT709)
        es_format->es->video.color_space = MMAL_COLOR_SPACE_ITUR_BT709;
      else if (CONF_FLAGS_YUVCOEF_MASK(m_iFlags) == CONF_FLAGS_YUVCOEF_BT601)
        es_format->es->video.color_space = MMAL_COLOR_SPACE_ITUR_BT601;
      else if (CONF_FLAGS_YUVCOEF_MASK(m_iFlags) == CONF_FLAGS_YUVCOEF_240M)
        es_format->es->video.color_space = MMAL_COLOR_SPACE_SMPTE240M;
    }
    if (m_bConfigured)
      UnInit();
    m_bConfigured = init_vout(es_format);
    mmal_format_free(es_format);
  }
  else
    m_bConfigured = true;

  return m_bConfigured;
}
Beispiel #19
0
GCObject*
sgen_try_alloc_obj_nolock (GCVTable vtable, size_t size)
{
	void **p;
	char *new_next;
	size_t real_size = size;
	TLAB_ACCESS_INIT;

	CANARIFY_SIZE(size);

	size = ALIGN_UP (size);
	SGEN_ASSERT (9, real_size >= SGEN_CLIENT_MINIMUM_OBJECT_SIZE, "Object too small");

	SGEN_ASSERT (6, sgen_vtable_get_descriptor (vtable), "VTable without descriptor");

	if (real_size > SGEN_MAX_SMALL_OBJ_SIZE)
		return NULL;

	if (G_UNLIKELY (size > tlab_size)) {
		/* Allocate directly from the nursery */
		p = (void **)sgen_nursery_alloc (size);
		if (!p)
			return NULL;
		sgen_set_nursery_scan_start ((char*)p);

		/*FIXME we should use weak memory ops here. Should help specially on x86. */
		zero_tlab_if_necessary (p, size);
	} else {
		int available_in_tlab;
		char *real_end;
		/* tlab_next and tlab_temp_end are TLS vars so accessing them might be expensive */

		p = (void**)TLAB_NEXT;
		/* FIXME: handle overflow */
		new_next = (char*)p + size;

		real_end = TLAB_REAL_END;
		available_in_tlab = (int)(real_end - (char*)p);//We'll never have tlabs > 2Gb

		if (G_LIKELY (new_next < real_end)) {
			TLAB_NEXT = new_next;

			/* Second case, we overflowed temp end */
			if (G_UNLIKELY (new_next >= TLAB_TEMP_END)) {
				sgen_set_nursery_scan_start (new_next);
				/* we just bump tlab_temp_end as well */
				TLAB_TEMP_END = MIN (TLAB_REAL_END, TLAB_NEXT + SGEN_SCAN_START_SIZE);
				SGEN_LOG (5, "Expanding local alloc: %p-%p", TLAB_NEXT, TLAB_TEMP_END);
			}
		} else if (available_in_tlab > SGEN_MAX_NURSERY_WASTE) {
			/* Allocate directly from the nursery */
			p = (void **)sgen_nursery_alloc (size);
			if (!p)
				return NULL;

			zero_tlab_if_necessary (p, size);
		} else {
			size_t alloc_size = 0;

			sgen_nursery_retire_region (p, available_in_tlab);
			new_next = (char *)sgen_nursery_alloc_range (tlab_size, size, &alloc_size);
			p = (void**)new_next;
			if (!p)
				return NULL;

			TLAB_START = (char*)new_next;
			TLAB_NEXT = new_next + size;
			TLAB_REAL_END = new_next + alloc_size;
			TLAB_TEMP_END = new_next + MIN (SGEN_SCAN_START_SIZE, alloc_size);
			sgen_set_nursery_scan_start ((char*)p);

			zero_tlab_if_necessary (new_next, alloc_size);
		}
	}

	HEAVY_STAT (++stat_objects_alloced);
	HEAVY_STAT (stat_bytes_alloced += size);

	CANARIFY_ALLOC(p,real_size);
	SGEN_LOG (6, "Allocated object %p, vtable: %p (%s), size: %zd", p, vtable, sgen_client_vtable_get_name (vtable), size);
	binary_protocol_alloc (p, vtable, size, sgen_client_get_provenance ());
	g_assert (*p == NULL); /* FIXME disable this in non debug builds */

	mono_atomic_store_seq (p, vtable);

	return (GCObject*)p;
}
Beispiel #20
0
grub_err_t
SUFFIX (grub_freebsd_load_elf_meta) (grub_file_t file, grub_addr_t *kern_end)
{
  grub_err_t err;
  Elf_Ehdr e;
  Elf_Shdr *s;
  char *shdr;
  unsigned symoff, stroff, symsize, strsize;
  grub_addr_t curload;
  grub_freebsd_addr_t symstart, symend, symentsize, dynamic;
  Elf_Sym *sym;
  const char *str;
  unsigned i;

  err = read_headers (file, &e, &shdr);
  if (err)
    return err;

  err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA |
			       FREEBSD_MODINFOMD_ELFHDR, &e,
			       sizeof (e));
  if (err)
    return err;

  for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) (shdr
						+ e.e_shnum * e.e_shentsize);
       s = (Elf_Shdr *) ((char *) s + e.e_shentsize))
      if (s->sh_type == SHT_SYMTAB)
	break;
  if (s >= (Elf_Shdr *) ((char *) shdr
			+ e.e_shnum * e.e_shentsize))
    return grub_error (GRUB_ERR_BAD_OS, "no symbol table");
  symoff = s->sh_offset;
  symsize = s->sh_size;
  symentsize = s->sh_entsize;
  s = (Elf_Shdr *) (shdr + e.e_shentsize * s->sh_link);
  stroff = s->sh_offset;
  strsize = s->sh_size;

  if (*kern_end + 4 * sizeof (grub_freebsd_addr_t) + symsize + strsize
      > grub_os_area_addr + grub_os_area_size)
    return grub_error (GRUB_ERR_OUT_OF_RANGE,
		       "not enough memory for kernel symbols");

  symstart = curload = ALIGN_UP (*kern_end, sizeof (grub_freebsd_addr_t));
  *((grub_freebsd_addr_t *) UINT_TO_PTR (curload)) = symsize;
  curload += sizeof (grub_freebsd_addr_t);
  if (grub_file_seek (file, symoff) == (grub_off_t) -1)
    return grub_errno;
  sym = (Elf_Sym *) UINT_TO_PTR (curload);
  if (grub_file_read (file, UINT_TO_PTR (curload), symsize) !=
      (grub_ssize_t) symsize)
    {
      if (! grub_errno)
	return grub_error (GRUB_ERR_BAD_OS, "invalid ELF");
      return grub_errno;
    }
  curload += symsize;

  *((grub_freebsd_addr_t *) UINT_TO_PTR (curload)) = strsize;
  curload += sizeof (grub_freebsd_addr_t);
  if (grub_file_seek (file, stroff) == (grub_off_t) -1)
    return grub_errno;
  str = (char *) UINT_TO_PTR (curload);
  if (grub_file_read (file, UINT_TO_PTR (curload), strsize)
      != (grub_ssize_t) strsize)
    {
      if (! grub_errno)
	return grub_error (GRUB_ERR_BAD_OS, "invalid ELF");
      return grub_errno;
    }
  curload += strsize;
  curload = ALIGN_UP (curload, sizeof (grub_freebsd_addr_t));
  symend = curload;

  for (i = 0;
       i * symentsize < symsize;
       i++, sym = (Elf_Sym *) ((char *) sym + symentsize))
    {
      const char *name = str + sym->st_name;
      if (grub_strcmp (name, "_DYNAMIC") == 0)
	break;
    }

  if (i * symentsize < symsize)
    {
      dynamic = sym->st_value;
      grub_dprintf ("bsd", "dynamic = %llx\n", (unsigned long long) dynamic);
      err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA |
				   FREEBSD_MODINFOMD_DYNAMIC, &dynamic,
				   sizeof (dynamic));
      if (err)
	return err;
    }

  err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA |
			       FREEBSD_MODINFOMD_SSYM, &symstart,
			       sizeof (symstart));
  if (err)
    return err;

  err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA |
			       FREEBSD_MODINFOMD_ESYM, &symend,
			       sizeof (symend));
  if (err)
    return err;
  *kern_end = ALIGN_PAGE (curload);

  return GRUB_ERR_NONE;
}
Beispiel #21
0
void rk_display_init(device_t dev, u32 lcdbase,
		unsigned long fb_size)
{
	struct edid edid;
	uint32_t val;
	struct soc_rockchip_rk3288_config *conf = dev->chip_info;
	uint32_t lower = ALIGN_DOWN(lcdbase, MiB);
	uint32_t upper = ALIGN_UP(lcdbase + fb_size, MiB);
	enum vop_modes detected_mode = VOP_MODE_UNKNOWN;

	printk(BIOS_SPEW, "LCD framebuffer @%p\n", (void *)(lcdbase));
	memset((void *)lcdbase, 0, fb_size);	/* clear the framebuffer */
	dcache_clean_invalidate_by_mva((void *)lower, upper - lower);
	mmu_config_range(lower / MiB, (upper - lower) / MiB, DCACHE_OFF);

	switch (conf->vop_mode) {
	case VOP_MODE_NONE:
		return;
	case VOP_MODE_AUTO_DETECT:
		/* try EDP first, then HDMI */
	case VOP_MODE_EDP:
		printk(BIOS_DEBUG, "Attempting to setup EDP display.\n");
		rkclk_configure_edp();
		rkclk_configure_vop_aclk(conf->vop_id, 192 * MHz);

		/* grf_edp_ref_clk_sel: from internal 24MHz or 27MHz clock */
		write32(&rk3288_grf->soc_con12, RK_SETBITS(1 << 4));

		/* select epd signal from vop0 or vop1 */
		val = (conf->vop_id == 1) ? RK_SETBITS(1 << 5) :
					    RK_CLRBITS(1 << 5);
		write32(&rk3288_grf->soc_con6, val);

		rk_edp_init();

		if (rk_edp_get_edid(&edid) == 0) {
			detected_mode = VOP_MODE_EDP;
			break;
		} else {
			printk(BIOS_WARNING, "Cannot get EDID from EDP.\n");
			if (conf->vop_mode == VOP_MODE_EDP)
				return;
		}
		/* fall thru */
	case VOP_MODE_HDMI:
		printk(BIOS_DEBUG, "Attempting to setup HDMI display.\n");
		rkclk_configure_hdmi();
		rkclk_configure_vop_aclk(conf->vop_id, 384 * MHz);
		rk_hdmi_init(conf->vop_id);

		if (rk_hdmi_get_edid(&edid) == 0) {
			detected_mode = VOP_MODE_HDMI;
			break;
		} else {
			printk(BIOS_WARNING, "Cannot get EDID from HDMI.\n");
			if (conf->vop_mode == VOP_MODE_HDMI)
				return;
		}
		/* fall thru */
	default:
		printk(BIOS_WARNING, "Cannot read any edid info, aborting.\n");
		return;
	}

	if (rkclk_configure_vop_dclk(conf->vop_id, edid.mode.pixel_clock * KHz)) {
		printk(BIOS_WARNING, "config vop err\n");
		return;
	}

	edid_set_framebuffer_bits_per_pixel(&edid,
		conf->framebuffer_bits_per_pixel, 0);
	rkvop_mode_set(conf->vop_id, &edid, detected_mode);

	rkvop_prepare(conf->vop_id, &edid);
	rkvop_enable(conf->vop_id, lcdbase);

	switch (detected_mode) {
	case VOP_MODE_HDMI:
		if (rk_hdmi_enable(&edid)) {
			printk(BIOS_WARNING, "hdmi enable err\n");
			return;
		}

		/*
		 * HACK: if we do remove this delay, HDMI TV may not show
		 * anythings. So we make an delay here, ensure TV have
		 * enough time to respond.
		 */
		mdelay(2000);
		break;

	case VOP_MODE_EDP:
	default:
		if (rk_edp_prepare()) {
			printk(BIOS_WARNING, "edp prepare err\n");
			return;
		}
		if (rk_edp_enable()) {
			printk(BIOS_WARNING, "edp enable err\n");
			return;
		}
		mainboard_power_on_backlight();
		break;
	}

	set_vbe_mode_info_valid(&edid, (uintptr_t)lcdbase);
}
Beispiel #22
0
static int scalecuda_resize(AVFilterContext *ctx,
                            AVFrame *out, AVFrame *in)
{
    AVHWFramesContext *in_frames_ctx = (AVHWFramesContext*)in->hw_frames_ctx->data;
    CUDAScaleContext *s = ctx->priv;

    switch (in_frames_ctx->sw_format) {
    case AV_PIX_FMT_YUV420P:
        call_resize_kernel(s, s->cu_func_uchar, s->cu_tex_uchar, 1,
                           in->data[0], in->width, in->height, in->linesize[0],
                           out->data[0], out->width, out->height, out->linesize[0],
                           1);
        call_resize_kernel(s, s->cu_func_uchar, s->cu_tex_uchar, 1,
                           in->data[0]+in->linesize[0]*in->height, in->width/2, in->height/2, in->linesize[0]/2,
                           out->data[0]+out->linesize[0]*out->height, out->width/2, out->height/2, out->linesize[0]/2,
                           1);
        call_resize_kernel(s, s->cu_func_uchar, s->cu_tex_uchar, 1,
                           in->data[0]+ ALIGN_UP((in->linesize[0]*in->height*5)/4, s->tex_alignment), in->width/2, in->height/2, in->linesize[0]/2,
                           out->data[0]+(out->linesize[0]*out->height*5)/4, out->width/2, out->height/2, out->linesize[0]/2,
                           1);
        break;
    case AV_PIX_FMT_YUV444P:
        call_resize_kernel(s, s->cu_func_uchar, s->cu_tex_uchar, 1,
                           in->data[0], in->width, in->height, in->linesize[0],
                           out->data[0], out->width, out->height, out->linesize[0],
                           1);
        call_resize_kernel(s, s->cu_func_uchar, s->cu_tex_uchar, 1,
                           in->data[0]+in->linesize[0]*in->height, in->width, in->height, in->linesize[0],
                           out->data[0]+out->linesize[0]*out->height, out->width, out->height, out->linesize[0],
                           1);
        call_resize_kernel(s, s->cu_func_uchar, s->cu_tex_uchar, 1,
                           in->data[0]+in->linesize[0]*in->height*2, in->width, in->height, in->linesize[0],
                           out->data[0]+out->linesize[0]*out->height*2, out->width, out->height, out->linesize[0],
                           1);
        break;
    case AV_PIX_FMT_NV12:
        call_resize_kernel(s, s->cu_func_uchar, s->cu_tex_uchar, 1,
                           in->data[0], in->width, in->height, in->linesize[0],
                           out->data[0], out->width, out->height, out->linesize[0],
                           1);
        call_resize_kernel(s, s->cu_func_uchar2, s->cu_tex_uchar2, 2,
                           in->data[1], in->width/2, in->height/2, in->linesize[1],
                           out->data[0] + out->linesize[0] * ((out->height + 31) & ~0x1f), out->width/2, out->height/2, out->linesize[1]/2,
                           1);
        break;
    case AV_PIX_FMT_P010LE:
        call_resize_kernel(s, s->cu_func_ushort, s->cu_tex_ushort, 1,
                           in->data[0], in->width, in->height, in->linesize[0]/2,
                           out->data[0], out->width, out->height, out->linesize[0]/2,
                           2);
        call_resize_kernel(s, s->cu_func_ushort2, s->cu_tex_ushort2, 2,
                           in->data[1], in->width / 2, in->height / 2, in->linesize[1]/2,
                           out->data[0] + out->linesize[0] * ((out->height + 31) & ~0x1f), out->width / 2, out->height / 2, out->linesize[1] / 4,
                           2);
        break;
    case AV_PIX_FMT_P016LE:
        call_resize_kernel(s, s->cu_func_ushort, s->cu_tex_ushort, 1,
                           in->data[0], in->width, in->height, in->linesize[0] / 2,
                           out->data[0], out->width, out->height, out->linesize[0] / 2,
                           2);
        call_resize_kernel(s, s->cu_func_ushort2, s->cu_tex_ushort2, 2,
                           in->data[1], in->width / 2, in->height / 2, in->linesize[1] / 2,
                           out->data[0] + out->linesize[0] * ((out->height + 31) & ~0x1f), out->width / 2, out->height / 2, out->linesize[1] / 4,
                           2);
        break;
    default:
        return AVERROR_BUG;
    }

    return 0;
}
Beispiel #23
0
/*************************************************
 * HOST DRIVERS
 *************************************************/
void hostGPUDRV(CUfunction drvfun, int N, int nrhs, hostdrv_pars_t *prhs) {


  unsigned int maxthreads = MAXTHREADS_STREAM;
  int nstreams = iDivUp(N, maxthreads*BLOCK_DIM1D);
  CUresult err = CUDA_SUCCESS;
  for (int str = 0; str < nstreams; str++) {
    int offset = str * maxthreads * BLOCK_DIM1D;
    int size = 0;
    if (str == (nstreams - 1))
      size = N - str * maxthreads * BLOCK_DIM1D;
    else
      size = maxthreads * BLOCK_DIM1D;


    int gridx = iDivUp(size, BLOCK_DIM1D); // number of x blocks

    // setup execution parameters

    if (CUDA_SUCCESS != (err = cuFuncSetBlockShape(drvfun, BLOCK_DIM1D, 1, 1))) {
      mexErrMsgTxt("Error in cuFuncSetBlockShape");
    }

    if (CUDA_SUCCESS != cuFuncSetSharedSize(drvfun, 0)) {
      mexErrMsgTxt("Error in cuFuncSetSharedSize");
    }


    // add parameters
    int poffset = 0;

    // CUDA kernels interface
    // N: number of elements
    // offset: used for streams
    ALIGN_UP(poffset, __alignof(size));
    if (CUDA_SUCCESS != cuParamSeti(drvfun, poffset, size)) {
      mexErrMsgTxt("Error in cuParamSeti");
    }
    poffset += sizeof(size);

    ALIGN_UP(poffset, __alignof(offset));
    if (CUDA_SUCCESS != cuParamSeti(drvfun, poffset, offset)) {
      mexErrMsgTxt("Error in cuParamSeti");
    }
    poffset += sizeof(offset);

    for (int p=0;p<nrhs;p++) {
      ALIGN_UP(poffset, prhs[p].align);
      if (CUDA_SUCCESS
          != cuParamSetv(drvfun, poffset, prhs[p].par, prhs[p].psize)) {
        mexErrMsgTxt("Error in cuParamSetv");
      }
      poffset += prhs[p].psize;
    }

    if (CUDA_SUCCESS != cuParamSetSize(drvfun, poffset)) {
      mexErrMsgTxt("Error in cuParamSetSize");
    }

    err = cuLaunchGridAsync(drvfun, gridx, 1, 0);
    if (CUDA_SUCCESS != err) {
      mexErrMsgTxt("Error running kernel");
    }
  }

}
Beispiel #24
0
internal_function
new_heap (size_t size, size_t top_pad)
{
  size_t pagesize = GLRO (dl_pagesize);
  char *p1, *p2;
  unsigned long ul;
  heap_info *h;

  if (size + top_pad < HEAP_MIN_SIZE)
    size = HEAP_MIN_SIZE;
  else if (size + top_pad <= HEAP_MAX_SIZE)
    size += top_pad;
  else if (size > HEAP_MAX_SIZE)
    return 0;
  else
    size = HEAP_MAX_SIZE;
  size = ALIGN_UP (size, pagesize);

  /* A memory region aligned to a multiple of HEAP_MAX_SIZE is needed.
     No swap space needs to be reserved for the following large
     mapping (on Linux, this is the case for all non-writable mappings
     anyway). */
  p2 = MAP_FAILED;
  if (aligned_heap_area)
    {
      p2 = (char *) MMAP (aligned_heap_area, HEAP_MAX_SIZE, PROT_NONE,
                          MAP_NORESERVE);
      aligned_heap_area = NULL;
      if (p2 != MAP_FAILED && ((unsigned long) p2 & (HEAP_MAX_SIZE - 1)))
        {
          __munmap (p2, HEAP_MAX_SIZE);
          p2 = MAP_FAILED;
        }
    }
  if (p2 == MAP_FAILED)
    {
      p1 = (char *) MMAP (0, HEAP_MAX_SIZE << 1, PROT_NONE, MAP_NORESERVE);
      if (p1 != MAP_FAILED)
        {
          p2 = (char *) (((unsigned long) p1 + (HEAP_MAX_SIZE - 1))
                         & ~(HEAP_MAX_SIZE - 1));
          ul = p2 - p1;
          if (ul)
            __munmap (p1, ul);
          else
            aligned_heap_area = p2 + HEAP_MAX_SIZE;
          __munmap (p2 + HEAP_MAX_SIZE, HEAP_MAX_SIZE - ul);
        }
      else
        {
          /* Try to take the chance that an allocation of only HEAP_MAX_SIZE
             is already aligned. */
          p2 = (char *) MMAP (0, HEAP_MAX_SIZE, PROT_NONE, MAP_NORESERVE);
          if (p2 == MAP_FAILED)
            return 0;

          if ((unsigned long) p2 & (HEAP_MAX_SIZE - 1))
            {
              __munmap (p2, HEAP_MAX_SIZE);
              return 0;
            }
        }
    }
  if (__mprotect (p2, size, PROT_READ | PROT_WRITE) != 0)
    {
      __munmap (p2, HEAP_MAX_SIZE);
      return 0;
    }
  h = (heap_info *) p2;
  h->size = size;
  h->mprotect_size = size;
  LIBC_PROBE (memory_heap_new, 2, h, h->size);
  return h;
}
Beispiel #25
0
int main(int argc, char *argv[]) {
    int quality = 75;
    if (argc == 2) {
        quality = atoi(argv[1]);
        if (quality < 10 || quality > 100) {
            fprintf(stderr, "invalid quality. must be between 10 and 100\n");
            return 1;
        }
    }

    bcm_host_init();

    uint32_t screen = 0;

    DISPMANX_DISPLAY_HANDLE_T display = vc_dispmanx_display_open(screen);
    DISPMANX_MODEINFO_T info;

    int ret = vc_dispmanx_display_get_info(display, &info);
    assert(ret == 0);

    /* DispmanX expects buffer rows to be aligned to a 32 bit boundary */
    int pitch = ALIGN_UP(2 * info.width, 32);

    uint32_t vc_image_ptr;
    VC_IMAGE_TYPE_T type = VC_IMAGE_RGB565;
    DISPMANX_RESOURCE_HANDLE_T resource = vc_dispmanx_resource_create(
        type, info.width, info.height, &vc_image_ptr
    );
    
    VC_IMAGE_TRANSFORM_T transform = 0;
    vc_dispmanx_snapshot(display, resource, transform);

    VC_RECT_T rect;
    vc_dispmanx_rect_set(&rect, 0, 0, info.width, info.height);

    unsigned char *image = malloc(pitch * info.height);
    assert(image);
    vc_dispmanx_resource_read_data(resource, &rect, image, info.width * 2);

    ret = vc_dispmanx_resource_delete(resource);
    assert(ret == 0);

    ret = vc_dispmanx_display_close(display);
    assert(ret == 0);

    struct jpeg_compress_struct cinfo;
    struct jpeg_error_mgr jerr;
    JSAMPROW row_pointer[1];

    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_compress(&cinfo);
    jpeg_stdio_dest(&cinfo, stdout);

    cinfo.image_width = info.width;
    cinfo.image_height = info.height;
    cinfo.input_components = 3;
    cinfo.in_color_space = JCS_RGB;

    jpeg_set_defaults(&cinfo);
    jpeg_set_quality(&cinfo, quality, TRUE);
    jpeg_start_compress(&cinfo, TRUE);

    int row_stride = cinfo.image_width * 3;
    while (cinfo.next_scanline < cinfo.image_height) {
        unsigned char row[row_stride];
        unsigned char *dst = &row[0];
        uint16_t *src = (uint16_t*)(image + pitch * cinfo.next_scanline);
        for (int x = 0; x < cinfo.image_width; x++, src++) {
            *dst++ = ((*src & 0xf800) >> 11) << 3;
            *dst++ = ((*src & 0x07e0) >>  5) << 2;
            *dst++ = ((*src & 0x001f) >>  0) << 3;
        }
        row_pointer[0] = row;
        jpeg_write_scanlines(&cinfo, row_pointer, 1);
    }
    jpeg_finish_compress(&cinfo);
    jpeg_destroy_compress(&cinfo);
    return 0;
}
Beispiel #26
0
void PackBvmlinuzI386::buildLoader(const Filter *ft)
{
    // prepare loader
    initLoader(stub_i386_linux_kernel_vmlinuz, sizeof(stub_i386_linux_kernel_vmlinuz));
    if (0!=page_offset) { // relocatable kernel
        assert(0==ft->id || 0x40==(0xf0 & ft->id));  // others assume fixed buffer address
        addLoader("LINUZ000,LINUZ001,LINUZVGA,LINUZ101,LINUZ110",
            ((0!=config_physical_align) ? "LINUZ120" : "LINUZ130"),
            "LINUZ140,LZCUTPOI,LINUZ141",
            (ft->id ? "LINUZ145" : ""),
            (ph.first_offset_found == 1 ? "LINUZ010" : ""),
            NULL);
    }
    else {
        addLoader("LINUZ000,LINUZ001,LINUZVGA,LINUZ005",
              ph.first_offset_found == 1 ? "LINUZ010" : "",
              (0x40==(0xf0 & ft->id)) ? "LZCKLLT1" : (ft->id ? "LZCALLT1" : ""),
              "LBZIMAGE,IDENTSTR",
              "+40", // align the stuff to 4 byte boundary
              "UPX1HEAD", // 32 byte
              "LZCUTPOI",
              NULL);
        // fake alignment for the start of the decompressor
        //linker->defineSymbol("LZCUTPOI", 0x1000);
    }

    addLoader(getDecompressorSections(), NULL);

    if (ft->id)
    {
            assert(ft->calls > 0);
        if (0x40==(0xf0 & ft->id)) {
            addLoader("LZCKLLT9", NULL);
        }
        else {
            addLoader("LZCALLT9", NULL);
        }
        addFilter32(ft->id);
    }
    if (0!=page_offset) {
        addLoader("LINUZ150,IDENTSTR,+40,UPX1HEAD", NULL);
        unsigned const l_len = getLoaderSize();
        unsigned const c_len = ALIGN_UP(ph.c_len, 4u);
        unsigned const e_len = getLoaderSectionStart("LINUZ141") -
                               getLoaderSectionStart("LINUZ110");
        linker->defineSymbol("compressed_length", c_len);
        linker->defineSymbol("load_physical_address", physical_start);  // FIXME
        if (0!=config_physical_align) {
            linker->defineSymbol("neg_config_physical_align", 0u - config_physical_align);
        }
        linker->defineSymbol("neg_length_mov", 0u - ALIGN_UP(c_len + l_len, 4u));
        linker->defineSymbol("neg_page_offset", 0u - page_offset);
        //linker->defineSymbol("physical_start", physical_start);
        linker->defineSymbol("unc_length", ph.u_len);
        linker->defineSymbol("dec_offset", ph.overlap_overhead + e_len);
        linker->defineSymbol("unc_offset", ph.overlap_overhead + ph.u_len - c_len);
    }
    else {
        addLoader("LINUZ990", NULL);
    }
}
Beispiel #27
0
/* this is really aimed at the lcd panel. That said, there are two display
 * devices on this part and we may someday want to extend it for other boards.
 */
void display_startup(device_t dev)
{
	struct soc_nvidia_tegra124_config *config = dev->chip_info;
	struct display_controller *disp_ctrl = (void *)config->display_controller;
	struct pwm_controller 	*pwm = (void *)TEGRA_PWM_BASE;
	struct tegra_dc		*dc = &dc_data;
	u32 plld_rate;

	/* init dc */
	dc->base = (void *)TEGRA_ARM_DISPLAYA;
	dc->config = config;
	config->dc_data = dc;

	/* Note dp_init may read EDID and change some config values. */
	dp_init(config);

	/* should probably just make it all MiB ... in future */
	u32 framebuffer_size_mb = config->framebuffer_size / MiB;
	u32 framebuffer_base_mb= config->framebuffer_base / MiB;

	/* light it all up */
	/* This one may have been done in romstage but that's ok for now. */
	if (config->panel_vdd_gpio){
		gpio_output(config->panel_vdd_gpio, 1);
		printk(BIOS_SPEW,"%s: panel_vdd setting gpio %08x to %d\n",
			__func__, config->panel_vdd_gpio, 1);
	}
	udelay(config->vdd_delay_ms * 1000);
	if (config->backlight_vdd_gpio){
		gpio_output(config->backlight_vdd_gpio, 1);
		printk(BIOS_SPEW,"%s: backlight vdd setting gpio %08x to %d\n",
			__func__, config->backlight_vdd_gpio, 1);
	}
	if (config->lvds_shutdown_gpio){
		gpio_output(config->lvds_shutdown_gpio, 0);
		printk(BIOS_SPEW,"%s: lvds shutdown setting gpio %08x to %d\n",
			__func__, config->lvds_shutdown_gpio, 0);
	}

	if (framebuffer_size_mb == 0){
		framebuffer_size_mb = ALIGN_UP(config->xres * config->yres *
			(config->framebuffer_bits_per_pixel / 8), MiB)/MiB;
	}

	if (! framebuffer_base_mb)
		framebuffer_base_mb = fb_base_mb();

	config->framebuffer_size = framebuffer_size_mb * MiB;
	config->framebuffer_base = framebuffer_base_mb * MiB;

	mmu_config_range(framebuffer_base_mb, framebuffer_size_mb,
		DCACHE_WRITETHROUGH);

	printk(BIOS_SPEW, "LCD frame buffer at %dMiB to %dMiB\n", framebuffer_base_mb,
		   framebuffer_base_mb + framebuffer_size_mb);

	/* GPIO magic here if needed to start powering up things. You
	 * really only want to enable vdd, wait a bit, and then enable
	 * the panel. However ... the timings in the tegra20 dts make
	 * no sense to me. I'm pretty sure they're wrong.
	 * The panel_vdd is done in the romstage, so we need only
	 * light things up here once we're sure it's all working.
	 */

	/* The plld is programmed with the assumption of the SHIFT_CLK_DIVIDER
	 * and PIXEL_CLK_DIVIDER are zero (divide by 1). See the
	 * update_display_mode() for detail.
	 */
	plld_rate = clock_display(config->pixel_clock * 2);
	if (plld_rate == 0) {
		printk(BIOS_ERR, "dc: clock init failed\n");
		return;
	} else if (plld_rate != config->pixel_clock * 2) {
		printk(BIOS_WARNING, "dc: plld rounded to %u\n", plld_rate);
		config->pixel_clock = plld_rate / 2;
	}

	/* Init dc */
	if (tegra_dc_init(disp_ctrl)) {
		printk(BIOS_ERR, "dc: init failed\n");
		return;
	}

	/* Configure dc mode */
	if (update_display_mode(disp_ctrl, config)) {
		printk(BIOS_ERR, "dc: failed to configure display mode.\n");
		return;
	}

	/* Enable dp */
	dp_enable(dc->out);

	/* Init frame buffer */
	memset((void *)(framebuffer_base_mb*MiB), 0x00,
			framebuffer_size_mb*MiB);

	update_window(disp_ctrl, config);

	/* Set up Tegra PWM n (where n is specified in config->pwm) to drive the
	 * panel backlight.
	 */
	printk(BIOS_SPEW, "%s: enable panel backlight pwm\n", __func__);
	WRITEL(((1 << NV_PWM_CSR_ENABLE_SHIFT) |
		(220 << NV_PWM_CSR_PULSE_WIDTH_SHIFT) | /* 220/256 */
		0x02e), /* frequency divider */
	       &pwm->pwm[config->pwm].csr);

	udelay(config->pwm_to_bl_delay_ms * 1000);
	if (config->backlight_en_gpio){
		gpio_output(config->backlight_en_gpio, 1);
		printk(BIOS_SPEW,"%s: backlight enable setting gpio %08x to %d\n",
			__func__, config->backlight_en_gpio, 1);
	}

	printk(BIOS_INFO, "%s: display init done.\n", __func__);

	/* tell depthcharge ...
	 */
	struct edid edid;
	edid.mode.va = config->yres;
	edid.mode.ha = config->xres;
	edid_set_framebuffer_bits_per_pixel(&edid,
		config->framebuffer_bits_per_pixel, 32);
	set_vbe_mode_info_valid(&edid, (uintptr_t)(framebuffer_base_mb*MiB));
}