mirror of
https://github.com/rui314/mold.git
synced 2024-12-26 01:44:29 +03:00
temporary
This commit is contained in:
parent
1c1b5bc286
commit
01d223f289
6
main.cc
6
main.cc
@ -311,10 +311,10 @@ static void check_duplicate_symbols() {
|
||||
auto is_error = [](ObjectFile *file, int i) {
|
||||
const ElfSym &esym = file->elf_syms[i];
|
||||
Symbol &sym = *file->symbols[i];
|
||||
bool is_weak = (esym.getBinding() == STB_WEAK);
|
||||
bool is_weak = (esym.st_bind == STB_WEAK);
|
||||
bool is_eliminated =
|
||||
!esym.isAbsolute() && !esym.isCommon() && !file->sections[esym.st_shndx];
|
||||
return esym.isDefined() && !is_weak && !is_eliminated && sym.file != file;
|
||||
!esym.is_abs() && !esym.is_common() && !file->sections[esym.st_shndx];
|
||||
return esym.is_defined() && !is_weak && !is_eliminated && sym.file != file;
|
||||
};
|
||||
|
||||
tbb::parallel_for_each(out::objs, [&](ObjectFile *file) {
|
||||
|
16
mold.h
16
mold.h
@ -161,9 +161,15 @@ private:
|
||||
// ELF
|
||||
//
|
||||
|
||||
static constexpr u32 SHN_UNDEF = 0;
|
||||
static constexpr u32 SHN_ABS = 0xfff1;
|
||||
static constexpr u32 SHN_COMMON = 0xfff2;
|
||||
|
||||
struct ElfSym {
|
||||
bool is_common() const { return sh_shndx == SHN_COMMON; }
|
||||
bool is_abs() const { return sh_shndx == SHN_ABS; }
|
||||
bool is_defined() const { return !is_undef(); }
|
||||
bool is_undef() const { return st_shndx == SHN_UNDEF; }
|
||||
bool is_abs() const { return st_shndx == SHN_ABS; }
|
||||
bool is_common() const { return st_shndx == SHN_COMMON; }
|
||||
|
||||
u32 st_name;
|
||||
|
||||
@ -175,8 +181,12 @@ struct ElfSym {
|
||||
};
|
||||
};
|
||||
|
||||
union {
|
||||
u8 st_other;
|
||||
u32 st_shndx;
|
||||
u8 st_visibility : 2;
|
||||
};
|
||||
|
||||
u16 st_shndx;
|
||||
u64 st_value;
|
||||
u64 st_size;
|
||||
};
|
||||
|
@ -22,6 +22,11 @@ static const ELF64LE::Shdr
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static std::string_view get_substr(std::string_view view, u32 offset) {
|
||||
u32 end = view.find('\0', offset);
|
||||
return view.substr(offset, end);
|
||||
}
|
||||
|
||||
void ObjectFile::initialize_sections() {
|
||||
std::string_view section_strtab = CHECK(obj.getSectionStringTable(elf_sections), this);
|
||||
|
||||
@ -38,7 +43,7 @@ void ObjectFile::initialize_sections() {
|
||||
if (shdr.sh_info >= elf_syms.size())
|
||||
error(toString(this) + ": invalid symbol index");
|
||||
const ElfSym &sym = elf_syms[shdr.sh_info];
|
||||
std::string_view signature = CHECK(sym.getName(symbol_strtab), this);
|
||||
std::string_view signature = symbol_strtab.data() + sym.st_name;
|
||||
|
||||
// Get comdat group members.
|
||||
ArrayRef<ELF64LE::Word> entries =
|
||||
@ -127,25 +132,25 @@ void ObjectFile::initialize_symbols() {
|
||||
// Initialize local symbols
|
||||
for (int i = 1; i < first_global; i++) {
|
||||
const ElfSym &esym = elf_syms[i];
|
||||
std::string_view name = CHECK(esym.getName(symbol_strtab), this);
|
||||
std::string_view name = symbol_strtab.data() + esym.st_name;
|
||||
|
||||
local_symbols.emplace_back(name);
|
||||
Symbol &sym = local_symbols.back();
|
||||
|
||||
sym.file = this;
|
||||
sym.type = esym.getType();
|
||||
sym.type = esym.st_type;
|
||||
sym.value = esym.st_value;
|
||||
sym.esym = &esym;
|
||||
|
||||
if (!esym.isAbsolute()) {
|
||||
if (esym.isCommon())
|
||||
if (!esym.is_abs()) {
|
||||
if (esym.is_common())
|
||||
error("common local symbol?");
|
||||
sym.input_section = sections[esym.st_shndx];
|
||||
}
|
||||
|
||||
symbols.push_back(&local_symbols.back());
|
||||
|
||||
if (esym.getType() != STT_SECTION) {
|
||||
if (esym.st_type != STT_SECTION) {
|
||||
strtab_size += name.size() + 1;
|
||||
local_symtab_size += sizeof(ElfSym);
|
||||
}
|
||||
@ -154,14 +159,14 @@ void ObjectFile::initialize_symbols() {
|
||||
// Initialize global symbols
|
||||
for (int i = first_global; i < elf_syms.size(); i++) {
|
||||
const ElfSym &esym = elf_syms[i];
|
||||
std::string_view name = CHECK(esym.getName(symbol_strtab), this);
|
||||
std::string_view name = symbol_strtab.data() + esym.st_name;
|
||||
int pos = name.find('@');
|
||||
if (pos != std::string_view::npos)
|
||||
name = name.substr(0, pos);
|
||||
|
||||
symbols.push_back(Symbol::intern(name));
|
||||
|
||||
if (esym.isCommon())
|
||||
if (esym.is_common())
|
||||
has_common_symbol = true;
|
||||
}
|
||||
}
|
||||
@ -253,7 +258,7 @@ void ObjectFile::initialize_mergeable_sections() {
|
||||
// Initialize sym_pieces
|
||||
for (int i = 0; i < elf_syms.size(); i++) {
|
||||
const ElfSym &esym = elf_syms[i];
|
||||
if (esym.isAbsolute() || esym.isCommon())
|
||||
if (esym.is_abs() || esym.is_common())
|
||||
continue;
|
||||
|
||||
InputSection *isec = sections[esym.st_shndx];
|
||||
@ -285,7 +290,8 @@ void ObjectFile::parse() {
|
||||
|
||||
if (symtab_sec) {
|
||||
first_global = symtab_sec->sh_info;
|
||||
elf_syms = CHECK(obj.symbols(symtab_sec), this);
|
||||
ArrayRef<ELF64LE::Sym> tmp = CHECK(obj.symbols(symtab_sec), this);
|
||||
elf_syms = {(ElfSym *)tmp.data(), tmp.size()};
|
||||
symbol_strtab = CHECK(obj.getStringTableForSymtab(*symtab_sec, elf_sections), this);
|
||||
}
|
||||
|
||||
@ -297,7 +303,7 @@ void ObjectFile::parse() {
|
||||
static Counter undefined("undefined_syms");
|
||||
|
||||
for (const ElfSym &esym : elf_syms) {
|
||||
if (esym.isDefined())
|
||||
if (esym.is_defined())
|
||||
defined.inc();
|
||||
else
|
||||
undefined.inc();
|
||||
@ -317,11 +323,11 @@ void ObjectFile::parse() {
|
||||
static u64 get_rank(InputFile *file, const ElfSym &esym, InputSection *isec) {
|
||||
if (isec && isec->is_comdat_member)
|
||||
return file->priority;
|
||||
if (esym.isUndefined()) {
|
||||
assert(esym.getBinding() == STB_WEAK);
|
||||
if (esym.is_undef()) {
|
||||
assert(esym.st_bind == STB_WEAK);
|
||||
return ((u64)2 << 32) + file->priority;
|
||||
}
|
||||
if (esym.getBinding() == STB_WEAK)
|
||||
if (esym.st_bind == STB_WEAK)
|
||||
return ((u64)1 << 32) + file->priority;
|
||||
return file->priority;
|
||||
}
|
||||
@ -337,7 +343,7 @@ static u64 get_rank(const Symbol &sym) {
|
||||
void ObjectFile::maybe_override_symbol(Symbol &sym, int symidx) {
|
||||
InputSection *isec = nullptr;
|
||||
const ElfSym &esym = elf_syms[symidx];
|
||||
if (!esym.isAbsolute() && !esym.isCommon())
|
||||
if (!esym.is_abs() && !esym.is_common())
|
||||
isec = sections[esym.st_shndx];
|
||||
|
||||
std::lock_guard lock(sym.mu);
|
||||
@ -351,10 +357,10 @@ void ObjectFile::maybe_override_symbol(Symbol &sym, int symidx) {
|
||||
sym.piece_ref = sym_pieces[symidx];
|
||||
sym.value = esym.st_value;
|
||||
sym.ver_idx = 0;
|
||||
sym.type = esym.getType();
|
||||
sym.type = esym.st_type;
|
||||
sym.esym = &esym;
|
||||
sym.is_placeholder = false;
|
||||
sym.is_weak = (esym.getBinding() == STB_WEAK);
|
||||
sym.is_weak = (esym.st_bind == STB_WEAK);
|
||||
sym.is_imported = false;
|
||||
|
||||
if (UNLIKELY(sym.traced))
|
||||
@ -367,7 +373,7 @@ void ObjectFile::maybe_override_symbol(Symbol &sym, int symidx) {
|
||||
void ObjectFile::resolve_symbols() {
|
||||
for (int i = first_global; i < symbols.size(); i++) {
|
||||
const ElfSym &esym = elf_syms[i];
|
||||
if (!esym.isDefined())
|
||||
if (!esym.is_defined())
|
||||
continue;
|
||||
|
||||
Symbol &sym = *symbols[i];
|
||||
@ -400,7 +406,7 @@ ObjectFile::mark_live_objects(tbb::parallel_do_feeder<ObjectFile *> &feeder) {
|
||||
const ElfSym &esym = elf_syms[i];
|
||||
Symbol &sym = *symbols[i];
|
||||
|
||||
if (esym.isDefined()) {
|
||||
if (esym.is_defined()) {
|
||||
if (is_in_archive)
|
||||
maybe_override_symbol(sym, i);
|
||||
continue;
|
||||
@ -409,7 +415,7 @@ ObjectFile::mark_live_objects(tbb::parallel_do_feeder<ObjectFile *> &feeder) {
|
||||
if (UNLIKELY(sym.traced))
|
||||
message("trace: " + toString(this) + ": reference to " + std::string(sym.name));
|
||||
|
||||
if (esym.getBinding() != STB_WEAK && sym.file &&
|
||||
if (esym.st_bind != STB_WEAK && sym.file &&
|
||||
!sym.file->is_alive.exchange(true)) {
|
||||
if (!sym.file->is_dso)
|
||||
feeder.add((ObjectFile *)sym.file);
|
||||
@ -429,7 +435,7 @@ void ObjectFile::handle_undefined_weak_symbols() {
|
||||
const ElfSym &esym = elf_syms[i];
|
||||
Symbol &sym = *symbols[i];
|
||||
|
||||
if (esym.isUndefined() && esym.getBinding() == STB_WEAK) {
|
||||
if (esym.is_undef() && esym.st_bind == STB_WEAK) {
|
||||
std::lock_guard lock(sym.mu);
|
||||
|
||||
bool is_new = !sym.file || sym.is_placeholder;
|
||||
@ -495,7 +501,7 @@ void ObjectFile::convert_common_symbols() {
|
||||
OutputSection::get_instance(".bss", SHF_WRITE | SHF_ALLOC, SHT_NOBITS);
|
||||
|
||||
for (int i = first_global; i < elf_syms.size(); i++) {
|
||||
if (!elf_syms[i].isCommon())
|
||||
if (!elf_syms[i].is_common())
|
||||
continue;
|
||||
|
||||
Symbol *sym = symbols[i];
|
||||
@ -523,7 +529,7 @@ void ObjectFile::compute_symtab() {
|
||||
const ElfSym &esym = elf_syms[i];
|
||||
Symbol &sym = *symbols[i];
|
||||
|
||||
if (esym.getType() != STT_SECTION && sym.file == this) {
|
||||
if (esym.st_type != STT_SECTION && sym.file == this) {
|
||||
global_symtab_size += sizeof(ElfSym);
|
||||
strtab_size += sym.name.size() + 1;
|
||||
}
|
||||
@ -553,7 +559,7 @@ void ObjectFile::write_symtab() {
|
||||
else if (sym.shndx)
|
||||
esym.st_shndx = sym.shndx;
|
||||
else
|
||||
esym.st_shndx = SHN_ABS;
|
||||
esym.st_shndx = ::SHN_ABS;
|
||||
|
||||
write_string(strtab_base + strtab_off, sym.name);
|
||||
strtab_off += sym.name.size() + 1;
|
||||
@ -589,10 +595,10 @@ ObjectFile *ObjectFile::create_internal_file() {
|
||||
|
||||
auto add = [&](std::string_view name, u8 visibility = STV_DEFAULT) {
|
||||
ElfSym esym = {};
|
||||
esym.setType(STT_NOTYPE);
|
||||
esym.st_shndx = SHN_ABS;
|
||||
esym.setBinding(STB_GLOBAL);
|
||||
esym.setVisibility(visibility);
|
||||
esym.st_type = STT_NOTYPE;
|
||||
esym.st_shndx = ::SHN_ABS;
|
||||
esym.st_bind = STB_GLOBAL;
|
||||
esym.st_visibility = visibility;
|
||||
elf_syms->push_back(esym);
|
||||
|
||||
Symbol *sym = Symbol::intern(name);
|
||||
@ -668,7 +674,8 @@ void SharedFile::parse() {
|
||||
|
||||
// Read a symbol table.
|
||||
int first_global = symtab_sec->sh_info;
|
||||
ArrayRef<ElfSym> esyms = CHECK(obj.symbols(symtab_sec), this);
|
||||
ArrayRef<ELF64LE::Sym> tmp = CHECK(obj.symbols(symtab_sec), this);
|
||||
ArrayRef<ElfSym> esyms = {(ElfSym *)tmp.data(), tmp.size()};
|
||||
ArrayRef<u16> vers;
|
||||
if (const ELF64LE::Shdr *sec = find_section(elf_sections, SHT_GNU_versym))
|
||||
vers = CHECK(obj.template getSectionContentsAsArray<u16>(*sec), this);
|
||||
@ -676,7 +683,7 @@ void SharedFile::parse() {
|
||||
std::vector<std::pair<const ElfSym *, u16>> pairs;
|
||||
|
||||
for (int i = first_global; i < esyms.size(); i++) {
|
||||
if (!esyms[i].isDefined())
|
||||
if (!esyms[i].is_defined())
|
||||
continue;
|
||||
if (!vers.empty() && (vers[i] >> 15) == 1)
|
||||
continue;
|
||||
@ -703,7 +710,7 @@ void SharedFile::parse() {
|
||||
elf_syms.push_back(x.first);
|
||||
versyms.push_back(x.second);
|
||||
|
||||
std::string_view name = CHECK(x.first->getName(symbol_strtab), this);
|
||||
std::string_view name = symbol_strtab.data() + x.first->st_name;
|
||||
symbols.push_back(Symbol::intern(name));
|
||||
}
|
||||
|
||||
@ -755,10 +762,10 @@ void SharedFile::resolve_symbols() {
|
||||
sym.piece_ref = {};
|
||||
sym.value = esym.st_value;
|
||||
sym.ver_idx = versyms[i];
|
||||
sym.type = (esym.getType() == STT_GNU_IFUNC) ? STT_FUNC : esym.getType();
|
||||
sym.type = (esym.st_type == STT_GNU_IFUNC) ? STT_FUNC : esym.st_type;
|
||||
sym.esym = &esym;
|
||||
sym.is_placeholder = false;
|
||||
sym.is_weak = (esym.getBinding() == STB_WEAK);
|
||||
sym.is_weak = (esym.st_bind == STB_WEAK);
|
||||
sym.is_imported = true;
|
||||
|
||||
if (UNLIKELY(sym.traced))
|
||||
|
@ -555,17 +555,17 @@ void DynsymSection::copy_buf() {
|
||||
auto &esym = *(ElfSym *)(base + sym->dynsym_idx * sizeof(ElfSym));
|
||||
memset(&esym, 0, sizeof(esym));
|
||||
esym.st_name = sym->dynstr_offset;
|
||||
esym.setType(sym->type);
|
||||
esym.setBinding(sym->esym->getBinding());
|
||||
esym.st_type = sym->type;
|
||||
esym.st_bind = sym->esym->st_bind;
|
||||
esym.st_size = sym->esym->st_size;
|
||||
|
||||
if (sym->copyrel_offset != -1) {
|
||||
esym.st_shndx = out::copyrel->shndx;
|
||||
esym.st_value = sym->get_addr();
|
||||
} else if (sym->is_imported || sym->esym->isUndefined()) {
|
||||
esym.st_shndx = SHN_UNDEF;
|
||||
} else if (sym->is_imported || sym->esym->is_undef()) {
|
||||
esym.st_shndx = ::SHN_UNDEF;
|
||||
} else if (!sym->input_section) {
|
||||
esym.st_shndx = SHN_ABS;
|
||||
esym.st_shndx = ::SHN_ABS;
|
||||
esym.st_value = sym->get_addr();
|
||||
} else {
|
||||
esym.st_shndx = sym->input_section->output_section->shndx;
|
||||
|
Loading…
Reference in New Issue
Block a user