authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-04-23 23:53:52-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-04-23 23:53:52-04:00
log229e99ca37441c758155fca113aecc3c4529c3ea
treef12edb06b93e0ebfdfcc1e0da7f2fed4544dca7c
parent2d35f71fa9a9c18dc5679a6de58969bebafae17f

codegen: write the updated code size to PT_LOAD section header


1 files changed, 67 insertions(+), 57 deletions(-)

src-self-hosted/link.zig+67-57
......@@ -332,61 +332,6 @@ const Update = struct {
332332 phdr_table_dirty = true;
333333 }
334334 const foreign_endian = self.module.target.cpu.arch.endian() != std.Target.current.cpu.arch.endian();
335 if (phdr_table_dirty) {
336 const allocated_size = self.allocatedSize(self.phdr_table_offset.?);
337 const needed_size = self.program_headers.items.len * phsize;
338
339 if (needed_size > allocated_size) {
340 self.phdr_table_offset = null; // free the space
341 self.phdr_table_offset = self.findFreeSpace(needed_size, phalign);
342 }
343
344 const allocator = self.program_headers.allocator;
345 switch (ptr_width) {
346 .p32 => {
347 const buf = try allocator.alloc(elf.Elf32_Phdr, self.program_headers.items.len);
348 defer allocator.free(buf);
349
350 for (buf) |*phdr, i| {
351 phdr.* = .{
352 .p_type = self.program_headers.items[i].p_type,
353 .p_flags = self.program_headers.items[i].p_flags,
354 .p_offset = @intCast(u32, self.program_headers.items[i].p_offset),
355 .p_vaddr = @intCast(u32, self.program_headers.items[i].p_vaddr),
356 .p_paddr = @intCast(u32, self.program_headers.items[i].p_paddr),
357 .p_filesz = @intCast(u32, self.program_headers.items[i].p_filesz),
358 .p_memsz = @intCast(u32, self.program_headers.items[i].p_memsz),
359 .p_align = @intCast(u32, self.program_headers.items[i].p_align),
360 };
361 if (foreign_endian) {
362 bswapAllFields(elf.Elf32_Phdr, phdr);
363 }
364 }
365 try self.file.pwriteAll(mem.sliceAsBytes(buf), self.phdr_table_offset.?);
366 },
367 .p64 => {
368 const buf = try allocator.alloc(elf.Elf64_Phdr, self.program_headers.items.len);
369 defer allocator.free(buf);
370
371 for (buf) |*phdr, i| {
372 phdr.* = .{
373 .p_type = self.program_headers.items[i].p_type,
374 .p_flags = self.program_headers.items[i].p_flags,
375 .p_offset = self.program_headers.items[i].p_offset,
376 .p_vaddr = self.program_headers.items[i].p_vaddr,
377 .p_paddr = self.program_headers.items[i].p_paddr,
378 .p_filesz = self.program_headers.items[i].p_filesz,
379 .p_memsz = self.program_headers.items[i].p_memsz,
380 .p_align = self.program_headers.items[i].p_align,
381 };
382 if (foreign_endian) {
383 bswapAllFields(elf.Elf64_Phdr, phdr);
384 }
385 }
386 try self.file.pwriteAll(mem.sliceAsBytes(buf), self.phdr_table_offset.?);
387 },
388 }
389 }
390335 if (shdr_table_dirty) {
391336 const allocated_size = self.allocatedSize(self.shdr_table_offset.?);
392337 const needed_size = self.sections.items.len * phsize;
......@@ -446,7 +391,64 @@ const Update = struct {
446391 },
447392 }
448393 }
449 try self.writeCodeAndSymbols();
394
395 try self.writeCodeAndSymbols(&phdr_table_dirty);
396
397 if (phdr_table_dirty) {
398 const allocated_size = self.allocatedSize(self.phdr_table_offset.?);
399 const needed_size = self.program_headers.items.len * phsize;
400
401 if (needed_size > allocated_size) {
402 self.phdr_table_offset = null; // free the space
403 self.phdr_table_offset = self.findFreeSpace(needed_size, phalign);
404 }
405
406 const allocator = self.program_headers.allocator;
407 switch (ptr_width) {
408 .p32 => {
409 const buf = try allocator.alloc(elf.Elf32_Phdr, self.program_headers.items.len);
410 defer allocator.free(buf);
411
412 for (buf) |*phdr, i| {
413 phdr.* = .{
414 .p_type = self.program_headers.items[i].p_type,
415 .p_flags = self.program_headers.items[i].p_flags,
416 .p_offset = @intCast(u32, self.program_headers.items[i].p_offset),
417 .p_vaddr = @intCast(u32, self.program_headers.items[i].p_vaddr),
418 .p_paddr = @intCast(u32, self.program_headers.items[i].p_paddr),
419 .p_filesz = @intCast(u32, self.program_headers.items[i].p_filesz),
420 .p_memsz = @intCast(u32, self.program_headers.items[i].p_memsz),
421 .p_align = @intCast(u32, self.program_headers.items[i].p_align),
422 };
423 if (foreign_endian) {
424 bswapAllFields(elf.Elf32_Phdr, phdr);
425 }
426 }
427 try self.file.pwriteAll(mem.sliceAsBytes(buf), self.phdr_table_offset.?);
428 },
429 .p64 => {
430 const buf = try allocator.alloc(elf.Elf64_Phdr, self.program_headers.items.len);
431 defer allocator.free(buf);
432
433 for (buf) |*phdr, i| {
434 phdr.* = .{
435 .p_type = self.program_headers.items[i].p_type,
436 .p_flags = self.program_headers.items[i].p_flags,
437 .p_offset = self.program_headers.items[i].p_offset,
438 .p_vaddr = self.program_headers.items[i].p_vaddr,
439 .p_paddr = self.program_headers.items[i].p_paddr,
440 .p_filesz = self.program_headers.items[i].p_filesz,
441 .p_memsz = self.program_headers.items[i].p_memsz,
442 .p_align = self.program_headers.items[i].p_align,
443 };
444 if (foreign_endian) {
445 bswapAllFields(elf.Elf64_Phdr, phdr);
446 }
447 }
448 try self.file.pwriteAll(mem.sliceAsBytes(buf), self.phdr_table_offset.?);
449 },
450 }
451 }
450452
451453 const shstrtab_sect = &self.sections.items[self.shstrtab_index.?];
452454 if (shstrtab_dirty or self.shstrtab.items.len != shstrtab_sect.sh_size) {
......@@ -590,7 +592,7 @@ const Update = struct {
590592 try self.file.pwriteAll(hdr_buf[0..index], 0);
591593 }
592594
593 fn writeCodeAndSymbols(self: *Update) !void {
595 fn writeCodeAndSymbols(self: *Update, phdr_table_dirty: *bool) !void {
594596 // index 0 is always a null symbol
595597 try self.symbols.resize(1);
596598 self.symbols.items[0] = .{
......@@ -638,6 +640,14 @@ const Update = struct {
638640 vaddr += code.items.len;
639641 }
640642
643 {
644 // Now that we know the code size, we need to update the program header for executable code
645 phdr.p_memsz = vaddr - phdr.p_vaddr;
646 phdr.p_filesz = phdr.p_memsz;
647
648 phdr_table_dirty.* = true;
649 }
650
641651 return self.writeSymbols();
642652 }
643653