2013-12-07 08:27:17 +08:00
|
|
|
//===- lib/ReaderWriter/PECOFF/GroupedSectionsPass.h ----------------------===//
|
2013-06-20 01:46:57 +08:00
|
|
|
//
|
|
|
|
// The LLVM Linker
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
///
|
2013-12-07 08:27:17 +08:00
|
|
|
/// \file \brief This pass sorts atoms by section name, so that they will appear
|
|
|
|
/// in the correct order in the output.
|
2013-06-20 01:46:57 +08:00
|
|
|
///
|
|
|
|
/// In COFF, sections will be merged into one section by the linker if their
|
|
|
|
/// names are the same after discarding the "$" character and all characters
|
|
|
|
/// follow it from their names. The characters following the "$" character
|
|
|
|
/// determines the merge order. Assume there's an object file containing four
|
|
|
|
/// data sections in the following order.
|
|
|
|
///
|
|
|
|
/// - .data$2
|
|
|
|
/// - .data$3
|
|
|
|
/// - .data$1
|
|
|
|
/// - .data
|
|
|
|
///
|
|
|
|
/// In this case, the resulting binary should have ".data" section with the
|
|
|
|
/// contents of ".data", ".data$1", ".data$2" and ".data$3" in that order.
|
|
|
|
///
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2013-11-15 11:09:26 +08:00
|
|
|
#ifndef LLD_READER_WRITER_PE_COFF_GROUPED_SECTIONS_PASS_H
|
|
|
|
#define LLD_READER_WRITER_PE_COFF_GROUPED_SECTIONS_PASS_H
|
2013-06-20 01:46:57 +08:00
|
|
|
|
|
|
|
#include "Atoms.h"
|
|
|
|
#include "lld/Core/Pass.h"
|
|
|
|
#include <algorithm>
|
|
|
|
|
|
|
|
namespace lld {
|
|
|
|
namespace pecoff {
|
|
|
|
|
2013-12-07 08:27:17 +08:00
|
|
|
static bool compare(const DefinedAtom *left, const DefinedAtom *right) {
|
|
|
|
if (left->sectionChoice() == DefinedAtom::sectionCustomRequired &&
|
|
|
|
right->sectionChoice() == DefinedAtom::sectionCustomRequired) {
|
|
|
|
return left->customSectionName().compare(right->customSectionName()) < 0;
|
|
|
|
}
|
|
|
|
return left->sectionChoice() == DefinedAtom::sectionCustomRequired &&
|
2013-12-11 22:10:25 +08:00
|
|
|
right->sectionChoice() != DefinedAtom::sectionCustomRequired;
|
2013-06-20 01:46:57 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
class GroupedSectionsPass : public lld::Pass {
|
2013-12-11 22:10:25 +08:00
|
|
|
public:
|
2014-03-06 03:50:03 +08:00
|
|
|
void perform(std::unique_ptr<MutableFile> &file) override {
|
2013-12-07 08:27:17 +08:00
|
|
|
auto definedAtoms = file->definedAtoms();
|
|
|
|
std::stable_sort(definedAtoms.begin(), definedAtoms.end(), compare);
|
2013-08-29 15:46:23 +08:00
|
|
|
}
|
2013-06-20 01:46:57 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace pecoff
|
|
|
|
} // namespace lld
|
|
|
|
|
|
|
|
#endif
|