llvm-project/lld/MachO/OutputSection.h
Jez Ng fcab06bd85 [lld-macho][nfc] Sort OutputSections based on explicit order of command-line inputs
This diff paves the way for {D102964} which adds a new kind of
InputSection.

We previously maintained section ordering implicitly: we created
InputSections as we parsed each file in command-line order, and passed
on this ordering when we created OutputSections and OutputSegments by
iterating over these InputSections. The implicitness of the ordering
made it difficult to refactor the code to e.g. handle a new type of
InputSection. As such, I've codified the ordering explicitly via
`inputOrder` fields. This also allows us to use `sort` instead of
`stable_sort`.

Benchmarking chromium_framework on my 3.2 GHz 16-Core Intel Xeon W:

      N           Min           Max        Median           Avg        Stddev
  x  20          4.23          4.35          4.27         4.274   0.030157481
  +  20          4.24          4.38          4.27        4.2815   0.033759989
  No difference proven at 95.0% confidence

Reviewed By: #lld-macho, alexshap

Differential Revision: https://reviews.llvm.org/D102972
2021-05-25 14:58:29 -04:00

82 lines
2.4 KiB
C++

//===- OutputSection.h ------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLD_MACHO_OUTPUT_SECTION_H
#define LLD_MACHO_OUTPUT_SECTION_H
#include "lld/Common/LLVM.h"
#include "llvm/ADT/DenseMap.h"
#include <limits>
namespace lld {
namespace macho {
class InputSection;
class OutputSegment;
// Output sections represent the finalized sections present within the final
// linked executable. They can represent special sections (like the symbol
// table), or represent coalesced sections from the various inputs given to the
// linker with the same segment / section name.
class OutputSection {
public:
enum Kind {
ConcatKind,
SyntheticKind,
};
OutputSection(Kind kind, StringRef name) : name(name), sectionKind(kind) {}
virtual ~OutputSection() = default;
Kind kind() const { return sectionKind; }
// These accessors will only be valid after finalizing the section.
uint64_t getSegmentOffset() const;
// How much space the section occupies in the address space.
virtual uint64_t getSize() const = 0;
// How much space the section occupies in the file. Most sections are copied
// as-is so their file size is the same as their address space size.
virtual uint64_t getFileSize() const { return getSize(); }
// Hidden sections omit header content, but body content may still be present.
virtual bool isHidden() const { return false; }
// Unneeded sections are omitted entirely (header and body).
virtual bool isNeeded() const { return true; }
virtual void finalize() {
// TODO investigate refactoring synthetic section finalization logic into
// overrides of this function.
}
virtual void writeTo(uint8_t *buf) const = 0;
StringRef name;
OutputSegment *parent = nullptr;
// For output sections that don't have explicit ordering requirements, their
// output order should be based on the order of the input sections they
// contain.
int inputOrder = std::numeric_limits<int>::max();
uint32_t index = 0;
uint64_t addr = 0;
uint64_t fileOff = 0;
uint32_t align = 1;
uint32_t flags = 0;
uint32_t reserved1 = 0;
uint32_t reserved2 = 0;
private:
Kind sectionKind;
};
} // namespace macho
} // namespace lld
#endif