From 839d85e4405aef4856d1a35a6580226e997cc369 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 30 Mar 2020 21:41:54 -0400 Subject: [PATCH] fixes to 32-bit handling, to support 32-bit arm --- lib/std/zig/system.zig | 16 ++++++++++------ src-self-hosted/translate_c.zig | 26 +++++++++++++++++++++++--- src/link.cpp | 1 + src/os.cpp | 4 ++-- 4 files changed, 36 insertions(+), 11 deletions(-) diff --git a/lib/std/zig/system.zig b/lib/std/zig/system.zig index 1da2002f9503..c65e8911dce8 100644 --- a/lib/std/zig/system.zig +++ b/lib/std/zig/system.zig @@ -622,9 +622,10 @@ pub const NativeTargetInfo = struct { const p_offset = elfInt(is_64, need_bswap, ph32.p_offset, ph64.p_offset); const p_filesz = elfInt(is_64, need_bswap, ph32.p_filesz, ph64.p_filesz); if (p_filesz > result.dynamic_linker.buffer.len) return error.NameTooLong; - _ = try preadMin(file, result.dynamic_linker.buffer[0..p_filesz], p_offset, p_filesz); - // PT_INTERP includes a null byte in p_filesz. - const len = p_filesz - 1; + const filesz = @intCast(usize, p_filesz); + _ = try preadMin(file, result.dynamic_linker.buffer[0..filesz], p_offset, filesz); + // PT_INTERP includes a null byte in filesz. + const len = filesz - 1; // dynamic_linker.max_byte is "max", not "len". // We know it will fit in u8 because we check against dynamic_linker.buffer.len above. result.dynamic_linker.max_byte = @intCast(u8, len - 1); @@ -645,7 +646,7 @@ pub const NativeTargetInfo = struct { { var dyn_off = elfInt(is_64, need_bswap, ph32.p_offset, ph64.p_offset); const p_filesz = elfInt(is_64, need_bswap, ph32.p_filesz, ph64.p_filesz); - const dyn_size: u64 = if (is_64) @sizeOf(elf.Elf64_Dyn) else @sizeOf(elf.Elf32_Dyn); + const dyn_size: usize = if (is_64) @sizeOf(elf.Elf64_Dyn) else @sizeOf(elf.Elf32_Dyn); const dyn_num = p_filesz / dyn_size; var dyn_buf: [16 * @sizeOf(elf.Elf64_Dyn)]u8 align(@alignOf(elf.Elf64_Dyn)) = undefined; var dyn_i: usize = 0; @@ -751,7 +752,10 @@ pub const NativeTargetInfo = struct { const strtab_read_len = try preadMin(file, &strtab_buf, ds.offset, shstrtab_len); const strtab = strtab_buf[0..strtab_read_len]; // TODO this pointer cast should not be necessary - const rpath_list = mem.spanZ(@ptrCast([*:0]u8, strtab[rpoff..].ptr)); + const rpoff_usize = std.math.cast(usize, rpoff) catch |err| switch (err) { + error.Overflow => return error.InvalidElfFile, + }; + const rpath_list = mem.spanZ(@ptrCast([*:0]u8, strtab[rpoff_usize..].ptr)); var it = mem.tokenize(rpath_list, ":"); while (it.next()) |rpath| { var dir = fs.cwd().openDir(rpath, .{}) catch |err| switch (err) { @@ -811,7 +815,7 @@ pub const NativeTargetInfo = struct { } fn preadMin(file: fs.File, buf: []u8, offset: u64, min_read_len: usize) !usize { - var i: u64 = 0; + var i: usize = 0; while (i < min_read_len) { const len = file.pread(buf[i .. buf.len - i], offset + i) catch |err| switch (err) { error.OperationAborted => unreachable, // Windows-only diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index f1d7d665468c..f8eec3578faa 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -3845,7 +3845,9 @@ fn transCreateNodePtrType( } fn transCreateNodeAPInt(c: *Context, int: *const ZigClangAPSInt) !*ast.Node { - const num_limbs = ZigClangAPSInt_getNumWords(int); + const num_limbs = math.cast(usize, ZigClangAPSInt_getNumWords(int)) catch |err| switch (err) { + error.Overflow => return error.OutOfMemory, + }; var aps_int = int; const is_negative = ZigClangAPSInt_isSigned(int) and ZigClangAPSInt_isNegative(int); if (is_negative) @@ -3855,8 +3857,26 @@ fn transCreateNodeAPInt(c: *Context, int: *const ZigClangAPSInt) !*ast.Node { big.negate(); defer big.deinit(); const data = ZigClangAPSInt_getRawData(aps_int); - var i: @TypeOf(num_limbs) = 0; - while (i < num_limbs) : (i += 1) big.limbs[i] = data[i]; + switch (@sizeOf(std.math.big.Limb)) { + 8 => { + var i: usize = 0; + while (i < num_limbs) : (i += 1) { + big.limbs[i] = data[i]; + } + }, + 4 => { + var limb_i: usize = 0; + var data_i: usize = 0; + while (limb_i < num_limbs) : ({ + limb_i += 2; + data_i += 1; + }) { + big.limbs[limb_i] = @truncate(u32, data[data_i]); + big.limbs[limb_i + 1] = @truncate(u32, data[data_i] >> 32); + } + }, + else => @compileError("unimplemented"), + } const str = big.toString(c.a(), 10) catch |err| switch (err) { error.OutOfMemory => return error.OutOfMemory, else => unreachable, diff --git a/src/link.cpp b/src/link.cpp index ed6275ec3a45..0d7a8a410b53 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -651,6 +651,7 @@ static const char *build_libunwind(CodeGen *parent, Stage2ProgressNode *progress if (parent->is_single_threaded) { c_file->args.append("-D_LIBUNWIND_HAS_NO_THREADS"); } + c_file->args.append("-Wno-bitwise-conditional-parentheses"); c_source_files.append(c_file); } child_gen->c_source_files = c_source_files; diff --git a/src/os.cpp b/src/os.cpp index 872c0270f1d7..a1deb0f6112f 100644 --- a/src/os.cpp +++ b/src/os.cpp @@ -1097,8 +1097,8 @@ static Error set_file_times(OsFile file, OsTimeStamp ts) { return ErrorNone; #else struct timespec times[2] = { - { (time_t)ts.sec, (time_t)ts.nsec }, - { (time_t)ts.sec, (time_t)ts.nsec }, + { (time_t)ts.sec, (long)ts.nsec }, + { (time_t)ts.sec, (long)ts.nsec }, }; if (futimens(file, times) == -1) { switch (errno) {