mirror of
https://github.com/rui314/mold.git
synced 2024-11-11 05:46:58 +03:00
[Mach-O] Handle .bss
This commit is contained in:
parent
16d904a198
commit
c227286dd5
@ -13,6 +13,7 @@ std::ostream &operator<<(std::ostream &out, const InputSection &sec) {
|
||||
InputSection::InputSection(Context &ctx, ObjectFile &file, const MachSection &hdr)
|
||||
: file(file), hdr(hdr),
|
||||
osec(*OutputSection::get_instance(ctx, hdr.get_segname(), hdr.get_sectname())) {
|
||||
if (hdr.type != S_ZEROFILL)
|
||||
contents = file.mf->get_contents().substr(hdr.offset, hdr.size);
|
||||
subsections.push_back({*this, 0, (u32)contents.size(), (u32)hdr.addr});
|
||||
}
|
||||
|
@ -62,6 +62,9 @@ static void create_synthetic_chunks(Context &ctx) {
|
||||
ctx.data_seg.chunks.push_back(&ctx.lazy_symbol_ptr);
|
||||
ctx.data_seg.chunks.push_back(ctx.data);
|
||||
|
||||
if (!ctx.bss->members.empty())
|
||||
ctx.data_seg.chunks.push_back(ctx.bss);
|
||||
|
||||
ctx.linkedit_seg.chunks.push_back(&ctx.rebase);
|
||||
ctx.linkedit_seg.chunks.push_back(&ctx.bind);
|
||||
ctx.linkedit_seg.chunks.push_back(&ctx.lazy_bind);
|
||||
|
@ -127,6 +127,7 @@ std::ostream &operator<<(std::ostream &out, const InputSection &sec);
|
||||
class Subsection {
|
||||
public:
|
||||
std::string_view get_contents() {
|
||||
assert(isec.hdr.type != S_ZEROFILL);
|
||||
return isec.contents.substr(input_offset, input_size);
|
||||
}
|
||||
|
||||
@ -583,8 +584,11 @@ struct Context {
|
||||
Context() {
|
||||
text = OutputSection::get_instance(*this, "__TEXT", "__text");
|
||||
data = OutputSection::get_instance(*this, "__DATA", "__data");
|
||||
bss = OutputSection::get_instance(*this, "__DATA", "__bss");
|
||||
cstring = OutputSection::get_instance(*this, "__TEXT", "__cstring");
|
||||
common = OutputSection::get_instance(*this, "__TEXT", "__common");
|
||||
|
||||
bss->hdr.type = S_ZEROFILL;
|
||||
cstring->hdr.type = S_CSTRING_LITERALS;
|
||||
}
|
||||
|
||||
@ -660,6 +664,7 @@ struct Context {
|
||||
|
||||
OutputSection *text = nullptr;
|
||||
OutputSection *data = nullptr;
|
||||
OutputSection *bss = nullptr;
|
||||
OutputSection *cstring = nullptr;
|
||||
OutputSection *common = nullptr;
|
||||
|
||||
|
@ -292,11 +292,13 @@ void OutputSection::copy_buf(Context &ctx) {
|
||||
u8 *buf = ctx.buf + hdr.offset;
|
||||
|
||||
for (Subsection *subsec : members) {
|
||||
if (subsec->isec.hdr.type != S_ZEROFILL) {
|
||||
std::string_view data = subsec->get_contents();
|
||||
memcpy(buf + subsec->output_offset, data.data(), data.size());
|
||||
subsec->apply_reloc(ctx, buf + subsec->output_offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OutputSegment::OutputSegment(std::string_view name, u32 prot, u32 flags) {
|
||||
cmd.cmd = LC_SEGMENT_64;
|
||||
@ -310,19 +312,36 @@ void OutputSegment::set_offset(Context &ctx, i64 fileoff, u64 vmaddr) {
|
||||
cmd.fileoff = fileoff;
|
||||
cmd.vmaddr = vmaddr;
|
||||
|
||||
i64 offset = 0;
|
||||
i64 i = 0;
|
||||
|
||||
for (Chunk *sec : chunks) {
|
||||
offset = align_to(offset, 1 << sec->hdr.p2align);
|
||||
sec->hdr.addr = vmaddr + offset;
|
||||
sec->hdr.offset = fileoff + offset;
|
||||
sec->compute_size(ctx);
|
||||
offset += sec->hdr.size;
|
||||
while (i < chunks.size() && chunks[i]->hdr.type != S_ZEROFILL) {
|
||||
Chunk &sec = *chunks[i++];
|
||||
fileoff = align_to(fileoff, 1 << sec.hdr.p2align);
|
||||
vmaddr = align_to(vmaddr, 1 << sec.hdr.p2align);
|
||||
|
||||
sec.hdr.offset = fileoff;
|
||||
sec.hdr.addr = vmaddr;
|
||||
|
||||
sec.compute_size(ctx);
|
||||
fileoff += sec.hdr.size;
|
||||
vmaddr += sec.hdr.size;
|
||||
}
|
||||
|
||||
cmd.vmsize = align_to(offset, PAGE_SIZE);
|
||||
cmd.filesize =
|
||||
(this == ctx.segments.back()) ? offset : align_to(offset, PAGE_SIZE);
|
||||
while (i < chunks.size()) {
|
||||
Chunk &sec = *chunks[i++];
|
||||
assert(sec.hdr.type == S_ZEROFILL);
|
||||
vmaddr = align_to(vmaddr, 1 << sec.hdr.p2align);
|
||||
sec.hdr.addr = vmaddr;
|
||||
sec.compute_size(ctx);
|
||||
vmaddr += sec.hdr.size;
|
||||
}
|
||||
|
||||
cmd.vmsize = align_to(vmaddr - cmd.vmaddr, PAGE_SIZE);
|
||||
|
||||
if (this == ctx.segments.back())
|
||||
cmd.filesize = fileoff - cmd.fileoff;
|
||||
else
|
||||
cmd.filesize = align_to(fileoff - cmd.fileoff, PAGE_SIZE);
|
||||
}
|
||||
|
||||
void OutputSegment::copy_buf(Context &ctx) {
|
||||
|
23
test/macho/bss.sh
Executable file
23
test/macho/bss.sh
Executable file
@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
cd $(dirname $0)
|
||||
mold=`pwd`/../../ld64.mold
|
||||
echo -n "Testing $(basename -s .sh $0) ... "
|
||||
t=$(pwd)/../../out/test/macho/$(basename -s .sh $0)
|
||||
mkdir -p $t
|
||||
|
||||
cat <<EOF | cc -o $t/a.o -c -xc -
|
||||
#include <stdio.h>
|
||||
|
||||
static int foo[100];
|
||||
|
||||
int main() {
|
||||
foo[1] = 5;
|
||||
printf("%d %d %p\n", foo[0], foo[1], foo);
|
||||
}
|
||||
EOF
|
||||
|
||||
clang -fuse-ld=$mold -o $t/exe $t/a.o
|
||||
$t/exe | grep -q '^0 5 '
|
||||
|
||||
echo OK
|
Loading…
Reference in New Issue
Block a user