Skip to content

Commit 377d7a1

Browse files
committed
add linker elf stubs
1 parent e7e111e commit 377d7a1

File tree

17 files changed

+188
-0
lines changed

17 files changed

+188
-0
lines changed

lib/caotral/linker.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ def link(input: @input, output: @output, debug: @debug, shared: @shared) = IO.po
1212

1313
def link_command(input: @input, output: @output, debug: @debug, shared: @shared)
1414
ld_path = []
15+
return to_elf(input:, output:, debug:) if @linker == "self"
16+
1517
if @shared
1618
ld_path << "--shared"
1719
ld_path << "#{libpath}/crti.o"
@@ -36,4 +38,9 @@ def link_command(input: @input, output: @output, debug: @debug, shared: @shared)
3638

3739
def libpath = @libpath ||= File.dirname(Dir.glob("/usr/lib*/**/crti.o").last)
3840
def gcc_libpath = @gcc_libpath ||= File.dirname(Dir.glob("/usr/lib/gcc/x86_64-*/*/crtbegin.o").last)
41+
42+
def to_elf(input: @input, output: @output, debug: @debug)
43+
elf_obj = Caotral::Linker::ELF::Reader.new(input:, debug:).read
44+
Caotral::Linker::ELF::Writer.new(elf_obj:, output:, debug:).write
45+
end
3946
end

lib/caotral/linker/elf.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
class Caotral::Linker::ELF
2+
attr_reader :sections, :header
3+
def initialize
4+
@sections = Caotral::Linker::ELF::Sections.new
5+
@header = Caotral::Linker::ELF::Header.new
6+
end
7+
end

lib/caotral/linker/elf/object.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
class Caotral::Linker::ELF::Object
2+
attr_reader :bin, :debug
3+
4+
def initialize(bin:, debug: false)
5+
@bin, @debug = bin, debug
6+
end
7+
end

lib/caotral/linker/elf/section.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
class Caotral::Linker::ELF::Section
2+
attr_accessor :name
3+
attr_reader :section_name, :header, :body
4+
def initialize(type:, options: {})
5+
type_string = type.to_s.capitalize
6+
type_string = type_string.upcase if type_string == "Bss"
7+
# section_name is extra information about section type
8+
@section_name = type_string.downcase
9+
# name is used in section header string table in elf file
10+
@name = section_name == "null" ? "" : "\0.#{section_name}"
11+
@header, @body = nil, nil
12+
end
13+
end
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
class Caotral::Linker::ELF::Section::Shstrtab
2+
include Caotral::Assembler::ELF::Utils
3+
def initialize(**opts) = @name = []
4+
def build = bytes.flatten.pack("C*")
5+
def set!(name:) = (@name << name!(name); self)
6+
end
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
class Caotral::Linker::ELF::Section::Strtab
2+
include Caotral::Assembler::ELF::Utils
3+
def initialize(names = "\0main\0", **opts) = @names = names
4+
def build = @names.bytes.pack("C*")
5+
end
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
class Caotral::Linker::ELF::Section::Symtab
2+
include Caotral::Assembler::ELF::Utils
3+
def initialize(**opts)
4+
@entsize = []
5+
@name = num2bytes(0, 4)
6+
@info = num2bytes(0, 1)
7+
@other = num2bytes(0, 1)
8+
@shndx = num2bytes(0, 2)
9+
@value = num2bytes(0, 8)
10+
@size = num2bytes(0, 8)
11+
end
12+
end
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
class Caotral::Linker::ELF::Section::Text
2+
def initialize = @bytes = []
3+
def build = @bytes.flatten.pack("C*")
4+
end
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
class Caotral::Linker::ELF::SectionHeader
2+
include Caotral::Assembler::ELF::Utils
3+
def initialize
4+
@name = nil
5+
@type = nil
6+
@flags = nil
7+
@addr = nil
8+
@offset = nil
9+
@size = nil
10+
@link = nil
11+
@info = nil
12+
@addralign = nil
13+
@entsize = nil
14+
end
15+
16+
def build = bytes.flatten.pack("C*")
17+
18+
def set!(name: nil, type: nil, flags: nil, addr: nil,
19+
offset: nil, size: nil, link: nil, info: nil,
20+
addralign: nil, entsize: nil)
21+
@name = num2bytes(name, 4) if check(name, 4)
22+
@type = num2bytes(type, 4) if check(type, 4)
23+
@flags = num2bytes(flags, 8) if check(flags, 8)
24+
@addr = num2bytes(addr, 8) if check(addr, 8)
25+
@offset = num2bytes(offset, 8) if check(offset, 8)
26+
@size = num2bytes(size, 8) if check(size, 8)
27+
@link = num2bytes(link, 4) if check(link, 4)
28+
@info = num2bytes(info, 4) if check(info, 4)
29+
@addralign = num2bytes(addralign, 8) if check(addralign, 8)
30+
@entsize = num2bytes(entsize, 8) if check(entsize, 8)
31+
self
32+
end
33+
34+
def null! = set!(name: 0, type: 0, flags: 0, addr: 0, offset: 0, size: 0, link: 0, info: 0, addralign: 0, entsize: 0)
35+
36+
private def bytes = [@name, @type, @flags, @addr, @offset, @size, @link, @info, @addralign, @entsize]
37+
end

lib/caotral/linker/elf/sections.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
class Caotral::Linker::ELF::Sections
2+
include Enumerable
3+
4+
def initialize = @sections = []
5+
def each(&block) = @sections.each(&block)
6+
def add(section) = @sections << section
7+
alias << add
8+
def [](index)
9+
case index
10+
when Integer
11+
@sections[index]
12+
when String, Symbol
13+
@sections.find { _1.section_name.to_s == index.to_s }
14+
else
15+
raise ArgumentError, "Invalid index type: #{index.class}"
16+
end
17+
end
18+
end

0 commit comments

Comments
 (0)