blob: 780ec57191a313784112aba5d4a80df879479fe6 [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"
16#include "llvm/CodeGen/MachineConstantPool.h"
17#include "llvm/CodeGen/MachineJumpTableInfo.h"
Bruno Cardoso Lopes4cb31432009-06-03 17:47:27 +000018#include "llvm/Target/TargetMachine.h"
Bruno Cardoso Lopes5d419102009-06-05 00:22:10 +000019#include "llvm/Support/Debug.h"
Bruno Cardoso Lopes4cb31432009-06-03 17:47:27 +000020
21//===----------------------------------------------------------------------===//
22// ELFCodeEmitter Implementation
23//===----------------------------------------------------------------------===//
24
25namespace llvm {
26
27/// startFunction - This callback is invoked when a new machine function is
28/// about to be emitted.
Bruno Cardoso Lopes5d419102009-06-05 00:22:10 +000029void ELFCodeEmitter::startFunction(MachineFunction &MF) {
Bruno Cardoso Lopes4cb31432009-06-03 17:47:27 +000030 // Get the ELF Section that this function belongs in.
Bruno Cardoso Lopes5d419102009-06-05 00:22:10 +000031 ES = &EW.getTextSection();
32
Bruno Cardoso Lopesc997d452009-06-11 19:16:03 +000033 DOUT << "processing function: " << MF.getFunction()->getName() << "\n";
34
Bruno Cardoso Lopes5d419102009-06-05 00:22:10 +000035 // FIXME: better memory management, this will be replaced by BinaryObjects
36 ES->SectionData.reserve(4096);
37 BufferBegin = &ES->SectionData[0];
38 BufferEnd = BufferBegin + ES->SectionData.capacity();
Bruno Cardoso Lopes4cb31432009-06-03 17:47:27 +000039
Bruno Cardoso Lopesc997d452009-06-11 19:16:03 +000040 // Align the output buffer with function alignment, and
41 // upgrade the section alignment if required
42 unsigned Align =
43 TM.getELFWriterInfo()->getFunctionAlignment(MF.getFunction());
Bruno Cardoso Lopes4cb31432009-06-03 17:47:27 +000044 if (ES->Align < Align) ES->Align = Align;
Bruno Cardoso Lopes5d419102009-06-05 00:22:10 +000045 ES->Size = (ES->Size + (Align-1)) & (-Align);
46
47 // Snaity check on allocated space for text section
48 assert( ES->Size < 4096 && "no more space in TextSection" );
49
50 // FIXME: Using ES->Size directly here instead of calculating it from the
51 // output buffer size (impossible because the code emitter deals only in raw
52 // bytes) forces us to manually synchronize size and write padding zero bytes
53 // to the output buffer for all non-text sections. For text sections, we do
54 // not synchonize the output buffer, and we just blow up if anyone tries to
55 // write non-code to it. An assert should probably be added to
56 // AddSymbolToSection to prevent calling it on the text section.
57 CurBufferPtr = BufferBegin + ES->Size;
58
59 // Record function start address relative to BufferBegin
60 FnStartPtr = CurBufferPtr;
Bruno Cardoso Lopes4cb31432009-06-03 17:47:27 +000061}
62
63/// finishFunction - This callback is invoked after the function is completely
64/// finished.
Bruno Cardoso Lopes5d419102009-06-05 00:22:10 +000065bool ELFCodeEmitter::finishFunction(MachineFunction &MF) {
66 // Add a symbol to represent the function.
Bruno Cardoso Lopesf5b0c5a2009-06-06 03:56:29 +000067 ELFSym FnSym(MF.getFunction());
Bruno Cardoso Lopes4cb31432009-06-03 17:47:27 +000068
Bruno Cardoso Lopesa029a272009-06-07 21:22:38 +000069 // Update Section Size
70 ES->Size = CurBufferPtr - BufferBegin;
71
Bruno Cardoso Lopes4cb31432009-06-03 17:47:27 +000072 // Figure out the binding (linkage) of the symbol.
Bruno Cardoso Lopes5d419102009-06-05 00:22:10 +000073 switch (MF.getFunction()->getLinkage()) {
Bruno Cardoso Lopes4cb31432009-06-03 17:47:27 +000074 default:
75 // appending linkage is illegal for functions.
76 assert(0 && "Unknown linkage type!");
77 case GlobalValue::ExternalLinkage:
Bruno Cardoso Lopesf5b0c5a2009-06-06 03:56:29 +000078 FnSym.SetBind(ELFSym::STB_GLOBAL);
Bruno Cardoso Lopes4cb31432009-06-03 17:47:27 +000079 break;
80 case GlobalValue::LinkOnceAnyLinkage:
81 case GlobalValue::LinkOnceODRLinkage:
82 case GlobalValue::WeakAnyLinkage:
83 case GlobalValue::WeakODRLinkage:
Bruno Cardoso Lopesf5b0c5a2009-06-06 03:56:29 +000084 FnSym.SetBind(ELFSym::STB_WEAK);
Bruno Cardoso Lopes4cb31432009-06-03 17:47:27 +000085 break;
86 case GlobalValue::PrivateLinkage:
87 assert (0 && "PrivateLinkage should not be in the symbol table.");
88 case GlobalValue::InternalLinkage:
Bruno Cardoso Lopesf5b0c5a2009-06-06 03:56:29 +000089 FnSym.SetBind(ELFSym::STB_LOCAL);
Bruno Cardoso Lopes4cb31432009-06-03 17:47:27 +000090 break;
91 }
92
Bruno Cardoso Lopes5d419102009-06-05 00:22:10 +000093 // Set the symbol type as a function
Bruno Cardoso Lopesf5b0c5a2009-06-06 03:56:29 +000094 FnSym.SetType(ELFSym::STT_FUNC);
Bruno Cardoso Lopes5d419102009-06-05 00:22:10 +000095
Bruno Cardoso Lopes4cb31432009-06-03 17:47:27 +000096 FnSym.SectionIdx = ES->SectionIdx;
Bruno Cardoso Lopes5d419102009-06-05 00:22:10 +000097 FnSym.Size = CurBufferPtr-FnStartPtr;
98
99 // Offset from start of Section
100 FnSym.Value = FnStartPtr-BufferBegin;
Bruno Cardoso Lopes4cb31432009-06-03 17:47:27 +0000101
102 // Finally, add it to the symtab.
103 EW.SymbolTable.push_back(FnSym);
Bruno Cardoso Lopes5d419102009-06-05 00:22:10 +0000104
Bruno Cardoso Lopesa029a272009-06-07 21:22:38 +0000105 // Relocations
106 // -----------
107 // If we have emitted any relocations to function-specific objects such as
108 // basic blocks, constant pools entries, or jump tables, record their
109 // addresses now so that we can rewrite them with the correct addresses
110 // later.
111 for (unsigned i = 0, e = Relocations.size(); i != e; ++i) {
112 MachineRelocation &MR = Relocations[i];
113 intptr_t Addr;
114
115 if (MR.isBasicBlock()) {
116 Addr = getMachineBasicBlockAddress(MR.getBasicBlock());
117 MR.setConstantVal(ES->SectionIdx);
118 MR.setResultPointer((void*)Addr);
119 } else if (MR.isGlobalValue()) {
120 EW.PendingGlobals.insert(MR.getGlobalValue());
121 } else {
122 assert(0 && "Unhandled relocation type");
123 }
124 ES->Relocations.push_back(MR);
125 }
126 Relocations.clear();
127
Bruno Cardoso Lopes4cb31432009-06-03 17:47:27 +0000128 return false;
129}
130
131} // end namespace llvm