authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-09-10 22:42:39+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-09-10 22:42:39+02:00
log6e0c3950b8115e1e274214447763733b3d3055d6
tree3c7d2486af8ea0380c5e89ed4dac586b62191981
parent8e5f7f5fe89e1c2979df2c735046c81e37c3f842

macho: rename blocks to atoms in Object.zig


2 files changed, 77 insertions(+), 79 deletions(-)

src/link/MachO.zig+5-5
......@@ -2649,7 +2649,7 @@ fn parseTextBlocks(self: *MachO) !void {
26492649 defer section_metadata.deinit();
26502650
26512651 for (self.objects.items) |*object, object_id| {
2652 var atoms_in_objects = try object.parseTextBlocks(self.base.allocator, @intCast(u16, object_id), self);
2652 var atoms_in_objects = try object.parseIntoAtoms(self.base.allocator, @intCast(u16, object_id), self);
26532653 defer atoms_in_objects.deinit();
26542654
26552655 var it = atoms_in_objects.iterator();
......@@ -4628,13 +4628,13 @@ fn writeSymbolTable(self: *MachO) !void {
46284628 .n_value = object.mtime orelse 0,
46294629 });
46304630
4631 for (object.text_blocks.items) |block| {
4632 if (block.stab) |stab| {
4633 const nlists = try stab.asNlists(block.local_sym_index, self);
4631 for (object.atoms.items) |atom| {
4632 if (atom.stab) |stab| {
4633 const nlists = try stab.asNlists(atom.local_sym_index, self);
46344634 defer self.base.allocator.free(nlists);
46354635 try locals.appendSlice(nlists);
46364636 } else {
4637 for (block.contained.items) |sym_at_off| {
4637 for (atom.contained.items) |sym_at_off| {
46384638 const stab = sym_at_off.stab orelse continue;
46394639 const nlists = try stab.asNlists(sym_at_off.local_sym_index, self);
46404640 defer self.base.allocator.free(nlists);
src/link/MachO/Object.zig+72-74
......@@ -20,8 +20,6 @@ const Atom = @import("Atom.zig");
2020const LoadCommand = commands.LoadCommand;
2121const MachO = @import("../MachO.zig");
2222
23const TextBlock = Atom;
24
2523file: fs.File,
2624name: []const u8,
2725
......@@ -57,7 +55,7 @@ tu_name: ?[]const u8 = null,
5755tu_comp_dir: ?[]const u8 = null,
5856mtime: ?u64 = null,
5957
60text_blocks: std.ArrayListUnmanaged(*TextBlock) = .{},
58atoms: std.ArrayListUnmanaged(*Atom) = .{},
6159sections_as_symbols: std.AutoHashMapUnmanaged(u16, u32) = .{},
6260
6361// TODO symbol mapping and its inverse can probably be simple arrays
......@@ -137,7 +135,7 @@ pub fn deinit(self: *Object, allocator: *Allocator) void {
137135 self.data_in_code_entries.deinit(allocator);
138136 self.symtab.deinit(allocator);
139137 self.strtab.deinit(allocator);
140 self.text_blocks.deinit(allocator);
138 self.atoms.deinit(allocator);
141139 self.sections_as_symbols.deinit(allocator);
142140 self.symbol_mapping.deinit(allocator);
143141 self.reverse_symbol_mapping.deinit(allocator);
......@@ -322,14 +320,14 @@ const Context = struct {
322320 parsed_atoms: *ParsedAtoms,
323321};
324322
325const TextBlockParser = struct {
323const AtomParser = struct {
326324 section: macho.section_64,
327325 code: []u8,
328326 relocs: []macho.relocation_info,
329327 nlists: []NlistWithIndex,
330328 index: u32 = 0,
331329
332 fn peek(self: TextBlockParser) ?NlistWithIndex {
330 fn peek(self: AtomParser) ?NlistWithIndex {
333331 return if (self.index + 1 < self.nlists.len) self.nlists[self.index + 1] else null;
334332 }
335333
......@@ -343,7 +341,7 @@ const TextBlockParser = struct {
343341 }
344342 }
345343
346 pub fn next(self: *TextBlockParser, context: Context) !?*TextBlock {
344 pub fn next(self: *AtomParser, context: Context) !?*Atom {
347345 if (self.index == self.nlists.len) return null;
348346
349347 var aliases = std.ArrayList(NlistWithIndex).init(context.allocator);
......@@ -368,12 +366,12 @@ const TextBlockParser = struct {
368366 }
369367
370368 if (aliases.items.len > 1) {
371 // Bubble-up senior symbol as the main link to the text block.
369 // Bubble-up senior symbol as the main link to the atom.
372370 sort.sort(
373371 NlistWithIndex,
374372 aliases.items,
375373 context,
376 TextBlockParser.lessThanBySeniority,
374 AtomParser.lessThanBySeniority,
377375 );
378376 }
379377
......@@ -393,12 +391,12 @@ const TextBlockParser = struct {
393391 else
394392 max_align;
395393
396 const stab: ?TextBlock.Stab = if (context.object.debug_info) |di| blk: {
394 const stab: ?Atom.Stab = if (context.object.debug_info) |di| blk: {
397395 // TODO there has to be a better to handle this.
398396 for (di.inner.func_list.items) |func| {
399397 if (func.pc_range) |range| {
400398 if (senior_nlist.nlist.n_value >= range.start and senior_nlist.nlist.n_value < range.end) {
401 break :blk TextBlock.Stab{
399 break :blk Atom.Stab{
402400 .function = range.end - range.start,
403401 };
404402 }
......@@ -409,25 +407,25 @@ const TextBlockParser = struct {
409407 break :blk .static;
410408 } else null;
411409
412 const block = try context.macho_file.createEmptyAtom(senior_nlist.index, size, actual_align);
413 block.stab = stab;
410 const atom = try context.macho_file.createEmptyAtom(senior_nlist.index, size, actual_align);
411 atom.stab = stab;
414412
415413 const is_zerofill = blk: {
416414 const section_type = commands.sectionType(self.section);
417415 break :blk section_type == macho.S_ZEROFILL or section_type == macho.S_THREAD_LOCAL_ZEROFILL;
418416 };
419417 if (!is_zerofill) {
420 mem.copy(u8, block.code.items, code);
418 mem.copy(u8, atom.code.items, code);
421419 }
422420
423 try block.aliases.ensureTotalCapacity(context.allocator, aliases.items.len);
421 try atom.aliases.ensureTotalCapacity(context.allocator, aliases.items.len);
424422 for (aliases.items) |alias| {
425 block.aliases.appendAssumeCapacity(alias.index);
423 atom.aliases.appendAssumeCapacity(alias.index);
426424 const sym = &context.macho_file.locals.items[alias.index];
427425 sym.n_sect = @intCast(u8, context.macho_file.section_ordinals.getIndex(context.match).? + 1);
428426 }
429427
430 try block.parseRelocs(self.relocs, .{
428 try atom.parseRelocs(self.relocs, .{
431429 .base_addr = self.section.addr,
432430 .base_offset = start_addr,
433431 .allocator = context.allocator,
......@@ -442,10 +440,10 @@ const TextBlockParser = struct {
442440 senior_nlist.nlist.n_value,
443441 senior_nlist.nlist.n_value + size,
444442 );
445 try block.dices.ensureTotalCapacity(context.allocator, dices.len);
443 try atom.dices.ensureTotalCapacity(context.allocator, dices.len);
446444
447445 for (dices) |dice| {
448 block.dices.appendAssumeCapacity(.{
446 atom.dices.appendAssumeCapacity(.{
449447 .offset = dice.offset - try math.cast(u32, senior_nlist.nlist.n_value),
450448 .length = dice.length,
451449 .kind = dice.kind,
......@@ -455,13 +453,13 @@ const TextBlockParser = struct {
455453
456454 self.index += 1;
457455
458 return block;
456 return atom;
459457 }
460458};
461459
462pub const ParsedAtoms = std.AutoHashMap(MachO.MatchingSection, *TextBlock);
460pub const ParsedAtoms = std.AutoHashMap(MachO.MatchingSection, *Atom);
463461
464pub fn parseTextBlocks(
462pub fn parseIntoAtoms(
465463 self: *Object,
466464 allocator: *Allocator,
467465 object_id: u16,
......@@ -508,7 +506,7 @@ pub fn parseTextBlocks(
508506
509507 for (seg.sections.items) |sect, id| {
510508 const sect_id = @intCast(u8, id);
511 log.debug("putting section '{s},{s}' as a TextBlock", .{
509 log.debug("putting section '{s},{s}' as an Atom", .{
512510 segmentName(sect),
513511 sectionName(sect),
514512 });
......@@ -551,12 +549,12 @@ pub fn parseTextBlocks(
551549 macho_file.has_stabs = macho_file.has_stabs or self.debug_info != null;
552550
553551 next: {
554 if (is_splittable) blocks: {
555 if (filtered_nlists.len == 0) break :blocks;
552 if (is_splittable) atoms: {
553 if (filtered_nlists.len == 0) break :atoms;
556554
557555 // If the first nlist does not match the start of the section,
558556 // then we need to encapsulate the memory range [section start, first symbol)
559 // as a temporary symbol and insert the matching TextBlock.
557 // as a temporary symbol and insert the matching Atom.
560558 const first_nlist = filtered_nlists[0].nlist;
561559 if (first_nlist.n_value > sect.addr) {
562560 const sym_name = try std.fmt.allocPrint(allocator, "l_{s}_{s}_{s}", .{
......@@ -566,8 +564,8 @@ pub fn parseTextBlocks(
566564 });
567565 defer allocator.free(sym_name);
568566
569 const block_local_sym_index = self.sections_as_symbols.get(sect_id) orelse blk: {
570 const block_local_sym_index = @intCast(u32, macho_file.locals.items.len);
567 const atom_local_sym_index = self.sections_as_symbols.get(sect_id) orelse blk: {
568 const atom_local_sym_index = @intCast(u32, macho_file.locals.items.len);
571569 try macho_file.locals.append(allocator, .{
572570 .n_strx = try macho_file.makeString(sym_name),
573571 .n_type = macho.N_SECT,
......@@ -575,22 +573,22 @@ pub fn parseTextBlocks(
575573 .n_desc = 0,
576574 .n_value = 0,
577575 });
578 try self.sections_as_symbols.putNoClobber(allocator, sect_id, block_local_sym_index);
579 break :blk block_local_sym_index;
576 try self.sections_as_symbols.putNoClobber(allocator, sect_id, atom_local_sym_index);
577 break :blk atom_local_sym_index;
580578 };
581 const block_code = code[0 .. first_nlist.n_value - sect.addr];
582 const block_size = block_code.len;
583 const block = try macho_file.createEmptyAtom(block_local_sym_index, block_size, sect.@"align");
579 const atom_code = code[0 .. first_nlist.n_value - sect.addr];
580 const atom_size = atom_code.len;
581 const atom = try macho_file.createEmptyAtom(atom_local_sym_index, atom_size, sect.@"align");
584582
585583 const is_zerofill = blk: {
586584 const section_type = commands.sectionType(sect);
587585 break :blk section_type == macho.S_ZEROFILL or section_type == macho.S_THREAD_LOCAL_ZEROFILL;
588586 };
589587 if (!is_zerofill) {
590 mem.copy(u8, block.code.items, block_code);
588 mem.copy(u8, atom.code.items, atom_code);
591589 }
592590
593 try block.parseRelocs(relocs, .{
591 try atom.parseRelocs(relocs, .{
594592 .base_addr = sect.addr,
595593 .base_offset = 0,
596594 .allocator = allocator,
......@@ -600,11 +598,11 @@ pub fn parseTextBlocks(
600598 });
601599
602600 if (macho_file.has_dices) {
603 const dices = filterDice(self.data_in_code_entries.items, sect.addr, sect.addr + block_size);
604 try block.dices.ensureTotalCapacity(allocator, dices.len);
601 const dices = filterDice(self.data_in_code_entries.items, sect.addr, sect.addr + atom_size);
602 try atom.dices.ensureTotalCapacity(allocator, dices.len);
605603
606604 for (dices) |dice| {
607 block.dices.appendAssumeCapacity(.{
605 atom.dices.appendAssumeCapacity(.{
608606 .offset = dice.offset - try math.cast(u32, sect.addr),
609607 .length = dice.length,
610608 .kind = dice.kind,
......@@ -613,16 +611,16 @@ pub fn parseTextBlocks(
613611 }
614612
615613 if (parsed_atoms.getPtr(match)) |last| {
616 last.*.next = block;
617 block.prev = last.*;
618 last.* = block;
614 last.*.next = atom;
615 atom.prev = last.*;
616 last.* = atom;
619617 } else {
620 try parsed_atoms.putNoClobber(match, block);
618 try parsed_atoms.putNoClobber(match, atom);
621619 }
622 try self.text_blocks.append(allocator, block);
620 try self.atoms.append(allocator, atom);
623621 }
624622
625 var parser = TextBlockParser{
623 var parser = AtomParser{
626624 .section = sect,
627625 .code = code,
628626 .relocs = relocs,
......@@ -635,10 +633,10 @@ pub fn parseTextBlocks(
635633 .macho_file = macho_file,
636634 .match = match,
637635 .parsed_atoms = &parsed_atoms,
638 })) |block| {
639 const sym = macho_file.locals.items[block.local_sym_index];
636 })) |atom| {
637 const sym = macho_file.locals.items[atom.local_sym_index];
640638 const is_ext = blk: {
641 const orig_sym_id = self.reverse_symbol_mapping.get(block.local_sym_index) orelse unreachable;
639 const orig_sym_id = self.reverse_symbol_mapping.get(atom.local_sym_index) orelse unreachable;
642640 break :blk MachO.symbolIsExt(self.symtab.items[orig_sym_id]);
643641 };
644642 if (is_ext) {
......@@ -662,26 +660,26 @@ pub fn parseTextBlocks(
662660 // In x86_64 relocs, it can so happen that the compiler refers to the same
663661 // atom by both the actual assigned symbol and the start of the section. In this
664662 // case, we need to link the two together so add an alias.
665 try block.aliases.append(allocator, alias);
663 try atom.aliases.append(allocator, alias);
666664 }
667665 }
668666
669667 if (parsed_atoms.getPtr(match)) |last| {
670 last.*.next = block;
671 block.prev = last.*;
672 last.* = block;
668 last.*.next = atom;
669 atom.prev = last.*;
670 last.* = atom;
673671 } else {
674 try parsed_atoms.putNoClobber(match, block);
672 try parsed_atoms.putNoClobber(match, atom);
675673 }
676 try self.text_blocks.append(allocator, block);
674 try self.atoms.append(allocator, atom);
677675 }
678676
679677 break :next;
680678 }
681679
682 // Since there is no symbol to refer to this block, we create
680 // Since there is no symbol to refer to this atom, we create
683681 // a temp one, unless we already did that when working out the relocations
684 // of other text blocks.
682 // of other atoms.
685683 const sym_name = try std.fmt.allocPrint(allocator, "l_{s}_{s}_{s}", .{
686684 self.name,
687685 segmentName(sect),
......@@ -689,8 +687,8 @@ pub fn parseTextBlocks(
689687 });
690688 defer allocator.free(sym_name);
691689
692 const block_local_sym_index = self.sections_as_symbols.get(sect_id) orelse blk: {
693 const block_local_sym_index = @intCast(u32, macho_file.locals.items.len);
690 const atom_local_sym_index = self.sections_as_symbols.get(sect_id) orelse blk: {
691 const atom_local_sym_index = @intCast(u32, macho_file.locals.items.len);
694692 try macho_file.locals.append(allocator, .{
695693 .n_strx = try macho_file.makeString(sym_name),
696694 .n_type = macho.N_SECT,
......@@ -698,20 +696,20 @@ pub fn parseTextBlocks(
698696 .n_desc = 0,
699697 .n_value = 0,
700698 });
701 try self.sections_as_symbols.putNoClobber(allocator, sect_id, block_local_sym_index);
702 break :blk block_local_sym_index;
699 try self.sections_as_symbols.putNoClobber(allocator, sect_id, atom_local_sym_index);
700 break :blk atom_local_sym_index;
703701 };
704 const block = try macho_file.createEmptyAtom(block_local_sym_index, sect.size, sect.@"align");
702 const atom = try macho_file.createEmptyAtom(atom_local_sym_index, sect.size, sect.@"align");
705703
706704 const is_zerofill = blk: {
707705 const section_type = commands.sectionType(sect);
708706 break :blk section_type == macho.S_ZEROFILL or section_type == macho.S_THREAD_LOCAL_ZEROFILL;
709707 };
710708 if (!is_zerofill) {
711 mem.copy(u8, block.code.items, code);
709 mem.copy(u8, atom.code.items, code);
712710 }
713711
714 try block.parseRelocs(relocs, .{
712 try atom.parseRelocs(relocs, .{
715713 .base_addr = sect.addr,
716714 .base_offset = 0,
717715 .allocator = allocator,
......@@ -722,10 +720,10 @@ pub fn parseTextBlocks(
722720
723721 if (macho_file.has_dices) {
724722 const dices = filterDice(self.data_in_code_entries.items, sect.addr, sect.addr + sect.size);
725 try block.dices.ensureTotalCapacity(allocator, dices.len);
723 try atom.dices.ensureTotalCapacity(allocator, dices.len);
726724
727725 for (dices) |dice| {
728 block.dices.appendAssumeCapacity(.{
726 atom.dices.appendAssumeCapacity(.{
729727 .offset = dice.offset - try math.cast(u32, sect.addr),
730728 .length = dice.length,
731729 .kind = dice.kind,
......@@ -733,12 +731,12 @@ pub fn parseTextBlocks(
733731 }
734732 }
735733
736 // Since this is block gets a helper local temporary symbol that didn't exist
734 // Since this is atom gets a helper local temporary symbol that didn't exist
737735 // in the object file which encompasses the entire section, we need traverse
738736 // the filtered symbols and note which symbol is contained within so that
739737 // we can properly allocate addresses down the line.
740738 // While we're at it, we need to update segment,section mapping of each symbol too.
741 try block.contained.ensureTotalCapacity(allocator, filtered_nlists.len);
739 try atom.contained.ensureTotalCapacity(allocator, filtered_nlists.len);
742740
743741 for (filtered_nlists) |nlist_with_index| {
744742 const nlist = nlist_with_index.nlist;
......@@ -746,12 +744,12 @@ pub fn parseTextBlocks(
746744 const local = &macho_file.locals.items[local_sym_index];
747745 local.n_sect = @intCast(u8, macho_file.section_ordinals.getIndex(match).? + 1);
748746
749 const stab: ?TextBlock.Stab = if (self.debug_info) |di| blk: {
747 const stab: ?Atom.Stab = if (self.debug_info) |di| blk: {
750748 // TODO there has to be a better to handle this.
751749 for (di.inner.func_list.items) |func| {
752750 if (func.pc_range) |range| {
753751 if (nlist.n_value >= range.start and nlist.n_value < range.end) {
754 break :blk TextBlock.Stab{
752 break :blk Atom.Stab{
755753 .function = range.end - range.start,
756754 };
757755 }
......@@ -762,7 +760,7 @@ pub fn parseTextBlocks(
762760 break :blk .static;
763761 } else null;
764762
765 block.contained.appendAssumeCapacity(.{
763 atom.contained.appendAssumeCapacity(.{
766764 .local_sym_index = local_sym_index,
767765 .offset = nlist.n_value - sect.addr,
768766 .stab = stab,
......@@ -770,13 +768,13 @@ pub fn parseTextBlocks(
770768 }
771769
772770 if (parsed_atoms.getPtr(match)) |last| {
773 last.*.next = block;
774 block.prev = last.*;
775 last.* = block;
771 last.*.next = atom;
772 atom.prev = last.*;
773 last.* = atom;
776774 } else {
777 try parsed_atoms.putNoClobber(match, block);
775 try parsed_atoms.putNoClobber(match, atom);
778776 }
779 try self.text_blocks.append(allocator, block);
777 try self.atoms.append(allocator, atom);
780778 }
781779 }
782780