| ... | ... | @@ -5,6 +5,7 @@ const build_options = @import("build_options"); |
| 5 | 5 | const builtin = @import("builtin"); |
| 6 | 6 | const assert = std.debug.assert; |
| 7 | 7 | const coff = std.coff; |
| 8 | const fmt = std.fmt; |
| 8 | 9 | const log = std.log.scoped(.link); |
| 9 | 10 | const math = std.math; |
| 10 | 11 | const mem = std.mem; |
| ... | ... | @@ -36,6 +37,7 @@ base: link.File, |
| 36 | 37 | error_flags: link.File.ErrorFlags = .{}, |
| 37 | 38 | |
| 38 | 39 | ptr_width: PtrWidth, |
| 40 | page_size: u32, |
| 39 | 41 | |
| 40 | 42 | sections: std.MultiArrayList(Section) = .{}, |
| 41 | 43 | data_directories: [16]coff.ImageDataDirectory, |
| ... | ... | @@ -69,7 +71,6 @@ managed_atoms: std.ArrayListUnmanaged(*Atom) = .{}, |
| 69 | 71 | /// Table of atoms indexed by the symbol index. |
| 70 | 72 | atom_by_index_table: std.AutoHashMapUnmanaged(u32, *Atom) = .{}, |
| 71 | 73 | |
| 72 | | const default_section_alignment: u16 = 0x1000; |
| 73 | 74 | const default_file_alignment: u16 = 0x200; |
| 74 | 75 | const default_image_base_dll: u64 = 0x10000000; |
| 75 | 76 | const default_image_base_exe: u64 = 0x10000; |
| ... | ... | @@ -150,6 +151,9 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*Coff { |
| 150 | 151 | 33...64 => .p64, |
| 151 | 152 | else => return error.UnsupportedCOFFArchitecture, |
| 152 | 153 | }; |
| 154 | const page_size: u32 = switch (options.target.cpu.arch) { |
| 155 | else => 0x1000, |
| 156 | }; |
| 153 | 157 | const self = try gpa.create(Coff); |
| 154 | 158 | errdefer gpa.destroy(self); |
| 155 | 159 | self.* = .{ |
| ... | ... | @@ -160,6 +164,7 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*Coff { |
| 160 | 164 | .file = null, |
| 161 | 165 | }, |
| 162 | 166 | .ptr_width = ptr_width, |
| 167 | .page_size = page_size, |
| 163 | 168 | .data_directories = comptime mem.zeroes([16]coff.ImageDataDirectory), |
| 164 | 169 | }; |
| 165 | 170 | |
| ... | ... | @@ -199,9 +204,15 @@ pub fn deinit(self: *Coff) void { |
| 199 | 204 | } |
| 200 | 205 | |
| 201 | 206 | fn populateMissingMetadata(self: *Coff) !void { |
| 207 | assert(self.llvm_object == null); |
| 202 | 208 | const gpa = self.base.allocator; |
| 203 | 209 | |
| 204 | | if (self.text_section_index == null) {} |
| 210 | if (self.text_section_index == null) { |
| 211 | self.text_section_index = @intCast(u16, self.sections.slice().len); |
| 212 | const file_size = self.base.options.program_code_size_hint; |
| 213 | const off = self.findFreeSpace(file_size, self.page_size); // TODO we are over-aligning in file; we should track both in file and in memory pointers |
| 214 | log.debug("found .text free space 0x{x} to 0x{x}", .{ off, off + file_size }); |
| 215 | } |
| 205 | 216 | |
| 206 | 217 | if (self.got_section_index == null) {} |
| 207 | 218 | |
| ... | ... | @@ -756,7 +767,7 @@ fn writeHeader(self: *Coff) !void { |
| 756 | 767 | }; |
| 757 | 768 | const subsystem: coff.Subsystem = .WINDOWS_CUI; |
| 758 | 769 | const size_of_headers: u32 = @intCast(u32, self.getSizeOfHeaders()); |
| 759 | | const size_of_image_aligned: u32 = mem.alignForwardGeneric(u32, size_of_headers, default_section_alignment); |
| 770 | const size_of_image_aligned: u32 = mem.alignForwardGeneric(u32, size_of_headers, self.page_size); |
| 760 | 771 | const size_of_headers_aligned: u32 = mem.alignForwardGeneric(u32, size_of_headers, default_file_alignment); |
| 761 | 772 | const image_base = self.base.options.image_base_override orelse switch (self.base.options.output_mode) { |
| 762 | 773 | .Exe => default_image_base_exe, |
| ... | ... | @@ -777,7 +788,7 @@ fn writeHeader(self: *Coff) !void { |
| 777 | 788 | .base_of_code = 0, |
| 778 | 789 | .base_of_data = 0, |
| 779 | 790 | .image_base = @intCast(u32, image_base), |
| 780 | | .section_alignment = default_section_alignment, |
| 791 | .section_alignment = self.page_size, |
| 781 | 792 | .file_alignment = default_file_alignment, |
| 782 | 793 | .major_operating_system_version = 6, |
| 783 | 794 | .minor_operating_system_version = 0, |
| ... | ... | @@ -811,7 +822,7 @@ fn writeHeader(self: *Coff) !void { |
| 811 | 822 | .address_of_entry_point = self.entry_addr orelse 0, |
| 812 | 823 | .base_of_code = 0, |
| 813 | 824 | .image_base = image_base, |
| 814 | | .section_alignment = default_section_alignment, |
| 825 | .section_alignment = self.page_size, |
| 815 | 826 | .file_alignment = default_file_alignment, |
| 816 | 827 | .major_operating_system_version = 6, |
| 817 | 828 | .minor_operating_system_version = 0, |
| ... | ... | @@ -956,3 +967,23 @@ pub fn getGotAtomForSymbol(self: *Coff, sym_loc: SymbolWithLoc) ?*Atom { |
| 956 | 967 | const got_index = self.got_entries.get(sym_loc) orelse return null; |
| 957 | 968 | return self.atom_by_index_table.get(got_index); |
| 958 | 969 | } |
| 970 | |
| 971 | fn setSectionName(self: *Coff, header: *coff.SectionHeader, name: []const u8) !void { |
| 972 | if (name.len <= 8) { |
| 973 | mem.copy(u8, &header.name, name); |
| 974 | return; |
| 975 | } |
| 976 | const offset = try self.strtab.insert(self.base.allocator, name); |
| 977 | const name_offset = try fmt.bufPrint(&header.name, "/{d}", .{offset}); |
| 978 | mem.set(u8, header.name[name_offset.len..], 0); |
| 979 | } |
| 980 | |
| 981 | fn setSymbolName(self: *Coff, symbol: *coff.Symbol, name: []const u8) !void { |
| 982 | if (name.len <= 8) { |
| 983 | mem.copy(u8, &symbol.name, name); |
| 984 | return; |
| 985 | } |
| 986 | const offset = try self.strtab.insert(self.base.allocator, name); |
| 987 | mem.copy(u8, symbol.name[0..4], 0); |
| 988 | _ = try fmt.bufPrint(symbol.name[4..], "{d}", .{offset}); |
| 989 | } |