Skip to content
This repository was archived by the owner on Apr 23, 2020. It is now read-only.

Commit d37f67c

Browse files
committed
[llvm-objcopy] [COFF] Update symbol indices in weak externals
Differential Revision: https://reviews.llvm.org/D57006 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351800 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent d3b89a1 commit d37f67c

File tree

6 files changed

+89
-6
lines changed

6 files changed

+89
-6
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# RUN: yaml2obj %s > %t.in.o
2+
3+
# RUN: llvm-objdump -t %t.in.o | FileCheck %s --check-prefixes=SYMBOLS,SYMBOLS-PRE
4+
5+
# RUN: llvm-objcopy -N func %t.in.o %t.out.o
6+
# RUN: llvm-objdump -t %t.out.o | FileCheck %s --check-prefixes=SYMBOLS,SYMBOLS-POST
7+
8+
# RUN: not llvm-objcopy -N .weak.foobar.file1 %t.in.o %t.err.o 2>&1 | FileCheck %s --check-prefix=ERROR
9+
10+
# SYMBOLS: SYMBOL TABLE:
11+
# SYMBOLS-PRE-NEXT: func
12+
# SYMBOLS-NEXT: .weak.foobar.file1
13+
# SYMBOLS-NEXT: foobar
14+
# SYMBOLS-PRE-NEXT: AUX indx 1
15+
# SYMBOLS-POST-NEXT: AUX indx 0
16+
# SYMBOLS-EMPTY:
17+
18+
# ERROR: Symbol 'foobar' is missing its weak target
19+
20+
--- !COFF
21+
header:
22+
Machine: IMAGE_FILE_MACHINE_AMD64
23+
Characteristics: [ ]
24+
sections:
25+
- Name: .text
26+
Characteristics: [ ]
27+
symbols:
28+
- Name: func
29+
Value: 0
30+
SectionNumber: 1
31+
SimpleType: IMAGE_SYM_TYPE_NULL
32+
ComplexType: IMAGE_SYM_DTYPE_NULL
33+
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
34+
- Name: .weak.foobar.file1
35+
Value: 1
36+
SectionNumber: 1
37+
SimpleType: IMAGE_SYM_TYPE_NULL
38+
ComplexType: IMAGE_SYM_DTYPE_NULL
39+
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
40+
- Name: foobar
41+
Value: 0
42+
SectionNumber: 0
43+
SimpleType: IMAGE_SYM_TYPE_NULL
44+
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
45+
StorageClass: IMAGE_SYM_CLASS_WEAK_EXTERNAL
46+
WeakExternal:
47+
TagIndex: 1
48+
Characteristics: IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY
49+
...

tools/llvm-objcopy/COFF/Object.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include "llvm/ADT/ArrayRef.h"
1313
#include "llvm/ADT/DenseMap.h"
14+
#include "llvm/ADT/Optional.h"
1415
#include "llvm/ADT/StringRef.h"
1516
#include "llvm/ADT/iterator_range.h"
1617
#include "llvm/BinaryFormat/COFF.h"
@@ -47,6 +48,7 @@ struct Symbol {
4748
std::vector<uint8_t> AuxData;
4849
ssize_t TargetSectionId;
4950
ssize_t AssociativeComdatTargetSectionId = 0;
51+
Optional<size_t> WeakTargetSymbolId;
5052
size_t UniqueId;
5153
size_t RawIndex;
5254
bool Referenced;

tools/llvm-objcopy/COFF/Reader.cpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,26 +121,46 @@ Error COFFReader::readSymbols(Object &Obj, bool IsBigObj) const {
121121
// For section definitions, check if it is comdat associative, and if
122122
// it is, find the target section unique id.
123123
const coff_aux_section_definition *SD = SymRef.getSectionDefinition();
124+
const coff_aux_weak_external *WE = SymRef.getWeakExternal();
124125
if (SD && SD->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE) {
125126
int32_t Index = SD->getNumber(IsBigObj);
126127
if (Index <= 0 || static_cast<uint32_t>(Index - 1) >= Sections.size())
127128
return createStringError(object_error::parse_failed,
128129
"Unexpected associative section index");
129130
Sym.AssociativeComdatTargetSectionId = Sections[Index - 1].UniqueId;
131+
} else if (WE) {
132+
// This is a raw symbol index for now, but store it in the Symbol
133+
// until we've added them to the Object, which assigns the final
134+
// unique ids.
135+
Sym.WeakTargetSymbolId = WE->TagIndex;
130136
}
131137
I += 1 + SymRef.getNumberOfAuxSymbols();
132138
}
133139
Obj.addSymbols(Symbols);
134140
return Error::success();
135141
}
136142

137-
Error COFFReader::setRelocTargets(Object &Obj) const {
143+
Error COFFReader::setSymbolTargets(Object &Obj) const {
138144
std::vector<const Symbol *> RawSymbolTable;
139145
for (const Symbol &Sym : Obj.getSymbols()) {
140146
RawSymbolTable.push_back(&Sym);
141147
for (size_t I = 0; I < Sym.Sym.NumberOfAuxSymbols; I++)
142148
RawSymbolTable.push_back(nullptr);
143149
}
150+
for (Symbol &Sym : Obj.getMutableSymbols()) {
151+
// Convert WeakTargetSymbolId from the original raw symbol index to
152+
// a proper unique id.
153+
if (Sym.WeakTargetSymbolId) {
154+
if (*Sym.WeakTargetSymbolId >= RawSymbolTable.size())
155+
return createStringError(object_error::parse_failed,
156+
"Weak external reference out of range");
157+
const Symbol *Target = RawSymbolTable[*Sym.WeakTargetSymbolId];
158+
if (Target == nullptr)
159+
return createStringError(object_error::parse_failed,
160+
"Invalid SymbolTableIndex");
161+
Sym.WeakTargetSymbolId = Target->UniqueId;
162+
}
163+
}
144164
for (Section &Sec : Obj.getMutableSections()) {
145165
for (Relocation &R : Sec.Relocs) {
146166
if (R.Reloc.SymbolTableIndex >= RawSymbolTable.size())
@@ -184,7 +204,7 @@ Expected<std::unique_ptr<Object>> COFFReader::create() const {
184204
return std::move(E);
185205
if (Error E = readSymbols(*Obj, IsBigObj))
186206
return std::move(E);
187-
if (Error E = setRelocTargets(*Obj))
207+
if (Error E = setSymbolTargets(*Obj))
188208
return std::move(E);
189209

190210
return std::move(Obj);

tools/llvm-objcopy/COFF/Reader.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class COFFReader {
2828
Error readExecutableHeaders(Object &Obj) const;
2929
Error readSections(Object &Obj) const;
3030
Error readSymbols(Object &Obj, bool IsBigObj) const;
31-
Error setRelocTargets(Object &Obj) const;
31+
Error setSymbolTargets(Object &Obj) const;
3232

3333
public:
3434
explicit COFFReader(const COFFObjectFile &O) : COFFObj(O) {}

tools/llvm-objcopy/COFF/Writer.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ Error COFFWriter::finalizeRelocTargets() {
3838
return Error::success();
3939
}
4040

41-
Error COFFWriter::finalizeSectionNumbers() {
41+
Error COFFWriter::finalizeSymbolContents() {
4242
for (Symbol &Sym : Obj.getMutableSymbols()) {
4343
if (Sym.TargetSectionId <= 0) {
4444
// Undefined, or a special kind of symbol. These negative values
@@ -75,6 +75,18 @@ Error COFFWriter::finalizeSectionNumbers() {
7575
SD->NumberHighPart = static_cast<uint16_t>(SDSectionNumber >> 16);
7676
}
7777
}
78+
// Check that we actually have got AuxData to match the weak symbol target
79+
// we want to set. Only >= 1 would be required, but only == 1 makes sense.
80+
if (Sym.WeakTargetSymbolId && Sym.Sym.NumberOfAuxSymbols == 1) {
81+
coff_aux_weak_external *WE =
82+
reinterpret_cast<coff_aux_weak_external *>(Sym.AuxData.data());
83+
const Symbol *Target = Obj.findSymbol(*Sym.WeakTargetSymbolId);
84+
if (Target == nullptr)
85+
return createStringError(object_error::invalid_symbol_index,
86+
"Symbol '%s' is missing its weak target",
87+
Sym.Name.str().c_str());
88+
WE->TagIndex = Target->RawIndex;
89+
}
7890
}
7991
return Error::success();
8092
}
@@ -137,7 +149,7 @@ std::pair<size_t, size_t> COFFWriter::finalizeSymbolTable() {
137149
Error COFFWriter::finalize(bool IsBigObj) {
138150
if (Error E = finalizeRelocTargets())
139151
return E;
140-
if (Error E = finalizeSectionNumbers())
152+
if (Error E = finalizeSymbolContents())
141153
return E;
142154

143155
size_t SizeOfHeaders = 0;

tools/llvm-objcopy/COFF/Writer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class COFFWriter {
3131
StringTableBuilder StrTabBuilder;
3232

3333
Error finalizeRelocTargets();
34-
Error finalizeSectionNumbers();
34+
Error finalizeSymbolContents();
3535
void layoutSections();
3636
size_t finalizeStringTable();
3737
template <class SymbolTy> std::pair<size_t, size_t> finalizeSymbolTable();

0 commit comments

Comments
 (0)