| Index: courgette/disassembler_elf_32.cc
|
| diff --git a/courgette/disassembler_elf_32.cc b/courgette/disassembler_elf_32.cc
|
| index 346d9a19906fbc4291464ff34027527639386423..d307fc4a6d3ef5aa65d2492cdefff2ebc018b753 100644
|
| --- a/courgette/disassembler_elf_32.cc
|
| +++ b/courgette/disassembler_elf_32.cc
|
| @@ -14,18 +14,20 @@ namespace courgette {
|
|
|
| namespace {
|
|
|
| -// Initializes |section_header_table| by copying |section_header_table_size|
|
| -// entries from |section_header_table_raw|, and sorting by |sh_offset|.
|
| -void SortSectionHeader(const Elf32_Shdr* section_header_table_raw,
|
| - Elf32_Half section_header_table_size,
|
| - std::vector<Elf32_Shdr>* section_header_table) {
|
| - section_header_table->assign(section_header_table_raw,
|
| - section_header_table_raw + section_header_table_size);
|
| - auto comp = [](const Elf32_Shdr& header1, const Elf32_Shdr& header2) {
|
| - return header1.sh_offset < header2.sh_offset;
|
| +// Sorts |section_headers| by file offset and stores the resulting permutation
|
| +// of section ids in |order|.
|
| +std::vector<Elf32_Half> GetSectionHeaderFileOffsetOrder(
|
| + const std::vector<Elf32_Shdr>& section_headers) {
|
| + size_t size = section_headers.size();
|
| + std::vector<Elf32_Half> order(size);
|
| + for (size_t i = 0; i < size; ++i)
|
| + order[i] = static_cast<Elf32_Half>(i);
|
| +
|
| + auto comp = [&](int idx1, int idx2) {
|
| + return section_headers[idx1].sh_offset < section_headers[idx2].sh_offset;
|
| };
|
| - std::stable_sort(
|
| - section_header_table->begin(), section_header_table->end(), comp);
|
| + std::stable_sort(order.begin(), order.end(), comp);
|
| + return order;
|
| }
|
|
|
| } // namespace
|
| @@ -44,8 +46,8 @@ RVA DisassemblerElf32::FileOffsetToRVA(FileOffset offset) const {
|
| // executables and so only need to support 32-bit file sizes.
|
| uint32_t offset32 = static_cast<uint32_t>(offset);
|
|
|
| - for (Elf32_Half section_id = 0; section_id < SectionHeaderCount();
|
| - ++section_id) {
|
| + // Visit section headers ordered by file offset.
|
| + for (Elf32_Half section_id : section_header_file_offset_order_) {
|
| const Elf32_Shdr* section_header = SectionHeader(section_id);
|
| // These can appear to have a size in the file, but don't.
|
| if (section_header->sh_type == SHT_NOBITS)
|
| @@ -112,12 +114,16 @@ bool DisassemblerElf32::ParseHeader() {
|
| if (!IsArrayInBounds(header_->e_shoff, header_->e_shnum, sizeof(Elf32_Shdr)))
|
| return Bad("Out of bounds section header table");
|
|
|
| + // Extract |section_header_table_|, ordered by section id.
|
| const Elf32_Shdr* section_header_table_raw =
|
| reinterpret_cast<const Elf32_Shdr*>(
|
| FileOffsetToPointer(header_->e_shoff));
|
| section_header_table_size_ = header_->e_shnum;
|
| - SortSectionHeader(section_header_table_raw, section_header_table_size_,
|
| - §ion_header_table_);
|
| + section_header_table_.assign(section_header_table_raw,
|
| + section_header_table_raw + section_header_table_size_);
|
| +
|
| + section_header_file_offset_order_ =
|
| + GetSectionHeaderFileOffsetOrder(section_header_table_);
|
|
|
| if (!IsArrayInBounds(header_->e_phoff, header_->e_phnum, sizeof(Elf32_Phdr)))
|
| return Bad("Out of bounds program header table");
|
| @@ -264,8 +270,8 @@ CheckBool DisassemblerElf32::ParseFile(AssemblyProgram* program) {
|
| std::vector<FileOffset>::iterator end_abs_offset = abs_offsets.end();
|
| ScopedVector<TypedRVA>::iterator end_rel = rel32_locations_.end();
|
|
|
| - for (Elf32_Half section_id = 0; section_id < SectionHeaderCount();
|
| - ++section_id) {
|
| + // Visit section headers ordered by file offset.
|
| + for (Elf32_Half section_id : section_header_file_offset_order_) {
|
| const Elf32_Shdr* section_header = SectionHeader(section_id);
|
|
|
| if (section_header->sh_type == SHT_NOBITS)
|
|
|