mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-03-13 08:35:46 +00:00
Get closer to handling globals correctly. We now generally get them in the
right section. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29871 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
30836fc74c
commit
f8f2c5a172
@ -14,8 +14,10 @@
|
||||
#ifndef LLVM_CODEGEN_MACHOWRITER_H
|
||||
#define LLVM_CODEGEN_MACHOWRITER_H
|
||||
|
||||
#include "llvm/CodeGen/MachineRelocation.h"
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include <list>
|
||||
|
||||
namespace llvm {
|
||||
@ -377,6 +379,31 @@ namespace llvm {
|
||||
MachOSection::S_ATTR_PURE_INSTRUCTIONS |
|
||||
MachOSection::S_ATTR_SOME_INSTRUCTIONS);
|
||||
}
|
||||
MachOSection &getBSSSection() {
|
||||
return getSection("__DATA", "__bss", MachOSection::S_ZEROFILL);
|
||||
}
|
||||
MachOSection &getDataSection() {
|
||||
return getSection("__DATA", "__data");
|
||||
}
|
||||
MachOSection &getConstSection(const Type *Ty) {
|
||||
// FIXME: support cstring literals and pointer literal
|
||||
if (Ty->isPrimitiveType()) {
|
||||
unsigned Size = TM.getTargetData()->getTypeSize(Ty);
|
||||
switch(Size) {
|
||||
default: break; // Fall through to __TEXT,__const
|
||||
case 4:
|
||||
return getSection("__TEXT", "__literal4",
|
||||
MachOSection::S_4BYTE_LITERALS);
|
||||
case 8:
|
||||
return getSection("__TEXT", "__literal8",
|
||||
MachOSection::S_8BYTE_LITERALS);
|
||||
case 16:
|
||||
return getSection("__TEXT", "__literal16",
|
||||
MachOSection::S_16BYTE_LITERALS);
|
||||
}
|
||||
}
|
||||
return getSection("__TEXT", "__const");
|
||||
}
|
||||
|
||||
/// MachOSymTab - This struct contains information about the offsets and
|
||||
/// size of symbol table information.
|
||||
@ -488,7 +515,8 @@ namespace llvm {
|
||||
static unsigned entrySize() { return 12; }
|
||||
|
||||
MachOSym(const GlobalValue *gv, uint8_t sect) : GV(gv), n_strx(0),
|
||||
n_type(N_UNDF), n_sect(sect), n_desc(0), n_value(0) {}
|
||||
n_type(sect == NO_SECT ? N_UNDF : N_SECT), n_sect(sect), n_desc(0),
|
||||
n_value(0) {}
|
||||
};
|
||||
|
||||
/// SymbolTable - This is the list of symbols we have emitted to the file.
|
||||
@ -496,6 +524,11 @@ namespace llvm {
|
||||
/// local symbols first in the list).
|
||||
std::vector<MachOSym> SymbolTable;
|
||||
|
||||
/// PendingSyms - This is a list of externally defined symbols that we have
|
||||
/// been asked to emit, but have not seen a reference to. When a reference
|
||||
/// is seen, the symbol will move from this list to the SymbolTable.
|
||||
std::vector<MachOSym> PendingSyms;
|
||||
|
||||
/// DynamicSymbolTable - This is just a vector of indices into
|
||||
/// SymbolTable to aid in emitting the DYSYMTAB load command.
|
||||
std::vector<unsigned> DynamicSymbolTable;
|
||||
@ -586,6 +619,7 @@ namespace llvm {
|
||||
|
||||
}
|
||||
private:
|
||||
void AddSymbolToSection(MachOSection &MOS, GlobalVariable *GV);
|
||||
void EmitGlobal(GlobalVariable *GV);
|
||||
void EmitHeaderAndLoadCommands();
|
||||
void EmitSections();
|
||||
|
@ -27,10 +27,9 @@
|
||||
#include "llvm/CodeGen/MachineConstantPool.h"
|
||||
#include "llvm/CodeGen/MachineRelocation.h"
|
||||
#include "llvm/CodeGen/MachOWriter.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
#include "llvm/Target/TargetJITInfo.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Support/Mangler.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include <iostream>
|
||||
using namespace llvm;
|
||||
|
||||
@ -137,10 +136,9 @@ bool MachOCodeEmitter::finishFunction(MachineFunction &F) {
|
||||
// appending linkage is illegal for functions.
|
||||
assert(0 && "Unknown linkage type!");
|
||||
case GlobalValue::ExternalLinkage:
|
||||
FnSym.n_type = MachOWriter::MachOSym::N_SECT | MachOWriter::MachOSym::N_EXT;
|
||||
FnSym.n_type |= MachOWriter::MachOSym::N_EXT;
|
||||
break;
|
||||
case GlobalValue::InternalLinkage:
|
||||
FnSym.n_type = MachOWriter::MachOSym::N_SECT;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -188,8 +186,75 @@ MachOWriter::~MachOWriter() {
|
||||
delete MCE;
|
||||
}
|
||||
|
||||
void MachOWriter::AddSymbolToSection(MachOSection &Sec, GlobalVariable *GV) {
|
||||
const Type *Ty = GV->getType()->getElementType();
|
||||
unsigned Size = TM.getTargetData()->getTypeSize(Ty);
|
||||
unsigned Align = Log2_32(TM.getTargetData()->getTypeAlignment(Ty));
|
||||
|
||||
MachOSym Sym(GV, Sec.Index);
|
||||
// Reserve space in the .bss section for this symbol while maintaining the
|
||||
// desired section alignment, which must be at least as much as required by
|
||||
// this symbol.
|
||||
if (Align) {
|
||||
Sec.align = std::max(Sec.align, Align);
|
||||
Sec.size = (Sec.size + Align - 1) & ~(Align-1);
|
||||
}
|
||||
// Record the offset of the symbol, and then allocate space for it.
|
||||
Sym.n_value = Sec.size;
|
||||
Sec.size += Size;
|
||||
|
||||
switch (GV->getLinkage()) {
|
||||
default: // weak/linkonce handled above
|
||||
assert(0 && "Unexpected linkage type!");
|
||||
case GlobalValue::ExternalLinkage:
|
||||
Sym.n_type |= MachOSym::N_EXT;
|
||||
break;
|
||||
case GlobalValue::InternalLinkage:
|
||||
break;
|
||||
}
|
||||
SymbolTable.push_back(Sym);
|
||||
}
|
||||
|
||||
void MachOWriter::EmitGlobal(GlobalVariable *GV) {
|
||||
// FIXME: do something smart here.
|
||||
const Type *Ty = GV->getType()->getElementType();
|
||||
unsigned Size = TM.getTargetData()->getTypeSize(Ty);
|
||||
bool NoInit = !GV->hasInitializer();
|
||||
|
||||
// If this global has a zero initializer, it is part of the .bss or common
|
||||
// section.
|
||||
if (NoInit || GV->getInitializer()->isNullValue()) {
|
||||
// If this global is part of the common block, add it now. Variables are
|
||||
// part of the common block if they are zero initialized and allowed to be
|
||||
// merged with other symbols.
|
||||
if (NoInit || GV->hasLinkOnceLinkage() || GV->hasWeakLinkage()) {
|
||||
MachOWriter::MachOSym ExtOrCommonSym(GV, MachOSym::NO_SECT);
|
||||
ExtOrCommonSym.n_type |= MachOSym::N_EXT;
|
||||
// For undefined (N_UNDF) external (N_EXT) types, n_value is the size in
|
||||
// bytes of the symbol.
|
||||
ExtOrCommonSym.n_value = Size;
|
||||
// If the symbol is external, we'll put it on a list of symbols whose
|
||||
// addition to the symbol table is being pended until we find a reference
|
||||
if (NoInit)
|
||||
PendingSyms.push_back(ExtOrCommonSym);
|
||||
else
|
||||
SymbolTable.push_back(ExtOrCommonSym);
|
||||
return;
|
||||
}
|
||||
// Otherwise, this symbol is part of the .bss section.
|
||||
MachOSection &BSS = getBSSSection();
|
||||
AddSymbolToSection(BSS, GV);
|
||||
return;
|
||||
}
|
||||
|
||||
// Scalar read-only data goes in a literal section if the scalar is 4, 8, or
|
||||
// 16 bytes, or a cstring. Other read only data goes into a regular const
|
||||
// section. Read-write data goes in the data section.
|
||||
MachOSection &Sec = GV->isConstant() ? getConstSection(Ty) : getDataSection();
|
||||
AddSymbolToSection(Sec, GV);
|
||||
|
||||
// FIXME: actually write out the initializer to the section. This will
|
||||
// require ExecutionEngine's InitializeMemory() function, which will need to
|
||||
// be enhanced to support relocations.
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user