1
1
mirror of https://github.com/rui314/mold.git synced 2024-09-22 10:27:48 +03:00

temporary

This commit is contained in:
Rui Ueyama 2020-11-29 12:59:08 +09:00
parent 36b941a71e
commit 3a004907d4
3 changed files with 60 additions and 14 deletions

45
main.cc
View File

@ -485,6 +485,49 @@ static void fill_symbol_versions() {
// Fill .gnu.versoin_r.
u8 *buf = (u8 *)&out::verneed->contents[0];
u16 version = 1;
auto start = [&](Symbol *sym) {
out::verneed->shdr.sh_info += 1;
SharedFile *file = (SharedFile *)sym->file;
auto *verneed = (ELF64LE::Verneed *)buf;
buf += sizeof(*verneed);
verneed->vn_version = 1;
verneed->vn_file = file->soname_dynstr_idx;
verneed->vn_aux = sizeof(ELF64LE::Verneed);
StringRef verstr = file->version_strings[sym->ver_idx];
auto *aux = (ELF64LE::Vernaux *)buf;
buf += sizeof(*aux);
aux->vna_hash = elf_hash(verstr);
aux->vna_other = ++version;
aux->vna_name = out::dynstr->add_string(verstr);
};
auto add = [&](Symbol *sym) {
auto *prev = (ELF64LE::Vernaux *)(buf - sizeof(ELF64LE::Vernaux));
prev->vna_next = sizeof(ELF64LE::Vernaux);
SharedFile *file = (SharedFile *)sym->file;
StringRef verstr = file->version_strings[sym->ver_idx];
auto *aux = (ELF64LE::Vernaux *)buf;
buf += sizeof(*aux);
aux->vna_hash = elf_hash(verstr);
aux->vna_other = ++version;
aux->vna_name = out::dynstr->add_string(verstr);
};
start(syms[0]);
for (int i = 1; i < syms.size(); i++) {
if (syms[i - 1]->file != syms[i]->file)
start(syms[i]);
else if (syms[i - 1]->ver_idx != syms[i]->ver_idx)
add(syms[i]);
out::versym->contents[syms[i]->dynsym_idx] = version;
}
}
static void write_merged_strings() {
@ -829,6 +872,8 @@ int main(int argc, char **argv) {
out::chunks.push_back(out::strtab);
out::chunks.push_back(out::hash);
out::chunks.push_back(out::copyrel);
out::chunks.push_back(out::versym);
out::chunks.push_back(out::verneed);
// Set priorities to files. File priority 1 is reserved for the internal file.
int priority = 2;

12
mold.h
View File

@ -922,6 +922,18 @@ inline u64 InputChunk::get_addr() const {
return output_section->shdr.sh_addr + offset;
}
inline u32 elf_hash(StringRef name) {
u32 h = 0;
for (char c : name) {
h = (h << 4) + c;
u32 g = h & 0xf0000000;
if (g != 0)
h ^= g >> 24;
h &= ~g;
}
return h;
}
inline void write_string(u8 *buf, StringRef str) {
memcpy(buf, str.data(), str.size());
buf[str.size()] = '\0';

View File

@ -611,24 +611,12 @@ void HashSection::copy_buf() {
hdr[0] = hdr[1] = num_slots;
for (Symbol *sym : out::dynsym->symbols) {
u32 i = hash(sym->name) % num_slots;
u32 i = elf_hash(sym->name) % num_slots;
chains[sym->dynsym_idx] = buckets[i];
buckets[i] = sym->dynsym_idx;
}
}
u32 HashSection::hash(StringRef name) {
u32 h = 0;
for (char c : name) {
h = (h << 4) + c;
u32 g = h & 0xf0000000;
if (g != 0)
h ^= g >> 24;
h &= ~g;
}
return h;
}
MergedSection *
MergedSection::get_instance(StringRef name, u64 flags, u32 type) {
name = get_output_name(name);
@ -673,7 +661,7 @@ void CopyrelSection::add_symbol(Symbol *sym) {
}
void VersymSection::update_shdr() {
shdr.sh_size = (out::dynsym->symbols.size() + 1) * 2;
shdr.sh_size = contents.size() * sizeof(contents[0]);
shdr.sh_link = out::dynsym->shndx;
}
@ -682,6 +670,7 @@ void VersymSection::copy_buf() {
}
void VerneedSection::update_shdr() {
shdr.sh_size = contents.size() * sizeof(contents[0]);
shdr.sh_link = out::dynstr->shndx;
}