[PATCH] D100818: [lld-macho] Implement branch-range-extension thunks
Jez Ng via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 30 05:52:11 PDT 2021
int3 added inline comments.
================
Comment at: lld/MachO/Arch/ARM64.cpp:112
stubSize = sizeof(stubCode);
+ thunkSize = llvm::alignTo<16>(stubSize);
+ branchRange = llvm::maxIntN(28) - thunkSize;
----------------
could you comment on why the alignTo is needed?
also remove llvm::
================
Comment at: lld/MachO/Arch/ARM64.cpp:120
+ thunk->align = 4;
+ // FIXME: populate data
+ thunk->data = {reinterpret_cast<const uint8_t *>(stubCode), sizeof(stubCode)};
----------------
stale comment? (since data seems like it's being populated)
================
Comment at: lld/MachO/InputSection.cpp:39
const RelocAttrs &relocAttrs = target->getRelocAttrs(type);
if (relocAttrs.hasAttr(RelocAttrBits::BRANCH)) {
+ return sym->resolveBranchVA();
----------------
I guess we can do away with the braces now
================
Comment at: lld/MachO/InputSection.h:48
+ bool isThunkable = false;
+ bool isFinal = false;
----------------
would be good to have a comment; the link to `finalize()` isn't immediately obvious
================
Comment at: lld/MachO/MergedOutputSection.cpp:37-38
input->parent = this;
+ if (input->isThunkable)
+ isThunkable = true;
}
----------------
nit: `isThunkable |= input->isThunkable;`
================
Comment at: lld/MachO/MergedOutputSection.cpp:88
+// prepareSymbolRelocation() and prepareBranchTarget() dig into
+// Reloc records. They flip the new booleans Reloc::isThunkable,
+// Inputsection::isThunkable, and MergedOutputSection::isThunkable
----------------
it won't be 'new' after this lands :)
================
Comment at: lld/MachO/MergedOutputSection.cpp:102
+// * MergedInputSection::finalize() and MergedInputSection::writeTo()
+// merge the inputs and thunks vectors (both ordered by asending
+// address), which is simple and cheap.
----------------
================
Comment at: lld/MachO/MergedOutputSection.cpp:127
+ size_t thunkSize = target->thunkSize;
+ if (thunkSize == 0) {
+ for (InputSection *isec : inputs)
----------------
seems more readable
================
Comment at: lld/MachO/MergedOutputSection.cpp:144-146
+ size_t ic = 0;
+ size_t ix = 0;
+ size_t ie = inputs.size();
----------------
I find these kind of hard to read, could we use slightly more verbose names?
================
Comment at: lld/MachO/MergedOutputSection.cpp:147
+ size_t ie = inputs.size();
+ assert(ie > 0);
+ // Kick-off by ensuring that the first input section has an address
----------------
doesn't seem like a useful assert
================
Comment at: lld/MachO/MergedOutputSection.cpp:149
+ // Kick-off by ensuring that the first input section has an address
+ finalizeOne(inputs[ix++]);
+ for (; ic < ie; ic++) {
----------------
tschuett wrote:
> LLVM prefers preincrement:
> https://llvm.org/docs/CodingStandards.html#prefer-preincrement
>
> There a couple of postincrements.
I mean this line actually does want to return a copy of the original value, so I think it's fine... but yeah the increments-for-effect-only should be preincrements
================
Comment at: lld/MachO/MergedOutputSection.cpp:158
+ continue;
+ assert(isec->getSize() > 0ull);
+ // Process relocs by ascending address
----------------
redundant assert
================
Comment at: lld/MachO/MergedOutputSection.cpp:160
+ // Process relocs by ascending address
+ for (Reloc &r : reverse(isec->relocs)) {
+ relocCount++;
----------------
I believe llvm-mc emits relocs in reverse order, but I don't think that's guaranteed anywhere in the format... we should probably sort it ourselves
================
Comment at: lld/MachO/MergedOutputSection.cpp:170-171
+ // Calculate our call referent address
+ auto *funcSym = r.referent.dyn_cast<Symbol *>();
+ assert(funcSym);
+ assert(isa<Defined>(funcSym) || isa<DylibSymbol>(funcSym));
----------------
(`get<>()` will assert)
================
Comment at: lld/MachO/MergedOutputSection.cpp:208
+ thunkInfo.isec->parent = this;
+ Twine thunkName =
+ funcSym->getName() + ".thunk." + std::to_string(thunkInfo.sequence++);
----------------
I think the lint is right here... the return value of `to_string` is going to be unowned
================
Comment at: lld/MachO/MergedOutputSection.cpp:222
+
+ if (config->verbose)
+ warn("thunks for " + parent->name + "," + name +
----------------
LLD-ELF handles `--verbose` by assigning to `errorHandler().verbose`, I think we should do likewise
================
Comment at: lld/MachO/MergedOutputSection.cpp:233-244
+ size_t i = 0, ie = inputs.size();
+ size_t t = 0, te = thunks.size();
+ while (i < ie || t < te) {
+ while (i < ie && (t == te || inputs[i]->getSize() == 0 ||
+ inputs[i]->outSecOff < thunks[t]->outSecOff)) {
+ inputs[i]->writeTo(buf + inputs[i]->outSecFileOff);
+ i++;
----------------
instead of two sorted arrays, would it be simpler to create a map of regular InputSection to an array of thunks that immediately follow it?
================
Comment at: lld/MachO/MergedOutputSection.h:22
+
+using InputsVector = std::vector<InputSection *>;
+
----------------
nit: this type seems too simple to be worth an alias. Also since other places in the codebase (like the global `inputSections`) don't use it, we now have two different ways to refer to the same type in the codebase...
================
Comment at: lld/MachO/MergedOutputSection.h:41-42
void finalize() override;
+ void finalizeWithThunks();
+ void finalizeWithoutThunks();
----------------
doesn't seem like these are implemented
================
Comment at: lld/MachO/MergedOutputSection.h:50-53
+ size_t createThunks();
+ Defined *makeThunk(StringRef name, uint64_t maxAddr);
+ uint64_t placeThunk(uint64_t callSiteAddr, uint64_t nearestThunkI) const;
+ bool needsThunk(Symbol funcSym, uint64_t callSiteAddr) const;
----------------
nor any of these
================
Comment at: lld/MachO/Symbols.h:251-257
+#define X(T) alignas(T) char u_##T[sizeof(T)]
+ X(Defined);
+ X(Undefined);
+ X(CommonSymbol);
+ X(DylibSymbol);
+ X(LazySymbol);
+#undef X
----------------
this can be committed on its own as an NFC commit... try to keep the diff to relevant changes only
================
Comment at: lld/MachO/Target.h:67
+ virtual void populateThunk(InputSection *thunk, Symbol *funcSym) {}
+
----------------
nit: insert `llvm_unreachable()` in the body?
================
Comment at: lld/MachO/Writer.cpp:545-546
}
+ } else {
+ return target->thunkSize > 0;
}
----------------
why aren't externalWeakDefs thunkable?
================
Comment at: lld/MachO/Writer.cpp:549
}
+ return false;
}
----------------
do we actually get here in practice? I would assume that `prepareBranchTarget` is only ever called on DylibSymbols and Defined symbols...
================
Comment at: lld/MachO/Writer.cpp:603-605
+ if (isa<LazySymbol>(sym))
+ warn("relocation to lazy symbol: " + toString(*sym) +
+ "\n>>> defined in " + toString(sym->getFile()));
----------------
I thought we discussed that this case should be impossible; how does it arise?
================
Comment at: lld/MachO/Writer.cpp:1070
+ // After this point, we create no new segments; HOWEVER, we might
+ // yet create branch-range extention thunks for architectures whose
+ // hardware call instructions have limited range, e.g., ARM(64)
----------------
================
Comment at: lld/MachO/Writer.cpp:1073
+ // Since the thunks are interspersed with text input sections,
+ // we create the t
sortSegmentsAndSections();
----------------
seems like you forgot to finish this sentence :p
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D100818/new/
https://reviews.llvm.org/D100818
More information about the llvm-commits
mailing list