Memory placement in linker script seems to be ignored

src/s.ld [main() in main.zig has linksection(“.text.main”)]

SECTIONS {
	.text : {
		*(.text.main)
		*(.text)
		*(.rodata .rodata.*)
	} = 0x80000000
}

build.zig

const std = @import("std");

pub fn build(b: *std.Build) !void {
	const q = std.Target.Query {
		.cpu_arch = .riscv32,
		.cpu_model = .{ .explicit = .generic(.riscv32) },
		.os_tag = .freestanding,
	};

	const mod = b.addModule("main", .{
		.root_source_file = b.path("src/main.zig"),
		.optimize = .ReleaseSmall,
		.target = b.resolveTargetQuery(q),
	});

	const obj = b.addObject(.{
		.name = "main",
		.root_module = mod,
	});

	obj.setLinkerScript(b.path("src/s.ld"));

	const oc = obj.addObjCopy(.{
		.format = .bin,
		.only_section = ".text",
	});

	b.default_step = &b.addInstallBinFile(oc.getOutput(), "out.bin").step;
	b.default_step.dependOn(&b.addInstallBinFile(obj.getEmittedBin(), "out.o").step);
}

All of this seems to be correct, however objdump and the disassembled code show address 0 being used instead of the proper 0x80000000. Is this an issue with my build/linker scripts, or something else?

Just a guess, but I believe addObject does not run the linker? Maybe b.addExecutable would do the trick?

The linker is being run, as the sections are being combined correctly.