llvm.org GIT mirror llvm / d6f761e
llvm-mc/Mach-O: Support .o emission for .org and .align. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@79684 91177308-0d34-0410-b5e6-96231b3b80d8 Daniel Dunbar 11 years ago
4 changed file(s) with 115 addition(s) and 40 deletion(s). Raw diff Collapse all Expand all
6363 FragmentType getKind() const { return Kind; }
6464
6565 // FIXME: This should be abstract, fix sentinel.
66 virtual unsigned getMaxFileSize() const {
66 virtual uint64_t getMaxFileSize() const {
6767 assert(0 && "Invalid getMaxFileSize call !");
6868 };
6969
101101 /// @name Accessors
102102 /// @{
103103
104 unsigned getMaxFileSize() const {
104 uint64_t getMaxFileSize() const {
105105 return Contents.size();
106106 }
107107
140140 /// @name Accessors
141141 /// @{
142142
143 unsigned getMaxFileSize() const {
143 uint64_t getMaxFileSize() const {
144144 return std::max(Alignment - 1, MaxBytesToEmit);
145145 }
146146
179179 /// @name Accessors
180180 /// @{
181181
182 unsigned getMaxFileSize() const {
182 uint64_t getMaxFileSize() const {
183183 return ValueSize * Count;
184184 }
185185
202202 MCValue Offset;
203203
204204 /// Value - Value to use for filling bytes.
205 int64_t Value;
206
207 /// ValueSize - The size (in bytes) of \arg Value to use when filling.
208 unsigned ValueSize;
209
210 public:
211 MCOrgFragment(MCValue _Offset, int64_t _Value, unsigned _ValueSize,
212 MCSectionData *SD = 0)
205 int8_t Value;
206
207 public:
208 MCOrgFragment(MCValue _Offset, int8_t _Value, MCSectionData *SD = 0)
213209 : MCFragment(FT_Org, SD),
214 Offset(_Offset), Value(_Value), ValueSize(_ValueSize) {}
210 Offset(_Offset), Value(_Value) {}
215211 /// @name Accessors
216212 /// @{
217213
218 unsigned getMaxFileSize() const {
219 // FIXME
220 return 0;
214 uint64_t getMaxFileSize() const {
215 // FIXME: This doesn't make much sense.
216 return ~UINT64_C(0);
221217 }
222218
223219 MCValue getOffset() const { return Offset; }
224220
225 int64_t getValue() const { return Value; }
226
227 unsigned getValueSize() const { return ValueSize; }
221 uint8_t getValue() const { return Value; }
228222
229223 /// @}
230224
77 //===----------------------------------------------------------------------===//
88
99 #include "llvm/MC/MCAssembler.h"
10
11 #include "llvm/ADT/Twine.h"
1012 #include "llvm/MC/MCSectionMachO.h"
1113 #include "llvm/Support/DataTypes.h"
1214 #include "llvm/Support/ErrorHandling.h"
231233 }
232234
233235 void MCAssembler::LayoutSection(MCSectionData &SD) {
234 uint64_t Offset = SD.getFileOffset();
236 uint64_t FileOffset = SD.getFileOffset();
237 uint64_t SectionOffset = 0;
235238
236239 for (MCSectionData::iterator it = SD.begin(), ie = SD.end(); it != ie; ++it) {
237240 MCFragment &F = *it;
238 F.setFileOffset(Offset);
239 F.setFileSize(F.getMaxFileSize());
240 Offset += F.getFileSize();
241
242 F.setFileOffset(FileOffset);
243
244 // Evaluate fragment size.
245 switch (F.getKind()) {
246 case MCFragment::FT_Align: {
247 MCAlignFragment &AF = cast(F);
248
249 uint64_t AlignedOffset =
250 RoundUpToAlignment(SectionOffset, AF.getAlignment());
251 uint64_t PaddingBytes = AlignedOffset - SectionOffset;
252
253 if (PaddingBytes > AF.getMaxBytesToEmit())
254 AF.setFileSize(0);
255 else
256 AF.setFileSize(PaddingBytes);
257 break;
258 }
259
260 case MCFragment::FT_Data:
261 case MCFragment::FT_Fill:
262 F.setFileSize(F.getMaxFileSize());
263 break;
264
265 case MCFragment::FT_Org: {
266 MCOrgFragment &OF = cast(F);
267
268 if (!OF.getOffset().isAbsolute())
269 llvm_unreachable("FIXME: Not yet implemented!");
270 uint64_t OrgOffset = OF.getOffset().getConstant();
271
272 // FIXME: We need a way to communicate this error.
273 if (OrgOffset < SectionOffset)
274 llvm_report_error("invalid .org offset '" + Twine(OrgOffset) +
275 "' (section offset '" + Twine(SectionOffset) + "'");
276
277 F.setFileSize(OrgOffset - SectionOffset);
278 break;
279 }
280 }
281
282 FileOffset += F.getFileSize();
283 SectionOffset += F.getFileSize();
241284 }
242285
243286 // FIXME: Pad section?
244 SD.setFileSize(Offset - SD.getFileOffset());
287 SD.setFileSize(FileOffset - SD.getFileOffset());
245288 }
246289
247290 /// WriteFileData - Write the \arg F data to the output file.
250293 uint64_t Start = OS.tell();
251294 (void) Start;
252295
296 assert(F.getFileOffset() == Start && "Invalid file offset!");
297
253298 // FIXME: Embed in fragments instead?
254299 switch (F.getKind()) {
255 default:
256 assert(0 && "Invalid section kind!");
300 case MCFragment::FT_Align: {
301 MCAlignFragment &AF = cast(F);
302 uint64_t Count = AF.getFileSize() / AF.getValueSize();
303
304 // FIXME: This error shouldn't actually occur (the front end should emit
305 // multiple .align directives to enforce the semantics it wants), but is
306 // severe enough that we want to report it. How to handle this?
307 if (Count * AF.getValueSize() != AF.getFileSize())
308 llvm_report_error("undefined .align directive, value size '" +
309 Twine(AF.getValueSize()) +
310 "' is not a divisor of padding size '" +
311 Twine(AF.getFileSize()) + "'");
312
313 for (uint64_t i = 0; i != Count; ++i) {
314 switch (AF.getValueSize()) {
315 default:
316 assert(0 && "Invalid size!");
317 case 1: MOW.Write8 (uint8_t (AF.getValue())); break;
318 case 2: MOW.Write16(uint16_t(AF.getValue())); break;
319 case 4: MOW.Write32(uint32_t(AF.getValue())); break;
320 case 8: MOW.Write64(uint64_t(AF.getValue())); break;
321 }
322 }
323 break;
324 }
257325
258326 case MCFragment::FT_Data:
259327 OS << cast(F).getContents().str();
260328 break;
261329
262 case MCFragment::FT_Align:
263 llvm_unreachable("FIXME: Not yet implemented!");
264
265330 case MCFragment::FT_Fill: {
266331 MCFillFragment &FF = cast(F);
267332
268333 if (!FF.getValue().isAbsolute())
269334 llvm_unreachable("FIXME: Not yet implemented!");
335 int64_t Value = FF.getValue().getConstant();
270336
271337 for (uint64_t i = 0, e = FF.getCount(); i != e; ++i) {
272338 switch (FF.getValueSize()) {
273339 default:
274340 assert(0 && "Invalid size!");
275 case 1: MOW.Write8 (uint8_t (FF.getValue().getConstant())); break;
276 case 2: MOW.Write16(uint16_t(FF.getValue().getConstant())); break;
277 case 4: MOW.Write32(uint32_t(FF.getValue().getConstant())); break;
278 case 8: MOW.Write64(uint64_t(FF.getValue().getConstant())); break;
341 case 1: MOW.Write8 (uint8_t (Value)); break;
342 case 2: MOW.Write16(uint16_t(Value)); break;
343 case 4: MOW.Write32(uint32_t(Value)); break;
344 case 8: MOW.Write64(uint64_t(Value)); break;
279345 }
280346 }
281347 break;
282348 }
283349
284 case MCFragment::FT_Org:
285 llvm_unreachable("FIXME: Not yet implemented!");
350 case MCFragment::FT_Org: {
351 MCOrgFragment &OF = cast(F);
352
353 for (uint64_t i = 0, e = OF.getFileSize(); i != e; ++i)
354 MOW.Write8(uint8_t(OF.getValue()));
355
356 break;
357 }
286358 }
287359
288360 assert(OS.tell() - Start == F.getFileSize());
149149 void MCMachOStreamer::EmitValueToAlignment(unsigned ByteAlignment,
150150 int64_t Value, unsigned ValueSize,
151151 unsigned MaxBytesToEmit) {
152 if (MaxBytesToEmit == 0)
153 MaxBytesToEmit = ByteAlignment;
152154 new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit,
153155 CurSectionData);
154156
159161
160162 void MCMachOStreamer::EmitValueToOffset(const MCValue &Offset,
161163 unsigned char Value) {
162 new MCOrgFragment(Offset, Value, 1, CurSectionData);
164 new MCOrgFragment(Offset, Value, CurSectionData);
163165 }
164166
165167 void MCMachOStreamer::EmitInstruction(const MCInst &Inst) {
55 .short 0xABCD
66 .long 0xABCDABCD
77 .quad 0xABCDABCDABCDABCD
8 .org 30
9 .long 0xF000 // 34
10 .p2align 3, 0xAB // 40 (0xAB * 6)
11 .short 0 // 42
12 .p2alignw 3, 0xABCD // 48 (0xABCD * 2)
13 .short 0 // 50
14 .p2alignw 3, 0xABCD, 5 // 50
815
916 // CHECK: ('cputype', 7)
1017 // CHECK: ('cpusubtype', 3)
1825 // CHECK: ('size', 192)
1926 // CHECK: ('segment_name', '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
2027 // CHECK: ('vm_addr', 0)
21 // CHECK: ('vm_size', 20)
28 // CHECK: ('vm_size', 50)
2229 // CHECK: ('file_offset', 220)
23 // CHECK: ('file_size', 20)
30 // CHECK: ('file_size', 50)
2431 // CHECK: ('maxprot', 7)
2532 // CHECK: ('initprot', 7)
2633 // CHECK: ('num_sections', 2)
4350 // CHECK: (('section_name', '__data\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
4451 // CHECK: ('segment_name', '__DATA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
4552 // CHECK: ('address', 0)
46 // CHECK: ('size', 20)
53 // CHECK: ('size', 50)
4754 // CHECK: ('offset', 220)
48 // CHECK: ('alignment', 0)
55 // CHECK: ('alignment', 3)
4956 // CHECK: ('reloc_offset', 0)
5057 // CHECK: ('num_reloc', 0)
5158 // CHECK: ('flags', 0x0)