blob: 0a0245f3dd59e9490ca23b805163576e68021a64 [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
10#include "ELFCodeEmitter.h"
11#include "llvm/Constants.h"
12#include "llvm/DerivedTypes.h"
13#include "llvm/Function.h"
14#include "llvm/CodeGen/MachineConstantPool.h"
15#include "llvm/CodeGen/MachineJumpTableInfo.h"
16#include "llvm/Target/TargetAsmInfo.h"
17#include "llvm/Target/TargetData.h"
18#include "llvm/Target/TargetMachine.h"
19#include "llvm/Support/Mangler.h"
20#include "llvm/Support/OutputBuffer.h"
21
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.
30void ELFCodeEmitter::startFunction(MachineFunction &F) {
31 // Align the output buffer to the appropriate alignment.
32 unsigned Align = 16; // FIXME: GENERICIZE!!
33 // Get the ELF Section that this function belongs in.
34 ES = &EW.getSection(".text", ELFWriter::ELFSection::SHT_PROGBITS,
35 ELFWriter::ELFSection::SHF_EXECINSTR |
36 ELFWriter::ELFSection::SHF_ALLOC);
37 OutBuffer = &ES->SectionData;
38 cerr << "FIXME: This code needs to be updated for changes in the "
39 << "CodeEmitter interfaces. In particular, this should set "
40 << "BufferBegin/BufferEnd/CurBufferPtr, not deal with OutBuffer!";
41 abort();
42
43 // Upgrade the section alignment if required.
44 if (ES->Align < Align) ES->Align = Align;
45
46 // Add padding zeros to the end of the buffer to make sure that the
47 // function will start on the correct byte alignment within the section.
48 OutputBuffer OB(*OutBuffer,
49 TM.getTargetData()->getPointerSizeInBits() == 64,
50 TM.getTargetData()->isLittleEndian());
51 OB.align(Align);
52 FnStart = OutBuffer->size();
53}
54
55/// finishFunction - This callback is invoked after the function is completely
56/// finished.
57bool ELFCodeEmitter::finishFunction(MachineFunction &F) {
58 // We now know the size of the function, add a symbol to represent it.
59 ELFWriter::ELFSym FnSym(F.getFunction());
60
61 // Figure out the binding (linkage) of the symbol.
62 switch (F.getFunction()->getLinkage()) {
63 default:
64 // appending linkage is illegal for functions.
65 assert(0 && "Unknown linkage type!");
66 case GlobalValue::ExternalLinkage:
67 FnSym.SetBind(ELFWriter::ELFSym::STB_GLOBAL);
68 break;
69 case GlobalValue::LinkOnceAnyLinkage:
70 case GlobalValue::LinkOnceODRLinkage:
71 case GlobalValue::WeakAnyLinkage:
72 case GlobalValue::WeakODRLinkage:
73 FnSym.SetBind(ELFWriter::ELFSym::STB_WEAK);
74 break;
75 case GlobalValue::PrivateLinkage:
76 assert (0 && "PrivateLinkage should not be in the symbol table.");
77 case GlobalValue::InternalLinkage:
78 FnSym.SetBind(ELFWriter::ELFSym::STB_LOCAL);
79 break;
80 }
81
82 ES->Size = OutBuffer->size();
83
84 FnSym.SetType(ELFWriter::ELFSym::STT_FUNC);
85 FnSym.SectionIdx = ES->SectionIdx;
86 FnSym.Value = FnStart; // Value = Offset from start of Section.
87 FnSym.Size = OutBuffer->size()-FnStart;
88
89 // Finally, add it to the symtab.
90 EW.SymbolTable.push_back(FnSym);
91 return false;
92}
93
94} // end namespace llvm