@@ -43,6 +43,9 @@ class BinaryData;
43
43
class BinarySection {
44
44
friend class BinaryContext ;
45
45
46
+ // / Count the number of sections created.
47
+ static uint64_t Count;
48
+
46
49
BinaryContext &BC; // Owning BinaryContext
47
50
std::string Name; // Section name
48
51
const SectionRef Section; // SectionRef (may be null)
@@ -86,6 +89,7 @@ class BinarySection {
86
89
uint64_t OutputSize{0 }; // Section size in the rewritten binary.
87
90
uint64_t OutputFileOffset{0 }; // File offset in the rewritten binary file.
88
91
StringRef OutputContents; // Rewritten section contents.
92
+ const uint64_t SectionNumber; // Order in which the section was created.
89
93
unsigned SectionID{-1u }; // Unique ID used for address mapping.
90
94
// Set by ExecutableFileMemoryManager.
91
95
uint32_t Index{0 }; // Section index in the output file.
@@ -147,13 +151,14 @@ class BinarySection {
147
151
Size(Section.getSize()), Alignment(Section.getAlignment()),
148
152
ELFType(Section.getELFType()), ELFFlags(Section.getELFFlags()),
149
153
Relocations(Section.Relocations),
150
- PendingRelocations(Section.PendingRelocations), OutputName(Name) {}
154
+ PendingRelocations(Section.PendingRelocations), OutputName(Name),
155
+ SectionNumber(++Count) {}
151
156
152
157
BinarySection (BinaryContext &BC, SectionRef Section)
153
158
: BC(BC), Name(getName(Section)), Section(Section),
154
159
Contents (getContents(Section)), Address(Section.getAddress()),
155
160
Size(Section.getSize()), Alignment(Section.getAlignment()),
156
- OutputName(Name) {
161
+ OutputName(Name), SectionNumber(++Count) {
157
162
if (isELF ()) {
158
163
ELFType = ELFSectionRef (Section).getType ();
159
164
ELFFlags = ELFSectionRef (Section).getFlags ();
@@ -173,7 +178,7 @@ class BinarySection {
173
178
Contents(reinterpret_cast <const char *>(Data), Data ? Size : 0),
174
179
Address(0 ), Size(Size ), Alignment(Alignment), ELFType(ELFType),
175
180
ELFFlags(ELFFlags), IsFinalized(true ), OutputName(Name),
176
- OutputSize(Size ), OutputContents(Contents) {
181
+ OutputSize(Size ), OutputContents(Contents), SectionNumber(++Count) {
177
182
assert (Alignment > 0 && " section alignment must be > 0" );
178
183
}
179
184
@@ -207,10 +212,34 @@ class BinarySection {
207
212
208
213
// Order sections by their immutable properties.
209
214
bool operator <(const BinarySection &Other) const {
210
- return (getAddress () < Other.getAddress () ||
211
- (getAddress () == Other.getAddress () &&
212
- (getSize () < Other.getSize () ||
213
- (getSize () == Other.getSize () && getName () < Other.getName ()))));
215
+ // Allocatable before non-allocatable.
216
+ if (isAllocatable () != Other.isAllocatable ())
217
+ return isAllocatable () > Other.isAllocatable ();
218
+
219
+ // Input sections take precedence.
220
+ if (hasSectionRef () != Other.hasSectionRef ())
221
+ return hasSectionRef () > Other.hasSectionRef ();
222
+
223
+ // Compare allocatable input sections by their address.
224
+ if (getAddress () != Other.getAddress ())
225
+ return getAddress () < Other.getAddress ();
226
+ if (getAddress () && getSize () != Other.getSize ())
227
+ return getSize () < Other.getSize ();
228
+
229
+ // Code before data.
230
+ if (isText () != Other.isText ())
231
+ return isText () > Other.isText ();
232
+
233
+ // Read-only before writable.
234
+ if (isReadOnly () != Other.isReadOnly ())
235
+ return isReadOnly () > Other.isReadOnly ();
236
+
237
+ // BSS at the end.
238
+ if (isBSS () != Other.isBSS ())
239
+ return isBSS () < Other.isBSS ();
240
+
241
+ // Otherwise, preserve the order of creation.
242
+ return SectionNumber < Other.SectionNumber ;
214
243
}
215
244
216
245
// /
@@ -228,13 +257,13 @@ class BinarySection {
228
257
bool isText () const {
229
258
if (isELF ())
230
259
return (ELFFlags & ELF::SHF_EXECINSTR);
231
- return getSectionRef ().isText ();
260
+ return hasSectionRef () && getSectionRef ().isText ();
232
261
}
233
262
bool isData () const {
234
263
if (isELF ())
235
264
return (ELFType == ELF::SHT_PROGBITS &&
236
265
(ELFFlags & (ELF::SHF_ALLOC | ELF::SHF_WRITE)));
237
- return getSectionRef ().isData ();
266
+ return hasSectionRef () && getSectionRef ().isData ();
238
267
}
239
268
bool isBSS () const {
240
269
return (ELFType == ELF::SHT_NOBITS &&
0 commit comments