| ... | @@ -22,7 +22,14 @@ weak: bool = false, | ... | @@ -22,7 +22,14 @@ weak: bool = false, |
| 22 | /// Parsed symbol table represented as hash map of symbols' | 22 | /// Parsed symbol table represented as hash map of symbols' |
| 23 | /// names. We can and should defer creating *Symbols until | 23 | /// names. We can and should defer creating *Symbols until |
| 24 | /// a symbol is referenced by an object file. | 24 | /// a symbol is referenced by an object file. |
| 25 | symbols: std.StringArrayHashMapUnmanaged(void) = .{}, | 25 | /// |
| | 26 | /// The value for each parsed symbol represents whether the |
| | 27 | /// symbol is defined as a weak symbol or strong. |
| | 28 | /// TODO when the referenced symbol is weak, ld64 marks it as |
| | 29 | /// N_REF_TO_WEAK but need to investigate if there's more to it |
| | 30 | /// such as weak binding entry or simply weak. For now, we generate |
| | 31 | /// standard bind or lazy bind. |
| | 32 | symbols: std.StringArrayHashMapUnmanaged(bool) = .{}, |
| 26 | | 33 | |
| 27 | pub const Id = struct { | 34 | pub const Id = struct { |
| 28 | name: []const u8, | 35 | name: []const u8, |
| ... | @@ -168,7 +175,7 @@ pub fn parseFromBinary( | ... | @@ -168,7 +175,7 @@ pub fn parseFromBinary( |
| 168 | if (!add_to_symtab) continue; | 175 | if (!add_to_symtab) continue; |
| 169 | | 176 | |
| 170 | const sym_name = mem.sliceTo(@ptrCast([*:0]const u8, strtab.ptr + sym.n_strx), 0); | 177 | const sym_name = mem.sliceTo(@ptrCast([*:0]const u8, strtab.ptr + sym.n_strx), 0); |
| 171 | try self.symbols.putNoClobber(allocator, try allocator.dupe(u8, sym_name), {}); | 178 | try self.symbols.putNoClobber(allocator, try allocator.dupe(u8, sym_name), false); |
| 172 | } | 179 | } |
| 173 | }, | 180 | }, |
| 174 | .ID_DYLIB => { | 181 | .ID_DYLIB => { |
| ... | @@ -202,25 +209,30 @@ fn addObjCClassSymbol(self: *Dylib, allocator: Allocator, sym_name: []const u8) | ... | @@ -202,25 +209,30 @@ fn addObjCClassSymbol(self: *Dylib, allocator: Allocator, sym_name: []const u8) |
| 202 | | 209 | |
| 203 | for (expanded) |sym| { | 210 | for (expanded) |sym| { |
| 204 | if (self.symbols.contains(sym)) continue; | 211 | if (self.symbols.contains(sym)) continue; |
| 205 | try self.symbols.putNoClobber(allocator, sym, {}); | 212 | try self.symbols.putNoClobber(allocator, sym, false); |
| 206 | } | 213 | } |
| 207 | } | 214 | } |
| 208 | | 215 | |
| 209 | fn addObjCIVarSymbol(self: *Dylib, allocator: Allocator, sym_name: []const u8) !void { | 216 | fn addObjCIVarSymbol(self: *Dylib, allocator: Allocator, sym_name: []const u8) !void { |
| 210 | const expanded = try std.fmt.allocPrint(allocator, "_OBJC_IVAR_$_{s}", .{sym_name}); | 217 | const expanded = try std.fmt.allocPrint(allocator, "_OBJC_IVAR_$_{s}", .{sym_name}); |
| 211 | if (self.symbols.contains(expanded)) return; | 218 | if (self.symbols.contains(expanded)) return; |
| 212 | try self.symbols.putNoClobber(allocator, expanded, {}); | 219 | try self.symbols.putNoClobber(allocator, expanded, false); |
| 213 | } | 220 | } |
| 214 | | 221 | |
| 215 | fn addObjCEhTypeSymbol(self: *Dylib, allocator: Allocator, sym_name: []const u8) !void { | 222 | fn addObjCEhTypeSymbol(self: *Dylib, allocator: Allocator, sym_name: []const u8) !void { |
| 216 | const expanded = try std.fmt.allocPrint(allocator, "_OBJC_EHTYPE_$_{s}", .{sym_name}); | 223 | const expanded = try std.fmt.allocPrint(allocator, "_OBJC_EHTYPE_$_{s}", .{sym_name}); |
| 217 | if (self.symbols.contains(expanded)) return; | 224 | if (self.symbols.contains(expanded)) return; |
| 218 | try self.symbols.putNoClobber(allocator, expanded, {}); | 225 | try self.symbols.putNoClobber(allocator, expanded, false); |
| 219 | } | 226 | } |
| 220 | | 227 | |
| 221 | fn addSymbol(self: *Dylib, allocator: Allocator, sym_name: []const u8) !void { | 228 | fn addSymbol(self: *Dylib, allocator: Allocator, sym_name: []const u8) !void { |
| 222 | if (self.symbols.contains(sym_name)) return; | 229 | if (self.symbols.contains(sym_name)) return; |
| 223 | try self.symbols.putNoClobber(allocator, try allocator.dupe(u8, sym_name), {}); | 230 | try self.symbols.putNoClobber(allocator, try allocator.dupe(u8, sym_name), false); |
| | 231 | } |
| | 232 | |
| | 233 | fn addWeakSymbol(self: *Dylib, allocator: Allocator, sym_name: []const u8) !void { |
| | 234 | if (self.symbols.contains(sym_name)) return; |
| | 235 | try self.symbols.putNoClobber(allocator, try allocator.dupe(u8, sym_name), true); |
| 224 | } | 236 | } |
| 225 | | 237 | |
| 226 | const TargetMatcher = struct { | 238 | const TargetMatcher = struct { |
| ... | @@ -359,6 +371,12 @@ pub fn parseFromStub( | ... | @@ -359,6 +371,12 @@ pub fn parseFromStub( |
| 359 | } | 371 | } |
| 360 | } | 372 | } |
| 361 | | 373 | |
| | 374 | if (exp.weak_symbols) |symbols| { |
| | 375 | for (symbols) |sym_name| { |
| | 376 | try self.addWeakSymbol(allocator, sym_name); |
| | 377 | } |
| | 378 | } |
| | 379 | |
| 362 | if (exp.objc_classes) |objc_classes| { | 380 | if (exp.objc_classes) |objc_classes| { |
| 363 | for (objc_classes) |class_name| { | 381 | for (objc_classes) |class_name| { |
| 364 | try self.addObjCClassSymbol(allocator, class_name); | 382 | try self.addObjCClassSymbol(allocator, class_name); |
| ... | @@ -402,6 +420,12 @@ pub fn parseFromStub( | ... | @@ -402,6 +420,12 @@ pub fn parseFromStub( |
| 402 | } | 420 | } |
| 403 | } | 421 | } |
| 404 | | 422 | |
| | 423 | if (exp.weak_symbols) |symbols| { |
| | 424 | for (symbols) |sym_name| { |
| | 425 | try self.addWeakSymbol(allocator, sym_name); |
| | 426 | } |
| | 427 | } |
| | 428 | |
| 405 | if (exp.objc_classes) |classes| { | 429 | if (exp.objc_classes) |classes| { |
| 406 | for (classes) |sym_name| { | 430 | for (classes) |sym_name| { |
| 407 | try self.addObjCClassSymbol(allocator, sym_name); | 431 | try self.addObjCClassSymbol(allocator, sym_name); |
| ... | @@ -432,6 +456,12 @@ pub fn parseFromStub( | ... | @@ -432,6 +456,12 @@ pub fn parseFromStub( |
| 432 | } | 456 | } |
| 433 | } | 457 | } |
| 434 | | 458 | |
| | 459 | if (reexp.weak_symbols) |symbols| { |
| | 460 | for (symbols) |sym_name| { |
| | 461 | try self.addWeakSymbol(allocator, sym_name); |
| | 462 | } |
| | 463 | } |
| | 464 | |
| 435 | if (reexp.objc_classes) |classes| { | 465 | if (reexp.objc_classes) |classes| { |
| 436 | for (classes) |sym_name| { | 466 | for (classes) |sym_name| { |
| 437 | try self.addObjCClassSymbol(allocator, sym_name); | 467 | try self.addObjCClassSymbol(allocator, sym_name); |