Permalink
Browse files

Add fat.h and fat.cc to share code in extract.cc

  • Loading branch information...
1 parent 4715f51 commit 6090b0abdefb1c7e37837bbfc148ad7e6adf87ec @shinh shinh committed Mar 10, 2011
Showing with 158 additions and 62 deletions.
  1. +3 −3 Makefile
  2. +18 −59 extract.cc
  3. +96 −0 fat.cc
  4. +41 −0 fat.h
View
@@ -22,10 +22,10 @@ $(MACTXTS): %.txt: %.bin
# ./genelf.sh
# touch $@
-extract: extract.o
- g++ $< -o $@ -g -I. -W -Wall
+extract: extract.o fat.o
+ g++ $^ -o $@ -g -I. -W -Wall
-macho2elf: macho2elf.o mach-o.o
+macho2elf: macho2elf.o mach-o.o fat.o
g++ $^ -o $@ -g
ld-mac: ld-mac.o mach-o.o
View
@@ -40,33 +40,9 @@
#include "mach-o/fat.h"
-using namespace std;
-
-bool be = false;
-
-static void fixEndian(uint32_t* p) {
- if (!be) {
- return;
- }
-
- uint32_t v = *p;
- *p = (v << 24) | ((v << 8) & 0x00ff0000) | ((v >> 8) & 0xff00) | (v >> 24);
-}
+#include "fat.h"
-static const char* getArchName(uint32_t a) {
- switch (a) {
- case CPU_TYPE_X86:
- return "x86";
- case CPU_TYPE_X86_64:
- return "x86-64";
- case CPU_TYPE_POWERPC:
- return "ppc";
- case CPU_TYPE_POWERPC64:
- return "ppc64";
- default:
- return "???";
- }
-}
+using namespace std;
int main(int argc, char* argv[]) {
if (argc < 2) {
@@ -84,55 +60,38 @@ int main(int argc, char* argv[]) {
char* bin = reinterpret_cast<char*>(
mmap(NULL, len,
PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, 0));
+ if (bin == MAP_FAILED) {
+ perror("mmap");
+ exit(1);
+ }
- fat_header* header = reinterpret_cast<fat_header*>(bin);
-
- if (header->magic == FAT_CIGAM) {
- be = true;
- } else if (header->magic != FAT_MAGIC) {
+ map<string, fat_arch> archs;
+ if (!readFatInfo(fd, &archs)) {
fprintf(stderr, "Not fat\n");
exit(1);
}
- fixEndian(&header->nfat_arch);
-
- printf("magic=%x nfat_arch=%d\n",
- header->magic, header->nfat_arch);
-
- map<string, fat_arch*> archs;
-
- char* fat_ptr = bin + sizeof(fat_header);
- for (uint32_t i = 0; i < header->nfat_arch; i++) {
- fat_arch* arch = reinterpret_cast<fat_arch*>(fat_ptr);
-
- fixEndian(&arch->cputype);
- fixEndian(&arch->cpusubtype);
- fixEndian(&arch->offset);
- fixEndian(&arch->size);
- fixEndian(&arch->align);
-
- const char* name = getArchName(arch->cputype);
-
+ printf("%lu archs:\n", archs.size());
+ for (map<string, fat_arch>::const_iterator iter = archs.begin();
+ iter != archs.end();
+ ++iter) {
+ const fat_arch& arch = iter->second;
printf("cputype=%d (%s) cpusubtype=%d offset=%d size=%d align=%d\n",
- arch->cputype, name, arch->cpusubtype,
- arch->offset, arch->size, arch->align);
-
- archs.insert(make_pair(name, arch));
-
- fat_ptr += sizeof(fat_arch);
+ arch.cputype, iter->first.c_str(), arch.cpusubtype,
+ arch.offset, arch.size, arch.align);
}
for (int i = 2; i + 1 < argc; i += 2) {
const char* arch_name = argv[i];
- map<string, fat_arch*>::const_iterator found = archs.find(arch_name);
+ map<string, fat_arch>::const_iterator found = archs.find(arch_name);
if (found == archs.end()) {
printf("unknown arch: %s\n", arch_name);
continue;
}
- fat_arch* arch = found->second;
+ const fat_arch& arch = found->second;
FILE* fp = fopen(argv[i+1], "wb");
- fwrite(bin + arch->offset, 1, arch->size, fp);
+ fwrite(bin + arch.offset, 1, arch.size, fp);
fclose(fp);
}
}
View
96 fat.cc
@@ -0,0 +1,96 @@
+// Copyright 2011 Shinichiro Hamaji. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials
+// provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY Shinichiro Hamaji ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Shinichiro Hamaji OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+// USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+// SUCH DAMAGE.
+
+#include "fat.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static void fixEndian(uint32_t* p, bool be) {
+ if (!be) {
+ return;
+ }
+
+ uint32_t v = *p;
+ *p = (v << 24) | ((v << 8) & 0x00ff0000) | ((v >> 8) & 0xff00) | (v >> 24);
+}
+
+static string getArchName(uint32_t a) {
+ switch (a) {
+ case CPU_TYPE_X86:
+ return "x86";
+ case CPU_TYPE_X86_64:
+ return "x86-64";
+ case CPU_TYPE_POWERPC:
+ return "ppc";
+ case CPU_TYPE_POWERPC64:
+ return "ppc64";
+ default:
+ char buf[99];
+ sprintf(buf, "??? (%u)", a);
+ return buf;
+ }
+}
+
+bool readFatInfo(int fd, map<string, fat_arch>* fat) {
+ lseek(fd, 0, SEEK_SET);
+
+ fat_header header;
+ ssize_t len = read(fd, &header, sizeof(header));
+ if (len < 0) {
+ perror("read");
+ exit(1);
+ }
+ if (len != sizeof(header)) {
+ return false;
+ }
+
+ bool be = false;
+ if (header.magic == FAT_CIGAM) {
+ be = true;
+ } else if (header.magic != FAT_MAGIC) {
+ return false;
+ }
+
+ fixEndian(&header.nfat_arch, be);
+ for (uint32_t i = 0; i < header.nfat_arch; i++) {
+ fat_arch arch;
+ len = read(fd, &arch, sizeof(arch));
+
+ fixEndian(&arch.cputype, be);
+ fixEndian(&arch.cpusubtype, be);
+ fixEndian(&arch.offset, be);
+ fixEndian(&arch.size, be);
+ fixEndian(&arch.align, be);
+
+ const string& name = getArchName(arch.cputype);
+ fat->insert(make_pair(name, arch));
+ }
+
+ return true;
+}
View
41 fat.h
@@ -0,0 +1,41 @@
+// Copyright 2011 Shinichiro Hamaji. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials
+// provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY Shinichiro Hamaji ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Shinichiro Hamaji OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+// USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+// SUCH DAMAGE.
+
+#ifndef FAT_H_
+#define FAT_H_
+
+#include <map>
+#include <string>
+
+#include "mach-o/fat.h"
+
+using namespace std;
+
+// Reads fd and fill fat info. Returns true if fd is a fat binary.
+bool readFatInfo(int fd, map<string, fat_arch>* fat);
+
+#endif // FAT_H_

0 comments on commit 6090b0a

Please sign in to comment.