/* * Read in a data_t from disk. This makes this process safe regardless of * the processor's byte order or how the fmt_t structure is packed. */ static int read_data_chunk(SDL_RWops *rw, data_t *data) { /* skip reading the chunk ID, since it was already read at this point... */ data->chunkID = dataID; BAIL_IF_MACRO(!read_le32(rw, &data->chunkSize), NULL, 0); return(1); } /* read_data_chunk */
float read_le32f() { union { uint32_t i; float f; } u = { read_le32() }; return u.f; }
/* * Read in a fmt_t from disk. This makes this process safe regardless of * the processor's byte order or how the fmt_t structure is packed. * Note that the union "fmt" is not read in here; that is handled as * needed in the read_fmt_* functions. */ static int read_fmt_chunk(SDL_RWops *rw, fmt_t *fmt) { /* skip reading the chunk ID, since it was already read at this point... */ fmt->chunkID = fmtID; BAIL_IF_MACRO(!read_le32(rw, &fmt->chunkSize), NULL, 0); BAIL_IF_MACRO(fmt->chunkSize < 16, "WAV: Invalid chunk size", 0); fmt->next_chunk_offset = SDL_RWtell(rw) + fmt->chunkSize; BAIL_IF_MACRO(!read_le16(rw, &fmt->wFormatTag), NULL, 0); BAIL_IF_MACRO(!read_le16(rw, &fmt->wChannels), NULL, 0); BAIL_IF_MACRO(!read_le32(rw, &fmt->dwSamplesPerSec), NULL, 0); BAIL_IF_MACRO(!read_le32(rw, &fmt->dwAvgBytesPerSec), NULL, 0); BAIL_IF_MACRO(!read_le16(rw, &fmt->wBlockAlign), NULL, 0); BAIL_IF_MACRO(!read_le16(rw, &fmt->wBitsPerSample), NULL, 0); return(1); } /* read_fmt_chunk */
float IOChannel::read_float32(){ union{ float f; unsigned int i; }u; u.i = read_le32(); return u.f; }
/* Return 0 if equal. Non-zero if not equal. */ static int guid_compare(const EFI_GUID *le_guid, const EFI_GUID *native_guid) { if (read_le32(&le_guid->Data1) != native_guid->Data1) return 1; if (read_le16(&le_guid->Data2) != native_guid->Data2) return 1; if (read_le16(&le_guid->Data3) != native_guid->Data3) return 1; return memcmp(le_guid->Data4, native_guid->Data4, ARRAY_SIZE(le_guid->Data4)); }
static size_t section_data_size(const EFI_COMMON_SECTION_HEADER *csh) { size_t section_size; if (csh_size(csh) == 0x00ffffff) section_size = read_le32(&SECTION2_SIZE(csh)); else section_size = csh_size(csh); return section_size - section_data_offset(csh); }
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; }
static size_t bmp_hdr_size(const u8* file) { const size_t hdr_size = sizeof(BmpHeader); if(file) { BmpHeader* hdr = (BmpHeader*)file; const u32 ofs = read_le32(&hdr->bfOffBits); ENSURE(ofs >= hdr_size && "bmp_hdr_size invalid"); return ofs; } return hdr_size; }
float IOChannel::read_float32() { union { float f; boost::uint32_t i; } u; BOOST_STATIC_ASSERT(sizeof(u) == sizeof(u.i)); u.i = read_le32(); return u.f; }
/* Read volume information */ static int vmfs_volinfo_read(vmfs_volume_t *volume) { DECL_ALIGNED_BUFFER(buf,1024); vmfs_volinfo_t *vol = &volume->vol_info; if (m_pread(volume->fd,buf,buf_len,volume->vmfs_base) != buf_len) return(-1); vol->magic = read_le32(buf,VMFS_VOLINFO_OFS_MAGIC); if (vol->magic != VMFS_VOLINFO_MAGIC) { fprintf(stderr,"VMFS VolInfo: invalid magic number 0x%8.8x\n", vol->magic); return(-1); } vol->version = read_le32(buf,VMFS_VOLINFO_OFS_VER); vol->size = read_le32(buf,VMFS_VOLINFO_OFS_SIZE); vol->lun = buf[VMFS_VOLINFO_OFS_LUN]; vol->name = strndup((char *)buf+VMFS_VOLINFO_OFS_NAME, VMFS_VOLINFO_OFS_NAME_SIZE); read_uuid(buf,VMFS_VOLINFO_OFS_UUID,&vol->uuid); vol->lvm_size = read_le64(buf,VMFS_LVMINFO_OFS_SIZE); vol->blocks = read_le64(buf,VMFS_LVMINFO_OFS_BLKS); vol->num_segments = read_le32(buf,VMFS_LVMINFO_OFS_NUM_SEGMENTS); vol->first_segment = read_le32(buf,VMFS_LVMINFO_OFS_FIRST_SEGMENT); vol->last_segment = read_le32(buf,VMFS_LVMINFO_OFS_LAST_SEGMENT); vol->num_extents = read_le32(buf,VMFS_LVMINFO_OFS_NUM_EXTENTS); read_uuid(buf,VMFS_LVMINFO_OFS_UUID,&vol->lvm_uuid); #ifdef VMFS_CHECK { /* The LVM UUID also appears as a string, so we can check whether our formatting function is correct. */ char uuidstr1[M_UUID_BUFLEN], uuidstr2[M_UUID_BUFLEN]; memcpy(uuidstr1,buf+VMFS_LVMINFO_OFS_UUID_STR,M_UUID_BUFLEN-1); uuidstr1[M_UUID_BUFLEN-1] = 0; if (memcmp(m_uuid_to_str(vol->lvm_uuid,uuidstr2),uuidstr1, M_UUID_BUFLEN-1)) { fprintf(stderr, "uuid mismatch:\n%s\n%s\n",uuidstr1,uuidstr2); return(-1); } } #endif return(0); }
static size_t ffs_file_size(const EFI_FFS_FILE_HEADER *ffsfh) { size_t size; if (IS_FFS_FILE2(ffsfh)) size = read_le32(&FFS_FILE2_SIZE(ffsfh)); else { size = read_le8(&ffsfh->Size[0]) << 0; size |= read_le8(&ffsfh->Size[1]) << 8; size |= read_le8(&ffsfh->Size[2]) << 16; } return size; }
void CFileUnpacker::Read(const VfsPath& filename, const char magic[4]) { // if the file doesn't exist, LoadFile would raise an annoying error dialog. // since this (unfortunately) happens so often, we perform a separate // check and "just" raise an exception for the caller to handle. // (this is nicer than somehow squelching internal VFS error reporting) if(!VfsFileExists(filename)) throw PSERROR_File_OpenFailed(); // load the whole thing into memory if(g_VFS->LoadFile(filename, m_buf, m_bufSize) < 0) throw PSERROR_File_OpenFailed(); // make sure we read enough for the header if(m_bufSize < sizeof(FileHeader)) { m_buf.reset(); m_bufSize = 0; throw PSERROR_File_ReadFailed(); } // extract data from header FileHeader* header = (FileHeader*)m_buf.get(); m_version = read_le32(&header->version_le); const size_t payloadSize = (size_t)read_le32(&header->payloadSize_le); // check we've got the right kind of file // .. and that we read exactly headerSize+payloadSize if(strncmp(header->magic, magic, 4) != 0 || m_bufSize != sizeof(FileHeader)+payloadSize) { m_buf.reset(); m_bufSize = 0; throw PSERROR_File_InvalidType(); } m_unpackPos = sizeof(FileHeader); }
void coreboot_table_setup(void *base) { cb_header_t *header = base; void *ptr; int i; if (strncmp(header->signature, "LBIO", 4)) { ERROR("coreboot table signature corrupt!\n"); return; } ptr = base + header->header_bytes; for (i = 0; i < header->table_entries; i++) { cb_entry_t *entry = ptr; if (ptr - base >= header->header_bytes + header->table_bytes) { ERROR("coreboot table exceeds its bounds!\n"); break; } switch (read_le32(&entry->tag)) { case CB_TAG_SERIAL: memcpy(&coreboot_serial, &entry->serial, sizeof(coreboot_serial)); break; case CB_TAG_CBMEM_CONSOLE: setup_cbmem_console(read_le64(&entry->uint64)); break; default: /* There are many tags TF doesn't need to care about. */ break; } ptr += read_le32(&entry->size); } }
void BsaArchive::loadNamed(size_t count, std::istream& stream) { std::vector<std::string> names; names.reserve(count); std::vector<Entry> entries; entries.reserve(count); std::streamsize base = stream.tellg(); if(!stream.seekg(std::streampos(count) * -18, std::ios_base::end)) throw std::runtime_error("Failed to seek to archive footer ("+std::to_string(count)+" entries)"); for(size_t i = 0;i < count;++i) { std::array<char,13> name; stream.read(name.data(), name.size()-1); name.back() = '\0'; // Ensure null termination std::replace(name.begin(), name.end(), '\\', '/'); names.push_back(std::string(name.data())); int iscompressed = read_le16(stream); if(iscompressed != 0) throw std::runtime_error("Compressed entries not supported"); Entry entry; entry.mStart = ((i == 0) ? base : entries[i-1].mEnd); entry.mEnd = entry.mStart + read_le32(stream); entries.push_back(entry); } if(!stream.good()) throw std::runtime_error("Failed reading archive footer"); for(const std::string &name : names) { auto iter = std::lower_bound(mLookupName.begin(), mLookupName.end(), name); if(iter == mLookupName.end() || *iter != name) mLookupName.insert(iter, name); } mEntries.resize(mLookupName.size()); for(size_t i = 0;i < count;++i) { auto iter = std::find(mLookupName.cbegin(), mLookupName.cend(), names[i]); mEntries[std::distance(mLookupName.cbegin(), iter)] = entries[i]; } }
static void decompress_init(void) { struct trx_header *hdr = NULL; unsigned long kofs,klen; printf("Looking for TRX header... "); /* look for trx header, 32-bit data access */ for (flash_ofs = 0; flash_ofs < FLASH_BANK_SIZE; flash_ofs += TRX_ALIGN) { if (read_le32(&flash_base[flash_ofs]) == TRX_MAGIC) { hdr = (struct trx_header *)&flash_base[flash_ofs]; break; } } if (hdr == NULL) { printf("not found!\n"); /* no compressed kernel found, halting */ halt(); } /* compressed kernel is in the partition 0 or 1 */ kofs = read_le32(&hdr->offsets[1]); if (kofs == 0 || kofs > 65536) { klen = kofs-read_le32(&hdr->offsets[0]); kofs = read_le32(&hdr->offsets[0]); } else { klen = read_le32(&hdr->offsets[2]); if (klen > kofs) klen -= kofs; else klen = read_le32(&hdr->len)-kofs; } printf("found at %08X, kernel:%08X len:%08X\n", flash_ofs, kofs, klen); flash_ofs += kofs; flash_max = flash_ofs+klen; }
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; }
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; }
static jack_default_audio_sample_t read_sample_le32(const char *buffer) { int32_t s = (int32_t)read_le32(buffer); uint32_t upper_bound = (uint32_t)INT32_MAX + (s <= 0); return (jack_default_audio_sample_t)s / (jack_default_audio_sample_t)upper_bound; }
static jack_default_audio_sample_t read_sample_le32u(const char *buffer) { uint32_t u = read_le32(buffer); return (((jack_default_audio_sample_t) u) / ((jack_default_audio_sample_t) UINT32_MAX)) * 2.0 - 2.0; }
std::string getString() { size_t size = read_le32(); return getString(size); }
int getInt() { return read_le32(); }
std::string NIFStream::getString() { size_t size = read_le32(); return getString(size); }
static int init(sh_audio_t *sh) { context_t *ctx = calloc(1, sizeof(context_t)); const uint8_t *hdr = (const uint8_t *)(sh->wf + 1); const SpeexMode *spx_mode; const SpeexStereoState st_st = SPEEX_STEREO_STATE_INIT; // hack if (sh->wf && sh->wf->cbSize >= 80) ctx->hdr = speex_packet_to_header((char *)&sh->wf[1], sh->wf->cbSize); if (!ctx->hdr && sh->wf->cbSize == 0x72 && hdr[0] == 1 && hdr[1] == 0) { // speex.acm format: raw SpeexHeader dump ctx->hdr = calloc(1, sizeof(*ctx->hdr)); hdr += 2; hdr += 8; // identifier string hdr += 20; // version string ctx->hdr->speex_version_id = read_le32(&hdr); ctx->hdr->header_size = read_le32(&hdr); ctx->hdr->rate = read_le32(&hdr); ctx->hdr->mode = read_le32(&hdr); ctx->hdr->mode_bitstream_version = read_le32(&hdr); ctx->hdr->nb_channels = read_le32(&hdr); ctx->hdr->bitrate = read_le32(&hdr); ctx->hdr->frame_size = read_le32(&hdr); ctx->hdr->vbr = read_le32(&hdr); ctx->hdr->frames_per_packet = read_le32(&hdr); } if (!ctx->hdr) { mp_msg(MSGT_DECAUDIO, MSGL_ERR, "Invalid or missing extradata! Assuming defaults.\n"); ctx->hdr = calloc(1, sizeof(*ctx->hdr)); ctx->hdr->frames_per_packet = 1; ctx->hdr->mode = 0; if (sh->wf) { ctx->hdr->nb_channels = sh->wf->nChannels; ctx->hdr->rate = sh->wf->nSamplesPerSec; if (ctx->hdr->rate > 16000) ctx->hdr->mode = 2; else if (ctx->hdr->rate > 8000) ctx->hdr->mode = 1; } } if (ctx->hdr->nb_channels != 1 && ctx->hdr->nb_channels != 2) { mp_msg(MSGT_DECAUDIO, MSGL_WARN, "Invalid number of channels (%i), " "assuming mono\n", ctx->hdr->nb_channels); ctx->hdr->nb_channels = 1; } if (ctx->hdr->frames_per_packet > MAX_FRAMES_PER_PACKET) { mp_msg(MSGT_DECAUDIO, MSGL_WARN, "Invalid number of frames per packet (%i), " "assuming 1\n", ctx->hdr->frames_per_packet); ctx->hdr->frames_per_packet = 1; } switch (ctx->hdr->mode) { case 0: spx_mode = &speex_nb_mode; break; case 1: spx_mode = &speex_wb_mode; break; case 2: spx_mode = &speex_uwb_mode; break; default: mp_msg(MSGT_DECAUDIO, MSGL_WARN, "Unknown speex mode (%i)\n", ctx->hdr->mode); spx_mode = &speex_nb_mode; } ctx->dec_context = speex_decoder_init(spx_mode); speex_bits_init(&ctx->bits); memcpy(&ctx->stereo, &st_st, sizeof(ctx->stereo)); // hack part 2 sh->channels = ctx->hdr->nb_channels; sh->samplerate = ctx->hdr->rate; sh->samplesize = 2; sh->sample_format = AF_FORMAT_S16_NE; sh->context = ctx; return 1; }
static uint64_t read_le64(uint64_t *p) { return read_le32((void *)p) | (uint64_t)read_le32((void *)p + 4) << 32; }
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; }
wavStream(std::istream *_fstream) : alureStream(_fstream), format(0), dataStart(0) { ALubyte buffer[25]; ALuint length; if(!fstream->read(reinterpret_cast<char*>(buffer), 12) || memcmp(buffer, "RIFF", 4) != 0 || memcmp(buffer+8, "WAVE", 4) != 0) return; while(!dataStart || format == AL_NONE) { char tag[4]; if(!fstream->read(tag, 4)) break; /* read chunk length */ length = read_le32(fstream); if(memcmp(tag, "fmt ", 4) == 0 && length >= 16) { /* Data type (should be 1 for PCM data, 3 for float PCM data, * 7 for muLaw, and 17 for IMA4 data) */ int type = read_le16(fstream); if(type != 0x0001 && type != 0x0003 && type != 0x0007 && type != 0x0011) break; /* mono or stereo data */ channels = read_le16(fstream); /* sample frequency */ samplerate = read_le32(fstream); /* skip average bytes per second */ fstream->ignore(4); /* bytes per block */ blockAlign = read_le16(fstream); if(blockAlign == 0) break; /* bits per sample */ sampleSize = read_le16(fstream); length -= 16; /* Look for any extra data and try to find the format */ ALuint extrabytes = 0; if(length >= 2) { extrabytes = read_le16(fstream); length -= 2; } extrabytes = std::min<ALuint>(extrabytes, length); if(type == 0x0001) format = GetSampleFormat(channels, sampleSize, false); else if(type == 0x0003) format = GetSampleFormat(channels, sampleSize, true); else if(type == 0x0007) { if(sampleSize == 8) { if(channels == 1) format = AL_FORMAT_MONO_MULAW; else if(channels == 2) format = AL_FORMAT_STEREO_MULAW; else if(channels == 4) format = AL_FORMAT_QUAD_MULAW; else if(channels == 6) format = AL_FORMAT_51CHN_MULAW; else if(channels == 7) format = AL_FORMAT_61CHN_MULAW; else if(channels == 8) format = AL_FORMAT_71CHN_MULAW; } } else if(type == 0x0011 && extrabytes >= 2) { int samples = read_le16(fstream); length -= 2; /* AL_EXT_IMA4 only supports 36 bytes-per-channel block * alignment, which has 65 uncompressed sample frames */ if(blockAlign == 36*channels && samples == 65*channels && alIsExtensionPresent("AL_EXT_IMA4")) { if(channels == 1) format = AL_FORMAT_MONO_IMA4; else if(channels == 2) format = AL_FORMAT_STEREO_IMA4; } } } else if(memcmp(tag, "data", 4) == 0) { dataStart = fstream->tellg(); dataLen = remLen = length; } fstream->seekg(length, std::ios_base::cur); } if(dataStart > 0 && format != AL_NONE) fstream->seekg(dataStart); }
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; }
unsigned int getUInt() { return read_le32(); }
/* * All keys are ASCII and length is 2..255 * * UTF-8: Artist, Album, Title, Genre * Integer: Track (N or N/M) * Date: Year (release), "Record Date" * * UTF-8 strings are NOT zero terminated. * * Also support "discnumber" (vorbis) and "disc" (non-standard) */ static int ape_parse_one(const char *buf, int size, char **keyp, char **valp) { int pos = 0; while (size - pos > 8) { uint32_t val_len, flags; char *key, *val; int max_key_len, key_len; val_len = read_le32(buf + pos); pos += 4; flags = read_le32(buf + pos); pos += 4; max_key_len = size - pos - val_len - 1; if (max_key_len < 0) { /* corrupt */ break; } for (key_len = 0; key_len < max_key_len && buf[pos + key_len]; key_len++) ; /* nothing */ if (buf[pos + key_len]) { /* corrupt */ break; } if (!AF_IS_UTF8(flags)) { /* ignore binary data */ pos += key_len + 1 + val_len; continue; } key = xstrdup(buf + pos); pos += key_len + 1; /* should not be NUL-terminated */ val = xstrndup(buf + pos, val_len); pos += val_len; /* could be moved to comment.c but I don't think anyone else would use it */ if (!strcasecmp(key, "record date") || !strcasecmp(key, "year")) { free(key); key = xstrdup("date"); } if (!strcasecmp(key, "date")) { /* Date format * * 1999-08-11 12:34:56 * 1999-08-11 12:34 * 1999-08-11 * 1999-08 * 1999 * 1999-W34 (week 34, totally crazy) * * convert to year, pl.c supports only years anyways * * FIXME: which one is the most common tag (year or record date)? */ if (strlen(val) > 4) val[4] = 0; } *keyp = key; *valp = val; return pos; } return -1; }
ALuint WaveDecoder::read(ALvoid *ptr, ALuint count) { mFile->clear(); auto pos = mFile->tellg(); size_t len = count * mFrameSize; ALuint total = 0; if(pos < mEnd) { len = std::min<std::istream::pos_type>(len, mEnd-pos); #ifdef __BIG_ENDIAN__ switch(mSampleType) { case SampleType_Float32: while(total < len && mFile->good() && !mFile->eof()) { char temp[256]; size_t todo = std::min(len-total, sizeof(temp)); mFile->read(temp, todo); std::streamsize got = mFile->gcount(); for(std::streamsize i = 0;i < got;++i) reinterpret_cast<char*>(ptr)[total+i] = temp[i^3]; total += got; } total /= mFrameSize; break; case SampleType_Int16: while(total < len && mFile->good() && !mFile->eof()) { char temp[256]; size_t todo = std::min(len-total, sizeof(temp)); mFile->read(temp, todo); std::streamsize got = mFile->gcount(); for(std::streamsize i = 0;i < got;++i) reinterpret_cast<char*>(ptr)[total+i] = temp[i^1]; total += got; } total /= mFrameSize; break; case SampleType_UInt8: case SampleType_Mulaw: #else { #endif mFile->read(reinterpret_cast<char*>(ptr), len); total = mFile->gcount() / mFrameSize; } } return total; } SharedPtr<Decoder> WaveDecoderFactory::createDecoder(SharedPtr<std::istream> file) { ChannelConfig channels = ChannelConfig_Mono; SampleType type = SampleType_UInt8; ALuint frequency = 0; ALuint framesize = 0; ALuint loop_pts[2]{0, 0}; ALuint blockalign = 0; ALuint framealign = 0; char tag[4]{}; if(!file->read(tag, 4) || file->gcount() != 4 || memcmp(tag, "RIFF", 4) != 0) return SharedPtr<Decoder>(nullptr); ALuint totalsize = read_le32(*file) & ~1u; if(!file->read(tag, 4) || file->gcount() != 4 || memcmp(tag, "WAVE", 4) != 0) return SharedPtr<Decoder>(nullptr); while(file->good() && !file->eof() && totalsize > 8) { if(!file->read(tag, 4) || file->gcount() != 4) return SharedPtr<Decoder>(nullptr); ALuint size = read_le32(*file); if(size < 2) return SharedPtr<Decoder>(nullptr); totalsize -= 8; size = std::min((size+1) & ~1u, totalsize); totalsize -= size; if(memcmp(tag, "fmt ", 4) == 0) { /* 'fmt ' tag needs at least 16 bytes. */ if(size < 16) goto next_chunk; /* format type */ ALushort fmttype = read_le16(*file); size -= 2; /* mono or stereo data */ int chancount = read_le16(*file); size -= 2; /* sample frequency */ frequency = read_le32(*file); size -= 4; /* skip average bytes per second */ read_le32(*file); size -= 4; /* bytes per block */ blockalign = read_le16(*file); size -= 2; /* bits per sample */ int bitdepth = read_le16(*file); size -= 2; /* Look for any extra data and try to find the format */ ALuint extrabytes = 0; if(size >= 2) { extrabytes = read_le16(*file); size -= 2; } extrabytes = std::min<ALuint>(extrabytes, size); /* Format type should be 0x0001 for integer PCM data, 0x0003 for * float PCM data, 0x0007 for muLaw, and 0xFFFE extensible data. */ if(fmttype == 0x0001) { if(chancount == 1) channels = ChannelConfig_Mono; else if(chancount == 2) channels = ChannelConfig_Stereo; else goto next_chunk; if(bitdepth == 8) type = SampleType_UInt8; else if(bitdepth == 16) type = SampleType_Int16; else goto next_chunk; } else if(fmttype == 0x0003) { if(chancount == 1) channels = ChannelConfig_Mono; else if(chancount == 2) channels = ChannelConfig_Stereo; else goto next_chunk; if(bitdepth == 32) type = SampleType_Float32; else goto next_chunk; } else if(fmttype == 0x0007) { if(chancount == 1) channels = ChannelConfig_Mono; else if(chancount == 2) channels = ChannelConfig_Stereo; else goto next_chunk; if(bitdepth == 8) type = SampleType_Mulaw; else goto next_chunk; } else if(fmttype == 0xFFFE) { if(size < 22) goto next_chunk; char subtype[16]; ALushort validbits = read_le16(*file); size -= 2; ALuint chanmask = read_le32(*file); size -= 4; file->read(subtype, 16); size -= file->gcount(); /* Padded bit depths not supported */ if(validbits != bitdepth) goto next_chunk; if(memcmp(subtype, SUBTYPE_BFORMAT_PCM, 16) == 0 || memcmp(subtype, SUBTYPE_BFORMAT_FLOAT, 16) == 0) { if(chanmask != 0) goto next_chunk; if(chancount == 3) channels = ChannelConfig_BFmt_WXY; else if(chancount == 4) channels = ChannelConfig_BFmt_WXYZ; else goto next_chunk; } else if(memcmp(subtype, SUBTYPE_PCM, 16) == 0 || memcmp(subtype, SUBTYPE_FLOAT, 16) == 0) { if(chancount == 1 && chanmask == CHANNELS_MONO) channels = ChannelConfig_Mono; else if(chancount == 2 && chanmask == CHANNELS_STEREO) channels = ChannelConfig_Stereo; else if(chancount == 4 && chanmask == CHANNELS_QUAD) channels = ChannelConfig_Quad; else if(chancount == 6 && (chanmask == CHANNELS_5DOT1 || chanmask == CHANNELS_5DOT1_REAR)) channels = ChannelConfig_X51; else if(chancount == 7 && chanmask == CHANNELS_6DOT1) channels = ChannelConfig_X61; else if(chancount == 8 && chanmask == CHANNELS_7DOT1) channels = ChannelConfig_X71; else goto next_chunk; } if(memcmp(subtype, SUBTYPE_PCM, 16) == 0 || memcmp(subtype, SUBTYPE_BFORMAT_PCM, 16) == 0) { if(bitdepth == 8) type = SampleType_UInt8; else if(bitdepth == 16) type = SampleType_Int16; else goto next_chunk; } else if(memcmp(subtype, SUBTYPE_FLOAT, 16) == 0 || memcmp(subtype, SUBTYPE_BFORMAT_FLOAT, 16) == 0) { if(bitdepth == 32) type = SampleType_Float32; else goto next_chunk; } else goto next_chunk; } else goto next_chunk; framesize = FramesToBytes(1, channels, type); /* Calculate the number of frames per block (ADPCM will need extra * consideration). */ framealign = blockalign / framesize; } else if(memcmp(tag, "smpl", 4) == 0) { /* sampler data needs at least 36 bytes */ if(size < 36) goto next_chunk; /* Most of this only affects MIDI sampling, but we only care about * the loop definitions at the end. */ /*ALuint manufacturer =*/ read_le32(*file); /*ALuint product =*/ read_le32(*file); /*ALuint smpperiod =*/ read_le32(*file); /*ALuint unitynote =*/ read_le32(*file); /*ALuint pitchfrac =*/ read_le32(*file); /*ALuint smptefmt =*/ read_le32(*file); /*ALuint smpteoffset =*/ read_le32(*file); ALuint loopcount = read_le32(*file); /*ALuint extrabytes =*/ read_le32(*file); size -= 36; for(ALuint i = 0;i < loopcount && size >= 24;++i) { /*ALuint id =*/ read_le32(*file); ALuint type = read_le32(*file); ALuint loopstart = read_le32(*file); ALuint loopend = read_le32(*file); /*ALuint frac =*/ read_le32(*file); ALuint numloops = read_le32(*file); size -= 24; /* Only handle indefinite forward loops. */ if(type == 0 || numloops == 0) { loop_pts[0] = loopstart; loop_pts[1] = loopend; break; } } } else if(memcmp(tag, "data", 4) == 0) { if(framesize == 0) goto next_chunk; /* Make sure there's at least one sample frame of audio data. */ std::istream::pos_type start = file->tellg(); std::istream::pos_type end = start + std::istream::pos_type(size - (size%framesize)); if(end-start >= framesize) { /* Loop points are byte offsets relative to the data start. * Convert to sample frame offsets. */ return SharedPtr<Decoder>(new WaveDecoder(file, channels, type, frequency, framesize, start, end, loop_pts[0] / blockalign * framealign, loop_pts[1] / blockalign * framealign )); } } next_chunk: if(size > 0) file->ignore(size); } return SharedPtr<Decoder>(nullptr); }