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