1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 10:42:39 +01:00

[llvm-objcopy] Delete --build-id-link-{dir,input,output}

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
This commit is contained in:
Fangrui Song 2021-02-15 11:17:32 -08:00
parent 1172c76018
commit 3296757d5e
13 changed files with 21 additions and 287 deletions

View 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

View 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
---------------------------------

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View 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 ||

View 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 =

View 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;

View 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();
}

View 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 ||

View 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">;

View 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() ||