| ... | @@ -796,16 +796,21 @@ pub const String = enum(u32) { | ... | @@ -796,16 +796,21 @@ pub const String = enum(u32) { |
| 796 | @".ctors$ZZZ" = 46, | 796 | @".ctors$ZZZ" = 46, |
| 797 | @".dtors" = 57, | 797 | @".dtors" = 57, |
| 798 | @".dtors$ZZZ" = 64, | 798 | @".dtors$ZZZ" = 64, |
| | 799 | @".bss" = 75, |
| 799 | _, | 800 | _, |
| 800 | | 801 | |
| 801 | pub const Optional = enum(u32) { | 802 | pub const Optional = enum(u32) { |
| 802 | @".data" = @intFromEnum(String.@".data"), | 803 | @".data" = @intFromEnum(String.@".data"), |
| | 804 | @".idata" = @intFromEnum(String.@".idata"), |
| 803 | @".rdata" = @intFromEnum(String.@".rdata"), | 805 | @".rdata" = @intFromEnum(String.@".rdata"), |
| 804 | @".text" = @intFromEnum(String.@".text"), | 806 | @".text" = @intFromEnum(String.@".text"), |
| 805 | @".tls$" = @intFromEnum(String.@".tls$"), | 807 | @".tls$" = @intFromEnum(String.@".tls$"), |
| 806 | @".edata" = @intFromEnum(String.@".edata"), | 808 | @".edata" = @intFromEnum(String.@".edata"), |
| | 809 | @".ctors" = @intFromEnum(String.@".ctors"), |
| | 810 | @".ctors$ZZZ" = @intFromEnum(String.@".ctors$ZZZ"), |
| 807 | @".dtors" = @intFromEnum(String.@".dtors"), | 811 | @".dtors" = @intFromEnum(String.@".dtors"), |
| 808 | @".dtors$ZZZ" = @intFromEnum(String.@".dtors$ZZZ"), | 812 | @".dtors$ZZZ" = @intFromEnum(String.@".dtors$ZZZ"), |
| | 813 | @".bss" = @intFromEnum(String.@".bss"), |
| 809 | none = std.math.maxInt(u32), | 814 | none = std.math.maxInt(u32), |
| 810 | _, | 815 | _, |
| 811 | | 816 | |
| ... | @@ -1000,6 +1005,7 @@ pub const Symbol = struct { | ... | @@ -1000,6 +1005,7 @@ pub const Symbol = struct { |
| 1000 | | 1005 | |
| 1001 | pub const Index = enum(u32) { | 1006 | pub const Index = enum(u32) { |
| 1002 | null, | 1007 | null, |
| | 1008 | bss, |
| 1003 | data, | 1009 | data, |
| 1004 | rdata, | 1010 | rdata, |
| 1005 | text, | 1011 | text, |
| ... | @@ -1707,7 +1713,7 @@ fn initHeaders( | ... | @@ -1707,7 +1713,7 @@ fn initHeaders( |
| 1707 | var expected_nodes_len: usize = Node.known_count; | 1713 | var expected_nodes_len: usize = Node.known_count; |
| 1708 | if (coff.hasCoffHeader()) { | 1714 | if (coff.hasCoffHeader()) { |
| 1709 | // Sections | 1715 | // Sections |
| 1710 | expected_nodes_len += 3; | 1716 | expected_nodes_len += 4; |
| 1711 | | 1717 | |
| 1712 | if (is_image) | 1718 | if (is_image) |
| 1713 | // Pseudo-sections and import / export table | 1719 | // Pseudo-sections and import / export table |
| ... | @@ -2000,6 +2006,14 @@ fn initHeaders( | ... | @@ -2000,6 +2006,14 @@ fn initHeaders( |
| 2000 | | 2006 | |
| 2001 | try coff.symbols.ensureTotalCapacity(gpa, Symbol.Index.known_count); | 2007 | try coff.symbols.ensureTotalCapacity(gpa, Symbol.Index.known_count); |
| 2002 | assert(coff.addSymbolAssumeCapacity() == .null); | 2008 | assert(coff.addSymbolAssumeCapacity() == .null); |
| | 2009 | // TODO: How do we tell MappedFile not to allocate physical space for these? |
| | 2010 | // TODO: Could have a node flag 'virtual' that can never have slice* called on it or fileLocation |
| | 2011 | |
| | 2012 | assert(try coff.addSection(.@".bss", .{ |
| | 2013 | .CNT_UNINITIALIZED_DATA = true, |
| | 2014 | .MEM_READ = true, |
| | 2015 | .MEM_WRITE = true, |
| | 2016 | }) == .bss); |
| 2003 | assert(try coff.addSection(.@".data", .{ | 2017 | assert(try coff.addSection(.@".data", .{ |
| 2004 | .CNT_INITIALIZED_DATA = true, | 2018 | .CNT_INITIALIZED_DATA = true, |
| 2005 | .MEM_READ = true, | 2019 | .MEM_READ = true, |
| ... | @@ -2021,7 +2035,7 @@ fn initHeaders( | ... | @@ -2021,7 +2035,7 @@ fn initHeaders( |
| 2021 | (try coff.objectSectionMapIndex( | 2035 | (try coff.objectSectionMapIndex( |
| 2022 | .@".idata", | 2036 | .@".idata", |
| 2023 | coff.mf.flags.block_size, | 2037 | coff.mf.flags.block_size, |
| 2024 | .{ .read = true }, | 2038 | .{ .read = true, .initialized = true }, |
| 2025 | )).symbol(coff).node(coff), | 2039 | )).symbol(coff).node(coff), |
| 2026 | .{ .alignment = .@"4", .moved = true }, | 2040 | .{ .alignment = .@"4", .moved = true }, |
| 2027 | ); | 2041 | ); |
| ... | @@ -2030,7 +2044,7 @@ fn initHeaders( | ... | @@ -2030,7 +2044,7 @@ fn initHeaders( |
| 2030 | coff.export_table.ni = (try coff.pseudoSectionMapIndex( | 2044 | coff.export_table.ni = (try coff.pseudoSectionMapIndex( |
| 2031 | .@".edata", | 2045 | .@".edata", |
| 2032 | .of(std.coff.ExportDirectoryTable), | 2046 | .of(std.coff.ExportDirectoryTable), |
| 2033 | .{ .read = true }, | 2047 | .{ .read = true, .initialized = true }, |
| 2034 | )).symbol(coff).node(coff); | 2048 | )).symbol(coff).node(coff); |
| 2035 | | 2049 | |
| 2036 | coff.export_table.export_directory_table_ni = try coff.mf.addLastChildNode( | 2050 | coff.export_table.export_directory_table_ni = try coff.mf.addLastChildNode( |
| ... | @@ -2115,7 +2129,7 @@ fn initHeaders( | ... | @@ -2115,7 +2129,7 @@ fn initHeaders( |
| 2115 | _ = try coff.objectSectionMapIndex( | 2129 | _ = try coff.objectSectionMapIndex( |
| 2116 | .@".tls$", | 2130 | .@".tls$", |
| 2117 | coff.mf.flags.block_size, | 2131 | coff.mf.flags.block_size, |
| 2118 | .{ .read = true, .write = !is_image }, | 2132 | .{ .read = true, .write = !is_image, .initialized = true }, |
| 2119 | ); | 2133 | ); |
| 2120 | } | 2134 | } |
| 2121 | } | 2135 | } |
| ... | @@ -2145,12 +2159,12 @@ pub fn initBuiltins(coff: *Coff) !void { | ... | @@ -2145,12 +2159,12 @@ pub fn initBuiltins(coff: *Coff) !void { |
| 2145 | const start_osmi = try coff.objectSectionMapIndex( | 2159 | const start_osmi = try coff.objectSectionMapIndex( |
| 2146 | list.start, | 2160 | list.start, |
| 2147 | addr_info.alignment, | 2161 | addr_info.alignment, |
| 2148 | .{ .read = true }, | 2162 | .{ .read = true, .initialized = true }, |
| 2149 | ); | 2163 | ); |
| 2150 | const end_osmi = try coff.objectSectionMapIndex( | 2164 | const end_osmi = try coff.objectSectionMapIndex( |
| 2151 | list.end, | 2165 | list.end, |
| 2152 | addr_info.alignment, | 2166 | addr_info.alignment, |
| 2153 | .{ .read = true }, | 2167 | .{ .read = true, .initialized = true }, |
| 2154 | ); | 2168 | ); |
| 2155 | | 2169 | |
| 2156 | const start_sym = start_osmi.symbol(coff).get(coff); | 2170 | const start_sym = start_osmi.symbol(coff).get(coff); |
| ... | @@ -2657,13 +2671,13 @@ fn navSection( | ... | @@ -2657,13 +2671,13 @@ fn navSection( |
| 2657 | const ip = &zcu.intern_pool; | 2671 | const ip = &zcu.intern_pool; |
| 2658 | const default: String, const attributes: ObjectSectionAttributes = | 2672 | const default: String, const attributes: ObjectSectionAttributes = |
| 2659 | if (nav_resolved.@"threadlocal" and coff.base.comp.config.any_non_single_threaded) .{ | 2673 | if (nav_resolved.@"threadlocal" and coff.base.comp.config.any_non_single_threaded) .{ |
| 2660 | .@".tls$", .{ .read = true, .write = true }, | 2674 | .@".tls$", .{ .read = true, .write = true, .initialized = true }, |
| 2661 | } else if (ip.isFunctionType(nav_resolved.type)) .{ | 2675 | } else if (ip.isFunctionType(nav_resolved.type)) .{ |
| 2662 | .@".text", .{ .read = true, .execute = true }, | 2676 | .@".text", .{ .read = true, .execute = true }, |
| 2663 | } else if (nav_resolved.@"const") .{ | 2677 | } else if (nav_resolved.@"const") .{ |
| 2664 | .@".rdata", .{ .read = true }, | 2678 | .@".rdata", .{ .read = true, .initialized = true }, |
| 2665 | } else .{ | 2679 | } else .{ |
| 2666 | .@".data", .{ .read = true, .write = true }, | 2680 | .@".data", .{ .read = true, .write = true, .initialized = true }, |
| 2667 | }; | 2681 | }; |
| 2668 | | 2682 | |
| 2669 | return (try coff.objectSectionMapIndex( | 2683 | return (try coff.objectSectionMapIndex( |
| ... | @@ -3180,6 +3194,8 @@ const ObjectSectionAttributes = packed struct { | ... | @@ -3180,6 +3194,8 @@ const ObjectSectionAttributes = packed struct { |
| 3180 | nocache: bool = false, | 3194 | nocache: bool = false, |
| 3181 | discard: bool = false, | 3195 | discard: bool = false, |
| 3182 | remove: bool = false, | 3196 | remove: bool = false, |
| | 3197 | initialized: bool = false, |
| | 3198 | uninitialized: bool = false, |
| 3183 | | 3199 | |
| 3184 | // TODO: Include init / not init flags? | 3200 | // TODO: Include init / not init flags? |
| 3185 | | 3201 | |
| ... | @@ -3193,6 +3209,8 @@ const ObjectSectionAttributes = packed struct { | ... | @@ -3193,6 +3209,8 @@ const ObjectSectionAttributes = packed struct { |
| 3193 | .nocache = flags.MEM_NOT_CACHED, | 3209 | .nocache = flags.MEM_NOT_CACHED, |
| 3194 | .discard = flags.MEM_DISCARDABLE, | 3210 | .discard = flags.MEM_DISCARDABLE, |
| 3195 | .remove = flags.LNK_REMOVE, | 3211 | .remove = flags.LNK_REMOVE, |
| | 3212 | .initialized = flags.CNT_INITIALIZED_DATA, |
| | 3213 | .uninitialized = flags.CNT_UNINITIALIZED_DATA, |
| 3196 | }; | 3214 | }; |
| 3197 | } | 3215 | } |
| 3198 | | 3216 | |
| ... | @@ -3206,6 +3224,8 @@ const ObjectSectionAttributes = packed struct { | ... | @@ -3206,6 +3224,8 @@ const ObjectSectionAttributes = packed struct { |
| 3206 | .MEM_NOT_CACHED = attr.nocache, | 3224 | .MEM_NOT_CACHED = attr.nocache, |
| 3207 | .MEM_DISCARDABLE = attr.discard, | 3225 | .MEM_DISCARDABLE = attr.discard, |
| 3208 | .LNK_REMOVE = attr.remove, | 3226 | .LNK_REMOVE = attr.remove, |
| | 3227 | .CNT_INITIALIZED_DATA = attr.uninitialized, |
| | 3228 | .CNT_UNINITIALIZED_DATA = attr.uninitialized, |
| 3209 | }; | 3229 | }; |
| 3210 | } | 3230 | } |
| 3211 | }; | 3231 | }; |
| ... | @@ -3220,7 +3240,9 @@ fn pseudoSectionMapIndex( | ... | @@ -3220,7 +3240,9 @@ fn pseudoSectionMapIndex( |
| 3220 | const pseudo_section_gop = try coff.pseudo_section_table.getOrPut(gpa, name); | 3240 | const pseudo_section_gop = try coff.pseudo_section_table.getOrPut(gpa, name); |
| 3221 | const psmi: Node.PseudoSectionMapIndex = @enumFromInt(pseudo_section_gop.index); | 3241 | const psmi: Node.PseudoSectionMapIndex = @enumFromInt(pseudo_section_gop.index); |
| 3222 | const sn = if (!pseudo_section_gop.found_existing) sn: { | 3242 | const sn = if (!pseudo_section_gop.found_existing) sn: { |
| 3223 | const default_parent: Symbol.Index = if (attributes.execute) | 3243 | const default_parent: Symbol.Index = if (attributes.uninitialized) |
| | 3244 | .bss |
| | 3245 | else if (attributes.execute) |
| 3224 | .text | 3246 | .text |
| 3225 | else if (attributes.write) | 3247 | else if (attributes.write) |
| 3226 | .data | 3248 | .data |
| ... | @@ -3401,6 +3423,8 @@ pub fn addReloc( | ... | @@ -3401,6 +3423,8 @@ pub fn addReloc( |
| 3401 | ) !void { | 3423 | ) !void { |
| 3402 | const gpa = coff.base.comp.gpa; | 3424 | const gpa = coff.base.comp.gpa; |
| 3403 | const target = target_si.get(coff); | 3425 | const target = target_si.get(coff); |
| | 3426 | // TODO: Could duplicate the uninit flag on Symbol.flags? |
| | 3427 | assert(!coff.targetLoad(loc_si.get(coff).section_number.header(coff).flags).CNT_UNINITIALIZED_DATA); |
| 3404 | | 3428 | |
| 3405 | const ri: Reloc.Index = @enumFromInt(coff.relocs.items.len); | 3429 | const ri: Reloc.Index = @enumFromInt(coff.relocs.items.len); |
| 3406 | log.debug("addReloc({d}@{d}+0x{x} -> {d}@{d}+0x{x}{s}) = {d}", .{ | 3430 | log.debug("addReloc({d}@{d}+0x{x} -> {d}@{d}+0x{x}{s}) = {d}", .{ |
| ... | @@ -4194,6 +4218,7 @@ fn loadObject( | ... | @@ -4194,6 +4218,7 @@ fn loadObject( |
| 4194 | const existing_crc = switch (coff.getNode(sym.ni)) { | 4218 | const existing_crc = switch (coff.getNode(sym.ni)) { |
| 4195 | .input_section => |isi| isi.inputSection(coff).crc, | 4219 | .input_section => |isi| isi.inputSection(coff).crc, |
| 4196 | // TODO: Should this result be cached somewhere? | 4220 | // TODO: Should this result be cached somewhere? |
| | 4221 | // TODO: Is this slice triggering has_content = true un-necessarily? Check section for init data flag. |
| 4197 | else => std.hash.crc.Crc32Jamcrc.hash(sym.ni.slice(&coff.mf)), | 4222 | else => std.hash.crc.Crc32Jamcrc.hash(sym.ni.slice(&coff.mf)), |
| 4198 | }; | 4223 | }; |
| 4199 | | 4224 | |
| ... | @@ -5750,7 +5775,7 @@ fn flushUav( | ... | @@ -5750,7 +5775,7 @@ fn flushUav( |
| 5750 | const sec_si = (try coff.objectSectionMapIndex( | 5775 | const sec_si = (try coff.objectSectionMapIndex( |
| 5751 | .@".rdata", | 5776 | .@".rdata", |
| 5752 | coff.mf.flags.block_size, | 5777 | coff.mf.flags.block_size, |
| 5753 | .{ .read = true }, | 5778 | .{ .read = true, .initialized = true }, |
| 5754 | )).symbol(coff); | 5779 | )).symbol(coff); |
| 5755 | try coff.nodes.ensureUnusedCapacity(gpa, 1); | 5780 | try coff.nodes.ensureUnusedCapacity(gpa, 1); |
| 5756 | if (!isImage(coff)) try coff.symbol_table.pending.ensureUnusedCapacity(gpa, 1); | 5781 | if (!isImage(coff)) try coff.symbol_table.pending.ensureUnusedCapacity(gpa, 1); |
| ... | @@ -6335,15 +6360,19 @@ fn flushMoved(coff: *Coff, ni: MappedFile.Node.Index) !void { | ... | @@ -6335,15 +6360,19 @@ fn flushMoved(coff: *Coff, ni: MappedFile.Node.Index) !void { |
| 6335 | .archive_member, | 6360 | .archive_member, |
| 6336 | => {}, | 6361 | => {}, |
| 6337 | .image_section => |si| { | 6362 | .image_section => |si| { |
| 6338 | const file_offset = if (isArchive(coff)) | 6363 | const sym = si.get(coff); |
| 6339 | si.get(coff).ni.location(&coff.mf).resolve(&coff.mf)[0] | 6364 | const flags = coff.targetLoad(&sym.section_number.header(coff).flags); |
| 6340 | else | 6365 | if (!flags.CNT_UNINITIALIZED_DATA) { |
| 6341 | ni.fileLocation(&coff.mf, false).offset; | 6366 | const file_offset = if (isArchive(coff)) |
| | 6367 | sym.ni.location(&coff.mf).resolve(&coff.mf)[0] |
| | 6368 | else |
| | 6369 | ni.fileLocation(&coff.mf, false).offset; |
| 6342 | | 6370 | |
| 6343 | return coff.targetStore( | 6371 | return coff.targetStore( |
| 6344 | &si.get(coff).section_number.header(coff).pointer_to_raw_data, | 6372 | &sym.section_number.header(coff).pointer_to_raw_data, |
| 6345 | @intCast(file_offset), | 6373 | @intCast(file_offset), |
| 6346 | ); | 6374 | ); |
| | 6375 | } |
| 6347 | }, | 6376 | }, |
| 6348 | .input_section => |isi| { | 6377 | .input_section => |isi| { |
| 6349 | isi.symbol(coff).flushMoved(coff); | 6378 | isi.symbol(coff).flushMoved(coff); |