2020-10-13 14:35:35 +03:00
|
|
|
#include "chibild.h"
|
|
|
|
|
2020-10-20 04:00:53 +03:00
|
|
|
using llvm::ELF::SHT_NOBITS;
|
|
|
|
|
2020-10-19 16:55:52 +03:00
|
|
|
static OutputSection *get_output_section(StringRef name) {
|
2020-10-19 16:57:46 +03:00
|
|
|
static OutputSection common_sections[] = {
|
2020-10-19 16:55:52 +03:00
|
|
|
{".text"}, {".data"}, {".data.rel.ro"}, {".rodata"}, {".bss"}, {".bss.rel.ro"},
|
|
|
|
{".ctors"}, {".dtors"}, {".init_array"}, {".fini_array"}, {".tbss"}, {".tdata"},
|
|
|
|
};
|
|
|
|
|
2020-10-19 16:57:46 +03:00
|
|
|
for (OutputSection &osec : common_sections) {
|
2020-10-19 16:55:52 +03:00
|
|
|
if (!name.startswith(osec.name))
|
|
|
|
continue;
|
|
|
|
if (name.size() == osec.name.size())
|
|
|
|
return &osec;
|
|
|
|
if (name.size() > osec.name.size() && name[osec.name.size()] == '.')
|
|
|
|
return &osec;
|
|
|
|
};
|
|
|
|
|
|
|
|
static ConcurrentMap<OutputSection> map;
|
|
|
|
return map.insert(name, OutputSection(name));
|
|
|
|
}
|
|
|
|
|
2020-10-13 14:35:35 +03:00
|
|
|
InputSection::InputSection(ObjectFile *file, const ELF64LE::Shdr *hdr, StringRef name)
|
2020-10-17 07:52:46 +03:00
|
|
|
: file(file), hdr(hdr) {
|
|
|
|
this->name = name;
|
2020-10-19 16:55:52 +03:00
|
|
|
this->output_section = get_output_section(name);
|
2020-10-19 17:37:29 +03:00
|
|
|
|
2020-10-19 18:08:07 +03:00
|
|
|
uint64_t align = (hdr->sh_addralign == 0) ? 1 : hdr->sh_addralign;
|
|
|
|
if (align > UINT32_MAX)
|
2020-10-19 17:37:29 +03:00
|
|
|
error(toString(file) + ": section sh_addralign is too large");
|
2020-10-19 18:08:07 +03:00
|
|
|
if (__builtin_popcount(align) != 1)
|
|
|
|
error(toString(file) + ": section sh_addralign is not a power of two");
|
|
|
|
this->alignment = align;
|
2020-10-17 07:52:46 +03:00
|
|
|
}
|
2020-10-14 10:27:45 +03:00
|
|
|
|
2020-10-15 13:27:35 +03:00
|
|
|
uint64_t InputSection::get_size() const {
|
2020-10-14 10:27:45 +03:00
|
|
|
return hdr->sh_size;
|
|
|
|
}
|
2020-10-15 13:27:35 +03:00
|
|
|
|
2020-10-16 10:38:03 +03:00
|
|
|
void InputSection::copy_to(uint8_t *buf) {
|
2020-10-20 04:00:53 +03:00
|
|
|
if (hdr->sh_type == SHT_NOBITS || hdr->sh_size == 0)
|
|
|
|
return;
|
2020-10-16 10:38:03 +03:00
|
|
|
ArrayRef<uint8_t> data = check(file->obj.getSectionContents(*hdr));
|
|
|
|
memcpy(buf + offset, &data[0], data.size());
|
2020-10-15 13:27:35 +03:00
|
|
|
}
|
2020-10-19 17:37:29 +03:00
|
|
|
|
2020-10-20 04:32:32 +03:00
|
|
|
void InputSection::relocate(uint8_t *buf) {
|
|
|
|
if (hdr->sh_type == SHT_NOBITS || hdr->sh_size == 0)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-10-19 17:37:29 +03:00
|
|
|
std::string toString(InputSection *isec) {
|
|
|
|
return (toString(isec->file) + ":(" + isec->name + ")").str();
|
|
|
|
}
|