зеркало из https://github.com/mozilla/gecko-dev.git
378 строки
18 KiB
Diff
378 строки
18 KiB
Diff
From 74c7d422cba163635394ec32f2b243b1de502a18 Mon Sep 17 00:00:00 2001
|
|
From: Martin Storsjo <martin@martin.st>
|
|
Date: Wed, 23 Jan 2019 11:54:51 +0000
|
|
Subject: [PATCH] [llvm-objcopy] [COFF] Fix handling of aux symbols for big
|
|
objects
|
|
|
|
The aux symbols were stored in an opaque std::vector<uint8_t>,
|
|
with contents interpreted according to the rest of the symbol.
|
|
|
|
All aux symbol types but one fit in 18 bytes (sizeof(coff_symbol16)),
|
|
and if written to a bigobj, two extra padding bytes are written (as
|
|
sizeof(coff_symbol32) is 20). In the storage agnostic intermediate
|
|
representation, store the aux symbols as a series of coff_symbol16
|
|
sized opaque blobs. (In practice, all such aux symbols only consist
|
|
of one aux symbol, so this is more flexible than what reality needs.)
|
|
|
|
The special case is the file aux symbols, which are written in
|
|
potentially more than one aux symbol slot, without any padding,
|
|
as one single long string. This can't be stored in the same opaque
|
|
vector of fixed sized aux symbol entries. The file aux symbols will
|
|
occupy a different number of aux symbol slots depending on the type
|
|
of output object file. As nothing in the intermediate process needs
|
|
to have accurate raw symbol indices, updating that is moved into the
|
|
writer class.
|
|
|
|
Differential Revision: https://reviews.llvm.org/D57009
|
|
|
|
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351947 91177308-0d34-0410-b5e6-96231b3b80d8
|
|
---
|
|
.../llvm-objcopy/COFF/Inputs/bigobj.o.gz | Bin 0 -> 7841 bytes
|
|
test/tools/llvm-objcopy/COFF/bigobj.test | 35 +++++++++++++
|
|
.../llvm-objcopy/ELF/auto-remove-shndx.test | 2 +-
|
|
.../tools/llvm-objcopy/ELF/many-sections.test | 2 +-
|
|
test/tools/llvm-objcopy/ELF/remove-shndx.test | 2 +-
|
|
.../tools/llvm-objcopy/ELF/strict-no-add.test | 2 +-
|
|
.../llvm-objcopy/{ELF => }/Inputs/ungzip.py | 0
|
|
tools/llvm-objcopy/COFF/COFFObjcopy.cpp | 6 +--
|
|
tools/llvm-objcopy/COFF/Object.cpp | 6 +--
|
|
tools/llvm-objcopy/COFF/Object.h | 18 ++++++-
|
|
tools/llvm-objcopy/COFF/Reader.cpp | 21 ++++++--
|
|
tools/llvm-objcopy/COFF/Writer.cpp | 49 +++++++++++++-----
|
|
tools/llvm-objcopy/COFF/Writer.h | 2 +-
|
|
13 files changed, 115 insertions(+), 30 deletions(-)
|
|
create mode 100644 test/tools/llvm-objcopy/COFF/Inputs/bigobj.o.gz
|
|
create mode 100644 test/tools/llvm-objcopy/COFF/bigobj.test
|
|
rename test/tools/llvm-objcopy/{ELF => }/Inputs/ungzip.py (100%)
|
|
|
|
diff --git a/llvm/test/tools/llvm-objcopy/COFF/Inputs/bigobj.o.gz b/llvm/test/tools/llvm-objcopy/COFF/Inputs/bigobj.o.gz
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..6435f4785ff76e0c6bca12f3e57bc6ad8888bece
|
|
GIT binary patch
|
|
literal 7841
|
|
zcmb2|=3r3v^@w3&etUMmo^zoH`-kGKM_vfJsF<z%6+Sz#g6qq)pf0Hj#_r`4B7DML
|
|
zW(h1l`+!x)t@&W-R@I~lyKmU3Ti&1Z=iKur;uBMy1MR!_ywlsouYY&-*4H1mU!Qw=
|
|
z`RpIDkw;!V4(WOF_)B3`(Vt|~S>?L-b)Wx@^wig`HIMAw|N8V<v65oeyETs611{)_
|
|
zm27RwTe)ENN|7SLgM~83N6}~qjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kinXb6mk
|
|
zz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kgRokHNw|D97mKRo|%+Z6Ym
|
|
z*X{Ku$4#4*Vqm}gyYR^b^Sc?_E*<<cFE#Q=*rt6OBmJeLZ=aoe_u9R>-w!^l5biDe
|
|
p{d@nvw*mU6<NG83=jxn4_wt_G?yUy#YeOF~KhH^=cj<;Y0{~9Br>p<~
|
|
|
|
literal 0
|
|
HcmV?d00001
|
|
|
|
diff --git a/llvm/test/tools/llvm-objcopy/COFF/bigobj.test b/llvm/test/tools/llvm-objcopy/COFF/bigobj.test
|
|
new file mode 100644
|
|
index 00000000000..17968f12b8a
|
|
--- /dev/null
|
|
+++ b/llvm/test/tools/llvm-objcopy/COFF/bigobj.test
|
|
@@ -0,0 +1,35 @@
|
|
+RUN: %python %p/../Inputs/ungzip.py %p/Inputs/bigobj.o.gz > %t.in.o
|
|
+
|
|
+RUN: llvm-objdump -t %t.in.o | FileCheck %s --check-prefixes=SYMBOLS,SYMBOLS-BIG,SYMBOLS-ORIG
|
|
+
|
|
+# Do a plain copy, to check that section numbers in symbols referring
|
|
+# to sections outside of the small object format are handled correctly.
|
|
+RUN: llvm-objcopy -R '.text$4' %t.in.o %t.small.o
|
|
+RUN: llvm-objdump -t %t.in.o | FileCheck %s --check-prefixes=SYMBOLS,SYMBOLS-BIG,SYMBOLS-ORIG
|
|
+
|
|
+# Remove a section, making the section count fit into a small object.
|
|
+RUN: llvm-objcopy -R '.text$4' %t.in.o %t.small.o
|
|
+RUN: llvm-objdump -t %t.small.o | FileCheck %s --check-prefixes=SYMBOLS,SYMBOLS-SMALL,SYMBOLS-REMOVED-SMALL
|
|
+
|
|
+# Add a .gnu_debuglink section, forcing the object back to big format.
|
|
+RUN: llvm-objcopy --add-gnu-debuglink=%t.in.o %t.small.o %t.big.o
|
|
+ llvm-objdump -t %t.big.o | FileCheck %s --check-prefixes=SYMBOLS,SYMBOLS-BIG,SYMBOLS-REMOVED-BIG
|
|
+
|
|
+# In big object format, the .file symbol occupies one symbol table entry for
|
|
+# the auxillary data, but needs two entries in the small format, forcing the
|
|
+# raw symbol indices of later symbols to change.
|
|
+SYMBOLS: SYMBOL TABLE:
|
|
+SYMBOLS-NEXT: [ 0]{{.*}} (nx 1) {{.*}} .text
|
|
+SYMBOLS-NEXT: AUX scnlen
|
|
+SYMBOLS-SMALL-NEXT: [ 2]{{.*}} (nx 2) {{.*}} .file
|
|
+SYMBOLS-BIG-NEXT: [ 2]{{.*}} (nx 1) {{.*}} .file
|
|
+SYMBOLS-NEXT: AUX abcdefghijklmnopqrs
|
|
+SYMBOLS-SMALL-NEXT: [ 5]{{.*}} (nx 0) {{.*}} foo
|
|
+SYMBOLS-BIG-NEXT: [ 4]{{.*}} (nx 0) {{.*}} foo
|
|
+
|
|
+# Check that the section numbers outside of signed 16 bit int range
|
|
+# are represented properly. After removing one section, the section
|
|
+# numbers decrease.
|
|
+SYMBOLS-ORIG: [ 5](sec 65280){{.*}} symbol65280
|
|
+SYMBOLS-REMOVED-SMALL: [ 6](sec 65279){{.*}} symbol65280
|
|
+SYMBOLS-REMOVED-BIG: [ 5](sec 65279){{.*}} symbol65280
|
|
diff --git a/llvm/test/tools/llvm-objcopy/ELF/auto-remove-shndx.test b/llvm/test/tools/llvm-objcopy/ELF/auto-remove-shndx.test
|
|
index 5a23493fa94..8e6c788bf48 100644
|
|
--- a/llvm/test/tools/llvm-objcopy/ELF/auto-remove-shndx.test
|
|
+++ b/llvm/test/tools/llvm-objcopy/ELF/auto-remove-shndx.test
|
|
@@ -1,4 +1,4 @@
|
|
-# RUN: %python %p/Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t
|
|
+# RUN: %python %p/../Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t
|
|
# RUN: llvm-objcopy -R .text -R s0 -R s1 -R s2 -R s3 -R s4 -R s5 -R s6 %t %t2
|
|
# RUN: llvm-readobj --sections %t2 | FileCheck --check-prefix=SECS %s
|
|
|
|
diff --git a/llvm/test/tools/llvm-objcopy/ELF/many-sections.test b/llvm/test/tools/llvm-objcopy/ELF/many-sections.test
|
|
index 57239f32e4a..1dd41cfb10c 100644
|
|
--- a/llvm/test/tools/llvm-objcopy/ELF/many-sections.test
|
|
+++ b/llvm/test/tools/llvm-objcopy/ELF/many-sections.test
|
|
@@ -1,4 +1,4 @@
|
|
-RUN: %python %p/Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t
|
|
+RUN: %python %p/../Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t
|
|
RUN: llvm-objcopy %t %t2
|
|
RUN: llvm-readobj --file-headers %t2 | FileCheck --check-prefix=EHDR %s
|
|
RUN: llvm-readobj --sections %t2 | FileCheck --check-prefix=SECS %s
|
|
diff --git a/llvm/test/tools/llvm-objcopy/ELF/remove-shndx.test b/llvm/test/tools/llvm-objcopy/ELF/remove-shndx.test
|
|
index 6cc3a1a291f..53ca8e7f220 100644
|
|
--- a/llvm/test/tools/llvm-objcopy/ELF/remove-shndx.test
|
|
+++ b/llvm/test/tools/llvm-objcopy/ELF/remove-shndx.test
|
|
@@ -1,6 +1,6 @@
|
|
# This test checks to see that a .symtab_shndx section is added to any binary
|
|
# that needs it, even if the original was removed.
|
|
-RUN: %python %p/Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t
|
|
+RUN: %python %p/../Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t
|
|
RUN: llvm-objcopy -R .symtab_shndx %t %t2
|
|
RUN: llvm-readobj --sections %t2 | FileCheck %s
|
|
|
|
diff --git a/llvm/test/tools/llvm-objcopy/ELF/strict-no-add.test b/llvm/test/tools/llvm-objcopy/ELF/strict-no-add.test
|
|
index 4f24df31bf9..348ab7c4fbd 100644
|
|
--- a/llvm/test/tools/llvm-objcopy/ELF/strict-no-add.test
|
|
+++ b/llvm/test/tools/llvm-objcopy/ELF/strict-no-add.test
|
|
@@ -1,7 +1,7 @@
|
|
# This test makes sure that sections added at the end that don't have symbols
|
|
# defined in them don't trigger the creation of a large index table.
|
|
|
|
-RUN: %python %p/Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t.0
|
|
+RUN: %python %p/../Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t.0
|
|
RUN: cat %p/Inputs/alloc-symtab.o > %t
|
|
RUN: llvm-objcopy -R .text -R s0 -R s1 -R s2 -R s3 -R s4 -R s5 -R s6 %t.0 %t2
|
|
RUN: llvm-objcopy --add-section=.s0=%t --add-section=.s1=%t --add-section=.s2=%t %t2 %t2
|
|
diff --git a/llvm/test/tools/llvm-objcopy/ELF/Inputs/ungzip.py b/llvm/test/tools/llvm-objcopy/Inputs/ungzip.py
|
|
similarity index 100%
|
|
rename from test/tools/llvm-objcopy/ELF/Inputs/ungzip.py
|
|
rename to test/tools/llvm-objcopy/Inputs/ungzip.py
|
|
diff --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
|
|
index 20adbe11e7a..64b4e79a4e0 100644
|
|
--- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
|
|
+++ b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
|
|
@@ -37,7 +37,7 @@ static uint64_t getNextRVA(const Object &Obj) {
|
|
return 0;
|
|
const Section &Last = Obj.getSections().back();
|
|
return alignTo(Last.Header.VirtualAddress + Last.Header.VirtualSize,
|
|
- Obj.PeHeader.SectionAlignment);
|
|
+ Obj.IsPE ? Obj.PeHeader.SectionAlignment : 1);
|
|
}
|
|
|
|
static uint32_t getCRC32(StringRef Data) {
|
|
@@ -74,8 +74,8 @@ static void addGnuDebugLink(Object &Obj, StringRef DebugLinkFile) {
|
|
Sec.Name = ".gnu_debuglink";
|
|
Sec.Header.VirtualSize = Sec.getContents().size();
|
|
Sec.Header.VirtualAddress = StartRVA;
|
|
- Sec.Header.SizeOfRawData =
|
|
- alignTo(Sec.Header.VirtualSize, Obj.PeHeader.FileAlignment);
|
|
+ Sec.Header.SizeOfRawData = alignTo(Sec.Header.VirtualSize,
|
|
+ Obj.IsPE ? Obj.PeHeader.FileAlignment : 1);
|
|
// Sec.Header.PointerToRawData is filled in by the writer.
|
|
Sec.Header.PointerToRelocations = 0;
|
|
Sec.Header.PointerToLinenumbers = 0;
|
|
diff --git a/llvm/tools/llvm-objcopy/COFF/Object.cpp b/llvm/tools/llvm-objcopy/COFF/Object.cpp
|
|
index 8c382c1faef..0ad5a05a144 100644
|
|
--- a/llvm/tools/llvm-objcopy/COFF/Object.cpp
|
|
+++ b/llvm/tools/llvm-objcopy/COFF/Object.cpp
|
|
@@ -26,12 +26,8 @@ void Object::addSymbols(ArrayRef<Symbol> NewSymbols) {
|
|
|
|
void Object::updateSymbols() {
|
|
SymbolMap = DenseMap<size_t, Symbol *>(Symbols.size());
|
|
- size_t RawSymIndex = 0;
|
|
- for (Symbol &Sym : Symbols) {
|
|
+ for (Symbol &Sym : Symbols)
|
|
SymbolMap[Sym.UniqueId] = &Sym;
|
|
- Sym.RawIndex = RawSymIndex;
|
|
- RawSymIndex += 1 + Sym.Sym.NumberOfAuxSymbols;
|
|
- }
|
|
}
|
|
|
|
const Symbol *Object::findSymbol(size_t UniqueId) const {
|
|
diff --git a/llvm/tools/llvm-objcopy/COFF/Object.h b/llvm/tools/llvm-objcopy/COFF/Object.h
|
|
index afa272286ef..21475b06862 100644
|
|
--- a/llvm/tools/llvm-objcopy/COFF/Object.h
|
|
+++ b/llvm/tools/llvm-objcopy/COFF/Object.h
|
|
@@ -66,10 +66,24 @@ private:
|
|
std::vector<uint8_t> OwnedContents;
|
|
};
|
|
|
|
+struct AuxSymbol {
|
|
+ AuxSymbol(ArrayRef<uint8_t> In) {
|
|
+ assert(In.size() == sizeof(Opaque));
|
|
+ std::copy(In.begin(), In.end(), Opaque);
|
|
+ }
|
|
+
|
|
+ ArrayRef<uint8_t> getRef() const {
|
|
+ return ArrayRef<uint8_t>(Opaque, sizeof(Opaque));
|
|
+ }
|
|
+
|
|
+ uint8_t Opaque[sizeof(object::coff_symbol16)];
|
|
+};
|
|
+
|
|
struct Symbol {
|
|
object::coff_symbol32 Sym;
|
|
StringRef Name;
|
|
- std::vector<uint8_t> AuxData;
|
|
+ std::vector<AuxSymbol> AuxData;
|
|
+ StringRef AuxFile;
|
|
ssize_t TargetSectionId;
|
|
ssize_t AssociativeComdatTargetSectionId = 0;
|
|
Optional<size_t> WeakTargetSymbolId;
|
|
@@ -132,7 +146,7 @@ private:
|
|
|
|
ssize_t NextSectionUniqueId = 1; // Allow a UniqueId 0 to mean undefined.
|
|
|
|
- // Update SymbolMap and RawIndex in each Symbol.
|
|
+ // Update SymbolMap.
|
|
void updateSymbols();
|
|
|
|
// Update SectionMap and Index in each Section.
|
|
diff --git a/llvm/tools/llvm-objcopy/COFF/Reader.cpp b/llvm/tools/llvm-objcopy/COFF/Reader.cpp
|
|
index 87dd60a43cf..7270bbf94de 100644
|
|
--- a/llvm/tools/llvm-objcopy/COFF/Reader.cpp
|
|
+++ b/llvm/tools/llvm-objcopy/COFF/Reader.cpp
|
|
@@ -107,9 +107,24 @@ Error COFFReader::readSymbols(Object &Obj, bool IsBigObj) const {
|
|
*reinterpret_cast<const coff_symbol16 *>(SymRef.getRawPtr()));
|
|
if (auto EC = COFFObj.getSymbolName(SymRef, Sym.Name))
|
|
return errorCodeToError(EC);
|
|
- Sym.AuxData = COFFObj.getSymbolAuxData(SymRef);
|
|
- assert((Sym.AuxData.size() %
|
|
- (IsBigObj ? sizeof(coff_symbol32) : sizeof(coff_symbol16))) == 0);
|
|
+
|
|
+ ArrayRef<uint8_t> AuxData = COFFObj.getSymbolAuxData(SymRef);
|
|
+ size_t SymSize = IsBigObj ? sizeof(coff_symbol32) : sizeof(coff_symbol16);
|
|
+ assert(AuxData.size() == SymSize * SymRef.getNumberOfAuxSymbols());
|
|
+ // The auxillary symbols are structs of sizeof(coff_symbol16) each.
|
|
+ // In the big object format (where symbols are coff_symbol32), each
|
|
+ // auxillary symbol is padded with 2 bytes at the end. Copy each
|
|
+ // auxillary symbol to the Sym.AuxData vector. For file symbols,
|
|
+ // the whole range of aux symbols are interpreted as one null padded
|
|
+ // string instead.
|
|
+ if (SymRef.isFileRecord())
|
|
+ Sym.AuxFile = StringRef(reinterpret_cast<const char *>(AuxData.data()),
|
|
+ AuxData.size())
|
|
+ .rtrim('\0');
|
|
+ else
|
|
+ for (size_t I = 0; I < SymRef.getNumberOfAuxSymbols(); I++)
|
|
+ Sym.AuxData.push_back(AuxData.slice(I * SymSize, sizeof(AuxSymbol)));
|
|
+
|
|
// Find the unique id of the section
|
|
if (SymRef.getSectionNumber() <=
|
|
0) // Special symbol (undefined/absolute/debug)
|
|
diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.cpp b/llvm/tools/llvm-objcopy/COFF/Writer.cpp
|
|
index db897e2ff33..6e69c597217 100644
|
|
--- a/llvm/tools/llvm-objcopy/COFF/Writer.cpp
|
|
+++ b/llvm/tools/llvm-objcopy/COFF/Writer.cpp
|
|
@@ -55,7 +55,8 @@ Error COFFWriter::finalizeSymbolContents() {
|
|
if (Sym.Sym.NumberOfAuxSymbols == 1 &&
|
|
Sym.Sym.StorageClass == IMAGE_SYM_CLASS_STATIC) {
|
|
coff_aux_section_definition *SD =
|
|
- reinterpret_cast<coff_aux_section_definition *>(Sym.AuxData.data());
|
|
+ reinterpret_cast<coff_aux_section_definition *>(
|
|
+ Sym.AuxData[0].Opaque);
|
|
uint32_t SDSectionNumber;
|
|
if (Sym.AssociativeComdatTargetSectionId == 0) {
|
|
// Not a comdat associative section; just set the Number field to
|
|
@@ -79,7 +80,7 @@ Error COFFWriter::finalizeSymbolContents() {
|
|
// we want to set. Only >= 1 would be required, but only == 1 makes sense.
|
|
if (Sym.WeakTargetSymbolId && Sym.Sym.NumberOfAuxSymbols == 1) {
|
|
coff_aux_weak_external *WE =
|
|
- reinterpret_cast<coff_aux_weak_external *>(Sym.AuxData.data());
|
|
+ reinterpret_cast<coff_aux_weak_external *>(Sym.AuxData[0].Opaque);
|
|
const Symbol *Target = Obj.findSymbol(*Sym.WeakTargetSymbolId);
|
|
if (Target == nullptr)
|
|
return createStringError(object_error::invalid_symbol_index,
|
|
@@ -141,13 +142,26 @@ size_t COFFWriter::finalizeStringTable() {
|
|
|
|
template <class SymbolTy>
|
|
std::pair<size_t, size_t> COFFWriter::finalizeSymbolTable() {
|
|
- size_t SymTabSize = Obj.getSymbols().size() * sizeof(SymbolTy);
|
|
- for (const auto &S : Obj.getSymbols())
|
|
- SymTabSize += S.AuxData.size();
|
|
- return std::make_pair(SymTabSize, sizeof(SymbolTy));
|
|
+ size_t RawSymIndex = 0;
|
|
+ for (auto &S : Obj.getMutableSymbols()) {
|
|
+ // Symbols normally have NumberOfAuxSymbols set correctly all the time.
|
|
+ // For file symbols, we need to know the output file's symbol size to be
|
|
+ // able to calculate the number of slots it occupies.
|
|
+ if (!S.AuxFile.empty())
|
|
+ S.Sym.NumberOfAuxSymbols =
|
|
+ alignTo(S.AuxFile.size(), sizeof(SymbolTy)) / sizeof(SymbolTy);
|
|
+ S.RawIndex = RawSymIndex;
|
|
+ RawSymIndex += 1 + S.Sym.NumberOfAuxSymbols;
|
|
+ }
|
|
+ return std::make_pair(RawSymIndex * sizeof(SymbolTy), sizeof(SymbolTy));
|
|
}
|
|
|
|
Error COFFWriter::finalize(bool IsBigObj) {
|
|
+ size_t SymTabSize, SymbolSize;
|
|
+ std::tie(SymTabSize, SymbolSize) = IsBigObj
|
|
+ ? finalizeSymbolTable<coff_symbol32>()
|
|
+ : finalizeSymbolTable<coff_symbol16>();
|
|
+
|
|
if (Error E = finalizeRelocTargets())
|
|
return E;
|
|
if (Error E = finalizeSymbolContents())
|
|
@@ -199,10 +213,6 @@ Error COFFWriter::finalize(bool IsBigObj) {
|
|
}
|
|
|
|
size_t StrTabSize = finalizeStringTable();
|
|
- size_t SymTabSize, SymbolSize;
|
|
- std::tie(SymTabSize, SymbolSize) = IsBigObj
|
|
- ? finalizeSymbolTable<coff_symbol32>()
|
|
- : finalizeSymbolTable<coff_symbol16>();
|
|
|
|
size_t PointerToSymbolTable = FileSize;
|
|
// StrTabSize <= 4 is the size of an empty string table, only consisting
|
|
@@ -312,8 +322,23 @@ template <class SymbolTy> void COFFWriter::writeSymbolStringTables() {
|
|
copySymbol<SymbolTy, coff_symbol32>(*reinterpret_cast<SymbolTy *>(Ptr),
|
|
S.Sym);
|
|
Ptr += sizeof(SymbolTy);
|
|
- std::copy(S.AuxData.begin(), S.AuxData.end(), Ptr);
|
|
- Ptr += S.AuxData.size();
|
|
+ if (!S.AuxFile.empty()) {
|
|
+ // For file symbols, just write the string into the aux symbol slots,
|
|
+ // assuming that the unwritten parts are initialized to zero in the memory
|
|
+ // mapped file.
|
|
+ std::copy(S.AuxFile.begin(), S.AuxFile.end(), Ptr);
|
|
+ Ptr += S.Sym.NumberOfAuxSymbols * sizeof(SymbolTy);
|
|
+ } else {
|
|
+ // For other auxillary symbols, write their opaque payload into one symbol
|
|
+ // table slot each. For big object files, the symbols are larger than the
|
|
+ // opaque auxillary symbol struct and we leave padding at the end of each
|
|
+ // entry.
|
|
+ for (const AuxSymbol &AuxSym : S.AuxData) {
|
|
+ ArrayRef<uint8_t> Ref = AuxSym.getRef();
|
|
+ std::copy(Ref.begin(), Ref.end(), Ptr);
|
|
+ Ptr += sizeof(SymbolTy);
|
|
+ }
|
|
+ }
|
|
}
|
|
if (StrTabBuilder.getSize() > 4 || !Obj.IsPE) {
|
|
// Always write a string table in object files, even an empty one.
|
|
diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.h b/llvm/tools/llvm-objcopy/COFF/Writer.h
|
|
index 9b1cfa91d00..681a8d5e4a6 100644
|
|
--- a/llvm/tools/llvm-objcopy/COFF/Writer.h
|
|
+++ b/llvm/tools/llvm-objcopy/COFF/Writer.h
|
|
@@ -30,11 +30,11 @@ class COFFWriter {
|
|
size_t SizeOfInitializedData;
|
|
StringTableBuilder StrTabBuilder;
|
|
|
|
+ template <class SymbolTy> std::pair<size_t, size_t> finalizeSymbolTable();
|
|
Error finalizeRelocTargets();
|
|
Error finalizeSymbolContents();
|
|
void layoutSections();
|
|
size_t finalizeStringTable();
|
|
- template <class SymbolTy> std::pair<size_t, size_t> finalizeSymbolTable();
|
|
|
|
Error finalize(bool IsBigObj);
|
|
|
|
--
|
|
2.17.1
|
|
|