xref: /aosp_15_r20/external/vixl/examples/aarch32/disasm-a32.cc (revision f5c631da2f1efdd72b5fd1e20510e4042af13d77)
1*f5c631daSSadaf Ebrahimi // Copyright 2016, VIXL authors
2*f5c631daSSadaf Ebrahimi // All rights reserved.
3*f5c631daSSadaf Ebrahimi //
4*f5c631daSSadaf Ebrahimi // Redistribution and use in source and binary forms, with or without
5*f5c631daSSadaf Ebrahimi // modification, are permitted provided that the following conditions are met:
6*f5c631daSSadaf Ebrahimi //
7*f5c631daSSadaf Ebrahimi //   * Redistributions of source code must retain the above copyright notice,
8*f5c631daSSadaf Ebrahimi //     this list of conditions and the following disclaimer.
9*f5c631daSSadaf Ebrahimi //   * Redistributions in binary form must reproduce the above copyright notice,
10*f5c631daSSadaf Ebrahimi //     this list of conditions and the following disclaimer in the documentation
11*f5c631daSSadaf Ebrahimi //     and/or other materials provided with the distribution.
12*f5c631daSSadaf Ebrahimi //   * Neither the name of ARM Limited nor the names of its contributors may be
13*f5c631daSSadaf Ebrahimi //     used to endorse or promote products derived from this software without
14*f5c631daSSadaf Ebrahimi //     specific prior written permission.
15*f5c631daSSadaf Ebrahimi //
16*f5c631daSSadaf Ebrahimi // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17*f5c631daSSadaf Ebrahimi // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18*f5c631daSSadaf Ebrahimi // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19*f5c631daSSadaf Ebrahimi // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20*f5c631daSSadaf Ebrahimi // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21*f5c631daSSadaf Ebrahimi // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22*f5c631daSSadaf Ebrahimi // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23*f5c631daSSadaf Ebrahimi // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24*f5c631daSSadaf Ebrahimi // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25*f5c631daSSadaf Ebrahimi // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*f5c631daSSadaf Ebrahimi 
27*f5c631daSSadaf Ebrahimi 
28*f5c631daSSadaf Ebrahimi // The example assumes support for ELF binaries.
29*f5c631daSSadaf Ebrahimi #ifdef __linux__
30*f5c631daSSadaf Ebrahimi 
31*f5c631daSSadaf Ebrahimi extern "C" {
32*f5c631daSSadaf Ebrahimi #include <elf.h>
33*f5c631daSSadaf Ebrahimi #include <fcntl.h>
34*f5c631daSSadaf Ebrahimi #include <stdint.h>
35*f5c631daSSadaf Ebrahimi #include <sys/mman.h>
36*f5c631daSSadaf Ebrahimi #include <sys/stat.h>
37*f5c631daSSadaf Ebrahimi #include <sys/types.h>
38*f5c631daSSadaf Ebrahimi #include <unistd.h>
39*f5c631daSSadaf Ebrahimi }
40*f5c631daSSadaf Ebrahimi 
41*f5c631daSSadaf Ebrahimi #include <cerrno>
42*f5c631daSSadaf Ebrahimi #include <iostream>
43*f5c631daSSadaf Ebrahimi #include <map>
44*f5c631daSSadaf Ebrahimi #include <string>
45*f5c631daSSadaf Ebrahimi 
46*f5c631daSSadaf Ebrahimi #include "globals-vixl.h"
47*f5c631daSSadaf Ebrahimi #include "aarch32/disasm-aarch32.h"
48*f5c631daSSadaf Ebrahimi #include "aarch32/instructions-aarch32.h"
49*f5c631daSSadaf Ebrahimi 
50*f5c631daSSadaf Ebrahimi class Symbol {
51*f5c631daSSadaf Ebrahimi   Elf32_Addr addr_;
52*f5c631daSSadaf Ebrahimi   int32_t offset_;
53*f5c631daSSadaf Ebrahimi   uint32_t size_;
54*f5c631daSSadaf Ebrahimi   int section_;
55*f5c631daSSadaf Ebrahimi   std::string name_;
56*f5c631daSSadaf Ebrahimi 
57*f5c631daSSadaf Ebrahimi  public:
Symbol(const char * name,Elf32_Addr addr,int32_t offset,uint32_t size,int section)58*f5c631daSSadaf Ebrahimi   Symbol(const char* name,
59*f5c631daSSadaf Ebrahimi          Elf32_Addr addr,
60*f5c631daSSadaf Ebrahimi          int32_t offset,
61*f5c631daSSadaf Ebrahimi          uint32_t size,
62*f5c631daSSadaf Ebrahimi          int section)
63*f5c631daSSadaf Ebrahimi       : addr_(addr),
64*f5c631daSSadaf Ebrahimi         offset_(offset),
65*f5c631daSSadaf Ebrahimi         size_(size),
66*f5c631daSSadaf Ebrahimi         section_(section),
67*f5c631daSSadaf Ebrahimi         name_(name) {}
Symbol(const Symbol & ref)68*f5c631daSSadaf Ebrahimi   Symbol(const Symbol& ref)
69*f5c631daSSadaf Ebrahimi       : addr_(ref.addr_),
70*f5c631daSSadaf Ebrahimi         offset_(ref.offset_),
71*f5c631daSSadaf Ebrahimi         size_(ref.size_),
72*f5c631daSSadaf Ebrahimi         section_(ref.section_),
73*f5c631daSSadaf Ebrahimi         name_(ref.name_) {}
74*f5c631daSSadaf Ebrahimi 
GetAddress() const75*f5c631daSSadaf Ebrahimi   Elf32_Addr GetAddress() const { return addr_; }
GetMemoryAddress() const76*f5c631daSSadaf Ebrahimi   Elf32_Addr GetMemoryAddress() const { return (addr_ & ~1) + offset_; }
GetSize() const77*f5c631daSSadaf Ebrahimi   uint32_t GetSize() const { return size_; }
GetName() const78*f5c631daSSadaf Ebrahimi   const std::string& GetName() const { return name_; }
GetSection() const79*f5c631daSSadaf Ebrahimi   int GetSection() const { return section_; }
80*f5c631daSSadaf Ebrahimi };
81*f5c631daSSadaf Ebrahimi 
82*f5c631daSSadaf Ebrahimi 
83*f5c631daSSadaf Ebrahimi class SymbolTable : public std::map<Elf32_Addr, Symbol> {
84*f5c631daSSadaf Ebrahimi  public:
insert(const Symbol & sym)85*f5c631daSSadaf Ebrahimi   void insert(const Symbol& sym) {
86*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(find(sym.GetAddress()) == end());
87*f5c631daSSadaf Ebrahimi     std::map<Elf32_Addr, Symbol>::insert(
88*f5c631daSSadaf Ebrahimi         std::make_pair(sym.GetMemoryAddress(), sym));
89*f5c631daSSadaf Ebrahimi   }
90*f5c631daSSadaf Ebrahimi };
91*f5c631daSSadaf Ebrahimi 
92*f5c631daSSadaf Ebrahimi 
93*f5c631daSSadaf Ebrahimi class SectionLocator {
94*f5c631daSSadaf Ebrahimi   const Elf32_Shdr* shdr_;
95*f5c631daSSadaf Ebrahimi   int nsections_;
96*f5c631daSSadaf Ebrahimi   const char* shstrtab_;
97*f5c631daSSadaf Ebrahimi 
98*f5c631daSSadaf Ebrahimi  public:
SectionLocator(const Elf32_Ehdr * ehdr)99*f5c631daSSadaf Ebrahimi   explicit SectionLocator(const Elf32_Ehdr* ehdr) {
100*f5c631daSSadaf Ebrahimi     shdr_ = reinterpret_cast<const Elf32_Shdr*>(
101*f5c631daSSadaf Ebrahimi         reinterpret_cast<const char*>(ehdr) + ehdr->e_shoff);
102*f5c631daSSadaf Ebrahimi     // shstrtab holds the section names as an offset in the file.
103*f5c631daSSadaf Ebrahimi     shstrtab_ =
104*f5c631daSSadaf Ebrahimi         reinterpret_cast<const char*>(ehdr) + shdr_[ehdr->e_shstrndx].sh_offset;
105*f5c631daSSadaf Ebrahimi     nsections_ = ehdr->e_shnum;
106*f5c631daSSadaf Ebrahimi   }
107*f5c631daSSadaf Ebrahimi 
Locate(Elf32_Word type,const std::string & section_name) const108*f5c631daSSadaf Ebrahimi   const Elf32_Shdr* Locate(Elf32_Word type,
109*f5c631daSSadaf Ebrahimi                            const std::string& section_name) const {
110*f5c631daSSadaf Ebrahimi     for (int shnum = 1; shnum < nsections_; shnum++) {
111*f5c631daSSadaf Ebrahimi       if ((shdr_[shnum].sh_type == type) &&
112*f5c631daSSadaf Ebrahimi           std::string(shstrtab_ + shdr_[shnum].sh_name) == section_name) {
113*f5c631daSSadaf Ebrahimi         return &shdr_[shnum];
114*f5c631daSSadaf Ebrahimi       }
115*f5c631daSSadaf Ebrahimi     }
116*f5c631daSSadaf Ebrahimi     return NULL;
117*f5c631daSSadaf Ebrahimi   }
118*f5c631daSSadaf Ebrahimi };
119*f5c631daSSadaf Ebrahimi 
120*f5c631daSSadaf Ebrahimi 
121*f5c631daSSadaf Ebrahimi template <typename VISITOR>
LocateSymbols(const Elf32_Ehdr * ehdr,const Elf32_Shdr * symtab,const Elf32_Shdr * strtab,VISITOR * visitor)122*f5c631daSSadaf Ebrahimi void LocateSymbols(const Elf32_Ehdr* ehdr,
123*f5c631daSSadaf Ebrahimi                    const Elf32_Shdr* symtab,
124*f5c631daSSadaf Ebrahimi                    const Elf32_Shdr* strtab,
125*f5c631daSSadaf Ebrahimi                    VISITOR* visitor) {
126*f5c631daSSadaf Ebrahimi   if ((symtab != NULL) && (strtab != NULL)) {
127*f5c631daSSadaf Ebrahimi     const Elf32_Shdr* shdr = reinterpret_cast<const Elf32_Shdr*>(
128*f5c631daSSadaf Ebrahimi         reinterpret_cast<const char*>(ehdr) + ehdr->e_shoff);
129*f5c631daSSadaf Ebrahimi 
130*f5c631daSSadaf Ebrahimi     const char* symnames =
131*f5c631daSSadaf Ebrahimi         reinterpret_cast<const char*>(ehdr) + strtab->sh_offset;
132*f5c631daSSadaf Ebrahimi     VIXL_CHECK(symnames != NULL);
133*f5c631daSSadaf Ebrahimi 
134*f5c631daSSadaf Ebrahimi     int nsym = symtab->sh_size / symtab->sh_entsize;
135*f5c631daSSadaf Ebrahimi     const Elf32_Sym* sym = reinterpret_cast<const Elf32_Sym*>(
136*f5c631daSSadaf Ebrahimi         reinterpret_cast<const char*>(ehdr) + symtab->sh_offset);
137*f5c631daSSadaf Ebrahimi     for (int snum = 0; snum < nsym; snum++) {
138*f5c631daSSadaf Ebrahimi       if ((sym[snum].st_shndx > 0) && (sym[snum].st_shndx < ehdr->e_shnum) &&
139*f5c631daSSadaf Ebrahimi           (sym[snum].st_value != 0) &&
140*f5c631daSSadaf Ebrahimi           (shdr[sym[snum].st_shndx].sh_type == SHT_PROGBITS) &&
141*f5c631daSSadaf Ebrahimi           ((ELF32_ST_BIND(sym[snum].st_info) == STB_LOCAL) ||
142*f5c631daSSadaf Ebrahimi            (ELF32_ST_BIND(sym[snum].st_info) == STB_GLOBAL)) &&
143*f5c631daSSadaf Ebrahimi           (ELF32_ST_TYPE(sym[snum].st_info) == STT_FUNC)) {
144*f5c631daSSadaf Ebrahimi         visitor->visit(symnames + sym[snum].st_name, sym[snum]);
145*f5c631daSSadaf Ebrahimi       }
146*f5c631daSSadaf Ebrahimi     }
147*f5c631daSSadaf Ebrahimi   }
148*f5c631daSSadaf Ebrahimi }
149*f5c631daSSadaf Ebrahimi 
150*f5c631daSSadaf Ebrahimi 
151*f5c631daSSadaf Ebrahimi class DynamicSymbolVisitor {
152*f5c631daSSadaf Ebrahimi   SymbolTable* symbols_;
153*f5c631daSSadaf Ebrahimi 
154*f5c631daSSadaf Ebrahimi  public:
DynamicSymbolVisitor(SymbolTable * symbols)155*f5c631daSSadaf Ebrahimi   explicit DynamicSymbolVisitor(SymbolTable* symbols) : symbols_(symbols) {}
visit(const char * symname,const Elf32_Sym & sym)156*f5c631daSSadaf Ebrahimi   void visit(const char* symname, const Elf32_Sym& sym) {
157*f5c631daSSadaf Ebrahimi     symbols_->insert(
158*f5c631daSSadaf Ebrahimi         Symbol(symname, sym.st_value, 0, sym.st_size, sym.st_shndx));
159*f5c631daSSadaf Ebrahimi   }
160*f5c631daSSadaf Ebrahimi };
161*f5c631daSSadaf Ebrahimi 
162*f5c631daSSadaf Ebrahimi 
163*f5c631daSSadaf Ebrahimi class StaticSymbolVisitor {
164*f5c631daSSadaf Ebrahimi   const Elf32_Ehdr* ehdr_;
165*f5c631daSSadaf Ebrahimi   const Elf32_Shdr* shdr_;
166*f5c631daSSadaf Ebrahimi   SymbolTable* symbols_;
167*f5c631daSSadaf Ebrahimi 
168*f5c631daSSadaf Ebrahimi  public:
StaticSymbolVisitor(const Elf32_Ehdr * ehdr,SymbolTable * symbols)169*f5c631daSSadaf Ebrahimi   StaticSymbolVisitor(const Elf32_Ehdr* ehdr, SymbolTable* symbols)
170*f5c631daSSadaf Ebrahimi       : ehdr_(ehdr),
171*f5c631daSSadaf Ebrahimi         shdr_(reinterpret_cast<const Elf32_Shdr*>(
172*f5c631daSSadaf Ebrahimi             reinterpret_cast<const char*>(ehdr) + ehdr->e_shoff)),
173*f5c631daSSadaf Ebrahimi         symbols_(symbols) {}
visit(const char * symname,const Elf32_Sym & sym)174*f5c631daSSadaf Ebrahimi   void visit(const char* symname, const Elf32_Sym& sym) {
175*f5c631daSSadaf Ebrahimi     if (ehdr_->e_type == ET_REL) {
176*f5c631daSSadaf Ebrahimi       symbols_->insert(Symbol(symname,
177*f5c631daSSadaf Ebrahimi                               sym.st_value,
178*f5c631daSSadaf Ebrahimi                               shdr_[sym.st_shndx].sh_offset,
179*f5c631daSSadaf Ebrahimi                               sym.st_size,
180*f5c631daSSadaf Ebrahimi                               sym.st_shndx));
181*f5c631daSSadaf Ebrahimi     } else {
182*f5c631daSSadaf Ebrahimi       symbols_->insert(
183*f5c631daSSadaf Ebrahimi           Symbol(symname,
184*f5c631daSSadaf Ebrahimi                  sym.st_value,
185*f5c631daSSadaf Ebrahimi                  shdr_[sym.st_shndx].sh_offset - shdr_[sym.st_shndx].sh_addr,
186*f5c631daSSadaf Ebrahimi                  sym.st_size,
187*f5c631daSSadaf Ebrahimi                  sym.st_shndx));
188*f5c631daSSadaf Ebrahimi     }
189*f5c631daSSadaf Ebrahimi   }
190*f5c631daSSadaf Ebrahimi };
191*f5c631daSSadaf Ebrahimi 
192*f5c631daSSadaf Ebrahimi 
usage()193*f5c631daSSadaf Ebrahimi void usage() {
194*f5c631daSSadaf Ebrahimi   std::cout << "usage: disasm-a32 <file>\n"
195*f5c631daSSadaf Ebrahimi                "where <file> is an ELF ARM binaryfile, either an executable, "
196*f5c631daSSadaf Ebrahimi                "a shared object, or an object file."
197*f5c631daSSadaf Ebrahimi             << std::endl;
198*f5c631daSSadaf Ebrahimi }
199*f5c631daSSadaf Ebrahimi 
200*f5c631daSSadaf Ebrahimi 
main(int argc,char ** argv)201*f5c631daSSadaf Ebrahimi int main(int argc, char** argv) {
202*f5c631daSSadaf Ebrahimi   const int kErrorNotARMELF32 = -1;
203*f5c631daSSadaf Ebrahimi   const int kErrorArguments = -2;
204*f5c631daSSadaf Ebrahimi   if (argc < 2) {
205*f5c631daSSadaf Ebrahimi     usage();
206*f5c631daSSadaf Ebrahimi     return kErrorArguments;
207*f5c631daSSadaf Ebrahimi   }
208*f5c631daSSadaf Ebrahimi 
209*f5c631daSSadaf Ebrahimi   const char* filename = argv[1];
210*f5c631daSSadaf Ebrahimi   struct stat sb;
211*f5c631daSSadaf Ebrahimi 
212*f5c631daSSadaf Ebrahimi 
213*f5c631daSSadaf Ebrahimi   if (lstat(filename, &sb) == -1) {
214*f5c631daSSadaf Ebrahimi     std::cerr << "Cannot stat this file" << filename << std::endl;
215*f5c631daSSadaf Ebrahimi     return errno;
216*f5c631daSSadaf Ebrahimi   }
217*f5c631daSSadaf Ebrahimi 
218*f5c631daSSadaf Ebrahimi   if (S_ISLNK(sb.st_mode)) {
219*f5c631daSSadaf Ebrahimi     static char linkname[4096];
220*f5c631daSSadaf Ebrahimi     filename = realpath(argv[1], linkname);
221*f5c631daSSadaf Ebrahimi     if (lstat(linkname, &sb) == -1) {
222*f5c631daSSadaf Ebrahimi       std::cerr << "Cannot stat this file: " << linkname << std::endl;
223*f5c631daSSadaf Ebrahimi       return errno;
224*f5c631daSSadaf Ebrahimi     }
225*f5c631daSSadaf Ebrahimi   }
226*f5c631daSSadaf Ebrahimi 
227*f5c631daSSadaf Ebrahimi   int elf_in;
228*f5c631daSSadaf Ebrahimi   if ((elf_in = open(filename, O_RDONLY)) < 0) {
229*f5c631daSSadaf Ebrahimi     std::cerr << "Cannot open: " << argv[1];
230*f5c631daSSadaf Ebrahimi     if (filename != argv[1]) std::cerr << " aka " << filename;
231*f5c631daSSadaf Ebrahimi     std::cerr << std::endl;
232*f5c631daSSadaf Ebrahimi     return errno;
233*f5c631daSSadaf Ebrahimi   }
234*f5c631daSSadaf Ebrahimi 
235*f5c631daSSadaf Ebrahimi   char* base_addr;
236*f5c631daSSadaf Ebrahimi   VIXL_CHECK((base_addr = reinterpret_cast<char*>(
237*f5c631daSSadaf Ebrahimi                   mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE, elf_in, 0))) !=
238*f5c631daSSadaf Ebrahimi              0);
239*f5c631daSSadaf Ebrahimi 
240*f5c631daSSadaf Ebrahimi   const Elf32_Ehdr* ehdr = reinterpret_cast<const Elf32_Ehdr*>(base_addr);
241*f5c631daSSadaf Ebrahimi   if ((ehdr->e_ident[0] != 0x7f) || (ehdr->e_ident[1] != 'E') ||
242*f5c631daSSadaf Ebrahimi       (ehdr->e_ident[2] != 'L') || (ehdr->e_ident[3] != 'F') ||
243*f5c631daSSadaf Ebrahimi       (ehdr->e_ehsize != sizeof(Elf32_Ehdr))) {
244*f5c631daSSadaf Ebrahimi     std::cerr << "This file is not an 32-bit ELF file." << std::endl;
245*f5c631daSSadaf Ebrahimi     munmap(base_addr, sb.st_size);
246*f5c631daSSadaf Ebrahimi     return kErrorNotARMELF32;
247*f5c631daSSadaf Ebrahimi   }
248*f5c631daSSadaf Ebrahimi 
249*f5c631daSSadaf Ebrahimi   if (ehdr->e_machine != EM_ARM) {
250*f5c631daSSadaf Ebrahimi     std::cerr << "This file is not using the ARM isa." << std::endl;
251*f5c631daSSadaf Ebrahimi     munmap(base_addr, sb.st_size);
252*f5c631daSSadaf Ebrahimi     return kErrorNotARMELF32;
253*f5c631daSSadaf Ebrahimi   }
254*f5c631daSSadaf Ebrahimi 
255*f5c631daSSadaf Ebrahimi   // shstrtab holds the section names as an offset in the file.
256*f5c631daSSadaf Ebrahimi   const Elf32_Shdr* shdr =
257*f5c631daSSadaf Ebrahimi       reinterpret_cast<const Elf32_Shdr*>(base_addr + ehdr->e_shoff);
258*f5c631daSSadaf Ebrahimi 
259*f5c631daSSadaf Ebrahimi   SectionLocator section_locator(ehdr);
260*f5c631daSSadaf Ebrahimi 
261*f5c631daSSadaf Ebrahimi   SymbolTable symbol_names;
262*f5c631daSSadaf Ebrahimi 
263*f5c631daSSadaf Ebrahimi   // Traverse the dynamic symbols defined in any text section
264*f5c631daSSadaf Ebrahimi   DynamicSymbolVisitor dynamic_visitor(&symbol_names);
265*f5c631daSSadaf Ebrahimi   LocateSymbols(ehdr,
266*f5c631daSSadaf Ebrahimi                 section_locator.Locate(SHT_DYNSYM, ".dynsym"),
267*f5c631daSSadaf Ebrahimi                 section_locator.Locate(SHT_STRTAB, ".dynstr"),
268*f5c631daSSadaf Ebrahimi                 &dynamic_visitor);
269*f5c631daSSadaf Ebrahimi 
270*f5c631daSSadaf Ebrahimi   // Traverse the static symbols defined in the any test section
271*f5c631daSSadaf Ebrahimi   StaticSymbolVisitor static_visitor(ehdr, &symbol_names);
272*f5c631daSSadaf Ebrahimi   LocateSymbols(ehdr,
273*f5c631daSSadaf Ebrahimi                 section_locator.Locate(SHT_SYMTAB, ".symtab"),
274*f5c631daSSadaf Ebrahimi                 section_locator.Locate(SHT_STRTAB, ".strtab"),
275*f5c631daSSadaf Ebrahimi                 &static_visitor);
276*f5c631daSSadaf Ebrahimi 
277*f5c631daSSadaf Ebrahimi 
278*f5c631daSSadaf Ebrahimi   vixl::aarch32::PrintDisassembler dis(std::cout, 0);
279*f5c631daSSadaf Ebrahimi   for (SymbolTable::iterator sres = symbol_names.begin();
280*f5c631daSSadaf Ebrahimi        sres != symbol_names.end();
281*f5c631daSSadaf Ebrahimi        sres++) {
282*f5c631daSSadaf Ebrahimi     const Symbol& symbol = sres->second;
283*f5c631daSSadaf Ebrahimi     uint32_t func_addr = symbol.GetAddress();
284*f5c631daSSadaf Ebrahimi     uint32_t func_size = symbol.GetSize();
285*f5c631daSSadaf Ebrahimi     if (func_size == 0) {
286*f5c631daSSadaf Ebrahimi       SymbolTable::iterator next_func = sres;
287*f5c631daSSadaf Ebrahimi       next_func++;
288*f5c631daSSadaf Ebrahimi       if (next_func == symbol_names.end()) {
289*f5c631daSSadaf Ebrahimi         const Elf32_Shdr& shndx = shdr[sres->second.GetSection()];
290*f5c631daSSadaf Ebrahimi         func_size = (shndx.sh_offset + shndx.sh_size) - sres->first;
291*f5c631daSSadaf Ebrahimi       } else {
292*f5c631daSSadaf Ebrahimi         func_size = next_func->first - sres->first;
293*f5c631daSSadaf Ebrahimi       }
294*f5c631daSSadaf Ebrahimi     }
295*f5c631daSSadaf Ebrahimi 
296*f5c631daSSadaf Ebrahimi     std::cout << "--- " << symbol.GetName() << ":" << std::endl;
297*f5c631daSSadaf Ebrahimi     if ((func_addr & 1) == 1) {
298*f5c631daSSadaf Ebrahimi       func_addr &= ~1;
299*f5c631daSSadaf Ebrahimi       dis.SetCodeAddress(func_addr);
300*f5c631daSSadaf Ebrahimi       dis.DisassembleT32Buffer(reinterpret_cast<uint16_t*>(
301*f5c631daSSadaf Ebrahimi                                    base_addr + symbol.GetMemoryAddress()),
302*f5c631daSSadaf Ebrahimi                                func_size);
303*f5c631daSSadaf Ebrahimi     } else {
304*f5c631daSSadaf Ebrahimi       dis.SetCodeAddress(func_addr);
305*f5c631daSSadaf Ebrahimi       dis.DisassembleA32Buffer(reinterpret_cast<uint32_t*>(
306*f5c631daSSadaf Ebrahimi                                    base_addr + symbol.GetMemoryAddress()),
307*f5c631daSSadaf Ebrahimi                                func_size);
308*f5c631daSSadaf Ebrahimi     }
309*f5c631daSSadaf Ebrahimi   }
310*f5c631daSSadaf Ebrahimi   munmap(base_addr, sb.st_size);
311*f5c631daSSadaf Ebrahimi   return 0;
312*f5c631daSSadaf Ebrahimi }
313*f5c631daSSadaf Ebrahimi 
314*f5c631daSSadaf Ebrahimi 
315*f5c631daSSadaf Ebrahimi #else
316*f5c631daSSadaf Ebrahimi 
317*f5c631daSSadaf Ebrahimi #include "globals-vixl.h"
318*f5c631daSSadaf Ebrahimi 
319*f5c631daSSadaf Ebrahimi // TODO: Implement this example for macOS.
main(void)320*f5c631daSSadaf Ebrahimi int main(void) {
321*f5c631daSSadaf Ebrahimi   VIXL_WARNING("This example has not been implemented for macOS.");
322*f5c631daSSadaf Ebrahimi   return 0;
323*f5c631daSSadaf Ebrahimi }
324*f5c631daSSadaf Ebrahimi 
325*f5c631daSSadaf Ebrahimi #endif  // __linux__
326