| ... | ... | @@ -81,8 +81,10 @@ pub const abbrev_base_type = 4; |
| 81 | 81 | pub const abbrev_ptr_type = 5; |
| 82 | 82 | pub const abbrev_struct_type = 6; |
| 83 | 83 | pub const abbrev_struct_member = 7; |
| 84 | | pub const abbrev_pad1 = 8; |
| 85 | | pub const abbrev_parameter = 9; |
| 84 | pub const abbrev_enum_type = 8; |
| 85 | pub const abbrev_enum_variant = 9; |
| 86 | pub const abbrev_pad1 = 10; |
| 87 | pub const abbrev_parameter = 11; |
| 86 | 88 | |
| 87 | 89 | /// The reloc offset for the virtual address of a function in its Line Number Program. |
| 88 | 90 | /// Size is a virtual address integer. |
| ... | ... | @@ -879,6 +881,11 @@ fn addDbgInfoType( |
| 879 | 881 | } |
| 880 | 882 | }, |
| 881 | 883 | .Struct => blk: { |
| 884 | if (ty.tag() == .tuple) { |
| 885 | log.debug("TODO implement .debug_info for type '{}'", .{ty.fmtDebug()}); |
| 886 | try dbg_info_buffer.append(abbrev_pad1); |
| 887 | break :blk; |
| 888 | } |
| 882 | 889 | // try dbg_info_buffer.ensureUnusedCapacity(23); |
| 883 | 890 | // DW.AT.structure_type |
| 884 | 891 | try dbg_info_buffer.append(abbrev_struct_type); |
| ... | ... | @@ -918,6 +925,46 @@ fn addDbgInfoType( |
| 918 | 925 | // DW.AT.structure_type delimit children |
| 919 | 926 | try dbg_info_buffer.append(0); |
| 920 | 927 | }, |
| 928 | .Enum => { |
| 929 | // DW.AT.enumeration_type |
| 930 | try dbg_info_buffer.append(abbrev_enum_type); |
| 931 | // DW.AT.byte_size, DW.FORM.sdata |
| 932 | const abi_size = ty.abiSize(target); |
| 933 | try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size); |
| 934 | // DW.AT.name, DW.FORM.string |
| 935 | const enum_name = try ty.nameAllocArena(arena, target); |
| 936 | try dbg_info_buffer.ensureUnusedCapacity(enum_name.len + 1); |
| 937 | dbg_info_buffer.appendSliceAssumeCapacity(enum_name); |
| 938 | dbg_info_buffer.appendAssumeCapacity(0); |
| 939 | |
| 940 | const fields = ty.enumFields(); |
| 941 | const values: ?Module.EnumFull.ValueMap = switch (ty.tag()) { |
| 942 | .enum_full, .enum_nonexhaustive => ty.cast(Type.Payload.EnumFull).?.data.values, |
| 943 | .enum_simple => null, |
| 944 | .enum_numbered => ty.castTag(.enum_numbered).?.data.values, |
| 945 | else => unreachable, |
| 946 | }; |
| 947 | const target_endian = self.target.cpu.arch.endian(); |
| 948 | for (fields.keys()) |field_name, field_i| { |
| 949 | // DW.AT.enumerator |
| 950 | try dbg_info_buffer.ensureUnusedCapacity(field_name.len + 2 + @sizeOf(u64)); |
| 951 | dbg_info_buffer.appendAssumeCapacity(abbrev_enum_variant); |
| 952 | // DW.AT.name, DW.FORM.string |
| 953 | dbg_info_buffer.appendSliceAssumeCapacity(field_name); |
| 954 | dbg_info_buffer.appendAssumeCapacity(0); |
| 955 | // DW.AT.const_value, DW.FORM.data8 |
| 956 | const value: u64 = if (values) |vals| value: { |
| 957 | if (vals.count() == 0) break :value @intCast(u64, field_i); // auto-numbered |
| 958 | const value = vals.keys()[field_i]; |
| 959 | var int_buffer: Value.Payload.U64 = undefined; |
| 960 | break :value value.enumToInt(ty, &int_buffer).toUnsignedInt(target); |
| 961 | } else @intCast(u64, field_i); |
| 962 | mem.writeInt(u64, dbg_info_buffer.addManyAsArrayAssumeCapacity(8), value, target_endian); |
| 963 | } |
| 964 | |
| 965 | // DW.AT.enumeration_type delimit children |
| 966 | try dbg_info_buffer.append(0); |
| 967 | }, |
| 921 | 968 | else => { |
| 922 | 969 | log.debug("TODO implement .debug_info for type '{}'", .{ty.fmtDebug()}); |
| 923 | 970 | try dbg_info_buffer.append(abbrev_pad1); |
| ... | ... | @@ -1006,6 +1053,24 @@ pub fn writeDbgAbbrev(self: *Dwarf, file: *File) !void { |
| 1006 | 1053 | DW.FORM.sdata, |
| 1007 | 1054 | 0, |
| 1008 | 1055 | 0, // table sentinel |
| 1056 | abbrev_enum_type, |
| 1057 | DW.TAG.enumeration_type, |
| 1058 | DW.CHILDREN.yes, // header |
| 1059 | DW.AT.byte_size, |
| 1060 | DW.FORM.sdata, |
| 1061 | DW.AT.name, |
| 1062 | DW.FORM.string, |
| 1063 | 0, |
| 1064 | 0, // table sentinel |
| 1065 | abbrev_enum_variant, |
| 1066 | DW.TAG.enumerator, |
| 1067 | DW.CHILDREN.no, // header |
| 1068 | DW.AT.name, |
| 1069 | DW.FORM.string, |
| 1070 | DW.AT.const_value, |
| 1071 | DW.FORM.data8, |
| 1072 | 0, |
| 1073 | 0, // table sentinel |
| 1009 | 1074 | abbrev_pad1, |
| 1010 | 1075 | DW.TAG.unspecified_type, |
| 1011 | 1076 | DW.CHILDREN.no, // header |