| ... | ... | @@ -796,16 +796,21 @@ pub const String = enum(u32) { |
| 796 | 796 | @".ctors$ZZZ" = 46, |
| 797 | 797 | @".dtors" = 57, |
| 798 | 798 | @".dtors$ZZZ" = 64, |
| 799 | @".bss" = 75, |
| 799 | 800 | _, |
| 800 | 801 | |
| 801 | 802 | pub const Optional = enum(u32) { |
| 802 | 803 | @".data" = @intFromEnum(String.@".data"), |
| 804 | @".idata" = @intFromEnum(String.@".idata"), |
| 803 | 805 | @".rdata" = @intFromEnum(String.@".rdata"), |
| 804 | 806 | @".text" = @intFromEnum(String.@".text"), |
| 805 | 807 | @".tls$" = @intFromEnum(String.@".tls$"), |
| 806 | 808 | @".edata" = @intFromEnum(String.@".edata"), |
| 809 | @".ctors" = @intFromEnum(String.@".ctors"), |
| 810 | @".ctors$ZZZ" = @intFromEnum(String.@".ctors$ZZZ"), |
| 807 | 811 | @".dtors" = @intFromEnum(String.@".dtors"), |
| 808 | 812 | @".dtors$ZZZ" = @intFromEnum(String.@".dtors$ZZZ"), |
| 813 | @".bss" = @intFromEnum(String.@".bss"), |
| 809 | 814 | none = std.math.maxInt(u32), |
| 810 | 815 | _, |
| 811 | 816 | |
| ... | ... | @@ -1000,6 +1005,7 @@ pub const Symbol = struct { |
| 1000 | 1005 | |
| 1001 | 1006 | pub const Index = enum(u32) { |
| 1002 | 1007 | null, |
| 1008 | bss, |
| 1003 | 1009 | data, |
| 1004 | 1010 | rdata, |
| 1005 | 1011 | text, |
| ... | ... | @@ -1707,7 +1713,7 @@ fn initHeaders( |
| 1707 | 1713 | var expected_nodes_len: usize = Node.known_count; |
| 1708 | 1714 | if (coff.hasCoffHeader()) { |
| 1709 | 1715 | // Sections |
| 1710 | | expected_nodes_len += 3; |
| 1716 | expected_nodes_len += 4; |
| 1711 | 1717 | |
| 1712 | 1718 | if (is_image) |
| 1713 | 1719 | // Pseudo-sections and import / export table |
| ... | ... | @@ -2000,6 +2006,14 @@ fn initHeaders( |
| 2000 | 2006 | |
| 2001 | 2007 | try coff.symbols.ensureTotalCapacity(gpa, Symbol.Index.known_count); |
| 2002 | 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 | 2017 | assert(try coff.addSection(.@".data", .{ |
| 2004 | 2018 | .CNT_INITIALIZED_DATA = true, |
| 2005 | 2019 | .MEM_READ = true, |
| ... | ... | @@ -2021,7 +2035,7 @@ fn initHeaders( |
| 2021 | 2035 | (try coff.objectSectionMapIndex( |
| 2022 | 2036 | .@".idata", |
| 2023 | 2037 | coff.mf.flags.block_size, |
| 2024 | | .{ .read = true }, |
| 2038 | .{ .read = true, .initialized = true }, |
| 2025 | 2039 | )).symbol(coff).node(coff), |
| 2026 | 2040 | .{ .alignment = .@"4", .moved = true }, |
| 2027 | 2041 | ); |
| ... | ... | @@ -2030,7 +2044,7 @@ fn initHeaders( |
| 2030 | 2044 | coff.export_table.ni = (try coff.pseudoSectionMapIndex( |
| 2031 | 2045 | .@".edata", |
| 2032 | 2046 | .of(std.coff.ExportDirectoryTable), |
| 2033 | | .{ .read = true }, |
| 2047 | .{ .read = true, .initialized = true }, |
| 2034 | 2048 | )).symbol(coff).node(coff); |
| 2035 | 2049 | |
| 2036 | 2050 | coff.export_table.export_directory_table_ni = try coff.mf.addLastChildNode( |
| ... | ... | @@ -2115,7 +2129,7 @@ fn initHeaders( |
| 2115 | 2129 | _ = try coff.objectSectionMapIndex( |
| 2116 | 2130 | .@".tls$", |
| 2117 | 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 | 2159 | const start_osmi = try coff.objectSectionMapIndex( |
| 2146 | 2160 | list.start, |
| 2147 | 2161 | addr_info.alignment, |
| 2148 | | .{ .read = true }, |
| 2162 | .{ .read = true, .initialized = true }, |
| 2149 | 2163 | ); |
| 2150 | 2164 | const end_osmi = try coff.objectSectionMapIndex( |
| 2151 | 2165 | list.end, |
| 2152 | 2166 | addr_info.alignment, |
| 2153 | | .{ .read = true }, |
| 2167 | .{ .read = true, .initialized = true }, |
| 2154 | 2168 | ); |
| 2155 | 2169 | |
| 2156 | 2170 | const start_sym = start_osmi.symbol(coff).get(coff); |
| ... | ... | @@ -2657,13 +2671,13 @@ fn navSection( |
| 2657 | 2671 | const ip = &zcu.intern_pool; |
| 2658 | 2672 | const default: String, const attributes: ObjectSectionAttributes = |
| 2659 | 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 | 2675 | } else if (ip.isFunctionType(nav_resolved.type)) .{ |
| 2662 | 2676 | .@".text", .{ .read = true, .execute = true }, |
| 2663 | 2677 | } else if (nav_resolved.@"const") .{ |
| 2664 | | .@".rdata", .{ .read = true }, |
| 2678 | .@".rdata", .{ .read = true, .initialized = true }, |
| 2665 | 2679 | } else .{ |
| 2666 | | .@".data", .{ .read = true, .write = true }, |
| 2680 | .@".data", .{ .read = true, .write = true, .initialized = true }, |
| 2667 | 2681 | }; |
| 2668 | 2682 | |
| 2669 | 2683 | return (try coff.objectSectionMapIndex( |
| ... | ... | @@ -3180,6 +3194,8 @@ const ObjectSectionAttributes = packed struct { |
| 3180 | 3194 | nocache: bool = false, |
| 3181 | 3195 | discard: bool = false, |
| 3182 | 3196 | remove: bool = false, |
| 3197 | initialized: bool = false, |
| 3198 | uninitialized: bool = false, |
| 3183 | 3199 | |
| 3184 | 3200 | // TODO: Include init / not init flags? |
| 3185 | 3201 | |
| ... | ... | @@ -3193,6 +3209,8 @@ const ObjectSectionAttributes = packed struct { |
| 3193 | 3209 | .nocache = flags.MEM_NOT_CACHED, |
| 3194 | 3210 | .discard = flags.MEM_DISCARDABLE, |
| 3195 | 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 | 3224 | .MEM_NOT_CACHED = attr.nocache, |
| 3207 | 3225 | .MEM_DISCARDABLE = attr.discard, |
| 3208 | 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 | 3240 | const pseudo_section_gop = try coff.pseudo_section_table.getOrPut(gpa, name); |
| 3221 | 3241 | const psmi: Node.PseudoSectionMapIndex = @enumFromInt(pseudo_section_gop.index); |
| 3222 | 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 | 3246 | .text |
| 3225 | 3247 | else if (attributes.write) |
| 3226 | 3248 | .data |
| ... | ... | @@ -3401,6 +3423,8 @@ pub fn addReloc( |
| 3401 | 3423 | ) !void { |
| 3402 | 3424 | const gpa = coff.base.comp.gpa; |
| 3403 | 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 | 3429 | const ri: Reloc.Index = @enumFromInt(coff.relocs.items.len); |
| 3406 | 3430 | log.debug("addReloc({d}@{d}+0x{x} -> {d}@{d}+0x{x}{s}) = {d}", .{ |
| ... | ... | @@ -4194,6 +4218,7 @@ fn loadObject( |
| 4194 | 4218 | const existing_crc = switch (coff.getNode(sym.ni)) { |
| 4195 | 4219 | .input_section => |isi| isi.inputSection(coff).crc, |
| 4196 | 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 | 4222 | else => std.hash.crc.Crc32Jamcrc.hash(sym.ni.slice(&coff.mf)), |
| 4198 | 4223 | }; |
| 4199 | 4224 | |
| ... | ... | @@ -5750,7 +5775,7 @@ fn flushUav( |
| 5750 | 5775 | const sec_si = (try coff.objectSectionMapIndex( |
| 5751 | 5776 | .@".rdata", |
| 5752 | 5777 | coff.mf.flags.block_size, |
| 5753 | | .{ .read = true }, |
| 5778 | .{ .read = true, .initialized = true }, |
| 5754 | 5779 | )).symbol(coff); |
| 5755 | 5780 | try coff.nodes.ensureUnusedCapacity(gpa, 1); |
| 5756 | 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 | 6360 | .archive_member, |
| 6336 | 6361 | => {}, |
| 6337 | 6362 | .image_section => |si| { |
| 6338 | | const file_offset = if (isArchive(coff)) |
| 6339 | | si.get(coff).ni.location(&coff.mf).resolve(&coff.mf)[0] |
| 6340 | | else |
| 6341 | | ni.fileLocation(&coff.mf, false).offset; |
| 6363 | const sym = si.get(coff); |
| 6364 | const flags = coff.targetLoad(&sym.section_number.header(coff).flags); |
| 6365 | if (!flags.CNT_UNINITIALIZED_DATA) { |
| 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( |
| 6344 | | &si.get(coff).section_number.header(coff).pointer_to_raw_data, |
| 6345 | | @intCast(file_offset), |
| 6346 | | ); |
| 6371 | return coff.targetStore( |
| 6372 | &sym.section_number.header(coff).pointer_to_raw_data, |
| 6373 | @intCast(file_offset), |
| 6374 | ); |
| 6375 | } |
| 6347 | 6376 | }, |
| 6348 | 6377 | .input_section => |isi| { |
| 6349 | 6378 | isi.symbol(coff).flushMoved(coff); |