)]}'
{
  "commit": "fb591bc876354b939ef767887e772c15f679a283",
  "tree": "9e5c52a39cfd69ce8d3d6c716a2acde45103b15d",
  "parents": [
    "0e49854a6799407b8a4e8f197a9af8fc46283e93"
  ],
  "author": {
    "name": "Joseph Gette",
    "email": "joseph.gette@datadoghq.com",
    "time": "Thu Oct 22 21:31:07 2026 +0200"
  },
  "committer": {
    "name": "GitHub",
    "email": "noreply@github.com",
    "time": "Thu Oct 22 21:31:07 2026 +0200"
  },
  "message": "link: stream the binary when setting content build IDs (#4764)\n\n**What type of PR is this?**\n\nOther\n\n**What does this PR do? Why is it needed?**\n\nFollow-up to #4728. `setContentBuildID` read the whole linked binary\ninto\nmemory, which can be prohibitive for large Go binaries. It now streams:\n\n- The binary is hashed with `io.Copy` into sha256.\n- ELF binaries are parsed with `elf.NewFile` over the open file. The\nplaceholder\ncheck is a `ReadAt` of the build ID note, and a read error is returned\ninstead\n  of being treated as \"no placeholder\".\n- Mach-O binaries are parsed with `macho.NewFile` over the open file.\nThe Go\nbuild ID is found by a chunked search (`indexReader`, 1 MiB buffer that\nkeeps\nthe last `len(pattern)-1` bytes between reads) instead of `bytes.Index`\nover\n  the whole file.\n\nPeak memory no longer scales with the binary size. On a ~500 MB padded\nELF, peak\nRSS of `setContentBuildID` went from 508 MB to 4.8 MB. The output is\nunchanged:\nELF (linux/amd64, linux/arm64) and Mach-O (darwin/arm64) binaries are\nbyte-identical to those produced before this change.\n\n`indexReader` is covered by a new unit test that places the match around\nthe\nbuffer boundary and reads in full and half chunks. The ELF path is\ncovered by\nthe existing `//tests/core/go_binary:buildid_test`, and the Mach-O path\nby\n`buildid_darwin_test`.\n\n**Which issues(s) does this PR fix?**\n\nN/A, follow-up to #4728.\n\n**Other notes for review**\n\n- Mach-O binaries are now read three times: once to hash, once to search\nfor the\nbuild ID, and once in `machoCodeSign`. Memory use is constant, and the\nextra\npasses hit the OS file cache. Searching while hashing would make it one\npass,\n  but it is not worth the added complexity.\n- `buildid_test` in `tests/core/go_binary` is Linux-only, so I could\nonly check\n  the ELF path locally by comparing the output of the old and new\n  `setContentBuildID` on the same binaries.\n- The two commits are independent: ELF and hashing first, Mach-O search\nand its\n  unit test second.",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "e78b556169c53c94e4c2f88eab662ddd38adca35",
      "old_mode": 33188,
      "old_path": "go/tools/builders/buildid.go",
      "new_id": "54230325a6b6429ff9e257763c1934f7ce640b2e",
      "new_mode": 33188,
      "new_path": "go/tools/builders/buildid.go"
    }
  ]
}
