| ... | ... | @@ -128,7 +128,7 @@ section_by_name: std.array_hash_map.Auto(String(.shstrtab), void), |
| 128 | 128 | changed_symtab_index: std.array_hash_map.Auto(String(.strtab), void), |
| 129 | 129 | /// Counts how many relocations are currently in `.rela.dyn` which would require a `DT_TEXTREL` |
| 130 | 130 | /// entry in the `.dynamic` section. This allows adding `DT_TEXTREL` to the output `.dynamic` |
| 131 | | /// section in `flush` only when it is actually necessary. See also `nodeRequiresTextrel`. |
| 131 | /// section in `flush` only when it is actually necessary. See also `nodeWantsDsoRelocation`. |
| 132 | 132 | textrel_count: u32, |
| 133 | 133 | |
| 134 | 134 | const_prog_node: std.Progress.Node, |
| ... | ... | @@ -1128,8 +1128,10 @@ const SymbolReloc = struct { |
| 1128 | 1128 | } |
| 1129 | 1129 | if (reloc.rela_index.unwrap()) |rela_index| { |
| 1130 | 1130 | reloc.relaSection(elf).relaDeleteOne(elf, rela_index); |
| 1131 | | if (elf.nodeRequiresTextrel(reloc.node)) { |
| 1132 | | elf.textrel_count -= 1; |
| 1131 | switch (elf.nodeWantsDsoRelocation(reloc.node)) { |
| 1132 | .no => unreachable, // there *was* a dynamic relocation! |
| 1133 | .yes => {}, |
| 1134 | .yes_textrel => elf.textrel_count -= 1, |
| 1133 | 1135 | } |
| 1134 | 1136 | } |
| 1135 | 1137 | if (reloc.type.dependsOnTlsSize()) { |
| ... | ... | @@ -1672,8 +1674,10 @@ fn setGlobalSymbolValue( |
| 1672 | 1674 | assert(reloc.target == Symbol.Id.global(global_name)); |
| 1673 | 1675 | if (reloc.rela_index.unwrap()) |rela_index| { |
| 1674 | 1676 | reloc.relaSection(elf).relaDeleteOne(elf, rela_index); |
| 1675 | | if (elf.nodeRequiresTextrel(reloc.node)) { |
| 1676 | | elf.textrel_count -= 1; |
| 1677 | switch (elf.nodeWantsDsoRelocation(reloc.node)) { |
| 1678 | .no => unreachable, // there *was* a dynamic relocation! |
| 1679 | .yes => {}, |
| 1680 | .yes_textrel => elf.textrel_count -= 1, |
| 1677 | 1681 | } |
| 1678 | 1682 | reloc.rela_index = .none; |
| 1679 | 1683 | } |
| ... | ... | @@ -5108,8 +5112,10 @@ fn addSymbolRelocAssumeCapacity( |
| 5108 | 5112 | } else elf.globalByName(name).?.dynsym_index, |
| 5109 | 5113 | }; |
| 5110 | 5114 | |
| 5111 | | if (elf.nodeRequiresTextrel(node)) { |
| 5112 | | elf.textrel_count += 1; |
| 5115 | switch (elf.nodeWantsDsoRelocation(node)) { |
| 5116 | .no => break :r .none, |
| 5117 | .yes => {}, |
| 5118 | .yes_textrel => elf.textrel_count += 1, |
| 5113 | 5119 | } |
| 5114 | 5120 | |
| 5115 | 5121 | // It currently looks like we need a runtime relocation for this. |
| ... | ... | @@ -5383,13 +5389,18 @@ fn updateGotEntry(elf: *Elf, got_index: usize) void { |
| 5383 | 5389 | }; |
| 5384 | 5390 | } |
| 5385 | 5391 | |
| 5386 | | /// Returns whether a `DT_TEXTREL` dynamic entry is needed to have a runtime relocation in `node`. |
| 5387 | | fn nodeRequiresTextrel(elf: *Elf, node: MappedFile.Node.Index) bool { |
| 5392 | /// If `node` cannot contain runtime relocations, returns `.no`. |
| 5393 | /// |
| 5394 | /// If `node` can contain runtime relocations, `returns `.yes_textrel` if such a relocation requires |
| 5395 | /// the presence of a `DT_TEXTREL` dynamic entry, or `.yes` otherwise. |
| 5396 | fn nodeWantsDsoRelocation(elf: *Elf, node: MappedFile.Node.Index) enum { yes, yes_textrel, no } { |
| 5388 | 5397 | const shndx = elf.getNodeShndx(node); |
| 5389 | 5398 | const shf: std.elf.SHF = switch (elf.shdrPtr(shndx)) { |
| 5390 | 5399 | inline else => |shdr| elf.targetLoad(&shdr.flags).shf, |
| 5391 | 5400 | }; |
| 5392 | | return shf.ALLOC and !shf.WRITE; |
| 5401 | if (!shf.ALLOC) return .no; |
| 5402 | if (!shf.WRITE) return .yes_textrel; |
| 5403 | return .yes; |
| 5393 | 5404 | } |
| 5394 | 5405 | |
| 5395 | 5406 | pub fn updateNav(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void { |