summaryrefslogtreecommitdiff
path: root/elf/segment.lua
blob: 662f42ee36ed3df0e1aa95cb17169756cb2f789a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
local ec = require("elf.constants")
local fmt = require("elf.fmt")

---@class Segment
---@field type SegmentType
---@field flags integer
---@field offset integer
---@field vaddr integer
---@field paddr integer
---@field filesz integer
---@field memsz integer
---@field align integer

---@class Segments
local M = {}

---@param phdr Segment
---@param endian Endian
---@return string
---@nodiscard
local function pack32(phdr, endian)
    return string.pack(
        fmt.endian(endian) .. string.rep(fmt.word(ec.Class.bit32), 8),
        phdr.type,
        phdr.offset,
        phdr.vaddr,
        phdr.paddr,
        phdr.filesz,
        phdr.memsz,
        phdr.flags,
        phdr.align)
end

---@param phdr Segment
---@param endian Endian
---@return string
---@nodiscard
local function pack64(phdr, endian)
    return string.pack(
        fmt.endian(endian) .. "I4I4" .. string.rep(fmt.word(ec.Class.bit64), 6),
        phdr.type,
        phdr.flags,
        phdr.offset,
        phdr.vaddr,
        phdr.paddr,
        phdr.filesz,
        phdr.memsz,
        phdr.align)
end

---@param phdrs Segment[]
---@param endian Endian
---@param class Class
---@return string
---@nodiscard
function M.pack(phdrs, endian, class)
    local p = {}
    for i, phdr in ipairs(phdrs) do
        p[i] = (class == ec.Class.bit32) and
            pack32(phdr, endian) or
            pack64(phdr, endian)
    end
    return table.concat(p)
end

return M