mirror of
https://github.com/rui314/mold.git
synced 2024-12-26 01:44:29 +03:00
Use i64 instead of int or u32
This commit is contained in:
parent
e0a09394a6
commit
f645a9deb1
@ -9,7 +9,7 @@ std::string_view InputChunk::get_contents() const {
|
||||
return file->get_string(shdr);
|
||||
}
|
||||
|
||||
static std::string rel_to_string(u32 r_type) {
|
||||
static std::string rel_to_string(u64 r_type) {
|
||||
switch (r_type) {
|
||||
case R_X86_64_NONE: return "R_X86_64_NONE";
|
||||
case R_X86_64_8: return "R_X86_64_8";
|
||||
@ -38,7 +38,7 @@ static std::string rel_to_string(u32 r_type) {
|
||||
unreachable();
|
||||
}
|
||||
|
||||
static void overflow_check(InputSection *sec, Symbol &sym, u32 r_type, u64 val) {
|
||||
static void overflow_check(InputSection *sec, Symbol &sym, u64 r_type, u64 val) {
|
||||
switch (r_type) {
|
||||
case R_X86_64_8:
|
||||
if (val != (u8)val)
|
||||
@ -98,7 +98,7 @@ static void overflow_check(InputSection *sec, Symbol &sym, u32 r_type, u64 val)
|
||||
unreachable();
|
||||
}
|
||||
|
||||
static void write_val(u32 r_type, u8 *loc, u64 val) {
|
||||
static void write_val(u64 r_type, u8 *loc, u64 val) {
|
||||
switch (r_type) {
|
||||
case R_X86_64_NONE:
|
||||
return;
|
||||
@ -156,14 +156,14 @@ void InputSection::copy_buf() {
|
||||
// mapped to memory at runtime) based on the result of
|
||||
// scan_relocations().
|
||||
void InputSection::apply_reloc_alloc(u8 *base) {
|
||||
int ref_idx = 0;
|
||||
i64 ref_idx = 0;
|
||||
ElfRela *dynrel = nullptr;
|
||||
|
||||
if (out::reldyn)
|
||||
dynrel = (ElfRela *)(out::buf + out::reldyn->shdr.sh_offset +
|
||||
file->reldyn_offset + reldyn_offset);
|
||||
|
||||
for (int i = 0; i < rels.size(); i++) {
|
||||
for (i64 i = 0; i < rels.size(); i++) {
|
||||
const ElfRela &rel = rels[i];
|
||||
Symbol &sym = *file->symbols[rel.r_sym];
|
||||
u8 *loc = base + rel.r_offset;
|
||||
@ -273,9 +273,9 @@ void InputSection::apply_reloc_nonalloc(u8 *base) {
|
||||
static Counter counter("reloc_nonalloc");
|
||||
counter.inc(rels.size());
|
||||
|
||||
int ref_idx = 0;
|
||||
i64 ref_idx = 0;
|
||||
|
||||
for (int i = 0; i < rels.size(); i++) {
|
||||
for (i64 i = 0; i < rels.size(); i++) {
|
||||
const ElfRela &rel = rels[i];
|
||||
Symbol &sym = *file->symbols[rel.r_sym];
|
||||
|
||||
@ -343,7 +343,7 @@ void InputSection::scan_relocations() {
|
||||
this->reldyn_offset = file->num_dynrel * sizeof(ElfRela);
|
||||
this->rel_types.resize(rels.size());
|
||||
|
||||
for (int i = 0; i < rels.size(); i++) {
|
||||
for (i64 i = 0; i < rels.size(); i++) {
|
||||
const ElfRela &rel = rels[i];
|
||||
Symbol &sym = *file->symbols[rel.r_sym];
|
||||
bool is_readonly = !(shdr.sh_flags & SHF_WRITE);
|
||||
|
@ -16,7 +16,7 @@ static std::vector<std::string_view> tokenize(std::string_view input) {
|
||||
}
|
||||
|
||||
if (input.starts_with("/*")) {
|
||||
int pos = input.find("*/", 2);
|
||||
i64 pos = input.find("*/", 2);
|
||||
if (pos == std::string_view::npos)
|
||||
Fatal() << "unclosed comment";
|
||||
input = input.substr(pos + 2);
|
||||
@ -24,7 +24,7 @@ static std::vector<std::string_view> tokenize(std::string_view input) {
|
||||
}
|
||||
|
||||
if (input[0] == '#') {
|
||||
int pos = input.find("\n", 1);
|
||||
i64 pos = input.find("\n", 1);
|
||||
if (pos == std::string_view::npos)
|
||||
break;
|
||||
input = input.substr(pos + 1);
|
||||
@ -32,7 +32,7 @@ static std::vector<std::string_view> tokenize(std::string_view input) {
|
||||
}
|
||||
|
||||
if (input[0] == '"') {
|
||||
int pos = input.find('"', 1);
|
||||
i64 pos = input.find('"', 1);
|
||||
if (pos == std::string_view::npos)
|
||||
Fatal() << "unclosed string literal";
|
||||
vec.push_back(input.substr(0, pos));
|
||||
@ -40,7 +40,7 @@ static std::vector<std::string_view> tokenize(std::string_view input) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int pos = input.find_first_not_of(
|
||||
i64 pos = input.find_first_not_of(
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789_.$/\\~=+[]*?-!^:");
|
||||
|
||||
@ -107,7 +107,7 @@ read_group(std::span<std::string_view> tok, bool as_needed) {
|
||||
void parse_linker_script(MemoryMappedFile *mb, bool as_needed) {
|
||||
script_dir = mb->name.substr(0, mb->name.find_last_of('/'));
|
||||
|
||||
std::vector<std::string_view> vec = tokenize({(char *)mb->data(), mb->size()});
|
||||
std::vector<std::string_view> vec = tokenize(mb->get_contents());
|
||||
std::span<std::string_view> tok = vec;
|
||||
|
||||
while (!tok.empty()) {
|
||||
@ -124,7 +124,7 @@ void parse_version_script(std::string path) {
|
||||
script_dir = path.substr(0, path.find_last_of('/'));
|
||||
|
||||
MemoryMappedFile *mb = MemoryMappedFile::must_open(path);
|
||||
std::vector<std::string_view> vec = tokenize({(char *)mb->data(), mb->size()});
|
||||
std::vector<std::string_view> vec = tokenize(mb->get_contents());
|
||||
std::span<std::string_view> tok = vec;
|
||||
tok = skip(tok, "{");
|
||||
|
||||
|
102
main.cc
102
main.cc
@ -75,7 +75,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
typedef std::tuple<std::string, u64, u64> Key;
|
||||
typedef std::tuple<std::string, i64, i64> Key;
|
||||
std::map<Key, std::vector<T *>> cache;
|
||||
};
|
||||
|
||||
@ -143,7 +143,7 @@ void read_file(MemoryMappedFile *mb, bool as_needed) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static std::vector<std::span<T>> split(std::vector<T> &input, int unit) {
|
||||
static std::vector<std::span<T>> split(std::vector<T> &input, i64 unit) {
|
||||
assert(input.size() > 0);
|
||||
std::span<T> span(input);
|
||||
std::vector<std::span<T>> vec;
|
||||
@ -213,7 +213,7 @@ static void handle_mergeable_strings() {
|
||||
// Calculate the total bytes of mergeable strings for each input section.
|
||||
tbb::parallel_for_each(out::objs, [](ObjectFile *file) {
|
||||
for (MergeableSection *isec : file->mergeable_sections) {
|
||||
u32 offset = 0;
|
||||
i64 offset = 0;
|
||||
for (SectionFragment *frag : isec->fragments) {
|
||||
if (frag->isec == isec && frag->offset == -1) {
|
||||
offset = align_to(offset, frag->alignment);
|
||||
@ -228,8 +228,8 @@ static void handle_mergeable_strings() {
|
||||
// Assign each mergeable input section a unique index.
|
||||
for (ObjectFile *file : out::objs) {
|
||||
for (MergeableSection *isec : file->mergeable_sections) {
|
||||
u64 offset = isec->parent.shdr.sh_size;
|
||||
u32 alignment = isec->shdr.sh_addralign;
|
||||
i64 offset = isec->parent.shdr.sh_size;
|
||||
i64 alignment = isec->shdr.sh_addralign;
|
||||
isec->padding = align_to(offset, alignment) - offset;
|
||||
isec->offset = offset + isec->padding;
|
||||
isec->parent.shdr.sh_size = offset + isec->padding + isec->size;
|
||||
@ -249,31 +249,31 @@ static void handle_mergeable_strings() {
|
||||
static void bin_sections() {
|
||||
Timer t("bin_sections");
|
||||
|
||||
int unit = (out::objs.size() + 127) / 128;
|
||||
i64 unit = (out::objs.size() + 127) / 128;
|
||||
std::vector<std::span<ObjectFile *>> slices = split(out::objs, unit);
|
||||
|
||||
int num_osec = OutputSection::instances.size();
|
||||
i64 num_osec = OutputSection::instances.size();
|
||||
|
||||
std::vector<std::vector<std::vector<InputSection *>>> groups(slices.size());
|
||||
for (int i = 0; i < groups.size(); i++)
|
||||
for (i64 i = 0; i < groups.size(); i++)
|
||||
groups[i].resize(num_osec);
|
||||
|
||||
tbb::parallel_for(0, (int)slices.size(), [&](int i) {
|
||||
tbb::parallel_for((i64)0, (i64)slices.size(), [&](i64 i) {
|
||||
for (ObjectFile *file : slices[i])
|
||||
for (InputSection *isec : file->sections)
|
||||
if (isec)
|
||||
groups[i][isec->output_section->idx].push_back(isec);
|
||||
});
|
||||
|
||||
std::vector<int> sizes(num_osec);
|
||||
std::vector<i64> sizes(num_osec);
|
||||
|
||||
for (std::span<std::vector<InputSection *>> group : groups)
|
||||
for (int i = 0; i < group.size(); i++)
|
||||
for (i64 i = 0; i < group.size(); i++)
|
||||
sizes[i] += group[i].size();
|
||||
|
||||
tbb::parallel_for(0, num_osec, [&](int j) {
|
||||
tbb::parallel_for((i64)0, num_osec, [&](i64 j) {
|
||||
OutputSection::instances[j]->members.reserve(sizes[j]);
|
||||
for (int i = 0; i < groups.size(); i++)
|
||||
for (i64 i = 0; i < groups.size(); i++)
|
||||
append(OutputSection::instances[j]->members, groups[i][j]);
|
||||
});
|
||||
}
|
||||
@ -282,7 +282,7 @@ static void check_duplicate_symbols() {
|
||||
Timer t("check_dup_syms");
|
||||
|
||||
tbb::parallel_for_each(out::objs, [&](ObjectFile *file) {
|
||||
for (int i = file->first_global; i < file->elf_syms.size(); i++) {
|
||||
for (i64 i = file->first_global; i < file->elf_syms.size(); i++) {
|
||||
const ElfSym &esym = file->elf_syms[i];
|
||||
Symbol &sym = *file->symbols[i];
|
||||
bool is_weak = (esym.st_bind == STB_WEAK);
|
||||
@ -306,31 +306,31 @@ static void set_isec_offsets() {
|
||||
return;
|
||||
|
||||
std::vector<std::span<InputSection *>> slices = split(osec->members, 10000);
|
||||
std::vector<u64> size(slices.size());
|
||||
std::vector<u32> alignments(slices.size());
|
||||
std::vector<i64> size(slices.size());
|
||||
std::vector<i64> alignments(slices.size());
|
||||
|
||||
tbb::parallel_for(0, (int)slices.size(), [&](int i) {
|
||||
u64 off = 0;
|
||||
u32 align = 1;
|
||||
tbb::parallel_for((i64)0, (i64)slices.size(), [&](i64 i) {
|
||||
i64 off = 0;
|
||||
i64 align = 1;
|
||||
|
||||
for (InputChunk *isec : slices[i]) {
|
||||
off = align_to(off, isec->shdr.sh_addralign);
|
||||
isec->offset = off;
|
||||
off += isec->shdr.sh_size;
|
||||
align = std::max<u32>(align, isec->shdr.sh_addralign);
|
||||
align = std::max<i64>(align, isec->shdr.sh_addralign);
|
||||
}
|
||||
|
||||
size[i] = off;
|
||||
alignments[i] = align;
|
||||
});
|
||||
|
||||
u32 align = *std::max_element(alignments.begin(), alignments.end());
|
||||
i64 align = *std::max_element(alignments.begin(), alignments.end());
|
||||
|
||||
std::vector<u64> start(slices.size());
|
||||
for (int i = 1; i < slices.size(); i++)
|
||||
std::vector<i64> start(slices.size());
|
||||
for (i64 i = 1; i < slices.size(); i++)
|
||||
start[i] = align_to(start[i - 1] + size[i - 1], align);
|
||||
|
||||
tbb::parallel_for(1, (int)slices.size(), [&](int i) {
|
||||
tbb::parallel_for((i64)1, (i64)slices.size(), [&](i64 i) {
|
||||
for (InputChunk *isec : slices[i])
|
||||
isec->offset += start[i];
|
||||
});
|
||||
@ -360,7 +360,7 @@ static void scan_rels() {
|
||||
|
||||
std::vector<std::vector<Symbol *>> vec(files.size());
|
||||
|
||||
tbb::parallel_for(0, (int)files.size(), [&](int i) {
|
||||
tbb::parallel_for((i64)0, (i64)files.size(), [&](i64 i) {
|
||||
for (Symbol *sym : files[i]->symbols)
|
||||
if (sym->flags && sym->file == files[i])
|
||||
vec[i].push_back(sym);
|
||||
@ -404,7 +404,7 @@ static void scan_rels() {
|
||||
static void export_dynamic() {
|
||||
Timer t("export_dynamic");
|
||||
|
||||
tbb::parallel_for(0, (int)out::objs.size(), [&](int i) {
|
||||
tbb::parallel_for((i64)0, (i64)out::objs.size(), [&](i64 i) {
|
||||
ObjectFile *file = out::objs[i];
|
||||
for (Symbol *sym : std::span(file->symbols).subspan(file->first_global))
|
||||
if (sym->file == file && config.export_dynamic)
|
||||
@ -416,7 +416,7 @@ static void export_dynamic() {
|
||||
|
||||
std::vector<std::vector<Symbol *>> vec(out::objs.size());
|
||||
|
||||
tbb::parallel_for(0, (int)out::objs.size(), [&](int i) {
|
||||
tbb::parallel_for((i64)0, (i64)out::objs.size(), [&](i64 i) {
|
||||
ObjectFile *file = out::objs[i];
|
||||
for (Symbol *sym : std::span(file->symbols).subspan(file->first_global))
|
||||
if (sym->file == file && sym->ver_idx != VER_NDX_LOCAL)
|
||||
@ -447,8 +447,8 @@ static void fill_symbol_versions() {
|
||||
out::versym->contents.resize(out::dynsym->symbols.size(), 1);
|
||||
out::versym->contents[0] = 0;
|
||||
|
||||
int sz = sizeof(ElfVerneed) + sizeof(ElfVernaux);
|
||||
for (int i = 1; i < syms.size(); i++) {
|
||||
i64 sz = sizeof(ElfVerneed) + sizeof(ElfVernaux);
|
||||
for (i64 i = 1; i < syms.size(); i++) {
|
||||
if (syms[i - 1]->file != syms[i]->file)
|
||||
sz += sizeof(ElfVerneed) + sizeof(ElfVernaux);
|
||||
else if (syms[i - 1]->ver_idx != syms[i]->ver_idx)
|
||||
@ -497,7 +497,7 @@ static void fill_symbol_versions() {
|
||||
add_verneed(syms[0]);
|
||||
out::versym->contents[syms[0]->dynsym_idx] = version;
|
||||
|
||||
for (int i = 1; i < syms.size(); i++) {
|
||||
for (i64 i = 1; i < syms.size(); i++) {
|
||||
if (syms[i - 1]->file != syms[i]->file)
|
||||
add_verneed(syms[i]);
|
||||
else if (syms[i - 1]->ver_idx != syms[i]->ver_idx)
|
||||
@ -506,17 +506,17 @@ static void fill_symbol_versions() {
|
||||
}
|
||||
}
|
||||
|
||||
static void clear_padding(u64 filesize) {
|
||||
static void clear_padding(i64 filesize) {
|
||||
Timer t("clear_padding");
|
||||
|
||||
auto zero = [](OutputChunk *chunk, u64 next_start) {
|
||||
u64 pos = chunk->shdr.sh_offset;
|
||||
auto zero = [](OutputChunk *chunk, i64 next_start) {
|
||||
i64 pos = chunk->shdr.sh_offset;
|
||||
if (chunk->shdr.sh_type != SHT_NOBITS)
|
||||
pos += chunk->shdr.sh_size;
|
||||
memset(out::buf + pos, 0, next_start - pos);
|
||||
};
|
||||
|
||||
for (int i = 1; i < out::chunks.size(); i++)
|
||||
for (i64 i = 1; i < out::chunks.size(); i++)
|
||||
zero(out::chunks[i - 1], out::chunks[i]->shdr.sh_offset);
|
||||
zero(out::chunks.back(), filesize);
|
||||
}
|
||||
@ -531,7 +531,7 @@ static void clear_padding(u64 filesize) {
|
||||
// alloc writable data
|
||||
// alloc writable bss
|
||||
// nonalloc
|
||||
static int get_section_rank(const ElfShdr &shdr) {
|
||||
static i64 get_section_rank(const ElfShdr &shdr) {
|
||||
bool note = shdr.sh_type == SHT_NOTE;
|
||||
bool alloc = shdr.sh_flags & SHF_ALLOC;
|
||||
bool writable = shdr.sh_flags & SHF_WRITE;
|
||||
@ -542,11 +542,11 @@ static int get_section_rank(const ElfShdr &shdr) {
|
||||
(exec << 3) | (!tls << 2) | nobits;
|
||||
}
|
||||
|
||||
static u64 set_osec_offsets(std::span<OutputChunk *> chunks) {
|
||||
static i64 set_osec_offsets(std::span<OutputChunk *> chunks) {
|
||||
Timer t("osec_offset");
|
||||
|
||||
u64 fileoff = 0;
|
||||
u64 vaddr = config.image_base;
|
||||
i64 fileoff = 0;
|
||||
i64 vaddr = config.image_base;
|
||||
|
||||
for (OutputChunk *chunk : chunks) {
|
||||
if (chunk->starts_new_ptload)
|
||||
@ -752,7 +752,7 @@ static bool read_z_flag(std::span<std::string_view> &args, std::string name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static u64 parse_hex(std::string opt, std::string_view value) {
|
||||
static i64 parse_hex(std::string opt, std::string_view value) {
|
||||
if (!value.starts_with("0x") && !value.starts_with("0X"))
|
||||
Fatal() << "option -" << opt << ": not a hexadecimal number";
|
||||
value = value.substr(2);
|
||||
@ -761,7 +761,7 @@ static u64 parse_hex(std::string opt, std::string_view value) {
|
||||
return std::stol(std::string(value), nullptr, 16);
|
||||
}
|
||||
|
||||
static u64 parse_number(std::string opt, std::string_view value) {
|
||||
static i64 parse_number(std::string opt, std::string_view value) {
|
||||
if (value.find_first_not_of("0123456789") != std::string_view::npos)
|
||||
Fatal() << "option -" << opt << ": not a number";
|
||||
return std::stol(std::string(value));
|
||||
@ -771,7 +771,7 @@ static std::vector<std::string_view> read_response_file(std::string_view path) {
|
||||
std::vector<std::string_view> vec;
|
||||
MemoryMappedFile *mb = MemoryMappedFile::must_open(std::string(path));
|
||||
|
||||
auto read_quoted = [&](int i, char quote) {
|
||||
auto read_quoted = [&](i64 i, char quote) {
|
||||
std::string *buf = new std::string;
|
||||
while (i < mb->size() && mb->data()[i] != quote) {
|
||||
if (mb->data()[i] == '\\') {
|
||||
@ -787,7 +787,7 @@ static std::vector<std::string_view> read_response_file(std::string_view path) {
|
||||
return i + 1;
|
||||
};
|
||||
|
||||
auto read_unquoted = [&](int i) {
|
||||
auto read_unquoted = [&](i64 i) {
|
||||
std::string *buf = new std::string;
|
||||
while (i < mb->size() && !isspace(mb->data()[i]))
|
||||
buf->append(1, mb->data()[i++]);
|
||||
@ -795,7 +795,7 @@ static std::vector<std::string_view> read_response_file(std::string_view path) {
|
||||
return i;
|
||||
};
|
||||
|
||||
for (int i = 0; i < mb->size();) {
|
||||
for (i64 i = 0; i < mb->size();) {
|
||||
if (isspace(mb->data()[i]))
|
||||
i++;
|
||||
else if (mb->data()[i] == '\'')
|
||||
@ -811,7 +811,7 @@ static std::vector<std::string_view> read_response_file(std::string_view path) {
|
||||
static std::vector<std::string_view> expand_response_files(char **argv) {
|
||||
std::vector<std::string_view> vec;
|
||||
|
||||
for (int i = 0; argv[i]; i++) {
|
||||
for (i64 i = 0; argv[i]; i++) {
|
||||
if (argv[i][0] == '@')
|
||||
append(vec, read_response_file(argv[i] + 1));
|
||||
else
|
||||
@ -994,7 +994,7 @@ static void read_input_files(std::span<std::string_view> args) {
|
||||
parser_tg.wait();
|
||||
}
|
||||
|
||||
static void compute_tree_hash(u8 *buf, u64 size, u8 *digest) {
|
||||
static void compute_tree_hash(u8 *buf, i64 size, u8 *digest) {
|
||||
i64 shard_size = 1024 * 1024;
|
||||
i64 num_shards = size / shard_size + 1;
|
||||
std::vector<u8> shards(num_shards * SHA256_SIZE);
|
||||
@ -1040,7 +1040,7 @@ int main(int argc, char **argv) {
|
||||
Fatal() << "-o option is missing";
|
||||
|
||||
if (!config.preload)
|
||||
if (int code; resume_daemon(argv, &code))
|
||||
if (i64 code; resume_daemon(argv, &code))
|
||||
exit(code);
|
||||
|
||||
tbb::global_control tbb_cont(tbb::global_control::max_allowed_parallelism,
|
||||
@ -1146,7 +1146,7 @@ int main(int argc, char **argv) {
|
||||
out::chunks.push_back(out::buildid);
|
||||
|
||||
// Set priorities to files. File priority 1 is reserved for the internal file.
|
||||
int priority = 2;
|
||||
i64 priority = 2;
|
||||
for (ObjectFile *file : out::objs)
|
||||
if (!file->is_in_archive)
|
||||
file->priority = priority++;
|
||||
@ -1190,8 +1190,8 @@ int main(int argc, char **argv) {
|
||||
// Sections are added to the section lists in an arbitrary order because
|
||||
// they are created in parallel. Sort them to to make the output deterministic.
|
||||
auto section_compare = [](OutputChunk *x, OutputChunk *y) {
|
||||
return std::tuple(x->name, (u32)x->shdr.sh_type, (u64)x->shdr.sh_flags) <
|
||||
std::tuple(y->name, (u32)y->shdr.sh_type, (u64)y->shdr.sh_flags);
|
||||
return std::tuple(x->name, x->shdr.sh_type, x->shdr.sh_flags) <
|
||||
std::tuple(y->name, y->shdr.sh_type, y->shdr.sh_flags);
|
||||
};
|
||||
|
||||
sort(OutputSection::instances, section_compare);
|
||||
@ -1288,7 +1288,7 @@ int main(int argc, char **argv) {
|
||||
erase(out::chunks, [](OutputChunk *c) { return c->shdr.sh_size == 0; });
|
||||
|
||||
// Set section indices.
|
||||
for (int i = 0, shndx = 1; i < out::chunks.size(); i++)
|
||||
for (i64 i = 0, shndx = 1; i < out::chunks.size(); i++)
|
||||
if (out::chunks[i]->kind != OutputChunk::HEADER)
|
||||
out::chunks[i]->shndx = shndx++;
|
||||
|
||||
@ -1296,7 +1296,7 @@ int main(int argc, char **argv) {
|
||||
chunk->update_shdr();
|
||||
|
||||
// Assign offsets to output sections
|
||||
u64 filesize = set_osec_offsets(out::chunks);
|
||||
i64 filesize = set_osec_offsets(out::chunks);
|
||||
|
||||
// At this point, file layout is fixed. Beyond this, you can assume
|
||||
// that symbol addresses including their GOT/PLT/etc addresses have
|
||||
|
46
mold.h
46
mold.h
@ -73,8 +73,8 @@ struct Config {
|
||||
bool strip_all = false;
|
||||
bool trace = false;
|
||||
bool z_now = false;
|
||||
int filler = -1;
|
||||
int thread_count = -1;
|
||||
i64 filler = -1;
|
||||
i64 thread_count = -1;
|
||||
std::string sysroot;
|
||||
std::vector<std::string> globals;
|
||||
std::vector<std::string_view> library_paths;
|
||||
@ -369,7 +369,7 @@ public:
|
||||
virtual void update_shdr() {}
|
||||
|
||||
std::string_view name;
|
||||
int shndx = 0;
|
||||
i64 shndx = 0;
|
||||
Kind kind;
|
||||
bool starts_new_ptload = false;
|
||||
ElfShdr shdr = { .sh_addralign = 1 };
|
||||
@ -426,7 +426,7 @@ public:
|
||||
// Sections
|
||||
class OutputSection : public OutputChunk {
|
||||
public:
|
||||
static OutputSection *get_instance(std::string_view name, u32 type, u64 flags);
|
||||
static OutputSection *get_instance(std::string_view name, u64 type, u64 flags);
|
||||
|
||||
OutputSection(std::string_view name, u32 type, u64 flags)
|
||||
: OutputChunk(REGULAR) {
|
||||
@ -560,8 +560,8 @@ DynstrSection() : OutputChunk(SYNTHETIC) {
|
||||
shdr.sh_size = 1;
|
||||
}
|
||||
|
||||
u32 add_string(std::string_view str);
|
||||
u32 find_string(std::string_view str);
|
||||
i64 add_string(std::string_view str);
|
||||
i64 find_string(std::string_view str);
|
||||
void copy_buf() override;
|
||||
|
||||
private:
|
||||
@ -642,10 +642,10 @@ public:
|
||||
void update_shdr() override;
|
||||
void copy_buf() override;
|
||||
|
||||
static constexpr int LOAD_FACTOR = 8;
|
||||
static constexpr int HEADER_SIZE = 16;
|
||||
static constexpr int BLOOM_SHIFT = 26;
|
||||
static constexpr int ELFCLASS_BITS = 64;
|
||||
static constexpr i64 LOAD_FACTOR = 8;
|
||||
static constexpr i64 HEADER_SIZE = 16;
|
||||
static constexpr i64 BLOOM_SHIFT = 26;
|
||||
static constexpr i64 ELFCLASS_BITS = 64;
|
||||
|
||||
u32 num_buckets = -1;
|
||||
u32 symoffset = -1;
|
||||
@ -654,7 +654,7 @@ public:
|
||||
|
||||
class MergedSection : public OutputChunk {
|
||||
public:
|
||||
static MergedSection *get_instance(std::string_view name, u32 type, u64 flags);
|
||||
static MergedSection *get_instance(std::string_view name, u64 type, u64 flags);
|
||||
|
||||
static inline std::vector<MergedSection *> instances;
|
||||
|
||||
@ -747,7 +747,7 @@ public:
|
||||
shdr.sh_size = HEADER_SIZE;
|
||||
}
|
||||
|
||||
static constexpr int HEADER_SIZE = 12;
|
||||
static constexpr i64 HEADER_SIZE = 12;
|
||||
};
|
||||
|
||||
class CopyrelSection : public OutputChunk {
|
||||
@ -837,16 +837,20 @@ public:
|
||||
MemoryMappedFile *slice(std::string name, u64 start, u64 size);
|
||||
|
||||
u8 *data();
|
||||
u64 size() { return size_; }
|
||||
i64 size() const { return size_; }
|
||||
|
||||
std::string_view get_contents() {
|
||||
return std::string_view((char *)data(), size());
|
||||
}
|
||||
|
||||
std::string name;
|
||||
u64 mtime = 0;
|
||||
i64 mtime = 0;
|
||||
|
||||
private:
|
||||
std::mutex mu;
|
||||
MemoryMappedFile *parent;
|
||||
std::atomic<u8 *> data_;
|
||||
u64 size_ = 0;
|
||||
i64 size_ = 0;
|
||||
};
|
||||
|
||||
class InputFile {
|
||||
@ -864,12 +868,12 @@ public:
|
||||
std::atomic_bool is_alive = false;
|
||||
|
||||
std::string_view get_string(const ElfShdr &shdr);
|
||||
std::string_view get_string(u32 idx);
|
||||
std::string_view get_string(i64 idx);
|
||||
|
||||
protected:
|
||||
template<typename T> std::span<T> get_data(const ElfShdr &shdr);
|
||||
template<typename T> std::span<T> get_data(u32 idx);
|
||||
ElfShdr *find_section(u32 type);
|
||||
template<typename T> std::span<T> get_data(i64 idx);
|
||||
ElfShdr *find_section(i64 type);
|
||||
|
||||
std::string_view shstrtab;
|
||||
};
|
||||
@ -895,7 +899,7 @@ public:
|
||||
std::string archive_name;
|
||||
std::vector<InputSection *> sections;
|
||||
std::span<ElfSym> elf_syms;
|
||||
int first_global = 0;
|
||||
i64 first_global = 0;
|
||||
const bool is_in_archive = false;
|
||||
std::vector<CieRecord> cies;
|
||||
|
||||
@ -917,7 +921,7 @@ private:
|
||||
void initialize_mergeable_sections();
|
||||
void initialize_ehframe_sections();
|
||||
void read_ehframe(InputSection &isec);
|
||||
void maybe_override_symbol(Symbol &sym, int symidx);
|
||||
void maybe_override_symbol(Symbol &sym, i64 symidx);
|
||||
|
||||
std::vector<std::pair<ComdatGroup *, std::span<u32>>> comdat_groups;
|
||||
std::vector<SectionFragmentRef> sym_fragments;
|
||||
@ -1059,7 +1063,7 @@ void print_map();
|
||||
inline char *socket_tmpfile;
|
||||
|
||||
std::function<void()> fork_child();
|
||||
bool resume_daemon(char **argv, int *code);
|
||||
bool resume_daemon(char **argv, i64 *code);
|
||||
void daemonize(char **argv, std::function<void()> *wait_for_client,
|
||||
std::function<void()> *on_complete);
|
||||
|
||||
|
@ -30,7 +30,7 @@ u8 *MemoryMappedFile::data() {
|
||||
if (data_)
|
||||
return data_;
|
||||
|
||||
int fd = ::open(name.c_str(), O_RDONLY);
|
||||
i64 fd = ::open(name.c_str(), O_RDONLY);
|
||||
if (fd == -1)
|
||||
Fatal() << name << ": cannot open: " << strerror(errno);
|
||||
|
||||
@ -73,7 +73,7 @@ std::string_view InputFile::get_string(const ElfShdr &shdr) {
|
||||
return {(char *)begin, (char *)end};
|
||||
}
|
||||
|
||||
std::string_view InputFile::get_string(u32 idx) {
|
||||
std::string_view InputFile::get_string(i64 idx) {
|
||||
if (elf_sections.size() <= idx)
|
||||
Fatal() << *this << ": invalid section index";
|
||||
return get_string(elf_sections[idx]);
|
||||
@ -88,13 +88,13 @@ std::span<T> InputFile::get_data(const ElfShdr &shdr) {
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::span<T> InputFile::get_data(u32 idx) {
|
||||
std::span<T> InputFile::get_data(i64 idx) {
|
||||
if (elf_sections.size() <= idx)
|
||||
Fatal() << *this << ": invalid section index";
|
||||
return get_data<T>(elf_sections[idx]);
|
||||
}
|
||||
|
||||
ElfShdr *InputFile::find_section(u32 type) {
|
||||
ElfShdr *InputFile::find_section(i64 type) {
|
||||
for (ElfShdr &sec : elf_sections)
|
||||
if (sec.sh_type == type)
|
||||
return &sec;
|
||||
@ -109,7 +109,7 @@ ObjectFile::ObjectFile(MemoryMappedFile *mb, std::string archive_name)
|
||||
|
||||
void ObjectFile::initialize_sections() {
|
||||
// Read sections
|
||||
for (int i = 0; i < elf_sections.size(); i++) {
|
||||
for (i64 i = 0; i < elf_sections.size(); i++) {
|
||||
const ElfShdr &shdr = elf_sections[i];
|
||||
|
||||
if ((shdr.sh_flags & SHF_EXCLUDE) && !(shdr.sh_flags & SHF_ALLOC))
|
||||
@ -179,14 +179,14 @@ void ObjectFile::initialize_sections() {
|
||||
// Set is_comdat_member bits.
|
||||
for (auto &pair : comdat_groups) {
|
||||
std::span<u32> entries = pair.second;
|
||||
for (u32 i : entries)
|
||||
for (i64 i : entries)
|
||||
if (this->sections[i])
|
||||
this->sections[i]->is_comdat_member = true;
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectFile::initialize_ehframe_sections() {
|
||||
for (int i = 0; i < sections.size(); i++) {
|
||||
for (i64 i = 0; i < sections.size(); i++) {
|
||||
InputSection *isec = sections[i];
|
||||
if (isec && isec->name == ".eh_frame") {
|
||||
read_ehframe(*isec);
|
||||
@ -332,7 +332,7 @@ void ObjectFile::initialize_symbols() {
|
||||
// Initialize local symbols
|
||||
Symbol *locals = new Symbol[first_global];
|
||||
|
||||
for (int i = 1; i < first_global; i++) {
|
||||
for (i64 i = 1; i < first_global; i++) {
|
||||
const ElfSym &esym = elf_syms[i];
|
||||
Symbol &sym = locals[i];
|
||||
|
||||
@ -358,14 +358,14 @@ void ObjectFile::initialize_symbols() {
|
||||
symbols.resize(elf_syms.size());
|
||||
sym_fragments.resize(elf_syms.size() - first_global);
|
||||
|
||||
for (int i = 0; i < first_global; i++)
|
||||
for (i64 i = 0; i < first_global; i++)
|
||||
symbols[i] = &locals[i];
|
||||
|
||||
// Initialize global symbols
|
||||
for (int i = first_global; i < elf_syms.size(); i++) {
|
||||
for (i64 i = first_global; i < elf_syms.size(); i++) {
|
||||
const ElfSym &esym = elf_syms[i];
|
||||
std::string_view name = symbol_strtab.data() + esym.st_name;
|
||||
int pos = name.find('@');
|
||||
i64 pos = name.find('@');
|
||||
if (pos != std::string_view::npos)
|
||||
name = name.substr(0, pos);
|
||||
|
||||
@ -376,13 +376,13 @@ void ObjectFile::initialize_symbols() {
|
||||
}
|
||||
}
|
||||
|
||||
static int binary_search(std::span<u32> span, u32 val) {
|
||||
static i64 binary_search(std::span<u32> span, i64 val) {
|
||||
if (val < span[0])
|
||||
return -1;
|
||||
|
||||
int ret = 0;
|
||||
i64 ret = 0;
|
||||
while (span.size() > 1) {
|
||||
u32 mid = span.size() / 2;
|
||||
i64 mid = span.size() / 2;
|
||||
if (val < span[mid]) {
|
||||
span = span.subspan(0, mid);
|
||||
} else {
|
||||
@ -396,7 +396,7 @@ static int binary_search(std::span<u32> span, u32 val) {
|
||||
void ObjectFile::initialize_mergeable_sections() {
|
||||
mergeable_sections.resize(sections.size());
|
||||
|
||||
for (int i = 0; i < sections.size(); i++) {
|
||||
for (i64 i = 0; i < sections.size(); i++) {
|
||||
if (InputSection *isec = sections[i]) {
|
||||
if (isec->shdr.sh_flags & SHF_MERGE) {
|
||||
mergeable_sections[i] = new MergeableSection(isec);
|
||||
@ -410,7 +410,7 @@ void ObjectFile::initialize_mergeable_sections() {
|
||||
if (!isec || isec->rels.empty())
|
||||
continue;
|
||||
|
||||
for (int i = 0; i < isec->rels.size(); i++) {
|
||||
for (i64 i = 0; i < isec->rels.size(); i++) {
|
||||
const ElfRela &rel = isec->rels[i];
|
||||
const ElfSym &esym = elf_syms[rel.r_sym];
|
||||
if (esym.st_type != STT_SECTION)
|
||||
@ -420,8 +420,8 @@ void ObjectFile::initialize_mergeable_sections() {
|
||||
if (!m)
|
||||
continue;
|
||||
|
||||
u32 offset = esym.st_value + rel.r_addend;
|
||||
int idx = binary_search(m->frag_offsets, offset);
|
||||
i64 offset = esym.st_value + rel.r_addend;
|
||||
i64 idx = binary_search(m->frag_offsets, offset);
|
||||
if (idx == -1)
|
||||
Fatal() << *this << ": bad relocation at " << rel.r_sym;
|
||||
|
||||
@ -432,7 +432,7 @@ void ObjectFile::initialize_mergeable_sections() {
|
||||
}
|
||||
|
||||
// Initialize sym_fragments
|
||||
for (int i = 0; i < elf_syms.size(); i++) {
|
||||
for (i64 i = 0; i < elf_syms.size(); i++) {
|
||||
const ElfSym &esym = elf_syms[i];
|
||||
if (esym.is_abs() || esym.is_common())
|
||||
continue;
|
||||
@ -441,7 +441,7 @@ void ObjectFile::initialize_mergeable_sections() {
|
||||
if (!m)
|
||||
continue;
|
||||
|
||||
int idx = binary_search(m->frag_offsets, esym.st_value);
|
||||
i64 idx = binary_search(m->frag_offsets, esym.st_value);
|
||||
if (idx == -1)
|
||||
Fatal() << *this << ": bad symbol value";
|
||||
|
||||
@ -502,7 +502,7 @@ static u64 get_rank(const Symbol &sym) {
|
||||
return get_rank(sym.file, *sym.esym, sym.input_section);
|
||||
}
|
||||
|
||||
void ObjectFile::maybe_override_symbol(Symbol &sym, int symidx) {
|
||||
void ObjectFile::maybe_override_symbol(Symbol &sym, i64 symidx) {
|
||||
InputSection *isec = nullptr;
|
||||
const ElfSym &esym = elf_syms[symidx];
|
||||
if (!esym.is_abs() && !esym.is_common())
|
||||
@ -533,7 +533,7 @@ void ObjectFile::maybe_override_symbol(Symbol &sym, int symidx) {
|
||||
}
|
||||
|
||||
void ObjectFile::resolve_symbols() {
|
||||
for (int i = first_global; i < symbols.size(); i++) {
|
||||
for (i64 i = first_global; i < symbols.size(); i++) {
|
||||
const ElfSym &esym = elf_syms[i];
|
||||
if (!esym.is_defined())
|
||||
continue;
|
||||
@ -563,7 +563,7 @@ std::vector<ObjectFile *> ObjectFile::mark_live_objects() {
|
||||
std::vector<ObjectFile *> vec;
|
||||
assert(is_alive);
|
||||
|
||||
for (int i = first_global; i < symbols.size(); i++) {
|
||||
for (i64 i = first_global; i < symbols.size(); i++) {
|
||||
const ElfSym &esym = elf_syms[i];
|
||||
Symbol &sym = *symbols[i];
|
||||
|
||||
@ -589,7 +589,7 @@ std::vector<ObjectFile *> ObjectFile::mark_live_objects() {
|
||||
}
|
||||
|
||||
void ObjectFile::handle_undefined_weak_symbols() {
|
||||
for (int i = first_global; i < symbols.size(); i++) {
|
||||
for (i64 i = first_global; i < symbols.size(); i++) {
|
||||
const ElfSym &esym = elf_syms[i];
|
||||
|
||||
if (esym.is_undef() && esym.st_bind == STB_WEAK) {
|
||||
@ -634,7 +634,7 @@ void ObjectFile::eliminate_duplicate_comdat_groups() {
|
||||
continue;
|
||||
|
||||
std::span<u32> entries = pair.second;
|
||||
for (u32 i : entries) {
|
||||
for (i64 i : entries) {
|
||||
if (sections[i])
|
||||
sections[i]->is_alive = false;
|
||||
sections[i] = nullptr;
|
||||
@ -652,7 +652,7 @@ void ObjectFile::convert_common_symbols() {
|
||||
static OutputSection *bss =
|
||||
OutputSection::get_instance(".bss", SHT_NOBITS, SHF_WRITE | SHF_ALLOC);
|
||||
|
||||
for (int i = first_global; i < elf_syms.size(); i++) {
|
||||
for (i64 i = first_global; i < elf_syms.size(); i++) {
|
||||
if (!elf_syms[i].is_common())
|
||||
continue;
|
||||
|
||||
@ -681,7 +681,7 @@ static bool should_write_global_symtab(Symbol &sym) {
|
||||
}
|
||||
|
||||
void ObjectFile::compute_symtab() {
|
||||
for (int i = first_global; i < elf_syms.size(); i++) {
|
||||
for (i64 i = first_global; i < elf_syms.size(); i++) {
|
||||
const ElfSym &esym = elf_syms[i];
|
||||
Symbol &sym = *symbols[i];
|
||||
|
||||
@ -695,10 +695,10 @@ void ObjectFile::compute_symtab() {
|
||||
void ObjectFile::write_symtab() {
|
||||
u8 *symtab_base = out::buf + out::symtab->shdr.sh_offset;
|
||||
u8 *strtab_base = out::buf + out::strtab->shdr.sh_offset;
|
||||
u32 symtab_off;
|
||||
u32 strtab_off = strtab_offset;
|
||||
i64 symtab_off;
|
||||
i64 strtab_off = strtab_offset;
|
||||
|
||||
auto write_sym = [&](u32 i) {
|
||||
auto write_sym = [&](i64 i) {
|
||||
Symbol &sym = *symbols[i];
|
||||
ElfSym &esym = *(ElfSym *)(symtab_base + symtab_off);
|
||||
symtab_off += sizeof(ElfSym);
|
||||
@ -723,12 +723,12 @@ void ObjectFile::write_symtab() {
|
||||
};
|
||||
|
||||
symtab_off = local_symtab_offset;
|
||||
for (int i = 1; i < first_global; i++)
|
||||
for (i64 i = 1; i < first_global; i++)
|
||||
if (symbols[i]->write_symtab)
|
||||
write_sym(i);
|
||||
|
||||
symtab_off = global_symtab_offset;
|
||||
for (int i = first_global; i < elf_syms.size(); i++)
|
||||
for (i64 i = first_global; i < elf_syms.size(); i++)
|
||||
if (symbols[i]->file == this && should_write_global_symtab(*symbols[i]))
|
||||
write_sym(i);
|
||||
}
|
||||
@ -821,7 +821,7 @@ void SharedFile::parse() {
|
||||
version_strings = read_verdef();
|
||||
|
||||
// Read a symbol table.
|
||||
int first_global = symtab_sec->sh_info;
|
||||
i64 first_global = symtab_sec->sh_info;
|
||||
std::span<ElfSym> esyms = get_data<ElfSym>(*symtab_sec);
|
||||
|
||||
std::span<u16> vers;
|
||||
@ -830,7 +830,7 @@ void SharedFile::parse() {
|
||||
|
||||
std::vector<std::pair<const ElfSym *, u16>> pairs;
|
||||
|
||||
for (int i = first_global; i < esyms.size(); i++) {
|
||||
for (i64 i = first_global; i < esyms.size(); i++) {
|
||||
if (!esyms[i].is_defined())
|
||||
continue;
|
||||
if (!vers.empty() && (vers[i] >> 15) == 1)
|
||||
@ -891,7 +891,7 @@ std::vector<std::string_view> SharedFile::read_verdef() {
|
||||
}
|
||||
|
||||
void SharedFile::resolve_symbols() {
|
||||
for (int i = 0; i < symbols.size(); i++) {
|
||||
for (i64 i = 0; i < symbols.size(); i++) {
|
||||
Symbol &sym = *symbols[i];
|
||||
const ElfSym &esym = *elf_syms[i];
|
||||
|
||||
|
108
output_chunks.cc
108
output_chunks.cc
@ -27,7 +27,7 @@ void OutputEhdr::copy_buf() {
|
||||
}
|
||||
|
||||
void OutputShdr::update_shdr() {
|
||||
int n = 1;
|
||||
i64 n = 1;
|
||||
for (OutputChunk *chunk : out::chunks)
|
||||
if (chunk->kind != OutputChunk::HEADER)
|
||||
n++;
|
||||
@ -38,14 +38,14 @@ void OutputShdr::copy_buf() {
|
||||
ElfShdr *hdr = (ElfShdr *)(out::buf + shdr.sh_offset);
|
||||
hdr[0] = {};
|
||||
|
||||
int i = 1;
|
||||
i64 i = 1;
|
||||
for (OutputChunk *chunk : out::chunks)
|
||||
if (chunk->kind != OutputChunk::HEADER)
|
||||
hdr[i++] = chunk->shdr;
|
||||
}
|
||||
|
||||
static u32 to_phdr_flags(OutputChunk *chunk) {
|
||||
u32 ret = PF_R;
|
||||
static i64 to_phdr_flags(OutputChunk *chunk) {
|
||||
i64 ret = PF_R;
|
||||
if (chunk->shdr.sh_flags & SHF_WRITE)
|
||||
ret |= PF_W;
|
||||
if (chunk->shdr.sh_flags & SHF_EXECINSTR)
|
||||
@ -56,7 +56,7 @@ static u32 to_phdr_flags(OutputChunk *chunk) {
|
||||
std::vector<ElfPhdr> create_phdr() {
|
||||
std::vector<ElfPhdr> vec;
|
||||
|
||||
auto define = [&](u32 type, u32 flags, u32 align, OutputChunk *chunk) {
|
||||
auto define = [&](u64 type, u64 flags, i64 align, OutputChunk *chunk) {
|
||||
vec.push_back({});
|
||||
ElfPhdr &phdr = vec.back();
|
||||
phdr.p_type = type;
|
||||
@ -94,13 +94,13 @@ std::vector<ElfPhdr> create_phdr() {
|
||||
|
||||
// Create a PT_NOTE for each group of SHF_NOTE sections with the same
|
||||
// alignment requirement.
|
||||
for (int i = 0, end = out::chunks.size(); i < end;) {
|
||||
for (i64 i = 0, end = out::chunks.size(); i < end;) {
|
||||
OutputChunk *first = out::chunks[i++];
|
||||
if (first->shdr.sh_type != SHT_NOTE)
|
||||
continue;
|
||||
|
||||
u32 flags = to_phdr_flags(first);
|
||||
u32 alignment = first->shdr.sh_addralign;
|
||||
i64 flags = to_phdr_flags(first);
|
||||
i64 alignment = first->shdr.sh_addralign;
|
||||
define(PT_NOTE, flags, alignment, first);
|
||||
|
||||
while (i < end && out::chunks[i]->shdr.sh_type == SHT_NOTE &&
|
||||
@ -110,12 +110,12 @@ std::vector<ElfPhdr> create_phdr() {
|
||||
}
|
||||
|
||||
// Create PT_LOAD segments.
|
||||
for (int i = 0, end = out::chunks.size(); i < end;) {
|
||||
for (i64 i = 0, end = out::chunks.size(); i < end;) {
|
||||
OutputChunk *first = out::chunks[i++];
|
||||
if (!(first->shdr.sh_flags & SHF_ALLOC))
|
||||
break;
|
||||
|
||||
u32 flags = to_phdr_flags(first);
|
||||
i64 flags = to_phdr_flags(first);
|
||||
define(PT_LOAD, flags, PAGE_SIZE, first);
|
||||
|
||||
if (!is_bss(first))
|
||||
@ -129,7 +129,7 @@ std::vector<ElfPhdr> create_phdr() {
|
||||
}
|
||||
|
||||
// Create a PT_TLS.
|
||||
for (int i = 0; i < out::chunks.size(); i++) {
|
||||
for (i64 i = 0; i < out::chunks.size(); i++) {
|
||||
if (!(out::chunks[i]->shdr.sh_flags & SHF_TLS))
|
||||
continue;
|
||||
|
||||
@ -173,7 +173,7 @@ void InterpSection::copy_buf() {
|
||||
void RelDynSection::update_shdr() {
|
||||
shdr.sh_link = out::dynsym->shndx;
|
||||
|
||||
int n = 0;
|
||||
i64 n = 0;
|
||||
for (Symbol *sym : out::got->got_syms)
|
||||
if (sym->is_imported || (config.pie && sym->is_relative()))
|
||||
n++;
|
||||
@ -240,7 +240,7 @@ void ShstrtabSection::copy_buf() {
|
||||
u8 *base = out::buf + shdr.sh_offset;
|
||||
base[0] = '\0';
|
||||
|
||||
int i = 1;
|
||||
i64 i = 1;
|
||||
for (OutputChunk *chunk : out::chunks) {
|
||||
if (!chunk->name.empty()) {
|
||||
write_string(base + i, chunk->name);
|
||||
@ -249,15 +249,15 @@ void ShstrtabSection::copy_buf() {
|
||||
}
|
||||
}
|
||||
|
||||
u32 DynstrSection::add_string(std::string_view str) {
|
||||
u32 ret = shdr.sh_size;
|
||||
i64 DynstrSection::add_string(std::string_view str) {
|
||||
i64 ret = shdr.sh_size;
|
||||
shdr.sh_size += str.size() + 1;
|
||||
contents.push_back(str);
|
||||
return ret;
|
||||
}
|
||||
|
||||
u32 DynstrSection::find_string(std::string_view str) {
|
||||
u32 i = 1;
|
||||
i64 DynstrSection::find_string(std::string_view str) {
|
||||
i64 i = 1;
|
||||
for (std::string_view s : contents) {
|
||||
if (s == str)
|
||||
return i;
|
||||
@ -270,7 +270,7 @@ void DynstrSection::copy_buf() {
|
||||
u8 *base = out::buf + shdr.sh_offset;
|
||||
base[0] = '\0';
|
||||
|
||||
int i = 1;
|
||||
i64 i = 1;
|
||||
for (std::string_view s : contents) {
|
||||
write_string(base + i, s);
|
||||
i += s.size() + 1;
|
||||
@ -353,8 +353,8 @@ static std::vector<u64> create_dynamic_section() {
|
||||
if (OutputChunk *chunk = find(".fini"))
|
||||
define(DT_FINI, chunk->shdr.sh_addr);
|
||||
|
||||
u32 flags = 0;
|
||||
u32 flags1 = 0;
|
||||
i64 flags = 0;
|
||||
i64 flags1 = 0;
|
||||
|
||||
if (config.pie)
|
||||
flags1 |= DF_1_PIE;
|
||||
@ -397,7 +397,7 @@ static std::string_view get_output_name(std::string_view name) {
|
||||
}
|
||||
|
||||
OutputSection *
|
||||
OutputSection::get_instance(std::string_view name, u32 type, u64 flags) {
|
||||
OutputSection::get_instance(std::string_view name, u64 type, u64 flags) {
|
||||
if (name == ".eh_frame" && type == SHT_X86_64_UNWIND)
|
||||
type = SHT_PROGBITS;
|
||||
|
||||
@ -431,7 +431,7 @@ void OutputSection::copy_buf() {
|
||||
if (shdr.sh_type == SHT_NOBITS)
|
||||
return;
|
||||
|
||||
tbb::parallel_for(0, (int)members.size(), [&](int i) {
|
||||
tbb::parallel_for((i64)0, (i64)members.size(), [&](u64 i) {
|
||||
InputSection &isec = *members[i];
|
||||
if (isec.shdr.sh_type == SHT_NOBITS)
|
||||
return;
|
||||
@ -530,7 +530,7 @@ void PltSection::copy_buf() {
|
||||
*(u32 *)(buf + 2) = out::gotplt->shdr.sh_addr - shdr.sh_addr + 2;
|
||||
*(u32 *)(buf + 8) = out::gotplt->shdr.sh_addr - shdr.sh_addr + 4;
|
||||
|
||||
int relplt_idx = 0;
|
||||
i64 relplt_idx = 0;
|
||||
|
||||
for (Symbol *sym : symbols) {
|
||||
u8 *ent = buf + sym->plt_idx * PLT_SIZE;
|
||||
@ -566,7 +566,7 @@ void RelPltSection::copy_buf() {
|
||||
ElfRela *buf = (ElfRela *)(out::buf + shdr.sh_offset);
|
||||
memset(buf, 0, shdr.sh_size);
|
||||
|
||||
int relplt_idx = 0;
|
||||
i64 relplt_idx = 0;
|
||||
|
||||
for (Symbol *sym : out::plt->symbols) {
|
||||
if (!sym->has_relplt)
|
||||
@ -610,18 +610,18 @@ void DynsymSection::sort_symbols() {
|
||||
first_global, symbols.end(),
|
||||
[](Symbol *sym) { return sym->is_imported || sym->esym->is_undef(); });
|
||||
|
||||
int num_defined = symbols.end() - first_defined;
|
||||
i64 num_defined = symbols.end() - first_defined;
|
||||
out::gnu_hash->num_buckets = num_defined / out::gnu_hash->LOAD_FACTOR + 1;
|
||||
out::gnu_hash->symoffset = first_defined - symbols.begin();
|
||||
|
||||
std::stable_sort(first_defined, symbols.end(), [&](Symbol *a, Symbol *b) {
|
||||
u32 x = gnu_hash(a->name) % out::gnu_hash->num_buckets;
|
||||
u32 y = gnu_hash(b->name) % out::gnu_hash->num_buckets;
|
||||
i64 x = gnu_hash(a->name) % out::gnu_hash->num_buckets;
|
||||
i64 y = gnu_hash(b->name) % out::gnu_hash->num_buckets;
|
||||
return x < y;
|
||||
});
|
||||
}
|
||||
|
||||
for (int i = 1; i < symbols.size(); i++) {
|
||||
for (i64 i = 1; i < symbols.size(); i++) {
|
||||
name_indices.push_back(out::dynstr->add_string(symbols[i]->name));
|
||||
symbols[i]->dynsym_idx = i;
|
||||
}
|
||||
@ -636,7 +636,7 @@ void DynsymSection::copy_buf() {
|
||||
u8 *base = out::buf + shdr.sh_offset;
|
||||
memset(base, 0, sizeof(ElfSym));
|
||||
|
||||
for (int i = 1; i < symbols.size(); i++) {
|
||||
for (i64 i = 1; i < symbols.size(); i++) {
|
||||
Symbol &sym = *symbols[i];
|
||||
|
||||
ElfSym &esym = *(ElfSym *)(base + sym.dynsym_idx * sizeof(ElfSym));
|
||||
@ -665,8 +665,8 @@ void DynsymSection::copy_buf() {
|
||||
}
|
||||
|
||||
void HashSection::update_shdr() {
|
||||
int header_size = 8;
|
||||
int num_slots = out::dynsym->symbols.size();
|
||||
i64 header_size = 8;
|
||||
i64 num_slots = out::dynsym->symbols.size();
|
||||
shdr.sh_size = header_size + num_slots * 8;
|
||||
shdr.sh_link = out::dynsym->shndx;
|
||||
}
|
||||
@ -675,16 +675,16 @@ void HashSection::copy_buf() {
|
||||
u8 *base = out::buf + shdr.sh_offset;
|
||||
memset(base, 0, shdr.sh_size);
|
||||
|
||||
int num_slots = out::dynsym->symbols.size();
|
||||
i64 num_slots = out::dynsym->symbols.size();
|
||||
u32 *hdr = (u32 *)base;
|
||||
u32 *buckets = (u32 *)(base + 8);
|
||||
u32 *chains = buckets + num_slots;
|
||||
|
||||
hdr[0] = hdr[1] = num_slots;
|
||||
|
||||
for (int i = 1; i < out::dynsym->symbols.size(); i++) {
|
||||
for (i64 i = 1; i < out::dynsym->symbols.size(); i++) {
|
||||
Symbol *sym = out::dynsym->symbols[i];
|
||||
u32 idx = elf_hash(sym->name) % num_slots;
|
||||
i64 idx = elf_hash(sym->name) % num_slots;
|
||||
chains[sym->dynsym_idx] = buckets[idx];
|
||||
buckets[idx] = sym->dynsym_idx;
|
||||
}
|
||||
@ -693,13 +693,13 @@ void HashSection::copy_buf() {
|
||||
void GnuHashSection::update_shdr() {
|
||||
shdr.sh_link = out::dynsym->shndx;
|
||||
|
||||
if (int num_symbols = out::dynsym->symbols.size() - symoffset) {
|
||||
if (i64 num_symbols = out::dynsym->symbols.size() - symoffset) {
|
||||
// We allocate 12 bits for each symbol in the bloom filter.
|
||||
int num_bits = num_symbols * 12;
|
||||
i64 num_bits = num_symbols * 12;
|
||||
num_bloom = next_power_of_two(num_bits / ELFCLASS_BITS);
|
||||
}
|
||||
|
||||
int num_symbols = out::dynsym->symbols.size() - symoffset;
|
||||
i64 num_symbols = out::dynsym->symbols.size() - symoffset;
|
||||
|
||||
shdr.sh_size = HEADER_SIZE; // Header
|
||||
shdr.sh_size += num_bloom * ELFCLASS_BITS / 8; // Bloom filter
|
||||
@ -718,28 +718,28 @@ void GnuHashSection::copy_buf() {
|
||||
|
||||
std::span<Symbol *> symbols = std::span(out::dynsym->symbols).subspan(symoffset);
|
||||
std::vector<u32> hashes(symbols.size());
|
||||
for (int i = 0; i < symbols.size(); i++)
|
||||
for (i64 i = 0; i < symbols.size(); i++)
|
||||
hashes[i] = gnu_hash(symbols[i]->name);
|
||||
|
||||
// Write a bloom filter
|
||||
u64 *bloom = (u64 *)(base + HEADER_SIZE);
|
||||
for (u32 hash : hashes) {
|
||||
u32 idx = (hash / 64) % num_bloom;
|
||||
for (i64 hash : hashes) {
|
||||
i64 idx = (hash / 64) % num_bloom;
|
||||
bloom[idx] |= (u64)1 << (hash % ELFCLASS_BITS);
|
||||
bloom[idx] |= (u64)1 << ((hash >> BLOOM_SHIFT) % ELFCLASS_BITS);
|
||||
}
|
||||
|
||||
// Write hash bucket indices
|
||||
u32 *buckets = (u32 *)(bloom + num_bloom);
|
||||
for (int i = 1; i < hashes.size(); i++) {
|
||||
u32 idx = hashes[i] % num_buckets;
|
||||
for (i64 i = 1; i < hashes.size(); i++) {
|
||||
i64 idx = hashes[i] % num_buckets;
|
||||
if (!buckets[idx])
|
||||
buckets[idx] = i + symoffset;
|
||||
}
|
||||
|
||||
// Write a hash table
|
||||
u32 *table = buckets + num_buckets;
|
||||
for (int i = 0; i < symbols.size(); i++) {
|
||||
for (i64 i = 0; i < symbols.size(); i++) {
|
||||
bool is_last = false;
|
||||
if (i == symbols.size() - 1 ||
|
||||
(hashes[i] % num_buckets) != (hashes[i + 1] % num_buckets))
|
||||
@ -753,7 +753,7 @@ void GnuHashSection::copy_buf() {
|
||||
}
|
||||
|
||||
MergedSection *
|
||||
MergedSection::get_instance(std::string_view name, u32 type, u64 flags) {
|
||||
MergedSection::get_instance(std::string_view name, u64 type, u64 flags) {
|
||||
name = get_output_name(name);
|
||||
flags = flags & ~(u64)SHF_MERGE & ~(u64)SHF_STRINGS;
|
||||
|
||||
@ -795,7 +795,7 @@ void MergedSection::copy_buf() {
|
||||
if (isec->padding)
|
||||
memset(base + isec->offset - isec->padding, 0, isec->padding);
|
||||
|
||||
u32 offset = 0;
|
||||
i64 offset = 0;
|
||||
for (SectionFragment *frag : isec->fragments) {
|
||||
if (frag->isec != isec)
|
||||
continue;
|
||||
@ -822,12 +822,12 @@ void MergedSection::copy_buf() {
|
||||
void EhFrameSection::construct() {
|
||||
// Remove dead FDEs and assign them offsets within their corresponding
|
||||
// CIE group.
|
||||
tbb::parallel_for(0, (int)out::objs.size(), [&](int i) {
|
||||
tbb::parallel_for((i64)0, (i64)out::objs.size(), [&](i64 i) {
|
||||
ObjectFile *file = out::objs[i];
|
||||
u32 count = 0;
|
||||
i64 count = 0;
|
||||
|
||||
for (CieRecord &cie : file->cies) {
|
||||
u32 offset = 0;
|
||||
i64 offset = 0;
|
||||
for (FdeRecord &fde : cie.fdes) {
|
||||
if (!fde.is_alive())
|
||||
continue;
|
||||
@ -839,7 +839,7 @@ void EhFrameSection::construct() {
|
||||
cie.fde_size = offset;
|
||||
}
|
||||
|
||||
for (int i = 0; i < file->sections.size(); i++) {
|
||||
for (i64 i = 0; i < file->sections.size(); i++) {
|
||||
if (file->sections[i] && file->sections[i]->is_ehframe)
|
||||
file->sections[i] = nullptr;
|
||||
}
|
||||
@ -862,8 +862,8 @@ void EhFrameSection::construct() {
|
||||
return a.contents == b.contents && a.rels == b.rels;
|
||||
};
|
||||
|
||||
u32 offset = 0;
|
||||
for (int i = 0; i < cies.size(); i++) {
|
||||
i64 offset = 0;
|
||||
for (i64 i = 0; i < cies.size(); i++) {
|
||||
CieRecord &cie = *cies[i];
|
||||
cie.offset = offset;
|
||||
|
||||
@ -905,7 +905,7 @@ void EhFrameSection::copy_buf() {
|
||||
|
||||
// Copy CIEs and FDEs.
|
||||
tbb::parallel_for_each(cies, [&](CieRecord *cie) {
|
||||
u32 cie_size = 0;
|
||||
i64 cie_size = 0;
|
||||
|
||||
Entry *entry = nullptr;
|
||||
if (out::eh_frame_hdr)
|
||||
@ -928,11 +928,11 @@ void EhFrameSection::copy_buf() {
|
||||
if (fde.offset == -1)
|
||||
continue;
|
||||
|
||||
u32 fde_off = cie->offset + cie_size + fde.offset;
|
||||
i64 fde_off = cie->offset + cie_size + fde.offset;
|
||||
memcpy(base + fde_off, fde.contents.data(), fde.contents.size());
|
||||
*(u32 *)(base + fde_off + 4) = fde_off + 4 - cie->leader_offset;
|
||||
|
||||
for (int i = 0; i < fde.rels.size(); i++) {
|
||||
for (i64 i = 0; i < fde.rels.size(); i++) {
|
||||
EhReloc &rel = fde.rels[i];
|
||||
u64 loc = fde_off + rel.offset;
|
||||
u64 val = rel.sym->get_addr() + rel.addend;
|
||||
|
@ -14,11 +14,11 @@ static u32 get_umask() {
|
||||
|
||||
class MemoryMappedOutputFile : public OutputFile {
|
||||
public:
|
||||
MemoryMappedOutputFile(std::string path, u64 filesize)
|
||||
MemoryMappedOutputFile(std::string path, i64 filesize)
|
||||
: OutputFile(path, filesize) {
|
||||
std::string dir = dirname(strdup(config.output.c_str()));
|
||||
tmpfile = strdup((dir + "/.mold-XXXXXX").c_str());
|
||||
int fd = mkstemp(tmpfile);
|
||||
i64 fd = mkstemp(tmpfile);
|
||||
if (fd == -1)
|
||||
Error() << "cannot open " << tmpfile << ": " << strerror(errno);
|
||||
|
||||
@ -68,7 +68,7 @@ public:
|
||||
|
||||
void close() override {
|
||||
Timer t("munmap");
|
||||
int fd = ::open(path.c_str(), O_RDWR | O_CREAT, 0777);
|
||||
i64 fd = ::open(path.c_str(), O_RDWR | O_CREAT, 0777);
|
||||
if (fd == -1)
|
||||
Error() << "cannot open " << config.output << ": " << strerror(errno);
|
||||
|
||||
|
10
perf.cc
10
perf.cc
@ -62,19 +62,19 @@ void Timer::stop() {
|
||||
}
|
||||
|
||||
void Timer::print() {
|
||||
for (int i = records.size() - 1; i >= 0; i--)
|
||||
for (i64 i = records.size() - 1; i >= 0; i--)
|
||||
records[i]->stop();
|
||||
|
||||
std::vector<int> depth(records.size());
|
||||
std::vector<i64> depth(records.size());
|
||||
|
||||
for (int i = 0; i < records.size(); i++)
|
||||
for (int j = 0; j < i; j++)
|
||||
for (i64 i = 0; i < records.size(); i++)
|
||||
for (i64 j = 0; j < i; j++)
|
||||
if (records[i]->end < records[j]->end)
|
||||
depth[i]++;
|
||||
|
||||
std::cout << " User System Real Name\n";
|
||||
|
||||
for (int i = 0; i < records.size(); i++) {
|
||||
for (i64 i = 0; i < records.size(); i++) {
|
||||
TimerRecord &rec = *records[i];
|
||||
printf(" % 8.3f % 8.3f % 8.3f %s%s\n",
|
||||
((double)rec.user / 1000000000),
|
||||
|
@ -28,7 +28,7 @@ std::function<void()> fork_child() {
|
||||
if (pid > 0) {
|
||||
// Parent
|
||||
close(pipefd[1]);
|
||||
int r = read(pipefd[0], (char[1]){}, 1);
|
||||
i64 r = read(pipefd[0], (char[1]){}, 1);
|
||||
_exit(r != 1);
|
||||
}
|
||||
|
||||
@ -50,7 +50,7 @@ static std::string base64(u8 *data, u64 size) {
|
||||
<< chars[(x >> 18) & 0b111111];
|
||||
};
|
||||
|
||||
int i = 0;
|
||||
i64 i = 0;
|
||||
for (; i < size - 3; i += 3)
|
||||
encode((data[i + 2] << 16) | (data[i + 1] << 8) | data[i]);
|
||||
|
||||
@ -65,7 +65,7 @@ static std::string compute_sha256(char **argv) {
|
||||
SHA256_CTX ctx;
|
||||
SHA256_Init(&ctx);
|
||||
|
||||
for (int i = 0; argv[i]; i++)
|
||||
for (i64 i = 0; argv[i]; i++)
|
||||
if (!strcmp(argv[i], "-preload") && !strcmp(argv[i], "--preload"))
|
||||
SHA256_Update(&ctx, argv[i], strlen(argv[i]) + 1);
|
||||
|
||||
@ -74,7 +74,7 @@ static std::string compute_sha256(char **argv) {
|
||||
return base64(digest, SHA256_SIZE);
|
||||
}
|
||||
|
||||
static void send_fd(int conn, int fd) {
|
||||
static void send_fd(i64 conn, i64 fd) {
|
||||
struct iovec iov;
|
||||
char dummy = '1';
|
||||
iov.iov_base = &dummy;
|
||||
@ -98,7 +98,7 @@ static void send_fd(int conn, int fd) {
|
||||
Error() << "sendmsg failed: " << strerror(errno);
|
||||
}
|
||||
|
||||
static int recv_fd(int conn) {
|
||||
static i64 recv_fd(i64 conn) {
|
||||
struct iovec iov;
|
||||
char buf[1];
|
||||
iov.iov_base = buf;
|
||||
@ -112,7 +112,7 @@ static int recv_fd(int conn) {
|
||||
msg.msg_control = (caddr_t)cmsgbuf;
|
||||
msg.msg_controllen = sizeof(cmsgbuf);
|
||||
|
||||
int len = recvmsg(conn, &msg, 0);
|
||||
i64 len = recvmsg(conn, &msg, 0);
|
||||
if (len <= 0)
|
||||
Error() << "recvmsg failed: " << strerror(errno);
|
||||
|
||||
@ -121,8 +121,8 @@ static int recv_fd(int conn) {
|
||||
return *(int *)CMSG_DATA(cmsg);
|
||||
}
|
||||
|
||||
bool resume_daemon(char **argv, int *code) {
|
||||
int conn = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
bool resume_daemon(char **argv, i64 *code) {
|
||||
i64 conn = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (conn == -1)
|
||||
Error() << "socket failed: " << strerror(errno);
|
||||
|
||||
@ -139,7 +139,7 @@ bool resume_daemon(char **argv, int *code) {
|
||||
|
||||
send_fd(conn, STDOUT_FILENO);
|
||||
send_fd(conn, STDERR_FILENO);
|
||||
int r = read(conn, (char[1]){}, 1);
|
||||
i64 r = read(conn, (char[1]){}, 1);
|
||||
*code = (r != 1);
|
||||
return true;
|
||||
}
|
||||
@ -149,7 +149,7 @@ void daemonize(char **argv, std::function<void()> *wait_for_client,
|
||||
if (daemon(1, 0) == -1)
|
||||
Error() << "daemon failed: " << strerror(errno);
|
||||
|
||||
int sock = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
i64 sock = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (sock == -1)
|
||||
Error() << "socket failed: " << strerror(errno);
|
||||
|
||||
@ -175,7 +175,7 @@ void daemonize(char **argv, std::function<void()> *wait_for_client,
|
||||
if (listen(sock, 0) == -1)
|
||||
Error() << "listen failed: " << strerror(errno);
|
||||
|
||||
static int conn = -1;
|
||||
static i64 conn = -1;
|
||||
|
||||
*wait_for_client = [=]() {
|
||||
fd_set rfds;
|
||||
@ -186,7 +186,7 @@ void daemonize(char **argv, std::function<void()> *wait_for_client,
|
||||
tv.tv_sec = DAEMON_TIMEOUT;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
int res = select(sock + 1, &rfds, NULL, NULL, &tv);
|
||||
i64 res = select(sock + 1, &rfds, NULL, NULL, &tv);
|
||||
if (res == -1)
|
||||
Error() << "select failed: " << strerror(errno);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user