| ... | ... | @@ -1948,29 +1948,52 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void { |
| 1948 | 1948 | args.source_target_sect_addr = source_sect.inner.addr; |
| 1949 | 1949 | } |
| 1950 | 1950 | |
| 1951 | | rebases: { |
| 1952 | | var hit: bool = false; |
| 1953 | | if (target_map.segment_id == self.data_segment_cmd_index.?) { |
| 1954 | | if (self.data_section_index) |index| { |
| 1955 | | if (index == target_map.section_id) hit = true; |
| 1951 | const flags = @truncate(u8, target_sect.flags & 0xff); |
| 1952 | const should_rebase = rebase: { |
| 1953 | if (!unsigned.is_64bit) break :rebase false; |
| 1954 | |
| 1955 | // TODO actually, a check similar to what dyld is doing, that is, verifying |
| 1956 | // that the segment is writable should be enough here. |
| 1957 | const is_right_segment = blk: { |
| 1958 | if (self.data_segment_cmd_index) |idx| { |
| 1959 | if (target_map.segment_id == idx) { |
| 1960 | break :blk true; |
| 1961 | } |
| 1956 | 1962 | } |
| 1963 | if (self.data_const_segment_cmd_index) |idx| { |
| 1964 | if (target_map.segment_id == idx) { |
| 1965 | break :blk true; |
| 1966 | } |
| 1967 | } |
| 1968 | break :blk false; |
| 1969 | }; |
| 1970 | |
| 1971 | if (!is_right_segment) break :rebase false; |
| 1972 | if (flags != macho.S_LITERAL_POINTERS and |
| 1973 | flags != macho.S_REGULAR) |
| 1974 | { |
| 1975 | break :rebase false; |
| 1957 | 1976 | } |
| 1958 | | if (target_map.segment_id == self.data_const_segment_cmd_index.?) { |
| 1959 | | if (self.data_const_section_index) |index| { |
| 1960 | | if (index == target_map.section_id) hit = true; |
| 1977 | if (rel.target == .symbol) { |
| 1978 | const final = rel.target.symbol.getTopmostAlias(); |
| 1979 | if (final.cast(Symbol.Proxy)) |_| { |
| 1980 | break :rebase false; |
| 1961 | 1981 | } |
| 1962 | 1982 | } |
| 1963 | 1983 | |
| 1964 | | if (!hit) break :rebases; |
| 1984 | break :rebase true; |
| 1985 | }; |
| 1965 | 1986 | |
| 1987 | if (should_rebase) { |
| 1966 | 1988 | try self.local_rebases.append(self.allocator, .{ |
| 1967 | 1989 | .offset = source_addr - target_seg.inner.vmaddr, |
| 1968 | 1990 | .segment_id = target_map.segment_id, |
| 1969 | 1991 | }); |
| 1970 | 1992 | } |
| 1993 | |
| 1971 | 1994 | // TLV is handled via a separate offset mechanism. |
| 1972 | 1995 | // Calculate the offset to the initializer. |
| 1973 | | if (target_sect.flags == macho.S_THREAD_LOCAL_VARIABLES) tlv: { |
| 1996 | if (flags == macho.S_THREAD_LOCAL_VARIABLES) tlv: { |
| 1974 | 1997 | // TODO we don't want to save offset to tlv_bootstrap |
| 1975 | 1998 | if (mem.eql(u8, rel.target.symbol.name, "__tlv_bootstrap")) break :tlv; |
| 1976 | 1999 | |