disassembler_elf_32.cc 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663
  1. // Copyright 2013 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "courgette/disassembler_elf_32.h"
  5. #include <algorithm>
  6. #include <iterator>
  7. #include "base/bind.h"
  8. #include "base/logging.h"
  9. #include "courgette/assembly_program.h"
  10. #include "courgette/courgette.h"
  11. namespace courgette {
  12. namespace {
  13. // Sorts |section_headers| by file offset and stores the resulting permutation
  14. // of section ids in |order|.
  15. std::vector<Elf32_Half> GetSectionHeaderFileOffsetOrder(
  16. const std::vector<Elf32_Shdr>& section_headers) {
  17. size_t size = section_headers.size();
  18. std::vector<Elf32_Half> order(size);
  19. for (size_t i = 0; i < size; ++i)
  20. order[i] = static_cast<Elf32_Half>(i);
  21. auto comp = [&](int idx1, int idx2) {
  22. return section_headers[idx1].sh_offset < section_headers[idx2].sh_offset;
  23. };
  24. std::stable_sort(order.begin(), order.end(), comp);
  25. return order;
  26. }
  27. } // namespace
  28. DisassemblerElf32::Elf32RvaVisitor_Rel32::Elf32RvaVisitor_Rel32(
  29. const std::vector<std::unique_ptr<TypedRVA>>& rva_locations)
  30. : VectorRvaVisitor<std::unique_ptr<TypedRVA>>(rva_locations) {
  31. }
  32. RVA DisassemblerElf32::Elf32RvaVisitor_Rel32::Get() const {
  33. return (*it_)->rva() + (*it_)->relative_target();
  34. }
  35. DisassemblerElf32::DisassemblerElf32(const uint8_t* start, size_t length)
  36. : Disassembler(start, length),
  37. header_(nullptr),
  38. section_header_table_size_(0),
  39. program_header_table_(nullptr),
  40. program_header_table_size_(0),
  41. default_string_section_(nullptr) {}
  42. RVA DisassemblerElf32::FileOffsetToRVA(FileOffset offset) const {
  43. // File offsets can be 64-bit values, but we are dealing with 32-bit
  44. // executables and so only need to support 32-bit file sizes.
  45. uint32_t offset32 = static_cast<uint32_t>(offset);
  46. // Visit section headers ordered by file offset.
  47. for (Elf32_Half section_id : section_header_file_offset_order_) {
  48. const Elf32_Shdr* section_header = SectionHeader(section_id);
  49. // These can appear to have a size in the file, but don't.
  50. if (section_header->sh_type == SHT_NOBITS)
  51. continue;
  52. Elf32_Off section_begin = section_header->sh_offset;
  53. Elf32_Off section_end = section_begin + section_header->sh_size;
  54. if (offset32 >= section_begin && offset32 < section_end) {
  55. return section_header->sh_addr + (offset32 - section_begin);
  56. }
  57. }
  58. return 0;
  59. }
  60. FileOffset DisassemblerElf32::RVAToFileOffset(RVA rva) const {
  61. for (Elf32_Half section_id = 0; section_id < SectionHeaderCount();
  62. ++section_id) {
  63. const Elf32_Shdr* section_header = SectionHeader(section_id);
  64. // These can appear to have a size in the file, but don't.
  65. if (section_header->sh_type == SHT_NOBITS)
  66. continue;
  67. Elf32_Addr begin = section_header->sh_addr;
  68. Elf32_Addr end = begin + section_header->sh_size;
  69. if (rva >= begin && rva < end)
  70. return section_header->sh_offset + (rva - begin);
  71. }
  72. return kNoFileOffset;
  73. }
  74. RVA DisassemblerElf32::PointerToTargetRVA(const uint8_t* p) const {
  75. // TODO(huangs): Add check (e.g., IsValidTargetRVA(), but more efficient).
  76. return Read32LittleEndian(p);
  77. }
  78. bool DisassemblerElf32::ParseHeader() {
  79. if (length() < sizeof(Elf32_Ehdr))
  80. return Bad("Too small");
  81. header_ = reinterpret_cast<const Elf32_Ehdr*>(start());
  82. // Perform DisassemblerElf32::QuickDetect() checks (with error messages).
  83. // Have magic for ELF header?
  84. if (header_->e_ident[EI_MAG0] != 0x7F || header_->e_ident[EI_MAG1] != 'E' ||
  85. header_->e_ident[EI_MAG2] != 'L' || header_->e_ident[EI_MAG3] != 'F') {
  86. return Bad("No Magic Number");
  87. }
  88. if (header_->e_ident[EI_CLASS] != ELFCLASS32 ||
  89. header_->e_ident[EI_DATA] != ELFDATA2LSB ||
  90. header_->e_machine != ElfEM()) {
  91. return Bad("Not a supported architecture");
  92. }
  93. if (header_->e_type != ET_EXEC && header_->e_type != ET_DYN)
  94. return Bad("Not an executable file or shared library");
  95. if (header_->e_version != 1 || header_->e_ident[EI_VERSION] != 1)
  96. return Bad("Unknown file version");
  97. if (header_->e_shentsize != sizeof(Elf32_Shdr))
  98. return Bad("Unexpected section header size");
  99. // Perform more complex checks, while extracting data.
  100. if (header_->e_shoff < sizeof(Elf32_Ehdr) ||
  101. !IsArrayInBounds(header_->e_shoff, header_->e_shnum,
  102. sizeof(Elf32_Shdr))) {
  103. return Bad("Out of bounds section header table");
  104. }
  105. // Extract |section_header_table_|, ordered by section id.
  106. const Elf32_Shdr* section_header_table_raw =
  107. reinterpret_cast<const Elf32_Shdr*>(
  108. FileOffsetToPointer(header_->e_shoff));
  109. section_header_table_size_ = header_->e_shnum;
  110. section_header_table_.assign(section_header_table_raw,
  111. section_header_table_raw + section_header_table_size_);
  112. if (!CheckSectionRanges())
  113. return Bad("Out of bound section");
  114. section_header_file_offset_order_ =
  115. GetSectionHeaderFileOffsetOrder(section_header_table_);
  116. if (header_->e_phoff < sizeof(Elf32_Ehdr) ||
  117. !IsArrayInBounds(header_->e_phoff, header_->e_phnum,
  118. sizeof(Elf32_Phdr))) {
  119. return Bad("Out of bounds program header table");
  120. }
  121. // Extract |program_header_table_|.
  122. program_header_table_size_ = header_->e_phnum;
  123. program_header_table_ = reinterpret_cast<const Elf32_Phdr*>(
  124. FileOffsetToPointer(header_->e_phoff));
  125. if (!CheckProgramSegmentRanges())
  126. return Bad("Out of bound segment");
  127. // Extract |default_string_section_|.
  128. Elf32_Half string_section_id = header_->e_shstrndx;
  129. if (string_section_id == SHN_UNDEF)
  130. return Bad("Missing string section");
  131. if (string_section_id >= header_->e_shnum)
  132. return Bad("Out of bounds string section index");
  133. if (SectionHeader(string_section_id)->sh_type != SHT_STRTAB)
  134. return Bad("Invalid string section");
  135. default_string_section_size_ = SectionHeader(string_section_id)->sh_size;
  136. default_string_section_ =
  137. reinterpret_cast<const char*>(SectionBody(string_section_id));
  138. // String section may be empty. If nonempty, then last byte must be null.
  139. if (default_string_section_size_ > 0) {
  140. if (default_string_section_[default_string_section_size_ - 1] != '\0')
  141. return Bad("String section does not terminate");
  142. }
  143. UpdateLength();
  144. return Good();
  145. }
  146. CheckBool DisassemblerElf32::IsValidTargetRVA(RVA rva) const {
  147. if (rva == kUnassignedRVA)
  148. return false;
  149. // |rva| is valid if it's contained in any program segment.
  150. for (Elf32_Half segment_id = 0; segment_id < ProgramSegmentHeaderCount();
  151. ++segment_id) {
  152. const Elf32_Phdr* segment_header = ProgramSegmentHeader(segment_id);
  153. if (segment_header->p_type != PT_LOAD)
  154. continue;
  155. Elf32_Addr begin = segment_header->p_vaddr;
  156. Elf32_Addr end = segment_header->p_vaddr + segment_header->p_memsz;
  157. if (rva >= begin && rva < end)
  158. return true;
  159. }
  160. return false;
  161. }
  162. // static
  163. bool DisassemblerElf32::QuickDetect(const uint8_t* start,
  164. size_t length,
  165. e_machine_values elf_em) {
  166. if (length < sizeof(Elf32_Ehdr))
  167. return false;
  168. const Elf32_Ehdr* header = reinterpret_cast<const Elf32_Ehdr*>(start);
  169. // Have magic for ELF header?
  170. if (header->e_ident[EI_MAG0] != 0x7F || header->e_ident[EI_MAG1] != 'E' ||
  171. header->e_ident[EI_MAG2] != 'L' || header->e_ident[EI_MAG3] != 'F') {
  172. return false;
  173. }
  174. if (header->e_ident[EI_CLASS] != ELFCLASS32 ||
  175. header->e_ident[EI_DATA] != ELFDATA2LSB || header->e_machine != elf_em) {
  176. return false;
  177. }
  178. if (header->e_type != ET_EXEC && header->e_type != ET_DYN)
  179. return false;
  180. if (header->e_version != 1 || header->e_ident[EI_VERSION] != 1)
  181. return false;
  182. if (header->e_shentsize != sizeof(Elf32_Shdr))
  183. return false;
  184. return true;
  185. }
  186. bool DisassemblerElf32::CheckSectionRanges() {
  187. for (Elf32_Half section_id = 0; section_id < SectionHeaderCount();
  188. ++section_id) {
  189. const Elf32_Shdr* section_header = SectionHeader(section_id);
  190. if (section_header->sh_type == SHT_NOBITS) // E.g., .bss.
  191. continue;
  192. if (!IsRangeInBounds(section_header->sh_offset, section_header->sh_size))
  193. return false;
  194. }
  195. return true;
  196. }
  197. bool DisassemblerElf32::CheckProgramSegmentRanges() {
  198. for (Elf32_Half segment_id = 0; segment_id < ProgramSegmentHeaderCount();
  199. ++segment_id) {
  200. const Elf32_Phdr* segment_header = ProgramSegmentHeader(segment_id);
  201. if (!IsRangeInBounds(segment_header->p_offset, segment_header->p_filesz))
  202. return false;
  203. }
  204. return true;
  205. }
  206. void DisassemblerElf32::UpdateLength() {
  207. Elf32_Off result = 0;
  208. // Find the end of the last section.
  209. for (Elf32_Half section_id = 0; section_id < SectionHeaderCount();
  210. ++section_id) {
  211. const Elf32_Shdr* section_header = SectionHeader(section_id);
  212. if (section_header->sh_type == SHT_NOBITS)
  213. continue;
  214. DCHECK(IsRangeInBounds(section_header->sh_offset, section_header->sh_size));
  215. Elf32_Off section_end = section_header->sh_offset + section_header->sh_size;
  216. result = std::max(result, section_end);
  217. }
  218. // Find the end of the last segment.
  219. for (Elf32_Half segment_id = 0; segment_id < ProgramSegmentHeaderCount();
  220. ++segment_id) {
  221. const Elf32_Phdr* segment_header = ProgramSegmentHeader(segment_id);
  222. DCHECK(IsRangeInBounds(segment_header->p_offset, segment_header->p_filesz));
  223. Elf32_Off segment_end = segment_header->p_offset + segment_header->p_filesz;
  224. result = std::max(result, segment_end);
  225. }
  226. Elf32_Off section_table_end =
  227. header_->e_shoff + (header_->e_shnum * sizeof(Elf32_Shdr));
  228. result = std::max(result, section_table_end);
  229. Elf32_Off segment_table_end =
  230. header_->e_phoff + (header_->e_phnum * sizeof(Elf32_Phdr));
  231. result = std::max(result, segment_table_end);
  232. ReduceLength(result);
  233. }
  234. CheckBool DisassemblerElf32::SectionName(const Elf32_Shdr& shdr,
  235. std::string* name) const {
  236. DCHECK(name);
  237. size_t string_pos = shdr.sh_name;
  238. if (string_pos == 0) {
  239. // Empty string by convention. Valid even if string section is empty.
  240. name->clear();
  241. } else {
  242. if (string_pos >= default_string_section_size_)
  243. return false;
  244. // Safe because string section must terminate with null.
  245. *name = default_string_section_ + string_pos;
  246. }
  247. return true;
  248. }
  249. CheckBool DisassemblerElf32::RVAsToFileOffsets(
  250. const std::vector<RVA>& rvas,
  251. std::vector<FileOffset>* file_offsets) const {
  252. file_offsets->clear();
  253. file_offsets->reserve(rvas.size());
  254. for (RVA rva : rvas) {
  255. FileOffset file_offset = RVAToFileOffset(rva);
  256. if (file_offset == kNoFileOffset)
  257. return false;
  258. file_offsets->push_back(file_offset);
  259. }
  260. return true;
  261. }
  262. CheckBool DisassemblerElf32::RVAsToFileOffsets(
  263. std::vector<std::unique_ptr<TypedRVA>>* typed_rvas) const {
  264. for (auto& typed_rva : *typed_rvas) {
  265. FileOffset file_offset = RVAToFileOffset(typed_rva->rva());
  266. if (file_offset == kNoFileOffset)
  267. return false;
  268. typed_rva->set_file_offset(file_offset);
  269. }
  270. return true;
  271. }
  272. bool DisassemblerElf32::ExtractAbs32Locations() {
  273. abs32_locations_.clear();
  274. // Loop through sections for relocation sections
  275. for (Elf32_Half section_id = 0; section_id < SectionHeaderCount();
  276. ++section_id) {
  277. const Elf32_Shdr* section_header = SectionHeader(section_id);
  278. if (section_header->sh_type == SHT_REL) {
  279. const Elf32_Rel* relocs_table =
  280. reinterpret_cast<const Elf32_Rel*>(SectionBody(section_id));
  281. // Reject if malformed.
  282. if (section_header->sh_entsize != sizeof(Elf32_Rel))
  283. return false;
  284. if (section_header->sh_size % section_header->sh_entsize != 0)
  285. return false;
  286. int relocs_table_count =
  287. section_header->sh_size / section_header->sh_entsize;
  288. // Elf32_Word relocation_section_id = section_header->sh_info;
  289. // Loop through relocation objects in the relocation section
  290. for (int rel_id = 0; rel_id < relocs_table_count; ++rel_id) {
  291. RVA rva;
  292. // Quite a few of these conversions fail, and we simply skip
  293. // them, that's okay.
  294. if (RelToRVA(relocs_table[rel_id], &rva) && CheckSection(rva))
  295. abs32_locations_.push_back(rva);
  296. }
  297. }
  298. }
  299. std::sort(abs32_locations_.begin(), abs32_locations_.end());
  300. DCHECK(abs32_locations_.empty() || abs32_locations_.back() != kUnassignedRVA);
  301. return true;
  302. }
  303. bool DisassemblerElf32::ExtractRel32Locations() {
  304. rel32_locations_.clear();
  305. bool found_rel32 = false;
  306. // Loop through sections for relocation sections
  307. for (Elf32_Half section_id = 0; section_id < SectionHeaderCount();
  308. ++section_id) {
  309. const Elf32_Shdr* section_header = SectionHeader(section_id);
  310. // Some debug sections can have sh_type=SHT_PROGBITS but sh_addr=0.
  311. if (section_header->sh_type != SHT_PROGBITS || section_header->sh_addr == 0)
  312. continue;
  313. // Heuristic: Only consider ".text" section.
  314. std::string section_name;
  315. if (!SectionName(*section_header, &section_name))
  316. return false;
  317. if (section_name != ".text")
  318. continue;
  319. found_rel32 = true;
  320. if (!ParseRel32RelocsFromSection(section_header))
  321. return false;
  322. }
  323. if (!found_rel32)
  324. VLOG(1) << "Warning: Found no rel32 addresses. Missing .text section?";
  325. std::sort(rel32_locations_.begin(), rel32_locations_.end(),
  326. TypedRVA::IsLessThanByRVA);
  327. DCHECK(rel32_locations_.empty() ||
  328. rel32_locations_.back()->rva() != kUnassignedRVA);
  329. return true;
  330. }
  331. RvaVisitor* DisassemblerElf32::CreateAbs32TargetRvaVisitor() {
  332. return new RvaVisitor_Abs32(abs32_locations_, *this);
  333. }
  334. RvaVisitor* DisassemblerElf32::CreateRel32TargetRvaVisitor() {
  335. return new Elf32RvaVisitor_Rel32(rel32_locations_);
  336. }
  337. void DisassemblerElf32::RemoveUnusedRel32Locations(AssemblyProgram* program) {
  338. auto tail_it = rel32_locations_.begin();
  339. for (auto head_it = rel32_locations_.begin();
  340. head_it != rel32_locations_.end(); ++head_it) {
  341. RVA target_rva = (*head_it)->rva() + (*head_it)->relative_target();
  342. if (program->FindRel32Label(target_rva) == nullptr) {
  343. // If address does not match a Label (because it was removed), deallocate.
  344. (*head_it).reset(nullptr);
  345. } else {
  346. // Else squeeze nullptr to end to compactify.
  347. if (tail_it != head_it)
  348. (*tail_it).swap(*head_it);
  349. ++tail_it;
  350. }
  351. }
  352. rel32_locations_.resize(std::distance(rel32_locations_.begin(), tail_it));
  353. }
  354. InstructionGenerator DisassemblerElf32::GetInstructionGenerator(
  355. AssemblyProgram* program) {
  356. return base::BindRepeating(&DisassemblerElf32::ParseFile,
  357. base::Unretained(this), program);
  358. }
  359. CheckBool DisassemblerElf32::ParseFile(AssemblyProgram* program,
  360. InstructionReceptor* receptor) const {
  361. // Walk all the bytes in the file, whether or not in a section.
  362. FileOffset file_offset = 0;
  363. // File parsing follows file offset order, and we visit abs32 and rel32
  364. // locations in lockstep. Therefore we need to extract and sort file offsets
  365. // of all abs32 and rel32 locations. For abs32, we copy the offsets to a new
  366. // array.
  367. std::vector<FileOffset> abs_offsets;
  368. if (!RVAsToFileOffsets(abs32_locations_, &abs_offsets))
  369. return false;
  370. std::sort(abs_offsets.begin(), abs_offsets.end());
  371. // For rel32, TypedRVA (rather than raw offset) is stored, so sort-by-offset
  372. // is performed in place to save memory. At the end of function we will
  373. // sort-by-RVA.
  374. if (!RVAsToFileOffsets(&rel32_locations_))
  375. return false;
  376. std::sort(rel32_locations_.begin(),
  377. rel32_locations_.end(),
  378. TypedRVA::IsLessThanByFileOffset);
  379. std::vector<FileOffset>::iterator current_abs_offset = abs_offsets.begin();
  380. std::vector<FileOffset>::iterator end_abs_offset = abs_offsets.end();
  381. std::vector<std::unique_ptr<TypedRVA>>::iterator current_rel =
  382. rel32_locations_.begin();
  383. std::vector<std::unique_ptr<TypedRVA>>::iterator end_rel =
  384. rel32_locations_.end();
  385. // Visit section headers ordered by file offset.
  386. for (Elf32_Half section_id : section_header_file_offset_order_) {
  387. const Elf32_Shdr* section_header = SectionHeader(section_id);
  388. if (section_header->sh_type == SHT_NOBITS)
  389. continue;
  390. if (!ParseSimpleRegion(file_offset, section_header->sh_offset, receptor))
  391. return false;
  392. file_offset = section_header->sh_offset;
  393. switch (section_header->sh_type) {
  394. case SHT_REL:
  395. if (!ParseRelocationSection(section_header, receptor))
  396. return false;
  397. file_offset = section_header->sh_offset + section_header->sh_size;
  398. break;
  399. case SHT_PROGBITS:
  400. if (!ParseProgbitsSection(section_header, &current_abs_offset,
  401. end_abs_offset, &current_rel, end_rel,
  402. program, receptor)) {
  403. return false;
  404. }
  405. file_offset = section_header->sh_offset + section_header->sh_size;
  406. break;
  407. case SHT_INIT_ARRAY:
  408. // Fall through
  409. case SHT_FINI_ARRAY:
  410. while (current_abs_offset != end_abs_offset &&
  411. *current_abs_offset >= section_header->sh_offset &&
  412. *current_abs_offset <
  413. section_header->sh_offset + section_header->sh_size) {
  414. // Skip any abs_offsets appear in the unsupported INIT_ARRAY section
  415. VLOG(1) << "Skipping relocation entry for unsupported section: "
  416. << section_header->sh_type;
  417. ++current_abs_offset;
  418. }
  419. break;
  420. default:
  421. if (current_abs_offset != end_abs_offset &&
  422. *current_abs_offset >= section_header->sh_offset &&
  423. *current_abs_offset <
  424. section_header->sh_offset + section_header->sh_size) {
  425. VLOG(1) << "Relocation address in unrecognized ELF section: "
  426. << section_header->sh_type;
  427. }
  428. break;
  429. }
  430. }
  431. // Rest of the file past the last section
  432. if (!ParseSimpleRegion(file_offset, length(), receptor))
  433. return false;
  434. // Restore original rel32 location order and sort by RVA order.
  435. std::sort(rel32_locations_.begin(), rel32_locations_.end(),
  436. TypedRVA::IsLessThanByRVA);
  437. // Make certain we consume all of the relocations as expected
  438. return (current_abs_offset == end_abs_offset);
  439. }
  440. CheckBool DisassemblerElf32::ParseProgbitsSection(
  441. const Elf32_Shdr* section_header,
  442. std::vector<FileOffset>::iterator* current_abs_offset,
  443. std::vector<FileOffset>::iterator end_abs_offset,
  444. std::vector<std::unique_ptr<TypedRVA>>::iterator* current_rel,
  445. std::vector<std::unique_ptr<TypedRVA>>::iterator end_rel,
  446. AssemblyProgram* program,
  447. InstructionReceptor* receptor) const {
  448. // Walk all the bytes in the file, whether or not in a section.
  449. FileOffset file_offset = section_header->sh_offset;
  450. FileOffset section_end = section_header->sh_offset + section_header->sh_size;
  451. Elf32_Addr origin = section_header->sh_addr;
  452. FileOffset origin_offset = section_header->sh_offset;
  453. if (!receptor->EmitOrigin(origin))
  454. return false;
  455. while (file_offset < section_end) {
  456. if (*current_abs_offset != end_abs_offset &&
  457. file_offset > **current_abs_offset)
  458. return false;
  459. while (*current_rel != end_rel &&
  460. file_offset > (**current_rel)->file_offset()) {
  461. ++(*current_rel);
  462. }
  463. FileOffset next_relocation = section_end;
  464. if (*current_abs_offset != end_abs_offset &&
  465. next_relocation > **current_abs_offset)
  466. next_relocation = **current_abs_offset;
  467. // Rel offsets are heuristically derived, and might (incorrectly) overlap
  468. // an Abs value, or the end of the section, so +3 to make sure there is
  469. // room for the full 4 byte value.
  470. if (*current_rel != end_rel &&
  471. next_relocation > ((**current_rel)->file_offset() + 3))
  472. next_relocation = (**current_rel)->file_offset();
  473. if (next_relocation > file_offset) {
  474. if (!ParseSimpleRegion(file_offset, next_relocation, receptor))
  475. return false;
  476. file_offset = next_relocation;
  477. continue;
  478. }
  479. if (*current_abs_offset != end_abs_offset &&
  480. file_offset == **current_abs_offset) {
  481. RVA target_rva = PointerToTargetRVA(FileOffsetToPointer(file_offset));
  482. DCHECK_NE(kNoRVA, target_rva);
  483. Label* label = program->FindAbs32Label(target_rva);
  484. CHECK(label);
  485. if (!receptor->EmitAbs32(label))
  486. return false;
  487. file_offset += sizeof(RVA);
  488. ++(*current_abs_offset);
  489. continue;
  490. }
  491. if (*current_rel != end_rel &&
  492. file_offset == (**current_rel)->file_offset()) {
  493. uint32_t relative_target = (**current_rel)->relative_target();
  494. CHECK_EQ(RVA(origin + (file_offset - origin_offset)),
  495. (**current_rel)->rva());
  496. // This cast is for 64 bit systems, and is only safe because we
  497. // are working on 32 bit executables.
  498. RVA target_rva = (RVA)(origin + (file_offset - origin_offset) +
  499. relative_target);
  500. Label* label = program->FindRel32Label(target_rva);
  501. CHECK(label);
  502. if (!(**current_rel)->EmitInstruction(label, receptor))
  503. return false;
  504. file_offset += (**current_rel)->op_size();
  505. ++(*current_rel);
  506. continue;
  507. }
  508. }
  509. // Rest of the section (if any)
  510. return ParseSimpleRegion(file_offset, section_end, receptor);
  511. }
  512. CheckBool DisassemblerElf32::ParseSimpleRegion(
  513. FileOffset start_file_offset,
  514. FileOffset end_file_offset,
  515. InstructionReceptor* receptor) const {
  516. // Callers don't guarantee start < end
  517. if (start_file_offset >= end_file_offset)
  518. return true;
  519. const size_t len = end_file_offset - start_file_offset;
  520. if (!receptor->EmitMultipleBytes(FileOffsetToPointer(start_file_offset),
  521. len)) {
  522. return false;
  523. }
  524. return true;
  525. }
  526. CheckBool DisassemblerElf32::CheckSection(RVA rva) {
  527. // Handle 32-bit references only.
  528. constexpr uint8_t kWidth = 4;
  529. FileOffset file_offset = RVAToFileOffset(rva);
  530. if (file_offset == kNoFileOffset)
  531. return false;
  532. for (Elf32_Half section_id = 0; section_id < SectionHeaderCount();
  533. ++section_id) {
  534. const Elf32_Shdr* section_header = SectionHeader(section_id);
  535. // Take account of pointer |kWidth|, and reject pointers that start within
  536. // the section but whose span lies outside.
  537. FileOffset start_offset = section_header->sh_offset;
  538. if (file_offset < start_offset || section_header->sh_size < kWidth)
  539. continue;
  540. FileOffset end_offset = start_offset + section_header->sh_size - kWidth + 1;
  541. if (file_offset >= end_offset)
  542. continue;
  543. switch (section_header->sh_type) {
  544. case SHT_REL: // Falls through.
  545. case SHT_PROGBITS:
  546. return true;
  547. }
  548. }
  549. return false;
  550. }
  551. } // namespace courgette