authorgravatar for noam@pixelhero.devNoam Preil <noam@pixelhero.dev> 2020-07-07 23:11:17-04:00
committergravatar for noam@pixelhero.devNoam Preil <noam@pixelhero.dev> 2020-07-07 23:11:17-04:00
log173e6712417c8102ff6bbd28fd964b89eda14f36
tree8bd5aba37e7e9672493b683549a5cdf7847a777e
parentb91cf1597267275dbbf57551acbe0461216ff08e
signature Commit is signed but in an unrecognized format.

CBE: Some cleanup


3 files changed, 44 insertions(+), 51 deletions(-)

src-self-hosted/link.zig+43-45
......@@ -125,36 +125,34 @@ pub const File = struct {
125125 }
126126
127127 pub fn makeWritable(base: *File, dir: fs.Dir, sub_path: []const u8) !void {
128 try switch (base.tag) {
129 .Elf => @fieldParentPtr(Elf, "base", base).makeWritable(dir, sub_path),
130 .C => @fieldParentPtr(C, "base", base).makeWritable(dir, sub_path),
128 switch (base.tag) {
129 .Elf => return @fieldParentPtr(Elf, "base", base).makeWritable(dir, sub_path),
130 .C => return @fieldParentPtr(C, "base", base).makeWritable(dir, sub_path),
131131 else => unreachable,
132 };
132 }
133133 }
134134
135135 pub fn makeExecutable(base: *File) !void {
136 try switch (base.tag) {
137 .Elf => @fieldParentPtr(Elf, "base", base).makeExecutable(),
136 switch (base.tag) {
137 .Elf => return @fieldParentPtr(Elf, "base", base).makeExecutable(),
138138 else => unreachable,
139 };
139 }
140140 }
141141
142142 pub fn updateDecl(base: *File, module: *Module, decl: *Module.Decl) !void {
143 try switch (base.tag) {
144 .Elf => @fieldParentPtr(Elf, "base", base).updateDecl(module, decl),
145 .C => @fieldParentPtr(C, "base", base).updateDecl(module, decl),
143 switch (base.tag) {
144 .Elf => return @fieldParentPtr(Elf, "base", base).updateDecl(module, decl),
145 .C => return @fieldParentPtr(C, "base", base).updateDecl(module, decl),
146146 else => unreachable,
147 };
147 }
148148 }
149149
150150 pub fn allocateDeclIndexes(base: *File, decl: *Module.Decl) !void {
151 try switch (base.tag) {
152 .Elf => @fieldParentPtr(Elf, "base", base).allocateDeclIndexes(decl),
153 .C => {
154 //TODO
155 },
151 switch (base.tag) {
152 .Elf => return @fieldParentPtr(Elf, "base", base).allocateDeclIndexes(decl),
153 .C => {},
156154 else => unreachable,
157 };
155 }
158156 }
159157
160158 pub fn deinit(base: *File) void {
......@@ -380,7 +378,7 @@ pub const File = struct {
380378 /// Returns how much room there is to grow in virtual address space.
381379 /// File offset relocation happens transparently, so it is not included in
382380 /// this calculation.
383 fn capacity(self: TextBlock, elf_file: File.Elf) u64 {
381 fn capacity(self: TextBlock, elf_file: Elf) u64 {
384382 const self_sym = elf_file.local_symbols.items[self.local_sym_index];
385383 if (self.next) |next| {
386384 const next_sym = elf_file.local_symbols.items[next.local_sym_index];
......@@ -391,7 +389,7 @@ pub const File = struct {
391389 }
392390 }
393391
394 fn freeListEligible(self: TextBlock, elf_file: File.Elf) bool {
392 fn freeListEligible(self: TextBlock, elf_file: Elf) bool {
395393 // No need to keep a free list node for the last block.
396394 const next = self.next orelse return false;
397395 const self_sym = elf_file.local_symbols.items[self.local_sym_index];
......@@ -408,7 +406,7 @@ pub const File = struct {
408406 sym_index: ?u32 = null,
409407 };
410408
411 pub fn deinit(self: *File.Elf) void {
409 pub fn deinit(self: *Elf) void {
412410 self.sections.deinit(self.allocator);
413411 self.program_headers.deinit(self.allocator);
414412 self.shstrtab.deinit(self.allocator);
......@@ -424,7 +422,7 @@ pub const File = struct {
424422 }
425423 }
426424
427 pub fn makeExecutable(self: *File.Elf) !void {
425 pub fn makeExecutable(self: *Elf) !void {
428426 assert(self.owns_file_handle);
429427 if (self.file) |f| {
430428 f.close();
......@@ -432,7 +430,7 @@ pub const File = struct {
432430 }
433431 }
434432
435 pub fn makeWritable(self: *File.Elf, dir: fs.Dir, sub_path: []const u8) !void {
433 pub fn makeWritable(self: *Elf, dir: fs.Dir, sub_path: []const u8) !void {
436434 assert(self.owns_file_handle);
437435 if (self.file != null) return;
438436 self.file = try dir.createFile(sub_path, .{
......@@ -443,7 +441,7 @@ pub const File = struct {
443441 }
444442
445443 /// Returns end pos of collision, if any.
446 fn detectAllocCollision(self: *File.Elf, start: u64, size: u64) ?u64 {
444 fn detectAllocCollision(self: *Elf, start: u64, size: u64) ?u64 {
447445 const small_ptr = self.options.target.cpu.arch.ptrBitWidth() == 32;
448446 const ehdr_size: u64 = if (small_ptr) @sizeOf(elf.Elf32_Ehdr) else @sizeOf(elf.Elf64_Ehdr);
449447 if (start < ehdr_size)
......@@ -488,7 +486,7 @@ pub const File = struct {
488486 return null;
489487 }
490488
491 fn allocatedSize(self: *File.Elf, start: u64) u64 {
489 fn allocatedSize(self: *Elf, start: u64) u64 {
492490 var min_pos: u64 = std.math.maxInt(u64);
493491 if (self.shdr_table_offset) |off| {
494492 if (off > start and off < min_pos) min_pos = off;
......@@ -507,7 +505,7 @@ pub const File = struct {
507505 return min_pos - start;
508506 }
509507
510 fn findFreeSpace(self: *File.Elf, object_size: u64, min_alignment: u16) u64 {
508 fn findFreeSpace(self: *Elf, object_size: u64, min_alignment: u16) u64 {
511509 var start: u64 = 0;
512510 while (self.detectAllocCollision(start, object_size)) |item_end| {
513511 start = mem.alignForwardGeneric(u64, item_end, min_alignment);
......@@ -515,7 +513,7 @@ pub const File = struct {
515513 return start;
516514 }
517515
518 fn makeString(self: *File.Elf, bytes: []const u8) !u32 {
516 fn makeString(self: *Elf, bytes: []const u8) !u32 {
519517 try self.shstrtab.ensureCapacity(self.allocator, self.shstrtab.items.len + bytes.len + 1);
520518 const result = self.shstrtab.items.len;
521519 self.shstrtab.appendSliceAssumeCapacity(bytes);
......@@ -523,12 +521,12 @@ pub const File = struct {
523521 return @intCast(u32, result);
524522 }
525523
526 fn getString(self: *File.Elf, str_off: u32) []const u8 {
524 fn getString(self: *Elf, str_off: u32) []const u8 {
527525 assert(str_off < self.shstrtab.items.len);
528526 return mem.spanZ(@ptrCast([*:0]const u8, self.shstrtab.items.ptr + str_off));
529527 }
530528
531 fn updateString(self: *File.Elf, old_str_off: u32, new_name: []const u8) !u32 {
529 fn updateString(self: *Elf, old_str_off: u32, new_name: []const u8) !u32 {
532530 const existing_name = self.getString(old_str_off);
533531 if (mem.eql(u8, existing_name, new_name)) {
534532 return old_str_off;
......@@ -536,7 +534,7 @@ pub const File = struct {
536534 return self.makeString(new_name);
537535 }
538536
539 pub fn populateMissingMetadata(self: *File.Elf) !void {
537 pub fn populateMissingMetadata(self: *Elf) !void {
540538 const small_ptr = switch (self.ptr_width) {
541539 .p32 => true,
542540 .p64 => false,
......@@ -703,7 +701,7 @@ pub const File = struct {
703701 }
704702
705703 /// Commit pending changes and write headers.
706 pub fn flush(self: *File.Elf) !void {
704 pub fn flush(self: *Elf) !void {
707705 const foreign_endian = self.options.target.cpu.arch.endian() != std.Target.current.cpu.arch.endian();
708706
709707 // Unfortunately these have to be buffered and done at the end because ELF does not allow
......@@ -839,7 +837,7 @@ pub const File = struct {
839837 assert(syms_sect.sh_info == self.local_symbols.items.len);
840838 }
841839
842 fn writeElfHeader(self: *File.Elf) !void {
840 fn writeElfHeader(self: *Elf) !void {
843841 var hdr_buf: [@sizeOf(elf.Elf64_Ehdr)]u8 = undefined;
844842
845843 var index: usize = 0;
......@@ -960,7 +958,7 @@ pub const File = struct {
960958 try self.file.?.pwriteAll(hdr_buf[0..index], 0);
961959 }
962960
963 fn freeTextBlock(self: *File.Elf, text_block: *TextBlock) void {
961 fn freeTextBlock(self: *Elf, text_block: *TextBlock) void {
964962 var already_have_free_list_node = false;
965963 {
966964 var i: usize = 0;
......@@ -1000,12 +998,12 @@ pub const File = struct {
1000998 }
1001999 }
10021000
1003 fn shrinkTextBlock(self: *File.Elf, text_block: *TextBlock, new_block_size: u64) void {
1001 fn shrinkTextBlock(self: *Elf, text_block: *TextBlock, new_block_size: u64) void {
10041002 // TODO check the new capacity, and if it crosses the size threshold into a big enough
10051003 // capacity, insert a free list node for it.
10061004 }
10071005
1008 fn growTextBlock(self: *File.Elf, text_block: *TextBlock, new_block_size: u64, alignment: u64) !u64 {
1006 fn growTextBlock(self: *Elf, text_block: *TextBlock, new_block_size: u64, alignment: u64) !u64 {
10091007 const sym = self.local_symbols.items[text_block.local_sym_index];
10101008 const align_ok = mem.alignBackwardGeneric(u64, sym.st_value, alignment) == sym.st_value;
10111009 const need_realloc = !align_ok or new_block_size > text_block.capacity(self.*);
......@@ -1013,7 +1011,7 @@ pub const File = struct {
10131011 return self.allocateTextBlock(text_block, new_block_size, alignment);
10141012 }
10151013
1016 fn allocateTextBlock(self: *File.Elf, text_block: *TextBlock, new_block_size: u64, alignment: u64) !u64 {
1014 fn allocateTextBlock(self: *Elf, text_block: *TextBlock, new_block_size: u64, alignment: u64) !u64 {
10171015 const phdr = &self.program_headers.items[self.phdr_load_re_index.?];
10181016 const shdr = &self.sections.items[self.text_section_index.?];
10191017 const new_block_ideal_capacity = new_block_size * alloc_num / alloc_den;
......@@ -1127,7 +1125,7 @@ pub const File = struct {
11271125 return vaddr;
11281126 }
11291127
1130 pub fn allocateDeclIndexes(self: *File.Elf, decl: *Module.Decl) !void {
1128 pub fn allocateDeclIndexes(self: *Elf, decl: *Module.Decl) !void {
11311129 if (decl.link.local_sym_index != 0) return;
11321130
11331131 // Here we also ensure capacity for the free lists so that they can be appended to without fail.
......@@ -1166,7 +1164,7 @@ pub const File = struct {
11661164 self.offset_table.items[decl.link.offset_table_index] = 0;
11671165 }
11681166
1169 pub fn freeDecl(self: *File.Elf, decl: *Module.Decl) void {
1167 pub fn freeDecl(self: *Elf, decl: *Module.Decl) void {
11701168 self.freeTextBlock(&decl.link);
11711169 if (decl.link.local_sym_index != 0) {
11721170 self.local_symbol_free_list.appendAssumeCapacity(decl.link.local_sym_index);
......@@ -1178,7 +1176,7 @@ pub const File = struct {
11781176 }
11791177 }
11801178
1181 pub fn updateDecl(self: *File.Elf, module: *Module, decl: *Module.Decl) !void {
1179 pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void {
11821180 var code_buffer = std.ArrayList(u8).init(self.allocator);
11831181 defer code_buffer.deinit();
11841182
......@@ -1258,7 +1256,7 @@ pub const File = struct {
12581256
12591257 /// Must be called only after a successful call to `updateDecl`.
12601258 pub fn updateDeclExports(
1261 self: *File.Elf,
1259 self: *Elf,
12621260 module: *Module,
12631261 decl: *const Module.Decl,
12641262 exports: []const *Module.Export,
......@@ -1331,13 +1329,13 @@ pub const File = struct {
13311329 }
13321330 }
13331331
1334 pub fn deleteExport(self: *File.Elf, exp: Export) void {
1332 pub fn deleteExport(self: *Elf, exp: Export) void {
13351333 const sym_index = exp.sym_index orelse return;
13361334 self.global_symbol_free_list.appendAssumeCapacity(sym_index);
13371335 self.global_symbols.items[sym_index].st_info = 0;
13381336 }
13391337
1340 fn writeProgHeader(self: *File.Elf, index: usize) !void {
1338 fn writeProgHeader(self: *Elf, index: usize) !void {
13411339 const foreign_endian = self.options.target.cpu.arch.endian() != std.Target.current.cpu.arch.endian();
13421340 const offset = self.program_headers.items[index].p_offset;
13431341 switch (self.options.target.cpu.arch.ptrBitWidth()) {
......@@ -1359,7 +1357,7 @@ pub const File = struct {
13591357 }
13601358 }
13611359
1362 fn writeSectHeader(self: *File.Elf, index: usize) !void {
1360 fn writeSectHeader(self: *Elf, index: usize) !void {
13631361 const foreign_endian = self.options.target.cpu.arch.endian() != std.Target.current.cpu.arch.endian();
13641362 const offset = self.sections.items[index].sh_offset;
13651363 switch (self.options.target.cpu.arch.ptrBitWidth()) {
......@@ -1382,7 +1380,7 @@ pub const File = struct {
13821380 }
13831381 }
13841382
1385 fn writeOffsetTableEntry(self: *File.Elf, index: usize) !void {
1383 fn writeOffsetTableEntry(self: *Elf, index: usize) !void {
13861384 const shdr = &self.sections.items[self.got_section_index.?];
13871385 const phdr = &self.program_headers.items[self.phdr_got_index.?];
13881386 const entry_size: u16 = switch (self.ptr_width) {
......@@ -1426,7 +1424,7 @@ pub const File = struct {
14261424 }
14271425 }
14281426
1429 fn writeSymbol(self: *File.Elf, index: usize) !void {
1427 fn writeSymbol(self: *Elf, index: usize) !void {
14301428 const syms_sect = &self.sections.items[self.symtab_section_index.?];
14311429 // Make sure we are not pointlessly writing symbol data that will have to get relocated
14321430 // due to running out of space.
......@@ -1482,7 +1480,7 @@ pub const File = struct {
14821480 }
14831481 }
14841482
1485 fn writeAllGlobalSymbols(self: *File.Elf) !void {
1483 fn writeAllGlobalSymbols(self: *Elf) !void {
14861484 const syms_sect = &self.sections.items[self.symtab_section_index.?];
14871485 const sym_size: u64 = switch (self.ptr_width) {
14881486 .p32 => @sizeOf(elf.Elf32_Sym),
src-self-hosted/main.zig-5
......@@ -364,11 +364,6 @@ fn buildOutputType(
364364 }
365365 }
366366
367 if (cbe and output_mode != .Obj) {
368 std.debug.print("The C backend must be used with build-obj\n", .{});
369 process.exit(1);
370 }
371
372367 const root_name = if (provided_name) |n| n else blk: {
373368 if (root_src_file) |file| {
374369 const basename = fs.path.basename(file);
src-self-hosted/test.zig+1-1
......@@ -66,7 +66,7 @@ pub const TestContext = struct {
6666 /// such as QEMU is required for tests to complete.
6767 target: std.zig.CrossTarget,
6868 /// In order to be able to run e.g. Execution updates, this must be set
69 /// to Executable. This is ignored when generating C output.
69 /// to Executable.
7070 output_mode: std.builtin.OutputMode,
7171 updates: std.ArrayList(Update),
7272 extension: TestType,