llvm.org GIT mirror llvm / d60c9c7
[yaml2obj] [MachO] Fill Segment and Section data This fills section data with 0xDEADBEEF and segment data not inside a section with 0xBAADDA7A. This results in yaml2obj generating a matching size object file. Any additional bytes in the file are zero'd. This is a starting point for populating the remaining segment data, and provides a hex viewable file that you can easily see the missing data in. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@270286 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Bieneman 3 years ago
1 changed file(s) with 61 addition(s) and 7 deletion(s). Raw diff Collapse all Expand all
2424
2525 class MachOWriter {
2626 public:
27 MachOWriter(MachOYAML::Object &Obj) : Obj(Obj) {
27 MachOWriter(MachOYAML::Object &Obj) : Obj(Obj), is64Bit(true), fileStart(0) {
2828 is64Bit = Obj.Header.magic == MachO::MH_MAGIC_64 ||
2929 Obj.Header.magic == MachO::MH_CIGAM_64;
3030 memset(reinterpret_cast(&Header64), 0,
4040 private:
4141 Error writeHeader(raw_ostream &OS);
4242 Error writeLoadCommands(raw_ostream &OS);
43 Error writeSectionData(raw_ostream &OS);
4344
4445 MachOYAML::Object &Obj;
4546 bool is64Bit;
47 uint64_t fileStart;
4648
4749 union {
4850 MachO::mach_header_64 Header64;
5153 };
5254
5355 Error MachOWriter::writeMachO(raw_ostream &OS) {
56 fileStart = OS.tell();
5457 if (auto Err = writeHeader(OS))
5558 return Err;
5659 if (auto Err = writeLoadCommands(OS))
60 return Err;
61 if (auto Err = writeSectionData(OS))
5762 return Err;
5863 return Error::success();
5964 }
147152 return writePayloadString(LC, OS);
148153 }
149154
155 void ZeroFillBytes(raw_ostream &OS, size_t Size) {
156 std::vector FillData;
157 FillData.insert(FillData.begin(), Size, 0);
158 OS.write(reinterpret_cast(FillData.data()), Size);
159 }
160
161 void Fill(raw_ostream &OS, size_t Size, uint32_t Data) {
162 std::vector FillData;
163 FillData.insert(FillData.begin(), (Size / 4) + 1, Data);
164 OS.write(reinterpret_cast(FillData.data()), Size);
165 }
166
150167 Error MachOWriter::writeLoadCommands(raw_ostream &OS) {
151168 for (auto &LC : Obj.LoadCommands) {
152169 size_t BytesWritten = 0;
175192 }
176193
177194 if (LC.ZeroPadBytes > 0) {
178 std::vector FillData;
179 FillData.insert(FillData.begin(), LC.ZeroPadBytes, 0);
180 OS.write(reinterpret_cast(FillData.data()), LC.ZeroPadBytes);
195 ZeroFillBytes(OS, LC.ZeroPadBytes);
181196 BytesWritten += LC.ZeroPadBytes;
182197 }
183198
185200 // specified test cases.
186201 auto BytesRemaining = LC.Data.load_command_data.cmdsize - BytesWritten;
187202 if (BytesRemaining > 0) {
188 std::vector FillData;
189 FillData.insert(FillData.begin(), BytesRemaining, 0);
190 OS.write(reinterpret_cast(FillData.data()), BytesRemaining);
203 ZeroFillBytes(OS, BytesRemaining);
204 }
205 }
206 return Error::success();
207 }
208
209 Error MachOWriter::writeSectionData(raw_ostream &OS) {
210 for (auto &LC : Obj.LoadCommands) {
211 switch (LC.Data.load_command_data.cmd) {
212 case MachO::LC_SEGMENT:
213 case MachO::LC_SEGMENT_64:
214 uint64_t segOff = is64Bit ? LC.Data.segment_command_64_data.fileoff
215 : LC.Data.segment_command_data.fileoff;
216
217 // Zero Fill any data between the end of the last thing we wrote and the
218 // start of this section.
219 auto currOffset = OS.tell() - fileStart;
220 if (currOffset < segOff) {
221 ZeroFillBytes(OS, segOff - currOffset);
222 }
223
224 for (auto &Sec : LC.Sections) {
225 // Zero Fill any data between the end of the last thing we wrote and the
226 // start of this section.
227 assert(OS.tell() - fileStart <= Sec.offset &&
228 "Wrote too much data somewhere, section offsets don't line up.");
229 currOffset = OS.tell() - fileStart;
230 if (currOffset < Sec.offset) {
231 ZeroFillBytes(OS, Sec.offset - currOffset);
232 }
233
234 // Fills section data with 0xDEADBEEF
235 Fill(OS, Sec.size, 0xDEADBEEFu);
236 }
237 uint64_t segSize = is64Bit ? LC.Data.segment_command_64_data.filesize
238 : LC.Data.segment_command_data.filesize;
239 currOffset = OS.tell() - fileStart;
240 if (currOffset < segOff + segSize) {
241 // Fills segment data not covered by a section with 0xBAADDA7A
242 Fill(OS, (segOff + segSize) - currOffset, 0xBAADDA7Au);
243 }
244 break;
191245 }
192246 }
193247 return Error::success();