mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-08 19:25:47 +00:00
llvm-mc/Mach-O: Set addresses for symbols.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@80065 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -39,6 +39,9 @@ public:
|
|||||||
private:
|
private:
|
||||||
FragmentType Kind;
|
FragmentType Kind;
|
||||||
|
|
||||||
|
/// Parent - The data for the section this fragment is in.
|
||||||
|
MCSectionData *Parent;
|
||||||
|
|
||||||
/// @name Assembler Backend Data
|
/// @name Assembler Backend Data
|
||||||
/// @{
|
/// @{
|
||||||
//
|
//
|
||||||
@@ -54,7 +57,7 @@ private:
|
|||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MCFragment(FragmentType _Kind, MCSectionData *SD = 0);
|
MCFragment(FragmentType _Kind, MCSectionData *_Parent = 0);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Only for sentinel.
|
// Only for sentinel.
|
||||||
@@ -63,6 +66,9 @@ public:
|
|||||||
|
|
||||||
FragmentType getKind() const { return Kind; }
|
FragmentType getKind() const { return Kind; }
|
||||||
|
|
||||||
|
MCSectionData *getParent() const { return Parent; }
|
||||||
|
void setParent(MCSectionData *Value) { Parent = Value; }
|
||||||
|
|
||||||
// FIXME: This should be abstract, fix sentinel.
|
// FIXME: This should be abstract, fix sentinel.
|
||||||
virtual uint64_t getMaxFileSize() const {
|
virtual uint64_t getMaxFileSize() const {
|
||||||
assert(0 && "Invalid getMaxFileSize call!");
|
assert(0 && "Invalid getMaxFileSize call!");
|
||||||
@@ -74,6 +80,8 @@ public:
|
|||||||
//
|
//
|
||||||
// FIXME: This could all be kept private to the assembler implementation.
|
// FIXME: This could all be kept private to the assembler implementation.
|
||||||
|
|
||||||
|
uint64_t getAddress() const;
|
||||||
|
|
||||||
unsigned getFileSize() const {
|
unsigned getFileSize() const {
|
||||||
assert(FileSize != ~UINT64_C(0) && "File size not set!");
|
assert(FileSize != ~UINT64_C(0) && "File size not set!");
|
||||||
return FileSize;
|
return FileSize;
|
||||||
@@ -255,6 +263,10 @@ private:
|
|||||||
//
|
//
|
||||||
// FIXME: This could all be kept private to the assembler implementation.
|
// 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
|
/// FileSize - The size of this section in the object file. This is ~0 until
|
||||||
/// initialized.
|
/// initialized.
|
||||||
uint64_t FileSize;
|
uint64_t FileSize;
|
||||||
@@ -293,6 +305,12 @@ public:
|
|||||||
//
|
//
|
||||||
// FIXME: This could all be kept private to the assembler implementation.
|
// 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 {
|
unsigned getFileSize() const {
|
||||||
assert(FileSize != ~UINT64_C(0) && "File size not set!");
|
assert(FileSize != ~UINT64_C(0) && "File size not set!");
|
||||||
return FileSize;
|
return FileSize;
|
||||||
|
@@ -216,7 +216,7 @@ public:
|
|||||||
static_cast<const MCSectionMachO&>(SD.getSection());
|
static_cast<const MCSectionMachO&>(SD.getSection());
|
||||||
WriteString(Section.getSectionName(), 16);
|
WriteString(Section.getSectionName(), 16);
|
||||||
WriteString(Section.getSegmentName(), 16);
|
WriteString(Section.getSegmentName(), 16);
|
||||||
Write32(0); // address
|
Write32(SD.getAddress()); // address
|
||||||
Write32(SD.getFileSize()); // size
|
Write32(SD.getFileSize()); // size
|
||||||
Write32(FileOffset);
|
Write32(FileOffset);
|
||||||
|
|
||||||
@@ -287,7 +287,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void WriteNlist32(MachSymbolData &MSD) {
|
void WriteNlist32(MachSymbolData &MSD) {
|
||||||
MCSymbol &Symbol = MSD.SymbolData->getSymbol();
|
MCSymbolData &Data = *MSD.SymbolData;
|
||||||
|
MCSymbol &Symbol = Data.getSymbol();
|
||||||
uint8_t Type = 0;
|
uint8_t Type = 0;
|
||||||
|
|
||||||
// Set the N_TYPE bits. See <mach-o/nlist.h>.
|
// Set the N_TYPE bits. See <mach-o/nlist.h>.
|
||||||
@@ -302,11 +303,11 @@ public:
|
|||||||
|
|
||||||
// FIXME: Set STAB bits.
|
// FIXME: Set STAB bits.
|
||||||
|
|
||||||
if (MSD.SymbolData->isPrivateExtern())
|
if (Data.isPrivateExtern())
|
||||||
Type |= STF_PrivateExtern;
|
Type |= STF_PrivateExtern;
|
||||||
|
|
||||||
// Set external bit.
|
// Set external bit.
|
||||||
if (MSD.SymbolData->isExternal() || Symbol.isUndefined())
|
if (Data.isExternal() || Symbol.isUndefined())
|
||||||
Type |= STF_External;
|
Type |= STF_External;
|
||||||
|
|
||||||
// struct nlist (12 bytes)
|
// struct nlist (12 bytes)
|
||||||
@@ -317,9 +318,18 @@ public:
|
|||||||
|
|
||||||
// The Mach-O streamer uses the lowest 16-bits of the flags for the 'desc'
|
// The Mach-O streamer uses the lowest 16-bits of the flags for the 'desc'
|
||||||
// value.
|
// 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,
|
void BindIndirectSymbols(MCAssembler &Asm,
|
||||||
@@ -640,17 +650,23 @@ public:
|
|||||||
MCFragment::MCFragment() : Kind(FragmentType(~0)) {
|
MCFragment::MCFragment() : Kind(FragmentType(~0)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
MCFragment::MCFragment(FragmentType _Kind, MCSectionData *SD)
|
MCFragment::MCFragment(FragmentType _Kind, MCSectionData *_Parent)
|
||||||
: Kind(_Kind),
|
: Kind(_Kind),
|
||||||
|
Parent(_Parent),
|
||||||
FileSize(~UINT64_C(0))
|
FileSize(~UINT64_C(0))
|
||||||
{
|
{
|
||||||
if (SD)
|
if (Parent)
|
||||||
SD->getFragmentList().push_back(this);
|
Parent->getFragmentList().push_back(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
MCFragment::~MCFragment() {
|
MCFragment::~MCFragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t MCFragment::getAddress() const {
|
||||||
|
assert(getParent() && "Missing Section!");
|
||||||
|
return getParent()->getAddress() + Offset;
|
||||||
|
}
|
||||||
|
|
||||||
/* *** */
|
/* *** */
|
||||||
|
|
||||||
MCSectionData::MCSectionData() : Section(*(MCSection*)0) {}
|
MCSectionData::MCSectionData() : Section(*(MCSection*)0) {}
|
||||||
@@ -658,6 +674,7 @@ MCSectionData::MCSectionData() : Section(*(MCSection*)0) {}
|
|||||||
MCSectionData::MCSectionData(const MCSection &_Section, MCAssembler *A)
|
MCSectionData::MCSectionData(const MCSection &_Section, MCAssembler *A)
|
||||||
: Section(_Section),
|
: Section(_Section),
|
||||||
Alignment(1),
|
Alignment(1),
|
||||||
|
Address(~UINT64_C(0)),
|
||||||
FileSize(~UINT64_C(0))
|
FileSize(~UINT64_C(0))
|
||||||
{
|
{
|
||||||
if (A)
|
if (A)
|
||||||
@@ -824,8 +841,12 @@ static void WriteFileData(raw_ostream &OS, const MCSectionData &SD,
|
|||||||
|
|
||||||
void MCAssembler::Finish() {
|
void MCAssembler::Finish() {
|
||||||
// Layout the sections and fragments.
|
// 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);
|
LayoutSection(*it);
|
||||||
|
Address += it->getFileSize();
|
||||||
|
}
|
||||||
|
|
||||||
// Write the object file.
|
// Write the object file.
|
||||||
MachObjectWriter MOW(OS);
|
MachObjectWriter MOW(OS);
|
||||||
|
@@ -134,6 +134,7 @@ void MCMachOStreamer::SwitchSection(const MCSection *Section) {
|
|||||||
void MCMachOStreamer::EmitLabel(MCSymbol *Symbol) {
|
void MCMachOStreamer::EmitLabel(MCSymbol *Symbol) {
|
||||||
assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
|
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());
|
MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
|
||||||
if (!F)
|
if (!F)
|
||||||
F = new MCDataFragment(CurSectionData);
|
F = new MCDataFragment(CurSectionData);
|
||||||
|
@@ -117,8 +117,7 @@ sym_nlp_G:
|
|||||||
// CHECK: # Section 2
|
// CHECK: # Section 2
|
||||||
// CHECK: (('section_name', '__nl_symbol_ptr\x00')
|
// CHECK: (('section_name', '__nl_symbol_ptr\x00')
|
||||||
// CHECK: ('segment_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')
|
||||||
// FIXME: Enable this when fixed!
|
// CHECK: ('address', 20)
|
||||||
// CHECX: ('address', 20)
|
|
||||||
// CHECK: ('size', 20)
|
// CHECK: ('size', 20)
|
||||||
// CHECK: ('offset', 412)
|
// CHECK: ('offset', 412)
|
||||||
// CHECK: ('alignment', 2)
|
// CHECK: ('alignment', 2)
|
||||||
@@ -145,8 +144,7 @@ sym_nlp_G:
|
|||||||
// CHECK: ('n_type', 0xe)
|
// CHECK: ('n_type', 0xe)
|
||||||
// CHECK: ('n_sect', 2)
|
// CHECK: ('n_sect', 2)
|
||||||
// CHECK: ('n_desc', 0)
|
// CHECK: ('n_desc', 0)
|
||||||
// FIXME: Enable this when fixed!
|
// CHECK: ('n_value', 8)
|
||||||
// CHECX: ('n_value', 8)
|
|
||||||
// CHECK: ('_string', 'sym_lsp_C')
|
// CHECK: ('_string', 'sym_lsp_C')
|
||||||
// CHECK: ),
|
// CHECK: ),
|
||||||
// CHECK: # Symbol 1
|
// CHECK: # Symbol 1
|
||||||
@@ -154,8 +152,7 @@ sym_nlp_G:
|
|||||||
// CHECK: ('n_type', 0xe)
|
// CHECK: ('n_type', 0xe)
|
||||||
// CHECK: ('n_sect', 3)
|
// CHECK: ('n_sect', 3)
|
||||||
// CHECK: ('n_desc', 0)
|
// CHECK: ('n_desc', 0)
|
||||||
// FIXME: Enable this when fixed!
|
// CHECK: ('n_value', 28)
|
||||||
// CHECX: ('n_value', 28)
|
|
||||||
// CHECK: ('_string', 'sym_nlp_C')
|
// CHECK: ('_string', 'sym_nlp_C')
|
||||||
// CHECK: ),
|
// CHECK: ),
|
||||||
// CHECK: # Symbol 2
|
// CHECK: # Symbol 2
|
||||||
@@ -163,8 +160,7 @@ sym_nlp_G:
|
|||||||
// CHECK: ('n_type', 0xf)
|
// CHECK: ('n_type', 0xf)
|
||||||
// CHECK: ('n_sect', 2)
|
// CHECK: ('n_sect', 2)
|
||||||
// CHECK: ('n_desc', 0)
|
// CHECK: ('n_desc', 0)
|
||||||
// FIXME: Enable this when fixed!
|
// CHECK: ('n_value', 16)
|
||||||
// CHECX: ('n_value', 16)
|
|
||||||
// CHECK: ('_string', 'sym_lsp_G')
|
// CHECK: ('_string', 'sym_lsp_G')
|
||||||
// CHECK: ),
|
// CHECK: ),
|
||||||
// CHECK: # Symbol 3
|
// CHECK: # Symbol 3
|
||||||
@@ -172,8 +168,7 @@ sym_nlp_G:
|
|||||||
// CHECK: ('n_type', 0xf)
|
// CHECK: ('n_type', 0xf)
|
||||||
// CHECK: ('n_sect', 3)
|
// CHECK: ('n_sect', 3)
|
||||||
// CHECK: ('n_desc', 0)
|
// CHECK: ('n_desc', 0)
|
||||||
// FIXME: Enable this when fixed!
|
// CHECK: ('n_value', 36)
|
||||||
// CHECX: ('n_value', 36)
|
|
||||||
// CHECK: ('_string', 'sym_nlp_G')
|
// CHECK: ('_string', 'sym_nlp_G')
|
||||||
// CHECK: ),
|
// CHECK: ),
|
||||||
// CHECK: # Symbol 4
|
// CHECK: # Symbol 4
|
||||||
|
135
test/MC/MachO/values.s
Normal file
135
test/MC/MachO/values.s
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
// 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: ])
|
Reference in New Issue
Block a user