mirror of
https://github.com/ziglang/zig.git
synced 2026-01-03 12:03:19 +00:00
zld: update relocs and start prepping for segment allocs
This commit is contained in:
parent
dfa69e3c30
commit
a04bc1ed14
@ -48,8 +48,6 @@ dwarf_debug_ranges_index: ?u16 = null,
|
||||
|
||||
symtab: std.ArrayListUnmanaged(macho.nlist_64) = .{},
|
||||
strtab: std.ArrayListUnmanaged(u8) = .{},
|
||||
|
||||
initializers: std.ArrayListUnmanaged(u32) = .{},
|
||||
data_in_code_entries: std.ArrayListUnmanaged(macho.data_in_code_entry) = .{},
|
||||
|
||||
symbols: std.ArrayListUnmanaged(*Symbol) = .{},
|
||||
@ -157,7 +155,6 @@ pub fn deinit(self: *Object) void {
|
||||
}
|
||||
self.load_commands.deinit(self.allocator);
|
||||
self.data_in_code_entries.deinit(self.allocator);
|
||||
self.initializers.deinit(self.allocator);
|
||||
self.symtab.deinit(self.allocator);
|
||||
self.strtab.deinit(self.allocator);
|
||||
self.symbols.deinit(self.allocator);
|
||||
@ -573,6 +570,7 @@ pub fn parseTextBlocks(self: *Object, zld: *Zld) !void {
|
||||
symbol.payload = .{
|
||||
.regular = .{
|
||||
.linkage = .translation_unit,
|
||||
.address = sect.addr,
|
||||
.segment_id = match.seg,
|
||||
.section_id = match.sect,
|
||||
.file = self,
|
||||
@ -657,6 +655,13 @@ pub fn symbolFromReloc(self: *Object, rel: macho.relocation_info) !*Symbol {
|
||||
});
|
||||
defer self.allocator.free(name);
|
||||
const symbol = try Symbol.new(self.allocator, name);
|
||||
symbol.payload = .{
|
||||
.regular = .{
|
||||
.linkage = .translation_unit,
|
||||
.address = sect.addr,
|
||||
.file = self,
|
||||
},
|
||||
};
|
||||
try self.sections_as_symbols.putNoClobber(self.allocator, sect_id, symbol);
|
||||
break :symbol symbol;
|
||||
};
|
||||
@ -666,22 +671,6 @@ pub fn symbolFromReloc(self: *Object, rel: macho.relocation_info) !*Symbol {
|
||||
return symbol;
|
||||
}
|
||||
|
||||
pub fn parseInitializers(self: *Object) !void {
|
||||
const index = self.mod_init_func_section_index orelse return;
|
||||
const section = self.sections.items[index];
|
||||
|
||||
log.debug("parsing initializers in {s}", .{self.name.?});
|
||||
|
||||
// Parse C++ initializers
|
||||
const relocs = section.relocs orelse unreachable;
|
||||
try self.initializers.ensureCapacity(self.allocator, relocs.len);
|
||||
for (relocs) |rel| {
|
||||
self.initializers.appendAssumeCapacity(rel.target.symbol);
|
||||
}
|
||||
|
||||
mem.reverse(u32, self.initializers.items);
|
||||
}
|
||||
|
||||
fn parseSymtab(self: *Object) !void {
|
||||
const index = self.symtab_cmd_index orelse return;
|
||||
const symtab_cmd = self.load_commands.items[index].Symtab;
|
||||
|
||||
@ -120,16 +120,6 @@ pub const Output = struct {
|
||||
install_name: ?[]const u8 = null,
|
||||
};
|
||||
|
||||
const TlvOffset = struct {
|
||||
source_addr: u64,
|
||||
offset: u64,
|
||||
|
||||
fn cmp(context: void, a: TlvOffset, b: TlvOffset) bool {
|
||||
_ = context;
|
||||
return a.source_addr < b.source_addr;
|
||||
}
|
||||
};
|
||||
|
||||
pub const TextBlock = struct {
|
||||
local_sym_index: u32,
|
||||
aliases: ?[]u32 = null,
|
||||
@ -274,12 +264,11 @@ pub fn link(self: *Zld, files: []const []const u8, output: Output, args: LinkArg
|
||||
try self.parseLibs(args.libs, args.syslibroot);
|
||||
try self.resolveSymbols();
|
||||
try self.parseTextBlocks();
|
||||
try self.sortSections();
|
||||
try self.addRpaths(args.rpaths);
|
||||
try self.addDataInCodeLC();
|
||||
try self.addCodeSignatureLC();
|
||||
return error.TODO;
|
||||
// try self.updateMetadata();
|
||||
// try self.sortSections();
|
||||
// try self.addRpaths(args.rpaths);
|
||||
// try self.addDataInCodeLC();
|
||||
// try self.addCodeSignatureLC();
|
||||
// try self.allocateTextSegment();
|
||||
// try self.allocateDataConstSegment();
|
||||
// try self.allocateDataSegment();
|
||||
@ -343,106 +332,6 @@ fn parseLibs(self: *Zld, libs: []const []const u8, syslibroot: ?[]const u8) !voi
|
||||
}
|
||||
}
|
||||
|
||||
fn mapAndUpdateSections(
|
||||
self: *Zld,
|
||||
object: *Object,
|
||||
source_sect_id: u16,
|
||||
target_seg_id: u16,
|
||||
target_sect_id: u16,
|
||||
) !void {
|
||||
const source_sect = &object.sections.items[source_sect_id];
|
||||
const target_seg = &self.load_commands.items[target_seg_id].Segment;
|
||||
const target_sect = &target_seg.sections.items[target_sect_id];
|
||||
|
||||
const alignment = try math.powi(u32, 2, target_sect.@"align");
|
||||
const offset = mem.alignForwardGeneric(u64, target_sect.size, alignment);
|
||||
const size = mem.alignForwardGeneric(u64, source_sect.inner.size, alignment);
|
||||
|
||||
log.debug("{s}: '{s},{s}' mapped to '{s},{s}' from 0x{x} to 0x{x}", .{
|
||||
object.name.?,
|
||||
segmentName(source_sect.inner),
|
||||
sectionName(source_sect.inner),
|
||||
segmentName(target_sect.*),
|
||||
sectionName(target_sect.*),
|
||||
offset,
|
||||
offset + size,
|
||||
});
|
||||
log.debug(" | flags 0x{x}", .{source_sect.inner.flags});
|
||||
|
||||
source_sect.target_map = .{
|
||||
.segment_id = target_seg_id,
|
||||
.section_id = target_sect_id,
|
||||
.offset = @intCast(u32, offset),
|
||||
};
|
||||
target_sect.size = offset + size;
|
||||
}
|
||||
|
||||
fn updateMetadata(self: *Zld) !void {
|
||||
for (self.objects.items) |object| {
|
||||
// Find ideal section alignment and update section mappings
|
||||
for (object.sections.items) |sect, sect_id| {
|
||||
const match = (try self.getMatchingSection(sect.inner)) orelse {
|
||||
log.debug("{s}: unhandled section type 0x{x} for '{s},{s}'", .{
|
||||
object.name.?,
|
||||
sect.inner.flags,
|
||||
segmentName(sect.inner),
|
||||
sectionName(sect.inner),
|
||||
});
|
||||
continue;
|
||||
};
|
||||
const target_seg = &self.load_commands.items[match.seg].Segment;
|
||||
const target_sect = &target_seg.sections.items[match.sect];
|
||||
target_sect.@"align" = math.max(target_sect.@"align", sect.inner.@"align");
|
||||
|
||||
try self.mapAndUpdateSections(object, @intCast(u16, sect_id), match.seg, match.sect);
|
||||
}
|
||||
}
|
||||
|
||||
tlv_align: {
|
||||
const has_tlv =
|
||||
self.tlv_section_index != null or
|
||||
self.tlv_data_section_index != null or
|
||||
self.tlv_bss_section_index != null;
|
||||
|
||||
if (!has_tlv) break :tlv_align;
|
||||
|
||||
const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
|
||||
|
||||
if (self.tlv_section_index) |index| {
|
||||
const sect = &seg.sections.items[index];
|
||||
sect.@"align" = 3; // __thread_vars is always 8byte aligned
|
||||
}
|
||||
|
||||
// Apparently __tlv_data and __tlv_bss need to have matching alignment, so fix it up.
|
||||
// <rdar://problem/24221680> All __thread_data and __thread_bss sections must have same alignment
|
||||
// https://github.com/apple-opensource/ld64/blob/e28c028b20af187a16a7161d89e91868a450cadc/src/ld/ld.cpp#L1172
|
||||
const data_align: u32 = data: {
|
||||
if (self.tlv_data_section_index) |index| {
|
||||
const sect = &seg.sections.items[index];
|
||||
break :data sect.@"align";
|
||||
}
|
||||
break :tlv_align;
|
||||
};
|
||||
const bss_align: u32 = bss: {
|
||||
if (self.tlv_bss_section_index) |index| {
|
||||
const sect = &seg.sections.items[index];
|
||||
break :bss sect.@"align";
|
||||
}
|
||||
break :tlv_align;
|
||||
};
|
||||
const max_align = math.max(data_align, bss_align);
|
||||
|
||||
if (self.tlv_data_section_index) |index| {
|
||||
const sect = &seg.sections.items[index];
|
||||
sect.@"align" = max_align;
|
||||
}
|
||||
if (self.tlv_bss_section_index) |index| {
|
||||
const sect = &seg.sections.items[index];
|
||||
sect.@"align" = max_align;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub const MatchingSection = struct {
|
||||
seg: u16,
|
||||
sect: u16,
|
||||
@ -946,36 +835,6 @@ fn sortSections(self: *Zld) !void {
|
||||
maybe_index.* = new_index;
|
||||
}
|
||||
}
|
||||
|
||||
for (self.objects.items) |object| {
|
||||
for (object.sections.items) |*sect| {
|
||||
const target_map = sect.target_map orelse continue;
|
||||
|
||||
const new_index = blk: {
|
||||
if (self.text_segment_cmd_index.? == target_map.segment_id) {
|
||||
break :blk text_index_mapping.get(target_map.section_id) orelse unreachable;
|
||||
} else if (self.data_const_segment_cmd_index.? == target_map.segment_id) {
|
||||
break :blk data_const_index_mapping.get(target_map.section_id) orelse unreachable;
|
||||
} else if (self.data_segment_cmd_index.? == target_map.segment_id) {
|
||||
break :blk data_index_mapping.get(target_map.section_id) orelse unreachable;
|
||||
} else unreachable;
|
||||
};
|
||||
|
||||
log.debug("remapping in {s}: '{s},{s}': {} => {}", .{
|
||||
object.name.?,
|
||||
segmentName(sect.inner),
|
||||
sectionName(sect.inner),
|
||||
target_map.section_id,
|
||||
new_index,
|
||||
});
|
||||
|
||||
sect.target_map = .{
|
||||
.segment_id = target_map.segment_id,
|
||||
.section_id = new_index,
|
||||
.offset = target_map.offset,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn allocateTextSegment(self: *Zld) !void {
|
||||
@ -1431,6 +1290,7 @@ fn resolveSymbolsInObject(self: *Zld, object: *Object) !void {
|
||||
symbol.payload = .{
|
||||
.regular = .{
|
||||
.linkage = .translation_unit,
|
||||
.address = sym.n_value,
|
||||
.weak_ref = Symbol.isWeakRef(sym),
|
||||
.file = object,
|
||||
.local_sym_index = @intCast(u32, self.locals.items.len),
|
||||
@ -1470,6 +1330,7 @@ fn resolveSymbolsInObject(self: *Zld, object: *Object) !void {
|
||||
symbol.payload = .{
|
||||
.regular = .{
|
||||
.linkage = linkage,
|
||||
.address = sym.n_value,
|
||||
.weak_ref = Symbol.isWeakRef(sym),
|
||||
.file = object,
|
||||
},
|
||||
@ -1672,80 +1533,6 @@ fn parseTextBlocks(self: *Zld) !void {
|
||||
}
|
||||
}
|
||||
|
||||
fn resolveRelocsAndWriteSections(self: *Zld) !void {
|
||||
for (self.objects.items) |object| {
|
||||
log.debug("relocating object {s}", .{object.name});
|
||||
|
||||
for (object.sections.items) |sect| {
|
||||
if (sectionType(sect.inner) == macho.S_MOD_INIT_FUNC_POINTERS or
|
||||
sectionType(sect.inner) == macho.S_MOD_TERM_FUNC_POINTERS) continue;
|
||||
|
||||
const segname = segmentName(sect.inner);
|
||||
const sectname = sectionName(sect.inner);
|
||||
|
||||
log.debug("relocating section '{s},{s}'", .{ segname, sectname });
|
||||
|
||||
// Get target mapping
|
||||
const target_map = sect.target_map orelse {
|
||||
log.debug("no mapping for '{s},{s}'; skipping", .{ segname, sectname });
|
||||
continue;
|
||||
};
|
||||
const target_seg = self.load_commands.items[target_map.segment_id].Segment;
|
||||
const target_sect = target_seg.sections.items[target_map.section_id];
|
||||
const target_sect_addr = target_sect.addr + target_map.offset;
|
||||
const target_sect_off = target_sect.offset + target_map.offset;
|
||||
|
||||
if (sect.relocs) |relocs| {
|
||||
for (relocs) |rel| {
|
||||
const source_addr = target_sect_addr + rel.offset;
|
||||
|
||||
var args: reloc.Relocation.ResolveArgs = .{
|
||||
.source_addr = source_addr,
|
||||
.target_addr = undefined,
|
||||
};
|
||||
|
||||
switch (rel.@"type") {
|
||||
.unsigned => {
|
||||
args.target_addr = try self.relocTargetAddr(object, rel.target);
|
||||
|
||||
const unsigned = rel.cast(reloc.Unsigned) orelse unreachable;
|
||||
if (unsigned.subtractor) |subtractor| {
|
||||
args.subtractor = try self.relocTargetAddr(object, subtractor);
|
||||
}
|
||||
if (rel.target == .section) {
|
||||
const source_sect = object.sections.items[rel.target.section];
|
||||
args.source_source_sect_addr = sect.inner.addr;
|
||||
args.source_target_sect_addr = source_sect.inner.addr;
|
||||
}
|
||||
},
|
||||
.got_page, .got_page_off, .got_load, .got, .pointer_to_got => {
|
||||
const dc_seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;
|
||||
const got = dc_seg.sections.items[self.got_section_index.?];
|
||||
const sym = object.symbols.items[rel.target.symbol];
|
||||
const got_index = sym.got_index orelse {
|
||||
log.err("expected GOT index relocating symbol '{s}'", .{sym.name});
|
||||
log.err("this is an internal linker error", .{});
|
||||
return error.FailedToResolveRelocationTarget;
|
||||
};
|
||||
args.target_addr = got.addr + got_index * @sizeOf(u64);
|
||||
},
|
||||
else => |tt| {
|
||||
if (tt == .signed and rel.target == .section) {
|
||||
const source_sect = object.sections.items[rel.target.section];
|
||||
args.source_source_sect_addr = sect.inner.addr;
|
||||
args.source_target_sect_addr = source_sect.inner.addr;
|
||||
}
|
||||
args.target_addr = try self.relocTargetAddr(object, rel.target);
|
||||
},
|
||||
}
|
||||
|
||||
try rel.resolve(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn populateMetadata(self: *Zld) !void {
|
||||
if (self.pagezero_segment_cmd_index == null) {
|
||||
self.pagezero_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
|
||||
|
||||
@ -48,33 +48,24 @@ pub const Relocation = struct {
|
||||
/// => * is unreachable
|
||||
is_64bit: bool,
|
||||
|
||||
source_sect_addr: ?u64 = null,
|
||||
|
||||
pub fn resolve(self: Unsigned, base: Relocation, source_addr: u64, target_addr: u64) !void {
|
||||
// const addend = if (unsigned.base.target == .section)
|
||||
// unsigned.addend - @intCast(i64, args.source_target_sect_addr.?)
|
||||
// else
|
||||
// unsigned.addend;
|
||||
const addend = if (self.source_sect_addr) |addr|
|
||||
self.addend - addr
|
||||
else
|
||||
self.addend;
|
||||
|
||||
// const result = if (args.subtractor) |subtractor|
|
||||
// @intCast(i64, args.target_addr) - @intCast(i64, subtractor) + addend
|
||||
// else
|
||||
// @intCast(i64, args.target_addr) + addend;
|
||||
const result = if (self.subtractor) |subtractor|
|
||||
@intCast(i64, target_addr) - @intCast(i64, subtractor.payload.regular.address) + addend
|
||||
else
|
||||
@intCast(i64, target_addr) + addend;
|
||||
|
||||
// log.debug(" | calculated addend 0x{x}", .{addend});
|
||||
// log.debug(" | calculated unsigned value 0x{x}", .{result});
|
||||
|
||||
// if (unsigned.is_64bit) {
|
||||
// mem.writeIntLittle(
|
||||
// u64,
|
||||
// unsigned.base.code[0..8],
|
||||
// @bitCast(u64, result),
|
||||
// );
|
||||
// } else {
|
||||
// mem.writeIntLittle(
|
||||
// u32,
|
||||
// unsigned.base.code[0..4],
|
||||
// @truncate(u32, @bitCast(u64, result)),
|
||||
// );
|
||||
// }
|
||||
if (self.is_64bit) {
|
||||
mem.writeIntLittle(u64, base.block.code[base.offset..][0..8], @bitCast(u64, result));
|
||||
} else {
|
||||
mem.writeIntLittle(u32, base.block.code[base.offset..][0..4], @truncate(u32, @bitCast(u64, result)));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn format(self: Unsigned, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
|
||||
@ -191,56 +182,119 @@ pub const Relocation = struct {
|
||||
pub fn resolve(self: PageOff, base: Relocation, source_addr: u64, target_addr: u64) !void {
|
||||
switch (self.kind) {
|
||||
.page => {
|
||||
// const target_addr = if (page_off.addend) |addend| args.target_addr + addend else args.target_addr;
|
||||
// const narrowed = @truncate(u12, target_addr);
|
||||
const actual_target_addr = if (self.addend) |addend| target_addr + addend else target_addr;
|
||||
const narrowed = @truncate(u12, actual_target_addr);
|
||||
|
||||
// log.debug(" | narrowed address within the page 0x{x}", .{narrowed});
|
||||
// log.debug(" | {s} opcode", .{page_off.op_kind});
|
||||
const op_kind = self.op_kind orelse unreachable;
|
||||
var inst: aarch64.Instruction = blk: {
|
||||
switch (op_kind) {
|
||||
.arithmetic => {
|
||||
break :blk .{
|
||||
.add_subtract_immediate = mem.bytesToValue(
|
||||
meta.TagPayload(
|
||||
aarch64.Instruction,
|
||||
aarch64.Instruction.add_subtract_immediate,
|
||||
),
|
||||
base.block.code[base.offset..][0..4],
|
||||
),
|
||||
};
|
||||
},
|
||||
.load => {
|
||||
break :blk .{
|
||||
.load_store_register = mem.bytesToValue(
|
||||
meta.TagPayload(
|
||||
aarch64.Instruction,
|
||||
aarch64.Instruction.load_store_register,
|
||||
),
|
||||
base.block.code[base.offset..][0..4],
|
||||
),
|
||||
};
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
// var inst = page_off.inst;
|
||||
// if (page_off.op_kind == .arithmetic) {
|
||||
// inst.add_subtract_immediate.imm12 = narrowed;
|
||||
// } else {
|
||||
// const offset: u12 = blk: {
|
||||
// if (inst.load_store_register.size == 0) {
|
||||
// if (inst.load_store_register.v == 1) {
|
||||
// // 128-bit SIMD is scaled by 16.
|
||||
// break :blk try math.divExact(u12, narrowed, 16);
|
||||
// }
|
||||
// // Otherwise, 8-bit SIMD or ldrb.
|
||||
// break :blk narrowed;
|
||||
// } else {
|
||||
// const denom: u4 = try math.powi(u4, 2, inst.load_store_register.size);
|
||||
// break :blk try math.divExact(u12, narrowed, denom);
|
||||
// }
|
||||
// };
|
||||
// inst.load_store_register.offset = offset;
|
||||
// }
|
||||
|
||||
// mem.writeIntLittle(u32, page_off.base.code[0..4], inst.toU32());
|
||||
if (op_kind == .arithmetic) {
|
||||
inst.add_subtract_immediate.imm12 = narrowed;
|
||||
} else {
|
||||
const offset: u12 = blk: {
|
||||
if (inst.load_store_register.size == 0) {
|
||||
if (inst.load_store_register.v == 1) {
|
||||
// 128-bit SIMD is scaled by 16.
|
||||
break :blk try math.divExact(u12, narrowed, 16);
|
||||
}
|
||||
// Otherwise, 8-bit SIMD or ldrb.
|
||||
break :blk narrowed;
|
||||
} else {
|
||||
const denom: u4 = try math.powi(u4, 2, inst.load_store_register.size);
|
||||
break :blk try math.divExact(u12, narrowed, denom);
|
||||
}
|
||||
};
|
||||
inst.load_store_register.offset = offset;
|
||||
}
|
||||
|
||||
mem.writeIntLittle(u32, base.block.code[base.offset..][0..4], inst.toU32());
|
||||
},
|
||||
.got => {
|
||||
// const narrowed = @truncate(u12, args.target_addr);
|
||||
|
||||
// log.debug(" | narrowed address within the page 0x{x}", .{narrowed});
|
||||
|
||||
// var inst = page_off.inst;
|
||||
// const offset = try math.divExact(u12, narrowed, 8);
|
||||
// inst.load_store_register.offset = offset;
|
||||
|
||||
// mem.writeIntLittle(u32, page_off.base.code[0..4], inst.toU32());
|
||||
const narrowed = @truncate(u12, target_addr);
|
||||
var inst = mem.bytesToValue(
|
||||
meta.TagPayload(
|
||||
aarch64.Instruction,
|
||||
aarch64.Instruction.load_store_register,
|
||||
),
|
||||
base.block.code[base.offset..][0..4],
|
||||
);
|
||||
const offset = try math.divExact(u12, narrowed, 8);
|
||||
inst.load_store_register.offset = offset;
|
||||
mem.writeIntLittle(u32, base.block.code[base.offset..][0..4], inst.toU32());
|
||||
},
|
||||
.tlvp => {
|
||||
|
||||
// const narrowed = @truncate(u12, args.target_addr);
|
||||
|
||||
// log.debug(" | narrowed address within the page 0x{x}", .{narrowed});
|
||||
|
||||
// var inst = page_off.inst;
|
||||
// inst.add_subtract_immediate.imm12 = narrowed;
|
||||
|
||||
// mem.writeIntLittle(u32, page_off.base.code[0..4], inst.toU32());
|
||||
const RegInfo = struct {
|
||||
rd: u5,
|
||||
rn: u5,
|
||||
size: u1,
|
||||
};
|
||||
const reg_info: RegInfo = blk: {
|
||||
if (isArithmeticOp(base.block.code[base.offset..][0..4])) {
|
||||
const inst = mem.bytesToValue(
|
||||
meta.TagPayload(
|
||||
aarch64.Instruction,
|
||||
aarch64.Instruction.add_subtract_immediate,
|
||||
),
|
||||
base.block.code[base.offset..][0..4],
|
||||
);
|
||||
break :blk .{
|
||||
.rd = inst.rd,
|
||||
.rn = inst.rn,
|
||||
.size = inst.sf,
|
||||
};
|
||||
} else {
|
||||
const inst = mem.bytesToValue(
|
||||
meta.TagPayload(
|
||||
aarch64.Instruction,
|
||||
aarch64.Instruction.load_store_register,
|
||||
),
|
||||
base.block.code[base.offset..][0..4],
|
||||
);
|
||||
break :blk .{
|
||||
.rd = inst.rt,
|
||||
.rn = inst.rn,
|
||||
.size = @truncate(u1, inst.size),
|
||||
};
|
||||
}
|
||||
};
|
||||
const narrowed = @truncate(u12, target_addr);
|
||||
var inst = aarch64.Instruction{
|
||||
.add_subtract_immediate = .{
|
||||
.rd = reg_info.rd,
|
||||
.rn = reg_info.rn,
|
||||
.imm12 = narrowed,
|
||||
.sh = 0,
|
||||
.s = 0,
|
||||
.op = 0,
|
||||
.sf = reg_info.size,
|
||||
},
|
||||
};
|
||||
mem.writeIntLittle(u32, base.block.code[base.offset..][0..4], inst.toU32());
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -661,12 +715,17 @@ pub const Parser = struct {
|
||||
mem.readIntLittle(i64, self.block.code[parsed.offset..][0..8])
|
||||
else
|
||||
mem.readIntLittle(i32, self.block.code[parsed.offset..][0..4]);
|
||||
const source_sect_addr = if (rel.r_extern == 0) blk: {
|
||||
if (parsed.target.payload == .regular) break :blk parsed.target.payload.regular.address;
|
||||
break :blk null;
|
||||
} else null;
|
||||
|
||||
parsed.payload = .{
|
||||
.unsigned = .{
|
||||
.subtractor = self.subtractor,
|
||||
.is_64bit = is_64bit,
|
||||
.addend = addend,
|
||||
.source_sect_addr = source_sect_addr,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user