16a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom/*
26a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * Copyright (C) 2012 The Android Open Source Project
36a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom *
46a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * Licensed under the Apache License, Version 2.0 (the "License");
56a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * you may not use this file except in compliance with the License.
66a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * You may obtain a copy of the License at
76a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom *
86a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom *      http://www.apache.org/licenses/LICENSE-2.0
96a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom *
106a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * Unless required by applicable law or agreed to in writing, software
116a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * distributed under the License is distributed on an "AS IS" BASIS,
126a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * See the License for the specific language governing permissions and
146a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * limitations under the License.
156a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom */
166a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom
17fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#ifndef ART_COMPILER_ELF_WRITER_QUICK_H_
18fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#define ART_COMPILER_ELF_WRITER_QUICK_H_
196a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom
20b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom#include "elf_utils.h"
216a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#include "elf_writer.h"
22b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom#include "instruction_set.h"
236a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom
246a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstromnamespace art {
256a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom
263d504075f7c1204d581923460754bf6d3714b13fIan Rogersclass ElfWriterQuick FINAL : public ElfWriter {
276a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom public:
286a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom  // Write an ELF file. Returns true on success, false on failure.
296a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom  static bool Create(File* file,
303d504075f7c1204d581923460754bf6d3714b13fIan Rogers                     OatWriter* oat_writer,
316a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom                     const std::vector<const DexFile*>& dex_files,
326a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom                     const std::string& android_root,
336a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom                     bool is_host,
346a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom                     const CompilerDriver& driver)
356a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
366a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom
376a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom protected:
383d504075f7c1204d581923460754bf6d3714b13fIan Rogers  bool Write(OatWriter* oat_writer,
393d504075f7c1204d581923460754bf6d3714b13fIan Rogers             const std::vector<const DexFile*>& dex_files,
403d504075f7c1204d581923460754bf6d3714b13fIan Rogers             const std::string& android_root,
413d504075f7c1204d581923460754bf6d3714b13fIan Rogers             bool is_host)
423d504075f7c1204d581923460754bf6d3714b13fIan Rogers      OVERRIDE
436a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
446a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom
456a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom private:
463d504075f7c1204d581923460754bf6d3714b13fIan Rogers  ElfWriterQuick(const CompilerDriver& driver, File* elf_file)
473d504075f7c1204d581923460754bf6d3714b13fIan Rogers    : ElfWriter(driver, elf_file) {}
483d504075f7c1204d581923460754bf6d3714b13fIan Rogers  ~ElfWriterQuick() {}
496a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom
50b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom  class ElfBuilder;
5178382fa44ee505cf16835e4d22515e7252a90864Alex Light  void AddDebugSymbols(ElfBuilder& builder,
5278382fa44ee505cf16835e4d22515e7252a90864Alex Light                       OatWriter* oat_writer,
5378382fa44ee505cf16835e4d22515e7252a90864Alex Light                       bool debug);
5453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  void ReservePatchSpace(std::vector<uint8_t>* buffer, bool debug);
5578382fa44ee505cf16835e4d22515e7252a90864Alex Light
56b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom  class ElfSectionBuilder {
57b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom   public:
58b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    ElfSectionBuilder(const std::string& sec_name, Elf32_Word type, Elf32_Word flags,
59b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom                      const ElfSectionBuilder *link, Elf32_Word info, Elf32_Word align,
60b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom                      Elf32_Word entsize)
61b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom        : name_(sec_name), link_(link) {
62b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom      memset(&section_, 0, sizeof(section_));
63b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom      section_.sh_type = type;
64b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom      section_.sh_flags = flags;
65b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom      section_.sh_info = info;
66b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom      section_.sh_addralign = align;
67b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom      section_.sh_entsize = entsize;
68b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    }
69b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom
70b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    virtual ~ElfSectionBuilder() {}
71b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom
72b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    Elf32_Shdr section_;
73b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    Elf32_Word section_index_ = 0;
74b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom
75b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom   protected:
76b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    const std::string name_;
77b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    const ElfSectionBuilder* link_;
78b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom
79b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    Elf32_Word GetLink() {
80b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom      return (link_) ? link_->section_index_ : 0;
81b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    }
82b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom
83b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom   private:
84b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    friend class ElfBuilder;
85b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom  };
86b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom
87b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom  class ElfDynamicBuilder : public ElfSectionBuilder {
88b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom   public:
898758c64a40e74ebb492a348556ec7b25a89c1491Brian Carlstrom    void AddDynamicTag(Elf32_Sword tag, Elf32_Word d_un);
908758c64a40e74ebb492a348556ec7b25a89c1491Brian Carlstrom    void AddDynamicTag(Elf32_Sword tag, Elf32_Word offset, ElfSectionBuilder* section);
91b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom
92b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    ElfDynamicBuilder(const std::string& sec_name, ElfSectionBuilder *link)
93b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom        : ElfSectionBuilder(sec_name, SHT_DYNAMIC, SHF_ALLOC | SHF_ALLOC, link,
94b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom                            0, kPageSize, sizeof(Elf32_Dyn)) {}
95b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    ~ElfDynamicBuilder() {}
96b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom
97b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom   protected:
98b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    struct ElfDynamicState {
99b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom      ElfSectionBuilder* section_;
100b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom      Elf32_Sword tag_;
1018758c64a40e74ebb492a348556ec7b25a89c1491Brian Carlstrom      Elf32_Word off_;
102b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    };
103b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    std::vector<ElfDynamicState> dynamics_;
1048758c64a40e74ebb492a348556ec7b25a89c1491Brian Carlstrom    Elf32_Word GetSize() {
105b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom      // Add 1 for the DT_NULL, 1 for DT_STRSZ, and 1 for DT_SONAME. All of
106b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom      // these must be added when we actually put the file together because
107b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom      // their values are very dependent on state.
108b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom      return dynamics_.size() + 3;
109b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    }
110b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom
111b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    // Create the actual dynamic vector. strsz should be the size of the .dynstr
112b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    // table and soname_off should be the offset of the soname in .dynstr.
113b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    // Since niether can be found prior to final layout we will wait until here
114b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    // to add them.
1158758c64a40e74ebb492a348556ec7b25a89c1491Brian Carlstrom    std::vector<Elf32_Dyn> GetDynamics(Elf32_Word strsz, Elf32_Word soname_off);
116b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom
117b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom   private:
118b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    friend class ElfBuilder;
119b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom  };
120b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom
121b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom  class ElfRawSectionBuilder : public ElfSectionBuilder {
122b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom   public:
123b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    ElfRawSectionBuilder(const std::string& sec_name, Elf32_Word type, Elf32_Word flags,
124b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom                         const ElfSectionBuilder* link, Elf32_Word info, Elf32_Word align,
125b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom                         Elf32_Word entsize)
126b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom        : ElfSectionBuilder(sec_name, type, flags, link, info, align, entsize) {}
127b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    ~ElfRawSectionBuilder() {}
128b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    std::vector<uint8_t>* GetBuffer() { return &buf_; }
129b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    void SetBuffer(std::vector<uint8_t> buf) { buf_ = buf; }
130b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom
131b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom   protected:
132b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    std::vector<uint8_t> buf_;
133b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom
134b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom   private:
135b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    friend class ElfBuilder;
136b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom  };
137b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom
138b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom  class ElfOatSectionBuilder : public ElfSectionBuilder {
139b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom   public:
140b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    ElfOatSectionBuilder(const std::string& sec_name, Elf32_Word size, Elf32_Word offset,
141b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom                         Elf32_Word type, Elf32_Word flags)
142b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom        : ElfSectionBuilder(sec_name, type, flags, NULL, 0, kPageSize, 0),
143b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom          offset_(offset), size_(size) {}
144b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    ~ElfOatSectionBuilder() {}
145b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom
146b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom   protected:
147b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    // Offset of the content within the file.
148b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    Elf32_Word offset_;
149b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    // Size of the content within the file.
150b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    Elf32_Word size_;
151b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom
152b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom   private:
153b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    friend class ElfBuilder;
154b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom  };
155b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom
156b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom  class ElfSymtabBuilder : public ElfSectionBuilder {
157b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom   public:
158b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    // Add a symbol with given name to this symtab. The symbol refers to
159b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    // 'relative_addr' within the given section and has the given attributes.
160b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    void AddSymbol(const std::string& name,
161b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom                   const ElfSectionBuilder* section,
162b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom                   Elf32_Addr addr,
163b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom                   bool is_relative,
164b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom                   Elf32_Word size,
165b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom                   uint8_t binding,
166b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom                   uint8_t type,
167b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom                   uint8_t other = 0);
168b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom
169b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    ElfSymtabBuilder(const std::string& sec_name, Elf32_Word type,
170b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom                     const std::string& str_name, Elf32_Word str_type, bool alloc)
171e130ee6fe902315062ce17f8ce115b1dc506576dBrian Carlstrom        : ElfSectionBuilder(sec_name, type, ((alloc) ? SHF_ALLOC : 0U), &strtab_, 0,
172b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom                            sizeof(Elf32_Word), sizeof(Elf32_Sym)),
173b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom          str_name_(str_name), str_type_(str_type),
174e130ee6fe902315062ce17f8ce115b1dc506576dBrian Carlstrom          strtab_(str_name, str_type, ((alloc) ? SHF_ALLOC : 0U), NULL, 0, 1, 1) {}
175b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    ~ElfSymtabBuilder() {}
176b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom
177b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom   protected:
178b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    std::vector<Elf32_Word> GenerateHashContents();
179b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    std::string GenerateStrtab();
180b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    std::vector<Elf32_Sym> GenerateSymtab();
181b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom
1828758c64a40e74ebb492a348556ec7b25a89c1491Brian Carlstrom    Elf32_Word GetSize() {
183b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom      // 1 is for the implicit NULL symbol.
184b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom      return symbols_.size() + 1;
185b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    }
186b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom
187b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    struct ElfSymbolState {
188b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom      const std::string name_;
189b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom      const ElfSectionBuilder* section_;
190b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom      Elf32_Addr addr_;
191b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom      Elf32_Word size_;
192b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom      bool is_relative_;
193b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom      uint8_t info_;
194b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom      uint8_t other_;
195b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom      // Used during Write() to temporarially hold name index in the strtab.
196b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom      Elf32_Word name_idx_;
197b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    };
198b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom
199b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    // Information for the strsym for dynstr sections.
200b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    const std::string str_name_;
201b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    Elf32_Word str_type_;
202b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    // The symbols in the same order they will be in the symbol table.
203b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    std::vector<ElfSymbolState> symbols_;
204b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    ElfSectionBuilder strtab_;
205b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom
206b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom   private:
207b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    friend class ElfBuilder;
208b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom  };
209b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom
210b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom  class ElfBuilder FINAL {
211b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom   public:
212b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    ElfBuilder(OatWriter* oat_writer,
213b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom               File* elf_file,
214b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom               InstructionSet isa,
215b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom               Elf32_Word rodata_relative_offset,
216b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom               Elf32_Word rodata_size,
217b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom               Elf32_Word text_relative_offset,
218b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom               Elf32_Word text_size,
219b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom               const bool add_symbols,
220b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom               bool debug = false)
221b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom        : oat_writer_(oat_writer),
222b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom          elf_file_(elf_file),
223b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom          add_symbols_(add_symbols),
224b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom          debug_logging_(debug),
225b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom          text_builder_(".text", text_size, text_relative_offset, SHT_PROGBITS,
226b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom                        SHF_ALLOC | SHF_EXECINSTR),
227b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom          rodata_builder_(".rodata", rodata_size, rodata_relative_offset,
228b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom                          SHT_PROGBITS, SHF_ALLOC),
229b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom          dynsym_builder_(".dynsym", SHT_DYNSYM, ".dynstr", SHT_STRTAB, true),
230b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom          symtab_builder_(".symtab", SHT_SYMTAB, ".strtab", SHT_STRTAB, false),
231b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom          hash_builder_(".hash", SHT_HASH, SHF_ALLOC, &dynsym_builder_, 0,
232b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom                        sizeof(Elf32_Word), sizeof(Elf32_Word)),
233b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom          dynamic_builder_(".dynamic", &dynsym_builder_),
234b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom          shstrtab_builder_(".shstrtab", SHT_STRTAB, 0, NULL, 0, 1, 1) {
235b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom      SetupEhdr();
236b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom      SetupDynamic();
237b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom      SetupRequiredSymbols();
238b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom      SetISA(isa);
239b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    }
240b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    ~ElfBuilder() {}
241b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom
242b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    bool Write();
243b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom
244b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    // Adds the given raw section to the builder. This will copy it. The caller
245b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    // is responsible for deallocating their copy.
246b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    void RegisterRawSection(ElfRawSectionBuilder bld) {
247b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom      other_builders_.push_back(bld);
248b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    }
249b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom
250b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom   private:
251b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    OatWriter* oat_writer_;
252b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    File* elf_file_;
253b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    const bool add_symbols_;
254b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    const bool debug_logging_;
255b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom
256b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    bool fatal_error_ = false;
257b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom
258b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    Elf32_Ehdr elf_header_;
259b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom
260b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom   public:
261b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    ElfOatSectionBuilder text_builder_;
262b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    ElfOatSectionBuilder rodata_builder_;
263b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    ElfSymtabBuilder dynsym_builder_;
264b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    ElfSymtabBuilder symtab_builder_;
265b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    ElfSectionBuilder hash_builder_;
266b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    ElfDynamicBuilder dynamic_builder_;
267b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    ElfSectionBuilder shstrtab_builder_;
268b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    std::vector<ElfRawSectionBuilder> other_builders_;
269b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom
270b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom   private:
271b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    void SetISA(InstructionSet isa);
272b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    void SetupEhdr();
273b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom
274b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    // Sets up a bunch of the required Dynamic Section entries.
275b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    // Namely it will initialize all the mandatory ones that it can.
276b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    // Specifically:
277b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    // DT_HASH
278b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    // DT_STRTAB
279b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    // DT_SYMTAB
280b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    // DT_SYMENT
281b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    //
282b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    // Some such as DT_SONAME, DT_STRSZ and DT_NULL will be put in later.
283b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    void SetupDynamic();
284b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom
285b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    // Sets up the basic dynamic symbols that are needed, namely all those we
286b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    // can know already.
287b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    //
288b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    // Specifically adds:
289b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    // oatdata
290b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    // oatexec
291b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    // oatlastword
292b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    void SetupRequiredSymbols();
293b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom    void AssignSectionStr(ElfSectionBuilder *builder, std::string* strtab);
294b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom
2958758c64a40e74ebb492a348556ec7b25a89c1491Brian Carlstrom    bool IncludingDebugSymbols() { return add_symbols_ && symtab_builder_.GetSize() > 1; }
296b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom  };
297b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom
298ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  /*
299ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell   * @brief Generate the DWARF debug_info and debug_abbrev sections
300ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell   * @param oat_writer The Oat file Writer.
301ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell   * @param dbg_info Compilation unit information.
302ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell   * @param dbg_abbrev Abbreviations used to generate dbg_info.
303ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell   * @param dbg_str Debug strings.
304ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell   */
305ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  void FillInCFIInformation(OatWriter* oat_writer, std::vector<uint8_t>* dbg_info,
306ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell                            std::vector<uint8_t>* dbg_abbrev, std::vector<uint8_t>* dbg_str);
307ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell
3086a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom  DISALLOW_IMPLICIT_CONSTRUCTORS(ElfWriterQuick);
3096a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom};
3106a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom
3116a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom}  // namespace art
3126a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom
313fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif  // ART_COMPILER_ELF_WRITER_QUICK_H_
314