mirror of
https://github.com/Gericom/teak-llvm.git
synced 2025-06-19 03:25:54 -04:00
[llvm-objcopy][COFF] Add support for --set-section-flags
Reviewers: jhenderson, MaskRay, alexshap, rupprecht, mstorsjo Reviewed By: jhenderson Subscribers: abrachet, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D73107
This commit is contained in:
parent
76fa5d50f3
commit
f69eba0772
@ -130,6 +130,45 @@ multiple file formats.
|
|||||||
Set the alignment of section ``<section>`` to `<align>``. Can be specified
|
Set the alignment of section ``<section>`` to `<align>``. Can be specified
|
||||||
multiple times to update multiple sections.
|
multiple times to update multiple sections.
|
||||||
|
|
||||||
|
.. option:: --set-section-flags <section>=<flag>[,<flag>,...]
|
||||||
|
|
||||||
|
Set section properties in the output of section ``<section>`` based on the
|
||||||
|
specified ``<flag>`` values. Can be specified multiple times to update multiple
|
||||||
|
sections.
|
||||||
|
|
||||||
|
Supported flag names are `alloc`, `load`, `noload`, `readonly`, `exclude`,
|
||||||
|
`debug`, `code`, `data`, `rom`, `share`, `contents`, `merge` and `strings`. Not
|
||||||
|
all flags are meaningful for all object file formats.
|
||||||
|
|
||||||
|
For ELF objects, the flags have the following effects:
|
||||||
|
|
||||||
|
- `alloc` = add the `SHF_ALLOC` flag.
|
||||||
|
- `load` = if the section has `SHT_NOBITS` type, mark it as a `SHT_PROGBITS`
|
||||||
|
section.
|
||||||
|
- `readonly` = if this flag is not specified, add the `SHF_WRITE` flag.
|
||||||
|
- `exclude` = add the `SHF_EXCLUDE` flag.
|
||||||
|
- `code` = add the `SHF_EXECINSTR` flag.
|
||||||
|
- `merge` = add the `SHF_MERGE` flag.
|
||||||
|
- `strings` = add the `SHF_STRINGS` flag.
|
||||||
|
- `contents` = if the section has `SHT_NOBITS` type, mark it as a `SHT_PROGBITS`
|
||||||
|
section.
|
||||||
|
|
||||||
|
For COFF objects, the flags have the following effects:
|
||||||
|
|
||||||
|
- `alloc` = add the `IMAGE_SCN_CNT_UNINITIALIZED_DATA` and `IMAGE_SCN_MEM_READ`
|
||||||
|
flags, unless the `load` flag is specified.
|
||||||
|
- `noload` = add the `IMAGE_SCN_LNK_REMOVE` and `IMAGE_SCN_MEM_READ` flags.
|
||||||
|
- `readonly` = if this flag is not specified, add the `IMAGE_SCN_MEM_WRITE`
|
||||||
|
flag.
|
||||||
|
- `exclude` = add the `IMAGE_SCN_LNK_REMOVE` and `IMAGE_SCN_MEM_READ` flags.
|
||||||
|
- `debug` = add the `IMAGE_SCN_CNT_INITIALIZED_DATA`,
|
||||||
|
`IMAGE_SCN_MEM_DISCARDABLE` and `IMAGE_SCN_MEM_READ` flags.
|
||||||
|
- `code` = add the `IMAGE_SCN_CNT_CODE`, `IMAGE_SCN_MEM_EXECUTE` and
|
||||||
|
`IMAGE_SCN_MEM_READ` flags.
|
||||||
|
- `data` = add the `IMAGE_SCN_CNT_INITIALIZED_DATA` and `IMAGE_SCN_MEM_READ`
|
||||||
|
flags.
|
||||||
|
- `share` = add the `IMAGE_SCN_MEM_SHARED` and `IMAGE_SCN_MEM_READ` flags.
|
||||||
|
|
||||||
.. option:: --strip-all-gnu
|
.. option:: --strip-all-gnu
|
||||||
|
|
||||||
Remove all symbols, debug sections and relocations from the output. This option
|
Remove all symbols, debug sections and relocations from the output. This option
|
||||||
@ -399,28 +438,6 @@ them.
|
|||||||
specified ``<flag>`` values. See :option:`--set-section-flags` for a list of
|
specified ``<flag>`` values. See :option:`--set-section-flags` for a list of
|
||||||
supported flags. Can be specified multiple times to rename multiple sections.
|
supported flags. Can be specified multiple times to rename multiple sections.
|
||||||
|
|
||||||
.. option:: --set-section-flags <section>=<flag>[,<flag>,...]
|
|
||||||
|
|
||||||
Set section properties in the output of section ``<section>`` based on the
|
|
||||||
specified ``<flag>`` values. Can be specified multiple times to update multiple
|
|
||||||
sections.
|
|
||||||
|
|
||||||
Following is a list of supported flags and their effects:
|
|
||||||
|
|
||||||
- `alloc` = add the `SHF_ALLOC` flag.
|
|
||||||
- `load` = if the section has `SHT_NOBITS` type, mark it as a `SHT_PROGBITS`
|
|
||||||
section.
|
|
||||||
- `readonly` = if this flag is not specified, add the `SHF_WRITE` flag.
|
|
||||||
- `exclude` = add the `SHF_EXCLUDE` flag.
|
|
||||||
- `code` = add the `SHF_EXECINSTR` flag.
|
|
||||||
- `merge` = add the `SHF_MERGE` flag.
|
|
||||||
- `strings` = add the `SHF_STRINGS` flag.
|
|
||||||
- `contents` = if the section has `SHT_NOBITS` type, mark it as a `SHT_PROGBITS`
|
|
||||||
section.
|
|
||||||
|
|
||||||
The following flags are also accepted, but are ignored for GNU compatibility:
|
|
||||||
`noload`, `debug`, `data`, `rom`, `share`.
|
|
||||||
|
|
||||||
.. option:: --set-start-addr <addr>
|
.. option:: --set-start-addr <addr>
|
||||||
|
|
||||||
Set the start address of the output to ``<addr>``. Overrides any previously
|
Set the start address of the output to ``<addr>``. Overrides any previously
|
||||||
|
82
llvm/test/tools/llvm-objcopy/COFF/set-section-flags.test
Normal file
82
llvm/test/tools/llvm-objcopy/COFF/set-section-flags.test
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
# RUN: yaml2obj %s -o %t
|
||||||
|
|
||||||
|
## Single flag on a section with no flags:
|
||||||
|
# RUN: llvm-objcopy --set-section-flags=.foo=alloc %t %t.alloc
|
||||||
|
# RUN: llvm-readobj --sections %t.alloc | FileCheck %s --check-prefixes=CHECK,UNINITDATA,READ,WRITE
|
||||||
|
# RUN: llvm-objcopy --set-section-flags=.foo=load %t %t.load
|
||||||
|
# RUN: llvm-readobj --sections %t.load | FileCheck %s --check-prefixes=CHECK,READ,WRITE
|
||||||
|
# RUN: llvm-objcopy --set-section-flags=.foo=noload %t %t.noload
|
||||||
|
# RUN: llvm-readobj --sections %t.noload | FileCheck %s --check-prefixes=CHECK,READ,WRITE,REMOVE
|
||||||
|
# RUN: llvm-objcopy --set-section-flags=.foo=readonly %t %t.readonly
|
||||||
|
# RUN: llvm-readobj --sections %t.readonly | FileCheck %s --check-prefixes=CHECK,READ
|
||||||
|
# RUN: llvm-objcopy --set-section-flags=.foo=exclude %t %t.exclude
|
||||||
|
# RUN: llvm-readobj --sections %t.exclude | FileCheck %s --check-prefixes=CHECK,READ,WRITE,REMOVE
|
||||||
|
# RUN: llvm-objcopy --set-section-flags=.foo=debug %t %t.debug
|
||||||
|
# RUN: llvm-readobj --sections %t.debug | FileCheck %s --check-prefixes=CHECK,INITDATA,DISCARDABLE,READ,WRITE
|
||||||
|
# RUN: llvm-objcopy --set-section-flags=.foo=code %t %t.code
|
||||||
|
# RUN: llvm-readobj --sections %t.code | FileCheck %s --check-prefixes=CHECK,CODE,EXECUTE,READ,WRITE
|
||||||
|
# RUN: llvm-objcopy --set-section-flags=.foo=data %t %t.data
|
||||||
|
# RUN: llvm-readobj --sections %t.data | FileCheck %s --check-prefixes=CHECK,INITDATA,READ,WRITE
|
||||||
|
# RUN: llvm-objcopy --set-section-flags=.foo=rom %t %t.rom
|
||||||
|
# RUN: llvm-readobj --sections %t.rom | FileCheck %s --check-prefixes=CHECK,READ,WRITE
|
||||||
|
# RUN: llvm-objcopy --set-section-flags=.foo=contents %t %t.contents
|
||||||
|
# RUN: llvm-readobj --sections %t.contents | FileCheck %s --check-prefixes=CHECK,READ,WRITE
|
||||||
|
# RUN: llvm-objcopy --set-section-flags=.foo=merge %t %t.merge
|
||||||
|
# RUN: llvm-readobj --sections %t.merge | FileCheck %s --check-prefixes=CHECK,READ,WRITE
|
||||||
|
# RUN: llvm-objcopy --set-section-flags=.foo=strings %t %t.strings
|
||||||
|
# RUN: llvm-readobj --sections %t.strings | FileCheck %s --check-prefixes=CHECK,READ,WRITE
|
||||||
|
# RUN: llvm-objcopy --set-section-flags=.foo=share %t %t.share
|
||||||
|
# RUN: llvm-readobj --sections %t.share | FileCheck %s --check-prefixes=CHECK,READ,SHARED,WRITE
|
||||||
|
|
||||||
|
## Multiple flags:
|
||||||
|
# RUN: llvm-objcopy --set-section-flags=.foo=alloc,readonly,share %t %t.alloc_ro_share
|
||||||
|
# RUN: llvm-readobj --sections %t.alloc_ro_share | FileCheck %s --check-prefixes=CHECK,UNINITDATA,READ,SHARED
|
||||||
|
# RUN: llvm-objcopy --set-section-flags=.foo=alloc,code %t %t.alloc_code
|
||||||
|
# RUN: llvm-readobj --sections %t.alloc_code | FileCheck %s --check-prefixes=CHECK,CODE,UNINITDATA,EXECUTE,READ,WRITE
|
||||||
|
|
||||||
|
## Invalid flags:
|
||||||
|
# RUN: not llvm-objcopy --set-section-flags=.foo=xyzzy %t %t.xyzzy 2>&1 | FileCheck %s --check-prefix=BAD-FLAG
|
||||||
|
|
||||||
|
## Bad flag format:
|
||||||
|
# RUN: not llvm-objcopy --set-section-flags=.foo %t %t2 2>&1 | FileCheck %s --check-prefix=BAD-FORMAT
|
||||||
|
|
||||||
|
## Setting flags for the same section multiple times:
|
||||||
|
# RUN: not llvm-objcopy --set-section-flags=.foo=alloc --set-section-flags=.foo=load %t %t2 2>&1 | FileCheck %s --check-prefix=MULTIPLE-SETS
|
||||||
|
|
||||||
|
## Upper-case flags:
|
||||||
|
# RUN: llvm-objcopy --set-section-flags=.foo=ALLOC,LOAD,NOLOAD,READONLY,DEBUG,CODE,DATA,ROM,CONTENTS,MERGE,STRINGS,SHARE %t %t.upper
|
||||||
|
# RUN: llvm-readobj --sections %t.upper | FileCheck %s --check-prefixes=CHECK,CODE,INITDATA,REMOVE,DISCARDABLE,EXECUTE,READ,SHARED
|
||||||
|
|
||||||
|
## Mixed-case flags:
|
||||||
|
# RUN: llvm-objcopy --set-section-flags=.foo=aLlOc,LoAd,NoLoad,rEAdONly,Debug,codE,DaTa,rOm,CoNtEnTs,mErGe,sTRINGs,SharE %t %t.mixed
|
||||||
|
# RUN: llvm-readobj --sections %t.mixed | FileCheck %s --check-prefixes=CHECK,CODE,INITDATA,REMOVE,DISCARDABLE,EXECUTE,READ,SHARED
|
||||||
|
|
||||||
|
--- !COFF
|
||||||
|
header:
|
||||||
|
Machine: IMAGE_FILE_MACHINE_AMD64
|
||||||
|
Characteristics: [ ]
|
||||||
|
sections:
|
||||||
|
- Name: .foo
|
||||||
|
Characteristics: [ ]
|
||||||
|
Alignment: 4
|
||||||
|
symbols:
|
||||||
|
...
|
||||||
|
|
||||||
|
# CHECK: Name: .foo
|
||||||
|
# CHECK: Characteristics [
|
||||||
|
# CHECK-NEXT: IMAGE_SCN_ALIGN_4BYTES
|
||||||
|
# CODE-NEXT: IMAGE_SCN_CNT_CODE
|
||||||
|
# INITDATA-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA
|
||||||
|
# UNINITDATA-NEXT: IMAGE_SCN_CNT_UNINITIALIZED_DATA
|
||||||
|
# REMOVE-NEXT: IMAGE_SCN_LNK_REMOVE
|
||||||
|
# DISCARDABLE-NEXT: IMAGE_SCN_MEM_DISCARDABLE
|
||||||
|
# EXECUTE-NEXT: IMAGE_SCN_MEM_EXECUTE
|
||||||
|
# READ-NEXT: IMAGE_SCN_MEM_READ
|
||||||
|
# SHARED-NEXT: IMAGE_SCN_MEM_SHARED
|
||||||
|
# WRITE-NEXT: IMAGE_SCN_MEM_WRITE
|
||||||
|
# CHECK-NEXT: ]
|
||||||
|
|
||||||
|
# BAD-FORMAT: bad format for --set-section-flags: missing '='
|
||||||
|
# MULTIPLE-SETS: --set-section-flags set multiple times for section '.foo'
|
||||||
|
|
||||||
|
# BAD-FLAG: unrecognized section flag 'xyzzy'. Flags supported for GNU compatibility: alloc, load, noload, readonly, exclude, debug, code, data, rom, share, contents, merge, strings
|
@ -89,6 +89,43 @@ static void addGnuDebugLink(Object &Obj, StringRef DebugLinkFile) {
|
|||||||
IMAGE_SCN_MEM_DISCARDABLE);
|
IMAGE_SCN_MEM_DISCARDABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void setSectionFlags(Section &Sec, SectionFlag AllFlags) {
|
||||||
|
// Need to preserve alignment flags.
|
||||||
|
const uint32_t PreserveMask =
|
||||||
|
IMAGE_SCN_ALIGN_1BYTES | IMAGE_SCN_ALIGN_2BYTES | IMAGE_SCN_ALIGN_4BYTES |
|
||||||
|
IMAGE_SCN_ALIGN_8BYTES | IMAGE_SCN_ALIGN_16BYTES |
|
||||||
|
IMAGE_SCN_ALIGN_32BYTES | IMAGE_SCN_ALIGN_64BYTES |
|
||||||
|
IMAGE_SCN_ALIGN_128BYTES | IMAGE_SCN_ALIGN_256BYTES |
|
||||||
|
IMAGE_SCN_ALIGN_512BYTES | IMAGE_SCN_ALIGN_1024BYTES |
|
||||||
|
IMAGE_SCN_ALIGN_2048BYTES | IMAGE_SCN_ALIGN_4096BYTES |
|
||||||
|
IMAGE_SCN_ALIGN_8192BYTES;
|
||||||
|
|
||||||
|
// Setup new section characteristics based on the flags provided in command
|
||||||
|
// line.
|
||||||
|
uint32_t NewCharacteristics =
|
||||||
|
(Sec.Header.Characteristics & PreserveMask) | IMAGE_SCN_MEM_READ;
|
||||||
|
|
||||||
|
if ((AllFlags & SectionFlag::SecAlloc) && !(AllFlags & SectionFlag::SecLoad))
|
||||||
|
NewCharacteristics |= IMAGE_SCN_CNT_UNINITIALIZED_DATA;
|
||||||
|
if (AllFlags & SectionFlag::SecNoload)
|
||||||
|
NewCharacteristics |= IMAGE_SCN_LNK_REMOVE;
|
||||||
|
if (!(AllFlags & SectionFlag::SecReadonly))
|
||||||
|
NewCharacteristics |= IMAGE_SCN_MEM_WRITE;
|
||||||
|
if (AllFlags & SectionFlag::SecDebug)
|
||||||
|
NewCharacteristics |=
|
||||||
|
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_DISCARDABLE;
|
||||||
|
if (AllFlags & SectionFlag::SecCode)
|
||||||
|
NewCharacteristics |= IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE;
|
||||||
|
if (AllFlags & SectionFlag::SecData)
|
||||||
|
NewCharacteristics |= IMAGE_SCN_CNT_INITIALIZED_DATA;
|
||||||
|
if (AllFlags & SectionFlag::SecShare)
|
||||||
|
NewCharacteristics |= IMAGE_SCN_MEM_SHARED;
|
||||||
|
if (AllFlags & SectionFlag::SecExclude)
|
||||||
|
NewCharacteristics |= IMAGE_SCN_LNK_REMOVE;
|
||||||
|
|
||||||
|
Sec.Header.Characteristics = NewCharacteristics;
|
||||||
|
}
|
||||||
|
|
||||||
static Error handleArgs(const CopyConfig &Config, Object &Obj) {
|
static Error handleArgs(const CopyConfig &Config, Object &Obj) {
|
||||||
// Perform the actual section removals.
|
// Perform the actual section removals.
|
||||||
Obj.removeSections([&Config](const Section &Sec) {
|
Obj.removeSections([&Config](const Section &Sec) {
|
||||||
@ -178,6 +215,13 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
|
|||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!Config.SetSectionFlags.empty())
|
||||||
|
for (Section &Sec : Obj.getMutableSections()) {
|
||||||
|
const auto It = Config.SetSectionFlags.find(Sec.Name);
|
||||||
|
if (It != Config.SetSectionFlags.end())
|
||||||
|
setSectionFlags(Sec, It->second.NewFlags);
|
||||||
|
}
|
||||||
|
|
||||||
for (const auto &Flag : Config.AddSection) {
|
for (const auto &Flag : Config.AddSection) {
|
||||||
StringRef SecName, FileName;
|
StringRef SecName, FileName;
|
||||||
std::tie(SecName, FileName) = Flag.split("=");
|
std::tie(SecName, FileName) = Flag.split("=");
|
||||||
@ -205,10 +249,10 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
|
|||||||
!Config.SymbolsToGlobalize.empty() || !Config.SymbolsToKeep.empty() ||
|
!Config.SymbolsToGlobalize.empty() || !Config.SymbolsToKeep.empty() ||
|
||||||
!Config.SymbolsToLocalize.empty() || !Config.SymbolsToWeaken.empty() ||
|
!Config.SymbolsToLocalize.empty() || !Config.SymbolsToWeaken.empty() ||
|
||||||
!Config.SymbolsToKeepGlobal.empty() || !Config.SectionsToRename.empty() ||
|
!Config.SymbolsToKeepGlobal.empty() || !Config.SectionsToRename.empty() ||
|
||||||
!Config.SetSectionAlignment.empty() || !Config.SetSectionFlags.empty() ||
|
!Config.SetSectionAlignment.empty() || Config.ExtractDWO ||
|
||||||
Config.ExtractDWO || Config.KeepFileSymbols || Config.LocalizeHidden ||
|
Config.KeepFileSymbols || Config.LocalizeHidden || Config.PreserveDates ||
|
||||||
Config.PreserveDates || Config.StripDWO || Config.StripNonAlloc ||
|
Config.StripDWO || Config.StripNonAlloc || Config.StripSections ||
|
||||||
Config.StripSections || Config.Weaken || Config.DecompressDebugSections ||
|
Config.Weaken || Config.DecompressDebugSections ||
|
||||||
Config.DiscardMode == DiscardType::Locals ||
|
Config.DiscardMode == DiscardType::Locals ||
|
||||||
!Config.SymbolsToAdd.empty() || Config.EntryExpr) {
|
!Config.SymbolsToAdd.empty() || Config.EntryExpr) {
|
||||||
return createStringError(llvm::errc::invalid_argument,
|
return createStringError(llvm::errc::invalid_argument,
|
||||||
|
Loading…
Reference in New Issue
Block a user