Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: a guest on Apr 15th, 2012  |  syntax: None  |  size: 10.91 KB  |  hits: 4  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. Index: local/lib/Object/MachOObjectFile.cpp
  2. ===================================================================
  3. --- /dev/null   1970-01-01 00:00:00.000000000 +0000
  4. +++ local/lib/Object/MachOObjectFile.cpp        2011-03-14 18:00:13.000000000 -0700
  5. @@ -0,0 +1,330 @@
  6. +//===- MachOObjectFile.cpp - Mach-O object file binding ---------*- C++ -*-===//
  7. +//
  8. +//                     The LLVM Compiler Infrastructure
  9. +//
  10. +// This file is distributed under the University of Illinois Open Source
  11. +// License. See LICENSE.TXT for details.
  12. +//
  13. +//===----------------------------------------------------------------------===//
  14. +//
  15. +// This file defines the MachOObjectFile class, which binds the MachOObject
  16. +// class to the generic ObjectFile wrapper.
  17. +//
  18. +//===----------------------------------------------------------------------===//
  19. +
  20. +#include "llvm/ADT/Triple.h"
  21. +#include "llvm/Object/MachOFormat.h"
  22. +#include "llvm/Object/MachOObject.h"
  23. +#include "llvm/Object/ObjectFile.h"
  24. +#include "llvm/Support/MemoryBuffer.h"
  25. +
  26. +#include <cctype>
  27. +#include <cstring>
  28. +#include <limits>
  29. +
  30. +using namespace llvm;
  31. +using namespace object;
  32. +
  33. +namespace llvm {
  34. +
  35. +typedef MachOObject::LoadCommandInfo LoadCommandInfo;
  36. +
  37. +class MachOObjectFile : public ObjectFile {
  38. +public:
  39. +  MachOObjectFile(MemoryBuffer *Object, MachOObject *MOO)
  40. +    : ObjectFile(Object),
  41. +      MachOObj(MOO),
  42. +      RegisteredStringTable(std::numeric_limits<uint32_t>::max()) {}
  43. +
  44. +  virtual symbol_iterator begin_symbols() const;
  45. +  virtual symbol_iterator end_symbols() const;
  46. +  virtual section_iterator begin_sections() const;
  47. +  virtual section_iterator end_sections() const;
  48. +
  49. +  virtual uint8_t getBytesInAddress() const;
  50. +  virtual StringRef getFileFormatName() const;
  51. +  virtual unsigned getArch() const;
  52. +
  53. +protected:
  54. +  virtual SymbolRef getSymbolNext(DataRefImpl Symb) const;
  55. +  virtual StringRef getSymbolName(DataRefImpl Symb) const;
  56. +  virtual uint64_t  getSymbolAddress(DataRefImpl Symb) const;
  57. +  virtual uint64_t  getSymbolSize(DataRefImpl Symb) const;
  58. +  virtual char      getSymbolNMTypeChar(DataRefImpl Symb) const;
  59. +  virtual bool      isSymbolInternal(DataRefImpl Symb) const;
  60. +
  61. +  virtual SectionRef getSectionNext(DataRefImpl Sec) const;
  62. +  virtual StringRef  getSectionName(DataRefImpl Sec) const;
  63. +  virtual uint64_t   getSectionAddress(DataRefImpl Sec) const;
  64. +  virtual uint64_t   getSectionSize(DataRefImpl Sec) const;
  65. +  virtual StringRef  getSectionContents(DataRefImpl Sec) const;
  66. +  virtual bool       isSectionText(DataRefImpl Sec) const;
  67. +
  68. +private:
  69. +  MachOObject *MachOObj;
  70. +  mutable uint32_t RegisteredStringTable;
  71. +
  72. +  void moveToNextSection(DataRefImpl &DRI) const;
  73. +  void getSymbolTableEntry(DataRefImpl DRI,
  74. +                           InMemoryStruct<macho::SymbolTableEntry> &Res) const;
  75. +  void moveToNextSymbol(DataRefImpl &DRI) const;
  76. +  void getSection(DataRefImpl DRI, InMemoryStruct<macho::Section> &Res) const;
  77. +};
  78. +
  79. +ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) {
  80. +  std::string Err;
  81. +  MachOObject *MachOObj = MachOObject::LoadFromBuffer(Buffer, &Err);
  82. +  if (!MachOObj)
  83. +    return NULL;
  84. +  return new MachOObjectFile(Buffer, MachOObj);
  85. +}
  86. +
  87. +/*===-- Symbols -----------------------------------------------------------===*/
  88. +
  89. +void MachOObjectFile::moveToNextSymbol(DataRefImpl &DRI) const {
  90. +  uint32_t LoadCommandCount = MachOObj->getHeader().NumLoadCommands;
  91. +  while (DRI.d.a < LoadCommandCount) {
  92. +    LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a);
  93. +    if (LCI.Command.Type == macho::LCT_Symtab) {
  94. +      InMemoryStruct<macho::SymtabLoadCommand> SymtabLoadCmd;
  95. +      MachOObj->ReadSymtabLoadCommand(LCI, SymtabLoadCmd);
  96. +      if (DRI.d.b < SymtabLoadCmd->NumSymbolTableEntries)
  97. +        return;
  98. +    }
  99. +
  100. +    DRI.d.a++;
  101. +    DRI.d.b = 0;
  102. +  }
  103. +}
  104. +
  105. +void MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI,
  106. +    InMemoryStruct<macho::SymbolTableEntry> &Res) const {
  107. +  InMemoryStruct<macho::SymtabLoadCommand> SymtabLoadCmd;
  108. +  LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a);
  109. +  MachOObj->ReadSymtabLoadCommand(LCI, SymtabLoadCmd);
  110. +
  111. +  if (RegisteredStringTable != DRI.d.a) {
  112. +    MachOObj->RegisterStringTable(*SymtabLoadCmd);
  113. +    RegisteredStringTable = DRI.d.a;
  114. +  }
  115. +
  116. +  MachOObj->ReadSymbolTableEntry(SymtabLoadCmd->SymbolTableOffset, DRI.d.b,
  117. +                                 Res);
  118. +}
  119. +
  120. +
  121. +SymbolRef MachOObjectFile::getSymbolNext(DataRefImpl DRI) const {
  122. +  DRI.d.b++;
  123. +  moveToNextSymbol(DRI);
  124. +  return SymbolRef(DRI, this);
  125. +}
  126. +
  127. +StringRef MachOObjectFile::getSymbolName(DataRefImpl DRI) const {
  128. +  InMemoryStruct<macho::SymbolTableEntry> Entry;
  129. +  getSymbolTableEntry(DRI, Entry);
  130. +  return MachOObj->getStringAtIndex(Entry->StringIndex);
  131. +}
  132. +
  133. +uint64_t MachOObjectFile::getSymbolAddress(DataRefImpl DRI) const {
  134. +  InMemoryStruct<macho::SymbolTableEntry> Entry;
  135. +  getSymbolTableEntry(DRI, Entry);
  136. +  return Entry->Value;
  137. +}
  138. +
  139. +uint64_t MachOObjectFile::getSymbolSize(DataRefImpl DRI) const {
  140. +  return UnknownAddressOrSize;
  141. +}
  142. +
  143. +char MachOObjectFile::getSymbolNMTypeChar(DataRefImpl DRI) const {
  144. +  InMemoryStruct<macho::SymbolTableEntry> Entry;
  145. +  getSymbolTableEntry(DRI, Entry);
  146. +
  147. +  char Char;
  148. +  switch (Entry->Type & macho::STF_TypeMask) {
  149. +    case macho::STT_Undefined:
  150. +      Char = 'u';
  151. +      break;
  152. +    case macho::STT_Absolute:
  153. +    case macho::STT_Section:
  154. +      Char = 's';
  155. +      break;
  156. +    default:
  157. +      Char = '?';
  158. +      break;
  159. +  }
  160. +
  161. +  if (Entry->Flags & (macho::STF_External | macho::STF_PrivateExtern))
  162. +    Char = toupper(Char);
  163. +  return Char;
  164. +}
  165. +
  166. +bool MachOObjectFile::isSymbolInternal(DataRefImpl DRI) const {
  167. +  InMemoryStruct<macho::SymbolTableEntry> Entry;
  168. +  getSymbolTableEntry(DRI, Entry);
  169. +  return Entry->Flags & macho::STF_StabsEntryMask;
  170. +}
  171. +
  172. +ObjectFile::symbol_iterator MachOObjectFile::begin_symbols() const {
  173. +  // DRI.d.a = segment number; DRI.d.b = symbol index.
  174. +  DataRefImpl DRI;
  175. +  DRI.d.a = DRI.d.b = 0;
  176. +  moveToNextSymbol(DRI);
  177. +  return symbol_iterator(SymbolRef(DRI, this));
  178. +}
  179. +
  180. +ObjectFile::symbol_iterator MachOObjectFile::end_symbols() const {
  181. +  DataRefImpl DRI;
  182. +  DRI.d.a = MachOObj->getHeader().NumLoadCommands;
  183. +  DRI.d.b = 0;
  184. +  return symbol_iterator(SymbolRef(DRI, this));
  185. +}
  186. +
  187. +
  188. +/*===-- Sections ----------------------------------------------------------===*/
  189. +
  190. +void MachOObjectFile::moveToNextSection(DataRefImpl &DRI) const {
  191. +  uint32_t LoadCommandCount = MachOObj->getHeader().NumLoadCommands;
  192. +  while (DRI.d.a < LoadCommandCount) {
  193. +    LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a);
  194. +    if (LCI.Command.Type == macho::LCT_Segment) {
  195. +      InMemoryStruct<macho::SegmentLoadCommand> SegmentLoadCmd;
  196. +      MachOObj->ReadSegmentLoadCommand(LCI, SegmentLoadCmd);
  197. +      if (DRI.d.b < SegmentLoadCmd->NumSections)
  198. +        return;
  199. +    } else if (LCI.Command.Type == macho::LCT_Segment64) {
  200. +      InMemoryStruct<macho::Segment64LoadCommand> Segment64LoadCmd;
  201. +      MachOObj->ReadSegment64LoadCommand(LCI, Segment64LoadCmd);
  202. +      if (DRI.d.b < Segment64LoadCmd->NumSections)
  203. +        return;
  204. +    }
  205. +
  206. +    DRI.d.a++;
  207. +    DRI.d.b = 0;
  208. +  }
  209. +}
  210. +
  211. +SectionRef MachOObjectFile::getSectionNext(DataRefImpl DRI) const {
  212. +  DRI.d.b++;
  213. +  moveToNextSection(DRI);
  214. +  return SectionRef(DRI, this);
  215. +}
  216. +
  217. +void
  218. +MachOObjectFile::getSection(DataRefImpl DRI,
  219. +                            InMemoryStruct<macho::Section> &Res) const {
  220. +  InMemoryStruct<macho::SegmentLoadCommand> SLC;
  221. +  LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a);
  222. +  MachOObj->ReadSegmentLoadCommand(LCI, SLC);
  223. +  MachOObj->ReadSection(LCI, DRI.d.b, Res);
  224. +}
  225. +
  226. +StringRef MachOObjectFile::getSectionName(DataRefImpl DRI) const {
  227. +  InMemoryStruct<macho::SegmentLoadCommand> SLC;
  228. +  LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a);
  229. +  MachOObj->ReadSegmentLoadCommand(LCI, SLC);
  230. +  InMemoryStruct<macho::Section> Sect;
  231. +  MachOObj->ReadSection(LCI, DRI.d.b, Sect);
  232. +
  233. +  static char Result[34];
  234. +  strcpy(Result, SLC->Name);
  235. +  strcat(Result, ",");
  236. +  strcat(Result, Sect->Name);
  237. +  return StringRef(Result);
  238. +}
  239. +
  240. +uint64_t MachOObjectFile::getSectionAddress(DataRefImpl DRI) const {
  241. +  InMemoryStruct<macho::Section> Sect;
  242. +  getSection(DRI, Sect);
  243. +  return Sect->Address;
  244. +}
  245. +
  246. +uint64_t MachOObjectFile::getSectionSize(DataRefImpl DRI) const {
  247. +  InMemoryStruct<macho::Section> Sect;
  248. +  getSection(DRI, Sect);
  249. +  return Sect->Size;
  250. +}
  251. +
  252. +StringRef MachOObjectFile::getSectionContents(DataRefImpl DRI) const {
  253. +  InMemoryStruct<macho::Section> Sect;
  254. +  getSection(DRI, Sect);
  255. +  return MachOObj->getData(Sect->Offset, Sect->Size);
  256. +}
  257. +
  258. +bool MachOObjectFile::isSectionText(DataRefImpl DRI) const {
  259. +  InMemoryStruct<macho::SegmentLoadCommand> SLC;
  260. +  LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a);
  261. +  MachOObj->ReadSegmentLoadCommand(LCI, SLC);
  262. +  return !strcmp(SLC->Name, "__TEXT");
  263. +}
  264. +
  265. +ObjectFile::section_iterator MachOObjectFile::begin_sections() const {
  266. +  DataRefImpl DRI;
  267. +  DRI.d.a = DRI.d.b = 0;
  268. +  moveToNextSection(DRI);
  269. +  return section_iterator(SectionRef(DRI, this));
  270. +}
  271. +
  272. +ObjectFile::section_iterator MachOObjectFile::end_sections() const {
  273. +  DataRefImpl DRI;
  274. +  DRI.d.a = MachOObj->getHeader().NumLoadCommands;
  275. +  DRI.d.b = 0;
  276. +  return section_iterator(SectionRef(DRI, this));
  277. +}
  278. +
  279. +/*===-- Miscellaneous -----------------------------------------------------===*/
  280. +
  281. +uint8_t MachOObjectFile::getBytesInAddress() const {
  282. +  return MachOObj->is64Bit() ? 8 : 4;
  283. +}
  284. +
  285. +StringRef MachOObjectFile::getFileFormatName() const {
  286. +  if (!MachOObj->is64Bit()) {
  287. +    switch (MachOObj->getHeader().CPUType) {
  288. +    case 0x00000007:
  289. +      return "MACHO32-i386";
  290. +    case 0x01000007:
  291. +      return "MACHO32-x86-64";
  292. +    case 0x0000000c:
  293. +      return "MACHO32-arm";
  294. +    case 0x00000012:
  295. +      return "MACHO32-ppc";
  296. +    case 0x01000012:
  297. +      return "MACHO32-ppc64";
  298. +    }
  299. +  }
  300. +
  301. +  switch (MachOObj->getHeader().CPUType) {
  302. +  case 0x00000007:
  303. +    return "MACHO64-i386";
  304. +  case 0x01000007:
  305. +    return "MACHO64-x86-64";
  306. +  case 0x0000000c:
  307. +    return "MACHO64-arm";
  308. +  case 0x00000012:
  309. +    return "MACHO64-ppc";
  310. +  case 0x01000012:
  311. +    return "MACHO64-ppc64";
  312. +  default:
  313. +    return "MACHO64-unknown";
  314. +  }
  315. +}
  316. +
  317. +unsigned MachOObjectFile::getArch() const {
  318. +  switch (MachOObj->getHeader().CPUType) {
  319. +  case 0x00000007:
  320. +    return Triple::x86;
  321. +  case 0x01000007:
  322. +    return Triple::x86_64;
  323. +  case 0x0000000c:
  324. +    return Triple::arm;
  325. +  case 0x00000012:
  326. +    return Triple::ppc;
  327. +  case 0x01000012:
  328. +    return Triple::ppc64;
  329. +  default:
  330. +    return Triple::UnknownArch;
  331. +  }
  332. +}
  333. +
  334. +} // end namespace llvm
  335. +
  336. Index: local/lib/Object/ObjectFile.cpp
  337. ===================================================================
  338. --- local.orig/lib/Object/ObjectFile.cpp        2011-03-14 17:56:36.000000000 -0700
  339. +++ local/lib/Object/ObjectFile.cpp     2011-03-14 18:00:13.000000000 -0700
  340. @@ -55,7 +55,7 @@
  341.      case sys::Mach_O_DynamicLinker_FileType:
  342.      case sys::Mach_O_Bundle_FileType:
  343.      case sys::Mach_O_DynamicallyLinkedSharedLibStub_FileType:
  344. -      return 0;
  345. +      return createMachOObjectFile(Object);
  346.      case sys::COFF_FileType:
  347.        return createCOFFObjectFile(Object);
  348.      default: