~louis/ubuntu/trusty/clamav/lp799623_fix_logrotate

« back to all changes in this revision

Viewing changes to libclamav/c++/llvm/lib/MC/MCAssembler.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Scott Kitterman
  • Date: 2010-03-12 11:30:04 UTC
  • mfrom: (0.41.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20100312113004-b0fop4bkycszdd0z
Tags: 0.96~rc1+dfsg-0ubuntu1
* New upstream RC - FFE (LP: #537636):
  - Add OfficialDatabaseOnly option to clamav-base.postinst.in
  - Add LocalSocketGroup option to clamav-base.postinst.in
  - Add LocalSocketMode option to clamav-base.postinst.in
  - Add CrossFilesystems option to clamav-base.postinst.in
  - Add ClamukoScannerCount option to clamav-base.postinst.in
  - Add BytecodeSecurity opiton to clamav-base.postinst.in
  - Add DetectionStatsHostID option to clamav-freshclam.postinst.in
  - Add Bytecode option to clamav-freshclam.postinst.in
  - Add MilterSocketGroup option to clamav-milter.postinst.in
  - Add MilterSocketMode option to clamav-milter.postinst.in
  - Add ReportHostname option to clamav-milter.postinst.in
  - Bump libclamav SO version to 6.1.0 in libclamav6.install
  - Drop clamdmon from clamav.examples (no longer shipped by upstream)
  - Drop libclamav.a from libclamav-dev.install (not built by upstream)
  - Update SO version for lintian override for libclamav6
  - Add new Bytecode Testing Tool, usr/bin/clambc, to clamav.install
  - Add build-depends on python and python-setuptools for new test suite
  - Update debian/copyright for the embedded copy of llvm (using the system
    llvm is not currently feasible)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//===- lib/MC/MCAssembler.cpp - Assembler Backend Implementation ----------===//
 
2
//
 
3
//                     The LLVM Compiler Infrastructure
 
4
//
 
5
// This file is distributed under the University of Illinois Open Source
 
6
// License. See LICENSE.TXT for details.
 
7
//
 
8
//===----------------------------------------------------------------------===//
 
9
 
 
10
#define DEBUG_TYPE "assembler"
 
11
#include "llvm/MC/MCAssembler.h"
 
12
#include "llvm/MC/MCExpr.h"
 
13
#include "llvm/MC/MCSectionMachO.h"
 
14
#include "llvm/MC/MCSymbol.h"
 
15
#include "llvm/MC/MCValue.h"
 
16
#include "llvm/ADT/DenseMap.h"
 
17
#include "llvm/ADT/SmallString.h"
 
18
#include "llvm/ADT/Statistic.h"
 
19
#include "llvm/ADT/StringExtras.h"
 
20
#include "llvm/ADT/StringMap.h"
 
21
#include "llvm/ADT/Twine.h"
 
22
#include "llvm/Support/ErrorHandling.h"
 
23
#include "llvm/Support/MachO.h"
 
24
#include "llvm/Support/raw_ostream.h"
 
25
#include "llvm/Support/Debug.h"
 
26
 
 
27
// FIXME: Gross.
 
28
#include "../Target/X86/X86FixupKinds.h"
 
29
 
 
30
#include <vector>
 
31
using namespace llvm;
 
32
 
 
33
class MachObjectWriter;
 
34
 
 
35
STATISTIC(EmittedFragments, "Number of emitted assembler fragments");
 
36
 
 
37
// FIXME FIXME FIXME: There are number of places in this file where we convert
 
38
// what is a 64-bit assembler value used for computation into a value in the
 
39
// object file, which may truncate it. We should detect that truncation where
 
40
// invalid and report errors back.
 
41
 
 
42
static void WriteFileData(raw_ostream &OS, const MCSectionData &SD,
 
43
                          MachObjectWriter &MOW);
 
44
 
 
45
static uint64_t WriteNopData(uint64_t Count, MachObjectWriter &MOW);
 
46
 
 
47
/// isVirtualSection - Check if this is a section which does not actually exist
 
48
/// in the object file.
 
49
static bool isVirtualSection(const MCSection &Section) {
 
50
  // FIXME: Lame.
 
51
  const MCSectionMachO &SMO = static_cast<const MCSectionMachO&>(Section);
 
52
  unsigned Type = SMO.getTypeAndAttributes() & MCSectionMachO::SECTION_TYPE;
 
53
  return (Type == MCSectionMachO::S_ZEROFILL);
 
54
}
 
55
 
 
56
static unsigned getFixupKindLog2Size(unsigned Kind) {
 
57
  switch (Kind) {
 
58
  default: llvm_unreachable("invalid fixup kind!");
 
59
  case X86::reloc_pcrel_1byte:
 
60
  case FK_Data_1: return 0;
 
61
  case FK_Data_2: return 1;
 
62
  case X86::reloc_pcrel_4byte:
 
63
  case X86::reloc_riprel_4byte:
 
64
  case FK_Data_4: return 2;
 
65
  case FK_Data_8: return 3;
 
66
  }
 
67
}
 
68
 
 
69
static bool isFixupKindPCRel(unsigned Kind) {
 
70
  switch (Kind) {
 
71
  default:
 
72
    return false;
 
73
  case X86::reloc_pcrel_1byte:
 
74
  case X86::reloc_pcrel_4byte:
 
75
  case X86::reloc_riprel_4byte:
 
76
    return true;
 
77
  }
 
78
}
 
79
 
 
80
class MachObjectWriter {
 
81
  // See <mach-o/loader.h>.
 
82
  enum {
 
83
    Header_Magic32 = 0xFEEDFACE,
 
84
    Header_Magic64 = 0xFEEDFACF
 
85
  };
 
86
 
 
87
  static const unsigned Header32Size = 28;
 
88
  static const unsigned Header64Size = 32;
 
89
  static const unsigned SegmentLoadCommand32Size = 56;
 
90
  static const unsigned Section32Size = 68;
 
91
  static const unsigned SymtabLoadCommandSize = 24;
 
92
  static const unsigned DysymtabLoadCommandSize = 80;
 
93
  static const unsigned Nlist32Size = 12;
 
94
  static const unsigned RelocationInfoSize = 8;
 
95
 
 
96
  enum HeaderFileType {
 
97
    HFT_Object = 0x1
 
98
  };
 
99
 
 
100
  enum HeaderFlags {
 
101
    HF_SubsectionsViaSymbols = 0x2000
 
102
  };
 
103
 
 
104
  enum LoadCommandType {
 
105
    LCT_Segment = 0x1,
 
106
    LCT_Symtab = 0x2,
 
107
    LCT_Dysymtab = 0xb
 
108
  };
 
109
 
 
110
  // See <mach-o/nlist.h>.
 
111
  enum SymbolTypeType {
 
112
    STT_Undefined = 0x00,
 
113
    STT_Absolute  = 0x02,
 
114
    STT_Section   = 0x0e
 
115
  };
 
116
 
 
117
  enum SymbolTypeFlags {
 
118
    // If any of these bits are set, then the entry is a stab entry number (see
 
119
    // <mach-o/stab.h>. Otherwise the other masks apply.
 
120
    STF_StabsEntryMask = 0xe0,
 
121
 
 
122
    STF_TypeMask       = 0x0e,
 
123
    STF_External       = 0x01,
 
124
    STF_PrivateExtern  = 0x10
 
125
  };
 
126
 
 
127
  /// IndirectSymbolFlags - Flags for encoding special values in the indirect
 
128
  /// symbol entry.
 
129
  enum IndirectSymbolFlags {
 
130
    ISF_Local    = 0x80000000,
 
131
    ISF_Absolute = 0x40000000
 
132
  };
 
133
 
 
134
  /// RelocationFlags - Special flags for addresses.
 
135
  enum RelocationFlags {
 
136
    RF_Scattered = 0x80000000
 
137
  };
 
138
 
 
139
  enum RelocationInfoType {
 
140
    RIT_Vanilla             = 0,
 
141
    RIT_Pair                = 1,
 
142
    RIT_Difference          = 2,
 
143
    RIT_PreboundLazyPointer = 3,
 
144
    RIT_LocalDifference     = 4
 
145
  };
 
146
 
 
147
  /// MachSymbolData - Helper struct for containing some precomputed information
 
148
  /// on symbols.
 
149
  struct MachSymbolData {
 
150
    MCSymbolData *SymbolData;
 
151
    uint64_t StringIndex;
 
152
    uint8_t SectionIndex;
 
153
 
 
154
    // Support lexicographic sorting.
 
155
    bool operator<(const MachSymbolData &RHS) const {
 
156
      const std::string &Name = SymbolData->getSymbol().getName();
 
157
      return Name < RHS.SymbolData->getSymbol().getName();
 
158
    }
 
159
  };
 
160
 
 
161
  raw_ostream &OS;
 
162
  bool IsLSB;
 
163
 
 
164
public:
 
165
  MachObjectWriter(raw_ostream &_OS, bool _IsLSB = true)
 
166
    : OS(_OS), IsLSB(_IsLSB) {
 
167
  }
 
168
 
 
169
  /// @name Helper Methods
 
170
  /// @{
 
171
 
 
172
  void Write8(uint8_t Value) {
 
173
    OS << char(Value);
 
174
  }
 
175
 
 
176
  void Write16(uint16_t Value) {
 
177
    if (IsLSB) {
 
178
      Write8(uint8_t(Value >> 0));
 
179
      Write8(uint8_t(Value >> 8));
 
180
    } else {
 
181
      Write8(uint8_t(Value >> 8));
 
182
      Write8(uint8_t(Value >> 0));
 
183
    }
 
184
  }
 
185
 
 
186
  void Write32(uint32_t Value) {
 
187
    if (IsLSB) {
 
188
      Write16(uint16_t(Value >> 0));
 
189
      Write16(uint16_t(Value >> 16));
 
190
    } else {
 
191
      Write16(uint16_t(Value >> 16));
 
192
      Write16(uint16_t(Value >> 0));
 
193
    }
 
194
  }
 
195
 
 
196
  void Write64(uint64_t Value) {
 
197
    if (IsLSB) {
 
198
      Write32(uint32_t(Value >> 0));
 
199
      Write32(uint32_t(Value >> 32));
 
200
    } else {
 
201
      Write32(uint32_t(Value >> 32));
 
202
      Write32(uint32_t(Value >> 0));
 
203
    }
 
204
  }
 
205
 
 
206
  void WriteZeros(unsigned N) {
 
207
    const char Zeros[16] = { 0 };
 
208
 
 
209
    for (unsigned i = 0, e = N / 16; i != e; ++i)
 
210
      OS << StringRef(Zeros, 16);
 
211
 
 
212
    OS << StringRef(Zeros, N % 16);
 
213
  }
 
214
 
 
215
  void WriteString(StringRef Str, unsigned ZeroFillSize = 0) {
 
216
    OS << Str;
 
217
    if (ZeroFillSize)
 
218
      WriteZeros(ZeroFillSize - Str.size());
 
219
  }
 
220
 
 
221
  /// @}
 
222
 
 
223
  void WriteHeader32(unsigned NumLoadCommands, unsigned LoadCommandsSize,
 
224
                     bool SubsectionsViaSymbols) {
 
225
    uint32_t Flags = 0;
 
226
 
 
227
    if (SubsectionsViaSymbols)
 
228
      Flags |= HF_SubsectionsViaSymbols;
 
229
 
 
230
    // struct mach_header (28 bytes)
 
231
 
 
232
    uint64_t Start = OS.tell();
 
233
    (void) Start;
 
234
 
 
235
    Write32(Header_Magic32);
 
236
 
 
237
    // FIXME: Support cputype.
 
238
    Write32(MachO::CPUTypeI386);
 
239
    // FIXME: Support cpusubtype.
 
240
    Write32(MachO::CPUSubType_I386_ALL);
 
241
    Write32(HFT_Object);
 
242
    Write32(NumLoadCommands);    // Object files have a single load command, the
 
243
                                 // segment.
 
244
    Write32(LoadCommandsSize);
 
245
    Write32(Flags);
 
246
 
 
247
    assert(OS.tell() - Start == Header32Size);
 
248
  }
 
249
 
 
250
  /// WriteSegmentLoadCommand32 - Write a 32-bit segment load command.
 
251
  ///
 
252
  /// \arg NumSections - The number of sections in this segment.
 
253
  /// \arg SectionDataSize - The total size of the sections.
 
254
  void WriteSegmentLoadCommand32(unsigned NumSections,
 
255
                                 uint64_t VMSize,
 
256
                                 uint64_t SectionDataStartOffset,
 
257
                                 uint64_t SectionDataSize) {
 
258
    // struct segment_command (56 bytes)
 
259
 
 
260
    uint64_t Start = OS.tell();
 
261
    (void) Start;
 
262
 
 
263
    Write32(LCT_Segment);
 
264
    Write32(SegmentLoadCommand32Size + NumSections * Section32Size);
 
265
 
 
266
    WriteString("", 16);
 
267
    Write32(0); // vmaddr
 
268
    Write32(VMSize); // vmsize
 
269
    Write32(SectionDataStartOffset); // file offset
 
270
    Write32(SectionDataSize); // file size
 
271
    Write32(0x7); // maxprot
 
272
    Write32(0x7); // initprot
 
273
    Write32(NumSections);
 
274
    Write32(0); // flags
 
275
 
 
276
    assert(OS.tell() - Start == SegmentLoadCommand32Size);
 
277
  }
 
278
 
 
279
  void WriteSection32(const MCSectionData &SD, uint64_t FileOffset,
 
280
                      uint64_t RelocationsStart, unsigned NumRelocations) {
 
281
    // The offset is unused for virtual sections.
 
282
    if (isVirtualSection(SD.getSection())) {
 
283
      assert(SD.getFileSize() == 0 && "Invalid file size!");
 
284
      FileOffset = 0;
 
285
    }
 
286
 
 
287
    // struct section (68 bytes)
 
288
 
 
289
    uint64_t Start = OS.tell();
 
290
    (void) Start;
 
291
 
 
292
    // FIXME: cast<> support!
 
293
    const MCSectionMachO &Section =
 
294
      static_cast<const MCSectionMachO&>(SD.getSection());
 
295
    WriteString(Section.getSectionName(), 16);
 
296
    WriteString(Section.getSegmentName(), 16);
 
297
    Write32(SD.getAddress()); // address
 
298
    Write32(SD.getSize()); // size
 
299
    Write32(FileOffset);
 
300
 
 
301
    unsigned Flags = Section.getTypeAndAttributes();
 
302
    if (SD.hasInstructions())
 
303
      Flags |= MCSectionMachO::S_ATTR_SOME_INSTRUCTIONS;
 
304
 
 
305
    assert(isPowerOf2_32(SD.getAlignment()) && "Invalid alignment!");
 
306
    Write32(Log2_32(SD.getAlignment()));
 
307
    Write32(NumRelocations ? RelocationsStart : 0);
 
308
    Write32(NumRelocations);
 
309
    Write32(Flags);
 
310
    Write32(0); // reserved1
 
311
    Write32(Section.getStubSize()); // reserved2
 
312
 
 
313
    assert(OS.tell() - Start == Section32Size);
 
314
  }
 
315
 
 
316
  void WriteSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols,
 
317
                              uint32_t StringTableOffset,
 
318
                              uint32_t StringTableSize) {
 
319
    // struct symtab_command (24 bytes)
 
320
 
 
321
    uint64_t Start = OS.tell();
 
322
    (void) Start;
 
323
 
 
324
    Write32(LCT_Symtab);
 
325
    Write32(SymtabLoadCommandSize);
 
326
    Write32(SymbolOffset);
 
327
    Write32(NumSymbols);
 
328
    Write32(StringTableOffset);
 
329
    Write32(StringTableSize);
 
330
 
 
331
    assert(OS.tell() - Start == SymtabLoadCommandSize);
 
332
  }
 
333
 
 
334
  void WriteDysymtabLoadCommand(uint32_t FirstLocalSymbol,
 
335
                                uint32_t NumLocalSymbols,
 
336
                                uint32_t FirstExternalSymbol,
 
337
                                uint32_t NumExternalSymbols,
 
338
                                uint32_t FirstUndefinedSymbol,
 
339
                                uint32_t NumUndefinedSymbols,
 
340
                                uint32_t IndirectSymbolOffset,
 
341
                                uint32_t NumIndirectSymbols) {
 
342
    // struct dysymtab_command (80 bytes)
 
343
 
 
344
    uint64_t Start = OS.tell();
 
345
    (void) Start;
 
346
 
 
347
    Write32(LCT_Dysymtab);
 
348
    Write32(DysymtabLoadCommandSize);
 
349
    Write32(FirstLocalSymbol);
 
350
    Write32(NumLocalSymbols);
 
351
    Write32(FirstExternalSymbol);
 
352
    Write32(NumExternalSymbols);
 
353
    Write32(FirstUndefinedSymbol);
 
354
    Write32(NumUndefinedSymbols);
 
355
    Write32(0); // tocoff
 
356
    Write32(0); // ntoc
 
357
    Write32(0); // modtaboff
 
358
    Write32(0); // nmodtab
 
359
    Write32(0); // extrefsymoff
 
360
    Write32(0); // nextrefsyms
 
361
    Write32(IndirectSymbolOffset);
 
362
    Write32(NumIndirectSymbols);
 
363
    Write32(0); // extreloff
 
364
    Write32(0); // nextrel
 
365
    Write32(0); // locreloff
 
366
    Write32(0); // nlocrel
 
367
 
 
368
    assert(OS.tell() - Start == DysymtabLoadCommandSize);
 
369
  }
 
370
 
 
371
  void WriteNlist32(MachSymbolData &MSD) {
 
372
    MCSymbolData &Data = *MSD.SymbolData;
 
373
    const MCSymbol &Symbol = Data.getSymbol();
 
374
    uint8_t Type = 0;
 
375
    uint16_t Flags = Data.getFlags();
 
376
    uint32_t Address = 0;
 
377
 
 
378
    // Set the N_TYPE bits. See <mach-o/nlist.h>.
 
379
    //
 
380
    // FIXME: Are the prebound or indirect fields possible here?
 
381
    if (Symbol.isUndefined())
 
382
      Type = STT_Undefined;
 
383
    else if (Symbol.isAbsolute())
 
384
      Type = STT_Absolute;
 
385
    else
 
386
      Type = STT_Section;
 
387
 
 
388
    // FIXME: Set STAB bits.
 
389
 
 
390
    if (Data.isPrivateExtern())
 
391
      Type |= STF_PrivateExtern;
 
392
 
 
393
    // Set external bit.
 
394
    if (Data.isExternal() || Symbol.isUndefined())
 
395
      Type |= STF_External;
 
396
 
 
397
    // Compute the symbol address.
 
398
    if (Symbol.isDefined()) {
 
399
      if (Symbol.isAbsolute()) {
 
400
        llvm_unreachable("FIXME: Not yet implemented!");
 
401
      } else {
 
402
        Address = Data.getFragment()->getAddress() + Data.getOffset();
 
403
      }
 
404
    } else if (Data.isCommon()) {
 
405
      // Common symbols are encoded with the size in the address
 
406
      // field, and their alignment in the flags.
 
407
      Address = Data.getCommonSize();
 
408
 
 
409
      // Common alignment is packed into the 'desc' bits.
 
410
      if (unsigned Align = Data.getCommonAlignment()) {
 
411
        unsigned Log2Size = Log2_32(Align);
 
412
        assert((1U << Log2Size) == Align && "Invalid 'common' alignment!");
 
413
        if (Log2Size > 15)
 
414
          llvm_report_error("invalid 'common' alignment '" +
 
415
                            Twine(Align) + "'");
 
416
        // FIXME: Keep this mask with the SymbolFlags enumeration.
 
417
        Flags = (Flags & 0xF0FF) | (Log2Size << 8);
 
418
      }
 
419
    }
 
420
 
 
421
    // struct nlist (12 bytes)
 
422
 
 
423
    Write32(MSD.StringIndex);
 
424
    Write8(Type);
 
425
    Write8(MSD.SectionIndex);
 
426
 
 
427
    // The Mach-O streamer uses the lowest 16-bits of the flags for the 'desc'
 
428
    // value.
 
429
    Write16(Flags);
 
430
    Write32(Address);
 
431
  }
 
432
 
 
433
  struct MachRelocationEntry {
 
434
    uint32_t Word0;
 
435
    uint32_t Word1;
 
436
  };
 
437
  void ComputeScatteredRelocationInfo(MCAssembler &Asm, MCFragment &Fragment,
 
438
                                      MCAsmFixup &Fixup,
 
439
                                      const MCValue &Target,
 
440
                             DenseMap<const MCSymbol*,MCSymbolData*> &SymbolMap,
 
441
                                     std::vector<MachRelocationEntry> &Relocs) {
 
442
    uint32_t Address = Fragment.getOffset() + Fixup.Offset;
 
443
    unsigned IsPCRel = 0;
 
444
    unsigned Log2Size = getFixupKindLog2Size(Fixup.Kind);
 
445
    unsigned Type = RIT_Vanilla;
 
446
 
 
447
    // See <reloc.h>.
 
448
    const MCSymbol *A = Target.getSymA();
 
449
    MCSymbolData *SD = SymbolMap.lookup(A);
 
450
    uint32_t Value = SD->getFragment()->getAddress() + SD->getOffset();
 
451
    uint32_t Value2 = 0;
 
452
 
 
453
    if (const MCSymbol *B = Target.getSymB()) {
 
454
      Type = RIT_LocalDifference;
 
455
 
 
456
      MCSymbolData *SD = SymbolMap.lookup(B);
 
457
      Value2 = SD->getFragment()->getAddress() + SD->getOffset();
 
458
    }
 
459
 
 
460
    // The value which goes in the fixup is current value of the expression.
 
461
    Fixup.FixedValue = Value - Value2 + Target.getConstant();
 
462
    if (isFixupKindPCRel(Fixup.Kind)) {
 
463
      Fixup.FixedValue -= Address;
 
464
      IsPCRel = 1;
 
465
    }
 
466
 
 
467
    MachRelocationEntry MRE;
 
468
    MRE.Word0 = ((Address   <<  0) |
 
469
                 (Type      << 24) |
 
470
                 (Log2Size  << 28) |
 
471
                 (IsPCRel   << 30) |
 
472
                 RF_Scattered);
 
473
    MRE.Word1 = Value;
 
474
    Relocs.push_back(MRE);
 
475
 
 
476
    if (Type == RIT_LocalDifference) {
 
477
      Type = RIT_Pair;
 
478
 
 
479
      MachRelocationEntry MRE;
 
480
      MRE.Word0 = ((0         <<  0) |
 
481
                   (Type      << 24) |
 
482
                   (Log2Size  << 28) |
 
483
                   (0   << 30) |
 
484
                   RF_Scattered);
 
485
      MRE.Word1 = Value2;
 
486
      Relocs.push_back(MRE);
 
487
    }
 
488
  }
 
489
 
 
490
  void ComputeRelocationInfo(MCAssembler &Asm, MCDataFragment &Fragment,
 
491
                             MCAsmFixup &Fixup,
 
492
                             DenseMap<const MCSymbol*,MCSymbolData*> &SymbolMap,
 
493
                             std::vector<MachRelocationEntry> &Relocs) {
 
494
    MCValue Target;
 
495
    if (!Fixup.Value->EvaluateAsRelocatable(Target))
 
496
      llvm_report_error("expected relocatable expression");
 
497
 
 
498
    // If this is a difference or a local symbol plus an offset, then we need a
 
499
    // scattered relocation entry.
 
500
    if (Target.getSymB() ||
 
501
        (Target.getSymA() && !Target.getSymA()->isUndefined() &&
 
502
         Target.getConstant()))
 
503
      return ComputeScatteredRelocationInfo(Asm, Fragment, Fixup, Target,
 
504
                                            SymbolMap, Relocs);
 
505
 
 
506
    // See <reloc.h>.
 
507
    uint32_t Address = Fragment.getOffset() + Fixup.Offset;
 
508
    uint32_t Value = 0;
 
509
    unsigned Index = 0;
 
510
    unsigned IsPCRel = 0;
 
511
    unsigned Log2Size = getFixupKindLog2Size(Fixup.Kind);
 
512
    unsigned IsExtern = 0;
 
513
    unsigned Type = 0;
 
514
 
 
515
    if (Target.isAbsolute()) { // constant
 
516
      // SymbolNum of 0 indicates the absolute section.
 
517
      //
 
518
      // FIXME: When is this generated?
 
519
      Type = RIT_Vanilla;
 
520
      Value = 0;
 
521
      llvm_unreachable("FIXME: Not yet implemented!");
 
522
    } else {
 
523
      const MCSymbol *Symbol = Target.getSymA();
 
524
      MCSymbolData *SD = SymbolMap.lookup(Symbol);
 
525
 
 
526
      if (Symbol->isUndefined()) {
 
527
        IsExtern = 1;
 
528
        Index = SD->getIndex();
 
529
        Value = 0;
 
530
      } else {
 
531
        // The index is the section ordinal.
 
532
        //
 
533
        // FIXME: O(N)
 
534
        Index = 1;
 
535
        MCAssembler::iterator it = Asm.begin(), ie = Asm.end();
 
536
        for (; it != ie; ++it, ++Index)
 
537
          if (&*it == SD->getFragment()->getParent())
 
538
            break;
 
539
        assert(it != ie && "Unable to find section index!");
 
540
        Value = SD->getFragment()->getAddress() + SD->getOffset();
 
541
      }
 
542
 
 
543
      Type = RIT_Vanilla;
 
544
    }
 
545
 
 
546
    // The value which goes in the fixup is current value of the expression.
 
547
    Fixup.FixedValue = Value + Target.getConstant();
 
548
 
 
549
    if (isFixupKindPCRel(Fixup.Kind)) {
 
550
      Fixup.FixedValue -= Address;
 
551
      IsPCRel = 1;
 
552
    }
 
553
 
 
554
    // struct relocation_info (8 bytes)
 
555
    MachRelocationEntry MRE;
 
556
    MRE.Word0 = Address;
 
557
    MRE.Word1 = ((Index     <<  0) |
 
558
                 (IsPCRel   << 24) |
 
559
                 (Log2Size  << 25) |
 
560
                 (IsExtern  << 27) |
 
561
                 (Type      << 28));
 
562
    Relocs.push_back(MRE);
 
563
  }
 
564
 
 
565
  void BindIndirectSymbols(MCAssembler &Asm,
 
566
                           DenseMap<const MCSymbol*,MCSymbolData*> &SymbolMap) {
 
567
    // This is the point where 'as' creates actual symbols for indirect symbols
 
568
    // (in the following two passes). It would be easier for us to do this
 
569
    // sooner when we see the attribute, but that makes getting the order in the
 
570
    // symbol table much more complicated than it is worth.
 
571
    //
 
572
    // FIXME: Revisit this when the dust settles.
 
573
 
 
574
    // Bind non lazy symbol pointers first.
 
575
    for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(),
 
576
           ie = Asm.indirect_symbol_end(); it != ie; ++it) {
 
577
      // FIXME: cast<> support!
 
578
      const MCSectionMachO &Section =
 
579
        static_cast<const MCSectionMachO&>(it->SectionData->getSection());
 
580
 
 
581
      unsigned Type =
 
582
        Section.getTypeAndAttributes() & MCSectionMachO::SECTION_TYPE;
 
583
      if (Type != MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS)
 
584
        continue;
 
585
 
 
586
      MCSymbolData *&Entry = SymbolMap[it->Symbol];
 
587
      if (!Entry)
 
588
        Entry = new MCSymbolData(*it->Symbol, 0, 0, &Asm);
 
589
    }
 
590
 
 
591
    // Then lazy symbol pointers and symbol stubs.
 
592
    for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(),
 
593
           ie = Asm.indirect_symbol_end(); it != ie; ++it) {
 
594
      // FIXME: cast<> support!
 
595
      const MCSectionMachO &Section =
 
596
        static_cast<const MCSectionMachO&>(it->SectionData->getSection());
 
597
 
 
598
      unsigned Type =
 
599
        Section.getTypeAndAttributes() & MCSectionMachO::SECTION_TYPE;
 
600
      if (Type != MCSectionMachO::S_LAZY_SYMBOL_POINTERS &&
 
601
          Type != MCSectionMachO::S_SYMBOL_STUBS)
 
602
        continue;
 
603
 
 
604
      MCSymbolData *&Entry = SymbolMap[it->Symbol];
 
605
      if (!Entry) {
 
606
        Entry = new MCSymbolData(*it->Symbol, 0, 0, &Asm);
 
607
 
 
608
        // Set the symbol type to undefined lazy, but only on construction.
 
609
        //
 
610
        // FIXME: Do not hardcode.
 
611
        Entry->setFlags(Entry->getFlags() | 0x0001);
 
612
      }
 
613
    }
 
614
  }
 
615
 
 
616
  /// ComputeSymbolTable - Compute the symbol table data
 
617
  ///
 
618
  /// \param StringTable [out] - The string table data.
 
619
  /// \param StringIndexMap [out] - Map from symbol names to offsets in the
 
620
  /// string table.
 
621
  void ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable,
 
622
                          std::vector<MachSymbolData> &LocalSymbolData,
 
623
                          std::vector<MachSymbolData> &ExternalSymbolData,
 
624
                          std::vector<MachSymbolData> &UndefinedSymbolData) {
 
625
    // Build section lookup table.
 
626
    DenseMap<const MCSection*, uint8_t> SectionIndexMap;
 
627
    unsigned Index = 1;
 
628
    for (MCAssembler::iterator it = Asm.begin(),
 
629
           ie = Asm.end(); it != ie; ++it, ++Index)
 
630
      SectionIndexMap[&it->getSection()] = Index;
 
631
    assert(Index <= 256 && "Too many sections!");
 
632
 
 
633
    // Index 0 is always the empty string.
 
634
    StringMap<uint64_t> StringIndexMap;
 
635
    StringTable += '\x00';
 
636
 
 
637
    // Build the symbol arrays and the string table, but only for non-local
 
638
    // symbols.
 
639
    //
 
640
    // The particular order that we collect the symbols and create the string
 
641
    // table, then sort the symbols is chosen to match 'as'. Even though it
 
642
    // doesn't matter for correctness, this is important for letting us diff .o
 
643
    // files.
 
644
    for (MCAssembler::symbol_iterator it = Asm.symbol_begin(),
 
645
           ie = Asm.symbol_end(); it != ie; ++it) {
 
646
      const MCSymbol &Symbol = it->getSymbol();
 
647
 
 
648
      // Ignore assembler temporaries.
 
649
      if (it->getSymbol().isTemporary())
 
650
        continue;
 
651
 
 
652
      if (!it->isExternal() && !Symbol.isUndefined())
 
653
        continue;
 
654
 
 
655
      uint64_t &Entry = StringIndexMap[Symbol.getName()];
 
656
      if (!Entry) {
 
657
        Entry = StringTable.size();
 
658
        StringTable += Symbol.getName();
 
659
        StringTable += '\x00';
 
660
      }
 
661
 
 
662
      MachSymbolData MSD;
 
663
      MSD.SymbolData = it;
 
664
      MSD.StringIndex = Entry;
 
665
 
 
666
      if (Symbol.isUndefined()) {
 
667
        MSD.SectionIndex = 0;
 
668
        UndefinedSymbolData.push_back(MSD);
 
669
      } else if (Symbol.isAbsolute()) {
 
670
        MSD.SectionIndex = 0;
 
671
        ExternalSymbolData.push_back(MSD);
 
672
      } else {
 
673
        MSD.SectionIndex = SectionIndexMap.lookup(&Symbol.getSection());
 
674
        assert(MSD.SectionIndex && "Invalid section index!");
 
675
        ExternalSymbolData.push_back(MSD);
 
676
      }
 
677
    }
 
678
 
 
679
    // Now add the data for local symbols.
 
680
    for (MCAssembler::symbol_iterator it = Asm.symbol_begin(),
 
681
           ie = Asm.symbol_end(); it != ie; ++it) {
 
682
      const MCSymbol &Symbol = it->getSymbol();
 
683
 
 
684
      // Ignore assembler temporaries.
 
685
      if (it->getSymbol().isTemporary())
 
686
        continue;
 
687
 
 
688
      if (it->isExternal() || Symbol.isUndefined())
 
689
        continue;
 
690
 
 
691
      uint64_t &Entry = StringIndexMap[Symbol.getName()];
 
692
      if (!Entry) {
 
693
        Entry = StringTable.size();
 
694
        StringTable += Symbol.getName();
 
695
        StringTable += '\x00';
 
696
      }
 
697
 
 
698
      MachSymbolData MSD;
 
699
      MSD.SymbolData = it;
 
700
      MSD.StringIndex = Entry;
 
701
 
 
702
      if (Symbol.isAbsolute()) {
 
703
        MSD.SectionIndex = 0;
 
704
        LocalSymbolData.push_back(MSD);
 
705
      } else {
 
706
        MSD.SectionIndex = SectionIndexMap.lookup(&Symbol.getSection());
 
707
        assert(MSD.SectionIndex && "Invalid section index!");
 
708
        LocalSymbolData.push_back(MSD);
 
709
      }
 
710
    }
 
711
 
 
712
    // External and undefined symbols are required to be in lexicographic order.
 
713
    std::sort(ExternalSymbolData.begin(), ExternalSymbolData.end());
 
714
    std::sort(UndefinedSymbolData.begin(), UndefinedSymbolData.end());
 
715
 
 
716
    // Set the symbol indices.
 
717
    Index = 0;
 
718
    for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i)
 
719
      LocalSymbolData[i].SymbolData->setIndex(Index++);
 
720
    for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i)
 
721
      ExternalSymbolData[i].SymbolData->setIndex(Index++);
 
722
    for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i)
 
723
      UndefinedSymbolData[i].SymbolData->setIndex(Index++);
 
724
 
 
725
    // The string table is padded to a multiple of 4.
 
726
    while (StringTable.size() % 4)
 
727
      StringTable += '\x00';
 
728
  }
 
729
 
 
730
  void WriteObject(MCAssembler &Asm) {
 
731
    unsigned NumSections = Asm.size();
 
732
 
 
733
    // Compute the symbol -> symbol data map.
 
734
    //
 
735
    // FIXME: This should not be here.
 
736
    DenseMap<const MCSymbol*, MCSymbolData *> SymbolMap;
 
737
    for (MCAssembler::symbol_iterator it = Asm.symbol_begin(),
 
738
           ie = Asm.symbol_end(); it != ie; ++it)
 
739
      SymbolMap[&it->getSymbol()] = it;
 
740
 
 
741
    // Create symbol data for any indirect symbols.
 
742
    BindIndirectSymbols(Asm, SymbolMap);
 
743
 
 
744
    // Compute symbol table information.
 
745
    SmallString<256> StringTable;
 
746
    std::vector<MachSymbolData> LocalSymbolData;
 
747
    std::vector<MachSymbolData> ExternalSymbolData;
 
748
    std::vector<MachSymbolData> UndefinedSymbolData;
 
749
    unsigned NumSymbols = Asm.symbol_size();
 
750
 
 
751
    // No symbol table command is written if there are no symbols.
 
752
    if (NumSymbols)
 
753
      ComputeSymbolTable(Asm, StringTable, LocalSymbolData, ExternalSymbolData,
 
754
                         UndefinedSymbolData);
 
755
 
 
756
    // The section data starts after the header, the segment load command (and
 
757
    // section headers) and the symbol table.
 
758
    unsigned NumLoadCommands = 1;
 
759
    uint64_t LoadCommandsSize =
 
760
      SegmentLoadCommand32Size + NumSections * Section32Size;
 
761
 
 
762
    // Add the symbol table load command sizes, if used.
 
763
    if (NumSymbols) {
 
764
      NumLoadCommands += 2;
 
765
      LoadCommandsSize += SymtabLoadCommandSize + DysymtabLoadCommandSize;
 
766
    }
 
767
 
 
768
    // Compute the total size of the section data, as well as its file size and
 
769
    // vm size.
 
770
    uint64_t SectionDataStart = Header32Size + LoadCommandsSize;
 
771
    uint64_t SectionDataSize = 0;
 
772
    uint64_t SectionDataFileSize = 0;
 
773
    uint64_t VMSize = 0;
 
774
    for (MCAssembler::iterator it = Asm.begin(),
 
775
           ie = Asm.end(); it != ie; ++it) {
 
776
      MCSectionData &SD = *it;
 
777
 
 
778
      VMSize = std::max(VMSize, SD.getAddress() + SD.getSize());
 
779
 
 
780
      if (isVirtualSection(SD.getSection()))
 
781
        continue;
 
782
 
 
783
      SectionDataSize = std::max(SectionDataSize,
 
784
                                 SD.getAddress() + SD.getSize());
 
785
      SectionDataFileSize = std::max(SectionDataFileSize,
 
786
                                     SD.getAddress() + SD.getFileSize());
 
787
    }
 
788
 
 
789
    // The section data is padded to 4 bytes.
 
790
    //
 
791
    // FIXME: Is this machine dependent?
 
792
    unsigned SectionDataPadding = OffsetToAlignment(SectionDataFileSize, 4);
 
793
    SectionDataFileSize += SectionDataPadding;
 
794
 
 
795
    // Write the prolog, starting with the header and load command...
 
796
    WriteHeader32(NumLoadCommands, LoadCommandsSize,
 
797
                  Asm.getSubsectionsViaSymbols());
 
798
    WriteSegmentLoadCommand32(NumSections, VMSize,
 
799
                              SectionDataStart, SectionDataSize);
 
800
 
 
801
    // ... and then the section headers.
 
802
    //
 
803
    // We also compute the section relocations while we do this. Note that
 
804
    // computing relocation info will also update the fixup to have the correct
 
805
    // value; this will overwrite the appropriate data in the fragment when it
 
806
    // is written.
 
807
    std::vector<MachRelocationEntry> RelocInfos;
 
808
    uint64_t RelocTableEnd = SectionDataStart + SectionDataFileSize;
 
809
    for (MCAssembler::iterator it = Asm.begin(),
 
810
           ie = Asm.end(); it != ie; ++it) {
 
811
      MCSectionData &SD = *it;
 
812
 
 
813
      // The assembler writes relocations in the reverse order they were seen.
 
814
      //
 
815
      // FIXME: It is probably more complicated than this.
 
816
      unsigned NumRelocsStart = RelocInfos.size();
 
817
      for (MCSectionData::reverse_iterator it2 = SD.rbegin(),
 
818
             ie2 = SD.rend(); it2 != ie2; ++it2)
 
819
        if (MCDataFragment *DF = dyn_cast<MCDataFragment>(&*it2))
 
820
          for (unsigned i = 0, e = DF->fixup_size(); i != e; ++i)
 
821
            ComputeRelocationInfo(Asm, *DF, DF->getFixups()[e - i - 1],
 
822
                                  SymbolMap, RelocInfos);
 
823
 
 
824
      unsigned NumRelocs = RelocInfos.size() - NumRelocsStart;
 
825
      uint64_t SectionStart = SectionDataStart + SD.getAddress();
 
826
      WriteSection32(SD, SectionStart, RelocTableEnd, NumRelocs);
 
827
      RelocTableEnd += NumRelocs * RelocationInfoSize;
 
828
    }
 
829
 
 
830
    // Write the symbol table load command, if used.
 
831
    if (NumSymbols) {
 
832
      unsigned FirstLocalSymbol = 0;
 
833
      unsigned NumLocalSymbols = LocalSymbolData.size();
 
834
      unsigned FirstExternalSymbol = FirstLocalSymbol + NumLocalSymbols;
 
835
      unsigned NumExternalSymbols = ExternalSymbolData.size();
 
836
      unsigned FirstUndefinedSymbol = FirstExternalSymbol + NumExternalSymbols;
 
837
      unsigned NumUndefinedSymbols = UndefinedSymbolData.size();
 
838
      unsigned NumIndirectSymbols = Asm.indirect_symbol_size();
 
839
      unsigned NumSymTabSymbols =
 
840
        NumLocalSymbols + NumExternalSymbols + NumUndefinedSymbols;
 
841
      uint64_t IndirectSymbolSize = NumIndirectSymbols * 4;
 
842
      uint64_t IndirectSymbolOffset = 0;
 
843
 
 
844
      // If used, the indirect symbols are written after the section data.
 
845
      if (NumIndirectSymbols)
 
846
        IndirectSymbolOffset = RelocTableEnd;
 
847
 
 
848
      // The symbol table is written after the indirect symbol data.
 
849
      uint64_t SymbolTableOffset = RelocTableEnd + IndirectSymbolSize;
 
850
 
 
851
      // The string table is written after symbol table.
 
852
      uint64_t StringTableOffset =
 
853
        SymbolTableOffset + NumSymTabSymbols * Nlist32Size;
 
854
      WriteSymtabLoadCommand(SymbolTableOffset, NumSymTabSymbols,
 
855
                             StringTableOffset, StringTable.size());
 
856
 
 
857
      WriteDysymtabLoadCommand(FirstLocalSymbol, NumLocalSymbols,
 
858
                               FirstExternalSymbol, NumExternalSymbols,
 
859
                               FirstUndefinedSymbol, NumUndefinedSymbols,
 
860
                               IndirectSymbolOffset, NumIndirectSymbols);
 
861
    }
 
862
 
 
863
    // Write the actual section data.
 
864
    for (MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); it != ie; ++it)
 
865
      WriteFileData(OS, *it, *this);
 
866
 
 
867
    // Write the extra padding.
 
868
    WriteZeros(SectionDataPadding);
 
869
 
 
870
    // Write the relocation entries.
 
871
    for (unsigned i = 0, e = RelocInfos.size(); i != e; ++i) {
 
872
      Write32(RelocInfos[i].Word0);
 
873
      Write32(RelocInfos[i].Word1);
 
874
    }
 
875
 
 
876
    // Write the symbol table data, if used.
 
877
    if (NumSymbols) {
 
878
      // Write the indirect symbol entries.
 
879
      for (MCAssembler::indirect_symbol_iterator
 
880
             it = Asm.indirect_symbol_begin(),
 
881
             ie = Asm.indirect_symbol_end(); it != ie; ++it) {
 
882
        // Indirect symbols in the non lazy symbol pointer section have some
 
883
        // special handling.
 
884
        const MCSectionMachO &Section =
 
885
          static_cast<const MCSectionMachO&>(it->SectionData->getSection());
 
886
        unsigned Type =
 
887
          Section.getTypeAndAttributes() & MCSectionMachO::SECTION_TYPE;
 
888
        if (Type == MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS) {
 
889
          // If this symbol is defined and internal, mark it as such.
 
890
          if (it->Symbol->isDefined() &&
 
891
              !SymbolMap.lookup(it->Symbol)->isExternal()) {
 
892
            uint32_t Flags = ISF_Local;
 
893
            if (it->Symbol->isAbsolute())
 
894
              Flags |= ISF_Absolute;
 
895
            Write32(Flags);
 
896
            continue;
 
897
          }
 
898
        }
 
899
 
 
900
        Write32(SymbolMap[it->Symbol]->getIndex());
 
901
      }
 
902
 
 
903
      // FIXME: Check that offsets match computed ones.
 
904
 
 
905
      // Write the symbol table entries.
 
906
      for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i)
 
907
        WriteNlist32(LocalSymbolData[i]);
 
908
      for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i)
 
909
        WriteNlist32(ExternalSymbolData[i]);
 
910
      for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i)
 
911
        WriteNlist32(UndefinedSymbolData[i]);
 
912
 
 
913
      // Write the string table.
 
914
      OS << StringTable.str();
 
915
    }
 
916
  }
 
917
 
 
918
  void ApplyFixup(const MCAsmFixup &Fixup, MCDataFragment &DF) {
 
919
    unsigned Size = 1 << getFixupKindLog2Size(Fixup.Kind);
 
920
 
 
921
    // FIXME: Endianness assumption.
 
922
    assert(Fixup.Offset + Size <= DF.getContents().size() &&
 
923
           "Invalid fixup offset!");
 
924
    for (unsigned i = 0; i != Size; ++i)
 
925
      DF.getContents()[Fixup.Offset + i] = uint8_t(Fixup.FixedValue >> (i * 8));
 
926
  }
 
927
};
 
928
 
 
929
/* *** */
 
930
 
 
931
MCFragment::MCFragment() : Kind(FragmentType(~0)) {
 
932
}
 
933
 
 
934
MCFragment::MCFragment(FragmentType _Kind, MCSectionData *_Parent)
 
935
  : Kind(_Kind),
 
936
    Parent(_Parent),
 
937
    FileSize(~UINT64_C(0))
 
938
{
 
939
  if (Parent)
 
940
    Parent->getFragmentList().push_back(this);
 
941
}
 
942
 
 
943
MCFragment::~MCFragment() {
 
944
}
 
945
 
 
946
uint64_t MCFragment::getAddress() const {
 
947
  assert(getParent() && "Missing Section!");
 
948
  return getParent()->getAddress() + Offset;
 
949
}
 
950
 
 
951
/* *** */
 
952
 
 
953
MCSectionData::MCSectionData() : Section(0) {}
 
954
 
 
955
MCSectionData::MCSectionData(const MCSection &_Section, MCAssembler *A)
 
956
  : Section(&_Section),
 
957
    Alignment(1),
 
958
    Address(~UINT64_C(0)),
 
959
    Size(~UINT64_C(0)),
 
960
    FileSize(~UINT64_C(0)),
 
961
    HasInstructions(false)
 
962
{
 
963
  if (A)
 
964
    A->getSectionList().push_back(this);
 
965
}
 
966
 
 
967
/* *** */
 
968
 
 
969
MCSymbolData::MCSymbolData() : Symbol(0) {}
 
970
 
 
971
MCSymbolData::MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment,
 
972
                           uint64_t _Offset, MCAssembler *A)
 
973
  : Symbol(&_Symbol), Fragment(_Fragment), Offset(_Offset),
 
974
    IsExternal(false), IsPrivateExtern(false),
 
975
    CommonSize(0), CommonAlign(0), Flags(0), Index(0)
 
976
{
 
977
  if (A)
 
978
    A->getSymbolList().push_back(this);
 
979
}
 
980
 
 
981
/* *** */
 
982
 
 
983
MCAssembler::MCAssembler(MCContext &_Context, raw_ostream &_OS)
 
984
  : Context(_Context), OS(_OS), SubsectionsViaSymbols(false)
 
985
{
 
986
}
 
987
 
 
988
MCAssembler::~MCAssembler() {
 
989
}
 
990
 
 
991
void MCAssembler::LayoutSection(MCSectionData &SD) {
 
992
  uint64_t Address = SD.getAddress();
 
993
 
 
994
  for (MCSectionData::iterator it = SD.begin(), ie = SD.end(); it != ie; ++it) {
 
995
    MCFragment &F = *it;
 
996
 
 
997
    F.setOffset(Address - SD.getAddress());
 
998
 
 
999
    // Evaluate fragment size.
 
1000
    switch (F.getKind()) {
 
1001
    case MCFragment::FT_Align: {
 
1002
      MCAlignFragment &AF = cast<MCAlignFragment>(F);
 
1003
 
 
1004
      uint64_t Size = OffsetToAlignment(Address, AF.getAlignment());
 
1005
      if (Size > AF.getMaxBytesToEmit())
 
1006
        AF.setFileSize(0);
 
1007
      else
 
1008
        AF.setFileSize(Size);
 
1009
      break;
 
1010
    }
 
1011
 
 
1012
    case MCFragment::FT_Data:
 
1013
    case MCFragment::FT_Fill:
 
1014
      F.setFileSize(F.getMaxFileSize());
 
1015
      break;
 
1016
 
 
1017
    case MCFragment::FT_Org: {
 
1018
      MCOrgFragment &OF = cast<MCOrgFragment>(F);
 
1019
 
 
1020
      MCValue Target;
 
1021
      if (!OF.getOffset().EvaluateAsRelocatable(Target))
 
1022
        llvm_report_error("expected relocatable expression");
 
1023
 
 
1024
      if (!Target.isAbsolute())
 
1025
        llvm_unreachable("FIXME: Not yet implemented!");
 
1026
      uint64_t OrgOffset = Target.getConstant();
 
1027
      uint64_t Offset = Address - SD.getAddress();
 
1028
 
 
1029
      // FIXME: We need a way to communicate this error.
 
1030
      if (OrgOffset < Offset)
 
1031
        llvm_report_error("invalid .org offset '" + Twine(OrgOffset) +
 
1032
                          "' (at offset '" + Twine(Offset) + "'");
 
1033
 
 
1034
      F.setFileSize(OrgOffset - Offset);
 
1035
      break;
 
1036
    }
 
1037
 
 
1038
    case MCFragment::FT_ZeroFill: {
 
1039
      MCZeroFillFragment &ZFF = cast<MCZeroFillFragment>(F);
 
1040
 
 
1041
      // Align the fragment offset; it is safe to adjust the offset freely since
 
1042
      // this is only in virtual sections.
 
1043
      uint64_t Aligned = RoundUpToAlignment(Address, ZFF.getAlignment());
 
1044
      F.setOffset(Aligned - SD.getAddress());
 
1045
 
 
1046
      // FIXME: This is misnamed.
 
1047
      F.setFileSize(ZFF.getSize());
 
1048
      break;
 
1049
    }
 
1050
    }
 
1051
 
 
1052
    Address += F.getFileSize();
 
1053
  }
 
1054
 
 
1055
  // Set the section sizes.
 
1056
  SD.setSize(Address - SD.getAddress());
 
1057
  if (isVirtualSection(SD.getSection()))
 
1058
    SD.setFileSize(0);
 
1059
  else
 
1060
    SD.setFileSize(Address - SD.getAddress());
 
1061
}
 
1062
 
 
1063
/// WriteNopData - Write optimal nops to the output file for the \arg Count
 
1064
/// bytes.  This returns the number of bytes written.  It may return 0 if
 
1065
/// the \arg Count is more than the maximum optimal nops.
 
1066
///
 
1067
/// FIXME this is X86 32-bit specific and should move to a better place.
 
1068
static uint64_t WriteNopData(uint64_t Count, MachObjectWriter &MOW) {
 
1069
  static const uint8_t Nops[16][16] = {
 
1070
    // nop
 
1071
    {0x90},
 
1072
    // xchg %ax,%ax
 
1073
    {0x66, 0x90},
 
1074
    // nopl (%[re]ax)
 
1075
    {0x0f, 0x1f, 0x00},
 
1076
    // nopl 0(%[re]ax)
 
1077
    {0x0f, 0x1f, 0x40, 0x00},
 
1078
    // nopl 0(%[re]ax,%[re]ax,1)
 
1079
    {0x0f, 0x1f, 0x44, 0x00, 0x00},
 
1080
    // nopw 0(%[re]ax,%[re]ax,1)
 
1081
    {0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00},
 
1082
    // nopl 0L(%[re]ax)
 
1083
    {0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00},
 
1084
    // nopl 0L(%[re]ax,%[re]ax,1)
 
1085
    {0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
 
1086
    // nopw 0L(%[re]ax,%[re]ax,1)
 
1087
    {0x66, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
 
1088
    // nopw %cs:0L(%[re]ax,%[re]ax,1)
 
1089
    {0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
 
1090
    // nopl 0(%[re]ax,%[re]ax,1)
 
1091
    // nopw 0(%[re]ax,%[re]ax,1)
 
1092
    {0x0f, 0x1f, 0x44, 0x00, 0x00,
 
1093
     0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00},
 
1094
    // nopw 0(%[re]ax,%[re]ax,1)
 
1095
    // nopw 0(%[re]ax,%[re]ax,1)
 
1096
    {0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00,
 
1097
     0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00},
 
1098
    // nopw 0(%[re]ax,%[re]ax,1)
 
1099
    // nopl 0L(%[re]ax) */
 
1100
    {0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00,
 
1101
     0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00},
 
1102
    // nopl 0L(%[re]ax)
 
1103
    // nopl 0L(%[re]ax)
 
1104
    {0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00,
 
1105
     0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00},
 
1106
    // nopl 0L(%[re]ax)
 
1107
    // nopl 0L(%[re]ax,%[re]ax,1)
 
1108
    {0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00,
 
1109
     0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}
 
1110
  };
 
1111
 
 
1112
  if (Count > 15)
 
1113
    return 0;
 
1114
 
 
1115
  for (uint64_t i = 0; i < Count; i++)
 
1116
    MOW.Write8 (uint8_t(Nops[Count - 1][i]));
 
1117
 
 
1118
  return Count;
 
1119
}
 
1120
 
 
1121
/// WriteFileData - Write the \arg F data to the output file.
 
1122
static void WriteFileData(raw_ostream &OS, const MCFragment &F,
 
1123
                          MachObjectWriter &MOW) {
 
1124
  uint64_t Start = OS.tell();
 
1125
  (void) Start;
 
1126
 
 
1127
  ++EmittedFragments;
 
1128
 
 
1129
  // FIXME: Embed in fragments instead?
 
1130
  switch (F.getKind()) {
 
1131
  case MCFragment::FT_Align: {
 
1132
    MCAlignFragment &AF = cast<MCAlignFragment>(F);
 
1133
    uint64_t Count = AF.getFileSize() / AF.getValueSize();
 
1134
 
 
1135
    // FIXME: This error shouldn't actually occur (the front end should emit
 
1136
    // multiple .align directives to enforce the semantics it wants), but is
 
1137
    // severe enough that we want to report it. How to handle this?
 
1138
    if (Count * AF.getValueSize() != AF.getFileSize())
 
1139
      llvm_report_error("undefined .align directive, value size '" +
 
1140
                        Twine(AF.getValueSize()) +
 
1141
                        "' is not a divisor of padding size '" +
 
1142
                        Twine(AF.getFileSize()) + "'");
 
1143
 
 
1144
    // See if we are aligning with nops, and if so do that first to try to fill
 
1145
    // the Count bytes.  Then if that did not fill any bytes or there are any
 
1146
    // bytes left to fill use the the Value and ValueSize to fill the rest.
 
1147
    if (AF.getEmitNops()) {
 
1148
      uint64_t NopByteCount = WriteNopData(Count, MOW);
 
1149
      Count -= NopByteCount;
 
1150
    }
 
1151
 
 
1152
    for (uint64_t i = 0; i != Count; ++i) {
 
1153
      switch (AF.getValueSize()) {
 
1154
      default:
 
1155
        assert(0 && "Invalid size!");
 
1156
      case 1: MOW.Write8 (uint8_t (AF.getValue())); break;
 
1157
      case 2: MOW.Write16(uint16_t(AF.getValue())); break;
 
1158
      case 4: MOW.Write32(uint32_t(AF.getValue())); break;
 
1159
      case 8: MOW.Write64(uint64_t(AF.getValue())); break;
 
1160
      }
 
1161
    }
 
1162
    break;
 
1163
  }
 
1164
 
 
1165
  case MCFragment::FT_Data: {
 
1166
    MCDataFragment &DF = cast<MCDataFragment>(F);
 
1167
 
 
1168
    // Apply the fixups.
 
1169
    //
 
1170
    // FIXME: Move elsewhere.
 
1171
    for (MCDataFragment::const_fixup_iterator it = DF.fixup_begin(),
 
1172
           ie = DF.fixup_end(); it != ie; ++it)
 
1173
      MOW.ApplyFixup(*it, DF);
 
1174
 
 
1175
    OS << cast<MCDataFragment>(F).getContents().str();
 
1176
    break;
 
1177
  }
 
1178
 
 
1179
  case MCFragment::FT_Fill: {
 
1180
    MCFillFragment &FF = cast<MCFillFragment>(F);
 
1181
    for (uint64_t i = 0, e = FF.getCount(); i != e; ++i) {
 
1182
      switch (FF.getValueSize()) {
 
1183
      default:
 
1184
        assert(0 && "Invalid size!");
 
1185
      case 1: MOW.Write8 (uint8_t (FF.getValue())); break;
 
1186
      case 2: MOW.Write16(uint16_t(FF.getValue())); break;
 
1187
      case 4: MOW.Write32(uint32_t(FF.getValue())); break;
 
1188
      case 8: MOW.Write64(uint64_t(FF.getValue())); break;
 
1189
      }
 
1190
    }
 
1191
    break;
 
1192
  }
 
1193
 
 
1194
  case MCFragment::FT_Org: {
 
1195
    MCOrgFragment &OF = cast<MCOrgFragment>(F);
 
1196
 
 
1197
    for (uint64_t i = 0, e = OF.getFileSize(); i != e; ++i)
 
1198
      MOW.Write8(uint8_t(OF.getValue()));
 
1199
 
 
1200
    break;
 
1201
  }
 
1202
 
 
1203
  case MCFragment::FT_ZeroFill: {
 
1204
    assert(0 && "Invalid zero fill fragment in concrete section!");
 
1205
    break;
 
1206
  }
 
1207
  }
 
1208
 
 
1209
  assert(OS.tell() - Start == F.getFileSize());
 
1210
}
 
1211
 
 
1212
/// WriteFileData - Write the \arg SD data to the output file.
 
1213
static void WriteFileData(raw_ostream &OS, const MCSectionData &SD,
 
1214
                          MachObjectWriter &MOW) {
 
1215
  // Ignore virtual sections.
 
1216
  if (isVirtualSection(SD.getSection())) {
 
1217
    assert(SD.getFileSize() == 0);
 
1218
    return;
 
1219
  }
 
1220
 
 
1221
  uint64_t Start = OS.tell();
 
1222
  (void) Start;
 
1223
 
 
1224
  for (MCSectionData::const_iterator it = SD.begin(),
 
1225
         ie = SD.end(); it != ie; ++it)
 
1226
    WriteFileData(OS, *it, MOW);
 
1227
 
 
1228
  // Add section padding.
 
1229
  assert(SD.getFileSize() >= SD.getSize() && "Invalid section sizes!");
 
1230
  MOW.WriteZeros(SD.getFileSize() - SD.getSize());
 
1231
 
 
1232
  assert(OS.tell() - Start == SD.getFileSize());
 
1233
}
 
1234
 
 
1235
void MCAssembler::Finish() {
 
1236
  DEBUG_WITH_TYPE("mc-dump", {
 
1237
      llvm::errs() << "assembler backend - pre-layout\n--\n";
 
1238
      dump(); });
 
1239
 
 
1240
  // Layout the concrete sections and fragments.
 
1241
  uint64_t Address = 0;
 
1242
  MCSectionData *Prev = 0;
 
1243
  for (iterator it = begin(), ie = end(); it != ie; ++it) {
 
1244
    MCSectionData &SD = *it;
 
1245
 
 
1246
    // Skip virtual sections.
 
1247
    if (isVirtualSection(SD.getSection()))
 
1248
      continue;
 
1249
 
 
1250
    // Align this section if necessary by adding padding bytes to the previous
 
1251
    // section.
 
1252
    if (uint64_t Pad = OffsetToAlignment(Address, it->getAlignment())) {
 
1253
      assert(Prev && "Missing prev section!");
 
1254
      Prev->setFileSize(Prev->getFileSize() + Pad);
 
1255
      Address += Pad;
 
1256
    }
 
1257
 
 
1258
    // Layout the section fragments and its size.
 
1259
    SD.setAddress(Address);
 
1260
    LayoutSection(SD);
 
1261
    Address += SD.getFileSize();
 
1262
 
 
1263
    Prev = &SD;
 
1264
  }
 
1265
 
 
1266
  // Layout the virtual sections.
 
1267
  for (iterator it = begin(), ie = end(); it != ie; ++it) {
 
1268
    MCSectionData &SD = *it;
 
1269
 
 
1270
    if (!isVirtualSection(SD.getSection()))
 
1271
      continue;
 
1272
 
 
1273
    SD.setAddress(Address);
 
1274
    LayoutSection(SD);
 
1275
    Address += SD.getSize();
 
1276
  }
 
1277
 
 
1278
  DEBUG_WITH_TYPE("mc-dump", {
 
1279
      llvm::errs() << "assembler backend - post-layout\n--\n";
 
1280
      dump(); });
 
1281
 
 
1282
  // Write the object file.
 
1283
  MachObjectWriter MOW(OS);
 
1284
  MOW.WriteObject(*this);
 
1285
 
 
1286
  OS.flush();
 
1287
}
 
1288
 
 
1289
 
 
1290
// Debugging methods
 
1291
 
 
1292
namespace llvm {
 
1293
 
 
1294
raw_ostream &operator<<(raw_ostream &OS, const MCAsmFixup &AF) {
 
1295
  OS << "<MCAsmFixup" << " Offset:" << AF.Offset << " Value:" << *AF.Value
 
1296
     << " Kind:" << AF.Kind << ">";
 
1297
  return OS;
 
1298
}
 
1299
 
 
1300
}
 
1301
 
 
1302
void MCFragment::dump() {
 
1303
  raw_ostream &OS = llvm::errs();
 
1304
 
 
1305
  OS << "<MCFragment " << (void*) this << " Offset:" << Offset
 
1306
     << " FileSize:" << FileSize;
 
1307
 
 
1308
  OS << ">";
 
1309
}
 
1310
 
 
1311
void MCAlignFragment::dump() {
 
1312
  raw_ostream &OS = llvm::errs();
 
1313
 
 
1314
  OS << "<MCAlignFragment ";
 
1315
  this->MCFragment::dump();
 
1316
  OS << "\n       ";
 
1317
  OS << " Alignment:" << getAlignment()
 
1318
     << " Value:" << getValue() << " ValueSize:" << getValueSize()
 
1319
     << " MaxBytesToEmit:" << getMaxBytesToEmit() << ">";
 
1320
}
 
1321
 
 
1322
void MCDataFragment::dump() {
 
1323
  raw_ostream &OS = llvm::errs();
 
1324
 
 
1325
  OS << "<MCDataFragment ";
 
1326
  this->MCFragment::dump();
 
1327
  OS << "\n       ";
 
1328
  OS << " Contents:[";
 
1329
  for (unsigned i = 0, e = getContents().size(); i != e; ++i) {
 
1330
    if (i) OS << ",";
 
1331
    OS << hexdigit((Contents[i] >> 4) & 0xF) << hexdigit(Contents[i] & 0xF);
 
1332
  }
 
1333
  OS << "] (" << getContents().size() << " bytes)";
 
1334
 
 
1335
  if (!getFixups().empty()) {
 
1336
    OS << ",\n       ";
 
1337
    OS << " Fixups:[";
 
1338
    for (fixup_iterator it = fixup_begin(), ie = fixup_end(); it != ie; ++it) {
 
1339
      if (it != fixup_begin()) OS << ",\n            ";
 
1340
      OS << *it;
 
1341
    }
 
1342
    OS << "]";
 
1343
  }
 
1344
 
 
1345
  OS << ">";
 
1346
}
 
1347
 
 
1348
void MCFillFragment::dump() {
 
1349
  raw_ostream &OS = llvm::errs();
 
1350
 
 
1351
  OS << "<MCFillFragment ";
 
1352
  this->MCFragment::dump();
 
1353
  OS << "\n       ";
 
1354
  OS << " Value:" << getValue() << " ValueSize:" << getValueSize()
 
1355
     << " Count:" << getCount() << ">";
 
1356
}
 
1357
 
 
1358
void MCOrgFragment::dump() {
 
1359
  raw_ostream &OS = llvm::errs();
 
1360
 
 
1361
  OS << "<MCOrgFragment ";
 
1362
  this->MCFragment::dump();
 
1363
  OS << "\n       ";
 
1364
  OS << " Offset:" << getOffset() << " Value:" << getValue() << ">";
 
1365
}
 
1366
 
 
1367
void MCZeroFillFragment::dump() {
 
1368
  raw_ostream &OS = llvm::errs();
 
1369
 
 
1370
  OS << "<MCZeroFillFragment ";
 
1371
  this->MCFragment::dump();
 
1372
  OS << "\n       ";
 
1373
  OS << " Size:" << getSize() << " Alignment:" << getAlignment() << ">";
 
1374
}
 
1375
 
 
1376
void MCSectionData::dump() {
 
1377
  raw_ostream &OS = llvm::errs();
 
1378
 
 
1379
  OS << "<MCSectionData";
 
1380
  OS << " Alignment:" << getAlignment() << " Address:" << Address
 
1381
     << " Size:" << Size << " FileSize:" << FileSize
 
1382
     << " Fragments:[";
 
1383
  for (iterator it = begin(), ie = end(); it != ie; ++it) {
 
1384
    if (it != begin()) OS << ",\n      ";
 
1385
    it->dump();
 
1386
  }
 
1387
  OS << "]>";
 
1388
}
 
1389
 
 
1390
void MCSymbolData::dump() {
 
1391
  raw_ostream &OS = llvm::errs();
 
1392
 
 
1393
  OS << "<MCSymbolData Symbol:" << getSymbol()
 
1394
     << " Fragment:" << getFragment() << " Offset:" << getOffset()
 
1395
     << " Flags:" << getFlags() << " Index:" << getIndex();
 
1396
  if (isCommon())
 
1397
    OS << " (common, size:" << getCommonSize()
 
1398
       << " align: " << getCommonAlignment() << ")";
 
1399
  if (isExternal())
 
1400
    OS << " (external)";
 
1401
  if (isPrivateExtern())
 
1402
    OS << " (private extern)";
 
1403
  OS << ">";
 
1404
}
 
1405
 
 
1406
void MCAssembler::dump() {
 
1407
  raw_ostream &OS = llvm::errs();
 
1408
 
 
1409
  OS << "<MCAssembler\n";
 
1410
  OS << "  Sections:[";
 
1411
  for (iterator it = begin(), ie = end(); it != ie; ++it) {
 
1412
    if (it != begin()) OS << ",\n    ";
 
1413
    it->dump();
 
1414
  }
 
1415
  OS << "],\n";
 
1416
  OS << "  Symbols:[";
 
1417
 
 
1418
  for (symbol_iterator it = symbol_begin(), ie = symbol_end(); it != ie; ++it) {
 
1419
    if (it != symbol_begin()) OS << ",\n    ";
 
1420
    it->dump();
 
1421
  }
 
1422
  OS << "]>\n";
 
1423
}