| ... | ... | @@ -550,6 +550,86 @@ pub fn parseTextBlocks(self: *Object, zld: *Zld) !void { |
| 550 | 550 | if (is_splittable) blocks: { |
| 551 | 551 | if (filtered_nlists.len == 0) break :blocks; |
| 552 | 552 | |
| 553 | // If the first nlist does not match the start of the section, |
| 554 | // then we need encapsulate the memory range [section start, first symbol) |
| 555 | // as a temporary symbol and insert the matching TextBlock. |
| 556 | const first_nlist = filtered_nlists[0].nlist; |
| 557 | if (first_nlist.n_value > sect.addr) { |
| 558 | const symbol = self.sections_as_symbols.get(sect_id) orelse symbol: { |
| 559 | const name = try std.fmt.allocPrint(self.allocator, "l_{s}_{s}_{s}", .{ |
| 560 | self.name.?, |
| 561 | segmentName(sect), |
| 562 | sectionName(sect), |
| 563 | }); |
| 564 | defer self.allocator.free(name); |
| 565 | const symbol = try Symbol.new(self.allocator, name); |
| 566 | try self.sections_as_symbols.putNoClobber(self.allocator, sect_id, symbol); |
| 567 | break :symbol symbol; |
| 568 | }; |
| 569 | |
| 570 | const local_sym_index = @intCast(u32, zld.locals.items.len); |
| 571 | symbol.payload = .{ |
| 572 | .regular = .{ |
| 573 | .linkage = .translation_unit, |
| 574 | .address = sect.addr, |
| 575 | .segment_id = match.seg, |
| 576 | .section_id = match.sect, |
| 577 | .file = self, |
| 578 | .local_sym_index = local_sym_index, |
| 579 | }, |
| 580 | }; |
| 581 | try zld.locals.append(zld.allocator, symbol); |
| 582 | |
| 583 | const block_code = code[0 .. first_nlist.n_value - sect.addr]; |
| 584 | const block_size = block_code.len; |
| 585 | |
| 586 | const block = try self.allocator.create(TextBlock); |
| 587 | errdefer self.allocator.destroy(block); |
| 588 | |
| 589 | block.* = TextBlock.init(self.allocator); |
| 590 | block.local_sym_index = local_sym_index; |
| 591 | block.code = try self.allocator.dupe(u8, block_code); |
| 592 | block.size = block_size; |
| 593 | block.alignment = sect.@"align"; |
| 594 | |
| 595 | const block_relocs = filterRelocs(relocs, 0, block_size); |
| 596 | if (block_relocs.len > 0) { |
| 597 | try self.parseRelocs(zld, block_relocs, block, 0); |
| 598 | } |
| 599 | |
| 600 | if (zld.has_dices) { |
| 601 | const dices = filterDice(self.data_in_code_entries.items, sect.addr, sect.addr + block_size); |
| 602 | try block.dices.ensureTotalCapacity(dices.len); |
| 603 | |
| 604 | for (dices) |dice| { |
| 605 | block.dices.appendAssumeCapacity(.{ |
| 606 | .offset = dice.offset - try math.cast(u32, sect.addr), |
| 607 | .length = dice.length, |
| 608 | .kind = dice.kind, |
| 609 | }); |
| 610 | } |
| 611 | } |
| 612 | |
| 613 | // Update target section's metadata |
| 614 | // TODO should we update segment's size here too? |
| 615 | // How does it tie with incremental space allocs? |
| 616 | const tseg = &zld.load_commands.items[match.seg].Segment; |
| 617 | const tsect = &tseg.sections.items[match.sect]; |
| 618 | const new_alignment = math.max(tsect.@"align", block.alignment); |
| 619 | const new_alignment_pow_2 = try math.powi(u32, 2, new_alignment); |
| 620 | const new_size = mem.alignForwardGeneric(u64, tsect.size + block.size, new_alignment_pow_2); |
| 621 | tsect.size = new_size; |
| 622 | tsect.@"align" = new_alignment; |
| 623 | |
| 624 | if (zld.blocks.getPtr(match)) |last| { |
| 625 | last.*.next = block; |
| 626 | block.prev = last.*; |
| 627 | last.* = block; |
| 628 | } else { |
| 629 | try zld.blocks.putNoClobber(zld.allocator, match, block); |
| 630 | } |
| 631 | } |
| 632 | |
| 553 | 633 | var parser = TextBlockParser{ |
| 554 | 634 | .allocator = self.allocator, |
| 555 | 635 | .section = sect, |
| ... | ... | @@ -610,6 +690,8 @@ pub fn parseTextBlocks(self: *Object, zld: *Zld) !void { |
| 610 | 690 | try self.sections_as_symbols.putNoClobber(self.allocator, sect_id, symbol); |
| 611 | 691 | break :symbol symbol; |
| 612 | 692 | }; |
| 693 | |
| 694 | const local_sym_index = @intCast(u32, zld.locals.items.len); |
| 613 | 695 | symbol.payload = .{ |
| 614 | 696 | .regular = .{ |
| 615 | 697 | .linkage = .translation_unit, |
| ... | ... | @@ -617,9 +699,9 @@ pub fn parseTextBlocks(self: *Object, zld: *Zld) !void { |
| 617 | 699 | .segment_id = match.seg, |
| 618 | 700 | .section_id = match.sect, |
| 619 | 701 | .file = self, |
| 702 | .local_sym_index = local_sym_index, |
| 620 | 703 | }, |
| 621 | 704 | }; |
| 622 | | const local_sym_index = @intCast(u32, zld.locals.items.len); |
| 623 | 705 | try zld.locals.append(zld.allocator, symbol); |
| 624 | 706 | |
| 625 | 707 | const block = try self.allocator.create(TextBlock); |