Mercurial > hg > CbC > CbC_llvm
diff lld/MachO/ConcatOutputSection.h @ 207:2e18cbf3894f
LLVM12
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 08 Jun 2021 06:07:14 +0900 |
parents | |
children | 5f17cb93ff66 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lld/MachO/ConcatOutputSection.h Tue Jun 08 06:07:14 2021 +0900 @@ -0,0 +1,87 @@ +//===- ConcatOutputSection.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_MERGED_OUTPUT_SECTION_H +#define LLD_MACHO_MERGED_OUTPUT_SECTION_H + +#include "InputSection.h" +#include "OutputSection.h" +#include "lld/Common/LLVM.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/MapVector.h" + +namespace lld { +namespace macho { + +class Defined; + +// Linking multiple files will inevitably mean resolving sections in different +// files that are labeled with the same segment and section name. This class +// contains all such sections and writes the data from each section sequentially +// in the final binary. +class ConcatOutputSection : public OutputSection { +public: + explicit ConcatOutputSection(StringRef name) + : OutputSection(ConcatKind, name) {} + + const InputSection *firstSection() const { return inputs.front(); } + const InputSection *lastSection() const { return inputs.back(); } + + // These accessors will only be valid after finalizing the section + uint64_t getSize() const override { return size; } + uint64_t getFileSize() const override { return fileSize; } + + void addInput(InputSection *input); + void finalize() override; + bool needsThunks() const; + uint64_t estimateStubsInRangeVA(size_t callIdx) const; + + void writeTo(uint8_t *buf) const override; + + std::vector<InputSection *> inputs; + std::vector<InputSection *> thunks; + + static bool classof(const OutputSection *sec) { + return sec->kind() == ConcatKind; + } + +private: + void mergeFlags(InputSection *input); + + size_t size = 0; + uint64_t fileSize = 0; +}; + +// We maintain one ThunkInfo per real function. +// +// The "active thunk" is represented by the sym/isec pair that +// turns-over during finalize(): as the call-site address advances, +// the active thunk goes out of branch-range, and we create a new +// thunk to take its place. +// +// The remaining members -- bools and counters -- apply to the +// collection of thunks associated with the real function. + +struct ThunkInfo { + // These denote the active thunk: + Defined *sym = nullptr; // private-extern symbol for active thunk + InputSection *isec = nullptr; // input section for active thunk + + // The following values are cumulative across all thunks on this function + uint32_t callSiteCount = 0; // how many calls to the real function? + uint32_t callSitesUsed = 0; // how many call sites processed so-far? + uint32_t thunkCallCount = 0; // how many call sites went to thunk? + uint8_t sequence = 0; // how many thunks created so-far? +}; + +extern llvm::DenseMap<Symbol *, ThunkInfo> thunkMap; + +} // namespace macho +} // namespace lld + +#endif