]> gitweb.factorcode.org Git - factor.git/commitdiff
Macho version of nm and testcase for it.
authorErik Charlebois <erikcharlebois@gmail.com>
Wed, 14 Apr 2010 00:58:45 +0000 (17:58 -0700)
committerErik Charlebois <erikcharlebois@gmail.com>
Wed, 14 Apr 2010 00:58:45 +0000 (17:58 -0700)
extra/elf/nm/nm-tests.factor
extra/elf/nm/nm.factor
extra/macho/a.macho [new file with mode: 0755]
extra/macho/macho-tests.factor [new file with mode: 0644]
extra/macho/macho.factor

index 2ecb4990814905229119275add1a31d41409a831..9e529ae43d8f71f8ceab6738ce8492e926cd1882 100644 (file)
@@ -6,46 +6,46 @@ IN: elf.nm.tests
 
 STRING: validation-output
 0000000000000000 absolute         init.c
-0000000004195436 .text            call_gmon_start
+000000000040046c .text            call_gmon_start
 0000000000000000 absolute         crtstuff.c
-0000000006295064 .ctors           __CTOR_LIST__
-0000000006295080 .dtors           __DTOR_LIST__
-0000000006295096 .jcr             __JCR_LIST__
-0000000004195472 .text            __do_global_dtors_aux
-0000000006295584 .bss             completed.7342
-0000000006295592 .bss             dtor_idx.7344
-0000000004195584 .text            frame_dummy
+0000000000600e18 .ctors           __CTOR_LIST__
+0000000000600e28 .dtors           __DTOR_LIST__
+0000000000600e38 .jcr             __JCR_LIST__
+0000000000400490 .text            __do_global_dtors_aux
+0000000000601020 .bss             completed.7342
+0000000000601028 .bss             dtor_idx.7344
+0000000000400500 .text            frame_dummy
 0000000000000000 absolute         crtstuff.c
-0000000006295072 .ctors           __CTOR_END__
-0000000004196056 .eh_frame        __FRAME_END__
-0000000006295096 .jcr             __JCR_END__
-0000000004195808 .text            __do_global_ctors_aux
+0000000000600e20 .ctors           __CTOR_END__
+00000000004006d8 .eh_frame        __FRAME_END__
+0000000000600e38 .jcr             __JCR_END__
+00000000004005e0 .text            __do_global_ctors_aux
 0000000000000000 absolute         test.c
-0000000006295528 .got.plt         _GLOBAL_OFFSET_TABLE_
-0000000006295060 .ctors           __init_array_end
-0000000006295060 .ctors           __init_array_start
-0000000006295104 .dynamic         _DYNAMIC
-0000000006295568 .data            data_start
+0000000000600fe8 .got.plt         _GLOBAL_OFFSET_TABLE_
+0000000000600e14 .ctors           __init_array_end
+0000000000600e14 .ctors           __init_array_start
+0000000000600e40 .dynamic         _DYNAMIC
+0000000000601010 .data            data_start
 0000000000000000 undefined        printf@@GLIBC_2.2.5
-0000000004195648 .text            __libc_csu_fini
-0000000004195392 .text            _start
+0000000000400540 .text            __libc_csu_fini
+0000000000400440 .text            _start
 0000000000000000 undefined        __gmon_start__
 0000000000000000 undefined        _Jv_RegisterClasses
-0000000004195864 .fini            _fini
+0000000000400618 .fini            _fini
 0000000000000000 undefined        __libc_start_main@@GLIBC_2.2.5
-0000000004195880 .rodata          _IO_stdin_used
-0000000006295568 .data            __data_start
-0000000006295576 .data            __dso_handle
-0000000006295088 .dtors           __DTOR_END__
-0000000004195664 .text            __libc_csu_init
-0000000006295584 absolute         __bss_start
-0000000006295600 absolute         _end
-0000000006295584 absolute         _edata
-0000000004195620 .text            main
-0000000004195312 .init            _init
+0000000000400628 .rodata          _IO_stdin_used
+0000000000601010 .data            __data_start
+0000000000601018 .data            __dso_handle
+0000000000600e30 .dtors           __DTOR_END__
+0000000000400550 .text            __libc_csu_init
+0000000000601020 absolute         __bss_start
+0000000000601030 absolute         _end
+0000000000601020 absolute         _edata
+0000000000400524 .text            main
+00000000004003f0 .init            _init
 
 ;
 
 { $ validation-output }
-[ <string-writer> dup [ "resource:extra/elf/a.elf" nm ] with-output-stream >string ]
+[ <string-writer> dup [ "resource:extra/elf/a.elf" elf-nm ] with-output-stream >string ]
 unit-test
index 87c9abf00bfbd60128855b3ec69bc2c2ccbcb3eb..52e1c66902e3c7f1d87d46a914cb0803bb0f4cca 100644 (file)
@@ -4,7 +4,7 @@ USING: accessors combinators elf formatting io.mmap kernel sequences ;
 IN: elf.nm
 
 : print-symbol ( sections symbol -- )
-    [ sym>> st_value>> "%016d " printf ]
+    [ sym>> st_value>> "%016x " printf ]
     [
         sym>> st_shndx>>
         {
@@ -16,7 +16,7 @@ IN: elf.nm
     ]
     [ name>> "%s\n" printf ] tri ;
     
-: nm ( path -- )
+: elf-nm ( path -- )
     [
         sections dup ".symtab" find-section
         symbols [ name>> empty? not ] filter
diff --git a/extra/macho/a.macho b/extra/macho/a.macho
new file mode 100755 (executable)
index 0000000..bc233d7
Binary files /dev/null and b/extra/macho/a.macho differ
diff --git a/extra/macho/macho-tests.factor b/extra/macho/macho-tests.factor
new file mode 100644 (file)
index 0000000..ca60d3d
--- /dev/null
@@ -0,0 +1,26 @@
+! Copyright (C) 2010 Erik Charlebois.
+! See http://factorcode.org/license.txt for BSD license.
+USING: io io.streams.string kernel literals macho multiline strings
+tools.test ;
+IN: macho.tests
+
+STRING: validation-output
+0000000100000f1c __stub_helper    stub helpers
+0000000100001040 __program_vars  _pvars
+0000000100001068 __data          _NXArgc
+0000000100001070 __data          _NXArgv
+0000000100001080 __data          ___progname
+0000000100000000                 __mh_execute_header
+0000000100001078 __data          _environ
+0000000100000ef8 __text          _main
+0000000100000ebc __text          start
+0000000000000000                 ___gxx_personality_v0
+0000000000000000                 _exit
+0000000000000000                 _printf
+0000000000000000                 dyld_stub_binder
+
+;
+
+{ $ validation-output }
+[ <string-writer> dup [ "resource:extra/macho/a.macho" macho-nm ] with-output-stream >string ]
+unit-test
index e3765260bb22a602023fd92bf4962fd96d28bd2c..b18ea57ce582f21750a3bcd3dba08903c55a106a 100644 (file)
@@ -1,8 +1,13 @@
 ! Copyright (C) 2010 Erik Charlebois.
 ! See http:// factorcode.org/license.txt for BSD license.
-USING: alien.c-types alien.syntax classes.struct kernel literals math ;
+USING: accessors alien alien.c-types alien.strings alien.syntax
+classes classes.struct combinators io.encodings.ascii
+io.encodings.string kernel literals make math sequences
+specialized-arrays typed fry io.mmap formatting locals ;
+FROM: alien.c-types => short ;
 IN: macho
 
+! FFI data
 TYPEDEF: int       integer_t
 TYPEDEF: int       vm_prot_t
 TYPEDEF: integer_t cpu_type_t
@@ -804,3 +809,124 @@ C-ENUM: reloc_type_ppc
     PPC_RELOC_JBSR
     PPC_RELOC_LO14_SECTDIFF
     PPC_RELOC_LOCAL_SECTDIFF ;
+
+! Low-level interface
+SPECIALIZED-ARRAYS: section section_64 nlist nlist_64 ;
+UNION: mach_header_32/64 mach_header mach_header_64 ;
+UNION: segment_command_32/64 segment_command segment_command_64 ;
+UNION: load-command segment_command segment_command_64
+    dylib_command sub_framework_command
+    sub_client_command sub_umbrella_command sub_library_command
+    prebound_dylib_command dylinker_command thread_command
+    routines_command routines_command_64 symtab_command
+    dysymtab_command twolevel_hints_command uuid_command ;
+UNION: section_32/64 section section_64 ;
+UNION: section_32/64-array section-array section_64-array ;
+UNION: nlist_32/64 nlist nlist_64 ;
+UNION: nlist_32/64-array nlist-array nlist_64-array ;
+
+TYPED: 64-bit? ( macho: mach_header_32/64 -- ? )
+    magic>> {
+        { MH_MAGIC_64 [ t ] }
+        { MH_CIGAM_64 [ t ] }
+        [ drop f ]
+    } case ;
+
+TYPED: macho-header ( c-ptr -- macho: mach_header_32/64 )
+    dup mach_header_64 memory>struct 64-bit?
+    [ mach_header_64 memory>struct ]
+    [ mach_header memory>struct ] if ;
+
+: cmd>load-command ( cmd -- load-command )
+    {
+        { LC_UUID           [ uuid_command           ] }
+        { LC_SEGMENT        [ segment_command        ] }
+        { LC_SEGMENT_64     [ segment_command_64     ] }
+        { LC_SYMTAB         [ symtab_command         ] }
+        { LC_DYSYMTAB       [ dysymtab_command       ] }
+        { LC_THREAD         [ thread_command         ] }
+        { LC_UNIXTHREAD     [ thread_command         ] }
+        { LC_LOAD_DYLIB     [ dylib_command          ] }
+        { LC_ID_DYLIB       [ dylib_command          ] }
+        { LC_PREBOUND_DYLIB [ prebound_dylib_command ] }
+        { LC_LOAD_DYLINKER  [ dylinker_command       ] }
+        { LC_ID_DYLINKER    [ dylinker_command       ] }
+        { LC_ROUTINES       [ routines_command       ] }
+        { LC_ROUTINES_64    [ routines_command_64    ] }
+        { LC_TWOLEVEL_HINTS [ twolevel_hints_command ] }
+        { LC_SUB_FRAMEWORK  [ sub_framework_command  ] }
+        { LC_SUB_UMBRELLA   [ sub_umbrella_command   ] }
+        { LC_SUB_LIBRARY    [ sub_library_command    ] }
+        { LC_SUB_CLIENT     [ sub_client_command     ] }
+        { LC_DYLD_INFO      [ dyld_info_command      ] }
+        { LC_DYLD_INFO_ONLY [ dyld_info_command      ] }
+    } case ;
+
+: read-command ( cmd -- next-cmd )
+    dup load_command memory>struct
+    [ cmd>> cmd>load-command memory>struct , ]
+    [ cmdsize>> swap <displaced-alien> ] 2bi ;
+
+TYPED: load-commands ( macho: mach_header_32/64 -- load-commands )
+    [
+        [ class heap-size ]
+        [ >c-ptr <displaced-alien> ]
+        [ ncmds>> ] tri iota [
+            drop read-command
+        ] each drop
+    ] { } make ;
+
+: segment-commands ( load-commands -- segment-commands )
+    [ segment_command_32/64? ] filter ; inline
+
+: symtab-commands ( load-commands -- segment-commands )
+    [ symtab_command? ] filter ; inline
+
+: read-array-string ( uchar-array -- string )
+    ascii decode [ 0 = not ] filter ;
+
+: segment-sections ( segment-command -- sections )
+    {
+        [ class heap-size ]
+        [ >c-ptr <displaced-alien> ]
+        [ nsects>> ]
+        [ segment_command_64? ]
+    } cleave
+    [ <direct-section_64-array> ]
+    [ <direct-section-array> ] if ;
+
+: sections-array ( segment-commands -- sections-array )
+    [
+        dup first segment_command_64?
+        [ section_64 ] [ section ] if <struct> ,
+        segment-commands [ segment-sections [ , ] each ] each
+    ] { } make ;
+
+: symbols ( mach-header symtab-command -- symbols string-table )
+    [ symoff>> swap >c-ptr <displaced-alien> ]
+    [ nsyms>> swap 64-bit?
+      [ <direct-nlist_64-array> ]
+      [ <direct-nlist-array> ] if ]
+    [ stroff>> swap >c-ptr <displaced-alien> ] 2tri ;
+    
+: symbol-name ( symbol string-table -- name )
+    [ n_strx>> ] dip <displaced-alien> ascii alien>string ;
+
+: with-mapped-macho ( path quot -- )
+    '[
+        address>> macho-header @
+    ] with-mapped-file ; inline
+
+: macho-nm ( path -- )
+    [| macho |
+        macho load-commands segment-commands sections-array :> sections
+        
+        macho load-commands symtab-commands [| symtab |
+            macho symtab symbols [
+                [ drop n_value>> "%016x " printf ]
+                [ drop n_sect>> sections nth sectname>>
+                  read-array-string "%-16s" printf ]
+                [ symbol-name "%s\n" printf ] 2tri
+            ] curry each
+        ] each
+    ] with-mapped-macho ;