| ... | ... | @@ -11,6 +11,7 @@ pub fn testAll(b: *std.Build) *Step { |
| 11 | 11 | macho_step.dependOn(testDeadStrip(b, .{ .target = default_target })); |
| 12 | 12 | macho_step.dependOn(testEntryPointDylib(b, .{ .target = default_target })); |
| 13 | 13 | macho_step.dependOn(testSectionBoundarySymbols(b, .{ .target = default_target })); |
| 14 | macho_step.dependOn(testSegmentBoundarySymbols(b, .{ .target = default_target })); |
| 14 | 15 | |
| 15 | 16 | return macho_step; |
| 16 | 17 | } |
| ... | ... | @@ -230,6 +231,74 @@ fn testSectionBoundarySymbols(b: *std.Build, opts: Options) *Step { |
| 230 | 231 | return test_step; |
| 231 | 232 | } |
| 232 | 233 | |
| 234 | fn testSegmentBoundarySymbols(b: *std.Build, opts: Options) *Step { |
| 235 | const test_step = addTestStep(b, "macho-segment-boundary-symbols", opts); |
| 236 | |
| 237 | const obj1 = addObject(b, opts, .{ .name = "a", .cpp_source_bytes = |
| 238 | \\constexpr const char* MESSAGE __attribute__((used, section("__DATA_CONST_1,__message_ptr"))) = "codebase"; |
| 239 | }); |
| 240 | |
| 241 | const main_o = addObject(b, opts, .{ .name = "main", .c_source_bytes = |
| 242 | \\#include <stdio.h> |
| 243 | \\const char* interop(); |
| 244 | \\int main() { |
| 245 | \\ printf("All your %s are belong to us.\n", interop()); |
| 246 | \\ return 0; |
| 247 | \\} |
| 248 | }); |
| 249 | |
| 250 | { |
| 251 | const obj2 = addObject(b, opts, .{ .name = "b", .cpp_source_bytes = |
| 252 | \\extern const char* message_pointer __asm("segment$start$__DATA_CONST_1"); |
| 253 | \\extern "C" const char* interop() { |
| 254 | \\ return message_pointer; |
| 255 | \\} |
| 256 | }); |
| 257 | |
| 258 | const exe = addExecutable(b, opts, .{ .name = "main" }); |
| 259 | exe.addObject(obj1); |
| 260 | exe.addObject(obj2); |
| 261 | exe.addObject(main_o); |
| 262 | |
| 263 | const run = addRunArtifact(exe); |
| 264 | run.expectStdOutEqual("All your codebase are belong to us.\n"); |
| 265 | test_step.dependOn(&run.step); |
| 266 | |
| 267 | const check = exe.checkObject(); |
| 268 | check.checkInSymtab(); |
| 269 | check.checkNotPresent("external segment$start$__DATA_CONST_1"); |
| 270 | test_step.dependOn(&check.step); |
| 271 | } |
| 272 | |
| 273 | { |
| 274 | const obj2 = addObject(b, opts, .{ .name = "c", .cpp_source_bytes = |
| 275 | \\extern const char* message_pointer __asm("segment$start$__DATA_1"); |
| 276 | \\extern "C" const char* interop() { |
| 277 | \\ return message_pointer; |
| 278 | \\} |
| 279 | }); |
| 280 | |
| 281 | const exe = addExecutable(b, opts, .{ .name = "main2" }); |
| 282 | exe.addObject(obj1); |
| 283 | exe.addObject(obj2); |
| 284 | exe.addObject(main_o); |
| 285 | |
| 286 | const check = exe.checkObject(); |
| 287 | check.checkInHeaders(); |
| 288 | check.checkExact("cmd SEGMENT_64"); |
| 289 | check.checkExact("segname __DATA_1"); |
| 290 | check.checkExtract("vmsize {vmsize}"); |
| 291 | check.checkExtract("filesz {filesz}"); |
| 292 | check.checkComputeCompare("vmsize", .{ .op = .eq, .value = .{ .literal = 0 } }); |
| 293 | check.checkComputeCompare("filesz", .{ .op = .eq, .value = .{ .literal = 0 } }); |
| 294 | check.checkInSymtab(); |
| 295 | check.checkNotPresent("external segment$start$__DATA_1"); |
| 296 | test_step.dependOn(&check.step); |
| 297 | } |
| 298 | |
| 299 | return test_step; |
| 300 | } |
| 301 | |
| 233 | 302 | fn addTestStep(b: *std.Build, comptime prefix: []const u8, opts: Options) *Step { |
| 234 | 303 | return link.addTestStep(b, "macho-" ++ prefix, opts); |
| 235 | 304 | } |