aboutsummaryrefslogtreecommitdiff
path: root/src/common/linux/synth_elf.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/linux/synth_elf.h')
-rw-r--r--src/common/linux/synth_elf.h155
1 files changed, 155 insertions, 0 deletions
diff --git a/src/common/linux/synth_elf.h b/src/common/linux/synth_elf.h
new file mode 100644
index 00000000..215fd997
--- /dev/null
+++ b/src/common/linux/synth_elf.h
@@ -0,0 +1,155 @@
+// -*- mode: C++ -*-
+
+// Copyright (c) 2011, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Original author: Ted Mielczarek <ted.mielczarek@gmail.com>
+
+// synth_elf.h: Interface to synth_elf::ELF: fake ELF generator.
+
+#ifndef COMMON_LINUX_SYNTH_ELF_H_
+#define COMMON_LINUX_SYNTH_ELF_H_
+
+#include "common/test_assembler.h"
+
+#include <list>
+#include <map>
+#include <string>
+#include <utility>
+
+namespace google_breakpad {
+namespace synth_elf {
+
+using std::list;
+using std::map;
+using std::pair;
+using std::string;
+using test_assembler::Endianness;
+using test_assembler::kLittleEndian;
+using test_assembler::kUnsetEndian;
+using test_assembler::Label;
+using test_assembler::Section;
+
+// String tables are common in ELF headers, so subclass Section
+// to make them easy to generate.
+class StringTable : public Section {
+public:
+ StringTable(Endianness endianness = kUnsetEndian)
+ : Section(endianness) {
+ start() = 0;
+ empty_string = Add("");
+ }
+
+ // Add the string s to the string table, and return
+ // a label containing the offset into the string table
+ // at which it was added.
+ Label Add(const string& s) {
+ if (strings_.find(s) != strings_.end())
+ return strings_[s];
+
+ Label string_label(Here());
+ AppendCString(s);
+ strings_[s] = string_label;
+ return string_label;
+ }
+
+ // All StringTables contain an empty string as their first
+ // entry.
+ Label empty_string;
+
+ // Avoid inserting duplicate strings.
+ map<string,Label> strings_;
+};
+
+// A Section representing an entire ELF file.
+class ELF : public Section {
+ public:
+ ELF(uint16_t machine, // EM_386, etc
+ uint8_t file_class, // ELFCLASS{32,64}
+ Endianness endianness = kLittleEndian);
+
+ // Add the Section section to the section header table and append it
+ // to the file. Returns the index of the section in the section
+ // header table.
+ int AddSection(const string& name, const Section& section,
+ uint32_t type, uint32_t flags = 0, uint64_t addr = 0,
+ uint32_t link = 0, uint64_t entsize = 0, uint64_t offset = 0);
+
+ // Write out all data. GetContents may be used after this.
+ void Finish();
+
+ private:
+ // Size of an address, in bytes.
+ const size_t addr_size_;
+
+ // Offset to the program header table.
+ Label program_header_label_;
+ // Number of entries in the program header table.
+ int program_count_;
+ Label program_count_label_;
+
+ // Offset to the section header table.
+ Label section_header_label_;
+ // Number of entries in the section header table.
+ int section_count_;
+ Label section_count_label_;
+ // The section header table itself.
+ Section section_header_table_;
+
+ // Index of the section header string table in the section
+ // header table.
+ Label section_header_string_index_;
+ // Section containing the names of section header table entries.
+ StringTable section_header_strings_;
+};
+
+// A class to build .symtab or .dynsym sections.
+class SymbolTable : public Section {
+ public:
+ // table is the StringTable that contains symbol names. The caller
+ // must ensure that it remains alive for the life of the
+ // SymbolTable.
+ SymbolTable(Endianness endianness, size_t addr_size, StringTable& table);
+
+ // Add an Elf32_Sym.
+ void AddSymbol(const string& name, uint32_t value,
+ uint32_t size, unsigned info, uint16_t shndx);
+ // Add an Elf64_Sym.
+ void AddSymbol(const string& name, uint64_t value,
+ uint64_t size, unsigned info, uint16_t shndx);
+
+ private:
+ size_t addr_size_;
+ StringTable& table_;
+};
+
+} // namespace synth_elf
+} // namespace google_breakpad
+
+#endif // COMMON_LINUX_SYNTH_ELF_H_