llvm-objcopy-7.patch 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. From d37f67c7311cd371d9ff1afd398bc92f309e6baf Mon Sep 17 00:00:00 2001
  2. From: Martin Storsjo <martin@martin.st>
  3. Date: Tue, 22 Jan 2019 10:58:09 +0000
  4. Subject: [PATCH] [llvm-objcopy] [COFF] Update symbol indices in weak externals
  5. Differential Revision: https://reviews.llvm.org/D57006
  6. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351800 91177308-0d34-0410-b5e6-96231b3b80d8
  7. ---
  8. .../llvm-objcopy/COFF/weak-external.test | 49 +++++++++++++++++++
  9. tools/llvm-objcopy/COFF/Object.h | 2 +
  10. tools/llvm-objcopy/COFF/Reader.cpp | 24 ++++++++-
  11. tools/llvm-objcopy/COFF/Reader.h | 2 +-
  12. tools/llvm-objcopy/COFF/Writer.cpp | 16 +++++-
  13. tools/llvm-objcopy/COFF/Writer.h | 2 +-
  14. 6 files changed, 89 insertions(+), 6 deletions(-)
  15. create mode 100644 test/tools/llvm-objcopy/COFF/weak-external.test
  16. diff --git a/llvm/test/tools/llvm-objcopy/COFF/weak-external.test b/llvm/test/tools/llvm-objcopy/COFF/weak-external.test
  17. new file mode 100644
  18. index 00000000000..d36a53b4eb1
  19. --- /dev/null
  20. +++ b/llvm/test/tools/llvm-objcopy/COFF/weak-external.test
  21. @@ -0,0 +1,49 @@
  22. +# RUN: yaml2obj %s > %t.in.o
  23. +
  24. +# RUN: llvm-objdump -t %t.in.o | FileCheck %s --check-prefixes=SYMBOLS,SYMBOLS-PRE
  25. +
  26. +# RUN: llvm-objcopy -N func %t.in.o %t.out.o
  27. +# RUN: llvm-objdump -t %t.out.o | FileCheck %s --check-prefixes=SYMBOLS,SYMBOLS-POST
  28. +
  29. +# RUN: not llvm-objcopy -N .weak.foobar.file1 %t.in.o %t.err.o 2>&1 | FileCheck %s --check-prefix=ERROR
  30. +
  31. +# SYMBOLS: SYMBOL TABLE:
  32. +# SYMBOLS-PRE-NEXT: func
  33. +# SYMBOLS-NEXT: .weak.foobar.file1
  34. +# SYMBOLS-NEXT: foobar
  35. +# SYMBOLS-PRE-NEXT: AUX indx 1
  36. +# SYMBOLS-POST-NEXT: AUX indx 0
  37. +# SYMBOLS-EMPTY:
  38. +
  39. +# ERROR: Symbol 'foobar' is missing its weak target
  40. +
  41. +--- !COFF
  42. +header:
  43. + Machine: IMAGE_FILE_MACHINE_AMD64
  44. + Characteristics: [ ]
  45. +sections:
  46. + - Name: .text
  47. + Characteristics: [ ]
  48. +symbols:
  49. + - Name: func
  50. + Value: 0
  51. + SectionNumber: 1
  52. + SimpleType: IMAGE_SYM_TYPE_NULL
  53. + ComplexType: IMAGE_SYM_DTYPE_NULL
  54. + StorageClass: IMAGE_SYM_CLASS_EXTERNAL
  55. + - Name: .weak.foobar.file1
  56. + Value: 1
  57. + SectionNumber: 1
  58. + SimpleType: IMAGE_SYM_TYPE_NULL
  59. + ComplexType: IMAGE_SYM_DTYPE_NULL
  60. + StorageClass: IMAGE_SYM_CLASS_EXTERNAL
  61. + - Name: foobar
  62. + Value: 0
  63. + SectionNumber: 0
  64. + SimpleType: IMAGE_SYM_TYPE_NULL
  65. + ComplexType: IMAGE_SYM_DTYPE_FUNCTION
  66. + StorageClass: IMAGE_SYM_CLASS_WEAK_EXTERNAL
  67. + WeakExternal:
  68. + TagIndex: 1
  69. + Characteristics: IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY
  70. +...
  71. diff --git a/llvm/tools/llvm-objcopy/COFF/Object.h b/llvm/tools/llvm-objcopy/COFF/Object.h
  72. index 8e200369f0b..0630f9c5ff8 100644
  73. --- a/llvm/tools/llvm-objcopy/COFF/Object.h
  74. +++ b/llvm/tools/llvm-objcopy/COFF/Object.h
  75. @@ -11,6 +11,7 @@
  76. #include "llvm/ADT/ArrayRef.h"
  77. #include "llvm/ADT/DenseMap.h"
  78. +#include "llvm/ADT/Optional.h"
  79. #include "llvm/ADT/StringRef.h"
  80. #include "llvm/ADT/iterator_range.h"
  81. #include "llvm/BinaryFormat/COFF.h"
  82. @@ -47,6 +48,7 @@ struct Symbol {
  83. std::vector<uint8_t> AuxData;
  84. ssize_t TargetSectionId;
  85. ssize_t AssociativeComdatTargetSectionId = 0;
  86. + Optional<size_t> WeakTargetSymbolId;
  87. size_t UniqueId;
  88. size_t RawIndex;
  89. bool Referenced;
  90. diff --git a/llvm/tools/llvm-objcopy/COFF/Reader.cpp b/llvm/tools/llvm-objcopy/COFF/Reader.cpp
  91. index 20ff32a59dc..2446277cc2b 100644
  92. --- a/llvm/tools/llvm-objcopy/COFF/Reader.cpp
  93. +++ b/llvm/tools/llvm-objcopy/COFF/Reader.cpp
  94. @@ -121,12 +121,18 @@ Error COFFReader::readSymbols(Object &Obj, bool IsBigObj) const {
  95. // For section definitions, check if it is comdat associative, and if
  96. // it is, find the target section unique id.
  97. const coff_aux_section_definition *SD = SymRef.getSectionDefinition();
  98. + const coff_aux_weak_external *WE = SymRef.getWeakExternal();
  99. if (SD && SD->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE) {
  100. int32_t Index = SD->getNumber(IsBigObj);
  101. if (Index <= 0 || static_cast<uint32_t>(Index - 1) >= Sections.size())
  102. return createStringError(object_error::parse_failed,
  103. "Unexpected associative section index");
  104. Sym.AssociativeComdatTargetSectionId = Sections[Index - 1].UniqueId;
  105. + } else if (WE) {
  106. + // This is a raw symbol index for now, but store it in the Symbol
  107. + // until we've added them to the Object, which assigns the final
  108. + // unique ids.
  109. + Sym.WeakTargetSymbolId = WE->TagIndex;
  110. }
  111. I += 1 + SymRef.getNumberOfAuxSymbols();
  112. }
  113. @@ -134,13 +140,27 @@ Error COFFReader::readSymbols(Object &Obj, bool IsBigObj) const {
  114. return Error::success();
  115. }
  116. -Error COFFReader::setRelocTargets(Object &Obj) const {
  117. +Error COFFReader::setSymbolTargets(Object &Obj) const {
  118. std::vector<const Symbol *> RawSymbolTable;
  119. for (const Symbol &Sym : Obj.getSymbols()) {
  120. RawSymbolTable.push_back(&Sym);
  121. for (size_t I = 0; I < Sym.Sym.NumberOfAuxSymbols; I++)
  122. RawSymbolTable.push_back(nullptr);
  123. }
  124. + for (Symbol &Sym : Obj.getMutableSymbols()) {
  125. + // Convert WeakTargetSymbolId from the original raw symbol index to
  126. + // a proper unique id.
  127. + if (Sym.WeakTargetSymbolId) {
  128. + if (*Sym.WeakTargetSymbolId >= RawSymbolTable.size())
  129. + return createStringError(object_error::parse_failed,
  130. + "Weak external reference out of range");
  131. + const Symbol *Target = RawSymbolTable[*Sym.WeakTargetSymbolId];
  132. + if (Target == nullptr)
  133. + return createStringError(object_error::parse_failed,
  134. + "Invalid SymbolTableIndex");
  135. + Sym.WeakTargetSymbolId = Target->UniqueId;
  136. + }
  137. + }
  138. for (Section &Sec : Obj.getMutableSections()) {
  139. for (Relocation &R : Sec.Relocs) {
  140. if (R.Reloc.SymbolTableIndex >= RawSymbolTable.size())
  141. @@ -184,7 +204,7 @@ Expected<std::unique_ptr<Object>> COFFReader::create() const {
  142. return std::move(E);
  143. if (Error E = readSymbols(*Obj, IsBigObj))
  144. return std::move(E);
  145. - if (Error E = setRelocTargets(*Obj))
  146. + if (Error E = setSymbolTargets(*Obj))
  147. return std::move(E);
  148. return std::move(Obj);
  149. diff --git a/llvm/tools/llvm-objcopy/COFF/Reader.h b/llvm/tools/llvm-objcopy/COFF/Reader.h
  150. index 4493705e73c..ec15369db0b 100644
  151. --- a/llvm/tools/llvm-objcopy/COFF/Reader.h
  152. +++ b/llvm/tools/llvm-objcopy/COFF/Reader.h
  153. @@ -28,7 +28,7 @@ class COFFReader {
  154. Error readExecutableHeaders(Object &Obj) const;
  155. Error readSections(Object &Obj) const;
  156. Error readSymbols(Object &Obj, bool IsBigObj) const;
  157. - Error setRelocTargets(Object &Obj) const;
  158. + Error setSymbolTargets(Object &Obj) const;
  159. public:
  160. explicit COFFReader(const COFFObjectFile &O) : COFFObj(O) {}
  161. diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.cpp b/llvm/tools/llvm-objcopy/COFF/Writer.cpp
  162. index 0321f94a896..4f57131d5ab 100644
  163. --- a/llvm/tools/llvm-objcopy/COFF/Writer.cpp
  164. +++ b/llvm/tools/llvm-objcopy/COFF/Writer.cpp
  165. @@ -38,7 +38,7 @@ Error COFFWriter::finalizeRelocTargets() {
  166. return Error::success();
  167. }
  168. -Error COFFWriter::finalizeSectionNumbers() {
  169. +Error COFFWriter::finalizeSymbolContents() {
  170. for (Symbol &Sym : Obj.getMutableSymbols()) {
  171. if (Sym.TargetSectionId <= 0) {
  172. // Undefined, or a special kind of symbol. These negative values
  173. @@ -75,6 +75,18 @@ Error COFFWriter::finalizeSectionNumbers() {
  174. SD->NumberHighPart = static_cast<uint16_t>(SDSectionNumber >> 16);
  175. }
  176. }
  177. + // Check that we actually have got AuxData to match the weak symbol target
  178. + // we want to set. Only >= 1 would be required, but only == 1 makes sense.
  179. + if (Sym.WeakTargetSymbolId && Sym.Sym.NumberOfAuxSymbols == 1) {
  180. + coff_aux_weak_external *WE =
  181. + reinterpret_cast<coff_aux_weak_external *>(Sym.AuxData.data());
  182. + const Symbol *Target = Obj.findSymbol(*Sym.WeakTargetSymbolId);
  183. + if (Target == nullptr)
  184. + return createStringError(object_error::invalid_symbol_index,
  185. + "Symbol '%s' is missing its weak target",
  186. + Sym.Name.str().c_str());
  187. + WE->TagIndex = Target->RawIndex;
  188. + }
  189. }
  190. return Error::success();
  191. }
  192. @@ -137,7 +149,7 @@ std::pair<size_t, size_t> COFFWriter::finalizeSymbolTable() {
  193. Error COFFWriter::finalize(bool IsBigObj) {
  194. if (Error E = finalizeRelocTargets())
  195. return E;
  196. - if (Error E = finalizeSectionNumbers())
  197. + if (Error E = finalizeSymbolContents())
  198. return E;
  199. size_t SizeOfHeaders = 0;
  200. diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.h b/llvm/tools/llvm-objcopy/COFF/Writer.h
  201. index a967a103df9..9b1cfa91d00 100644
  202. --- a/llvm/tools/llvm-objcopy/COFF/Writer.h
  203. +++ b/llvm/tools/llvm-objcopy/COFF/Writer.h
  204. @@ -31,7 +31,7 @@ class COFFWriter {
  205. StringTableBuilder StrTabBuilder;
  206. Error finalizeRelocTargets();
  207. - Error finalizeSectionNumbers();
  208. + Error finalizeSymbolContents();
  209. void layoutSections();
  210. size_t finalizeStringTable();
  211. template <class SymbolTy> std::pair<size_t, size_t> finalizeSymbolTable();
  212. --
  213. 2.17.1