diff options
| author | V1K1NGbg <victor@ilchev.com> | 2024-08-22 17:49:06 -0300 |
|---|---|---|
| committer | Hisham Muhammad <hisham@gobolinux.org> | 2024-10-21 13:30:51 -0300 |
| commit | f6e87b31d404f99b892b9a1e579b6932f47c6bca (patch) | |
| tree | 80cf419a122b6d5796a7361ac15ff5e64d4c664c /src | |
| parent | dddf557babfb022b77e3db387117e01fb9cf402a (diff) | |
| download | luarocks-f6e87b31d404f99b892b9a1e579b6932f47c6bca.tar.gz luarocks-f6e87b31d404f99b892b9a1e579b6932f47c6bca.tar.bz2 luarocks-f6e87b31d404f99b892b9a1e579b6932f47c6bca.zip | |
Teal: convert luarocks.core.sysdetect
Diffstat (limited to 'src')
| -rw-r--r-- | src/luarocks/core/sysdetect.tl (renamed from src/luarocks/core/sysdetect.lua) | 193 |
1 files changed, 141 insertions, 52 deletions
diff --git a/src/luarocks/core/sysdetect.lua b/src/luarocks/core/sysdetect.tl index 06454f2b..63692e4a 100644 --- a/src/luarocks/core/sysdetect.lua +++ b/src/luarocks/core/sysdetect.tl | |||
| @@ -4,15 +4,65 @@ | |||
| 4 | -- but aiming to cover every platform where LuaRocks is known to run. | 4 | -- but aiming to cover every platform where LuaRocks is known to run. |
| 5 | -- If your system is not detected, patches are welcome! | 5 | -- If your system is not detected, patches are welcome! |
| 6 | 6 | ||
| 7 | local sysdetect = {} | 7 | local record sysdetect |
| 8 | enum Processor | ||
| 9 | "unknown" | ||
| 10 | "sparc" | ||
| 11 | "x86" | ||
| 12 | "mips" | ||
| 13 | "hppa" | ||
| 14 | "sparcv8" | ||
| 15 | "ppc" | ||
| 16 | "ppc64" | ||
| 17 | "ppc64le" | ||
| 18 | "s390" | ||
| 19 | "arm" | ||
| 20 | "armv7l" | ||
| 21 | "arm64" | ||
| 22 | "superh" | ||
| 23 | "sparcv9" | ||
| 24 | "ia_64" | ||
| 25 | "x86_64" | ||
| 26 | "alpha" | ||
| 27 | "aarch64" | ||
| 28 | "riscv64" | ||
| 29 | "alpha" | ||
| 30 | end | ||
| 31 | |||
| 32 | enum System | ||
| 33 | "sysv" | ||
| 34 | "hpux" | ||
| 35 | "netbsd" | ||
| 36 | "linux" | ||
| 37 | "hurd" | ||
| 38 | "solaris" | ||
| 39 | "aix" | ||
| 40 | "irix" | ||
| 41 | "freebsd" | ||
| 42 | "openbsd" | ||
| 43 | "dragonfly" | ||
| 44 | "haiku" | ||
| 45 | "windows" | ||
| 46 | "cygwin" | ||
| 47 | "macosx" | ||
| 48 | end | ||
| 49 | end | ||
| 50 | |||
| 51 | local type System = sysdetect.System | ||
| 52 | local type Processor = sysdetect.Processor | ||
| 8 | 53 | ||
| 9 | local function hex(s) | 54 | local enum Endian |
| 10 | return s:gsub("$(..)", function(x) | 55 | "little" |
| 56 | "big" | ||
| 57 | end | ||
| 58 | |||
| 59 | local function hex(s: string): string | ||
| 60 | return (s:gsub("$(..)", function(x: string): string | ||
| 11 | return string.char(tonumber(x, 16)) | 61 | return string.char(tonumber(x, 16)) |
| 12 | end) | 62 | end)) |
| 13 | end | 63 | end |
| 14 | 64 | ||
| 15 | local function read_int8(fd) | 65 | local function read_int8(fd: FILE): integer |
| 16 | if io.type(fd) == "closed file" then | 66 | if io.type(fd) == "closed file" then |
| 17 | return nil | 67 | return nil |
| 18 | end | 68 | end |
| @@ -24,12 +74,9 @@ local function read_int8(fd) | |||
| 24 | return s:byte() | 74 | return s:byte() |
| 25 | end | 75 | end |
| 26 | 76 | ||
| 27 | local LITTLE = 1 | 77 | local function bytes2number(s: string, endian: Endian): integer |
| 28 | -- local BIG = 2 | 78 | local r: integer = 0 |
| 29 | 79 | if endian == "little" then | |
| 30 | local function bytes2number(s, endian) | ||
| 31 | local r = 0 | ||
| 32 | if endian == LITTLE then | ||
| 33 | for i = #s, 1, -1 do | 80 | for i = #s, 1, -1 do |
| 34 | r = r*256 + s:byte(i,i) | 81 | r = r*256 + s:byte(i,i) |
| 35 | end | 82 | end |
| @@ -41,11 +88,11 @@ local function bytes2number(s, endian) | |||
| 41 | return r | 88 | return r |
| 42 | end | 89 | end |
| 43 | 90 | ||
| 44 | local function read(fd, bytes, endian) | 91 | local function read(fd: FILE, bytes: integer, endian: Endian): integer |
| 45 | if io.type(fd) == "closed file" then | 92 | if io.type(fd) == "closed file" then |
| 46 | return nil | 93 | return nil |
| 47 | end | 94 | end |
| 48 | local s = fd:read(bytes) | 95 | local s: string = fd:read(bytes) |
| 49 | if not s | 96 | if not s |
| 50 | then fd:close() | 97 | then fd:close() |
| 51 | return nil | 98 | return nil |
| @@ -53,15 +100,57 @@ local function read(fd, bytes, endian) | |||
| 53 | return bytes2number(s, endian) | 100 | return bytes2number(s, endian) |
| 54 | end | 101 | end |
| 55 | 102 | ||
| 56 | local function read_int32le(fd) | 103 | local function read_int32le(fd: FILE): integer |
| 57 | return read(fd, 4, LITTLE) | 104 | return read(fd, 4, "little") |
| 58 | end | 105 | end |
| 59 | 106 | ||
| 60 | -------------------------------------------------------------------------------- | 107 | -------------------------------------------------------------------------------- |
| 61 | -- @section ELF | 108 | -- @section ELF |
| 62 | -------------------------------------------------------------------------------- | 109 | -------------------------------------------------------------------------------- |
| 63 | 110 | ||
| 64 | local e_osabi = { | 111 | local record ElfHeader |
| 112 | osabi: integer | ||
| 113 | bits: integer | ||
| 114 | endian: integer | ||
| 115 | elf_version: integer | ||
| 116 | word: integer | ||
| 117 | e_type: integer | ||
| 118 | e_entry: integer | ||
| 119 | e_phoff: integer | ||
| 120 | e_shoff: integer | ||
| 121 | e_flags: integer | ||
| 122 | e_ehsize: integer | ||
| 123 | e_phentsize: integer | ||
| 124 | e_phnum: integer | ||
| 125 | e_shentsize: integer | ||
| 126 | e_shnum: integer | ||
| 127 | e_shstrndx: integer | ||
| 128 | end | ||
| 129 | |||
| 130 | local record ElfSection | ||
| 131 | sh_name_off: integer | ||
| 132 | sh_type: integer | ||
| 133 | sh_flags: integer | ||
| 134 | sh_addr: integer | ||
| 135 | sh_offset: integer | ||
| 136 | sh_size: integer | ||
| 137 | sh_link: integer | ||
| 138 | sh_info: integer | ||
| 139 | |||
| 140 | name: string | ||
| 141 | namesz: integer | ||
| 142 | namedata: string | ||
| 143 | descsz: integer | ||
| 144 | descdata: string | ||
| 145 | type: integer | ||
| 146 | end | ||
| 147 | |||
| 148 | local endians: {integer:Endian} = { | ||
| 149 | [0x01] = "little", | ||
| 150 | [0x02] = "big", | ||
| 151 | } | ||
| 152 | |||
| 153 | local e_osabi: {integer:System} = { | ||
| 65 | [0x00] = "sysv", | 154 | [0x00] = "sysv", |
| 66 | [0x01] = "hpux", | 155 | [0x01] = "hpux", |
| 67 | [0x02] = "netbsd", | 156 | [0x02] = "netbsd", |
| @@ -74,7 +163,7 @@ local e_osabi = { | |||
| 74 | [0x0c] = "openbsd", | 163 | [0x0c] = "openbsd", |
| 75 | } | 164 | } |
| 76 | 165 | ||
| 77 | local e_machines = { | 166 | local e_machines: {integer:Processor} = { |
| 78 | [0x02] = "sparc", | 167 | [0x02] = "sparc", |
| 79 | [0x03] = "x86", | 168 | [0x03] = "x86", |
| 80 | [0x08] = "mips", | 169 | [0x08] = "mips", |
| @@ -94,17 +183,18 @@ local e_machines = { | |||
| 94 | [0x9026] = "alpha", | 183 | [0x9026] = "alpha", |
| 95 | } | 184 | } |
| 96 | 185 | ||
| 97 | local SHT_NOTE = 7 | 186 | local SHT_NOTE <const> = 7 |
| 98 | 187 | ||
| 99 | local function read_elf_section_headers(fd, hdr) | 188 | local function read_elf_section_headers(fd: FILE, hdr: ElfHeader): {string: ElfSection} |
| 100 | local endian = hdr.endian | 189 | local endian = endians[hdr.endian] |
| 101 | local word = hdr.word | 190 | local word: integer = hdr.word |
| 102 | 191 | ||
| 103 | local strtab_offset | 192 | local strtab_offset: integer |
| 104 | local sections = {} | 193 | local sections: {string:ElfSection} = {} |
| 194 | local secarray: {ElfSection} = {} | ||
| 105 | for i = 0, hdr.e_shnum - 1 do | 195 | for i = 0, hdr.e_shnum - 1 do |
| 106 | fd:seek("set", hdr.e_shoff + (i * hdr.e_shentsize)) | 196 | fd:seek("set", hdr.e_shoff + (i * hdr.e_shentsize)) |
| 107 | local section = {} | 197 | local section: ElfSection = {} |
| 108 | section.sh_name_off = read(fd, 4, endian) | 198 | section.sh_name_off = read(fd, 4, endian) |
| 109 | section.sh_type = read(fd, 4, endian) | 199 | section.sh_type = read(fd, 4, endian) |
| 110 | section.sh_flags = read(fd, word, endian) | 200 | section.sh_flags = read(fd, word, endian) |
| @@ -123,10 +213,10 @@ local function read_elf_section_headers(fd, hdr) | |||
| 123 | elseif i == hdr.e_shstrndx then | 213 | elseif i == hdr.e_shstrndx then |
| 124 | strtab_offset = section.sh_offset | 214 | strtab_offset = section.sh_offset |
| 125 | end | 215 | end |
| 126 | table.insert(sections, section) | 216 | table.insert(secarray, section) |
| 127 | end | 217 | end |
| 128 | if strtab_offset then | 218 | if strtab_offset then |
| 129 | for _, section in ipairs(sections) do | 219 | for _, section in ipairs(secarray) do |
| 130 | fd:seek("set", strtab_offset + section.sh_name_off) | 220 | fd:seek("set", strtab_offset + section.sh_name_off) |
| 131 | section.name = fd:read(32):gsub("%z.*", "") | 221 | section.name = fd:read(32):gsub("%z.*", "") |
| 132 | sections[section.name] = section | 222 | sections[section.name] = section |
| @@ -135,9 +225,9 @@ local function read_elf_section_headers(fd, hdr) | |||
| 135 | return sections | 225 | return sections |
| 136 | end | 226 | end |
| 137 | 227 | ||
| 138 | local function detect_elf_system(fd, hdr, sections) | 228 | local function detect_elf_system(fd: FILE, hdr: ElfHeader, sections: {string:ElfSection}): System |
| 139 | local system = e_osabi[hdr.osabi] | 229 | local system = e_osabi[hdr.osabi] |
| 140 | local endian = hdr.endian | 230 | local endian = endians[hdr.endian] |
| 141 | 231 | ||
| 142 | if system == "sysv" then | 232 | if system == "sysv" then |
| 143 | local abitag = sections[".note.ABI-tag"] | 233 | local abitag = sections[".note.ABI-tag"] |
| @@ -197,8 +287,8 @@ local function detect_elf_system(fd, hdr, sections) | |||
| 197 | return system | 287 | return system |
| 198 | end | 288 | end |
| 199 | 289 | ||
| 200 | local function read_elf_header(fd) | 290 | local function read_elf_header(fd: FILE): ElfHeader, Processor |
| 201 | local hdr = {} | 291 | local hdr: ElfHeader = {} |
| 202 | 292 | ||
| 203 | hdr.bits = read_int8(fd) | 293 | hdr.bits = read_int8(fd) |
| 204 | hdr.endian = read_int8(fd) | 294 | hdr.endian = read_int8(fd) |
| @@ -211,12 +301,12 @@ local function read_elf_header(fd) | |||
| 211 | return nil | 301 | return nil |
| 212 | end | 302 | end |
| 213 | 303 | ||
| 214 | local endian = hdr.endian | 304 | local endian = endians[hdr.endian] |
| 215 | fd:seek("set", 0x10) | 305 | fd:seek("set", 0x10) |
| 216 | hdr.e_type = read(fd, 2, endian) | 306 | hdr.e_type = read(fd, 2, endian) |
| 217 | local machine = read(fd, 2, endian) | 307 | local machine = read(fd, 2, endian) |
| 218 | local processor = e_machines[machine] or "unknown" | 308 | local processor = e_machines[machine] or "unknown" |
| 219 | if endian == 1 and processor == "ppc64" then | 309 | if endian == "little" and processor == "ppc64" then |
| 220 | processor = "ppc64le" | 310 | processor = "ppc64le" |
| 221 | end | 311 | end |
| 222 | 312 | ||
| @@ -242,7 +332,7 @@ local function read_elf_header(fd) | |||
| 242 | return hdr, processor | 332 | return hdr, processor |
| 243 | end | 333 | end |
| 244 | 334 | ||
| 245 | local function detect_elf(fd) | 335 | local function detect_elf(fd: FILE): System, Processor |
| 246 | local hdr, processor = read_elf_header(fd) | 336 | local hdr, processor = read_elf_header(fd) |
| 247 | if not hdr then | 337 | if not hdr then |
| 248 | return nil | 338 | return nil |
| @@ -256,25 +346,25 @@ end | |||
| 256 | -- @section Mach Objects (Apple) | 346 | -- @section Mach Objects (Apple) |
| 257 | -------------------------------------------------------------------------------- | 347 | -------------------------------------------------------------------------------- |
| 258 | 348 | ||
| 259 | local mach_l64 = { | 349 | local mach_l64: {integer:Processor} = { |
| 260 | [7] = "x86_64", | 350 | [7] = "x86_64", |
| 261 | [12] = "aarch64", | 351 | [12] = "aarch64", |
| 262 | } | 352 | } |
| 263 | 353 | ||
| 264 | local mach_b64 = { | 354 | local mach_b64: {integer:Processor} = { |
| 265 | [0] = "ppc64", | 355 | [0] = "ppc64", |
| 266 | } | 356 | } |
| 267 | 357 | ||
| 268 | local mach_l32 = { | 358 | local mach_l32: {integer:Processor} = { |
| 269 | [7] = "x86", | 359 | [7] = "x86", |
| 270 | [12] = "arm", | 360 | [12] = "arm", |
| 271 | } | 361 | } |
| 272 | 362 | ||
| 273 | local mach_b32 = { | 363 | local mach_b32: {integer:Processor} = { |
| 274 | [0] = "ppc", | 364 | [0] = "ppc", |
| 275 | } | 365 | } |
| 276 | 366 | ||
| 277 | local function detect_mach(magic, fd) | 367 | local function detect_mach(magic: string, fd: FILE): System, Processor |
| 278 | if not magic then | 368 | if not magic then |
| 279 | return nil | 369 | return nil |
| 280 | end | 370 | end |
| @@ -316,20 +406,20 @@ local pe_machine = { | |||
| 316 | [0x014c] = "x86", | 406 | [0x014c] = "x86", |
| 317 | } | 407 | } |
| 318 | 408 | ||
| 319 | local function detect_pe(fd) | 409 | local function detect_pe(fd: FILE): System, Processor |
| 320 | fd:seek("set", 60) -- position of PE header position | 410 | fd:seek("set", 60) -- position of PE header position |
| 321 | local peoffset = read_int32le(fd) -- read position of PE header | 411 | local peoffset = read_int32le(fd) -- read position of PE header |
| 322 | if not peoffset then | 412 | if not peoffset then |
| 323 | return nil | 413 | return nil |
| 324 | end | 414 | end |
| 325 | local system = "windows" | 415 | local system: System = "windows" |
| 326 | fd:seek("set", peoffset + 4) -- move to position of Machine section | 416 | fd:seek("set", peoffset + 4) -- move to position of Machine section |
| 327 | local machine = read(fd, 2, LITTLE) | 417 | local machine = read(fd, 2, "little") |
| 328 | local processor = pe_machine[machine] | 418 | local processor: Processor = pe_machine[machine] |
| 329 | 419 | ||
| 330 | local rdata_pos = fd:read(736):match(".rdata%z%z............(....)") | 420 | local rdata_pos_s = fd:read(736):match(".rdata%z%z............(....)") |
| 331 | if rdata_pos then | 421 | if rdata_pos_s then |
| 332 | rdata_pos = bytes2number(rdata_pos, LITTLE) | 422 | local rdata_pos = bytes2number(rdata_pos_s, "little") |
| 333 | fd:seek("set", rdata_pos) | 423 | fd:seek("set", rdata_pos) |
| 334 | local data = fd:read(512) | 424 | local data = fd:read(512) |
| 335 | if data:match("cygwin") or data:match("cyggcc") then | 425 | if data:match("cygwin") or data:match("cyggcc") then |
| @@ -344,8 +434,7 @@ end | |||
| 344 | -- @section API | 434 | -- @section API |
| 345 | -------------------------------------------------------------------------------- | 435 | -------------------------------------------------------------------------------- |
| 346 | 436 | ||
| 347 | function sysdetect.detect_file(file) | 437 | function sysdetect.detect_file(file: string): System, Processor |
| 348 | assert(type(file) == "string") | ||
| 349 | local fd = io.open(file, "rb") | 438 | local fd = io.open(file, "rb") |
| 350 | if not fd then | 439 | if not fd then |
| 351 | return nil | 440 | return nil |
| @@ -360,12 +449,12 @@ function sysdetect.detect_file(file) | |||
| 360 | return detect_mach(magic, fd) | 449 | return detect_mach(magic, fd) |
| 361 | end | 450 | end |
| 362 | 451 | ||
| 363 | local cache_system | 452 | local cache_system: System |
| 364 | local cache_processor | 453 | local cache_processor: Processor |
| 365 | 454 | ||
| 366 | function sysdetect.detect(input_file) | 455 | function sysdetect.detect(input_file: string): System, Processor |
| 367 | local dirsep = package.config:sub(1,1) | 456 | local dirsep = package.config:sub(1,1) |
| 368 | local files | 457 | local files: {string} |
| 369 | 458 | ||
| 370 | if input_file then | 459 | if input_file then |
| 371 | files = { input_file } | 460 | files = { input_file } |
| @@ -374,7 +463,7 @@ function sysdetect.detect(input_file) | |||
| 374 | return cache_system, cache_processor | 463 | return cache_system, cache_processor |
| 375 | end | 464 | end |
| 376 | 465 | ||
| 377 | local PATHsep | 466 | local PATHsep: string |
| 378 | local interp = arg and arg[-1] | 467 | local interp = arg and arg[-1] |
| 379 | if dirsep == "/" then | 468 | if dirsep == "/" then |
| 380 | -- Unix | 469 | -- Unix |
