ELFObjectFile.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. //===- ELFObjectFile.cpp - ELF object file implementation -------*- C++ -*-===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // Part of the ELFObjectFile class implementation.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "llvm/Object/ELFObjectFile.h"
  14. #include "llvm/Support/MathExtras.h"
  15. namespace llvm {
  16. using namespace object;
  17. ELFObjectFileBase::ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source)
  18. : ObjectFile(Type, Source) {}
  19. ErrorOr<std::unique_ptr<ObjectFile>>
  20. ObjectFile::createELFObjectFile(MemoryBufferRef Obj) {
  21. std::pair<unsigned char, unsigned char> Ident =
  22. getElfArchType(Obj.getBuffer());
  23. std::size_t MaxAlignment =
  24. 1ULL << countTrailingZeros(uintptr_t(Obj.getBufferStart()));
  25. if (MaxAlignment < 2)
  26. return object_error::parse_failed;
  27. std::error_code EC;
  28. std::unique_ptr<ObjectFile> R;
  29. if (Ident.first == ELF::ELFCLASS32) {
  30. if (Ident.second == ELF::ELFDATA2LSB)
  31. R.reset(new ELFObjectFile<ELFType<support::little, false>>(Obj, EC));
  32. else if (Ident.second == ELF::ELFDATA2MSB)
  33. R.reset(new ELFObjectFile<ELFType<support::big, false>>(Obj, EC));
  34. else
  35. return object_error::parse_failed;
  36. } else if (Ident.first == ELF::ELFCLASS64) {
  37. if (Ident.second == ELF::ELFDATA2LSB)
  38. R.reset(new ELFObjectFile<ELFType<support::little, true>>(Obj, EC));
  39. else if (Ident.second == ELF::ELFDATA2MSB)
  40. R.reset(new ELFObjectFile<ELFType<support::big, true>>(Obj, EC));
  41. else
  42. return object_error::parse_failed;
  43. } else {
  44. return object_error::parse_failed;
  45. }
  46. if (EC)
  47. return EC;
  48. return std::move(R);
  49. }
  50. SubtargetFeatures ELFObjectFileBase::getFeatures() const {
  51. switch (getEMachine()) {
  52. case ELF::EM_MIPS: {
  53. SubtargetFeatures Features;
  54. unsigned PlatformFlags;
  55. getPlatformFlags(PlatformFlags);
  56. switch (PlatformFlags & ELF::EF_MIPS_ARCH) {
  57. case ELF::EF_MIPS_ARCH_1:
  58. break;
  59. case ELF::EF_MIPS_ARCH_2:
  60. Features.AddFeature("mips2");
  61. break;
  62. case ELF::EF_MIPS_ARCH_3:
  63. Features.AddFeature("mips3");
  64. break;
  65. case ELF::EF_MIPS_ARCH_4:
  66. Features.AddFeature("mips4");
  67. break;
  68. case ELF::EF_MIPS_ARCH_5:
  69. Features.AddFeature("mips5");
  70. break;
  71. case ELF::EF_MIPS_ARCH_32:
  72. Features.AddFeature("mips32");
  73. break;
  74. case ELF::EF_MIPS_ARCH_64:
  75. Features.AddFeature("mips64");
  76. break;
  77. case ELF::EF_MIPS_ARCH_32R2:
  78. Features.AddFeature("mips32r2");
  79. break;
  80. case ELF::EF_MIPS_ARCH_64R2:
  81. Features.AddFeature("mips64r2");
  82. break;
  83. case ELF::EF_MIPS_ARCH_32R6:
  84. Features.AddFeature("mips32r6");
  85. break;
  86. case ELF::EF_MIPS_ARCH_64R6:
  87. Features.AddFeature("mips64r6");
  88. break;
  89. default:
  90. llvm_unreachable("Unknown EF_MIPS_ARCH value");
  91. }
  92. switch (PlatformFlags & ELF::EF_MIPS_MACH) {
  93. case ELF::EF_MIPS_MACH_NONE:
  94. // No feature associated with this value.
  95. break;
  96. case ELF::EF_MIPS_MACH_OCTEON:
  97. Features.AddFeature("cnmips");
  98. break;
  99. default:
  100. llvm_unreachable("Unknown EF_MIPS_ARCH value");
  101. }
  102. if (PlatformFlags & ELF::EF_MIPS_ARCH_ASE_M16)
  103. Features.AddFeature("mips16");
  104. if (PlatformFlags & ELF::EF_MIPS_MICROMIPS)
  105. Features.AddFeature("micromips");
  106. return Features;
  107. }
  108. default:
  109. return SubtargetFeatures();
  110. }
  111. }
  112. // FIXME Encode from a tablegen description or target parser.
  113. void ELFObjectFileBase::setARMSubArch(Triple &TheTriple) const {
  114. if (TheTriple.getSubArch() != Triple::NoSubArch)
  115. return;
  116. ARMAttributeParser Attributes;
  117. std::error_code EC = getBuildAttributes(Attributes);
  118. if (EC)
  119. return;
  120. std::string Triple;
  121. // Default to ARM, but use the triple if it's been set.
  122. if (TheTriple.getArch() == Triple::thumb ||
  123. TheTriple.getArch() == Triple::thumbeb)
  124. Triple = "thumb";
  125. else
  126. Triple = "arm";
  127. if (Attributes.hasAttribute(ARMBuildAttrs::CPU_arch)) {
  128. switch(Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch)) {
  129. case ARMBuildAttrs::v4:
  130. Triple += "v4";
  131. break;
  132. case ARMBuildAttrs::v4T:
  133. Triple += "v4t";
  134. break;
  135. case ARMBuildAttrs::v5T:
  136. Triple += "v5t";
  137. break;
  138. case ARMBuildAttrs::v5TE:
  139. Triple += "v5te";
  140. break;
  141. case ARMBuildAttrs::v5TEJ:
  142. Triple += "v5tej";
  143. break;
  144. case ARMBuildAttrs::v6:
  145. Triple += "v6";
  146. break;
  147. case ARMBuildAttrs::v6KZ:
  148. Triple += "v6kz";
  149. break;
  150. case ARMBuildAttrs::v6T2:
  151. Triple += "v6t2";
  152. break;
  153. case ARMBuildAttrs::v6K:
  154. Triple += "v6k";
  155. break;
  156. case ARMBuildAttrs::v7:
  157. Triple += "v7";
  158. break;
  159. case ARMBuildAttrs::v6_M:
  160. Triple += "v6m";
  161. break;
  162. case ARMBuildAttrs::v6S_M:
  163. Triple += "v6sm";
  164. break;
  165. case ARMBuildAttrs::v7E_M:
  166. Triple += "v7em";
  167. break;
  168. }
  169. }
  170. if (!isLittleEndian())
  171. Triple += "eb";
  172. TheTriple.setArchName(Triple);
  173. }
  174. } // end namespace llvm