~ubuntu-branches/ubuntu/wily/clamav/wily-proposed

« back to all changes in this revision

Viewing changes to libclamav/c++/llvm/include/llvm/MC/MCAssembler.h

  • Committer: Package Import Robot
  • Author(s): Scott Kitterman, Sebastian Andrzej Siewior, Andreas Cadhalpun, Scott Kitterman, Javier Fernández-Sanguino
  • Date: 2015-01-28 00:25:13 UTC
  • mfrom: (0.48.14 sid)
  • Revision ID: package-import@ubuntu.com-20150128002513-lil2oi74cooy4lzr
Tags: 0.98.6+dfsg-1
[ Sebastian Andrzej Siewior ]
* update "fix-ssize_t-size_t-off_t-printf-modifier", include of misc.h was
  missing but was pulled in via the systemd patch.
* Don't leak return codes from libmspack to clamav API. (Closes: #774686).

[ Andreas Cadhalpun ]
* Add patch to avoid emitting incremental progress messages when not
  outputting to a terminal. (Closes: #767350)
* Update lintian-overrides for unused-file-paragraph-in-dep5-copyright.
* clamav-base.postinst: always chown /var/log/clamav and /var/lib/clamav
  to clamav:clamav, not only on fresh installations. (Closes: #775400)
* Adapt the clamav-daemon and clamav-freshclam logrotate scripts,
  so that they correctly work under systemd.
* Move the PidFile variable from the clamd/freshclam configuration files
  to the init scripts. This makes the init scripts more robust against
  misconfiguration and avoids error messages with systemd. (Closes: #767353)
* debian/copyright: drop files from Files-Excluded only present in github
  tarballs
* Drop Workaround-a-bug-in-libc-on-Hurd.patch, because hurd got fixed.
  (see #752237)
* debian/rules: Remove useless --with-system-tommath --without-included-ltdl
  configure options.

[ Scott Kitterman ]
* Stop stripping llvm when repacking the tarball as the system llvm on some
  releases is too old to use
* New upstream bugfix release
  - Library shared object revisions.
  - Includes a patch from Sebastian Andrzej Siewior making ClamAV pid files
    compatible with systemd.
  - Fix a heap out of bounds condition with crafted Yoda's crypter files.
    This issue was discovered by Felix Groebert of the Google Security Team.
  - Fix a heap out of bounds condition with crafted mew packer files. This
    issue was discovered by Felix Groebert of the Google Security Team.
  - Fix a heap out of bounds condition with crafted upx packer files. This
    issue was discovered by Kevin Szkudlapski of Quarkslab.
  - Fix a heap out of bounds condition with crafted upack packer files. This
    issue was discovered by Sebastian Andrzej Siewior. CVE-2014-9328.
  - Compensate a crash due to incorrect compiler optimization when handling
    crafted petite packer files. This issue was discovered by Sebastian
    Andrzej Siewior.
* Update lintian override for embedded zlib to match new so version

[ Javier Fernández-Sanguino ]
* Updated Spanish Debconf template translation (Closes: #773563)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//===- MCAssembler.h - Object File Generation -------------------*- C++ -*-===//
 
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
#ifndef LLVM_MC_MCASSEMBLER_H
 
11
#define LLVM_MC_MCASSEMBLER_H
 
12
 
 
13
#include "llvm/ADT/DenseMap.h"
 
14
#include "llvm/ADT/SmallString.h"
 
15
#include "llvm/ADT/ilist.h"
 
16
#include "llvm/ADT/ilist_node.h"
 
17
#include "llvm/Support/Casting.h"
 
18
#include "llvm/MC/MCFixup.h"
 
19
#include "llvm/MC/MCInst.h"
 
20
#include "llvm/System/DataTypes.h"
 
21
#include <vector> // FIXME: Shouldn't be needed.
 
22
 
 
23
namespace llvm {
 
24
class raw_ostream;
 
25
class MCAsmLayout;
 
26
class MCAssembler;
 
27
class MCBinaryExpr;
 
28
class MCContext;
 
29
class MCCodeEmitter;
 
30
class MCExpr;
 
31
class MCFragment;
 
32
class MCObjectWriter;
 
33
class MCSection;
 
34
class MCSectionData;
 
35
class MCSymbol;
 
36
class MCSymbolData;
 
37
class MCValue;
 
38
class TargetAsmBackend;
 
39
 
 
40
class MCFragment : public ilist_node<MCFragment> {
 
41
  friend class MCAsmLayout;
 
42
 
 
43
  MCFragment(const MCFragment&);     // DO NOT IMPLEMENT
 
44
  void operator=(const MCFragment&); // DO NOT IMPLEMENT
 
45
 
 
46
public:
 
47
  enum FragmentType {
 
48
    FT_Align,
 
49
    FT_Data,
 
50
    FT_Fill,
 
51
    FT_Inst,
 
52
    FT_Org
 
53
  };
 
54
 
 
55
private:
 
56
  FragmentType Kind;
 
57
 
 
58
  /// Parent - The data for the section this fragment is in.
 
59
  MCSectionData *Parent;
 
60
 
 
61
  /// Atom - The atom this fragment is in, as represented by it's defining
 
62
  /// symbol. Atom's are only used by backends which set
 
63
  /// \see MCAsmBackend::hasReliableSymbolDifference().
 
64
  MCSymbolData *Atom;
 
65
 
 
66
  /// @name Assembler Backend Data
 
67
  /// @{
 
68
  //
 
69
  // FIXME: This could all be kept private to the assembler implementation.
 
70
 
 
71
  /// Offset - The offset of this fragment in its section. This is ~0 until
 
72
  /// initialized.
 
73
  uint64_t Offset;
 
74
 
 
75
  /// EffectiveSize - The compute size of this section. This is ~0 until
 
76
  /// initialized.
 
77
  uint64_t EffectiveSize;
 
78
 
 
79
  /// LayoutOrder - The global layout order of this fragment. This is the index
 
80
  /// across all fragments in the file, not just within the section.
 
81
  unsigned LayoutOrder;
 
82
 
 
83
  /// @}
 
84
 
 
85
protected:
 
86
  MCFragment(FragmentType _Kind, MCSectionData *_Parent = 0);
 
87
 
 
88
public:
 
89
  // Only for sentinel.
 
90
  MCFragment();
 
91
  virtual ~MCFragment();
 
92
 
 
93
  FragmentType getKind() const { return Kind; }
 
94
 
 
95
  MCSectionData *getParent() const { return Parent; }
 
96
  void setParent(MCSectionData *Value) { Parent = Value; }
 
97
 
 
98
  MCSymbolData *getAtom() const { return Atom; }
 
99
  void setAtom(MCSymbolData *Value) { Atom = Value; }
 
100
 
 
101
  unsigned getLayoutOrder() const { return LayoutOrder; }
 
102
  void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
 
103
 
 
104
  static bool classof(const MCFragment *O) { return true; }
 
105
 
 
106
  void dump();
 
107
};
 
108
 
 
109
class MCDataFragment : public MCFragment {
 
110
  SmallString<32> Contents;
 
111
 
 
112
  /// Fixups - The list of fixups in this fragment.
 
113
  std::vector<MCFixup> Fixups;
 
114
 
 
115
public:
 
116
  typedef std::vector<MCFixup>::const_iterator const_fixup_iterator;
 
117
  typedef std::vector<MCFixup>::iterator fixup_iterator;
 
118
 
 
119
public:
 
120
  MCDataFragment(MCSectionData *SD = 0) : MCFragment(FT_Data, SD) {}
 
121
 
 
122
  /// @name Accessors
 
123
  /// @{
 
124
 
 
125
  SmallString<32> &getContents() { return Contents; }
 
126
  const SmallString<32> &getContents() const { return Contents; }
 
127
 
 
128
  /// @}
 
129
  /// @name Fixup Access
 
130
  /// @{
 
131
 
 
132
  void addFixup(MCFixup Fixup) {
 
133
    // Enforce invariant that fixups are in offset order.
 
134
    assert((Fixups.empty() || Fixup.getOffset() > Fixups.back().getOffset()) &&
 
135
           "Fixups must be added in order!");
 
136
    Fixups.push_back(Fixup);
 
137
  }
 
138
 
 
139
  std::vector<MCFixup> &getFixups() { return Fixups; }
 
140
  const std::vector<MCFixup> &getFixups() const { return Fixups; }
 
141
 
 
142
  fixup_iterator fixup_begin() { return Fixups.begin(); }
 
143
  const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
 
144
 
 
145
  fixup_iterator fixup_end() {return Fixups.end();}
 
146
  const_fixup_iterator fixup_end() const {return Fixups.end();}
 
147
 
 
148
  size_t fixup_size() const { return Fixups.size(); }
 
149
 
 
150
  /// @}
 
151
 
 
152
  static bool classof(const MCFragment *F) {
 
153
    return F->getKind() == MCFragment::FT_Data;
 
154
  }
 
155
  static bool classof(const MCDataFragment *) { return true; }
 
156
};
 
157
 
 
158
// FIXME: This current incarnation of MCInstFragment doesn't make much sense, as
 
159
// it is almost entirely a duplicate of MCDataFragment. If we decide to stick
 
160
// with this approach (as opposed to making MCInstFragment a very light weight
 
161
// object with just the MCInst and a code size, then we should just change
 
162
// MCDataFragment to have an optional MCInst at its end.
 
163
class MCInstFragment : public MCFragment {
 
164
  /// Inst - The instruction this is a fragment for.
 
165
  MCInst Inst;
 
166
 
 
167
  /// Code - Binary data for the currently encoded instruction.
 
168
  SmallString<8> Code;
 
169
 
 
170
  /// Fixups - The list of fixups in this fragment.
 
171
  SmallVector<MCFixup, 1> Fixups;
 
172
 
 
173
public:
 
174
  typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator;
 
175
  typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator;
 
176
 
 
177
public:
 
178
  MCInstFragment(MCInst _Inst, MCSectionData *SD = 0)
 
179
    : MCFragment(FT_Inst, SD), Inst(_Inst) {
 
180
  }
 
181
 
 
182
  /// @name Accessors
 
183
  /// @{
 
184
 
 
185
  SmallVectorImpl<char> &getCode() { return Code; }
 
186
  const SmallVectorImpl<char> &getCode() const { return Code; }
 
187
 
 
188
  unsigned getInstSize() const { return Code.size(); }
 
189
 
 
190
  MCInst &getInst() { return Inst; }
 
191
  const MCInst &getInst() const { return Inst; }
 
192
 
 
193
  void setInst(MCInst Value) { Inst = Value; }
 
194
 
 
195
  /// @}
 
196
  /// @name Fixup Access
 
197
  /// @{
 
198
 
 
199
  SmallVectorImpl<MCFixup> &getFixups() { return Fixups; }
 
200
  const SmallVectorImpl<MCFixup> &getFixups() const { return Fixups; }
 
201
 
 
202
  fixup_iterator fixup_begin() { return Fixups.begin(); }
 
203
  const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
 
204
 
 
205
  fixup_iterator fixup_end() {return Fixups.end();}
 
206
  const_fixup_iterator fixup_end() const {return Fixups.end();}
 
207
 
 
208
  size_t fixup_size() const { return Fixups.size(); }
 
209
 
 
210
  /// @}
 
211
 
 
212
  static bool classof(const MCFragment *F) {
 
213
    return F->getKind() == MCFragment::FT_Inst;
 
214
  }
 
215
  static bool classof(const MCInstFragment *) { return true; }
 
216
};
 
217
 
 
218
class MCAlignFragment : public MCFragment {
 
219
  /// Alignment - The alignment to ensure, in bytes.
 
220
  unsigned Alignment;
 
221
 
 
222
  /// Value - Value to use for filling padding bytes.
 
223
  int64_t Value;
 
224
 
 
225
  /// ValueSize - The size of the integer (in bytes) of \arg Value.
 
226
  unsigned ValueSize;
 
227
 
 
228
  /// MaxBytesToEmit - The maximum number of bytes to emit; if the alignment
 
229
  /// cannot be satisfied in this width then this fragment is ignored.
 
230
  unsigned MaxBytesToEmit;
 
231
 
 
232
  /// EmitNops - Flag to indicate that (optimal) NOPs should be emitted instead
 
233
  /// of using the provided value. The exact interpretation of this flag is
 
234
  /// target dependent.
 
235
  bool EmitNops : 1;
 
236
 
 
237
  /// OnlyAlignAddress - Flag to indicate that this align is only used to adjust
 
238
  /// the address space size of a section and that it should not be included as
 
239
  /// part of the section size. This flag can only be used on the last fragment
 
240
  /// in a section.
 
241
  bool OnlyAlignAddress : 1;
 
242
 
 
243
public:
 
244
  MCAlignFragment(unsigned _Alignment, int64_t _Value, unsigned _ValueSize,
 
245
                  unsigned _MaxBytesToEmit, MCSectionData *SD = 0)
 
246
    : MCFragment(FT_Align, SD), Alignment(_Alignment),
 
247
      Value(_Value),ValueSize(_ValueSize),
 
248
      MaxBytesToEmit(_MaxBytesToEmit), EmitNops(false),
 
249
      OnlyAlignAddress(false) {}
 
250
 
 
251
  /// @name Accessors
 
252
  /// @{
 
253
 
 
254
  unsigned getAlignment() const { return Alignment; }
 
255
 
 
256
  int64_t getValue() const { return Value; }
 
257
 
 
258
  unsigned getValueSize() const { return ValueSize; }
 
259
 
 
260
  unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; }
 
261
 
 
262
  bool hasEmitNops() const { return EmitNops; }
 
263
  void setEmitNops(bool Value) { EmitNops = Value; }
 
264
 
 
265
  bool hasOnlyAlignAddress() const { return OnlyAlignAddress; }
 
266
  void setOnlyAlignAddress(bool Value) { OnlyAlignAddress = Value; }
 
267
 
 
268
  /// @}
 
269
 
 
270
  static bool classof(const MCFragment *F) {
 
271
    return F->getKind() == MCFragment::FT_Align;
 
272
  }
 
273
  static bool classof(const MCAlignFragment *) { return true; }
 
274
};
 
275
 
 
276
class MCFillFragment : public MCFragment {
 
277
  /// Value - Value to use for filling bytes.
 
278
  int64_t Value;
 
279
 
 
280
  /// ValueSize - The size (in bytes) of \arg Value to use when filling, or 0 if
 
281
  /// this is a virtual fill fragment.
 
282
  unsigned ValueSize;
 
283
 
 
284
  /// Size - The number of bytes to insert.
 
285
  uint64_t Size;
 
286
 
 
287
public:
 
288
  MCFillFragment(int64_t _Value, unsigned _ValueSize, uint64_t _Size,
 
289
                 MCSectionData *SD = 0)
 
290
    : MCFragment(FT_Fill, SD),
 
291
      Value(_Value), ValueSize(_ValueSize), Size(_Size) {
 
292
    assert((!ValueSize || (Size % ValueSize) == 0) &&
 
293
           "Fill size must be a multiple of the value size!");
 
294
  }
 
295
 
 
296
  /// @name Accessors
 
297
  /// @{
 
298
 
 
299
  int64_t getValue() const { return Value; }
 
300
 
 
301
  unsigned getValueSize() const { return ValueSize; }
 
302
 
 
303
  uint64_t getSize() const { return Size; }
 
304
 
 
305
  /// @}
 
306
 
 
307
  static bool classof(const MCFragment *F) {
 
308
    return F->getKind() == MCFragment::FT_Fill;
 
309
  }
 
310
  static bool classof(const MCFillFragment *) { return true; }
 
311
};
 
312
 
 
313
class MCOrgFragment : public MCFragment {
 
314
  /// Offset - The offset this fragment should start at.
 
315
  const MCExpr *Offset;
 
316
 
 
317
  /// Value - Value to use for filling bytes.
 
318
  int8_t Value;
 
319
 
 
320
public:
 
321
  MCOrgFragment(const MCExpr &_Offset, int8_t _Value, MCSectionData *SD = 0)
 
322
    : MCFragment(FT_Org, SD),
 
323
      Offset(&_Offset), Value(_Value) {}
 
324
 
 
325
  /// @name Accessors
 
326
  /// @{
 
327
 
 
328
  const MCExpr &getOffset() const { return *Offset; }
 
329
 
 
330
  uint8_t getValue() const { return Value; }
 
331
 
 
332
  /// @}
 
333
 
 
334
  static bool classof(const MCFragment *F) {
 
335
    return F->getKind() == MCFragment::FT_Org;
 
336
  }
 
337
  static bool classof(const MCOrgFragment *) { return true; }
 
338
};
 
339
 
 
340
// FIXME: Should this be a separate class, or just merged into MCSection? Since
 
341
// we anticipate the fast path being through an MCAssembler, the only reason to
 
342
// keep it out is for API abstraction.
 
343
class MCSectionData : public ilist_node<MCSectionData> {
 
344
  friend class MCAsmLayout;
 
345
 
 
346
  MCSectionData(const MCSectionData&);  // DO NOT IMPLEMENT
 
347
  void operator=(const MCSectionData&); // DO NOT IMPLEMENT
 
348
 
 
349
public:
 
350
  typedef iplist<MCFragment> FragmentListType;
 
351
 
 
352
  typedef FragmentListType::const_iterator const_iterator;
 
353
  typedef FragmentListType::iterator iterator;
 
354
 
 
355
  typedef FragmentListType::const_reverse_iterator const_reverse_iterator;
 
356
  typedef FragmentListType::reverse_iterator reverse_iterator;
 
357
 
 
358
private:
 
359
  FragmentListType Fragments;
 
360
  const MCSection *Section;
 
361
 
 
362
  /// Ordinal - The section index in the assemblers section list.
 
363
  unsigned Ordinal;
 
364
 
 
365
  /// LayoutOrder - The index of this section in the layout order.
 
366
  unsigned LayoutOrder;
 
367
 
 
368
  /// Alignment - The maximum alignment seen in this section.
 
369
  unsigned Alignment;
 
370
 
 
371
  /// @name Assembler Backend Data
 
372
  /// @{
 
373
  //
 
374
  // FIXME: This could all be kept private to the assembler implementation.
 
375
 
 
376
  /// Address - The computed address of this section. This is ~0 until
 
377
  /// initialized.
 
378
  uint64_t Address;
 
379
 
 
380
  /// HasInstructions - Whether this section has had instructions emitted into
 
381
  /// it.
 
382
  unsigned HasInstructions : 1;
 
383
 
 
384
  /// @}
 
385
 
 
386
public:
 
387
  // Only for use as sentinel.
 
388
  MCSectionData();
 
389
  MCSectionData(const MCSection &Section, MCAssembler *A = 0);
 
390
 
 
391
  const MCSection &getSection() const { return *Section; }
 
392
 
 
393
  unsigned getAlignment() const { return Alignment; }
 
394
  void setAlignment(unsigned Value) { Alignment = Value; }
 
395
 
 
396
  bool hasInstructions() const { return HasInstructions; }
 
397
  void setHasInstructions(bool Value) { HasInstructions = Value; }
 
398
 
 
399
  unsigned getOrdinal() const { return Ordinal; }
 
400
  void setOrdinal(unsigned Value) { Ordinal = Value; }
 
401
 
 
402
  unsigned getLayoutOrder() const { return LayoutOrder; }
 
403
  void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
 
404
 
 
405
  /// @name Fragment Access
 
406
  /// @{
 
407
 
 
408
  const FragmentListType &getFragmentList() const { return Fragments; }
 
409
  FragmentListType &getFragmentList() { return Fragments; }
 
410
 
 
411
  iterator begin() { return Fragments.begin(); }
 
412
  const_iterator begin() const { return Fragments.begin(); }
 
413
 
 
414
  iterator end() { return Fragments.end(); }
 
415
  const_iterator end() const { return Fragments.end(); }
 
416
 
 
417
  reverse_iterator rbegin() { return Fragments.rbegin(); }
 
418
  const_reverse_iterator rbegin() const { return Fragments.rbegin(); }
 
419
 
 
420
  reverse_iterator rend() { return Fragments.rend(); }
 
421
  const_reverse_iterator rend() const { return Fragments.rend(); }
 
422
 
 
423
  size_t size() const { return Fragments.size(); }
 
424
 
 
425
  bool empty() const { return Fragments.empty(); }
 
426
 
 
427
  void dump();
 
428
 
 
429
  /// @}
 
430
};
 
431
 
 
432
// FIXME: Same concerns as with SectionData.
 
433
class MCSymbolData : public ilist_node<MCSymbolData> {
 
434
public:
 
435
  const MCSymbol *Symbol;
 
436
 
 
437
  /// Fragment - The fragment this symbol's value is relative to, if any.
 
438
  MCFragment *Fragment;
 
439
 
 
440
  /// Offset - The offset to apply to the fragment address to form this symbol's
 
441
  /// value.
 
442
  uint64_t Offset;
 
443
 
 
444
  /// IsExternal - True if this symbol is visible outside this translation
 
445
  /// unit.
 
446
  unsigned IsExternal : 1;
 
447
 
 
448
  /// IsPrivateExtern - True if this symbol is private extern.
 
449
  unsigned IsPrivateExtern : 1;
 
450
 
 
451
  /// CommonSize - The size of the symbol, if it is 'common', or 0.
 
452
  //
 
453
  // FIXME: Pack this in with other fields? We could put it in offset, since a
 
454
  // common symbol can never get a definition.
 
455
  uint64_t CommonSize;
 
456
 
 
457
  /// SymbolSize - An expression describing how to calculate the size of
 
458
  /// a symbol. If a symbol has no size this field will be NULL.
 
459
  const MCExpr *SymbolSize;
 
460
 
 
461
  /// CommonAlign - The alignment of the symbol, if it is 'common'.
 
462
  //
 
463
  // FIXME: Pack this in with other fields?
 
464
  unsigned CommonAlign;
 
465
 
 
466
  /// Flags - The Flags field is used by object file implementations to store
 
467
  /// additional per symbol information which is not easily classified.
 
468
  uint32_t Flags;
 
469
 
 
470
  /// Index - Index field, for use by the object file implementation.
 
471
  uint64_t Index;
 
472
 
 
473
public:
 
474
  // Only for use as sentinel.
 
475
  MCSymbolData();
 
476
  MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment, uint64_t _Offset,
 
477
               MCAssembler *A = 0);
 
478
 
 
479
  /// @name Accessors
 
480
  /// @{
 
481
 
 
482
  const MCSymbol &getSymbol() const { return *Symbol; }
 
483
 
 
484
  MCFragment *getFragment() const { return Fragment; }
 
485
  void setFragment(MCFragment *Value) { Fragment = Value; }
 
486
 
 
487
  uint64_t getOffset() const { return Offset; }
 
488
  void setOffset(uint64_t Value) { Offset = Value; }
 
489
 
 
490
  /// @}
 
491
  /// @name Symbol Attributes
 
492
  /// @{
 
493
 
 
494
  bool isExternal() const { return IsExternal; }
 
495
  void setExternal(bool Value) { IsExternal = Value; }
 
496
 
 
497
  bool isPrivateExtern() const { return IsPrivateExtern; }
 
498
  void setPrivateExtern(bool Value) { IsPrivateExtern = Value; }
 
499
 
 
500
  /// isCommon - Is this a 'common' symbol.
 
501
  bool isCommon() const { return CommonSize != 0; }
 
502
 
 
503
  /// setCommon - Mark this symbol as being 'common'.
 
504
  ///
 
505
  /// \param Size - The size of the symbol.
 
506
  /// \param Align - The alignment of the symbol.
 
507
  void setCommon(uint64_t Size, unsigned Align) {
 
508
    CommonSize = Size;
 
509
    CommonAlign = Align;
 
510
  }
 
511
 
 
512
  /// getCommonSize - Return the size of a 'common' symbol.
 
513
  uint64_t getCommonSize() const {
 
514
    assert(isCommon() && "Not a 'common' symbol!");
 
515
    return CommonSize;
 
516
  }
 
517
 
 
518
  void setSize(const MCExpr *SS) {
 
519
    SymbolSize = SS;
 
520
  }
 
521
 
 
522
  const MCExpr *getSize() const {
 
523
    return SymbolSize;
 
524
  }
 
525
 
 
526
 
 
527
  /// getCommonAlignment - Return the alignment of a 'common' symbol.
 
528
  unsigned getCommonAlignment() const {
 
529
    assert(isCommon() && "Not a 'common' symbol!");
 
530
    return CommonAlign;
 
531
  }
 
532
 
 
533
  /// getFlags - Get the (implementation defined) symbol flags.
 
534
  uint32_t getFlags() const { return Flags; }
 
535
 
 
536
  /// setFlags - Set the (implementation defined) symbol flags.
 
537
  void setFlags(uint32_t Value) { Flags = Value; }
 
538
 
 
539
  /// modifyFlags - Modify the flags via a mask
 
540
  void modifyFlags(uint32_t Value, uint32_t Mask) {
 
541
    Flags = (Flags & ~Mask) | Value;
 
542
  }
 
543
 
 
544
  /// getIndex - Get the (implementation defined) index.
 
545
  uint64_t getIndex() const { return Index; }
 
546
 
 
547
  /// setIndex - Set the (implementation defined) index.
 
548
  void setIndex(uint64_t Value) { Index = Value; }
 
549
 
 
550
  /// @}
 
551
 
 
552
  void dump();
 
553
};
 
554
 
 
555
// FIXME: This really doesn't belong here. See comments below.
 
556
struct IndirectSymbolData {
 
557
  MCSymbol *Symbol;
 
558
  MCSectionData *SectionData;
 
559
};
 
560
 
 
561
class MCAssembler {
 
562
  friend class MCAsmLayout;
 
563
 
 
564
public:
 
565
  typedef iplist<MCSectionData> SectionDataListType;
 
566
  typedef iplist<MCSymbolData> SymbolDataListType;
 
567
 
 
568
  typedef SectionDataListType::const_iterator const_iterator;
 
569
  typedef SectionDataListType::iterator iterator;
 
570
 
 
571
  typedef SymbolDataListType::const_iterator const_symbol_iterator;
 
572
  typedef SymbolDataListType::iterator symbol_iterator;
 
573
 
 
574
  typedef std::vector<IndirectSymbolData>::const_iterator
 
575
    const_indirect_symbol_iterator;
 
576
  typedef std::vector<IndirectSymbolData>::iterator indirect_symbol_iterator;
 
577
 
 
578
private:
 
579
  MCAssembler(const MCAssembler&);    // DO NOT IMPLEMENT
 
580
  void operator=(const MCAssembler&); // DO NOT IMPLEMENT
 
581
 
 
582
  MCContext &Context;
 
583
 
 
584
  TargetAsmBackend &Backend;
 
585
 
 
586
  MCCodeEmitter &Emitter;
 
587
 
 
588
  raw_ostream &OS;
 
589
 
 
590
  iplist<MCSectionData> Sections;
 
591
 
 
592
  iplist<MCSymbolData> Symbols;
 
593
 
 
594
  /// The map of sections to their associated assembler backend data.
 
595
  //
 
596
  // FIXME: Avoid this indirection?
 
597
  DenseMap<const MCSection*, MCSectionData*> SectionMap;
 
598
 
 
599
  /// The map of symbols to their associated assembler backend data.
 
600
  //
 
601
  // FIXME: Avoid this indirection?
 
602
  DenseMap<const MCSymbol*, MCSymbolData*> SymbolMap;
 
603
 
 
604
  std::vector<IndirectSymbolData> IndirectSymbols;
 
605
 
 
606
  unsigned RelaxAll : 1;
 
607
  unsigned SubsectionsViaSymbols : 1;
 
608
 
 
609
private:
 
610
  /// Evaluate a fixup to a relocatable expression and the value which should be
 
611
  /// placed into the fixup.
 
612
  ///
 
613
  /// \param Layout The layout to use for evaluation.
 
614
  /// \param Fixup The fixup to evaluate.
 
615
  /// \param DF The fragment the fixup is inside.
 
616
  /// \param Target [out] On return, the relocatable expression the fixup
 
617
  /// evaluates to.
 
618
  /// \param Value [out] On return, the value of the fixup as currently layed
 
619
  /// out.
 
620
  /// \return Whether the fixup value was fully resolved. This is true if the
 
621
  /// \arg Value result is fixed, otherwise the value may change due to
 
622
  /// relocation.
 
623
  bool EvaluateFixup(const MCAsmLayout &Layout,
 
624
                     const MCFixup &Fixup, const MCFragment *DF,
 
625
                     MCValue &Target, uint64_t &Value) const;
 
626
 
 
627
  /// Check whether a fixup can be satisfied, or whether it needs to be relaxed
 
628
  /// (increased in size, in order to hold its value correctly).
 
629
  bool FixupNeedsRelaxation(const MCFixup &Fixup, const MCFragment *DF,
 
630
                            const MCAsmLayout &Layout) const;
 
631
 
 
632
  /// Check whether the given fragment needs relaxation.
 
633
  bool FragmentNeedsRelaxation(const MCInstFragment *IF,
 
634
                               const MCAsmLayout &Layout) const;
 
635
 
 
636
  /// Compute the effective fragment size assuming it is layed out at the given
 
637
  /// \arg SectionAddress and \arg FragmentOffset.
 
638
  uint64_t ComputeFragmentSize(MCAsmLayout &Layout, const MCFragment &F,
 
639
                               uint64_t SectionAddress,
 
640
                               uint64_t FragmentOffset) const;
 
641
 
 
642
  /// LayoutOnce - Perform one layout iteration and return true if any offsets
 
643
  /// were adjusted.
 
644
  bool LayoutOnce(MCAsmLayout &Layout);
 
645
 
 
646
  /// FinishLayout - Finalize a layout, including fragment lowering.
 
647
  void FinishLayout(MCAsmLayout &Layout);
 
648
 
 
649
public:
 
650
  /// Find the symbol which defines the atom containing the given symbol, or
 
651
  /// null if there is no such symbol.
 
652
  const MCSymbolData *getAtom(const MCAsmLayout &Layout,
 
653
                              const MCSymbolData *Symbol) const;
 
654
 
 
655
  /// Check whether a particular symbol is visible to the linker and is required
 
656
  /// in the symbol table, or whether it can be discarded by the assembler. This
 
657
  /// also effects whether the assembler treats the label as potentially
 
658
  /// defining a separate atom.
 
659
  bool isSymbolLinkerVisible(const MCSymbol &SD) const;
 
660
 
 
661
  /// Emit the section contents using the given object writer.
 
662
  //
 
663
  // FIXME: Should MCAssembler always have a reference to the object writer?
 
664
  void WriteSectionData(const MCSectionData *Section, const MCAsmLayout &Layout,
 
665
                        MCObjectWriter *OW) const;
 
666
 
 
667
  void AddSectionToTheEnd(MCSectionData &SD, MCAsmLayout &Layout);
 
668
 
 
669
public:
 
670
  /// Construct a new assembler instance.
 
671
  ///
 
672
  /// \arg OS - The stream to output to.
 
673
  //
 
674
  // FIXME: How are we going to parameterize this? Two obvious options are stay
 
675
  // concrete and require clients to pass in a target like object. The other
 
676
  // option is to make this abstract, and have targets provide concrete
 
677
  // implementations as we do with AsmParser.
 
678
  MCAssembler(MCContext &_Context, TargetAsmBackend &_Backend,
 
679
              MCCodeEmitter &_Emitter, raw_ostream &OS);
 
680
  ~MCAssembler();
 
681
 
 
682
  MCContext &getContext() const { return Context; }
 
683
 
 
684
  TargetAsmBackend &getBackend() const { return Backend; }
 
685
 
 
686
  MCCodeEmitter &getEmitter() const { return Emitter; }
 
687
 
 
688
  /// Finish - Do final processing and write the object to the output stream.
 
689
  /// \arg Writer is used for custom object writer (as the MCJIT does),
 
690
  /// if not specified it is automatically created from backend.
 
691
  void Finish(MCObjectWriter *Writer = 0);
 
692
 
 
693
  // FIXME: This does not belong here.
 
694
  bool getSubsectionsViaSymbols() const {
 
695
    return SubsectionsViaSymbols;
 
696
  }
 
697
  void setSubsectionsViaSymbols(bool Value) {
 
698
    SubsectionsViaSymbols = Value;
 
699
  }
 
700
 
 
701
  bool getRelaxAll() const { return RelaxAll; }
 
702
  void setRelaxAll(bool Value) { RelaxAll = Value; }
 
703
 
 
704
  /// @name Section List Access
 
705
  /// @{
 
706
 
 
707
  const SectionDataListType &getSectionList() const { return Sections; }
 
708
  SectionDataListType &getSectionList() { return Sections; }
 
709
 
 
710
  iterator begin() { return Sections.begin(); }
 
711
  const_iterator begin() const { return Sections.begin(); }
 
712
 
 
713
  iterator end() { return Sections.end(); }
 
714
  const_iterator end() const { return Sections.end(); }
 
715
 
 
716
  size_t size() const { return Sections.size(); }
 
717
 
 
718
  /// @}
 
719
  /// @name Symbol List Access
 
720
  /// @{
 
721
 
 
722
  const SymbolDataListType &getSymbolList() const { return Symbols; }
 
723
  SymbolDataListType &getSymbolList() { return Symbols; }
 
724
 
 
725
  symbol_iterator symbol_begin() { return Symbols.begin(); }
 
726
  const_symbol_iterator symbol_begin() const { return Symbols.begin(); }
 
727
 
 
728
  symbol_iterator symbol_end() { return Symbols.end(); }
 
729
  const_symbol_iterator symbol_end() const { return Symbols.end(); }
 
730
 
 
731
  size_t symbol_size() const { return Symbols.size(); }
 
732
 
 
733
  /// @}
 
734
  /// @name Indirect Symbol List Access
 
735
  /// @{
 
736
 
 
737
  // FIXME: This is a total hack, this should not be here. Once things are
 
738
  // factored so that the streamer has direct access to the .o writer, it can
 
739
  // disappear.
 
740
  std::vector<IndirectSymbolData> &getIndirectSymbols() {
 
741
    return IndirectSymbols;
 
742
  }
 
743
 
 
744
  indirect_symbol_iterator indirect_symbol_begin() {
 
745
    return IndirectSymbols.begin();
 
746
  }
 
747
  const_indirect_symbol_iterator indirect_symbol_begin() const {
 
748
    return IndirectSymbols.begin();
 
749
  }
 
750
 
 
751
  indirect_symbol_iterator indirect_symbol_end() {
 
752
    return IndirectSymbols.end();
 
753
  }
 
754
  const_indirect_symbol_iterator indirect_symbol_end() const {
 
755
    return IndirectSymbols.end();
 
756
  }
 
757
 
 
758
  size_t indirect_symbol_size() const { return IndirectSymbols.size(); }
 
759
 
 
760
  /// @}
 
761
  /// @name Backend Data Access
 
762
  /// @{
 
763
 
 
764
  MCSectionData &getSectionData(const MCSection &Section) const {
 
765
    MCSectionData *Entry = SectionMap.lookup(&Section);
 
766
    assert(Entry && "Missing section data!");
 
767
    return *Entry;
 
768
  }
 
769
 
 
770
  MCSectionData &getOrCreateSectionData(const MCSection &Section,
 
771
                                        bool *Created = 0) {
 
772
    MCSectionData *&Entry = SectionMap[&Section];
 
773
 
 
774
    if (Created) *Created = !Entry;
 
775
    if (!Entry)
 
776
      Entry = new MCSectionData(Section, this);
 
777
 
 
778
    return *Entry;
 
779
  }
 
780
 
 
781
  MCSymbolData &getSymbolData(const MCSymbol &Symbol) const {
 
782
    MCSymbolData *Entry = SymbolMap.lookup(&Symbol);
 
783
    assert(Entry && "Missing symbol data!");
 
784
    return *Entry;
 
785
  }
 
786
 
 
787
  MCSymbolData &getOrCreateSymbolData(const MCSymbol &Symbol,
 
788
                                      bool *Created = 0) {
 
789
    MCSymbolData *&Entry = SymbolMap[&Symbol];
 
790
 
 
791
    if (Created) *Created = !Entry;
 
792
    if (!Entry)
 
793
      Entry = new MCSymbolData(Symbol, 0, 0, this);
 
794
 
 
795
    return *Entry;
 
796
  }
 
797
 
 
798
  /// @}
 
799
 
 
800
  void dump();
 
801
};
 
802
 
 
803
} // end namespace llvm
 
804
 
 
805
#endif