aboutsummaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/MachOWriter.cpp
diff options
context:
space:
mode:
authorNate Begeman <natebegeman@mac.com>2006-08-25 06:36:58 +0000
committerNate Begeman <natebegeman@mac.com>2006-08-25 06:36:58 +0000
commitf8f2c5a1723b46290c0e2d4ba6cf05ee11993002 (patch)
tree26800a61a1244f4279cdb65c2f3e52f114a40f8d /lib/CodeGen/MachOWriter.cpp
parent30836fc74ce18fbd8f7a2d1ecb4c3a0f7a02392c (diff)
downloadexternal_llvm-f8f2c5a1723b46290c0e2d4ba6cf05ee11993002.zip
external_llvm-f8f2c5a1723b46290c0e2d4ba6cf05ee11993002.tar.gz
external_llvm-f8f2c5a1723b46290c0e2d4ba6cf05ee11993002.tar.bz2
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
Diffstat (limited to 'lib/CodeGen/MachOWriter.cpp')
-rw-r--r--lib/CodeGen/MachOWriter.cpp75
1 files changed, 70 insertions, 5 deletions
diff --git a/lib/CodeGen/MachOWriter.cpp b/lib/CodeGen/MachOWriter.cpp
index e3228cb..d9e3b88 100644
--- a/lib/CodeGen/MachOWriter.cpp
+++ b/lib/CodeGen/MachOWriter.cpp
@@ -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.
}