| ... | @@ -321,7 +321,8 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*Elf { | ... | @@ -321,7 +321,8 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*Elf { |
| 321 | .sparc64 => 0x2000, | 321 | .sparc64 => 0x2000, |
| 322 | else => 0x1000, | 322 | else => 0x1000, |
| 323 | }; | 323 | }; |
| 324 | const default_sym_version: elf.Elf64_Versym = if (options.output_mode == .Lib and options.link_mode == .Dynamic) | 324 | const is_dyn_lib = options.output_mode == .Lib and options.link_mode == .Dynamic; |
| | 325 | const default_sym_version: elf.Elf64_Versym = if (is_dyn_lib or options.rdynamic) |
| 325 | elf.VER_NDX_GLOBAL | 326 | elf.VER_NDX_GLOBAL |
| 326 | else | 327 | else |
| 327 | elf.VER_NDX_LOCAL; | 328 | elf.VER_NDX_LOCAL; |
| ... | @@ -1155,6 +1156,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node | ... | @@ -1155,6 +1156,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1155 | break :blk path; | 1156 | break :blk path; |
| 1156 | } | 1157 | } |
| 1157 | } else null; | 1158 | } else null; |
| | 1159 | const gc_sections = self.base.options.gc_sections orelse false; |
| 1158 | | 1160 | |
| 1159 | if (self.base.options.output_mode == .Obj and self.zig_module_index == null) { | 1161 | if (self.base.options.output_mode == .Obj and self.zig_module_index == null) { |
| 1160 | // TODO this will become -r route I guess. For now, just copy the object file. | 1162 | // TODO this will become -r route I guess. For now, just copy the object file. |
| ... | @@ -1181,11 +1183,261 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node | ... | @@ -1181,11 +1183,261 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1181 | return; | 1183 | return; |
| 1182 | } | 1184 | } |
| 1183 | | 1185 | |
| | 1186 | var csu = try CsuObjects.init(arena, self.base.options, comp); |
| | 1187 | const compiler_rt_path: ?[]const u8 = blk: { |
| | 1188 | if (comp.compiler_rt_lib) |x| break :blk x.full_object_path; |
| | 1189 | if (comp.compiler_rt_obj) |x| break :blk x.full_object_path; |
| | 1190 | break :blk null; |
| | 1191 | }; |
| | 1192 | |
| | 1193 | // --verbose-link |
| | 1194 | if (self.base.options.verbose_link) { |
| | 1195 | var argv = std.ArrayList([]const u8).init(arena); |
| | 1196 | |
| | 1197 | try argv.append("zig"); |
| | 1198 | try argv.append("ld"); |
| | 1199 | |
| | 1200 | try argv.append("-o"); |
| | 1201 | try argv.append(full_out_path); |
| | 1202 | |
| | 1203 | if (self.base.options.entry) |entry| { |
| | 1204 | try argv.append("--entry"); |
| | 1205 | try argv.append(entry); |
| | 1206 | } |
| | 1207 | |
| | 1208 | if (self.base.options.dynamic_linker) |path| { |
| | 1209 | try argv.append("-dynamic-linker"); |
| | 1210 | try argv.append(path); |
| | 1211 | } |
| | 1212 | |
| | 1213 | if (self.base.options.soname) |name| { |
| | 1214 | try argv.append("-soname"); |
| | 1215 | try argv.append(name); |
| | 1216 | } |
| | 1217 | |
| | 1218 | for (self.base.options.rpath_list) |rpath| { |
| | 1219 | try argv.append("-rpath"); |
| | 1220 | try argv.append(rpath); |
| | 1221 | } |
| | 1222 | |
| | 1223 | if (self.base.options.each_lib_rpath) { |
| | 1224 | for (self.base.options.lib_dirs) |lib_dir_path| { |
| | 1225 | try argv.append("-rpath"); |
| | 1226 | try argv.append(lib_dir_path); |
| | 1227 | } |
| | 1228 | for (self.base.options.objects) |obj| { |
| | 1229 | if (Compilation.classifyFileExt(obj.path) == .shared_library) { |
| | 1230 | const lib_dir_path = std.fs.path.dirname(obj.path) orelse continue; |
| | 1231 | if (obj.loption) continue; |
| | 1232 | |
| | 1233 | try argv.append("-rpath"); |
| | 1234 | try argv.append(lib_dir_path); |
| | 1235 | } |
| | 1236 | } |
| | 1237 | } |
| | 1238 | |
| | 1239 | if (self.base.options.stack_size_override) |ss| { |
| | 1240 | try argv.append("-z"); |
| | 1241 | try argv.append(try std.fmt.allocPrint(arena, "stack-size={d}", .{ss})); |
| | 1242 | } |
| | 1243 | |
| | 1244 | if (self.base.options.image_base_override) |image_base| { |
| | 1245 | try argv.append(try std.fmt.allocPrint(arena, "--image-base={d}", .{image_base})); |
| | 1246 | } |
| | 1247 | |
| | 1248 | if (gc_sections) { |
| | 1249 | try argv.append("--gc-sections"); |
| | 1250 | } |
| | 1251 | |
| | 1252 | if (self.base.options.print_gc_sections) { |
| | 1253 | try argv.append("--print-gc-sections"); |
| | 1254 | } |
| | 1255 | |
| | 1256 | if (self.base.options.eh_frame_hdr) { |
| | 1257 | try argv.append("--eh-frame-hdr"); |
| | 1258 | } |
| | 1259 | |
| | 1260 | if (self.base.options.rdynamic) { |
| | 1261 | try argv.append("--export-dynamic"); |
| | 1262 | } |
| | 1263 | |
| | 1264 | if (self.base.options.strip) { |
| | 1265 | try argv.append("-s"); |
| | 1266 | } |
| | 1267 | |
| | 1268 | if (self.base.options.z_notext) { |
| | 1269 | try argv.append("-z"); |
| | 1270 | try argv.append("notext"); |
| | 1271 | } |
| | 1272 | |
| | 1273 | if (self.base.options.z_nocopyreloc) { |
| | 1274 | try argv.append("-z"); |
| | 1275 | try argv.append("nocopyreloc"); |
| | 1276 | } |
| | 1277 | |
| | 1278 | if (self.base.options.z_now) { |
| | 1279 | try argv.append("-z"); |
| | 1280 | try argv.append("now"); |
| | 1281 | } |
| | 1282 | |
| | 1283 | if (self.isStatic()) { |
| | 1284 | try argv.append("-static"); |
| | 1285 | } else if (self.isDynLib()) { |
| | 1286 | try argv.append("-shared"); |
| | 1287 | } |
| | 1288 | |
| | 1289 | if (self.base.options.pie and self.isExe()) { |
| | 1290 | try argv.append("-pie"); |
| | 1291 | } |
| | 1292 | |
| | 1293 | // csu prelude |
| | 1294 | if (csu.crt0) |v| try argv.append(v); |
| | 1295 | if (csu.crti) |v| try argv.append(v); |
| | 1296 | if (csu.crtbegin) |v| try argv.append(v); |
| | 1297 | |
| | 1298 | for (self.base.options.lib_dirs) |lib_dir| { |
| | 1299 | try argv.append("-L"); |
| | 1300 | try argv.append(lib_dir); |
| | 1301 | } |
| | 1302 | |
| | 1303 | if (self.base.options.link_libc) { |
| | 1304 | if (self.base.options.libc_installation) |libc_installation| { |
| | 1305 | try argv.append("-L"); |
| | 1306 | try argv.append(libc_installation.crt_dir.?); |
| | 1307 | } |
| | 1308 | } |
| | 1309 | |
| | 1310 | var whole_archive = false; |
| | 1311 | for (self.base.options.objects) |obj| { |
| | 1312 | if (obj.must_link and !whole_archive) { |
| | 1313 | try argv.append("-whole-archive"); |
| | 1314 | whole_archive = true; |
| | 1315 | } else if (!obj.must_link and whole_archive) { |
| | 1316 | try argv.append("-no-whole-archive"); |
| | 1317 | whole_archive = false; |
| | 1318 | } |
| | 1319 | |
| | 1320 | if (obj.loption) { |
| | 1321 | assert(obj.path[0] == ':'); |
| | 1322 | try argv.append("-l"); |
| | 1323 | } |
| | 1324 | try argv.append(obj.path); |
| | 1325 | } |
| | 1326 | if (whole_archive) { |
| | 1327 | try argv.append("-no-whole-archive"); |
| | 1328 | whole_archive = false; |
| | 1329 | } |
| | 1330 | |
| | 1331 | for (comp.c_object_table.keys()) |key| { |
| | 1332 | try argv.append(key.status.success.object_path); |
| | 1333 | } |
| | 1334 | |
| | 1335 | if (module_obj_path) |p| { |
| | 1336 | try argv.append(p); |
| | 1337 | } |
| | 1338 | |
| | 1339 | // TSAN |
| | 1340 | if (self.base.options.tsan) { |
| | 1341 | try argv.append(comp.tsan_static_lib.?.full_object_path); |
| | 1342 | } |
| | 1343 | |
| | 1344 | // libc |
| | 1345 | if (!self.base.options.skip_linker_dependencies and |
| | 1346 | !self.base.options.link_libc) |
| | 1347 | { |
| | 1348 | if (comp.libc_static_lib) |lib| { |
| | 1349 | try argv.append(lib.full_object_path); |
| | 1350 | } |
| | 1351 | } |
| | 1352 | |
| | 1353 | // stack-protector. |
| | 1354 | // Related: https://github.com/ziglang/zig/issues/7265 |
| | 1355 | if (comp.libssp_static_lib) |ssp| { |
| | 1356 | try argv.append(ssp.full_object_path); |
| | 1357 | } |
| | 1358 | |
| | 1359 | // Shared libraries. |
| | 1360 | // Worst-case, we need an --as-needed argument for every lib, as well |
| | 1361 | // as one before and one after. |
| | 1362 | try argv.ensureUnusedCapacity(self.base.options.system_libs.keys().len * 2 + 2); |
| | 1363 | argv.appendAssumeCapacity("--as-needed"); |
| | 1364 | var as_needed = true; |
| | 1365 | |
| | 1366 | for (self.base.options.system_libs.values()) |lib_info| { |
| | 1367 | const lib_as_needed = !lib_info.needed; |
| | 1368 | switch ((@as(u2, @intFromBool(lib_as_needed)) << 1) | @intFromBool(as_needed)) { |
| | 1369 | 0b00, 0b11 => {}, |
| | 1370 | 0b01 => { |
| | 1371 | argv.appendAssumeCapacity("--no-as-needed"); |
| | 1372 | as_needed = false; |
| | 1373 | }, |
| | 1374 | 0b10 => { |
| | 1375 | argv.appendAssumeCapacity("--as-needed"); |
| | 1376 | as_needed = true; |
| | 1377 | }, |
| | 1378 | } |
| | 1379 | argv.appendAssumeCapacity(lib_info.path.?); |
| | 1380 | } |
| | 1381 | |
| | 1382 | if (!as_needed) { |
| | 1383 | argv.appendAssumeCapacity("--as-needed"); |
| | 1384 | as_needed = true; |
| | 1385 | } |
| | 1386 | |
| | 1387 | // libc++ dep |
| | 1388 | if (self.base.options.link_libcpp) { |
| | 1389 | try argv.append(comp.libcxxabi_static_lib.?.full_object_path); |
| | 1390 | try argv.append(comp.libcxx_static_lib.?.full_object_path); |
| | 1391 | } |
| | 1392 | |
| | 1393 | // libunwind dep |
| | 1394 | if (self.base.options.link_libunwind) { |
| | 1395 | try argv.append(comp.libunwind_static_lib.?.full_object_path); |
| | 1396 | } |
| | 1397 | |
| | 1398 | // libc dep |
| | 1399 | if (self.base.options.link_libc) { |
| | 1400 | if (self.base.options.libc_installation != null) { |
| | 1401 | const needs_grouping = self.base.options.link_mode == .Static; |
| | 1402 | if (needs_grouping) try argv.append("--start-group"); |
| | 1403 | try argv.appendSlice(target_util.libcFullLinkFlags(target)); |
| | 1404 | if (needs_grouping) try argv.append("--end-group"); |
| | 1405 | } else if (target.isGnuLibC()) { |
| | 1406 | for (glibc.libs) |lib| { |
| | 1407 | const lib_path = try std.fmt.allocPrint(arena, "{s}{c}lib{s}.so.{d}", .{ |
| | 1408 | comp.glibc_so_files.?.dir_path, fs.path.sep, lib.name, lib.sover, |
| | 1409 | }); |
| | 1410 | try argv.append(lib_path); |
| | 1411 | } |
| | 1412 | try argv.append(try comp.get_libc_crt_file(arena, "libc_nonshared.a")); |
| | 1413 | } else if (target.isMusl()) { |
| | 1414 | try argv.append(try comp.get_libc_crt_file(arena, switch (self.base.options.link_mode) { |
| | 1415 | .Static => "libc.a", |
| | 1416 | .Dynamic => "libc.so", |
| | 1417 | })); |
| | 1418 | } |
| | 1419 | } |
| | 1420 | |
| | 1421 | // compiler-rt |
| | 1422 | if (compiler_rt_path) |p| { |
| | 1423 | try argv.append(p); |
| | 1424 | } |
| | 1425 | |
| | 1426 | // crt postlude |
| | 1427 | if (csu.crtend) |v| try argv.append(v); |
| | 1428 | if (csu.crtn) |v| try argv.append(v); |
| | 1429 | |
| | 1430 | Compilation.dump_argv(argv.items); |
| | 1431 | } |
| | 1432 | |
| 1184 | // Here we will parse input positional and library files (if referenced). | 1433 | // Here we will parse input positional and library files (if referenced). |
| 1185 | // This will roughly match in any linker backend we support. | 1434 | // This will roughly match in any linker backend we support. |
| 1186 | var positionals = std.ArrayList(Compilation.LinkObject).init(arena); | 1435 | var positionals = std.ArrayList(Compilation.LinkObject).init(arena); |
| 1187 | | 1436 | |
| 1188 | if (module_obj_path) |path| try positionals.append(.{ .path = path }); | 1437 | // csu prelude |
| | 1438 | if (csu.crt0) |v| try positionals.append(.{ .path = v }); |
| | 1439 | if (csu.crti) |v| try positionals.append(.{ .path = v }); |
| | 1440 | if (csu.crtbegin) |v| try positionals.append(.{ .path = v }); |
| 1189 | | 1441 | |
| 1190 | try positionals.ensureUnusedCapacity(self.base.options.objects.len); | 1442 | try positionals.ensureUnusedCapacity(self.base.options.objects.len); |
| 1191 | positionals.appendSliceAssumeCapacity(self.base.options.objects); | 1443 | positionals.appendSliceAssumeCapacity(self.base.options.objects); |
| ... | @@ -1197,11 +1449,60 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node | ... | @@ -1197,11 +1449,60 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1197 | try positionals.append(.{ .path = key.status.success.object_path }); | 1449 | try positionals.append(.{ .path = key.status.success.object_path }); |
| 1198 | } | 1450 | } |
| 1199 | | 1451 | |
| 1200 | // csu prelude | 1452 | if (module_obj_path) |path| try positionals.append(.{ .path = path }); |
| 1201 | var csu = try CsuObjects.init(arena, self.base.options, comp); | 1453 | |
| 1202 | if (csu.crt0) |v| try positionals.append(.{ .path = v }); | 1454 | // rpaths |
| 1203 | if (csu.crti) |v| try positionals.append(.{ .path = v }); | 1455 | var rpath_table = std.StringArrayHashMap(void).init(self.base.allocator); |
| 1204 | if (csu.crtbegin) |v| try positionals.append(.{ .path = v }); | 1456 | defer rpath_table.deinit(); |
| | 1457 | for (self.base.options.rpath_list) |rpath| { |
| | 1458 | _ = try rpath_table.put(rpath, {}); |
| | 1459 | } |
| | 1460 | |
| | 1461 | if (self.base.options.each_lib_rpath) { |
| | 1462 | var test_path = std.ArrayList(u8).init(self.base.allocator); |
| | 1463 | defer test_path.deinit(); |
| | 1464 | for (self.base.options.lib_dirs) |lib_dir_path| { |
| | 1465 | for (self.base.options.system_libs.keys()) |link_lib| { |
| | 1466 | test_path.clearRetainingCapacity(); |
| | 1467 | const sep = fs.path.sep_str; |
| | 1468 | try test_path.writer().print("{s}" ++ sep ++ "lib{s}.so", .{ |
| | 1469 | lib_dir_path, link_lib, |
| | 1470 | }); |
| | 1471 | fs.cwd().access(test_path.items, .{}) catch |err| switch (err) { |
| | 1472 | error.FileNotFound => continue, |
| | 1473 | else => |e| return e, |
| | 1474 | }; |
| | 1475 | _ = try rpath_table.put(lib_dir_path, {}); |
| | 1476 | } |
| | 1477 | } |
| | 1478 | for (self.base.options.objects) |obj| { |
| | 1479 | if (Compilation.classifyFileExt(obj.path) == .shared_library) { |
| | 1480 | const lib_dir_path = std.fs.path.dirname(obj.path) orelse continue; |
| | 1481 | if (obj.loption) continue; |
| | 1482 | _ = try rpath_table.put(lib_dir_path, {}); |
| | 1483 | } |
| | 1484 | } |
| | 1485 | } |
| | 1486 | |
| | 1487 | // TSAN |
| | 1488 | if (self.base.options.tsan) { |
| | 1489 | try positionals.append(.{ .path = comp.tsan_static_lib.?.full_object_path }); |
| | 1490 | } |
| | 1491 | |
| | 1492 | // libc |
| | 1493 | if (!self.base.options.skip_linker_dependencies and |
| | 1494 | !self.base.options.link_libc) |
| | 1495 | { |
| | 1496 | if (comp.libc_static_lib) |lib| { |
| | 1497 | try positionals.append(.{ .path = lib.full_object_path }); |
| | 1498 | } |
| | 1499 | } |
| | 1500 | |
| | 1501 | // stack-protector. |
| | 1502 | // Related: https://github.com/ziglang/zig/issues/7265 |
| | 1503 | if (comp.libssp_static_lib) |ssp| { |
| | 1504 | try positionals.append(.{ .path = ssp.full_object_path }); |
| | 1505 | } |
| 1205 | | 1506 | |
| 1206 | for (positionals.items) |obj| { | 1507 | for (positionals.items) |obj| { |
| 1207 | const in_file = try std.fs.cwd().openFile(obj.path, .{}); | 1508 | const in_file = try std.fs.cwd().openFile(obj.path, .{}); |
| ... | @@ -1213,6 +1514,11 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node | ... | @@ -1213,6 +1514,11 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1213 | | 1514 | |
| 1214 | var system_libs = std.ArrayList(SystemLib).init(arena); | 1515 | var system_libs = std.ArrayList(SystemLib).init(arena); |
| 1215 | | 1516 | |
| | 1517 | try system_libs.ensureUnusedCapacity(self.base.options.system_libs.values().len); |
| | 1518 | for (self.base.options.system_libs.values()) |lib_info| { |
| | 1519 | system_libs.appendAssumeCapacity(.{ .needed = lib_info.needed, .path = lib_info.path.? }); |
| | 1520 | } |
| | 1521 | |
| 1216 | // libc++ dep | 1522 | // libc++ dep |
| 1217 | if (self.base.options.link_libcpp) { | 1523 | if (self.base.options.link_libcpp) { |
| 1218 | try system_libs.ensureUnusedCapacity(2); | 1524 | try system_libs.ensureUnusedCapacity(2); |
| ... | @@ -1266,11 +1572,6 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node | ... | @@ -1266,11 +1572,6 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1266 | // compiler-rt. Since compiler_rt exports symbols like `memset`, it needs | 1572 | // compiler-rt. Since compiler_rt exports symbols like `memset`, it needs |
| 1267 | // to be after the shared libraries, so they are picked up from the shared | 1573 | // to be after the shared libraries, so they are picked up from the shared |
| 1268 | // libraries, not libcompiler_rt. | 1574 | // libraries, not libcompiler_rt. |
| 1269 | const compiler_rt_path: ?[]const u8 = blk: { | | |
| 1270 | if (comp.compiler_rt_lib) |x| break :blk x.full_object_path; | | |
| 1271 | if (comp.compiler_rt_obj) |x| break :blk x.full_object_path; | | |
| 1272 | break :blk null; | | |
| 1273 | }; | | |
| 1274 | if (compiler_rt_path) |path| try positionals.append(.{ .path = path }); | 1575 | if (compiler_rt_path) |path| try positionals.append(.{ .path = path }); |
| 1275 | | 1576 | |
| 1276 | // csu postlude | 1577 | // csu postlude |
| ... | @@ -1363,13 +1664,12 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node | ... | @@ -1363,13 +1664,12 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1363 | self.entry_index = if (entry) |name| self.globalByName(name) else null; | 1664 | self.entry_index = if (entry) |name| self.globalByName(name) else null; |
| 1364 | } | 1665 | } |
| 1365 | | 1666 | |
| 1366 | const gc_sections = self.base.options.gc_sections orelse false; | | |
| 1367 | if (gc_sections) { | 1667 | if (gc_sections) { |
| 1368 | try gc.gcAtoms(self); | 1668 | try gc.gcAtoms(self); |
| 1369 | | 1669 | |
| 1370 | // if (self.base.options.print_gc_sections) { | 1670 | if (self.base.options.print_gc_sections) { |
| 1371 | // try gc.dumpPrunedAtoms(self); | 1671 | try gc.dumpPrunedAtoms(self); |
| 1372 | // } | 1672 | } |
| 1373 | } | 1673 | } |
| 1374 | | 1674 | |
| 1375 | try self.addLinkerDefinedSymbols(); | 1675 | try self.addLinkerDefinedSymbols(); |
| ... | @@ -1385,7 +1685,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node | ... | @@ -1385,7 +1685,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1385 | try self.file(index).?.object.addAtomsToOutputSections(self); | 1685 | try self.file(index).?.object.addAtomsToOutputSections(self); |
| 1386 | } | 1686 | } |
| 1387 | try self.sortInitFini(); | 1687 | try self.sortInitFini(); |
| 1388 | try self.setDynamicSection(); | 1688 | try self.setDynamicSection(rpath_table.keys()); |
| 1389 | self.sortDynamicSymtab(); | 1689 | self.sortDynamicSymtab(); |
| 1390 | try self.setHashSections(); | 1690 | try self.setHashSections(); |
| 1391 | try self.setVersionSymtab(); | 1691 | try self.setVersionSymtab(); |
| ... | @@ -3879,7 +4179,7 @@ fn sortInitFini(self: *Elf) !void { | ... | @@ -3879,7 +4179,7 @@ fn sortInitFini(self: *Elf) !void { |
| 3879 | } | 4179 | } |
| 3880 | } | 4180 | } |
| 3881 | | 4181 | |
| 3882 | fn setDynamicSection(self: *Elf) !void { | 4182 | fn setDynamicSection(self: *Elf, rpaths: []const []const u8) !void { |
| 3883 | if (self.dynamic_section_index == null) return; | 4183 | if (self.dynamic_section_index == null) return; |
| 3884 | | 4184 | |
| 3885 | for (self.shared_objects.items) |index| { | 4185 | for (self.shared_objects.items) |index| { |
| ... | @@ -3892,7 +4192,7 @@ fn setDynamicSection(self: *Elf) !void { | ... | @@ -3892,7 +4192,7 @@ fn setDynamicSection(self: *Elf) !void { |
| 3892 | try self.dynamic.setSoname(soname, self); | 4192 | try self.dynamic.setSoname(soname, self); |
| 3893 | } | 4193 | } |
| 3894 | | 4194 | |
| 3895 | try self.dynamic.setRpath(self.base.options.rpath_list, self); | 4195 | try self.dynamic.setRpath(rpaths, self); |
| 3896 | } | 4196 | } |
| 3897 | | 4197 | |
| 3898 | fn sortDynamicSymtab(self: *Elf) void { | 4198 | fn sortDynamicSymtab(self: *Elf) void { |
| ... | @@ -5153,6 +5453,10 @@ pub fn isStatic(self: Elf) bool { | ... | @@ -5153,6 +5453,10 @@ pub fn isStatic(self: Elf) bool { |
| 5153 | return self.base.options.link_mode == .Static; | 5453 | return self.base.options.link_mode == .Static; |
| 5154 | } | 5454 | } |
| 5155 | | 5455 | |
| | 5456 | pub fn isExe(self: Elf) bool { |
| | 5457 | return self.base.options.effectiveOutputMode() == .Exe; |
| | 5458 | } |
| | 5459 | |
| 5156 | pub fn isDynLib(self: Elf) bool { | 5460 | pub fn isDynLib(self: Elf) bool { |
| 5157 | return self.base.options.effectiveOutputMode() == .Lib and self.base.options.link_mode == .Dynamic; | 5461 | return self.base.options.effectiveOutputMode() == .Lib and self.base.options.link_mode == .Dynamic; |
| 5158 | } | 5462 | } |