2010-03-19 18:43:15 +08:00
|
|
|
//===- lib/MC/MCObjectWriter.cpp - MCObjectWriter implementation ----------===//
|
2010-03-19 17:28:59 +08:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2010-12-25 05:22:02 +08:00
|
|
|
#include "llvm/MC/MCAssembler.h"
|
2010-12-18 14:27:54 +08:00
|
|
|
#include "llvm/MC/MCExpr.h"
|
2010-03-19 17:28:59 +08:00
|
|
|
#include "llvm/MC/MCObjectWriter.h"
|
2010-12-18 14:27:54 +08:00
|
|
|
#include "llvm/MC/MCSymbol.h"
|
2010-03-19 17:28:59 +08:00
|
|
|
|
|
|
|
using namespace llvm;
|
|
|
|
|
|
|
|
MCObjectWriter::~MCObjectWriter() {
|
|
|
|
}
|
2010-10-01 00:52:03 +08:00
|
|
|
|
|
|
|
/// Utility function to encode a SLEB128 value.
|
|
|
|
void MCObjectWriter::EncodeSLEB128(int64_t Value, raw_ostream &OS) {
|
|
|
|
bool More;
|
|
|
|
do {
|
|
|
|
uint8_t Byte = Value & 0x7f;
|
|
|
|
// NOTE: this assumes that this signed shift is an arithmetic right shift.
|
|
|
|
Value >>= 7;
|
|
|
|
More = !((((Value == 0 ) && ((Byte & 0x40) == 0)) ||
|
|
|
|
((Value == -1) && ((Byte & 0x40) != 0))));
|
|
|
|
if (More)
|
|
|
|
Byte |= 0x80; // Mark this byte that that more bytes will follow.
|
|
|
|
OS << char(Byte);
|
|
|
|
} while (More);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Utility function to encode a ULEB128 value.
|
2011-11-05 19:52:44 +08:00
|
|
|
void MCObjectWriter::EncodeULEB128(uint64_t Value, raw_ostream &OS,
|
|
|
|
unsigned Padding) {
|
2010-10-01 00:52:03 +08:00
|
|
|
do {
|
|
|
|
uint8_t Byte = Value & 0x7f;
|
|
|
|
Value >>= 7;
|
2011-11-05 19:52:44 +08:00
|
|
|
if (Value != 0 || Padding != 0)
|
2010-10-01 00:52:03 +08:00
|
|
|
Byte |= 0x80; // Mark this byte that that more bytes will follow.
|
|
|
|
OS << char(Byte);
|
|
|
|
} while (Value != 0);
|
2011-11-05 19:52:44 +08:00
|
|
|
|
|
|
|
// Pad with 0x80 and emit a null byte at the end.
|
|
|
|
if (Padding != 0) {
|
|
|
|
for (; Padding != 1; --Padding)
|
|
|
|
OS << '\x80';
|
|
|
|
OS << '\x00';
|
|
|
|
}
|
2010-10-01 00:52:03 +08:00
|
|
|
}
|
2010-12-18 14:27:54 +08:00
|
|
|
|
|
|
|
bool
|
|
|
|
MCObjectWriter::IsSymbolRefDifferenceFullyResolved(const MCAssembler &Asm,
|
|
|
|
const MCSymbolRefExpr *A,
|
|
|
|
const MCSymbolRefExpr *B,
|
|
|
|
bool InSet) const {
|
|
|
|
// Modified symbol references cannot be resolved.
|
|
|
|
if (A->getKind() != MCSymbolRefExpr::VK_None ||
|
|
|
|
B->getKind() != MCSymbolRefExpr::VK_None)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
const MCSymbol &SA = A->getSymbol();
|
|
|
|
const MCSymbol &SB = B->getSymbol();
|
2010-12-25 05:22:02 +08:00
|
|
|
if (SA.AliasedSymbol().isUndefined() || SB.AliasedSymbol().isUndefined())
|
2010-12-18 14:27:54 +08:00
|
|
|
return false;
|
|
|
|
|
2010-12-25 05:22:02 +08:00
|
|
|
const MCSymbolData &DataA = Asm.getSymbolData(SA);
|
|
|
|
const MCSymbolData &DataB = Asm.getSymbolData(SB);
|
2012-02-01 07:02:57 +08:00
|
|
|
if(!DataA.getFragment() || !DataB.getFragment())
|
|
|
|
return false;
|
2010-12-25 05:22:02 +08:00
|
|
|
|
|
|
|
return IsSymbolRefDifferenceFullyResolvedImpl(Asm, DataA,
|
|
|
|
*DataB.getFragment(),
|
|
|
|
InSet,
|
|
|
|
false);
|
2010-12-18 14:27:54 +08:00
|
|
|
}
|
2011-02-16 11:25:55 +08:00
|
|
|
|
|
|
|
bool
|
|
|
|
MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
|
|
|
|
const MCSymbolData &DataA,
|
|
|
|
const MCFragment &FB,
|
|
|
|
bool InSet,
|
|
|
|
bool IsPCRel) const {
|
|
|
|
const MCSection &SecA = DataA.getSymbol().AliasedSymbol().getSection();
|
|
|
|
const MCSection &SecB = FB.getParent()->getSection();
|
|
|
|
// On ELF and COFF A - B is absolute if A and B are in the same section.
|
|
|
|
return &SecA == &SecB;
|
|
|
|
}
|