@@ -87,9 +87,14 @@ static cl::opt<bool> ShowAtomGraph(
87
87
cl::init(false ));
88
88
89
89
static cl::opt<bool > ShowSizes (
90
- " show-sizes" ,
91
- cl::desc (" Show sizes: pre- and post-dead stripping, and allocations" ),
92
- cl::init(false ));
90
+ " show-sizes" ,
91
+ cl::desc (" Show sizes pre- and post-dead stripping, and allocations" ),
92
+ cl::init(false ));
93
+
94
+ static cl::opt<bool > ShowRelocatedSectionContents (
95
+ " show-relocated-section-contents" ,
96
+ cl::desc (" show section contents after fixups have been applied" ),
97
+ cl::init(false ));
93
98
94
99
ExitOnError ExitOnErr;
95
100
@@ -139,6 +144,74 @@ static uint64_t computeTotalAtomSizes(AtomGraph &G) {
139
144
return TotalSize;
140
145
}
141
146
147
+ static void dumpSectionContents (raw_ostream &OS, AtomGraph &G) {
148
+ constexpr JITTargetAddress DumpWidth = 16 ;
149
+ static_assert (isPowerOf2_64 (DumpWidth), " DumpWidth must be a power of two" );
150
+
151
+ // Put sections in address order.
152
+ std::vector<Section *> Sections;
153
+ for (auto &S : G.sections ())
154
+ Sections.push_back (&S);
155
+
156
+ std::sort (Sections.begin (), Sections.end (),
157
+ [](const Section *LHS, const Section *RHS) {
158
+ if (LHS->atoms_empty () && RHS->atoms_empty ())
159
+ return false ;
160
+ if (LHS->atoms_empty ())
161
+ return false ;
162
+ if (RHS->atoms_empty ())
163
+ return true ;
164
+ return (*LHS->atoms ().begin ())->getAddress () <
165
+ (*RHS->atoms ().begin ())->getAddress ();
166
+ });
167
+
168
+ for (auto *S : Sections) {
169
+ OS << S->getName () << " content:" ;
170
+ if (S->atoms_empty ()) {
171
+ OS << " \n section empty\n " ;
172
+ continue ;
173
+ }
174
+
175
+ // Sort atoms into order, then render.
176
+ std::vector<DefinedAtom *> Atoms (S->atoms ().begin (), S->atoms ().end ());
177
+ std::sort (Atoms.begin (), Atoms.end (),
178
+ [](const DefinedAtom *LHS, const DefinedAtom *RHS) {
179
+ return LHS->getAddress () < RHS->getAddress ();
180
+ });
181
+
182
+ JITTargetAddress NextAddr = Atoms.front ()->getAddress () & ~(DumpWidth - 1 );
183
+ for (auto *DA : Atoms) {
184
+ bool IsZeroFill = DA->isZeroFill ();
185
+ JITTargetAddress AtomStart = DA->getAddress ();
186
+ JITTargetAddress AtomSize =
187
+ IsZeroFill ? DA->getZeroFillSize () : DA->getContent ().size ();
188
+ JITTargetAddress AtomEnd = AtomStart + AtomSize;
189
+ const uint8_t *AtomData =
190
+ IsZeroFill ? nullptr : DA->getContent ().bytes_begin ();
191
+
192
+ // Pad any space before the atom starts.
193
+ while (NextAddr != AtomStart) {
194
+ if (NextAddr % DumpWidth == 0 )
195
+ OS << formatv (" \n {0:x16}:" , NextAddr);
196
+ OS << " " ;
197
+ ++NextAddr;
198
+ }
199
+
200
+ // Render the atom content.
201
+ while (NextAddr != AtomEnd) {
202
+ if (NextAddr % DumpWidth == 0 )
203
+ OS << formatv (" \n {0:x16}:" , NextAddr);
204
+ if (IsZeroFill)
205
+ OS << " 00" ;
206
+ else
207
+ OS << formatv (" {0:x-2}" , AtomData[NextAddr - AtomStart]);
208
+ ++NextAddr;
209
+ }
210
+ }
211
+ OS << " \n " ;
212
+ }
213
+ }
214
+
142
215
Session::Session (Triple TT)
143
216
: ObjLayer(ES, MemMgr, ObjectLinkingLayer::NotifyLoadedFunction(),
144
217
ObjectLinkingLayer::NotifyEmittedFunction (),
@@ -181,6 +254,12 @@ void Session::modifyPassConfig(const Triple &FTT,
181
254
});
182
255
}
183
256
257
+ if (ShowRelocatedSectionContents)
258
+ PassConfig.PostFixupPasses .push_back ([](AtomGraph &G) -> Error {
259
+ outs () << " Relocated section contents for " << G.getName () << " :\n " ;
260
+ dumpSectionContents (outs (), G);
261
+ return Error::success ();
262
+ });
184
263
}
185
264
186
265
Expected<Session::FileInfo &> Session::findFileInfo (StringRef FileName) {
0 commit comments