llvm.org GIT mirror llvm / 77ebf7c
[JITLink][MachO] Mark atoms in sections 'no-dead-strip' set live by default. If a MachO section has the no-dead-strip attribute set then its atoms should be preserved, regardless of whether they're public or referenced elsewhere in the object. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@360477 91177308-0d34-0410-b5e6-96231b3b80d8 Lang Hames 1 year, 6 months ago
3 changed file(s) with 75 addition(s) and 36 deletion(s). Raw diff Collapse all Expand all
9999 if (auto EC = SecRef.getName(Name))
100100 return errorCodeToError(EC);
101101
102 StringRef Content;
103
104 // If this is a virtual section, leave its content empty.
105 if (!SecRef.isVirtual()) {
106 if (auto EC = SecRef.getContents(Content))
107 return errorCodeToError(EC);
108 if (Content.size() != SecRef.getSize())
109 return make_error("Section content size does not match "
110 "declared size for " +
111 Name);
112 }
113
114102 unsigned SectionIndex = SecRef.getIndex() + 1;
115
116 LLVM_DEBUG({
117 dbgs() << "Adding section " << Name << ": "
118 << format("0x%016" PRIx64, SecRef.getAddress())
119 << ", size: " << Content.size()
120 << ", align: " << SecRef.getAlignment() << "\n";
121 });
122103
123104 // FIXME: Get real section permissions
124105 // How, exactly, on MachO?
131112 sys::Memory::MF_WRITE);
132113
133114 auto &GenericSection = G->createSection(Name, Prot, SecRef.isBSS());
134 if (SecRef.isVirtual())
135 Sections[SectionIndex] =
136 MachOSection(GenericSection, SecRef.getAddress(),
137 SecRef.getAlignment(), SecRef.getSize());
138 Sections[SectionIndex] = MachOSection(GenericSection, SecRef.getAddress(),
139 SecRef.getAlignment(), Content);
115
116 LLVM_DEBUG({
117 dbgs() << "Adding section " << Name << ": "
118 << format("0x%016" PRIx64, SecRef.getAddress())
119 << ", align: " << SecRef.getAlignment() << "\n";
120 });
121
122 assert(!Sections.count(SectionIndex) && "Section index already in use");
123
124 auto &MachOSec =
125 Sections
126 .try_emplace(SectionIndex, GenericSection, SecRef.getAddress(),
127 SecRef.getAlignment())
128 .first->second;
129
130 if (!SecRef.isVirtual()) {
131 // If this section has content then record it.
132 StringRef Content;
133 if (auto EC = SecRef.getContents(Content))
134 return errorCodeToError(EC);
135 if (Content.size() != SecRef.getSize())
136 return make_error("Section content size does not match "
137 "declared size for " +
138 Name);
139 MachOSec.setContent(Content);
140 } else {
141 // If this is a zero-fill section then just record the size.
142 MachOSec.setZeroFill(SecRef.getSize());
143 }
144
145 uint32_t SectionFlags =
146 Obj.is64Bit() ? Obj.getSection64(SecRef.getRawDataRefImpl()).flags
147 : Obj.getSection(SecRef.getRawDataRefImpl()).flags;
148
149 MachOSec.setNoDeadStrip(SectionFlags & MachO::S_ATTR_NO_DEAD_STRIP);
140150 }
141151
142152 return Error::success();
289299
290300 LLVM_DEBUG(dbgs() << "MachOGraphBuilder setting atom content\n");
291301
292 // Set atom contents.
302 // Set atom contents and any section-based flags.
293303 for (auto &KV : SecToAtoms) {
294304 auto &S = *KV.first;
295305 auto &SecAtoms = KV.second;
303313 dbgs() << " " << A << " to [ " << S.getAddress() + Offset << " .. "
304314 << S.getAddress() + LastAtomAddr << " ]\n";
305315 });
316
306317 if (S.isZeroFill())
307318 A.setZeroFill(LastAtomAddr - Offset);
308319 else
309320 A.setContent(S.getContent().substr(Offset, LastAtomAddr - Offset));
321
322 // If the section has no-dead-strip set then mark the atom as live.
323 if (S.isNoDeadStrip())
324 A.setLive(true);
325
310326 LastAtomAddr = Offset;
311327 }
312328 }
3333 public:
3434 MachOSection() = default;
3535
36 /// Create a MachO section with the given content.
36 /// Create a MachO section with the given address and alignment.
3737 MachOSection(Section &GenericSection, JITTargetAddress Address,
38 unsigned Alignment, StringRef Content)
38 unsigned Alignment)
3939 : Address(Address), GenericSection(&GenericSection),
40 ContentPtr(Content.data()), Size(Content.size()),
41 Alignment(Alignment) {}
42
43 /// Create a zero-fill MachO section with the given size.
44 MachOSection(Section &GenericSection, JITTargetAddress Address,
45 unsigned Alignment, size_t ZeroFillSize)
46 : Address(Address), GenericSection(&GenericSection), Size(ZeroFillSize),
4740 Alignment(Alignment) {}
4841
4942 /// Create a section without address, content or size (used for common
5851 StringRef getName() const {
5952 assert(GenericSection && "No generic section attached");
6053 return GenericSection->getName();
54 }
55
56 MachOSection &setContent(StringRef Content) {
57 assert(!ContentPtr && !Size && "Content/zeroFill already set");
58 ContentPtr = Content.data();
59 Size = Content.size();
60 return *this;
61 }
62
63 MachOSection &setZeroFill(uint64_t Size) {
64 assert(!ContentPtr && !Size && "Content/zeroFill already set");
65 this->Size = Size;
66 return *this;
6167 }
6268
6369 bool isZeroFill() const { return !ContentPtr; }
7581
7682 unsigned getAlignment() const { return Alignment; }
7783
84 MachOSection &setNoDeadStrip(bool NoDeadStrip) {
85 this->NoDeadStrip = NoDeadStrip;
86 return *this;
87 }
88
89 bool isNoDeadStrip() const { return NoDeadStrip; }
90
7891 private:
7992 JITTargetAddress Address = 0;
8093 Section *GenericSection = nullptr;
8194 const char *ContentPtr = nullptr;
82 size_t Size = 0;
95 uint64_t Size = 0;
8396 unsigned Alignment = 0;
97 bool NoDeadStrip = false;
8498 };
8599
86100 using CustomAtomizeFunction = std::function;
262262 subtractor_with_alt_entry_subtrahend_quad_B:
263263 .quad 0
264264
265 # Check that unreferenced atoms in no-dead-strip sections are not dead stripped.
266 # We need to use a local symbol for this as any named symbol will end up in the
267 # ORC responsibility set, which is automatically marked live and would couse
268 # spurious passes.
269 #
270 # jitlink-check: *{8}section_addr(macho_reloc.o, __nds_test_sect) = 0
271 .section __DATA,__nds_test_sect,regular,no_dead_strip
272 .quad 0
273
265274 .subsections_via_symbols