1
1
mirror of https://github.com/rui314/mold.git synced 2024-09-20 09:27:45 +03:00
mold/chibild.h

147 lines
2.8 KiB
C
Raw Normal View History

2020-10-04 12:00:33 +03:00
#pragma once
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Twine.h"
2020-10-09 14:47:45 +03:00
#include "llvm/BinaryFormat/Magic.h"
#include "llvm/Object/ELF.h"
2020-10-04 12:00:33 +03:00
#include "llvm/Object/ELFTypes.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/MemoryBuffer.h"
2020-10-09 14:47:45 +03:00
#include "tbb/concurrent_hash_map.h"
2020-10-04 12:00:33 +03:00
#include <cstdlib>
#include <cstdint>
#include <string>
using llvm::ArrayRef;
2020-10-09 14:47:45 +03:00
using llvm::ErrorOr;
2020-10-04 12:00:33 +03:00
using llvm::Expected;
using llvm::MemoryBufferRef;
using llvm::SmallVector;
using llvm::StringRef;
using llvm::Twine;
using llvm::object::ELF64LE;
2020-10-09 14:47:45 +03:00
using llvm::object::ELFFile;
2020-10-04 12:00:33 +03:00
2020-10-08 11:01:54 +03:00
class Symbol;
class InputFile;
class ObjectFile;
class InputSection;
2020-10-04 12:00:33 +03:00
struct Config {
StringRef output;
};
extern Config config;
[[noreturn]] inline void error(const Twine &msg) {
llvm::errs() << msg << "\n";
exit(1);
}
2020-10-09 14:47:45 +03:00
template <class T> T check(ErrorOr<T> e) {
if (auto ec = e.getError())
error(ec.message());
return std::move(*e);
}
template <class T> T check(Expected<T> e) {
if (!e)
error(llvm::toString(e.takeError()));
return std::move(*e);
}
template <class T>
T check2(ErrorOr<T> e, llvm::function_ref<std::string()> prefix) {
if (auto ec = e.getError())
error(prefix() + ": " + ec.message());
return std::move(*e);
}
template <class T>
T check2(Expected<T> e, llvm::function_ref<std::string()> prefix) {
if (!e)
error(prefix() + ": " + toString(e.takeError()));
return std::move(*e);
}
inline std::string toString(const Twine &s) { return s.str(); }
#define CHECK(E, S) check2((E), [&] { return toString(S); })
class Symbol;
class SymbolTable;
class InputSection;
class ObjectFile;
2020-10-04 12:00:33 +03:00
class Symbol {
public:
2020-10-09 14:47:45 +03:00
StringRef name;
ObjectFile *file;
};
2020-10-09 16:00:24 +03:00
namespace tbb {
template<>
struct tbb_hash_compare<StringRef> {
static size_t hash(const StringRef& k) {
return llvm::hash_value(k);
}
static bool equal(const StringRef& k1, const StringRef& k2) {
return k1 == k2;
}
};
}
2020-10-09 14:47:45 +03:00
class SymbolTable {
public:
2020-10-10 06:18:11 +03:00
void add(StringRef key, Symbol sym);
Symbol *get(StringRef key);
2020-10-09 16:29:25 +03:00
private:
2020-10-10 06:18:11 +03:00
typedef tbb::concurrent_hash_map<StringRef, Symbol> MapType;
2020-10-09 16:29:25 +03:00
MapType map;
2020-10-04 12:00:33 +03:00
};
2020-10-08 11:01:54 +03:00
class InputSection {
public:
InputSection(ObjectFile *file, ELF64LE::Shdr *hdr, StringRef name);
void writeTo(uint8_t *buf);
uint64_t getOffset() const;
uint64_t getVA() const;
InputFile *file;
};
2020-10-04 12:00:33 +03:00
class ObjectFile {
public:
2020-10-09 14:47:45 +03:00
ObjectFile(MemoryBufferRef mb);
2020-10-04 12:00:33 +03:00
2020-10-09 14:47:45 +03:00
void parse();
2020-10-04 12:00:33 +03:00
void register_defined_symbols();
void register_undefined_symbols();
2020-10-09 14:47:45 +03:00
StringRef getFilename();
2020-10-04 12:00:33 +03:00
2020-10-09 17:26:26 +03:00
int priority;
2020-10-09 14:47:45 +03:00
private:
MemoryBufferRef mb;
std::vector<InputSection> sections;
2020-10-04 12:00:33 +03:00
std::vector<Symbol *> symbols;
2020-10-09 17:26:26 +03:00
std::vector<Symbol> symbol_instances;
2020-10-10 06:18:11 +03:00
int firstGlobal;
2020-10-04 12:00:33 +03:00
bool is_alive = false;
};
2020-10-09 14:47:45 +03:00
MemoryBufferRef readFile(StringRef path);
std::string toString(ObjectFile *);
2020-10-09 16:29:25 +03:00
extern SymbolTable symbol_table;
2020-10-09 14:47:45 +03:00
2020-10-04 12:00:33 +03:00
void write();