| ... | ... | @@ -3047,6 +3047,9 @@ fn createMhExecuteHeaderAtom(self: *MachO) !void { |
| 3047 | 3047 | .seg = self.text_segment_cmd_index.?, |
| 3048 | 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 | 3053 | const n_strx = try self.makeString("__mh_execute_header"); |
| 3051 | 3054 | const local_sym_index = @intCast(u32, self.locals.items.len); |
| 3052 | 3055 | var nlist = macho.nlist_64{ |
| ... | ... | @@ -3054,29 +3057,42 @@ fn createMhExecuteHeaderAtom(self: *MachO) !void { |
| 3054 | 3057 | .n_type = macho.N_SECT, |
| 3055 | 3058 | .n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1), |
| 3056 | 3059 | .n_desc = 0, |
| 3057 | | .n_value = 0, |
| 3060 | .n_value = sect.addr, |
| 3058 | 3061 | }; |
| 3059 | 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; |
| 3062 | | const global_sym_index = @intCast(u32, self.globals.items.len); |
| 3063 | | try self.globals.append(self.base.allocator, nlist); |
| 3064 | | try self.symbol_resolver.putNoClobber(self.base.allocator, n_strx, .{ |
| 3065 | | .where = .global, |
| 3066 | | .where_index = global_sym_index, |
| 3067 | | .local_sym_index = local_sym_index, |
| 3068 | | .file = null, |
| 3069 | | }); |
| 3065 | if (self.symbol_resolver.getPtr(n_strx)) |resolv| { |
| 3066 | const global = &self.globals.items[resolv.where_index]; |
| 3067 | if (!(global.weakDef() or !global.pext())) { |
| 3068 | log.err("symbol '__mh_execute_header' defined multiple times", .{}); |
| 3069 | return error.MultipleSymbolDefinitions; |
| 3070 | } |
| 3071 | resolv.local_sym_index = local_sym_index; |
| 3072 | } else { |
| 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 | 3085 | const atom = try self.createEmptyAtom(local_sym_index, 0, 0); |
| 3072 | | |
| 3073 | | if (self.needs_prealloc) { |
| 3074 | | const sym = &self.locals.items[local_sym_index]; |
| 3075 | | const vaddr = try self.allocateAtom(atom, 0, 1, match); |
| 3076 | | sym.n_value = vaddr; |
| 3077 | | } else try self.addAtomToSection(atom, match); |
| 3078 | | |
| 3079 | | self.mh_execute_header_index = local_sym_index; |
| 3086 | if (self.atoms.get(match)) |last| { |
| 3087 | var first = last; |
| 3088 | while (first.prev) |prev| { |
| 3089 | first = prev; |
| 3090 | } |
| 3091 | atom.next = first; |
| 3092 | first.prev = atom; |
| 3093 | } else { |
| 3094 | try self.atoms.putNoClobber(self.base.allocator, match, atom); |
| 3095 | } |
| 3080 | 3096 | } |
| 3081 | 3097 | |
| 3082 | 3098 | fn resolveDyldStubBinder(self: *MachO) !void { |
| ... | ... | @@ -3747,9 +3763,12 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl: *Module.De |
| 3747 | 3763 | } |
| 3748 | 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 | 3769 | const name_str_index = blk: { |
| 3751 | 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 | 3772 | defer self.base.allocator.free(name); |
| 3754 | 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 | 4060 | decl_ptr.* = try self.getMatchingSectionAtom(&decl.link.macho, decl.ty, decl.val); |
| 4042 | 4061 | } |
| 4043 | 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 | 4066 | if (decl.link.macho.size != 0) { |
| 4046 | 4067 | const capacity = decl.link.macho.capacity(self.*); |
| 4047 | 4068 | const need_realloc = code_len > capacity or !mem.isAlignedGeneric(u64, symbol.n_value, required_alignment); |
| 4069 | |
| 4048 | 4070 | if (need_realloc) { |
| 4049 | 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 | 4075 | if (vaddr != symbol.n_value) { |
| 4054 | 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 | 4096 | decl.link.macho.size = code_len; |
| 4075 | 4097 | decl.link.macho.dirty = true; |
| 4076 | 4098 | |
| 4077 | | const new_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{ |
| 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); |
| 4099 | symbol.n_strx = try self.makeString(sym_name); |
| 4083 | 4100 | symbol.n_type = macho.N_SECT; |
| 4084 | 4101 | symbol.n_sect = @intCast(u8, self.text_section_index.?) + 1; |
| 4085 | 4102 | symbol.n_desc = 0; |
| 4086 | 4103 | } else { |
| 4087 | | const decl_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{ |
| 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); |
| 4104 | const name_str_index = try self.makeString(sym_name); |
| 4093 | 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 | 4109 | errdefer self.freeAtom(&decl.link.macho, match, false); |
| 4098 | 4110 | |
| ... | ... | @@ -6675,17 +6687,17 @@ fn snapshotState(self: *MachO) !void { |
| 6675 | 6687 | fn logSymtab(self: MachO) void { |
| 6676 | 6688 | log.debug("locals:", .{}); |
| 6677 | 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 | 6693 | log.debug("globals:", .{}); |
| 6682 | 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 | 6698 | log.debug("undefs:", .{}); |
| 6687 | 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 | 6712 | for (self.got_entries_table.values()) |value| { |
| 6701 | 6713 | const key = self.got_entries.items[value].target; |
| 6702 | 6714 | const atom = self.got_entries.items[value].atom; |
| 6715 | const n_value = self.locals.items[atom.local_sym_index].n_value; |
| 6703 | 6716 | switch (key) { |
| 6704 | | .local => { |
| 6705 | | const sym = self.locals.items[atom.local_sym_index]; |
| 6706 | | log.debug(" {} => {s}", .{ key, self.getString(sym.n_strx) }); |
| 6707 | | }, |
| 6708 | | .global => |n_strx| log.debug(" {} => {s}", .{ key, self.getString(n_strx) }), |
| 6717 | .local => |ndx| log.debug(" {d}: @{x}", .{ ndx, n_value }), |
| 6718 | .global => |n_strx| log.debug(" {s}: @{x}", .{ self.getString(n_strx), n_value }), |
| 6709 | 6719 | } |
| 6710 | 6720 | } |
| 6711 | 6721 | |
| 6712 | 6722 | log.debug("__thread_ptrs entries:", .{}); |
| 6713 | | for (self.tlv_ptr_entries_table.keys()) |key| { |
| 6714 | | switch (key) { |
| 6715 | | .local => unreachable, |
| 6716 | | .global => |n_strx| log.debug(" {} => {s}", .{ key, self.getString(n_strx) }), |
| 6717 | | } |
| 6723 | for (self.tlv_ptr_entries_table.values()) |value| { |
| 6724 | const key = self.tlv_ptr_entries.items[value].target; |
| 6725 | const atom = self.tlv_ptr_entries.items[value].atom; |
| 6726 | const n_value = self.locals.items[atom.local_sym_index].n_value; |
| 6727 | assert(key == .global); |
| 6728 | log.debug(" {s}: @{x}", .{ self.getString(key.global), n_value }); |
| 6718 | 6729 | } |
| 6719 | 6730 | |
| 6720 | 6731 | log.debug("stubs:", .{}); |
| 6721 | 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 | |