Skip to content

Commit a795bd9

Browse files
author
Georgii Rymar
committed
[llvm-objcopy] - Do not crash on object that has relocations but no symbol table.
It was revealed by D69260. Tool crashed when scanned relocations in a object without a symbol table. This patch teaches it either to handle such objects (when relocations does not use symbols we do not need a symbol table to proceed) or to show an appropriate error otherwise. Differential revision: https://reviews.llvm.org/D69304
1 parent 27f6eed commit a795bd9

File tree

3 files changed

+115
-10
lines changed

3 files changed

+115
-10
lines changed

llvm/test/tools/llvm-objcopy/ELF/no-symbol-relocation.test

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
# RUN: yaml2obj %s > %t
2-
# RUN: llvm-objcopy %t %t2
1+
# RUN: yaml2obj --docnum=1 %s > %t1
2+
# RUN: llvm-objcopy %t1 %t2
33
# RUN: llvm-readobj --relocations %t2 | FileCheck %s
44

5-
!ELF
5+
--- !ELF
66
FileHeader:
77
Class: ELFCLASS64
88
Data: ELFDATA2LSB
@@ -21,11 +21,50 @@ Sections:
2121
Relocations:
2222
- Offset: 0x1000
2323
Type: R_X86_64_RELATIVE
24-
## TODO: llvm-objcopy crashes without the following line.
25-
Symbols: []
2624

2725
# CHECK: Relocations [
2826
# CHECK-NEXT: Section (2) .rel.text {
2927
# CHECK-NEXT: 0x1000 R_X86_64_RELATIVE - 0x0
3028
# CHECK-NEXT: }
3129
# CHECK-NEXT:]
30+
31+
## Check we produce a valid output when stripping unneeded symbols from an object that
32+
## has a symbol table and a relocation with a symbol index of 0.
33+
34+
# RUN: yaml2obj --docnum=2 %s > %t3
35+
# RUN: llvm-objcopy --strip-unneeded %t3 %t4
36+
# RUN: llvm-readobj --relocations --sections --symbols %t4 | FileCheck %s --check-prefix=STRIP
37+
38+
# STRIP: Relocations [
39+
# STRIP-NEXT: Section {{.*}} .rel.text {
40+
# STRIP-NEXT: 0x1000 R_X86_64_NONE - 0x0
41+
# STRIP-NEXT: }
42+
# STRIP-NEXT: ]
43+
# STRIP-NEXT: Symbols [
44+
# STRIP-NEXT: Symbol {
45+
# STRIP-NEXT: Name: (0)
46+
# STRIP-NEXT: Value: 0x0
47+
# STRIP-NEXT: Size: 0
48+
# STRIP-NEXT: Binding: Local (0x0)
49+
# STRIP-NEXT: Type: None (0x0)
50+
# STRIP-NEXT: Other: 0
51+
# STRIP-NEXT: Section: Undefined (0x0)
52+
# STRIP-NEXT: }
53+
# STRIP-NEXT: ]
54+
55+
--- !ELF
56+
FileHeader:
57+
Class: ELFCLASS64
58+
Data: ELFDATA2LSB
59+
Type: ET_REL
60+
Machine: EM_X86_64
61+
Sections:
62+
- Name: .text
63+
Type: SHT_PROGBITS
64+
- Name: .rel.text
65+
Type: SHT_REL
66+
Info: .text
67+
Relocations:
68+
- Offset: 0x1000
69+
Type: R_X86_64_NONE
70+
Symbols: []
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
## Check that we can copy an object that has a relocation
2+
## with a symbol index of 0 even when there is no symbol table.
3+
4+
# RUN: yaml2obj --docnum=1 %s -o %t1
5+
# RUN: llvm-objcopy %t1 %t2
6+
# RUN: llvm-readobj --relocations %t2 | FileCheck %s
7+
8+
# CHECK: Relocations [
9+
# CHECK-NEXT: Section {{.*}} .rel.text {
10+
# CHECK-NEXT: 0x1000 R_X86_64_RELATIVE - 0x0
11+
# CHECK-NEXT: }
12+
# CHECK-NEXT:]
13+
14+
--- !ELF
15+
FileHeader:
16+
Class: ELFCLASS64
17+
Data: ELFDATA2LSB
18+
Type: ET_REL
19+
Machine: EM_X86_64
20+
Sections:
21+
- Name: .text
22+
Type: SHT_PROGBITS
23+
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
24+
- Name: .rel.text
25+
Type: SHT_REL
26+
Info: .text
27+
Relocations:
28+
- Offset: 0x1000
29+
Type: R_X86_64_RELATIVE
30+
31+
## Check that we report an error when a relocation refers to a
32+
## non-zero symbol index but there is no symbol table.
33+
34+
# RUN: yaml2obj --docnum=2 %s -o %t3
35+
# RUN: not llvm-objcopy %t3 /dev/null 2>&1 | FileCheck %s --check-prefix=ERR
36+
37+
# ERR: error: '.rel.text': relocation references symbol with index 1, but there is no symbol table
38+
39+
--- !ELF
40+
FileHeader:
41+
Class: ELFCLASS64
42+
Data: ELFDATA2LSB
43+
Type: ET_REL
44+
Machine: EM_X86_64
45+
Sections:
46+
- Name: .text
47+
Type: SHT_PROGBITS
48+
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
49+
- Name: .rel.text
50+
Type: SHT_REL
51+
Info: .text
52+
Relocations:
53+
- Offset: 0x1000
54+
Symbol: 1
55+
Type: R_X86_64_NONE

llvm/tools/llvm-objcopy/ELF/Object.cpp

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -815,7 +815,8 @@ Error RelocationSection::removeSectionReferences(
815815
}
816816

817817
for (const Relocation &R : Relocations) {
818-
if (!R.RelocSymbol->DefinedIn || !ToRemove(R.RelocSymbol->DefinedIn))
818+
if (!R.RelocSymbol || !R.RelocSymbol->DefinedIn ||
819+
!ToRemove(R.RelocSymbol->DefinedIn))
819820
continue;
820821
return createStringError(llvm::errc::invalid_argument,
821822
"section '%s' cannot be removed: (%s+0x%" PRIx64
@@ -868,7 +869,8 @@ static void writeRel(const RelRange &Relocations, T *Buf) {
868869
for (const auto &Reloc : Relocations) {
869870
Buf->r_offset = Reloc.Offset;
870871
setAddend(*Buf, Reloc.Addend);
871-
Buf->setSymbolAndType(Reloc.RelocSymbol->Index, Reloc.Type, false);
872+
Buf->setSymbolAndType(Reloc.RelocSymbol ? Reloc.RelocSymbol->Index : 0,
873+
Reloc.Type, false);
872874
++Buf;
873875
}
874876
}
@@ -893,7 +895,7 @@ void RelocationSection::accept(MutableSectionVisitor &Visitor) {
893895
Error RelocationSection::removeSymbols(
894896
function_ref<bool(const Symbol &)> ToRemove) {
895897
for (const Relocation &Reloc : Relocations)
896-
if (ToRemove(*Reloc.RelocSymbol))
898+
if (Reloc.RelocSymbol && ToRemove(*Reloc.RelocSymbol))
897899
return createStringError(
898900
llvm::errc::invalid_argument,
899901
"not stripping symbol '%s' because it is named in a relocation",
@@ -903,7 +905,8 @@ Error RelocationSection::removeSymbols(
903905

904906
void RelocationSection::markSymbols() {
905907
for (const Relocation &Reloc : Relocations)
906-
Reloc.RelocSymbol->Referenced = true;
908+
if (Reloc.RelocSymbol)
909+
Reloc.RelocSymbol->Referenced = true;
907910
}
908911

909912
void RelocationSection::replaceSectionReferences(
@@ -1418,7 +1421,15 @@ static void initRelocations(RelocationSection *Relocs,
14181421
ToAdd.Offset = Rel.r_offset;
14191422
getAddend(ToAdd.Addend, Rel);
14201423
ToAdd.Type = Rel.getType(false);
1421-
ToAdd.RelocSymbol = SymbolTable->getSymbolByIndex(Rel.getSymbol(false));
1424+
1425+
if (uint32_t Sym = Rel.getSymbol(false)) {
1426+
if (!SymbolTable)
1427+
error("'" + Relocs->Name +
1428+
"': relocation references symbol with index " + Twine(Sym) +
1429+
", but there is no symbol table");
1430+
ToAdd.RelocSymbol = SymbolTable->getSymbolByIndex(Sym);
1431+
}
1432+
14221433
Relocs->addRelocation(ToAdd);
14231434
}
14241435
}

0 commit comments

Comments
 (0)