[PATCH] D123752: [lld] Implement safe icf for MachO
Jez Ng via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 19 12:28:18 PDT 2022
int3 added inline comments.
================
Comment at: lld/MachO/Driver.cpp:1510-1512
+ if (config->icfLevel == ICFLevel::safe) {
+ markAddrSigSymbols(inputFiles, &*symtab, &*config);
+ }
----------------
nit: can omit `if` braces
================
Comment at: lld/MachO/ICF.cpp:361-365
+ if (auto *d = dyn_cast_or_null<Defined>(s)) {
+ if (d->isec) {
+ d->isec->keepUnique = true;
+ }
+ }
----------------
can omit braces
================
Comment at: lld/MachO/ICF.cpp:370-371
+ SymbolTable *symtab, Configuration *config) {
+ // Symbols in the dynsym could be address-significant in other executables
+ // or DSOs, so we conservatively mark them as address-significant.
+ for (Symbol *sym : symtab->getSymbols()) {
----------------
hmm if I understand correctly, the failure case we are trying to avoid here is that a DSO may export two symbols `a` and `b`, and whatever loads that DSO may end up comparing the addresses of `a` and `b` for equality? If that's the case I think any exported symbol in a DSO should be marked as address-significant. But... that seems like we would end up marking a lot of symbols :/
`referencedDynamically` is only used to mark symbols that shouldn't be stripped (and currently only applies to `__mh_execute_header`, as per its block comment); but stripped symbols can still have their addresses taken if they are in the export trie.
What does LLD-ELF do here?
================
Comment at: lld/MachO/ICF.cpp:373
+ for (Symbol *sym : symtab->getSymbols()) {
+ Defined *def = dyn_cast_or_null<Defined>(sym);
+ if (def && def->referencedDynamically) {
----------------
I think the `_or_null` isn't necessary, this should always be nonnull
================
Comment at: lld/MachO/ICF.cpp:380
+ for (InputFile *file : inputFiles) {
+ auto *obj = dyn_cast_or_null<ObjFile>(file);
+ if (!obj)
----------------
================
Comment at: lld/MachO/ICF.cpp:389-390
+
+ auto *subSection = &addrSigSection->subsections[0];
+ auto &contents = subSection->isec->data;
+
----------------
codebase convention is to avoid `auto` for simple types
================
Comment at: lld/MachO/ICF.cpp:427
isClassRefsSection(isec)) &&
+ (isec->keepUnique == false) &&
!isec->shouldOmitFromOutput() &&
----------------
================
Comment at: lld/MachO/ICF.h:24
+void markAddrSigSymbols(llvm::SetVector<InputFile *> &inputFiles,
+ SymbolTable *symtab, Configuration *config);
+void markSymAsAddrSig(Symbol *s);
----------------
`symtab` and `config` are globals in LLD; no need to pass them explicitly
================
Comment at: lld/MachO/InputSection.h:74
bool isFinal = false;
+ bool keepUnique = false;
uint32_t align = 1;
----------------
would be nice to have a comment here
================
Comment at: lld/test/MachO/icf-options.s:12
+# RUN: %lld -lSystem --icf=safe -o %t/safe %t/main.o 2>&1 \
+# RUN: | FileCheck %s --check-prefix=DIAG-SAFE --allow-empty
# RUN: not %lld -lSystem --icf=junk -o %t/junk %t/main.o 2>&1 \
----------------
can just reuse `DIAG-EMPTY` here, no need for `DIAG-SAFE`
================
Comment at: lld/test/MachO/icf-safe.s:16-18
+; ICFALL-LABEL: _main
+; ICFALL: bl _func05
+; ICFALL-NEXT: bl _func05
----------------
nit: align
================
Comment at: lld/test/MachO/icf-safe.s:34-39
+ %0 = load i32, ptr @nr1
+ %1 = load i32, ptr @nr2
+ %2 = load i32, ptr @nr3
+ %mul = mul nsw i32 %2, %1
+ %add = add nsw i32 %mul, %0
+ ret i32 %add
----------------
we usually try to create test cases that are as minimal as possible. can this just be a `ret void`?
================
Comment at: lld/test/MachO/icf-safe.s:104-106
+attributes #0 = { minsize mustprogress nofree noinline norecurse nosync nounwind optsize readonly ssp willreturn uwtable "frame-pointer"="non-leaf" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="apple-a7" "target-features"="+aes,+crypto,+fp-armv8,+neon,+sha2,+v8a,+zcm,+zcz" }
+attributes #1 = { minsize nofree norecurse nounwind optsize ssp uwtable "frame-pointer"="non-leaf" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="apple-a7" "target-features"="+aes,+crypto,+fp-armv8,+neon,+sha2,+v8a,+zcm,+zcz" }
+attributes #2 = { minsize optsize }
----------------
ditto, I suppose we need `noinline` but can we omit the others?
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D123752/new/
https://reviews.llvm.org/D123752
More information about the llvm-commits
mailing list