MachOObjectFile.cpp 129 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491
  1. //===- MachOObjectFile.cpp - Mach-O object file binding ---------*- 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. // This file defines the MachOObjectFile class, which binds the MachOObject
  11. // class to the generic ObjectFile wrapper.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "llvm/Object/MachO.h"
  15. #include "llvm/ADT/STLExtras.h"
  16. #include "llvm/ADT/StringSwitch.h"
  17. #include "llvm/ADT/Triple.h"
  18. #include "llvm/Support/DataExtractor.h"
  19. #include "llvm/Support/Debug.h"
  20. #include "llvm/Support/Format.h"
  21. #include "llvm/Support/Host.h"
  22. #include "llvm/Support/LEB128.h"
  23. #include "llvm/Support/MachO.h"
  24. #include "llvm/Support/MemoryBuffer.h"
  25. #include "llvm/Support/raw_ostream.h"
  26. #include <cctype>
  27. #include <cstring>
  28. #include <limits>
  29. #include <list>
  30. using namespace llvm;
  31. using namespace object;
  32. namespace {
  33. struct section_base {
  34. char sectname[16];
  35. char segname[16];
  36. };
  37. }
  38. static Error
  39. malformedError(Twine Msg) {
  40. std::string StringMsg = "truncated or malformed object (" + Msg.str() + ")";
  41. return make_error<GenericBinaryError>(std::move(StringMsg),
  42. object_error::parse_failed);
  43. }
  44. // FIXME: Replace all uses of this function with getStructOrErr.
  45. template <typename T>
  46. static T getStruct(const MachOObjectFile *O, const char *P) {
  47. // Don't read before the beginning or past the end of the file
  48. if (P < O->getData().begin() || P + sizeof(T) > O->getData().end())
  49. report_fatal_error("Malformed MachO file.");
  50. T Cmd;
  51. memcpy(&Cmd, P, sizeof(T));
  52. if (O->isLittleEndian() != sys::IsLittleEndianHost)
  53. MachO::swapStruct(Cmd);
  54. return Cmd;
  55. }
  56. template <typename T>
  57. static Expected<T> getStructOrErr(const MachOObjectFile *O, const char *P) {
  58. // Don't read before the beginning or past the end of the file
  59. if (P < O->getData().begin() || P + sizeof(T) > O->getData().end())
  60. return malformedError("Structure read out-of-range");
  61. T Cmd;
  62. memcpy(&Cmd, P, sizeof(T));
  63. if (O->isLittleEndian() != sys::IsLittleEndianHost)
  64. MachO::swapStruct(Cmd);
  65. return Cmd;
  66. }
  67. static const char *
  68. getSectionPtr(const MachOObjectFile *O, MachOObjectFile::LoadCommandInfo L,
  69. unsigned Sec) {
  70. uintptr_t CommandAddr = reinterpret_cast<uintptr_t>(L.Ptr);
  71. bool Is64 = O->is64Bit();
  72. unsigned SegmentLoadSize = Is64 ? sizeof(MachO::segment_command_64) :
  73. sizeof(MachO::segment_command);
  74. unsigned SectionSize = Is64 ? sizeof(MachO::section_64) :
  75. sizeof(MachO::section);
  76. uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec * SectionSize;
  77. return reinterpret_cast<const char*>(SectionAddr);
  78. }
  79. static const char *getPtr(const MachOObjectFile *O, size_t Offset) {
  80. return O->getData().substr(Offset, 1).data();
  81. }
  82. static MachO::nlist_base
  83. getSymbolTableEntryBase(const MachOObjectFile *O, DataRefImpl DRI) {
  84. const char *P = reinterpret_cast<const char *>(DRI.p);
  85. return getStruct<MachO::nlist_base>(O, P);
  86. }
  87. static StringRef parseSegmentOrSectionName(const char *P) {
  88. if (P[15] == 0)
  89. // Null terminated.
  90. return P;
  91. // Not null terminated, so this is a 16 char string.
  92. return StringRef(P, 16);
  93. }
  94. // Helper to advance a section or symbol iterator multiple increments at a time.
  95. template<class T>
  96. static void advance(T &it, size_t Val) {
  97. while (Val--)
  98. ++it;
  99. }
  100. static unsigned getCPUType(const MachOObjectFile *O) {
  101. return O->getHeader().cputype;
  102. }
  103. static uint32_t
  104. getPlainRelocationAddress(const MachO::any_relocation_info &RE) {
  105. return RE.r_word0;
  106. }
  107. static unsigned
  108. getScatteredRelocationAddress(const MachO::any_relocation_info &RE) {
  109. return RE.r_word0 & 0xffffff;
  110. }
  111. static bool getPlainRelocationPCRel(const MachOObjectFile *O,
  112. const MachO::any_relocation_info &RE) {
  113. if (O->isLittleEndian())
  114. return (RE.r_word1 >> 24) & 1;
  115. return (RE.r_word1 >> 7) & 1;
  116. }
  117. static bool
  118. getScatteredRelocationPCRel(const MachOObjectFile *O,
  119. const MachO::any_relocation_info &RE) {
  120. return (RE.r_word0 >> 30) & 1;
  121. }
  122. static unsigned getPlainRelocationLength(const MachOObjectFile *O,
  123. const MachO::any_relocation_info &RE) {
  124. if (O->isLittleEndian())
  125. return (RE.r_word1 >> 25) & 3;
  126. return (RE.r_word1 >> 5) & 3;
  127. }
  128. static unsigned
  129. getScatteredRelocationLength(const MachO::any_relocation_info &RE) {
  130. return (RE.r_word0 >> 28) & 3;
  131. }
  132. static unsigned getPlainRelocationType(const MachOObjectFile *O,
  133. const MachO::any_relocation_info &RE) {
  134. if (O->isLittleEndian())
  135. return RE.r_word1 >> 28;
  136. return RE.r_word1 & 0xf;
  137. }
  138. static uint32_t getSectionFlags(const MachOObjectFile *O,
  139. DataRefImpl Sec) {
  140. if (O->is64Bit()) {
  141. MachO::section_64 Sect = O->getSection64(Sec);
  142. return Sect.flags;
  143. }
  144. MachO::section Sect = O->getSection(Sec);
  145. return Sect.flags;
  146. }
  147. static Expected<MachOObjectFile::LoadCommandInfo>
  148. getLoadCommandInfo(const MachOObjectFile *Obj, const char *Ptr,
  149. uint32_t LoadCommandIndex) {
  150. if (auto CmdOrErr = getStructOrErr<MachO::load_command>(Obj, Ptr)) {
  151. if (CmdOrErr->cmdsize < 8)
  152. return malformedError("load command " + Twine(LoadCommandIndex) +
  153. " with size less than 8 bytes");
  154. return MachOObjectFile::LoadCommandInfo({Ptr, *CmdOrErr});
  155. } else
  156. return CmdOrErr.takeError();
  157. }
  158. static Expected<MachOObjectFile::LoadCommandInfo>
  159. getFirstLoadCommandInfo(const MachOObjectFile *Obj) {
  160. unsigned HeaderSize = Obj->is64Bit() ? sizeof(MachO::mach_header_64)
  161. : sizeof(MachO::mach_header);
  162. if (sizeof(MachO::load_command) > Obj->getHeader().sizeofcmds)
  163. return malformedError("load command 0 extends past the end all load "
  164. "commands in the file");
  165. return getLoadCommandInfo(Obj, getPtr(Obj, HeaderSize), 0);
  166. }
  167. static Expected<MachOObjectFile::LoadCommandInfo>
  168. getNextLoadCommandInfo(const MachOObjectFile *Obj, uint32_t LoadCommandIndex,
  169. const MachOObjectFile::LoadCommandInfo &L) {
  170. unsigned HeaderSize = Obj->is64Bit() ? sizeof(MachO::mach_header_64)
  171. : sizeof(MachO::mach_header);
  172. if (L.Ptr + L.C.cmdsize + sizeof(MachO::load_command) >
  173. Obj->getData().data() + HeaderSize + Obj->getHeader().sizeofcmds)
  174. return malformedError("load command " + Twine(LoadCommandIndex + 1) +
  175. " extends past the end all load commands in the file");
  176. return getLoadCommandInfo(Obj, L.Ptr + L.C.cmdsize, LoadCommandIndex + 1);
  177. }
  178. template <typename T>
  179. static void parseHeader(const MachOObjectFile *Obj, T &Header,
  180. Error &Err) {
  181. if (sizeof(T) > Obj->getData().size()) {
  182. Err = malformedError("the mach header extends past the end of the "
  183. "file");
  184. return;
  185. }
  186. if (auto HeaderOrErr = getStructOrErr<T>(Obj, getPtr(Obj, 0)))
  187. Header = *HeaderOrErr;
  188. else
  189. Err = HeaderOrErr.takeError();
  190. }
  191. // This is used to check for overlapping of Mach-O elements.
  192. struct MachOElement {
  193. uint64_t Offset;
  194. uint64_t Size;
  195. const char *Name;
  196. };
  197. static Error checkOverlappingElement(std::list<MachOElement> &Elements,
  198. uint64_t Offset, uint64_t Size,
  199. const char *Name) {
  200. if (Size == 0)
  201. return Error::success();
  202. for (auto it=Elements.begin() ; it != Elements.end(); ++it) {
  203. auto E = *it;
  204. if ((Offset >= E.Offset && Offset < E.Offset + E.Size) ||
  205. (Offset + Size > E.Offset && Offset + Size < E.Offset + E.Size) ||
  206. (Offset <= E.Offset && Offset + Size >= E.Offset + E.Size))
  207. return malformedError(Twine(Name) + " at offset " + Twine(Offset) +
  208. " with a size of " + Twine(Size) + ", overlaps " +
  209. E.Name + " at offset " + Twine(E.Offset) + " with "
  210. "a size of " + Twine(E.Size));
  211. auto nt = it;
  212. nt++;
  213. if (nt != Elements.end()) {
  214. auto N = *nt;
  215. if (Offset + Size <= N.Offset) {
  216. Elements.insert(nt, {Offset, Size, Name});
  217. return Error::success();
  218. }
  219. }
  220. }
  221. Elements.push_back({Offset, Size, Name});
  222. return Error::success();
  223. }
  224. // Parses LC_SEGMENT or LC_SEGMENT_64 load command, adds addresses of all
  225. // sections to \param Sections, and optionally sets
  226. // \param IsPageZeroSegment to true.
  227. template <typename Segment, typename Section>
  228. static Error parseSegmentLoadCommand(
  229. const MachOObjectFile *Obj, const MachOObjectFile::LoadCommandInfo &Load,
  230. SmallVectorImpl<const char *> &Sections, bool &IsPageZeroSegment,
  231. uint32_t LoadCommandIndex, const char *CmdName, uint64_t SizeOfHeaders,
  232. std::list<MachOElement> &Elements) {
  233. const unsigned SegmentLoadSize = sizeof(Segment);
  234. if (Load.C.cmdsize < SegmentLoadSize)
  235. return malformedError("load command " + Twine(LoadCommandIndex) +
  236. " " + CmdName + " cmdsize too small");
  237. if (auto SegOrErr = getStructOrErr<Segment>(Obj, Load.Ptr)) {
  238. Segment S = SegOrErr.get();
  239. const unsigned SectionSize = sizeof(Section);
  240. uint64_t FileSize = Obj->getData().size();
  241. if (S.nsects > std::numeric_limits<uint32_t>::max() / SectionSize ||
  242. S.nsects * SectionSize > Load.C.cmdsize - SegmentLoadSize)
  243. return malformedError("load command " + Twine(LoadCommandIndex) +
  244. " inconsistent cmdsize in " + CmdName +
  245. " for the number of sections");
  246. for (unsigned J = 0; J < S.nsects; ++J) {
  247. const char *Sec = getSectionPtr(Obj, Load, J);
  248. Sections.push_back(Sec);
  249. Section s = getStruct<Section>(Obj, Sec);
  250. if (Obj->getHeader().filetype != MachO::MH_DYLIB_STUB &&
  251. Obj->getHeader().filetype != MachO::MH_DSYM &&
  252. s.flags != MachO::S_ZEROFILL &&
  253. s.flags != MachO::S_THREAD_LOCAL_ZEROFILL &&
  254. s.offset > FileSize)
  255. return malformedError("offset field of section " + Twine(J) + " in " +
  256. CmdName + " command " + Twine(LoadCommandIndex) +
  257. " extends past the end of the file");
  258. if (Obj->getHeader().filetype != MachO::MH_DYLIB_STUB &&
  259. Obj->getHeader().filetype != MachO::MH_DSYM &&
  260. s.flags != MachO::S_ZEROFILL &&
  261. s.flags != MachO::S_THREAD_LOCAL_ZEROFILL && S.fileoff == 0 &&
  262. s.offset < SizeOfHeaders && s.size != 0)
  263. return malformedError("offset field of section " + Twine(J) + " in " +
  264. CmdName + " command " + Twine(LoadCommandIndex) +
  265. " not past the headers of the file");
  266. uint64_t BigSize = s.offset;
  267. BigSize += s.size;
  268. if (Obj->getHeader().filetype != MachO::MH_DYLIB_STUB &&
  269. Obj->getHeader().filetype != MachO::MH_DSYM &&
  270. s.flags != MachO::S_ZEROFILL &&
  271. s.flags != MachO::S_THREAD_LOCAL_ZEROFILL &&
  272. BigSize > FileSize)
  273. return malformedError("offset field plus size field of section " +
  274. Twine(J) + " in " + CmdName + " command " +
  275. Twine(LoadCommandIndex) +
  276. " extends past the end of the file");
  277. if (Obj->getHeader().filetype != MachO::MH_DYLIB_STUB &&
  278. Obj->getHeader().filetype != MachO::MH_DSYM &&
  279. s.flags != MachO::S_ZEROFILL &&
  280. s.flags != MachO::S_THREAD_LOCAL_ZEROFILL &&
  281. s.size > S.filesize)
  282. return malformedError("size field of section " +
  283. Twine(J) + " in " + CmdName + " command " +
  284. Twine(LoadCommandIndex) +
  285. " greater than the segment");
  286. if (Obj->getHeader().filetype != MachO::MH_DYLIB_STUB &&
  287. Obj->getHeader().filetype != MachO::MH_DSYM && s.size != 0 &&
  288. s.addr < S.vmaddr)
  289. return malformedError("addr field of section " + Twine(J) + " in " +
  290. CmdName + " command " + Twine(LoadCommandIndex) +
  291. " less than the segment's vmaddr");
  292. BigSize = s.addr;
  293. BigSize += s.size;
  294. uint64_t BigEnd = S.vmaddr;
  295. BigEnd += S.vmsize;
  296. if (S.vmsize != 0 && s.size != 0 && BigSize > BigEnd)
  297. return malformedError("addr field plus size of section " + Twine(J) +
  298. " in " + CmdName + " command " +
  299. Twine(LoadCommandIndex) +
  300. " greater than than "
  301. "the segment's vmaddr plus vmsize");
  302. if (Obj->getHeader().filetype != MachO::MH_DYLIB_STUB &&
  303. Obj->getHeader().filetype != MachO::MH_DSYM &&
  304. s.flags != MachO::S_ZEROFILL &&
  305. s.flags != MachO::S_THREAD_LOCAL_ZEROFILL)
  306. if (Error Err = checkOverlappingElement(Elements, s.offset, s.size,
  307. "section contents"))
  308. return Err;
  309. if (s.reloff > FileSize)
  310. return malformedError("reloff field of section " + Twine(J) + " in " +
  311. CmdName + " command " + Twine(LoadCommandIndex) +
  312. " extends past the end of the file");
  313. BigSize = s.nreloc;
  314. BigSize *= sizeof(struct MachO::relocation_info);
  315. BigSize += s.reloff;
  316. if (BigSize > FileSize)
  317. return malformedError("reloff field plus nreloc field times sizeof("
  318. "struct relocation_info) of section " +
  319. Twine(J) + " in " + CmdName + " command " +
  320. Twine(LoadCommandIndex) +
  321. " extends past the end of the file");
  322. if (Error Err = checkOverlappingElement(Elements, s.reloff, s.nreloc *
  323. sizeof(struct
  324. MachO::relocation_info),
  325. "section relocation entries"))
  326. return Err;
  327. }
  328. if (S.fileoff > FileSize)
  329. return malformedError("load command " + Twine(LoadCommandIndex) +
  330. " fileoff field in " + CmdName +
  331. " extends past the end of the file");
  332. uint64_t BigSize = S.fileoff;
  333. BigSize += S.filesize;
  334. if (BigSize > FileSize)
  335. return malformedError("load command " + Twine(LoadCommandIndex) +
  336. " fileoff field plus filesize field in " +
  337. CmdName + " extends past the end of the file");
  338. if (S.vmsize != 0 && S.filesize > S.vmsize)
  339. return malformedError("load command " + Twine(LoadCommandIndex) +
  340. " fileoff field in " + CmdName +
  341. " greater than vmsize field");
  342. IsPageZeroSegment |= StringRef("__PAGEZERO").equals(S.segname);
  343. } else
  344. return SegOrErr.takeError();
  345. return Error::success();
  346. }
  347. static Error checkSymtabCommand(const MachOObjectFile *Obj,
  348. const MachOObjectFile::LoadCommandInfo &Load,
  349. uint32_t LoadCommandIndex,
  350. const char **SymtabLoadCmd,
  351. std::list<MachOElement> &Elements) {
  352. if (Load.C.cmdsize < sizeof(MachO::symtab_command))
  353. return malformedError("load command " + Twine(LoadCommandIndex) +
  354. " LC_SYMTAB cmdsize too small");
  355. if (*SymtabLoadCmd != nullptr)
  356. return malformedError("more than one LC_SYMTAB command");
  357. MachO::symtab_command Symtab =
  358. getStruct<MachO::symtab_command>(Obj, Load.Ptr);
  359. if (Symtab.cmdsize != sizeof(MachO::symtab_command))
  360. return malformedError("LC_SYMTAB command " + Twine(LoadCommandIndex) +
  361. " has incorrect cmdsize");
  362. uint64_t FileSize = Obj->getData().size();
  363. if (Symtab.symoff > FileSize)
  364. return malformedError("symoff field of LC_SYMTAB command " +
  365. Twine(LoadCommandIndex) + " extends past the end "
  366. "of the file");
  367. uint64_t SymtabSize = Symtab.nsyms;
  368. const char *struct_nlist_name;
  369. if (Obj->is64Bit()) {
  370. SymtabSize *= sizeof(MachO::nlist_64);
  371. struct_nlist_name = "struct nlist_64";
  372. } else {
  373. SymtabSize *= sizeof(MachO::nlist);
  374. struct_nlist_name = "struct nlist";
  375. }
  376. uint64_t BigSize = SymtabSize;
  377. BigSize += Symtab.symoff;
  378. if (BigSize > FileSize)
  379. return malformedError("symoff field plus nsyms field times sizeof(" +
  380. Twine(struct_nlist_name) + ") of LC_SYMTAB command " +
  381. Twine(LoadCommandIndex) + " extends past the end "
  382. "of the file");
  383. if (Error Err = checkOverlappingElement(Elements, Symtab.symoff, SymtabSize,
  384. "symbol table"))
  385. return Err;
  386. if (Symtab.stroff > FileSize)
  387. return malformedError("stroff field of LC_SYMTAB command " +
  388. Twine(LoadCommandIndex) + " extends past the end "
  389. "of the file");
  390. BigSize = Symtab.stroff;
  391. BigSize += Symtab.strsize;
  392. if (BigSize > FileSize)
  393. return malformedError("stroff field plus strsize field of LC_SYMTAB "
  394. "command " + Twine(LoadCommandIndex) + " extends "
  395. "past the end of the file");
  396. if (Error Err = checkOverlappingElement(Elements, Symtab.stroff,
  397. Symtab.strsize, "string table"))
  398. return Err;
  399. *SymtabLoadCmd = Load.Ptr;
  400. return Error::success();
  401. }
  402. static Error checkDysymtabCommand(const MachOObjectFile *Obj,
  403. const MachOObjectFile::LoadCommandInfo &Load,
  404. uint32_t LoadCommandIndex,
  405. const char **DysymtabLoadCmd,
  406. std::list<MachOElement> &Elements) {
  407. if (Load.C.cmdsize < sizeof(MachO::dysymtab_command))
  408. return malformedError("load command " + Twine(LoadCommandIndex) +
  409. " LC_DYSYMTAB cmdsize too small");
  410. if (*DysymtabLoadCmd != nullptr)
  411. return malformedError("more than one LC_DYSYMTAB command");
  412. MachO::dysymtab_command Dysymtab =
  413. getStruct<MachO::dysymtab_command>(Obj, Load.Ptr);
  414. if (Dysymtab.cmdsize != sizeof(MachO::dysymtab_command))
  415. return malformedError("LC_DYSYMTAB command " + Twine(LoadCommandIndex) +
  416. " has incorrect cmdsize");
  417. uint64_t FileSize = Obj->getData().size();
  418. if (Dysymtab.tocoff > FileSize)
  419. return malformedError("tocoff field of LC_DYSYMTAB command " +
  420. Twine(LoadCommandIndex) + " extends past the end of "
  421. "the file");
  422. uint64_t BigSize = Dysymtab.ntoc;
  423. BigSize *= sizeof(MachO::dylib_table_of_contents);
  424. BigSize += Dysymtab.tocoff;
  425. if (BigSize > FileSize)
  426. return malformedError("tocoff field plus ntoc field times sizeof(struct "
  427. "dylib_table_of_contents) of LC_DYSYMTAB command " +
  428. Twine(LoadCommandIndex) + " extends past the end of "
  429. "the file");
  430. if (Error Err = checkOverlappingElement(Elements, Dysymtab.tocoff,
  431. Dysymtab.ntoc * sizeof(struct
  432. MachO::dylib_table_of_contents),
  433. "table of contents"))
  434. return Err;
  435. if (Dysymtab.modtaboff > FileSize)
  436. return malformedError("modtaboff field of LC_DYSYMTAB command " +
  437. Twine(LoadCommandIndex) + " extends past the end of "
  438. "the file");
  439. BigSize = Dysymtab.nmodtab;
  440. const char *struct_dylib_module_name;
  441. uint64_t sizeof_modtab;
  442. if (Obj->is64Bit()) {
  443. sizeof_modtab = sizeof(MachO::dylib_module_64);
  444. struct_dylib_module_name = "struct dylib_module_64";
  445. } else {
  446. sizeof_modtab = sizeof(MachO::dylib_module);
  447. struct_dylib_module_name = "struct dylib_module";
  448. }
  449. BigSize *= sizeof_modtab;
  450. BigSize += Dysymtab.modtaboff;
  451. if (BigSize > FileSize)
  452. return malformedError("modtaboff field plus nmodtab field times sizeof(" +
  453. Twine(struct_dylib_module_name) + ") of LC_DYSYMTAB "
  454. "command " + Twine(LoadCommandIndex) + " extends "
  455. "past the end of the file");
  456. if (Error Err = checkOverlappingElement(Elements, Dysymtab.modtaboff,
  457. Dysymtab.nmodtab * sizeof_modtab,
  458. "module table"))
  459. return Err;
  460. if (Dysymtab.extrefsymoff > FileSize)
  461. return malformedError("extrefsymoff field of LC_DYSYMTAB command " +
  462. Twine(LoadCommandIndex) + " extends past the end of "
  463. "the file");
  464. BigSize = Dysymtab.nextrefsyms;
  465. BigSize *= sizeof(MachO::dylib_reference);
  466. BigSize += Dysymtab.extrefsymoff;
  467. if (BigSize > FileSize)
  468. return malformedError("extrefsymoff field plus nextrefsyms field times "
  469. "sizeof(struct dylib_reference) of LC_DYSYMTAB "
  470. "command " + Twine(LoadCommandIndex) + " extends "
  471. "past the end of the file");
  472. if (Error Err = checkOverlappingElement(Elements, Dysymtab.extrefsymoff,
  473. Dysymtab.nextrefsyms *
  474. sizeof(MachO::dylib_reference),
  475. "reference table"))
  476. return Err;
  477. if (Dysymtab.indirectsymoff > FileSize)
  478. return malformedError("indirectsymoff field of LC_DYSYMTAB command " +
  479. Twine(LoadCommandIndex) + " extends past the end of "
  480. "the file");
  481. BigSize = Dysymtab.nindirectsyms;
  482. BigSize *= sizeof(uint32_t);
  483. BigSize += Dysymtab.indirectsymoff;
  484. if (BigSize > FileSize)
  485. return malformedError("indirectsymoff field plus nindirectsyms field times "
  486. "sizeof(uint32_t) of LC_DYSYMTAB command " +
  487. Twine(LoadCommandIndex) + " extends past the end of "
  488. "the file");
  489. if (Error Err = checkOverlappingElement(Elements, Dysymtab.indirectsymoff,
  490. Dysymtab.nindirectsyms *
  491. sizeof(uint32_t),
  492. "indirect table"))
  493. return Err;
  494. if (Dysymtab.extreloff > FileSize)
  495. return malformedError("extreloff field of LC_DYSYMTAB command " +
  496. Twine(LoadCommandIndex) + " extends past the end of "
  497. "the file");
  498. BigSize = Dysymtab.nextrel;
  499. BigSize *= sizeof(MachO::relocation_info);
  500. BigSize += Dysymtab.extreloff;
  501. if (BigSize > FileSize)
  502. return malformedError("extreloff field plus nextrel field times sizeof"
  503. "(struct relocation_info) of LC_DYSYMTAB command " +
  504. Twine(LoadCommandIndex) + " extends past the end of "
  505. "the file");
  506. if (Error Err = checkOverlappingElement(Elements, Dysymtab.extreloff,
  507. Dysymtab.nextrel *
  508. sizeof(MachO::relocation_info),
  509. "external relocation table"))
  510. return Err;
  511. if (Dysymtab.locreloff > FileSize)
  512. return malformedError("locreloff field of LC_DYSYMTAB command " +
  513. Twine(LoadCommandIndex) + " extends past the end of "
  514. "the file");
  515. BigSize = Dysymtab.nlocrel;
  516. BigSize *= sizeof(MachO::relocation_info);
  517. BigSize += Dysymtab.locreloff;
  518. if (BigSize > FileSize)
  519. return malformedError("locreloff field plus nlocrel field times sizeof"
  520. "(struct relocation_info) of LC_DYSYMTAB command " +
  521. Twine(LoadCommandIndex) + " extends past the end of "
  522. "the file");
  523. if (Error Err = checkOverlappingElement(Elements, Dysymtab.locreloff,
  524. Dysymtab.nlocrel *
  525. sizeof(MachO::relocation_info),
  526. "local relocation table"))
  527. return Err;
  528. *DysymtabLoadCmd = Load.Ptr;
  529. return Error::success();
  530. }
  531. static Error checkLinkeditDataCommand(const MachOObjectFile *Obj,
  532. const MachOObjectFile::LoadCommandInfo &Load,
  533. uint32_t LoadCommandIndex,
  534. const char **LoadCmd, const char *CmdName,
  535. std::list<MachOElement> &Elements,
  536. const char *ElementName) {
  537. if (Load.C.cmdsize < sizeof(MachO::linkedit_data_command))
  538. return malformedError("load command " + Twine(LoadCommandIndex) + " " +
  539. CmdName + " cmdsize too small");
  540. if (*LoadCmd != nullptr)
  541. return malformedError("more than one " + Twine(CmdName) + " command");
  542. MachO::linkedit_data_command LinkData =
  543. getStruct<MachO::linkedit_data_command>(Obj, Load.Ptr);
  544. if (LinkData.cmdsize != sizeof(MachO::linkedit_data_command))
  545. return malformedError(Twine(CmdName) + " command " +
  546. Twine(LoadCommandIndex) + " has incorrect cmdsize");
  547. uint64_t FileSize = Obj->getData().size();
  548. if (LinkData.dataoff > FileSize)
  549. return malformedError("dataoff field of " + Twine(CmdName) + " command " +
  550. Twine(LoadCommandIndex) + " extends past the end of "
  551. "the file");
  552. uint64_t BigSize = LinkData.dataoff;
  553. BigSize += LinkData.datasize;
  554. if (BigSize > FileSize)
  555. return malformedError("dataoff field plus datasize field of " +
  556. Twine(CmdName) + " command " +
  557. Twine(LoadCommandIndex) + " extends past the end of "
  558. "the file");
  559. if (Error Err = checkOverlappingElement(Elements, LinkData.dataoff,
  560. LinkData.datasize, ElementName))
  561. return Err;
  562. *LoadCmd = Load.Ptr;
  563. return Error::success();
  564. }
  565. static Error checkDyldInfoCommand(const MachOObjectFile *Obj,
  566. const MachOObjectFile::LoadCommandInfo &Load,
  567. uint32_t LoadCommandIndex,
  568. const char **LoadCmd, const char *CmdName,
  569. std::list<MachOElement> &Elements) {
  570. if (Load.C.cmdsize < sizeof(MachO::dyld_info_command))
  571. return malformedError("load command " + Twine(LoadCommandIndex) + " " +
  572. CmdName + " cmdsize too small");
  573. if (*LoadCmd != nullptr)
  574. return malformedError("more than one LC_DYLD_INFO and or LC_DYLD_INFO_ONLY "
  575. "command");
  576. MachO::dyld_info_command DyldInfo =
  577. getStruct<MachO::dyld_info_command>(Obj, Load.Ptr);
  578. if (DyldInfo.cmdsize != sizeof(MachO::dyld_info_command))
  579. return malformedError(Twine(CmdName) + " command " +
  580. Twine(LoadCommandIndex) + " has incorrect cmdsize");
  581. uint64_t FileSize = Obj->getData().size();
  582. if (DyldInfo.rebase_off > FileSize)
  583. return malformedError("rebase_off field of " + Twine(CmdName) +
  584. " command " + Twine(LoadCommandIndex) + " extends "
  585. "past the end of the file");
  586. uint64_t BigSize = DyldInfo.rebase_off;
  587. BigSize += DyldInfo.rebase_size;
  588. if (BigSize > FileSize)
  589. return malformedError("rebase_off field plus rebase_size field of " +
  590. Twine(CmdName) + " command " +
  591. Twine(LoadCommandIndex) + " extends past the end of "
  592. "the file");
  593. if (Error Err = checkOverlappingElement(Elements, DyldInfo.rebase_off,
  594. DyldInfo.rebase_size,
  595. "dyld rebase info"))
  596. return Err;
  597. if (DyldInfo.bind_off > FileSize)
  598. return malformedError("bind_off field of " + Twine(CmdName) +
  599. " command " + Twine(LoadCommandIndex) + " extends "
  600. "past the end of the file");
  601. BigSize = DyldInfo.bind_off;
  602. BigSize += DyldInfo.bind_size;
  603. if (BigSize > FileSize)
  604. return malformedError("bind_off field plus bind_size field of " +
  605. Twine(CmdName) + " command " +
  606. Twine(LoadCommandIndex) + " extends past the end of "
  607. "the file");
  608. if (Error Err = checkOverlappingElement(Elements, DyldInfo.bind_off,
  609. DyldInfo.bind_size,
  610. "dyld bind info"))
  611. return Err;
  612. if (DyldInfo.weak_bind_off > FileSize)
  613. return malformedError("weak_bind_off field of " + Twine(CmdName) +
  614. " command " + Twine(LoadCommandIndex) + " extends "
  615. "past the end of the file");
  616. BigSize = DyldInfo.weak_bind_off;
  617. BigSize += DyldInfo.weak_bind_size;
  618. if (BigSize > FileSize)
  619. return malformedError("weak_bind_off field plus weak_bind_size field of " +
  620. Twine(CmdName) + " command " +
  621. Twine(LoadCommandIndex) + " extends past the end of "
  622. "the file");
  623. if (Error Err = checkOverlappingElement(Elements, DyldInfo.weak_bind_off,
  624. DyldInfo.weak_bind_size,
  625. "dyld weak bind info"))
  626. return Err;
  627. if (DyldInfo.lazy_bind_off > FileSize)
  628. return malformedError("lazy_bind_off field of " + Twine(CmdName) +
  629. " command " + Twine(LoadCommandIndex) + " extends "
  630. "past the end of the file");
  631. BigSize = DyldInfo.lazy_bind_off;
  632. BigSize += DyldInfo.lazy_bind_size;
  633. if (BigSize > FileSize)
  634. return malformedError("lazy_bind_off field plus lazy_bind_size field of " +
  635. Twine(CmdName) + " command " +
  636. Twine(LoadCommandIndex) + " extends past the end of "
  637. "the file");
  638. if (Error Err = checkOverlappingElement(Elements, DyldInfo.lazy_bind_off,
  639. DyldInfo.lazy_bind_size,
  640. "dyld lazy bind info"))
  641. return Err;
  642. if (DyldInfo.export_off > FileSize)
  643. return malformedError("export_off field of " + Twine(CmdName) +
  644. " command " + Twine(LoadCommandIndex) + " extends "
  645. "past the end of the file");
  646. BigSize = DyldInfo.export_off;
  647. BigSize += DyldInfo.export_size;
  648. if (BigSize > FileSize)
  649. return malformedError("export_off field plus export_size field of " +
  650. Twine(CmdName) + " command " +
  651. Twine(LoadCommandIndex) + " extends past the end of "
  652. "the file");
  653. if (Error Err = checkOverlappingElement(Elements, DyldInfo.export_off,
  654. DyldInfo.export_size,
  655. "dyld export info"))
  656. return Err;
  657. *LoadCmd = Load.Ptr;
  658. return Error::success();
  659. }
  660. static Error checkDylibCommand(const MachOObjectFile *Obj,
  661. const MachOObjectFile::LoadCommandInfo &Load,
  662. uint32_t LoadCommandIndex, const char *CmdName) {
  663. if (Load.C.cmdsize < sizeof(MachO::dylib_command))
  664. return malformedError("load command " + Twine(LoadCommandIndex) + " " +
  665. CmdName + " cmdsize too small");
  666. MachO::dylib_command D = getStruct<MachO::dylib_command>(Obj, Load.Ptr);
  667. if (D.dylib.name < sizeof(MachO::dylib_command))
  668. return malformedError("load command " + Twine(LoadCommandIndex) + " " +
  669. CmdName + " name.offset field too small, not past "
  670. "the end of the dylib_command struct");
  671. if (D.dylib.name >= D.cmdsize)
  672. return malformedError("load command " + Twine(LoadCommandIndex) + " " +
  673. CmdName + " name.offset field extends past the end "
  674. "of the load command");
  675. // Make sure there is a null between the starting offset of the name and
  676. // the end of the load command.
  677. uint32_t i;
  678. const char *P = (const char *)Load.Ptr;
  679. for (i = D.dylib.name; i < D.cmdsize; i++)
  680. if (P[i] == '\0')
  681. break;
  682. if (i >= D.cmdsize)
  683. return malformedError("load command " + Twine(LoadCommandIndex) + " " +
  684. CmdName + " library name extends past the end of the "
  685. "load command");
  686. return Error::success();
  687. }
  688. static Error checkDylibIdCommand(const MachOObjectFile *Obj,
  689. const MachOObjectFile::LoadCommandInfo &Load,
  690. uint32_t LoadCommandIndex,
  691. const char **LoadCmd) {
  692. if (Error Err = checkDylibCommand(Obj, Load, LoadCommandIndex,
  693. "LC_ID_DYLIB"))
  694. return Err;
  695. if (*LoadCmd != nullptr)
  696. return malformedError("more than one LC_ID_DYLIB command");
  697. if (Obj->getHeader().filetype != MachO::MH_DYLIB &&
  698. Obj->getHeader().filetype != MachO::MH_DYLIB_STUB)
  699. return malformedError("LC_ID_DYLIB load command in non-dynamic library "
  700. "file type");
  701. *LoadCmd = Load.Ptr;
  702. return Error::success();
  703. }
  704. static Error checkDyldCommand(const MachOObjectFile *Obj,
  705. const MachOObjectFile::LoadCommandInfo &Load,
  706. uint32_t LoadCommandIndex, const char *CmdName) {
  707. if (Load.C.cmdsize < sizeof(MachO::dylinker_command))
  708. return malformedError("load command " + Twine(LoadCommandIndex) + " " +
  709. CmdName + " cmdsize too small");
  710. MachO::dylinker_command D = getStruct<MachO::dylinker_command>(Obj, Load.Ptr);
  711. if (D.name < sizeof(MachO::dylinker_command))
  712. return malformedError("load command " + Twine(LoadCommandIndex) + " " +
  713. CmdName + " name.offset field too small, not past "
  714. "the end of the dylinker_command struct");
  715. if (D.name >= D.cmdsize)
  716. return malformedError("load command " + Twine(LoadCommandIndex) + " " +
  717. CmdName + " name.offset field extends past the end "
  718. "of the load command");
  719. // Make sure there is a null between the starting offset of the name and
  720. // the end of the load command.
  721. uint32_t i;
  722. const char *P = (const char *)Load.Ptr;
  723. for (i = D.name; i < D.cmdsize; i++)
  724. if (P[i] == '\0')
  725. break;
  726. if (i >= D.cmdsize)
  727. return malformedError("load command " + Twine(LoadCommandIndex) + " " +
  728. CmdName + " dyld name extends past the end of the "
  729. "load command");
  730. return Error::success();
  731. }
  732. static Error checkVersCommand(const MachOObjectFile *Obj,
  733. const MachOObjectFile::LoadCommandInfo &Load,
  734. uint32_t LoadCommandIndex,
  735. const char **LoadCmd, const char *CmdName) {
  736. if (Load.C.cmdsize != sizeof(MachO::version_min_command))
  737. return malformedError("load command " + Twine(LoadCommandIndex) + " " +
  738. CmdName + " has incorrect cmdsize");
  739. if (*LoadCmd != nullptr)
  740. return malformedError("more than one LC_VERSION_MIN_MACOSX, "
  741. "LC_VERSION_MIN_IPHONEOS, LC_VERSION_MIN_TVOS or "
  742. "LC_VERSION_MIN_WATCHOS command");
  743. *LoadCmd = Load.Ptr;
  744. return Error::success();
  745. }
  746. static Error checkRpathCommand(const MachOObjectFile *Obj,
  747. const MachOObjectFile::LoadCommandInfo &Load,
  748. uint32_t LoadCommandIndex) {
  749. if (Load.C.cmdsize < sizeof(MachO::rpath_command))
  750. return malformedError("load command " + Twine(LoadCommandIndex) +
  751. " LC_RPATH cmdsize too small");
  752. MachO::rpath_command R = getStruct<MachO::rpath_command>(Obj, Load.Ptr);
  753. if (R.path < sizeof(MachO::rpath_command))
  754. return malformedError("load command " + Twine(LoadCommandIndex) +
  755. " LC_RPATH path.offset field too small, not past "
  756. "the end of the rpath_command struct");
  757. if (R.path >= R.cmdsize)
  758. return malformedError("load command " + Twine(LoadCommandIndex) +
  759. " LC_RPATH path.offset field extends past the end "
  760. "of the load command");
  761. // Make sure there is a null between the starting offset of the path and
  762. // the end of the load command.
  763. uint32_t i;
  764. const char *P = (const char *)Load.Ptr;
  765. for (i = R.path; i < R.cmdsize; i++)
  766. if (P[i] == '\0')
  767. break;
  768. if (i >= R.cmdsize)
  769. return malformedError("load command " + Twine(LoadCommandIndex) +
  770. " LC_RPATH library name extends past the end of the "
  771. "load command");
  772. return Error::success();
  773. }
  774. static Error checkEncryptCommand(const MachOObjectFile *Obj,
  775. const MachOObjectFile::LoadCommandInfo &Load,
  776. uint32_t LoadCommandIndex,
  777. uint64_t cryptoff, uint64_t cryptsize,
  778. const char **LoadCmd, const char *CmdName) {
  779. if (*LoadCmd != nullptr)
  780. return malformedError("more than one LC_ENCRYPTION_INFO and or "
  781. "LC_ENCRYPTION_INFO_64 command");
  782. uint64_t FileSize = Obj->getData().size();
  783. if (cryptoff > FileSize)
  784. return malformedError("cryptoff field of " + Twine(CmdName) +
  785. " command " + Twine(LoadCommandIndex) + " extends "
  786. "past the end of the file");
  787. uint64_t BigSize = cryptoff;
  788. BigSize += cryptsize;
  789. if (BigSize > FileSize)
  790. return malformedError("cryptoff field plus cryptsize field of " +
  791. Twine(CmdName) + " command " +
  792. Twine(LoadCommandIndex) + " extends past the end of "
  793. "the file");
  794. *LoadCmd = Load.Ptr;
  795. return Error::success();
  796. }
  797. static Error checkLinkerOptCommand(const MachOObjectFile *Obj,
  798. const MachOObjectFile::LoadCommandInfo &Load,
  799. uint32_t LoadCommandIndex) {
  800. if (Load.C.cmdsize < sizeof(MachO::linker_option_command))
  801. return malformedError("load command " + Twine(LoadCommandIndex) +
  802. " LC_LINKER_OPTION cmdsize too small");
  803. MachO::linker_option_command L =
  804. getStruct<MachO::linker_option_command>(Obj, Load.Ptr);
  805. // Make sure the count of strings is correct.
  806. const char *string = (const char *)Load.Ptr +
  807. sizeof(struct MachO::linker_option_command);
  808. uint32_t left = L.cmdsize - sizeof(struct MachO::linker_option_command);
  809. uint32_t i = 0;
  810. while (left > 0) {
  811. while (*string == '\0' && left > 0) {
  812. string++;
  813. left--;
  814. }
  815. if (left > 0) {
  816. i++;
  817. uint32_t NullPos = StringRef(string, left).find('\0');
  818. uint32_t len = std::min(NullPos, left) + 1;
  819. string += len;
  820. left -= len;
  821. }
  822. }
  823. if (L.count != i)
  824. return malformedError("load command " + Twine(LoadCommandIndex) +
  825. " LC_LINKER_OPTION string count " + Twine(L.count) +
  826. " does not match number of strings");
  827. return Error::success();
  828. }
  829. static Error checkSubCommand(const MachOObjectFile *Obj,
  830. const MachOObjectFile::LoadCommandInfo &Load,
  831. uint32_t LoadCommandIndex, const char *CmdName,
  832. size_t SizeOfCmd, const char *CmdStructName,
  833. uint32_t PathOffset, const char *PathFieldName) {
  834. if (PathOffset < SizeOfCmd)
  835. return malformedError("load command " + Twine(LoadCommandIndex) + " " +
  836. CmdName + " " + PathFieldName + ".offset field too "
  837. "small, not past the end of the " + CmdStructName);
  838. if (PathOffset >= Load.C.cmdsize)
  839. return malformedError("load command " + Twine(LoadCommandIndex) + " " +
  840. CmdName + " " + PathFieldName + ".offset field "
  841. "extends past the end of the load command");
  842. // Make sure there is a null between the starting offset of the path and
  843. // the end of the load command.
  844. uint32_t i;
  845. const char *P = (const char *)Load.Ptr;
  846. for (i = PathOffset; i < Load.C.cmdsize; i++)
  847. if (P[i] == '\0')
  848. break;
  849. if (i >= Load.C.cmdsize)
  850. return malformedError("load command " + Twine(LoadCommandIndex) + " " +
  851. CmdName + " " + PathFieldName + " name extends past "
  852. "the end of the load command");
  853. return Error::success();
  854. }
  855. static Error checkThreadCommand(const MachOObjectFile *Obj,
  856. const MachOObjectFile::LoadCommandInfo &Load,
  857. uint32_t LoadCommandIndex,
  858. const char *CmdName) {
  859. if (Load.C.cmdsize < sizeof(MachO::thread_command))
  860. return malformedError("load command " + Twine(LoadCommandIndex) +
  861. CmdName + " cmdsize too small");
  862. MachO::thread_command T =
  863. getStruct<MachO::thread_command>(Obj, Load.Ptr);
  864. const char *state = Load.Ptr + sizeof(MachO::thread_command);
  865. const char *end = Load.Ptr + T.cmdsize;
  866. uint32_t nflavor = 0;
  867. uint32_t cputype = getCPUType(Obj);
  868. while (state < end) {
  869. if(state + sizeof(uint32_t) > end)
  870. return malformedError("load command " + Twine(LoadCommandIndex) +
  871. "flavor in " + CmdName + " extends past end of "
  872. "command");
  873. uint32_t flavor;
  874. memcpy(&flavor, state, sizeof(uint32_t));
  875. if (Obj->isLittleEndian() != sys::IsLittleEndianHost)
  876. sys::swapByteOrder(flavor);
  877. state += sizeof(uint32_t);
  878. if(state + sizeof(uint32_t) > end)
  879. return malformedError("load command " + Twine(LoadCommandIndex) +
  880. " count in " + CmdName + " extends past end of "
  881. "command");
  882. uint32_t count;
  883. memcpy(&count, state, sizeof(uint32_t));
  884. if (Obj->isLittleEndian() != sys::IsLittleEndianHost)
  885. sys::swapByteOrder(count);
  886. state += sizeof(uint32_t);
  887. if (cputype == MachO::CPU_TYPE_X86_64) {
  888. if (flavor == MachO::x86_THREAD_STATE64) {
  889. if (count != MachO::x86_THREAD_STATE64_COUNT)
  890. return malformedError("load command " + Twine(LoadCommandIndex) +
  891. " count not x86_THREAD_STATE64_COUNT for "
  892. "flavor number " + Twine(nflavor) + " which is "
  893. "a x86_THREAD_STATE64 flavor in " + CmdName +
  894. " command");
  895. if (state + sizeof(MachO::x86_thread_state64_t) > end)
  896. return malformedError("load command " + Twine(LoadCommandIndex) +
  897. " x86_THREAD_STATE64 extends past end of "
  898. "command in " + CmdName + " command");
  899. state += sizeof(MachO::x86_thread_state64_t);
  900. } else {
  901. return malformedError("load command " + Twine(LoadCommandIndex) +
  902. " unknown flavor (" + Twine(flavor) + ") for "
  903. "flavor number " + Twine(nflavor) + " in " +
  904. CmdName + " command");
  905. }
  906. } else if (cputype == MachO::CPU_TYPE_ARM) {
  907. if (flavor == MachO::ARM_THREAD_STATE) {
  908. if (count != MachO::ARM_THREAD_STATE_COUNT)
  909. return malformedError("load command " + Twine(LoadCommandIndex) +
  910. " count not ARM_THREAD_STATE_COUNT for "
  911. "flavor number " + Twine(nflavor) + " which is "
  912. "a ARM_THREAD_STATE flavor in " + CmdName +
  913. " command");
  914. if (state + sizeof(MachO::arm_thread_state32_t) > end)
  915. return malformedError("load command " + Twine(LoadCommandIndex) +
  916. " ARM_THREAD_STATE extends past end of "
  917. "command in " + CmdName + " command");
  918. state += sizeof(MachO::arm_thread_state32_t);
  919. } else {
  920. return malformedError("load command " + Twine(LoadCommandIndex) +
  921. " unknown flavor (" + Twine(flavor) + ") for "
  922. "flavor number " + Twine(nflavor) + " in " +
  923. CmdName + " command");
  924. }
  925. } else if (cputype == MachO::CPU_TYPE_ARM64) {
  926. if (flavor == MachO::ARM_THREAD_STATE64) {
  927. if (count != MachO::ARM_THREAD_STATE64_COUNT)
  928. return malformedError("load command " + Twine(LoadCommandIndex) +
  929. " count not ARM_THREAD_STATE64_COUNT for "
  930. "flavor number " + Twine(nflavor) + " which is "
  931. "a ARM_THREAD_STATE64 flavor in " + CmdName +
  932. " command");
  933. if (state + sizeof(MachO::arm_thread_state64_t) > end)
  934. return malformedError("load command " + Twine(LoadCommandIndex) +
  935. " ARM_THREAD_STATE64 extends past end of "
  936. "command in " + CmdName + " command");
  937. state += sizeof(MachO::arm_thread_state64_t);
  938. } else {
  939. return malformedError("load command " + Twine(LoadCommandIndex) +
  940. " unknown flavor (" + Twine(flavor) + ") for "
  941. "flavor number " + Twine(nflavor) + " in " +
  942. CmdName + " command");
  943. }
  944. } else if (cputype == MachO::CPU_TYPE_POWERPC) {
  945. if (flavor == MachO::PPC_THREAD_STATE) {
  946. if (count != MachO::PPC_THREAD_STATE_COUNT)
  947. return malformedError("load command " + Twine(LoadCommandIndex) +
  948. " count not PPC_THREAD_STATE_COUNT for "
  949. "flavor number " + Twine(nflavor) + " which is "
  950. "a PPC_THREAD_STATE flavor in " + CmdName +
  951. " command");
  952. if (state + sizeof(MachO::ppc_thread_state32_t) > end)
  953. return malformedError("load command " + Twine(LoadCommandIndex) +
  954. " PPC_THREAD_STATE extends past end of "
  955. "command in " + CmdName + " command");
  956. state += sizeof(MachO::ppc_thread_state32_t);
  957. } else {
  958. return malformedError("load command " + Twine(LoadCommandIndex) +
  959. " unknown flavor (" + Twine(flavor) + ") for "
  960. "flavor number " + Twine(nflavor) + " in " +
  961. CmdName + " command");
  962. }
  963. } else {
  964. return malformedError("unknown cputype (" + Twine(cputype) + ") load "
  965. "command " + Twine(LoadCommandIndex) + " for " +
  966. CmdName + " command can't be checked");
  967. }
  968. nflavor++;
  969. }
  970. return Error::success();
  971. }
  972. static Error checkTwoLevelHintsCommand(const MachOObjectFile *Obj,
  973. const MachOObjectFile::LoadCommandInfo
  974. &Load,
  975. uint32_t LoadCommandIndex,
  976. const char **LoadCmd,
  977. std::list<MachOElement> &Elements) {
  978. if (Load.C.cmdsize != sizeof(MachO::twolevel_hints_command))
  979. return malformedError("load command " + Twine(LoadCommandIndex) +
  980. " LC_TWOLEVEL_HINTS has incorrect cmdsize");
  981. if (*LoadCmd != nullptr)
  982. return malformedError("more than one LC_TWOLEVEL_HINTS command");
  983. MachO::twolevel_hints_command Hints =
  984. getStruct<MachO::twolevel_hints_command>(Obj, Load.Ptr);
  985. uint64_t FileSize = Obj->getData().size();
  986. if (Hints.offset > FileSize)
  987. return malformedError("offset field of LC_TWOLEVEL_HINTS command " +
  988. Twine(LoadCommandIndex) + " extends past the end of "
  989. "the file");
  990. uint64_t BigSize = Hints.nhints;
  991. BigSize *= Hints.nhints * sizeof(MachO::twolevel_hint);
  992. BigSize += Hints.offset;
  993. if (BigSize > FileSize)
  994. return malformedError("offset field plus nhints times sizeof(struct "
  995. "twolevel_hint) field of LC_TWOLEVEL_HINTS command " +
  996. Twine(LoadCommandIndex) + " extends past the end of "
  997. "the file");
  998. if (Error Err = checkOverlappingElement(Elements, Hints.offset, Hints.nhints *
  999. sizeof(MachO::twolevel_hint),
  1000. "two level hints"))
  1001. return Err;
  1002. *LoadCmd = Load.Ptr;
  1003. return Error::success();
  1004. }
  1005. // Returns true if the libObject code does not support the load command and its
  1006. // contents. The cmd value it is treated as an unknown load command but with
  1007. // an error message that says the cmd value is obsolete.
  1008. static bool isLoadCommandObsolete(uint32_t cmd) {
  1009. if (cmd == MachO::LC_SYMSEG ||
  1010. cmd == MachO::LC_LOADFVMLIB ||
  1011. cmd == MachO::LC_IDFVMLIB ||
  1012. cmd == MachO::LC_IDENT ||
  1013. cmd == MachO::LC_FVMFILE ||
  1014. cmd == MachO::LC_PREPAGE ||
  1015. cmd == MachO::LC_PREBOUND_DYLIB ||
  1016. cmd == MachO::LC_TWOLEVEL_HINTS ||
  1017. cmd == MachO::LC_PREBIND_CKSUM)
  1018. return true;
  1019. return false;
  1020. }
  1021. Expected<std::unique_ptr<MachOObjectFile>>
  1022. MachOObjectFile::create(MemoryBufferRef Object, bool IsLittleEndian,
  1023. bool Is64Bits, uint32_t UniversalCputype,
  1024. uint32_t UniversalIndex) {
  1025. Error Err = Error::success();
  1026. std::unique_ptr<MachOObjectFile> Obj(
  1027. new MachOObjectFile(std::move(Object), IsLittleEndian,
  1028. Is64Bits, Err, UniversalCputype,
  1029. UniversalIndex));
  1030. if (Err)
  1031. return std::move(Err);
  1032. return std::move(Obj);
  1033. }
  1034. MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
  1035. bool Is64bits, Error &Err,
  1036. uint32_t UniversalCputype,
  1037. uint32_t UniversalIndex)
  1038. : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object),
  1039. SymtabLoadCmd(nullptr), DysymtabLoadCmd(nullptr),
  1040. DataInCodeLoadCmd(nullptr), LinkOptHintsLoadCmd(nullptr),
  1041. DyldInfoLoadCmd(nullptr), UuidLoadCmd(nullptr),
  1042. HasPageZeroSegment(false) {
  1043. ErrorAsOutParameter ErrAsOutParam(&Err);
  1044. uint64_t SizeOfHeaders;
  1045. uint32_t cputype;
  1046. if (is64Bit()) {
  1047. parseHeader(this, Header64, Err);
  1048. SizeOfHeaders = sizeof(MachO::mach_header_64);
  1049. cputype = Header64.cputype;
  1050. } else {
  1051. parseHeader(this, Header, Err);
  1052. SizeOfHeaders = sizeof(MachO::mach_header);
  1053. cputype = Header.cputype;
  1054. }
  1055. if (Err)
  1056. return;
  1057. SizeOfHeaders += getHeader().sizeofcmds;
  1058. if (getData().data() + SizeOfHeaders > getData().end()) {
  1059. Err = malformedError("load commands extend past the end of the file");
  1060. return;
  1061. }
  1062. if (UniversalCputype != 0 && cputype != UniversalCputype) {
  1063. Err = malformedError("universal header architecture: " +
  1064. Twine(UniversalIndex) + "'s cputype does not match "
  1065. "object file's mach header");
  1066. return;
  1067. }
  1068. std::list<MachOElement> Elements;
  1069. Elements.push_back({0, SizeOfHeaders, "Mach-O headers"});
  1070. uint32_t LoadCommandCount = getHeader().ncmds;
  1071. LoadCommandInfo Load;
  1072. if (LoadCommandCount != 0) {
  1073. if (auto LoadOrErr = getFirstLoadCommandInfo(this))
  1074. Load = *LoadOrErr;
  1075. else {
  1076. Err = LoadOrErr.takeError();
  1077. return;
  1078. }
  1079. }
  1080. const char *DyldIdLoadCmd = nullptr;
  1081. const char *FuncStartsLoadCmd = nullptr;
  1082. const char *SplitInfoLoadCmd = nullptr;
  1083. const char *CodeSignDrsLoadCmd = nullptr;
  1084. const char *CodeSignLoadCmd = nullptr;
  1085. const char *VersLoadCmd = nullptr;
  1086. const char *SourceLoadCmd = nullptr;
  1087. const char *EntryPointLoadCmd = nullptr;
  1088. const char *EncryptLoadCmd = nullptr;
  1089. const char *RoutinesLoadCmd = nullptr;
  1090. const char *UnixThreadLoadCmd = nullptr;
  1091. const char *TwoLevelHintsLoadCmd = nullptr;
  1092. for (unsigned I = 0; I < LoadCommandCount; ++I) {
  1093. if (is64Bit()) {
  1094. if (Load.C.cmdsize % 8 != 0) {
  1095. // We have a hack here to allow 64-bit Mach-O core files to have
  1096. // LC_THREAD commands that are only a multiple of 4 and not 8 to be
  1097. // allowed since the macOS kernel produces them.
  1098. if (getHeader().filetype != MachO::MH_CORE ||
  1099. Load.C.cmd != MachO::LC_THREAD || Load.C.cmdsize % 4) {
  1100. Err = malformedError("load command " + Twine(I) + " cmdsize not a "
  1101. "multiple of 8");
  1102. return;
  1103. }
  1104. }
  1105. } else {
  1106. if (Load.C.cmdsize % 4 != 0) {
  1107. Err = malformedError("load command " + Twine(I) + " cmdsize not a "
  1108. "multiple of 4");
  1109. return;
  1110. }
  1111. }
  1112. LoadCommands.push_back(Load);
  1113. if (Load.C.cmd == MachO::LC_SYMTAB) {
  1114. if ((Err = checkSymtabCommand(this, Load, I, &SymtabLoadCmd, Elements)))
  1115. return;
  1116. } else if (Load.C.cmd == MachO::LC_DYSYMTAB) {
  1117. if ((Err = checkDysymtabCommand(this, Load, I, &DysymtabLoadCmd,
  1118. Elements)))
  1119. return;
  1120. } else if (Load.C.cmd == MachO::LC_DATA_IN_CODE) {
  1121. if ((Err = checkLinkeditDataCommand(this, Load, I, &DataInCodeLoadCmd,
  1122. "LC_DATA_IN_CODE", Elements,
  1123. "data in code info")))
  1124. return;
  1125. } else if (Load.C.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT) {
  1126. if ((Err = checkLinkeditDataCommand(this, Load, I, &LinkOptHintsLoadCmd,
  1127. "LC_LINKER_OPTIMIZATION_HINT",
  1128. Elements, "linker optimization "
  1129. "hints")))
  1130. return;
  1131. } else if (Load.C.cmd == MachO::LC_FUNCTION_STARTS) {
  1132. if ((Err = checkLinkeditDataCommand(this, Load, I, &FuncStartsLoadCmd,
  1133. "LC_FUNCTION_STARTS", Elements,
  1134. "function starts data")))
  1135. return;
  1136. } else if (Load.C.cmd == MachO::LC_SEGMENT_SPLIT_INFO) {
  1137. if ((Err = checkLinkeditDataCommand(this, Load, I, &SplitInfoLoadCmd,
  1138. "LC_SEGMENT_SPLIT_INFO", Elements,
  1139. "split info data")))
  1140. return;
  1141. } else if (Load.C.cmd == MachO::LC_DYLIB_CODE_SIGN_DRS) {
  1142. if ((Err = checkLinkeditDataCommand(this, Load, I, &CodeSignDrsLoadCmd,
  1143. "LC_DYLIB_CODE_SIGN_DRS", Elements,
  1144. "code signing RDs data")))
  1145. return;
  1146. } else if (Load.C.cmd == MachO::LC_CODE_SIGNATURE) {
  1147. if ((Err = checkLinkeditDataCommand(this, Load, I, &CodeSignLoadCmd,
  1148. "LC_CODE_SIGNATURE", Elements,
  1149. "code signature data")))
  1150. return;
  1151. } else if (Load.C.cmd == MachO::LC_DYLD_INFO) {
  1152. if ((Err = checkDyldInfoCommand(this, Load, I, &DyldInfoLoadCmd,
  1153. "LC_DYLD_INFO", Elements)))
  1154. return;
  1155. } else if (Load.C.cmd == MachO::LC_DYLD_INFO_ONLY) {
  1156. if ((Err = checkDyldInfoCommand(this, Load, I, &DyldInfoLoadCmd,
  1157. "LC_DYLD_INFO_ONLY", Elements)))
  1158. return;
  1159. } else if (Load.C.cmd == MachO::LC_UUID) {
  1160. if (Load.C.cmdsize != sizeof(MachO::uuid_command)) {
  1161. Err = malformedError("LC_UUID command " + Twine(I) + " has incorrect "
  1162. "cmdsize");
  1163. return;
  1164. }
  1165. if (UuidLoadCmd) {
  1166. Err = malformedError("more than one LC_UUID command");
  1167. return;
  1168. }
  1169. UuidLoadCmd = Load.Ptr;
  1170. } else if (Load.C.cmd == MachO::LC_SEGMENT_64) {
  1171. if ((Err = parseSegmentLoadCommand<MachO::segment_command_64,
  1172. MachO::section_64>(
  1173. this, Load, Sections, HasPageZeroSegment, I,
  1174. "LC_SEGMENT_64", SizeOfHeaders, Elements)))
  1175. return;
  1176. } else if (Load.C.cmd == MachO::LC_SEGMENT) {
  1177. if ((Err = parseSegmentLoadCommand<MachO::segment_command,
  1178. MachO::section>(
  1179. this, Load, Sections, HasPageZeroSegment, I,
  1180. "LC_SEGMENT", SizeOfHeaders, Elements)))
  1181. return;
  1182. } else if (Load.C.cmd == MachO::LC_ID_DYLIB) {
  1183. if ((Err = checkDylibIdCommand(this, Load, I, &DyldIdLoadCmd)))
  1184. return;
  1185. } else if (Load.C.cmd == MachO::LC_LOAD_DYLIB) {
  1186. if ((Err = checkDylibCommand(this, Load, I, "LC_LOAD_DYLIB")))
  1187. return;
  1188. Libraries.push_back(Load.Ptr);
  1189. } else if (Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB) {
  1190. if ((Err = checkDylibCommand(this, Load, I, "LC_LOAD_WEAK_DYLIB")))
  1191. return;
  1192. Libraries.push_back(Load.Ptr);
  1193. } else if (Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB) {
  1194. if ((Err = checkDylibCommand(this, Load, I, "LC_LAZY_LOAD_DYLIB")))
  1195. return;
  1196. Libraries.push_back(Load.Ptr);
  1197. } else if (Load.C.cmd == MachO::LC_REEXPORT_DYLIB) {
  1198. if ((Err = checkDylibCommand(this, Load, I, "LC_REEXPORT_DYLIB")))
  1199. return;
  1200. Libraries.push_back(Load.Ptr);
  1201. } else if (Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) {
  1202. if ((Err = checkDylibCommand(this, Load, I, "LC_LOAD_UPWARD_DYLIB")))
  1203. return;
  1204. Libraries.push_back(Load.Ptr);
  1205. } else if (Load.C.cmd == MachO::LC_ID_DYLINKER) {
  1206. if ((Err = checkDyldCommand(this, Load, I, "LC_ID_DYLINKER")))
  1207. return;
  1208. } else if (Load.C.cmd == MachO::LC_LOAD_DYLINKER) {
  1209. if ((Err = checkDyldCommand(this, Load, I, "LC_LOAD_DYLINKER")))
  1210. return;
  1211. } else if (Load.C.cmd == MachO::LC_DYLD_ENVIRONMENT) {
  1212. if ((Err = checkDyldCommand(this, Load, I, "LC_DYLD_ENVIRONMENT")))
  1213. return;
  1214. } else if (Load.C.cmd == MachO::LC_VERSION_MIN_MACOSX) {
  1215. if ((Err = checkVersCommand(this, Load, I, &VersLoadCmd,
  1216. "LC_VERSION_MIN_MACOSX")))
  1217. return;
  1218. } else if (Load.C.cmd == MachO::LC_VERSION_MIN_IPHONEOS) {
  1219. if ((Err = checkVersCommand(this, Load, I, &VersLoadCmd,
  1220. "LC_VERSION_MIN_IPHONEOS")))
  1221. return;
  1222. } else if (Load.C.cmd == MachO::LC_VERSION_MIN_TVOS) {
  1223. if ((Err = checkVersCommand(this, Load, I, &VersLoadCmd,
  1224. "LC_VERSION_MIN_TVOS")))
  1225. return;
  1226. } else if (Load.C.cmd == MachO::LC_VERSION_MIN_WATCHOS) {
  1227. if ((Err = checkVersCommand(this, Load, I, &VersLoadCmd,
  1228. "LC_VERSION_MIN_WATCHOS")))
  1229. return;
  1230. } else if (Load.C.cmd == MachO::LC_RPATH) {
  1231. if ((Err = checkRpathCommand(this, Load, I)))
  1232. return;
  1233. } else if (Load.C.cmd == MachO::LC_SOURCE_VERSION) {
  1234. if (Load.C.cmdsize != sizeof(MachO::source_version_command)) {
  1235. Err = malformedError("LC_SOURCE_VERSION command " + Twine(I) +
  1236. " has incorrect cmdsize");
  1237. return;
  1238. }
  1239. if (SourceLoadCmd) {
  1240. Err = malformedError("more than one LC_SOURCE_VERSION command");
  1241. return;
  1242. }
  1243. SourceLoadCmd = Load.Ptr;
  1244. } else if (Load.C.cmd == MachO::LC_MAIN) {
  1245. if (Load.C.cmdsize != sizeof(MachO::entry_point_command)) {
  1246. Err = malformedError("LC_MAIN command " + Twine(I) +
  1247. " has incorrect cmdsize");
  1248. return;
  1249. }
  1250. if (EntryPointLoadCmd) {
  1251. Err = malformedError("more than one LC_MAIN command");
  1252. return;
  1253. }
  1254. EntryPointLoadCmd = Load.Ptr;
  1255. } else if (Load.C.cmd == MachO::LC_ENCRYPTION_INFO) {
  1256. if (Load.C.cmdsize != sizeof(MachO::encryption_info_command)) {
  1257. Err = malformedError("LC_ENCRYPTION_INFO command " + Twine(I) +
  1258. " has incorrect cmdsize");
  1259. return;
  1260. }
  1261. MachO::encryption_info_command E =
  1262. getStruct<MachO::encryption_info_command>(this, Load.Ptr);
  1263. if ((Err = checkEncryptCommand(this, Load, I, E.cryptoff, E.cryptsize,
  1264. &EncryptLoadCmd, "LC_ENCRYPTION_INFO")))
  1265. return;
  1266. } else if (Load.C.cmd == MachO::LC_ENCRYPTION_INFO_64) {
  1267. if (Load.C.cmdsize != sizeof(MachO::encryption_info_command_64)) {
  1268. Err = malformedError("LC_ENCRYPTION_INFO_64 command " + Twine(I) +
  1269. " has incorrect cmdsize");
  1270. return;
  1271. }
  1272. MachO::encryption_info_command_64 E =
  1273. getStruct<MachO::encryption_info_command_64>(this, Load.Ptr);
  1274. if ((Err = checkEncryptCommand(this, Load, I, E.cryptoff, E.cryptsize,
  1275. &EncryptLoadCmd, "LC_ENCRYPTION_INFO_64")))
  1276. return;
  1277. } else if (Load.C.cmd == MachO::LC_LINKER_OPTION) {
  1278. if ((Err = checkLinkerOptCommand(this, Load, I)))
  1279. return;
  1280. } else if (Load.C.cmd == MachO::LC_SUB_FRAMEWORK) {
  1281. if (Load.C.cmdsize < sizeof(MachO::sub_framework_command)) {
  1282. Err = malformedError("load command " + Twine(I) +
  1283. " LC_SUB_FRAMEWORK cmdsize too small");
  1284. return;
  1285. }
  1286. MachO::sub_framework_command S =
  1287. getStruct<MachO::sub_framework_command>(this, Load.Ptr);
  1288. if ((Err = checkSubCommand(this, Load, I, "LC_SUB_FRAMEWORK",
  1289. sizeof(MachO::sub_framework_command),
  1290. "sub_framework_command", S.umbrella,
  1291. "umbrella")))
  1292. return;
  1293. } else if (Load.C.cmd == MachO::LC_SUB_UMBRELLA) {
  1294. if (Load.C.cmdsize < sizeof(MachO::sub_umbrella_command)) {
  1295. Err = malformedError("load command " + Twine(I) +
  1296. " LC_SUB_UMBRELLA cmdsize too small");
  1297. return;
  1298. }
  1299. MachO::sub_umbrella_command S =
  1300. getStruct<MachO::sub_umbrella_command>(this, Load.Ptr);
  1301. if ((Err = checkSubCommand(this, Load, I, "LC_SUB_UMBRELLA",
  1302. sizeof(MachO::sub_umbrella_command),
  1303. "sub_umbrella_command", S.sub_umbrella,
  1304. "sub_umbrella")))
  1305. return;
  1306. } else if (Load.C.cmd == MachO::LC_SUB_LIBRARY) {
  1307. if (Load.C.cmdsize < sizeof(MachO::sub_library_command)) {
  1308. Err = malformedError("load command " + Twine(I) +
  1309. " LC_SUB_LIBRARY cmdsize too small");
  1310. return;
  1311. }
  1312. MachO::sub_library_command S =
  1313. getStruct<MachO::sub_library_command>(this, Load.Ptr);
  1314. if ((Err = checkSubCommand(this, Load, I, "LC_SUB_LIBRARY",
  1315. sizeof(MachO::sub_library_command),
  1316. "sub_library_command", S.sub_library,
  1317. "sub_library")))
  1318. return;
  1319. } else if (Load.C.cmd == MachO::LC_SUB_CLIENT) {
  1320. if (Load.C.cmdsize < sizeof(MachO::sub_client_command)) {
  1321. Err = malformedError("load command " + Twine(I) +
  1322. " LC_SUB_CLIENT cmdsize too small");
  1323. return;
  1324. }
  1325. MachO::sub_client_command S =
  1326. getStruct<MachO::sub_client_command>(this, Load.Ptr);
  1327. if ((Err = checkSubCommand(this, Load, I, "LC_SUB_CLIENT",
  1328. sizeof(MachO::sub_client_command),
  1329. "sub_client_command", S.client, "client")))
  1330. return;
  1331. } else if (Load.C.cmd == MachO::LC_ROUTINES) {
  1332. if (Load.C.cmdsize != sizeof(MachO::routines_command)) {
  1333. Err = malformedError("LC_ROUTINES command " + Twine(I) +
  1334. " has incorrect cmdsize");
  1335. return;
  1336. }
  1337. if (RoutinesLoadCmd) {
  1338. Err = malformedError("more than one LC_ROUTINES and or LC_ROUTINES_64 "
  1339. "command");
  1340. return;
  1341. }
  1342. RoutinesLoadCmd = Load.Ptr;
  1343. } else if (Load.C.cmd == MachO::LC_ROUTINES_64) {
  1344. if (Load.C.cmdsize != sizeof(MachO::routines_command_64)) {
  1345. Err = malformedError("LC_ROUTINES_64 command " + Twine(I) +
  1346. " has incorrect cmdsize");
  1347. return;
  1348. }
  1349. if (RoutinesLoadCmd) {
  1350. Err = malformedError("more than one LC_ROUTINES_64 and or LC_ROUTINES "
  1351. "command");
  1352. return;
  1353. }
  1354. RoutinesLoadCmd = Load.Ptr;
  1355. } else if (Load.C.cmd == MachO::LC_UNIXTHREAD) {
  1356. if ((Err = checkThreadCommand(this, Load, I, "LC_UNIXTHREAD")))
  1357. return;
  1358. if (UnixThreadLoadCmd) {
  1359. Err = malformedError("more than one LC_UNIXTHREAD command");
  1360. return;
  1361. }
  1362. UnixThreadLoadCmd = Load.Ptr;
  1363. } else if (Load.C.cmd == MachO::LC_THREAD) {
  1364. if ((Err = checkThreadCommand(this, Load, I, "LC_THREAD")))
  1365. return;
  1366. // Note: LC_TWOLEVEL_HINTS is really obsolete and is not supported.
  1367. } else if (Load.C.cmd == MachO::LC_TWOLEVEL_HINTS) {
  1368. if ((Err = checkTwoLevelHintsCommand(this, Load, I,
  1369. &TwoLevelHintsLoadCmd, Elements)))
  1370. return;
  1371. } else if (isLoadCommandObsolete(Load.C.cmd)) {
  1372. Err = malformedError("load command " + Twine(I) + " for cmd value of: " +
  1373. Twine(Load.C.cmd) + " is obsolete and not "
  1374. "supported");
  1375. return;
  1376. }
  1377. // TODO: generate a error for unknown load commands by default. But still
  1378. // need work out an approach to allow or not allow unknown values like this
  1379. // as an option for some uses like lldb.
  1380. if (I < LoadCommandCount - 1) {
  1381. if (auto LoadOrErr = getNextLoadCommandInfo(this, I, Load))
  1382. Load = *LoadOrErr;
  1383. else {
  1384. Err = LoadOrErr.takeError();
  1385. return;
  1386. }
  1387. }
  1388. }
  1389. if (!SymtabLoadCmd) {
  1390. if (DysymtabLoadCmd) {
  1391. Err = malformedError("contains LC_DYSYMTAB load command without a "
  1392. "LC_SYMTAB load command");
  1393. return;
  1394. }
  1395. } else if (DysymtabLoadCmd) {
  1396. MachO::symtab_command Symtab =
  1397. getStruct<MachO::symtab_command>(this, SymtabLoadCmd);
  1398. MachO::dysymtab_command Dysymtab =
  1399. getStruct<MachO::dysymtab_command>(this, DysymtabLoadCmd);
  1400. if (Dysymtab.nlocalsym != 0 && Dysymtab.ilocalsym > Symtab.nsyms) {
  1401. Err = malformedError("ilocalsym in LC_DYSYMTAB load command "
  1402. "extends past the end of the symbol table");
  1403. return;
  1404. }
  1405. uint64_t BigSize = Dysymtab.ilocalsym;
  1406. BigSize += Dysymtab.nlocalsym;
  1407. if (Dysymtab.nlocalsym != 0 && BigSize > Symtab.nsyms) {
  1408. Err = malformedError("ilocalsym plus nlocalsym in LC_DYSYMTAB load "
  1409. "command extends past the end of the symbol table");
  1410. return;
  1411. }
  1412. if (Dysymtab.nextdefsym != 0 && Dysymtab.ilocalsym > Symtab.nsyms) {
  1413. Err = malformedError("nextdefsym in LC_DYSYMTAB load command "
  1414. "extends past the end of the symbol table");
  1415. return;
  1416. }
  1417. BigSize = Dysymtab.iextdefsym;
  1418. BigSize += Dysymtab.nextdefsym;
  1419. if (Dysymtab.nextdefsym != 0 && BigSize > Symtab.nsyms) {
  1420. Err = malformedError("iextdefsym plus nextdefsym in LC_DYSYMTAB "
  1421. "load command extends past the end of the symbol "
  1422. "table");
  1423. return;
  1424. }
  1425. if (Dysymtab.nundefsym != 0 && Dysymtab.iundefsym > Symtab.nsyms) {
  1426. Err = malformedError("nundefsym in LC_DYSYMTAB load command "
  1427. "extends past the end of the symbol table");
  1428. return;
  1429. }
  1430. BigSize = Dysymtab.iundefsym;
  1431. BigSize += Dysymtab.nundefsym;
  1432. if (Dysymtab.nundefsym != 0 && BigSize > Symtab.nsyms) {
  1433. Err = malformedError("iundefsym plus nundefsym in LC_DYSYMTAB load "
  1434. " command extends past the end of the symbol table");
  1435. return;
  1436. }
  1437. }
  1438. if ((getHeader().filetype == MachO::MH_DYLIB ||
  1439. getHeader().filetype == MachO::MH_DYLIB_STUB) &&
  1440. DyldIdLoadCmd == nullptr) {
  1441. Err = malformedError("no LC_ID_DYLIB load command in dynamic library "
  1442. "filetype");
  1443. return;
  1444. }
  1445. assert(LoadCommands.size() == LoadCommandCount);
  1446. Err = Error::success();
  1447. }
  1448. void MachOObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
  1449. unsigned SymbolTableEntrySize = is64Bit() ?
  1450. sizeof(MachO::nlist_64) :
  1451. sizeof(MachO::nlist);
  1452. Symb.p += SymbolTableEntrySize;
  1453. }
  1454. Expected<StringRef> MachOObjectFile::getSymbolName(DataRefImpl Symb) const {
  1455. StringRef StringTable = getStringTableData();
  1456. MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
  1457. const char *Start = &StringTable.data()[Entry.n_strx];
  1458. if (Start < getData().begin() || Start >= getData().end()) {
  1459. return malformedError("bad string index: " + Twine(Entry.n_strx) +
  1460. " for symbol at index " + Twine(getSymbolIndex(Symb)));
  1461. }
  1462. return StringRef(Start);
  1463. }
  1464. unsigned MachOObjectFile::getSectionType(SectionRef Sec) const {
  1465. DataRefImpl DRI = Sec.getRawDataRefImpl();
  1466. uint32_t Flags = getSectionFlags(this, DRI);
  1467. return Flags & MachO::SECTION_TYPE;
  1468. }
  1469. uint64_t MachOObjectFile::getNValue(DataRefImpl Sym) const {
  1470. if (is64Bit()) {
  1471. MachO::nlist_64 Entry = getSymbol64TableEntry(Sym);
  1472. return Entry.n_value;
  1473. }
  1474. MachO::nlist Entry = getSymbolTableEntry(Sym);
  1475. return Entry.n_value;
  1476. }
  1477. // getIndirectName() returns the name of the alias'ed symbol who's string table
  1478. // index is in the n_value field.
  1479. std::error_code MachOObjectFile::getIndirectName(DataRefImpl Symb,
  1480. StringRef &Res) const {
  1481. StringRef StringTable = getStringTableData();
  1482. MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
  1483. if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR)
  1484. return object_error::parse_failed;
  1485. uint64_t NValue = getNValue(Symb);
  1486. if (NValue >= StringTable.size())
  1487. return object_error::parse_failed;
  1488. const char *Start = &StringTable.data()[NValue];
  1489. Res = StringRef(Start);
  1490. return std::error_code();
  1491. }
  1492. uint64_t MachOObjectFile::getSymbolValueImpl(DataRefImpl Sym) const {
  1493. return getNValue(Sym);
  1494. }
  1495. Expected<uint64_t> MachOObjectFile::getSymbolAddress(DataRefImpl Sym) const {
  1496. return getSymbolValue(Sym);
  1497. }
  1498. uint32_t MachOObjectFile::getSymbolAlignment(DataRefImpl DRI) const {
  1499. uint32_t flags = getSymbolFlags(DRI);
  1500. if (flags & SymbolRef::SF_Common) {
  1501. MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
  1502. return 1 << MachO::GET_COMM_ALIGN(Entry.n_desc);
  1503. }
  1504. return 0;
  1505. }
  1506. uint64_t MachOObjectFile::getCommonSymbolSizeImpl(DataRefImpl DRI) const {
  1507. return getNValue(DRI);
  1508. }
  1509. Expected<SymbolRef::Type>
  1510. MachOObjectFile::getSymbolType(DataRefImpl Symb) const {
  1511. MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
  1512. uint8_t n_type = Entry.n_type;
  1513. // If this is a STAB debugging symbol, we can do nothing more.
  1514. if (n_type & MachO::N_STAB)
  1515. return SymbolRef::ST_Debug;
  1516. switch (n_type & MachO::N_TYPE) {
  1517. case MachO::N_UNDF :
  1518. return SymbolRef::ST_Unknown;
  1519. case MachO::N_SECT :
  1520. Expected<section_iterator> SecOrError = getSymbolSection(Symb);
  1521. if (!SecOrError)
  1522. return SecOrError.takeError();
  1523. section_iterator Sec = *SecOrError;
  1524. if (Sec->isData() || Sec->isBSS())
  1525. return SymbolRef::ST_Data;
  1526. return SymbolRef::ST_Function;
  1527. }
  1528. return SymbolRef::ST_Other;
  1529. }
  1530. uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const {
  1531. MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
  1532. uint8_t MachOType = Entry.n_type;
  1533. uint16_t MachOFlags = Entry.n_desc;
  1534. uint32_t Result = SymbolRef::SF_None;
  1535. if ((MachOType & MachO::N_TYPE) == MachO::N_INDR)
  1536. Result |= SymbolRef::SF_Indirect;
  1537. if (MachOType & MachO::N_STAB)
  1538. Result |= SymbolRef::SF_FormatSpecific;
  1539. if (MachOType & MachO::N_EXT) {
  1540. Result |= SymbolRef::SF_Global;
  1541. if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) {
  1542. if (getNValue(DRI))
  1543. Result |= SymbolRef::SF_Common;
  1544. else
  1545. Result |= SymbolRef::SF_Undefined;
  1546. }
  1547. if (!(MachOType & MachO::N_PEXT))
  1548. Result |= SymbolRef::SF_Exported;
  1549. }
  1550. if (MachOFlags & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF))
  1551. Result |= SymbolRef::SF_Weak;
  1552. if (MachOFlags & (MachO::N_ARM_THUMB_DEF))
  1553. Result |= SymbolRef::SF_Thumb;
  1554. if ((MachOType & MachO::N_TYPE) == MachO::N_ABS)
  1555. Result |= SymbolRef::SF_Absolute;
  1556. return Result;
  1557. }
  1558. Expected<section_iterator>
  1559. MachOObjectFile::getSymbolSection(DataRefImpl Symb) const {
  1560. MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
  1561. uint8_t index = Entry.n_sect;
  1562. if (index == 0)
  1563. return section_end();
  1564. DataRefImpl DRI;
  1565. DRI.d.a = index - 1;
  1566. if (DRI.d.a >= Sections.size()){
  1567. return malformedError("bad section index: " + Twine((int)index) +
  1568. " for symbol at index " + Twine(getSymbolIndex(Symb)));
  1569. }
  1570. return section_iterator(SectionRef(DRI, this));
  1571. }
  1572. unsigned MachOObjectFile::getSymbolSectionID(SymbolRef Sym) const {
  1573. MachO::nlist_base Entry =
  1574. getSymbolTableEntryBase(this, Sym.getRawDataRefImpl());
  1575. return Entry.n_sect - 1;
  1576. }
  1577. void MachOObjectFile::moveSectionNext(DataRefImpl &Sec) const {
  1578. Sec.d.a++;
  1579. }
  1580. std::error_code MachOObjectFile::getSectionName(DataRefImpl Sec,
  1581. StringRef &Result) const {
  1582. ArrayRef<char> Raw = getSectionRawName(Sec);
  1583. Result = parseSegmentOrSectionName(Raw.data());
  1584. return std::error_code();
  1585. }
  1586. uint64_t MachOObjectFile::getSectionAddress(DataRefImpl Sec) const {
  1587. if (is64Bit())
  1588. return getSection64(Sec).addr;
  1589. return getSection(Sec).addr;
  1590. }
  1591. uint64_t MachOObjectFile::getSectionSize(DataRefImpl Sec) const {
  1592. // In the case if a malformed Mach-O file where the section offset is past
  1593. // the end of the file or some part of the section size is past the end of
  1594. // the file return a size of zero or a size that covers the rest of the file
  1595. // but does not extend past the end of the file.
  1596. uint32_t SectOffset, SectType;
  1597. uint64_t SectSize;
  1598. if (is64Bit()) {
  1599. MachO::section_64 Sect = getSection64(Sec);
  1600. SectOffset = Sect.offset;
  1601. SectSize = Sect.size;
  1602. SectType = Sect.flags & MachO::SECTION_TYPE;
  1603. } else {
  1604. MachO::section Sect = getSection(Sec);
  1605. SectOffset = Sect.offset;
  1606. SectSize = Sect.size;
  1607. SectType = Sect.flags & MachO::SECTION_TYPE;
  1608. }
  1609. if (SectType == MachO::S_ZEROFILL || SectType == MachO::S_GB_ZEROFILL)
  1610. return SectSize;
  1611. uint64_t FileSize = getData().size();
  1612. if (SectOffset > FileSize)
  1613. return 0;
  1614. if (FileSize - SectOffset < SectSize)
  1615. return FileSize - SectOffset;
  1616. return SectSize;
  1617. }
  1618. std::error_code MachOObjectFile::getSectionContents(DataRefImpl Sec,
  1619. StringRef &Res) const {
  1620. uint32_t Offset;
  1621. uint64_t Size;
  1622. if (is64Bit()) {
  1623. MachO::section_64 Sect = getSection64(Sec);
  1624. Offset = Sect.offset;
  1625. Size = Sect.size;
  1626. } else {
  1627. MachO::section Sect = getSection(Sec);
  1628. Offset = Sect.offset;
  1629. Size = Sect.size;
  1630. }
  1631. Res = this->getData().substr(Offset, Size);
  1632. return std::error_code();
  1633. }
  1634. uint64_t MachOObjectFile::getSectionAlignment(DataRefImpl Sec) const {
  1635. uint32_t Align;
  1636. if (is64Bit()) {
  1637. MachO::section_64 Sect = getSection64(Sec);
  1638. Align = Sect.align;
  1639. } else {
  1640. MachO::section Sect = getSection(Sec);
  1641. Align = Sect.align;
  1642. }
  1643. return uint64_t(1) << Align;
  1644. }
  1645. bool MachOObjectFile::isSectionCompressed(DataRefImpl Sec) const {
  1646. return false;
  1647. }
  1648. bool MachOObjectFile::isSectionText(DataRefImpl Sec) const {
  1649. uint32_t Flags = getSectionFlags(this, Sec);
  1650. return Flags & MachO::S_ATTR_PURE_INSTRUCTIONS;
  1651. }
  1652. bool MachOObjectFile::isSectionData(DataRefImpl Sec) const {
  1653. uint32_t Flags = getSectionFlags(this, Sec);
  1654. unsigned SectionType = Flags & MachO::SECTION_TYPE;
  1655. return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
  1656. !(SectionType == MachO::S_ZEROFILL ||
  1657. SectionType == MachO::S_GB_ZEROFILL);
  1658. }
  1659. bool MachOObjectFile::isSectionBSS(DataRefImpl Sec) const {
  1660. uint32_t Flags = getSectionFlags(this, Sec);
  1661. unsigned SectionType = Flags & MachO::SECTION_TYPE;
  1662. return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
  1663. (SectionType == MachO::S_ZEROFILL ||
  1664. SectionType == MachO::S_GB_ZEROFILL);
  1665. }
  1666. unsigned MachOObjectFile::getSectionID(SectionRef Sec) const {
  1667. return Sec.getRawDataRefImpl().d.a;
  1668. }
  1669. bool MachOObjectFile::isSectionVirtual(DataRefImpl Sec) const {
  1670. // FIXME: Unimplemented.
  1671. return false;
  1672. }
  1673. bool MachOObjectFile::isSectionBitcode(DataRefImpl Sec) const {
  1674. StringRef SegmentName = getSectionFinalSegmentName(Sec);
  1675. StringRef SectName;
  1676. if (!getSectionName(Sec, SectName))
  1677. return (SegmentName == "__LLVM" && SectName == "__bitcode");
  1678. return false;
  1679. }
  1680. relocation_iterator MachOObjectFile::section_rel_begin(DataRefImpl Sec) const {
  1681. DataRefImpl Ret;
  1682. Ret.d.a = Sec.d.a;
  1683. Ret.d.b = 0;
  1684. return relocation_iterator(RelocationRef(Ret, this));
  1685. }
  1686. relocation_iterator
  1687. MachOObjectFile::section_rel_end(DataRefImpl Sec) const {
  1688. uint32_t Num;
  1689. if (is64Bit()) {
  1690. MachO::section_64 Sect = getSection64(Sec);
  1691. Num = Sect.nreloc;
  1692. } else {
  1693. MachO::section Sect = getSection(Sec);
  1694. Num = Sect.nreloc;
  1695. }
  1696. DataRefImpl Ret;
  1697. Ret.d.a = Sec.d.a;
  1698. Ret.d.b = Num;
  1699. return relocation_iterator(RelocationRef(Ret, this));
  1700. }
  1701. void MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
  1702. ++Rel.d.b;
  1703. }
  1704. uint64_t MachOObjectFile::getRelocationOffset(DataRefImpl Rel) const {
  1705. assert(getHeader().filetype == MachO::MH_OBJECT &&
  1706. "Only implemented for MH_OBJECT");
  1707. MachO::any_relocation_info RE = getRelocation(Rel);
  1708. return getAnyRelocationAddress(RE);
  1709. }
  1710. symbol_iterator
  1711. MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
  1712. MachO::any_relocation_info RE = getRelocation(Rel);
  1713. if (isRelocationScattered(RE))
  1714. return symbol_end();
  1715. uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE);
  1716. bool isExtern = getPlainRelocationExternal(RE);
  1717. if (!isExtern)
  1718. return symbol_end();
  1719. MachO::symtab_command S = getSymtabLoadCommand();
  1720. unsigned SymbolTableEntrySize = is64Bit() ?
  1721. sizeof(MachO::nlist_64) :
  1722. sizeof(MachO::nlist);
  1723. uint64_t Offset = S.symoff + SymbolIdx * SymbolTableEntrySize;
  1724. DataRefImpl Sym;
  1725. Sym.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
  1726. return symbol_iterator(SymbolRef(Sym, this));
  1727. }
  1728. section_iterator
  1729. MachOObjectFile::getRelocationSection(DataRefImpl Rel) const {
  1730. return section_iterator(getAnyRelocationSection(getRelocation(Rel)));
  1731. }
  1732. uint64_t MachOObjectFile::getRelocationType(DataRefImpl Rel) const {
  1733. MachO::any_relocation_info RE = getRelocation(Rel);
  1734. return getAnyRelocationType(RE);
  1735. }
  1736. void MachOObjectFile::getRelocationTypeName(
  1737. DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
  1738. StringRef res;
  1739. uint64_t RType = getRelocationType(Rel);
  1740. unsigned Arch = this->getArch();
  1741. switch (Arch) {
  1742. case Triple::x86: {
  1743. static const char *const Table[] = {
  1744. "GENERIC_RELOC_VANILLA",
  1745. "GENERIC_RELOC_PAIR",
  1746. "GENERIC_RELOC_SECTDIFF",
  1747. "GENERIC_RELOC_PB_LA_PTR",
  1748. "GENERIC_RELOC_LOCAL_SECTDIFF",
  1749. "GENERIC_RELOC_TLV" };
  1750. if (RType > 5)
  1751. res = "Unknown";
  1752. else
  1753. res = Table[RType];
  1754. break;
  1755. }
  1756. case Triple::x86_64: {
  1757. static const char *const Table[] = {
  1758. "X86_64_RELOC_UNSIGNED",
  1759. "X86_64_RELOC_SIGNED",
  1760. "X86_64_RELOC_BRANCH",
  1761. "X86_64_RELOC_GOT_LOAD",
  1762. "X86_64_RELOC_GOT",
  1763. "X86_64_RELOC_SUBTRACTOR",
  1764. "X86_64_RELOC_SIGNED_1",
  1765. "X86_64_RELOC_SIGNED_2",
  1766. "X86_64_RELOC_SIGNED_4",
  1767. "X86_64_RELOC_TLV" };
  1768. if (RType > 9)
  1769. res = "Unknown";
  1770. else
  1771. res = Table[RType];
  1772. break;
  1773. }
  1774. case Triple::arm: {
  1775. static const char *const Table[] = {
  1776. "ARM_RELOC_VANILLA",
  1777. "ARM_RELOC_PAIR",
  1778. "ARM_RELOC_SECTDIFF",
  1779. "ARM_RELOC_LOCAL_SECTDIFF",
  1780. "ARM_RELOC_PB_LA_PTR",
  1781. "ARM_RELOC_BR24",
  1782. "ARM_THUMB_RELOC_BR22",
  1783. "ARM_THUMB_32BIT_BRANCH",
  1784. "ARM_RELOC_HALF",
  1785. "ARM_RELOC_HALF_SECTDIFF" };
  1786. if (RType > 9)
  1787. res = "Unknown";
  1788. else
  1789. res = Table[RType];
  1790. break;
  1791. }
  1792. case Triple::aarch64: {
  1793. static const char *const Table[] = {
  1794. "ARM64_RELOC_UNSIGNED", "ARM64_RELOC_SUBTRACTOR",
  1795. "ARM64_RELOC_BRANCH26", "ARM64_RELOC_PAGE21",
  1796. "ARM64_RELOC_PAGEOFF12", "ARM64_RELOC_GOT_LOAD_PAGE21",
  1797. "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT",
  1798. "ARM64_RELOC_TLVP_LOAD_PAGE21", "ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
  1799. "ARM64_RELOC_ADDEND"
  1800. };
  1801. if (RType >= array_lengthof(Table))
  1802. res = "Unknown";
  1803. else
  1804. res = Table[RType];
  1805. break;
  1806. }
  1807. case Triple::ppc: {
  1808. static const char *const Table[] = {
  1809. "PPC_RELOC_VANILLA",
  1810. "PPC_RELOC_PAIR",
  1811. "PPC_RELOC_BR14",
  1812. "PPC_RELOC_BR24",
  1813. "PPC_RELOC_HI16",
  1814. "PPC_RELOC_LO16",
  1815. "PPC_RELOC_HA16",
  1816. "PPC_RELOC_LO14",
  1817. "PPC_RELOC_SECTDIFF",
  1818. "PPC_RELOC_PB_LA_PTR",
  1819. "PPC_RELOC_HI16_SECTDIFF",
  1820. "PPC_RELOC_LO16_SECTDIFF",
  1821. "PPC_RELOC_HA16_SECTDIFF",
  1822. "PPC_RELOC_JBSR",
  1823. "PPC_RELOC_LO14_SECTDIFF",
  1824. "PPC_RELOC_LOCAL_SECTDIFF" };
  1825. if (RType > 15)
  1826. res = "Unknown";
  1827. else
  1828. res = Table[RType];
  1829. break;
  1830. }
  1831. case Triple::UnknownArch:
  1832. res = "Unknown";
  1833. break;
  1834. }
  1835. Result.append(res.begin(), res.end());
  1836. }
  1837. uint8_t MachOObjectFile::getRelocationLength(DataRefImpl Rel) const {
  1838. MachO::any_relocation_info RE = getRelocation(Rel);
  1839. return getAnyRelocationLength(RE);
  1840. }
  1841. //
  1842. // guessLibraryShortName() is passed a name of a dynamic library and returns a
  1843. // guess on what the short name is. Then name is returned as a substring of the
  1844. // StringRef Name passed in. The name of the dynamic library is recognized as
  1845. // a framework if it has one of the two following forms:
  1846. // Foo.framework/Versions/A/Foo
  1847. // Foo.framework/Foo
  1848. // Where A and Foo can be any string. And may contain a trailing suffix
  1849. // starting with an underbar. If the Name is recognized as a framework then
  1850. // isFramework is set to true else it is set to false. If the Name has a
  1851. // suffix then Suffix is set to the substring in Name that contains the suffix
  1852. // else it is set to a NULL StringRef.
  1853. //
  1854. // The Name of the dynamic library is recognized as a library name if it has
  1855. // one of the two following forms:
  1856. // libFoo.A.dylib
  1857. // libFoo.dylib
  1858. // The library may have a suffix trailing the name Foo of the form:
  1859. // libFoo_profile.A.dylib
  1860. // libFoo_profile.dylib
  1861. //
  1862. // The Name of the dynamic library is also recognized as a library name if it
  1863. // has the following form:
  1864. // Foo.qtx
  1865. //
  1866. // If the Name of the dynamic library is none of the forms above then a NULL
  1867. // StringRef is returned.
  1868. //
  1869. StringRef MachOObjectFile::guessLibraryShortName(StringRef Name,
  1870. bool &isFramework,
  1871. StringRef &Suffix) {
  1872. StringRef Foo, F, DotFramework, V, Dylib, Lib, Dot, Qtx;
  1873. size_t a, b, c, d, Idx;
  1874. isFramework = false;
  1875. Suffix = StringRef();
  1876. // Pull off the last component and make Foo point to it
  1877. a = Name.rfind('/');
  1878. if (a == Name.npos || a == 0)
  1879. goto guess_library;
  1880. Foo = Name.slice(a+1, Name.npos);
  1881. // Look for a suffix starting with a '_'
  1882. Idx = Foo.rfind('_');
  1883. if (Idx != Foo.npos && Foo.size() >= 2) {
  1884. Suffix = Foo.slice(Idx, Foo.npos);
  1885. Foo = Foo.slice(0, Idx);
  1886. }
  1887. // First look for the form Foo.framework/Foo
  1888. b = Name.rfind('/', a);
  1889. if (b == Name.npos)
  1890. Idx = 0;
  1891. else
  1892. Idx = b+1;
  1893. F = Name.slice(Idx, Idx + Foo.size());
  1894. DotFramework = Name.slice(Idx + Foo.size(),
  1895. Idx + Foo.size() + sizeof(".framework/")-1);
  1896. if (F == Foo && DotFramework == ".framework/") {
  1897. isFramework = true;
  1898. return Foo;
  1899. }
  1900. // Next look for the form Foo.framework/Versions/A/Foo
  1901. if (b == Name.npos)
  1902. goto guess_library;
  1903. c = Name.rfind('/', b);
  1904. if (c == Name.npos || c == 0)
  1905. goto guess_library;
  1906. V = Name.slice(c+1, Name.npos);
  1907. if (!V.startswith("Versions/"))
  1908. goto guess_library;
  1909. d = Name.rfind('/', c);
  1910. if (d == Name.npos)
  1911. Idx = 0;
  1912. else
  1913. Idx = d+1;
  1914. F = Name.slice(Idx, Idx + Foo.size());
  1915. DotFramework = Name.slice(Idx + Foo.size(),
  1916. Idx + Foo.size() + sizeof(".framework/")-1);
  1917. if (F == Foo && DotFramework == ".framework/") {
  1918. isFramework = true;
  1919. return Foo;
  1920. }
  1921. guess_library:
  1922. // pull off the suffix after the "." and make a point to it
  1923. a = Name.rfind('.');
  1924. if (a == Name.npos || a == 0)
  1925. return StringRef();
  1926. Dylib = Name.slice(a, Name.npos);
  1927. if (Dylib != ".dylib")
  1928. goto guess_qtx;
  1929. // First pull off the version letter for the form Foo.A.dylib if any.
  1930. if (a >= 3) {
  1931. Dot = Name.slice(a-2, a-1);
  1932. if (Dot == ".")
  1933. a = a - 2;
  1934. }
  1935. b = Name.rfind('/', a);
  1936. if (b == Name.npos)
  1937. b = 0;
  1938. else
  1939. b = b+1;
  1940. // ignore any suffix after an underbar like Foo_profile.A.dylib
  1941. Idx = Name.find('_', b);
  1942. if (Idx != Name.npos && Idx != b) {
  1943. Lib = Name.slice(b, Idx);
  1944. Suffix = Name.slice(Idx, a);
  1945. }
  1946. else
  1947. Lib = Name.slice(b, a);
  1948. // There are incorrect library names of the form:
  1949. // libATS.A_profile.dylib so check for these.
  1950. if (Lib.size() >= 3) {
  1951. Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
  1952. if (Dot == ".")
  1953. Lib = Lib.slice(0, Lib.size()-2);
  1954. }
  1955. return Lib;
  1956. guess_qtx:
  1957. Qtx = Name.slice(a, Name.npos);
  1958. if (Qtx != ".qtx")
  1959. return StringRef();
  1960. b = Name.rfind('/', a);
  1961. if (b == Name.npos)
  1962. Lib = Name.slice(0, a);
  1963. else
  1964. Lib = Name.slice(b+1, a);
  1965. // There are library names of the form: QT.A.qtx so check for these.
  1966. if (Lib.size() >= 3) {
  1967. Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
  1968. if (Dot == ".")
  1969. Lib = Lib.slice(0, Lib.size()-2);
  1970. }
  1971. return Lib;
  1972. }
  1973. // getLibraryShortNameByIndex() is used to get the short name of the library
  1974. // for an undefined symbol in a linked Mach-O binary that was linked with the
  1975. // normal two-level namespace default (that is MH_TWOLEVEL in the header).
  1976. // It is passed the index (0 - based) of the library as translated from
  1977. // GET_LIBRARY_ORDINAL (1 - based).
  1978. std::error_code MachOObjectFile::getLibraryShortNameByIndex(unsigned Index,
  1979. StringRef &Res) const {
  1980. if (Index >= Libraries.size())
  1981. return object_error::parse_failed;
  1982. // If the cache of LibrariesShortNames is not built up do that first for
  1983. // all the Libraries.
  1984. if (LibrariesShortNames.size() == 0) {
  1985. for (unsigned i = 0; i < Libraries.size(); i++) {
  1986. MachO::dylib_command D =
  1987. getStruct<MachO::dylib_command>(this, Libraries[i]);
  1988. if (D.dylib.name >= D.cmdsize)
  1989. return object_error::parse_failed;
  1990. const char *P = (const char *)(Libraries[i]) + D.dylib.name;
  1991. StringRef Name = StringRef(P);
  1992. if (D.dylib.name+Name.size() >= D.cmdsize)
  1993. return object_error::parse_failed;
  1994. StringRef Suffix;
  1995. bool isFramework;
  1996. StringRef shortName = guessLibraryShortName(Name, isFramework, Suffix);
  1997. if (shortName.empty())
  1998. LibrariesShortNames.push_back(Name);
  1999. else
  2000. LibrariesShortNames.push_back(shortName);
  2001. }
  2002. }
  2003. Res = LibrariesShortNames[Index];
  2004. return std::error_code();
  2005. }
  2006. section_iterator
  2007. MachOObjectFile::getRelocationRelocatedSection(relocation_iterator Rel) const {
  2008. DataRefImpl Sec;
  2009. Sec.d.a = Rel->getRawDataRefImpl().d.a;
  2010. return section_iterator(SectionRef(Sec, this));
  2011. }
  2012. basic_symbol_iterator MachOObjectFile::symbol_begin_impl() const {
  2013. DataRefImpl DRI;
  2014. MachO::symtab_command Symtab = getSymtabLoadCommand();
  2015. if (!SymtabLoadCmd || Symtab.nsyms == 0)
  2016. return basic_symbol_iterator(SymbolRef(DRI, this));
  2017. return getSymbolByIndex(0);
  2018. }
  2019. basic_symbol_iterator MachOObjectFile::symbol_end_impl() const {
  2020. DataRefImpl DRI;
  2021. MachO::symtab_command Symtab = getSymtabLoadCommand();
  2022. if (!SymtabLoadCmd || Symtab.nsyms == 0)
  2023. return basic_symbol_iterator(SymbolRef(DRI, this));
  2024. unsigned SymbolTableEntrySize = is64Bit() ?
  2025. sizeof(MachO::nlist_64) :
  2026. sizeof(MachO::nlist);
  2027. unsigned Offset = Symtab.symoff +
  2028. Symtab.nsyms * SymbolTableEntrySize;
  2029. DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
  2030. return basic_symbol_iterator(SymbolRef(DRI, this));
  2031. }
  2032. basic_symbol_iterator MachOObjectFile::getSymbolByIndex(unsigned Index) const {
  2033. MachO::symtab_command Symtab = getSymtabLoadCommand();
  2034. if (!SymtabLoadCmd || Index >= Symtab.nsyms)
  2035. report_fatal_error("Requested symbol index is out of range.");
  2036. unsigned SymbolTableEntrySize =
  2037. is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
  2038. DataRefImpl DRI;
  2039. DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff));
  2040. DRI.p += Index * SymbolTableEntrySize;
  2041. return basic_symbol_iterator(SymbolRef(DRI, this));
  2042. }
  2043. uint64_t MachOObjectFile::getSymbolIndex(DataRefImpl Symb) const {
  2044. MachO::symtab_command Symtab = getSymtabLoadCommand();
  2045. if (!SymtabLoadCmd)
  2046. report_fatal_error("getSymbolIndex() called with no symbol table symbol");
  2047. unsigned SymbolTableEntrySize =
  2048. is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
  2049. DataRefImpl DRIstart;
  2050. DRIstart.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff));
  2051. uint64_t Index = (Symb.p - DRIstart.p) / SymbolTableEntrySize;
  2052. return Index;
  2053. }
  2054. section_iterator MachOObjectFile::section_begin() const {
  2055. DataRefImpl DRI;
  2056. return section_iterator(SectionRef(DRI, this));
  2057. }
  2058. section_iterator MachOObjectFile::section_end() const {
  2059. DataRefImpl DRI;
  2060. DRI.d.a = Sections.size();
  2061. return section_iterator(SectionRef(DRI, this));
  2062. }
  2063. uint8_t MachOObjectFile::getBytesInAddress() const {
  2064. return is64Bit() ? 8 : 4;
  2065. }
  2066. StringRef MachOObjectFile::getFileFormatName() const {
  2067. unsigned CPUType = getCPUType(this);
  2068. if (!is64Bit()) {
  2069. switch (CPUType) {
  2070. case llvm::MachO::CPU_TYPE_I386:
  2071. return "Mach-O 32-bit i386";
  2072. case llvm::MachO::CPU_TYPE_ARM:
  2073. return "Mach-O arm";
  2074. case llvm::MachO::CPU_TYPE_POWERPC:
  2075. return "Mach-O 32-bit ppc";
  2076. default:
  2077. return "Mach-O 32-bit unknown";
  2078. }
  2079. }
  2080. switch (CPUType) {
  2081. case llvm::MachO::CPU_TYPE_X86_64:
  2082. return "Mach-O 64-bit x86-64";
  2083. case llvm::MachO::CPU_TYPE_ARM64:
  2084. return "Mach-O arm64";
  2085. case llvm::MachO::CPU_TYPE_POWERPC64:
  2086. return "Mach-O 64-bit ppc64";
  2087. default:
  2088. return "Mach-O 64-bit unknown";
  2089. }
  2090. }
  2091. Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) {
  2092. switch (CPUType) {
  2093. case llvm::MachO::CPU_TYPE_I386:
  2094. return Triple::x86;
  2095. case llvm::MachO::CPU_TYPE_X86_64:
  2096. return Triple::x86_64;
  2097. case llvm::MachO::CPU_TYPE_ARM:
  2098. return Triple::arm;
  2099. case llvm::MachO::CPU_TYPE_ARM64:
  2100. return Triple::aarch64;
  2101. case llvm::MachO::CPU_TYPE_POWERPC:
  2102. return Triple::ppc;
  2103. case llvm::MachO::CPU_TYPE_POWERPC64:
  2104. return Triple::ppc64;
  2105. default:
  2106. return Triple::UnknownArch;
  2107. }
  2108. }
  2109. Triple MachOObjectFile::getArchTriple(uint32_t CPUType, uint32_t CPUSubType,
  2110. const char **McpuDefault) {
  2111. if (McpuDefault)
  2112. *McpuDefault = nullptr;
  2113. switch (CPUType) {
  2114. case MachO::CPU_TYPE_I386:
  2115. switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
  2116. case MachO::CPU_SUBTYPE_I386_ALL:
  2117. return Triple("i386-apple-darwin");
  2118. default:
  2119. return Triple();
  2120. }
  2121. case MachO::CPU_TYPE_X86_64:
  2122. switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
  2123. case MachO::CPU_SUBTYPE_X86_64_ALL:
  2124. return Triple("x86_64-apple-darwin");
  2125. case MachO::CPU_SUBTYPE_X86_64_H:
  2126. return Triple("x86_64h-apple-darwin");
  2127. default:
  2128. return Triple();
  2129. }
  2130. case MachO::CPU_TYPE_ARM:
  2131. switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
  2132. case MachO::CPU_SUBTYPE_ARM_V4T:
  2133. return Triple("armv4t-apple-darwin");
  2134. case MachO::CPU_SUBTYPE_ARM_V5TEJ:
  2135. return Triple("armv5e-apple-darwin");
  2136. case MachO::CPU_SUBTYPE_ARM_XSCALE:
  2137. return Triple("xscale-apple-darwin");
  2138. case MachO::CPU_SUBTYPE_ARM_V6:
  2139. return Triple("armv6-apple-darwin");
  2140. case MachO::CPU_SUBTYPE_ARM_V6M:
  2141. if (McpuDefault)
  2142. *McpuDefault = "cortex-m0";
  2143. return Triple("armv6m-apple-darwin");
  2144. case MachO::CPU_SUBTYPE_ARM_V7:
  2145. return Triple("armv7-apple-darwin");
  2146. case MachO::CPU_SUBTYPE_ARM_V7EM:
  2147. if (McpuDefault)
  2148. *McpuDefault = "cortex-m4";
  2149. return Triple("thumbv7em-apple-darwin");
  2150. case MachO::CPU_SUBTYPE_ARM_V7K:
  2151. return Triple("armv7k-apple-darwin");
  2152. case MachO::CPU_SUBTYPE_ARM_V7M:
  2153. if (McpuDefault)
  2154. *McpuDefault = "cortex-m3";
  2155. return Triple("thumbv7m-apple-darwin");
  2156. case MachO::CPU_SUBTYPE_ARM_V7S:
  2157. return Triple("armv7s-apple-darwin");
  2158. default:
  2159. return Triple();
  2160. }
  2161. case MachO::CPU_TYPE_ARM64:
  2162. switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
  2163. case MachO::CPU_SUBTYPE_ARM64_ALL:
  2164. return Triple("arm64-apple-darwin");
  2165. default:
  2166. return Triple();
  2167. }
  2168. case MachO::CPU_TYPE_POWERPC:
  2169. switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
  2170. case MachO::CPU_SUBTYPE_POWERPC_ALL:
  2171. return Triple("ppc-apple-darwin");
  2172. default:
  2173. return Triple();
  2174. }
  2175. case MachO::CPU_TYPE_POWERPC64:
  2176. switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
  2177. case MachO::CPU_SUBTYPE_POWERPC_ALL:
  2178. return Triple("ppc64-apple-darwin");
  2179. default:
  2180. return Triple();
  2181. }
  2182. default:
  2183. return Triple();
  2184. }
  2185. }
  2186. Triple MachOObjectFile::getHostArch() {
  2187. return Triple(sys::getDefaultTargetTriple());
  2188. }
  2189. bool MachOObjectFile::isValidArch(StringRef ArchFlag) {
  2190. return StringSwitch<bool>(ArchFlag)
  2191. .Case("i386", true)
  2192. .Case("x86_64", true)
  2193. .Case("x86_64h", true)
  2194. .Case("armv4t", true)
  2195. .Case("arm", true)
  2196. .Case("armv5e", true)
  2197. .Case("armv6", true)
  2198. .Case("armv6m", true)
  2199. .Case("armv7", true)
  2200. .Case("armv7em", true)
  2201. .Case("armv7k", true)
  2202. .Case("armv7m", true)
  2203. .Case("armv7s", true)
  2204. .Case("arm64", true)
  2205. .Case("ppc", true)
  2206. .Case("ppc64", true)
  2207. .Default(false);
  2208. }
  2209. unsigned MachOObjectFile::getArch() const {
  2210. return getArch(getCPUType(this));
  2211. }
  2212. Triple MachOObjectFile::getArchTriple(const char **McpuDefault) const {
  2213. return getArchTriple(Header.cputype, Header.cpusubtype, McpuDefault);
  2214. }
  2215. relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const {
  2216. DataRefImpl DRI;
  2217. DRI.d.a = Index;
  2218. return section_rel_begin(DRI);
  2219. }
  2220. relocation_iterator MachOObjectFile::section_rel_end(unsigned Index) const {
  2221. DataRefImpl DRI;
  2222. DRI.d.a = Index;
  2223. return section_rel_end(DRI);
  2224. }
  2225. dice_iterator MachOObjectFile::begin_dices() const {
  2226. DataRefImpl DRI;
  2227. if (!DataInCodeLoadCmd)
  2228. return dice_iterator(DiceRef(DRI, this));
  2229. MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
  2230. DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, DicLC.dataoff));
  2231. return dice_iterator(DiceRef(DRI, this));
  2232. }
  2233. dice_iterator MachOObjectFile::end_dices() const {
  2234. DataRefImpl DRI;
  2235. if (!DataInCodeLoadCmd)
  2236. return dice_iterator(DiceRef(DRI, this));
  2237. MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
  2238. unsigned Offset = DicLC.dataoff + DicLC.datasize;
  2239. DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
  2240. return dice_iterator(DiceRef(DRI, this));
  2241. }
  2242. ExportEntry::ExportEntry(ArrayRef<uint8_t> T)
  2243. : Trie(T), Malformed(false), Done(false) {}
  2244. void ExportEntry::moveToFirst() {
  2245. pushNode(0);
  2246. pushDownUntilBottom();
  2247. }
  2248. void ExportEntry::moveToEnd() {
  2249. Stack.clear();
  2250. Done = true;
  2251. }
  2252. bool ExportEntry::operator==(const ExportEntry &Other) const {
  2253. // Common case, one at end, other iterating from begin.
  2254. if (Done || Other.Done)
  2255. return (Done == Other.Done);
  2256. // Not equal if different stack sizes.
  2257. if (Stack.size() != Other.Stack.size())
  2258. return false;
  2259. // Not equal if different cumulative strings.
  2260. if (!CumulativeString.equals(Other.CumulativeString))
  2261. return false;
  2262. // Equal if all nodes in both stacks match.
  2263. for (unsigned i=0; i < Stack.size(); ++i) {
  2264. if (Stack[i].Start != Other.Stack[i].Start)
  2265. return false;
  2266. }
  2267. return true;
  2268. }
  2269. uint64_t ExportEntry::readULEB128(const uint8_t *&Ptr) {
  2270. unsigned Count;
  2271. uint64_t Result = decodeULEB128(Ptr, &Count);
  2272. Ptr += Count;
  2273. if (Ptr > Trie.end()) {
  2274. Ptr = Trie.end();
  2275. Malformed = true;
  2276. }
  2277. return Result;
  2278. }
  2279. StringRef ExportEntry::name() const {
  2280. return CumulativeString;
  2281. }
  2282. uint64_t ExportEntry::flags() const {
  2283. return Stack.back().Flags;
  2284. }
  2285. uint64_t ExportEntry::address() const {
  2286. return Stack.back().Address;
  2287. }
  2288. uint64_t ExportEntry::other() const {
  2289. return Stack.back().Other;
  2290. }
  2291. StringRef ExportEntry::otherName() const {
  2292. const char* ImportName = Stack.back().ImportName;
  2293. if (ImportName)
  2294. return StringRef(ImportName);
  2295. return StringRef();
  2296. }
  2297. uint32_t ExportEntry::nodeOffset() const {
  2298. return Stack.back().Start - Trie.begin();
  2299. }
  2300. ExportEntry::NodeState::NodeState(const uint8_t *Ptr)
  2301. : Start(Ptr), Current(Ptr), Flags(0), Address(0), Other(0),
  2302. ImportName(nullptr), ChildCount(0), NextChildIndex(0),
  2303. ParentStringLength(0), IsExportNode(false) {}
  2304. void ExportEntry::pushNode(uint64_t offset) {
  2305. const uint8_t *Ptr = Trie.begin() + offset;
  2306. NodeState State(Ptr);
  2307. uint64_t ExportInfoSize = readULEB128(State.Current);
  2308. State.IsExportNode = (ExportInfoSize != 0);
  2309. const uint8_t* Children = State.Current + ExportInfoSize;
  2310. if (State.IsExportNode) {
  2311. State.Flags = readULEB128(State.Current);
  2312. if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT) {
  2313. State.Address = 0;
  2314. State.Other = readULEB128(State.Current); // dylib ordinal
  2315. State.ImportName = reinterpret_cast<const char*>(State.Current);
  2316. } else {
  2317. State.Address = readULEB128(State.Current);
  2318. if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER)
  2319. State.Other = readULEB128(State.Current);
  2320. }
  2321. }
  2322. State.ChildCount = *Children;
  2323. State.Current = Children + 1;
  2324. State.NextChildIndex = 0;
  2325. State.ParentStringLength = CumulativeString.size();
  2326. Stack.push_back(State);
  2327. }
  2328. void ExportEntry::pushDownUntilBottom() {
  2329. while (Stack.back().NextChildIndex < Stack.back().ChildCount) {
  2330. NodeState &Top = Stack.back();
  2331. CumulativeString.resize(Top.ParentStringLength);
  2332. for (;*Top.Current != 0; Top.Current++) {
  2333. char C = *Top.Current;
  2334. CumulativeString.push_back(C);
  2335. }
  2336. Top.Current += 1;
  2337. uint64_t childNodeIndex = readULEB128(Top.Current);
  2338. Top.NextChildIndex += 1;
  2339. pushNode(childNodeIndex);
  2340. }
  2341. if (!Stack.back().IsExportNode) {
  2342. Malformed = true;
  2343. moveToEnd();
  2344. }
  2345. }
  2346. // We have a trie data structure and need a way to walk it that is compatible
  2347. // with the C++ iterator model. The solution is a non-recursive depth first
  2348. // traversal where the iterator contains a stack of parent nodes along with a
  2349. // string that is the accumulation of all edge strings along the parent chain
  2350. // to this point.
  2351. //
  2352. // There is one "export" node for each exported symbol. But because some
  2353. // symbols may be a prefix of another symbol (e.g. _dup and _dup2), an export
  2354. // node may have child nodes too.
  2355. //
  2356. // The algorithm for moveNext() is to keep moving down the leftmost unvisited
  2357. // child until hitting a node with no children (which is an export node or
  2358. // else the trie is malformed). On the way down, each node is pushed on the
  2359. // stack ivar. If there is no more ways down, it pops up one and tries to go
  2360. // down a sibling path until a childless node is reached.
  2361. void ExportEntry::moveNext() {
  2362. if (Stack.empty() || !Stack.back().IsExportNode) {
  2363. Malformed = true;
  2364. moveToEnd();
  2365. return;
  2366. }
  2367. Stack.pop_back();
  2368. while (!Stack.empty()) {
  2369. NodeState &Top = Stack.back();
  2370. if (Top.NextChildIndex < Top.ChildCount) {
  2371. pushDownUntilBottom();
  2372. // Now at the next export node.
  2373. return;
  2374. } else {
  2375. if (Top.IsExportNode) {
  2376. // This node has no children but is itself an export node.
  2377. CumulativeString.resize(Top.ParentStringLength);
  2378. return;
  2379. }
  2380. Stack.pop_back();
  2381. }
  2382. }
  2383. Done = true;
  2384. }
  2385. iterator_range<export_iterator>
  2386. MachOObjectFile::exports(ArrayRef<uint8_t> Trie) {
  2387. ExportEntry Start(Trie);
  2388. if (Trie.size() == 0)
  2389. Start.moveToEnd();
  2390. else
  2391. Start.moveToFirst();
  2392. ExportEntry Finish(Trie);
  2393. Finish.moveToEnd();
  2394. return make_range(export_iterator(Start), export_iterator(Finish));
  2395. }
  2396. iterator_range<export_iterator> MachOObjectFile::exports() const {
  2397. return exports(getDyldInfoExportsTrie());
  2398. }
  2399. MachORebaseEntry::MachORebaseEntry(ArrayRef<uint8_t> Bytes, bool is64Bit)
  2400. : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0),
  2401. RemainingLoopCount(0), AdvanceAmount(0), RebaseType(0),
  2402. PointerSize(is64Bit ? 8 : 4), Malformed(false), Done(false) {}
  2403. void MachORebaseEntry::moveToFirst() {
  2404. Ptr = Opcodes.begin();
  2405. moveNext();
  2406. }
  2407. void MachORebaseEntry::moveToEnd() {
  2408. Ptr = Opcodes.end();
  2409. RemainingLoopCount = 0;
  2410. Done = true;
  2411. }
  2412. void MachORebaseEntry::moveNext() {
  2413. // If in the middle of some loop, move to next rebasing in loop.
  2414. SegmentOffset += AdvanceAmount;
  2415. if (RemainingLoopCount) {
  2416. --RemainingLoopCount;
  2417. return;
  2418. }
  2419. if (Ptr == Opcodes.end()) {
  2420. Done = true;
  2421. return;
  2422. }
  2423. bool More = true;
  2424. while (More && !Malformed) {
  2425. // Parse next opcode and set up next loop.
  2426. uint8_t Byte = *Ptr++;
  2427. uint8_t ImmValue = Byte & MachO::REBASE_IMMEDIATE_MASK;
  2428. uint8_t Opcode = Byte & MachO::REBASE_OPCODE_MASK;
  2429. switch (Opcode) {
  2430. case MachO::REBASE_OPCODE_DONE:
  2431. More = false;
  2432. Done = true;
  2433. moveToEnd();
  2434. DEBUG_WITH_TYPE("mach-o-rebase", llvm::dbgs() << "REBASE_OPCODE_DONE\n");
  2435. break;
  2436. case MachO::REBASE_OPCODE_SET_TYPE_IMM:
  2437. RebaseType = ImmValue;
  2438. DEBUG_WITH_TYPE(
  2439. "mach-o-rebase",
  2440. llvm::dbgs() << "REBASE_OPCODE_SET_TYPE_IMM: "
  2441. << "RebaseType=" << (int) RebaseType << "\n");
  2442. break;
  2443. case MachO::REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
  2444. SegmentIndex = ImmValue;
  2445. SegmentOffset = readULEB128();
  2446. DEBUG_WITH_TYPE(
  2447. "mach-o-rebase",
  2448. llvm::dbgs() << "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
  2449. << "SegmentIndex=" << SegmentIndex << ", "
  2450. << format("SegmentOffset=0x%06X", SegmentOffset)
  2451. << "\n");
  2452. break;
  2453. case MachO::REBASE_OPCODE_ADD_ADDR_ULEB:
  2454. SegmentOffset += readULEB128();
  2455. DEBUG_WITH_TYPE("mach-o-rebase",
  2456. llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_ULEB: "
  2457. << format("SegmentOffset=0x%06X",
  2458. SegmentOffset) << "\n");
  2459. break;
  2460. case MachO::REBASE_OPCODE_ADD_ADDR_IMM_SCALED:
  2461. SegmentOffset += ImmValue * PointerSize;
  2462. DEBUG_WITH_TYPE("mach-o-rebase",
  2463. llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_IMM_SCALED: "
  2464. << format("SegmentOffset=0x%06X",
  2465. SegmentOffset) << "\n");
  2466. break;
  2467. case MachO::REBASE_OPCODE_DO_REBASE_IMM_TIMES:
  2468. AdvanceAmount = PointerSize;
  2469. RemainingLoopCount = ImmValue - 1;
  2470. DEBUG_WITH_TYPE(
  2471. "mach-o-rebase",
  2472. llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: "
  2473. << format("SegmentOffset=0x%06X", SegmentOffset)
  2474. << ", AdvanceAmount=" << AdvanceAmount
  2475. << ", RemainingLoopCount=" << RemainingLoopCount
  2476. << "\n");
  2477. return;
  2478. case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES:
  2479. AdvanceAmount = PointerSize;
  2480. RemainingLoopCount = readULEB128() - 1;
  2481. DEBUG_WITH_TYPE(
  2482. "mach-o-rebase",
  2483. llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: "
  2484. << format("SegmentOffset=0x%06X", SegmentOffset)
  2485. << ", AdvanceAmount=" << AdvanceAmount
  2486. << ", RemainingLoopCount=" << RemainingLoopCount
  2487. << "\n");
  2488. return;
  2489. case MachO::REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB:
  2490. AdvanceAmount = readULEB128() + PointerSize;
  2491. RemainingLoopCount = 0;
  2492. DEBUG_WITH_TYPE(
  2493. "mach-o-rebase",
  2494. llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: "
  2495. << format("SegmentOffset=0x%06X", SegmentOffset)
  2496. << ", AdvanceAmount=" << AdvanceAmount
  2497. << ", RemainingLoopCount=" << RemainingLoopCount
  2498. << "\n");
  2499. return;
  2500. case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB:
  2501. RemainingLoopCount = readULEB128() - 1;
  2502. AdvanceAmount = readULEB128() + PointerSize;
  2503. DEBUG_WITH_TYPE(
  2504. "mach-o-rebase",
  2505. llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: "
  2506. << format("SegmentOffset=0x%06X", SegmentOffset)
  2507. << ", AdvanceAmount=" << AdvanceAmount
  2508. << ", RemainingLoopCount=" << RemainingLoopCount
  2509. << "\n");
  2510. return;
  2511. default:
  2512. Malformed = true;
  2513. }
  2514. }
  2515. }
  2516. uint64_t MachORebaseEntry::readULEB128() {
  2517. unsigned Count;
  2518. uint64_t Result = decodeULEB128(Ptr, &Count);
  2519. Ptr += Count;
  2520. if (Ptr > Opcodes.end()) {
  2521. Ptr = Opcodes.end();
  2522. Malformed = true;
  2523. }
  2524. return Result;
  2525. }
  2526. uint32_t MachORebaseEntry::segmentIndex() const { return SegmentIndex; }
  2527. uint64_t MachORebaseEntry::segmentOffset() const { return SegmentOffset; }
  2528. StringRef MachORebaseEntry::typeName() const {
  2529. switch (RebaseType) {
  2530. case MachO::REBASE_TYPE_POINTER:
  2531. return "pointer";
  2532. case MachO::REBASE_TYPE_TEXT_ABSOLUTE32:
  2533. return "text abs32";
  2534. case MachO::REBASE_TYPE_TEXT_PCREL32:
  2535. return "text rel32";
  2536. }
  2537. return "unknown";
  2538. }
  2539. bool MachORebaseEntry::operator==(const MachORebaseEntry &Other) const {
  2540. assert(Opcodes == Other.Opcodes && "compare iterators of different files");
  2541. return (Ptr == Other.Ptr) &&
  2542. (RemainingLoopCount == Other.RemainingLoopCount) &&
  2543. (Done == Other.Done);
  2544. }
  2545. iterator_range<rebase_iterator>
  2546. MachOObjectFile::rebaseTable(ArrayRef<uint8_t> Opcodes, bool is64) {
  2547. MachORebaseEntry Start(Opcodes, is64);
  2548. Start.moveToFirst();
  2549. MachORebaseEntry Finish(Opcodes, is64);
  2550. Finish.moveToEnd();
  2551. return make_range(rebase_iterator(Start), rebase_iterator(Finish));
  2552. }
  2553. iterator_range<rebase_iterator> MachOObjectFile::rebaseTable() const {
  2554. return rebaseTable(getDyldInfoRebaseOpcodes(), is64Bit());
  2555. }
  2556. MachOBindEntry::MachOBindEntry(ArrayRef<uint8_t> Bytes, bool is64Bit, Kind BK)
  2557. : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0),
  2558. Ordinal(0), Flags(0), Addend(0), RemainingLoopCount(0), AdvanceAmount(0),
  2559. BindType(0), PointerSize(is64Bit ? 8 : 4),
  2560. TableKind(BK), Malformed(false), Done(false) {}
  2561. void MachOBindEntry::moveToFirst() {
  2562. Ptr = Opcodes.begin();
  2563. moveNext();
  2564. }
  2565. void MachOBindEntry::moveToEnd() {
  2566. Ptr = Opcodes.end();
  2567. RemainingLoopCount = 0;
  2568. Done = true;
  2569. }
  2570. void MachOBindEntry::moveNext() {
  2571. // If in the middle of some loop, move to next binding in loop.
  2572. SegmentOffset += AdvanceAmount;
  2573. if (RemainingLoopCount) {
  2574. --RemainingLoopCount;
  2575. return;
  2576. }
  2577. if (Ptr == Opcodes.end()) {
  2578. Done = true;
  2579. return;
  2580. }
  2581. bool More = true;
  2582. while (More && !Malformed) {
  2583. // Parse next opcode and set up next loop.
  2584. uint8_t Byte = *Ptr++;
  2585. uint8_t ImmValue = Byte & MachO::BIND_IMMEDIATE_MASK;
  2586. uint8_t Opcode = Byte & MachO::BIND_OPCODE_MASK;
  2587. int8_t SignExtended;
  2588. const uint8_t *SymStart;
  2589. switch (Opcode) {
  2590. case MachO::BIND_OPCODE_DONE:
  2591. if (TableKind == Kind::Lazy) {
  2592. // Lazying bindings have a DONE opcode between entries. Need to ignore
  2593. // it to advance to next entry. But need not if this is last entry.
  2594. bool NotLastEntry = false;
  2595. for (const uint8_t *P = Ptr; P < Opcodes.end(); ++P) {
  2596. if (*P) {
  2597. NotLastEntry = true;
  2598. }
  2599. }
  2600. if (NotLastEntry)
  2601. break;
  2602. }
  2603. More = false;
  2604. Done = true;
  2605. moveToEnd();
  2606. DEBUG_WITH_TYPE("mach-o-bind", llvm::dbgs() << "BIND_OPCODE_DONE\n");
  2607. break;
  2608. case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_IMM:
  2609. Ordinal = ImmValue;
  2610. DEBUG_WITH_TYPE(
  2611. "mach-o-bind",
  2612. llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: "
  2613. << "Ordinal=" << Ordinal << "\n");
  2614. break;
  2615. case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB:
  2616. Ordinal = readULEB128();
  2617. DEBUG_WITH_TYPE(
  2618. "mach-o-bind",
  2619. llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: "
  2620. << "Ordinal=" << Ordinal << "\n");
  2621. break;
  2622. case MachO::BIND_OPCODE_SET_DYLIB_SPECIAL_IMM:
  2623. if (ImmValue) {
  2624. SignExtended = MachO::BIND_OPCODE_MASK | ImmValue;
  2625. Ordinal = SignExtended;
  2626. } else
  2627. Ordinal = 0;
  2628. DEBUG_WITH_TYPE(
  2629. "mach-o-bind",
  2630. llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: "
  2631. << "Ordinal=" << Ordinal << "\n");
  2632. break;
  2633. case MachO::BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM:
  2634. Flags = ImmValue;
  2635. SymStart = Ptr;
  2636. while (*Ptr) {
  2637. ++Ptr;
  2638. }
  2639. SymbolName = StringRef(reinterpret_cast<const char*>(SymStart),
  2640. Ptr-SymStart);
  2641. ++Ptr;
  2642. DEBUG_WITH_TYPE(
  2643. "mach-o-bind",
  2644. llvm::dbgs() << "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: "
  2645. << "SymbolName=" << SymbolName << "\n");
  2646. if (TableKind == Kind::Weak) {
  2647. if (ImmValue & MachO::BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION)
  2648. return;
  2649. }
  2650. break;
  2651. case MachO::BIND_OPCODE_SET_TYPE_IMM:
  2652. BindType = ImmValue;
  2653. DEBUG_WITH_TYPE(
  2654. "mach-o-bind",
  2655. llvm::dbgs() << "BIND_OPCODE_SET_TYPE_IMM: "
  2656. << "BindType=" << (int)BindType << "\n");
  2657. break;
  2658. case MachO::BIND_OPCODE_SET_ADDEND_SLEB:
  2659. Addend = readSLEB128();
  2660. if (TableKind == Kind::Lazy)
  2661. Malformed = true;
  2662. DEBUG_WITH_TYPE(
  2663. "mach-o-bind",
  2664. llvm::dbgs() << "BIND_OPCODE_SET_ADDEND_SLEB: "
  2665. << "Addend=" << Addend << "\n");
  2666. break;
  2667. case MachO::BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
  2668. SegmentIndex = ImmValue;
  2669. SegmentOffset = readULEB128();
  2670. DEBUG_WITH_TYPE(
  2671. "mach-o-bind",
  2672. llvm::dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
  2673. << "SegmentIndex=" << SegmentIndex << ", "
  2674. << format("SegmentOffset=0x%06X", SegmentOffset)
  2675. << "\n");
  2676. break;
  2677. case MachO::BIND_OPCODE_ADD_ADDR_ULEB:
  2678. SegmentOffset += readULEB128();
  2679. DEBUG_WITH_TYPE("mach-o-bind",
  2680. llvm::dbgs() << "BIND_OPCODE_ADD_ADDR_ULEB: "
  2681. << format("SegmentOffset=0x%06X",
  2682. SegmentOffset) << "\n");
  2683. break;
  2684. case MachO::BIND_OPCODE_DO_BIND:
  2685. AdvanceAmount = PointerSize;
  2686. RemainingLoopCount = 0;
  2687. DEBUG_WITH_TYPE("mach-o-bind",
  2688. llvm::dbgs() << "BIND_OPCODE_DO_BIND: "
  2689. << format("SegmentOffset=0x%06X",
  2690. SegmentOffset) << "\n");
  2691. return;
  2692. case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB:
  2693. AdvanceAmount = readULEB128() + PointerSize;
  2694. RemainingLoopCount = 0;
  2695. if (TableKind == Kind::Lazy)
  2696. Malformed = true;
  2697. DEBUG_WITH_TYPE(
  2698. "mach-o-bind",
  2699. llvm::dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: "
  2700. << format("SegmentOffset=0x%06X", SegmentOffset)
  2701. << ", AdvanceAmount=" << AdvanceAmount
  2702. << ", RemainingLoopCount=" << RemainingLoopCount
  2703. << "\n");
  2704. return;
  2705. case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED:
  2706. AdvanceAmount = ImmValue * PointerSize + PointerSize;
  2707. RemainingLoopCount = 0;
  2708. if (TableKind == Kind::Lazy)
  2709. Malformed = true;
  2710. DEBUG_WITH_TYPE("mach-o-bind",
  2711. llvm::dbgs()
  2712. << "BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: "
  2713. << format("SegmentOffset=0x%06X",
  2714. SegmentOffset) << "\n");
  2715. return;
  2716. case MachO::BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB:
  2717. RemainingLoopCount = readULEB128() - 1;
  2718. AdvanceAmount = readULEB128() + PointerSize;
  2719. if (TableKind == Kind::Lazy)
  2720. Malformed = true;
  2721. DEBUG_WITH_TYPE(
  2722. "mach-o-bind",
  2723. llvm::dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: "
  2724. << format("SegmentOffset=0x%06X", SegmentOffset)
  2725. << ", AdvanceAmount=" << AdvanceAmount
  2726. << ", RemainingLoopCount=" << RemainingLoopCount
  2727. << "\n");
  2728. return;
  2729. default:
  2730. Malformed = true;
  2731. }
  2732. }
  2733. }
  2734. uint64_t MachOBindEntry::readULEB128() {
  2735. unsigned Count;
  2736. uint64_t Result = decodeULEB128(Ptr, &Count);
  2737. Ptr += Count;
  2738. if (Ptr > Opcodes.end()) {
  2739. Ptr = Opcodes.end();
  2740. Malformed = true;
  2741. }
  2742. return Result;
  2743. }
  2744. int64_t MachOBindEntry::readSLEB128() {
  2745. unsigned Count;
  2746. int64_t Result = decodeSLEB128(Ptr, &Count);
  2747. Ptr += Count;
  2748. if (Ptr > Opcodes.end()) {
  2749. Ptr = Opcodes.end();
  2750. Malformed = true;
  2751. }
  2752. return Result;
  2753. }
  2754. uint32_t MachOBindEntry::segmentIndex() const { return SegmentIndex; }
  2755. uint64_t MachOBindEntry::segmentOffset() const { return SegmentOffset; }
  2756. StringRef MachOBindEntry::typeName() const {
  2757. switch (BindType) {
  2758. case MachO::BIND_TYPE_POINTER:
  2759. return "pointer";
  2760. case MachO::BIND_TYPE_TEXT_ABSOLUTE32:
  2761. return "text abs32";
  2762. case MachO::BIND_TYPE_TEXT_PCREL32:
  2763. return "text rel32";
  2764. }
  2765. return "unknown";
  2766. }
  2767. StringRef MachOBindEntry::symbolName() const { return SymbolName; }
  2768. int64_t MachOBindEntry::addend() const { return Addend; }
  2769. uint32_t MachOBindEntry::flags() const { return Flags; }
  2770. int MachOBindEntry::ordinal() const { return Ordinal; }
  2771. bool MachOBindEntry::operator==(const MachOBindEntry &Other) const {
  2772. assert(Opcodes == Other.Opcodes && "compare iterators of different files");
  2773. return (Ptr == Other.Ptr) &&
  2774. (RemainingLoopCount == Other.RemainingLoopCount) &&
  2775. (Done == Other.Done);
  2776. }
  2777. iterator_range<bind_iterator>
  2778. MachOObjectFile::bindTable(ArrayRef<uint8_t> Opcodes, bool is64,
  2779. MachOBindEntry::Kind BKind) {
  2780. MachOBindEntry Start(Opcodes, is64, BKind);
  2781. Start.moveToFirst();
  2782. MachOBindEntry Finish(Opcodes, is64, BKind);
  2783. Finish.moveToEnd();
  2784. return make_range(bind_iterator(Start), bind_iterator(Finish));
  2785. }
  2786. iterator_range<bind_iterator> MachOObjectFile::bindTable() const {
  2787. return bindTable(getDyldInfoBindOpcodes(), is64Bit(),
  2788. MachOBindEntry::Kind::Regular);
  2789. }
  2790. iterator_range<bind_iterator> MachOObjectFile::lazyBindTable() const {
  2791. return bindTable(getDyldInfoLazyBindOpcodes(), is64Bit(),
  2792. MachOBindEntry::Kind::Lazy);
  2793. }
  2794. iterator_range<bind_iterator> MachOObjectFile::weakBindTable() const {
  2795. return bindTable(getDyldInfoWeakBindOpcodes(), is64Bit(),
  2796. MachOBindEntry::Kind::Weak);
  2797. }
  2798. MachOObjectFile::load_command_iterator
  2799. MachOObjectFile::begin_load_commands() const {
  2800. return LoadCommands.begin();
  2801. }
  2802. MachOObjectFile::load_command_iterator
  2803. MachOObjectFile::end_load_commands() const {
  2804. return LoadCommands.end();
  2805. }
  2806. iterator_range<MachOObjectFile::load_command_iterator>
  2807. MachOObjectFile::load_commands() const {
  2808. return make_range(begin_load_commands(), end_load_commands());
  2809. }
  2810. StringRef
  2811. MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const {
  2812. ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);
  2813. return parseSegmentOrSectionName(Raw.data());
  2814. }
  2815. ArrayRef<char>
  2816. MachOObjectFile::getSectionRawName(DataRefImpl Sec) const {
  2817. assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
  2818. const section_base *Base =
  2819. reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
  2820. return makeArrayRef(Base->sectname);
  2821. }
  2822. ArrayRef<char>
  2823. MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
  2824. assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
  2825. const section_base *Base =
  2826. reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
  2827. return makeArrayRef(Base->segname);
  2828. }
  2829. bool
  2830. MachOObjectFile::isRelocationScattered(const MachO::any_relocation_info &RE)
  2831. const {
  2832. if (getCPUType(this) == MachO::CPU_TYPE_X86_64)
  2833. return false;
  2834. return getPlainRelocationAddress(RE) & MachO::R_SCATTERED;
  2835. }
  2836. unsigned MachOObjectFile::getPlainRelocationSymbolNum(
  2837. const MachO::any_relocation_info &RE) const {
  2838. if (isLittleEndian())
  2839. return RE.r_word1 & 0xffffff;
  2840. return RE.r_word1 >> 8;
  2841. }
  2842. bool MachOObjectFile::getPlainRelocationExternal(
  2843. const MachO::any_relocation_info &RE) const {
  2844. if (isLittleEndian())
  2845. return (RE.r_word1 >> 27) & 1;
  2846. return (RE.r_word1 >> 4) & 1;
  2847. }
  2848. bool MachOObjectFile::getScatteredRelocationScattered(
  2849. const MachO::any_relocation_info &RE) const {
  2850. return RE.r_word0 >> 31;
  2851. }
  2852. uint32_t MachOObjectFile::getScatteredRelocationValue(
  2853. const MachO::any_relocation_info &RE) const {
  2854. return RE.r_word1;
  2855. }
  2856. uint32_t MachOObjectFile::getScatteredRelocationType(
  2857. const MachO::any_relocation_info &RE) const {
  2858. return (RE.r_word0 >> 24) & 0xf;
  2859. }
  2860. unsigned MachOObjectFile::getAnyRelocationAddress(
  2861. const MachO::any_relocation_info &RE) const {
  2862. if (isRelocationScattered(RE))
  2863. return getScatteredRelocationAddress(RE);
  2864. return getPlainRelocationAddress(RE);
  2865. }
  2866. unsigned MachOObjectFile::getAnyRelocationPCRel(
  2867. const MachO::any_relocation_info &RE) const {
  2868. if (isRelocationScattered(RE))
  2869. return getScatteredRelocationPCRel(this, RE);
  2870. return getPlainRelocationPCRel(this, RE);
  2871. }
  2872. unsigned MachOObjectFile::getAnyRelocationLength(
  2873. const MachO::any_relocation_info &RE) const {
  2874. if (isRelocationScattered(RE))
  2875. return getScatteredRelocationLength(RE);
  2876. return getPlainRelocationLength(this, RE);
  2877. }
  2878. unsigned
  2879. MachOObjectFile::getAnyRelocationType(
  2880. const MachO::any_relocation_info &RE) const {
  2881. if (isRelocationScattered(RE))
  2882. return getScatteredRelocationType(RE);
  2883. return getPlainRelocationType(this, RE);
  2884. }
  2885. SectionRef
  2886. MachOObjectFile::getAnyRelocationSection(
  2887. const MachO::any_relocation_info &RE) const {
  2888. if (isRelocationScattered(RE) || getPlainRelocationExternal(RE))
  2889. return *section_end();
  2890. unsigned SecNum = getPlainRelocationSymbolNum(RE);
  2891. if (SecNum == MachO::R_ABS || SecNum > Sections.size())
  2892. return *section_end();
  2893. DataRefImpl DRI;
  2894. DRI.d.a = SecNum - 1;
  2895. return SectionRef(DRI, this);
  2896. }
  2897. MachO::section MachOObjectFile::getSection(DataRefImpl DRI) const {
  2898. assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
  2899. return getStruct<MachO::section>(this, Sections[DRI.d.a]);
  2900. }
  2901. MachO::section_64 MachOObjectFile::getSection64(DataRefImpl DRI) const {
  2902. assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
  2903. return getStruct<MachO::section_64>(this, Sections[DRI.d.a]);
  2904. }
  2905. MachO::section MachOObjectFile::getSection(const LoadCommandInfo &L,
  2906. unsigned Index) const {
  2907. const char *Sec = getSectionPtr(this, L, Index);
  2908. return getStruct<MachO::section>(this, Sec);
  2909. }
  2910. MachO::section_64 MachOObjectFile::getSection64(const LoadCommandInfo &L,
  2911. unsigned Index) const {
  2912. const char *Sec = getSectionPtr(this, L, Index);
  2913. return getStruct<MachO::section_64>(this, Sec);
  2914. }
  2915. MachO::nlist
  2916. MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {
  2917. const char *P = reinterpret_cast<const char *>(DRI.p);
  2918. return getStruct<MachO::nlist>(this, P);
  2919. }
  2920. MachO::nlist_64
  2921. MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const {
  2922. const char *P = reinterpret_cast<const char *>(DRI.p);
  2923. return getStruct<MachO::nlist_64>(this, P);
  2924. }
  2925. MachO::linkedit_data_command
  2926. MachOObjectFile::getLinkeditDataLoadCommand(const LoadCommandInfo &L) const {
  2927. return getStruct<MachO::linkedit_data_command>(this, L.Ptr);
  2928. }
  2929. MachO::segment_command
  2930. MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const {
  2931. return getStruct<MachO::segment_command>(this, L.Ptr);
  2932. }
  2933. MachO::segment_command_64
  2934. MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const {
  2935. return getStruct<MachO::segment_command_64>(this, L.Ptr);
  2936. }
  2937. MachO::linker_option_command
  2938. MachOObjectFile::getLinkerOptionLoadCommand(const LoadCommandInfo &L) const {
  2939. return getStruct<MachO::linker_option_command>(this, L.Ptr);
  2940. }
  2941. MachO::version_min_command
  2942. MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const {
  2943. return getStruct<MachO::version_min_command>(this, L.Ptr);
  2944. }
  2945. MachO::dylib_command
  2946. MachOObjectFile::getDylibIDLoadCommand(const LoadCommandInfo &L) const {
  2947. return getStruct<MachO::dylib_command>(this, L.Ptr);
  2948. }
  2949. MachO::dyld_info_command
  2950. MachOObjectFile::getDyldInfoLoadCommand(const LoadCommandInfo &L) const {
  2951. return getStruct<MachO::dyld_info_command>(this, L.Ptr);
  2952. }
  2953. MachO::dylinker_command
  2954. MachOObjectFile::getDylinkerCommand(const LoadCommandInfo &L) const {
  2955. return getStruct<MachO::dylinker_command>(this, L.Ptr);
  2956. }
  2957. MachO::uuid_command
  2958. MachOObjectFile::getUuidCommand(const LoadCommandInfo &L) const {
  2959. return getStruct<MachO::uuid_command>(this, L.Ptr);
  2960. }
  2961. MachO::rpath_command
  2962. MachOObjectFile::getRpathCommand(const LoadCommandInfo &L) const {
  2963. return getStruct<MachO::rpath_command>(this, L.Ptr);
  2964. }
  2965. MachO::source_version_command
  2966. MachOObjectFile::getSourceVersionCommand(const LoadCommandInfo &L) const {
  2967. return getStruct<MachO::source_version_command>(this, L.Ptr);
  2968. }
  2969. MachO::entry_point_command
  2970. MachOObjectFile::getEntryPointCommand(const LoadCommandInfo &L) const {
  2971. return getStruct<MachO::entry_point_command>(this, L.Ptr);
  2972. }
  2973. MachO::encryption_info_command
  2974. MachOObjectFile::getEncryptionInfoCommand(const LoadCommandInfo &L) const {
  2975. return getStruct<MachO::encryption_info_command>(this, L.Ptr);
  2976. }
  2977. MachO::encryption_info_command_64
  2978. MachOObjectFile::getEncryptionInfoCommand64(const LoadCommandInfo &L) const {
  2979. return getStruct<MachO::encryption_info_command_64>(this, L.Ptr);
  2980. }
  2981. MachO::sub_framework_command
  2982. MachOObjectFile::getSubFrameworkCommand(const LoadCommandInfo &L) const {
  2983. return getStruct<MachO::sub_framework_command>(this, L.Ptr);
  2984. }
  2985. MachO::sub_umbrella_command
  2986. MachOObjectFile::getSubUmbrellaCommand(const LoadCommandInfo &L) const {
  2987. return getStruct<MachO::sub_umbrella_command>(this, L.Ptr);
  2988. }
  2989. MachO::sub_library_command
  2990. MachOObjectFile::getSubLibraryCommand(const LoadCommandInfo &L) const {
  2991. return getStruct<MachO::sub_library_command>(this, L.Ptr);
  2992. }
  2993. MachO::sub_client_command
  2994. MachOObjectFile::getSubClientCommand(const LoadCommandInfo &L) const {
  2995. return getStruct<MachO::sub_client_command>(this, L.Ptr);
  2996. }
  2997. MachO::routines_command
  2998. MachOObjectFile::getRoutinesCommand(const LoadCommandInfo &L) const {
  2999. return getStruct<MachO::routines_command>(this, L.Ptr);
  3000. }
  3001. MachO::routines_command_64
  3002. MachOObjectFile::getRoutinesCommand64(const LoadCommandInfo &L) const {
  3003. return getStruct<MachO::routines_command_64>(this, L.Ptr);
  3004. }
  3005. MachO::thread_command
  3006. MachOObjectFile::getThreadCommand(const LoadCommandInfo &L) const {
  3007. return getStruct<MachO::thread_command>(this, L.Ptr);
  3008. }
  3009. MachO::any_relocation_info
  3010. MachOObjectFile::getRelocation(DataRefImpl Rel) const {
  3011. DataRefImpl Sec;
  3012. Sec.d.a = Rel.d.a;
  3013. uint32_t Offset;
  3014. if (is64Bit()) {
  3015. MachO::section_64 Sect = getSection64(Sec);
  3016. Offset = Sect.reloff;
  3017. } else {
  3018. MachO::section Sect = getSection(Sec);
  3019. Offset = Sect.reloff;
  3020. }
  3021. auto P = reinterpret_cast<const MachO::any_relocation_info *>(
  3022. getPtr(this, Offset)) + Rel.d.b;
  3023. return getStruct<MachO::any_relocation_info>(
  3024. this, reinterpret_cast<const char *>(P));
  3025. }
  3026. MachO::data_in_code_entry
  3027. MachOObjectFile::getDice(DataRefImpl Rel) const {
  3028. const char *P = reinterpret_cast<const char *>(Rel.p);
  3029. return getStruct<MachO::data_in_code_entry>(this, P);
  3030. }
  3031. const MachO::mach_header &MachOObjectFile::getHeader() const {
  3032. return Header;
  3033. }
  3034. const MachO::mach_header_64 &MachOObjectFile::getHeader64() const {
  3035. assert(is64Bit());
  3036. return Header64;
  3037. }
  3038. uint32_t MachOObjectFile::getIndirectSymbolTableEntry(
  3039. const MachO::dysymtab_command &DLC,
  3040. unsigned Index) const {
  3041. uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t);
  3042. return getStruct<uint32_t>(this, getPtr(this, Offset));
  3043. }
  3044. MachO::data_in_code_entry
  3045. MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset,
  3046. unsigned Index) const {
  3047. uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry);
  3048. return getStruct<MachO::data_in_code_entry>(this, getPtr(this, Offset));
  3049. }
  3050. MachO::symtab_command MachOObjectFile::getSymtabLoadCommand() const {
  3051. if (SymtabLoadCmd)
  3052. return getStruct<MachO::symtab_command>(this, SymtabLoadCmd);
  3053. // If there is no SymtabLoadCmd return a load command with zero'ed fields.
  3054. MachO::symtab_command Cmd;
  3055. Cmd.cmd = MachO::LC_SYMTAB;
  3056. Cmd.cmdsize = sizeof(MachO::symtab_command);
  3057. Cmd.symoff = 0;
  3058. Cmd.nsyms = 0;
  3059. Cmd.stroff = 0;
  3060. Cmd.strsize = 0;
  3061. return Cmd;
  3062. }
  3063. MachO::dysymtab_command MachOObjectFile::getDysymtabLoadCommand() const {
  3064. if (DysymtabLoadCmd)
  3065. return getStruct<MachO::dysymtab_command>(this, DysymtabLoadCmd);
  3066. // If there is no DysymtabLoadCmd return a load command with zero'ed fields.
  3067. MachO::dysymtab_command Cmd;
  3068. Cmd.cmd = MachO::LC_DYSYMTAB;
  3069. Cmd.cmdsize = sizeof(MachO::dysymtab_command);
  3070. Cmd.ilocalsym = 0;
  3071. Cmd.nlocalsym = 0;
  3072. Cmd.iextdefsym = 0;
  3073. Cmd.nextdefsym = 0;
  3074. Cmd.iundefsym = 0;
  3075. Cmd.nundefsym = 0;
  3076. Cmd.tocoff = 0;
  3077. Cmd.ntoc = 0;
  3078. Cmd.modtaboff = 0;
  3079. Cmd.nmodtab = 0;
  3080. Cmd.extrefsymoff = 0;
  3081. Cmd.nextrefsyms = 0;
  3082. Cmd.indirectsymoff = 0;
  3083. Cmd.nindirectsyms = 0;
  3084. Cmd.extreloff = 0;
  3085. Cmd.nextrel = 0;
  3086. Cmd.locreloff = 0;
  3087. Cmd.nlocrel = 0;
  3088. return Cmd;
  3089. }
  3090. MachO::linkedit_data_command
  3091. MachOObjectFile::getDataInCodeLoadCommand() const {
  3092. if (DataInCodeLoadCmd)
  3093. return getStruct<MachO::linkedit_data_command>(this, DataInCodeLoadCmd);
  3094. // If there is no DataInCodeLoadCmd return a load command with zero'ed fields.
  3095. MachO::linkedit_data_command Cmd;
  3096. Cmd.cmd = MachO::LC_DATA_IN_CODE;
  3097. Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
  3098. Cmd.dataoff = 0;
  3099. Cmd.datasize = 0;
  3100. return Cmd;
  3101. }
  3102. MachO::linkedit_data_command
  3103. MachOObjectFile::getLinkOptHintsLoadCommand() const {
  3104. if (LinkOptHintsLoadCmd)
  3105. return getStruct<MachO::linkedit_data_command>(this, LinkOptHintsLoadCmd);
  3106. // If there is no LinkOptHintsLoadCmd return a load command with zero'ed
  3107. // fields.
  3108. MachO::linkedit_data_command Cmd;
  3109. Cmd.cmd = MachO::LC_LINKER_OPTIMIZATION_HINT;
  3110. Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
  3111. Cmd.dataoff = 0;
  3112. Cmd.datasize = 0;
  3113. return Cmd;
  3114. }
  3115. ArrayRef<uint8_t> MachOObjectFile::getDyldInfoRebaseOpcodes() const {
  3116. if (!DyldInfoLoadCmd)
  3117. return None;
  3118. MachO::dyld_info_command DyldInfo =
  3119. getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
  3120. const uint8_t *Ptr =
  3121. reinterpret_cast<const uint8_t *>(getPtr(this, DyldInfo.rebase_off));
  3122. return makeArrayRef(Ptr, DyldInfo.rebase_size);
  3123. }
  3124. ArrayRef<uint8_t> MachOObjectFile::getDyldInfoBindOpcodes() const {
  3125. if (!DyldInfoLoadCmd)
  3126. return None;
  3127. MachO::dyld_info_command DyldInfo =
  3128. getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
  3129. const uint8_t *Ptr =
  3130. reinterpret_cast<const uint8_t *>(getPtr(this, DyldInfo.bind_off));
  3131. return makeArrayRef(Ptr, DyldInfo.bind_size);
  3132. }
  3133. ArrayRef<uint8_t> MachOObjectFile::getDyldInfoWeakBindOpcodes() const {
  3134. if (!DyldInfoLoadCmd)
  3135. return None;
  3136. MachO::dyld_info_command DyldInfo =
  3137. getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
  3138. const uint8_t *Ptr =
  3139. reinterpret_cast<const uint8_t *>(getPtr(this, DyldInfo.weak_bind_off));
  3140. return makeArrayRef(Ptr, DyldInfo.weak_bind_size);
  3141. }
  3142. ArrayRef<uint8_t> MachOObjectFile::getDyldInfoLazyBindOpcodes() const {
  3143. if (!DyldInfoLoadCmd)
  3144. return None;
  3145. MachO::dyld_info_command DyldInfo =
  3146. getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
  3147. const uint8_t *Ptr =
  3148. reinterpret_cast<const uint8_t *>(getPtr(this, DyldInfo.lazy_bind_off));
  3149. return makeArrayRef(Ptr, DyldInfo.lazy_bind_size);
  3150. }
  3151. ArrayRef<uint8_t> MachOObjectFile::getDyldInfoExportsTrie() const {
  3152. if (!DyldInfoLoadCmd)
  3153. return None;
  3154. MachO::dyld_info_command DyldInfo =
  3155. getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
  3156. const uint8_t *Ptr =
  3157. reinterpret_cast<const uint8_t *>(getPtr(this, DyldInfo.export_off));
  3158. return makeArrayRef(Ptr, DyldInfo.export_size);
  3159. }
  3160. ArrayRef<uint8_t> MachOObjectFile::getUuid() const {
  3161. if (!UuidLoadCmd)
  3162. return None;
  3163. // Returning a pointer is fine as uuid doesn't need endian swapping.
  3164. const char *Ptr = UuidLoadCmd + offsetof(MachO::uuid_command, uuid);
  3165. return makeArrayRef(reinterpret_cast<const uint8_t *>(Ptr), 16);
  3166. }
  3167. StringRef MachOObjectFile::getStringTableData() const {
  3168. MachO::symtab_command S = getSymtabLoadCommand();
  3169. return getData().substr(S.stroff, S.strsize);
  3170. }
  3171. bool MachOObjectFile::is64Bit() const {
  3172. return getType() == getMachOType(false, true) ||
  3173. getType() == getMachOType(true, true);
  3174. }
  3175. void MachOObjectFile::ReadULEB128s(uint64_t Index,
  3176. SmallVectorImpl<uint64_t> &Out) const {
  3177. DataExtractor extractor(ObjectFile::getData(), true, 0);
  3178. uint32_t offset = Index;
  3179. uint64_t data = 0;
  3180. while (uint64_t delta = extractor.getULEB128(&offset)) {
  3181. data += delta;
  3182. Out.push_back(data);
  3183. }
  3184. }
  3185. bool MachOObjectFile::isRelocatableObject() const {
  3186. return getHeader().filetype == MachO::MH_OBJECT;
  3187. }
  3188. Expected<std::unique_ptr<MachOObjectFile>>
  3189. ObjectFile::createMachOObjectFile(MemoryBufferRef Buffer,
  3190. uint32_t UniversalCputype,
  3191. uint32_t UniversalIndex) {
  3192. StringRef Magic = Buffer.getBuffer().slice(0, 4);
  3193. if (Magic == "\xFE\xED\xFA\xCE")
  3194. return MachOObjectFile::create(Buffer, false, false,
  3195. UniversalCputype, UniversalIndex);
  3196. if (Magic == "\xCE\xFA\xED\xFE")
  3197. return MachOObjectFile::create(Buffer, true, false,
  3198. UniversalCputype, UniversalIndex);
  3199. if (Magic == "\xFE\xED\xFA\xCF")
  3200. return MachOObjectFile::create(Buffer, false, true,
  3201. UniversalCputype, UniversalIndex);
  3202. if (Magic == "\xCF\xFA\xED\xFE")
  3203. return MachOObjectFile::create(Buffer, true, true,
  3204. UniversalCputype, UniversalIndex);
  3205. return make_error<GenericBinaryError>("Unrecognized MachO magic number",
  3206. object_error::invalid_file_type);
  3207. }