[llvm-objcopy] remove split dwo file creation from executeObjcopyOnBinary.

This patch removes creation of the resulting file from the
executeObjcopyOnBinary() function. For the most use cases, the
executeObjcopyOnBinary receives output file as a parameter
- raw_ostream &Out. The splitting .dwo file is implemented differently:
file containg .dwo tables is created inside executeObjcopyOnBinary().
When objcopy functionality would be moved into separate library,
current implementation will become inconvenient. The goal of that
refactoring is to separate concerns: It might be convenient to
to do dwo tables splitting but to create resulting file differently.

Differential Revision: https://reviews.llvm.org/D98582
This commit is contained in:
Alexey Lapshin 2021-03-12 01:31:06 +03:00
parent b1afa187c8
commit f134a7158b
2 changed files with 60 additions and 61 deletions

View File

@ -173,32 +173,6 @@ static Error makeStringError(std::error_code EC, const Twine &Msg,
return createStringError(EC, FullMsg.c_str(), std::forward<Ts>(Args)...);
}
static Error splitDWOToFile(const CopyConfig &Config, const Reader &Reader,
StringRef File, ElfType OutputElfType) {
Expected<std::unique_ptr<Object>> DWOFile = Reader.create(false);
if (!DWOFile)
return DWOFile.takeError();
auto OnlyKeepDWOPred = [&DWOFile](const SectionBase &Sec) {
return onlyKeepDWOPred(**DWOFile, Sec);
};
if (Error E =
(*DWOFile)->removeSections(Config.AllowBrokenLinks, OnlyKeepDWOPred))
return E;
if (Config.OutputArch) {
(*DWOFile)->Machine = Config.OutputArch.getValue().EMachine;
(*DWOFile)->OSABI = Config.OutputArch.getValue().OSABI;
}
return writeToFile(File, [&](raw_ostream &OutFile) -> Error {
std::unique_ptr<Writer> Writer =
createWriter(Config, **DWOFile, OutFile, OutputElfType);
if (Error E = Writer->finalize())
return E;
return Writer->write();
});
}
static Error dumpSectionToFile(StringRef SecName, StringRef Filename,
Object &Obj) {
for (auto &Sec : Obj.sections()) {
@ -374,7 +348,7 @@ static Error replaceAndRemoveSections(const CopyConfig &Config, Object &Obj) {
};
}
if (Config.StripDWO || !Config.SplitDWO.empty())
if (Config.StripDWO)
RemovePred = [RemovePred](const SectionBase &Sec) {
return isDWOSection(Sec) || RemovePred(Sec);
};
@ -532,21 +506,22 @@ static Error replaceAndRemoveSections(const CopyConfig &Config, Object &Obj) {
// any previous removals. Lastly whether or not something is removed shouldn't
// depend a) on the order the options occur in or b) on some opaque priority
// system. The only priority is that keeps/copies overrule removes.
static Error handleArgs(const CopyConfig &Config, Object &Obj,
const Reader &Reader, ElfType OutputElfType) {
static Error handleArgs(const CopyConfig &Config, Object &Obj) {
if (Config.StripSwiftSymbols || Config.KeepUndefined)
return createStringError(llvm::errc::invalid_argument,
"option not supported by llvm-objcopy for ELF");
if (!Config.SplitDWO.empty())
if (Error E =
splitDWOToFile(Config, Reader, Config.SplitDWO, OutputElfType))
return E;
if (Config.OutputArch) {
Obj.Machine = Config.OutputArch.getValue().EMachine;
Obj.OSABI = Config.OutputArch.getValue().OSABI;
}
if (!Config.SplitDWO.empty() && Config.ExtractDWO) {
return Obj.removeSections(
Config.AllowBrokenLinks,
[&Obj](const SectionBase &Sec) { return onlyKeepDWOPred(Obj, Sec); });
}
// Dump sections before add/remove for compatibility with GNU objcopy.
for (StringRef Flag : Config.DumpSection) {
StringRef SectionName;
@ -706,7 +681,7 @@ Error executeObjcopyOnIHex(const CopyConfig &Config, MemoryBuffer &In,
const ElfType OutputElfType =
getOutputElfType(Config.OutputArch.getValueOr(MachineInfo()));
if (Error E = handleArgs(Config, **Obj, Reader, OutputElfType))
if (Error E = handleArgs(Config, **Obj))
return E;
return writeOutput(Config, **Obj, Out, OutputElfType);
}
@ -724,7 +699,7 @@ Error executeObjcopyOnRawBinary(const CopyConfig &Config, MemoryBuffer &In,
// (-B<arch>).
const ElfType OutputElfType =
getOutputElfType(Config.OutputArch.getValueOr(MachineInfo()));
if (Error E = handleArgs(Config, **Obj, Reader, OutputElfType))
if (Error E = handleArgs(Config, **Obj))
return E;
return writeOutput(Config, **Obj, Out, OutputElfType);
}
@ -741,7 +716,7 @@ Error executeObjcopyOnBinary(const CopyConfig &Config,
Config.OutputArch ? getOutputElfType(Config.OutputArch.getValue())
: getOutputElfType(In);
if (Error E = handleArgs(Config, **Obj, Reader, OutputElfType))
if (Error E = handleArgs(Config, **Obj))
return createFileError(Config.InputFilename, std::move(E));
if (Error E = writeOutput(Config, **Obj, Out, OutputElfType))

View File

@ -322,44 +322,68 @@ static Error executeObjcopy(CopyConfig &Config) {
Stat.permissions(static_cast<sys::fs::perms>(0777));
}
using ProcessRawFn = Error (*)(CopyConfig &, MemoryBuffer &, raw_ostream &);
ProcessRawFn ProcessRaw;
switch (Config.InputFormat) {
case FileFormat::Binary:
ProcessRaw = executeObjcopyOnRawBinary;
break;
case FileFormat::IHex:
ProcessRaw = executeObjcopyOnIHex;
break;
default:
ProcessRaw = nullptr;
}
std::function<Error(raw_ostream & OutFile)> ObjcopyFunc;
if (ProcessRaw) {
auto BufOrErr = MemoryBuffer::getFileOrSTDIN(Config.InputFilename);
OwningBinary<llvm::object::Binary> BinaryHolder;
std::unique_ptr<MemoryBuffer> MemoryBufferHolder;
if (Config.InputFormat == FileFormat::Binary ||
Config.InputFormat == FileFormat::IHex) {
ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =
MemoryBuffer::getFileOrSTDIN(Config.InputFilename);
if (!BufOrErr)
return createFileError(Config.InputFilename, BufOrErr.getError());
MemoryBufferHolder = std::move(*BufOrErr);
if (Error E = writeToFile(
Config.OutputFilename, [&](raw_ostream &OutFile) -> Error {
return ProcessRaw(Config, *BufOrErr->get(), OutFile);
}))
return E;
if (Config.InputFormat == FileFormat::Binary)
ObjcopyFunc = [&](raw_ostream &OutFile) -> Error {
// Handle FileFormat::Binary.
return executeObjcopyOnRawBinary(Config, *MemoryBufferHolder, OutFile);
};
else
ObjcopyFunc = [&](raw_ostream &OutFile) -> Error {
// Handle FileFormat::IHex.
return executeObjcopyOnIHex(Config, *MemoryBufferHolder, OutFile);
};
} else {
Expected<OwningBinary<llvm::object::Binary>> BinaryOrErr =
createBinary(Config.InputFilename);
if (!BinaryOrErr)
return createFileError(Config.InputFilename, BinaryOrErr.takeError());
BinaryHolder = std::move(*BinaryOrErr);
if (Archive *Ar = dyn_cast<Archive>(BinaryOrErr.get().getBinary())) {
if (Archive *Ar = dyn_cast<Archive>(BinaryHolder.getBinary())) {
// Handle Archive.
if (Error E = executeObjcopyOnArchive(Config, *Ar))
return E;
} else {
if (Error E = writeToFile(
Config.OutputFilename, [&](raw_ostream &OutFile) -> Error {
return executeObjcopyOnBinary(
Config, *BinaryOrErr.get().getBinary(), OutFile);
}))
// Handle llvm::object::Binary.
ObjcopyFunc = [&](raw_ostream &OutFile) -> Error {
return executeObjcopyOnBinary(Config, *BinaryHolder.getBinary(),
OutFile);
};
}
}
if (ObjcopyFunc) {
if (Config.SplitDWO.empty()) {
// Apply transformations described by Config and store result into
// Config.OutputFilename using specified ObjcopyFunc function.
if (Error E = writeToFile(Config.OutputFilename, ObjcopyFunc))
return E;
} else {
Config.ExtractDWO = true;
Config.StripDWO = false;
// Copy .dwo tables from the Config.InputFilename into Config.SplitDWO
// file using specified ObjcopyFunc function.
if (Error E = writeToFile(Config.SplitDWO, ObjcopyFunc))
return E;
Config.ExtractDWO = false;
Config.StripDWO = true;
// Apply transformations described by Config, remove .dwo tables and
// store result into Config.OutputFilename using specified ObjcopyFunc
// function.
if (Error E = writeToFile(Config.OutputFilename, ObjcopyFunc))
return E;
}
}