| ... | @@ -819,20 +819,15 @@ pub const Section = struct { | ... | @@ -819,20 +819,15 @@ pub const Section = struct { |
| 819 | | 819 | |
| 820 | pub const GlobalName = struct { name: String, lib_name: String.Optional }; | 820 | pub const GlobalName = struct { name: String, lib_name: String.Optional }; |
| 821 | | 821 | |
| 822 | pub const DllStorageClass = enum(u2) { | | |
| 823 | default, | | |
| 824 | dllimport, | | |
| 825 | dllexport, | | |
| 826 | }; | | |
| 827 | | | |
| 828 | pub const Symbol = struct { | 822 | pub const Symbol = struct { |
| 829 | ni: MappedFile.Node.Index, | 823 | ni: MappedFile.Node.Index, |
| 830 | rva: u32, | 824 | rva: u32, |
| 831 | value: std.meta.BareUnion(Symbol.Value), | 825 | value: std.meta.BareUnion(Symbol.Value), |
| 832 | flags: packed struct(u16) { | 826 | flags: packed struct(u16) { |
| 833 | value_tag: ValueTag, | 827 | value_tag: ValueTag, |
| | 828 | type: Symbol.Type, |
| 834 | dll_storage_class: DllStorageClass, | 829 | dll_storage_class: DllStorageClass, |
| 835 | _: u12 = 0, | 830 | _: u10 = 0, |
| 836 | }, | 831 | }, |
| 837 | /// Relocations contained within this symbol | 832 | /// Relocations contained within this symbol |
| 838 | loc_relocs: Reloc.Index, | 833 | loc_relocs: Reloc.Index, |
| ... | @@ -843,6 +838,18 @@ pub const Symbol = struct { | ... | @@ -843,6 +838,18 @@ pub const Symbol = struct { |
| 843 | sti: SymbolTable.Index, | 838 | sti: SymbolTable.Index, |
| 844 | gmi: Node.GlobalMapIndex, | 839 | gmi: Node.GlobalMapIndex, |
| 845 | | 840 | |
| | 841 | pub const DllStorageClass = enum(u2) { |
| | 842 | default, |
| | 843 | dllimport, |
| | 844 | dllexport, |
| | 845 | }; |
| | 846 | |
| | 847 | pub const Type = enum(u2) { |
| | 848 | unknown, |
| | 849 | code, |
| | 850 | data, |
| | 851 | }; |
| | 852 | |
| 846 | const ValueTag = enum(u2) { | 853 | const ValueTag = enum(u2) { |
| 847 | node_offset, | 854 | node_offset, |
| 848 | alias_si, | 855 | alias_si, |
| ... | @@ -2314,6 +2321,7 @@ fn addSymbolAssumeCapacity(coff: *Coff) Symbol.Index { | ... | @@ -2314,6 +2321,7 @@ fn addSymbolAssumeCapacity(coff: *Coff) Symbol.Index { |
| 2314 | .value = .{ .size = 0 }, | 2321 | .value = .{ .size = 0 }, |
| 2315 | .flags = .{ | 2322 | .flags = .{ |
| 2316 | .value_tag = .size, | 2323 | .value_tag = .size, |
| | 2324 | .type = .unknown, |
| 2317 | .dll_storage_class = .default, | 2325 | .dll_storage_class = .default, |
| 2318 | }, | 2326 | }, |
| 2319 | .loc_relocs = .none, | 2327 | .loc_relocs = .none, |
| ... | @@ -2401,8 +2409,9 @@ fn getOrPutStringAssumeCapacity(coff: *Coff, string: []const u8) String { | ... | @@ -2401,8 +2409,9 @@ fn getOrPutStringAssumeCapacity(coff: *Coff, string: []const u8) String { |
| 2401 | | 2409 | |
| 2402 | const GlobalOptions = struct { | 2410 | const GlobalOptions = struct { |
| 2403 | name: []const u8, | 2411 | name: []const u8, |
| | 2412 | type: Symbol.Type = .unknown, |
| 2404 | lib_name: ?[]const u8 = null, | 2413 | lib_name: ?[]const u8 = null, |
| 2405 | dll_storage_class: DllStorageClass = .default, | 2414 | dll_storage_class: Symbol.DllStorageClass = .default, |
| 2406 | }; | 2415 | }; |
| 2407 | | 2416 | |
| 2408 | fn getOrPutGlobalSymbol( | 2417 | fn getOrPutGlobalSymbol( |
| ... | @@ -2420,6 +2429,7 @@ fn getOrPutGlobalSymbol( | ... | @@ -2420,6 +2429,7 @@ fn getOrPutGlobalSymbol( |
| 2420 | const sym = si.get(coff); | 2429 | const sym = si.get(coff); |
| 2421 | sym.setValue(.{ .alias_si = .null }); | 2430 | sym.setValue(.{ .alias_si = .null }); |
| 2422 | sym.gmi = .wrap(@intCast(sym_gop.index)); | 2431 | sym.gmi = .wrap(@intCast(sym_gop.index)); |
| | 2432 | sym.flags.type = opts.type; |
| 2423 | sym.flags.dll_storage_class = opts.dll_storage_class; | 2433 | sym.flags.dll_storage_class = opts.dll_storage_class; |
| 2424 | sym_gop.value_ptr.* = si; | 2434 | sym_gop.value_ptr.* = si; |
| 2425 | coff.synth_prog_node.increaseEstimatedTotalItems(1); | 2435 | coff.synth_prog_node.increaseEstimatedTotalItems(1); |
| ... | @@ -2493,6 +2503,8 @@ pub fn navSymbol(coff: *Coff, zcu: *Zcu, nav_index: InternPool.Nav.Index) !Symbo | ... | @@ -2493,6 +2503,8 @@ pub fn navSymbol(coff: *Coff, zcu: *Zcu, nav_index: InternPool.Nav.Index) !Symbo |
| 2493 | if (nav.getExtern(ip)) |@"extern"| return coff.globalSymbol(.{ | 2503 | if (nav.getExtern(ip)) |@"extern"| return coff.globalSymbol(.{ |
| 2494 | .name = @"extern".name.toSlice(ip), | 2504 | .name = @"extern".name.toSlice(ip), |
| 2495 | .lib_name = @"extern".lib_name.toSlice(ip), | 2505 | .lib_name = @"extern".lib_name.toSlice(ip), |
| | 2506 | // TODO: Threadlocal as well? |
| | 2507 | .type = if (ip.isFunctionType(nav.resolved.?.type)) .code else .data, |
| 2496 | .dll_storage_class = if (@"extern".is_dll_import) .dllimport else .default, | 2508 | .dll_storage_class = if (@"extern".is_dll_import) .dllimport else .default, |
| 2497 | }); | 2509 | }); |
| 2498 | const nmi = try coff.navMapIndex(zcu, nav_index); | 2510 | const nmi = try coff.navMapIndex(zcu, nav_index); |
| ... | @@ -3881,7 +3893,7 @@ fn loadObject( | ... | @@ -3881,7 +3893,7 @@ fn loadObject( |
| 3881 | else | 3893 | else |
| 3882 | break :comdat .include; | 3894 | break :comdat .include; |
| 3883 | }, | 3895 | }, |
| 3884 | else => { | 3896 | .external => { |
| 3885 | const global_gop = try coff.getOrPutGlobalSymbol(.{ | 3897 | const global_gop = try coff.getOrPutGlobalSymbol(.{ |
| 3886 | .name = symbol.name.toSlice(coff), | 3898 | .name = symbol.name.toSlice(coff), |
| 3887 | .lib_name = null, | 3899 | .lib_name = null, |
| ... | @@ -5451,6 +5463,8 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool { | ... | @@ -5451,6 +5463,8 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool { |
| 5451 | break :name .{ coff.getOrPutStringAssumeCapacity(name), true }; | 5463 | break :name .{ coff.getOrPutStringAssumeCapacity(name), true }; |
| 5452 | }; | 5464 | }; |
| 5453 | | 5465 | |
| | 5466 | // TODO: Try to search for __imp_ even when !is_imp, we want to not use thunks if we can |
| | 5467 | |
| 5454 | if (coff.input_archive_symbol_indices.get(search_name)) |indices_list| { | 5468 | if (coff.input_archive_symbol_indices.get(search_name)) |indices_list| { |
| 5455 | var iter: InputArchive.Member.Symbol.Index = indices_list.first; | 5469 | var iter: InputArchive.Member.Symbol.Index = indices_list.first; |
| 5456 | while (true) { | 5470 | while (true) { |
| ... | @@ -5459,8 +5473,10 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool { | ... | @@ -5459,8 +5473,10 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool { |
| 5459 | member: switch (member.content) { | 5473 | member: switch (member.content) { |
| 5460 | .object => if (!member.flags.is_loaded) { | 5474 | .object => if (!member.flags.is_loaded) { |
| 5461 | if (gn.lib_name.unwrap()) |lib_name| | 5475 | if (gn.lib_name.unwrap()) |lib_name| |
| 5462 | if (!std.mem.eql(u8, lib_name.toSlice(coff), member.iai.path(coff).stem())) | 5476 | if (!std.ascii.eqlIgnoreCase( |
| 5463 | break :member; | 5477 | lib_name.toSlice(coff), |
| | 5478 | member.iai.path(coff).stem(), |
| | 5479 | )) break :member; |
| 5464 | | 5480 | |
| 5465 | // Try loading the input member and then retry. | 5481 | // Try loading the input member and then retry. |
| 5466 | // This could still be a member containing imports | 5482 | // This could still be a member containing imports |
| ... | @@ -5470,8 +5486,10 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool { | ... | @@ -5470,8 +5486,10 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool { |
| 5470 | }, | 5486 | }, |
| 5471 | .import => |import| { | 5487 | .import => |import| { |
| 5472 | if (gn.lib_name.unwrap()) |lib_name| | 5488 | if (gn.lib_name.unwrap()) |lib_name| |
| 5473 | if (import.lib_name != lib_name) | 5489 | if (!std.ascii.eqlIgnoreCase( |
| 5474 | break :member; | 5490 | import.lib_name.toSlice(coff), |
| | 5491 | lib_name.toSlice(coff), |
| | 5492 | )) break :member; |
| 5475 | | 5493 | |
| 5476 | const name: String.Optional = name: switch (import.name_type) { | 5494 | const name: String.Optional = name: switch (import.name_type) { |
| 5477 | .NAME, | 5495 | .NAME, |
| ... | @@ -5524,12 +5542,16 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool { | ... | @@ -5524,12 +5542,16 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool { |
| 5524 | // Allow importing symbols with no implib entry, if a lib_name was specified. | 5542 | // Allow importing symbols with no implib entry, if a lib_name was specified. |
| 5525 | // This is necessary for certain ntdll symbols, such as LdrRegisterDllNotification, | 5543 | // This is necessary for certain ntdll symbols, such as LdrRegisterDllNotification, |
| 5526 | // which are not in the implib. | 5544 | // which are not in the implib. |
| 5527 | break :import if (gn.lib_name.unwrap()) |lib_name| .{ | 5545 | if (sym.flags.type != .unknown) { |
| 5528 | .lib_name = lib_name, | 5546 | if (gn.lib_name.unwrap()) |lib_name| break :import .{ |
| 5529 | .name = gn.name.toOptional(), | 5547 | .lib_name = lib_name, |
| 5530 | .ordinal_hint = 0, | 5548 | .name = gn.name.toOptional(), |
| 5531 | .kind = .iat_ptr, | 5549 | .ordinal_hint = 0, |
| 5532 | } else null; | 5550 | .kind = if (sym.flags.type == .code) .thunk else .iat_ptr, |
| | 5551 | }; |
| | 5552 | } |
| | 5553 | |
| | 5554 | break :import null; |
| 5533 | } else null; | 5555 | } else null; |
| 5534 | | 5556 | |
| 5535 | if (opt_import) |import| { | 5557 | if (opt_import) |import| { |