| ... | ... | @@ -484,38 +484,6 @@ fn findFreeSpace(self: *Elf, object_size: u64, min_alignment: u64) u64 { |
| 484 | 484 | return start; |
| 485 | 485 | } |
| 486 | 486 | |
| 487 | | const AllocateSegmentOpts = struct { |
| 488 | | addr: u64, |
| 489 | | memsz: u64, |
| 490 | | filesz: u64, |
| 491 | | alignment: u64, |
| 492 | | flags: u32 = elf.PF_R, |
| 493 | | }; |
| 494 | | |
| 495 | | pub fn allocateSegment(self: *Elf, opts: AllocateSegmentOpts) error{OutOfMemory}!u16 { |
| 496 | | const off = self.findFreeSpace(opts.filesz, opts.alignment); |
| 497 | | const index = try self.addPhdr(.{ |
| 498 | | .type = elf.PT_LOAD, |
| 499 | | .offset = off, |
| 500 | | .filesz = opts.filesz, |
| 501 | | .addr = opts.addr, |
| 502 | | .memsz = opts.memsz, |
| 503 | | .@"align" = opts.alignment, |
| 504 | | .flags = opts.flags, |
| 505 | | }); |
| 506 | | log.debug("allocating phdr({d})({c}{c}{c}) from 0x{x} to 0x{x} (0x{x} - 0x{x})", .{ |
| 507 | | index, |
| 508 | | if (opts.flags & elf.PF_R != 0) @as(u8, 'R') else '_', |
| 509 | | if (opts.flags & elf.PF_W != 0) @as(u8, 'W') else '_', |
| 510 | | if (opts.flags & elf.PF_X != 0) @as(u8, 'X') else '_', |
| 511 | | off, |
| 512 | | off + opts.filesz, |
| 513 | | opts.addr, |
| 514 | | opts.addr + opts.memsz, |
| 515 | | }); |
| 516 | | return index; |
| 517 | | } |
| 518 | | |
| 519 | 487 | const AllocateAllocSectionOpts = struct { |
| 520 | 488 | name: [:0]const u8, |
| 521 | 489 | phdr_index: u16, |
| ... | ... | @@ -590,11 +558,15 @@ pub fn initMetadata(self: *Elf) !void { |
| 590 | 558 | comptime assert(number_of_zig_segments == 5); |
| 591 | 559 | |
| 592 | 560 | if (self.phdr_zig_load_re_index == null) { |
| 593 | | self.phdr_zig_load_re_index = try self.allocateSegment(.{ |
| 561 | const filesz = self.base.options.program_code_size_hint; |
| 562 | const off = self.findFreeSpace(filesz, self.page_size); |
| 563 | self.phdr_zig_load_re_index = try self.addPhdr(.{ |
| 564 | .type = elf.PT_LOAD, |
| 565 | .offset = off, |
| 566 | .filesz = filesz, |
| 594 | 567 | .addr = if (ptr_bit_width >= 32) 0x8000000 else 0x8000, |
| 595 | | .memsz = self.base.options.program_code_size_hint, |
| 596 | | .filesz = self.base.options.program_code_size_hint, |
| 597 | | .alignment = self.page_size, |
| 568 | .memsz = filesz, |
| 569 | .@"align" = self.page_size, |
| 598 | 570 | .flags = elf.PF_X | elf.PF_R | elf.PF_W, |
| 599 | 571 | }); |
| 600 | 572 | } |
| ... | ... | @@ -603,33 +575,45 @@ pub fn initMetadata(self: *Elf) !void { |
| 603 | 575 | // We really only need ptr alignment but since we are using PROGBITS, linux requires |
| 604 | 576 | // page align. |
| 605 | 577 | const alignment = if (is_linux) self.page_size else @as(u16, ptr_size); |
| 606 | | self.phdr_zig_got_index = try self.allocateSegment(.{ |
| 578 | const filesz = @as(u64, ptr_size) * self.base.options.symbol_count_hint; |
| 579 | const off = self.findFreeSpace(filesz, alignment); |
| 580 | self.phdr_zig_got_index = try self.addPhdr(.{ |
| 581 | .type = elf.PT_LOAD, |
| 582 | .offset = off, |
| 583 | .filesz = filesz, |
| 607 | 584 | .addr = if (ptr_bit_width >= 32) 0x4000000 else 0x4000, |
| 608 | | .memsz = @as(u64, ptr_size) * self.base.options.symbol_count_hint, |
| 609 | | .filesz = @as(u64, ptr_size) * self.base.options.symbol_count_hint, |
| 610 | | .alignment = alignment, |
| 585 | .memsz = filesz, |
| 586 | .@"align" = alignment, |
| 611 | 587 | .flags = elf.PF_R | elf.PF_W, |
| 612 | 588 | }); |
| 613 | 589 | } |
| 614 | 590 | |
| 615 | 591 | if (self.phdr_zig_load_ro_index == null) { |
| 616 | 592 | const alignment = if (is_linux) self.page_size else @as(u16, ptr_size); |
| 617 | | self.phdr_zig_load_ro_index = try self.allocateSegment(.{ |
| 593 | const filesz: u64 = 1024; |
| 594 | const off = self.findFreeSpace(filesz, alignment); |
| 595 | self.phdr_zig_load_ro_index = try self.addPhdr(.{ |
| 596 | .type = elf.PT_LOAD, |
| 597 | .offset = off, |
| 598 | .filesz = filesz, |
| 618 | 599 | .addr = if (ptr_bit_width >= 32) 0xc000000 else 0xa000, |
| 619 | | .memsz = 1024, |
| 620 | | .filesz = 1024, |
| 621 | | .alignment = alignment, |
| 600 | .memsz = filesz, |
| 601 | .@"align" = alignment, |
| 622 | 602 | .flags = elf.PF_R | elf.PF_W, |
| 623 | 603 | }); |
| 624 | 604 | } |
| 625 | 605 | |
| 626 | 606 | if (self.phdr_zig_load_rw_index == null) { |
| 627 | 607 | const alignment = if (is_linux) self.page_size else @as(u16, ptr_size); |
| 628 | | self.phdr_zig_load_rw_index = try self.allocateSegment(.{ |
| 608 | const filesz: u64 = 1024; |
| 609 | const off = self.findFreeSpace(filesz, alignment); |
| 610 | self.phdr_zig_load_rw_index = try self.addPhdr(.{ |
| 611 | .type = elf.PT_LOAD, |
| 612 | .offset = off, |
| 613 | .filesz = filesz, |
| 629 | 614 | .addr = if (ptr_bit_width >= 32) 0x10000000 else 0xc000, |
| 630 | | .memsz = 1024, |
| 631 | | .filesz = 1024, |
| 632 | | .alignment = alignment, |
| 615 | .memsz = filesz, |
| 616 | .@"align" = alignment, |
| 633 | 617 | .flags = elf.PF_R | elf.PF_W, |
| 634 | 618 | }); |
| 635 | 619 | } |