| ... | @@ -6381,11 +6381,11 @@ fn getNodeVAddr(elf: *Elf, ni: MappedFile.Node.Index) u64 { | ... | @@ -6381,11 +6381,11 @@ fn getNodeVAddr(elf: *Elf, ni: MappedFile.Node.Index) u64 { |
| 6381 | }; | 6381 | }; |
| 6382 | } | 6382 | } |
| 6383 | | 6383 | |
| 6384 | fn tbssSegmentOffset(elf: *Elf) u64 { | 6384 | fn tbssBaseOffset(elf: *Elf) u64 { |
| 6385 | const tbss_addr = elf.shndx.tbss.vaddr(elf); | 6385 | const tbss_addr = elf.shndx.tbss.vaddr(elf); |
| 6386 | | 6386 | |
| 6387 | // Hasn't been laid out yet. | 6387 | // Hasn't been laid out yet. |
| 6388 | if (tbss_addr == 0) return 0; | 6388 | if (tbss_addr == 0 or elf.ehdrType() == .REL) return 0; |
| 6389 | | 6389 | |
| 6390 | const tls_ni = elf.ni.tls.unwrap().?; | 6390 | const tls_ni = elf.ni.tls.unwrap().?; |
| 6391 | const tls_phndx = elf.getNode(tls_ni).segment; | 6391 | const tls_phndx = elf.getNode(tls_ni).segment; |
| ... | @@ -7016,6 +7016,7 @@ fn mapInputSection(elf: *Elf, opts: struct { | ... | @@ -7016,6 +7016,7 @@ fn mapInputSection(elf: *Elf, opts: struct { |
| 7016 | StripSection, | 7016 | StripSection, |
| 7017 | SectionFlagsConflict, | 7017 | SectionFlagsConflict, |
| 7018 | SectionTypeConflict, | 7018 | SectionTypeConflict, |
| | 7019 | UnsupportedNobitsSection, |
| 7019 | })!Section.Index { | 7020 | })!Section.Index { |
| 7020 | const gpa = elf.base.comp.gpa; | 7021 | const gpa = elf.base.comp.gpa; |
| 7021 | if (opts.flags.INFO_LINK or | 7022 | if (opts.flags.INFO_LINK or |
| ... | @@ -7073,7 +7074,8 @@ fn mapInputSection(elf: *Elf, opts: struct { | ... | @@ -7073,7 +7074,8 @@ fn mapInputSection(elf: *Elf, opts: struct { |
| 7073 | .name = name, | 7074 | .name = name, |
| 7074 | .type = switch (opts.type) { | 7075 | .type = switch (opts.type) { |
| 7075 | .PROGBITS => .NULL, // size is 0 | 7076 | .PROGBITS => .NULL, // size is 0 |
| 7076 | .NOBITS => .NOBITS, | 7077 | .X86_64_UNWIND => .X86_64_UNWIND, |
| | 7078 | .NOBITS => return error.UnsupportedNobitsSection, |
| 7077 | else => unreachable, | 7079 | else => unreachable, |
| 7078 | }, | 7080 | }, |
| 7079 | .flags = flags: { | 7081 | .flags = flags: { |
| ... | @@ -7099,7 +7101,7 @@ fn mapInputSection(elf: *Elf, opts: struct { | ... | @@ -7099,7 +7101,7 @@ fn mapInputSection(elf: *Elf, opts: struct { |
| 7099 | const existing_type = elf.targetLoad(&shdr.type); | 7101 | const existing_type = elf.targetLoad(&shdr.type); |
| 7100 | | 7102 | |
| 7101 | switch (opts.type) { | 7103 | switch (opts.type) { |
| 7102 | .PROGBITS => switch (existing_type) { | 7104 | .PROGBITS, .X86_64_UNWIND => switch (existing_type) { |
| 7103 | .NULL, .PROGBITS, .X86_64_UNWIND => {}, | 7105 | .NULL, .PROGBITS, .X86_64_UNWIND => {}, |
| 7104 | else => return error.SectionTypeConflict, | 7106 | else => return error.SectionTypeConflict, |
| 7105 | }, | 7107 | }, |
| ... | @@ -7157,6 +7159,7 @@ fn navMapIndex(elf: *Elf, zcu: *Zcu, nav_index: InternPool.Nav.Index) Error!Node | ... | @@ -7157,6 +7159,7 @@ fn navMapIndex(elf: *Elf, zcu: *Zcu, nav_index: InternPool.Nav.Index) Error!Node |
| 7157 | error.UnsupportedSectionFlags, | 7159 | error.UnsupportedSectionFlags, |
| 7158 | error.SectionTypeConflict, | 7160 | error.SectionTypeConflict, |
| 7159 | error.SectionFlagsConflict, | 7161 | error.SectionFlagsConflict, |
| | 7162 | error.UnsupportedNobitsSection, |
| 7160 | => {}, // fall back to default behavior below | 7163 | => {}, // fall back to default behavior below |
| 7161 | | 7164 | |
| 7162 | } | 7165 | } |
| ... | @@ -7548,16 +7551,15 @@ fn loadObject( | ... | @@ -7548,16 +7551,15 @@ fn loadObject( |
| 7548 | | 7551 | |
| 7549 | const sections = try gpa.alloc(struct { | 7552 | const sections = try gpa.alloc(struct { |
| 7550 | shdr: ElfN.Shdr, | 7553 | shdr: ElfN.Shdr, |
| 7551 | placement: ?union(enum) { | 7554 | placement: union(enum) { |
| 7552 | progbits: InputSection.Index, | 7555 | progbits: InputSection.Index, |
| 7553 | bss: struct { | 7556 | bss: struct { |
| 7554 | shndx: Section.Index, | | |
| 7555 | offset: u64, | 7557 | offset: u64, |
| 7556 | }, | 7558 | }, |
| 7557 | tbss: struct { | 7559 | tbss: struct { |
| 7558 | shndx: Section.Index, | | |
| 7559 | offset: u64, | 7560 | offset: u64, |
| 7560 | }, | 7561 | }, |
| | 7562 | none, |
| 7561 | }, | 7563 | }, |
| 7562 | }, ehdr.shnum); | 7564 | }, ehdr.shnum); |
| 7563 | | 7565 | |
| ... | @@ -7566,7 +7568,7 @@ fn loadObject( | ... | @@ -7566,7 +7568,7 @@ fn loadObject( |
| 7566 | for (sections) |*section| { | 7568 | for (sections) |*section| { |
| 7567 | section.* = .{ | 7569 | section.* = .{ |
| 7568 | .shdr = try r.peekStruct(ElfN.Shdr, target_endian), | 7570 | .shdr = try r.peekStruct(ElfN.Shdr, target_endian), |
| 7569 | .placement = null, | 7571 | .placement = .none, |
| 7570 | }; | 7572 | }; |
| 7571 | try r.discardAll(ehdr.shentsize); | 7573 | try r.discardAll(ehdr.shentsize); |
| 7572 | switch (section.shdr.type) { | 7574 | switch (section.shdr.type) { |
| ... | @@ -7594,10 +7596,6 @@ fn loadObject( | ... | @@ -7594,10 +7596,6 @@ fn loadObject( |
| 7594 | const name = std.mem.sliceTo(shstrtab[section.shdr.name..], 0); | 7596 | const name = std.mem.sliceTo(shstrtab[section.shdr.name..], 0); |
| 7595 | if (!comp.config.any_unwind_tables and std.mem.eql(u8, name, ".eh_frame")) continue; | 7597 | if (!comp.config.any_unwind_tables and std.mem.eql(u8, name, ".eh_frame")) continue; |
| 7596 | const sect_type = section.shdr.type; | 7598 | const sect_type = section.shdr.type; |
| 7597 | const is_bss = (std.mem.startsWith(u8, name, ".bss.") or | | |
| 7598 | std.mem.eql(u8, name, ".bss")) and sect_type == .NOBITS; | | |
| 7599 | const is_tbss = (std.mem.startsWith(u8, name, ".tbss.") or | | |
| 7600 | std.mem.eql(u8, name, ".tbss")) and sect_type == .NOBITS; | | |
| 7601 | const opts: struct { | 7599 | const opts: struct { |
| 7602 | shndx: Section.Index, | 7600 | shndx: Section.Index, |
| 7603 | node_fixed: bool, | 7601 | node_fixed: bool, |
| ... | @@ -7608,7 +7606,7 @@ fn loadObject( | ... | @@ -7608,7 +7606,7 @@ fn loadObject( |
| 7608 | .name = name, | 7606 | .name = name, |
| 7609 | .flags = section.shdr.flags.shf, | 7607 | .flags = section.shdr.flags.shf, |
| 7610 | .entsize = section.shdr.entsize, | 7608 | .entsize = section.shdr.entsize, |
| 7611 | .type = if (is_bss or is_tbss) .NOBITS else .PROGBITS, | 7609 | .type = section.shdr.type, |
| 7612 | }) catch |err| switch (err) { | 7610 | }) catch |err| switch (err) { |
| 7613 | else => |e| return e, | 7611 | else => |e| return e, |
| 7614 | error.StripSection => continue, | 7612 | error.StripSection => continue, |
| ... | @@ -7641,6 +7639,11 @@ fn loadObject( | ... | @@ -7641,6 +7639,11 @@ fn loadObject( |
| 7641 | "flags of section '{s}' conflict with other inputs", | 7639 | "flags of section '{s}' conflict with other inputs", |
| 7642 | .{name}, | 7640 | .{name}, |
| 7643 | ), | 7641 | ), |
| | 7642 | error.UnsupportedNobitsSection => return diags.failParse( |
| | 7643 | path, |
| | 7644 | "unsupported section type SHT_NOBITS for non-bss section '{s}'", |
| | 7645 | .{name}, |
| | 7646 | ), |
| 7644 | }; | 7647 | }; |
| 7645 | if (section.shdr.flags.shf.COMPRESSED) { | 7648 | if (section.shdr.flags.shf.COMPRESSED) { |
| 7646 | // SHF_COMPRESSED is only allowed on non-alloc sections. | 7649 | // SHF_COMPRESSED is only allowed on non-alloc sections. |
| ... | @@ -7664,8 +7667,7 @@ fn loadObject( | ... | @@ -7664,8 +7667,7 @@ fn loadObject( |
| 7664 | shndx != .rodata and | 7667 | shndx != .rodata and |
| 7665 | shndx != .data and | 7668 | shndx != .data and |
| 7666 | shndx != .data_rel_ro and | 7669 | shndx != .data_rel_ro and |
| 7667 | shndx != elf.shndx.tdata and | 7670 | shndx != elf.shndx.tdata, |
| 7668 | shndx != elf.shndx.tbss, | | |
| 7669 | }; | 7671 | }; |
| 7670 | }, | 7672 | }, |
| 7671 | inline .INIT_ARRAY, .FINI_ARRAY, .PREINIT_ARRAY => |@"type"| .{ | 7673 | inline .INIT_ARRAY, .FINI_ARRAY, .PREINIT_ARRAY => |@"type"| .{ |
| ... | @@ -7711,35 +7713,25 @@ fn loadObject( | ... | @@ -7711,35 +7713,25 @@ fn loadObject( |
| 7711 | | 7713 | |
| 7712 | try opts.shndx.ensureAligned(elf, need_align); | 7714 | try opts.shndx.ensureAligned(elf, need_align); |
| 7713 | | 7715 | |
| 7714 | if (is_bss or is_tbss) { | 7716 | if (sect_type == .NOBITS) { |
| 7715 | const offset: u64 = offset: { | 7717 | const offset: u64 = switch (elf.shdrPtr(opts.shndx)) { |
| 7716 | switch (elf.shdrPtr(opts.shndx)) { | 7718 | inline else => |shdr| offset: { |
| 7717 | inline else => |shdr| { | 7719 | // Bump our BSS output section size |
| 7718 | // Bump our BSS output section size. | 7720 | const old_size: u64 = elf.targetLoad(&shdr.size); |
| 7719 | const old_size: u64 = elf.targetLoad(&shdr.size); | 7721 | const offset = need_align.forward(old_size); |
| 7720 | const offset = need_align.forward(old_size); | 7722 | elf.targetStore(&shdr.size, @intCast(offset + section.shdr.size)); |
| 7721 | const new_size = offset + section.shdr.size; | 7723 | break :offset offset; |
| 7722 | elf.targetStore(&shdr.size, @intCast(new_size)); | 7724 | }, |
| 7723 | break :offset offset; | | |
| 7724 | }, | | |
| 7725 | } | | |
| 7726 | }; | 7725 | }; |
| 7727 | | 7726 | |
| 7728 | if (is_bss) { | 7727 | if (opts.shndx == elf.shndx.bss) { |
| 7729 | section.placement = .{ .bss = .{ | 7728 | section.placement = .{ .bss = .{ .offset = offset } }; |
| 7730 | .shndx = opts.shndx, | | |
| 7731 | .offset = offset, | | |
| 7732 | } }; | | |
| 7733 | input_has_bss = true; | 7729 | input_has_bss = true; |
| 7734 | continue; | 7730 | } else if (opts.shndx == elf.shndx.tbss) { |
| 7735 | } | 7731 | section.placement = .{ .tbss = .{ .offset = offset } }; |
| 7736 | | | |
| 7737 | if (is_tbss) { | | |
| 7738 | section.placement = .{ .tbss = .{ | | |
| 7739 | .shndx = opts.shndx, | | |
| 7740 | .offset = offset, | | |
| 7741 | } }; | | |
| 7742 | input_has_tbss = true; | 7732 | input_has_tbss = true; |
| | 7733 | } else { |
| | 7734 | unreachable; |
| 7743 | } | 7735 | } |
| 7744 | | 7736 | |
| 7745 | continue; | 7737 | continue; |
| ... | @@ -7861,8 +7853,9 @@ fn loadObject( | ... | @@ -7861,8 +7853,9 @@ fn loadObject( |
| 7861 | }, | 7853 | }, |
| 7862 | }; | 7854 | }; |
| 7863 | | 7855 | |
| 7864 | const placement = | 7856 | const placement = sections[input_sym.shndx].placement; |
| 7865 | sections[input_sym.shndx].placement orelse continue; | 7857 | |
| | 7858 | if (placement == .none) continue; |
| 7866 | | 7859 | |
| 7867 | const symbol_oni: MappedFile.Node.Index.Optional, const output_shndx, const symbol_value = switch (placement) { | 7860 | const symbol_oni: MappedFile.Node.Index.Optional, const output_shndx, const symbol_value = switch (placement) { |
| 7868 | .progbits => |isi| .{ | 7861 | .progbits => |isi| .{ |
| ... | @@ -7871,20 +7864,16 @@ fn loadObject( | ... | @@ -7871,20 +7864,16 @@ fn loadObject( |
| 7871 | input_sym.value, | 7864 | input_sym.value, |
| 7872 | }, | 7865 | }, |
| 7873 | .bss => |bss| .{ | 7866 | .bss => |bss| .{ |
| 7874 | bss.shndx.get(elf).ni, | 7867 | .none, |
| 7875 | bss.shndx, | 7868 | elf.shndx.bss, |
| 7876 | bss.shndx.vaddr(elf) + bss.offset + input_sym.value, | 7869 | elf.shndx.bss.vaddr(elf) + bss.offset + input_sym.value, |
| 7877 | }, | 7870 | }, |
| 7878 | .tbss => |tbss| .{ | 7871 | .tbss => |tbss| .{ |
| 7879 | tbss.shndx.get(elf).ni, | 7872 | .none, |
| 7880 | tbss.shndx, | 7873 | elf.shndx.tbss, |
| 7881 | switch (elf.ehdrType()) { | 7874 | elf.tbssBaseOffset() + tbss.offset + input_sym.value, |
| 7882 | .REL => tbss.offset + input_sym.value, | | |
| 7883 | .EXEC, .DYN => elf.tbssSegmentOffset() + | | |
| 7884 | tbss.offset + | | |
| 7885 | input_sym.value, | | |
| 7886 | }, | | |
| 7887 | }, | 7875 | }, |
| | 7876 | .none => unreachable, |
| 7888 | }; | 7877 | }; |
| 7889 | | 7878 | |
| 7890 | switch (input_sym.info.bind) { | 7879 | switch (input_sym.info.bind) { |
| ... | @@ -7949,7 +7938,8 @@ fn loadObject( | ... | @@ -7949,7 +7938,8 @@ fn loadObject( |
| 7949 | return diags.failParse(path, "unsupported rel entsize", .{}); | 7938 | return diags.failParse(path, "unsupported rel entsize", .{}); |
| 7950 | | 7939 | |
| 7951 | const loc_sec = &sections[rel_sec.shdr.info]; | 7940 | const loc_sec = &sections[rel_sec.shdr.info]; |
| 7952 | const loc_node = switch (loc_sec.placement orelse continue) { | 7941 | const loc_node = switch (loc_sec.placement) { |
| | 7942 | .none => continue, |
| 7953 | .progbits => |isi| isi.node(elf), | 7943 | .progbits => |isi| isi.node(elf), |
| 7954 | .bss, .tbss => return diags.failParse( | 7944 | .bss, .tbss => return diags.failParse( |
| 7955 | path, | 7945 | path, |
| ... | @@ -9007,6 +8997,8 @@ fn flushDynamic(elf: *Elf) void { | ... | @@ -9007,6 +8997,8 @@ fn flushDynamic(elf: *Elf) void { |
| 9007 | | 8997 | |
| 9008 | fn addSection(elf: *Elf, segment_ni: MappedFile.Node.Index, opts: struct { | 8998 | fn addSection(elf: *Elf, segment_ni: MappedFile.Node.Index, opts: struct { |
| 9009 | name: []const u8 = "", | 8999 | name: []const u8 = "", |
| | 9000 | /// If this is `.NOBITS`, then the section's address is initialized to 0, and it is the caller's |
| | 9001 | /// responsibility to populate it. |
| 9010 | type: std.elf.SHT = .NULL, | 9002 | type: std.elf.SHT = .NULL, |
| 9011 | flags: std.elf.SHF = .{}, | 9003 | flags: std.elf.SHF = .{}, |
| 9012 | size: std.elf.Xword = 0, | 9004 | size: std.elf.Xword = 0, |
| ... | @@ -11229,7 +11221,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void | ... | @@ -11229,7 +11221,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void |
| 11229 | }, | 11221 | }, |
| 11230 | | 11222 | |
| 11231 | .TLS => { | 11223 | .TLS => { |
| 11232 | const tbss_base = elf.tbssSegmentOffset(); | 11224 | const tbss_base = elf.tbssBaseOffset(); |
| 11233 | const new_vaddr = elf.computeNodeVAddr(ni); | 11225 | const new_vaddr = elf.computeNodeVAddr(ni); |
| 11234 | const tls_offset = elf.targetLoad(&ph.offset); | 11226 | const tls_offset = elf.targetLoad(&ph.offset); |
| 11235 | const tls_filesz = elf.targetLoad(&ph.filesz); | 11227 | const tls_filesz = elf.targetLoad(&ph.filesz); |
| ... | @@ -11237,16 +11229,17 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void | ... | @@ -11237,16 +11229,17 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void |
| 11237 | elf.targetStore(&ph.vaddr, @intCast(new_vaddr)); | 11229 | elf.targetStore(&ph.vaddr, @intCast(new_vaddr)); |
| 11238 | elf.targetStore(&ph.paddr, @intCast(new_vaddr)); | 11230 | elf.targetStore(&ph.paddr, @intCast(new_vaddr)); |
| 11239 | | 11231 | |
| 11240 | // This may seem like a no-op since we're moving to and fro the same base, | 11232 | const tbss_shndx = elf.shndx.tbss; |
| 11241 | // but we also need to update the section STT_SECTION symbol, which this | 11233 | const tbss_addr = new_vaddr + tbss_base; |
| 11242 | // function will conveniently do for us. | 11234 | switch (elf.shdrPtr(tbss_shndx)) { |
| 11243 | elf.updateNobitsAddress( | 11235 | inline else => |shdr| { |
| 11244 | elf.shndx.tbss, | 11236 | elf.targetStore(&shdr.addr, @intCast(tbss_addr)); |
| 11245 | new_vaddr + tbss_base, | 11237 | elf.targetStore(&shdr.offset, @intCast(tls_offset + tls_filesz)); |
| 11246 | tls_offset + tls_filesz, | 11238 | }, |
| 11247 | tbss_base, | 11239 | } |
| 11248 | tbss_base, | 11240 | Symbol.Id.local(tbss_shndx.get(elf).lsi).flushMoved( |
| 11249 | elf.tbss_inputs.items, | 11241 | elf, |
| | 11242 | tbss_addr, |
| 11250 | ); | 11243 | ); |
| 11251 | }, | 11244 | }, |
| 11252 | } | 11245 | } |
| ... | @@ -11651,6 +11644,34 @@ fn updateNobitsAddress( | ... | @@ -11651,6 +11644,34 @@ fn updateNobitsAddress( |
| 11651 | ); | 11644 | ); |
| 11652 | } | 11645 | } |
| 11653 | | 11646 | |
| | 11647 | fn loadSegmentChildrenMoved( |
| | 11648 | elf: *Elf, |
| | 11649 | segment_ni: MappedFile.Node.Index, |
| | 11650 | old_vaddr: u64, |
| | 11651 | new_vaddr: u64, |
| | 11652 | offset: u64, |
| | 11653 | filesz: u64, |
| | 11654 | ) std.mem.Allocator.Error!void { |
| | 11655 | if (segment_ni == elf.ni.data and elf.shndx.bss != .UNDEF) { |
| | 11656 | const bss_shndx = elf.shndx.bss; |
| | 11657 | const old_bss_addr = bss_shndx.vaddr(elf); |
| | 11658 | const new_bss_addr = new_vaddr + filesz; |
| | 11659 | |
| | 11660 | elf.updateNobitsAddress( |
| | 11661 | bss_shndx, |
| | 11662 | new_bss_addr, |
| | 11663 | offset + filesz, |
| | 11664 | old_bss_addr, |
| | 11665 | new_bss_addr, |
| | 11666 | elf.bss_inputs.items, |
| | 11667 | ); |
| | 11668 | } |
| | 11669 | |
| | 11670 | if (old_vaddr != new_vaddr) { |
| | 11671 | try segment_ni.childrenMoved(elf.base.comp.gpa, &elf.mf); |
| | 11672 | } |
| | 11673 | } |
| | 11674 | |
| 11654 | /// Given the index of a `PT_LOAD`/`PT_NULL` segment, assumes that the phdr's `offset` and `filesz` | 11675 | /// Given the index of a `PT_LOAD`/`PT_NULL` segment, assumes that the phdr's `offset` and `filesz` |
| 11655 | /// have been updated as needed by the caller, and updates the `@"align"`, `vaddr`, `paddr`, and | 11676 | /// have been updated as needed by the caller, and updates the `@"align"`, `vaddr`, `paddr`, and |
| 11656 | /// `memsz` fields of the segment, in order to place it at a valid virtual address. | 11677 | /// `memsz` fields of the segment, in order to place it at a valid virtual address. |
| ... | @@ -11693,6 +11714,8 @@ fn allocateSegmentLoadAddress(elf: *Elf, orig_phndx: u32) std.mem.Allocator.Erro | ... | @@ -11693,6 +11714,8 @@ fn allocateSegmentLoadAddress(elf: *Elf, orig_phndx: u32) std.mem.Allocator.Erro |
| 11693 | var vaddr: u64 = orig_vaddr; | 11714 | var vaddr: u64 = orig_vaddr; |
| 11694 | | 11715 | |
| 11695 | elf.targetStore(&phdr[orig_phndx].@"align", @intCast(ph_align.toByteUnits())); | 11716 | elf.targetStore(&phdr[orig_phndx].@"align", @intCast(ph_align.toByteUnits())); |
| | 11717 | elf.targetStore(&phdr[orig_phndx].memsz, @intCast(memsz)); |
| | 11718 | elf.targetStore(&phdr[orig_phndx].type, if (memsz > 0) .LOAD else .NULL); |
| 11696 | | 11719 | |
| 11697 | // First, we will shift the virtual address as needed in order to maintain the required | 11720 | // First, we will shift the virtual address as needed in order to maintain the required |
| 11698 | // property that vaddr is congruent to offset modulo the phdr alignment. | 11721 | // property that vaddr is congruent to offset modulo the phdr alignment. |
| ... | @@ -11770,22 +11793,15 @@ fn allocateSegmentLoadAddress(elf: *Elf, orig_phndx: u32) std.mem.Allocator.Erro | ... | @@ -11770,22 +11793,15 @@ fn allocateSegmentLoadAddress(elf: *Elf, orig_phndx: u32) std.mem.Allocator.Erro |
| 11770 | elf.targetStore(&next_ph.vaddr, @intCast(next_new_vaddr)); | 11793 | elf.targetStore(&next_ph.vaddr, @intCast(next_new_vaddr)); |
| 11771 | elf.targetStore(&next_ph.paddr, @intCast(next_new_vaddr)); | 11794 | elf.targetStore(&next_ph.paddr, @intCast(next_new_vaddr)); |
| 11772 | | 11795 | |
| 11773 | const bss_shndx = elf.shndx.bss; | | |
| 11774 | const next_filesz = elf.targetLoad(&next_ph.filesz); | 11796 | const next_filesz = elf.targetLoad(&next_ph.filesz); |
| 11775 | const old_bss_addr = bss_shndx.vaddr(elf); | 11797 | try elf.loadSegmentChildrenMoved( |
| 11776 | const new_bss_addr = next_new_vaddr + next_filesz; | 11798 | next_ni, |
| 11777 | | 11799 | next_vaddr, |
| 11778 | elf.updateNobitsAddress( | 11800 | next_new_vaddr, |
| 11779 | bss_shndx, | 11801 | next_offset, |
| 11780 | new_bss_addr, | 11802 | next_filesz, |
| 11781 | next_offset + next_filesz, | | |
| 11782 | old_bss_addr, | | |
| 11783 | new_bss_addr, | | |
| 11784 | elf.bss_inputs.items, | | |
| 11785 | ); | 11803 | ); |
| 11786 | | 11804 | |
| 11787 | try next_ni.childrenMoved(elf.base.comp.gpa, &elf.mf); | | |
| 11788 | | | |
| 11789 | break; | 11805 | break; |
| 11790 | }, | 11806 | }, |
| 11791 | } | 11807 | } |
| ... | @@ -11809,29 +11825,15 @@ fn allocateSegmentLoadAddress(elf: *Elf, orig_phndx: u32) std.mem.Allocator.Erro | ... | @@ -11809,29 +11825,15 @@ fn allocateSegmentLoadAddress(elf: *Elf, orig_phndx: u32) std.mem.Allocator.Erro |
| 11809 | if (vaddr != orig_vaddr) { | 11825 | if (vaddr != orig_vaddr) { |
| 11810 | elf.targetStore(&phdr[phndx].vaddr, @intCast(vaddr)); | 11826 | elf.targetStore(&phdr[phndx].vaddr, @intCast(vaddr)); |
| 11811 | elf.targetStore(&phdr[phndx].paddr, @intCast(vaddr)); | 11827 | elf.targetStore(&phdr[phndx].paddr, @intCast(vaddr)); |
| 11812 | try segment_ni.childrenMoved(elf.base.comp.gpa, &elf.mf); | | |
| 11813 | } | 11828 | } |
| 11814 | | 11829 | |
| 11815 | const ph = &phdr[phndx]; | 11830 | try elf.loadSegmentChildrenMoved( |
| 11816 | | 11831 | segment_ni, |
| 11817 | elf.targetStore(&ph.memsz, @intCast(memsz)); | 11832 | orig_vaddr, |
| 11818 | elf.targetStore(&ph.type, if (memsz > 0) .LOAD else .NULL); | 11833 | vaddr, |
| 11819 | | 11834 | offset, |
| 11820 | if (segment_ni == elf.ni.data and elf.shndx.bss != .UNDEF) { | 11835 | filesz, |
| 11821 | const bss_shndx = elf.shndx.bss; | 11836 | ); |
| 11822 | | | |
| 11823 | const old_bss_addr = bss_shndx.vaddr(elf); | | |
| 11824 | const new_bss_addr = vaddr + filesz; | | |
| 11825 | | | |
| 11826 | elf.updateNobitsAddress( | | |
| 11827 | bss_shndx, | | |
| 11828 | new_bss_addr, | | |
| 11829 | offset + filesz, | | |
| 11830 | old_bss_addr, | | |
| 11831 | new_bss_addr, | | |
| 11832 | elf.bss_inputs.items, | | |
| 11833 | ); | | |
| 11834 | } | | |
| 11835 | }, | 11837 | }, |
| 11836 | } | 11838 | } |
| 11837 | } | 11839 | } |
| ... | @@ -11867,7 +11869,6 @@ fn flushResized(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!vo | ... | @@ -11867,7 +11869,6 @@ fn flushResized(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!vo |
| 11867 | switch (elf.targetLoad(&ph.type)) { | 11869 | switch (elf.targetLoad(&ph.type)) { |
| 11868 | else => unreachable, | 11870 | else => unreachable, |
| 11869 | .NULL, .LOAD => { | 11871 | .NULL, .LOAD => { |
| 11870 | elf.targetStore(&ph.type, if (size > 0) .LOAD else .NULL); | | |
| 11871 | try elf.allocateSegmentLoadAddress(phndx); | 11872 | try elf.allocateSegmentLoadAddress(phndx); |
| 11872 | }, | 11873 | }, |
| 11873 | .DYNAMIC, .INTERP, .PHDR, .GNU_EH_FRAME, .GNU_RELRO => { | 11874 | .DYNAMIC, .INTERP, .PHDR, .GNU_EH_FRAME, .GNU_RELRO => { |
| ... | @@ -11876,7 +11877,7 @@ fn flushResized(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!vo | ... | @@ -11876,7 +11877,7 @@ fn flushResized(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!vo |
| 11876 | .TLS => { | 11877 | .TLS => { |
| 11877 | const tls_filesz: u64 = size; | 11878 | const tls_filesz: u64 = size; |
| 11878 | | 11879 | |
| 11879 | const old_tbss_base = elf.tbssSegmentOffset(); | 11880 | const old_tbss_base = elf.tbssBaseOffset(); |
| 11880 | const new_tbss_base = tls_filesz; | 11881 | const new_tbss_base = tls_filesz; |
| 11881 | const tbss_size = elf.shndx.tbss.size(elf); | 11882 | const tbss_size = elf.shndx.tbss.size(elf); |
| 11882 | const tls_vaddr = elf.targetLoad(&ph.vaddr); | 11883 | const tls_vaddr = elf.targetLoad(&ph.vaddr); |