aboutsummaryrefslogtreecommitdiff
path: root/lib/std
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-08-30 13:02:43 -0700
committerAndrew Kelley <andrew@ziglang.org>2022-08-30 13:02:43 -0700
commit1e21876de25f5725dd093f2243bcfdb3f6c6c44e (patch)
tree1482b1d8b7cb025006c02b9705295d3e50cf44e1 /lib/std
parent1cb8065a52c9bf74f913c46a011ab0118c92f0fa (diff)
parentf559ea95b1c37fd6ede8fff6ffb2d74d5c2abc4e (diff)
downloadzig-1e21876de25f5725dd093f2243bcfdb3f6c6c44e.tar.gz
zig-1e21876de25f5725dd093f2243bcfdb3f6c6c44e.zip
Merge remote-tracking branch 'origin/master' into llvm15
Diffstat (limited to 'lib/std')
-rw-r--r--lib/std/coff.zig335
-rw-r--r--lib/std/rand.zig2
-rw-r--r--lib/std/rand/test.zig2
-rw-r--r--lib/std/start.zig2
4 files changed, 214 insertions, 127 deletions
diff --git a/lib/std/coff.zig b/lib/std/coff.zig
index f9de318e7a..e822416f70 100644
--- a/lib/std/coff.zig
+++ b/lib/std/coff.zig
@@ -256,20 +256,89 @@ pub const OptionalHeaderPE64 = extern struct {
number_of_rva_and_sizes: u32,
};
+pub const IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16;
+
+pub const DirectoryEntry = enum(u16) {
+ /// Export Directory
+ EXPORT = 0,
+
+ /// Import Directory
+ IMPORT = 1,
+
+ /// Resource Directory
+ RESOURCE = 2,
+
+ /// Exception Directory
+ EXCEPTION = 3,
+
+ /// Security Directory
+ SECURITY = 4,
+
+ /// Base Relocation Table
+ BASERELOC = 5,
+
+ /// Debug Directory
+ DEBUG = 6,
+
+ /// Architecture Specific Data
+ ARCHITECTURE = 7,
+
+ /// RVA of GP
+ GLOBALPTR = 8,
+
+ /// TLS Directory
+ TLS = 9,
+
+ /// Load Configuration Directory
+ LOAD_CONFIG = 10,
+
+ /// Bound Import Directory in headers
+ BOUND_IMPORT = 11,
+
+ /// Import Address Table
+ IAT = 12,
+
+ /// Delay Load Import Descriptors
+ DELAY_IMPORT = 13,
+
+ /// COM Runtime descriptor
+ COM_DESCRIPTOR = 14,
+};
+
+pub const ImageDataDirectory = extern struct {
+ virtual_address: u32,
+ size: u32,
+};
+
pub const DebugDirectoryEntry = extern struct {
- characteristiccs: u32,
+ characteristics: u32,
time_date_stamp: u32,
major_version: u16,
minor_version: u16,
- @"type": u32,
+ @"type": DebugType,
size_of_data: u32,
address_of_raw_data: u32,
pointer_to_raw_data: u32,
};
-pub const ImageDataDirectory = extern struct {
- virtual_address: u32,
- size: u32,
+pub const DebugType = enum(u32) {
+ UNKNOWN = 0,
+ COFF = 1,
+ CODEVIEW = 2,
+ FPO = 3,
+ MISC = 4,
+ EXCEPTION = 5,
+ FIXUP = 6,
+ OMAP_TO_SRC = 7,
+ OMAP_FROM_SRC = 8,
+ BORLAND = 9,
+ RESERVED10 = 10,
+ VC_FEATURE = 12,
+ POGO = 13,
+ ILTCG = 14,
+ MPX = 15,
+ REPRO = 16,
+ EX_DLLCHARACTERISTICS = 20,
};
pub const SectionHeader = extern struct {
@@ -303,6 +372,15 @@ pub const SectionHeader = extern struct {
return std.math.powi(u16, 2, self.flags.ALIGN - 1) catch unreachable;
}
+ pub fn setAlignment(self: *SectionHeader, new_alignment: u16) void {
+ assert(new_alignment > 0 and new_alignment <= 8192);
+ self.flags.ALIGN = std.math.log2(new_alignment);
+ }
+
+ pub fn isCode(self: SectionHeader) bool {
+ return self.flags.CNT_CODE == 0b1;
+ }
+
pub fn isComdat(self: SectionHeader) bool {
return self.flags.LNK_COMDAT == 0b1;
}
@@ -778,6 +856,21 @@ pub const MachineType = enum(u16) {
/// MIPS little-endian WCE v2
WCEMIPSV2 = 0x169,
+ pub fn fromTargetCpuArch(arch: std.Target.Cpu.Arch) MachineType {
+ return switch (arch) {
+ .arm => .ARM,
+ .powerpc => .POWERPC,
+ .riscv32 => .RISCV32,
+ .thumb => .Thumb,
+ .i386 => .I386,
+ .aarch64 => .ARM64,
+ .riscv64 => .RISCV64,
+ .x86_64 => .X64,
+ // there's cases we don't (yet) handle
+ else => unreachable,
+ };
+ }
+
pub fn toTargetCpuArch(machine_type: MachineType) ?std.Target.Cpu.Arch {
return switch (machine_type) {
.ARM => .arm,
@@ -794,10 +887,6 @@ pub const MachineType = enum(u16) {
}
};
-const IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16;
-const IMAGE_DEBUG_TYPE_CODEVIEW = 2;
-const DEBUG_DIRECTORY = 6;
-
pub const CoffError = error{
InvalidPEMagic,
InvalidPEHeader,
@@ -831,7 +920,7 @@ pub const Coff = struct {
var stream = std.io.fixedBufferStream(self.data);
const reader = stream.reader();
try stream.seekTo(pe_pointer_offset);
- const coff_header_offset = try reader.readByte();
+ const coff_header_offset = try reader.readIntLittle(u32);
try stream.seekTo(coff_header_offset);
var buf: [4]u8 = undefined;
try reader.readNoEof(&buf);
@@ -862,7 +951,7 @@ pub const Coff = struct {
};
const data_dirs = self.getDataDirectories();
- const debug_dir = data_dirs[DEBUG_DIRECTORY];
+ const debug_dir = data_dirs[@enumToInt(DirectoryEntry.DEBUG)];
const file_offset = debug_dir.virtual_address - header.virtual_address + header.pointer_to_raw_data;
var stream = std.io.fixedBufferStream(self.data);
@@ -875,7 +964,7 @@ pub const Coff = struct {
var i: u32 = 0;
blk: while (i < debug_dir_entry_count) : (i += 1) {
const debug_dir_entry = try reader.readStruct(DebugDirectoryEntry);
- if (debug_dir_entry.type == IMAGE_DEBUG_TYPE_CODEVIEW) {
+ if (debug_dir_entry.type == .CODEVIEW) {
for (self.getSectionHeaders()) |*section| {
const section_start = section.virtual_address;
const section_size = section.virtual_size;
@@ -1011,132 +1100,132 @@ pub const Coff = struct {
mem.copy(u8, out_buff, self.data[sec.pointer_to_raw_data..][0..sec.virtual_size]);
return out_buff;
}
+};
- pub const Symtab = struct {
- buffer: []const u8,
-
- fn len(self: Symtab) usize {
- return @divExact(self.buffer.len, Symbol.sizeOf());
- }
-
- const Tag = enum {
- symbol,
- func_def,
- debug_info,
- weak_ext,
- file_def,
- sect_def,
- };
+pub const Symtab = struct {
+ buffer: []const u8,
- const Record = union(Tag) {
- symbol: Symbol,
- debug_info: DebugInfoDefinition,
- func_def: FunctionDefinition,
- weak_ext: WeakExternalDefinition,
- file_def: FileDefinition,
- sect_def: SectionDefinition,
- };
+ pub fn len(self: Symtab) usize {
+ return @divExact(self.buffer.len, Symbol.sizeOf());
+ }
- /// Lives as long as Symtab instance.
- fn at(self: Symtab, index: usize, tag: Tag) Record {
- const offset = index * Symbol.sizeOf();
- const raw = self.buffer[offset..][0..Symbol.sizeOf()];
- return switch (tag) {
- .symbol => .{ .symbol = asSymbol(raw) },
- .debug_info => .{ .debug_info = asDebugInfo(raw) },
- .func_def => .{ .func_def = asFuncDef(raw) },
- .weak_ext => .{ .weak_ext = asWeakExtDef(raw) },
- .file_def => .{ .file_def = asFileDef(raw) },
- .sect_def => .{ .sect_def = asSectDef(raw) },
- };
- }
+ pub const Tag = enum {
+ symbol,
+ func_def,
+ debug_info,
+ weak_ext,
+ file_def,
+ sect_def,
+ };
- fn asSymbol(raw: []const u8) Symbol {
- return .{
- .name = raw[0..8].*,
- .value = mem.readIntLittle(u32, raw[8..12]),
- .section_number = @intToEnum(SectionNumber, mem.readIntLittle(u16, raw[12..14])),
- .@"type" = @bitCast(SymType, mem.readIntLittle(u16, raw[14..16])),
- .storage_class = @intToEnum(StorageClass, raw[16]),
- .number_of_aux_symbols = raw[17],
- };
- }
+ pub const Record = union(Tag) {
+ symbol: Symbol,
+ debug_info: DebugInfoDefinition,
+ func_def: FunctionDefinition,
+ weak_ext: WeakExternalDefinition,
+ file_def: FileDefinition,
+ sect_def: SectionDefinition,
+ };
- fn asDebugInfo(raw: []const u8) DebugInfoDefinition {
- return .{
- .unused_1 = raw[0..4].*,
- .linenumber = mem.readIntLittle(u16, raw[4..6]),
- .unused_2 = raw[6..12].*,
- .pointer_to_next_function = mem.readIntLittle(u32, raw[12..16]),
- .unused_3 = raw[16..18].*,
- };
- }
+ /// Lives as long as Symtab instance.
+ pub fn at(self: Symtab, index: usize, tag: Tag) Record {
+ const offset = index * Symbol.sizeOf();
+ const raw = self.buffer[offset..][0..Symbol.sizeOf()];
+ return switch (tag) {
+ .symbol => .{ .symbol = asSymbol(raw) },
+ .debug_info => .{ .debug_info = asDebugInfo(raw) },
+ .func_def => .{ .func_def = asFuncDef(raw) },
+ .weak_ext => .{ .weak_ext = asWeakExtDef(raw) },
+ .file_def => .{ .file_def = asFileDef(raw) },
+ .sect_def => .{ .sect_def = asSectDef(raw) },
+ };
+ }
- fn asFuncDef(raw: []const u8) FunctionDefinition {
- return .{
- .tag_index = mem.readIntLittle(u32, raw[0..4]),
- .total_size = mem.readIntLittle(u32, raw[4..8]),
- .pointer_to_linenumber = mem.readIntLittle(u32, raw[8..12]),
- .pointer_to_next_function = mem.readIntLittle(u32, raw[12..16]),
- .unused = raw[16..18].*,
- };
- }
+ fn asSymbol(raw: []const u8) Symbol {
+ return .{
+ .name = raw[0..8].*,
+ .value = mem.readIntLittle(u32, raw[8..12]),
+ .section_number = @intToEnum(SectionNumber, mem.readIntLittle(u16, raw[12..14])),
+ .@"type" = @bitCast(SymType, mem.readIntLittle(u16, raw[14..16])),
+ .storage_class = @intToEnum(StorageClass, raw[16]),
+ .number_of_aux_symbols = raw[17],
+ };
+ }
- fn asWeakExtDef(raw: []const u8) WeakExternalDefinition {
- return .{
- .tag_index = mem.readIntLittle(u32, raw[0..4]),
- .flag = @intToEnum(WeakExternalFlag, mem.readIntLittle(u32, raw[4..8])),
- .unused = raw[8..18].*,
- };
- }
+ fn asDebugInfo(raw: []const u8) DebugInfoDefinition {
+ return .{
+ .unused_1 = raw[0..4].*,
+ .linenumber = mem.readIntLittle(u16, raw[4..6]),
+ .unused_2 = raw[6..12].*,
+ .pointer_to_next_function = mem.readIntLittle(u32, raw[12..16]),
+ .unused_3 = raw[16..18].*,
+ };
+ }
- fn asFileDef(raw: []const u8) FileDefinition {
- return .{
- .file_name = raw[0..18].*,
- };
- }
+ fn asFuncDef(raw: []const u8) FunctionDefinition {
+ return .{
+ .tag_index = mem.readIntLittle(u32, raw[0..4]),
+ .total_size = mem.readIntLittle(u32, raw[4..8]),
+ .pointer_to_linenumber = mem.readIntLittle(u32, raw[8..12]),
+ .pointer_to_next_function = mem.readIntLittle(u32, raw[12..16]),
+ .unused = raw[16..18].*,
+ };
+ }
- fn asSectDef(raw: []const u8) SectionDefinition {
- return .{
- .length = mem.readIntLittle(u32, raw[0..4]),
- .number_of_relocations = mem.readIntLittle(u16, raw[4..6]),
- .number_of_linenumbers = mem.readIntLittle(u16, raw[6..8]),
- .checksum = mem.readIntLittle(u32, raw[8..12]),
- .number = mem.readIntLittle(u16, raw[12..14]),
- .selection = @intToEnum(ComdatSelection, raw[14]),
- .unused = raw[15..18].*,
- };
- }
+ fn asWeakExtDef(raw: []const u8) WeakExternalDefinition {
+ return .{
+ .tag_index = mem.readIntLittle(u32, raw[0..4]),
+ .flag = @intToEnum(WeakExternalFlag, mem.readIntLittle(u32, raw[4..8])),
+ .unused = raw[8..18].*,
+ };
+ }
- const Slice = struct {
- buffer: []const u8,
- num: usize,
- count: usize = 0,
-
- /// Lives as long as Symtab instance.
- fn next(self: *Slice) ?Symbol {
- if (self.count >= self.num) return null;
- const sym = asSymbol(self.buffer[0..Symbol.sizeOf()]);
- self.count += 1;
- self.buffer = self.buffer[Symbol.sizeOf()..];
- return sym;
- }
+ fn asFileDef(raw: []const u8) FileDefinition {
+ return .{
+ .file_name = raw[0..18].*,
};
+ }
- fn slice(self: Symtab, start: usize, end: ?usize) Slice {
- const offset = start * Symbol.sizeOf();
- const llen = if (end) |e| e * Symbol.sizeOf() else self.buffer.len;
- const num = @divExact(llen - offset, Symbol.sizeOf());
- return Slice{ .buffer = self.buffer[offset..][0..llen], .num = num };
- }
- };
+ fn asSectDef(raw: []const u8) SectionDefinition {
+ return .{
+ .length = mem.readIntLittle(u32, raw[0..4]),
+ .number_of_relocations = mem.readIntLittle(u16, raw[4..6]),
+ .number_of_linenumbers = mem.readIntLittle(u16, raw[6..8]),
+ .checksum = mem.readIntLittle(u32, raw[8..12]),
+ .number = mem.readIntLittle(u16, raw[12..14]),
+ .selection = @intToEnum(ComdatSelection, raw[14]),
+ .unused = raw[15..18].*,
+ };
+ }
- pub const Strtab = struct {
+ pub const Slice = struct {
buffer: []const u8,
+ num: usize,
+ count: usize = 0,
- fn get(self: Strtab, off: u32) []const u8 {
- assert(off < self.buffer.len);
- return mem.sliceTo(@ptrCast([*:0]const u8, self.buffer.ptr + off), 0);
+ /// Lives as long as Symtab instance.
+ pub fn next(self: *Slice) ?Symbol {
+ if (self.count >= self.num) return null;
+ const sym = asSymbol(self.buffer[0..Symbol.sizeOf()]);
+ self.count += 1;
+ self.buffer = self.buffer[Symbol.sizeOf()..];
+ return sym;
}
};
+
+ pub fn slice(self: Symtab, start: usize, end: ?usize) Slice {
+ const offset = start * Symbol.sizeOf();
+ const llen = if (end) |e| e * Symbol.sizeOf() else self.buffer.len;
+ const num = @divExact(llen - offset, Symbol.sizeOf());
+ return Slice{ .buffer = self.buffer[offset..][0..llen], .num = num };
+ }
+};
+
+pub const Strtab = struct {
+ buffer: []const u8,
+
+ pub fn get(self: Strtab, off: u32) []const u8 {
+ assert(off < self.buffer.len);
+ return mem.sliceTo(@ptrCast([*:0]const u8, self.buffer.ptr + off), 0);
+ }
};
diff --git a/lib/std/rand.zig b/lib/std/rand.zig
index c13d2895c9..e94578c119 100644
--- a/lib/std/rand.zig
+++ b/lib/std/rand.zig
@@ -343,7 +343,7 @@ pub const Random = struct {
///
/// This is useful for selecting an item from a slice where weights are not equal.
/// `T` must be a numeric type capable of holding the sum of `proportions`.
- pub fn weightedIndex(r: std.rand.Random, comptime T: type, proportions: []T) usize {
+ pub fn weightedIndex(r: std.rand.Random, comptime T: type, proportions: []const T) usize {
// This implementation works by summing the proportions and picking a random
// point in [0, sum). We then loop over the proportions, accumulating
// until our accumulator is greater than the random point.
diff --git a/lib/std/rand/test.zig b/lib/std/rand/test.zig
index cae77d6e37..1ad9adbeb8 100644
--- a/lib/std/rand/test.zig
+++ b/lib/std/rand/test.zig
@@ -452,7 +452,7 @@ test "Random weightedIndex" {
var prng = DefaultPrng.init(0);
const random = prng.random();
- var proportions = [_]T{ 2, 1, 1, 2 };
+ const proportions = [_]T{ 2, 1, 1, 2 };
var counts = [_]f64{ 0, 0, 0, 0 };
const n_trials: u64 = 10_000;
diff --git a/lib/std/start.zig b/lib/std/start.zig
index e6a7b7991a..49094ab02d 100644
--- a/lib/std/start.zig
+++ b/lib/std/start.zig
@@ -36,8 +36,6 @@ comptime {
if (@typeInfo(@TypeOf(root.main)).Fn.calling_convention != .C) {
@export(main2, .{ .name = "main" });
}
- } else if (builtin.os.tag == .windows) {
- @export(wWinMainCRTStartup2, .{ .name = "wWinMainCRTStartup" });
} else if (builtin.os.tag == .wasi and @hasDecl(root, "main")) {
@export(wasiMain2, .{ .name = "_start" });
} else {