blob: ca683969e411b7e66bda017812e444231712913d [file] [log] [blame]
Bruno Cardoso Lopes4cb31432009-06-03 17:47:27 +00001//===-- lib/CodeGen/ELFCodeEmitter.cpp ------------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Bruno Cardoso Lopes5d419102009-06-05 00:22:10 +000010#define DEBUG_TYPE "elfce"
11
Bruno Cardoso Lopes4cb31432009-06-03 17:47:27 +000012#include "ELFCodeEmitter.h"
13#include "llvm/Constants.h"
14#include "llvm/DerivedTypes.h"
15#include "llvm/Function.h"
Bruno Cardoso Lopesae9163f2009-06-14 07:53:21 +000016#include "llvm/CodeGen/BinaryObject.h"
Bruno Cardoso Lopes4cb31432009-06-03 17:47:27 +000017#include "llvm/CodeGen/MachineConstantPool.h"
18#include "llvm/CodeGen/MachineJumpTableInfo.h"
Bruno Cardoso Lopes4cb31432009-06-03 17:47:27 +000019#include "llvm/Target/TargetMachine.h"
Bruno Cardoso Lopes5d419102009-06-05 00:22:10 +000020#include "llvm/Support/Debug.h"
Bruno Cardoso Lopes4cb31432009-06-03 17:47:27 +000021
22//===----------------------------------------------------------------------===//
23// ELFCodeEmitter Implementation
24//===----------------------------------------------------------------------===//
25
26namespace llvm {
27
28/// startFunction - This callback is invoked when a new machine function is
29/// about to be emitted.
Bruno Cardoso Lopes5d419102009-06-05 00:22:10 +000030void ELFCodeEmitter::startFunction(MachineFunction &MF) {
Bruno Cardoso Lopes4cb31432009-06-03 17:47:27 +000031 // Get the ELF Section that this function belongs in.
Bruno Cardoso Lopes5d419102009-06-05 00:22:10 +000032 ES = &EW.getTextSection();
33
Bruno Cardoso Lopesc997d452009-06-11 19:16:03 +000034 DOUT << "processing function: " << MF.getFunction()->getName() << "\n";
35
Bruno Cardoso Lopes5d419102009-06-05 00:22:10 +000036 // FIXME: better memory management, this will be replaced by BinaryObjects
Bruno Cardoso Lopesae9163f2009-06-14 07:53:21 +000037 BinaryData &BD = ES->getData();
38 BD.reserve(4096);
39 BufferBegin = &BD[0];
40 BufferEnd = BufferBegin + BD.capacity();
Bruno Cardoso Lopes4cb31432009-06-03 17:47:27 +000041
Bruno Cardoso Lopesc997d452009-06-11 19:16:03 +000042 // Align the output buffer with function alignment, and
43 // upgrade the section alignment if required
44 unsigned Align =
45 TM.getELFWriterInfo()->getFunctionAlignment(MF.getFunction());
Bruno Cardoso Lopes4cb31432009-06-03 17:47:27 +000046 if (ES->Align < Align) ES->Align = Align;
Bruno Cardoso Lopes5d419102009-06-05 00:22:10 +000047 ES->Size = (ES->Size + (Align-1)) & (-Align);
48
49 // Snaity check on allocated space for text section
50 assert( ES->Size < 4096 && "no more space in TextSection" );
51
52 // FIXME: Using ES->Size directly here instead of calculating it from the
53 // output buffer size (impossible because the code emitter deals only in raw
54 // bytes) forces us to manually synchronize size and write padding zero bytes
55 // to the output buffer for all non-text sections. For text sections, we do
56 // not synchonize the output buffer, and we just blow up if anyone tries to
57 // write non-code to it. An assert should probably be added to
58 // AddSymbolToSection to prevent calling it on the text section.
59 CurBufferPtr = BufferBegin + ES->Size;
60
61 // Record function start address relative to BufferBegin
62 FnStartPtr = CurBufferPtr;
Bruno Cardoso Lopes4cb31432009-06-03 17:47:27 +000063}
64
65/// finishFunction - This callback is invoked after the function is completely
66/// finished.
Bruno Cardoso Lopes5d419102009-06-05 00:22:10 +000067bool ELFCodeEmitter::finishFunction(MachineFunction &MF) {
68 // Add a symbol to represent the function.
Bruno Cardoso Lopesf5b0c5a2009-06-06 03:56:29 +000069 ELFSym FnSym(MF.getFunction());
Bruno Cardoso Lopes4cb31432009-06-03 17:47:27 +000070
Bruno Cardoso Lopesa029a272009-06-07 21:22:38 +000071 // Update Section Size
72 ES->Size = CurBufferPtr - BufferBegin;
73
Bruno Cardoso Lopes4cb31432009-06-03 17:47:27 +000074 // Figure out the binding (linkage) of the symbol.
Bruno Cardoso Lopes5d419102009-06-05 00:22:10 +000075 switch (MF.getFunction()->getLinkage()) {
Bruno Cardoso Lopes4cb31432009-06-03 17:47:27 +000076 default:
77 // appending linkage is illegal for functions.
78 assert(0 && "Unknown linkage type!");
79 case GlobalValue::ExternalLinkage:
Bruno Cardoso Lopesf5b0c5a2009-06-06 03:56:29 +000080 FnSym.SetBind(ELFSym::STB_GLOBAL);
Bruno Cardoso Lopes4cb31432009-06-03 17:47:27 +000081 break;
82 case GlobalValue::LinkOnceAnyLinkage:
83 case GlobalValue::LinkOnceODRLinkage:
84 case GlobalValue::WeakAnyLinkage:
85 case GlobalValue::WeakODRLinkage:
Bruno Cardoso Lopesf5b0c5a2009-06-06 03:56:29 +000086 FnSym.SetBind(ELFSym::STB_WEAK);
Bruno Cardoso Lopes4cb31432009-06-03 17:47:27 +000087 break;
88 case GlobalValue::PrivateLinkage:
89 assert (0 && "PrivateLinkage should not be in the symbol table.");
90 case GlobalValue::InternalLinkage:
Bruno Cardoso Lopesf5b0c5a2009-06-06 03:56:29 +000091 FnSym.SetBind(ELFSym::STB_LOCAL);
Bruno Cardoso Lopes4cb31432009-06-03 17:47:27 +000092 break;
93 }
94
Bruno Cardoso Lopes5d419102009-06-05 00:22:10 +000095 // Set the symbol type as a function
Bruno Cardoso Lopesf5b0c5a2009-06-06 03:56:29 +000096 FnSym.SetType(ELFSym::STT_FUNC);
Bruno Cardoso Lopes5d419102009-06-05 00:22:10 +000097
Bruno Cardoso Lopes4cb31432009-06-03 17:47:27 +000098 FnSym.SectionIdx = ES->SectionIdx;
Bruno Cardoso Lopes5d419102009-06-05 00:22:10 +000099 FnSym.Size = CurBufferPtr-FnStartPtr;
100
101 // Offset from start of Section
102 FnSym.Value = FnStartPtr-BufferBegin;
Bruno Cardoso Lopes4cb31432009-06-03 17:47:27 +0000103
104 // Finally, add it to the symtab.
Bruno Cardoso Lopesae9163f2009-06-14 07:53:21 +0000105 EW.SymbolList.push_back(FnSym);
Bruno Cardoso Lopes5d419102009-06-05 00:22:10 +0000106
Bruno Cardoso Lopesa029a272009-06-07 21:22:38 +0000107 // Relocations
108 // -----------
109 // If we have emitted any relocations to function-specific objects such as
110 // basic blocks, constant pools entries, or jump tables, record their
111 // addresses now so that we can rewrite them with the correct addresses
112 // later.
113 for (unsigned i = 0, e = Relocations.size(); i != e; ++i) {
114 MachineRelocation &MR = Relocations[i];
115 intptr_t Addr;
116
117 if (MR.isBasicBlock()) {
118 Addr = getMachineBasicBlockAddress(MR.getBasicBlock());
119 MR.setConstantVal(ES->SectionIdx);
120 MR.setResultPointer((void*)Addr);
121 } else if (MR.isGlobalValue()) {
122 EW.PendingGlobals.insert(MR.getGlobalValue());
123 } else {
124 assert(0 && "Unhandled relocation type");
125 }
Bruno Cardoso Lopesae9163f2009-06-14 07:53:21 +0000126 ES->addRelocation(MR);
Bruno Cardoso Lopesa029a272009-06-07 21:22:38 +0000127 }
128 Relocations.clear();
129
Bruno Cardoso Lopes4cb31432009-06-03 17:47:27 +0000130 return false;
131}
132
133} // end namespace llvm