| ... | @@ -286,7 +286,11 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: std.Progre | ... | @@ -286,7 +286,11 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: std.Progre |
| 286 | .owner = undefined, | 286 | .owner = undefined, |
| 287 | }; | 287 | }; |
| 288 | }; | 288 | }; |
| 289 | var files = [_]Compilation.CSourceFile{ start_o, abi_note_o }; | 289 | const init_o: Compilation.CSourceFile = .{ |
| | 290 | .src_path = try lib_path(comp, arena, lib_libc_glibc ++ "csu" ++ path.sep_str ++ "init.c"), |
| | 291 | .owner = undefined, |
| | 292 | }; |
| | 293 | var files = [_]Compilation.CSourceFile{ start_o, abi_note_o, init_o }; |
| 290 | return comp.build_crt_file("Scrt1", .Obj, .@"glibc Scrt1.o", prog_node, &files); | 294 | return comp.build_crt_file("Scrt1", .Obj, .@"glibc Scrt1.o", prog_node, &files); |
| 291 | }, | 295 | }, |
| 292 | .libc_nonshared_a => { | 296 | .libc_nonshared_a => { |
| ... | @@ -682,6 +686,12 @@ pub const BuiltSharedObjects = struct { | ... | @@ -682,6 +686,12 @@ pub const BuiltSharedObjects = struct { |
| 682 | | 686 | |
| 683 | const all_map_basename = "all.map"; | 687 | const all_map_basename = "all.map"; |
| 684 | | 688 | |
| | 689 | fn wordDirective(target: std.Target) []const u8 { |
| | 690 | // Based on its description in the GNU `as` manual, you might assume that `.word` is sized |
| | 691 | // according to the target word size. But no; that would just make too much sense. |
| | 692 | return if (target.ptrBitWidth() == 64) ".quad" else ".long"; |
| | 693 | } |
| | 694 | |
| 685 | pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) !void { | 695 | pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) !void { |
| 686 | const tracy = trace(@src()); | 696 | const tracy = trace(@src()); |
| 687 | defer tracy.end(); | 697 | defer tracy.end(); |
| ... | @@ -923,6 +933,31 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) !voi | ... | @@ -923,6 +933,31 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) !voi |
| 923 | | 933 | |
| 924 | try stubs_asm.appendSlice(".data\n"); | 934 | try stubs_asm.appendSlice(".data\n"); |
| 925 | | 935 | |
| | 936 | // For some targets, the real `libc.so.6` will contain a weak reference to `_IO_stdin_used`, |
| | 937 | // making the linker put the symbol in the dynamic symbol table. We likewise need to emit a |
| | 938 | // reference to it here for that effect, or it will not show up, which in turn will cause |
| | 939 | // the real glibc to think that the program was built against an ancient `FILE` structure |
| | 940 | // (pre-glibc 2.1). |
| | 941 | // |
| | 942 | // Note that glibc only compiles in the legacy compatibility code for some targets; it |
| | 943 | // depends on what is defined in the `shlib-versions` file for the particular architecture |
| | 944 | // and ABI. Those files are preprocessed by 2 separate tools during the glibc build to get |
| | 945 | // the final `abi-versions.h`, so it would be quite brittle to try to condition our emission |
| | 946 | // of the `_IO_stdin_used` reference in the exact same way. The only downside of emitting |
| | 947 | // the reference unconditionally is that it ends up being unused for newer targets; it |
| | 948 | // otherwise has no negative effect. |
| | 949 | // |
| | 950 | // glibc uses a weak reference because it has to work with programs compiled against pre-2.1 |
| | 951 | // versions where the symbol didn't exist. We only care about modern glibc versions, so use |
| | 952 | // a strong reference. |
| | 953 | if (std.mem.eql(u8, lib.name, "c")) { |
| | 954 | try stubs_asm.writer().print( |
| | 955 | \\.globl _IO_stdin_used |
| | 956 | \\{s} _IO_stdin_used |
| | 957 | \\ |
| | 958 | , .{wordDirective(target)}); |
| | 959 | } |
| | 960 | |
| 926 | const obj_inclusions_len = mem.readInt(u16, metadata.inclusions[inc_i..][0..2], .little); | 961 | const obj_inclusions_len = mem.readInt(u16, metadata.inclusions[inc_i..][0..2], .little); |
| 927 | inc_i += 2; | 962 | inc_i += 2; |
| 928 | | 963 | |