diff options
author | Fangrui Song <i@maskray.me> | 2022-07-13 10:04:21 -0700 |
---|---|---|
committer | Fangrui Song <i@maskray.me> | 2022-07-13 10:04:21 -0700 |
commit | b28412d5397dc5a23f172d6ebeac760c82a82248 (patch) | |
tree | a05095acda126839c245f260d53d4157023d8029 /llvm/tools/llvm-objcopy | |
parent | 31cccebb5c811a3d63146005d15a4e3b4f819980 (diff) | |
download | llvm-b28412d5397dc5a23f172d6ebeac760c82a82248.zip llvm-b28412d5397dc5a23f172d6ebeac760c82a82248.tar.gz llvm-b28412d5397dc5a23f172d6ebeac760c82a82248.tar.bz2 |
[llvm-objcopy][ELF] Add --set-section-type
The request is mentioned on D129053. I feel that having this functionality is
mildly useful (not strong).
* Rename .ctors to .init_array and change sh_type to SHT_INIT_ARRAY (GNU objcopy
detects the special name but we don't).
* Craft tests for a new SHT_LLVM_* extension
Reviewed By: jhenderson
Differential Revision: https://reviews.llvm.org/D129337
Diffstat (limited to 'llvm/tools/llvm-objcopy')
-rw-r--r-- | llvm/tools/llvm-objcopy/ObjcopyOptions.cpp | 48 | ||||
-rw-r--r-- | llvm/tools/llvm-objcopy/ObjcopyOpts.td | 5 |
2 files changed, 34 insertions, 19 deletions
diff --git a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp index 30ca506..8a2b485 100644 --- a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp +++ b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp @@ -236,23 +236,21 @@ static Expected<SectionRename> parseRenameSectionValue(StringRef FlagValue) { } static Expected<std::pair<StringRef, uint64_t>> -parseSetSectionAlignment(StringRef FlagValue) { +parseSetSectionAttribute(StringRef Option, StringRef FlagValue) { if (!FlagValue.contains('=')) - return createStringError( - errc::invalid_argument, - "bad format for --set-section-alignment: missing '='"); + return make_error<StringError>("bad format for " + Option + ": missing '='", + errc::invalid_argument); auto Split = StringRef(FlagValue).split('='); if (Split.first.empty()) - return createStringError( - errc::invalid_argument, - "bad format for --set-section-alignment: missing section name"); - uint64_t NewAlign; - if (Split.second.getAsInteger(0, NewAlign)) - return createStringError( - errc::invalid_argument, - "invalid alignment for --set-section-alignment: '%s'", - Split.second.str().c_str()); - return std::make_pair(Split.first, NewAlign); + return make_error<StringError>("bad format for " + Option + + ": missing section name", + errc::invalid_argument); + uint64_t Value; + if (Split.second.getAsInteger(0, Value)) + return make_error<StringError>("invalid value for " + Option + ": '" + + Split.second + "'", + errc::invalid_argument); + return std::make_pair(Split.first, Value); } static Expected<SectionFlagsUpdate> @@ -793,7 +791,7 @@ objcopy::parseObjcopyOptions(ArrayRef<const char *> RawArgsArr, } for (auto Arg : InputArgs.filtered(OBJCOPY_set_section_alignment)) { Expected<std::pair<StringRef, uint64_t>> NameAndAlign = - parseSetSectionAlignment(Arg->getValue()); + parseSetSectionAttribute("--set-section-alignment", Arg->getValue()); if (!NameAndAlign) return NameAndAlign.takeError(); Config.SetSectionAlignment[NameAndAlign->first] = NameAndAlign->second; @@ -809,16 +807,28 @@ objcopy::parseObjcopyOptions(ArrayRef<const char *> RawArgsArr, "--set-section-flags set multiple times for section '%s'", SFU->Name.str().c_str()); } - // Prohibit combinations of --set-section-flags when the section name is used - // as the destination of a --rename-section. + for (auto Arg : InputArgs.filtered(OBJCOPY_set_section_type)) { + Expected<std::pair<StringRef, uint64_t>> NameAndType = + parseSetSectionAttribute("--set-section-type", Arg->getValue()); + if (!NameAndType) + return NameAndType.takeError(); + Config.SetSectionType[NameAndType->first] = NameAndType->second; + } + // Prohibit combinations of --set-section-{flags,type} when the section name + // is used as the destination of a --rename-section. for (const auto &E : Config.SectionsToRename) { const SectionRename &SR = E.second; - if (Config.SetSectionFlags.count(SR.NewName)) + auto Err = [&](const char *Option) { return createStringError( errc::invalid_argument, - "--set-section-flags=%s conflicts with --rename-section=%s=%s", + "--set-section-%s=%s conflicts with --rename-section=%s=%s", Option, SR.NewName.str().c_str(), SR.OriginalName.str().c_str(), SR.NewName.str().c_str()); + }; + if (Config.SetSectionFlags.count(SR.NewName)) + return Err("flags"); + if (Config.SetSectionType.count(SR.NewName)) + return Err("type"); } for (auto Arg : InputArgs.filtered(OBJCOPY_remove_section)) diff --git a/llvm/tools/llvm-objcopy/ObjcopyOpts.td b/llvm/tools/llvm-objcopy/ObjcopyOpts.td index ff732659..962028d 100644 --- a/llvm/tools/llvm-objcopy/ObjcopyOpts.td +++ b/llvm/tools/llvm-objcopy/ObjcopyOpts.td @@ -87,6 +87,11 @@ defm set_section_flags "data, rom, share, contents, merge, strings.">, MetaVarName<"section=flag1[,flag2,...]">; +defm set_section_type + : Eq<"set-section-type", + "Set the type of section <section> to the integer <type>">, + MetaVarName<"section=type">; + def S : Flag<["-"], "S">, Alias<strip_all>, HelpText<"Alias for --strip-all">; |