13ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek#include "common/linux/synth_elf.h"
23ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
33ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek#include <assert.h>
43ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek#include <elf.h>
53ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek#include <stdio.h>
68ade75f9558e31d25aec862a552fe78f9ba98c82ted.mielczarek#include <string.h>
73ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
86cddd17e9db8be3e6c39cb64fcf58e883ca8f19cthestig@chromium.org#include "common/linux/elf_gnu_compat.h"
94e518a4357a2d1c379d4a91df6d4e153ee791101ivan.penkov@gmail.com#include "common/using_std_string.h"
104e518a4357a2d1c379d4a91df6d4e153ee791101ivan.penkov@gmail.com
113ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczareknamespace google_breakpad {
123ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczareknamespace synth_elf {
133ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
143ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarekELF::ELF(uint16_t machine,
153ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek         uint8_t file_class,
163ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek         Endianness endianness)
173ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  : Section(endianness),
183ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    addr_size_(file_class == ELFCLASS64 ? 8 : 4),
193ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    program_count_(0),
20cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com    program_header_table_(endianness),
213ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    section_count_(0),
223ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    section_header_table_(endianness),
233ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    section_header_strings_(endianness) {
243ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  // Could add support for more machine types here if needed.
253ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  assert(machine == EM_386 ||
263ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek         machine == EM_X86_64 ||
273ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek         machine == EM_ARM);
283ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  assert(file_class == ELFCLASS32 || file_class == ELFCLASS64);
293ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
303ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  start() = 0;
313ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  // Add ELF header
323ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  // e_ident
333ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  // EI_MAG0...EI_MAG3
343ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  D8(ELFMAG0);
353ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  D8(ELFMAG1);
363ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  D8(ELFMAG2);
373ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  D8(ELFMAG3);
383ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  // EI_CLASS
393ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  D8(file_class);
403ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  // EI_DATA
413ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  D8(endianness == kLittleEndian ? ELFDATA2LSB : ELFDATA2MSB);
423ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  // EI_VERSION
433ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  D8(EV_CURRENT);
443ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  // EI_OSABI
453ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  D8(ELFOSABI_SYSV);
463ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  // EI_ABIVERSION
473ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  D8(0);
483ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  // EI_PAD
493ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  Append(7, 0);
503ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  assert(Size() == EI_NIDENT);
513ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
523ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  // e_type
533ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  D16(ET_EXEC);  //TODO: allow passing ET_DYN?
543ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  // e_machine
553ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  D16(machine);
563ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  // e_version
573ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  D32(EV_CURRENT);
583ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  // e_entry
593ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  Append(endianness, addr_size_, 0);
603ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  // e_phoff
613ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  Append(endianness, addr_size_, program_header_label_);
623ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  // e_shoff
633ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  Append(endianness, addr_size_, section_header_label_);
643ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  // e_flags
653ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  D32(0);
663ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  // e_ehsize
673ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  D16(addr_size_ == 8 ? sizeof(Elf64_Ehdr) : sizeof(Elf32_Ehdr));
683ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  // e_phentsize
693ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  D16(addr_size_ == 8 ? sizeof(Elf64_Phdr) : sizeof(Elf32_Phdr));
703ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  // e_phnum
713ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  D16(program_count_label_);
723ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  // e_shentsize
733ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  D16(addr_size_ == 8 ? sizeof(Elf64_Shdr) : sizeof(Elf32_Shdr));
743ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  // e_shnum
753ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  D16(section_count_label_);
763ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  // e_shstrndx
773ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  D16(section_header_string_index_);
783ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
793ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  // Add an empty section for SHN_UNDEF.
803ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  Section shn_undef;
813ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  AddSection("", shn_undef, SHT_NULL);
823ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek}
833ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
843ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarekint ELF::AddSection(const string& name, const Section& section,
853ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek                    uint32_t type, uint32_t flags, uint64_t addr,
863ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek                    uint32_t link, uint64_t entsize, uint64_t offset) {
873ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  Label offset_label;
883ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  Label string_label(section_header_strings_.Add(name));
893ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  size_t size = section.Size();
903ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
913ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  int index = section_count_;
923ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  ++section_count_;
933ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
943ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  section_header_table_
953ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    // sh_name
963ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    .D32(string_label)
973ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    // sh_type
983ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    .D32(type)
993ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    // sh_flags
1003ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    .Append(endianness(), addr_size_, flags)
1013ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    // sh_addr
1023ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    .Append(endianness(), addr_size_, addr)
1033ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    // sh_offset
1043ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    .Append(endianness(), addr_size_, offset_label)
1053ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    // sh_size
1063ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    .Append(endianness(), addr_size_, size)
1073ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    // sh_link
1083ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    .D32(link)
1093ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    // sh_info
1103ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    .D32(0)
1113ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    // sh_addralign
1123ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    .Append(endianness(), addr_size_, 0)
1133ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    // sh_entsize
1143ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    .Append(endianness(), addr_size_, entsize);
1153ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
116cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  sections_.push_back(ElfSection(section, type, addr, offset, offset_label,
117cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com                                 size));
118cbf39e56602e459e270b1f7e415a3b8fb1f63f81ted.mielczarek@gmail.com  return index;
119cbf39e56602e459e270b1f7e415a3b8fb1f63f81ted.mielczarek@gmail.com}
120cbf39e56602e459e270b1f7e415a3b8fb1f63f81ted.mielczarek@gmail.com
121cbf39e56602e459e270b1f7e415a3b8fb1f63f81ted.mielczarek@gmail.comvoid ELF::AppendSection(ElfSection &section) {
1223ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  // NULL and NOBITS sections have no content, so they
1233ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  // don't need to be written to the file.
124cbf39e56602e459e270b1f7e415a3b8fb1f63f81ted.mielczarek@gmail.com  if (section.type_ == SHT_NULL) {
125cbf39e56602e459e270b1f7e415a3b8fb1f63f81ted.mielczarek@gmail.com    section.offset_label_ = 0;
126cbf39e56602e459e270b1f7e415a3b8fb1f63f81ted.mielczarek@gmail.com  } else if (section.type_ == SHT_NOBITS) {
127cbf39e56602e459e270b1f7e415a3b8fb1f63f81ted.mielczarek@gmail.com    section.offset_label_ = section.offset_;
1283ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  } else {
129cbf39e56602e459e270b1f7e415a3b8fb1f63f81ted.mielczarek@gmail.com    Mark(&section.offset_label_);
1303ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    Append(section);
1313ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    Align(4);
1323ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  }
1333ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek}
1343ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
135cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.comvoid ELF::AddSegment(int start, int end, uint32_t type, uint32_t flags) {
136cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  assert(start > 0);
137cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  assert(size_t(start) < sections_.size());
138cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  assert(end > 0);
139cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  assert(size_t(end) < sections_.size());
140cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  ++program_count_;
141cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com
142cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  // p_type
143cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  program_header_table_.D32(type);
144cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com
145cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  if (addr_size_ == 8) {
146cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com    // p_flags
147cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com    program_header_table_.D32(flags);
148cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  }
149cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com
150cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  size_t filesz = 0;
151cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  size_t memsz = 0;
152cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  bool prev_was_nobits = false;
153cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  for (int i = start; i <= end; ++i) {
154cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com    size_t size = sections_[i].size_;
155cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com    if (sections_[i].type_ != SHT_NOBITS) {
156cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com      assert(!prev_was_nobits);
157cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com      // non SHT_NOBITS sections are 4-byte aligned (see AddSection)
158cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com      size = (size + 3) & ~3;
159cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com      filesz += size;
160cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com    } else {
161cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com      prev_was_nobits = true;
162cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com    }
163cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com    memsz += size;
164cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  }
165cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com
166cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  program_header_table_
167cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com    // p_offset
168cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com    .Append(endianness(), addr_size_, sections_[start].offset_label_)
169cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com    // p_vaddr
170cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com    .Append(endianness(), addr_size_, sections_[start].addr_)
171cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com    // p_paddr
172cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com    .Append(endianness(), addr_size_, sections_[start].addr_)
173cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com    // p_filesz
174cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com    .Append(endianness(), addr_size_, filesz)
175cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com    // p_memsz
176cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com    .Append(endianness(), addr_size_, memsz);
177cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com
178cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  if (addr_size_ == 4) {
179cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com    // p_flags
180cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com    program_header_table_.D32(flags);
181cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  }
182cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com
183cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  // p_align
184cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  program_header_table_.Append(endianness(), addr_size_, 0);
185cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com}
186cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com
1873ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarekvoid ELF::Finish() {
1883ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  // Add the section header string table at the end.
1893ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  section_header_string_index_ = section_count_;
1903ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  //printf(".shstrtab size: %ld\n", section_header_strings_.Size());
1913ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  AddSection(".shstrtab", section_header_strings_, SHT_STRTAB);
1923ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  //printf("section_count_: %ld, sections_.size(): %ld\n",
1933ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  //     section_count_, sections_.size());
194cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  if (program_count_) {
195cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com    Mark(&program_header_label_);
196cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com    Append(program_header_table_);
197cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  } else {
198cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com    program_header_label_ = 0;
199cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  }
200cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com
201cbf39e56602e459e270b1f7e415a3b8fb1f63f81ted.mielczarek@gmail.com  for (vector<ElfSection>::iterator it = sections_.begin();
202cbf39e56602e459e270b1f7e415a3b8fb1f63f81ted.mielczarek@gmail.com       it < sections_.end(); ++it) {
203cbf39e56602e459e270b1f7e415a3b8fb1f63f81ted.mielczarek@gmail.com    AppendSection(*it);
204cbf39e56602e459e270b1f7e415a3b8fb1f63f81ted.mielczarek@gmail.com  }
2053ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  section_count_label_ = section_count_;
2063ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  program_count_label_ = program_count_;
2073ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
2083ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  // Section header table starts here.
2093ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  Mark(&section_header_label_);
2103ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  Append(section_header_table_);
2113ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek}
2123ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
2133ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarekSymbolTable::SymbolTable(Endianness endianness,
2143ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek                         size_t addr_size,
2153ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek                         StringTable& table) : Section(endianness),
2163ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek                                               addr_size_(addr_size),
2173ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek                                               table_(table) {
2183ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  assert(addr_size_ == 4 || addr_size_ == 8);
2193ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek}
2203ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
2213ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarekvoid SymbolTable::AddSymbol(const string& name, uint32_t value,
2223ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek                            uint32_t size, unsigned info, uint16_t shndx) {
2233ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  assert(addr_size_ == 4);
2243ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  D32(table_.Add(name));
2253ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  D32(value);
2263ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  D32(size);
2273ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  D8(info);
2283ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  D8(0); // other
2293ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  D16(shndx);
2303ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek}
2313ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
2323ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarekvoid SymbolTable::AddSymbol(const string& name, uint64_t value,
2333ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek                            uint64_t size, unsigned info, uint16_t shndx) {
2343ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  assert(addr_size_ == 8);
2353ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  D32(table_.Add(name));
2363ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  D8(info);
2373ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  D8(0); // other
2383ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  D16(shndx);
2393ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  D64(value);
2403ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  D64(size);
2413ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek}
2423ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
243ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.comvoid Notes::AddNote(int type, const string &name, const uint8_t* desc_bytes,
244ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com                    size_t desc_size) {
2458ade75f9558e31d25aec862a552fe78f9ba98c82ted.mielczarek  // Elf32_Nhdr and Elf64_Nhdr are exactly the same.
2468ade75f9558e31d25aec862a552fe78f9ba98c82ted.mielczarek  Elf32_Nhdr note_header;
2478ade75f9558e31d25aec862a552fe78f9ba98c82ted.mielczarek  memset(&note_header, 0, sizeof(note_header));
248ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com  note_header.n_namesz = name.length() + 1;
249ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com  note_header.n_descsz = desc_size;
250ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com  note_header.n_type = type;
2518ade75f9558e31d25aec862a552fe78f9ba98c82ted.mielczarek
2528ade75f9558e31d25aec862a552fe78f9ba98c82ted.mielczarek  Append(reinterpret_cast<const uint8_t*>(&note_header),
2538ade75f9558e31d25aec862a552fe78f9ba98c82ted.mielczarek         sizeof(note_header));
254ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com  AppendCString(name);
255ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com  Align(4);
256ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com  Append(desc_bytes, desc_size);
257ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com  Align(4);
2588ade75f9558e31d25aec862a552fe78f9ba98c82ted.mielczarek}
2598ade75f9558e31d25aec862a552fe78f9ba98c82ted.mielczarek
2603ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek}  // namespace synth_elf
2613ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek}  // namespace google_breakpad
262