================
@@ -613,32 +645,34 @@ void macho::foldIdenticalSections(bool onlyCfStrings) {
       for (Defined *d : isec->symbols)
         if (d->unwindEntry())
           foldable.push_back(d->unwindEntry());
-
-      // Some sections have embedded addends that foil ICF's hashing / equality
-      // checks. (We can ignore embedded addends when doing ICF because the 
same
-      // information gets recorded in our Reloc structs.) We therefore create a
-      // mutable copy of the section data and zero out the embedded addends
-      // before performing any hashing / equality checks.
-      if (isFoldableWithAddendsRemoved) {
-        // We have to do this copying serially as the BumpPtrAllocator is not
-        // thread-safe. FIXME: Make a thread-safe allocator.
-        MutableArrayRef<uint8_t> copy = isec->data.copy(bAlloc());
-        for (const Relocation &r : isec->relocs)
-          target->relocateOne(copy.data() + r.offset, r, /*va=*/0,
-                              /*relocVA=*/0);
-        isec->data = copy;
-      }
-    } else if (!isEhFrameSection(isec)) {
-      // EH frames are gathered as foldables from unwindEntry above; give a
-      // unique ID to everything else.
+    } else if (isEhFrameSection(isec)) {
+      // __eh_frame contains two types of records: FDEs and CIEs.
+      // Functions point to FDEs, which are already collected above via
+      // unwindEntry(). CIEs are shared headers and are not attached to
+      // individual functions. Collect only CIEs here so they can also be 
hashed
+      // and deduplicated.
+      auto *obj = dyn_cast_or_null<ObjFile>(isec->getFile());
+      if (!onlyCfStrings && obj && !obj->fdes.contains(isec) &&
+          !isec->shouldOmitFromOutput())
+        foldable.push_back(isec);
+    } else {
+      // Give a unique ID to everything else.
       isec->icfEqClass[0] = ++icfUniqueID;
     }
   }
----------------
ellishg wrote:

I added some logs here
```
  for (auto *isec : foldable) {
    for (auto &r : isec->relocs) {
      errs() << isec << " " << isec->symbols[0]->getName() << " " << r.offset 
<< "\n";
    }
  }
```

And got this output

```
0x281cf0 ltmp0 4
0x2821c0 EH_Frame 25
0x2821c0 EH_Frame 0
0x2821c0 EH_Frame 8
0x2821c0 EH_Frame 0
0x2821c0 EH_Frame 4
0x2821c0 EH_Frame 4
0x2825b0 _padB 4
0x2824d0 EH_Frame 25
0x2824d0 EH_Frame 0
0x2824d0 EH_Frame 8
0x2824d0 EH_Frame 0
0x2824d0 EH_Frame 4
0x2824d0 EH_Frame 4
0x282620 _foldA 4
0x282230 EH_Frame 25
0x282230 EH_Frame 0
0x282230 EH_Frame 8
0x282230 EH_Frame 0
0x282230 EH_Frame 4
0x282230 EH_Frame 4
...
```

We can see some relocations have an offset zero, which would cause 
`getNormalizedData()` to zero out the first byte in the section. I think that 
is the length byte and the size is already checked in `compareData()`, so it 
might not cause incorrect folding in this case. But still this could lead to a 
bug. This is the point I tried to make in 
https://github.com/llvm/llvm-project/pull/213778#discussion_r3806288211.

https://github.com/llvm/llvm-project/pull/216895
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to