Beispiel #1
0
/* Write a directory entry */
static int vmfs_dirent_write(const vmfs_dirent_t *entry,u_char *buf)
{
   write_le32(buf,VMFS_DIRENT_OFS_TYPE,entry->type);
   write_le32(buf,VMFS_DIRENT_OFS_BLK_ID,entry->block_id);
   write_le32(buf,VMFS_DIRENT_OFS_REC_ID,entry->record_id);
   memcpy(buf+VMFS_DIRENT_OFS_NAME,entry->name,VMFS_DIRENT_OFS_NAME_SIZE);
   return(0);
}
Beispiel #2
0
/* Write a heartbeat info */
int vmfs_heartbeat_write(const vmfs_heartbeat_t *hb,u_char *buf)
{
   write_le32(buf,VMFS_HB_OFS_MAGIC,hb->magic);
   write_le64(buf,VMFS_HB_OFS_POS,hb->pos);
   write_le64(buf,VMFS_HB_OFS_SEQ,hb->seq);
   write_le64(buf,VMFS_HB_OFS_UPTIME,hb->uptime);
   write_le32(buf,VMFS_HB_OFS_JOURNAL_BLK,hb->journal_blk);
   write_uuid(buf,VMFS_HB_OFS_UUID,&hb->uuid);
   return(0);
}
Beispiel #3
0
CFilePacker::CFilePacker(u32 version, const char magic[4])
{
	// put header in our data array.
	// (its payloadSize_le will be updated on every Pack*() call)
	FileHeader header;
	strncpy(header.magic, magic, 4);	// not 0-terminated => no _s
	write_le32(&header.version_le, version);
	write_le32(&header.payloadSize_le, 0);
	m_writeBuffer.Append(&header, sizeof(FileHeader));
}
Beispiel #4
0
/* Write a metadata header */
int vmfs_metadata_hdr_write(const vmfs_metadata_hdr_t *mdh,u_char *buf)
{
   memset(buf,0,VMFS_METADATA_HDR_SIZE);
   write_le32(buf,VMFS_MDH_OFS_MAGIC,mdh->magic);
   write_le64(buf,VMFS_MDH_OFS_POS,mdh->pos);
   write_le64(buf,VMFS_MDH_OFS_HB_POS,mdh->hb_pos);
   write_le64(buf,VMFS_MDH_OFS_HB_SEQ,mdh->hb_seq);
   write_le64(buf,VMFS_MDH_OFS_OBJ_SEQ,mdh->obj_seq);
   write_le32(buf,VMFS_MDH_OFS_HB_LOCK,mdh->hb_lock);
   write_le64(buf,VMFS_MDH_OFS_MTIME,mdh->mtime);
   write_uuid(buf,VMFS_MDH_OFS_HB_UUID,&mdh->hb_uuid);
   return(0);
}
static int relocate_patch_table(void *fsp, size_t size, size_t offset,
				ssize_t adjustment)
{
	struct fsp_patch_table *table;
	size_t num;
	size_t num_entries;

	table = relative_offset(fsp, offset);

	if ((offset + sizeof(*table) > size) ||
	    (read_le16(&table->header_length) + offset) > size) {
		printk(BIOS_ERR, "FSPP not entirely contained in region.\n");
		return -1;
	}

	num_entries = read_le32(&table->patch_entry_num);
	printk(FSP_DBG_LVL, "FSPP relocs: %zx\n", num_entries);

	for (num = 0; num < num_entries; num++) {
		uint32_t *reloc;
		uint32_t reloc_val;

		reloc = fspp_reloc(fsp, size,
				read_le32(&table->patch_entries[num]));

		if (reloc == NULL) {
			printk(BIOS_ERR, "Ignoring FSPP entry: %x\n",
				read_le32(&table->patch_entries[num]));
			continue;
		}

		reloc_val = read_le32(reloc);
		printk(FSP_DBG_LVL, "Adjusting %p %x -> %x\n",
			reloc, reloc_val,
			(unsigned int)(reloc_val + adjustment));

		write_le32(reloc, reloc_val + adjustment);
	}

	return 0;
}
Beispiel #6
0
int main() {
    output_file = fopen("output.wav", "wb");
    if (!output_file)
        die_perror("failed to open file");

    int samplerate    = SAMPLE_RATE;
    int channels      = 2;
    int bitspersample = 16;

    int datarate = samplerate * channels * (bitspersample / 8);
    int blockalign = channels * (bitspersample / 8);

    // write wav header
    output_write("RIFF", 4);
    long riff_len_pos = ftell(output_file);     // need to write 36+datalen to riff_len_pos
    write_le32(0);      
    output_write("WAVE", 4);
    output_write("fmt ", 4);
    write_le32(16);
    write_le16(1);
    write_le16(channels);
    write_le32(samplerate);
    write_le32(datarate);
    write_le16(blockalign);
    write_le16(bitspersample);
    output_write("data", 4);
    long wav_data_pos = ftell(output_file);     // need to write datalen to wav_data_pos
    write_le32(0);      

    int i;
    for (i = 0; i < 22050; i++) output_sample(0, 0);    // write 500ms of silence

    write_pulse(1, 4909, 1000000);         // command start
    write_pulse(0, 4320, 1000000);

    i = 0;
    unsigned code = 0xe0e040bf;
    for (i = 0; i < 32; i++) {
        int bit = (code >> (31 - i)) & 0x1;

        if (bit) {
            write_pulse(1, 818, 1000000);         // 1 bit
            write_pulse(0, 1425, 1000000);
        } else {
            write_pulse(1, 818, 1000000);         // 0 bit
            write_pulse(0, 325, 1000000);
        }
    }

    write_pulse(1, 717, 1000000);          // command stop
    write_pulse(0, 717, 1000000);

    for (i = 0; i < 22050; i++) output_sample(0, 0);    // write 500ms of silence

    fseek(output_file, riff_len_pos, SEEK_SET);
    write_le32(36 + datalen);

    fseek(output_file, wav_data_pos, SEEK_SET);
    write_le32(datalen);

    fclose(output_file);

    return 0;
}
bool RageSurfaceUtils::SaveBMP( RageSurface *surface, RageFile &f )
{
	/* Convert the surface to 24bpp. */
	RageSurface *converted_surface;
	converted_surface = CreateSurface( surface->w, surface->h, 24,
		Swap24LE( 0xFF0000 ), Swap24LE( 0x00FF00 ), Swap24LE( 0x0000FF ), 0 );
	RageSurfaceUtils::CopySurface( surface, converted_surface );

	RString sError;

	int iFilePitch = converted_surface->pitch;
	iFilePitch = (iFilePitch+3) & ~3; // round up a multiple of 4

	int iDataSize = converted_surface->h * iFilePitch;
	const int iHeaderSize = 0x36;

	WriteBytes( f, sError, "BM", 2 );
	write_le32( f, sError, iHeaderSize+iDataSize ); // size (offset 0x2)
	write_le32( f, sError, 0 ); // reserved (offset 0x6)
	write_le32( f, sError, iHeaderSize ); // bitmap offset (offset 0xA)
	write_le32( f, sError, 0x28 ); // header size (offset 0xE)
	write_le32( f, sError, surface->w ); // width (offset 0x14)
	write_le32( f, sError, surface->h ); // height (offset 0x18)
	write_le16( f, sError, 1 ); // planes (offset 0x1A)
	write_le16( f, sError, (uint16_t) converted_surface->fmt.BytesPerPixel*8 ); // bpp (offset 0x1C)
	write_le32( f, sError, 0 ); // compression (offset 0x1E)
	write_le32( f, sError, iDataSize ); // bitmap size (offset 0x22)
	write_le32( f, sError, 0 ); // horiz resolution (offset 0x26)
	write_le32( f, sError, 0 ); // vert resolution (offset 0x2A)
	write_le32( f, sError, 0 ); // colors (offset 0x2E)
	write_le32( f, sError, 0 ); // important colors (offset 0x32)

	for( int y = converted_surface->h-1; y >= 0; --y )
	{
		const uint8_t *pRow = converted_surface->pixels + converted_surface->pitch*y;
		WriteBytes( f, sError, pRow, converted_surface->pitch );

		/* Pad the row to the pitch. */
		uint8_t padding[4] = { 0,0,0,0 };
		WriteBytes( f, sError, padding, iFilePitch-converted_surface->pitch );
	}

	delete converted_surface;

	if( sError.size() != 0 )
		return false;

	if( f.Flush() == -1 )
		return false;

	return true;
}
static ssize_t relocate_remaining_items(void *fsp, size_t size,
					uintptr_t new_addr, size_t fih_offset)
{
	EFI_FFS_FILE_HEADER *ffsfh;
	EFI_COMMON_SECTION_HEADER *csh;
	FSP_INFO_HEADER *fih;
	ssize_t adjustment;
	size_t offset;

	printk(FSP_DBG_LVL, "FSP_INFO_HEADER offset is %zx\n", fih_offset);

	if (fih_offset == 0) {
		printk(BIOS_ERR, "FSP_INFO_HEADER offset is 0.\n");
		return -1;
	}

	/* FSP_INFO_HEADER at first file in FV within first RAW section. */
	ffsfh = relative_offset(fsp, fih_offset);
	fih_offset += file_section_offset(ffsfh);
	csh = relative_offset(fsp, fih_offset);
	fih_offset += section_data_offset(csh);
	fih = relative_offset(fsp, fih_offset);

	if (guid_compare(&ffsfh->Name, &fih_guid)) {
		printk(BIOS_ERR, "Bad FIH GUID.\n");
		return -1;
	}

	if (read_le8(&csh->Type) != EFI_SECTION_RAW) {
		printk(BIOS_ERR, "FIH file should have raw section: %x\n",
			read_le8(&csh->Type));
		return -1;
	}

	if (read_le32(&fih->Signature) != FSP_SIG) {
		printk(BIOS_ERR, "Unexpected FIH signature: %08x\n",
			read_le32(&fih->Signature));
		return -1;
	}

	adjustment = (intptr_t)new_addr - read_le32(&fih->ImageBase);

	/* Update ImageBase to reflect FSP's new home. */
	write_le32(&fih->ImageBase, adjustment + read_le32(&fih->ImageBase));

	/* Need to find patch table and adjust each entry. The tables
	 * following FSP_INFO_HEADER have a 32-bit signature and header
	 * length. The patch table is denoted as having a 'FSPP' signature;
	 * the table format doesn't follow the other tables. */
	offset = fih_offset + read_le32(&fih->HeaderLength);
	while (offset + 2 * sizeof(uint32_t) <= size) {
		uint32_t *table_headers;

		table_headers = relative_offset(fsp, offset);

		printk(FSP_DBG_LVL, "Checking offset %zx for 'FSPP'\n",
			offset);

		if (read_le32(&table_headers[0]) != FSPP_SIG) {
			offset += read_le32(&table_headers[1]);
			continue;
		}

		if (relocate_patch_table(fsp, size, offset, adjustment)) {
			printk(BIOS_ERR, "FSPP relocation failed.\n");
			return -1;
		}

		return fih_offset;
	}

	printk(BIOS_ERR, "Could not find the FSP patch table.\n");
	return -1;
}
static int te_relocate(uintptr_t new_addr, void *te)
{
	EFI_TE_IMAGE_HEADER *teih;
	EFI_IMAGE_DATA_DIRECTORY *relocd;
	EFI_IMAGE_BASE_RELOCATION *relocb;
	uintptr_t image_base;
	size_t fixup_offset;
	size_t num_relocs;
	uint16_t *reloc;
	size_t relocd_offset;
	uint8_t *te_base;
	uint32_t adj;

	teih = te;

	if (read_le16(&teih->Signature) != EFI_TE_IMAGE_HEADER_SIGNATURE) {
		printk(BIOS_ERR, "TE Signature mismatch: %x vs %x\n",
			read_le16(&teih->Signature),
			EFI_TE_IMAGE_HEADER_SIGNATURE);
		return -1;
	}

	/*
	 * A TE image is created by converting a PE file. Because of this
	 * the offsets within the headers are off. In order to calculate
	 * the correct releative offets one needs to subtract fixup_offset
	 * from the encoded offets.  Similarly, the linked address of the
	 * program is found by adding the fixup_offset to the ImageBase.
	 */
	fixup_offset = read_le16(&teih->StrippedSize);
	fixup_offset -= sizeof(EFI_TE_IMAGE_HEADER);
	/* Keep track of a base that is correctly adjusted so that offsets
	 * can be used directly. */
	te_base = te;
	te_base -= fixup_offset;

	image_base = read_le64(&teih->ImageBase);
	adj = new_addr - (image_base + fixup_offset);

	printk(FSP_DBG_LVL, "TE Image %p -> %p adjust value: %x\n",
		(void *)image_base, (void *)new_addr, adj);

	/* Adjust ImageBase for consistency. */
	write_le64(&teih->ImageBase, (uint32_t)(image_base + adj));

	relocd = &teih->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC];

	relocd_offset = 0;
	/* Though the field name is VirtualAddress it's actually relative to
	 * the beginning of the image which is linked at ImageBase. */
	relocb = relative_offset(te,
			read_le32(&relocd->VirtualAddress) - fixup_offset);
	while (relocd_offset < read_le32(&relocd->Size)) {
		size_t rva_offset = read_le32(&relocb->VirtualAddress);

		printk(FSP_DBG_LVL, "Relocs for RVA offset %zx\n", rva_offset);
		num_relocs = read_le32(&relocb->SizeOfBlock) - sizeof(*relocb);
		num_relocs /= sizeof(uint16_t);
		reloc = relative_offset(relocb, sizeof(*relocb));

		printk(FSP_DBG_LVL, "Num relocs in block: %zx\n", num_relocs);

		while (num_relocs > 0) {
			uint16_t reloc_val = read_le16(reloc);
			int type = reloc_type(reloc_val);
			size_t offset = reloc_offset(reloc_val);

			printk(FSP_DBG_LVL, "reloc type %x offset %zx\n",
				type, offset);

			if (type == EFI_IMAGE_REL_BASED_HIGHLOW) {
				uint32_t *reloc_addr;
				uint32_t val;

				offset += rva_offset;
				reloc_addr = (void *)&te_base[offset];
				val = read_le32(reloc_addr);

				printk(FSP_DBG_LVL, "Adjusting %p %x -> %x\n",
					reloc_addr, val, val + adj);
				write_le32(reloc_addr, val + adj);
			} else if (type != EFI_IMAGE_REL_BASED_ABSOLUTE) {
				printk(BIOS_ERR, "Unknown reloc type: %x\n",
					type);
				return -1;
			}
			num_relocs--;
			reloc++;
		}

		/* Track consumption of relocation directory contents. */
		relocd_offset += read_le32(&relocb->SizeOfBlock);
		/* Get next relocation block to process. */
		relocb = relative_offset(relocb,
					read_le32(&relocb->SizeOfBlock));
	}

	return 0;
}
Beispiel #10
0
unsigned long fw_cfg_acpi_tables(unsigned long start)
{
	BiosLinkerLoaderEntry *s;
	unsigned long *addrs, current;
	uint8_t *ptr;
	int rc, i, j, src, dst, max;

	rc = fw_cfg_check_file("etc/table-loader");
	if (rc < 0)
		return 0;

	printk(BIOS_DEBUG, "QEMU: found ACPI tables in fw_cfg.\n");

	max = rc / sizeof(*s);
	s = malloc(rc);
	addrs = malloc(max * sizeof(*addrs));
	fw_cfg_load_file("etc/table-loader", s);

	current = start;
	for (i = 0; i < max && s[i].command != 0; i++) {
		void *cksum_data;
		uint32_t cksum;
		uint32_t addr4;
		uint64_t addr8;
		switch (s[i].command) {
		case BIOS_LINKER_LOADER_COMMAND_ALLOCATE:
			current = ALIGN(current, s[i].alloc.align);
			rc = fw_cfg_check_file(s[i].alloc.file);
			if (rc < 0)
				goto err;
			printk(BIOS_DEBUG, "QEMU: loading \"%s\" to 0x%lx (len %d)\n",
			       s[i].alloc.file, current, rc);
			fw_cfg_load_file(s[i].alloc.file, (void*)current);
			addrs[i] = current;
			current += rc;
			break;

		case BIOS_LINKER_LOADER_COMMAND_ADD_POINTER:
			src = -1; dst = -1;
			for (j = 0; j < i; j++) {
				if (s[j].command != BIOS_LINKER_LOADER_COMMAND_ALLOCATE)
					continue;
				if (strcmp(s[j].alloc.file, s[i].pointer.dest_file) == 0)
					dst = j;
				if (strcmp(s[j].alloc.file, s[i].pointer.src_file) == 0)
					src = j;
			}
			if (src == -1 || dst == -1)
				goto err;

			switch (s[i].pointer.size) {
			case 4:
				ptr = (uint8_t *)addrs[dst];
				ptr += s[i].pointer.offset;
				addr4 = read_le32(ptr);
				addr4 += addrs[src];
				write_le32(ptr, addr4);
				break;

			case 8:
				ptr = (uint8_t *)addrs[dst];
				ptr += s[i].pointer.offset;
				addr8 = read_le64(ptr);
				addr8 += addrs[src];
				write_le64(ptr, addr8);
				break;

			default:
				/*
				 * Should not happen.  ACPI knows 1 and 2 byte ptrs
				 * too, but we are operating with 32bit offsets which
				 * would simply not fit in there ...
				 */
				printk(BIOS_DEBUG, "QEMU: acpi: unimplemented ptr size %d\n",
				       s[i].pointer.size);
				goto err;
			}
			break;

		case BIOS_LINKER_LOADER_COMMAND_ADD_CHECKSUM:
			dst = -1;
			for (j = 0; j < i; j++) {
				if (s[j].command != BIOS_LINKER_LOADER_COMMAND_ALLOCATE)
					continue;
				if (strcmp(s[j].alloc.file, s[i].cksum.file) == 0)
					dst = j;
			}
			if (dst == -1)
				goto err;

			ptr = (uint8_t *)(addrs[dst] + s[i].cksum.offset);
			cksum_data = (void *)(addrs[dst] + s[i].cksum.start);
			cksum = acpi_checksum(cksum_data, s[i].cksum.length);
			write_le8(ptr, cksum);
			break;

		default:
			printk(BIOS_DEBUG, "QEMU: acpi: unknown script cmd 0x%x @ %p\n",
			       s[i].command, s+i);
			goto err;
		};
	}

	printk(BIOS_DEBUG, "QEMU: loaded ACPI tables from fw_cfg.\n");
	free(s);
	free(addrs);
	return ALIGN(current, 16);

err:
	printk(BIOS_DEBUG, "QEMU: loading ACPI tables from fw_cfg failed.\n");
	free(s);
	free(addrs);
	return 0;
}
Beispiel #11
0
static int cmd_remove(vmfs_fs_t *fs,int argc,char *argv[])
{
   /* Dangerous */
   vmfs_lvm_t *lvm = (vmfs_lvm_t *)fs->dev;
   vmfs_volume_t *extent;
   DECL_ALIGNED_BUFFER(buf,512);
   vmfs_bitmap_entry_t entry;
   uint32_t i, blocks_per_segment, items_per_area,
            items_in_last_entry, old_area_count;

   fprintf(stderr, "Extents removal is experimental ! Use at your own risk !\n");
   while (1) {
      char *answer = local_readline("Are you sure you want to go further? [y/N] ");
      char a = answer[0];
      char null = answer[1];
      free(answer);
      if ((a == 0) || ((tolower(a) == 'n') && (null == 0)))
         return(2);
      if ((tolower(a) == 'y') && (null == 0))
         break;
   }
   if (lvm->lvm_info.num_extents == 1) {
      fprintf(stderr, "Can't remove an extent when there is only one\n");
      return(1);
   }

   /* Get last extent */
   extent = lvm->extents[lvm->loaded_extents - 1];

   /* Check whether data blocks are used on the last extents */
   blocks_per_segment = VMFS_LVM_SEGMENT_SIZE / vmfs_fs_get_blocksize(fs);
   for (i = extent->vol_info.first_segment * blocks_per_segment;
        i < extent->vol_info.last_segment * blocks_per_segment;
        i++)
      if (vmfs_block_get_status(fs, VMFS_BLK_FB_BUILD(i, 0))) {
         fprintf(stderr, "There is data on the last extent ; can't remove it\n");
         return(1);
      }

   /* At filesystem level, only the FBB needs to be downsized */
   fs->fbb->bmh.total_items -= extent->vol_info.num_segments * blocks_per_segment;
   items_per_area = fs->fbb->bmh.items_per_bitmap_entry *
                    fs->fbb->bmh.bmp_entries_per_area;
   old_area_count = fs->fbb->bmh.area_count;
   fs->fbb->bmh.area_count = (fs->fbb->bmh.total_items + items_per_area - 1) /
                             items_per_area;

   memset(buf, 0, buf_len);
   vmfs_bmh_write(&fs->fbb->bmh, buf);
   /* TODO: Error handling */
   vmfs_file_pwrite(fs->fbb->f, buf, buf_len, 0);

   /* Adjust new last entry */
   if ((items_in_last_entry =
        fs->fbb->bmh.total_items % fs->fbb->bmh.items_per_bitmap_entry)) {
      vmfs_bitmap_get_entry(fs->fbb, 0, fs->fbb->bmh.total_items, &entry);
      entry.free -= entry.total - items_in_last_entry;
      entry.total = items_in_last_entry;
      if (entry.ffree > entry.total)
         entry.ffree = 0;
      /* Adjust bitmap in last entry */
      if (items_in_last_entry % 8)
         entry.bitmap[items_in_last_entry / 8] &=
            0xff << (8 - (items_in_last_entry % 8));
      memset(&entry.bitmap[(items_in_last_entry + 7) / 8], 0,
         (fs->fbb->bmh.items_per_bitmap_entry - items_in_last_entry - 7) / 8);
      vmfs_bme_update(fs, &entry);
   }
   /* Truncate the fbb file depending on the new area count */
   if (old_area_count != fs->fbb->bmh.area_count)
      vmfs_file_truncate(fs->fbb->f, fs->fbb->bmh.hdr_size +
                            fs->fbb->bmh.area_count * fs->fbb->bmh.area_size);
   /* Adjust entries after the new last one */
   for (i = fs->fbb->bmh.total_items + (items_in_last_entry ?
           (fs->fbb->bmh.items_per_bitmap_entry - items_in_last_entry) : 0);
        i < fs->fbb->bmh.area_count * items_per_area;
        i += fs->fbb->bmh.items_per_bitmap_entry) {
      uint64_t pos;
      vmfs_bitmap_get_entry(fs->fbb, 0, i, &entry);
      pos = entry.mdh.pos;
      memset(&entry, 0, sizeof(entry));
      vmfs_device_write(fs->dev, pos, (u_char *)&entry, sizeof(entry));
   }

   /* At LVM level, all extents need to have the LVM information updated */
   for (i = 0; i < lvm->loaded_extents - 1; i++) {
      lvm->extents[i]->vol_info.blocks -= extent->vol_info.num_segments + 1;
      lvm->extents[i]->vol_info.num_extents--;
      lvm->extents[i]->vol_info.lvm_size =
         (lvm->extents[i]->vol_info.blocks -
            lvm->extents[i]->vol_info.num_extents) * VMFS_LVM_SEGMENT_SIZE;

      /* Until there is an API for that, do it by hand */
      m_pread(lvm->extents[i]->fd,buf,buf_len,
              lvm->extents[i]->vmfs_base + VMFS_LVMINFO_OFFSET);
      write_le64(buf, VMFS_LVMINFO_OFS_SIZE - VMFS_LVMINFO_OFFSET,
         lvm->extents[i]->vol_info.lvm_size);
      write_le64(buf, VMFS_LVMINFO_OFS_BLKS - VMFS_LVMINFO_OFFSET,
         lvm->extents[i]->vol_info.blocks);
      write_le32(buf, VMFS_LVMINFO_OFS_NUM_EXTENTS - VMFS_LVMINFO_OFFSET,
         lvm->extents[i]->vol_info.num_extents);
      m_pwrite(lvm->extents[i]->fd,buf,buf_len,
               lvm->extents[i]->vmfs_base + VMFS_LVMINFO_OFFSET);
   }
   return(0);
}