| ... | @@ -3047,6 +3047,9 @@ fn createMhExecuteHeaderAtom(self: *MachO) !void { | ... | @@ -3047,6 +3047,9 @@ fn createMhExecuteHeaderAtom(self: *MachO) !void { |
| 3047 | .seg = self.text_segment_cmd_index.?, | 3047 | .seg = self.text_segment_cmd_index.?, |
| 3048 | .sect = self.text_section_index.?, | 3048 | .sect = self.text_section_index.?, |
| 3049 | }; | 3049 | }; |
| | 3050 | const seg = self.load_commands.items[match.seg].segment; |
| | 3051 | const sect = seg.sections.items[match.sect]; |
| | 3052 | |
| 3050 | const n_strx = try self.makeString("__mh_execute_header"); | 3053 | const n_strx = try self.makeString("__mh_execute_header"); |
| 3051 | const local_sym_index = @intCast(u32, self.locals.items.len); | 3054 | const local_sym_index = @intCast(u32, self.locals.items.len); |
| 3052 | var nlist = macho.nlist_64{ | 3055 | var nlist = macho.nlist_64{ |
| ... | @@ -3054,29 +3057,42 @@ fn createMhExecuteHeaderAtom(self: *MachO) !void { | ... | @@ -3054,29 +3057,42 @@ fn createMhExecuteHeaderAtom(self: *MachO) !void { |
| 3054 | .n_type = macho.N_SECT, | 3057 | .n_type = macho.N_SECT, |
| 3055 | .n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1), | 3058 | .n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1), |
| 3056 | .n_desc = 0, | 3059 | .n_desc = 0, |
| 3057 | .n_value = 0, | 3060 | .n_value = sect.addr, |
| 3058 | }; | 3061 | }; |
| 3059 | try self.locals.append(self.base.allocator, nlist); | 3062 | try self.locals.append(self.base.allocator, nlist); |
| | 3063 | self.mh_execute_header_index = local_sym_index; |
| 3060 | | 3064 | |
| 3061 | nlist.n_type |= macho.N_EXT; | 3065 | if (self.symbol_resolver.getPtr(n_strx)) |resolv| { |
| 3062 | const global_sym_index = @intCast(u32, self.globals.items.len); | 3066 | const global = &self.globals.items[resolv.where_index]; |
| 3063 | try self.globals.append(self.base.allocator, nlist); | 3067 | if (!(global.weakDef() or !global.pext())) { |
| 3064 | try self.symbol_resolver.putNoClobber(self.base.allocator, n_strx, .{ | 3068 | log.err("symbol '__mh_execute_header' defined multiple times", .{}); |
| 3065 | .where = .global, | 3069 | return error.MultipleSymbolDefinitions; |
| 3066 | .where_index = global_sym_index, | 3070 | } |
| 3067 | .local_sym_index = local_sym_index, | 3071 | resolv.local_sym_index = local_sym_index; |
| 3068 | .file = null, | 3072 | } else { |
| 3069 | }); | 3073 | const global_sym_index = @intCast(u32, self.globals.items.len); |
| | 3074 | nlist.n_type |= macho.N_EXT; |
| | 3075 | try self.globals.append(self.base.allocator, nlist); |
| | 3076 | try self.symbol_resolver.putNoClobber(self.base.allocator, n_strx, .{ |
| | 3077 | .where = .global, |
| | 3078 | .where_index = global_sym_index, |
| | 3079 | .local_sym_index = local_sym_index, |
| | 3080 | .file = null, |
| | 3081 | }); |
| | 3082 | } |
| 3070 | | 3083 | |
| | 3084 | // We always set the __mh_execute_header to point to the beginning of the __TEXT,__text section |
| 3071 | const atom = try self.createEmptyAtom(local_sym_index, 0, 0); | 3085 | const atom = try self.createEmptyAtom(local_sym_index, 0, 0); |
| 3072 | | 3086 | if (self.atoms.get(match)) |last| { |
| 3073 | if (self.needs_prealloc) { | 3087 | var first = last; |
| 3074 | const sym = &self.locals.items[local_sym_index]; | 3088 | while (first.prev) |prev| { |
| 3075 | const vaddr = try self.allocateAtom(atom, 0, 1, match); | 3089 | first = prev; |
| 3076 | sym.n_value = vaddr; | 3090 | } |
| 3077 | } else try self.addAtomToSection(atom, match); | 3091 | atom.next = first; |
| 3078 | | 3092 | first.prev = atom; |
| 3079 | self.mh_execute_header_index = local_sym_index; | 3093 | } else { |
| | 3094 | try self.atoms.putNoClobber(self.base.allocator, match, atom); |
| | 3095 | } |
| 3080 | } | 3096 | } |
| 3081 | | 3097 | |
| 3082 | fn resolveDyldStubBinder(self: *MachO) !void { | 3098 | fn resolveDyldStubBinder(self: *MachO) !void { |
| ... | @@ -3747,9 +3763,12 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl: *Module.De | ... | @@ -3747,9 +3763,12 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl: *Module.De |
| 3747 | } | 3763 | } |
| 3748 | const unnamed_consts = gop.value_ptr; | 3764 | const unnamed_consts = gop.value_ptr; |
| 3749 | | 3765 | |
| | 3766 | const decl_name = try decl.getFullyQualifiedName(self.base.allocator); |
| | 3767 | defer self.base.allocator.free(decl_name); |
| | 3768 | |
| 3750 | const name_str_index = blk: { | 3769 | const name_str_index = blk: { |
| 3751 | const index = unnamed_consts.items.len; | 3770 | const index = unnamed_consts.items.len; |
| 3752 | const name = try std.fmt.allocPrint(self.base.allocator, "__unnamed_{s}_{d}", .{ decl.name, index }); | 3771 | const name = try std.fmt.allocPrint(self.base.allocator, "__unnamed_{s}_{d}", .{ decl_name, index }); |
| 3753 | defer self.base.allocator.free(name); | 3772 | defer self.base.allocator.free(name); |
| 3754 | break :blk try self.makeString(name); | 3773 | break :blk try self.makeString(name); |
| 3755 | }; | 3774 | }; |
| ... | @@ -4041,14 +4060,17 @@ fn placeDecl(self: *MachO, decl: *Module.Decl, code_len: usize) !*macho.nlist_64 | ... | @@ -4041,14 +4060,17 @@ fn placeDecl(self: *MachO, decl: *Module.Decl, code_len: usize) !*macho.nlist_64 |
| 4041 | decl_ptr.* = try self.getMatchingSectionAtom(&decl.link.macho, decl.ty, decl.val); | 4060 | decl_ptr.* = try self.getMatchingSectionAtom(&decl.link.macho, decl.ty, decl.val); |
| 4042 | } | 4061 | } |
| 4043 | const match = decl_ptr.*.?; | 4062 | const match = decl_ptr.*.?; |
| | 4063 | const sym_name = try decl.getFullyQualifiedName(self.base.allocator); |
| | 4064 | defer self.base.allocator.free(sym_name); |
| 4044 | | 4065 | |
| 4045 | if (decl.link.macho.size != 0) { | 4066 | if (decl.link.macho.size != 0) { |
| 4046 | const capacity = decl.link.macho.capacity(self.*); | 4067 | const capacity = decl.link.macho.capacity(self.*); |
| 4047 | const need_realloc = code_len > capacity or !mem.isAlignedGeneric(u64, symbol.n_value, required_alignment); | 4068 | const need_realloc = code_len > capacity or !mem.isAlignedGeneric(u64, symbol.n_value, required_alignment); |
| | 4069 | |
| 4048 | if (need_realloc) { | 4070 | if (need_realloc) { |
| 4049 | const vaddr = try self.growAtom(&decl.link.macho, code_len, required_alignment, match); | 4071 | const vaddr = try self.growAtom(&decl.link.macho, code_len, required_alignment, match); |
| 4050 | | 4072 | |
| 4051 | log.debug("growing {s} and moving from 0x{x} to 0x{x}", .{ decl.name, symbol.n_value, vaddr }); | 4073 | log.debug("growing {s} and moving from 0x{x} to 0x{x}", .{ sym_name, symbol.n_value, vaddr }); |
| 4052 | | 4074 | |
| 4053 | if (vaddr != symbol.n_value) { | 4075 | if (vaddr != symbol.n_value) { |
| 4054 | log.debug(" (writing new GOT entry)", .{}); | 4076 | log.debug(" (writing new GOT entry)", .{}); |
| ... | @@ -4074,25 +4096,15 @@ fn placeDecl(self: *MachO, decl: *Module.Decl, code_len: usize) !*macho.nlist_64 | ... | @@ -4074,25 +4096,15 @@ fn placeDecl(self: *MachO, decl: *Module.Decl, code_len: usize) !*macho.nlist_64 |
| 4074 | decl.link.macho.size = code_len; | 4096 | decl.link.macho.size = code_len; |
| 4075 | decl.link.macho.dirty = true; | 4097 | decl.link.macho.dirty = true; |
| 4076 | | 4098 | |
| 4077 | const new_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{ | 4099 | symbol.n_strx = try self.makeString(sym_name); |
| 4078 | mem.sliceTo(decl.name, 0), | | |
| 4079 | }); | | |
| 4080 | defer self.base.allocator.free(new_name); | | |
| 4081 | | | |
| 4082 | symbol.n_strx = try self.makeString(new_name); | | |
| 4083 | symbol.n_type = macho.N_SECT; | 4100 | symbol.n_type = macho.N_SECT; |
| 4084 | symbol.n_sect = @intCast(u8, self.text_section_index.?) + 1; | 4101 | symbol.n_sect = @intCast(u8, self.text_section_index.?) + 1; |
| 4085 | symbol.n_desc = 0; | 4102 | symbol.n_desc = 0; |
| 4086 | } else { | 4103 | } else { |
| 4087 | const decl_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{ | 4104 | const name_str_index = try self.makeString(sym_name); |
| 4088 | mem.sliceTo(decl.name, 0), | | |
| 4089 | }); | | |
| 4090 | defer self.base.allocator.free(decl_name); | | |
| 4091 | | | |
| 4092 | const name_str_index = try self.makeString(decl_name); | | |
| 4093 | const addr = try self.allocateAtom(&decl.link.macho, code_len, required_alignment, match); | 4105 | const addr = try self.allocateAtom(&decl.link.macho, code_len, required_alignment, match); |
| 4094 | | 4106 | |
| 4095 | log.debug("allocated atom for {s} at 0x{x}", .{ decl_name, addr }); | 4107 | log.debug("allocated atom for {s} at 0x{x}", .{ sym_name, addr }); |
| 4096 | | 4108 | |
| 4097 | errdefer self.freeAtom(&decl.link.macho, match, false); | 4109 | errdefer self.freeAtom(&decl.link.macho, match, false); |
| 4098 | | 4110 | |
| ... | @@ -6675,17 +6687,17 @@ fn snapshotState(self: *MachO) !void { | ... | @@ -6675,17 +6687,17 @@ fn snapshotState(self: *MachO) !void { |
| 6675 | fn logSymtab(self: MachO) void { | 6687 | fn logSymtab(self: MachO) void { |
| 6676 | log.debug("locals:", .{}); | 6688 | log.debug("locals:", .{}); |
| 6677 | for (self.locals.items) |sym, id| { | 6689 | for (self.locals.items) |sym, id| { |
| 6678 | log.debug(" {d}: {s}: {}", .{ id, self.getString(sym.n_strx), sym }); | 6690 | log.debug(" {d}: {s}: @{x} in {d}", .{ id, self.getString(sym.n_strx), sym.n_value, sym.n_sect }); |
| 6679 | } | 6691 | } |
| 6680 | | 6692 | |
| 6681 | log.debug("globals:", .{}); | 6693 | log.debug("globals:", .{}); |
| 6682 | for (self.globals.items) |sym, id| { | 6694 | for (self.globals.items) |sym, id| { |
| 6683 | log.debug(" {d}: {s}: {}", .{ id, self.getString(sym.n_strx), sym }); | 6695 | log.debug(" {d}: {s}: @{x} in {d}", .{ id, self.getString(sym.n_strx), sym.n_value, sym.n_sect }); |
| 6684 | } | 6696 | } |
| 6685 | | 6697 | |
| 6686 | log.debug("undefs:", .{}); | 6698 | log.debug("undefs:", .{}); |
| 6687 | for (self.undefs.items) |sym, id| { | 6699 | for (self.undefs.items) |sym, id| { |
| 6688 | log.debug(" {d}: {s}: {}", .{ id, self.getString(sym.n_strx), sym }); | 6700 | log.debug(" {d}: {s}: in {d}", .{ id, self.getString(sym.n_strx), sym.n_desc }); |
| 6689 | } | 6701 | } |
| 6690 | | 6702 | |
| 6691 | { | 6703 | { |
| ... | @@ -6700,26 +6712,28 @@ fn logSymtab(self: MachO) void { | ... | @@ -6700,26 +6712,28 @@ fn logSymtab(self: MachO) void { |
| 6700 | for (self.got_entries_table.values()) |value| { | 6712 | for (self.got_entries_table.values()) |value| { |
| 6701 | const key = self.got_entries.items[value].target; | 6713 | const key = self.got_entries.items[value].target; |
| 6702 | const atom = self.got_entries.items[value].atom; | 6714 | const atom = self.got_entries.items[value].atom; |
| | 6715 | const n_value = self.locals.items[atom.local_sym_index].n_value; |
| 6703 | switch (key) { | 6716 | switch (key) { |
| 6704 | .local => { | 6717 | .local => |ndx| log.debug(" {d}: @{x}", .{ ndx, n_value }), |
| 6705 | const sym = self.locals.items[atom.local_sym_index]; | 6718 | .global => |n_strx| log.debug(" {s}: @{x}", .{ self.getString(n_strx), n_value }), |
| 6706 | log.debug(" {} => {s}", .{ key, self.getString(sym.n_strx) }); | | |
| 6707 | }, | | |
| 6708 | .global => |n_strx| log.debug(" {} => {s}", .{ key, self.getString(n_strx) }), | | |
| 6709 | } | 6719 | } |
| 6710 | } | 6720 | } |
| 6711 | | 6721 | |
| 6712 | log.debug("__thread_ptrs entries:", .{}); | 6722 | log.debug("__thread_ptrs entries:", .{}); |
| 6713 | for (self.tlv_ptr_entries_table.keys()) |key| { | 6723 | for (self.tlv_ptr_entries_table.values()) |value| { |
| 6714 | switch (key) { | 6724 | const key = self.tlv_ptr_entries.items[value].target; |
| 6715 | .local => unreachable, | 6725 | const atom = self.tlv_ptr_entries.items[value].atom; |
| 6716 | .global => |n_strx| log.debug(" {} => {s}", .{ key, self.getString(n_strx) }), | 6726 | const n_value = self.locals.items[atom.local_sym_index].n_value; |
| 6717 | } | 6727 | assert(key == .global); |
| | 6728 | log.debug(" {s}: @{x}", .{ self.getString(key.global), n_value }); |
| 6718 | } | 6729 | } |
| 6719 | | 6730 | |
| 6720 | log.debug("stubs:", .{}); | 6731 | log.debug("stubs:", .{}); |
| 6721 | for (self.stubs_table.keys()) |key| { | 6732 | for (self.stubs_table.keys()) |key| { |
| 6722 | log.debug(" {} => {s}", .{ key, self.getString(key) }); | 6733 | const value = self.stubs_table.get(key).?; |
| | 6734 | const atom = self.stubs.items[value]; |
| | 6735 | const sym = self.locals.items[atom.local_sym_index]; |
| | 6736 | log.debug(" {s}: @{x}", .{ self.getString(key), sym.n_value }); |
| 6723 | } | 6737 | } |
| 6724 | } | 6738 | } |
| 6725 | | 6739 | |