| 1234 | } |
| 1235 | |
| 1236 | int cbfs_export_entry(struct cbfs_image *image, const char *entry_name, |
| 1237 | const char *filename, uint32_t arch, bool do_processing) |
| 1238 | { |
| 1239 | struct cbfs_file *entry = cbfs_get_entry(image, entry_name); |
| 1240 | struct buffer buffer; |
| 1241 | if (!entry) { |
| 1242 | ERROR("File not found: %s\n", entry_name); |
| 1243 | return -1; |
| 1244 | } |
| 1245 | |
| 1246 | unsigned int compressed_size = be32toh(entry->len); |
| 1247 | unsigned int decompressed_size = 0; |
| 1248 | unsigned int compression = cbfs_file_get_compression_info(entry, |
| 1249 | &decompressed_size); |
| 1250 | unsigned int buffer_len; |
| 1251 | decomp_func_ptr decompress; |
| 1252 | |
| 1253 | if (do_processing) { |
| 1254 | decompress = decompression_function(compression); |
| 1255 | if (!decompress) { |
| 1256 | ERROR("looking up decompression routine failed\n"); |
| 1257 | return -1; |
| 1258 | } |
| 1259 | buffer_len = decompressed_size; |
| 1260 | } else { |
| 1261 | /* Force nop decompression */ |
| 1262 | decompress = decompression_function(CBFS_COMPRESS_NONE); |
| 1263 | buffer_len = compressed_size; |
| 1264 | } |
| 1265 | |
| 1266 | LOG("Found file %.30s at 0x%x, type %.12s, compressed %d, size %d\n", |
| 1267 | entry_name, cbfs_get_entry_addr(image, entry), |
| 1268 | get_cbfs_entry_type_name(be32toh(entry->type)), compressed_size, |
| 1269 | decompressed_size); |
| 1270 | |
| 1271 | buffer_init(&buffer, strdup("(cbfs_export_entry)"), NULL, 0); |
| 1272 | buffer.data = malloc(buffer_len); |
| 1273 | buffer.size = buffer_len; |
| 1274 | |
| 1275 | if (decompress(CBFS_SUBHEADER(entry), compressed_size, |
| 1276 | buffer.data, buffer.size, NULL)) { |
| 1277 | ERROR("decompression failed for %s\n", entry_name); |
| 1278 | buffer_delete(&buffer); |
| 1279 | return -1; |
| 1280 | } |
| 1281 | |
| 1282 | /* |
| 1283 | * We want to export stages and payloads as ELFs, not with coreboot's |
| 1284 | * custom stage/SELF binary formats, so we need to do extra processing |
| 1285 | * to turn them back into an ELF. |
| 1286 | */ |
| 1287 | if (do_processing) { |
| 1288 | int (*make_elf)(struct buffer *, uint32_t, |
| 1289 | struct cbfs_file *) = NULL; |
| 1290 | switch (be32toh(entry->type)) { |
| 1291 | case CBFS_TYPE_STAGE: |
| 1292 | make_elf = cbfs_stage_make_elf; |
| 1293 | break; |
no test coverage detected