llvm.org GIT mirror llvm / 0382b30
[yaml2obj][ELF] Start factoring into "single point of truth". git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@184457 91177308-0d34-0410-b5e6-96231b3b80d8 Sean Silva 7 years ago
1 changed file(s) with 51 addition(s) and 19 deletion(s). Raw diff Collapse all Expand all
133133 SHeader.sh_addralign = 1;
134134 }
135135
136 // FIXME: This function is hideous. Between the sheer number of parameters
137 // and the hideous ELF typenames, it's just a travesty. Factor the ELF
138 // output into a class (templated on ELFT) and share some typedefs.
136 namespace {
137 /// \brief "Single point of truth" for the ELF file construction.
138 /// TODO: This class still has a ways to go before it is truly a "single
139 /// point of truth".
140 template
141 class ELFState {
142 /// \brief The future ".strtab" section.
143 StringTableBuilder DotStrtab;
144 /// \brief The section number of the ".strtab" section.
145 unsigned DotStrtabSecNo;
146 /// \brief The accumulated contents of all sections so far.
147 ContiguousBlobAccumulator &SectionContentAccum;
148 typedef typename object::ELFObjectFile::Elf_Ehdr Elf_Ehdr;
149 /// \brief The ELF file header.
150 Elf_Ehdr &Header;
151
152 public:
153
154 ELFState(Elf_Ehdr &Header_, ContiguousBlobAccumulator &Accum,
155 unsigned DotStrtabSecNo_)
156 : DotStrtab(), DotStrtabSecNo(DotStrtabSecNo_),
157 SectionContentAccum(Accum), Header(Header_) {}
158
159 unsigned getDotStrTabSecNo() const { return DotStrtabSecNo; }
160 StringTableBuilder &getStringTable() { return DotStrtab; }
161 ContiguousBlobAccumulator &getSectionContentAccum() {
162 return SectionContentAccum;
163 }
164 };
165 } // end anonymous namespace
166
167 // FIXME: This function is hideous. The hideous ELF type names are hideous.
168 // Factor the ELF output into a class (templated on ELFT) and share some
169 // typedefs.
139170 template
140171 static void handleSymtabSectionHeader(
141 const ELFYAML::Section &Sec,
142 typename object::ELFObjectFile::Elf_Shdr &SHeader,
143 StringTableBuilder &StrTab, ContiguousBlobAccumulator &CBA,
144 unsigned DotStrtabSecNo) {
172 const ELFYAML::Section &Sec, ELFState &State,
173 typename object::ELFObjectFile::Elf_Shdr &SHeader) {
145174
146175 typedef typename object::ELFObjectFile::Elf_Sym Elf_Sym;
147176 // TODO: Ensure that a manually specified `Link` field is diagnosed as an
148177 // error for SHT_SYMTAB.
149 SHeader.sh_link = DotStrtabSecNo;
178 SHeader.sh_link = State.getDotStrTabSecNo();
150179 // TODO: Once we handle symbol binding, this should be one greater than
151180 // symbol table index of the last local symbol.
152181 SHeader.sh_info = 0;
164193 Elf_Sym Symbol;
165194 zero(Symbol);
166195 if (!Sym.Name.empty())
167 Symbol.st_name = StrTab.addString(Sym.Name);
196 Symbol.st_name = State.getStringTable().addString(Sym.Name);
168197 Symbol.setBindingAndType(Sym.Binding, Sym.Type);
169198 Syms.push_back(Symbol);
170199 }
171200
201 ContiguousBlobAccumulator &CBA = State.getSectionContentAccum();
172202 SHeader.sh_offset = CBA.currentOffset();
173203 SHeader.sh_size = vectorDataSize(Syms);
174204 writeVectorData(CBA.getOS(), Syms);
216246 Header.e_shstrndx = Header.e_shnum - 1;
217247 const unsigned DotStrtabSecNo = Header.e_shnum - 2;
218248
249 // XXX: This offset is tightly coupled with the order that we write
250 // things to `OS`.
251 const size_t SectionContentBeginOffset =
252 Header.e_ehsize + Header.e_shentsize * Header.e_shnum;
253 ContiguousBlobAccumulator CBA(SectionContentBeginOffset);
254 ELFState State(Header, CBA, DotStrtabSecNo);
255
219256 SectionNameToIdxMap SN2I;
220257 for (unsigned i = 0, e = Sections.size(); i != e; ++i) {
221258 StringRef Name = Sections[i].Name;
230267 }
231268
232269 StringTableBuilder SHStrTab;
233 // XXX: This offset is tightly coupled with the order that we write
234 // things to `OS`.
235 const size_t SectionContentBeginOffset =
236 Header.e_ehsize + Header.e_shentsize * Header.e_shnum;
237 ContiguousBlobAccumulator CBA(SectionContentBeginOffset);
238270 std::vector SHeaders;
239271 {
240272 // Ensure SHN_UNDEF entry is present. An all-zero section header is a
243275 zero(SHdr);
244276 SHeaders.push_back(SHdr);
245277 }
246 StringTableBuilder DotStrTab;
247278 for (unsigned i = 0, e = Sections.size(); i != e; ++i) {
248279 const ELFYAML::Section &Sec = Sections[i];
249280 Elf_Shdr SHeader;
269300 SHeader.sh_info = 0;
270301 SHeader.sh_addralign = Sec.AddressAlign;
271302 SHeader.sh_entsize = 0;
272 // XXX: Really ugly right now. Need to put common state into a class.
303 // XXX: Really ugly right now. Should not be writing to `CBA` above
304 // (and setting sh_offset and sh_size) when going through this branch
305 // here.
273306 if (Sec.Type == ELFYAML::ELF_SHT(SHT_SYMTAB))
274 handleSymtabSectionHeader(Sec, SHeader, DotStrTab, CBA,
275 DotStrtabSecNo);
307 handleSymtabSectionHeader(Sec, State, SHeader);
276308 SHeaders.push_back(SHeader);
277309 }
278310
280312 Elf_Shdr DotStrTabSHeader;
281313 zero(DotStrTabSHeader);
282314 DotStrTabSHeader.sh_name = SHStrTab.addString(StringRef(".strtab"));
283 createStringTableSectionHeader(DotStrTabSHeader, DotStrTab, CBA);
315 createStringTableSectionHeader(DotStrTabSHeader, State.getStringTable(), CBA);
284316
285317 // Section header string table header.
286318 Elf_Shdr SHStrTabSHeader;