llvm/lld/ELF/Symbols.h

//===- Symbols.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
//
//===----------------------------------------------------------------------===//
//
// This file defines various types of Symbols.
//
//===----------------------------------------------------------------------===//

#ifndef LLD_ELF_SYMBOLS_H
#define LLD_ELF_SYMBOLS_H

#include "Config.h"
#include "lld/Common/LLVM.h"
#include "lld/Common/Memory.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Object/ELF.h"
#include "llvm/Support/Compiler.h"
#include <tuple>

namespace lld {
namespace elf {
class Symbol;
}
// Returns a string representation for a symbol for diagnostics.
std::string toString(const elf::Symbol &);

namespace elf {
class CommonSymbol;
class Defined;
class OutputSection;
class SectionBase;
class InputSectionBase;
class SharedSymbol;
class Symbol;
class Undefined;
class LazySymbol;
class InputFile;

void printTraceSymbol(const Symbol &sym, StringRef name);

enum {};

// The base class for real symbol classes.
class Symbol {};

// Represents a symbol that is defined in the current output file.
class Defined : public Symbol {};

// Represents a common symbol.
//
// On Unix, it is traditionally allowed to write variable definitions
// without initialization expressions (such as "int foo;") to header
// files. Such definition is called "tentative definition".
//
// Using tentative definition is usually considered a bad practice
// because you should write only declarations (such as "extern int
// foo;") to header files. Nevertheless, the linker and the compiler
// have to do something to support bad code by allowing duplicate
// definitions for this particular case.
//
// Common symbols represent variable definitions without initializations.
// The compiler creates common symbols when it sees variable definitions
// without initialization (you can suppress this behavior and let the
// compiler create a regular defined symbol by -fno-common).
//
// The linker allows common symbols to be replaced by regular defined
// symbols. If there are remaining common symbols after name resolution is
// complete, they are converted to regular defined symbols in a .bss
// section. (Therefore, the later passes don't see any CommonSymbols.)
class CommonSymbol : public Symbol {};

class Undefined : public Symbol {};

class SharedSymbol : public Symbol {};

// LazySymbol symbols represent symbols in object files between --start-lib and
// --end-lib options. LLD also handles traditional archives as if all the files
// in the archive are surrounded by --start-lib and --end-lib.
//
// A special complication is the handling of weak undefined symbols. They should
// not load a file, but we have to remember we have seen both the weak undefined
// and the lazy. We represent that with a lazy symbol with a weak binding. This
// means that code looking for undefined symbols normally also has to take lazy
// symbols into consideration.
class LazySymbol : public Symbol {};

// A buffer class that is large enough to hold any Symbol-derived
// object. We allocate memory using this class and instantiate a symbol
// using the placement new.

// It is important to keep the size of SymbolUnion small for performance and
// memory usage reasons. 64 bytes is a soft limit based on the size of Defined
// on a 64-bit system. This is enforced by a static_assert in Symbols.cpp.
SymbolUnion;

template <typename... T> Defined *makeDefined(T &&...args) {}

void reportDuplicate(const Symbol &sym, const InputFile *newFile,
                     InputSectionBase *errSec, uint64_t errOffset);
void maybeWarnUnorderableSymbol(const Symbol *sym);
bool computeIsPreemptible(const Symbol &sym);

} // namespace elf
} // namespace lld

#endif