[llvm-objcopy] Delete --build-id-link-{dir,input,output}
authorFangrui Song <i@maskray.me>
Mon, 15 Feb 2021 19:17:32 +0000 (11:17 -0800)
committerFangrui Song <i@maskray.me>
Mon, 15 Feb 2021 19:17:32 +0000 (11:17 -0800)
The few options are niche. They solved a problem which was traditionally solved
with more shell commands (`llvm-readelf -n` fetches the Build ID. Then
`ln` is used to hard link the file to a directory derived from the Build ID.)

Due to limitation, they are no longer used by Fuchsia and they don't appear to
be used elsewhere (checked with Google Search and Debian Code Search). So delete
them without a transition period.

Announcement: https://lists.llvm.org/pipermail/llvm-dev/2021-February/148446.html

Differential Revision: https://reviews.llvm.org/D96310

13 files changed:
llvm/docs/CommandGuide/llvm-objcopy.rst
llvm/docs/ReleaseNotes.rst
llvm/test/tools/llvm-objcopy/ELF/bad-build-id.test [deleted file]
llvm/test/tools/llvm-objcopy/ELF/build-id-link-dir.test [deleted file]
llvm/test/tools/llvm-objcopy/ELF/no-build-id-no-notes.test [deleted file]
llvm/test/tools/llvm-objcopy/ELF/no-build-id.test [deleted file]
llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
llvm/tools/llvm-objcopy/CopyConfig.cpp
llvm/tools/llvm-objcopy/CopyConfig.h
llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp
llvm/tools/llvm-objcopy/ObjcopyOpts.td
llvm/tools/llvm-objcopy/wasm/WasmObjcopy.cpp

index c5cff2e..c4e3b6e 100644 (file)
@@ -285,23 +285,6 @@ them.
  Allow :program:`llvm-objcopy` to remove sections even if it would leave invalid
  section references. Any invalid sh_link fields will be set to zero.
 
-.. option:: --build-id-link-dir <dir>
-
- Set the directory used by :option:`--build-id-link-input` and
- :option:`--build-id-link-output`.
-
-.. option:: --build-id-link-input <suffix>
-
- Hard-link the input to ``<dir>/xx/xxx<suffix>``, where ``<dir>`` is the directory
- specified by :option:`--build-id-link-dir`. The path used is derived from the
- hex build ID.
-
-.. option:: --build-id-link-output <suffix>
-
- Hard-link the output to ``<dir>/xx/xxx<suffix>``, where ``<dir>`` is the directory
- specified by :option:`--build-id-link-dir`. The path used is derived from the
- hex build ID.
-
 .. option:: --change-start <incr>, --adjust-start
 
  Add ``<incr>`` to the program's start address. Can be specified multiple
index 5def448..1de11f0 100644 (file)
@@ -124,6 +124,9 @@ During this release ...
 Changes to the LLVM tools
 ---------------------------------
 
+* The options ``--build-id-link-{dir,input,output}`` have been deleted.
+  (`D96310 <https://reviews.llvm.org/D96310>`_)
+
 Changes to LLDB
 ---------------------------------
 
diff --git a/llvm/test/tools/llvm-objcopy/ELF/bad-build-id.test b/llvm/test/tools/llvm-objcopy/ELF/bad-build-id.test
deleted file mode 100644 (file)
index 0c97fc5..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-# RUN: yaml2obj %s -o %t
-# RUN: not llvm-objcopy --build-id-link-dir=%t-dir --build-id-link-input=.debug %t 2>&1 >/dev/null | FileCheck %s
-
-# CHECK: build ID is smaller than two bytes
-
---- !ELF
-FileHeader:
-  Class:           ELFCLASS64
-  Data:            ELFDATA2LSB
-  Type:            ET_EXEC
-  Machine:         EM_X86_64
-Sections:
-  - Name:            .note.gnu.build-id
-    Type:            SHT_NOTE
-    Flags:           [ SHF_ALLOC ]
-    Content:         040000000100000003000000474E55004F000000
-ProgramHeaders:
-  - Type:     PT_NOTE
-    Flags:    [ PF_R ]
-    FirstSec: .note.gnu.build-id
-    LastSec:  .note.gnu.build-id
diff --git a/llvm/test/tools/llvm-objcopy/ELF/build-id-link-dir.test b/llvm/test/tools/llvm-objcopy/ELF/build-id-link-dir.test
deleted file mode 100644 (file)
index 54c68af..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-# RUN: yaml2obj %s -o %t
-# RUN: rm -fr %t-dir && mkdir %t-dir
-
-# RUN: llvm-objcopy --build-id-link-dir=%t-dir %t %t2
-# RUN: not test -e %t-dir/4f/cb712aa6387724a9f465a32cd8c14b
-
-# RUN: llvm-objcopy --build-id-link-dir=%t-dir --build-id-link-input=.debug %t %t3
-# RUN: cmp %t-dir/4f/cb712aa6387724a9f465a32cd8c14b.debug %t
-# RUN: rm %t-dir/4f/cb712aa6387724a9f465a32cd8c14b.debug
-
-# RUN: llvm-objcopy --build-id-link-dir=%t-dir --build-id-link-output "" --strip-sections %t %t4
-# RUN: cmp %t-dir/4f/cb712aa6387724a9f465a32cd8c14b %t4
-# RUN: rm %t-dir/4f/cb712aa6387724a9f465a32cd8c14b
-
-# Linking the output of an inplace argument means that the file in the build-id
-# directory will be hard-linked to the resulting file.
-# RUN: cp %t %t5
-# RUN: llvm-objcopy --build-id-link-dir=%t-dir --build-id-link-output "" --strip-sections %t5
-# RUN: cmp %t-dir/4f/cb712aa6387724a9f465a32cd8c14b %t5
-# RUN: rm %t-dir/4f/cb712aa6387724a9f465a32cd8c14b
-
-# Linking the input of an inplace argument means that the file in the build-id
-# directory will be hard-linked to the original file.
-# RUN: cp %t %t6
-# RUN: llvm-objcopy --build-id-link-dir=%t-dir --build-id-link-input=.debug --strip-sections %t6
-# RUN: cmp %t-dir/4f/cb712aa6387724a9f465a32cd8c14b.debug %t
-# RUN: rm %t-dir/4f/cb712aa6387724a9f465a32cd8c14b.debug
-
-# You can use both at once.
-# RUN: llvm-objcopy --build-id-link-dir=%t-dir --build-id-link-output "" --build-id-link-input=.debug --strip-sections %t %t7
-# RUN: cmp %t-dir/4f/cb712aa6387724a9f465a32cd8c14b.debug %t
-# RUN: cmp %t-dir/4f/cb712aa6387724a9f465a32cd8c14b %t7
-# RUN: rm %t-dir/4f/cb712aa6387724a9f465a32cd8c14b.debug
-# RUN: rm %t-dir/4f/cb712aa6387724a9f465a32cd8c14b
-
-# --build-id-link-output can have a suffix as well
-# RUN: llvm-objcopy --build-id-link-dir=%t-dir --build-id-link-output=.debug --only-keep-debug %t %t8
-# RUN: cmp %t-dir/4f/cb712aa6387724a9f465a32cd8c14b.debug %t8
-# RUN: rm %t-dir/4f/cb712aa6387724a9f465a32cd8c14b.debug
-
---- !ELF
-FileHeader:
-  Class:           ELFCLASS64
-  Data:            ELFDATA2LSB
-  Type:            ET_EXEC
-  Machine:         EM_X86_64
-Sections:
-  - Name:            .note.gnu.build-id
-    Type:            SHT_NOTE
-    Flags:           [ SHF_ALLOC ]
-    Content:         040000001000000003000000474E55004FCB712AA6387724A9F465A32CD8C14B
-ProgramHeaders:
-  - Type:     PT_NOTE
-    Flags:    [ PF_R ]
-    FirstSec: .note.gnu.build-id
-    LastSec:  .note.gnu.build-id
diff --git a/llvm/test/tools/llvm-objcopy/ELF/no-build-id-no-notes.test b/llvm/test/tools/llvm-objcopy/ELF/no-build-id-no-notes.test
deleted file mode 100644 (file)
index 6c3936d..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-# RUN: yaml2obj %s -o %t
-# RUN: not llvm-objcopy --build-id-link-dir=%t-dir --build-id-link-input=.debug %t 2>&1 >/dev/null | FileCheck %s
-
-# CHECK: could not find build ID
-
---- !ELF
-FileHeader:
-  Class:           ELFCLASS64
-  Data:            ELFDATA2LSB
-  Type:            ET_EXEC
-  Machine:         EM_X86_64
diff --git a/llvm/test/tools/llvm-objcopy/ELF/no-build-id.test b/llvm/test/tools/llvm-objcopy/ELF/no-build-id.test
deleted file mode 100644 (file)
index a75b343..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-# RUN: yaml2obj %s -o %t
-# RUN: not llvm-objcopy --build-id-link-dir=%t-dir --build-id-link-input=.debug %t 2>&1 >/dev/null | FileCheck %s -DINPUT=%t
-
-# CHECK: error: '[[INPUT]]': could not find build ID
-
---- !ELF
-FileHeader:
-  Class:           ELFCLASS64
-  Data:            ELFDATA2LSB
-  Type:            ET_EXEC
-  Machine:         EM_X86_64
-Sections:
-  - Name:            .note.foo
-    Type:            SHT_NOTE
-    Flags:           [ SHF_ALLOC ]
-    Content:         000000000000000000000000
-ProgramHeaders:
-  - Type:     PT_NOTE
-    Flags:    [ PF_R ]
-    FirstSec: .note.foo
-    LastSec:  .note.foo
index b5de8a4..f5f0691 100644 (file)
@@ -249,17 +249,15 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
     if (Error E = addGnuDebugLink(Obj, Config.AddGnuDebugLink))
       return E;
 
-  if (Config.AllowBrokenLinks || !Config.BuildIdLinkDir.empty() ||
-      Config.BuildIdLinkInput || Config.BuildIdLinkOutput ||
-      !Config.SplitDWO.empty() || !Config.SymbolsPrefix.empty() ||
-      !Config.AllocSectionsPrefix.empty() || !Config.DumpSection.empty() ||
-      !Config.KeepSection.empty() || Config.NewSymbolVisibility ||
-      !Config.SymbolsToGlobalize.empty() || !Config.SymbolsToKeep.empty() ||
-      !Config.SymbolsToLocalize.empty() || !Config.SymbolsToWeaken.empty() ||
-      !Config.SymbolsToKeepGlobal.empty() || !Config.SectionsToRename.empty() ||
-      !Config.SetSectionAlignment.empty() || Config.ExtractDWO ||
-      Config.LocalizeHidden || Config.PreserveDates || Config.StripDWO ||
-      Config.StripNonAlloc || Config.StripSections ||
+  if (Config.AllowBrokenLinks || !Config.SplitDWO.empty() ||
+      !Config.SymbolsPrefix.empty() || !Config.AllocSectionsPrefix.empty() ||
+      !Config.DumpSection.empty() || !Config.KeepSection.empty() ||
+      Config.NewSymbolVisibility || !Config.SymbolsToGlobalize.empty() ||
+      !Config.SymbolsToKeep.empty() || !Config.SymbolsToLocalize.empty() ||
+      !Config.SymbolsToWeaken.empty() || !Config.SymbolsToKeepGlobal.empty() ||
+      !Config.SectionsToRename.empty() || !Config.SetSectionAlignment.empty() ||
+      Config.ExtractDWO || Config.LocalizeHidden || Config.PreserveDates ||
+      Config.StripDWO || Config.StripNonAlloc || Config.StripSections ||
       Config.StripSwiftSymbols || Config.Weaken ||
       Config.DecompressDebugSections ||
       Config.DiscardMode == DiscardType::Locals ||
index ba74759..d006c9a 100644 (file)
@@ -607,13 +607,6 @@ parseObjcopyOptions(ArrayRef<const char *> ArgsArr,
     Config.GnuDebugLinkCRC32 =
         llvm::crc32(arrayRefFromStringRef(Debug->getBuffer()));
   }
-  Config.BuildIdLinkDir = InputArgs.getLastArgValue(OBJCOPY_build_id_link_dir);
-  if (InputArgs.hasArg(OBJCOPY_build_id_link_input))
-    Config.BuildIdLinkInput =
-        InputArgs.getLastArgValue(OBJCOPY_build_id_link_input);
-  if (InputArgs.hasArg(OBJCOPY_build_id_link_output))
-    Config.BuildIdLinkOutput =
-        InputArgs.getLastArgValue(OBJCOPY_build_id_link_output);
   Config.SplitDWO = InputArgs.getLastArgValue(OBJCOPY_split_dwo);
   Config.SymbolsPrefix = InputArgs.getLastArgValue(OBJCOPY_prefix_symbols);
   Config.AllocSectionsPrefix =
index 07eac9d..bc996cb 100644 (file)
@@ -163,9 +163,6 @@ struct CopyConfig {
   StringRef AddGnuDebugLink;
   // Cached gnu_debuglink's target CRC
   uint32_t GnuDebugLinkCRC32;
-  StringRef BuildIdLinkDir;
-  Optional<StringRef> BuildIdLinkInput;
-  Optional<StringRef> BuildIdLinkOutput;
   Optional<StringRef> ExtractPartition;
   StringRef SplitDWO;
   StringRef SymbolsPrefix;
index c53a34b..a05b1d4 100644 (file)
@@ -166,43 +166,6 @@ static std::unique_ptr<Writer> createWriter(const CopyConfig &Config,
   }
 }
 
-template <class ELFT>
-static Expected<ArrayRef<uint8_t>>
-findBuildID(const CopyConfig &Config, const object::ELFFile<ELFT> &In) {
-  auto PhdrsOrErr = In.program_headers();
-  if (auto Err = PhdrsOrErr.takeError())
-    return createFileError(Config.InputFilename, std::move(Err));
-
-  for (const auto &Phdr : *PhdrsOrErr) {
-    if (Phdr.p_type != PT_NOTE)
-      continue;
-    Error Err = Error::success();
-    for (auto Note : In.notes(Phdr, Err))
-      if (Note.getType() == NT_GNU_BUILD_ID && Note.getName() == ELF_NOTE_GNU)
-        return Note.getDesc();
-    if (Err)
-      return createFileError(Config.InputFilename, std::move(Err));
-  }
-
-  return createFileError(Config.InputFilename,
-                         createStringError(llvm::errc::invalid_argument,
-                                           "could not find build ID"));
-}
-
-static Expected<ArrayRef<uint8_t>>
-findBuildID(const CopyConfig &Config, const object::ELFObjectFileBase &In) {
-  if (auto *O = dyn_cast<ELFObjectFile<ELF32LE>>(&In))
-    return findBuildID(Config, O->getELFFile());
-  else if (auto *O = dyn_cast<ELFObjectFile<ELF64LE>>(&In))
-    return findBuildID(Config, O->getELFFile());
-  else if (auto *O = dyn_cast<ELFObjectFile<ELF32BE>>(&In))
-    return findBuildID(Config, O->getELFFile());
-  else if (auto *O = dyn_cast<ELFObjectFile<ELF64BE>>(&In))
-    return findBuildID(Config, O->getELFFile());
-
-  llvm_unreachable("Bad file format");
-}
-
 template <class... Ts>
 static Error makeStringError(std::error_code EC, const Twine &Msg,
                              Ts &&... Args) {
@@ -210,59 +173,6 @@ static Error makeStringError(std::error_code EC, const Twine &Msg,
   return createStringError(EC, FullMsg.c_str(), std::forward<Ts>(Args)...);
 }
 
-#define MODEL_8 "%%%%%%%%"
-#define MODEL_16 MODEL_8 MODEL_8
-#define MODEL_32 (MODEL_16 MODEL_16)
-
-static Error linkToBuildIdDir(const CopyConfig &Config, StringRef ToLink,
-                              StringRef Suffix,
-                              ArrayRef<uint8_t> BuildIdBytes) {
-  SmallString<128> Path = Config.BuildIdLinkDir;
-  sys::path::append(Path, llvm::toHex(BuildIdBytes[0], /*LowerCase*/ true));
-  if (auto EC = sys::fs::create_directories(Path))
-    return createFileError(
-        Path.str(),
-        makeStringError(EC, "cannot create build ID link directory"));
-
-  sys::path::append(Path,
-                    llvm::toHex(BuildIdBytes.slice(1), /*LowerCase*/ true));
-  Path += Suffix;
-  SmallString<128> TmpPath;
-  // create_hard_link races so we need to link to a temporary path but
-  // we want to make sure that we choose a filename that does not exist.
-  // By using 32 model characters we get 128-bits of entropy. It is
-  // unlikely that this string has ever existed before much less exists
-  // on this disk or in the current working directory.
-  // Additionally we prepend the original Path for debugging but also
-  // because it ensures that we're linking within a directory on the same
-  // partition on the same device which is critical. It has the added
-  // win of yet further decreasing the odds of a conflict.
-  sys::fs::createUniquePath(Twine(Path) + "-" + MODEL_32 + ".tmp", TmpPath,
-                            /*MakeAbsolute*/ false);
-  if (auto EC = sys::fs::create_hard_link(ToLink, TmpPath)) {
-    Path.push_back('\0');
-    return makeStringError(EC, "cannot link '%s' to '%s'", ToLink.data(),
-                           Path.data());
-  }
-  // We then atomically rename the link into place which will just move the
-  // link. If rename fails something is more seriously wrong so just return
-  // an error.
-  if (auto EC = sys::fs::rename(TmpPath, Path)) {
-    Path.push_back('\0');
-    return makeStringError(EC, "cannot link '%s' to '%s'", ToLink.data(),
-                           Path.data());
-  }
-  // If `Path` was already a hard-link to the same underlying file then the
-  // temp file will be left so we need to remove it. Remove will not cause
-  // an error by default if the file is already gone so just blindly remove
-  // it rather than checking.
-  if (auto EC = sys::fs::remove(TmpPath)) {
-    TmpPath.push_back('\0');
-    return makeStringError(EC, "could not remove '%s'", TmpPath.data());
-  }
-  return Error::success();
-}
-
 static Error splitDWOToFile(const CopyConfig &Config, const Reader &Reader,
                             StringRef File, ElfType OutputElfType) {
   Expected<std::unique_ptr<Object>> DWOFile = Reader.create(false);
@@ -828,37 +738,12 @@ Error executeObjcopyOnBinary(const CopyConfig &Config,
   const ElfType OutputElfType =
       Config.OutputArch ? getOutputElfType(Config.OutputArch.getValue())
                         : getOutputElfType(In);
-  ArrayRef<uint8_t> BuildIdBytes;
-
-  if (!Config.BuildIdLinkDir.empty()) {
-    auto BuildIdBytesOrErr = findBuildID(Config, In);
-    if (auto E = BuildIdBytesOrErr.takeError())
-      return E;
-    BuildIdBytes = *BuildIdBytesOrErr;
-
-    if (BuildIdBytes.size() < 2)
-      return createFileError(
-          Config.InputFilename,
-          createStringError(object_error::parse_failed,
-                            "build ID is smaller than two bytes"));
-  }
-
-  if (!Config.BuildIdLinkDir.empty() && Config.BuildIdLinkInput)
-    if (Error E =
-            linkToBuildIdDir(Config, Config.InputFilename,
-                             Config.BuildIdLinkInput.getValue(), BuildIdBytes))
-      return E;
 
   if (Error E = handleArgs(Config, **Obj, Reader, OutputElfType))
     return createFileError(Config.InputFilename, std::move(E));
 
   if (Error E = writeOutput(Config, **Obj, Out, OutputElfType))
     return createFileError(Config.InputFilename, std::move(E));
-  if (!Config.BuildIdLinkDir.empty() && Config.BuildIdLinkOutput)
-    if (Error E =
-            linkToBuildIdDir(Config, Config.OutputFilename,
-                             Config.BuildIdLinkOutput.getValue(), BuildIdBytes))
-      return createFileError(Config.OutputFilename, std::move(E));
 
   return Error::success();
 }
index fef4a0a..1cda7bf 100644 (file)
@@ -327,14 +327,12 @@ static Error isValidMachOCannonicalName(StringRef Name) {
 }
 
 static Error handleArgs(const CopyConfig &Config, Object &Obj) {
-  if (Config.AllowBrokenLinks || !Config.BuildIdLinkDir.empty() ||
-      Config.BuildIdLinkInput || Config.BuildIdLinkOutput ||
-      !Config.SplitDWO.empty() || !Config.SymbolsPrefix.empty() ||
-      !Config.AllocSectionsPrefix.empty() || !Config.KeepSection.empty() ||
-      Config.NewSymbolVisibility || !Config.SymbolsToGlobalize.empty() ||
-      !Config.SymbolsToKeep.empty() || !Config.SymbolsToLocalize.empty() ||
-      !Config.SymbolsToWeaken.empty() || !Config.SymbolsToKeepGlobal.empty() ||
-      !Config.SectionsToRename.empty() ||
+  if (Config.AllowBrokenLinks || !Config.SplitDWO.empty() ||
+      !Config.SymbolsPrefix.empty() || !Config.AllocSectionsPrefix.empty() ||
+      !Config.KeepSection.empty() || Config.NewSymbolVisibility ||
+      !Config.SymbolsToGlobalize.empty() || !Config.SymbolsToKeep.empty() ||
+      !Config.SymbolsToLocalize.empty() || !Config.SymbolsToWeaken.empty() ||
+      !Config.SymbolsToKeepGlobal.empty() || !Config.SectionsToRename.empty() ||
       !Config.UnneededSymbolsToRemove.empty() ||
       !Config.SetSectionAlignment.empty() || !Config.SetSectionFlags.empty() ||
       Config.ExtractDWO || Config.LocalizeHidden || Config.PreserveDates ||
index 9e6b6f0..63abbe4 100644 (file)
@@ -196,19 +196,6 @@ defm prefix_alloc_sections
     : Eq<"prefix-alloc-sections", "Add <prefix> to the start of every allocated section name">,
       MetaVarName<"prefix">;
 
-defm build_id_link_dir
-    : Eq<"build-id-link-dir", "Set directory for --build-id-link-input and "
-                              "--build-id-link-output to <dir>">,
-      MetaVarName<"dir">;
-defm build_id_link_input
-    : Eq<"build-id-link-input", "Hard-link the input to <dir>/xx/xxx<suffix> "
-                                "name derived from hex build ID">,
-      MetaVarName<"suffix">;
-defm build_id_link_output
-    : Eq<"build-id-link-output", "Hard-link the output to <dir>/xx/xxx<suffix> "
-                                 "name derived from hex build ID">,
-      MetaVarName<"suffix">;
-
 defm set_start : Eq<"set-start", "Set the start address to <addr>. Overrides "
                     "any previous --change-start or --adjust-start values.">,
                  MetaVarName<"addr">;
index eb0e563..f8dc645 100644 (file)
@@ -72,10 +72,9 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
     Obj.addSectionWithOwnedContents(Sec, std::move(Buf));
   }
 
-  if (!Config.AddGnuDebugLink.empty() || !Config.BuildIdLinkDir.empty() ||
-      Config.BuildIdLinkInput || Config.BuildIdLinkOutput ||
-      Config.ExtractPartition || !Config.SplitDWO.empty() ||
-      !Config.SymbolsPrefix.empty() || !Config.AllocSectionsPrefix.empty() ||
+  if (!Config.AddGnuDebugLink.empty() || Config.ExtractPartition ||
+      !Config.SplitDWO.empty() || !Config.SymbolsPrefix.empty() ||
+      !Config.AllocSectionsPrefix.empty() ||
       Config.DiscardMode != DiscardType::None || Config.NewSymbolVisibility ||
       !Config.SymbolsToAdd.empty() || !Config.RPathToAdd.empty() ||
       !Config.OnlySection.empty() || !Config.SymbolsToGlobalize.empty() ||