Added #getObjectFileInfoFor:
authorJan Vrany <jan.vrany@fit.cvut.cz>
Fri, 20 Mar 2015 11:14:00 +0100
changeset 17631 0441ae93a3e4
parent 17630 918d3b1dde77
child 17632 0f6674a899a0
Added #getObjectFileInfoFor: It returns an object that could be further used to get more information about an object file. Currently, only isFor32/32BitArchitecture is supported but could be easily extended when a need for more information comes. The information is retrieved by reading ELD header.
UnixOperatingSystem.st
--- a/UnixOperatingSystem.st	Fri Mar 20 10:16:12 2015 +0100
+++ b/UnixOperatingSystem.st	Fri Mar 20 11:14:00 2015 +0100
@@ -1,5 +1,3 @@
-"{ Encoding: utf8 }"
-
 "
  COPYRIGHT (c) 1988 by Claus Gittinger
 	      All Rights Reserved
@@ -25,6 +23,40 @@
 	category:'OS-Unix'
 !
 
+SharedPool subclass:#ELFConstants
+	instanceVariableNames:''
+	classVariableNames:'EI_MAG0 ELFMAG0 EI_MAG1 ELFMAG1 EI_MAG2 ELFMAG2 EI_MAG3 ELFMAG3
+		EI_CLASS ELFCLASSNONE ELFCLASS32 ELFCLASS64 ELFCLASSNUM EI_DATA
+		ELFDATANONE ELFDATA2LSB ELFDATA2MSB ELFDATANUM EI_VERSION
+		EI_OSABI ELFOSABI_NONE ELFOSABI_SYSV ELFOSABI_HPUX
+		ELFOSABI_NETBSD ELFOSABI_GNU ELFOSABI_LINUX ELFOSABI_SOLARIS
+		ELFOSABI_AIX ELFOSABI_IRIX ELFOSABI_FREEBSD ELFOSABI_TRU64
+		ELFOSABI_MODESTO ELFOSABI_OPENBSD ELFOSABI_ARM_AEABI ELFOSABI_ARM
+		ELFOSABI_STANDALONE EI_ABIVERSION EI_PAD ET_NONE ET_REL ET_EXEC
+		ET_DYN ET_CORE ET_LOOS ET_HIOS ET_LOPROC ET_HIPROC EM_NONE EM_M32
+		EM_SPARC EM_386 EM_68K EM_88K EM_860 EM_MIPS EM_S370
+		EM_MIPS_RS3_LE EM_PARISC EM_VPP500 EM_SPARC32PLUS EM_960 EM_PPC
+		EM_PPC64 EM_S390 EM_V800 EM_FR20 EM_RH32 EM_RCE EM_ARM
+		EM_FAKE_ALPHA EM_SH EM_SPARCV9 EM_TRICORE EM_ARC EM_H8_300
+		EM_H8_300H EM_H8S EM_H8_500 EM_IA_64 EM_MIPS_X EM_COLDFIRE
+		EM_68HC12 EM_MMA EM_PCP EM_NCPU EM_NDR1 EM_STARCORE EM_ME16
+		EM_ST100 EM_TINYJ EM_X86_64 EM_PDSP EM_FX66 EM_ST9PLUS EM_ST7
+		EM_68HC16 EM_68HC11 EM_68HC08 EM_68HC05 EM_SVX EM_ST19 EM_VAX
+		EM_CRIS EM_JAVELIN EM_FIREPATH EM_ZSP EM_MMIX EM_HUANY EM_PRISM
+		EM_AVR EM_FR30 EM_D10V EM_D30V EM_V850 EM_M32R EM_MN10300
+		EM_MN10200 EM_PJ EM_OPENRISC EM_ARC_A5 EM_XTENSA EM_AARCH64
+		EM_TILEPRO EM_MICROBLAZE EM_TILEGX EM_ALPHA EV_NONE EV_CURRENT'
+	poolDictionaries:''
+	privateIn:UnixOperatingSystem
+!
+
+Object subclass:#ELFFileHeader
+	instanceVariableNames:'file data msb'
+	classVariableNames:''
+	poolDictionaries:'UnixOperatingSystem::ELFConstants'
+	privateIn:UnixOperatingSystem
+!
+
 Object subclass:#FileDescriptorHandle
 	instanceVariableNames:'fd'
 	classVariableNames:'OpenFiles'
@@ -558,6 +590,13 @@
 # endif
 #endif
 
+#if (defined(__ELD__) || defined (ELF))
+# ifndef ELFMAG1
+#  include <elf.h>
+# endif
+#endif
+
+
 %}
 ! !
 
@@ -4821,6 +4860,22 @@
     ^ '/dev/null'
 !
 
+getObjectFileInfoFor:aStringOrFilename
+    "Return and info object for given executable or shared object
+     or throw an error if given file is not a valid an executable now
+     shared object.
+
+     The info object returned is OS-specific, however it responds to at
+     least
+        #isFor32BitArchitecture
+        #isFor64BitArchitecture ... returns true, if the given object is for
+                                     32bit, 64bit architecture respectively
+    "
+    ^ ELFFileHeader fromFile: aStringOrFilename
+
+    "Created: / 17-03-2015 / 20:52:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
 infoOf:aPathName
     "return some object filled with info for the file 'aPathName';
      the info (for which corresponding access methods are understood by
@@ -9317,7 +9372,7 @@
      Codeset := #'utf8-mac'.
      CodesetEncoder := nil.
      OperatingSystem getCodesetEncoder
-     OperatingSystem encodePath:'äöü'
+     OperatingSystem encodePath:'äöü'
     "
 
     "Modified: / 23-01-2013 / 10:00:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
@@ -10905,6 +10960,247 @@
     ^ self primitiveFailed
 ! !
 
+!UnixOperatingSystem::ELFConstants class methodsFor:'initialization'!
+
+initialize
+    "Invoked at system start or when the class is dynamically loaded."
+
+%{
+#define DEFCONST(c) __GLOBAL_SET(__MKSYMBOL("UnixOperatingSystem::ELFConstants:" #c, (OBJ *)0), __MKSMALLINT(c), (OBJ *)0);
+
+    /* Fields in the e_ident array.  The EI_* macros are indices into the
+       array.  The macros under each EI_* macro are the values the byte
+       may have.  */
+
+    DEFCONST(EI_MAG0)		/* File identification byte 0 index */
+    DEFCONST(EI_MAG1)		/* File identification byte 1 index */
+    DEFCONST(EI_MAG2)		/* File identification byte 2 index */
+    DEFCONST(EI_MAG3)		/* File identification byte 3 index */
+
+    DEFCONST(EI_CLASS)		/* File class byte index */
+    DEFCONST(ELFCLASSNONE)	/* Invalid class */
+    DEFCONST(ELFCLASS32)	/* 32-bit objects */
+    DEFCONST(ELFCLASS64)	/* 64-bit objects */
+    DEFCONST(ELFCLASSNUM)
+
+    DEFCONST(EI_DATA)		/* Data encoding byte index */
+    DEFCONST(ELFDATANONE)	/* Invalid data encoding */
+    DEFCONST(ELFDATA2LSB)	/* 2's complement, little endian */
+    DEFCONST(ELFDATA2MSB)	/* 2's complement, big endian */
+    DEFCONST(ELFDATANUM)
+
+    DEFCONST(EI_VERSION)	/* File version byte index */
+				/* Value must be EV_CURRENT */
+
+    DEFCONST(EI_OSABI)		/* OS ABI identification */
+    DEFCONST(ELFOSABI_NONE)	/* UNIX System V ABI */
+    DEFCONST(ELFOSABI_SYSV)	/* Alias.  */
+    DEFCONST(ELFOSABI_HPUX)	/* HP-UX */
+    DEFCONST(ELFOSABI_NETBSD)	/* NetBSD.  */
+    DEFCONST(ELFOSABI_GNU)	/* Object uses GNU ELF extensions.  */
+    DEFCONST(ELFOSABI_LINUX)    /* Compatibility alias.  */
+    DEFCONST(ELFOSABI_SOLARIS)	/* Sun Solaris.  */
+    DEFCONST(ELFOSABI_AIX)	/* IBM AIX.  */
+    DEFCONST(ELFOSABI_IRIX)	/* SGI Irix.  */
+    DEFCONST(ELFOSABI_FREEBSD)	/* FreeBSD.  */
+    DEFCONST(ELFOSABI_TRU64)	/* Compaq TRU64 UNIX.  */
+    DEFCONST(ELFOSABI_MODESTO)	/* Novell Modesto.  */
+    DEFCONST(ELFOSABI_OPENBSD)	/* OpenBSD.  */
+    DEFCONST(ELFOSABI_ARM_AEABI)/* ARM EABI */
+    DEFCONST(ELFOSABI_ARM)	/* ARM */
+    DEFCONST(ELFOSABI_STANDALONE)/* Standalone (embedded) application */
+
+    DEFCONST(EI_ABIVERSION)	/* ABI version */
+
+    DEFCONST(EI_PAD)		/* Byte index of padding bytes */
+
+    /* Legal values for e_type (object file type).  */
+
+    DEFCONST(ET_NONE)		/* No file type */
+    DEFCONST(ET_REL)		/* Relocatable file */
+    DEFCONST(ET_EXEC)		/* Executable file */
+    DEFCONST(ET_DYN)		/* Shared object file */
+    DEFCONST(ET_CORE)		/* Core file */
+
+    DEFCONST(ET_LOOS)		/* OS-specific range start */
+    DEFCONST(ET_HIOS)		/* OS-specific range end */
+    DEFCONST(ET_LOPROC)		/* Processor-specific range start */
+    DEFCONST(ET_HIPROC)		/* Processor-specific range end */
+
+    /* Legal values for e_machine (architecture).  */
+
+    DEFCONST(EM_NONE)		/* No machine */
+    DEFCONST(EM_M32)		/* AT&T WE 32100 */
+    DEFCONST(EM_SPARC)		/* SUN SPARC */
+    DEFCONST(EM_386)		/* Intel 80386 */
+    DEFCONST(EM_68K)		/* Motorola m68k family */
+    DEFCONST(EM_88K)		/* Motorola m88k family */
+    DEFCONST(EM_860)		/* Intel 80860 */
+    DEFCONST(EM_MIPS)		/* MIPS R3000 big-endian */
+    DEFCONST(EM_S370)		/* IBM System/370 */
+    DEFCONST(EM_MIPS_RS3_LE)	/* MIPS R3000 little-endian */
+
+    DEFCONST(EM_PARISC)		/* HPPA */
+    DEFCONST(EM_VPP500)		/* Fujitsu VPP500 */
+    DEFCONST(EM_SPARC32PLUS)	/* Sun's "v8plus" */
+    DEFCONST(EM_960)		/* Intel 80960 */
+    DEFCONST(EM_PPC)		/* PowerPC */
+    DEFCONST(EM_PPC64)		/* PowerPC 64-bit */
+    DEFCONST(EM_S390)		/* IBM S390 */
+
+    DEFCONST(EM_V800)		/* NEC V800 series */
+    DEFCONST(EM_FR20)		/* Fujitsu FR20 */
+    DEFCONST(EM_RH32)		/* TRW RH-32 */
+    DEFCONST(EM_RCE)		/* Motorola RCE */
+    DEFCONST(EM_ARM)		/* ARM */
+    DEFCONST(EM_FAKE_ALPHA)	/* Digital Alpha */
+    DEFCONST(EM_SH)		/* Hitachi SH */
+    DEFCONST(EM_SPARCV9)	/* SPARC v9 64-bit */
+    DEFCONST(EM_TRICORE)	/* Siemens Tricore */
+    DEFCONST(EM_ARC)		/* Argonaut RISC Core */
+    DEFCONST(EM_H8_300)		/* Hitachi H8/300 */
+    DEFCONST(EM_H8_300H)	/* Hitachi H8/300H */
+    DEFCONST(EM_H8S)		/* Hitachi H8S */
+    DEFCONST(EM_H8_500)		/* Hitachi H8/500 */
+    DEFCONST(EM_IA_64)		/* Intel Merced */
+    DEFCONST(EM_MIPS_X)		/* Stanford MIPS-X */
+    DEFCONST(EM_COLDFIRE)	/* Motorola Coldfire */
+    DEFCONST(EM_68HC12)		/* Motorola M68HC12 */
+    DEFCONST(EM_MMA)		/* Fujitsu MMA Multimedia Accelerator*/
+    DEFCONST(EM_PCP)		/* Siemens PCP */
+    DEFCONST(EM_NCPU)		/* Sony nCPU embeeded RISC */
+    DEFCONST(EM_NDR1)		/* Denso NDR1 microprocessor */
+    DEFCONST(EM_STARCORE)	/* Motorola Start*Core processor */
+    DEFCONST(EM_ME16)		/* Toyota ME16 processor */
+    DEFCONST(EM_ST100)		/* STMicroelectronic ST100 processor */
+    DEFCONST(EM_TINYJ)		/* Advanced Logic Corp. Tinyj emb.fam*/
+    DEFCONST(EM_X86_64)		/* AMD x86-64 architecture */
+    DEFCONST(EM_PDSP)		/* Sony DSP Processor */
+
+    DEFCONST(EM_FX66)		/* Siemens FX66 microcontroller */
+    DEFCONST(EM_ST9PLUS)	/* STMicroelectronics ST9+ 8/16 mc */
+    DEFCONST(EM_ST7)		/* STmicroelectronics ST7 8 bit mc */
+    DEFCONST(EM_68HC16)		/* Motorola MC68HC16 microcontroller */
+    DEFCONST(EM_68HC11)		/* Motorola MC68HC11 microcontroller */
+    DEFCONST(EM_68HC08)		/* Motorola MC68HC08 microcontroller */
+    DEFCONST(EM_68HC05)		/* Motorola MC68HC05 microcontroller */
+    DEFCONST(EM_SVX)		/* Silicon Graphics SVx */
+    DEFCONST(EM_ST19)		/* STMicroelectronics ST19 8 bit mc */
+    DEFCONST(EM_VAX)		/* Digital VAX */
+    DEFCONST(EM_CRIS)		/* Axis Communications 32-bit embedded processor */
+    DEFCONST(EM_JAVELIN)	/* Infineon Technologies 32-bit embedded processor */
+    DEFCONST(EM_FIREPATH)	/* Element 14 64-bit DSP Processor */
+    DEFCONST(EM_ZSP)		/* LSI Logic 16-bit DSP Processor */
+    DEFCONST(EM_MMIX)		/* Donald Knuth's educational 64-bit processor */
+    DEFCONST(EM_HUANY)		/* Harvard University machine-independent object files */
+    DEFCONST(EM_PRISM)		/* SiTera Prism */
+    DEFCONST(EM_AVR)		/* Atmel AVR 8-bit microcontroller */
+    DEFCONST(EM_FR30)		/* Fujitsu FR30 */
+    DEFCONST(EM_D10V)		/* Mitsubishi D10V */
+    DEFCONST(EM_D30V)		/* Mitsubishi D30V */
+    DEFCONST(EM_V850)		/* NEC v850 */
+    DEFCONST(EM_M32R)		/* Mitsubishi M32R */
+    DEFCONST(EM_MN10300)	/* Matsushita MN10300 */
+    DEFCONST(EM_MN10200)	/* Matsushita MN10200 */
+    DEFCONST(EM_PJ)		/* picoJava */
+    DEFCONST(EM_OPENRISC)	/* OpenRISC 32-bit embedded processor */
+    DEFCONST(EM_ARC_A5)		/* ARC Cores Tangent-A5 */
+    DEFCONST(EM_XTENSA)		/* Tensilica Xtensa Architecture */
+    DEFCONST(EM_AARCH64)	/* ARM AARCH64 */
+    DEFCONST(EM_TILEPRO)	/* Tilera TILEPro */
+    DEFCONST(EM_MICROBLAZE)	/* Xilinx MicroBlaze */
+    DEFCONST(EM_TILEGX)		/* Tilera TILE-Gx */
+
+   /* If it is necessary to assign new unofficial EM_* values, please
+      pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the
+      chances of collision with official or non-GNU unofficial values.  */
+
+    DEFCONST(EM_ALPHA)
+
+    /* Legal values for e_version (version).  */
+
+    DEFCONST(EV_NONE)		/* Invalid ELF version */
+    DEFCONST(EV_CURRENT)	/* Current version */
+
+#undef DEFCONST
+%}.
+    ELFMAG0 := 16r7F.
+    ELFMAG1 := $E codePoint.
+    ELFMAG2 := $L codePoint.
+    ELFMAG3 := $F codePoint.
+
+    "Modified (comment): / 16-03-2015 / 15:15:29 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UnixOperatingSystem::ELFFileHeader class methodsFor:'instance creation'!
+
+fromFile: aStringOrFilename
+    ^ self new initializeOnFile: aStringOrFilename
+
+    "Created: / 16-03-2015 / 16:12:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UnixOperatingSystem::ELFFileHeader methodsFor:'accessing'!
+
+e_ident_class
+    ^ data at: 1 + EI_CLASS
+
+    "Created: / 17-03-2015 / 20:26:54 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+e_machine
+    ^ data unsignedShortAt: 1 + 16r12 bigEndian: msb
+
+    "Created: / 16-03-2015 / 16:29:54 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UnixOperatingSystem::ELFFileHeader methodsFor:'initialization'!
+
+initializeOnFile: aStringOrFilename
+    file := aStringOrFilename asFilename.
+    file exists ifFalse:[ 
+        self error:'Given file does not exist'.
+        ^ nil
+    ].
+    file isRegularFile ifFalse:[ 
+        self error:'Given file is not a regular file'.
+        ^ nil
+    ].
+    file readingFileDo:[ :s |
+        s binary.
+        data := s next: 16r18.
+        (data at: 1 + EI_MAG0) ~~ ELFMAG0 ifTrue:[ 
+            self error:'Given file is not a valid ELF file (magic not found)'.
+        ].
+        (data at: 1 + EI_MAG1) ~~ ELFMAG1 ifTrue:[ 
+            self error:'Given file is not a valid ELF file (magic not found)'.
+        ].
+        (data at: 1 + EI_MAG2) ~~ ELFMAG2 ifTrue:[ 
+            self error:'Given file is not a valid ELF file (magic not found)'.
+        ].
+        (data at: 1 + EI_MAG3) ~~ ELFMAG3 ifTrue:[ 
+            self error:'Given file is not a valid ELF file (magic not found)'.
+        ].
+        msb := (data at: 1 + EI_DATA) == ELFDATA2MSB
+    ].
+
+    "Created: / 16-03-2015 / 16:13:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UnixOperatingSystem::ELFFileHeader methodsFor:'queries'!
+
+isFor32BitArchitecture
+    ^ self e_ident_class == ELFCLASS32
+
+    "Created: / 17-03-2015 / 20:31:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+isFor64BitArchitecture
+    ^ self e_ident_class == ELFCLASS64
+
+    "Created: / 17-03-2015 / 20:31:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
 !UnixOperatingSystem::FileDescriptorHandle class methodsFor:'change & update'!
 
 update:aspect with:argument from:anObject
@@ -12455,7 +12751,7 @@
 	    domain:#'AF_INET' type:nil protocol:nil flags:nil
      self getAddressInfo:'www.exept.de' serviceName:nil
 	    domain:#'AF_INET6' type:nil protocol:nil flags:nil
-     self getAddressInfo:'www.baden-württemberg.de' serviceName:nil
+     self getAddressInfo:'www.baden-württemberg.de' serviceName:nil
 	    domain:#'AF_INET' type:#stream protocol:nil flags:nil
     "
 !
@@ -13857,13 +14153,14 @@
 !UnixOperatingSystem class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/UnixOperatingSystem.st,v 1.423 2015-03-09 17:46:04 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/UnixOperatingSystem.st,v 1.424 2015-03-20 10:14:00 vrany Exp $'
 !
 
 version_CVS
-    ^ '$Header: /cvs/stx/stx/libbasic/UnixOperatingSystem.st,v 1.423 2015-03-09 17:46:04 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/UnixOperatingSystem.st,v 1.424 2015-03-20 10:14:00 vrany Exp $'
 ! !
 
 
 UnixOperatingSystem initialize!
+UnixOperatingSystem::ELFConstants initialize!
 UnixOperatingSystem::FileDescriptorHandle initialize!