llvm-objcopy-11.patch 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. From 74c7d422cba163635394ec32f2b243b1de502a18 Mon Sep 17 00:00:00 2001
  2. From: Martin Storsjo <martin@martin.st>
  3. Date: Wed, 23 Jan 2019 11:54:51 +0000
  4. Subject: [PATCH] [llvm-objcopy] [COFF] Fix handling of aux symbols for big
  5. objects
  6. The aux symbols were stored in an opaque std::vector<uint8_t>,
  7. with contents interpreted according to the rest of the symbol.
  8. All aux symbol types but one fit in 18 bytes (sizeof(coff_symbol16)),
  9. and if written to a bigobj, two extra padding bytes are written (as
  10. sizeof(coff_symbol32) is 20). In the storage agnostic intermediate
  11. representation, store the aux symbols as a series of coff_symbol16
  12. sized opaque blobs. (In practice, all such aux symbols only consist
  13. of one aux symbol, so this is more flexible than what reality needs.)
  14. The special case is the file aux symbols, which are written in
  15. potentially more than one aux symbol slot, without any padding,
  16. as one single long string. This can't be stored in the same opaque
  17. vector of fixed sized aux symbol entries. The file aux symbols will
  18. occupy a different number of aux symbol slots depending on the type
  19. of output object file. As nothing in the intermediate process needs
  20. to have accurate raw symbol indices, updating that is moved into the
  21. writer class.
  22. Differential Revision: https://reviews.llvm.org/D57009
  23. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351947 91177308-0d34-0410-b5e6-96231b3b80d8
  24. ---
  25. .../llvm-objcopy/COFF/Inputs/bigobj.o.gz | Bin 0 -> 7841 bytes
  26. test/tools/llvm-objcopy/COFF/bigobj.test | 35 +++++++++++++
  27. .../llvm-objcopy/ELF/auto-remove-shndx.test | 2 +-
  28. .../tools/llvm-objcopy/ELF/many-sections.test | 2 +-
  29. test/tools/llvm-objcopy/ELF/remove-shndx.test | 2 +-
  30. .../tools/llvm-objcopy/ELF/strict-no-add.test | 2 +-
  31. .../llvm-objcopy/{ELF => }/Inputs/ungzip.py | 0
  32. tools/llvm-objcopy/COFF/COFFObjcopy.cpp | 6 +--
  33. tools/llvm-objcopy/COFF/Object.cpp | 6 +--
  34. tools/llvm-objcopy/COFF/Object.h | 18 ++++++-
  35. tools/llvm-objcopy/COFF/Reader.cpp | 21 ++++++--
  36. tools/llvm-objcopy/COFF/Writer.cpp | 49 +++++++++++++-----
  37. tools/llvm-objcopy/COFF/Writer.h | 2 +-
  38. 13 files changed, 115 insertions(+), 30 deletions(-)
  39. create mode 100644 test/tools/llvm-objcopy/COFF/Inputs/bigobj.o.gz
  40. create mode 100644 test/tools/llvm-objcopy/COFF/bigobj.test
  41. rename test/tools/llvm-objcopy/{ELF => }/Inputs/ungzip.py (100%)
  42. diff --git a/llvm/test/tools/llvm-objcopy/COFF/Inputs/bigobj.o.gz b/llvm/test/tools/llvm-objcopy/COFF/Inputs/bigobj.o.gz
  43. new file mode 100644
  44. index 0000000000000000000000000000000000000000..6435f4785ff76e0c6bca12f3e57bc6ad8888bece
  45. GIT binary patch
  46. literal 7841
  47. zcmb2|=3r3v^@w3&etUMmo^zoH`-kGKM_vfJsF<z%6+Sz#g6qq)pf0Hj#_r`4B7DML
  48. zW(h1l`+!x)t@&W-R@I~lyKmU3Ti&1Z=iKur;uBMy1MR!_ywlsouYY&-*4H1mU!Qw=
  49. z`RpIDkw;!V4(WOF_)B3`(Vt|~S>?L-b)Wx@^wig`HIMAw|N8V<v65oeyETs611{)_
  50. zm27RwTe)ENN|7SLgM~83N6}~qjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kinXb6mk
  51. zz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kgRokHNw|D97mKRo|%+Z6Ym
  52. z*X{Ku$4#4*Vqm}gyYR^b^Sc?_E*<<cFE#Q=*rt6OBmJeLZ=aoe_u9R>-w!^l5biDe
  53. p{d@nvw*mU6<NG83=jxn4_wt_G?yUy#YeOF~KhH^=cj<;Y0{~9Br>p<~
  54. literal 0
  55. HcmV?d00001
  56. diff --git a/llvm/test/tools/llvm-objcopy/COFF/bigobj.test b/llvm/test/tools/llvm-objcopy/COFF/bigobj.test
  57. new file mode 100644
  58. index 00000000000..17968f12b8a
  59. --- /dev/null
  60. +++ b/llvm/test/tools/llvm-objcopy/COFF/bigobj.test
  61. @@ -0,0 +1,35 @@
  62. +RUN: %python %p/../Inputs/ungzip.py %p/Inputs/bigobj.o.gz > %t.in.o
  63. +
  64. +RUN: llvm-objdump -t %t.in.o | FileCheck %s --check-prefixes=SYMBOLS,SYMBOLS-BIG,SYMBOLS-ORIG
  65. +
  66. +# Do a plain copy, to check that section numbers in symbols referring
  67. +# to sections outside of the small object format are handled correctly.
  68. +RUN: llvm-objcopy -R '.text$4' %t.in.o %t.small.o
  69. +RUN: llvm-objdump -t %t.in.o | FileCheck %s --check-prefixes=SYMBOLS,SYMBOLS-BIG,SYMBOLS-ORIG
  70. +
  71. +# Remove a section, making the section count fit into a small object.
  72. +RUN: llvm-objcopy -R '.text$4' %t.in.o %t.small.o
  73. +RUN: llvm-objdump -t %t.small.o | FileCheck %s --check-prefixes=SYMBOLS,SYMBOLS-SMALL,SYMBOLS-REMOVED-SMALL
  74. +
  75. +# Add a .gnu_debuglink section, forcing the object back to big format.
  76. +RUN: llvm-objcopy --add-gnu-debuglink=%t.in.o %t.small.o %t.big.o
  77. + llvm-objdump -t %t.big.o | FileCheck %s --check-prefixes=SYMBOLS,SYMBOLS-BIG,SYMBOLS-REMOVED-BIG
  78. +
  79. +# In big object format, the .file symbol occupies one symbol table entry for
  80. +# the auxillary data, but needs two entries in the small format, forcing the
  81. +# raw symbol indices of later symbols to change.
  82. +SYMBOLS: SYMBOL TABLE:
  83. +SYMBOLS-NEXT: [ 0]{{.*}} (nx 1) {{.*}} .text
  84. +SYMBOLS-NEXT: AUX scnlen
  85. +SYMBOLS-SMALL-NEXT: [ 2]{{.*}} (nx 2) {{.*}} .file
  86. +SYMBOLS-BIG-NEXT: [ 2]{{.*}} (nx 1) {{.*}} .file
  87. +SYMBOLS-NEXT: AUX abcdefghijklmnopqrs
  88. +SYMBOLS-SMALL-NEXT: [ 5]{{.*}} (nx 0) {{.*}} foo
  89. +SYMBOLS-BIG-NEXT: [ 4]{{.*}} (nx 0) {{.*}} foo
  90. +
  91. +# Check that the section numbers outside of signed 16 bit int range
  92. +# are represented properly. After removing one section, the section
  93. +# numbers decrease.
  94. +SYMBOLS-ORIG: [ 5](sec 65280){{.*}} symbol65280
  95. +SYMBOLS-REMOVED-SMALL: [ 6](sec 65279){{.*}} symbol65280
  96. +SYMBOLS-REMOVED-BIG: [ 5](sec 65279){{.*}} symbol65280
  97. diff --git a/llvm/test/tools/llvm-objcopy/ELF/auto-remove-shndx.test b/llvm/test/tools/llvm-objcopy/ELF/auto-remove-shndx.test
  98. index 5a23493fa94..8e6c788bf48 100644
  99. --- a/llvm/test/tools/llvm-objcopy/ELF/auto-remove-shndx.test
  100. +++ b/llvm/test/tools/llvm-objcopy/ELF/auto-remove-shndx.test
  101. @@ -1,4 +1,4 @@
  102. -# RUN: %python %p/Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t
  103. +# RUN: %python %p/../Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t
  104. # RUN: llvm-objcopy -R .text -R s0 -R s1 -R s2 -R s3 -R s4 -R s5 -R s6 %t %t2
  105. # RUN: llvm-readobj --sections %t2 | FileCheck --check-prefix=SECS %s
  106. diff --git a/llvm/test/tools/llvm-objcopy/ELF/many-sections.test b/llvm/test/tools/llvm-objcopy/ELF/many-sections.test
  107. index 57239f32e4a..1dd41cfb10c 100644
  108. --- a/llvm/test/tools/llvm-objcopy/ELF/many-sections.test
  109. +++ b/llvm/test/tools/llvm-objcopy/ELF/many-sections.test
  110. @@ -1,4 +1,4 @@
  111. -RUN: %python %p/Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t
  112. +RUN: %python %p/../Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t
  113. RUN: llvm-objcopy %t %t2
  114. RUN: llvm-readobj --file-headers %t2 | FileCheck --check-prefix=EHDR %s
  115. RUN: llvm-readobj --sections %t2 | FileCheck --check-prefix=SECS %s
  116. diff --git a/llvm/test/tools/llvm-objcopy/ELF/remove-shndx.test b/llvm/test/tools/llvm-objcopy/ELF/remove-shndx.test
  117. index 6cc3a1a291f..53ca8e7f220 100644
  118. --- a/llvm/test/tools/llvm-objcopy/ELF/remove-shndx.test
  119. +++ b/llvm/test/tools/llvm-objcopy/ELF/remove-shndx.test
  120. @@ -1,6 +1,6 @@
  121. # This test checks to see that a .symtab_shndx section is added to any binary
  122. # that needs it, even if the original was removed.
  123. -RUN: %python %p/Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t
  124. +RUN: %python %p/../Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t
  125. RUN: llvm-objcopy -R .symtab_shndx %t %t2
  126. RUN: llvm-readobj --sections %t2 | FileCheck %s
  127. diff --git a/llvm/test/tools/llvm-objcopy/ELF/strict-no-add.test b/llvm/test/tools/llvm-objcopy/ELF/strict-no-add.test
  128. index 4f24df31bf9..348ab7c4fbd 100644
  129. --- a/llvm/test/tools/llvm-objcopy/ELF/strict-no-add.test
  130. +++ b/llvm/test/tools/llvm-objcopy/ELF/strict-no-add.test
  131. @@ -1,7 +1,7 @@
  132. # This test makes sure that sections added at the end that don't have symbols
  133. # defined in them don't trigger the creation of a large index table.
  134. -RUN: %python %p/Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t.0
  135. +RUN: %python %p/../Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t.0
  136. RUN: cat %p/Inputs/alloc-symtab.o > %t
  137. RUN: llvm-objcopy -R .text -R s0 -R s1 -R s2 -R s3 -R s4 -R s5 -R s6 %t.0 %t2
  138. RUN: llvm-objcopy --add-section=.s0=%t --add-section=.s1=%t --add-section=.s2=%t %t2 %t2
  139. diff --git a/llvm/test/tools/llvm-objcopy/ELF/Inputs/ungzip.py b/llvm/test/tools/llvm-objcopy/Inputs/ungzip.py
  140. similarity index 100%
  141. rename from llvm/test/tools/llvm-objcopy/ELF/Inputs/ungzip.py
  142. rename to llvm/test/tools/llvm-objcopy/Inputs/ungzip.py
  143. diff --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
  144. index 20adbe11e7a..64b4e79a4e0 100644
  145. --- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
  146. +++ b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
  147. @@ -37,7 +37,7 @@ static uint64_t getNextRVA(const Object &Obj) {
  148. return 0;
  149. const Section &Last = Obj.getSections().back();
  150. return alignTo(Last.Header.VirtualAddress + Last.Header.VirtualSize,
  151. - Obj.PeHeader.SectionAlignment);
  152. + Obj.IsPE ? Obj.PeHeader.SectionAlignment : 1);
  153. }
  154. static uint32_t getCRC32(StringRef Data) {
  155. @@ -74,8 +74,8 @@ static void addGnuDebugLink(Object &Obj, StringRef DebugLinkFile) {
  156. Sec.Name = ".gnu_debuglink";
  157. Sec.Header.VirtualSize = Sec.getContents().size();
  158. Sec.Header.VirtualAddress = StartRVA;
  159. - Sec.Header.SizeOfRawData =
  160. - alignTo(Sec.Header.VirtualSize, Obj.PeHeader.FileAlignment);
  161. + Sec.Header.SizeOfRawData = alignTo(Sec.Header.VirtualSize,
  162. + Obj.IsPE ? Obj.PeHeader.FileAlignment : 1);
  163. // Sec.Header.PointerToRawData is filled in by the writer.
  164. Sec.Header.PointerToRelocations = 0;
  165. Sec.Header.PointerToLinenumbers = 0;
  166. diff --git a/llvm/tools/llvm-objcopy/COFF/Object.cpp b/llvm/tools/llvm-objcopy/COFF/Object.cpp
  167. index 8c382c1faef..0ad5a05a144 100644
  168. --- a/llvm/tools/llvm-objcopy/COFF/Object.cpp
  169. +++ b/llvm/tools/llvm-objcopy/COFF/Object.cpp
  170. @@ -26,12 +26,8 @@ void Object::addSymbols(ArrayRef<Symbol> NewSymbols) {
  171. void Object::updateSymbols() {
  172. SymbolMap = DenseMap<size_t, Symbol *>(Symbols.size());
  173. - size_t RawSymIndex = 0;
  174. - for (Symbol &Sym : Symbols) {
  175. + for (Symbol &Sym : Symbols)
  176. SymbolMap[Sym.UniqueId] = &Sym;
  177. - Sym.RawIndex = RawSymIndex;
  178. - RawSymIndex += 1 + Sym.Sym.NumberOfAuxSymbols;
  179. - }
  180. }
  181. const Symbol *Object::findSymbol(size_t UniqueId) const {
  182. diff --git a/llvm/tools/llvm-objcopy/COFF/Object.h b/llvm/tools/llvm-objcopy/COFF/Object.h
  183. index afa272286ef..21475b06862 100644
  184. --- a/llvm/tools/llvm-objcopy/COFF/Object.h
  185. +++ b/llvm/tools/llvm-objcopy/COFF/Object.h
  186. @@ -66,10 +66,24 @@ private:
  187. std::vector<uint8_t> OwnedContents;
  188. };
  189. +struct AuxSymbol {
  190. + AuxSymbol(ArrayRef<uint8_t> In) {
  191. + assert(In.size() == sizeof(Opaque));
  192. + std::copy(In.begin(), In.end(), Opaque);
  193. + }
  194. +
  195. + ArrayRef<uint8_t> getRef() const {
  196. + return ArrayRef<uint8_t>(Opaque, sizeof(Opaque));
  197. + }
  198. +
  199. + uint8_t Opaque[sizeof(object::coff_symbol16)];
  200. +};
  201. +
  202. struct Symbol {
  203. object::coff_symbol32 Sym;
  204. StringRef Name;
  205. - std::vector<uint8_t> AuxData;
  206. + std::vector<AuxSymbol> AuxData;
  207. + StringRef AuxFile;
  208. ssize_t TargetSectionId;
  209. ssize_t AssociativeComdatTargetSectionId = 0;
  210. Optional<size_t> WeakTargetSymbolId;
  211. @@ -132,7 +146,7 @@ private:
  212. ssize_t NextSectionUniqueId = 1; // Allow a UniqueId 0 to mean undefined.
  213. - // Update SymbolMap and RawIndex in each Symbol.
  214. + // Update SymbolMap.
  215. void updateSymbols();
  216. // Update SectionMap and Index in each Section.
  217. diff --git a/llvm/tools/llvm-objcopy/COFF/Reader.cpp b/llvm/tools/llvm-objcopy/COFF/Reader.cpp
  218. index 87dd60a43cf..7270bbf94de 100644
  219. --- a/llvm/tools/llvm-objcopy/COFF/Reader.cpp
  220. +++ b/llvm/tools/llvm-objcopy/COFF/Reader.cpp
  221. @@ -107,9 +107,24 @@ Error COFFReader::readSymbols(Object &Obj, bool IsBigObj) const {
  222. *reinterpret_cast<const coff_symbol16 *>(SymRef.getRawPtr()));
  223. if (auto EC = COFFObj.getSymbolName(SymRef, Sym.Name))
  224. return errorCodeToError(EC);
  225. - Sym.AuxData = COFFObj.getSymbolAuxData(SymRef);
  226. - assert((Sym.AuxData.size() %
  227. - (IsBigObj ? sizeof(coff_symbol32) : sizeof(coff_symbol16))) == 0);
  228. +
  229. + ArrayRef<uint8_t> AuxData = COFFObj.getSymbolAuxData(SymRef);
  230. + size_t SymSize = IsBigObj ? sizeof(coff_symbol32) : sizeof(coff_symbol16);
  231. + assert(AuxData.size() == SymSize * SymRef.getNumberOfAuxSymbols());
  232. + // The auxillary symbols are structs of sizeof(coff_symbol16) each.
  233. + // In the big object format (where symbols are coff_symbol32), each
  234. + // auxillary symbol is padded with 2 bytes at the end. Copy each
  235. + // auxillary symbol to the Sym.AuxData vector. For file symbols,
  236. + // the whole range of aux symbols are interpreted as one null padded
  237. + // string instead.
  238. + if (SymRef.isFileRecord())
  239. + Sym.AuxFile = StringRef(reinterpret_cast<const char *>(AuxData.data()),
  240. + AuxData.size())
  241. + .rtrim('\0');
  242. + else
  243. + for (size_t I = 0; I < SymRef.getNumberOfAuxSymbols(); I++)
  244. + Sym.AuxData.push_back(AuxData.slice(I * SymSize, sizeof(AuxSymbol)));
  245. +
  246. // Find the unique id of the section
  247. if (SymRef.getSectionNumber() <=
  248. 0) // Special symbol (undefined/absolute/debug)
  249. diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.cpp b/llvm/tools/llvm-objcopy/COFF/Writer.cpp
  250. index db897e2ff33..6e69c597217 100644
  251. --- a/llvm/tools/llvm-objcopy/COFF/Writer.cpp
  252. +++ b/llvm/tools/llvm-objcopy/COFF/Writer.cpp
  253. @@ -55,7 +55,8 @@ Error COFFWriter::finalizeSymbolContents() {
  254. if (Sym.Sym.NumberOfAuxSymbols == 1 &&
  255. Sym.Sym.StorageClass == IMAGE_SYM_CLASS_STATIC) {
  256. coff_aux_section_definition *SD =
  257. - reinterpret_cast<coff_aux_section_definition *>(Sym.AuxData.data());
  258. + reinterpret_cast<coff_aux_section_definition *>(
  259. + Sym.AuxData[0].Opaque);
  260. uint32_t SDSectionNumber;
  261. if (Sym.AssociativeComdatTargetSectionId == 0) {
  262. // Not a comdat associative section; just set the Number field to
  263. @@ -79,7 +80,7 @@ Error COFFWriter::finalizeSymbolContents() {
  264. // we want to set. Only >= 1 would be required, but only == 1 makes sense.
  265. if (Sym.WeakTargetSymbolId && Sym.Sym.NumberOfAuxSymbols == 1) {
  266. coff_aux_weak_external *WE =
  267. - reinterpret_cast<coff_aux_weak_external *>(Sym.AuxData.data());
  268. + reinterpret_cast<coff_aux_weak_external *>(Sym.AuxData[0].Opaque);
  269. const Symbol *Target = Obj.findSymbol(*Sym.WeakTargetSymbolId);
  270. if (Target == nullptr)
  271. return createStringError(object_error::invalid_symbol_index,
  272. @@ -141,13 +142,26 @@ size_t COFFWriter::finalizeStringTable() {
  273. template <class SymbolTy>
  274. std::pair<size_t, size_t> COFFWriter::finalizeSymbolTable() {
  275. - size_t SymTabSize = Obj.getSymbols().size() * sizeof(SymbolTy);
  276. - for (const auto &S : Obj.getSymbols())
  277. - SymTabSize += S.AuxData.size();
  278. - return std::make_pair(SymTabSize, sizeof(SymbolTy));
  279. + size_t RawSymIndex = 0;
  280. + for (auto &S : Obj.getMutableSymbols()) {
  281. + // Symbols normally have NumberOfAuxSymbols set correctly all the time.
  282. + // For file symbols, we need to know the output file's symbol size to be
  283. + // able to calculate the number of slots it occupies.
  284. + if (!S.AuxFile.empty())
  285. + S.Sym.NumberOfAuxSymbols =
  286. + alignTo(S.AuxFile.size(), sizeof(SymbolTy)) / sizeof(SymbolTy);
  287. + S.RawIndex = RawSymIndex;
  288. + RawSymIndex += 1 + S.Sym.NumberOfAuxSymbols;
  289. + }
  290. + return std::make_pair(RawSymIndex * sizeof(SymbolTy), sizeof(SymbolTy));
  291. }
  292. Error COFFWriter::finalize(bool IsBigObj) {
  293. + size_t SymTabSize, SymbolSize;
  294. + std::tie(SymTabSize, SymbolSize) = IsBigObj
  295. + ? finalizeSymbolTable<coff_symbol32>()
  296. + : finalizeSymbolTable<coff_symbol16>();
  297. +
  298. if (Error E = finalizeRelocTargets())
  299. return E;
  300. if (Error E = finalizeSymbolContents())
  301. @@ -199,10 +213,6 @@ Error COFFWriter::finalize(bool IsBigObj) {
  302. }
  303. size_t StrTabSize = finalizeStringTable();
  304. - size_t SymTabSize, SymbolSize;
  305. - std::tie(SymTabSize, SymbolSize) = IsBigObj
  306. - ? finalizeSymbolTable<coff_symbol32>()
  307. - : finalizeSymbolTable<coff_symbol16>();
  308. size_t PointerToSymbolTable = FileSize;
  309. // StrTabSize <= 4 is the size of an empty string table, only consisting
  310. @@ -312,8 +322,23 @@ template <class SymbolTy> void COFFWriter::writeSymbolStringTables() {
  311. copySymbol<SymbolTy, coff_symbol32>(*reinterpret_cast<SymbolTy *>(Ptr),
  312. S.Sym);
  313. Ptr += sizeof(SymbolTy);
  314. - std::copy(S.AuxData.begin(), S.AuxData.end(), Ptr);
  315. - Ptr += S.AuxData.size();
  316. + if (!S.AuxFile.empty()) {
  317. + // For file symbols, just write the string into the aux symbol slots,
  318. + // assuming that the unwritten parts are initialized to zero in the memory
  319. + // mapped file.
  320. + std::copy(S.AuxFile.begin(), S.AuxFile.end(), Ptr);
  321. + Ptr += S.Sym.NumberOfAuxSymbols * sizeof(SymbolTy);
  322. + } else {
  323. + // For other auxillary symbols, write their opaque payload into one symbol
  324. + // table slot each. For big object files, the symbols are larger than the
  325. + // opaque auxillary symbol struct and we leave padding at the end of each
  326. + // entry.
  327. + for (const AuxSymbol &AuxSym : S.AuxData) {
  328. + ArrayRef<uint8_t> Ref = AuxSym.getRef();
  329. + std::copy(Ref.begin(), Ref.end(), Ptr);
  330. + Ptr += sizeof(SymbolTy);
  331. + }
  332. + }
  333. }
  334. if (StrTabBuilder.getSize() > 4 || !Obj.IsPE) {
  335. // Always write a string table in object files, even an empty one.
  336. diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.h b/llvm/tools/llvm-objcopy/COFF/Writer.h
  337. index 9b1cfa91d00..681a8d5e4a6 100644
  338. --- a/llvm/tools/llvm-objcopy/COFF/Writer.h
  339. +++ b/llvm/tools/llvm-objcopy/COFF/Writer.h
  340. @@ -30,11 +30,11 @@ class COFFWriter {
  341. size_t SizeOfInitializedData;
  342. StringTableBuilder StrTabBuilder;
  343. + template <class SymbolTy> std::pair<size_t, size_t> finalizeSymbolTable();
  344. Error finalizeRelocTargets();
  345. Error finalizeSymbolContents();
  346. void layoutSections();
  347. size_t finalizeStringTable();
  348. - template <class SymbolTy> std::pair<size_t, size_t> finalizeSymbolTable();
  349. Error finalize(bool IsBigObj);
  350. --
  351. 2.17.1