- chunk_offsets_malloced = true;
- }
-
- /* Set the implicit offset of the first chunk if it's included in the
- * needed chunks. */
- if (start_chunk == 0)
- chunk_offsets[0] = 0;
-
- /* Calculate the index of the first needed entry in the chunk table. */
- u64 start_table_idx = (start_chunk == 0) ? 0 : start_chunk - 1;
-
- /* Calculate the number of entries that need to be read from the chunk
- * table. */
- u64 num_needed_chunk_entries = (start_chunk == 0) ?
- num_alloc_chunk_entries - 1 : num_alloc_chunk_entries;
-
- /* Calculate the number of bytes of data that need to be read from the
- * chunk table. */
- size_t chunk_table_needed_size =
- num_needed_chunk_entries * chunk_entry_size;
- if ((u64)chunk_table_needed_size !=
- num_needed_chunk_entries * chunk_entry_size)
- {
- ERROR("Compressed read request too large to fit into memory!");
- ret = WIMLIB_ERR_NOMEM;
- goto out_free_chunk_offsets;
- }
-
- /* Calculate the byte offset, in the WIM file, of the first chunk table
- * entry to read. Take into account that if the WIM file is in the
- * special "pipable" format, then the chunk table is at the end of the
- * resource, not the beginning. */
- u64 file_offset_of_needed_chunk_entries =
- lte->resource_entry.offset + (start_table_idx *
- chunk_entry_size);
- if (lte->is_pipable)
- file_offset_of_needed_chunk_entries += lte->resource_entry.size -
- chunk_table_size;
-
- /* Read the needed chunk table entries into the end of the chunk_offsets
- * buffer. */
- void *chunk_tab_data = (u8*)&chunk_offsets[num_alloc_chunk_entries] -
- chunk_table_needed_size;
- ret = full_pread(in_fd, chunk_tab_data, chunk_table_needed_size,
- file_offset_of_needed_chunk_entries);
- if (ret)
- goto read_error;
-
- /* Now fill in chunk_offsets from the entries we have read in
- * chunk_tab_data. Careful: chunk_offsets aliases chunk_tab_data, which
- * breaks C's aliasing rules when we read 32-bit integers and store
- * 64-bit integers. But since the operations are safe as long as the
- * compiler doesn't mess with their order, we use the gcc may_alias
- * extension to tell the compiler that loads from the 32-bit integers
- * may alias stores to the 64-bit integers. */
- {
- typedef le64 __attribute__((may_alias)) aliased_le64_t;
- typedef le32 __attribute__((may_alias)) aliased_le32_t;
- u64 *chunk_offsets_p = chunk_offsets;
- u64 i;