mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
parent
8e9f2f02d2
commit
09bc118c9f
2 changed files with 142 additions and 1 deletions
|
|
@ -1140,7 +1140,109 @@ fn getNavShdrIndex(
|
|||
const ptr_size = elf_file.ptrWidthBytes();
|
||||
const ip = &zcu.intern_pool;
|
||||
const nav_val = zcu.navValue(nav_index);
|
||||
if (ip.isFunctionType(nav_val.typeOf(zcu).toIntern())) {
|
||||
const is_func = ip.isFunctionType(nav_val.typeOf(zcu).toIntern());
|
||||
if (ip.getNav(nav_index).getLinkSection().unwrap()) |@"linksection"| {
|
||||
const section_name = @"linksection".toSlice(ip);
|
||||
if (elf_file.sectionByName(section_name)) |osec| {
|
||||
if (is_func) {
|
||||
elf_file.sections.items(.shdr)[osec].sh_flags |= elf.SHF_EXECINSTR;
|
||||
} else {
|
||||
elf_file.sections.items(.shdr)[osec].sh_flags |= elf.SHF_WRITE;
|
||||
}
|
||||
return osec;
|
||||
}
|
||||
const osec = try elf_file.addSection(.{
|
||||
.type = elf.SHT_PROGBITS,
|
||||
.flags = elf.SHF_ALLOC | @as(u64, if (is_func) elf.SHF_EXECINSTR else elf.SHF_WRITE),
|
||||
.name = try elf_file.insertShString(section_name),
|
||||
.addralign = 1,
|
||||
});
|
||||
const section_index = try self.addSectionSymbol(gpa, try self.addString(gpa, section_name), osec);
|
||||
if (std.mem.eql(u8, section_name, ".text")) {
|
||||
elf_file.sections.items(.shdr)[osec].sh_flags = elf.SHF_ALLOC | elf.SHF_EXECINSTR;
|
||||
self.text_index = section_index;
|
||||
} else if (std.mem.startsWith(u8, section_name, ".text.")) {
|
||||
elf_file.sections.items(.shdr)[osec].sh_flags = elf.SHF_ALLOC | elf.SHF_EXECINSTR;
|
||||
} else if (std.mem.eql(u8, section_name, ".rodata")) {
|
||||
elf_file.sections.items(.shdr)[osec].sh_flags = elf.SHF_ALLOC;
|
||||
self.rodata_index = section_index;
|
||||
} else if (std.mem.startsWith(u8, section_name, ".rodata.")) {
|
||||
elf_file.sections.items(.shdr)[osec].sh_flags = elf.SHF_ALLOC;
|
||||
} else if (std.mem.eql(u8, section_name, ".data.rel.ro")) {
|
||||
elf_file.sections.items(.shdr)[osec].sh_flags = elf.SHF_ALLOC | elf.SHF_WRITE;
|
||||
self.data_relro_index = section_index;
|
||||
} else if (std.mem.eql(u8, section_name, ".data")) {
|
||||
elf_file.sections.items(.shdr)[osec].sh_flags = elf.SHF_ALLOC | elf.SHF_WRITE;
|
||||
self.data_index = section_index;
|
||||
} else if (std.mem.startsWith(u8, section_name, ".data.")) {
|
||||
elf_file.sections.items(.shdr)[osec].sh_flags = elf.SHF_ALLOC | elf.SHF_WRITE;
|
||||
} else if (std.mem.eql(u8, section_name, ".bss")) {
|
||||
const shdr = &elf_file.sections.items(.shdr)[osec];
|
||||
shdr.sh_type = elf.SHT_NOBITS;
|
||||
shdr.sh_flags = elf.SHF_ALLOC | elf.SHF_WRITE;
|
||||
self.bss_index = section_index;
|
||||
} else if (std.mem.startsWith(u8, section_name, ".bss.")) {
|
||||
const shdr = &elf_file.sections.items(.shdr)[osec];
|
||||
shdr.sh_type = elf.SHT_NOBITS;
|
||||
shdr.sh_flags = elf.SHF_ALLOC | elf.SHF_WRITE;
|
||||
} else if (std.mem.eql(u8, section_name, ".tdata")) {
|
||||
elf_file.sections.items(.shdr)[osec].sh_flags = elf.SHF_ALLOC | elf.SHF_WRITE | elf.SHF_TLS;
|
||||
self.tdata_index = section_index;
|
||||
} else if (std.mem.startsWith(u8, section_name, ".tdata.")) {
|
||||
elf_file.sections.items(.shdr)[osec].sh_flags = elf.SHF_ALLOC | elf.SHF_WRITE | elf.SHF_TLS;
|
||||
} else if (std.mem.eql(u8, section_name, ".tbss")) {
|
||||
const shdr = &elf_file.sections.items(.shdr)[osec];
|
||||
shdr.sh_type = elf.SHT_NOBITS;
|
||||
shdr.sh_flags = elf.SHF_ALLOC | elf.SHF_WRITE | elf.SHF_TLS;
|
||||
self.tbss_index = section_index;
|
||||
} else if (std.mem.startsWith(u8, section_name, ".tbss.")) {
|
||||
const shdr = &elf_file.sections.items(.shdr)[osec];
|
||||
shdr.sh_type = elf.SHT_NOBITS;
|
||||
shdr.sh_flags = elf.SHF_ALLOC | elf.SHF_WRITE | elf.SHF_TLS;
|
||||
} else if (std.mem.eql(u8, section_name, ".eh_frame")) {
|
||||
const target = &zcu.navFileScope(nav_index).mod.?.resolved_target.result;
|
||||
const shdr = &elf_file.sections.items(.shdr)[osec];
|
||||
if (target.cpu.arch == .x86_64) shdr.sh_type = elf.SHT_X86_64_UNWIND;
|
||||
shdr.sh_flags = elf.SHF_ALLOC;
|
||||
self.eh_frame_index = section_index;
|
||||
} else if (std.mem.eql(u8, section_name, ".debug_info")) {
|
||||
elf_file.sections.items(.shdr)[osec].sh_flags = 0;
|
||||
self.debug_info_index = section_index;
|
||||
} else if (std.mem.eql(u8, section_name, ".debug_abbrev")) {
|
||||
elf_file.sections.items(.shdr)[osec].sh_flags = 0;
|
||||
self.debug_abbrev_index = section_index;
|
||||
} else if (std.mem.eql(u8, section_name, ".debug_aranges")) {
|
||||
elf_file.sections.items(.shdr)[osec].sh_flags = 0;
|
||||
self.debug_aranges_index = section_index;
|
||||
} else if (std.mem.eql(u8, section_name, ".debug_str")) {
|
||||
elf_file.sections.items(.shdr)[osec].sh_flags = 0;
|
||||
self.debug_str_index = section_index;
|
||||
} else if (std.mem.eql(u8, section_name, ".debug_line")) {
|
||||
elf_file.sections.items(.shdr)[osec].sh_flags = 0;
|
||||
self.debug_line_index = section_index;
|
||||
} else if (std.mem.eql(u8, section_name, ".debug_line_str")) {
|
||||
elf_file.sections.items(.shdr)[osec].sh_flags = 0;
|
||||
self.debug_line_str_index = section_index;
|
||||
} else if (std.mem.eql(u8, section_name, ".debug_loclists")) {
|
||||
elf_file.sections.items(.shdr)[osec].sh_flags = 0;
|
||||
self.debug_loclists_index = section_index;
|
||||
} else if (std.mem.eql(u8, section_name, ".debug_rnglists")) {
|
||||
elf_file.sections.items(.shdr)[osec].sh_flags = 0;
|
||||
self.debug_rnglists_index = section_index;
|
||||
} else if (std.mem.startsWith(u8, section_name, ".debug")) {
|
||||
elf_file.sections.items(.shdr)[osec].sh_flags = 0;
|
||||
} else if (std.mem.eql(u8, section_name, ".init_array") or std.mem.startsWith(u8, section_name, ".init_array.")) {
|
||||
const shdr = &elf_file.sections.items(.shdr)[osec];
|
||||
shdr.sh_type = elf.SHT_INIT_ARRAY;
|
||||
shdr.sh_flags = elf.SHF_ALLOC | elf.SHF_WRITE;
|
||||
} else if (std.mem.eql(u8, section_name, ".fini_array") or std.mem.startsWith(u8, section_name, ".fini_array.")) {
|
||||
const shdr = &elf_file.sections.items(.shdr)[osec];
|
||||
shdr.sh_type = elf.SHT_FINI_ARRAY;
|
||||
shdr.sh_flags = elf.SHF_ALLOC | elf.SHF_WRITE;
|
||||
}
|
||||
return osec;
|
||||
}
|
||||
if (is_func) {
|
||||
if (self.text_index) |symbol_index|
|
||||
return self.symbol(symbol_index).outputShndx(elf_file).?;
|
||||
const osec = try elf_file.addSection(.{
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ pub fn testAll(b: *Build, build_opts: BuildOptions) *Step {
|
|||
elf_step.dependOn(testLinkingC(b, .{ .target = musl_target }));
|
||||
elf_step.dependOn(testLinkingCpp(b, .{ .target = musl_target }));
|
||||
elf_step.dependOn(testLinkingZig(b, .{ .target = musl_target }));
|
||||
elf_step.dependOn(testLinksection(b, .{ .target = musl_target }));
|
||||
elf_step.dependOn(testMergeStrings(b, .{ .target = musl_target }));
|
||||
elf_step.dependOn(testMergeStrings2(b, .{ .target = musl_target }));
|
||||
// https://github.com/ziglang/zig/issues/17451
|
||||
|
|
@ -165,6 +166,7 @@ pub fn testAll(b: *Build, build_opts: BuildOptions) *Step {
|
|||
elf_step.dependOn(testLinkingObj(b, .{ .use_llvm = false, .target = default_target }));
|
||||
elf_step.dependOn(testLinkingStaticLib(b, .{ .use_llvm = false, .target = default_target }));
|
||||
elf_step.dependOn(testLinkingZig(b, .{ .use_llvm = false, .target = default_target }));
|
||||
elf_step.dependOn(testLinksection(b, .{ .use_llvm = false, .target = default_target }));
|
||||
elf_step.dependOn(testImportingDataDynamic(b, .{ .use_llvm = false, .target = x86_64_gnu }));
|
||||
elf_step.dependOn(testImportingDataStatic(b, .{ .use_llvm = false, .target = x86_64_musl }));
|
||||
|
||||
|
|
@ -2439,6 +2441,43 @@ fn testLinkingZig(b: *Build, opts: Options) *Step {
|
|||
return test_step;
|
||||
}
|
||||
|
||||
fn testLinksection(b: *Build, opts: Options) *Step {
|
||||
const test_step = addTestStep(b, "linksection", opts);
|
||||
|
||||
const obj = addObject(b, opts, .{ .name = "main", .zig_source_bytes =
|
||||
\\export var test_global: u32 linksection(".TestGlobal") = undefined;
|
||||
\\export fn testFn() linksection(".TestFn") callconv(.c) void {
|
||||
\\ TestGenericFn("A").f();
|
||||
\\}
|
||||
\\fn TestGenericFn(comptime suffix: []const u8) type {
|
||||
\\ return struct {
|
||||
\\ fn f() linksection(".TestGenFn" ++ suffix) void {}
|
||||
\\ };
|
||||
\\}
|
||||
});
|
||||
|
||||
const check = obj.checkObject();
|
||||
check.checkInSymtab();
|
||||
check.checkContains("SECTION LOCAL DEFAULT .TestGlobal");
|
||||
check.checkInSymtab();
|
||||
check.checkContains("SECTION LOCAL DEFAULT .TestFn");
|
||||
check.checkInSymtab();
|
||||
check.checkContains("SECTION LOCAL DEFAULT .TestGenFnA");
|
||||
check.checkInSymtab();
|
||||
check.checkContains("OBJECT GLOBAL DEFAULT test_global");
|
||||
check.checkInSymtab();
|
||||
check.checkContains("FUNC GLOBAL DEFAULT testFn");
|
||||
|
||||
if (opts.optimize == .Debug) {
|
||||
check.checkInSymtab();
|
||||
check.checkContains("FUNC LOCAL DEFAULT main.TestGenericFn(");
|
||||
}
|
||||
|
||||
test_step.dependOn(&check.step);
|
||||
|
||||
return test_step;
|
||||
}
|
||||
|
||||
// Adapted from https://github.com/rui314/mold/blob/main/test/elf/mergeable-strings.sh
|
||||
fn testMergeStrings(b: *Build, opts: Options) *Step {
|
||||
const test_step = addTestStep(b, "merge-strings", opts);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue