MachOObjectFile.cpp revision dce4a407a24b04eebc6a376f8e62b41aaa7b071f
14b6829f0d28990dd645e16386eb226d0f10c8731shiqian//===- MachOObjectFile.cpp - Mach-O object file binding ---------*- C++ -*-===//
24b6829f0d28990dd645e16386eb226d0f10c8731shiqian//
34b6829f0d28990dd645e16386eb226d0f10c8731shiqian//                     The LLVM Compiler Infrastructure
44b6829f0d28990dd645e16386eb226d0f10c8731shiqian//
54b6829f0d28990dd645e16386eb226d0f10c8731shiqian// This file is distributed under the University of Illinois Open Source
64b6829f0d28990dd645e16386eb226d0f10c8731shiqian// License. See LICENSE.TXT for details.
74b6829f0d28990dd645e16386eb226d0f10c8731shiqian//
84b6829f0d28990dd645e16386eb226d0f10c8731shiqian//===----------------------------------------------------------------------===//
94b6829f0d28990dd645e16386eb226d0f10c8731shiqian//
104b6829f0d28990dd645e16386eb226d0f10c8731shiqian// This file defines the MachOObjectFile class, which binds the MachOObject
114b6829f0d28990dd645e16386eb226d0f10c8731shiqian// class to the generic ObjectFile wrapper.
124b6829f0d28990dd645e16386eb226d0f10c8731shiqian//
134b6829f0d28990dd645e16386eb226d0f10c8731shiqian//===----------------------------------------------------------------------===//
144b6829f0d28990dd645e16386eb226d0f10c8731shiqian
154b6829f0d28990dd645e16386eb226d0f10c8731shiqian#include "llvm/Object/MachO.h"
164b6829f0d28990dd645e16386eb226d0f10c8731shiqian#include "llvm/ADT/STLExtras.h"
174b6829f0d28990dd645e16386eb226d0f10c8731shiqian#include "llvm/ADT/Triple.h"
184b6829f0d28990dd645e16386eb226d0f10c8731shiqian#include "llvm/Support/DataExtractor.h"
194b6829f0d28990dd645e16386eb226d0f10c8731shiqian#include "llvm/Support/Format.h"
204b6829f0d28990dd645e16386eb226d0f10c8731shiqian#include "llvm/Support/Host.h"
214b6829f0d28990dd645e16386eb226d0f10c8731shiqian#include "llvm/Support/MemoryBuffer.h"
224b6829f0d28990dd645e16386eb226d0f10c8731shiqian#include "llvm/Support/raw_ostream.h"
234b6829f0d28990dd645e16386eb226d0f10c8731shiqian#include <cctype>
244b6829f0d28990dd645e16386eb226d0f10c8731shiqian#include <cstring>
254b6829f0d28990dd645e16386eb226d0f10c8731shiqian#include <limits>
264b6829f0d28990dd645e16386eb226d0f10c8731shiqian
274b6829f0d28990dd645e16386eb226d0f10c8731shiqianusing namespace llvm;
284b6829f0d28990dd645e16386eb226d0f10c8731shiqianusing namespace object;
294b6829f0d28990dd645e16386eb226d0f10c8731shiqian
304b6829f0d28990dd645e16386eb226d0f10c8731shiqiannamespace llvm {
314b6829f0d28990dd645e16386eb226d0f10c8731shiqiannamespace object {
324b6829f0d28990dd645e16386eb226d0f10c8731shiqian
334b6829f0d28990dd645e16386eb226d0f10c8731shiqianstruct nlist_base {
344b6829f0d28990dd645e16386eb226d0f10c8731shiqian  uint32_t n_strx;
354b6829f0d28990dd645e16386eb226d0f10c8731shiqian  uint8_t n_type;
364b6829f0d28990dd645e16386eb226d0f10c8731shiqian  uint8_t n_sect;
374b6829f0d28990dd645e16386eb226d0f10c8731shiqian  uint16_t n_desc;
384b6829f0d28990dd645e16386eb226d0f10c8731shiqian};
394b6829f0d28990dd645e16386eb226d0f10c8731shiqian
402620c79810d4741922e9fa89050c0af564994f24zhanyong.wanstruct section_base {
414b6829f0d28990dd645e16386eb226d0f10c8731shiqian  char sectname[16];
424cd62602913a032a7aec091d4c8055ff9af95e37zhanyong.wan  char segname[16];
43733a54a398766289b74cf3daebe083d7115cf388zhanyong.wan};
44733a54a398766289b74cf3daebe083d7115cf388zhanyong.wan
45733a54a398766289b74cf3daebe083d7115cf388zhanyong.wantemplate<typename T>
46733a54a398766289b74cf3daebe083d7115cf388zhanyong.wanstatic void SwapValue(T &Value) {
474b6829f0d28990dd645e16386eb226d0f10c8731shiqian  Value = sys::SwapByteOrder(Value);
484b6829f0d28990dd645e16386eb226d0f10c8731shiqian}
49e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian
50e8ff148b4309e115da1c55089dc3b9a241a928dcshiqiantemplate<typename T>
51e8ff148b4309e115da1c55089dc3b9a241a928dcshiqianstatic void SwapStruct(T &Value);
52e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian
53e8ff148b4309e115da1c55089dc3b9a241a928dcshiqiantemplate<>
544b6829f0d28990dd645e16386eb226d0f10c8731shiqianvoid SwapStruct(MachO::any_relocation_info &H) {
552620c79810d4741922e9fa89050c0af564994f24zhanyong.wan  SwapValue(H.r_word0);
562620c79810d4741922e9fa89050c0af564994f24zhanyong.wan  SwapValue(H.r_word1);
572620c79810d4741922e9fa89050c0af564994f24zhanyong.wan}
584b6829f0d28990dd645e16386eb226d0f10c8731shiqian
594b6829f0d28990dd645e16386eb226d0f10c8731shiqiantemplate<>
604b6829f0d28990dd645e16386eb226d0f10c8731shiqianvoid SwapStruct(MachO::load_command &L) {
614b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(L.cmd);
624b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(L.cmdsize);
634b6829f0d28990dd645e16386eb226d0f10c8731shiqian}
644b6829f0d28990dd645e16386eb226d0f10c8731shiqian
654b6829f0d28990dd645e16386eb226d0f10c8731shiqiantemplate<>
664b6829f0d28990dd645e16386eb226d0f10c8731shiqianvoid SwapStruct(nlist_base &S) {
67e44602ec83c65102035ce5304ae8de0cb16e9e56shiqian  SwapValue(S.n_strx);
68e44602ec83c65102035ce5304ae8de0cb16e9e56shiqian  SwapValue(S.n_desc);
694b6829f0d28990dd645e16386eb226d0f10c8731shiqian}
704b6829f0d28990dd645e16386eb226d0f10c8731shiqian
714b6829f0d28990dd645e16386eb226d0f10c8731shiqiantemplate<>
724b6829f0d28990dd645e16386eb226d0f10c8731shiqianvoid SwapStruct(MachO::section &S) {
734b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(S.addr);
744b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(S.size);
754b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(S.offset);
764b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(S.align);
774b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(S.reloff);
784b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(S.nreloc);
794b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(S.flags);
804b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(S.reserved1);
814b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(S.reserved2);
824b6829f0d28990dd645e16386eb226d0f10c8731shiqian}
834b6829f0d28990dd645e16386eb226d0f10c8731shiqian
844b6829f0d28990dd645e16386eb226d0f10c8731shiqiantemplate<>
854b6829f0d28990dd645e16386eb226d0f10c8731shiqianvoid SwapStruct(MachO::section_64 &S) {
864b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(S.addr);
874b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(S.size);
884b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(S.offset);
894b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(S.align);
904b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(S.reloff);
914b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(S.nreloc);
924b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(S.flags);
934b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(S.reserved1);
944b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(S.reserved2);
954b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(S.reserved3);
964b6829f0d28990dd645e16386eb226d0f10c8731shiqian}
974b6829f0d28990dd645e16386eb226d0f10c8731shiqian
984b6829f0d28990dd645e16386eb226d0f10c8731shiqiantemplate<>
994b6829f0d28990dd645e16386eb226d0f10c8731shiqianvoid SwapStruct(MachO::nlist &S) {
100678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  SwapValue(S.n_strx);
101678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  SwapValue(S.n_desc);
102678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  SwapValue(S.n_value);
1034b6829f0d28990dd645e16386eb226d0f10c8731shiqian}
1044b6829f0d28990dd645e16386eb226d0f10c8731shiqian
10539dc95e495fd9f888bcd460c383a2594bf57429dzhanyong.wantemplate<>
1064b6829f0d28990dd645e16386eb226d0f10c8731shiqianvoid SwapStruct(MachO::nlist_64 &S) {
1071cdc76325936ad3312be0d456b4936c8b8e6bf70zhanyong.wan  SwapValue(S.n_strx);
1084b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(S.n_desc);
1094834581321d60c17997d65a2360c7674f15f9bbcshiqian  SwapValue(S.n_value);
1104b6829f0d28990dd645e16386eb226d0f10c8731shiqian}
1111cdc76325936ad3312be0d456b4936c8b8e6bf70zhanyong.wan
1124b6829f0d28990dd645e16386eb226d0f10c8731shiqiantemplate<>
1134b6829f0d28990dd645e16386eb226d0f10c8731shiqianvoid SwapStruct(MachO::mach_header &H) {
11439dc95e495fd9f888bcd460c383a2594bf57429dzhanyong.wan  SwapValue(H.magic);
11539dc95e495fd9f888bcd460c383a2594bf57429dzhanyong.wan  SwapValue(H.cputype);
11639dc95e495fd9f888bcd460c383a2594bf57429dzhanyong.wan  SwapValue(H.cpusubtype);
1174b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(H.filetype);
1184b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(H.ncmds);
1194b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(H.sizeofcmds);
1204b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(H.flags);
1214b6829f0d28990dd645e16386eb226d0f10c8731shiqian}
1224b6829f0d28990dd645e16386eb226d0f10c8731shiqian
1234b6829f0d28990dd645e16386eb226d0f10c8731shiqiantemplate<>
124f179f4ee7cc76e7103a726ebf666902b07f89659vladlosevvoid SwapStruct(MachO::mach_header_64 &H) {
125f179f4ee7cc76e7103a726ebf666902b07f89659vladlosev  SwapValue(H.magic);
126f179f4ee7cc76e7103a726ebf666902b07f89659vladlosev  SwapValue(H.cputype);
127e44602ec83c65102035ce5304ae8de0cb16e9e56shiqian  SwapValue(H.cpusubtype);
128e44602ec83c65102035ce5304ae8de0cb16e9e56shiqian  SwapValue(H.filetype);
1291ce454985edf37b17f2f266d499c2b7dec339002zhanyong.wan  SwapValue(H.ncmds);
130e44602ec83c65102035ce5304ae8de0cb16e9e56shiqian  SwapValue(H.sizeofcmds);
1314b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(H.flags);
1324b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(H.reserved);
1334b6829f0d28990dd645e16386eb226d0f10c8731shiqian}
1344b6829f0d28990dd645e16386eb226d0f10c8731shiqian
1354b6829f0d28990dd645e16386eb226d0f10c8731shiqiantemplate<>
1364b6829f0d28990dd645e16386eb226d0f10c8731shiqianvoid SwapStruct(MachO::symtab_command &C) {
1374b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.cmd);
1384b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.cmdsize);
1394b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.symoff);
1404b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.nsyms);
1414b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.stroff);
1424b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.strsize);
1434b6829f0d28990dd645e16386eb226d0f10c8731shiqian}
1444b6829f0d28990dd645e16386eb226d0f10c8731shiqian
1454b6829f0d28990dd645e16386eb226d0f10c8731shiqiantemplate<>
1464b6829f0d28990dd645e16386eb226d0f10c8731shiqianvoid SwapStruct(MachO::dysymtab_command &C) {
1474b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.cmd);
1484b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.cmdsize);
1494b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.ilocalsym);
1504b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.nlocalsym);
1514b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.iextdefsym);
1524b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.nextdefsym);
1534b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.iundefsym);
1544b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.nundefsym);
1554b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.tocoff);
1563eddf52d9cae4e9fd28eda46dcfe38bdeb09d1c0zhanyong.wan  SwapValue(C.ntoc);
1573eddf52d9cae4e9fd28eda46dcfe38bdeb09d1c0zhanyong.wan  SwapValue(C.modtaboff);
1583eddf52d9cae4e9fd28eda46dcfe38bdeb09d1c0zhanyong.wan  SwapValue(C.nmodtab);
159733a54a398766289b74cf3daebe083d7115cf388zhanyong.wan  SwapValue(C.extrefsymoff);
160941b5ee8ebaad627df59eaa03509021b3cfa3bafshiqian  SwapValue(C.nextrefsyms);
161733a54a398766289b74cf3daebe083d7115cf388zhanyong.wan  SwapValue(C.indirectsymoff);
1624b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.nindirectsyms);
1633eddf52d9cae4e9fd28eda46dcfe38bdeb09d1c0zhanyong.wan  SwapValue(C.extreloff);
1644b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.nextrel);
1654b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.locreloff);
1661ce454985edf37b17f2f266d499c2b7dec339002zhanyong.wan  SwapValue(C.nlocrel);
1671ce454985edf37b17f2f266d499c2b7dec339002zhanyong.wan}
1684b6829f0d28990dd645e16386eb226d0f10c8731shiqian
1694b6829f0d28990dd645e16386eb226d0f10c8731shiqiantemplate<>
170e4092294d7c1f38f303e8c7f67da31ba3e7e7d9azhanyong.wanvoid SwapStruct(MachO::linkedit_data_command &C) {
1714b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.cmd);
1724b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.cmdsize);
1734b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.dataoff);
1744b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.datasize);
1754b6829f0d28990dd645e16386eb226d0f10c8731shiqian}
1764b6829f0d28990dd645e16386eb226d0f10c8731shiqian
1774b6829f0d28990dd645e16386eb226d0f10c8731shiqiantemplate<>
1784b6829f0d28990dd645e16386eb226d0f10c8731shiqianvoid SwapStruct(MachO::segment_command &C) {
1794b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.cmd);
1804b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.cmdsize);
1814b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.vmaddr);
1824b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.vmsize);
183e44602ec83c65102035ce5304ae8de0cb16e9e56shiqian  SwapValue(C.fileoff);
184e44602ec83c65102035ce5304ae8de0cb16e9e56shiqian  SwapValue(C.filesize);
185e44602ec83c65102035ce5304ae8de0cb16e9e56shiqian  SwapValue(C.maxprot);
186e44602ec83c65102035ce5304ae8de0cb16e9e56shiqian  SwapValue(C.initprot);
1874b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.nsects);
1884b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.flags);
1894b6829f0d28990dd645e16386eb226d0f10c8731shiqian}
1904b6829f0d28990dd645e16386eb226d0f10c8731shiqian
1914b6829f0d28990dd645e16386eb226d0f10c8731shiqiantemplate<>
1924b6829f0d28990dd645e16386eb226d0f10c8731shiqianvoid SwapStruct(MachO::segment_command_64 &C) {
1934b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.cmd);
1944b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.cmdsize);
1954b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.vmaddr);
1964b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.vmsize);
1974b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.fileoff);
19839dc95e495fd9f888bcd460c383a2594bf57429dzhanyong.wan  SwapValue(C.filesize);
1994b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.maxprot);
20039dc95e495fd9f888bcd460c383a2594bf57429dzhanyong.wan  SwapValue(C.initprot);
20139dc95e495fd9f888bcd460c383a2594bf57429dzhanyong.wan  SwapValue(C.nsects);
2024b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.flags);
2034b6829f0d28990dd645e16386eb226d0f10c8731shiqian}
20439dc95e495fd9f888bcd460c383a2594bf57429dzhanyong.wan
20539dc95e495fd9f888bcd460c383a2594bf57429dzhanyong.wantemplate<>
20639dc95e495fd9f888bcd460c383a2594bf57429dzhanyong.wanvoid SwapStruct(uint32_t &C) {
207e44602ec83c65102035ce5304ae8de0cb16e9e56shiqian  SwapValue(C);
2084b6829f0d28990dd645e16386eb226d0f10c8731shiqian}
20939dc95e495fd9f888bcd460c383a2594bf57429dzhanyong.wan
2104b6829f0d28990dd645e16386eb226d0f10c8731shiqiantemplate<>
2114b6829f0d28990dd645e16386eb226d0f10c8731shiqianvoid SwapStruct(MachO::linker_options_command &C) {
2124b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.cmd);
21339dc95e495fd9f888bcd460c383a2594bf57429dzhanyong.wan  SwapValue(C.cmdsize);
21439dc95e495fd9f888bcd460c383a2594bf57429dzhanyong.wan  SwapValue(C.count);
2154b6829f0d28990dd645e16386eb226d0f10c8731shiqian}
2164b6829f0d28990dd645e16386eb226d0f10c8731shiqian
2174b6829f0d28990dd645e16386eb226d0f10c8731shiqiantemplate<>
218e44602ec83c65102035ce5304ae8de0cb16e9e56shiqianvoid SwapStruct(MachO::version_min_command&C) {
2194b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.cmd);
220e44602ec83c65102035ce5304ae8de0cb16e9e56shiqian  SwapValue(C.cmdsize);
2214b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.version);
2224b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.reserved);
2234b6829f0d28990dd645e16386eb226d0f10c8731shiqian}
224e44602ec83c65102035ce5304ae8de0cb16e9e56shiqian
2254b6829f0d28990dd645e16386eb226d0f10c8731shiqiantemplate<>
2264b6829f0d28990dd645e16386eb226d0f10c8731shiqianvoid SwapStruct(MachO::data_in_code_entry &C) {
227e44602ec83c65102035ce5304ae8de0cb16e9e56shiqian  SwapValue(C.offset);
2284b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.length);
2294b6829f0d28990dd645e16386eb226d0f10c8731shiqian  SwapValue(C.kind);
230e44602ec83c65102035ce5304ae8de0cb16e9e56shiqian}
2314b6829f0d28990dd645e16386eb226d0f10c8731shiqian
23239dc95e495fd9f888bcd460c383a2594bf57429dzhanyong.wantemplate<typename T>
23339dc95e495fd9f888bcd460c383a2594bf57429dzhanyong.wanT getStruct(const MachOObjectFile *O, const char *P) {
23439dc95e495fd9f888bcd460c383a2594bf57429dzhanyong.wan  T Cmd;
23539dc95e495fd9f888bcd460c383a2594bf57429dzhanyong.wan  memcpy(&Cmd, P, sizeof(T));
23639dc95e495fd9f888bcd460c383a2594bf57429dzhanyong.wan  if (O->isLittleEndian() != sys::IsLittleEndianHost)
23739dc95e495fd9f888bcd460c383a2594bf57429dzhanyong.wan    SwapStruct(Cmd);
23839dc95e495fd9f888bcd460c383a2594bf57429dzhanyong.wan  return Cmd;
23939dc95e495fd9f888bcd460c383a2594bf57429dzhanyong.wan}
24039dc95e495fd9f888bcd460c383a2594bf57429dzhanyong.wan
24139dc95e495fd9f888bcd460c383a2594bf57429dzhanyong.wanstatic uint32_t
24239dc95e495fd9f888bcd460c383a2594bf57429dzhanyong.wangetSegmentLoadCommandNumSections(const MachOObjectFile *O,
24339dc95e495fd9f888bcd460c383a2594bf57429dzhanyong.wan                                 const MachOObjectFile::LoadCommandInfo &L) {
24439dc95e495fd9f888bcd460c383a2594bf57429dzhanyong.wan  if (O->is64Bit()) {
24539dc95e495fd9f888bcd460c383a2594bf57429dzhanyong.wan    MachO::segment_command_64 S = O->getSegment64LoadCommand(L);
24639dc95e495fd9f888bcd460c383a2594bf57429dzhanyong.wan    return S.nsects;
24739dc95e495fd9f888bcd460c383a2594bf57429dzhanyong.wan  }
24839dc95e495fd9f888bcd460c383a2594bf57429dzhanyong.wan  MachO::segment_command S = O->getSegmentLoadCommand(L);
24939dc95e495fd9f888bcd460c383a2594bf57429dzhanyong.wan  return S.nsects;
25039dc95e495fd9f888bcd460c383a2594bf57429dzhanyong.wan}
25139dc95e495fd9f888bcd460c383a2594bf57429dzhanyong.wan
25239dc95e495fd9f888bcd460c383a2594bf57429dzhanyong.wanstatic const char *
2534b6829f0d28990dd645e16386eb226d0f10c8731shiqiangetSectionPtr(const MachOObjectFile *O, MachOObjectFile::LoadCommandInfo L,
2544b6829f0d28990dd645e16386eb226d0f10c8731shiqian              unsigned Sec) {
2554b6829f0d28990dd645e16386eb226d0f10c8731shiqian  uintptr_t CommandAddr = reinterpret_cast<uintptr_t>(L.Ptr);
2564b6829f0d28990dd645e16386eb226d0f10c8731shiqian
2574b6829f0d28990dd645e16386eb226d0f10c8731shiqian  bool Is64 = O->is64Bit();
2584b6829f0d28990dd645e16386eb226d0f10c8731shiqian  unsigned SegmentLoadSize = Is64 ? sizeof(MachO::segment_command_64) :
2594b6829f0d28990dd645e16386eb226d0f10c8731shiqian                                    sizeof(MachO::segment_command);
2604b6829f0d28990dd645e16386eb226d0f10c8731shiqian  unsigned SectionSize = Is64 ? sizeof(MachO::section_64) :
2614b6829f0d28990dd645e16386eb226d0f10c8731shiqian                                sizeof(MachO::section);
2624b6829f0d28990dd645e16386eb226d0f10c8731shiqian
2634b6829f0d28990dd645e16386eb226d0f10c8731shiqian  uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec * SectionSize;
2644b6829f0d28990dd645e16386eb226d0f10c8731shiqian  return reinterpret_cast<const char*>(SectionAddr);
2654b6829f0d28990dd645e16386eb226d0f10c8731shiqian}
2664b6829f0d28990dd645e16386eb226d0f10c8731shiqian
2674b6829f0d28990dd645e16386eb226d0f10c8731shiqianstatic const char *getPtr(const MachOObjectFile *O, size_t Offset) {
268e4092294d7c1f38f303e8c7f67da31ba3e7e7d9azhanyong.wan  return O->getData().substr(Offset, 1).data();
269e4092294d7c1f38f303e8c7f67da31ba3e7e7d9azhanyong.wan}
270e4092294d7c1f38f303e8c7f67da31ba3e7e7d9azhanyong.wan
271e4092294d7c1f38f303e8c7f67da31ba3e7e7d9azhanyong.wanstatic nlist_base
272e4092294d7c1f38f303e8c7f67da31ba3e7e7d9azhanyong.wangetSymbolTableEntryBase(const MachOObjectFile *O, DataRefImpl DRI) {
2734b6829f0d28990dd645e16386eb226d0f10c8731shiqian  const char *P = reinterpret_cast<const char *>(DRI.p);
274fbd53a53c1e01dec71c65754cf73282e4759bc40vladlosev  return getStruct<nlist_base>(O, P);
275e4092294d7c1f38f303e8c7f67da31ba3e7e7d9azhanyong.wan}
276e4092294d7c1f38f303e8c7f67da31ba3e7e7d9azhanyong.wan
277e4092294d7c1f38f303e8c7f67da31ba3e7e7d9azhanyong.wanstatic StringRef parseSegmentOrSectionName(const char *P) {
278e4092294d7c1f38f303e8c7f67da31ba3e7e7d9azhanyong.wan  if (P[15] == 0)
279e4092294d7c1f38f303e8c7f67da31ba3e7e7d9azhanyong.wan    // Null terminated.
2804b6829f0d28990dd645e16386eb226d0f10c8731shiqian    return P;
2814b6829f0d28990dd645e16386eb226d0f10c8731shiqian  // Not null terminated, so this is a 16 char string.
2824b6829f0d28990dd645e16386eb226d0f10c8731shiqian  return StringRef(P, 16);
2834b6829f0d28990dd645e16386eb226d0f10c8731shiqian}
2844b6829f0d28990dd645e16386eb226d0f10c8731shiqian
2854b6829f0d28990dd645e16386eb226d0f10c8731shiqian// Helper to advance a section or symbol iterator multiple increments at a time.
2864b6829f0d28990dd645e16386eb226d0f10c8731shiqiantemplate<class T>
2874b6829f0d28990dd645e16386eb226d0f10c8731shiqianstatic void advance(T &it, size_t Val) {
2884b6829f0d28990dd645e16386eb226d0f10c8731shiqian  while (Val--)
2894b6829f0d28990dd645e16386eb226d0f10c8731shiqian    ++it;
2904b6829f0d28990dd645e16386eb226d0f10c8731shiqian}
2914b6829f0d28990dd645e16386eb226d0f10c8731shiqian
2924b6829f0d28990dd645e16386eb226d0f10c8731shiqianstatic unsigned getCPUType(const MachOObjectFile *O) {
2934b6829f0d28990dd645e16386eb226d0f10c8731shiqian  return O->getHeader().cputype;
2944b6829f0d28990dd645e16386eb226d0f10c8731shiqian}
2954b6829f0d28990dd645e16386eb226d0f10c8731shiqian
2964b6829f0d28990dd645e16386eb226d0f10c8731shiqianstatic void printRelocationTargetName(const MachOObjectFile *O,
2974b6829f0d28990dd645e16386eb226d0f10c8731shiqian                                      const MachO::any_relocation_info &RE,
2984b6829f0d28990dd645e16386eb226d0f10c8731shiqian                                      raw_string_ostream &fmt) {
2994b6829f0d28990dd645e16386eb226d0f10c8731shiqian  bool IsScattered = O->isRelocationScattered(RE);
3004b6829f0d28990dd645e16386eb226d0f10c8731shiqian
3014b6829f0d28990dd645e16386eb226d0f10c8731shiqian  // Target of a scattered relocation is an address.  In the interest of
3024b6829f0d28990dd645e16386eb226d0f10c8731shiqian  // generating pretty output, scan through the symbol table looking for a
3034b6829f0d28990dd645e16386eb226d0f10c8731shiqian  // symbol that aligns with that address.  If we find one, print it.
3044b6829f0d28990dd645e16386eb226d0f10c8731shiqian  // Otherwise, we just print the hex address of the target.
3054b6829f0d28990dd645e16386eb226d0f10c8731shiqian  if (IsScattered) {
3064b6829f0d28990dd645e16386eb226d0f10c8731shiqian    uint32_t Val = O->getPlainRelocationSymbolNum(RE);
3074b6829f0d28990dd645e16386eb226d0f10c8731shiqian
3084b6829f0d28990dd645e16386eb226d0f10c8731shiqian    for (const SymbolRef &Symbol : O->symbols()) {
3094b6829f0d28990dd645e16386eb226d0f10c8731shiqian      error_code ec;
3104b6829f0d28990dd645e16386eb226d0f10c8731shiqian      uint64_t Addr;
3114b6829f0d28990dd645e16386eb226d0f10c8731shiqian      StringRef Name;
3124b6829f0d28990dd645e16386eb226d0f10c8731shiqian
3134b6829f0d28990dd645e16386eb226d0f10c8731shiqian      if ((ec = Symbol.getAddress(Addr)))
3144b6829f0d28990dd645e16386eb226d0f10c8731shiqian        report_fatal_error(ec.message());
3154b6829f0d28990dd645e16386eb226d0f10c8731shiqian      if (Addr != Val)
3164b6829f0d28990dd645e16386eb226d0f10c8731shiqian        continue;
3174b6829f0d28990dd645e16386eb226d0f10c8731shiqian      if ((ec = Symbol.getName(Name)))
3184b6829f0d28990dd645e16386eb226d0f10c8731shiqian        report_fatal_error(ec.message());
3194b6829f0d28990dd645e16386eb226d0f10c8731shiqian      fmt << Name;
3204b6829f0d28990dd645e16386eb226d0f10c8731shiqian      return;
3214b6829f0d28990dd645e16386eb226d0f10c8731shiqian    }
3224b6829f0d28990dd645e16386eb226d0f10c8731shiqian
3234b6829f0d28990dd645e16386eb226d0f10c8731shiqian    // If we couldn't find a symbol that this relocation refers to, try
3244b6829f0d28990dd645e16386eb226d0f10c8731shiqian    // to find a section beginning instead.
3254b6829f0d28990dd645e16386eb226d0f10c8731shiqian    for (const SectionRef &Section : O->sections()) {
3264b6829f0d28990dd645e16386eb226d0f10c8731shiqian      error_code ec;
3274b6829f0d28990dd645e16386eb226d0f10c8731shiqian      uint64_t Addr;
3284b6829f0d28990dd645e16386eb226d0f10c8731shiqian      StringRef Name;
3294b6829f0d28990dd645e16386eb226d0f10c8731shiqian
3304b6829f0d28990dd645e16386eb226d0f10c8731shiqian      if ((ec = Section.getAddress(Addr)))
3314b6829f0d28990dd645e16386eb226d0f10c8731shiqian        report_fatal_error(ec.message());
3324b6829f0d28990dd645e16386eb226d0f10c8731shiqian      if (Addr != Val)
3334b6829f0d28990dd645e16386eb226d0f10c8731shiqian        continue;
3344b6829f0d28990dd645e16386eb226d0f10c8731shiqian      if ((ec = Section.getName(Name)))
3354b6829f0d28990dd645e16386eb226d0f10c8731shiqian        report_fatal_error(ec.message());
3364b6829f0d28990dd645e16386eb226d0f10c8731shiqian      fmt << Name;
3374b6829f0d28990dd645e16386eb226d0f10c8731shiqian      return;
3384b6829f0d28990dd645e16386eb226d0f10c8731shiqian    }
3394b6829f0d28990dd645e16386eb226d0f10c8731shiqian
3404b6829f0d28990dd645e16386eb226d0f10c8731shiqian    fmt << format("0x%x", Val);
3414b6829f0d28990dd645e16386eb226d0f10c8731shiqian    return;
3424b6829f0d28990dd645e16386eb226d0f10c8731shiqian  }
3434b6829f0d28990dd645e16386eb226d0f10c8731shiqian
3444b6829f0d28990dd645e16386eb226d0f10c8731shiqian  StringRef S;
3454b6829f0d28990dd645e16386eb226d0f10c8731shiqian  bool isExtern = O->getPlainRelocationExternal(RE);
3464b6829f0d28990dd645e16386eb226d0f10c8731shiqian  uint64_t Val = O->getPlainRelocationSymbolNum(RE);
3474b6829f0d28990dd645e16386eb226d0f10c8731shiqian
3484b6829f0d28990dd645e16386eb226d0f10c8731shiqian  if (isExtern) {
3494b6829f0d28990dd645e16386eb226d0f10c8731shiqian    symbol_iterator SI = O->symbol_begin();
3504b6829f0d28990dd645e16386eb226d0f10c8731shiqian    advance(SI, Val);
3514b6829f0d28990dd645e16386eb226d0f10c8731shiqian    SI->getName(S);
3524b6829f0d28990dd645e16386eb226d0f10c8731shiqian  } else {
3534b6829f0d28990dd645e16386eb226d0f10c8731shiqian    section_iterator SI = O->section_begin();
3544b6829f0d28990dd645e16386eb226d0f10c8731shiqian    // Adjust for the fact that sections are 1-indexed.
3554b6829f0d28990dd645e16386eb226d0f10c8731shiqian    advance(SI, Val - 1);
3564b6829f0d28990dd645e16386eb226d0f10c8731shiqian    SI->getName(S);
3574b6829f0d28990dd645e16386eb226d0f10c8731shiqian  }
3584b6829f0d28990dd645e16386eb226d0f10c8731shiqian
35998efcc49448a78cae3af3ed793a3ad6927620fc4zhanyong.wan  fmt << S;
3604b6829f0d28990dd645e16386eb226d0f10c8731shiqian}
3614b6829f0d28990dd645e16386eb226d0f10c8731shiqian
3624b6829f0d28990dd645e16386eb226d0f10c8731shiqianstatic uint32_t
3634b6829f0d28990dd645e16386eb226d0f10c8731shiqiangetPlainRelocationAddress(const MachO::any_relocation_info &RE) {
3644b6829f0d28990dd645e16386eb226d0f10c8731shiqian  return RE.r_word0;
3654b6829f0d28990dd645e16386eb226d0f10c8731shiqian}
3664b6829f0d28990dd645e16386eb226d0f10c8731shiqian
3674b6829f0d28990dd645e16386eb226d0f10c8731shiqianstatic unsigned
36898efcc49448a78cae3af3ed793a3ad6927620fc4zhanyong.wangetScatteredRelocationAddress(const MachO::any_relocation_info &RE) {
36998efcc49448a78cae3af3ed793a3ad6927620fc4zhanyong.wan  return RE.r_word0 & 0xffffff;
3704b6829f0d28990dd645e16386eb226d0f10c8731shiqian}
3714b6829f0d28990dd645e16386eb226d0f10c8731shiqian
3724b6829f0d28990dd645e16386eb226d0f10c8731shiqianstatic bool getPlainRelocationPCRel(const MachOObjectFile *O,
3734b6829f0d28990dd645e16386eb226d0f10c8731shiqian                                    const MachO::any_relocation_info &RE) {
3744b6829f0d28990dd645e16386eb226d0f10c8731shiqian  if (O->isLittleEndian())
3754b6829f0d28990dd645e16386eb226d0f10c8731shiqian    return (RE.r_word1 >> 24) & 1;
3764b6829f0d28990dd645e16386eb226d0f10c8731shiqian  return (RE.r_word1 >> 7) & 1;
3774b6829f0d28990dd645e16386eb226d0f10c8731shiqian}
3784b6829f0d28990dd645e16386eb226d0f10c8731shiqian
3794b6829f0d28990dd645e16386eb226d0f10c8731shiqianstatic bool
38098efcc49448a78cae3af3ed793a3ad6927620fc4zhanyong.wangetScatteredRelocationPCRel(const MachOObjectFile *O,
3814b6829f0d28990dd645e16386eb226d0f10c8731shiqian                            const MachO::any_relocation_info &RE) {
3824b6829f0d28990dd645e16386eb226d0f10c8731shiqian  return (RE.r_word0 >> 30) & 1;
38398efcc49448a78cae3af3ed793a3ad6927620fc4zhanyong.wan}
3844b6829f0d28990dd645e16386eb226d0f10c8731shiqian
3854b6829f0d28990dd645e16386eb226d0f10c8731shiqianstatic unsigned getPlainRelocationLength(const MachOObjectFile *O,
38698efcc49448a78cae3af3ed793a3ad6927620fc4zhanyong.wan                                         const MachO::any_relocation_info &RE) {
3874b6829f0d28990dd645e16386eb226d0f10c8731shiqian  if (O->isLittleEndian())
3884b6829f0d28990dd645e16386eb226d0f10c8731shiqian    return (RE.r_word1 >> 25) & 3;
38998efcc49448a78cae3af3ed793a3ad6927620fc4zhanyong.wan  return (RE.r_word1 >> 5) & 3;
3904b6829f0d28990dd645e16386eb226d0f10c8731shiqian}
3914b6829f0d28990dd645e16386eb226d0f10c8731shiqian
3924b6829f0d28990dd645e16386eb226d0f10c8731shiqianstatic unsigned
3934b6829f0d28990dd645e16386eb226d0f10c8731shiqiangetScatteredRelocationLength(const MachO::any_relocation_info &RE) {
3944b6829f0d28990dd645e16386eb226d0f10c8731shiqian  return (RE.r_word0 >> 28) & 3;
3954b6829f0d28990dd645e16386eb226d0f10c8731shiqian}
3964b6829f0d28990dd645e16386eb226d0f10c8731shiqian
3974b6829f0d28990dd645e16386eb226d0f10c8731shiqianstatic unsigned getPlainRelocationType(const MachOObjectFile *O,
3984b6829f0d28990dd645e16386eb226d0f10c8731shiqian                                       const MachO::any_relocation_info &RE) {
3994b6829f0d28990dd645e16386eb226d0f10c8731shiqian  if (O->isLittleEndian())
4004b6829f0d28990dd645e16386eb226d0f10c8731shiqian    return RE.r_word1 >> 28;
4014b6829f0d28990dd645e16386eb226d0f10c8731shiqian  return RE.r_word1 & 0xf;
4024b6829f0d28990dd645e16386eb226d0f10c8731shiqian}
4034b6829f0d28990dd645e16386eb226d0f10c8731shiqian
4044b6829f0d28990dd645e16386eb226d0f10c8731shiqianstatic unsigned
4054b6829f0d28990dd645e16386eb226d0f10c8731shiqiangetScatteredRelocationType(const MachO::any_relocation_info &RE) {
4064b6829f0d28990dd645e16386eb226d0f10c8731shiqian  return (RE.r_word0 >> 24) & 0xf;
4074b6829f0d28990dd645e16386eb226d0f10c8731shiqian}
4084b6829f0d28990dd645e16386eb226d0f10c8731shiqian
40998efcc49448a78cae3af3ed793a3ad6927620fc4zhanyong.wanstatic uint32_t getSectionFlags(const MachOObjectFile *O,
41098efcc49448a78cae3af3ed793a3ad6927620fc4zhanyong.wan                                DataRefImpl Sec) {
4114b6829f0d28990dd645e16386eb226d0f10c8731shiqian  if (O->is64Bit()) {
4124b6829f0d28990dd645e16386eb226d0f10c8731shiqian    MachO::section_64 Sect = O->getSection64(Sec);
4134b6829f0d28990dd645e16386eb226d0f10c8731shiqian    return Sect.flags;
41498efcc49448a78cae3af3ed793a3ad6927620fc4zhanyong.wan  }
41598efcc49448a78cae3af3ed793a3ad6927620fc4zhanyong.wan  MachO::section Sect = O->getSection(Sec);
41698efcc49448a78cae3af3ed793a3ad6927620fc4zhanyong.wan  return Sect.flags;
41798efcc49448a78cae3af3ed793a3ad6927620fc4zhanyong.wan}
41898efcc49448a78cae3af3ed793a3ad6927620fc4zhanyong.wan
41998efcc49448a78cae3af3ed793a3ad6927620fc4zhanyong.wanMachOObjectFile::MachOObjectFile(MemoryBuffer *Object, bool IsLittleEndian,
4204b6829f0d28990dd645e16386eb226d0f10c8731shiqian                                 bool Is64bits, error_code &EC,
4214b6829f0d28990dd645e16386eb226d0f10c8731shiqian                                 bool BufferOwned)
4224b6829f0d28990dd645e16386eb226d0f10c8731shiqian    : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object, BufferOwned),
4234b6829f0d28990dd645e16386eb226d0f10c8731shiqian      SymtabLoadCmd(nullptr), DysymtabLoadCmd(nullptr),
4244b6829f0d28990dd645e16386eb226d0f10c8731shiqian      DataInCodeLoadCmd(nullptr) {
4254b6829f0d28990dd645e16386eb226d0f10c8731shiqian  uint32_t LoadCommandCount = this->getHeader().ncmds;
4264b6829f0d28990dd645e16386eb226d0f10c8731shiqian  MachO::LoadCommandType SegmentLoadType = is64Bit() ?
4274b6829f0d28990dd645e16386eb226d0f10c8731shiqian    MachO::LC_SEGMENT_64 : MachO::LC_SEGMENT;
4284b6829f0d28990dd645e16386eb226d0f10c8731shiqian
4294b6829f0d28990dd645e16386eb226d0f10c8731shiqian  MachOObjectFile::LoadCommandInfo Load = getFirstLoadCommandInfo();
4304b6829f0d28990dd645e16386eb226d0f10c8731shiqian  for (unsigned I = 0; ; ++I) {
4314b6829f0d28990dd645e16386eb226d0f10c8731shiqian    if (Load.C.cmd == MachO::LC_SYMTAB) {
4324b6829f0d28990dd645e16386eb226d0f10c8731shiqian      assert(!SymtabLoadCmd && "Multiple symbol tables");
4334b6829f0d28990dd645e16386eb226d0f10c8731shiqian      SymtabLoadCmd = Load.Ptr;
4344b6829f0d28990dd645e16386eb226d0f10c8731shiqian    } else if (Load.C.cmd == MachO::LC_DYSYMTAB) {
4354b6829f0d28990dd645e16386eb226d0f10c8731shiqian      assert(!DysymtabLoadCmd && "Multiple dynamic symbol tables");
4364b6829f0d28990dd645e16386eb226d0f10c8731shiqian      DysymtabLoadCmd = Load.Ptr;
4374b6829f0d28990dd645e16386eb226d0f10c8731shiqian    } else if (Load.C.cmd == MachO::LC_DATA_IN_CODE) {
4384b6829f0d28990dd645e16386eb226d0f10c8731shiqian      assert(!DataInCodeLoadCmd && "Multiple data in code tables");
4394b6829f0d28990dd645e16386eb226d0f10c8731shiqian      DataInCodeLoadCmd = Load.Ptr;
4404b6829f0d28990dd645e16386eb226d0f10c8731shiqian    } else if (Load.C.cmd == SegmentLoadType) {
4414b6829f0d28990dd645e16386eb226d0f10c8731shiqian      uint32_t NumSections = getSegmentLoadCommandNumSections(this, Load);
4424b6829f0d28990dd645e16386eb226d0f10c8731shiqian      for (unsigned J = 0; J < NumSections; ++J) {
4434b6829f0d28990dd645e16386eb226d0f10c8731shiqian        const char *Sec = getSectionPtr(this, Load, J);
4444b6829f0d28990dd645e16386eb226d0f10c8731shiqian        Sections.push_back(Sec);
4454b6829f0d28990dd645e16386eb226d0f10c8731shiqian      }
4464b6829f0d28990dd645e16386eb226d0f10c8731shiqian    }
4474b6829f0d28990dd645e16386eb226d0f10c8731shiqian
4484b6829f0d28990dd645e16386eb226d0f10c8731shiqian    if (I == LoadCommandCount - 1)
4494b6829f0d28990dd645e16386eb226d0f10c8731shiqian      break;
4504b6829f0d28990dd645e16386eb226d0f10c8731shiqian    else
4514b6829f0d28990dd645e16386eb226d0f10c8731shiqian      Load = getNextLoadCommandInfo(Load);
4524b6829f0d28990dd645e16386eb226d0f10c8731shiqian  }
4534b6829f0d28990dd645e16386eb226d0f10c8731shiqian}
45498efcc49448a78cae3af3ed793a3ad6927620fc4zhanyong.wan
4554b6829f0d28990dd645e16386eb226d0f10c8731shiqianvoid MachOObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
4564b6829f0d28990dd645e16386eb226d0f10c8731shiqian  unsigned SymbolTableEntrySize = is64Bit() ?
4574b6829f0d28990dd645e16386eb226d0f10c8731shiqian    sizeof(MachO::nlist_64) :
4584b6829f0d28990dd645e16386eb226d0f10c8731shiqian    sizeof(MachO::nlist);
4594b6829f0d28990dd645e16386eb226d0f10c8731shiqian  Symb.p += SymbolTableEntrySize;
4604b6829f0d28990dd645e16386eb226d0f10c8731shiqian}
4614b6829f0d28990dd645e16386eb226d0f10c8731shiqian
4624b6829f0d28990dd645e16386eb226d0f10c8731shiqianerror_code MachOObjectFile::getSymbolName(DataRefImpl Symb,
4634b6829f0d28990dd645e16386eb226d0f10c8731shiqian                                          StringRef &Res) const {
4644b6829f0d28990dd645e16386eb226d0f10c8731shiqian  StringRef StringTable = getStringTableData();
4654b6829f0d28990dd645e16386eb226d0f10c8731shiqian  nlist_base Entry = getSymbolTableEntryBase(this, Symb);
4664b6829f0d28990dd645e16386eb226d0f10c8731shiqian  const char *Start = &StringTable.data()[Entry.n_strx];
4674b6829f0d28990dd645e16386eb226d0f10c8731shiqian  Res = StringRef(Start);
468fe6a9a48c2a8280439e58c2e9020268a80df89b3shiqian  return object_error::success;
469fe6a9a48c2a8280439e58c2e9020268a80df89b3shiqian}
470fe6a9a48c2a8280439e58c2e9020268a80df89b3shiqian
471fe6a9a48c2a8280439e58c2e9020268a80df89b3shiqianerror_code MachOObjectFile::getSymbolAddress(DataRefImpl Symb,
472fe6a9a48c2a8280439e58c2e9020268a80df89b3shiqian                                             uint64_t &Res) const {
473fe6a9a48c2a8280439e58c2e9020268a80df89b3shiqian  if (is64Bit()) {
474fe6a9a48c2a8280439e58c2e9020268a80df89b3shiqian    MachO::nlist_64 Entry = getSymbol64TableEntry(Symb);
475fe6a9a48c2a8280439e58c2e9020268a80df89b3shiqian    if ((Entry.n_type & MachO::N_TYPE) == MachO::N_UNDF &&
476fe6a9a48c2a8280439e58c2e9020268a80df89b3shiqian        Entry.n_value == 0)
477fe6a9a48c2a8280439e58c2e9020268a80df89b3shiqian      Res = UnknownAddressOrSize;
478fe6a9a48c2a8280439e58c2e9020268a80df89b3shiqian    else
479fe6a9a48c2a8280439e58c2e9020268a80df89b3shiqian      Res = Entry.n_value;
480fe6a9a48c2a8280439e58c2e9020268a80df89b3shiqian  } else {
4814b6829f0d28990dd645e16386eb226d0f10c8731shiqian    MachO::nlist Entry = getSymbolTableEntry(Symb);
4824b6829f0d28990dd645e16386eb226d0f10c8731shiqian    if ((Entry.n_type & MachO::N_TYPE) == MachO::N_UNDF &&
4834b6829f0d28990dd645e16386eb226d0f10c8731shiqian        Entry.n_value == 0)
4844b6829f0d28990dd645e16386eb226d0f10c8731shiqian      Res = UnknownAddressOrSize;
4854b6829f0d28990dd645e16386eb226d0f10c8731shiqian    else
486fe6a9a48c2a8280439e58c2e9020268a80df89b3shiqian      Res = Entry.n_value;
487fe6a9a48c2a8280439e58c2e9020268a80df89b3shiqian  }
488fe6a9a48c2a8280439e58c2e9020268a80df89b3shiqian  return object_error::success;
489fe6a9a48c2a8280439e58c2e9020268a80df89b3shiqian}
490fe6a9a48c2a8280439e58c2e9020268a80df89b3shiqian
491fe6a9a48c2a8280439e58c2e9020268a80df89b3shiqianerror_code MachOObjectFile::getSymbolAlignment(DataRefImpl DRI,
4924b6829f0d28990dd645e16386eb226d0f10c8731shiqian                                               uint32_t &Result) const {
4934b6829f0d28990dd645e16386eb226d0f10c8731shiqian  uint32_t flags = getSymbolFlags(DRI);
494fe6a9a48c2a8280439e58c2e9020268a80df89b3shiqian  if (flags & SymbolRef::SF_Common) {
495fe6a9a48c2a8280439e58c2e9020268a80df89b3shiqian    nlist_base Entry = getSymbolTableEntryBase(this, DRI);
496fe6a9a48c2a8280439e58c2e9020268a80df89b3shiqian    Result = 1 << MachO::GET_COMM_ALIGN(Entry.n_desc);
497fe6a9a48c2a8280439e58c2e9020268a80df89b3shiqian  } else {
498fe6a9a48c2a8280439e58c2e9020268a80df89b3shiqian    Result = 0;
499e4092294d7c1f38f303e8c7f67da31ba3e7e7d9azhanyong.wan  }
500fe6a9a48c2a8280439e58c2e9020268a80df89b3shiqian  return object_error::success;
5014834581321d60c17997d65a2360c7674f15f9bbcshiqian}
5024834581321d60c17997d65a2360c7674f15f9bbcshiqian
5034834581321d60c17997d65a2360c7674f15f9bbcshiqianerror_code MachOObjectFile::getSymbolSize(DataRefImpl DRI,
5044834581321d60c17997d65a2360c7674f15f9bbcshiqian                                          uint64_t &Result) const {
5054834581321d60c17997d65a2360c7674f15f9bbcshiqian  uint64_t BeginOffset;
5064834581321d60c17997d65a2360c7674f15f9bbcshiqian  uint64_t EndOffset = 0;
5074834581321d60c17997d65a2360c7674f15f9bbcshiqian  uint8_t SectionIndex;
5084834581321d60c17997d65a2360c7674f15f9bbcshiqian
5094834581321d60c17997d65a2360c7674f15f9bbcshiqian  nlist_base Entry = getSymbolTableEntryBase(this, DRI);
5104834581321d60c17997d65a2360c7674f15f9bbcshiqian  uint64_t Value;
5114834581321d60c17997d65a2360c7674f15f9bbcshiqian  getSymbolAddress(DRI, Value);
5124834581321d60c17997d65a2360c7674f15f9bbcshiqian  if (Value == UnknownAddressOrSize) {
5134834581321d60c17997d65a2360c7674f15f9bbcshiqian    Result = UnknownAddressOrSize;
5144834581321d60c17997d65a2360c7674f15f9bbcshiqian    return object_error::success;
515e44602ec83c65102035ce5304ae8de0cb16e9e56shiqian  }
5164834581321d60c17997d65a2360c7674f15f9bbcshiqian
5174834581321d60c17997d65a2360c7674f15f9bbcshiqian  BeginOffset = Value;
5184834581321d60c17997d65a2360c7674f15f9bbcshiqian
5194834581321d60c17997d65a2360c7674f15f9bbcshiqian  SectionIndex = Entry.n_sect;
5204834581321d60c17997d65a2360c7674f15f9bbcshiqian  if (!SectionIndex) {
5214834581321d60c17997d65a2360c7674f15f9bbcshiqian    uint32_t flags = getSymbolFlags(DRI);
5224834581321d60c17997d65a2360c7674f15f9bbcshiqian    if (flags & SymbolRef::SF_Common)
5234834581321d60c17997d65a2360c7674f15f9bbcshiqian      Result = Value;
5244834581321d60c17997d65a2360c7674f15f9bbcshiqian    else
5254834581321d60c17997d65a2360c7674f15f9bbcshiqian      Result = UnknownAddressOrSize;
5264cd62602913a032a7aec091d4c8055ff9af95e37zhanyong.wan    return object_error::success;
5274b6829f0d28990dd645e16386eb226d0f10c8731shiqian  }
5284b6829f0d28990dd645e16386eb226d0f10c8731shiqian  // Unfortunately symbols are unsorted so we need to touch all
5294b6829f0d28990dd645e16386eb226d0f10c8731shiqian  // symbols from load command
5304b6829f0d28990dd645e16386eb226d0f10c8731shiqian  for (const SymbolRef &Symbol : symbols()) {
5314b6829f0d28990dd645e16386eb226d0f10c8731shiqian    DataRefImpl DRI = Symbol.getRawDataRefImpl();
532e4092294d7c1f38f303e8c7f67da31ba3e7e7d9azhanyong.wan    Entry = getSymbolTableEntryBase(this, DRI);
533e4092294d7c1f38f303e8c7f67da31ba3e7e7d9azhanyong.wan    getSymbolAddress(DRI, Value);
534e4092294d7c1f38f303e8c7f67da31ba3e7e7d9azhanyong.wan    if (Value == UnknownAddressOrSize)
535e4092294d7c1f38f303e8c7f67da31ba3e7e7d9azhanyong.wan      continue;
5364b6829f0d28990dd645e16386eb226d0f10c8731shiqian    if (Entry.n_sect == SectionIndex && Value > BeginOffset)
5374b6829f0d28990dd645e16386eb226d0f10c8731shiqian      if (!EndOffset || Value < EndOffset)
5384b6829f0d28990dd645e16386eb226d0f10c8731shiqian        EndOffset = Value;
539e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  }
540e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  if (!EndOffset) {
541e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian    uint64_t Size;
542e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian    DataRefImpl Sec;
543e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian    Sec.d.a = SectionIndex-1;
544e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian    getSectionSize(Sec, Size);
545e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian    getSectionAddress(Sec, EndOffset);
546e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian    EndOffset += Size;
547e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  }
548e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  Result = EndOffset - BeginOffset;
549e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  return object_error::success;
550a33163a3ddbb60a6c45340e436310f78044c1a7dzhanyong.wan}
551a33163a3ddbb60a6c45340e436310f78044c1a7dzhanyong.wan
552a33163a3ddbb60a6c45340e436310f78044c1a7dzhanyong.wanerror_code MachOObjectFile::getSymbolType(DataRefImpl Symb,
553a33163a3ddbb60a6c45340e436310f78044c1a7dzhanyong.wan                                          SymbolRef::Type &Res) const {
554e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  nlist_base Entry = getSymbolTableEntryBase(this, Symb);
555e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  uint8_t n_type = Entry.n_type;
556e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian
557e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  Res = SymbolRef::ST_Other;
558e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian
559e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  // If this is a STAB debugging symbol, we can do nothing more.
560e4092294d7c1f38f303e8c7f67da31ba3e7e7d9azhanyong.wan  if (n_type & MachO::N_STAB) {
561e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian    Res = SymbolRef::ST_Debug;
562a33163a3ddbb60a6c45340e436310f78044c1a7dzhanyong.wan    return object_error::success;
563a33163a3ddbb60a6c45340e436310f78044c1a7dzhanyong.wan  }
564e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian
565e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  switch (n_type & MachO::N_TYPE) {
566e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian    case MachO::N_UNDF :
567e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian      Res = SymbolRef::ST_Unknown;
568e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian      break;
5694e08d4fffc0fd85cec52bf26ca8e60768c4db39azhanyong.wan    case MachO::N_SECT :
5704e08d4fffc0fd85cec52bf26ca8e60768c4db39azhanyong.wan      Res = SymbolRef::ST_Function;
5714e08d4fffc0fd85cec52bf26ca8e60768c4db39azhanyong.wan      break;
5729748de060f19f81fd9dd7ccabf2be4bb624237b5zhanyong.wan  }
5734e08d4fffc0fd85cec52bf26ca8e60768c4db39azhanyong.wan  return object_error::success;
5744cd62602913a032a7aec091d4c8055ff9af95e37zhanyong.wan}
575e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian
576e8ff148b4309e115da1c55089dc3b9a241a928dcshiqianuint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const {
577e4092294d7c1f38f303e8c7f67da31ba3e7e7d9azhanyong.wan  nlist_base Entry = getSymbolTableEntryBase(this, DRI);
578e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian
579e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  uint8_t MachOType = Entry.n_type;
580e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  uint16_t MachOFlags = Entry.n_desc;
581e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian
582e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  uint32_t Result = SymbolRef::SF_None;
583e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian
584e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF)
585e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian    Result |= SymbolRef::SF_Undefined;
586e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian
587e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  if (MachOType & MachO::N_STAB)
588e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian    Result |= SymbolRef::SF_FormatSpecific;
589e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian
590dd617c1bc8e67a915068e8462881fbc5e2f6ae30zhanyong.wan  if (MachOType & MachO::N_EXT) {
591c427f5e8ab231012d7663a0ee408f1225bac971azhanyong.wan    Result |= SymbolRef::SF_Global;
592e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian    if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) {
593e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian      uint64_t Value;
594e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian      getSymbolAddress(DRI, Value);
595e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian      if (Value && Value != UnknownAddressOrSize)
596e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian        Result |= SymbolRef::SF_Common;
597e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian    }
598e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  }
599e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian
600e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  if (MachOFlags & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF))
601e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian    Result |= SymbolRef::SF_Weak;
602e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian
603e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  if ((MachOType & MachO::N_TYPE) == MachO::N_ABS)
604e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian    Result |= SymbolRef::SF_Absolute;
605e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian
606e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  return Result;
607e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian}
608e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian
609e8ff148b4309e115da1c55089dc3b9a241a928dcshiqianerror_code
610e8ff148b4309e115da1c55089dc3b9a241a928dcshiqianMachOObjectFile::getSymbolSection(DataRefImpl Symb,
611e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian                                  section_iterator &Res) const {
612e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  nlist_base Entry = getSymbolTableEntryBase(this, Symb);
613e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  uint8_t index = Entry.n_sect;
614e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian
6155d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  if (index == 0) {
616e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian    Res = section_end();
617e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  } else {
618e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian    DataRefImpl DRI;
619e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian    DRI.d.a = index - 1;
620e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian    Res = section_iterator(SectionRef(DRI, this));
621e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  }
622e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian
623e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  return object_error::success;
624e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian}
625e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian
626e8ff148b4309e115da1c55089dc3b9a241a928dcshiqianvoid MachOObjectFile::moveSectionNext(DataRefImpl &Sec) const {
627e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  Sec.d.a++;
628e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian}
629e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian
630e8ff148b4309e115da1c55089dc3b9a241a928dcshiqianerror_code
631e8ff148b4309e115da1c55089dc3b9a241a928dcshiqianMachOObjectFile::getSectionName(DataRefImpl Sec, StringRef &Result) const {
632e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  ArrayRef<char> Raw = getSectionRawName(Sec);
633e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  Result = parseSegmentOrSectionName(Raw.data());
634e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  return object_error::success;
635e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian}
636e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian
637e8ff148b4309e115da1c55089dc3b9a241a928dcshiqianerror_code
638e8ff148b4309e115da1c55089dc3b9a241a928dcshiqianMachOObjectFile::getSectionAddress(DataRefImpl Sec, uint64_t &Res) const {
639e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  if (is64Bit()) {
640e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian    MachO::section_64 Sect = getSection64(Sec);
641e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian    Res = Sect.addr;
642e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  } else {
643e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian    MachO::section Sect = getSection(Sec);
644e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian    Res = Sect.addr;
645e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  }
646e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  return object_error::success;
647e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian}
648e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian
649e8ff148b4309e115da1c55089dc3b9a241a928dcshiqianerror_code
650e8ff148b4309e115da1c55089dc3b9a241a928dcshiqianMachOObjectFile::getSectionSize(DataRefImpl Sec, uint64_t &Res) const {
651e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  if (is64Bit()) {
652a33163a3ddbb60a6c45340e436310f78044c1a7dzhanyong.wan    MachO::section_64 Sect = getSection64(Sec);
653a33163a3ddbb60a6c45340e436310f78044c1a7dzhanyong.wan    Res = Sect.size;
654e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  } else {
655e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian    MachO::section Sect = getSection(Sec);
656e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian    Res = Sect.size;
657e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  }
658e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian
659e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  return object_error::success;
660e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian}
661e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian
662e8ff148b4309e115da1c55089dc3b9a241a928dcshiqianerror_code
663e8ff148b4309e115da1c55089dc3b9a241a928dcshiqianMachOObjectFile::getSectionContents(DataRefImpl Sec, StringRef &Res) const {
664e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  uint32_t Offset;
665e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  uint64_t Size;
666e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian
667e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  if (is64Bit()) {
668e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian    MachO::section_64 Sect = getSection64(Sec);
669e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian    Offset = Sect.offset;
670e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian    Size = Sect.size;
671e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  } else {
672e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian    MachO::section Sect = getSection(Sec);
673e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian    Offset = Sect.offset;
674e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian    Size = Sect.size;
675e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  }
676e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian
677e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  Res = this->getData().substr(Offset, Size);
678e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  return object_error::success;
679e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian}
680e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian
681e8ff148b4309e115da1c55089dc3b9a241a928dcshiqianerror_code
682e8ff148b4309e115da1c55089dc3b9a241a928dcshiqianMachOObjectFile::getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const {
683e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  uint32_t Align;
684e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  if (is64Bit()) {
685e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian    MachO::section_64 Sect = getSection64(Sec);
686e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian    Align = Sect.align;
687e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  } else {
688e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian    MachO::section Sect = getSection(Sec);
689e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian    Align = Sect.align;
690e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  }
691e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian
692e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  Res = uint64_t(1) << Align;
693e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  return object_error::success;
694e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian}
695e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian
696e8ff148b4309e115da1c55089dc3b9a241a928dcshiqianerror_code
697e8ff148b4309e115da1c55089dc3b9a241a928dcshiqianMachOObjectFile::isSectionText(DataRefImpl Sec, bool &Res) const {
698e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  uint32_t Flags = getSectionFlags(this, Sec);
699e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  Res = Flags & MachO::S_ATTR_PURE_INSTRUCTIONS;
70037ce949fb6ee00109391035835d4893a94f250a9zhanyong.wan  return object_error::success;
70137ce949fb6ee00109391035835d4893a94f250a9zhanyong.wan}
702e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian
703e8ff148b4309e115da1c55089dc3b9a241a928dcshiqianerror_code MachOObjectFile::isSectionData(DataRefImpl Sec, bool &Result) const {
704e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  uint32_t Flags = getSectionFlags(this, Sec);
705e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  unsigned SectionType = Flags & MachO::SECTION_TYPE;
706e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  Result = !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
707e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian           !(SectionType == MachO::S_ZEROFILL ||
708f904a612d9444ab36c07a8e619c113432e046f49vladlosev             SectionType == MachO::S_GB_ZEROFILL);
709f904a612d9444ab36c07a8e619c113432e046f49vladlosev  return object_error::success;
710f904a612d9444ab36c07a8e619c113432e046f49vladlosev}
711f904a612d9444ab36c07a8e619c113432e046f49vladlosev
712f904a612d9444ab36c07a8e619c113432e046f49vladloseverror_code MachOObjectFile::isSectionBSS(DataRefImpl Sec, bool &Result) const {
713f904a612d9444ab36c07a8e619c113432e046f49vladlosev  uint32_t Flags = getSectionFlags(this, Sec);
714f904a612d9444ab36c07a8e619c113432e046f49vladlosev  unsigned SectionType = Flags & MachO::SECTION_TYPE;
715f904a612d9444ab36c07a8e619c113432e046f49vladlosev  Result = !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
716f904a612d9444ab36c07a8e619c113432e046f49vladlosev           (SectionType == MachO::S_ZEROFILL ||
717f904a612d9444ab36c07a8e619c113432e046f49vladlosev            SectionType == MachO::S_GB_ZEROFILL);
7181ce454985edf37b17f2f266d499c2b7dec339002zhanyong.wan  return object_error::success;
7191ce454985edf37b17f2f266d499c2b7dec339002zhanyong.wan}
720f904a612d9444ab36c07a8e619c113432e046f49vladlosev
721f6d087b78d230d875bf5d8281112662795044680zhanyong.wanerror_code
722f6d087b78d230d875bf5d8281112662795044680zhanyong.wanMachOObjectFile::isSectionRequiredForExecution(DataRefImpl Sec,
723f6d087b78d230d875bf5d8281112662795044680zhanyong.wan                                               bool &Result) const {
724f6d087b78d230d875bf5d8281112662795044680zhanyong.wan  // FIXME: Unimplemented.
725e4092294d7c1f38f303e8c7f67da31ba3e7e7d9azhanyong.wan  Result = true;
726b0a12f719caf4e37894868334ce41b1864b0be53zhanyong.wan  return object_error::success;
727f6d087b78d230d875bf5d8281112662795044680zhanyong.wan}
728f6d087b78d230d875bf5d8281112662795044680zhanyong.wan
729f6d087b78d230d875bf5d8281112662795044680zhanyong.wanerror_code MachOObjectFile::isSectionVirtual(DataRefImpl Sec,
73099f2fd8ac474e2a8cf922410af199fa7a0057f7bzhanyong.wan                                             bool &Result) const {
73199f2fd8ac474e2a8cf922410af199fa7a0057f7bzhanyong.wan  // FIXME: Unimplemented.
73299f2fd8ac474e2a8cf922410af199fa7a0057f7bzhanyong.wan  Result = false;
73399f2fd8ac474e2a8cf922410af199fa7a0057f7bzhanyong.wan  return object_error::success;
73499f2fd8ac474e2a8cf922410af199fa7a0057f7bzhanyong.wan}
73599f2fd8ac474e2a8cf922410af199fa7a0057f7bzhanyong.wan
73699f2fd8ac474e2a8cf922410af199fa7a0057f7bzhanyong.wanerror_code
73799f2fd8ac474e2a8cf922410af199fa7a0057f7bzhanyong.wanMachOObjectFile::isSectionZeroInit(DataRefImpl Sec, bool &Res) const {
73899f2fd8ac474e2a8cf922410af199fa7a0057f7bzhanyong.wan  uint32_t Flags = getSectionFlags(this, Sec);
73985f555add7acc03149b76db239a4cdd18433a558zhanyong.wan  unsigned SectionType = Flags & MachO::SECTION_TYPE;
74085f555add7acc03149b76db239a4cdd18433a558zhanyong.wan  Res = SectionType == MachO::S_ZEROFILL ||
74185f555add7acc03149b76db239a4cdd18433a558zhanyong.wan    SectionType == MachO::S_GB_ZEROFILL;
74285f555add7acc03149b76db239a4cdd18433a558zhanyong.wan  return object_error::success;
74385f555add7acc03149b76db239a4cdd18433a558zhanyong.wan}
7441ce454985edf37b17f2f266d499c2b7dec339002zhanyong.wan
74585f555add7acc03149b76db239a4cdd18433a558zhanyong.wanerror_code MachOObjectFile::isSectionReadOnlyData(DataRefImpl Sec,
74685f555add7acc03149b76db239a4cdd18433a558zhanyong.wan                                                  bool &Result) const {
74785f555add7acc03149b76db239a4cdd18433a558zhanyong.wan  // Consider using the code from isSectionText to look for __const sections.
74885f555add7acc03149b76db239a4cdd18433a558zhanyong.wan  // Alternately, emit S_ATTR_PURE_INSTRUCTIONS and/or S_ATTR_SOME_INSTRUCTIONS
74985f555add7acc03149b76db239a4cdd18433a558zhanyong.wan  // to use section attributes to distinguish code from data.
75085f555add7acc03149b76db239a4cdd18433a558zhanyong.wan
75185f555add7acc03149b76db239a4cdd18433a558zhanyong.wan  // FIXME: Unimplemented.
75285f555add7acc03149b76db239a4cdd18433a558zhanyong.wan  Result = false;
75385f555add7acc03149b76db239a4cdd18433a558zhanyong.wan  return object_error::success;
75485f555add7acc03149b76db239a4cdd18433a558zhanyong.wan}
75585f555add7acc03149b76db239a4cdd18433a558zhanyong.wan
75685f555add7acc03149b76db239a4cdd18433a558zhanyong.wanerror_code
75785f555add7acc03149b76db239a4cdd18433a558zhanyong.wanMachOObjectFile::sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
75885f555add7acc03149b76db239a4cdd18433a558zhanyong.wan                                       bool &Result) const {
75985f555add7acc03149b76db239a4cdd18433a558zhanyong.wan  SymbolRef::Type ST;
76085f555add7acc03149b76db239a4cdd18433a558zhanyong.wan  this->getSymbolType(Symb, ST);
761678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  if (ST == SymbolRef::ST_Unknown) {
762678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan    Result = false;
763678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan    return object_error::success;
764678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  }
765678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
766678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  uint64_t SectBegin, SectEnd;
767678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  getSectionAddress(Sec, SectBegin);
768678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  getSectionSize(Sec, SectEnd);
769678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  SectEnd += SectBegin;
770678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
771678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  uint64_t SymAddr;
772678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  getSymbolAddress(Symb, SymAddr);
773678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd);
774678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
775678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  return object_error::success;
776678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan}
777678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
778678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wanrelocation_iterator MachOObjectFile::section_rel_begin(DataRefImpl Sec) const {
779678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  DataRefImpl Ret;
780678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  Ret.d.a = Sec.d.a;
781678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  Ret.d.b = 0;
782678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  return relocation_iterator(RelocationRef(Ret, this));
783678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan}
784678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
785678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wanrelocation_iterator
786678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wanMachOObjectFile::section_rel_end(DataRefImpl Sec) const {
787678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  uint32_t Num;
788678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  if (is64Bit()) {
789678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan    MachO::section_64 Sect = getSection64(Sec);
790678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan    Num = Sect.nreloc;
7913aa2af18a9c47b16824fe0e7462c807533fcdea7zhanyong.wan  } else {
7923aa2af18a9c47b16824fe0e7462c807533fcdea7zhanyong.wan    MachO::section Sect = getSection(Sec);
7933aa2af18a9c47b16824fe0e7462c807533fcdea7zhanyong.wan    Num = Sect.nreloc;
7943aa2af18a9c47b16824fe0e7462c807533fcdea7zhanyong.wan  }
7953aa2af18a9c47b16824fe0e7462c807533fcdea7zhanyong.wan
7963aa2af18a9c47b16824fe0e7462c807533fcdea7zhanyong.wan  DataRefImpl Ret;
797678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  Ret.d.a = Sec.d.a;
7983aa2af18a9c47b16824fe0e7462c807533fcdea7zhanyong.wan  Ret.d.b = Num;
799678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  return relocation_iterator(RelocationRef(Ret, this));
800678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan}
801585ec31ea716f08233a815e680fc0d4699843938zhanyong.wan
802678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wanvoid MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
803678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  ++Rel.d.b;
804678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan}
805678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
806678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wanerror_code
807678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wanMachOObjectFile::getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const {
808c3ad69057c28427c2a000a462468b34883853c6ezhanyong.wan  uint64_t Offset;
809c3ad69057c28427c2a000a462468b34883853c6ezhanyong.wan  getRelocationOffset(Rel, Offset);
810c3ad69057c28427c2a000a462468b34883853c6ezhanyong.wan
811c3ad69057c28427c2a000a462468b34883853c6ezhanyong.wan  DataRefImpl Sec;
812678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  Sec.d.a = Rel.d.a;
813678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  uint64_t SecAddress;
814678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  getSectionAddress(Sec, SecAddress);
815678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  Res = SecAddress + Offset;
816678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  return object_error::success;
817678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan}
818678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
819678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wanerror_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel,
820678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan                                                uint64_t &Res) const {
821678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  assert(getHeader().filetype == MachO::MH_OBJECT &&
822678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan         "Only implemented for MH_OBJECT");
823678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  MachO::any_relocation_info RE = getRelocation(Rel);
824678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  Res = getAnyRelocationAddress(RE);
825678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  return object_error::success;
826678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan}
827678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
828678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wansymbol_iterator
829678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wanMachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
830678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  MachO::any_relocation_info RE = getRelocation(Rel);
831678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE);
832678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  bool isExtern = getPlainRelocationExternal(RE);
833678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  if (!isExtern)
834678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan    return symbol_end();
835678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
836678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  MachO::symtab_command S = getSymtabLoadCommand();
837678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  unsigned SymbolTableEntrySize = is64Bit() ?
838678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan    sizeof(MachO::nlist_64) :
839678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan    sizeof(MachO::nlist);
840678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  uint64_t Offset = S.symoff + SymbolIdx * SymbolTableEntrySize;
841678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  DataRefImpl Sym;
842678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  Sym.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
843678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  return symbol_iterator(SymbolRef(Sym, this));
844678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan}
845678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
846678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wanerror_code MachOObjectFile::getRelocationType(DataRefImpl Rel,
847678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan                                              uint64_t &Res) const {
848678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  MachO::any_relocation_info RE = getRelocation(Rel);
849678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  Res = getAnyRelocationType(RE);
850678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  return object_error::success;
851678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan}
852678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
853678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wanerror_code
854678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wanMachOObjectFile::getRelocationTypeName(DataRefImpl Rel,
855678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan                                       SmallVectorImpl<char> &Result) const {
856678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  StringRef res;
857678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  uint64_t RType;
858678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  getRelocationType(Rel, RType);
859678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
860678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  unsigned Arch = this->getArch();
861678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
862678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  switch (Arch) {
863678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan    case Triple::x86: {
864678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan      static const char *const Table[] =  {
865678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        "GENERIC_RELOC_VANILLA",
866678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        "GENERIC_RELOC_PAIR",
867678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        "GENERIC_RELOC_SECTDIFF",
868678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        "GENERIC_RELOC_PB_LA_PTR",
869678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        "GENERIC_RELOC_LOCAL_SECTDIFF",
870678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        "GENERIC_RELOC_TLV" };
871733a54a398766289b74cf3daebe083d7115cf388zhanyong.wan
872733a54a398766289b74cf3daebe083d7115cf388zhanyong.wan      if (RType > 5)
873733a54a398766289b74cf3daebe083d7115cf388zhanyong.wan        res = "Unknown";
874678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan      else
875678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        res = Table[RType];
876733a54a398766289b74cf3daebe083d7115cf388zhanyong.wan      break;
877ed1042b09b7d6f7857ff3a4ad33acef08a016960zhanyong.wan    }
878ed1042b09b7d6f7857ff3a4ad33acef08a016960zhanyong.wan    case Triple::x86_64: {
879ed1042b09b7d6f7857ff3a4ad33acef08a016960zhanyong.wan      static const char *const Table[] =  {
880ed1042b09b7d6f7857ff3a4ad33acef08a016960zhanyong.wan        "X86_64_RELOC_UNSIGNED",
881ed1042b09b7d6f7857ff3a4ad33acef08a016960zhanyong.wan        "X86_64_RELOC_SIGNED",
882678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        "X86_64_RELOC_BRANCH",
883678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        "X86_64_RELOC_GOT_LOAD",
884678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        "X86_64_RELOC_GOT",
885678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        "X86_64_RELOC_SUBTRACTOR",
886678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        "X86_64_RELOC_SIGNED_1",
887678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        "X86_64_RELOC_SIGNED_2",
888678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        "X86_64_RELOC_SIGNED_4",
889678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        "X86_64_RELOC_TLV" };
890678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
891678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan      if (RType > 9)
892678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        res = "Unknown";
893678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan      else
894678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        res = Table[RType];
895678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan      break;
896678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan    }
897678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan    case Triple::arm: {
898678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan      static const char *const Table[] =  {
899678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        "ARM_RELOC_VANILLA",
9006c5116014ce51ef3273d800cbf75fcef99e798c6zhanyong.wan        "ARM_RELOC_PAIR",
9016c5116014ce51ef3273d800cbf75fcef99e798c6zhanyong.wan        "ARM_RELOC_SECTDIFF",
9026c5116014ce51ef3273d800cbf75fcef99e798c6zhanyong.wan        "ARM_RELOC_LOCAL_SECTDIFF",
9036c5116014ce51ef3273d800cbf75fcef99e798c6zhanyong.wan        "ARM_RELOC_PB_LA_PTR",
9046c5116014ce51ef3273d800cbf75fcef99e798c6zhanyong.wan        "ARM_RELOC_BR24",
9056c5116014ce51ef3273d800cbf75fcef99e798c6zhanyong.wan        "ARM_THUMB_RELOC_BR22",
9066c5116014ce51ef3273d800cbf75fcef99e798c6zhanyong.wan        "ARM_THUMB_32BIT_BRANCH",
9076c5116014ce51ef3273d800cbf75fcef99e798c6zhanyong.wan        "ARM_RELOC_HALF",
9086c5116014ce51ef3273d800cbf75fcef99e798c6zhanyong.wan        "ARM_RELOC_HALF_SECTDIFF" };
9096c5116014ce51ef3273d800cbf75fcef99e798c6zhanyong.wan
9106c5116014ce51ef3273d800cbf75fcef99e798c6zhanyong.wan      if (RType > 9)
9116c5116014ce51ef3273d800cbf75fcef99e798c6zhanyong.wan        res = "Unknown";
9126c5116014ce51ef3273d800cbf75fcef99e798c6zhanyong.wan      else
9136c5116014ce51ef3273d800cbf75fcef99e798c6zhanyong.wan        res = Table[RType];
9146c5116014ce51ef3273d800cbf75fcef99e798c6zhanyong.wan      break;
9156c5116014ce51ef3273d800cbf75fcef99e798c6zhanyong.wan    }
9166c5116014ce51ef3273d800cbf75fcef99e798c6zhanyong.wan    case Triple::arm64:
9176c5116014ce51ef3273d800cbf75fcef99e798c6zhanyong.wan    case Triple::aarch64: {
9186c5116014ce51ef3273d800cbf75fcef99e798c6zhanyong.wan      static const char *const Table[] = {
9196c5116014ce51ef3273d800cbf75fcef99e798c6zhanyong.wan        "ARM64_RELOC_UNSIGNED",           "ARM64_RELOC_SUBTRACTOR",
9206c5116014ce51ef3273d800cbf75fcef99e798c6zhanyong.wan        "ARM64_RELOC_BRANCH26",           "ARM64_RELOC_PAGE21",
921678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        "ARM64_RELOC_PAGEOFF12",          "ARM64_RELOC_GOT_LOAD_PAGE21",
922678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT",
9236c5116014ce51ef3273d800cbf75fcef99e798c6zhanyong.wan        "ARM64_RELOC_TLVP_LOAD_PAGE21",   "ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
9246c5116014ce51ef3273d800cbf75fcef99e798c6zhanyong.wan        "ARM64_RELOC_ADDEND"
9256c5116014ce51ef3273d800cbf75fcef99e798c6zhanyong.wan      };
9266c5116014ce51ef3273d800cbf75fcef99e798c6zhanyong.wan
9276c5116014ce51ef3273d800cbf75fcef99e798c6zhanyong.wan      if (RType >= array_lengthof(Table))
928678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        res = "Unknown";
929678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan      else
930678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        res = Table[RType];
9316c5116014ce51ef3273d800cbf75fcef99e798c6zhanyong.wan      break;
932678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan    }
9335e255e0b6affbdc56718d81f0bb5d1b802a1c6c2zhanyong.wan    case Triple::ppc: {
9345e255e0b6affbdc56718d81f0bb5d1b802a1c6c2zhanyong.wan      static const char *const Table[] =  {
9355e255e0b6affbdc56718d81f0bb5d1b802a1c6c2zhanyong.wan        "PPC_RELOC_VANILLA",
9365e255e0b6affbdc56718d81f0bb5d1b802a1c6c2zhanyong.wan        "PPC_RELOC_PAIR",
9375e255e0b6affbdc56718d81f0bb5d1b802a1c6c2zhanyong.wan        "PPC_RELOC_BR14",
9385e255e0b6affbdc56718d81f0bb5d1b802a1c6c2zhanyong.wan        "PPC_RELOC_BR24",
9395e255e0b6affbdc56718d81f0bb5d1b802a1c6c2zhanyong.wan        "PPC_RELOC_HI16",
940678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        "PPC_RELOC_LO16",
941678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        "PPC_RELOC_HA16",
942678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        "PPC_RELOC_LO14",
943678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        "PPC_RELOC_SECTDIFF",
944678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        "PPC_RELOC_PB_LA_PTR",
945678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        "PPC_RELOC_HI16_SECTDIFF",
946678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        "PPC_RELOC_LO16_SECTDIFF",
947678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        "PPC_RELOC_HA16_SECTDIFF",
948678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        "PPC_RELOC_JBSR",
949678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        "PPC_RELOC_LO14_SECTDIFF",
950678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        "PPC_RELOC_LOCAL_SECTDIFF" };
951678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
952678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan      if (RType > 15)
953678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        res = "Unknown";
954678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan      else
955678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        res = Table[RType];
956678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan      break;
957678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan    }
958678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan    case Triple::UnknownArch:
959678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan      res = "Unknown";
960678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan      break;
961678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  }
962678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  Result.append(res.begin(), res.end());
963678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  return object_error::success;
964678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan}
965678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
966678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wanerror_code
967678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wanMachOObjectFile::getRelocationValueString(DataRefImpl Rel,
968678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan                                          SmallVectorImpl<char> &Result) const {
969678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  MachO::any_relocation_info RE = getRelocation(Rel);
970678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
971678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  unsigned Arch = this->getArch();
972678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
973678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  std::string fmtbuf;
974678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  raw_string_ostream fmt(fmtbuf);
975678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  unsigned Type = this->getAnyRelocationType(RE);
976678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  bool IsPCRel = this->getAnyRelocationPCRel(RE);
977678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
978678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  // Determine any addends that should be displayed with the relocation.
979678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  // These require decoding the relocation type, which is triple-specific.
980678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
981678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  // X86_64 has entirely custom relocation types.
982678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  if (Arch == Triple::x86_64) {
983678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan    bool isPCRel = getAnyRelocationPCRel(RE);
984678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
985678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan    switch (Type) {
986678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan      case MachO::X86_64_RELOC_GOT_LOAD:
987678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan      case MachO::X86_64_RELOC_GOT: {
988678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        printRelocationTargetName(this, RE, fmt);
989678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        fmt << "@GOT";
990678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        if (isPCRel) fmt << "PCREL";
991678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        break;
992678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan      }
993678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan      case MachO::X86_64_RELOC_SUBTRACTOR: {
994678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        DataRefImpl RelNext = Rel;
995678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        moveRelocationNext(RelNext);
996678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        MachO::any_relocation_info RENext = getRelocation(RelNext);
997678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
998678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        // X86_64_RELOC_SUBTRACTOR must be followed by a relocation of type
999678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        // X86_64_RELOC_UNSIGNED.
1000678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        // NOTE: Scattered relocations don't exist on x86_64.
1001678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        unsigned RType = getAnyRelocationType(RENext);
1002678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        if (RType != MachO::X86_64_RELOC_UNSIGNED)
1003678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan          report_fatal_error("Expected X86_64_RELOC_UNSIGNED after "
1004678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan                             "X86_64_RELOC_SUBTRACTOR.");
1005678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
1006678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        // The X86_64_RELOC_UNSIGNED contains the minuend symbol;
1007678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        // X86_64_RELOC_SUBTRACTOR contains the subtrahend.
1008678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        printRelocationTargetName(this, RENext, fmt);
1009678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        fmt << "-";
1010678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        printRelocationTargetName(this, RE, fmt);
1011678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        break;
1012678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan      }
1013678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan      case MachO::X86_64_RELOC_TLV:
1014678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        printRelocationTargetName(this, RE, fmt);
1015678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        fmt << "@TLV";
1016678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        if (isPCRel) fmt << "P";
1017678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        break;
1018678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan      case MachO::X86_64_RELOC_SIGNED_1:
1019678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        printRelocationTargetName(this, RE, fmt);
1020678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        fmt << "-1";
1021678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        break;
1022678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan      case MachO::X86_64_RELOC_SIGNED_2:
1023678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        printRelocationTargetName(this, RE, fmt);
1024678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        fmt << "-2";
1025678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        break;
1026678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan      case MachO::X86_64_RELOC_SIGNED_4:
1027678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        printRelocationTargetName(this, RE, fmt);
1028678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        fmt << "-4";
1029678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        break;
10306c5116014ce51ef3273d800cbf75fcef99e798c6zhanyong.wan      default:
1031678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        printRelocationTargetName(this, RE, fmt);
1032678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        break;
1033678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan    }
1034678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  // X86 and ARM share some relocation types in common.
1035678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  } else if (Arch == Triple::x86 || Arch == Triple::arm ||
1036678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan             Arch == Triple::ppc) {
1037678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan    // Generic relocation types...
1038678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan    switch (Type) {
1039678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan      case MachO::GENERIC_RELOC_PAIR: // prints no info
1040678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        return object_error::success;
1041678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan      case MachO::GENERIC_RELOC_SECTDIFF: {
1042678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        DataRefImpl RelNext = Rel;
1043678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        moveRelocationNext(RelNext);
1044678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        MachO::any_relocation_info RENext = getRelocation(RelNext);
1045678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
1046678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        // X86 sect diff's must be followed by a relocation of type
1047c3ad69057c28427c2a000a462468b34883853c6ezhanyong.wan        // GENERIC_RELOC_PAIR.
1048678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        unsigned RType = getAnyRelocationType(RENext);
1049678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
1050678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        if (RType != MachO::GENERIC_RELOC_PAIR)
1051678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan          report_fatal_error("Expected GENERIC_RELOC_PAIR after "
1052678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan                             "GENERIC_RELOC_SECTDIFF.");
1053678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
1054678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        printRelocationTargetName(this, RE, fmt);
1055678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        fmt << "-";
1056678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        printRelocationTargetName(this, RENext, fmt);
1057678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        break;
1058678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan      }
1059678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan    }
1060678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
1061678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan    if (Arch == Triple::x86 || Arch == Triple::ppc) {
1062678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan      switch (Type) {
1063678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        case MachO::GENERIC_RELOC_LOCAL_SECTDIFF: {
1064678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan          DataRefImpl RelNext = Rel;
1065678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan          moveRelocationNext(RelNext);
1066678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan          MachO::any_relocation_info RENext = getRelocation(RelNext);
1067678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
1068678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan          // X86 sect diff's must be followed by a relocation of type
1069678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan          // GENERIC_RELOC_PAIR.
1070678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan          unsigned RType = getAnyRelocationType(RENext);
1071678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan          if (RType != MachO::GENERIC_RELOC_PAIR)
1072678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan            report_fatal_error("Expected GENERIC_RELOC_PAIR after "
1073678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan                               "GENERIC_RELOC_LOCAL_SECTDIFF.");
1074678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
1075678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan          printRelocationTargetName(this, RE, fmt);
1076678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan          fmt << "-";
1077678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan          printRelocationTargetName(this, RENext, fmt);
1078678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan          break;
1079678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        }
1080678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan        case MachO::GENERIC_RELOC_TLV: {
1081678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan          printRelocationTargetName(this, RE, fmt);
1082678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan          fmt << "@TLV";
10834b6829f0d28990dd645e16386eb226d0f10c8731shiqian          if (IsPCRel) fmt << "P";
10844b6829f0d28990dd645e16386eb226d0f10c8731shiqian          break;
10854b6829f0d28990dd645e16386eb226d0f10c8731shiqian        }
1086d5ad2ca82051c34b19af628a3c81131ca65010c2zhanyong.wan        default:
1087d5ad2ca82051c34b19af628a3c81131ca65010c2zhanyong.wan          printRelocationTargetName(this, RE, fmt);
10884b6829f0d28990dd645e16386eb226d0f10c8731shiqian      }
10894b6829f0d28990dd645e16386eb226d0f10c8731shiqian    } else { // ARM-specific relocations
1090d5ad2ca82051c34b19af628a3c81131ca65010c2zhanyong.wan      switch (Type) {
1091d5ad2ca82051c34b19af628a3c81131ca65010c2zhanyong.wan        case MachO::ARM_RELOC_HALF:
1092d5ad2ca82051c34b19af628a3c81131ca65010c2zhanyong.wan        case MachO::ARM_RELOC_HALF_SECTDIFF: {
1093e44602ec83c65102035ce5304ae8de0cb16e9e56shiqian          // Half relocations steal a bit from the length field to encode
1094334aaead71ccf797a18f2128c320f0304e724860zhanyong.wan          // whether this is an upper16 or a lower16 relocation.
10954b6829f0d28990dd645e16386eb226d0f10c8731shiqian          bool isUpper = getAnyRelocationLength(RE) >> 1;
1096e44602ec83c65102035ce5304ae8de0cb16e9e56shiqian
1097334aaead71ccf797a18f2128c320f0304e724860zhanyong.wan          if (isUpper)
10984b6829f0d28990dd645e16386eb226d0f10c8731shiqian            fmt << ":upper16:(";
1099e44602ec83c65102035ce5304ae8de0cb16e9e56shiqian          else
1100334aaead71ccf797a18f2128c320f0304e724860zhanyong.wan            fmt << ":lower16:(";
11014b6829f0d28990dd645e16386eb226d0f10c8731shiqian          printRelocationTargetName(this, RE, fmt);
1102e0ca02f7b4175a1c21f7416039f9f06c028b544azhanyong.wan
1103e0ca02f7b4175a1c21f7416039f9f06c028b544azhanyong.wan          DataRefImpl RelNext = Rel;
1104e0ca02f7b4175a1c21f7416039f9f06c028b544azhanyong.wan          moveRelocationNext(RelNext);
11052962b23886e9b922398b573fadfa7993f1cb26d7zhanyong.wan          MachO::any_relocation_info RENext = getRelocation(RelNext);
1106e0ca02f7b4175a1c21f7416039f9f06c028b544azhanyong.wan
1107e0ca02f7b4175a1c21f7416039f9f06c028b544azhanyong.wan          // ARM half relocs must be followed by a relocation of type
1108e44602ec83c65102035ce5304ae8de0cb16e9e56shiqian          // ARM_RELOC_PAIR.
1109e44602ec83c65102035ce5304ae8de0cb16e9e56shiqian          unsigned RType = getAnyRelocationType(RENext);
111099f2fd8ac474e2a8cf922410af199fa7a0057f7bzhanyong.wan          if (RType != MachO::ARM_RELOC_PAIR)
11119204c8ec6edda2013cd81bf3c93e9cb6c45b9bb5shiqian            report_fatal_error("Expected ARM_RELOC_PAIR after "
11129204c8ec6edda2013cd81bf3c93e9cb6c45b9bb5shiqian                               "ARM_RELOC_HALF");
11132962b23886e9b922398b573fadfa7993f1cb26d7zhanyong.wan
11149204c8ec6edda2013cd81bf3c93e9cb6c45b9bb5shiqian          // NOTE: The half of the target virtual address is stashed in the
11159204c8ec6edda2013cd81bf3c93e9cb6c45b9bb5shiqian          // address field of the secondary relocation, but we can't reverse
11169204c8ec6edda2013cd81bf3c93e9cb6c45b9bb5shiqian          // engineer the constant offset from it without decoding the movw/movt
11179204c8ec6edda2013cd81bf3c93e9cb6c45b9bb5shiqian          // instruction to find the other half in its immediate field.
11189204c8ec6edda2013cd81bf3c93e9cb6c45b9bb5shiqian
111999f2fd8ac474e2a8cf922410af199fa7a0057f7bzhanyong.wan          // ARM_RELOC_HALF_SECTDIFF encodes the second section in the
112099f2fd8ac474e2a8cf922410af199fa7a0057f7bzhanyong.wan          // symbol/section pointer of the follow-on relocation.
112199f2fd8ac474e2a8cf922410af199fa7a0057f7bzhanyong.wan          if (Type == MachO::ARM_RELOC_HALF_SECTDIFF) {
1122e44602ec83c65102035ce5304ae8de0cb16e9e56shiqian            fmt << "-";
11239204c8ec6edda2013cd81bf3c93e9cb6c45b9bb5shiqian            printRelocationTargetName(this, RENext, fmt);
11249204c8ec6edda2013cd81bf3c93e9cb6c45b9bb5shiqian          }
112599f2fd8ac474e2a8cf922410af199fa7a0057f7bzhanyong.wan
112699f2fd8ac474e2a8cf922410af199fa7a0057f7bzhanyong.wan          fmt << ")";
112799f2fd8ac474e2a8cf922410af199fa7a0057f7bzhanyong.wan          break;
1128e44602ec83c65102035ce5304ae8de0cb16e9e56shiqian        }
11299204c8ec6edda2013cd81bf3c93e9cb6c45b9bb5shiqian        default: {
11309204c8ec6edda2013cd81bf3c93e9cb6c45b9bb5shiqian          printRelocationTargetName(this, RE, fmt);
1131e44602ec83c65102035ce5304ae8de0cb16e9e56shiqian        }
113299f2fd8ac474e2a8cf922410af199fa7a0057f7bzhanyong.wan      }
11339204c8ec6edda2013cd81bf3c93e9cb6c45b9bb5shiqian    }
1134e44602ec83c65102035ce5304ae8de0cb16e9e56shiqian  } else
1135e44602ec83c65102035ce5304ae8de0cb16e9e56shiqian    printRelocationTargetName(this, RE, fmt);
113699f2fd8ac474e2a8cf922410af199fa7a0057f7bzhanyong.wan
11379204c8ec6edda2013cd81bf3c93e9cb6c45b9bb5shiqian  fmt.flush();
11382962b23886e9b922398b573fadfa7993f1cb26d7zhanyong.wan  Result.append(fmtbuf.begin(), fmtbuf.end());
11399204c8ec6edda2013cd81bf3c93e9cb6c45b9bb5shiqian  return object_error::success;
11409204c8ec6edda2013cd81bf3c93e9cb6c45b9bb5shiqian}
1141e44602ec83c65102035ce5304ae8de0cb16e9e56shiqian
11429204c8ec6edda2013cd81bf3c93e9cb6c45b9bb5shiqianerror_code
11439204c8ec6edda2013cd81bf3c93e9cb6c45b9bb5shiqianMachOObjectFile::getRelocationHidden(DataRefImpl Rel, bool &Result) const {
1144e44602ec83c65102035ce5304ae8de0cb16e9e56shiqian  unsigned Arch = getArch();
114599f2fd8ac474e2a8cf922410af199fa7a0057f7bzhanyong.wan  uint64_t Type;
114699f2fd8ac474e2a8cf922410af199fa7a0057f7bzhanyong.wan  getRelocationType(Rel, Type);
11479204c8ec6edda2013cd81bf3c93e9cb6c45b9bb5shiqian
1148e44602ec83c65102035ce5304ae8de0cb16e9e56shiqian  Result = false;
1149e44602ec83c65102035ce5304ae8de0cb16e9e56shiqian
115099f2fd8ac474e2a8cf922410af199fa7a0057f7bzhanyong.wan  // On arches that use the generic relocations, GENERIC_RELOC_PAIR
11519204c8ec6edda2013cd81bf3c93e9cb6c45b9bb5shiqian  // is always hidden.
11529204c8ec6edda2013cd81bf3c93e9cb6c45b9bb5shiqian  if (Arch == Triple::x86 || Arch == Triple::arm || Arch == Triple::ppc) {
11532962b23886e9b922398b573fadfa7993f1cb26d7zhanyong.wan    if (Type == MachO::GENERIC_RELOC_PAIR) Result = true;
11549204c8ec6edda2013cd81bf3c93e9cb6c45b9bb5shiqian  } else if (Arch == Triple::x86_64) {
11559204c8ec6edda2013cd81bf3c93e9cb6c45b9bb5shiqian    // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows
11569204c8ec6edda2013cd81bf3c93e9cb6c45b9bb5shiqian    // an X86_64_RELOC_SUBTRACTOR.
11579204c8ec6edda2013cd81bf3c93e9cb6c45b9bb5shiqian    if (Type == MachO::X86_64_RELOC_UNSIGNED && Rel.d.a > 0) {
11589204c8ec6edda2013cd81bf3c93e9cb6c45b9bb5shiqian      DataRefImpl RelPrev = Rel;
1159e44602ec83c65102035ce5304ae8de0cb16e9e56shiqian      RelPrev.d.a--;
11609204c8ec6edda2013cd81bf3c93e9cb6c45b9bb5shiqian      uint64_t PrevType;
11619204c8ec6edda2013cd81bf3c93e9cb6c45b9bb5shiqian      getRelocationType(RelPrev, PrevType);
1162e44602ec83c65102035ce5304ae8de0cb16e9e56shiqian      if (PrevType == MachO::X86_64_RELOC_SUBTRACTOR)
116399f2fd8ac474e2a8cf922410af199fa7a0057f7bzhanyong.wan        Result = true;
116499f2fd8ac474e2a8cf922410af199fa7a0057f7bzhanyong.wan    }
11659204c8ec6edda2013cd81bf3c93e9cb6c45b9bb5shiqian  }
11669204c8ec6edda2013cd81bf3c93e9cb6c45b9bb5shiqian
1167fbd53a53c1e01dec71c65754cf73282e4759bc40vladlosev  return object_error::success;
1168fbd53a53c1e01dec71c65754cf73282e4759bc40vladlosev}
1169fbd53a53c1e01dec71c65754cf73282e4759bc40vladlosev
1170fbd53a53c1e01dec71c65754cf73282e4759bc40vladloseverror_code MachOObjectFile::getLibraryNext(DataRefImpl LibData,
1171e44602ec83c65102035ce5304ae8de0cb16e9e56shiqian                                           LibraryRef &Res) const {
1172fbd53a53c1e01dec71c65754cf73282e4759bc40vladlosev  report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
1173fbd53a53c1e01dec71c65754cf73282e4759bc40vladlosev}
11744b6829f0d28990dd645e16386eb226d0f10c8731shiqian
11754b6829f0d28990dd645e16386eb226d0f10c8731shiqianerror_code MachOObjectFile::getLibraryPath(DataRefImpl LibData,
1176fbd53a53c1e01dec71c65754cf73282e4759bc40vladlosev                                           StringRef &Res) const {
1177fbd53a53c1e01dec71c65754cf73282e4759bc40vladlosev  report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
11784b6829f0d28990dd645e16386eb226d0f10c8731shiqian}
1179e44602ec83c65102035ce5304ae8de0cb16e9e56shiqian
1180e44602ec83c65102035ce5304ae8de0cb16e9e56shiqianbasic_symbol_iterator MachOObjectFile::symbol_begin_impl() const {
118199f2fd8ac474e2a8cf922410af199fa7a0057f7bzhanyong.wan  return getSymbolByIndex(0);
1182e44602ec83c65102035ce5304ae8de0cb16e9e56shiqian}
11832962b23886e9b922398b573fadfa7993f1cb26d7zhanyong.wan
1184e44602ec83c65102035ce5304ae8de0cb16e9e56shiqianbasic_symbol_iterator MachOObjectFile::symbol_end_impl() const {
1185e44602ec83c65102035ce5304ae8de0cb16e9e56shiqian  DataRefImpl DRI;
1186e44602ec83c65102035ce5304ae8de0cb16e9e56shiqian  if (!SymtabLoadCmd)
1187e44602ec83c65102035ce5304ae8de0cb16e9e56shiqian    return basic_symbol_iterator(SymbolRef(DRI, this));
1188e44602ec83c65102035ce5304ae8de0cb16e9e56shiqian
118999f2fd8ac474e2a8cf922410af199fa7a0057f7bzhanyong.wan  MachO::symtab_command Symtab = getSymtabLoadCommand();
119099f2fd8ac474e2a8cf922410af199fa7a0057f7bzhanyong.wan  unsigned SymbolTableEntrySize = is64Bit() ?
119199f2fd8ac474e2a8cf922410af199fa7a0057f7bzhanyong.wan    sizeof(MachO::nlist_64) :
1192e44602ec83c65102035ce5304ae8de0cb16e9e56shiqian    sizeof(MachO::nlist);
1193e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  unsigned Offset = Symtab.symoff +
1194e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian    Symtab.nsyms * SymbolTableEntrySize;
1195e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1196e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  return basic_symbol_iterator(SymbolRef(DRI, this));
11974b6829f0d28990dd645e16386eb226d0f10c8731shiqian}
1198fe6a9a48c2a8280439e58c2e9020268a80df89b3shiqian
1199e8ff148b4309e115da1c55089dc3b9a241a928dcshiqianbasic_symbol_iterator MachOObjectFile::getSymbolByIndex(unsigned Index) const {
12004b6829f0d28990dd645e16386eb226d0f10c8731shiqian  DataRefImpl DRI;
1201e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  if (!SymtabLoadCmd)
12024b6829f0d28990dd645e16386eb226d0f10c8731shiqian    return basic_symbol_iterator(SymbolRef(DRI, this));
12034b6829f0d28990dd645e16386eb226d0f10c8731shiqian
12045e255e0b6affbdc56718d81f0bb5d1b802a1c6c2zhanyong.wan  MachO::symtab_command Symtab = getSymtabLoadCommand();
1205e44602ec83c65102035ce5304ae8de0cb16e9e56shiqian  assert(Index < Symtab.nsyms && "Requested symbol index is out of range.");
1206e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  unsigned SymbolTableEntrySize =
12074b6829f0d28990dd645e16386eb226d0f10c8731shiqian    is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
12084b6829f0d28990dd645e16386eb226d0f10c8731shiqian  DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff));
1209e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  DRI.p += Index * SymbolTableEntrySize;
1210e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian  return basic_symbol_iterator(SymbolRef(DRI, this));
1211e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian}
1212a33163a3ddbb60a6c45340e436310f78044c1a7dzhanyong.wan
1213fe6a9a48c2a8280439e58c2e9020268a80df89b3shiqiansection_iterator MachOObjectFile::section_begin() const {
12144834581321d60c17997d65a2360c7674f15f9bbcshiqian  DataRefImpl DRI;
12154834581321d60c17997d65a2360c7674f15f9bbcshiqian  return section_iterator(SectionRef(DRI, this));
12164834581321d60c17997d65a2360c7674f15f9bbcshiqian}
1217e8ff148b4309e115da1c55089dc3b9a241a928dcshiqian
1218e8ff148b4309e115da1c55089dc3b9a241a928dcshiqiansection_iterator MachOObjectFile::section_end() const {
12194b6829f0d28990dd645e16386eb226d0f10c8731shiqian  DataRefImpl DRI;
12204b6829f0d28990dd645e16386eb226d0f10c8731shiqian  DRI.d.a = Sections.size();
1221  return section_iterator(SectionRef(DRI, this));
1222}
1223
1224library_iterator MachOObjectFile::needed_library_begin() const {
1225  // TODO: implement
1226  report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
1227}
1228
1229library_iterator MachOObjectFile::needed_library_end() const {
1230  // TODO: implement
1231  report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
1232}
1233
1234uint8_t MachOObjectFile::getBytesInAddress() const {
1235  return is64Bit() ? 8 : 4;
1236}
1237
1238StringRef MachOObjectFile::getFileFormatName() const {
1239  unsigned CPUType = getCPUType(this);
1240  if (!is64Bit()) {
1241    switch (CPUType) {
1242    case llvm::MachO::CPU_TYPE_I386:
1243      return "Mach-O 32-bit i386";
1244    case llvm::MachO::CPU_TYPE_ARM:
1245      return "Mach-O arm";
1246    case llvm::MachO::CPU_TYPE_POWERPC:
1247      return "Mach-O 32-bit ppc";
1248    default:
1249      assert((CPUType & llvm::MachO::CPU_ARCH_ABI64) == 0 &&
1250             "64-bit object file when we're not 64-bit?");
1251      return "Mach-O 32-bit unknown";
1252    }
1253  }
1254
1255  // Make sure the cpu type has the correct mask.
1256  assert((CPUType & llvm::MachO::CPU_ARCH_ABI64)
1257         == llvm::MachO::CPU_ARCH_ABI64 &&
1258         "32-bit object file when we're 64-bit?");
1259
1260  switch (CPUType) {
1261  case llvm::MachO::CPU_TYPE_X86_64:
1262    return "Mach-O 64-bit x86-64";
1263  case llvm::MachO::CPU_TYPE_ARM64:
1264    return "Mach-O arm64";
1265  case llvm::MachO::CPU_TYPE_POWERPC64:
1266    return "Mach-O 64-bit ppc64";
1267  default:
1268    return "Mach-O 64-bit unknown";
1269  }
1270}
1271
1272Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) {
1273  switch (CPUType) {
1274  case llvm::MachO::CPU_TYPE_I386:
1275    return Triple::x86;
1276  case llvm::MachO::CPU_TYPE_X86_64:
1277    return Triple::x86_64;
1278  case llvm::MachO::CPU_TYPE_ARM:
1279    return Triple::arm;
1280  case llvm::MachO::CPU_TYPE_ARM64:
1281    return Triple::arm64;
1282  case llvm::MachO::CPU_TYPE_POWERPC:
1283    return Triple::ppc;
1284  case llvm::MachO::CPU_TYPE_POWERPC64:
1285    return Triple::ppc64;
1286  default:
1287    return Triple::UnknownArch;
1288  }
1289}
1290
1291unsigned MachOObjectFile::getArch() const {
1292  return getArch(getCPUType(this));
1293}
1294
1295StringRef MachOObjectFile::getLoadName() const {
1296  // TODO: Implement
1297  report_fatal_error("get_load_name() unimplemented in MachOObjectFile");
1298}
1299
1300relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const {
1301  DataRefImpl DRI;
1302  DRI.d.a = Index;
1303  return section_rel_begin(DRI);
1304}
1305
1306relocation_iterator MachOObjectFile::section_rel_end(unsigned Index) const {
1307  DataRefImpl DRI;
1308  DRI.d.a = Index;
1309  return section_rel_end(DRI);
1310}
1311
1312dice_iterator MachOObjectFile::begin_dices() const {
1313  DataRefImpl DRI;
1314  if (!DataInCodeLoadCmd)
1315    return dice_iterator(DiceRef(DRI, this));
1316
1317  MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1318  DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, DicLC.dataoff));
1319  return dice_iterator(DiceRef(DRI, this));
1320}
1321
1322dice_iterator MachOObjectFile::end_dices() const {
1323  DataRefImpl DRI;
1324  if (!DataInCodeLoadCmd)
1325    return dice_iterator(DiceRef(DRI, this));
1326
1327  MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1328  unsigned Offset = DicLC.dataoff + DicLC.datasize;
1329  DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1330  return dice_iterator(DiceRef(DRI, this));
1331}
1332
1333StringRef
1334MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const {
1335  ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);
1336  return parseSegmentOrSectionName(Raw.data());
1337}
1338
1339ArrayRef<char>
1340MachOObjectFile::getSectionRawName(DataRefImpl Sec) const {
1341  const section_base *Base =
1342    reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
1343  return ArrayRef<char>(Base->sectname);
1344}
1345
1346ArrayRef<char>
1347MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
1348  const section_base *Base =
1349    reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
1350  return ArrayRef<char>(Base->segname);
1351}
1352
1353bool
1354MachOObjectFile::isRelocationScattered(const MachO::any_relocation_info &RE)
1355  const {
1356  if (getCPUType(this) == MachO::CPU_TYPE_X86_64)
1357    return false;
1358  return getPlainRelocationAddress(RE) & MachO::R_SCATTERED;
1359}
1360
1361unsigned MachOObjectFile::getPlainRelocationSymbolNum(
1362    const MachO::any_relocation_info &RE) const {
1363  if (isLittleEndian())
1364    return RE.r_word1 & 0xffffff;
1365  return RE.r_word1 >> 8;
1366}
1367
1368bool MachOObjectFile::getPlainRelocationExternal(
1369    const MachO::any_relocation_info &RE) const {
1370  if (isLittleEndian())
1371    return (RE.r_word1 >> 27) & 1;
1372  return (RE.r_word1 >> 4) & 1;
1373}
1374
1375bool MachOObjectFile::getScatteredRelocationScattered(
1376    const MachO::any_relocation_info &RE) const {
1377  return RE.r_word0 >> 31;
1378}
1379
1380uint32_t MachOObjectFile::getScatteredRelocationValue(
1381    const MachO::any_relocation_info &RE) const {
1382  return RE.r_word1;
1383}
1384
1385unsigned MachOObjectFile::getAnyRelocationAddress(
1386    const MachO::any_relocation_info &RE) const {
1387  if (isRelocationScattered(RE))
1388    return getScatteredRelocationAddress(RE);
1389  return getPlainRelocationAddress(RE);
1390}
1391
1392unsigned MachOObjectFile::getAnyRelocationPCRel(
1393    const MachO::any_relocation_info &RE) const {
1394  if (isRelocationScattered(RE))
1395    return getScatteredRelocationPCRel(this, RE);
1396  return getPlainRelocationPCRel(this, RE);
1397}
1398
1399unsigned MachOObjectFile::getAnyRelocationLength(
1400    const MachO::any_relocation_info &RE) const {
1401  if (isRelocationScattered(RE))
1402    return getScatteredRelocationLength(RE);
1403  return getPlainRelocationLength(this, RE);
1404}
1405
1406unsigned
1407MachOObjectFile::getAnyRelocationType(
1408                                   const MachO::any_relocation_info &RE) const {
1409  if (isRelocationScattered(RE))
1410    return getScatteredRelocationType(RE);
1411  return getPlainRelocationType(this, RE);
1412}
1413
1414SectionRef
1415MachOObjectFile::getRelocationSection(
1416                                   const MachO::any_relocation_info &RE) const {
1417  if (isRelocationScattered(RE) || getPlainRelocationExternal(RE))
1418    return *section_end();
1419  unsigned SecNum = getPlainRelocationSymbolNum(RE) - 1;
1420  DataRefImpl DRI;
1421  DRI.d.a = SecNum;
1422  return SectionRef(DRI, this);
1423}
1424
1425MachOObjectFile::LoadCommandInfo
1426MachOObjectFile::getFirstLoadCommandInfo() const {
1427  MachOObjectFile::LoadCommandInfo Load;
1428
1429  unsigned HeaderSize = is64Bit() ? sizeof(MachO::mach_header_64) :
1430                                    sizeof(MachO::mach_header);
1431  Load.Ptr = getPtr(this, HeaderSize);
1432  Load.C = getStruct<MachO::load_command>(this, Load.Ptr);
1433  return Load;
1434}
1435
1436MachOObjectFile::LoadCommandInfo
1437MachOObjectFile::getNextLoadCommandInfo(const LoadCommandInfo &L) const {
1438  MachOObjectFile::LoadCommandInfo Next;
1439  Next.Ptr = L.Ptr + L.C.cmdsize;
1440  Next.C = getStruct<MachO::load_command>(this, Next.Ptr);
1441  return Next;
1442}
1443
1444MachO::section MachOObjectFile::getSection(DataRefImpl DRI) const {
1445  return getStruct<MachO::section>(this, Sections[DRI.d.a]);
1446}
1447
1448MachO::section_64 MachOObjectFile::getSection64(DataRefImpl DRI) const {
1449  return getStruct<MachO::section_64>(this, Sections[DRI.d.a]);
1450}
1451
1452MachO::section MachOObjectFile::getSection(const LoadCommandInfo &L,
1453                                           unsigned Index) const {
1454  const char *Sec = getSectionPtr(this, L, Index);
1455  return getStruct<MachO::section>(this, Sec);
1456}
1457
1458MachO::section_64 MachOObjectFile::getSection64(const LoadCommandInfo &L,
1459                                                unsigned Index) const {
1460  const char *Sec = getSectionPtr(this, L, Index);
1461  return getStruct<MachO::section_64>(this, Sec);
1462}
1463
1464MachO::nlist
1465MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {
1466  const char *P = reinterpret_cast<const char *>(DRI.p);
1467  return getStruct<MachO::nlist>(this, P);
1468}
1469
1470MachO::nlist_64
1471MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const {
1472  const char *P = reinterpret_cast<const char *>(DRI.p);
1473  return getStruct<MachO::nlist_64>(this, P);
1474}
1475
1476MachO::linkedit_data_command
1477MachOObjectFile::getLinkeditDataLoadCommand(const LoadCommandInfo &L) const {
1478  return getStruct<MachO::linkedit_data_command>(this, L.Ptr);
1479}
1480
1481MachO::segment_command
1482MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const {
1483  return getStruct<MachO::segment_command>(this, L.Ptr);
1484}
1485
1486MachO::segment_command_64
1487MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const {
1488  return getStruct<MachO::segment_command_64>(this, L.Ptr);
1489}
1490
1491MachO::linker_options_command
1492MachOObjectFile::getLinkerOptionsLoadCommand(const LoadCommandInfo &L) const {
1493  return getStruct<MachO::linker_options_command>(this, L.Ptr);
1494}
1495
1496MachO::version_min_command
1497MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const {
1498  return getStruct<MachO::version_min_command>(this, L.Ptr);
1499}
1500
1501MachO::any_relocation_info
1502MachOObjectFile::getRelocation(DataRefImpl Rel) const {
1503  DataRefImpl Sec;
1504  Sec.d.a = Rel.d.a;
1505  uint32_t Offset;
1506  if (is64Bit()) {
1507    MachO::section_64 Sect = getSection64(Sec);
1508    Offset = Sect.reloff;
1509  } else {
1510    MachO::section Sect = getSection(Sec);
1511    Offset = Sect.reloff;
1512  }
1513
1514  auto P = reinterpret_cast<const MachO::any_relocation_info *>(
1515      getPtr(this, Offset)) + Rel.d.b;
1516  return getStruct<MachO::any_relocation_info>(
1517      this, reinterpret_cast<const char *>(P));
1518}
1519
1520MachO::data_in_code_entry
1521MachOObjectFile::getDice(DataRefImpl Rel) const {
1522  const char *P = reinterpret_cast<const char *>(Rel.p);
1523  return getStruct<MachO::data_in_code_entry>(this, P);
1524}
1525
1526MachO::mach_header MachOObjectFile::getHeader() const {
1527  return getStruct<MachO::mach_header>(this, getPtr(this, 0));
1528}
1529
1530MachO::mach_header_64 MachOObjectFile::getHeader64() const {
1531  return getStruct<MachO::mach_header_64>(this, getPtr(this, 0));
1532}
1533
1534uint32_t MachOObjectFile::getIndirectSymbolTableEntry(
1535                                             const MachO::dysymtab_command &DLC,
1536                                             unsigned Index) const {
1537  uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t);
1538  return getStruct<uint32_t>(this, getPtr(this, Offset));
1539}
1540
1541MachO::data_in_code_entry
1542MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset,
1543                                         unsigned Index) const {
1544  uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry);
1545  return getStruct<MachO::data_in_code_entry>(this, getPtr(this, Offset));
1546}
1547
1548MachO::symtab_command MachOObjectFile::getSymtabLoadCommand() const {
1549  return getStruct<MachO::symtab_command>(this, SymtabLoadCmd);
1550}
1551
1552MachO::dysymtab_command MachOObjectFile::getDysymtabLoadCommand() const {
1553  return getStruct<MachO::dysymtab_command>(this, DysymtabLoadCmd);
1554}
1555
1556MachO::linkedit_data_command
1557MachOObjectFile::getDataInCodeLoadCommand() const {
1558  if (DataInCodeLoadCmd)
1559    return getStruct<MachO::linkedit_data_command>(this, DataInCodeLoadCmd);
1560
1561  // If there is no DataInCodeLoadCmd return a load command with zero'ed fields.
1562  MachO::linkedit_data_command Cmd;
1563  Cmd.cmd = MachO::LC_DATA_IN_CODE;
1564  Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
1565  Cmd.dataoff = 0;
1566  Cmd.datasize = 0;
1567  return Cmd;
1568}
1569
1570StringRef MachOObjectFile::getStringTableData() const {
1571  MachO::symtab_command S = getSymtabLoadCommand();
1572  return getData().substr(S.stroff, S.strsize);
1573}
1574
1575bool MachOObjectFile::is64Bit() const {
1576  return getType() == getMachOType(false, true) ||
1577    getType() == getMachOType(true, true);
1578}
1579
1580void MachOObjectFile::ReadULEB128s(uint64_t Index,
1581                                   SmallVectorImpl<uint64_t> &Out) const {
1582  DataExtractor extractor(ObjectFile::getData(), true, 0);
1583
1584  uint32_t offset = Index;
1585  uint64_t data = 0;
1586  while (uint64_t delta = extractor.getULEB128(&offset)) {
1587    data += delta;
1588    Out.push_back(data);
1589  }
1590}
1591
1592ErrorOr<ObjectFile *> ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer,
1593                                                        bool BufferOwned) {
1594  StringRef Magic = Buffer->getBuffer().slice(0, 4);
1595  error_code EC;
1596  std::unique_ptr<MachOObjectFile> Ret;
1597  if (Magic == "\xFE\xED\xFA\xCE")
1598    Ret.reset(new MachOObjectFile(Buffer, false, false, EC, BufferOwned));
1599  else if (Magic == "\xCE\xFA\xED\xFE")
1600    Ret.reset(new MachOObjectFile(Buffer, true, false, EC, BufferOwned));
1601  else if (Magic == "\xFE\xED\xFA\xCF")
1602    Ret.reset(new MachOObjectFile(Buffer, false, true, EC, BufferOwned));
1603  else if (Magic == "\xCF\xFA\xED\xFE")
1604    Ret.reset(new MachOObjectFile(Buffer, true, true, EC, BufferOwned));
1605  else {
1606    delete Buffer;
1607    return object_error::parse_failed;
1608  }
1609
1610  if (EC)
1611    return EC;
1612  return Ret.release();
1613}
1614
1615} // end namespace object
1616} // end namespace llvm
1617