mirror of
https://github.com/rui314/mold.git
synced 2024-11-13 09:39:13 +03:00
temporary
This commit is contained in:
parent
c2ca7d2c1a
commit
0c0a6714d4
@ -3,53 +3,11 @@
|
||||
using namespace llvm::ELF;
|
||||
|
||||
std::atomic_int num_relocs;
|
||||
std::vector<OutputSection *> OutputSection::all_instances;
|
||||
|
||||
static StringRef get_output_name(StringRef name) {
|
||||
static StringRef common_names[] = {
|
||||
".text.", ".data.rel.ro.", ".data.", ".rodata.", ".bss.rel.ro.",
|
||||
".bss.", ".init_array.", ".fini_array.", ".tbss.", ".tdata.",
|
||||
};
|
||||
|
||||
for (StringRef s : common_names)
|
||||
if (name.startswith(s) || name == s.drop_back())
|
||||
return s.drop_back();
|
||||
return name;
|
||||
}
|
||||
|
||||
static OutputSection *get_output_section(InputSection *isec) {
|
||||
StringRef iname = get_output_name(isec->name);
|
||||
uint64_t iflags = isec->hdr->sh_flags & ~SHF_GROUP;
|
||||
|
||||
auto find = [&]() -> OutputSection * {
|
||||
for (OutputSection *osec : OutputSection::all_instances)
|
||||
if (iname == osec->name && iflags == (osec->hdr.sh_flags & ~SHF_GROUP) &&
|
||||
isec->hdr->sh_type == osec->hdr.sh_type)
|
||||
return osec;
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
// Search for an exiting output section.
|
||||
static std::shared_mutex mu;
|
||||
std::shared_lock shared_lock(mu);
|
||||
if (OutputSection *osec = find())
|
||||
return osec;
|
||||
shared_lock.unlock();
|
||||
|
||||
// Create a new output section.
|
||||
std::unique_lock unique_lock(mu);
|
||||
if (OutputSection *osec = find())
|
||||
return osec;
|
||||
|
||||
OutputSection *osec = new OutputSection(iname, iflags, isec->hdr->sh_type);
|
||||
OutputSection::all_instances.push_back(osec);
|
||||
return osec;
|
||||
}
|
||||
|
||||
InputSection::InputSection(ObjectFile *file, const ELF64LE::Shdr *hdr, StringRef name)
|
||||
: file(file), hdr(hdr) {
|
||||
this->name = name;
|
||||
this->output_section = get_output_section(this);
|
||||
this->output_section = OutputSection::get_instance(this);
|
||||
|
||||
uint64_t align = (hdr->sh_addralign == 0) ? 1 : hdr->sh_addralign;
|
||||
if (align > UINT32_MAX)
|
||||
|
45
main.cc
45
main.cc
@ -103,12 +103,14 @@ static std::vector<ObjectFile *> read_file(StringRef path) {
|
||||
return vec;
|
||||
}
|
||||
|
||||
static InputChunk *create_interp_section() {
|
||||
static OutputSection *create_interp_section() {
|
||||
static char loader[] = "/lib64/ld-linux-x86-64.so.2";
|
||||
auto *osec = new OutputSection(".interp", PF_R, PT_INTERP);
|
||||
return new GenericSection(".interp",
|
||||
makeArrayRef((uint8_t *)loader, sizeof(loader)),
|
||||
osec, llvm::ELF::SHF_ALLOC, llvm::ELF::SHT_PROGBITS);
|
||||
auto *isec = new GenericSection(".interp",
|
||||
makeArrayRef((uint8_t *)loader, sizeof(loader)),
|
||||
osec, llvm::ELF::SHF_ALLOC, llvm::ELF::SHT_PROGBITS);
|
||||
osec->chunks.push_back(isec);
|
||||
return osec;
|
||||
}
|
||||
|
||||
static std::vector<ELF64LE::Phdr> create_phdrs() {
|
||||
@ -125,6 +127,13 @@ create_shdrs(ArrayRef<OutputChunk *> output_chunks) {
|
||||
return vec;
|
||||
}
|
||||
|
||||
static void bin_input_sections(std::vector<ObjectFile *> &files) {
|
||||
for (ObjectFile *file : files)
|
||||
for (InputSection *isec : file->sections)
|
||||
if (isec)
|
||||
isec->output_section->chunks.push_back(isec);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
// Parse command line options
|
||||
MyOptTable opt_table;
|
||||
@ -181,6 +190,11 @@ int main(int argc, char **argv) {
|
||||
file->eliminate_duplicate_comdat_groups();
|
||||
comdat_timer.stopTimer();
|
||||
|
||||
// Bin input sections into output sections
|
||||
output_section_timer.startTimer();
|
||||
bin_input_sections(files);
|
||||
output_section_timer.stopTimer();
|
||||
|
||||
// Create an ELF header, a section header and a program header.
|
||||
std::vector<OutputChunk *> output_chunks;
|
||||
out::ehdr = new OutputEhdr;
|
||||
@ -188,26 +202,13 @@ int main(int argc, char **argv) {
|
||||
output_chunks.push_back(out::ehdr);
|
||||
output_chunks.push_back(out::phdr);
|
||||
|
||||
auto add_section = [&](InputChunk *chunk) {
|
||||
if (!chunk)
|
||||
return;
|
||||
OutputSection *osec = chunk->output_section;
|
||||
assert(osec);
|
||||
if (osec->chunks.empty())
|
||||
output_chunks.push_back(osec);
|
||||
osec->chunks.push_back(chunk);
|
||||
};
|
||||
|
||||
// Add .interp section
|
||||
add_section(create_interp_section());
|
||||
output_chunks.push_back(create_interp_section());
|
||||
|
||||
// Bin input sections into output sections
|
||||
output_section_timer.startTimer();
|
||||
|
||||
for (ObjectFile *file : files)
|
||||
for (InputSection *isec : file->sections)
|
||||
add_section(isec);
|
||||
output_section_timer.stopTimer();
|
||||
// Add other output sections
|
||||
for (OutputSection *osec : OutputSection::all_instances)
|
||||
if (!osec->chunks.empty())
|
||||
output_chunks.push_back(osec);
|
||||
|
||||
// Create program header contents.
|
||||
out::phdr->hdr = create_phdrs();
|
||||
|
2
mold.h
2
mold.h
@ -297,6 +297,8 @@ public:
|
||||
// Sections
|
||||
class OutputSection : public OutputChunk {
|
||||
public:
|
||||
static OutputSection *get_instance(InputSection *isec);
|
||||
|
||||
OutputSection(StringRef name, uint64_t flags, uint32_t type)
|
||||
: name(name) {
|
||||
hdr.sh_flags = flags;
|
||||
|
@ -5,6 +5,7 @@ using namespace llvm::ELF;
|
||||
OutputEhdr *out::ehdr;
|
||||
OutputShdr *out::shdr;
|
||||
OutputPhdr *out::phdr;
|
||||
std::vector<OutputSection *> OutputSection::all_instances;
|
||||
|
||||
void OutputEhdr::relocate(uint8_t *buf) {
|
||||
auto *hdr = (ELF64LE::Ehdr *)buf;
|
||||
@ -37,3 +38,44 @@ void OutputSection::set_offset(uint64_t off) {
|
||||
}
|
||||
size = off - offset;
|
||||
}
|
||||
|
||||
static StringRef get_output_name(StringRef name) {
|
||||
static StringRef common_names[] = {
|
||||
".text.", ".data.rel.ro.", ".data.", ".rodata.", ".bss.rel.ro.",
|
||||
".bss.", ".init_array.", ".fini_array.", ".tbss.", ".tdata.",
|
||||
};
|
||||
|
||||
for (StringRef s : common_names)
|
||||
if (name.startswith(s) || name == s.drop_back())
|
||||
return s.drop_back();
|
||||
return name;
|
||||
}
|
||||
|
||||
OutputSection *OutputSection::get_instance(InputSection *isec) {
|
||||
StringRef iname = get_output_name(isec->name);
|
||||
uint64_t iflags = isec->hdr->sh_flags & ~SHF_GROUP;
|
||||
|
||||
auto find = [&]() -> OutputSection * {
|
||||
for (OutputSection *osec : OutputSection::all_instances)
|
||||
if (iname == osec->name && iflags == (osec->hdr.sh_flags & ~SHF_GROUP) &&
|
||||
isec->hdr->sh_type == osec->hdr.sh_type)
|
||||
return osec;
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
// Search for an exiting output section.
|
||||
static std::shared_mutex mu;
|
||||
std::shared_lock shared_lock(mu);
|
||||
if (OutputSection *osec = find())
|
||||
return osec;
|
||||
shared_lock.unlock();
|
||||
|
||||
// Create a new output section.
|
||||
std::unique_lock unique_lock(mu);
|
||||
if (OutputSection *osec = find())
|
||||
return osec;
|
||||
|
||||
OutputSection *osec = new OutputSection(iname, iflags, isec->hdr->sh_type);
|
||||
OutputSection::all_instances.push_back(osec);
|
||||
return osec;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user