Mercurial > hg > CbC > CbC_llvm
comparison lld/ELF/InputFiles.cpp @ 173:0572611fdcc8 llvm10 llvm12
reorgnization done
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 25 May 2020 11:55:54 +0900 |
parents | 1d019706d866 |
children | 2e18cbf3894f |
comparison
equal
deleted
inserted
replaced
172:9fbae9c8bf63 | 173:0572611fdcc8 |
---|---|
34 using namespace llvm::ELF; | 34 using namespace llvm::ELF; |
35 using namespace llvm::object; | 35 using namespace llvm::object; |
36 using namespace llvm::sys; | 36 using namespace llvm::sys; |
37 using namespace llvm::sys::fs; | 37 using namespace llvm::sys::fs; |
38 using namespace llvm::support::endian; | 38 using namespace llvm::support::endian; |
39 | 39 using namespace lld; |
40 namespace lld { | 40 using namespace lld::elf; |
41 | |
42 bool InputFile::isInGroup; | |
43 uint32_t InputFile::nextGroupId; | |
44 | |
45 std::vector<ArchiveFile *> elf::archiveFiles; | |
46 std::vector<BinaryFile *> elf::binaryFiles; | |
47 std::vector<BitcodeFile *> elf::bitcodeFiles; | |
48 std::vector<LazyObjFile *> elf::lazyObjFiles; | |
49 std::vector<InputFile *> elf::objectFiles; | |
50 std::vector<SharedFile *> elf::sharedFiles; | |
51 | |
52 std::unique_ptr<TarWriter> elf::tar; | |
53 | |
41 // Returns "<internal>", "foo.a(bar.o)" or "baz.o". | 54 // Returns "<internal>", "foo.a(bar.o)" or "baz.o". |
42 std::string toString(const elf::InputFile *f) { | 55 std::string lld::toString(const InputFile *f) { |
43 if (!f) | 56 if (!f) |
44 return "<internal>"; | 57 return "<internal>"; |
45 | 58 |
46 if (f->toStringCache.empty()) { | 59 if (f->toStringCache.empty()) { |
47 if (f->archiveName.empty()) | 60 if (f->archiveName.empty()) |
49 else | 62 else |
50 f->toStringCache = (f->archiveName + "(" + f->getName() + ")").str(); | 63 f->toStringCache = (f->archiveName + "(" + f->getName() + ")").str(); |
51 } | 64 } |
52 return f->toStringCache; | 65 return f->toStringCache; |
53 } | 66 } |
54 | |
55 namespace elf { | |
56 bool InputFile::isInGroup; | |
57 uint32_t InputFile::nextGroupId; | |
58 std::vector<BinaryFile *> binaryFiles; | |
59 std::vector<BitcodeFile *> bitcodeFiles; | |
60 std::vector<LazyObjFile *> lazyObjFiles; | |
61 std::vector<InputFile *> objectFiles; | |
62 std::vector<SharedFile *> sharedFiles; | |
63 | |
64 std::unique_ptr<TarWriter> tar; | |
65 | 67 |
66 static ELFKind getELFKind(MemoryBufferRef mb, StringRef archiveName) { | 68 static ELFKind getELFKind(MemoryBufferRef mb, StringRef archiveName) { |
67 unsigned char size; | 69 unsigned char size; |
68 unsigned char endian; | 70 unsigned char endian; |
69 std::tie(size, endian) = getElfArchType(mb.getBuffer()); | 71 std::tie(size, endian) = getElfArchType(mb.getBuffer()); |
99 // Otherwise, a new file will get a new group ID. | 101 // Otherwise, a new file will get a new group ID. |
100 if (!isInGroup) | 102 if (!isInGroup) |
101 ++nextGroupId; | 103 ++nextGroupId; |
102 } | 104 } |
103 | 105 |
104 Optional<MemoryBufferRef> readFile(StringRef path) { | 106 Optional<MemoryBufferRef> elf::readFile(StringRef path) { |
105 // The --chroot option changes our virtual root directory. | 107 // The --chroot option changes our virtual root directory. |
106 // This is useful when you are dealing with files created by --reproduce. | 108 // This is useful when you are dealing with files created by --reproduce. |
107 if (!config->chroot.empty() && path.startswith("/")) | 109 if (!config->chroot.empty() && path.startswith("/")) |
108 path = saver.save(config->chroot + path); | 110 path = saver.save(config->chroot + path); |
109 | 111 |
136 return true; | 138 return true; |
137 if (isMipsN32Abi(file) == config->mipsN32Abi) | 139 if (isMipsN32Abi(file) == config->mipsN32Abi) |
138 return true; | 140 return true; |
139 } | 141 } |
140 | 142 |
141 if (!config->emulation.empty()) { | 143 StringRef target = |
142 error(toString(file) + " is incompatible with " + config->emulation); | 144 !config->bfdname.empty() ? config->bfdname : config->emulation; |
145 if (!target.empty()) { | |
146 error(toString(file) + " is incompatible with " + target); | |
143 return false; | 147 return false; |
144 } | 148 } |
145 | 149 |
146 InputFile *existing; | 150 InputFile *existing; |
147 if (!objectFiles.empty()) | 151 if (!objectFiles.empty()) |
148 existing = objectFiles[0]; | 152 existing = objectFiles[0]; |
149 else if (!sharedFiles.empty()) | 153 else if (!sharedFiles.empty()) |
150 existing = sharedFiles[0]; | 154 existing = sharedFiles[0]; |
155 else if (!bitcodeFiles.empty()) | |
156 existing = bitcodeFiles[0]; | |
151 else | 157 else |
152 existing = bitcodeFiles[0]; | 158 llvm_unreachable("Must have -m, OUTPUT_FORMAT or existing input file to " |
159 "determine target emulation"); | |
153 | 160 |
154 error(toString(file) + " is incompatible with " + toString(existing)); | 161 error(toString(file) + " is incompatible with " + toString(existing)); |
155 return false; | 162 return false; |
156 } | 163 } |
157 | 164 |
166 return; | 173 return; |
167 } | 174 } |
168 | 175 |
169 // .a file | 176 // .a file |
170 if (auto *f = dyn_cast<ArchiveFile>(file)) { | 177 if (auto *f = dyn_cast<ArchiveFile>(file)) { |
178 archiveFiles.push_back(f); | |
171 f->parse(); | 179 f->parse(); |
172 return; | 180 return; |
173 } | 181 } |
174 | 182 |
175 // Lazy object file | 183 // Lazy object file |
199 objectFiles.push_back(file); | 207 objectFiles.push_back(file); |
200 cast<ObjFile<ELFT>>(file)->parse(); | 208 cast<ObjFile<ELFT>>(file)->parse(); |
201 } | 209 } |
202 | 210 |
203 // Add symbols in File to the symbol table. | 211 // Add symbols in File to the symbol table. |
204 void parseFile(InputFile *file) { | 212 void elf::parseFile(InputFile *file) { |
205 switch (config->ekind) { | 213 switch (config->ekind) { |
206 case ELF32LEKind: | 214 case ELF32LEKind: |
207 doParseFile<ELF32LE>(file); | 215 doParseFile<ELF32LE>(file); |
208 return; | 216 return; |
209 case ELF32BEKind: | 217 case ELF32BEKind: |
262 case ELF64BEKind: | 270 case ELF64BEKind: |
263 return getSrcMsgAux(cast<ObjFile<ELF64BE>>(*this), sym, sec, offset); | 271 return getSrcMsgAux(cast<ObjFile<ELF64BE>>(*this), sym, sec, offset); |
264 } | 272 } |
265 } | 273 } |
266 | 274 |
267 template <class ELFT> void ObjFile<ELFT>::initializeDwarf() { | 275 template <class ELFT> DWARFCache *ObjFile<ELFT>::getDwarf() { |
268 dwarf = make<DWARFCache>(std::make_unique<DWARFContext>( | 276 llvm::call_once(initDwarf, [this]() { |
269 std::make_unique<LLDDwarfObj<ELFT>>(this))); | 277 dwarf = std::make_unique<DWARFCache>(std::make_unique<DWARFContext>( |
278 std::make_unique<LLDDwarfObj<ELFT>>(this), "", | |
279 [&](Error err) { warn(getName() + ": " + toString(std::move(err))); }, | |
280 [&](Error warning) { | |
281 warn(getName() + ": " + toString(std::move(warning))); | |
282 })); | |
283 }); | |
284 | |
285 return dwarf.get(); | |
270 } | 286 } |
271 | 287 |
272 // Returns the pair of file name and line number describing location of data | 288 // Returns the pair of file name and line number describing location of data |
273 // object (variable, array, etc) definition. | 289 // object (variable, array, etc) definition. |
274 template <class ELFT> | 290 template <class ELFT> |
275 Optional<std::pair<std::string, unsigned>> | 291 Optional<std::pair<std::string, unsigned>> |
276 ObjFile<ELFT>::getVariableLoc(StringRef name) { | 292 ObjFile<ELFT>::getVariableLoc(StringRef name) { |
277 llvm::call_once(initDwarfLine, [this]() { initializeDwarf(); }); | 293 return getDwarf()->getVariableLoc(name); |
278 | |
279 return dwarf->getVariableLoc(name); | |
280 } | 294 } |
281 | 295 |
282 // Returns source line information for a given offset | 296 // Returns source line information for a given offset |
283 // using DWARF debug info. | 297 // using DWARF debug info. |
284 template <class ELFT> | 298 template <class ELFT> |
285 Optional<DILineInfo> ObjFile<ELFT>::getDILineInfo(InputSectionBase *s, | 299 Optional<DILineInfo> ObjFile<ELFT>::getDILineInfo(InputSectionBase *s, |
286 uint64_t offset) { | 300 uint64_t offset) { |
287 llvm::call_once(initDwarfLine, [this]() { initializeDwarf(); }); | |
288 | |
289 // Detect SectionIndex for specified section. | 301 // Detect SectionIndex for specified section. |
290 uint64_t sectionIndex = object::SectionedAddress::UndefSection; | 302 uint64_t sectionIndex = object::SectionedAddress::UndefSection; |
291 ArrayRef<InputSectionBase *> sections = s->file->getSections(); | 303 ArrayRef<InputSectionBase *> sections = s->file->getSections(); |
292 for (uint64_t curIndex = 0; curIndex < sections.size(); ++curIndex) { | 304 for (uint64_t curIndex = 0; curIndex < sections.size(); ++curIndex) { |
293 if (s == sections[curIndex]) { | 305 if (s == sections[curIndex]) { |
294 sectionIndex = curIndex; | 306 sectionIndex = curIndex; |
295 break; | 307 break; |
296 } | 308 } |
297 } | 309 } |
298 | 310 |
299 // Use fake address calculated by adding section file offset and offset in | 311 return getDwarf()->getDILineInfo(offset, sectionIndex); |
300 // section. See comments for ObjectInfo class. | |
301 return dwarf->getDILineInfo(s->getOffsetInFile() + offset, sectionIndex); | |
302 } | 312 } |
303 | 313 |
304 ELFFileBase::ELFFileBase(Kind k, MemoryBufferRef mb) : InputFile(k, mb) { | 314 ELFFileBase::ELFFileBase(Kind k, MemoryBufferRef mb) : InputFile(k, mb) { |
305 ekind = getELFKind(mb, ""); | 315 ekind = getELFKind(mb, ""); |
306 | 316 |
415 return signature; | 425 return signature; |
416 } | 426 } |
417 | 427 |
418 template <class ELFT> | 428 template <class ELFT> |
419 bool ObjFile<ELFT>::shouldMerge(const Elf_Shdr &sec, StringRef name) { | 429 bool ObjFile<ELFT>::shouldMerge(const Elf_Shdr &sec, StringRef name) { |
430 if (!(sec.sh_flags & SHF_MERGE)) | |
431 return false; | |
432 | |
420 // On a regular link we don't merge sections if -O0 (default is -O1). This | 433 // On a regular link we don't merge sections if -O0 (default is -O1). This |
421 // sometimes makes the linker significantly faster, although the output will | 434 // sometimes makes the linker significantly faster, although the output will |
422 // be bigger. | 435 // be bigger. |
423 // | 436 // |
424 // Doing the same for -r would create a problem as it would combine sections | 437 // Doing the same for -r would create a problem as it would combine sections |
450 if (sec.sh_size % entSize) | 463 if (sec.sh_size % entSize) |
451 fatal(toString(this) + ":(" + name + "): SHF_MERGE section size (" + | 464 fatal(toString(this) + ":(" + name + "): SHF_MERGE section size (" + |
452 Twine(sec.sh_size) + ") must be a multiple of sh_entsize (" + | 465 Twine(sec.sh_size) + ") must be a multiple of sh_entsize (" + |
453 Twine(entSize) + ")"); | 466 Twine(entSize) + ")"); |
454 | 467 |
455 uint64_t flags = sec.sh_flags; | 468 if (sec.sh_flags & SHF_WRITE) |
456 if (!(flags & SHF_MERGE)) | |
457 return false; | |
458 if (flags & SHF_WRITE) | |
459 fatal(toString(this) + ":(" + name + | 469 fatal(toString(this) + ":(" + name + |
460 "): writable SHF_MERGE section is not supported"); | 470 "): writable SHF_MERGE section is not supported"); |
461 | 471 |
462 return true; | 472 return true; |
463 } | 473 } |
660 // For ARM only, to set the EF_ARM_ABI_FLOAT_SOFT or EF_ARM_ABI_FLOAT_HARD | 670 // For ARM only, to set the EF_ARM_ABI_FLOAT_SOFT or EF_ARM_ABI_FLOAT_HARD |
661 // flag in the ELF Header we need to look at Tag_ABI_VFP_args to find out how | 671 // flag in the ELF Header we need to look at Tag_ABI_VFP_args to find out how |
662 // the input objects have been compiled. | 672 // the input objects have been compiled. |
663 static void updateARMVFPArgs(const ARMAttributeParser &attributes, | 673 static void updateARMVFPArgs(const ARMAttributeParser &attributes, |
664 const InputFile *f) { | 674 const InputFile *f) { |
665 if (!attributes.hasAttribute(ARMBuildAttrs::ABI_VFP_args)) | 675 Optional<unsigned> attr = |
676 attributes.getAttributeValue(ARMBuildAttrs::ABI_VFP_args); | |
677 if (!attr.hasValue()) | |
666 // If an ABI tag isn't present then it is implicitly given the value of 0 | 678 // If an ABI tag isn't present then it is implicitly given the value of 0 |
667 // which maps to ARMBuildAttrs::BaseAAPCS. However many assembler files, | 679 // which maps to ARMBuildAttrs::BaseAAPCS. However many assembler files, |
668 // including some in glibc that don't use FP args (and should have value 3) | 680 // including some in glibc that don't use FP args (and should have value 3) |
669 // don't have the attribute so we do not consider an implicit value of 0 | 681 // don't have the attribute so we do not consider an implicit value of 0 |
670 // as a clash. | 682 // as a clash. |
671 return; | 683 return; |
672 | 684 |
673 unsigned vfpArgs = attributes.getAttributeValue(ARMBuildAttrs::ABI_VFP_args); | 685 unsigned vfpArgs = attr.getValue(); |
674 ARMVFPArgKind arg; | 686 ARMVFPArgKind arg; |
675 switch (vfpArgs) { | 687 switch (vfpArgs) { |
676 case ARMBuildAttrs::BaseAAPCS: | 688 case ARMBuildAttrs::BaseAAPCS: |
677 arg = ARMVFPArgKind::Base; | 689 arg = ARMVFPArgKind::Base; |
678 break; | 690 break; |
705 // The ARM Attributes section contains information about the architecture chosen | 717 // The ARM Attributes section contains information about the architecture chosen |
706 // at compile time. We follow the convention that if at least one input object | 718 // at compile time. We follow the convention that if at least one input object |
707 // is compiled with an architecture that supports these features then lld is | 719 // is compiled with an architecture that supports these features then lld is |
708 // permitted to use them. | 720 // permitted to use them. |
709 static void updateSupportedARMFeatures(const ARMAttributeParser &attributes) { | 721 static void updateSupportedARMFeatures(const ARMAttributeParser &attributes) { |
710 if (!attributes.hasAttribute(ARMBuildAttrs::CPU_arch)) | 722 Optional<unsigned> attr = |
711 return; | 723 attributes.getAttributeValue(ARMBuildAttrs::CPU_arch); |
712 auto arch = attributes.getAttributeValue(ARMBuildAttrs::CPU_arch); | 724 if (!attr.hasValue()) |
725 return; | |
726 auto arch = attr.getValue(); | |
713 switch (arch) { | 727 switch (arch) { |
714 case ARMBuildAttrs::Pre_v4: | 728 case ARMBuildAttrs::Pre_v4: |
715 case ARMBuildAttrs::v4: | 729 case ARMBuildAttrs::v4: |
716 case ARMBuildAttrs::v4T: | 730 case ARMBuildAttrs::v4T: |
717 // Architectures prior to v5 do not support BLX instruction | 731 // Architectures prior to v5 do not support BLX instruction |
840 case SHT_ARM_ATTRIBUTES: { | 854 case SHT_ARM_ATTRIBUTES: { |
841 if (config->emachine != EM_ARM) | 855 if (config->emachine != EM_ARM) |
842 break; | 856 break; |
843 ARMAttributeParser attributes; | 857 ARMAttributeParser attributes; |
844 ArrayRef<uint8_t> contents = check(this->getObj().getSectionContents(&sec)); | 858 ArrayRef<uint8_t> contents = check(this->getObj().getSectionContents(&sec)); |
845 attributes.Parse(contents, /*isLittle*/ config->ekind == ELF32LEKind); | 859 if (Error e = attributes.parse(contents, config->ekind == ELF32LEKind |
860 ? support::little | |
861 : support::big)) { | |
862 auto *isec = make<InputSection>(*this, sec, name); | |
863 warn(toString(isec) + ": " + llvm::toString(std::move(e))); | |
864 break; | |
865 } | |
846 updateSupportedARMFeatures(attributes); | 866 updateSupportedARMFeatures(attributes); |
847 updateARMVFPArgs(attributes, this); | 867 updateARMVFPArgs(attributes, this); |
848 | 868 |
849 // FIXME: Retain the first attribute section we see. The eglibc ARM | 869 // FIXME: Retain the first attribute section we see. The eglibc ARM |
850 // dynamic loaders require the presence of an attribute section for dlopen | 870 // dynamic loaders require the presence of an attribute section for dlopen |
1140 toELFString(sym)); | 1160 toELFString(sym)); |
1141 | 1161 |
1142 if (tar && c.getParent()->isThin()) | 1162 if (tar && c.getParent()->isThin()) |
1143 tar->append(relativeToRoot(CHECK(c.getFullName(), this)), mb.getBuffer()); | 1163 tar->append(relativeToRoot(CHECK(c.getFullName(), this)), mb.getBuffer()); |
1144 | 1164 |
1145 InputFile *file = createObjectFile( | 1165 InputFile *file = createObjectFile(mb, getName(), c.getChildOffset()); |
1146 mb, getName(), c.getParent()->isThin() ? 0 : c.getChildOffset()); | |
1147 file->groupId = groupId; | 1166 file->groupId = groupId; |
1148 parseFile(file); | 1167 parseFile(file); |
1168 } | |
1169 | |
1170 size_t ArchiveFile::getMemberCount() const { | |
1171 size_t count = 0; | |
1172 Error err = Error::success(); | |
1173 for (const Archive::Child &c : file->children(err)) { | |
1174 (void)c; | |
1175 ++count; | |
1176 } | |
1177 // This function is used by --print-archive-stats=, where an error does not | |
1178 // really matter. | |
1179 consumeError(std::move(err)); | |
1180 return count; | |
1149 } | 1181 } |
1150 | 1182 |
1151 unsigned SharedFile::vernauxNum; | 1183 unsigned SharedFile::vernauxNum; |
1152 | 1184 |
1153 // Parse the version definitions in the object file if present, and return a | 1185 // Parse the version definitions in the object file if present, and return a |
1175 unsigned verdefIndex = curVerdef->vd_ndx; | 1207 unsigned verdefIndex = curVerdef->vd_ndx; |
1176 verdefs.resize(verdefIndex + 1); | 1208 verdefs.resize(verdefIndex + 1); |
1177 verdefs[verdefIndex] = curVerdef; | 1209 verdefs[verdefIndex] = curVerdef; |
1178 } | 1210 } |
1179 return verdefs; | 1211 return verdefs; |
1212 } | |
1213 | |
1214 // Parse SHT_GNU_verneed to properly set the name of a versioned undefined | |
1215 // symbol. We detect fatal issues which would cause vulnerabilities, but do not | |
1216 // implement sophisticated error checking like in llvm-readobj because the value | |
1217 // of such diagnostics is low. | |
1218 template <typename ELFT> | |
1219 std::vector<uint32_t> SharedFile::parseVerneed(const ELFFile<ELFT> &obj, | |
1220 const typename ELFT::Shdr *sec) { | |
1221 if (!sec) | |
1222 return {}; | |
1223 std::vector<uint32_t> verneeds; | |
1224 ArrayRef<uint8_t> data = CHECK(obj.getSectionContents(sec), this); | |
1225 const uint8_t *verneedBuf = data.begin(); | |
1226 for (unsigned i = 0; i != sec->sh_info; ++i) { | |
1227 if (verneedBuf + sizeof(typename ELFT::Verneed) > data.end() || | |
1228 uintptr_t(verneedBuf) % sizeof(uint32_t) != 0) | |
1229 fatal(toString(this) + " has an invalid Verneed"); | |
1230 auto *vn = reinterpret_cast<const typename ELFT::Verneed *>(verneedBuf); | |
1231 const uint8_t *vernauxBuf = verneedBuf + vn->vn_aux; | |
1232 for (unsigned j = 0; j != vn->vn_cnt; ++j) { | |
1233 if (vernauxBuf + sizeof(typename ELFT::Vernaux) > data.end() || | |
1234 uintptr_t(vernauxBuf) % sizeof(uint32_t) != 0) | |
1235 fatal(toString(this) + " has an invalid Vernaux"); | |
1236 auto *aux = reinterpret_cast<const typename ELFT::Vernaux *>(vernauxBuf); | |
1237 if (aux->vna_name >= this->stringTable.size()) | |
1238 fatal(toString(this) + " has a Vernaux with an invalid vna_name"); | |
1239 uint16_t version = aux->vna_other & VERSYM_VERSION; | |
1240 if (version >= verneeds.size()) | |
1241 verneeds.resize(version + 1); | |
1242 verneeds[version] = aux->vna_name; | |
1243 vernauxBuf += aux->vna_next; | |
1244 } | |
1245 verneedBuf += vn->vn_next; | |
1246 } | |
1247 return verneeds; | |
1180 } | 1248 } |
1181 | 1249 |
1182 // We do not usually care about alignments of data in shared object | 1250 // We do not usually care about alignments of data in shared object |
1183 // files because the loader takes care of it. However, if we promote a | 1251 // files because the loader takes care of it. However, if we promote a |
1184 // DSO symbol to point to .bss due to copy relocation, we need to keep | 1252 // DSO symbol to point to .bss due to copy relocation, we need to keep |
1220 const ELFFile<ELFT> obj = this->getObj<ELFT>(); | 1288 const ELFFile<ELFT> obj = this->getObj<ELFT>(); |
1221 ArrayRef<Elf_Shdr> sections = CHECK(obj.sections(), this); | 1289 ArrayRef<Elf_Shdr> sections = CHECK(obj.sections(), this); |
1222 | 1290 |
1223 const Elf_Shdr *versymSec = nullptr; | 1291 const Elf_Shdr *versymSec = nullptr; |
1224 const Elf_Shdr *verdefSec = nullptr; | 1292 const Elf_Shdr *verdefSec = nullptr; |
1293 const Elf_Shdr *verneedSec = nullptr; | |
1225 | 1294 |
1226 // Search for .dynsym, .dynamic, .symtab, .gnu.version and .gnu.version_d. | 1295 // Search for .dynsym, .dynamic, .symtab, .gnu.version and .gnu.version_d. |
1227 for (const Elf_Shdr &sec : sections) { | 1296 for (const Elf_Shdr &sec : sections) { |
1228 switch (sec.sh_type) { | 1297 switch (sec.sh_type) { |
1229 default: | 1298 default: |
1236 versymSec = &sec; | 1305 versymSec = &sec; |
1237 break; | 1306 break; |
1238 case SHT_GNU_verdef: | 1307 case SHT_GNU_verdef: |
1239 verdefSec = &sec; | 1308 verdefSec = &sec; |
1240 break; | 1309 break; |
1310 case SHT_GNU_verneed: | |
1311 verneedSec = &sec; | |
1312 break; | |
1241 } | 1313 } |
1242 } | 1314 } |
1243 | 1315 |
1244 if (versymSec && numELFSyms == 0) { | 1316 if (versymSec && numELFSyms == 0) { |
1245 error("SHT_GNU_versym should be associated with symbol table"); | 1317 error("SHT_GNU_versym should be associated with symbol table"); |
1275 return; | 1347 return; |
1276 | 1348 |
1277 sharedFiles.push_back(this); | 1349 sharedFiles.push_back(this); |
1278 | 1350 |
1279 verdefs = parseVerdefs<ELFT>(obj.base(), verdefSec); | 1351 verdefs = parseVerdefs<ELFT>(obj.base(), verdefSec); |
1352 std::vector<uint32_t> verneeds = parseVerneed<ELFT>(obj, verneedSec); | |
1280 | 1353 |
1281 // Parse ".gnu.version" section which is a parallel array for the symbol | 1354 // Parse ".gnu.version" section which is a parallel array for the symbol |
1282 // table. If a given file doesn't have a ".gnu.version" section, we use | 1355 // table. If a given file doesn't have a ".gnu.version" section, we use |
1283 // VER_NDX_GLOBAL. | 1356 // VER_NDX_GLOBAL. |
1284 size_t size = numELFSyms - firstGlobal; | 1357 size_t size = numELFSyms - firstGlobal; |
1285 std::vector<uint32_t> versyms(size, VER_NDX_GLOBAL); | 1358 std::vector<uint16_t> versyms(size, VER_NDX_GLOBAL); |
1286 if (versymSec) { | 1359 if (versymSec) { |
1287 ArrayRef<Elf_Versym> versym = | 1360 ArrayRef<Elf_Versym> versym = |
1288 CHECK(obj.template getSectionContentsAsArray<Elf_Versym>(versymSec), | 1361 CHECK(obj.template getSectionContentsAsArray<Elf_Versym>(versymSec), |
1289 this) | 1362 this) |
1290 .slice(firstGlobal); | 1363 .slice(firstGlobal); |
1311 warn("found local symbol '" + name + | 1384 warn("found local symbol '" + name + |
1312 "' in global part of symbol table in file " + toString(this)); | 1385 "' in global part of symbol table in file " + toString(this)); |
1313 continue; | 1386 continue; |
1314 } | 1387 } |
1315 | 1388 |
1389 uint16_t idx = versyms[i] & ~VERSYM_HIDDEN; | |
1316 if (sym.isUndefined()) { | 1390 if (sym.isUndefined()) { |
1391 // For unversioned undefined symbols, VER_NDX_GLOBAL makes more sense but | |
1392 // as of binutils 2.34, GNU ld produces VER_NDX_LOCAL. | |
1393 if (idx != VER_NDX_LOCAL && idx != VER_NDX_GLOBAL) { | |
1394 if (idx >= verneeds.size()) { | |
1395 error("corrupt input file: version need index " + Twine(idx) + | |
1396 " for symbol " + name + " is out of bounds\n>>> defined in " + | |
1397 toString(this)); | |
1398 continue; | |
1399 } | |
1400 StringRef verName = this->stringTable.data() + verneeds[idx]; | |
1401 versionedNameBuffer.clear(); | |
1402 name = | |
1403 saver.save((name + "@" + verName).toStringRef(versionedNameBuffer)); | |
1404 } | |
1317 Symbol *s = symtab->addSymbol( | 1405 Symbol *s = symtab->addSymbol( |
1318 Undefined{this, name, sym.getBinding(), sym.st_other, sym.getType()}); | 1406 Undefined{this, name, sym.getBinding(), sym.st_other, sym.getType()}); |
1319 s->exportDynamic = true; | 1407 s->exportDynamic = true; |
1320 continue; | 1408 continue; |
1321 } | 1409 } |
1322 | 1410 |
1323 // MIPS BFD linker puts _gp_disp symbol into DSO files and incorrectly | 1411 // MIPS BFD linker puts _gp_disp symbol into DSO files and incorrectly |
1324 // assigns VER_NDX_LOCAL to this section global symbol. Here is a | 1412 // assigns VER_NDX_LOCAL to this section global symbol. Here is a |
1325 // workaround for this bug. | 1413 // workaround for this bug. |
1326 uint32_t idx = versyms[i] & ~VERSYM_HIDDEN; | |
1327 if (config->emachine == EM_MIPS && idx == VER_NDX_LOCAL && | 1414 if (config->emachine == EM_MIPS && idx == VER_NDX_LOCAL && |
1328 name == "_gp_disp") | 1415 name == "_gp_disp") |
1329 continue; | 1416 continue; |
1330 | 1417 |
1331 uint32_t alignment = getAlignment<ELFT>(sections, sym); | 1418 uint32_t alignment = getAlignment<ELFT>(sections, sym); |
1415 // name. If two archives define two members with the same name, this | 1502 // name. If two archives define two members with the same name, this |
1416 // causes a collision which result in only one of the objects being taken | 1503 // causes a collision which result in only one of the objects being taken |
1417 // into consideration at LTO time (which very likely causes undefined | 1504 // into consideration at LTO time (which very likely causes undefined |
1418 // symbols later in the link stage). So we append file offset to make | 1505 // symbols later in the link stage). So we append file offset to make |
1419 // filename unique. | 1506 // filename unique. |
1420 StringRef name = archiveName.empty() | 1507 StringRef name = |
1421 ? saver.save(path) | 1508 archiveName.empty() |
1422 : saver.save(archiveName + "(" + path + " at " + | 1509 ? saver.save(path) |
1423 utostr(offsetInArchive) + ")"); | 1510 : saver.save(archiveName + "(" + path::filename(path) + " at " + |
1511 utostr(offsetInArchive) + ")"); | |
1424 MemoryBufferRef mbref(mb.getBuffer(), name); | 1512 MemoryBufferRef mbref(mb.getBuffer(), name); |
1425 | 1513 |
1426 obj = CHECK(lto::InputFile::create(mbref), this); | 1514 obj = CHECK(lto::InputFile::create(mbref), this); |
1427 | 1515 |
1428 Triple t(obj->getTargetTriple()); | 1516 Triple t(obj->getTargetTriple()); |
1507 STV_DEFAULT, STT_OBJECT, data.size(), 0, section}); | 1595 STV_DEFAULT, STT_OBJECT, data.size(), 0, section}); |
1508 symtab->addSymbol(Defined{nullptr, saver.save(s + "_size"), STB_GLOBAL, | 1596 symtab->addSymbol(Defined{nullptr, saver.save(s + "_size"), STB_GLOBAL, |
1509 STV_DEFAULT, STT_OBJECT, data.size(), 0, nullptr}); | 1597 STV_DEFAULT, STT_OBJECT, data.size(), 0, nullptr}); |
1510 } | 1598 } |
1511 | 1599 |
1512 InputFile *createObjectFile(MemoryBufferRef mb, StringRef archiveName, | 1600 InputFile *elf::createObjectFile(MemoryBufferRef mb, StringRef archiveName, |
1513 uint64_t offsetInArchive) { | 1601 uint64_t offsetInArchive) { |
1514 if (isBitcode(mb)) | 1602 if (isBitcode(mb)) |
1515 return make<BitcodeFile>(mb, archiveName, offsetInArchive); | 1603 return make<BitcodeFile>(mb, archiveName, offsetInArchive); |
1516 | 1604 |
1517 switch (getELFKind(mb, archiveName)) { | 1605 switch (getELFKind(mb, archiveName)) { |
1518 case ELF32LEKind: | 1606 case ELF32LEKind: |
1599 } | 1687 } |
1600 return; | 1688 return; |
1601 } | 1689 } |
1602 } | 1690 } |
1603 | 1691 |
1604 std::string replaceThinLTOSuffix(StringRef path) { | 1692 std::string elf::replaceThinLTOSuffix(StringRef path) { |
1605 StringRef suffix = config->thinLTOObjectSuffixReplace.first; | 1693 StringRef suffix = config->thinLTOObjectSuffixReplace.first; |
1606 StringRef repl = config->thinLTOObjectSuffixReplace.second; | 1694 StringRef repl = config->thinLTOObjectSuffixReplace.second; |
1607 | 1695 |
1608 if (path.consume_back(suffix)) | 1696 if (path.consume_back(suffix)) |
1609 return (path + repl).str(); | 1697 return (path + repl).str(); |
1618 template void LazyObjFile::parse<ELF32LE>(); | 1706 template void LazyObjFile::parse<ELF32LE>(); |
1619 template void LazyObjFile::parse<ELF32BE>(); | 1707 template void LazyObjFile::parse<ELF32BE>(); |
1620 template void LazyObjFile::parse<ELF64LE>(); | 1708 template void LazyObjFile::parse<ELF64LE>(); |
1621 template void LazyObjFile::parse<ELF64BE>(); | 1709 template void LazyObjFile::parse<ELF64BE>(); |
1622 | 1710 |
1623 template class ObjFile<ELF32LE>; | 1711 template class elf::ObjFile<ELF32LE>; |
1624 template class ObjFile<ELF32BE>; | 1712 template class elf::ObjFile<ELF32BE>; |
1625 template class ObjFile<ELF64LE>; | 1713 template class elf::ObjFile<ELF64LE>; |
1626 template class ObjFile<ELF64BE>; | 1714 template class elf::ObjFile<ELF64BE>; |
1627 | 1715 |
1628 template void SharedFile::parse<ELF32LE>(); | 1716 template void SharedFile::parse<ELF32LE>(); |
1629 template void SharedFile::parse<ELF32BE>(); | 1717 template void SharedFile::parse<ELF32BE>(); |
1630 template void SharedFile::parse<ELF64LE>(); | 1718 template void SharedFile::parse<ELF64LE>(); |
1631 template void SharedFile::parse<ELF64BE>(); | 1719 template void SharedFile::parse<ELF64BE>(); |
1632 | |
1633 } // namespace elf | |
1634 } // namespace lld |