[llvm-objcopy]Preserve data in segments not covered by sections

llvm-objcopy previously knew nothing about data in segments that wasn't
covered by section headers, meaning that it wrote zeroes instead of what
was there. As it is possible for this data to be useful to the loader,
this patch causes llvm-objcopy to start preserving this data. Data in
sections that are explicitly removed continues to be written as zeroes.

This fixes https://bugs.llvm.org/show_bug.cgi?id=41005.

Reviewed by: jakehehrlich, rupprecht

Differential Revision: https://reviews.llvm.org/D59483

llvm-svn: 356919
This commit is contained in:
James Henderson 2019-03-25 16:36:26 +00:00
parent 36db489874
commit 1f44814952
4 changed files with 727 additions and 5 deletions

View File

@ -0,0 +1,41 @@
## Show that llvm-objcopy correctly updates the elf header and program header
## table when they are within a segment.
# RUN: yaml2obj %s -o %t.in
## Validate that the properties are different before the removal.
# RUN: llvm-readobj --file-headers --program-headers %t.in | FileCheck %s --check-prefix=BEFORE
# RUN: llvm-objcopy %t.in %t.out -R .remove_me
# RUN: llvm-readobj --file-headers --program-headers %t.out | FileCheck %s --check-prefix=AFTER
# BEFORE: SectionHeaderCount: 6
# BEFORE: Type: PT_LOAD
# BEFORE-NEXT: Offset: 0x0
# BEFORE: Type: PT_LOAD
# BEFORE-NEXT: Offset: 0x240
# AFTER: SectionHeaderCount: 5
# AFTER: Type: PT_LOAD
# AFTER-NEXT: Offset: 0x0
# AFTER: Type: PT_LOAD
# AFTER-NEXT: Offset: 0xB0
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_EXEC
Machine: EM_X86_64
Sections:
- Name: .remove_me
Type: SHT_PROGBITS
Size: 0x10
- Name: .keep_me
Type: SHT_PROGBITS
Size: 0x10
ProgramHeaders:
- Type: PT_LOAD
Offset: 0
FileSize: 176 # sizeof(Elf64_Ehdr) + 2 * sizeof(Elf64_Phdr)
- Type: PT_LOAD
Sections:
- Section: .keep_me

View File

@ -0,0 +1,639 @@
# We want to preserve areas in segments that are not covered by section headers.
# This test shows that we do this for areas at the start of a segment, between
# sections in a segment, and after all sections in a segment.
# To create inputs with arbitrary data in segments, not covered by sections, we
# use yaml2obj to create segments with sections covering all areas, then remove
# some sections in those segments, and finally write over the areas of the
# removed sections using python.
# blob* sections are the sections that will be removed to create unlabelled
# areas and then overwritten with data to show we preserve the data.
# RUN: yaml2obj %s -o %t.base
# RUN: llvm-objcopy %t.base %t.stripped --regex -R blob.*
# Show that the removal leaves the bytes as zeroes, as desired, for all our
# test cases.
# RUN: od -t x1 -j 0x2000 -N 24 %t.stripped | FileCheck %s --check-prefix=CHECK1 -DPATTERN="00 00 00 00"
# RUN: od -t x1 -j 0x2100 -N 12 %t.stripped | FileCheck %s --check-prefix=CHECK2 -DPATTERN="00 00 00 00"
# RUN: od -t x1 -j 0x2200 -N 4 %t.stripped | FileCheck %s --check-prefix=CHECK3 -DPATTERN="00 00 00 00"
# RUN: od -t x1 -j 0x2300 -N 12 %t.stripped | FileCheck %s --check-prefix=CHECK4 -DPATTERN="00 00 00 00"
# RUN: od -t x1 -j 0x3000 -N 68 %t.stripped | FileCheck %s --check-prefix=CHECK5 -DPATTERN="00 00 00 00"
# RUN: od -t x1 -j 0x4000 -N 60 %t.stripped | FileCheck %s --check-prefix=CHECK6 -DPATTERN="00 00 00 00"
# RUN: od -t x1 -j 0x5000 -N 60 %t.stripped | FileCheck %s --check-prefix=CHECK7 -DPATTERN="00 00 00 00"
# RUN: cp %t.stripped %t.in
# RUN: echo "with open('%/t.in', 'r+') as input:" > %t.py
# RUN: echo " for offset in [" >> %t.py
# RUN: echo " 0x2000, 0x2008, 0x200C, 0x2014, 0x2104, 0x2300," >> %t.py
# RUN: echo " 0x3008, 0x3010, 0x3018, 0x3020, 0x3028, 0x302C, 0x3034, 0x303C," >> %t.py
# RUN: echo " 0x4000, 0x4008, 0x4010, 0x4014, 0x401C, 0x4024, 0x4034," >> %t.py
# RUN: echo " 0x5000, 0x5008, 0x5010, 0x501C, 0x5024, 0x502C, 0x5030, 0x5038]:" >> %t.py
# RUN: echo " input.seek(offset)" >> %t.py
# RUN: echo " input.write('\xDE\xAD\xBE\xEF')" >> %t.py
# RUN: %python %t.py
# RUN: llvm-objcopy %t.in %t.out
# RUN: od -t x1 -j 0x2000 -N 24 %t.out | FileCheck %s --check-prefix=CHECK1 -DPATTERN="de ad be ef"
# RUN: od -t x1 -j 0x2100 -N 12 %t.out | FileCheck %s --check-prefix=CHECK2 -DPATTERN="de ad be ef"
# RUN: od -t x1 -j 0x2200 -N 4 %t.out | FileCheck %s --check-prefix=CHECK3 -DPATTERN="de ad be ef"
# RUN: od -t x1 -j 0x2300 -N 12 %t.out | FileCheck %s --check-prefix=CHECK4 -DPATTERN="de ad be ef"
# RUN: od -t x1 -j 0x3000 -N 68 %t.out | FileCheck %s --check-prefix=CHECK5 -DPATTERN="de ad be ef"
# RUN: od -t x1 -j 0x4000 -N 60 %t.out | FileCheck %s --check-prefix=CHECK6 -DPATTERN="de ad be ef"
# RUN: od -t x1 -j 0x5000 -N 60 %t.out | FileCheck %s --check-prefix=CHECK7 -DPATTERN="de ad be ef"
# CHECK1: [[PATTERN]] 11 22 33 44 [[PATTERN]] [[PATTERN]]
# CHECK1-NEXT: 55 66 77 88 [[PATTERN]]
# CHECK2: 99 00 aa bb [[PATTERN]] cc dd ee ff
# CHECK3: fe fe fe fe
# CHECK4: [[PATTERN]] 00 00 00 00 00 00 00 00
# CHECK5: ff ff ee ee dd dd cc cc [[PATTERN]] bb bb aa aa
# CHECK5-NEXT: [[PATTERN]] 00 00 99 99 [[PATTERN]] 88 88 77 77
# CHECK5-NEXT: [[PATTERN]] 66 66 55 55 [[PATTERN]] [[PATTERN]]
# CHECK5-NEXT: 44 44 33 33 [[PATTERN]] 22 22 11 11 [[PATTERN]]
# CHECK5-NEXT: 00 11 22 33
# CHECK6: [[PATTERN]] 44 55 66 77 [[PATTERN]] 88 99 aa bb
# CHECK6-NEXT: [[PATTERN]] [[PATTERN]] cc dd ee ff [[PATTERN]]
# CHECK6-NEXT: ff ee dd cc [[PATTERN]] bb aa 99 88 77 66 55 44
# CHECK6-NEXT: 33 22 11 00 [[PATTERN]] 11 11 11 11
# CHECK7: [[PATTERN]] 12 34 56 78 [[PATTERN]] 90 ab cd ef
# CHECK7-NEXT: [[PATTERN]] fe dc ba 09 87 65 43 21 [[PATTERN]]
# CHECK7-NEXT: 22 22 22 22 [[PATTERN]] 33 33 33 33 [[PATTERN]]
# CHECK7-NEXT: [[PATTERN]] 44 44 44 44 [[PATTERN]]
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_EXEC
Machine: EM_X86_64
Sections:
- Name: blob1
Type: SHT_PROGBITS
Content: 'abbababa'
Address: 0x2000
AddressAlign: 0x2000
- Name: section1
Type: SHT_PROGBITS
Address: 0x2004
Content: '11223344'
- Name: blob2
Type: SHT_PROGBITS
Content: 'abbababa'
Address: 0x2008
- Name: section2
Type: SHT_NOBITS
Size: 4
Address: 0x200C
- Name: blob3
Type: SHT_PROGBITS
Content: 'abbababa'
Address: 0x2010
- Name: section3
Type: SHT_PROGBITS
Content: '55667788'
Address: 0x2014
- Name: blob4
Type: SHT_PROGBITS
Content: 'abbababa'
Address: 0x2018
- Name: section4
Type: SHT_PROGBITS
Content: '9900aabb'
Address: 0x2100
AddressAlign: 0x100
- Name: blob5
Type: SHT_PROGBITS
Content: 'abbababa'
Address: 0x2104
- Name: section5
Type: SHT_PROGBITS
Address: 0x2108
Content: 'ccddeeff'
- Name: section6
Type: SHT_PROGBITS
Content: 'fefefefe'
Address: 0x2200
AddressAlign: 0x100
- Name: blob6
Type: SHT_PROGBITS
Content: 'abbababa'
Address: 0x2300
AddressAlign: 0x100
- Name: sectionA
Type: SHT_PROGBITS
Content: 'ffffeeee'
Address: 0x3000
AddressAlign: 0x1000
- Name: sectionB
Type: SHT_PROGBITS
Content: 'ddddcccc'
Address: 0x3004
- Name: blobA
Type: SHT_PROGBITS
Content: 'abbababa'
Address: 0x3008
- Name: sectionC
Type: SHT_PROGBITS
Content: 'bbbbaaaa'
Address: 0x300C
- Name: blobB
Type: SHT_PROGBITS
Content: 'abbababa'
Address: 0x3010
- Name: sectionD
Type: SHT_PROGBITS
Content: '00009999'
Address: 0x3014
- Name: blobC
Type: SHT_PROGBITS
Content: 'abbababa'
Address: 0x3018
- Name: sectionE
Type: SHT_PROGBITS
Content: '88887777'
Address: 0x301C
- Name: blobD
Type: SHT_PROGBITS
Content: 'abbababa'
Address: 0x3020
- Name: sectionF
Type: SHT_PROGBITS
Content: '66665555'
Address: 0x3024
- Name: blobE
Type: SHT_PROGBITS
Content: 'abbababa'
Address: 0x3028
- Name: blobF
Type: SHT_PROGBITS
Content: 'abbababa'
Address: 0x302C
- Name: sectionG
Type: SHT_PROGBITS
Content: '44443333'
Address: 0x3030
- Name: blobG
Type: SHT_PROGBITS
Content: 'abbababa'
Address: 0x3034
- Name: sectionH
Type: SHT_PROGBITS
Content: '22221111'
Address: 0x3038
- Name: blobH
Type: SHT_PROGBITS
Content: 'abbababa'
Address: 0x303C
- Name: sectionI
Type: SHT_PROGBITS
Content: '00112233'
Address: 0x3040
- Name: blobz
Type: SHT_PROGBITS
Content: 'abbababa'
Address: 0x4000
AddressAlign: 0x1000
- Name: sectionz
Type: SHT_PROGBITS
Content: '44556677'
Address: 0x4004
- Name: bloby
Type: SHT_PROGBITS
Content: 'abbababa'
Address: 0x4008
- Name: sectiony
Type: SHT_PROGBITS
Content: '8899aabb'
Address: 0x400C
- Name: blobx
Type: SHT_PROGBITS
Content: 'abbababa'
Address: 0x4010
- Name: blobw
Type: SHT_PROGBITS
Content: 'abbababa'
Address: 0x4014
- Name: sectionx
Type: SHT_PROGBITS
Content: 'ccddeeff'
Address: 0x4018
- Name: blobv
Type: SHT_PROGBITS
Content: 'abbababa'
Address: 0x401C
- Name: sectionw
Type: SHT_PROGBITS
Content: 'ffeeddcc'
Address: 0x4020
- Name: blobu
Type: SHT_PROGBITS
Content: 'abbababa'
Address: 0x4024
- Name: sectionv
Type: SHT_PROGBITS
Content: 'bbaa9988'
Address: 0x4028
- Name: sectionu
Type: SHT_PROGBITS
Content: '77665544'
Address: 0x402C
- Name: sectiont
Type: SHT_PROGBITS
Content: '33221100'
Address: 0x4030
- Name: blobt
Type: SHT_PROGBITS
Content: 'abbababa'
Address: 0x4034
- Name: sections
Type: SHT_PROGBITS
Content: '11111111'
Address: 0x4038
- Name: bloba
Type: SHT_PROGBITS
Content: 'abbababa'
Address: 0x5000
AddressAlign: 0x1000
- Name: sectiona
Type: SHT_PROGBITS
Content: '12345678'
Address: 0x5004
- Name: blobb
Type: SHT_PROGBITS
Content: 'abbababa'
Address: 0x5008
- Name: sectionb
Type: SHT_PROGBITS
Content: '90abcdef'
Address: 0x500C
- Name: blobc
Type: SHT_PROGBITS
Content: 'abbababa'
Address: 0x5010
- Name: sectionc
Type: SHT_PROGBITS
Content: 'fedcba09'
Address: 0x5014
- Name: sectiond
Type: SHT_PROGBITS
Content: '87654321'
Address: 0x5018
- Name: blobd
Type: SHT_PROGBITS
Content: 'abbababa'
Address: 0x501C
- Name: sectione
Type: SHT_PROGBITS
Content: '22222222'
Address: 0x5020
- Name: blobe
Type: SHT_PROGBITS
Content: 'abbababa'
Address: 0x5024
- Name: sectionf
Type: SHT_PROGBITS
Content: '33333333'
Address: 0x5028
- Name: blobf
Type: SHT_PROGBITS
Content: 'abbababa'
Address: 0x502C
- Name: blobg
Type: SHT_PROGBITS
Content: 'abbababa'
Address: 0x5030
- Name: sectiong
Type: SHT_PROGBITS
Content: '44444444'
Address: 0x5034
- Name: blobh
Type: SHT_PROGBITS
Content: 'abbababa'
Address: 0x5038
ProgramHeaders:
# First segment has unlabelled space at start and end.
- Type: 0x6ABCDEF0 # Non-specific segment type.
VAddr: 0x2000
PAddr: 0x2000
Align: 0x2000
Sections:
- Section: blob1
- Section: section1
- Section: blob2
- Section: section2 # nobits
- Section: blob3
- Section: section3
- Section: blob4
# Second segment has sections at start and end.
- Type: 0x6ABCDEF0
VAddr: 0x2100
PAddr: 0x2100
Align: 0x100
Sections:
- Section: section4
- Section: blob5
- Section: section5
# Third segment is all covered by a section.
- Type: 0x6ABCDEF0
VAddr: 0x2200
PAddr: 0x2200
Align: 0x100
Sections:
- Section: section6
# Fourth segment has no sections (after removing blob headers).
- Type: 0x6ABCDEF0
VAddr: 0x2300
PAddr: 0x2300
Align: 0x100
Sections:
- Section: blob6
# Fifth segment is empty.
- Type: 0x6ABCDEF0
VAddr: 0x2308
PAddr: 0x2308
Offset: 0x2308
# The next few segments test behaviour of fully nested segments.
# Sixth segment is the "parent" segment.
- Type: 0x6ABCDEF0
VAddr: 0x3000
PAddr: 0x3000
Align: 0x1000
Sections:
- Section: sectionA
- Section: sectionB
- Section: blobA
- Section: sectionC
- Section: blobB
- Section: sectionD
- Section: blobC
- Section: sectionE
- Section: blobD
- Section: sectionF
- Section: blobE
- Section: blobF
- Section: sectionG
- Section: blobG
- Section: sectionH
- Section: blobH
- Section: sectionI
# Seventh segment is empty and nested.
- Type: 0x6ABCDEF0
VAddr: 0x3002
PAddr: 0x3002
Offset: 0x3002
# Eighth segment contains only a section and is nested.
- Type: 0x6ABCDEF0
VAddr: 0x3004
PAddr: 0x3004
Sections:
- Section: sectionB
# Ninth segment contains only unlabelled space and is nested.
- Type: 0x6ABCDEF0
VAddr: 0x3008
PAddr: 0x3008
Sections:
- Section: blobA
# Tenth segment contains two sections with space between and is nested.
- Type: 0x6ABCDEF0
VAddr: 0x300C
PAddr: 0x300C
Sections:
- Section: sectionC
- Section: blobB
- Section: sectionD
# Eleventh segment contains two sections with space between and at ends and is nested.
- Type: 0x6ABCDEF0
VAddr: 0x3018
PAddr: 0x3018
Sections:
- Section: blobC
- Section: sectionE
- Section: blobD
- Section: sectionF
- Section: blobE
# Twelfth segment contains one section with space at ends adjacent to space in parent segment.
- Type: 0x6ABCDEF0
VAddr: 0x302E
PAddr: 0x302E
Offset: 0x302E
FileSize: 8
Sections:
- Section: sectionG
# Thirteenth segment contains overlaps sections at either end in parent segment.
- Type: 0x6ABCDEF0
VAddr: 0x303A
PAddr: 0x303A
Offset: 0x303A
FileSize: 0x8
Sections:
- Section: blobH
# The next batch of segments are segments that only partially overlap other segments.
# Segment14: |-unlabelled-|-Sec-|
# Segment15: |--|-Sec-|-unlabelled-|
- Type: 0x6ABCDEF0
VAddr: 0x4000
PAddr: 0x4000
Sections:
- Section: blobz
- Section: sectionz
- Type: 0x6ABCDEF0
VAddr: 0x4002
PAddr: 0x4002
Offset: 0x4002
Sections:
- Section: sectionz
- Section: bloby
# Segment16: |-Sec-|--|
# Segment17: |--|----unlabelled---|
- Type: 0x6ABCDEF0
VAddr: 0x400C
PAddr: 0x400C
FileSize: 6
Sections:
- Section: sectiony
- Type: 0x6ABCDEF0
VAddr: 0x400E
PAddr: 0x400E
Offset: 0x400E
Sections:
- Section: blobx
# Segment18: |-unlabelled-|-Sec-|
# Segment19: |-Sec-|-unlabelled-|
- Type: 0x6ABCDEF0
VAddr: 0x4014
PAddr: 0x4014
Sections:
- Section: blobw
- Section: sectionx
- Type: 0x6ABCDEF0
VAddr: 0x4018
PAddr: 0x4018
Sections:
- Section: sectionx
- Section: blobv
# Segment20: |-Sec-|
# Segment21: |--|-unlabelled-|-Sec-|
- Type: 0x6ABCDEF0
VAddr: 0x4020
PAddr: 0x4020
Sections:
- Section: sectionw
- Type: 0x6ABCDEF0
VAddr: 0x4022
PAddr: 0x4022
Offset: 0x4022
Sections:
- Section: blobu
- Section: sectionv
# Segment22: |-Sec-|
# Segment23: |--|-Sec-|
- Type: 0x6ABCDEF0
VAddr: 0x402C
PAddr: 0x402C
Sections:
- Section: sectionu
- Type: 0x6ABCDEF0
VAddr: 0x402E
PAddr: 0x402E
Offset: 0x402E
Sections:
- Section: sectiont
# Segment24: |-unlabelled-|--|
# Segment25: |--Sec--|
- Type: 0x6ABCDEF0
VAddr: 0x4034
PAddr: 0x4034
FileSize: 6
Sections:
- Section: blobt
- Type: 0x6ABCDEF0
VAddr: 0x4038
PAddr: 0x4038
Sections:
- Section: sections
# The next batch of segments represent groups of three nested/overlapping segments,
# with one parent segment containing two overlapping segments.
# Segment26: |-unlabelled-|-Sec-|-unlabelled-|
# Segment27: |------------|--|
# Segment28: |-Sec-|------------|
- Type: 0x6ABCDEF0
VAddr: 0x5000
PAddr: 0x5000
Align: 0x1000
Sections:
- Section: bloba
- Section: sectiona
- Section: blobb
- Type: 0x6ABCDEF0
VAddr: 0x5000
PAddr: 0x5000
FileSize: 6
Sections:
- Section: bloba
- Type: 0x6ABCDEF0
VAddr: 0x5004
PAddr: 0x5004
Sections:
- Section: sectiona
- Section: blobb
# Segment29: |-Sec-|-unlabelled-|-Sec-|
# Segment30: |-Sec-|--------|
# Segment31: |---------|-Sec-|
- Type: 0x6ABCDEF0
VAddr: 0x500C
PAddr: 0x500C
Sections:
- Section: sectionb
- Section: blobc
- Section: sectionc
- Type: 0x6ABCDEF0
VAddr: 0x500C
PAddr: 0x500C
FileSize: 7
Sections:
- Section: sectionb
- Type: 0x6ABCDEF0
VAddr: 0x5011
PAddr: 0x5011
Offset: 0x5011
Sections:
- Section: sectionc
# Segment32: |-Sec-|-unlabelled-|-Sec-|
# Segment33: |-Sec-|------------|
# Segment34: |------------|-Sec-|
- Type: 0x6ABCDEF0
VAddr: 0x5018
PAddr: 0x5018
Sections:
- Section: sectiond
- Section: blobd
- Section: sectione
- Type: 0x6ABCDEF0
VAddr: 0x5018
PAddr: 0x5018
Sections:
- Section: sectiond
- Section: blobd
- Type: 0x6ABCDEF0
VAddr: 0x501C
PAddr: 0x501C
Sections:
- Section: blobd
- Section: sectione
# Segment35: |-unlabelled-|-Sec-|-unlabelled-|
# Segment36: |------------|-Sec-|
# Segment37: |-Sec-|------------|
- Type: 0x6ABCDEF0
VAddr: 0x5024
PAddr: 0x5024
Sections:
- Section: blobe
- Section: sectionf
- Section: blobf
- Type: 0x6ABCDEF0
VAddr: 0x5024
PAddr: 0x5024
Sections:
- Section: blobe
- Section: sectionf
- Type: 0x6ABCDEF0
VAddr: 0x5028
PAddr: 0x5028
Sections:
- Section: sectionf
- Section: blobf
# Segment38: |-unlabelled-|-Sec-|-unlabelled-|
# Segment39: |------------|---|
# Segment40: |---|------------|
- Type: 0x6ABCDEF0
VAddr: 0x5030
PAddr: 0x5030
Sections:
- Section: blobg
- Section: sectiong
- Section: blobh
- Type: 0x6ABCDEF0
VAddr: 0x5030
PAddr: 0x5030
FileSize: 7
Sections:
- Section: blobg
- Type: 0x6ABCDEF0
VAddr: 0x5035
PAddr: 0x5035
Offset: 0x5035
Sections:
- Section: blobh

View File

@ -906,7 +906,9 @@ template <class ELFT> void ELFBuilder<ELFT>::setParentSegment(Segment &Child) {
template <class ELFT> void ELFBuilder<ELFT>::readProgramHeaders() {
uint32_t Index = 0;
for (const auto &Phdr : unwrapOrError(ElfFile.program_headers())) {
Segment &Seg = Obj.addSegment();
ArrayRef<uint8_t> Data{ElfFile.base() + Phdr.p_offset,
(size_t)Phdr.p_filesz};
Segment &Seg = Obj.addSegment(Data);
Seg.Type = Phdr.p_type;
Seg.Flags = Phdr.p_flags;
Seg.OriginalOffset = Phdr.p_offset;
@ -1350,7 +1352,31 @@ template <class ELFT> void ELFWriter<ELFT>::writeShdrs() {
template <class ELFT> void ELFWriter<ELFT>::writeSectionData() {
for (auto &Sec : Obj.sections())
Sec.accept(*SecWriter);
// Segments are responsible for writing their contents, so only write the
// section data if the section is not in a segment. Note that this renders
// sections in segments effectively immutable.
if (Sec.ParentSegment == nullptr)
Sec.accept(*SecWriter);
}
template <class ELFT> void ELFWriter<ELFT>::writeSegmentData() {
for (Segment &Seg : Obj.segments()) {
uint8_t *B = Buf.getBufferStart() + Seg.Offset;
assert(Seg.FileSize == Seg.getContents().size() &&
"Segment size must match contents size");
std::memcpy(B, Seg.getContents().data(), Seg.FileSize);
}
// Iterate over removed sections and overwrite their old data with zeroes.
for (auto &Sec : Obj.removedSections()) {
Segment *Parent = Sec.ParentSegment;
if (Parent == nullptr || Sec.Type == SHT_NOBITS || Sec.Size == 0)
continue;
uint64_t Offset =
Sec.OriginalOffset - Parent->OriginalOffset + Parent->Offset;
uint8_t *B = Buf.getBufferStart();
std::memset(B + Offset, 0, Sec.Size);
}
}
Error Object::removeSections(
@ -1396,7 +1422,10 @@ Error Object::removeSections(
return E;
}
// Now finally get rid of them all togethor.
// Transfer removed sections into the Object RemovedSections container for use
// later.
std::move(Iter, Sections.end(), std::back_inserter(RemovedSections));
// Now finally get rid of them all together.
Sections.erase(Iter, std::end(Sections));
return Error::success();
}
@ -1542,6 +1571,9 @@ template <class ELFT> size_t ELFWriter<ELFT>::totalSize() const {
}
template <class ELFT> Error ELFWriter<ELFT>::write() {
// Segment data must be written first, so that the ELF header and program
// header tables can overwrite it, if covered by a segment.
writeSegmentData();
writeEhdr();
writePhdrs();
writeSectionData();

View File

@ -215,6 +215,7 @@ private:
void writePhdrs();
void writeShdrs();
void writeSectionData();
void writeSegmentData();
void assignOffsets();
@ -312,6 +313,10 @@ public:
uint32_t Index;
uint64_t OriginalOffset;
Segment *ParentSegment = nullptr;
ArrayRef<uint8_t> Contents;
explicit Segment(ArrayRef<uint8_t> Data) : Contents(Data) {}
Segment() {}
const SectionBase *firstSection() const {
if (!Sections.empty())
@ -321,6 +326,8 @@ public:
void removeSection(const SectionBase *Sec) { Sections.erase(Sec); }
void addSection(const SectionBase *Sec) { Sections.insert(Sec); }
ArrayRef<uint8_t> getContents() const { return Contents; }
};
class Section : public SectionBase {
@ -773,6 +780,7 @@ private:
std::vector<SecPtr> Sections;
std::vector<SegPtr> Segments;
std::vector<SecPtr> RemovedSections;
public:
template <class T>
@ -815,6 +823,8 @@ public:
find_if(Sections, [&](const SecPtr &Sec) { return Sec->Name == Name; });
return SecIt == Sections.end() ? nullptr : SecIt->get();
}
SectionTableRef removedSections() { return SectionTableRef(RemovedSections); }
Range<Segment> segments() { return make_pointee_range(Segments); }
ConstRange<Segment> segments() const { return make_pointee_range(Segments); }
@ -827,8 +837,8 @@ public:
Ptr->Index = Sections.size();
return *Ptr;
}
Segment &addSegment() {
Segments.emplace_back(llvm::make_unique<Segment>());
Segment &addSegment(ArrayRef<uint8_t> Data) {
Segments.emplace_back(llvm::make_unique<Segment>(Data));
return *Segments.back();
}
};