mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-01 01:43:57 +00:00
Remove elf specific info from ELFWriter.h to Elf.h. Code cleanup and more comments added
llvm-svn: 72982
This commit is contained in:
parent
c7d37a1c3a
commit
b3b24681ca
@ -25,9 +25,23 @@ namespace llvm {
|
||||
// e_machine member of the ELF header.
|
||||
unsigned short EMachine;
|
||||
public:
|
||||
|
||||
// Machine architectures
|
||||
enum MachineType {
|
||||
NoMachine,
|
||||
EM_386 = 3
|
||||
EM_NONE = 0, // No machine
|
||||
EM_M32 = 1, // AT&T WE 32100
|
||||
EM_SPARC = 2, // SPARC
|
||||
EM_386 = 3, // Intel 386
|
||||
EM_68K = 4, // Motorola 68000
|
||||
EM_88K = 5, // Motorola 88000
|
||||
EM_486 = 6, // Intel 486 (deprecated)
|
||||
EM_860 = 7, // Intel 80860
|
||||
EM_MIPS = 8, // MIPS R3000
|
||||
EM_PPC = 20, // PowerPC
|
||||
EM_ARM = 40, // ARM
|
||||
EM_ALPHA = 41, // DEC Alpha
|
||||
EM_SPARCV9 = 43, // SPARC V9
|
||||
EM_X86_64 = 62 // AMD64
|
||||
};
|
||||
|
||||
explicit TargetELFWriterInfo(MachineType machine) : EMachine(machine) {}
|
||||
|
186
lib/CodeGen/ELF.h
Normal file
186
lib/CodeGen/ELF.h
Normal file
@ -0,0 +1,186 @@
|
||||
//===-- lib/CodeGen/ELF.h - ELF constants and data structures ---*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This header contains common, non-processor-specific data structures and
|
||||
// constants for the ELF file format.
|
||||
//
|
||||
// The details of the ELF32 bits in this file are largely based on
|
||||
// the Tool Interface Standard (TIS) Executable and Linking Format
|
||||
// (ELF) Specification Version 1.2, May 1995. The ELF64 stuff is not
|
||||
// standardized, as far as I can tell. It was largely based on information
|
||||
// I found in OpenBSD header files.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef CODEGEN_ELF_H
|
||||
#define CODEGEN_ELF_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include <cstring>
|
||||
|
||||
namespace llvm {
|
||||
class GlobalVariable;
|
||||
|
||||
// Identification Indexes
|
||||
enum {
|
||||
EI_MAG0 = 0,
|
||||
EI_MAG1 = 1,
|
||||
EI_MAG2 = 2,
|
||||
EI_MAG3 = 3
|
||||
};
|
||||
|
||||
// File types
|
||||
enum {
|
||||
ET_NONE = 0, // No file type
|
||||
ET_REL = 1, // Relocatable file
|
||||
ET_EXEC = 2, // Executable file
|
||||
ET_DYN = 3, // Shared object file
|
||||
ET_CORE = 4, // Core file
|
||||
ET_LOPROC = 0xff00, // Beginning of processor-specific codes
|
||||
ET_HIPROC = 0xffff // Processor-specific
|
||||
};
|
||||
|
||||
// Object file classes.
|
||||
enum {
|
||||
ELFCLASS32 = 1, // 32-bit object file
|
||||
ELFCLASS64 = 2 // 64-bit object file
|
||||
};
|
||||
|
||||
// Object file byte orderings.
|
||||
enum {
|
||||
ELFDATA2LSB = 1, // Little-endian object file
|
||||
ELFDATA2MSB = 2 // Big-endian object file
|
||||
};
|
||||
|
||||
// Versioning
|
||||
enum {
|
||||
EV_NONE = 0,
|
||||
EV_CURRENT = 1
|
||||
};
|
||||
|
||||
/// ELFSection - This struct contains information about each section that is
|
||||
/// emitted to the file. This is eventually turned into the section header
|
||||
/// table at the end of the file.
|
||||
struct ELFSection {
|
||||
|
||||
// ELF specific fields
|
||||
std::string Name; // Name of the section.
|
||||
unsigned NameIdx; // Index in .shstrtab of name, once emitted.
|
||||
unsigned Type;
|
||||
unsigned Flags;
|
||||
uint64_t Addr;
|
||||
unsigned Offset;
|
||||
unsigned Size;
|
||||
unsigned Link;
|
||||
unsigned Info;
|
||||
unsigned Align;
|
||||
unsigned EntSize;
|
||||
|
||||
// Section Header Flags
|
||||
enum {
|
||||
SHF_WRITE = 1 << 0, // Writable
|
||||
SHF_ALLOC = 1 << 1, // Mapped into the process addr space
|
||||
SHF_EXECINSTR = 1 << 2, // Executable
|
||||
SHF_MERGE = 1 << 4, // Might be merged if equal
|
||||
SHF_STRINGS = 1 << 5, // Contains null-terminated strings
|
||||
SHF_INFO_LINK = 1 << 6, // 'sh_info' contains SHT index
|
||||
SHF_LINK_ORDER = 1 << 7, // Preserve order after combining
|
||||
SHF_OS_NONCONFORMING = 1 << 8, // nonstandard OS support required
|
||||
SHF_GROUP = 1 << 9, // Section is a member of a group
|
||||
SHF_TLS = 1 << 10 // Section holds thread-local data
|
||||
};
|
||||
|
||||
// Section Types
|
||||
enum {
|
||||
SHT_NULL = 0, // No associated section (inactive entry).
|
||||
SHT_PROGBITS = 1, // Program-defined contents.
|
||||
SHT_SYMTAB = 2, // Symbol table.
|
||||
SHT_STRTAB = 3, // String table.
|
||||
SHT_RELA = 4, // Relocation entries; explicit addends.
|
||||
SHT_HASH = 5, // Symbol hash table.
|
||||
SHT_DYNAMIC = 6, // Information for dynamic linking.
|
||||
SHT_NOTE = 7, // Information about the file.
|
||||
SHT_NOBITS = 8, // Data occupies no space in the file.
|
||||
SHT_REL = 9, // Relocation entries; no explicit addends.
|
||||
SHT_SHLIB = 10, // Reserved.
|
||||
SHT_DYNSYM = 11, // Symbol table.
|
||||
SHT_LOPROC = 0x70000000, // Lowest processor architecture-specific type.
|
||||
SHT_HIPROC = 0x7fffffff, // Highest processor architecture-specific type.
|
||||
SHT_LOUSER = 0x80000000, // Lowest type reserved for applications.
|
||||
SHT_HIUSER = 0xffffffff // Highest type reserved for applications.
|
||||
};
|
||||
|
||||
// Special section indices.
|
||||
enum {
|
||||
SHN_UNDEF = 0, // Undefined, missing, irrelevant, or meaningless
|
||||
SHN_LORESERVE = 0xff00, // Lowest reserved index
|
||||
SHN_LOPROC = 0xff00, // Lowest processor-specific index
|
||||
SHN_HIPROC = 0xff1f, // Highest processor-specific index
|
||||
SHN_ABS = 0xfff1, // Symbol has absolute value; does not need relocation
|
||||
SHN_COMMON = 0xfff2, // FORTRAN COMMON or C external global variables
|
||||
SHN_HIRESERVE = 0xffff // Highest reserved index
|
||||
};
|
||||
|
||||
/// SectionIdx - The number of the section in the Section Table.
|
||||
unsigned short SectionIdx;
|
||||
|
||||
/// SectionData - The actual data for this section which we are building
|
||||
/// up for emission to the file.
|
||||
std::vector<unsigned char> SectionData;
|
||||
|
||||
ELFSection(const std::string &name)
|
||||
: Name(name), Type(0), Flags(0), Addr(0), Offset(0), Size(0),
|
||||
Link(0), Info(0), Align(0), EntSize(0) {}
|
||||
};
|
||||
|
||||
/// ELFSym - This struct contains information about each symbol that is
|
||||
/// added to logical symbol table for the module. This is eventually
|
||||
/// turned into a real symbol table in the file.
|
||||
struct ELFSym {
|
||||
const GlobalValue *GV; // The global value this corresponds to.
|
||||
|
||||
// ELF specific fields
|
||||
unsigned NameIdx; // Index in .strtab of name, once emitted.
|
||||
uint64_t Value;
|
||||
unsigned Size;
|
||||
uint8_t Info;
|
||||
uint8_t Other;
|
||||
unsigned short SectionIdx;
|
||||
|
||||
enum {
|
||||
STB_LOCAL = 0,
|
||||
STB_GLOBAL = 1,
|
||||
STB_WEAK = 2
|
||||
};
|
||||
|
||||
enum {
|
||||
STT_NOTYPE = 0,
|
||||
STT_OBJECT = 1,
|
||||
STT_FUNC = 2,
|
||||
STT_SECTION = 3,
|
||||
STT_FILE = 4
|
||||
};
|
||||
|
||||
ELFSym(const GlobalValue *gv) : GV(gv), Value(0),
|
||||
Size(0), Info(0), Other(0),
|
||||
SectionIdx(ELFSection::SHN_UNDEF) {}
|
||||
|
||||
void SetBind(unsigned X) {
|
||||
assert(X == (X & 0xF) && "Bind value out of range!");
|
||||
Info = (Info & 0x0F) | (X << 4);
|
||||
}
|
||||
void SetType(unsigned X) {
|
||||
assert(X == (X & 0xF) && "Type value out of range!");
|
||||
Info = (Info & 0xF0) | X;
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
@ -71,7 +71,7 @@ void ELFCodeEmitter::startFunction(MachineFunction &MF) {
|
||||
/// finished.
|
||||
bool ELFCodeEmitter::finishFunction(MachineFunction &MF) {
|
||||
// Add a symbol to represent the function.
|
||||
ELFWriter::ELFSym FnSym(MF.getFunction());
|
||||
ELFSym FnSym(MF.getFunction());
|
||||
|
||||
// Figure out the binding (linkage) of the symbol.
|
||||
switch (MF.getFunction()->getLinkage()) {
|
||||
@ -79,23 +79,23 @@ bool ELFCodeEmitter::finishFunction(MachineFunction &MF) {
|
||||
// appending linkage is illegal for functions.
|
||||
assert(0 && "Unknown linkage type!");
|
||||
case GlobalValue::ExternalLinkage:
|
||||
FnSym.SetBind(ELFWriter::ELFSym::STB_GLOBAL);
|
||||
FnSym.SetBind(ELFSym::STB_GLOBAL);
|
||||
break;
|
||||
case GlobalValue::LinkOnceAnyLinkage:
|
||||
case GlobalValue::LinkOnceODRLinkage:
|
||||
case GlobalValue::WeakAnyLinkage:
|
||||
case GlobalValue::WeakODRLinkage:
|
||||
FnSym.SetBind(ELFWriter::ELFSym::STB_WEAK);
|
||||
FnSym.SetBind(ELFSym::STB_WEAK);
|
||||
break;
|
||||
case GlobalValue::PrivateLinkage:
|
||||
assert (0 && "PrivateLinkage should not be in the symbol table.");
|
||||
case GlobalValue::InternalLinkage:
|
||||
FnSym.SetBind(ELFWriter::ELFSym::STB_LOCAL);
|
||||
FnSym.SetBind(ELFSym::STB_LOCAL);
|
||||
break;
|
||||
}
|
||||
|
||||
// Set the symbol type as a function
|
||||
FnSym.SetType(ELFWriter::ELFSym::STT_FUNC);
|
||||
FnSym.SetType(ELFSym::STT_FUNC);
|
||||
|
||||
FnSym.SectionIdx = ES->SectionIdx;
|
||||
FnSym.Size = CurBufferPtr-FnStartPtr;
|
||||
|
@ -21,7 +21,7 @@ namespace llvm {
|
||||
class ELFCodeEmitter : public MachineCodeEmitter {
|
||||
ELFWriter &EW;
|
||||
TargetMachine &TM;
|
||||
ELFWriter::ELFSection *ES; // Section to write to.
|
||||
ELFSection *ES; // Section to write to.
|
||||
uint8_t *FnStartPtr;
|
||||
public:
|
||||
explicit ELFCodeEmitter(ELFWriter &ew) : EW(ew), TM(EW.TM) {}
|
||||
|
@ -33,6 +33,7 @@
|
||||
|
||||
#include "ELFWriter.h"
|
||||
#include "ELFCodeEmitter.h"
|
||||
#include "ELF.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/PassManager.h"
|
||||
#include "llvm/DerivedTypes.h"
|
||||
@ -67,7 +68,8 @@ MachineCodeEmitter *llvm::AddELFWriter(PassManagerBase &PM,
|
||||
|
||||
ELFWriter::ELFWriter(raw_ostream &o, TargetMachine &tm)
|
||||
: MachineFunctionPass(&ID), O(o), TM(tm) {
|
||||
e_flags = 0; // e_flags defaults to 0, no flags.
|
||||
e_flags = 0; // e_flags defaults to 0, no flags.
|
||||
e_machine = TM.getELFWriterInfo()->getEMachine();
|
||||
|
||||
is64Bit = TM.getTargetData()->getPointerSizeInBits() == 64;
|
||||
isLittleEndian = TM.getTargetData()->isLittleEndian();
|
||||
@ -90,24 +92,39 @@ bool ELFWriter::doInitialization(Module &M) {
|
||||
std::vector<unsigned char> &FH = FileHeader;
|
||||
OutputBuffer FHOut(FH, is64Bit, isLittleEndian);
|
||||
|
||||
FHOut.outbyte(0x7F); // EI_MAG0
|
||||
FHOut.outbyte('E'); // EI_MAG1
|
||||
FHOut.outbyte('L'); // EI_MAG2
|
||||
FHOut.outbyte('F'); // EI_MAG3
|
||||
FHOut.outbyte(is64Bit ? 2 : 1); // EI_CLASS
|
||||
FHOut.outbyte(isLittleEndian ? 1 : 2); // EI_DATA
|
||||
FHOut.outbyte(1); // EI_VERSION
|
||||
FH.resize(16); // EI_PAD up to 16 bytes.
|
||||
unsigned ElfClass = is64Bit ? ELFCLASS64 : ELFCLASS32;
|
||||
unsigned ElfEndian = isLittleEndian ? ELFDATA2LSB : ELFDATA2MSB;
|
||||
|
||||
// This should change for shared objects.
|
||||
FHOut.outhalf(1); // e_type = ET_REL
|
||||
FHOut.outhalf(TM.getELFWriterInfo()->getEMachine()); // target-defined
|
||||
FHOut.outword(1); // e_version = 1
|
||||
FHOut.outaddr(0); // e_entry = 0 -> no entry point in .o file
|
||||
FHOut.outaddr(0); // e_phoff = 0 -> no program header for .o
|
||||
// ELF Header
|
||||
// ----------
|
||||
// Fields e_shnum e_shstrndx are only known after all section have
|
||||
// been emitted. They locations in the ouput buffer are recorded so
|
||||
// to be patched up later.
|
||||
//
|
||||
// Note
|
||||
// ----
|
||||
// FHOut.outaddr method behaves differently for ELF32 and ELF64 writing
|
||||
// 4 bytes in the former and 8 in the last for *_off and *_addr elf types
|
||||
|
||||
ELFHeader_e_shoff_Offset = FH.size();
|
||||
FHOut.outaddr(0); // e_shoff
|
||||
FHOut.outbyte(0x7f); // e_ident[EI_MAG0]
|
||||
FHOut.outbyte('E'); // e_ident[EI_MAG1]
|
||||
FHOut.outbyte('L'); // e_ident[EI_MAG2]
|
||||
FHOut.outbyte('F'); // e_ident[EI_MAG3]
|
||||
|
||||
FHOut.outbyte(ElfClass); // e_ident[EI_CLASS]
|
||||
FHOut.outbyte(ElfEndian); // e_ident[EI_DATA]
|
||||
FHOut.outbyte(EV_CURRENT); // e_ident[EI_VERSION]
|
||||
|
||||
FH.resize(16); // e_ident[EI_NIDENT-EI_PAD]
|
||||
|
||||
FHOut.outhalf(ET_REL); // e_type
|
||||
FHOut.outhalf(e_machine); // e_machine = target
|
||||
FHOut.outword(EV_CURRENT); // e_version
|
||||
FHOut.outaddr(0); // e_entry = 0 -> no entry point in .o file
|
||||
FHOut.outaddr(0); // e_phoff = 0 -> no program header for .o
|
||||
|
||||
ELFHdr_e_shoff_Offset = FH.size();
|
||||
FHOut.outaddr(0); // e_shoff = sec hdr table off in bytes
|
||||
FHOut.outword(e_flags); // e_flags = whatever the target wants
|
||||
|
||||
FHOut.outhalf(is64Bit ? 64 : 52); // e_ehsize = ELF header size
|
||||
@ -115,14 +132,16 @@ bool ELFWriter::doInitialization(Module &M) {
|
||||
FHOut.outhalf(0); // e_phnum = # prog header entries = 0
|
||||
FHOut.outhalf(is64Bit ? 64 : 40); // e_shentsize = sect hdr entry size
|
||||
|
||||
// e_shnum = # of section header ents
|
||||
ELFHdr_e_shnum_Offset = FH.size();
|
||||
FHOut.outhalf(0);
|
||||
|
||||
ELFHeader_e_shnum_Offset = FH.size();
|
||||
FHOut.outhalf(0); // e_shnum = # of section header ents
|
||||
ELFHeader_e_shstrndx_Offset = FH.size();
|
||||
FHOut.outhalf(0); // e_shstrndx = Section # of '.shstrtab'
|
||||
// e_shstrndx = Section # of '.shstrtab'
|
||||
ELFHdr_e_shstrndx_Offset = FH.size();
|
||||
FHOut.outhalf(0);
|
||||
|
||||
// Add the null section, which is required to be first in the file.
|
||||
getSection("", 0, 0);
|
||||
getSection("", ELFSection::SHT_NULL, 0);
|
||||
|
||||
// Start up the symbol table. The first entry in the symtab is the null
|
||||
// entry.
|
||||
@ -334,7 +353,7 @@ void ELFWriter::EmitSectionTableStringTable() {
|
||||
// Now that we know which section number is the .shstrtab section, update the
|
||||
// e_shstrndx entry in the ELF header.
|
||||
OutputBuffer FHOut(FileHeader, is64Bit, isLittleEndian);
|
||||
FHOut.fixhalf(SHStrTab.SectionIdx, ELFHeader_e_shstrndx_Offset);
|
||||
FHOut.fixhalf(SHStrTab.SectionIdx, ELFHdr_e_shstrndx_Offset);
|
||||
|
||||
// Set the NameIdx of each section in the string table and emit the bytes for
|
||||
// the string table.
|
||||
@ -386,11 +405,11 @@ void ELFWriter::OutputSectionsAndSectionTable() {
|
||||
// Now that we know where all of the sections will be emitted, set the e_shnum
|
||||
// entry in the ELF header.
|
||||
OutputBuffer FHOut(FileHeader, is64Bit, isLittleEndian);
|
||||
FHOut.fixhalf(NumSections, ELFHeader_e_shnum_Offset);
|
||||
FHOut.fixhalf(NumSections, ELFHdr_e_shnum_Offset);
|
||||
|
||||
// Now that we know the offset in the file of the section table, update the
|
||||
// e_shoff address in the ELF header.
|
||||
FHOut.fixaddr(FileOff, ELFHeader_e_shoff_Offset);
|
||||
FHOut.fixaddr(FileOff, ELFHdr_e_shoff_Offset);
|
||||
|
||||
// Now that we know all of the data in the file header, emit it and all of the
|
||||
// sections!
|
||||
|
@ -15,6 +15,7 @@
|
||||
#define ELFWRITER_H
|
||||
|
||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||
#include "ELF.h"
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
@ -82,10 +83,8 @@ namespace llvm {
|
||||
/// doInitialization - Emit the file header and all of the global variables
|
||||
/// for the module to the ELF file.
|
||||
bool doInitialization(Module &M);
|
||||
|
||||
bool runOnMachineFunction(MachineFunction &MF);
|
||||
|
||||
|
||||
/// doFinalization - Now that the module has been completely processed, emit
|
||||
/// the ELF file to 'O'.
|
||||
bool doFinalization(Module &M);
|
||||
@ -96,53 +95,6 @@ namespace llvm {
|
||||
// as well!).
|
||||
DataBuffer FileHeader;
|
||||
|
||||
/// ELFSection - This struct contains information about each section that is
|
||||
/// emitted to the file. This is eventually turned into the section header
|
||||
/// table at the end of the file.
|
||||
struct ELFSection {
|
||||
std::string Name; // Name of the section.
|
||||
unsigned NameIdx; // Index in .shstrtab of name, once emitted.
|
||||
unsigned Type;
|
||||
unsigned Flags;
|
||||
uint64_t Addr;
|
||||
unsigned Offset;
|
||||
unsigned Size;
|
||||
unsigned Link;
|
||||
unsigned Info;
|
||||
unsigned Align;
|
||||
unsigned EntSize;
|
||||
|
||||
/// SectionIdx - The number of the section in the Section Table.
|
||||
///
|
||||
unsigned short SectionIdx;
|
||||
|
||||
/// SectionData - The actual data for this section which we are building
|
||||
/// up for emission to the file.
|
||||
DataBuffer SectionData;
|
||||
|
||||
enum { SHT_NULL = 0, SHT_PROGBITS = 1, SHT_SYMTAB = 2, SHT_STRTAB = 3,
|
||||
SHT_RELA = 4, SHT_HASH = 5, SHT_DYNAMIC = 6, SHT_NOTE = 7,
|
||||
SHT_NOBITS = 8, SHT_REL = 9, SHT_SHLIB = 10, SHT_DYNSYM = 11 };
|
||||
enum { SHN_UNDEF = 0, SHN_ABS = 0xFFF1, SHN_COMMON = 0xFFF2 };
|
||||
enum { // SHF - ELF Section Header Flags
|
||||
SHF_WRITE = 1 << 0, // Writable
|
||||
SHF_ALLOC = 1 << 1, // Mapped into the process addr space
|
||||
SHF_EXECINSTR = 1 << 2, // Executable
|
||||
SHF_MERGE = 1 << 4, // Might be merged if equal
|
||||
SHF_STRINGS = 1 << 5, // Contains null-terminated strings
|
||||
SHF_INFO_LINK = 1 << 6, // 'sh_info' contains SHT index
|
||||
SHF_LINK_ORDER = 1 << 7, // Preserve order after combining
|
||||
SHF_OS_NONCONFORMING = 1 << 8, // nonstandard OS support required
|
||||
SHF_GROUP = 1 << 9, // Section is a member of a group
|
||||
SHF_TLS = 1 << 10 // Section holds thread-local data
|
||||
};
|
||||
|
||||
ELFSection(const std::string &name)
|
||||
: Name(name), Type(0), Flags(0), Addr(0), Offset(0), Size(0),
|
||||
Link(0), Info(0), Align(0), EntSize(0) {
|
||||
}
|
||||
};
|
||||
|
||||
/// SectionList - This is the list of sections that we have emitted to the
|
||||
/// file. Once the file has been completely built, the section header table
|
||||
/// is constructed from this info.
|
||||
@ -165,13 +117,13 @@ namespace llvm {
|
||||
SN->SectionIdx = NumSections++;
|
||||
SN->Type = Type;
|
||||
SN->Flags = Flags;
|
||||
SN->Link = ELFSection::SHN_UNDEF;
|
||||
return *SN;
|
||||
}
|
||||
|
||||
ELFSection &getTextSection() {
|
||||
return getSection(".text", ELFWriter::ELFSection::SHT_PROGBITS,
|
||||
ELFWriter::ELFSection::SHF_EXECINSTR |
|
||||
ELFWriter::ELFSection::SHF_ALLOC);
|
||||
return getSection(".text", ELFSection::SHT_PROGBITS,
|
||||
ELFSection::SHF_EXECINSTR | ELFSection::SHF_ALLOC);
|
||||
}
|
||||
|
||||
ELFSection &getDataSection() {
|
||||
@ -183,34 +135,6 @@ namespace llvm {
|
||||
ELFSection::SHF_WRITE | ELFSection::SHF_ALLOC);
|
||||
}
|
||||
|
||||
/// ELFSym - This struct contains information about each symbol that is
|
||||
/// added to logical symbol table for the module. This is eventually
|
||||
/// turned into a real symbol table in the file.
|
||||
struct ELFSym {
|
||||
const GlobalValue *GV; // The global value this corresponds to.
|
||||
unsigned NameIdx; // Index in .strtab of name, once emitted.
|
||||
uint64_t Value;
|
||||
unsigned Size;
|
||||
unsigned char Info;
|
||||
unsigned char Other;
|
||||
unsigned short SectionIdx;
|
||||
|
||||
enum { STB_LOCAL = 0, STB_GLOBAL = 1, STB_WEAK = 2 };
|
||||
enum { STT_NOTYPE = 0, STT_OBJECT = 1, STT_FUNC = 2, STT_SECTION = 3,
|
||||
STT_FILE = 4 };
|
||||
ELFSym(const GlobalValue *gv) : GV(gv), Value(0), Size(0), Info(0),
|
||||
Other(0), SectionIdx(0) {}
|
||||
|
||||
void SetBind(unsigned X) {
|
||||
assert(X == (X & 0xF) && "Bind value out of range!");
|
||||
Info = (Info & 0x0F) | (X << 4);
|
||||
}
|
||||
void SetType(unsigned X) {
|
||||
assert(X == (X & 0xF) && "Type value out of range!");
|
||||
Info = (Info & 0xF0) | X;
|
||||
}
|
||||
};
|
||||
|
||||
/// SymbolTable - This is the list of symbols we have emitted to the file.
|
||||
/// This actually gets rearranged before emission to the file (to put the
|
||||
/// local symbols first in the list).
|
||||
@ -220,9 +144,9 @@ namespace llvm {
|
||||
// (e.g. the location of the section table). These members keep track of
|
||||
// the offset in ELFHeader of these various pieces to update and other
|
||||
// locations in the file.
|
||||
unsigned ELFHeader_e_shoff_Offset; // e_shoff in ELF header.
|
||||
unsigned ELFHeader_e_shstrndx_Offset; // e_shstrndx in ELF header.
|
||||
unsigned ELFHeader_e_shnum_Offset; // e_shnum in ELF header.
|
||||
unsigned ELFHdr_e_shoff_Offset; // e_shoff in ELF header.
|
||||
unsigned ELFHdr_e_shstrndx_Offset; // e_shstrndx in ELF header.
|
||||
unsigned ELFHdr_e_shnum_Offset; // e_shnum in ELF header.
|
||||
private:
|
||||
void EmitGlobal(GlobalVariable *GV);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user