| ... | @@ -5207,7 +5207,7 @@ fn initHeaders( | ... | @@ -5207,7 +5207,7 @@ fn initHeaders( |
| 5207 | // Must be at least `addr_align` for `elf.ni.phdr` to be placed inside this node | 5207 | // Must be at least `addr_align` for `elf.ni.phdr` to be placed inside this node |
| 5208 | .alignment = node_block_align.max(addr_align), | 5208 | .alignment = node_block_align.max(addr_align), |
| 5209 | .moved = true, | 5209 | .moved = true, |
| 5210 | .bubbles_moved = false, | 5210 | .bubbles_moved = false, // see loadable segment handling in `flushMoved` |
| 5211 | }), .{ .segment = phndx.rodata }); | 5211 | }), .{ .segment = phndx.rodata }); |
| 5212 | elf.phdrs.items[phndx.rodata] = .wrap(elf.ni.rodata); | 5212 | elf.phdrs.items[phndx.rodata] = .wrap(elf.ni.rodata); |
| 5213 | | 5213 | |
| ... | @@ -5216,14 +5216,13 @@ fn initHeaders( | ... | @@ -5216,14 +5216,13 @@ fn initHeaders( |
| 5216 | .alignment = addr_align, // keep in sync with `elf.ni.rodata` alignment above | 5216 | .alignment = addr_align, // keep in sync with `elf.ni.rodata` alignment above |
| 5217 | .moved = true, | 5217 | .moved = true, |
| 5218 | .resized = true, | 5218 | .resized = true, |
| 5219 | .bubbles_moved = false, | | |
| 5220 | }), .{ .segment = phndx.phdr }); | 5219 | }), .{ .segment = phndx.phdr }); |
| 5221 | elf.phdrs.items[phndx.phdr] = .wrap(elf.ni.phdr); | 5220 | elf.phdrs.items[phndx.phdr] = .wrap(elf.ni.phdr); |
| 5222 | | 5221 | |
| 5223 | elf.ni.text = elf.addNodeAssumeCapacity(try elf.ni.elf.addFloatingChild(gpa, &elf.mf, .{ | 5222 | elf.ni.text = elf.addNodeAssumeCapacity(try elf.ni.elf.addFloatingChild(gpa, &elf.mf, .{ |
| 5224 | .alignment = node_block_align, | 5223 | .alignment = node_block_align, |
| 5225 | .moved = true, | 5224 | .moved = true, |
| 5226 | .bubbles_moved = false, | 5225 | .bubbles_moved = false, // see loadable segment handling in `flushMoved` |
| 5227 | }), .{ .segment = phndx.text }); | 5226 | }), .{ .segment = phndx.text }); |
| 5228 | elf.phdrs.items[phndx.text] = .wrap(elf.ni.text); | 5227 | elf.phdrs.items[phndx.text] = .wrap(elf.ni.text); |
| 5229 | | 5228 | |
| ... | @@ -5231,7 +5230,7 @@ fn initHeaders( | ... | @@ -5231,7 +5230,7 @@ fn initHeaders( |
| 5231 | // Must be at least `addr_align` for `elf.ni.data_rel_ro` to be placed inside this node | 5230 | // Must be at least `addr_align` for `elf.ni.data_rel_ro` to be placed inside this node |
| 5232 | .alignment = node_block_align.max(addr_align), | 5231 | .alignment = node_block_align.max(addr_align), |
| 5233 | .moved = true, | 5232 | .moved = true, |
| 5234 | .bubbles_moved = false, | 5233 | .bubbles_moved = false, // see loadable segment handling in `flushMoved` |
| 5235 | }), .{ .segment = phndx.data }); | 5234 | }), .{ .segment = phndx.data }); |
| 5236 | elf.phdrs.items[phndx.data] = .wrap(elf.ni.data); | 5235 | elf.phdrs.items[phndx.data] = .wrap(elf.ni.data); |
| 5237 | | 5236 | |
| ... | @@ -5239,7 +5238,7 @@ fn initHeaders( | ... | @@ -5239,7 +5238,7 @@ fn initHeaders( |
| 5239 | try elf.ni.elf.addFloatingChild(gpa, &elf.mf, .{ | 5238 | try elf.ni.elf.addFloatingChild(gpa, &elf.mf, .{ |
| 5240 | .alignment = node_block_align, | 5239 | .alignment = node_block_align, |
| 5241 | .moved = true, | 5240 | .moved = true, |
| 5242 | .bubbles_moved = false, | 5241 | .bubbles_moved = false, // see loadable segment handling in `flushMoved` |
| 5243 | }), | 5242 | }), |
| 5244 | .{ .segment = phndx.plt }, | 5243 | .{ .segment = phndx.plt }, |
| 5245 | )); | 5244 | )); |
| ... | @@ -5249,7 +5248,6 @@ fn initHeaders( | ... | @@ -5249,7 +5248,6 @@ fn initHeaders( |
| 5249 | // later (if `have_dynamic_section`). Keep in sync with `elf.ni.data` alignment above. | 5248 | // later (if `have_dynamic_section`). Keep in sync with `elf.ni.data` alignment above. |
| 5250 | .alignment = node_block_align.max(addr_align), | 5249 | .alignment = node_block_align.max(addr_align), |
| 5251 | .moved = true, | 5250 | .moved = true, |
| 5252 | .bubbles_moved = false, | | |
| 5253 | }), .{ .segment = phndx.relro }); | 5251 | }), .{ .segment = phndx.relro }); |
| 5254 | elf.phdrs.items[phndx.relro] = .wrap(elf.ni.data_rel_ro); | 5252 | elf.phdrs.items[phndx.relro] = .wrap(elf.ni.data_rel_ro); |
| 5255 | | 5253 | |
| ... | @@ -5258,7 +5256,7 @@ fn initHeaders( | ... | @@ -5258,7 +5256,7 @@ fn initHeaders( |
| 5258 | try elf.ni.rodata.addFloatingChild(gpa, &elf.mf, .{ | 5256 | try elf.ni.rodata.addFloatingChild(gpa, &elf.mf, .{ |
| 5259 | .alignment = node_block_align, | 5257 | .alignment = node_block_align, |
| 5260 | .moved = true, | 5258 | .moved = true, |
| 5261 | .bubbles_moved = false, | 5259 | .bubbles_moved = false, // see TLS segment handling in `flushMoved` |
| 5262 | }), | 5260 | }), |
| 5263 | .{ .segment = phndx.tls }, | 5261 | .{ .segment = phndx.tls }, |
| 5264 | )); | 5262 | )); |
| ... | @@ -5676,7 +5674,6 @@ fn initHeaders( | ... | @@ -5676,7 +5674,6 @@ fn initHeaders( |
| 5676 | .size = interp.len + 1, | 5674 | .size = interp.len + 1, |
| 5677 | .moved = true, | 5675 | .moved = true, |
| 5678 | .resized = true, | 5676 | .resized = true, |
| 5679 | .bubbles_moved = false, | | |
| 5680 | }), | 5677 | }), |
| 5681 | .{ .segment = phndx.interp }, | 5678 | .{ .segment = phndx.interp }, |
| 5682 | ); | 5679 | ); |
| ... | @@ -5698,7 +5695,6 @@ fn initHeaders( | ... | @@ -5698,7 +5695,6 @@ fn initHeaders( |
| 5698 | try elf.ni.data_rel_ro.addFloatingChild(gpa, &elf.mf, .{ | 5695 | try elf.ni.data_rel_ro.addFloatingChild(gpa, &elf.mf, .{ |
| 5699 | .alignment = addr_align, | 5696 | .alignment = addr_align, |
| 5700 | .moved = true, | 5697 | .moved = true, |
| 5701 | .bubbles_moved = false, | | |
| 5702 | }), | 5698 | }), |
| 5703 | .{ .segment = phndx.dynamic }, | 5699 | .{ .segment = phndx.dynamic }, |
| 5704 | ); | 5700 | ); |
| ... | @@ -5952,7 +5948,6 @@ fn initHeaders( | ... | @@ -5952,7 +5948,6 @@ fn initHeaders( |
| 5952 | .size = @sizeOf(Dwarf.EhFrameHdr), | 5948 | .size = @sizeOf(Dwarf.EhFrameHdr), |
| 5953 | .alignment = .@"4", | 5949 | .alignment = .@"4", |
| 5954 | .moved = true, | 5950 | .moved = true, |
| 5955 | .bubbles_moved = false, | | |
| 5956 | }), | 5951 | }), |
| 5957 | .{ .segment = phndx.gnu_eh_frame }, | 5952 | .{ .segment = phndx.gnu_eh_frame }, |
| 5958 | ); | 5953 | ); |
| ... | @@ -9119,7 +9114,7 @@ fn addSection(elf: *Elf, segment_ni: MappedFile.Node.Index, opts: struct { | ... | @@ -9119,7 +9114,7 @@ fn addSection(elf: *Elf, segment_ni: MappedFile.Node.Index, opts: struct { |
| 9119 | .size = opts.node_align.forward(opts.size), | 9114 | .size = opts.node_align.forward(opts.size), |
| 9120 | .alignment = opts.addralign.max(opts.node_align), | 9115 | .alignment = opts.addralign.max(opts.node_align), |
| 9121 | .resized = opts.size > 0, | 9116 | .resized = opts.size > 0, |
| 9122 | .bubbles_moved = opts.flags.ALLOC, | 9117 | .bubbles_moved = opts.flags.ALLOC, // see handling in `flushMoved` |
| 9123 | }), | 9118 | }), |
| 9124 | if (opts.manual_size) .{ .section_manual_size = shndx } else .{ .section = shndx }, | 9119 | if (opts.manual_size) .{ .section_manual_size = shndx } else .{ .section = shndx }, |
| 9125 | )), | 9120 | )), |
| ... | @@ -11309,6 +11304,9 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void | ... | @@ -11309,6 +11304,9 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void |
| 11309 | | 11304 | |
| 11310 | .NULL, .LOAD => { | 11305 | .NULL, .LOAD => { |
| 11311 | try elf.allocateSegmentLoadAddress(phndx); | 11306 | try elf.allocateSegmentLoadAddress(phndx); |
| | 11307 | // Do not bubble moved---our child nodes only care if our virtual |
| | 11308 | // address changes, which is handled by `updateSegmentLoadAddress`. |
| | 11309 | return; |
| 11312 | }, | 11310 | }, |
| 11313 | | 11311 | |
| 11314 | .DYNAMIC, | 11312 | .DYNAMIC, |
| ... | @@ -11336,6 +11334,12 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void | ... | @@ -11336,6 +11334,12 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void |
| 11336 | elf, | 11334 | elf, |
| 11337 | tbss_addr, | 11335 | tbss_addr, |
| 11338 | ); | 11336 | ); |
| | 11337 | |
| | 11338 | // Do not bubble moved---our child nodes don't care about our virtual |
| | 11339 | // address changing, because symbols in the TLS segment have values |
| | 11340 | // defined relative to the base of the segment. (This is also why we |
| | 11341 | // don't update tbss symbols here.) |
| | 11342 | return; |
| 11339 | }, | 11343 | }, |
| 11340 | } | 11344 | } |
| 11341 | }, | 11345 | }, |
| ... | @@ -11388,6 +11392,12 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void | ... | @@ -11388,6 +11392,12 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void |
| 11388 | .first_symbol_reloc = elf.eh_frame_hdr_first_symbol_reloc, | 11392 | .first_symbol_reloc = elf.eh_frame_hdr_first_symbol_reloc, |
| 11389 | }); | 11393 | }); |
| 11390 | } | 11394 | } |
| | 11395 | |
| | 11396 | if (!flags.ALLOC) { |
| | 11397 | // Do not bubble moved---our virtual address hasn't changed (because it's always 0 |
| | 11398 | // for non-ALLOC sections), so there's nothing for our children to worry about. |
| | 11399 | return; |
| | 11400 | } |
| 11391 | }, | 11401 | }, |
| 11392 | .input_section => |isi| { | 11402 | .input_section => |isi| { |
| 11393 | const old_section_addr = isi.ptr(elf).vaddr; | 11403 | const old_section_addr = isi.ptr(elf).vaddr; |