|  | 
| 11 | 11 | #include "Symbols.h" | 
| 12 | 12 | #include "SyntheticSections.h" | 
| 13 | 13 | #include "Target.h" | 
| 14 |  | -#include "TargetImpl.h" | 
| 15 | 14 | #include "llvm/BinaryFormat/ELF.h" | 
| 16 | 15 | #include "llvm/Support/Endian.h" | 
| 17 | 16 | #include "llvm/Support/MathExtras.h" | 
| @@ -50,7 +49,6 @@ class X86_64 : public TargetInfo { | 
| 50 | 49 |   bool deleteFallThruJmpInsn(InputSection &is, InputFile *file, | 
| 51 | 50 |                              InputSection *nextIS) const override; | 
| 52 | 51 |   bool relaxOnce(int pass) const override; | 
| 53 |  | -  void applyBranchToBranchOpt() const override; | 
| 54 | 52 | 
 | 
| 55 | 53 | private: | 
| 56 | 54 |   void relaxTlsGdToLe(uint8_t *loc, const Relocation &rel, uint64_t val) const; | 
| @@ -1163,72 +1161,6 @@ void X86_64::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const { | 
| 1163 | 1161 |   } | 
| 1164 | 1162 | } | 
| 1165 | 1163 | 
 | 
| 1166 |  | -static std::optional<uint64_t> getControlTransferAddend(InputSection &is, | 
| 1167 |  | -                                                        Relocation &r) { | 
| 1168 |  | -  // Identify a control transfer relocation for the branch-to-branch | 
| 1169 |  | -  // optimization. A "control transfer relocation" usually means a CALL or JMP | 
| 1170 |  | -  // target but it also includes relative vtable relocations for example. | 
| 1171 |  | -  // | 
| 1172 |  | -  // We require the relocation type to be PLT32. With a relocation type of PLT32 | 
| 1173 |  | -  // the value may be assumed to be used for branching directly to the symbol | 
| 1174 |  | -  // and the addend is only used to produce the relocated value (hence the | 
| 1175 |  | -  // effective addend is always 0). This is because if a PLT is needed the | 
| 1176 |  | -  // addend will be added to the address of the PLT, and it doesn't make sense | 
| 1177 |  | -  // to branch into the middle of a PLT. For example, relative vtable | 
| 1178 |  | -  // relocations use PLT32 and 0 or a positive value as the addend but still are | 
| 1179 |  | -  // used to branch to the symbol. | 
| 1180 |  | -  // | 
| 1181 |  | -  // STT_SECTION symbols are a special case on x86 because the LLVM assembler | 
| 1182 |  | -  // uses them for branches to local symbols which are assembled as referring to | 
| 1183 |  | -  // the section symbol with the addend equal to the symbol value - 4. | 
| 1184 |  | -  if (r.type == R_X86_64_PLT32) { | 
| 1185 |  | -    if (r.sym->isSection()) | 
| 1186 |  | -      return r.addend + 4; | 
| 1187 |  | -    return 0; | 
| 1188 |  | -  } | 
| 1189 |  | -  return std::nullopt; | 
| 1190 |  | -} | 
| 1191 |  | - | 
| 1192 |  | -static std::pair<Relocation *, uint64_t> | 
| 1193 |  | -getBranchInfoAtTarget(InputSection &is, uint64_t offset) { | 
| 1194 |  | -  auto content = is.contentMaybeDecompress(); | 
| 1195 |  | -  if (content.size() > offset && content[offset] == 0xe9) { // JMP immediate | 
| 1196 |  | -    auto *i = llvm::partition_point( | 
| 1197 |  | -        is.relocations, [&](Relocation &r) { return r.offset < offset + 1; }); | 
| 1198 |  | -    // Unlike with getControlTransferAddend() it is valid to accept a PC32 | 
| 1199 |  | -    // relocation here because we know that this is actually a JMP and not some | 
| 1200 |  | -    // other reference, so the interpretation is that we add 4 to the addend and | 
| 1201 |  | -    // use that as the effective addend. | 
| 1202 |  | -    if (i != is.relocations.end() && i->offset == offset + 1 && | 
| 1203 |  | -        (i->type == R_X86_64_PC32 || i->type == R_X86_64_PLT32)) { | 
| 1204 |  | -      return {i, i->addend + 4}; | 
| 1205 |  | -    } | 
| 1206 |  | -  } | 
| 1207 |  | -  return {nullptr, 0}; | 
| 1208 |  | -} | 
| 1209 |  | - | 
| 1210 |  | -static void redirectControlTransferRelocations(Relocation &r1, | 
| 1211 |  | -                                               const Relocation &r2) { | 
| 1212 |  | -  // The isSection() check handles the STT_SECTION case described above. | 
| 1213 |  | -  // In that case the original addend is irrelevant because it referred to an | 
| 1214 |  | -  // offset within the original target section so we overwrite it. | 
| 1215 |  | -  // | 
| 1216 |  | -  // The +4 is here to compensate for r2.addend which will likely be -4, | 
| 1217 |  | -  // but may also be addend-4 in case of a PC32 branch to symbol+addend. | 
| 1218 |  | -  if (r1.sym->isSection()) | 
| 1219 |  | -    r1.addend = r2.addend; | 
| 1220 |  | -  else | 
| 1221 |  | -    r1.addend += r2.addend + 4; | 
| 1222 |  | -  r1.expr = r2.expr; | 
| 1223 |  | -  r1.sym = r2.sym; | 
| 1224 |  | -} | 
| 1225 |  | - | 
| 1226 |  | -void X86_64::applyBranchToBranchOpt() const { | 
| 1227 |  | -  applyBranchToBranchOptImpl(ctx, getControlTransferAddend, | 
| 1228 |  | -                             getBranchInfoAtTarget, | 
| 1229 |  | -                             redirectControlTransferRelocations); | 
| 1230 |  | -} | 
| 1231 |  | - | 
| 1232 | 1164 | // If Intel Indirect Branch Tracking is enabled, we have to emit special PLT | 
| 1233 | 1165 | // entries containing endbr64 instructions. A PLT entry will be split into two | 
| 1234 | 1166 | // parts, one in .plt.sec (writePlt), and the other in .plt (writeIBTPlt). | 
|  | 
0 commit comments