summaryrefslogtreecommitdiff
path: root/lib/MC/ELFObjectWriter.cpp
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2014-03-25 22:43:53 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2014-03-25 22:43:53 +0000
commit78f7e6f04fed54619122d8ffcc5d11808d0f4feb (patch)
treef1106c16402dd1a207564190abb6931908958cd2 /lib/MC/ELFObjectWriter.cpp
parentfe07617f803ffd24d02bc9645112caf4f5f9f54a (diff)
downloadllvm-78f7e6f04fed54619122d8ffcc5d11808d0f4feb.tar.gz
llvm-78f7e6f04fed54619122d8ffcc5d11808d0f4feb.tar.bz2
llvm-78f7e6f04fed54619122d8ffcc5d11808d0f4feb.tar.xz
Use Endian.h to simplify this code a bit.
While at it, factor some logic into FragmentWriter. This will allow more code to be factored out of the fairly large ELFObjectWriter. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@204765 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC/ELFObjectWriter.cpp')
-rw-r--r--lib/MC/ELFObjectWriter.cpp168
1 files changed, 64 insertions, 104 deletions
diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp
index fcf6d87e42..a484c1bf44 100644
--- a/lib/MC/ELFObjectWriter.cpp
+++ b/lib/MC/ELFObjectWriter.cpp
@@ -28,6 +28,7 @@
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCValue.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/Endian.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/ErrorHandling.h"
#include <vector>
@@ -37,7 +38,18 @@ using namespace llvm;
#define DEBUG_TYPE "reloc-info"
namespace {
+
+class FragmentWriter {
+ bool IsLittleEndian;
+
+public:
+ FragmentWriter(bool IsLittleEndian);
+ template <typename T> void write(MCDataFragment &F, T Val);
+};
+
class ELFObjectWriter : public MCObjectWriter {
+ FragmentWriter FWriter;
+
protected:
static bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind);
@@ -147,12 +159,10 @@ class ELFObjectWriter : public MCObjectWriter {
}
public:
- ELFObjectWriter(MCELFObjectTargetWriter *MOTW,
- raw_ostream &_OS, bool IsLittleEndian)
- : MCObjectWriter(_OS, IsLittleEndian),
- TargetObjectWriter(MOTW),
- NeedsGOT(false), NeedsSymtabShndx(false) {
- }
+ ELFObjectWriter(MCELFObjectTargetWriter *MOTW, raw_ostream &_OS,
+ bool IsLittleEndian)
+ : MCObjectWriter(_OS, IsLittleEndian), FWriter(IsLittleEndian),
+ TargetObjectWriter(MOTW), NeedsGOT(false), NeedsSymtabShndx(false) {}
virtual ~ELFObjectWriter();
@@ -163,78 +173,17 @@ class ELFObjectWriter : public MCObjectWriter {
Write32(W);
}
- void StringLE16(char *buf, uint16_t Value) {
- buf[0] = char(Value >> 0);
- buf[1] = char(Value >> 8);
- }
-
- void StringLE32(char *buf, uint32_t Value) {
- StringLE16(buf, uint16_t(Value >> 0));
- StringLE16(buf + 2, uint16_t(Value >> 16));
- }
-
- void StringLE64(char *buf, uint64_t Value) {
- StringLE32(buf, uint32_t(Value >> 0));
- StringLE32(buf + 4, uint32_t(Value >> 32));
- }
-
- void StringBE16(char *buf ,uint16_t Value) {
- buf[0] = char(Value >> 8);
- buf[1] = char(Value >> 0);
- }
-
- void StringBE32(char *buf, uint32_t Value) {
- StringBE16(buf, uint16_t(Value >> 16));
- StringBE16(buf + 2, uint16_t(Value >> 0));
- }
-
- void StringBE64(char *buf, uint64_t Value) {
- StringBE32(buf, uint32_t(Value >> 32));
- StringBE32(buf + 4, uint32_t(Value >> 0));
- }
-
- void String8(MCDataFragment &F, uint8_t Value) {
- char buf[1];
- buf[0] = Value;
- F.getContents().append(&buf[0], &buf[1]);
- }
-
- void String16(MCDataFragment &F, uint16_t Value) {
- char buf[2];
- if (isLittleEndian())
- StringLE16(buf, Value);
- else
- StringBE16(buf, Value);
- F.getContents().append(&buf[0], &buf[2]);
- }
-
- void String32(MCDataFragment &F, uint32_t Value) {
- char buf[4];
- if (isLittleEndian())
- StringLE32(buf, Value);
- else
- StringBE32(buf, Value);
- F.getContents().append(&buf[0], &buf[4]);
- }
-
- void String64(MCDataFragment &F, uint64_t Value) {
- char buf[8];
- if (isLittleEndian())
- StringLE64(buf, Value);
- else
- StringBE64(buf, Value);
- F.getContents().append(&buf[0], &buf[8]);
+ template <typename T> void write(MCDataFragment &F, T Value) {
+ FWriter.write(F, Value);
}
void WriteHeader(const MCAssembler &Asm,
uint64_t SectionDataSize,
unsigned NumberOfSections);
- void WriteSymbolEntry(MCDataFragment *SymtabF,
- MCDataFragment *ShndxF,
- uint64_t name, uint8_t info,
- uint64_t value, uint64_t size,
- uint8_t other, uint32_t shndx,
+ void WriteSymbolEntry(MCDataFragment *SymtabF, MCDataFragment *ShndxF,
+ uint32_t name, uint8_t info, uint64_t value,
+ uint64_t size, uint8_t other, uint32_t shndx,
bool Reserved);
void WriteSymbol(MCDataFragment *SymtabF, MCDataFragment *ShndxF,
@@ -333,6 +282,18 @@ class ELFObjectWriter : public MCObjectWriter {
};
}
+FragmentWriter::FragmentWriter(bool IsLittleEndian)
+ : IsLittleEndian(IsLittleEndian) {}
+
+template <typename T> void FragmentWriter::write(MCDataFragment &F, T Val) {
+ if (IsLittleEndian)
+ Val = support::endian::byte_swap<T, support::little>(Val);
+ else
+ Val = support::endian::byte_swap<T, support::big>(Val);
+ const char *Start = (const char *)&Val;
+ F.getContents().append(Start, Start + sizeof(T));
+}
+
bool ELFObjectWriter::isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind) {
const MCFixupKindInfo &FKI =
Asm.getBackend().getFixupKindInfo((MCFixupKind) Kind);
@@ -429,36 +390,34 @@ void ELFObjectWriter::WriteHeader(const MCAssembler &Asm,
}
void ELFObjectWriter::WriteSymbolEntry(MCDataFragment *SymtabF,
- MCDataFragment *ShndxF,
- uint64_t name,
+ MCDataFragment *ShndxF, uint32_t name,
uint8_t info, uint64_t value,
uint64_t size, uint8_t other,
- uint32_t shndx,
- bool Reserved) {
+ uint32_t shndx, bool Reserved) {
if (ShndxF) {
if (shndx >= ELF::SHN_LORESERVE && !Reserved)
- String32(*ShndxF, shndx);
+ write(*ShndxF, shndx);
else
- String32(*ShndxF, 0);
+ write(*ShndxF, uint32_t(0));
}
uint16_t Index = (shndx >= ELF::SHN_LORESERVE && !Reserved) ?
uint16_t(ELF::SHN_XINDEX) : shndx;
if (is64Bit()) {
- String32(*SymtabF, name); // st_name
- String8(*SymtabF, info); // st_info
- String8(*SymtabF, other); // st_other
- String16(*SymtabF, Index); // st_shndx
- String64(*SymtabF, value); // st_value
- String64(*SymtabF, size); // st_size
+ write(*SymtabF, name); // st_name
+ write(*SymtabF, info); // st_info
+ write(*SymtabF, other); // st_other
+ write(*SymtabF, Index); // st_shndx
+ write(*SymtabF, value); // st_value
+ write(*SymtabF, size); // st_size
} else {
- String32(*SymtabF, name); // st_name
- String32(*SymtabF, value); // st_value
- String32(*SymtabF, size); // st_size
- String8(*SymtabF, info); // st_info
- String8(*SymtabF, other); // st_other
- String16(*SymtabF, Index); // st_shndx
+ write(*SymtabF, name); // st_name
+ write(*SymtabF, uint32_t(value)); // st_value
+ write(*SymtabF, uint32_t(size)); // st_size
+ write(*SymtabF, info); // st_info
+ write(*SymtabF, other); // st_other
+ write(*SymtabF, Index); // st_shndx
}
}
@@ -1163,36 +1122,37 @@ void ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm,
if (!entry.Index)
;
+ // FIXME: this is most likely a bug if index overflows.
else if (entry.Index < 0)
entry.Index = getSymbolIndexInSymbolTable(Asm, entry.Symbol);
else
entry.Index += FileSymbolData.size() + LocalSymbolData.size();
if (is64Bit()) {
- String64(*F, entry.r_offset);
+ write(*F, entry.r_offset);
if (TargetObjectWriter->isN64()) {
- String32(*F, entry.Index);
+ write(*F, uint32_t(entry.Index));
- String8(*F, TargetObjectWriter->getRSsym(entry.Type));
- String8(*F, TargetObjectWriter->getRType3(entry.Type));
- String8(*F, TargetObjectWriter->getRType2(entry.Type));
- String8(*F, TargetObjectWriter->getRType(entry.Type));
+ write(*F, TargetObjectWriter->getRSsym(entry.Type));
+ write(*F, TargetObjectWriter->getRType3(entry.Type));
+ write(*F, TargetObjectWriter->getRType2(entry.Type));
+ write(*F, TargetObjectWriter->getRType(entry.Type));
}
else {
struct ELF::Elf64_Rela ERE64;
ERE64.setSymbolAndType(entry.Index, entry.Type);
- String64(*F, ERE64.r_info);
+ write(*F, ERE64.r_info);
}
if (hasRelocationAddend())
- String64(*F, entry.r_addend);
+ write(*F, entry.r_addend);
} else {
- String32(*F, entry.r_offset);
+ write(*F, uint32_t(entry.r_offset));
struct ELF::Elf32_Rela ERE32;
ERE32.setSymbolAndType(entry.Index, entry.Type);
- String32(*F, ERE32.r_info);
+ write(*F, ERE32.r_info);
if (hasRelocationAddend())
- String32(*F, entry.r_addend);
+ write(*F, uint32_t(entry.r_addend));
}
}
}
@@ -1340,7 +1300,7 @@ void ELFObjectWriter::CreateIndexedSections(MCAssembler &Asm,
MCSectionData &Data = Asm.getOrCreateSectionData(*Group);
Data.setAlignment(4);
MCDataFragment *F = new MCDataFragment(&Data);
- String32(*F, ELF::GRP_COMDAT);
+ write(*F, uint32_t(ELF::GRP_COMDAT));
}
GroupMap[Group] = SignatureSymbol;
}
@@ -1358,8 +1318,8 @@ void ELFObjectWriter::CreateIndexedSections(MCAssembler &Asm,
MCSectionData &Data = Asm.getOrCreateSectionData(*Group);
// FIXME: we could use the previous fragment
MCDataFragment *F = new MCDataFragment(&Data);
- unsigned Index = SectionIndexMap.lookup(&Section);
- String32(*F, Index);
+ uint32_t Index = SectionIndexMap.lookup(&Section);
+ write(*F, Index);
}
}