private:
FragmentType Kind;
+ /// Parent - The data for the section this fragment is in.
+ MCSectionData *Parent;
+
/// @name Assembler Backend Data
/// @{
//
/// @}
protected:
- MCFragment(FragmentType _Kind, MCSectionData *SD = 0);
+ MCFragment(FragmentType _Kind, MCSectionData *_Parent = 0);
public:
// Only for sentinel.
FragmentType getKind() const { return Kind; }
+ MCSectionData *getParent() const { return Parent; }
+ void setParent(MCSectionData *Value) { Parent = Value; }
+
// FIXME: This should be abstract, fix sentinel.
virtual uint64_t getMaxFileSize() const {
assert(0 && "Invalid getMaxFileSize call!");
//
// FIXME: This could all be kept private to the assembler implementation.
+ uint64_t getAddress() const;
+
unsigned getFileSize() const {
assert(FileSize != ~UINT64_C(0) && "File size not set!");
return FileSize;
//
// FIXME: This could all be kept private to the assembler implementation.
+ /// Address - The computed address of this section. This is ~0 until
+ /// initialized.
+ uint64_t Address;
+
/// FileSize - The size of this section in the object file. This is ~0 until
/// initialized.
uint64_t FileSize;
//
// FIXME: This could all be kept private to the assembler implementation.
+ unsigned getAddress() const {
+ assert(Address != ~UINT64_C(0) && "Address not set!");
+ return Address;
+ }
+ void setAddress(uint64_t Value) { Address = Value; }
+
unsigned getFileSize() const {
assert(FileSize != ~UINT64_C(0) && "File size not set!");
return FileSize;
static_cast<const MCSectionMachO&>(SD.getSection());
WriteString(Section.getSectionName(), 16);
WriteString(Section.getSegmentName(), 16);
- Write32(0); // address
+ Write32(SD.getAddress()); // address
Write32(SD.getFileSize()); // size
Write32(FileOffset);
}
void WriteNlist32(MachSymbolData &MSD) {
- MCSymbol &Symbol = MSD.SymbolData->getSymbol();
+ MCSymbolData &Data = *MSD.SymbolData;
+ MCSymbol &Symbol = Data.getSymbol();
uint8_t Type = 0;
// Set the N_TYPE bits. See <mach-o/nlist.h>.
// FIXME: Set STAB bits.
- if (MSD.SymbolData->isPrivateExtern())
+ if (Data.isPrivateExtern())
Type |= STF_PrivateExtern;
// Set external bit.
- if (MSD.SymbolData->isExternal() || Symbol.isUndefined())
+ if (Data.isExternal() || Symbol.isUndefined())
Type |= STF_External;
// struct nlist (12 bytes)
// The Mach-O streamer uses the lowest 16-bits of the flags for the 'desc'
// value.
- Write16(MSD.SymbolData->getFlags() & 0xFFFF);
+ Write16(Data.getFlags() & 0xFFFF);
- Write32(0); // FIXME: Value
+ // Write the symbol address.
+ uint32_t Address = 0;
+ if (Symbol.isDefined()) {
+ if (Symbol.isAbsolute()) {
+ llvm_unreachable("FIXME: Not yet implemented!");
+ } else {
+ Address = Data.getFragment()->getAddress() + Data.getOffset();
+ }
+ }
+ Write32(Address);
}
void BindIndirectSymbols(MCAssembler &Asm,
MCFragment::MCFragment() : Kind(FragmentType(~0)) {
}
-MCFragment::MCFragment(FragmentType _Kind, MCSectionData *SD)
+MCFragment::MCFragment(FragmentType _Kind, MCSectionData *_Parent)
: Kind(_Kind),
+ Parent(_Parent),
FileSize(~UINT64_C(0))
{
- if (SD)
- SD->getFragmentList().push_back(this);
+ if (Parent)
+ Parent->getFragmentList().push_back(this);
}
MCFragment::~MCFragment() {
}
+uint64_t MCFragment::getAddress() const {
+ assert(getParent() && "Missing Section!");
+ return getParent()->getAddress() + Offset;
+}
+
/* *** */
MCSectionData::MCSectionData() : Section(*(MCSection*)0) {}
MCSectionData::MCSectionData(const MCSection &_Section, MCAssembler *A)
: Section(_Section),
Alignment(1),
+ Address(~UINT64_C(0)),
FileSize(~UINT64_C(0))
{
if (A)
void MCAssembler::Finish() {
// Layout the sections and fragments.
- for (iterator it = begin(), ie = end(); it != ie; ++it)
+ uint64_t Address = 0;
+ for (iterator it = begin(), ie = end(); it != ie; ++it) {
+ it->setAddress(Address);
LayoutSection(*it);
+ Address += it->getFileSize();
+ }
// Write the object file.
MachObjectWriter MOW(OS);
void MCMachOStreamer::EmitLabel(MCSymbol *Symbol) {
assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
+ // FIXME: We should also use offsets into Fill fragments.
MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
if (!F)
F = new MCDataFragment(CurSectionData);
// CHECK: # Section 2
// CHECK: (('section_name', '__nl_symbol_ptr\x00')
// CHECK: ('segment_name', '__DATA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
- // FIXME: Enable this when fixed!
-// CHECX: ('address', 20)
+// CHECK: ('address', 20)
// CHECK: ('size', 20)
// CHECK: ('offset', 412)
// CHECK: ('alignment', 2)
// CHECK: ('n_type', 0xe)
// CHECK: ('n_sect', 2)
// CHECK: ('n_desc', 0)
- // FIXME: Enable this when fixed!
-// CHECX: ('n_value', 8)
+// CHECK: ('n_value', 8)
// CHECK: ('_string', 'sym_lsp_C')
// CHECK: ),
// CHECK: # Symbol 1
// CHECK: ('n_type', 0xe)
// CHECK: ('n_sect', 3)
// CHECK: ('n_desc', 0)
- // FIXME: Enable this when fixed!
-// CHECX: ('n_value', 28)
+// CHECK: ('n_value', 28)
// CHECK: ('_string', 'sym_nlp_C')
// CHECK: ),
// CHECK: # Symbol 2
// CHECK: ('n_type', 0xf)
// CHECK: ('n_sect', 2)
// CHECK: ('n_desc', 0)
- // FIXME: Enable this when fixed!
-// CHECX: ('n_value', 16)
+// CHECK: ('n_value', 16)
// CHECK: ('_string', 'sym_lsp_G')
// CHECK: ),
// CHECK: # Symbol 3
// CHECK: ('n_type', 0xf)
// CHECK: ('n_sect', 3)
// CHECK: ('n_desc', 0)
- // FIXME: Enable this when fixed!
-// CHECX: ('n_value', 36)
+// CHECK: ('n_value', 36)
// CHECK: ('_string', 'sym_nlp_G')
// CHECK: ),
// CHECK: # Symbol 4
--- /dev/null
+// RUN: llvm-mc -triple i386-apple-darwin9 %s -filetype=obj -o - | macho-dump | FileCheck %s
+
+ .long 0
+text_def_int:
+ .long 0
+
+ .globl text_def_ext
+text_def_ext:
+ .long 0
+
+ .data
+ .long 0
+data_def_int:
+ .long 0
+
+ .globl data_def_ext
+data_def_ext:
+ .long 0
+
+// CHECK: ('cputype', 7)
+// CHECK: ('cpusubtype', 3)
+// CHECK: ('filetype', 1)
+// CHECK: ('num_load_commands', 1)
+// CHECK: ('load_commands_size', 296)
+// CHECK: ('flag', 0)
+// CHECK: ('load_commands', [
+// CHECK: # Load Command 0
+// CHECK: (('command', 1)
+// CHECK: ('size', 192)
+// CHECK: ('segment_name', '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
+// CHECK: ('vm_addr', 0)
+// CHECK: ('vm_size', 24)
+// CHECK: ('file_offset', 324)
+// CHECK: ('file_size', 24)
+// CHECK: ('maxprot', 7)
+// CHECK: ('initprot', 7)
+// CHECK: ('num_sections', 2)
+// CHECK: ('flags', 0)
+// CHECK: ('sections', [
+// CHECK: # Section 0
+// CHECK: (('section_name', '__text\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
+// CHECK: ('segment_name', '__TEXT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
+// CHECK: ('address', 0)
+// CHECK: ('size', 12)
+// CHECK: ('offset', 324)
+// CHECK: ('alignment', 0)
+// CHECK: ('reloc_offset', 0)
+// CHECK: ('num_reloc', 0)
+// CHECK: ('flags', 0x80000000)
+// CHECK: ('reserved1', 0)
+// CHECK: ('reserved2', 0)
+// CHECK: ),
+// CHECK: # Section 1
+// CHECK: (('section_name', '__data\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
+// CHECK: ('segment_name', '__DATA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
+// CHECK: ('address', 12)
+// CHECK: ('size', 12)
+// CHECK: ('offset', 336)
+// CHECK: ('alignment', 0)
+// CHECK: ('reloc_offset', 0)
+// CHECK: ('num_reloc', 0)
+// CHECK: ('flags', 0x0)
+// CHECK: ('reserved1', 0)
+// CHECK: ('reserved2', 0)
+// CHECK: ),
+// CHECK: ])
+// CHECK: ),
+// CHECK: # Load Command 1
+// CHECK: (('command', 2)
+// CHECK: ('size', 24)
+// CHECK: ('symoff', 348)
+// CHECK: ('nsyms', 4)
+// CHECK: ('stroff', 396)
+// CHECK: ('strsize', 56)
+// CHECK: ('_string_data', '\x00text_def_ext\x00data_def_ext\x00text_def_int\x00data_def_int\x00\x00\x00\x00')
+// CHECK: ('_symbols', [
+// CHECK: # Symbol 0
+// CHECK: (('n_strx', 27)
+// CHECK: ('n_type', 0xe)
+// CHECK: ('n_sect', 1)
+// CHECK: ('n_desc', 0)
+// CHECK: ('n_value', 4)
+// CHECK: ('_string', 'text_def_int')
+// CHECK: ),
+// CHECK: # Symbol 1
+// CHECK: (('n_strx', 40)
+// CHECK: ('n_type', 0xe)
+// CHECK: ('n_sect', 2)
+// CHECK: ('n_desc', 0)
+// CHECK: ('n_value', 16)
+// CHECK: ('_string', 'data_def_int')
+// CHECK: ),
+// CHECK: # Symbol 2
+// CHECK: (('n_strx', 14)
+// CHECK: ('n_type', 0xf)
+// CHECK: ('n_sect', 2)
+// CHECK: ('n_desc', 0)
+// CHECK: ('n_value', 20)
+// CHECK: ('_string', 'data_def_ext')
+// CHECK: ),
+// CHECK: # Symbol 3
+// CHECK: (('n_strx', 1)
+// CHECK: ('n_type', 0xf)
+// CHECK: ('n_sect', 1)
+// CHECK: ('n_desc', 0)
+// CHECK: ('n_value', 8)
+// CHECK: ('_string', 'text_def_ext')
+// CHECK: ),
+// CHECK: ])
+// CHECK: ),
+// CHECK: # Load Command 2
+// CHECK: (('command', 11)
+// CHECK: ('size', 80)
+// CHECK: ('ilocalsym', 0)
+// CHECK: ('nlocalsym', 2)
+// CHECK: ('iextdefsym', 2)
+// CHECK: ('nextdefsym', 2)
+// CHECK: ('iundefsym', 4)
+// CHECK: ('nundefsym', 0)
+// CHECK: ('tocoff', 0)
+// CHECK: ('ntoc', 0)
+// CHECK: ('modtaboff', 0)
+// CHECK: ('nmodtab', 0)
+// CHECK: ('extrefsymoff', 0)
+// CHECK: ('nextrefsyms', 0)
+// CHECK: ('indirectsymoff', 0)
+// CHECK: ('nindirectsyms', 0)
+// CHECK: ('extreloff', 0)
+// CHECK: ('nextrel', 0)
+// CHECK: ('locreloff', 0)
+// CHECK: ('nlocrel', 0)
+// CHECK: ('_indirect_symbols', [
+// CHECK: ])
+// CHECK: ),
+// CHECK: ])