Skip to content

Commit

Permalink
[llvm-objcopy] Fix prints wrong path when section output path doesn't…
Browse files Browse the repository at this point in the history
… exist
  • Loading branch information
AmrDeveloper committed Feb 1, 2025
1 parent 7612dcc commit cf63b7e
Show file tree
Hide file tree
Showing 6 changed files with 191 additions and 46 deletions.
66 changes: 40 additions & 26 deletions llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,27 +186,32 @@ static std::unique_ptr<Writer> createWriter(const CommonConfig &Config,
}

static Error dumpSectionToFile(StringRef SecName, StringRef Filename,
Object &Obj) {
StringRef InputFilename, Object &Obj) {
for (auto &Sec : Obj.sections()) {
if (Sec.Name == SecName) {
if (Sec.Type == SHT_NOBITS)
return createStringError(object_error::parse_failed,
"cannot dump section '%s': it has no contents",
SecName.str().c_str());
if (Sec.Type == SHT_NOBITS) {
Error E =
createStringError(object_error::parse_failed,
"cannot dump section '%s': it has no contents",
SecName.str().c_str());
return createFileError(InputFilename, std::move(E));
}
Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
FileOutputBuffer::create(Filename, Sec.OriginalData.size());
if (!BufferOrErr)
return BufferOrErr.takeError();
return createFileError(Filename, BufferOrErr.takeError());
std::unique_ptr<FileOutputBuffer> Buf = std::move(*BufferOrErr);
std::copy(Sec.OriginalData.begin(), Sec.OriginalData.end(),
Buf->getBufferStart());
if (Error E = Buf->commit())
return E;
return createFileError(Filename, std::move(E));
return Error::success();
}
}
return createStringError(object_error::parse_failed, "section '%s' not found",
SecName.str().c_str());
Error E = createStringError(object_error::parse_failed,
"section '%s' not found", SecName.str().c_str());

return createFileError(InputFilename, std::move(E));
}

Error Object::compressOrDecompressSections(const CommonConfig &Config) {
Expand Down Expand Up @@ -798,7 +803,8 @@ static Error handleArgs(const CommonConfig &Config, const ELFConfig &ELFConfig,
StringRef SectionName;
StringRef FileName;
std::tie(SectionName, FileName) = Flag.split('=');
if (Error E = dumpSectionToFile(SectionName, FileName, Obj))
if (Error E =
dumpSectionToFile(SectionName, FileName, Config.InputFilename, Obj))
return E;
}

Expand All @@ -807,10 +813,10 @@ static Error handleArgs(const CommonConfig &Config, const ELFConfig &ELFConfig,
// us to avoid reporting the inappropriate errors about removing symbols
// named in relocations.
if (Error E = replaceAndRemoveSections(Config, ELFConfig, Obj))
return E;
return createFileError(Config.InputFilename, std::move(E));

if (Error E = updateAndRemoveSymbols(Config, ELFConfig, Obj))
return E;
return createFileError(Config.InputFilename, std::move(E));

if (!Config.SetSectionAlignment.empty()) {
for (SectionBase &Sec : Obj.sections()) {
Expand All @@ -826,33 +832,37 @@ static Error handleArgs(const CommonConfig &Config, const ELFConfig &ELFConfig,
if (Config.ChangeSectionLMAValAll > 0 &&
Seg.PAddr > std::numeric_limits<uint64_t>::max() -
Config.ChangeSectionLMAValAll) {
return createStringError(
Error E = createStringError(
errc::invalid_argument,
"address 0x" + Twine::utohexstr(Seg.PAddr) +
" cannot be increased by 0x" +
Twine::utohexstr(Config.ChangeSectionLMAValAll) +
". The result would overflow");
return createFileError(Config.InputFilename, std::move(E));
} else if (Config.ChangeSectionLMAValAll < 0 &&
Seg.PAddr < std::numeric_limits<uint64_t>::min() -
Config.ChangeSectionLMAValAll) {
return createStringError(
Error E = createStringError(
errc::invalid_argument,
"address 0x" + Twine::utohexstr(Seg.PAddr) +
" cannot be decreased by 0x" +
Twine::utohexstr(std::abs(Config.ChangeSectionLMAValAll)) +
". The result would underflow");

return createFileError(Config.InputFilename, std::move(E));
}
Seg.PAddr += Config.ChangeSectionLMAValAll;
}
}
}

if (!Config.ChangeSectionAddress.empty()) {
if (Obj.Type != ELF::ET_REL)
return createStringError(
if (Obj.Type != ELF::ET_REL) {
Error E = createStringError(
object_error::invalid_file_type,
"cannot change section address in a non-relocatable file");

return createFileError(Config.InputFilename, std::move(E));
}
StringMap<AddressUpdate> SectionsToUpdateAddress;
for (const SectionPatternAddressUpdate &PatternUpdate :
make_range(Config.ChangeSectionAddress.rbegin(),
Expand All @@ -863,22 +873,26 @@ static Error handleArgs(const CommonConfig &Config, const ELFConfig &ELFConfig,
.second) {
if (PatternUpdate.Update.Kind == AdjustKind::Subtract &&
Sec.Addr < PatternUpdate.Update.Value) {
return createStringError(
Error E = createStringError(
errc::invalid_argument,
"address 0x" + Twine::utohexstr(Sec.Addr) +
" cannot be decreased by 0x" +
Twine::utohexstr(PatternUpdate.Update.Value) +
". The result would underflow");

return createFileError(Config.InputFilename, std::move(E));
}
if (PatternUpdate.Update.Kind == AdjustKind::Add &&
Sec.Addr > std::numeric_limits<uint64_t>::max() -
PatternUpdate.Update.Value) {
return createStringError(
Error E = createStringError(
errc::invalid_argument,
"address 0x" + Twine::utohexstr(Sec.Addr) +
" cannot be increased by 0x" +
Twine::utohexstr(PatternUpdate.Update.Value) +
". The result would overflow");

return createFileError(Config.InputFilename, std::move(E));
}

switch (PatternUpdate.Update.Kind) {
Expand Down Expand Up @@ -909,7 +923,7 @@ static Error handleArgs(const CommonConfig &Config, const ELFConfig &ELFConfig,
if (!ELFConfig.NotesToRemove.empty()) {
if (Error Err =
removeNotes(Obj, E, ELFConfig.NotesToRemove, Config.ErrorCallback))
return Err;
return createFileError(Config.InputFilename, std::move(Err));
}

for (const NewSectionInfo &AddedSection : Config.AddSection) {
Expand All @@ -924,15 +938,15 @@ static Error handleArgs(const CommonConfig &Config, const ELFConfig &ELFConfig,
return Error::success();
};
if (Error E = handleUserSection(AddedSection, AddSection))
return E;
return createFileError(Config.InputFilename, std::move(E));
}

for (const NewSectionInfo &NewSection : Config.UpdateSection) {
auto UpdateSection = [&](StringRef Name, ArrayRef<uint8_t> Data) {
return Obj.updateSection(Name, Data);
};
if (Error E = handleUserSection(NewSection, UpdateSection))
return E;
return createFileError(Config.InputFilename, std::move(E));
}

if (!Config.AddGnuDebugLink.empty())
Expand All @@ -943,7 +957,7 @@ static Error handleArgs(const CommonConfig &Config, const ELFConfig &ELFConfig,
// before adding new symbols.
if (!Obj.SymbolTable && !Config.SymbolsToAdd.empty())
if (Error E = Obj.addNewSymbolTable())
return E;
return createFileError(Config.InputFilename, std::move(E));

for (const NewSymbolInfo &SI : Config.SymbolsToAdd)
addSymbol(Obj, SI, ELFConfig.NewSymbolVisibility);
Expand All @@ -955,7 +969,7 @@ static Error handleArgs(const CommonConfig &Config, const ELFConfig &ELFConfig,
if (Iter != Config.SetSectionFlags.end()) {
const SectionFlagsUpdate &SFU = Iter->second;
if (Error E = setSectionFlagsAndType(Sec, SFU.NewFlags, Obj.Machine))
return E;
return createFileError(Config.InputFilename, std::move(E));
}
auto It2 = Config.SetSectionType.find(Sec.Name);
if (It2 != Config.SetSectionType.end())
Expand All @@ -974,7 +988,7 @@ static Error handleArgs(const CommonConfig &Config, const ELFConfig &ELFConfig,
Sec.Name = std::string(SR.NewName);
if (SR.NewFlags) {
if (Error E = setSectionFlagsAndType(Sec, *SR.NewFlags, Obj.Machine))
return E;
return createFileError(Config.InputFilename, std::move(E));
}
RenamedSections.insert(&Sec);
} else if (RelocSec && !(Sec.Flags & SHF_ALLOC))
Expand Down Expand Up @@ -1091,7 +1105,7 @@ Error objcopy::elf::executeObjcopyOnBinary(const CommonConfig &Config,
: getOutputElfType(In);

if (Error E = handleArgs(Config, ELFConfig, OutputElfType, **Obj))
return createFileError(Config.InputFilename, std::move(E));
return E;

if (Error E = writeOutput(Config, **Obj, Out, OutputElfType))
return createFileError(Config.InputFilename, std::move(E));
Expand Down
28 changes: 15 additions & 13 deletions llvm/lib/ObjCopy/MachO/MachOObjcopy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,25 +306,26 @@ static Error processLoadCommands(const MachOConfig &MachOConfig, Object &Obj) {
}

static Error dumpSectionToFile(StringRef SecName, StringRef Filename,
Object &Obj) {
StringRef InputFilename, Object &Obj) {
for (LoadCommand &LC : Obj.LoadCommands)
for (const std::unique_ptr<Section> &Sec : LC.Sections) {
if (Sec->CanonicalName == SecName) {
Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
FileOutputBuffer::create(Filename, Sec->Content.size());
if (!BufferOrErr)
return BufferOrErr.takeError();
return createFileError(Filename, BufferOrErr.takeError());
std::unique_ptr<FileOutputBuffer> Buf = std::move(*BufferOrErr);
llvm::copy(Sec->Content, Buf->getBufferStart());

if (Error E = Buf->commit())
return E;
return createFileError(Filename, std::move(E));
return Error::success();
}
}

return createStringError(object_error::parse_failed, "section '%s' not found",
SecName.str().c_str());
Error E = createStringError(object_error::parse_failed,
"section '%s' not found", SecName.str().c_str());
return createFileError(InputFilename, std::move(E));
}

static Error addSection(const NewSectionInfo &NewSection, Object &Obj) {
Expand Down Expand Up @@ -426,12 +427,13 @@ static Error handleArgs(const CommonConfig &Config,
StringRef SectionName;
StringRef FileName;
std::tie(SectionName, FileName) = Flag.split('=');
if (Error E = dumpSectionToFile(SectionName, FileName, Obj))
if (Error E =
dumpSectionToFile(SectionName, FileName, Config.InputFilename, Obj))
return E;
}

if (Error E = removeSections(Config, Obj))
return E;
return createFileError(Config.InputFilename, std::move(E));

// Mark symbols to determine which symbols are still needed.
if (Config.StripAll)
Expand All @@ -446,20 +448,20 @@ static Error handleArgs(const CommonConfig &Config,

for (const NewSectionInfo &NewSection : Config.AddSection) {
if (Error E = isValidMachOCannonicalName(NewSection.SectionName))
return E;
return createFileError(Config.InputFilename, std::move(E));
if (Error E = addSection(NewSection, Obj))
return E;
return createFileError(Config.InputFilename, std::move(E));
}

for (const NewSectionInfo &NewSection : Config.UpdateSection) {
if (Error E = isValidMachOCannonicalName(NewSection.SectionName))
return E;
return createFileError(Config.InputFilename, std::move(E));
if (Error E = updateSection(NewSection, Obj))
return E;
return createFileError(Config.InputFilename, std::move(E));
}

if (Error E = processLoadCommands(MachOConfig, Obj))
return E;
return createFileError(Config.InputFilename, std::move(E));

return Error::success();
}
Expand All @@ -479,7 +481,7 @@ Error objcopy::macho::executeObjcopyOnBinary(const CommonConfig &Config,
Config.InputFilename.str().c_str());

if (Error E = handleArgs(Config, MachOConfig, **O))
return createFileError(Config.InputFilename, std::move(E));
return E;

// Page size used for alignment of segment sizes in Mach-O executables and
// dynamic libraries.
Expand Down
16 changes: 9 additions & 7 deletions llvm/lib/ObjCopy/wasm/WasmObjcopy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,23 +38,24 @@ static bool isCommentSection(const Section &Sec) {
}

static Error dumpSectionToFile(StringRef SecName, StringRef Filename,
Object &Obj) {
StringRef InputFilename, Object &Obj) {
for (const Section &Sec : Obj.Sections) {
if (Sec.Name == SecName) {
ArrayRef<uint8_t> Contents = Sec.Contents;
Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
FileOutputBuffer::create(Filename, Contents.size());
if (!BufferOrErr)
return BufferOrErr.takeError();
return createFileError(Filename, BufferOrErr.takeError());
std::unique_ptr<FileOutputBuffer> Buf = std::move(*BufferOrErr);
std::copy(Contents.begin(), Contents.end(), Buf->getBufferStart());
if (Error E = Buf->commit())
return E;
return createFileError(Filename, std::move(E));
return Error::success();
}
}
return createStringError(errc::invalid_argument, "section '%s' not found",
SecName.str().c_str());
Error E = createStringError(errc::invalid_argument, "section '%s' not found",
SecName.str().c_str());
return createFileError(Filename, std::move(E));
}

static void removeSections(const CommonConfig &Config, Object &Obj) {
Expand Down Expand Up @@ -115,8 +116,9 @@ static Error handleArgs(const CommonConfig &Config, Object &Obj) {
StringRef SecName;
StringRef FileName;
std::tie(SecName, FileName) = Flag.split("=");
if (Error E = dumpSectionToFile(SecName, FileName, Obj))
return createFileError(FileName, std::move(E));
if (Error E =
dumpSectionToFile(SecName, FileName, Config.InputFilename, Obj))
return E;
}

removeSections(Config, Obj);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
## Show that llvm-objcopy report that section file path is not exists.

# RUN: yaml2obj %s -o %t

# RUN: not llvm-objcopy --dump-section .text=not_exists/text-section %t 2>&1 \
# RUN: | FileCheck %s -DINPUT=%t --check-prefix=NO-SUCH-PATH
# NO-SUCH-PATH: error: 'not_exists/text-section': No such file or directory

!ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_EXEC
Machine: EM_X86_64
Sections:
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
AddressAlign: 0x0000000000001000
Content: "DEADBEEF"
- Name: .foo
Type: SHT_PROGBITS
Flags: [ SHF_WRITE ]
Content: "CAFE"
- Name: .empty
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC ]
- Name: .bar
Type: SHT_NOBITS
Flags: [ SHF_WRITE ]
ProgramHeaders:
- Type: PT_LOAD
Flags: [ PF_X, PF_R ]
FirstSec: .text
LastSec: .text

Loading

0 comments on commit cf63b7e

Please sign in to comment.