elf.cpp 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  4. #undef NDEBUG
  5. #include <cstring>
  6. #include <assert.h>
  7. #include "elfxx.h"
  8. template <class endian, typename R, typename T>
  9. void Elf_Ehdr_Traits::swap(T &t, R &r)
  10. {
  11. memcpy(r.e_ident, t.e_ident, sizeof(r.e_ident));
  12. r.e_type = endian::swap(t.e_type);
  13. r.e_machine = endian::swap(t.e_machine);
  14. r.e_version = endian::swap(t.e_version);
  15. r.e_entry = endian::swap(t.e_entry);
  16. r.e_phoff = endian::swap(t.e_phoff);
  17. r.e_shoff = endian::swap(t.e_shoff);
  18. r.e_flags = endian::swap(t.e_flags);
  19. r.e_ehsize = endian::swap(t.e_ehsize);
  20. r.e_phentsize = endian::swap(t.e_phentsize);
  21. r.e_phnum = endian::swap(t.e_phnum);
  22. r.e_shentsize = endian::swap(t.e_shentsize);
  23. r.e_shnum = endian::swap(t.e_shnum);
  24. r.e_shstrndx = endian::swap(t.e_shstrndx);
  25. }
  26. template <class endian, typename R, typename T>
  27. void Elf_Phdr_Traits::swap(T &t, R &r)
  28. {
  29. r.p_type = endian::swap(t.p_type);
  30. r.p_offset = endian::swap(t.p_offset);
  31. r.p_vaddr = endian::swap(t.p_vaddr);
  32. r.p_paddr = endian::swap(t.p_paddr);
  33. r.p_filesz = endian::swap(t.p_filesz);
  34. r.p_memsz = endian::swap(t.p_memsz);
  35. r.p_flags = endian::swap(t.p_flags);
  36. r.p_align = endian::swap(t.p_align);
  37. }
  38. template <class endian, typename R, typename T>
  39. void Elf_Shdr_Traits::swap(T &t, R &r)
  40. {
  41. r.sh_name = endian::swap(t.sh_name);
  42. r.sh_type = endian::swap(t.sh_type);
  43. r.sh_flags = endian::swap(t.sh_flags);
  44. r.sh_addr = endian::swap(t.sh_addr);
  45. r.sh_offset = endian::swap(t.sh_offset);
  46. r.sh_size = endian::swap(t.sh_size);
  47. r.sh_link = endian::swap(t.sh_link);
  48. r.sh_info = endian::swap(t.sh_info);
  49. r.sh_addralign = endian::swap(t.sh_addralign);
  50. r.sh_entsize = endian::swap(t.sh_entsize);
  51. }
  52. template <class endian, typename R, typename T>
  53. void Elf_Dyn_Traits::swap(T &t, R &r)
  54. {
  55. r.d_tag = endian::swap(t.d_tag);
  56. r.d_un.d_val = endian::swap(t.d_un.d_val);
  57. }
  58. template <class endian, typename R, typename T>
  59. void Elf_Sym_Traits::swap(T &t, R &r)
  60. {
  61. r.st_name = endian::swap(t.st_name);
  62. r.st_value = endian::swap(t.st_value);
  63. r.st_size = endian::swap(t.st_size);
  64. r.st_info = t.st_info;
  65. r.st_other = t.st_other;
  66. r.st_shndx = endian::swap(t.st_shndx);
  67. }
  68. template <class endian>
  69. struct _Rel_info {
  70. static inline void swap(Elf32_Word &t, Elf32_Word &r) { r = endian::swap(t); }
  71. static inline void swap(Elf64_Xword &t, Elf64_Xword &r) { r = endian::swap(t); }
  72. static inline void swap(Elf64_Xword &t, Elf32_Word &r) {
  73. r = endian::swap(ELF32_R_INFO(ELF64_R_SYM(t), ELF64_R_TYPE(t)));
  74. }
  75. static inline void swap(Elf32_Word &t, Elf64_Xword &r) {
  76. r = endian::swap(ELF64_R_INFO(ELF32_R_SYM(t), ELF32_R_TYPE(t)));
  77. }
  78. };
  79. template <class endian, typename R, typename T>
  80. void Elf_Rel_Traits::swap(T &t, R &r)
  81. {
  82. r.r_offset = endian::swap(t.r_offset);
  83. _Rel_info<endian>::swap(t.r_info, r.r_info);
  84. }
  85. template <class endian, typename R, typename T>
  86. void Elf_Rela_Traits::swap(T &t, R &r)
  87. {
  88. r.r_offset = endian::swap(t.r_offset);
  89. _Rel_info<endian>::swap(t.r_info, r.r_info);
  90. r.r_addend = endian::swap(t.r_addend);
  91. }
  92. static const Elf32_Shdr null32_section =
  93. { 0, SHT_NULL, 0, 0, 0, 0, SHN_UNDEF, 0, 0, 0 };
  94. Elf_Shdr null_section(null32_section);
  95. Elf_Ehdr::Elf_Ehdr(std::ifstream &file, char ei_class, char ei_data)
  96. : serializable<Elf_Ehdr_Traits>(file, ei_class, ei_data),
  97. ElfSection(null_section, nullptr, nullptr)
  98. {
  99. shdr.sh_size = Elf_Ehdr::size(ei_class);
  100. }
  101. Elf::Elf(std::ifstream &file)
  102. {
  103. if (!file.is_open())
  104. throw std::runtime_error("Error opening file");
  105. file.exceptions(std::ifstream::eofbit | std::ifstream::failbit | std::ifstream::badbit);
  106. // Read ELF magic number and identification information
  107. char e_ident[EI_VERSION];
  108. file.seekg(0);
  109. file.read(e_ident, sizeof(e_ident));
  110. file.seekg(0);
  111. ehdr = new Elf_Ehdr(file, e_ident[EI_CLASS], e_ident[EI_DATA]);
  112. // ELFOSABI_LINUX is kept unsupported because I haven't looked whether
  113. // STB_GNU_UNIQUE or STT_GNU_IFUNC would need special casing.
  114. if ((ehdr->e_ident[EI_OSABI] != ELFOSABI_NONE) && (ehdr->e_ident[EI_ABIVERSION] != 0))
  115. throw std::runtime_error("unsupported ELF ABI");
  116. if (ehdr->e_version != 1)
  117. throw std::runtime_error("unsupported ELF version");
  118. // Sanity checks
  119. if (ehdr->e_shnum == 0)
  120. throw std::runtime_error("sstripped ELF files aren't supported");
  121. if (ehdr->e_ehsize != Elf_Ehdr::size(e_ident[EI_CLASS]))
  122. throw std::runtime_error("unsupported ELF inconsistency: ehdr.e_ehsize != sizeof(ehdr)");
  123. if (ehdr->e_shentsize != Elf_Shdr::size(e_ident[EI_CLASS]))
  124. throw std::runtime_error("unsupported ELF inconsistency: ehdr.e_shentsize != sizeof(shdr)");
  125. if (ehdr->e_phnum == 0) {
  126. if (ehdr->e_phoff != 0)
  127. throw std::runtime_error("unsupported ELF inconsistency: e_phnum == 0 && e_phoff != 0");
  128. if (ehdr->e_phentsize != 0)
  129. throw std::runtime_error("unsupported ELF inconsistency: e_phnum == 0 && e_phentsize != 0");
  130. } else if (ehdr->e_phoff != ehdr->e_ehsize)
  131. throw std::runtime_error("unsupported ELF inconsistency: ehdr->e_phoff != ehdr->e_ehsize");
  132. else if (ehdr->e_phentsize != Elf_Phdr::size(e_ident[EI_CLASS]))
  133. throw std::runtime_error("unsupported ELF inconsistency: ehdr->e_phentsize != sizeof(phdr)");
  134. // Read section headers
  135. Elf_Shdr **shdr = new Elf_Shdr *[ehdr->e_shnum];
  136. file.seekg(ehdr->e_shoff);
  137. for (int i = 0; i < ehdr->e_shnum; i++)
  138. shdr[i] = new Elf_Shdr(file, e_ident[EI_CLASS], e_ident[EI_DATA]);
  139. // Sanity check in section header for index 0
  140. if ((shdr[0]->sh_name != 0) || (shdr[0]->sh_type != SHT_NULL) ||
  141. (shdr[0]->sh_flags != 0) || (shdr[0]->sh_addr != 0) ||
  142. (shdr[0]->sh_offset != 0) || (shdr[0]->sh_size != 0) ||
  143. (shdr[0]->sh_link != SHN_UNDEF) || (shdr[0]->sh_info != 0) ||
  144. (shdr[0]->sh_addralign != 0) || (shdr[0]->sh_entsize != 0))
  145. throw std::runtime_error("Section header for index 0 contains unsupported values");
  146. if ((shdr[ehdr->e_shstrndx]->sh_link != 0) || (shdr[ehdr->e_shstrndx]->sh_info != 0))
  147. throw std::runtime_error("unsupported ELF content: string table with sh_link != 0 || sh_info != 0");
  148. // Store these temporarily
  149. tmp_shdr = shdr;
  150. tmp_file = &file;
  151. // Fill sections list
  152. sections = new ElfSection *[ehdr->e_shnum];
  153. for (int i = 0; i < ehdr->e_shnum; i++)
  154. sections[i] = nullptr;
  155. for (int i = 1; i < ehdr->e_shnum; i++) {
  156. if (sections[i] != nullptr)
  157. continue;
  158. getSection(i);
  159. }
  160. Elf_Shdr s;
  161. s.sh_name = 0;
  162. s.sh_type = SHT_NULL;
  163. s.sh_flags = 0;
  164. s.sh_addr = 0;
  165. s.sh_offset = ehdr->e_shoff;
  166. s.sh_entsize = Elf_Shdr::size(e_ident[EI_CLASS]);
  167. s.sh_size = s.sh_entsize * ehdr->e_shnum;
  168. s.sh_link = 0;
  169. s.sh_info = 0;
  170. s.sh_addralign = (e_ident[EI_CLASS] == ELFCLASS32) ? 4 : 8;
  171. shdr_section = new ElfSection(s, nullptr, nullptr);
  172. // Fake section for program headers
  173. s.sh_offset = ehdr->e_phoff;
  174. s.sh_addr = ehdr->e_phoff;
  175. s.sh_entsize = Elf_Phdr::size(e_ident[EI_CLASS]);
  176. s.sh_size = s.sh_entsize * ehdr->e_phnum;
  177. phdr_section = new ElfSection(s, nullptr, nullptr);
  178. phdr_section->insertAfter(ehdr, false);
  179. sections[1]->insertAfter(phdr_section, false);
  180. for (int i = 2; i < ehdr->e_shnum; i++) {
  181. // TODO: this should be done in a better way
  182. if ((shdr_section->getPrevious() == nullptr) && (shdr[i]->sh_offset > ehdr->e_shoff)) {
  183. shdr_section->insertAfter(sections[i - 1], false);
  184. sections[i]->insertAfter(shdr_section, false);
  185. } else
  186. sections[i]->insertAfter(sections[i - 1], false);
  187. }
  188. if (shdr_section->getPrevious() == nullptr)
  189. shdr_section->insertAfter(sections[ehdr->e_shnum - 1], false);
  190. tmp_file = nullptr;
  191. tmp_shdr = nullptr;
  192. for (int i = 0; i < ehdr->e_shnum; i++)
  193. delete shdr[i];
  194. delete[] shdr;
  195. eh_shstrndx = (ElfStrtab_Section *)sections[ehdr->e_shstrndx];
  196. // Skip reading program headers if there aren't any
  197. if (ehdr->e_phnum == 0)
  198. return;
  199. // Read program headers
  200. file.seekg(ehdr->e_phoff);
  201. for (int i = 0; i < ehdr->e_phnum; i++) {
  202. Elf_Phdr phdr(file, e_ident[EI_CLASS], e_ident[EI_DATA]);
  203. if (phdr.p_type == PT_LOAD) {
  204. // Default alignment for PT_LOAD on x86-64 prevents elfhack from
  205. // doing anything useful. However, the system doesn't actually
  206. // require such a big alignment, so in order for elfhack to work
  207. // efficiently, reduce alignment when it's originally the default
  208. // one.
  209. if ((ehdr->e_machine == EM_X86_64) && (phdr.p_align == 0x200000))
  210. phdr.p_align = 0x1000;
  211. }
  212. ElfSegment *segment = new ElfSegment(&phdr);
  213. // Some segments aren't entirely filled (if at all) by sections
  214. // For those, we use fake sections
  215. if ((phdr.p_type == PT_LOAD) && (phdr.p_offset == 0)) {
  216. // Use a fake section for ehdr and phdr
  217. ehdr->getShdr().sh_addr = phdr.p_vaddr;
  218. phdr_section->getShdr().sh_addr += phdr.p_vaddr;
  219. segment->addSection(ehdr);
  220. segment->addSection(phdr_section);
  221. }
  222. if (phdr.p_type == PT_PHDR)
  223. segment->addSection(phdr_section);
  224. for (int j = 1; j < ehdr->e_shnum; j++)
  225. if (phdr.contains(sections[j]))
  226. segment->addSection(sections[j]);
  227. // Make sure that our view of segments corresponds to the original
  228. // ELF file.
  229. // GNU gold likes to start some segments before the first section
  230. // they contain. https://sourceware.org/bugzilla/show_bug.cgi?id=19392
  231. unsigned int gold_adjustment = segment->getAddr() - phdr.p_vaddr;
  232. assert(segment->getFileSize() == phdr.p_filesz - gold_adjustment);
  233. // gold makes TLS segments end on an aligned virtual address, even
  234. // when the underlying section ends before that, while bfd ld
  235. // doesn't. It's fine if we don't keep that alignment.
  236. unsigned int memsize = segment->getMemSize();
  237. if (phdr.p_type == PT_TLS && memsize != phdr.p_memsz) {
  238. unsigned int align = segment->getAlign();
  239. memsize = (memsize + align - 1) & ~(align - 1);
  240. }
  241. assert(memsize == phdr.p_memsz - gold_adjustment);
  242. segments.push_back(segment);
  243. }
  244. new (&eh_entry) ElfLocation(ehdr->e_entry, this);
  245. }
  246. Elf::~Elf()
  247. {
  248. for (std::vector<ElfSegment *>::iterator seg = segments.begin(); seg != segments.end(); seg++)
  249. delete *seg;
  250. delete[] sections;
  251. ElfSection *section = ehdr;
  252. while (section != nullptr) {
  253. ElfSection *next = section->getNext();
  254. delete section;
  255. section = next;
  256. }
  257. }
  258. // TODO: This shouldn't fail after inserting sections
  259. ElfSection *Elf::getSection(int index)
  260. {
  261. if ((index < -1) || (index >= ehdr->e_shnum))
  262. throw std::runtime_error("Section index out of bounds");
  263. if (index == -1)
  264. index = ehdr->e_shstrndx; // TODO: should be fixed to use the actual current number
  265. // Special case: the section at index 0 is void
  266. if (index == 0)
  267. return nullptr;
  268. // Infinite recursion guard
  269. if (sections[index] == (ElfSection *)this)
  270. return nullptr;
  271. if (sections[index] == nullptr) {
  272. sections[index] = (ElfSection *)this;
  273. switch (tmp_shdr[index]->sh_type) {
  274. case SHT_DYNAMIC:
  275. sections[index] = new ElfDynamic_Section(*tmp_shdr[index], tmp_file, this);
  276. break;
  277. case SHT_REL:
  278. sections[index] = new ElfRel_Section<Elf_Rel>(*tmp_shdr[index], tmp_file, this);
  279. break;
  280. case SHT_RELA:
  281. sections[index] = new ElfRel_Section<Elf_Rela>(*tmp_shdr[index], tmp_file, this);
  282. break;
  283. case SHT_DYNSYM:
  284. case SHT_SYMTAB:
  285. sections[index] = new ElfSymtab_Section(*tmp_shdr[index], tmp_file, this);
  286. break;
  287. case SHT_STRTAB:
  288. sections[index] = new ElfStrtab_Section(*tmp_shdr[index], tmp_file, this);
  289. break;
  290. default:
  291. sections[index] = new ElfSection(*tmp_shdr[index], tmp_file, this);
  292. }
  293. }
  294. return sections[index];
  295. }
  296. ElfSection *Elf::getSectionAt(unsigned int offset)
  297. {
  298. for (int i = 1; i < ehdr->e_shnum; i++) {
  299. ElfSection *section = getSection(i);
  300. if ((section != nullptr) && (section->getFlags() & SHF_ALLOC) && !(section->getFlags() & SHF_TLS) &&
  301. (offset >= section->getAddr()) && (offset < section->getAddr() + section->getSize()))
  302. return section;
  303. }
  304. return nullptr;
  305. }
  306. ElfSegment *Elf::getSegmentByType(unsigned int type, ElfSegment *last)
  307. {
  308. std::vector<ElfSegment *>::iterator seg;
  309. if (last) {
  310. seg = std::find(segments.begin(), segments.end(), last);
  311. ++seg;
  312. } else
  313. seg = segments.begin();
  314. for (; seg != segments.end(); seg++)
  315. if ((*seg)->getType() == type)
  316. return *seg;
  317. return nullptr;
  318. }
  319. void Elf::removeSegment(ElfSegment *segment)
  320. {
  321. if (!segment)
  322. return;
  323. std::vector<ElfSegment *>::iterator seg;
  324. seg = std::find(segments.begin(), segments.end(), segment);
  325. if (seg == segments.end())
  326. return;
  327. segment->clear();
  328. segments.erase(seg);
  329. }
  330. ElfDynamic_Section *Elf::getDynSection()
  331. {
  332. for (std::vector<ElfSegment *>::iterator seg = segments.begin(); seg != segments.end(); seg++)
  333. if (((*seg)->getType() == PT_DYNAMIC) && ((*seg)->getFirstSection() != nullptr) &&
  334. (*seg)->getFirstSection()->getType() == SHT_DYNAMIC)
  335. return (ElfDynamic_Section *)(*seg)->getFirstSection();
  336. return nullptr;
  337. }
  338. void Elf::normalize()
  339. {
  340. // fixup section headers sh_name; TODO: that should be done by sections
  341. // themselves
  342. for (ElfSection *section = ehdr; section != nullptr; section = section->getNext()) {
  343. if (section->getIndex() == 0)
  344. continue;
  345. else
  346. ehdr->e_shnum = section->getIndex() + 1;
  347. section->getShdr().sh_name = eh_shstrndx->getStrIndex(section->getName());
  348. }
  349. ehdr->markDirty();
  350. // Check segments consistency
  351. int i = 0;
  352. for (std::vector<ElfSegment *>::iterator seg = segments.begin(); seg != segments.end(); seg++, i++) {
  353. std::list<ElfSection *>::iterator it = (*seg)->begin();
  354. for (ElfSection *last = *(it++); it != (*seg)->end(); last = *(it++)) {
  355. if (((*it)->getType() != SHT_NOBITS) &&
  356. ((*it)->getAddr() - last->getAddr()) != ((*it)->getOffset() - last->getOffset())) {
  357. throw std::runtime_error("Segments inconsistency");
  358. }
  359. }
  360. }
  361. // fixup ehdr before writing
  362. if (ehdr->e_phnum != segments.size()) {
  363. ehdr->e_phnum = segments.size();
  364. phdr_section->getShdr().sh_size = segments.size() * Elf_Phdr::size(ehdr->e_ident[EI_CLASS]);
  365. phdr_section->getNext()->markDirty();
  366. }
  367. // fixup shdr before writing
  368. if (ehdr->e_shnum != shdr_section->getSize() / shdr_section->getEntSize())
  369. shdr_section->getShdr().sh_size = ehdr->e_shnum * Elf_Shdr::size(ehdr->e_ident[EI_CLASS]);
  370. ehdr->e_shoff = shdr_section->getOffset();
  371. ehdr->e_entry = eh_entry.getValue();
  372. ehdr->e_shstrndx = eh_shstrndx->getIndex();
  373. }
  374. void Elf::write(std::ofstream &file)
  375. {
  376. normalize();
  377. for (ElfSection *section = ehdr;
  378. section != nullptr; section = section->getNext()) {
  379. file.seekp(section->getOffset());
  380. if (section == phdr_section) {
  381. for (std::vector<ElfSegment *>::iterator seg = segments.begin(); seg != segments.end(); seg++) {
  382. Elf_Phdr phdr;
  383. phdr.p_type = (*seg)->getType();
  384. phdr.p_flags = (*seg)->getFlags();
  385. phdr.p_offset = (*seg)->getOffset();
  386. phdr.p_vaddr = (*seg)->getAddr();
  387. phdr.p_paddr = phdr.p_vaddr + (*seg)->getVPDiff();
  388. phdr.p_filesz = (*seg)->getFileSize();
  389. phdr.p_memsz = (*seg)->getMemSize();
  390. phdr.p_align = (*seg)->getAlign();
  391. phdr.serialize(file, ehdr->e_ident[EI_CLASS], ehdr->e_ident[EI_DATA]);
  392. }
  393. } else if (section == shdr_section) {
  394. null_section.serialize(file, ehdr->e_ident[EI_CLASS], ehdr->e_ident[EI_DATA]);
  395. for (ElfSection *sec = ehdr; sec!= nullptr; sec = sec->getNext()) {
  396. if (sec->getType() != SHT_NULL)
  397. sec->getShdr().serialize(file, ehdr->e_ident[EI_CLASS], ehdr->e_ident[EI_DATA]);
  398. }
  399. } else
  400. section->serialize(file, ehdr->e_ident[EI_CLASS], ehdr->e_ident[EI_DATA]);
  401. }
  402. }
  403. ElfSection::ElfSection(Elf_Shdr &s, std::ifstream *file, Elf *parent)
  404. : shdr(s),
  405. link(shdr.sh_link == SHN_UNDEF ? nullptr : parent->getSection(shdr.sh_link)),
  406. next(nullptr), previous(nullptr), index(-1)
  407. {
  408. if ((file == nullptr) || (shdr.sh_type == SHT_NULL) || (shdr.sh_type == SHT_NOBITS))
  409. data = nullptr;
  410. else {
  411. data = new char[shdr.sh_size];
  412. int pos = file->tellg();
  413. file->seekg(shdr.sh_offset);
  414. file->read(data, shdr.sh_size);
  415. file->seekg(pos);
  416. }
  417. if (shdr.sh_name == 0)
  418. name = nullptr;
  419. else {
  420. ElfStrtab_Section *strtab = (ElfStrtab_Section *) parent->getSection(-1);
  421. // Special case (see elfgeneric.cpp): if strtab is nullptr, the
  422. // section being created is the strtab.
  423. if (strtab == nullptr)
  424. name = &data[shdr.sh_name];
  425. else
  426. name = strtab->getStr(shdr.sh_name);
  427. }
  428. // Only SHT_REL/SHT_RELA sections use sh_info to store a section
  429. // number.
  430. if ((shdr.sh_type == SHT_REL) || (shdr.sh_type == SHT_RELA))
  431. info.section = shdr.sh_info ? parent->getSection(shdr.sh_info) : nullptr;
  432. else
  433. info.index = shdr.sh_info;
  434. }
  435. unsigned int ElfSection::getAddr()
  436. {
  437. if (shdr.sh_addr != (Elf32_Word)-1)
  438. return shdr.sh_addr;
  439. // It should be safe to adjust sh_addr for all allocated sections that
  440. // are neither SHT_NOBITS nor SHT_PROGBITS
  441. if ((previous != nullptr) && isRelocatable()) {
  442. unsigned int addr = previous->getAddr();
  443. if (previous->getType() != SHT_NOBITS)
  444. addr += previous->getSize();
  445. if (addr & (getAddrAlign() - 1))
  446. addr = (addr | (getAddrAlign() - 1)) + 1;
  447. return (shdr.sh_addr = addr);
  448. }
  449. return shdr.sh_addr;
  450. }
  451. unsigned int ElfSection::getOffset()
  452. {
  453. if (shdr.sh_offset != (Elf32_Word)-1)
  454. return shdr.sh_offset;
  455. if (previous == nullptr)
  456. return (shdr.sh_offset = 0);
  457. unsigned int offset = previous->getOffset();
  458. ElfSegment *ptload = getSegmentByType(PT_LOAD);
  459. ElfSegment *prev_ptload = previous->getSegmentByType(PT_LOAD);
  460. if (ptload && (ptload == prev_ptload)) {
  461. offset += getAddr() - previous->getAddr();
  462. return (shdr.sh_offset = offset);
  463. }
  464. if (previous->getType() != SHT_NOBITS)
  465. offset += previous->getSize();
  466. Elf32_Word align = 0x1000;
  467. for (std::vector<ElfSegment *>::iterator seg = segments.begin(); seg != segments.end(); seg++)
  468. align = std::max(align, (*seg)->getAlign());
  469. Elf32_Word mask = align - 1;
  470. // SHF_TLS is used for .tbss which is some kind of special case.
  471. if (((getType() != SHT_NOBITS) || (getFlags() & SHF_TLS)) && (getFlags() & SHF_ALLOC)) {
  472. if ((getAddr() & mask) < (offset & mask))
  473. offset = (offset | mask) + (getAddr() & mask) + 1;
  474. else
  475. offset = (offset & ~mask) + (getAddr() & mask);
  476. }
  477. if ((getType() != SHT_NOBITS) && (offset & (getAddrAlign() - 1)))
  478. offset = (offset | (getAddrAlign() - 1)) + 1;
  479. // Two subsequent sections can't be mapped in the same page in memory
  480. // if they aren't in the same 4K block on disk.
  481. if ((getType() != SHT_NOBITS) && getAddr()) {
  482. if (((offset >> 12) != (previous->getOffset() >> 12)) &&
  483. ((getAddr() >> 12) == (previous->getAddr() >> 12)))
  484. throw std::runtime_error("Moving section would require overlapping segments");
  485. }
  486. return (shdr.sh_offset = offset);
  487. }
  488. int ElfSection::getIndex()
  489. {
  490. if (index != -1)
  491. return index;
  492. if (getType() == SHT_NULL)
  493. return (index = 0);
  494. ElfSection *reference;
  495. for (reference = previous; (reference != nullptr) && (reference->getType() == SHT_NULL); reference = reference->getPrevious());
  496. if (reference == nullptr)
  497. return (index = 1);
  498. return (index = reference->getIndex() + 1);
  499. }
  500. Elf_Shdr &ElfSection::getShdr()
  501. {
  502. getOffset();
  503. if (shdr.sh_link == (Elf32_Word)-1)
  504. shdr.sh_link = getLink() ? getLink()->getIndex() : 0;
  505. if (shdr.sh_info == (Elf32_Word)-1)
  506. shdr.sh_info = ((getType() == SHT_REL) || (getType() == SHT_RELA)) ?
  507. (getInfo().section ? getInfo().section->getIndex() : 0) :
  508. getInfo().index;
  509. return shdr;
  510. }
  511. ElfSegment::ElfSegment(Elf_Phdr *phdr)
  512. : type(phdr->p_type), v_p_diff(phdr->p_paddr - phdr->p_vaddr),
  513. flags(phdr->p_flags), align(phdr->p_align), vaddr(phdr->p_vaddr),
  514. filesz(phdr->p_filesz), memsz(phdr->p_memsz) {}
  515. void ElfSegment::addSection(ElfSection *section)
  516. {
  517. // Make sure all sections in PT_GNU_RELRO won't be moved by elfhack
  518. assert(!((type == PT_GNU_RELRO) && (section->isRelocatable())));
  519. //TODO: Check overlapping sections
  520. std::list<ElfSection *>::iterator i;
  521. for (i = sections.begin(); i != sections.end(); ++i)
  522. if ((*i)->getAddr() > section->getAddr())
  523. break;
  524. sections.insert(i, section);
  525. section->addToSegment(this);
  526. }
  527. void ElfSegment::removeSection(ElfSection *section)
  528. {
  529. sections.remove(section);
  530. section->removeFromSegment(this);
  531. }
  532. unsigned int ElfSegment::getFileSize()
  533. {
  534. if (type == PT_GNU_RELRO || isElfHackFillerSegment())
  535. return filesz;
  536. if (sections.empty())
  537. return 0;
  538. // Search the last section that is not SHT_NOBITS
  539. std::list<ElfSection *>::reverse_iterator i;
  540. for (i = sections.rbegin(); (i != sections.rend()) && ((*i)->getType() == SHT_NOBITS); ++i);
  541. // All sections are SHT_NOBITS
  542. if (i == sections.rend())
  543. return 0;
  544. unsigned int end = (*i)->getAddr() + (*i)->getSize();
  545. return end - sections.front()->getAddr();
  546. }
  547. unsigned int ElfSegment::getMemSize()
  548. {
  549. if (type == PT_GNU_RELRO || isElfHackFillerSegment())
  550. return memsz;
  551. if (sections.empty())
  552. return 0;
  553. unsigned int end = sections.back()->getAddr() + sections.back()->getSize();
  554. return end - sections.front()->getAddr();
  555. }
  556. unsigned int ElfSegment::getOffset()
  557. {
  558. if ((type == PT_GNU_RELRO) && !sections.empty() &&
  559. (sections.front()->getAddr() != vaddr))
  560. throw std::runtime_error("PT_GNU_RELRO segment doesn't start on a section start");
  561. // Neither bionic nor glibc linkers seem to like when the offset of that segment is 0
  562. if (isElfHackFillerSegment())
  563. return vaddr;
  564. return sections.empty() ? 0 : sections.front()->getOffset();
  565. }
  566. unsigned int ElfSegment::getAddr()
  567. {
  568. if ((type == PT_GNU_RELRO) && !sections.empty() &&
  569. (sections.front()->getAddr() != vaddr))
  570. throw std::runtime_error("PT_GNU_RELRO segment doesn't start on a section start");
  571. if (isElfHackFillerSegment())
  572. return vaddr;
  573. return sections.empty() ? 0 : sections.front()->getAddr();
  574. }
  575. void ElfSegment::clear()
  576. {
  577. for (std::list<ElfSection *>::iterator i = sections.begin(); i != sections.end(); ++i)
  578. (*i)->removeFromSegment(this);
  579. sections.clear();
  580. }
  581. ElfValue *ElfDynamic_Section::getValueForType(unsigned int tag)
  582. {
  583. for (unsigned int i = 0; i < shdr.sh_size / shdr.sh_entsize; i++)
  584. if (dyns[i].tag == tag)
  585. return dyns[i].value;
  586. return nullptr;
  587. }
  588. ElfSection *ElfDynamic_Section::getSectionForType(unsigned int tag)
  589. {
  590. ElfValue *value = getValueForType(tag);
  591. return value ? value->getSection() : nullptr;
  592. }
  593. bool ElfDynamic_Section::setValueForType(unsigned int tag, ElfValue *val)
  594. {
  595. unsigned int i;
  596. unsigned int shnum = shdr.sh_size / shdr.sh_entsize;
  597. for (i = 0; (i < shnum) && (dyns[i].tag != DT_NULL); i++)
  598. if (dyns[i].tag == tag) {
  599. delete dyns[i].value;
  600. dyns[i].value = val;
  601. return true;
  602. }
  603. // If we get here, this means we didn't match for the given tag
  604. // Most of the time, there are a few DT_NULL entries, that we can
  605. // use to add our value, but if we are on the last entry, we can't.
  606. if (i >= shnum - 1)
  607. return false;
  608. dyns[i].tag = tag;
  609. dyns[i].value = val;
  610. return true;
  611. }
  612. ElfDynamic_Section::ElfDynamic_Section(Elf_Shdr &s, std::ifstream *file, Elf *parent)
  613. : ElfSection(s, file, parent)
  614. {
  615. int pos = file->tellg();
  616. dyns.resize(s.sh_size / s.sh_entsize);
  617. file->seekg(shdr.sh_offset);
  618. // Here we assume tags refer to only one section (e.g. DT_RELSZ accounts
  619. // for .rel.dyn size)
  620. for (unsigned int i = 0; i < s.sh_size / s.sh_entsize; i++) {
  621. Elf_Dyn dyn(*file, parent->getClass(), parent->getData());
  622. dyns[i].tag = dyn.d_tag;
  623. switch (dyn.d_tag) {
  624. case DT_NULL:
  625. case DT_SYMBOLIC:
  626. case DT_TEXTREL:
  627. case DT_BIND_NOW:
  628. dyns[i].value = new ElfValue();
  629. break;
  630. case DT_NEEDED:
  631. case DT_SONAME:
  632. case DT_RPATH:
  633. case DT_PLTREL:
  634. case DT_RUNPATH:
  635. case DT_FLAGS:
  636. case DT_RELACOUNT:
  637. case DT_RELCOUNT:
  638. case DT_VERDEFNUM:
  639. case DT_VERNEEDNUM:
  640. dyns[i].value = new ElfPlainValue(dyn.d_un.d_val);
  641. break;
  642. case DT_PLTGOT:
  643. case DT_HASH:
  644. case DT_STRTAB:
  645. case DT_SYMTAB:
  646. case DT_RELA:
  647. case DT_INIT:
  648. case DT_FINI:
  649. case DT_REL:
  650. case DT_JMPREL:
  651. case DT_INIT_ARRAY:
  652. case DT_FINI_ARRAY:
  653. case DT_GNU_HASH:
  654. case DT_VERSYM:
  655. case DT_VERNEED:
  656. case DT_VERDEF:
  657. dyns[i].value = new ElfLocation(dyn.d_un.d_ptr, parent);
  658. break;
  659. default:
  660. dyns[i].value = nullptr;
  661. }
  662. }
  663. // Another loop to get the section sizes
  664. for (unsigned int i = 0; i < s.sh_size / s.sh_entsize; i++)
  665. switch (dyns[i].tag) {
  666. case DT_PLTRELSZ:
  667. dyns[i].value = new ElfSize(getSectionForType(DT_JMPREL));
  668. break;
  669. case DT_RELASZ:
  670. dyns[i].value = new ElfSize(getSectionForType(DT_RELA));
  671. break;
  672. case DT_STRSZ:
  673. dyns[i].value = new ElfSize(getSectionForType(DT_STRTAB));
  674. break;
  675. case DT_RELSZ:
  676. dyns[i].value = new ElfSize(getSectionForType(DT_REL));
  677. break;
  678. case DT_INIT_ARRAYSZ:
  679. dyns[i].value = new ElfSize(getSectionForType(DT_INIT_ARRAY));
  680. break;
  681. case DT_FINI_ARRAYSZ:
  682. dyns[i].value = new ElfSize(getSectionForType(DT_FINI_ARRAY));
  683. break;
  684. case DT_RELAENT:
  685. dyns[i].value = new ElfEntSize(getSectionForType(DT_RELA));
  686. break;
  687. case DT_SYMENT:
  688. dyns[i].value = new ElfEntSize(getSectionForType(DT_SYMTAB));
  689. break;
  690. case DT_RELENT:
  691. dyns[i].value = new ElfEntSize(getSectionForType(DT_REL));
  692. break;
  693. }
  694. file->seekg(pos);
  695. }
  696. ElfDynamic_Section::~ElfDynamic_Section()
  697. {
  698. for (unsigned int i = 0; i < shdr.sh_size / shdr.sh_entsize; i++)
  699. delete dyns[i].value;
  700. }
  701. void ElfDynamic_Section::serialize(std::ofstream &file, char ei_class, char ei_data)
  702. {
  703. for (unsigned int i = 0; i < shdr.sh_size / shdr.sh_entsize; i++) {
  704. Elf_Dyn dyn;
  705. dyn.d_tag = dyns[i].tag;
  706. dyn.d_un.d_val = (dyns[i].value != nullptr) ? dyns[i].value->getValue() : 0;
  707. dyn.serialize(file, ei_class, ei_data);
  708. }
  709. }
  710. ElfSymtab_Section::ElfSymtab_Section(Elf_Shdr &s, std::ifstream *file, Elf *parent)
  711. : ElfSection(s, file, parent)
  712. {
  713. int pos = file->tellg();
  714. syms.resize(s.sh_size / s.sh_entsize);
  715. ElfStrtab_Section *strtab = (ElfStrtab_Section *)getLink();
  716. file->seekg(shdr.sh_offset);
  717. for (unsigned int i = 0; i < shdr.sh_size / shdr.sh_entsize; i++) {
  718. Elf_Sym sym(*file, parent->getClass(), parent->getData());
  719. syms[i].name = strtab->getStr(sym.st_name);
  720. syms[i].info = sym.st_info;
  721. syms[i].other = sym.st_other;
  722. ElfSection *section = (sym.st_shndx == SHN_ABS) ? nullptr : parent->getSection(sym.st_shndx);
  723. new (&syms[i].value) ElfLocation(section, sym.st_value, ElfLocation::ABSOLUTE);
  724. syms[i].size = sym.st_size;
  725. syms[i].defined = (sym.st_shndx != SHN_UNDEF);
  726. }
  727. file->seekg(pos);
  728. }
  729. void
  730. ElfSymtab_Section::serialize(std::ofstream &file, char ei_class, char ei_data)
  731. {
  732. ElfStrtab_Section *strtab = (ElfStrtab_Section *)getLink();
  733. for (unsigned int i = 0; i < shdr.sh_size / shdr.sh_entsize; i++) {
  734. Elf_Sym sym;
  735. sym.st_name = strtab->getStrIndex(syms[i].name);
  736. sym.st_info = syms[i].info;
  737. sym.st_other = syms[i].other;
  738. sym.st_value = syms[i].value.getValue();
  739. ElfSection *section = syms[i].value.getSection();
  740. if (syms[i].defined)
  741. sym.st_shndx = section ? section->getIndex() : SHN_ABS;
  742. else
  743. sym.st_shndx = SHN_UNDEF;
  744. sym.st_size = syms[i].size;
  745. sym.serialize(file, ei_class, ei_data);
  746. }
  747. }
  748. Elf_SymValue *
  749. ElfSymtab_Section::lookup(const char *name, unsigned int type_filter)
  750. {
  751. for (std::vector<Elf_SymValue>::iterator sym = syms.begin();
  752. sym != syms.end(); sym++) {
  753. if ((type_filter & (1 << ELF32_ST_TYPE(sym->info))) &&
  754. (strcmp(sym->name, name) == 0)) {
  755. return &*sym;
  756. }
  757. }
  758. return nullptr;
  759. }
  760. const char *
  761. ElfStrtab_Section::getStr(unsigned int index)
  762. {
  763. for (std::vector<table_storage>::iterator t = table.begin();
  764. t != table.end(); t++) {
  765. if (index < t->used)
  766. return t->buf + index;
  767. index -= t->used;
  768. }
  769. assert(1 == 0);
  770. return nullptr;
  771. }
  772. const char *
  773. ElfStrtab_Section::getStr(const char *string)
  774. {
  775. if (string == nullptr)
  776. return nullptr;
  777. // If the given string is within the section, return it
  778. for (std::vector<table_storage>::iterator t = table.begin();
  779. t != table.end(); t++)
  780. if ((string >= t->buf) && (string < t->buf + t->used))
  781. return string;
  782. // TODO: should scan in the section to find an existing string
  783. // If not, we need to allocate the string in the section
  784. size_t len = strlen(string) + 1;
  785. if (table.back().size - table.back().used < len)
  786. table.resize(table.size() + 1);
  787. char *alloc_str = table.back().buf + table.back().used;
  788. memcpy(alloc_str, string, len);
  789. table.back().used += len;
  790. shdr.sh_size += len;
  791. markDirty();
  792. return alloc_str;
  793. }
  794. unsigned int
  795. ElfStrtab_Section::getStrIndex(const char *string)
  796. {
  797. if (string == nullptr)
  798. return 0;
  799. unsigned int index = 0;
  800. string = getStr(string);
  801. for (std::vector<table_storage>::iterator t = table.begin();
  802. t != table.end(); t++) {
  803. if ((string >= t->buf) && (string < t->buf + t->used))
  804. return index + (string - t->buf);
  805. index += t->used;
  806. }
  807. assert(1 == 0);
  808. return 0;
  809. }
  810. void
  811. ElfStrtab_Section::serialize(std::ofstream &file, char ei_class, char ei_data)
  812. {
  813. file.seekp(getOffset());
  814. for (std::vector<table_storage>::iterator t = table.begin();
  815. t != table.end(); t++)
  816. file.write(t->buf, t->used);
  817. }