diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp --- a/bolt/lib/Rewrite/RewriteInstance.cpp +++ b/bolt/lib/Rewrite/RewriteInstance.cpp @@ -1277,9 +1277,12 @@ ErrorOr Section = BC->getSectionForAddress(EntryAddress); assert(Section && "cannot get section for address"); - BF = BC->createBinaryFunction(Rel->Symbol->getName().str() + "@PLT", *Section, - EntryAddress, 0, EntrySize, - Section->getAlignment()); + if (!BF) + BF = BC->createBinaryFunction(Rel->Symbol->getName().str() + "@PLT", + *Section, EntryAddress, 0, EntrySize, + Section->getAlignment()); + else + BF->addAlternativeName(Rel->Symbol->getName().str() + "@PLT"); setPLTSymbol(BF, Rel->Symbol->getName()); } @@ -1411,15 +1414,19 @@ continue; analyzeOnePLTSection(Section, PLTSI->EntrySize); - // If we did not register any function at the start of the section, - // then it must be a general PLT entry. Add a function at the location. - if (BC->getBinaryFunctions().find(Section.getAddress()) == - BC->getBinaryFunctions().end()) { - BinaryFunction *BF = BC->createBinaryFunction( + + BinaryFunction *PltBF; + auto BFIter = BC->getBinaryFunctions().find(Section.getAddress()); + if (BFIter != BC->getBinaryFunctions().end()) { + PltBF = &BFIter->second; + } else { + // If we did not register any function at the start of the section, + // then it must be a general PLT entry. Add a function at the location. + PltBF = BC->createBinaryFunction( "__BOLT_PSEUDO_" + Section.getName().str(), Section, Section.getAddress(), 0, PLTSI->EntrySize, Section.getAlignment()); - BF->setPseudo(true); } + PltBF->setPseudo(true); } } diff --git a/bolt/test/X86/Inputs/plt-mold.yaml b/bolt/test/X86/Inputs/plt-mold.yaml new file mode 100644 --- /dev/null +++ b/bolt/test/X86/Inputs/plt-mold.yaml @@ -0,0 +1,399 @@ +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 + Entry: 0x13D0 +ProgramHeaders: + - Type: PT_PHDR + Flags: [ PF_R ] + VAddr: 0x40 + Align: 0x8 + - Type: PT_INTERP + Flags: [ PF_R ] + FirstSec: .interp + LastSec: .interp + VAddr: 0x270 + - Type: PT_LOAD + Flags: [ PF_R ] + FirstSec: .interp + LastSec: .rodata.str + Align: 0x1000 + - Type: PT_LOAD + Flags: [ PF_X, PF_R ] + FirstSec: .plt + LastSec: .text + VAddr: 0x13A0 + Align: 0x1000 + - Type: PT_LOAD + Flags: [ PF_W, PF_R ] + FirstSec: .dynamic + LastSec: .relro_padding + VAddr: 0x23F8 + Align: 0x1000 + - Type: PT_LOAD + Flags: [ PF_W, PF_R ] + FirstSec: .got.plt + LastSec: .got.plt + VAddr: 0x3550 + Align: 0x1000 + - Type: PT_DYNAMIC + Flags: [ PF_W, PF_R ] + FirstSec: .dynamic + LastSec: .dynamic + VAddr: 0x23F8 + Align: 0x8 + - Type: PT_GNU_EH_FRAME + Flags: [ PF_R ] + FirstSec: .eh_frame_hdr + LastSec: .eh_frame_hdr + VAddr: 0x37C + Align: 0x4 + - Type: PT_GNU_STACK + Flags: [ PF_W, PF_R ] + - Type: PT_GNU_RELRO + Flags: [ PF_R ] + FirstSec: .dynamic + LastSec: .relro_padding + VAddr: 0x23F8 +Sections: + - Name: .interp + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Address: 0x270 + AddressAlign: 0x1 + Content: 2F6C696236342F6C642D6C696E75782D7838362D36342E736F2E3200 + - Name: .gnu.hash + Type: SHT_GNU_HASH + Flags: [ SHF_ALLOC ] + Address: 0x290 + Link: .dynsym + AddressAlign: 0x8 + Header: + SymNdx: 0x2 + Shift2: 0x1A + BloomFilter: [ 0x0 ] + HashBuckets: [ 0x0 ] + HashValues: [ ] + - Name: .dynsym + Type: SHT_DYNSYM + Flags: [ SHF_ALLOC ] + Address: 0x2B0 + Link: .dynstr + AddressAlign: 0x8 + - Name: .dynstr + Type: SHT_STRTAB + Flags: [ SHF_ALLOC ] + Address: 0x2E0 + AddressAlign: 0x1 + - Name: .gnu.version + Type: SHT_GNU_versym + Flags: [ SHF_ALLOC ] + Address: 0x2FE + Link: .dynsym + AddressAlign: 0x2 + Entries: [ 0, 2 ] + - Name: .gnu.version_r + Type: SHT_GNU_verneed + Flags: [ SHF_ALLOC ] + Address: 0x308 + Link: .dynstr + AddressAlign: 0x8 + Dependencies: + - Version: 1 + File: libc.so.6 + Entries: + - Name: GLIBC_2.2.5 + Hash: 157882997 + Flags: 0 + Other: 2 + - Name: .rela.plt + Type: SHT_RELA + Flags: [ SHF_ALLOC, SHF_INFO_LINK ] + Address: 0x328 + Link: .dynsym + AddressAlign: 0x8 + Info: .got.plt + Relocations: + - Offset: 0x3568 + Symbol: printf + Type: R_X86_64_JUMP_SLOT + - Name: .eh_frame + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Address: 0x340 + AddressAlign: 0x8 + Content: 1400000000000000017A5200017810011B0C0708900100001C0000001C000000701000002500000000410E108602430D06600C070800000000000000 + - Name: .eh_frame_hdr + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Address: 0x37C + AddressAlign: 0x4 + Content: 011B033BC0FFFFFF0100000054100000DCFFFFFF + - Name: .rodata.str + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Address: 0x390 + AddressAlign: 0x1 + Content: 48656C6C6F20776F726C64210A00 + - Name: .plt + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x13A0 + AddressAlign: 0x10 + Content: F30F1EFA4153FF35AC210000FF25AE210000CCCCCCCCCCCCCCCCCCCCCCCCCCCCF30F1EFA41BB00000000FF2598210000 + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x13D0 + AddressAlign: 0x10 + Content: 554889E54883EC10C745FC00000000488D3DAAEFFFFFB000E8D3FFFFFF31C04883C4105DC3 + - Name: .dynamic + Type: SHT_DYNAMIC + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x23F8 + Link: .dynstr + AddressAlign: 0x8 + Entries: + - Tag: DT_NEEDED + Value: 0x1 + - Tag: DT_JMPREL + Value: 0x328 + - Tag: DT_PLTRELSZ + Value: 0x18 + - Tag: DT_PLTREL + Value: 0x7 + - Tag: DT_PLTGOT + Value: 0x3550 + - Tag: DT_SYMTAB + Value: 0x2B0 + - Tag: DT_SYMENT + Value: 0x18 + - Tag: DT_STRTAB + Value: 0x2E0 + - Tag: DT_STRSZ + Value: 0x1E + - Tag: DT_VERSYM + Value: 0x2FE + - Tag: DT_VERNEED + Value: 0x308 + - Tag: DT_VERNEEDNUM + Value: 0x1 + - Tag: DT_GNU_HASH + Value: 0x290 + - Tag: DT_FLAGS_1 + Value: 0x8000000 + - Tag: DT_DEBUG + Value: 0x0 + - Tag: DT_NULL + Value: 0x0 + - Tag: DT_NULL + Value: 0x0 + - Tag: DT_NULL + Value: 0x0 + - Tag: DT_NULL + Value: 0x0 + - Tag: DT_NULL + Value: 0x0 + - Tag: DT_NULL + Value: 0x0 + - Name: .got + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x2548 + AddressAlign: 0x8 + Content: '0000000000000000' + - Name: .relro_padding + Type: SHT_NOBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x2550 + AddressAlign: 0x1 + Size: 0xAB0 + - Name: .got.plt + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x3550 + AddressAlign: 0x8 + Content: F82300000000000000000000000000000000000000000000A013000000000000 + - Name: .rela.text + Type: SHT_RELA + Flags: [ SHF_INFO_LINK ] + Link: .symtab + AddressAlign: 0x8 + Info: .text + Relocations: + - Offset: 0x13E2 + Symbol: .L.str + Type: R_X86_64_PC32 + Addend: -4 + - Offset: 0x13E9 + Symbol: printf + Type: R_X86_64_PLT32 + Addend: -4 + - Type: SectionHeaderTable + Sections: + - Name: .interp + - Name: .gnu.hash + - Name: .dynsym + - Name: .dynstr + - Name: .gnu.version + - Name: .gnu.version_r + - Name: .rela.plt + - Name: .eh_frame + - Name: .eh_frame_hdr + - Name: .rodata.str + - Name: .plt + - Name: .text + - Name: .rela.text + - Name: .dynamic + - Name: .got + - Name: .relro_padding + - Name: .got.plt + - Name: .symtab + - Name: .strtab + - Name: .shstrtab +Symbols: + - Name: .interp + Type: STT_SECTION + Section: .interp + Value: 0x270 + - Name: .gnu.hash + Type: STT_SECTION + Section: .gnu.hash + Value: 0x290 + - Name: .dynsym + Type: STT_SECTION + Section: .dynsym + Value: 0x2B0 + - Name: .dynstr + Type: STT_SECTION + Section: .dynstr + Value: 0x2E0 + - Name: .gnu.version + Type: STT_SECTION + Section: .gnu.version + Value: 0x2FE + - Name: .gnu.version_r + Type: STT_SECTION + Section: .gnu.version_r + Value: 0x308 + - Name: .rela.plt + Type: STT_SECTION + Section: .rela.plt + Value: 0x328 + - Name: .eh_frame + Type: STT_SECTION + Section: .eh_frame + Value: 0x340 + - Name: .eh_frame_hdr + Type: STT_SECTION + Section: .eh_frame_hdr + Value: 0x37C + - Name: .rodata.str + Type: STT_SECTION + Section: .rodata.str + Value: 0x390 + - Name: .plt + Type: STT_SECTION + Section: .plt + Value: 0x13A0 + - Name: .text + Type: STT_SECTION + Section: .text + Value: 0x13D0 + - Name: .dynamic + Type: STT_SECTION + Section: .dynamic + Value: 0x23F8 + - Name: .got + Type: STT_SECTION + Section: .got + Value: 0x2548 + - Name: .relro_padding + Type: STT_SECTION + Section: .relro_padding + Value: 0x2550 + - Name: .got.plt + Type: STT_SECTION + Section: .got.plt + Value: 0x3550 + - Name: 'printf$plt' + Type: STT_FUNC + Section: .plt + Value: 0x13C0 + - Name: hello.c + Type: STT_FILE + Index: SHN_ABS + - Name: .L.str + Type: STT_OBJECT + Section: .rodata.str + Value: 0x390 + - Name: main + Type: STT_FUNC + Section: .text + Value: 0x13D0 + Size: 0x25 + - Name: __ehdr_start + Section: .interp + - Name: __init_array_start + Index: SHN_ABS + - Name: __init_array_end + Index: SHN_ABS + - Name: __fini_array_start + Index: SHN_ABS + - Name: __fini_array_end + Index: SHN_ABS + - Name: __preinit_array_start + Index: SHN_ABS + - Name: __preinit_array_end + Index: SHN_ABS + - Name: _DYNAMIC + Section: .dynamic + Value: 0x23F8 + - Name: _GLOBAL_OFFSET_TABLE_ + Section: .got.plt + Value: 0x3550 + - Name: _PROCEDURE_LINKAGE_TABLE_ + Section: .plt + Value: 0x13A0 + - Name: __bss_start + Index: SHN_ABS + - Name: _end + Section: .got.plt + Value: 0x3570 + - Name: _etext + Section: .text + Value: 0x13F5 + - Name: _edata + Section: .got.plt + Value: 0x3570 + - Name: __executable_start + Section: .interp + - Name: __rela_iplt_start + Index: SHN_ABS + - Name: __rela_iplt_end + Index: SHN_ABS + - Name: __GNU_EH_FRAME_HDR + Section: .eh_frame_hdr + Value: 0x37C + - Name: end + Section: .got.plt + Value: 0x3570 + - Name: etext + Section: .text + Value: 0x13F5 + - Name: edata + Section: .got.plt + Value: 0x3570 + - Name: __dso_handle + Section: .interp + - Name: _TLS_MODULE_BASE_ + Section: .interp + - Name: printf + Binding: STB_GLOBAL +DynamicSymbols: + - Name: printf + Type: STT_FUNC + Binding: STB_GLOBAL +... diff --git a/bolt/test/X86/plt-mold.test b/bolt/test/X86/plt-mold.test new file mode 100644 --- /dev/null +++ b/bolt/test/X86/plt-mold.test @@ -0,0 +1,6 @@ +# RUN: yaml2obj %p/Inputs/plt-mold.yaml &> %t.exe +# RUN: llvm-bolt %t.exe --print-cfg --print-only=main.* -o %t.out | FileCheck %s + +## Check that llvm-bolt correctly parses PLT created by mold linker. +## The only call instruction in main() should be a call to printf() in PLT. +CHECK: callq "printf$plt