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