Skip to content

Commit

Permalink
Simple ELF32 files can now be written.
Browse files Browse the repository at this point in the history
  • Loading branch information
martinmcclure committed Aug 22, 2015
1 parent e94f534 commit 6881fae
Show file tree
Hide file tree
Showing 50 changed files with 245 additions and 45 deletions.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
instance creation
bitWidth

^32
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
instance creation
headerSize

^52
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
instance creation
programHeaderTableEntrySize
^32
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ELF header
eMachine
^ 3 "x86"
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ELF header
elfClass
^ 1"ELFCLASS64"
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
little-endian writing
writeAddress: value
self write4: value
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
program header table
writeProgramHeaderTable
"Currently only handles a single segment"
self write4: 1; "Loadable segment"
writeAddress: 0; "offset of segment from start of file"
writeAddress: elfInfo loadAddress; "where to load the segment in virtual memory"
writeAddress: 0; "unused physical address"
writeAddress: elfInfo segmentSizeInFile; "size of segment in file"
writeAddress: elfInfo segmentSize; "size of segment in memory -- how much memory to allocate"
write4: 7; "rwx permissions"
writeAddress: 4. "32-bit alignment"

Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"class" : {
"bitWidth" : "MartinMcClure 8/22/2015 12:57",
"headerSize" : "MartinMcClure 8/22/2015 13:06",
"programHeaderTableEntrySize" : "MartinMcClure 8/22/2015 13:20" },
"instance" : {
"eMachine" : "MartinMcClure 8/22/2015 11:10",
"elfClass" : "MartinMcClure 8/22/2015 13:09",
"writeAddress:" : "MartinMcClure 8/21/2015 19:57",
"writeProgramHeaderTable" : "MartinMcClure 8/22/2015 12:48" } }
14 changes: 14 additions & 0 deletions packages/Mist-Elf.package/MistElf32Writer.class/properties.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"category" : "Mist-Elf",
"classinstvars" : [
],
"classvars" : [
],
"commentStamp" : "",
"instvars" : [
],
"name" : "MistElf32Writer",
"pools" : [
],
"super" : "MistElfWriter",
"type" : "normal" }
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
instance creation
bitWidth

^64
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
instance creation
headerSize

^64
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
instance creation
programHeaderTableEntrySize
^56
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ELF header
eMachine
^ 62 "x86_64"
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ELF header
elfClass
^ 2 "ELFCLASS64"
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
little-endian writing
writeAddress: value
self write8: value
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
program header table
writeProgramHeaderTable
"Currently only handles a single segment"
self write4: 1; "Loadable segment"
write4: 7; "rwx permissions"
writeAddress: 0; "offset of segment from start of file"
writeAddress: elfInfo loadAddress; "where to load the segment in virtual memory"
writeAddress: 0; "unused physical address"
writeAddress: elfInfo segmentSizeInFile; "size of segment in file"
writeAddress: elfInfo segmentSize; "size of segment in memory -- how much memory to allocate"
writeAddress: 8. "64-bit alignment"

Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"class" : {
"bitWidth" : "MartinMcClure 8/22/2015 12:58",
"headerSize" : "MartinMcClure 8/22/2015 13:06",
"programHeaderTableEntrySize" : "MartinMcClure 8/22/2015 13:19" },
"instance" : {
"eMachine" : "MartinMcClure 8/22/2015 11:09",
"elfClass" : "MartinMcClure 8/21/2015 20:08",
"writeAddress:" : "MartinMcClure 8/21/2015 19:58",
"writeProgramHeaderTable" : "MartinMcClure 8/22/2015 12:32" } }
14 changes: 14 additions & 0 deletions packages/Mist-Elf.package/MistElf64Writer.class/properties.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"category" : "Mist-Elf",
"classinstvars" : [
],
"classvars" : [
],
"commentStamp" : "",
"instvars" : [
],
"name" : "MistElf64Writer",
"pools" : [
],
"super" : "MistElfWriter",
"type" : "normal" }
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
instance creation
bitWidth

^nil
10 changes: 6 additions & 4 deletions packages/Mist-Elf.package/MistElfWriter.class/class/for.on..st
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
instance creation
for: elfInfo on: stream
| inst |
inst := self new.
inst

| instanceClass instance |
instanceClass := self withAllSubclasses detect: [ :any | any bitWidth = elfInfo bitWidth ].
instance := instanceClass new.
instance
elfInfo: elfInfo;
stream: stream.
^ inst
^ instance
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
instance creation
headerSize

self subclassResponsibility
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
instance creation
programHeaderTableEntrySize
self subclassResponsibility
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ELF header
elfClass
self subclassResponsibility
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
ELF header
headerSize

^self class headerSize
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
program header table
programHeaderTableEntrySize
^ self class programHeaderTableEntrySize
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ writeElfHeader

self writeIdent;
write2: 2; "type executable"
write2: 62; "machine: x86_64"
write4: 1; "current version"
write8: elfInfo entryAddress; "the address to start executing code"
write8: 64; "program header table immediately follows this header"
write8: 0; "section header table offset, none in this case"
write2: self eMachine;
write4: 1; "current version"
writeAddress: elfInfo entryAddress; "the address to start executing code"
writeAddress: self headerSize; "program header table immediately follows this header"
writeAddress: 0; "section header table offset, none in this case"
write4: 0; "processor-specific flags. I don't know what's supposed to be here."
write2: 64; "size of this header in bytes"
write2: 56; "bytes in a program header table entry"
write2: self headerSize; "size of this header in bytes"
write2: self programHeaderTableEntrySize; "bytes in a program header table entry"
write2: 1; "number of program header table entries"
write2: 0; "size of a section table entry, which we're not using"
write2: 0; "number of section header table entries"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
ELF header
writeIdent
self write1: 16r7f; "magic"
writeString: 'ELF';
write1: 2; "ELFCLASS64"
write1: 1; "little-endian"
write1: 1; "current version"
write1: 0; "os/abi=sysv"
write1: 0; "abiversion"
writeZeros: 7 "padding"
self
write1: 16r7f; "magic"
writeString: 'ELF';
write1: self elfClass;
write1: 1;
write1: 1;
write1: 0;
write1: 0;
writeZeros: 7 "little-endian" "current version" "os/abi=sysv" "abiversion" "padding"

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
{
"class" : {
"for:on:" : "MartinMcClure 7/21/2013 11:11" },
"bitWidth" : "MartinMcClure 8/22/2015 12:57",
"for:on:" : "MartinMcClure 8/22/2015 12:59",
"headerSize" : "MartinMcClure 8/22/2015 13:02",
"programHeaderTableEntrySize" : "MartinMcClure 8/22/2015 13:20" },
"instance" : {
"elfClass" : "MartinMcClure 8/21/2015 20:07",
"elfInfo:" : "MartinMcClure 7/21/2013 11:13",
"headerSize" : "MartinMcClure 8/22/2015 13:03",
"programHeaderTableEntrySize" : "MartinMcClure 8/22/2015 13:20",
"stream:" : "MartinMcClure 7/21/2013 11:13",
"write" : "MartinMcClure 7/21/2013 11:01",
"write1:" : "MartinMcClure 7/21/2013 10:54",
"write2:" : "MartinMcClure 7/21/2013 10:54",
"write4:" : "MartinMcClure 7/21/2013 10:54",
"write8:" : "MartinMcClure 7/21/2013 10:55",
"writeElfHeader" : "MartinMcClure 7/21/2013 10:59",
"writeIdent" : "MartinMcClure 7/21/2013 10:54",
"writeProgramHeaderTable" : "MartinMcClure 7/21/2013 11:05",
"writeElfHeader" : "MartinMcClure 8/22/2015 12:21",
"writeIdent" : "MartinMcClure 8/21/2015 20:09",
"writeString:" : "MartinMcClure 7/21/2013 11:21",
"writeZeros:" : "MartinMcClure 7/21/2013 10:55" } }
2 changes: 1 addition & 1 deletion packages/Mist-Elf.package/monticello.meta/version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
(name 'Mist-Elf-MartinMcClure.6' message 'Cleaned up some no-longer-used things in the ELF header writing.' id '79051f68-5d46-4a41-b740-e5c08f268468' date '19 August 2015' time '9:18:16.126916 pm' author 'MartinMcClure' ancestors ((name 'Mist-Elf-MartinMcClure.5' message 'ElfFile has become MistElfWriter, with changes to support writing of an image with an ElfHeader object rather than just a program with no objects in it.' id 'f7ad70d1-beec-4d04-bff8-b78c24bcd3ea' date '12 August 2013' time '10:45:02.685 am' author 'MartinMcClure' ancestors ((name 'Mist-Elf-MartinMcClure.4' message 'Another example for GDB disassembly.' id '70b8ebbb-f25e-42fe-8aab-cdd5a56c2e4e' date '27 January 2013' time '9:36:05.139 pm' author 'MartinMcClure' ancestors ((name 'Mist-Elf-MartinMcClure.3' message 'Added two more ELF examples -- these as examples to see how GDB disassembles certain bytes.' id 'd03e7ba4-8b98-481f-86c3-4a7690d169c3' date '27 January 2013' time '4:48:04.674 pm' author 'MartinMcClure' ancestors ((name 'Mist-Elf-MartinMcClure.2' message 'Fixed the ELF examples, which had gotten broken at some opint.' id '6516d4aa-8999-46b5-87f6-38fc45c3a787' date '22 January 2013' time '10:43:34.05 pm' author 'MartinMcClure' ancestors ((name 'Mist-Elf-MartinMcClure.1' message 'Refactored the sole Mist package into multiple packages.' id 'c9dccf15-c8e6-476c-a656-a5e58555942a' date '25 November 2012' time '11:21:20.51 pm' author 'MartinMcClure' ancestors () stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())
(name 'Mist-Elf-MartinMcClure.7' message 'Simple ELF32 files can now be written.' id 'a87cfb9f-c832-4f2f-9494-c3f503b31240' date '22 August 2015' time '1:52:06.459754 pm' author 'MartinMcClure' ancestors ((name 'Mist-Elf-MartinMcClure.6' message 'Cleaned up some no-longer-used things in the ELF header writing.' id '79051f68-5d46-4a41-b740-e5c08f268468' date '19 August 2015' time '9:18:16.126916 pm' author 'MartinMcClure' ancestors ((name 'Mist-Elf-MartinMcClure.5' message 'ElfFile has become MistElfWriter, with changes to support writing of an image with an ElfHeader object rather than just a program with no objects in it.' id 'f7ad70d1-beec-4d04-bff8-b78c24bcd3ea' date '12 August 2013' time '10:45:02.685 am' author 'MartinMcClure' ancestors ((name 'Mist-Elf-MartinMcClure.4' message 'Another example for GDB disassembly.' id '70b8ebbb-f25e-42fe-8aab-cdd5a56c2e4e' date '27 January 2013' time '9:36:05.139 pm' author 'MartinMcClure' ancestors ((name 'Mist-Elf-MartinMcClure.3' message 'Added two more ELF examples -- these as examples to see how GDB disassembles certain bytes.' id 'd03e7ba4-8b98-481f-86c3-4a7690d169c3' date '27 January 2013' time '4:48:04.674 pm' author 'MartinMcClure' ancestors ((name 'Mist-Elf-MartinMcClure.2' message 'Fixed the ELF examples, which had gotten broken at some opint.' id '6516d4aa-8999-46b5-87f6-38fc45c3a787' date '22 January 2013' time '10:43:34.05 pm' author 'MartinMcClure' ancestors ((name 'Mist-Elf-MartinMcClure.1' message 'Refactored the sole Mist package into multiple packages.' id 'c9dccf15-c8e6-476c-a656-a5e58555942a' date '25 November 2012' time '11:21:20.51 pm' author 'MartinMcClure' ancestors () stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
accessing
bitWidth: anObject
bitWidth := anObject
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
accessing
bitWidth
^ bitWidth
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
private
computeBytes
"Prerequisite: my instvars must all be set. Initialize my sruct bytes to be a valid ELF header based on those instvars. For now, only a single program segment is allowed, and that's all Mist needs at present."
"Prerequisite: my instvars must all be set. Initialize my struct bytes to be a valid ELF header based on those instvars. For now, only a single program segment is allowed, and that's all Mist needs at present."

| stream writer |
stream := WriteStream on: theBytes.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ initialize-release
initialize
sizeInBytes := 256.
theBytes := ByteArray new: 120.
bitWidth := 64.

Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
"class" : {
},
"instance" : {
"computeBytes" : "MartinMcClure 7/21/2013 11:14",
"bitWidth" : "MartinMcClure 8/22/2015 12:55",
"bitWidth:" : "MartinMcClure 8/22/2015 12:55",
"computeBytes" : "MartinMcClure 8/22/2015 12:54",
"entryAddress" : "MartinMcClure 7/21/2013 10:58",
"entryAddress:" : "MartinMcClure 7/20/2013 23:54",
"initialize" : "MartinMcClure 7/19/2013 11:04",
"initialize" : "MartinMcClure 8/22/2015 12:56",
"loadAddress" : "MartinMcClure 7/21/2013 11:03",
"loadAddress:" : "MartinMcClure 7/19/2013 15:45",
"segmentSize" : "MartinMcClure 7/21/2013 11:22",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"segmentSize",
"segmentSizeInFile",
"loadAddress",
"entryAddress" ],
"entryAddress",
"bitWidth" ],
"name" : "MistElfInfo",
"pools" : [
],
Expand Down
2 changes: 1 addition & 1 deletion packages/Mist-Objects.package/monticello.meta/version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
(name 'Mist-Objects-MartinMcClure.2' message 'Many little changes. Most are connected with getting call and return to work, and handling args and temps of methods correctly with call and return.' id '0677a69c-78f1-495f-803e-f45a4dce3154' date '28 December 2013' time '5:43:35.126 pm' author 'MartinMcClure' ancestors ((name 'Mist-Objects-MartinMcClure.1' message 'Look! Mist now has images that contain objects, including an ElfInfo object that provides the ELF header to the file, Method objects that can be executed, and FreeObjects that are not allocated for any other purpose.' id 'f85907b0-a787-4509-98de-43efc3eea889' date '12 August 2013' time '10:47:30.861 am' author 'MartinMcClure' ancestors () stepChildren ())) stepChildren ())
(name 'Mist-Objects-MartinMcClure.3' message 'Simple ELF32 files can now be written.' id 'e4af33a5-92dd-4ce8-88df-ff0bfb62b76e' date '22 August 2015' time '1:52:29.74985 pm' author 'MartinMcClure' ancestors ((name 'Mist-Objects-MartinMcClure.2' message 'Many little changes. Most are connected with getting call and return to work, and handling args and temps of methods correctly with call and return.' id '0677a69c-78f1-495f-803e-f45a4dce3154' date '28 December 2013' time '5:43:35.126 pm' author 'MartinMcClure' ancestors ((name 'Mist-Objects-MartinMcClure.1' message 'Look! Mist now has images that contain objects, including an ElfInfo object that provides the ELF header to the file, Method objects that can be executed, and FreeObjects that are not allocated for any other purpose.' id 'f85907b0-a787-4509-98de-43efc3eea889' date '12 August 2013' time '10:47:30.861 am' author 'MartinMcClure' ancestors () stepChildren ())) stepChildren ())) stepChildren ())
Empty file.
23 changes: 23 additions & 0 deletions packages/Mist-Tests.package/Elf32Test.class/instance/test42.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
tests
test42
"Write the hand-assembled program to a 64-bit ELF file, and run it.
The program should exit with code 42."

| elfInfo program imageStream loadAddress elfClass headersSize |
program := #[16rC7 16rC0 252 0 0 0 16rC7 16rC3 16r2A 00 00 00 16rCD 16r80]. "16rCC" "mov rax,231 (exit_group)" "mov rdi,16r2a" "syscall"
loadAddress := 16r400000.
elfClass := MistElf32Writer.
headersSize := elfClass headerSize + elfClass programHeaderTableEntrySize.
elfInfo := MistElfInfo new.
elfInfo
bitWidth: 32;
loadAddress: loadAddress;
entryAddress: loadAddress + headersSize;
segmentSize: 16r1000;
segmentSizeInFile: headersSize + program size. "One page is plenty for this executable."
imageStream := self fileStream.
(elfClass for: elfInfo on: imageStream) write.
imageStream
nextPutAll: program;
close.
self executeWithInput: '' expectingOutput: '' expectingExitStatus: 42
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"class" : {
},
"instance" : {
"test42" : "MartinMcClure 8/22/2015 13:50" } }
14 changes: 14 additions & 0 deletions packages/Mist-Tests.package/Elf32Test.class/properties.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"category" : "Mist-Tests",
"classinstvars" : [
],
"classvars" : [
],
"commentStamp" : "",
"instvars" : [
],
"name" : "Elf32Test",
"pools" : [
],
"super" : "ElfTest",
"type" : "normal" }
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ test42
segmentSize: 16r1000;
segmentSizeInFile: 128 + program size. "One page is plenty for this executable."
imageStream := self fileStream.
(MistElfWriter for: elfInfo on: imageStream)
(MistElf64Writer for: elfInfo on: imageStream)
write;
write8: 0.
imageStream
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
"class" : {
},
"instance" : {
"test42" : "MartinMcClure 8/21/2015 19:15" } }
"test42" : "MartinMcClure 8/21/2015 19:33" } }
Loading

0 comments on commit 6881fae

Please sign in to comment.