OSDN Git Service

d743efbde65463f73e6f5e97247aad2299a4e2dd
[android-x86/external-llvm.git] / tools / llvm-objcopy / Object.h
1 //===- Object.h -------------------------------------------------*- C++ -*-===//
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 #ifndef LLVM_OBJCOPY_OBJECT_H
11 #define LLVM_OBJCOPY_OBJECT_H
12
13 #include "llvm/MC/StringTableBuilder.h"
14 #include "llvm/Object/ELFObjectFile.h"
15 #include "llvm/Support/FileOutputBuffer.h"
16
17 #include <memory>
18 #include <set>
19
20 class Segment;
21
22 class SectionBase {
23 public:
24   llvm::StringRef Name;
25   Segment *ParentSegment = nullptr;
26   uint64_t HeaderOffset;
27   uint64_t OriginalOffset;
28   uint32_t Index;
29
30   uint64_t Addr = 0;
31   uint64_t Align = 1;
32   uint32_t EntrySize = 0;
33   uint64_t Flags = 0;
34   uint64_t Info = 0;
35   uint64_t Link = llvm::ELF::SHN_UNDEF;
36   uint64_t NameIndex = 0;
37   uint64_t Offset = 0;
38   uint64_t Size = 0;
39   uint64_t Type = llvm::ELF::SHT_NULL;
40
41   virtual ~SectionBase() {}
42   virtual void finalize();
43   template <class ELFT> void writeHeader(llvm::FileOutputBuffer &Out) const;
44   virtual void writeSection(llvm::FileOutputBuffer &Out) const = 0;
45 };
46
47 class Segment {
48 private:
49   struct SectionCompare {
50     bool operator()(const SectionBase *Lhs, const SectionBase *Rhs) const {
51       // Some sections might have the same address if one of them is empty. To
52       // fix this we can use the lexicographic ordering on ->Addr and the
53       // address of the actully stored section.
54       if (Lhs->OriginalOffset == Rhs->OriginalOffset)
55         return Lhs < Rhs;
56       return Lhs->OriginalOffset < Rhs->OriginalOffset;
57     }
58   };
59
60   std::set<const SectionBase *, SectionCompare> Sections;
61
62 public:
63   uint64_t Align;
64   uint64_t FileSize;
65   uint32_t Flags;
66   uint32_t Index;
67   uint64_t MemSize;
68   uint64_t Offset;
69   uint64_t PAddr;
70   uint64_t Type;
71   uint64_t VAddr;
72
73   void finalize();
74   const SectionBase *firstSection() const {
75     if (!Sections.empty())
76       return *Sections.begin();
77     return nullptr;
78   }
79   void addSection(const SectionBase *sec) { Sections.insert(sec); }
80   template <class ELFT> void writeHeader(llvm::FileOutputBuffer &Out) const;
81 };
82
83 class Section : public SectionBase {
84 private:
85   llvm::ArrayRef<uint8_t> Contents;
86
87 public:
88   Section(llvm::ArrayRef<uint8_t> Data) : Contents(Data) {}
89   void writeSection(llvm::FileOutputBuffer &Out) const override;
90 };
91
92 // This is just a wraper around a StringTableBuilder that implements SectionBase
93 class StringTableSection : public SectionBase {
94 private:
95   llvm::StringTableBuilder StrTabBuilder;
96
97 public:
98   StringTableSection() : StrTabBuilder(llvm::StringTableBuilder::ELF) {
99     Type = llvm::ELF::SHT_STRTAB;
100   }
101
102   void addString(llvm::StringRef Name);
103   uint32_t findIndex(llvm::StringRef Name) const;
104   void finalize() override;
105   void writeSection(llvm::FileOutputBuffer &Out) const override;
106   static bool classof(const SectionBase *S) {
107     return S->Type == llvm::ELF::SHT_STRTAB;
108   }
109 };
110
111 template <class ELFT> class Object {
112 private:
113   typedef std::unique_ptr<SectionBase> SecPtr;
114   typedef std::unique_ptr<Segment> SegPtr;
115
116   typedef typename ELFT::Shdr Elf_Shdr;
117   typedef typename ELFT::Ehdr Elf_Ehdr;
118   typedef typename ELFT::Phdr Elf_Phdr;
119
120   StringTableSection *SectionNames;
121   std::vector<SecPtr> Sections;
122   std::vector<SegPtr> Segments;
123
124   void sortSections();
125   void assignOffsets();
126   SecPtr makeSection(const llvm::object::ELFFile<ELFT> &ElfFile,
127                      const Elf_Shdr &Shdr);
128   void readProgramHeaders(const llvm::object::ELFFile<ELFT> &ElfFile);
129   void readSectionHeaders(const llvm::object::ELFFile<ELFT> &ElfFile);
130   void writeHeader(llvm::FileOutputBuffer &Out) const;
131   void writeProgramHeaders(llvm::FileOutputBuffer &Out) const;
132   void writeSectionData(llvm::FileOutputBuffer &Out) const;
133   void writeSectionHeaders(llvm::FileOutputBuffer &Out) const;
134
135 public:
136   uint8_t Ident[16];
137   uint64_t Entry;
138   uint64_t SHOffset;
139   uint32_t Type;
140   uint32_t Machine;
141   uint32_t Version;
142   uint32_t Flags;
143
144   Object(const llvm::object::ELFObjectFile<ELFT> &Obj);
145   size_t totalSize() const;
146   void finalize();
147   void write(llvm::FileOutputBuffer &Out);
148 };
149
150 #endif