image.c (49188B)
1 #include "obj/image.h" 2 3 #include <kit/object.h> 4 #include <string.h> 5 6 #include "core/diag.h" 7 8 /* A contiguous piece of output. Both the segment path (flat load image) and 9 * the section path (ordered concatenation) lower to a list of these. 10 * 11 * data/size : the bytes to emit (borrowed from object_bytes). 12 * addr/end : layout addresses for the segment path; for the section path 13 * these are synthesized so the ranges pack with no holes. 14 * name : diagnostic spelling. 15 * order : stable tiebreak for equal addresses. */ 16 typedef struct ImageRange { 17 const uint8_t* data; 18 uint64_t size; 19 uint64_t original_addr; 20 uint64_t addr; 21 uint64_t end; /* addr + on-disk size (file end) */ 22 KitSlice name; 23 uint32_t order; 24 } ImageRange; 25 26 static int u64_add(uint64_t a, uint64_t b, uint64_t* out) { 27 if (UINT64_MAX - a < b) return 0; 28 *out = a + b; 29 return 1; 30 } 31 32 static int u64_add_bias(uint64_t a, int64_t bias, uint64_t* out) { 33 if (bias >= 0) return u64_add(a, (uint64_t)bias, out); 34 { 35 uint64_t mag = (uint64_t)(-(bias + 1)) + 1u; 36 if (a < mag) return 0; 37 *out = a - mag; 38 return 1; 39 } 40 } 41 42 static int u64_align_up(uint64_t v, uint64_t align, uint64_t* out) { 43 uint64_t rem; 44 if (align <= 1) { 45 *out = v; 46 return 1; 47 } 48 rem = v % align; 49 if (!rem) { 50 *out = v; 51 return 1; 52 } 53 return u64_add(v, align - rem, out); 54 } 55 56 static void put_u32le(uint8_t* p, uint32_t v) { 57 p[0] = (uint8_t)v; 58 p[1] = (uint8_t)(v >> 8); 59 p[2] = (uint8_t)(v >> 16); 60 p[3] = (uint8_t)(v >> 24); 61 } 62 63 static void put_u64le(uint8_t* p, uint64_t v) { 64 put_u32le(p, (uint32_t)v); 65 put_u32le(p + 4, (uint32_t)(v >> 32)); 66 } 67 68 static int ascii_lower(int c) { 69 return (c >= 'A' && c <= 'Z') ? c + ('a' - 'A') : c; 70 } 71 72 static int slice_ieq(KitSlice a, KitSlice b) { 73 size_t i; 74 if (a.len != b.len) return 0; 75 for (i = 0; i < a.len; ++i) { 76 if (ascii_lower((unsigned char)a.s[i]) != 77 ascii_lower((unsigned char)b.s[i])) 78 return 0; 79 } 80 return 1; 81 } 82 83 static int slice_eq(KitSlice a, KitSlice b) { 84 if (a.len != b.len) return 0; 85 return a.len == 0 || memcmp(a.s, b.s, a.len) == 0; 86 } 87 88 static int name_in_list(KitSlice name, const KitSlice* list, uint32_t n) { 89 uint32_t i; 90 for (i = 0; i < n; ++i) { 91 if (slice_eq(name, list[i])) return 1; 92 } 93 return 0; 94 } 95 96 #define KIT_IHEX_DATA_MAX 16u 97 #define KIT_SREC_DATA_MAX 16u 98 99 static const char kHex[] = "0123456789ABCDEF"; 100 101 static void line_append_hex_u8(char* line, size_t* n, uint8_t v) { 102 line[(*n)++] = kHex[(v >> 4) & 0xfu]; 103 line[(*n)++] = kHex[v & 0xfu]; 104 } 105 106 static void line_append_hex_u16(char* line, size_t* n, uint16_t v) { 107 line_append_hex_u8(line, n, (uint8_t)(v >> 8)); 108 line_append_hex_u8(line, n, (uint8_t)v); 109 } 110 111 static void line_append_hex_u64_be(char* line, size_t* n, uint64_t v, 112 uint32_t nbytes) { 113 uint32_t i; 114 uint32_t shift = (nbytes - 1u) * 8u; 115 for (i = 0; i < nbytes; ++i, shift -= 8u) { 116 line_append_hex_u8(line, n, (uint8_t)(v >> shift)); 117 } 118 } 119 120 static KitStatus write_line(KitWriter* out, const char* data, size_t n) { 121 return (kit_writer_write(out, data, n) == KIT_OK) ? KIT_OK : KIT_IO; 122 } 123 124 static KitSlice drop_pt_prefix(KitSlice s) { 125 if (s.len > 3 && ascii_lower((unsigned char)s.s[0]) == 'p' && 126 ascii_lower((unsigned char)s.s[1]) == 't' && s.s[2] == '_') { 127 s.s += 3; 128 s.len -= 3; 129 } 130 return s; 131 } 132 133 static int segment_name_match(KitSlice have, KitSlice want) { 134 have = drop_pt_prefix(have); 135 want = drop_pt_prefix(want); 136 return slice_ieq(have, want); 137 } 138 139 static int is_load_segment(KitSlice name) { 140 return segment_name_match(name, KIT_SLICE_LIT("LOAD")); 141 } 142 143 static int segment_in_list(KitSlice have, const KitSlice* list, uint32_t n) { 144 uint32_t i; 145 for (i = 0; i < n; ++i) { 146 if (segment_name_match(have, list[i])) return 1; 147 } 148 return 0; 149 } 150 151 static int select_segment(KitObjFmt fmt, const KitObjSegInfo* seg, 152 const KitImageOptions* opts) { 153 /* --remove-section drops a segment by name regardless of base selection. */ 154 if (opts->nremove_sections && 155 segment_in_list(seg->name, opts->remove_sections, 156 opts->nremove_sections)) 157 return 0; 158 /* --only-section, when given, is the authoritative keep-set. */ 159 if (opts->nonly_sections) 160 return segment_in_list(seg->name, opts->only_sections, 161 opts->nonly_sections); 162 if (opts->nsegments == 0) { 163 if (fmt == KIT_OBJ_ELF) return is_load_segment(seg->name); 164 return 1; 165 } 166 return segment_in_list(seg->name, opts->segments, opts->nsegments); 167 } 168 169 static int select_alloc_section(const KitObjSecInfo* sec, 170 const KitImageOptions* opts) { 171 if (!(sec->flags & KIT_SF_ALLOC)) return 0; 172 if (opts->nonly_sections && 173 !name_in_list(sec->name, opts->only_sections, opts->nonly_sections)) 174 return 0; 175 if (opts->nremove_sections && 176 name_in_list(sec->name, opts->remove_sections, opts->nremove_sections)) 177 return 0; 178 return 1; 179 } 180 181 bool obj_image_segment_selected(KitObjFmt fmt, const KitObjSegInfo* seg, 182 const KitImageOptions* opts) { 183 /* A segment contributes bytes to the emitted image iff the base/only/remove 184 * policy keeps it AND it has on-disk contents. This is the exact predicate 185 * the segment collector applies (see collect_ranges): callers that need to 186 * report "what the image contains" must route through here rather than 187 * reimplementing the matching, which would drift from the emitter. */ 188 if (seg->file_size == 0) return false; 189 return select_segment(fmt, seg, opts) != 0; 190 } 191 192 static uint64_t seg_addr(const KitObjSegInfo* seg, 193 const KitImageOptions* opts) { 194 switch ((KitImageAddrKind)opts->addr) { 195 case KIT_IMAGE_ADDR_PADDR: 196 case KIT_IMAGE_ADDR_LMA: 197 return seg->paddr; 198 case KIT_IMAGE_ADDR_VADDR: 199 default: 200 return seg->vaddr; 201 } 202 } 203 204 static KitStatus ranges_push(const KitContext* ctx, ImageRange** ranges, 205 uint32_t* nranges, uint32_t* cap, 206 const ImageRange* r) { 207 KitHeap* h = ctx->heap; 208 if (*nranges >= *cap) { 209 uint32_t newcap = *cap ? *cap * 2u : 4u; 210 ImageRange* next; 211 if (newcap <= *cap) return KIT_NOMEM; 212 next = (ImageRange*)h->alloc(h, (size_t)newcap * sizeof(*next), 213 _Alignof(ImageRange)); 214 if (!next) return KIT_NOMEM; 215 if (*ranges) { 216 memcpy(next, *ranges, (size_t)(*nranges) * sizeof(*next)); 217 h->free(h, *ranges, (size_t)(*cap) * sizeof(**ranges)); 218 } 219 *ranges = next; 220 *cap = newcap; 221 } 222 (*ranges)[(*nranges)++] = *r; 223 return KIT_OK; 224 } 225 226 static void ranges_free(const KitContext* ctx, ImageRange* ranges, 227 uint32_t cap) { 228 if (ranges) ctx->heap->free(ctx->heap, ranges, (size_t)cap * sizeof(*ranges)); 229 } 230 231 static void ranges_sort(ImageRange* r, uint32_t n) { 232 uint32_t i; 233 for (i = 1; i < n; ++i) { 234 ImageRange key = r[i]; 235 uint32_t j = i; 236 while (j > 0) { 237 int move = r[j - 1].addr > key.addr || 238 (r[j - 1].addr == key.addr && r[j - 1].order > key.order); 239 if (!move) break; 240 r[j] = r[j - 1]; 241 --j; 242 } 243 r[j] = key; 244 } 245 } 246 247 /* Convert possibly-overlapping input ranges into disjoint fragments. Ranges 248 * are applied in selection order; a later range replaces bytes from every 249 * earlier range it covers. This is deterministic for relocatable formats 250 * whose allocated sections commonly all report address zero, and avoids 251 * allocating a potentially enormous flat staging buffer. */ 252 static KitStatus normalize_overlaps(const KitContext* ctx, 253 const ImageRange* source, 254 uint32_t nsource, ImageRange** ranges_out, 255 uint32_t* nranges_out, uint32_t* cap_out) { 256 ImageRange* ranges = NULL; 257 uint32_t nranges = 0, cap = 0, i; 258 KitStatus st; 259 260 *ranges_out = NULL; 261 *nranges_out = 0; 262 *cap_out = 0; 263 for (i = 0; i < nsource; ++i) { 264 ImageRange incoming = source[i]; 265 uint32_t j = 0; 266 while (j < nranges) { 267 ImageRange old = ranges[j]; 268 if (old.end <= incoming.addr || old.addr >= incoming.end) { 269 ++j; 270 continue; 271 } 272 if (old.addr < incoming.addr) { 273 /* Preserve the old prefix. If it also has a suffix, append that as a 274 * second borrowed fragment before installing the incoming range. */ 275 ranges[j].size = incoming.addr - old.addr; 276 ranges[j].end = incoming.addr; 277 if (old.end > incoming.end) { 278 ImageRange suffix = old; 279 uint64_t delta = incoming.end - old.addr; 280 suffix.data += (size_t)delta; 281 suffix.size = old.end - incoming.end; 282 suffix.original_addr += delta; 283 suffix.addr = incoming.end; 284 st = ranges_push(ctx, &ranges, &nranges, &cap, &suffix); 285 if (st != KIT_OK) { 286 ranges_free(ctx, ranges, cap); 287 return st; 288 } 289 } 290 ++j; 291 continue; 292 } 293 if (old.end > incoming.end) { 294 uint64_t delta = incoming.end - old.addr; 295 ranges[j].data += (size_t)delta; 296 ranges[j].size = old.end - incoming.end; 297 ranges[j].original_addr += delta; 298 ranges[j].addr = incoming.end; 299 ++j; 300 continue; 301 } 302 /* Fully covered old fragment. Preserve no ordering significance here; 303 * the final address sort establishes the emission order. */ 304 if (j + 1u < nranges) 305 memmove(&ranges[j], &ranges[j + 1u], 306 (size_t)(nranges - j - 1u) * sizeof(*ranges)); 307 --nranges; 308 } 309 st = ranges_push(ctx, &ranges, &nranges, &cap, &incoming); 310 if (st != KIT_OK) { 311 ranges_free(ctx, ranges, cap); 312 return st; 313 } 314 } 315 ranges_sort(ranges, nranges); 316 *ranges_out = ranges; 317 *nranges_out = nranges; 318 *cap_out = cap; 319 return KIT_OK; 320 } 321 322 static KitStatus collect_ranges(const KitContext* ctx, KitObjFile* obj, 323 const KitSlice* bytes, 324 const KitImageOptions* opts, 325 ImageRange** ranges_out, uint32_t* nranges_out, 326 uint32_t* cap_out, uint64_t* mem_end_out) { 327 KitObjSegIter* it = NULL; 328 KitObjSegInfo seg; 329 ImageRange* ranges = NULL; 330 uint32_t nranges = 0, cap = 0, order = 0; 331 uint64_t mem_end_max = 0; 332 KitStatus st; 333 KitObjFmt fmt; 334 335 *ranges_out = NULL; 336 *nranges_out = 0; 337 *cap_out = 0; 338 *mem_end_out = 0; 339 340 fmt = kit_obj_fmt(obj); 341 st = kit_obj_segiter_new(obj, &it); 342 if (st != KIT_OK) return st; 343 344 while (kit_obj_segiter_next(it, &seg) == KIT_ITER_ITEM) { 345 ImageRange r; 346 uint64_t addr; 347 uint64_t end; 348 349 if (!select_segment(fmt, &seg, opts)) { 350 ++order; 351 continue; 352 } 353 /* Memory-span accounting runs for every selected loadable segment, 354 * including BSS-only ones (file_size == 0) that contribute no bytes but do 355 * extend the in-memory footprint an Image header's image_size must report. 356 * vsize (>= file_size) carries the trailing BSS. */ 357 { 358 uint64_t maddr, mend; 359 uint64_t msize = seg.vsize >= seg.file_size ? seg.vsize : seg.file_size; 360 if (u64_add_bias(seg_addr(&seg, opts), opts->bias, &maddr) && 361 u64_add(maddr, msize, &mend) && mend > mem_end_max) 362 mem_end_max = mend; 363 } 364 if (seg.file_size == 0) { 365 ++order; 366 continue; 367 } 368 if (seg.file_off > bytes->len || seg.file_size > bytes->len - seg.file_off) { 369 kit_ctx_diagf(ctx, "image: segment %.*s file range is out of bounds", 370 KIT_SLICE_ARG(seg.name)); 371 kit_obj_segiter_free(it); 372 ranges_free(ctx, ranges, cap); 373 return KIT_MALFORMED; 374 } 375 if (!u64_add_bias(seg_addr(&seg, opts), opts->bias, &addr) || 376 !u64_add(addr, seg.file_size, &end)) { 377 kit_ctx_diagf(ctx, "image: segment %.*s address range overflows", 378 KIT_SLICE_ARG(seg.name)); 379 kit_obj_segiter_free(it); 380 ranges_free(ctx, ranges, cap); 381 return KIT_MALFORMED; 382 } 383 384 memset(&r, 0, sizeof r); 385 r.data = bytes->data + (size_t)seg.file_off; 386 r.size = seg.file_size; 387 r.original_addr = seg_addr(&seg, opts); 388 r.addr = addr; 389 r.end = end; 390 r.name = seg.name; 391 r.order = order; 392 st = ranges_push(ctx, &ranges, &nranges, &cap, &r); 393 if (st != KIT_OK) { 394 kit_obj_segiter_free(it); 395 ranges_free(ctx, ranges, cap); 396 return st; 397 } 398 ++order; 399 } 400 kit_obj_segiter_free(it); 401 402 if (!nranges) { 403 kit_ctx_diagf(ctx, "image: no selected loadable segment bytes"); 404 ranges_free(ctx, ranges, cap); 405 return KIT_NOT_FOUND; 406 } 407 *ranges_out = ranges; 408 *nranges_out = nranges; 409 *cap_out = cap; 410 *mem_end_out = mem_end_max; 411 return KIT_OK; 412 } 413 414 static KitStatus reject_selected_relocations(const KitContext* ctx, 415 KitObjFile* obj, 416 const KitImageOptions* opts) { 417 KitObjRelocIter* it = NULL; 418 KitObjReloc reloc; 419 KitStatus st = kit_obj_reliter_new(obj, &it); 420 if (st != KIT_OK) return st; 421 while (kit_obj_reliter_next(it, &reloc) == KIT_ITER_ITEM) { 422 KitObjSecInfo sec; 423 if (kit_obj_section(obj, reloc.section, &sec) != KIT_OK) { 424 kit_obj_reliter_free(it); 425 kit_ctx_diagf(ctx, "image: relocation refers to an invalid section"); 426 return KIT_MALFORMED; 427 } 428 if (!select_alloc_section(&sec, opts)) continue; 429 kit_ctx_diagf(ctx, 430 "image: unapplied relocation %.*s in selected section %.*s" 431 "%s%.*s", 432 KIT_SLICE_ARG(reloc.kind_name), KIT_SLICE_ARG(sec.name), 433 reloc.sym_name.len ? " against " : "", 434 KIT_SLICE_ARG(reloc.sym_name)); 435 kit_obj_reliter_free(it); 436 return KIT_UNSUPPORTED; 437 } 438 kit_obj_reliter_free(it); 439 return KIT_OK; 440 } 441 442 /* Address-bearing allocated-section collection. Relocatable objects have no 443 * load segments, so this is their canonical raw-image source. Linked inputs 444 * use it only when section keep/drop filters are explicit. */ 445 static KitStatus collect_alloc_sections(const KitContext* ctx, 446 KitObjFile* obj, 447 const KitImageOptions* opts, 448 ImageRange** ranges_out, 449 uint32_t* nranges_out, 450 uint32_t* cap_out, 451 uint64_t* mem_end_out) { 452 ImageRange* ranges = NULL; 453 uint32_t nranges = 0, cap = 0, i, nsections; 454 uint64_t mem_end_max = 0; 455 KitStatus st; 456 457 *ranges_out = NULL; 458 *nranges_out = 0; 459 *cap_out = 0; 460 *mem_end_out = 0; 461 462 if (kit_obj_kind(obj) == KIT_OBJ_KIND_REL) { 463 if (opts->nsegments) { 464 kit_ctx_diagf(ctx, 465 "image: --segment is not valid for a relocatable object; " 466 "use --only-section"); 467 return KIT_INVALID; 468 } 469 st = reject_selected_relocations(ctx, obj, opts); 470 if (st != KIT_OK) return st; 471 } 472 473 nsections = kit_obj_nsections(obj); 474 for (i = 0; i < nsections; ++i) { 475 KitObjSecInfo sec; 476 const uint8_t* data = NULL; 477 size_t len = 0; 478 uint64_t addr, end, mend; 479 ImageRange r; 480 st = kit_obj_section(obj, i, &sec); 481 if (st == KIT_NOT_FOUND) continue; 482 if (st != KIT_OK) { 483 ranges_free(ctx, ranges, cap); 484 return KIT_MALFORMED; 485 } 486 if (!select_alloc_section(&sec, opts)) continue; 487 if (!u64_add_bias(sec.addr, opts->bias, &addr) || 488 !u64_add(addr, sec.size, &mend)) { 489 kit_ctx_diagf(ctx, "image: section %.*s address range overflows", 490 KIT_SLICE_ARG(sec.name)); 491 ranges_free(ctx, ranges, cap); 492 return KIT_MALFORMED; 493 } 494 if (mend > mem_end_max) mem_end_max = mend; 495 if (sec.kind == KIT_SEC_BSS || sec.size == 0) continue; 496 if (kit_obj_section_data(obj, i, &data, &len) != KIT_OK) { 497 kit_ctx_diagf(ctx, "image: cannot read selected section %.*s", 498 KIT_SLICE_ARG(sec.name)); 499 ranges_free(ctx, ranges, cap); 500 return KIT_MALFORMED; 501 } 502 if (!data || len == 0) continue; 503 if (!u64_add(addr, (uint64_t)len, &end)) { 504 kit_ctx_diagf(ctx, "image: section %.*s file range overflows", 505 KIT_SLICE_ARG(sec.name)); 506 ranges_free(ctx, ranges, cap); 507 return KIT_MALFORMED; 508 } 509 memset(&r, 0, sizeof r); 510 r.data = data; 511 r.size = (uint64_t)len; 512 r.original_addr = sec.addr; 513 r.addr = addr; 514 r.end = end; 515 r.name = sec.name; 516 r.order = i; 517 st = ranges_push(ctx, &ranges, &nranges, &cap, &r); 518 if (st != KIT_OK) { 519 ranges_free(ctx, ranges, cap); 520 return st; 521 } 522 } 523 if (!nranges) { 524 kit_ctx_diagf(ctx, "image: no selected allocated section bytes"); 525 ranges_free(ctx, ranges, cap); 526 return KIT_NOT_FOUND; 527 } 528 *ranges_out = ranges; 529 *nranges_out = nranges; 530 *cap_out = cap; 531 *mem_end_out = mem_end_max; 532 return KIT_OK; 533 } 534 535 /* Section-based collection: gather sections named by opts->section_order in 536 * that exact order. The result is a pure concatenation — addresses are 537 * synthesized so the ranges pack with no holes, and the caller must not treat 538 * the layout base as a load address (report->sections_concat is set). */ 539 static KitStatus collect_sections(const KitContext* ctx, KitObjFile* obj, 540 const KitImageOptions* opts, 541 ImageRange** ranges_out, uint32_t* nranges_out, 542 uint32_t* cap_out, uint64_t* mem_end_out) { 543 ImageRange* ranges = NULL; 544 uint32_t nranges = 0, cap = 0; 545 uint64_t cursor = 0; 546 uint32_t i; 547 KitStatus st; 548 549 *ranges_out = NULL; 550 *nranges_out = 0; 551 *cap_out = 0; 552 *mem_end_out = 0; 553 554 if (opts->nsection_order == 0) { 555 kit_ctx_diagf(ctx, "image: --format sections requires at least one " 556 "--section NAME"); 557 return KIT_INVALID; 558 } 559 560 for (i = 0; i < opts->nsection_order; ++i) { 561 KitSlice want = opts->section_order[i]; 562 KitObjSection sid = KIT_SECTION_NONE; 563 const uint8_t* data = NULL; 564 size_t len = 0; 565 ImageRange r; 566 uint64_t end; 567 568 if (opts->nremove_sections && 569 name_in_list(want, opts->remove_sections, opts->nremove_sections)) { 570 kit_ctx_diagf(ctx, 571 "image: section %.*s is both selected and --remove-section", 572 KIT_SLICE_ARG(want)); 573 ranges_free(ctx, ranges, cap); 574 return KIT_INVALID; 575 } 576 if (kit_obj_section_by_name(obj, want, &sid) != KIT_OK || 577 sid == KIT_SECTION_NONE) { 578 kit_ctx_diagf(ctx, "image: section %.*s not found", KIT_SLICE_ARG(want)); 579 ranges_free(ctx, ranges, cap); 580 return KIT_NOT_FOUND; 581 } 582 if (kit_obj_section_data(obj, sid, &data, &len) != KIT_OK) { 583 kit_ctx_diagf(ctx, "image: cannot read section %.*s bytes", 584 KIT_SLICE_ARG(want)); 585 ranges_free(ctx, ranges, cap); 586 return KIT_MALFORMED; 587 } 588 if (len == 0 || data == NULL) { 589 /* A NOBITS (.bss) or empty section contributes no bytes; skip it but 590 * keep the position so order is preserved deterministically. */ 591 continue; 592 } 593 if (!u64_add(cursor, (uint64_t)len, &end)) { 594 kit_ctx_diagf(ctx, "image: concatenated section size overflows"); 595 ranges_free(ctx, ranges, cap); 596 return KIT_MALFORMED; 597 } 598 599 memset(&r, 0, sizeof r); 600 r.data = data; 601 r.size = (uint64_t)len; 602 r.addr = cursor; 603 r.end = end; 604 r.name = want; 605 r.order = i; 606 st = ranges_push(ctx, &ranges, &nranges, &cap, &r); 607 if (st != KIT_OK) { 608 ranges_free(ctx, ranges, cap); 609 return st; 610 } 611 cursor = end; 612 } 613 614 if (!nranges) { 615 kit_ctx_diagf(ctx, "image: selected sections contain no bytes"); 616 ranges_free(ctx, ranges, cap); 617 return KIT_NOT_FOUND; 618 } 619 /* Already in declared order with packed addresses; no sort needed. */ 620 *ranges_out = ranges; 621 *nranges_out = nranges; 622 *cap_out = cap; 623 *mem_end_out = cursor; /* concatenation has no separate memory image */ 624 return KIT_OK; 625 } 626 627 static KitStatus compute_layout(const KitContext* ctx, const ImageRange* ranges, 628 uint32_t nranges, const KitImageOptions* opts, 629 uint64_t seg_mem_end, KitImageReport* report) { 630 uint64_t base = opts->have_base ? opts->base : ranges[0].addr; 631 uint64_t cur = base; 632 uint64_t payload = 0; 633 uint64_t max_hole = 0; 634 uint32_t i; 635 int had_holes = 0; 636 637 if (base > ranges[0].addr) { 638 kit_ctx_diagf(ctx, "image: base 0x%llx is above first selected byte 0x%llx", 639 (unsigned long long)base, 640 (unsigned long long)ranges[0].addr); 641 return KIT_INVALID; 642 } 643 644 for (i = 0; i < nranges; ++i) { 645 const ImageRange* r = &ranges[i]; 646 uint64_t hole; 647 if (r->addr < cur) { 648 kit_ctx_diagf(ctx, 649 "image: selected segments overlap at address 0x%llx", 650 (unsigned long long)r->addr); 651 return KIT_MALFORMED; 652 } 653 hole = r->addr - cur; 654 if (hole) { 655 had_holes = 1; 656 if (hole > max_hole) max_hole = hole; 657 if (opts->fail_on_holes) { 658 kit_ctx_diagf(ctx, "image: hole of %llu bytes at address 0x%llx", 659 (unsigned long long)hole, (unsigned long long)cur); 660 return KIT_ERR; 661 } 662 if (opts->have_max_hole && hole > opts->max_hole) { 663 kit_ctx_diagf( 664 ctx, 665 "image: hole of %llu bytes at address 0x%llx exceeds limit %llu", 666 (unsigned long long)hole, (unsigned long long)cur, 667 (unsigned long long)opts->max_hole); 668 return KIT_ERR; 669 } 670 } 671 if (!u64_add(payload, r->size, &payload)) { 672 kit_ctx_diagf(ctx, "image: payload size overflows"); 673 return KIT_MALFORMED; 674 } 675 cur = r->end; 676 } 677 678 report->base = base; 679 report->size = cur - base; 680 report->payload_size = payload; 681 report->max_hole = max_hole; 682 /* In-memory span from the image base. seg_mem_end covers BSS-only segments 683 * the byte ranges skip; fall back to the file span if it is somehow lower. */ 684 report->mem_size = seg_mem_end > base ? seg_mem_end - base : cur - base; 685 report->nranges = nranges; 686 report->had_holes = had_holes ? true : false; 687 688 if (opts->have_align) { 689 uint64_t aligned; 690 if (!u64_align_up(report->size, opts->align, &aligned)) { 691 kit_ctx_diagf(ctx, "image: aligned output size overflows"); 692 return KIT_MALFORMED; 693 } 694 report->size = aligned; 695 } 696 if (opts->have_pad_to) { 697 if (opts->pad_to < report->size) { 698 kit_ctx_diagf(ctx, "image: --pad-to %llu is smaller than image size %llu", 699 (unsigned long long)opts->pad_to, 700 (unsigned long long)report->size); 701 return KIT_ERR; 702 } 703 report->size = opts->pad_to; 704 } 705 if (opts->have_max_size && report->size > opts->max_size) { 706 kit_ctx_diagf(ctx, "image: output size %llu exceeds maximum %llu", 707 (unsigned long long)report->size, 708 (unsigned long long)opts->max_size); 709 return KIT_ERR; 710 } 711 return KIT_OK; 712 } 713 714 static KitStatus write_fill(KitWriter* out, uint8_t fill, uint64_t n) { 715 uint8_t buf[256]; 716 memset(buf, fill, sizeof buf); 717 while (n) { 718 size_t chunk = n > sizeof buf ? sizeof buf : (size_t)n; 719 if (kit_writer_write(out, buf, chunk) != KIT_OK) return KIT_IO; 720 n -= chunk; 721 } 722 return KIT_OK; 723 } 724 725 static KitStatus write_bytes(KitWriter* out, const uint8_t* data, size_t n) { 726 return n ? kit_writer_write(out, data, n) : KIT_OK; 727 } 728 729 /* Resolve a requested Image-header kind (possibly AUTO) to a concrete arch from 730 * the object's machine. */ 731 static KitStatus resolve_image_header(const KitContext* ctx, KitObjFile* obj, 732 uint32_t want, KitImageHeader* out) { 733 KitTargetSpec spec; 734 if (want == KIT_IMAGE_HEADER_ARM64 || want == KIT_IMAGE_HEADER_RISCV) { 735 *out = (KitImageHeader)want; 736 return KIT_OK; 737 } 738 spec = kit_obj_target(obj); 739 switch (spec.arch) { 740 case KIT_ARCH_ARM_64: 741 *out = KIT_IMAGE_HEADER_ARM64; 742 return KIT_OK; 743 case KIT_ARCH_RV64: 744 case KIT_ARCH_RV32: 745 *out = KIT_IMAGE_HEADER_RISCV; 746 return KIT_OK; 747 default: 748 break; 749 } 750 kit_ctx_diagf(ctx, "image: --image-header could not infer the architecture; " 751 "pass --image-header=arm64 or =riscv"); 752 return KIT_INVALID; 753 } 754 755 /* Fill a 64-byte flat-kernel Image header. code0/code1 (the first 8 bytes of the 756 * first loadable segment, i.e. the author's entry branch) are preserved; the 757 * 56-byte metadata tail is synthesized deterministically. */ 758 static KitStatus build_image_header(const KitContext* ctx, KitImageHeader kind, 759 const ImageRange* first, 760 const KitImageReport* report, 761 const KitImageOptions* opts, 762 uint8_t hdr[64]) { 763 uint64_t flags = 0; 764 uint64_t text_offset = 765 opts->have_image_text_offset ? opts->image_text_offset : 0; 766 767 if (first->addr != report->base) { 768 kit_ctx_diagf(ctx, "image: --image-header needs the first loadable segment " 769 "at the image base (no leading hole)"); 770 return KIT_INVALID; 771 } 772 if (first->size < 64) { 773 kit_ctx_diagf(ctx, "image: --image-header needs the first loadable segment " 774 "to reserve a 64-byte header"); 775 return KIT_INVALID; 776 } 777 778 if (opts->image_big_endian) flags |= 1u; 779 if (opts->image_page_size_kib) { 780 if (kind != KIT_IMAGE_HEADER_ARM64) { 781 kit_ctx_diagf(ctx, 782 "image: --image-page-size applies only to the arm64 header"); 783 return KIT_INVALID; 784 } 785 switch (opts->image_page_size_kib) { 786 case 4: 787 flags |= (uint64_t)1u << 1; 788 break; 789 case 16: 790 flags |= (uint64_t)2u << 1; 791 break; 792 case 64: 793 flags |= (uint64_t)3u << 1; 794 break; 795 default: 796 kit_ctx_diagf(ctx, 797 "image: --image-page-size must be 4, 16, or 64 (KiB)"); 798 return KIT_INVALID; 799 } 800 } 801 802 memset(hdr, 0, 64); 803 memcpy(hdr, first->data, 8); /* code0/code1: preserve the entry branch */ 804 put_u64le(hdr + 8, text_offset); 805 put_u64le(hdr + 16, report->mem_size); 806 put_u64le(hdr + 24, flags); 807 if (kind == KIT_IMAGE_HEADER_ARM64) { 808 /* res2..res4 zero; magic "ARM\x64" at 56; PE-offset slot (60) zero. */ 809 hdr[56] = 0x41; 810 hdr[57] = 0x52; 811 hdr[58] = 0x4d; 812 hdr[59] = 0x64; 813 } else { 814 /* version 2 at 32; reserved/deprecated-magic zero; magic2 "RSC\x05" at 56. */ 815 put_u32le(hdr + 32, 0x00000002u); 816 hdr[56] = 0x52; 817 hdr[57] = 0x53; 818 hdr[58] = 0x43; 819 hdr[59] = 0x05; 820 } 821 return KIT_OK; 822 } 823 824 static KitStatus write_layout(const KitContext* ctx, const ImageRange* ranges, 825 uint32_t nranges, const KitImageOptions* opts, 826 const KitImageReport* report, 827 const uint8_t* image_hdr, KitWriter* out) { 828 uint64_t cur = report->base; 829 uint32_t i; 830 for (i = 0; i < nranges; ++i) { 831 const ImageRange* r = &ranges[i]; 832 uint64_t hole = r->addr - cur; 833 if (hole && write_fill(out, opts->fill, hole) != KIT_OK) { 834 kit_ctx_diagf(ctx, "image: failed to write hole fill"); 835 return KIT_IO; 836 } 837 /* The synthesized header overlays the first 64 bytes of the first range 838 * (validated >= 64 and at the base); the remaining bytes follow verbatim. */ 839 if (i == 0 && image_hdr) { 840 if (write_bytes(out, image_hdr, 64) != KIT_OK || 841 write_bytes(out, r->data + 64, (size_t)(r->size - 64)) != KIT_OK) { 842 kit_ctx_diagf(ctx, "image: failed to write header + segment bytes"); 843 return KIT_IO; 844 } 845 cur = r->end; 846 continue; 847 } 848 if (write_bytes(out, r->data, (size_t)r->size) != KIT_OK) { 849 kit_ctx_diagf(ctx, "image: failed to write segment bytes"); 850 return KIT_IO; 851 } 852 cur = r->end; 853 } 854 if (report->size > cur - report->base) { 855 uint64_t pad = report->size - (cur - report->base); 856 if (write_fill(out, opts->fill, pad) != KIT_OK) { 857 kit_ctx_diagf(ctx, "image: failed to write trailing padding"); 858 return KIT_IO; 859 } 860 } 861 return kit_writer_status(out); 862 } 863 864 static KitStatus check_32bit_text_image_range(const KitContext* ctx, 865 const KitImageReport* report, 866 const char* name) { 867 if (report->base > UINT32_MAX || 868 report->size > ((uint64_t)UINT32_MAX + 1u) - report->base) { 869 kit_ctx_diagf(ctx, "image: %s cannot emit above 32-bit addresses", name); 870 return KIT_UNSUPPORTED; 871 } 872 return KIT_OK; 873 } 874 875 static KitStatus emit_ihex_ela_record(KitWriter* out, uint16_t upper) { 876 uint8_t payload[2]; 877 char line[32]; 878 uint32_t sum; 879 size_t n = 0; 880 881 payload[0] = (uint8_t)(upper >> 8); 882 payload[1] = (uint8_t)(upper & 0xffu); 883 sum = 2u + 0u + 0u + 4u + payload[0] + payload[1]; 884 885 line[n++] = ':'; 886 line_append_hex_u8(line, &n, 2u); 887 line_append_hex_u16(line, &n, 0u); 888 line_append_hex_u8(line, &n, 4u); 889 line_append_hex_u8(line, &n, payload[0]); 890 line_append_hex_u8(line, &n, payload[1]); 891 line_append_hex_u8(line, &n, (uint8_t)(~sum + 1u)); 892 line[n++] = '\n'; 893 894 return write_line(out, line, n); 895 } 896 897 static KitStatus emit_ihex_data_record(KitWriter* out, uint16_t addr, 898 const uint8_t* data, size_t len) { 899 uint32_t sum; 900 size_t i; 901 char line[64]; 902 size_t n = 0; 903 904 if (len > KIT_IHEX_DATA_MAX || !len) return KIT_INVALID; 905 906 sum = (uint32_t)len; 907 sum += (uint32_t)(addr >> 8); 908 sum += (uint32_t)(addr & 0xffu); 909 sum += 0u; 910 line[n++] = ':'; 911 line_append_hex_u8(line, &n, (uint8_t)len); 912 line_append_hex_u16(line, &n, addr); 913 line_append_hex_u8(line, &n, 0u); 914 for (i = 0; i < len; ++i) { 915 line_append_hex_u8(line, &n, data[i]); 916 sum += data[i]; 917 } 918 line_append_hex_u8(line, &n, (uint8_t)(~sum + 1u)); 919 line[n++] = '\n'; 920 return write_line(out, line, n); 921 } 922 923 static KitStatus emit_ihex_eof_record(KitWriter* out) { 924 char line[16]; 925 size_t n = 0; 926 927 line[n++] = ':'; 928 line_append_hex_u8(line, &n, 0u); 929 line_append_hex_u16(line, &n, 0u); 930 line_append_hex_u8(line, &n, 1u); 931 line_append_hex_u8(line, &n, 0xffu); 932 line[n++] = '\n'; 933 return write_line(out, line, n); 934 } 935 936 static KitStatus emit_ihex_start_record(KitWriter* out, uint32_t entry) { 937 uint8_t payload[4]; 938 uint32_t sum; 939 size_t i; 940 char line[32]; 941 size_t n = 0; 942 943 payload[0] = (uint8_t)(entry >> 24); 944 payload[1] = (uint8_t)(entry >> 16); 945 payload[2] = (uint8_t)(entry >> 8); 946 payload[3] = (uint8_t)entry; 947 sum = 4u + 5u; 948 949 line[n++] = ':'; 950 line_append_hex_u8(line, &n, 4u); 951 line_append_hex_u16(line, &n, 0u); 952 line_append_hex_u8(line, &n, 5u); 953 for (i = 0; i < sizeof payload; ++i) { 954 line_append_hex_u8(line, &n, payload[i]); 955 sum += payload[i]; 956 } 957 line_append_hex_u8(line, &n, (uint8_t)(~sum + 1u)); 958 line[n++] = '\n'; 959 return write_line(out, line, n); 960 } 961 962 static KitStatus emit_ihex_blob(const KitContext* ctx, KitWriter* out, 963 uint64_t addr, const uint8_t* src, 964 uint64_t len, uint8_t fill, int as_fill, 965 uint16_t* current_upper) { 966 uint8_t chunk[KIT_IHEX_DATA_MAX]; 967 uint16_t upper; 968 uint32_t chunk_len; 969 uint64_t at; 970 KitStatus st; 971 972 while (len) { 973 if (addr > UINT32_MAX) { 974 kit_ctx_diagf(ctx, "image: ihex cannot emit above 32-bit addresses"); 975 return KIT_UNSUPPORTED; 976 } 977 upper = (uint16_t)(addr >> 16); 978 if (*current_upper != upper) { 979 st = emit_ihex_ela_record(out, upper); 980 if (st != KIT_OK) return st; 981 *current_upper = upper; 982 } 983 at = addr & 0xffffu; 984 chunk_len = (uint32_t)(0x10000ull - at); 985 if (chunk_len > len) chunk_len = (uint32_t)len; 986 if (chunk_len > KIT_IHEX_DATA_MAX) chunk_len = KIT_IHEX_DATA_MAX; 987 if (as_fill) { 988 memset(chunk, fill, (size_t)chunk_len); 989 } else { 990 memcpy(chunk, src, (size_t)chunk_len); 991 src += chunk_len; 992 } 993 st = emit_ihex_data_record(out, (uint16_t)addr, chunk, (size_t)chunk_len); 994 if (st != KIT_OK) return st; 995 addr += chunk_len; 996 len -= chunk_len; 997 } 998 return KIT_OK; 999 } 1000 1001 static KitStatus write_ihex_records(const KitContext* ctx, const ImageRange* ranges, 1002 uint32_t nranges, const KitImageOptions* opts, 1003 const KitImageReport* report, 1004 KitWriter* out) { 1005 uint64_t cur = report->base; 1006 uint64_t pad = 0; 1007 uint16_t current_upper = 0xffffu; 1008 uint32_t i; 1009 KitStatus st; 1010 1011 for (i = 0; i < nranges; ++i) { 1012 const ImageRange* r = &ranges[i]; 1013 uint64_t hole = r->addr - cur; 1014 if (hole) { 1015 st = emit_ihex_blob(ctx, out, cur, NULL, hole, opts->fill, 1, 1016 ¤t_upper); 1017 if (st != KIT_OK) return st; 1018 } 1019 st = emit_ihex_blob(ctx, out, r->addr, r->data, r->size, 0, 0, 1020 ¤t_upper); 1021 if (st != KIT_OK) return st; 1022 cur = r->end; 1023 } 1024 if (report->size > cur - report->base) { 1025 pad = report->size - (cur - report->base); 1026 st = emit_ihex_blob(ctx, out, cur, NULL, pad, opts->fill, 1, 1027 ¤t_upper); 1028 if (st != KIT_OK) return st; 1029 } 1030 if (report->has_entry) { 1031 st = emit_ihex_start_record(out, (uint32_t)report->emitted_entry); 1032 if (st != KIT_OK) return st; 1033 } 1034 return emit_ihex_eof_record(out); 1035 } 1036 1037 static KitStatus srec_data_type(const KitContext* ctx, uint64_t addr, char* type, 1038 uint32_t* addr_bytes) { 1039 if (addr <= 0xffffu) { 1040 *type = '1'; 1041 *addr_bytes = 2u; 1042 return KIT_OK; 1043 } 1044 if (addr <= 0xffffffu) { 1045 *type = '2'; 1046 *addr_bytes = 3u; 1047 return KIT_OK; 1048 } 1049 if (addr <= 0xffffffffu) { 1050 *type = '3'; 1051 *addr_bytes = 4u; 1052 return KIT_OK; 1053 } 1054 kit_ctx_diagf(ctx, 1055 "image: srec cannot emit above 32-bit addresses (got 0x%llx)", 1056 (unsigned long long)addr); 1057 return KIT_UNSUPPORTED; 1058 } 1059 1060 static KitStatus emit_srec_data_record(KitWriter* out, char type, uint32_t addr_bytes, 1061 uint64_t addr, const uint8_t* data, 1062 size_t len) { 1063 uint8_t sum; 1064 size_t i; 1065 char line[128]; 1066 size_t n = 0; 1067 uint8_t count; 1068 1069 if (addr_bytes < 2u || addr_bytes > 4u) return KIT_INVALID; 1070 if (len > KIT_SREC_DATA_MAX) return KIT_INVALID; 1071 if (!data && len != 0u) return KIT_INVALID; 1072 1073 count = (uint8_t)(addr_bytes + len + 1u); 1074 sum = count; 1075 1076 line[n++] = 'S'; 1077 line[n++] = (char)type; 1078 line_append_hex_u8(line, &n, count); 1079 line_append_hex_u64_be(line, &n, addr, addr_bytes); 1080 for (i = 0; i < addr_bytes; ++i) { 1081 sum += (uint8_t)(addr >> (8u * (addr_bytes - 1u - i))); 1082 } 1083 if (data) { 1084 for (i = 0; i < len; ++i) { 1085 line_append_hex_u8(line, &n, data[i]); 1086 sum += data[i]; 1087 } 1088 } 1089 line_append_hex_u8(line, &n, (uint8_t)(~sum)); 1090 line[n++] = '\n'; 1091 return write_line(out, line, n); 1092 } 1093 1094 static KitStatus emit_srec_blob(const KitContext* ctx, KitWriter* out, uint64_t addr, 1095 const uint8_t* src, uint64_t len, uint8_t fill, 1096 int as_fill) { 1097 uint8_t chunk[KIT_SREC_DATA_MAX]; 1098 size_t chunk_len_u; 1099 uint64_t chunk_len; 1100 uint64_t block_size; 1101 uint64_t at; 1102 char type; 1103 uint32_t addr_bytes; 1104 KitStatus st; 1105 1106 while (len) { 1107 st = srec_data_type(ctx, addr, &type, &addr_bytes); 1108 if (st != KIT_OK) return st; 1109 at = addr & (((uint64_t)1u << (addr_bytes * 8u)) - 1u); 1110 block_size = (uint64_t)1u << (addr_bytes * 8u); 1111 chunk_len = block_size - at; 1112 if (chunk_len > len) chunk_len = len; 1113 if (chunk_len > KIT_SREC_DATA_MAX) chunk_len = KIT_SREC_DATA_MAX; 1114 chunk_len_u = (size_t)chunk_len; 1115 if (as_fill) { 1116 memset(chunk, fill, chunk_len_u); 1117 } else { 1118 memcpy(chunk, src, chunk_len_u); 1119 src += chunk_len_u; 1120 } 1121 st = emit_srec_data_record(out, type, addr_bytes, addr, chunk, chunk_len_u); 1122 if (st != KIT_OK) return st; 1123 addr += chunk_len; 1124 len -= chunk_len; 1125 } 1126 return KIT_OK; 1127 } 1128 1129 static char srec_start_type(uint64_t addr) { 1130 if (addr <= 0xffffu) return '9'; 1131 if (addr <= 0xffffffu) return '8'; 1132 return '7'; 1133 } 1134 1135 static uint32_t srec_start_addr_bytes(uint64_t addr) { 1136 if (addr <= 0xffffu) return 2u; 1137 if (addr <= 0xffffffu) return 3u; 1138 return 4u; 1139 } 1140 1141 static KitStatus write_srec_records(const KitContext* ctx, const ImageRange* ranges, 1142 uint32_t nranges, const KitImageOptions* opts, 1143 const KitImageReport* report, 1144 KitWriter* out) { 1145 const uint8_t header_name[] = "KIT"; 1146 uint64_t cur; 1147 uint64_t pad = 0; 1148 uint32_t i; 1149 KitStatus st; 1150 1151 if (emit_srec_data_record(out, '0', 2u, 0u, header_name, 1152 sizeof(header_name) - 1u) != KIT_OK) { 1153 return KIT_IO; 1154 } 1155 1156 if (nranges == 0) return KIT_NOT_FOUND; 1157 cur = report->base; 1158 for (i = 0; i < nranges; ++i) { 1159 const ImageRange* r = &ranges[i]; 1160 uint64_t hole = r->addr - cur; 1161 if (hole) { 1162 st = emit_srec_blob(ctx, out, cur, NULL, hole, opts->fill, 1); 1163 if (st != KIT_OK) return st; 1164 } 1165 st = emit_srec_blob(ctx, out, r->addr, r->data, r->size, 0u, 0); 1166 if (st != KIT_OK) return st; 1167 cur = r->end; 1168 } 1169 if (report->size > cur - report->base) { 1170 pad = report->size - (cur - report->base); 1171 st = emit_srec_blob(ctx, out, cur, NULL, pad, opts->fill, 1); 1172 if (st != KIT_OK) return st; 1173 } 1174 if (report->has_entry) { 1175 uint64_t entry = report->emitted_entry; 1176 if (emit_srec_data_record(out, srec_start_type(entry), 1177 srec_start_addr_bytes(entry), entry, NULL, 0u) != 1178 KIT_OK) { 1179 return KIT_IO; 1180 } 1181 } 1182 return KIT_OK; 1183 } 1184 1185 /* Validation pass: --require-entry / --require-symbol / --require-section / 1186 * --no-dynamic. Runs against the opened object before any bytes are written. */ 1187 static KitStatus validate_object(const KitContext* ctx, KitObjFile* obj, 1188 const KitImageOptions* opts) { 1189 uint32_t i; 1190 1191 if (opts->require_entry) { 1192 KitObjImageInfo info; 1193 if (kit_obj_image_info(obj, &info) != KIT_OK || info.entry == 0) { 1194 kit_ctx_diagf(ctx, "image: --require-entry: input declares no entry point"); 1195 return KIT_NOT_FOUND; 1196 } 1197 } 1198 1199 for (i = 0; i < opts->nrequire_sections; ++i) { 1200 KitObjSection sid = KIT_SECTION_NONE; 1201 KitSlice want = opts->require_sections[i]; 1202 if (kit_obj_section_by_name(obj, want, &sid) != KIT_OK || 1203 sid == KIT_SECTION_NONE) { 1204 kit_ctx_diagf(ctx, "image: --require-section: %.*s not found", 1205 KIT_SLICE_ARG(want)); 1206 return KIT_NOT_FOUND; 1207 } 1208 } 1209 1210 for (i = 0; i < opts->nrequire_symbols; ++i) { 1211 KitObjSymInfo si; 1212 KitSlice want = opts->require_symbols[i]; 1213 if (kit_obj_symbol_by_name(obj, want, &si) != KIT_OK) { 1214 /* Fall back to the dynamic symbol table for stripped linked images. */ 1215 KitObjSymIter* dit = NULL; 1216 int found = 0; 1217 if (kit_obj_dynsymiter_new(obj, &dit) == KIT_OK) { 1218 KitObjSymInfo di; 1219 while (kit_obj_symiter_next(dit, &di) == KIT_ITER_ITEM) { 1220 if (slice_eq(di.name, want)) { 1221 found = 1; 1222 break; 1223 } 1224 } 1225 kit_obj_symiter_free(dit); 1226 } 1227 if (!found) { 1228 kit_ctx_diagf(ctx, "image: --require-symbol: %.*s not found", 1229 KIT_SLICE_ARG(want)); 1230 return KIT_NOT_FOUND; 1231 } 1232 } 1233 } 1234 1235 if (opts->no_dynamic) { 1236 KitObjImageInfo info; 1237 KitObjDepIter* dep = NULL; 1238 KitObjDepInfo di; 1239 int has_dep = 0; 1240 KitObjSection sid = KIT_SECTION_NONE; 1241 static const char* dyn_secs[] = {".dynamic", ".interp", ".plt", 1242 ".got.plt", ".got", ".dynsym"}; 1243 size_t k; 1244 1245 if (kit_obj_image_info(obj, &info) == KIT_OK && info.interp.len) { 1246 kit_ctx_diagf(ctx, 1247 "image: --no-dynamic: input has a dynamic interpreter %.*s", 1248 KIT_SLICE_ARG(info.interp)); 1249 return KIT_ERR; 1250 } 1251 if (kit_obj_depiter_new(obj, &dep) == KIT_OK) { 1252 if (kit_obj_depiter_next(dep, &di) == KIT_ITER_ITEM) has_dep = 1; 1253 kit_obj_depiter_free(dep); 1254 } 1255 if (has_dep) { 1256 kit_ctx_diagf(ctx, 1257 "image: --no-dynamic: input depends on a shared library"); 1258 return KIT_ERR; 1259 } 1260 for (k = 0; k < sizeof(dyn_secs) / sizeof(dyn_secs[0]); ++k) { 1261 if (kit_obj_section_by_name(obj, kit_slice_cstr(dyn_secs[k]), &sid) == 1262 KIT_OK && 1263 sid != KIT_SECTION_NONE) { 1264 kit_ctx_diagf(ctx, 1265 "image: --no-dynamic: input has a dynamic section %s", 1266 dyn_secs[k]); 1267 return KIT_ERR; 1268 } 1269 } 1270 } 1271 1272 return KIT_OK; 1273 } 1274 1275 KitStatus obj_emit_image(const KitContext* ctx, KitObjFile* obj, 1276 const KitSlice* object_bytes, 1277 const KitImageOptions* opts, KitWriter* out, 1278 KitImageReport* report_out) { 1279 KitImageOptions defopts; 1280 KitImageReport report; 1281 ImageRange* ranges = NULL; 1282 uint32_t nranges = 0, cap = 0; 1283 KitImageFormat format; 1284 KitStatus st; 1285 int from_sections; 1286 int address_sections; 1287 uint64_t seg_mem_end = 0; 1288 uint8_t image_hdr[64]; 1289 const uint8_t* image_hdr_p = NULL; 1290 1291 if (!ctx || !ctx->heap || !obj || !object_bytes || !out) return KIT_INVALID; 1292 if (!object_bytes->data && object_bytes->len) return KIT_INVALID; 1293 1294 if (!opts) { 1295 memset(&defopts, 0, sizeof defopts); 1296 defopts.format = KIT_IMAGE_FORMAT_BIN; 1297 defopts.from = KIT_IMAGE_FROM_SEGMENTS; 1298 defopts.addr = KIT_IMAGE_ADDR_VADDR; 1299 defopts.fill = 0; 1300 opts = &defopts; 1301 } 1302 1303 format = (KitImageFormat)opts->format; 1304 if (format != KIT_IMAGE_FORMAT_BIN && format != KIT_IMAGE_FORMAT_ROM && 1305 format != KIT_IMAGE_FORMAT_SECTIONS && format != KIT_IMAGE_FORMAT_IHEX && 1306 format != KIT_IMAGE_FORMAT_SREC && format != KIT_IMAGE_FORMAT_ELF) { 1307 kit_ctx_diagf(ctx, "image: unknown output format"); 1308 return KIT_INVALID; 1309 } 1310 if (format == KIT_IMAGE_FORMAT_ELF) { 1311 kit_ctx_diagf(ctx, 1312 "image: --format elf is not implemented; use `kit objcopy` " 1313 "/ `kit strip` to copy, normalize, or strip a linked ELF"); 1314 return KIT_UNSUPPORTED; 1315 } 1316 if (opts->have_base && 1317 (format == KIT_IMAGE_FORMAT_IHEX || format == KIT_IMAGE_FORMAT_SREC)) { 1318 kit_ctx_diagf(ctx, 1319 "image: --base is only valid for flat output; use --bias " 1320 "to rebase ihex/srec addresses"); 1321 return KIT_INVALID; 1322 } 1323 if (opts->from != KIT_IMAGE_FROM_SEGMENTS && 1324 opts->from != KIT_IMAGE_FROM_SECTIONS) { 1325 kit_ctx_diagf(ctx, "image: invalid --from source"); 1326 return KIT_INVALID; 1327 } 1328 if (opts->addr != KIT_IMAGE_ADDR_VADDR && 1329 opts->addr != KIT_IMAGE_ADDR_PADDR && opts->addr != KIT_IMAGE_ADDR_LMA) { 1330 kit_ctx_diagf(ctx, "image: invalid address kind"); 1331 return KIT_INVALID; 1332 } 1333 if (opts->nsegments && !opts->segments) { 1334 kit_ctx_diagf(ctx, "image: segment list is missing"); 1335 return KIT_INVALID; 1336 } 1337 if (opts->have_align && opts->align == 0) { 1338 kit_ctx_diagf(ctx, "image: --align must be non-zero"); 1339 return KIT_INVALID; 1340 } 1341 1342 /* Source selection. Five formats, two byte sources: 1343 * bin/srec/ihex : linked load segments, or allocated sections for a 1344 * relocatable input / explicit section filters. 1345 * rom : load segments by default, or named sections when a 1346 * --section list (or --from sections) is supplied. 1347 * sections : named sections only (the format IS the concatenation). 1348 * --section is the section-order list; it implies the section source for the 1349 * formats that allow it and is rejected for bin / ihex / srec. */ 1350 if ((format == KIT_IMAGE_FORMAT_BIN || format == KIT_IMAGE_FORMAT_IHEX || 1351 format == KIT_IMAGE_FORMAT_SREC) && 1352 opts->nsection_order) { 1353 kit_ctx_diagf(ctx, 1354 "image: --section is only valid with --format sections or " 1355 "--format rom"); 1356 return KIT_INVALID; 1357 } 1358 if ((format == KIT_IMAGE_FORMAT_BIN || format == KIT_IMAGE_FORMAT_IHEX || 1359 format == KIT_IMAGE_FORMAT_SREC) && 1360 opts->from == KIT_IMAGE_FROM_SECTIONS) { 1361 kit_ctx_diagf(ctx, 1362 "image: --from sections requires --format sections or rom"); 1363 return KIT_INVALID; 1364 } 1365 from_sections = (format == KIT_IMAGE_FORMAT_SECTIONS) || 1366 (opts->from == KIT_IMAGE_FROM_SECTIONS) || 1367 (format == KIT_IMAGE_FORMAT_ROM && opts->nsection_order > 0); 1368 if (from_sections && opts->nsection_order == 0) { 1369 kit_ctx_diagf(ctx, 1370 "image: a section source requires at least one --section " 1371 "NAME"); 1372 return KIT_INVALID; 1373 } 1374 if (format == KIT_IMAGE_FORMAT_ROM && !opts->have_pad_to) { 1375 kit_ctx_diagf(ctx, 1376 "image: --format rom requires an explicit size via --pad-to"); 1377 return KIT_INVALID; 1378 } 1379 if (opts->image_header != KIT_IMAGE_HEADER_NONE) { 1380 if (format != KIT_IMAGE_FORMAT_BIN && format != KIT_IMAGE_FORMAT_ROM) { 1381 kit_ctx_diagf(ctx, "image: --image-header requires --format bin or rom"); 1382 return KIT_INVALID; 1383 } 1384 if (from_sections) { 1385 kit_ctx_diagf( 1386 ctx, "image: --image-header is incompatible with a section source"); 1387 return KIT_INVALID; 1388 } 1389 } 1390 1391 st = validate_object(ctx, obj, opts); 1392 if (st != KIT_OK) return st; 1393 1394 address_sections = !from_sections && 1395 (kit_obj_kind(obj) == KIT_OBJ_KIND_REL || 1396 opts->nonly_sections || opts->nremove_sections); 1397 if (from_sections) { 1398 st = collect_sections(ctx, obj, opts, &ranges, &nranges, &cap, &seg_mem_end); 1399 } else if (address_sections) { 1400 st = collect_alloc_sections(ctx, obj, opts, &ranges, &nranges, &cap, 1401 &seg_mem_end); 1402 } else { 1403 st = collect_ranges(ctx, obj, object_bytes, opts, &ranges, &nranges, &cap, 1404 &seg_mem_end); 1405 } 1406 if (st == KIT_OK && !from_sections) { 1407 ImageRange* normalized = NULL; 1408 uint32_t nnormalized = 0, normalized_cap = 0; 1409 st = normalize_overlaps(ctx, ranges, nranges, &normalized, &nnormalized, 1410 &normalized_cap); 1411 if (st == KIT_OK) { 1412 ranges_free(ctx, ranges, cap); 1413 ranges = normalized; 1414 nranges = nnormalized; 1415 cap = normalized_cap; 1416 } 1417 } 1418 if (st == KIT_OK) { 1419 KitObjImageInfo info; 1420 memset(&report, 0, sizeof report); 1421 report.sections_concat = from_sections ? true : false; 1422 report.section_ranges = address_sections ? true : false; 1423 report.base_is_load_address = 1424 (!from_sections && !address_sections) ? true : false; 1425 if (!from_sections) report.original_base = ranges[0].original_addr; 1426 st = compute_layout(ctx, ranges, nranges, opts, seg_mem_end, &report); 1427 if (st == KIT_OK) { 1428 report.emitted_base = report.base; 1429 if (kit_obj_kind(obj) != KIT_OBJ_KIND_REL && 1430 kit_obj_image_info(obj, &info) == KIT_OK && info.entry != 0) { 1431 report.has_entry = true; 1432 report.original_entry = info.entry; 1433 if (!u64_add_bias(info.entry, opts->bias, &report.emitted_entry)) { 1434 kit_ctx_diagf(ctx, "image: entry address overflows after --bias"); 1435 st = KIT_INVALID; 1436 } 1437 } 1438 } 1439 } 1440 if (st == KIT_OK && opts->image_header != KIT_IMAGE_HEADER_NONE) { 1441 KitImageHeader kind; 1442 st = resolve_image_header(ctx, obj, opts->image_header, &kind); 1443 if (st == KIT_OK) 1444 st = build_image_header(ctx, kind, &ranges[0], &report, opts, image_hdr); 1445 if (st == KIT_OK) { 1446 image_hdr_p = image_hdr; 1447 report.image_header = (uint32_t)kind; 1448 } 1449 } 1450 if (st == KIT_OK) { 1451 if (format == KIT_IMAGE_FORMAT_IHEX) { 1452 st = check_32bit_text_image_range(ctx, &report, "ihex"); 1453 if (st == KIT_OK && report.has_entry && 1454 report.emitted_entry > UINT32_MAX) { 1455 kit_ctx_diagf(ctx, 1456 "image: ihex entry cannot emit above 32-bit addresses"); 1457 st = KIT_UNSUPPORTED; 1458 } 1459 if (st == KIT_OK) 1460 st = write_ihex_records(ctx, ranges, nranges, opts, &report, out); 1461 } else if (format == KIT_IMAGE_FORMAT_SREC) { 1462 st = check_32bit_text_image_range(ctx, &report, "srec"); 1463 if (st == KIT_OK && report.has_entry && 1464 report.emitted_entry > UINT32_MAX) { 1465 kit_ctx_diagf(ctx, 1466 "image: srec entry cannot emit above 32-bit addresses"); 1467 st = KIT_UNSUPPORTED; 1468 } 1469 if (st == KIT_OK) 1470 st = write_srec_records(ctx, ranges, nranges, opts, &report, out); 1471 } else { 1472 st = write_layout(ctx, ranges, nranges, opts, &report, image_hdr_p, out); 1473 } 1474 } 1475 if (st == KIT_OK && report_out) *report_out = report; 1476 ranges_free(ctx, ranges, cap); 1477 return st; 1478 }