From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from [87.239.111.99] (localhost [127.0.0.1]) by dev.tarantool.org (Postfix) with ESMTP id C712B45ECC8; Wed, 31 May 2023 17:50:02 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org C712B45ECC8 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1685544602; bh=aEWve6bpbS8ZGWU9+qQCWN3tP+VYVl3Cj+AOTk+dGrg=; h=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=PAbsaFhYjtyIGijSUTzJc7lRjmUOC9rEnKJrX+Xe3dEXK3HxqZ211GpLb3z7uDi7m 6yYFP5cxv8Ry5I7qA27gpwpsQ7W0WSKJ4GHXyIqiMVqVFmo2/TmIK+edY57jGGrE1p pNhFgEOaLUFUYUwycFHVy5R6Ld9Q/6ztVUT2Fmh8= Received: from smtp47.i.mail.ru (smtp47.i.mail.ru [95.163.41.85]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id 61A6F45ECC8 for ; Wed, 31 May 2023 17:50:01 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 61A6F45ECC8 Received: by smtp47.i.mail.ru with esmtpa (envelope-from ) id 1q4N9E-00Fy19-BA; Wed, 31 May 2023 17:50:00 +0300 Content-Type: multipart/alternative; boundary="------------Ts8B9jJCEnzvKEz3EfJTlp3i" Message-ID: <8e60e454-de80-e532-ee1d-ad771956ab16@tarantool.org> Date: Wed, 31 May 2023 17:50:00 +0300 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.11.0 To: Maxim Kokryashkin , Sergey Bronnikov References: <7be88fa24695ad2f3c15a9a23bd884ca0acc36f5.1685433737.git.sergeyb@tarantool.org> <1685437504.620113247@f480.i.mail.ru> Content-Language: en-US In-Reply-To: <1685437504.620113247@f480.i.mail.ru> X-Mailru-Src: smtp X-4EC0790: 10 X-7564579A: 646B95376F6C166E X-77F55803: 4F1203BC0FB41BD9FA9FE7958A526B77434C4E65687CAA01A384C92BBF1940FA00894C459B0CD1B92E671F8E51FE30C6CD067218A474075A0003DDACC933C129DB5804FDCCB62C7C X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE7AA1605287C7F04D6EA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F7900637E5A8E5ECB3FF24018638F802B75D45FF36EB9D2243A4F8B5A6FCA7DBDB1FC311F39EFFDF887939037866D6147AF826D8BFF8378DC68F09AD1D08209C2CC2ED1C117882F4460429728776938767073520B28585415E75ADA92CC0D3CB04F14752D2E47CDBA5A96583BA9C0B312567BB2376E601842F6C81A19E625A9149C048EE7B96B19DC4093321A68A47777D5C6D9CD8FC6C240DEA7642DBF02ECDB25306B2B78CF848AE20165D0A6AB1C7CE11FEE3632EDEA9CD5989A3BA3038C0950A5D36B5C8C57E37DE458B330BD67F2E7D9AF16D1867E19FE14079C09775C1D3CA48CFED8438A78DFE0A9E1DD303D21008E298D5E8D9A59859A8B6B372FE9A2E580EFC725E5C173C3A84C3335407143AA9223635872C767BF85DA2F004C90652538430E4A6367B16DE6309 X-B7AD71C0: 1B70FBA5C9BEEE72C9761FC34675ADEB871C96603B655635EE9D5CB6078CC77CBD06D4073086D21D135824B3FEAB4495 X-C1DE0DAB: 0D63561A33F958A55B4B1AA6E8F4046ECA22985309EA67B5EAFEA8E5C9EF9E03F87CCE6106E1FC07E67D4AC08A07B9B062B3BD3CC35DA588CB5012B2E24CD356 X-C8649E89: 1C3962B70DF3F0AD75DCE07D45A749953FED46C3ACD6F73ED3581295AF09D3DF87807E0823442EA2ED31085941D9CD0AF7F820E7B07EA4CF9799B5E413FB318B3956D15EBC635466A62DCDB1904EFF8FC92D24591DD6310EAF1510F4A86D2C81A3AF5313DFD170D720EA288CE66922A83534EABBDE181759A74DFFEFA5DC0E7F02C26D483E81D6BE0DBAE6F56676BC7117BB6831D7356A2DEC5B5AD62611EEC62B5AFB4261A09AF0 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojiEKym4lkdssGGF95z3BZ+w== X-Mailru-Sender: 11C2EC085EDE56FAC07928AF2646A7695679832EDFC9E300465E9EE1D95A35787962F9E9328436E1EBA65886582A37BD66FEC6BF5C9C28D98A98C1125256619760D574B6FC815AB872D6B4FCE48DF648AE208404248635DF X-Mras: Ok Subject: Re: [Tarantool-patches] [PATCH luajit v2 1/1] Fix saved bytecode encapsulated in ELF objects. X-BeenThere: tarantool-patches@dev.tarantool.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Sergey Bronnikov via Tarantool-patches Reply-To: Sergey Bronnikov Cc: tarantool-patches@dev.tarantool.org Errors-To: tarantool-patches-bounces@dev.tarantool.org Sender: "Tarantool-patches" This is a multi-part message in MIME format. --------------Ts8B9jJCEnzvKEz3EfJTlp3i Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Hello, Max! Thanks for comments! Fixed all comments except checks for constant size and offset, fixes force-pushed. Sergey On 5/30/23 12:05, Maxim Kokryashkin wrote: > Hi, Sergey! > Thanks for the patch! > LGTM, except for a few comments below. > > > > diff --git > a/test/tarantool-tests/lj-366-strtab-correct-size.test.lua > b/test/tarantool-tests/lj-366-strtab-correct-size.test.lua > new file mode 100644 > index 00000000..5dec6751 > --- /dev/null > +++ b/test/tarantool-tests/lj-366-strtab-correct-size.test.lua > @@ -0,0 +1,202 @@ > +local tap = require('tap') > +local test = tap.test('lj-366-strtab-correct-size'):skipcond({ > + -- The test is ELF-specific, and because LuaJIT exports object > + -- files in ELF format for all operating systems except macOS > + -- and Windows we skip test on these OSes. > > Typo: s/we skip test/we skip it/ > Fixed! > + -- See src/jit/bcsave.lua:bcsave_obj. > + ['Disabled on Windows'] = jit.os == 'Windows', > + ['Disabled on macOS'] = jit.os == 'OSX', > +}) > + > +local ffi = require 'ffi' > + > +-- Command below exports bytecode as an object file in ELF > format: > +-- $ luajit -b -n 'lango_team' -e 'print()' xxx.obj > +-- $ file xxx.obj > +-- xxx.obj: ELF 64-bit LSB relocatable, x86-64, version 1 > (SYSV), not stripped > +-- > +-- With read_elf(1) it is possible displaying the entries in > symbol table > > Typo: s/possible displaying the entries/possible to display entries/ > Fixed! > +-- section of the file, if it has one. Object file contains a > single symbol > > Typo: s/a single symbol/the single symbol/ > > +-- with name 'luaJIT_BC_lango_team': > +-- > +-- $ readelf --symbols xxx.obj > +-- > +-- Symbol table '.symtab' contains 2 entries: > +-- Num: Value Size Type Bind Vis Ndx Name > +-- 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND > +-- 1: 0000000000000000 66 OBJECT GLOBAL DEFAULT 4 > luaJIT_BC_lango_team > +-- > +-- and displaying the information contained in the file's > section headers, if > > Typo: s/and to display/ > Fixed! > Also, that sentence seems to be a continuation for the previous > sentence about > `readelf`’s functionality, however it is completely detached from > it both by the > setence inbetween them and grammatically. I suggest moving the > demonstration > of `.symtab` contents after the introduction of readelf’s > functionality, to improve > readability. > > +-- it has any. For our purposes we are interesting in section > .symtab, > > Typo: s/are interesting in section .symtab/are interested in > .symtab section/ > Fixed! > +-- so other sections snipped in the output: > > Typo: s/sections snipped/sections are snipped/ > Fixed! > +-- > +-- $ readelf --section-headers xxx.obj > +-- There are 6 section headers, starting at offset 0x40: > +-- > +-- Section Headers: > +-- [Nr] Name Type Address Offset > +-- Size EntSize Flags Link Info Align > +-- ... > +-- > +-- [ 3] .strtab STRTAB 0000000000000000 00000223 > +-- 0000000000000016 0000000000000000 0 0 1 > +-- ... > +-- Reference numbers for strtab offset and size could be > obtained with > +-- readelf(1). Note that number system of these numbers are > hexadecimal. > + > +local expected_strtab_size = 0x16 > +local expected_strtab_offset = 0x223 > +local module_name = 'lango_team' > > Simple value constants should be uppercased. > Fixed. > + > +-- Symbol name prefix for LuaJIT bytecode defined in bcsave.lua. > +local LJBC_PREFIX = 'luaJIT_BC_' > + > +-- Defined in elf.h. > +local SHT_SYMTAB = 2 > + > +-- Using the same declarations as defined in > . > +ffi.cdef[[ > +typedef struct { > + uint8_t emagic[4], eclass, eendian, eversion, eosabi, > eabiversion, epad[7]; > + uint16_t type, machine; > + uint32_t version; > + uint32_t entry, phofs, shofs; > + uint32_t flags; > + uint16_t ehsize, phentsize, phnum, shentsize, shnum, shstridx; > +} ELF32header; > + > +typedef struct { > + uint8_t emagic[4], eclass, eendian, eversion, eosabi, > eabiversion, epad[7]; > + uint16_t type, machine; > + uint32_t version; > + uint64_t entry, phofs, shofs; > + uint32_t flags; > + uint16_t ehsize, phentsize, phnum, shentsize, shnum, shstridx; > +} ELF64header; > + > +typedef struct { > + uint32_t name, type, flags, addr, ofs, size, link, info, > align, entsize; > +} ELF32sectheader; > + > +typedef struct { > + uint32_t name, type; > + uint64_t flags, addr, ofs, size; > + uint32_t link, info; > + uint64_t align, entsize; > +} ELF64sectheader; > + > +typedef struct { > + uint32_t name, value, size; > + uint8_t info, other; > + uint16_t sectidx; > +} ELF32symbol; > + > +typedef struct { > + uint32_t name; > + uint8_t info, other; > + uint16_t sectidx; > + uint64_t value, size; > +} ELF64symbol; > + > +typedef struct { > + ELF32header hdr; > + ELF32sectheader sect[6]; > + ELF32symbol sym[2]; > + uint8_t space[4096]; > +} ELF32obj; > + > +typedef struct { > + ELF64header hdr; > + ELF64sectheader sect[6]; > + ELF64symbol sym[2]; > + uint8_t space[4096]; > +} ELF64obj; > +]] > + > +local is64_arch = { > + ['x64'] = true, > + ['arm64'] = true, > + ['arm64be'] = true, > + ['ppc'] = false, > + ['mips'] = false, > +} > + > +local is64 = is64_arch[jit.arch] or false > + > +local function create_obj_file(name) > + local elf_filename = os.tmpname() .. '.obj' > + local lua_path = os.getenv('LUA_PATH') > + local lua_bin = require('utils').luacmd(arg):match('%S+') > + local cmd_fmt = 'LUA_PATH="%s" %s -b -n "%s" -e "print()" %s' > + local cmd = (cmd_fmt):format(lua_path, lua_bin, name, > elf_filename) > + local ret = os.execute(cmd) > + assert(ret == 0, 'create an object file') > + return elf_filename > +end > + > +-- Reads a file located in a specified path and returns its > content. > +local function read_file(path) > + local file = assert(io.open(path), 'cannot open an object file') > + local content = file:read('*a') > + file:close() > + return content > +end > + > +-- Parses a buffer in an ELF format and returns an offset and > a size of strtab > +-- and symtab sections. > +local function read_elf(elf_content) > + local ELFobj_type = ffi.typeof(is64 and 'ELF64obj *' or > 'ELF32obj *') > + local ELFsectheader_type = ffi.typeof(is64 and > 'ELF64sectheader *' or 'ELF32sectheader *') > + local elf = ffi.cast(ELFobj_type, elf_content) > + local symtab_hdr, strtab_hdr > + -- Iterate by section headers. > + for i = 0, elf.hdr.shnum do > + local sec = ffi.cast(ELFsectheader_type, elf.sect[i]) > + if sec.type == SHT_SYMTAB then > + symtab_hdr = sec > + strtab_hdr = ffi.cast(ELFsectheader_type, > elf.sect[symtab_hdr.link]) > + break > + end > + end > + > + assert(strtab_hdr ~= nil, 'section .strtab was not found') > + assert(symtab_hdr ~= nil, 'section .symtab was not found') > + > + return strtab_hdr, symtab_hdr > +end > + > +test:plan(3) > + > +local elf_filename = create_obj_file(module_name) > +local elf_content = read_file(elf_filename) > +assert(#elf_content ~= 0, 'cannot read an object file') > + > +local strtab, symtab = read_elf(elf_content) > +local strtab_size = tonumber(strtab.size) > +local strtab_offset = tonumber(strtab.ofs) > +local symtab_size = tonumber(symtab.size) > +local sym_cnt = tonumber(symtab_size / symtab.entsize) > +assert(sym_cnt ~= 0, 'number of symbols is zero') > + > +test:is(strtab_size, expected_strtab_size, 'check .strtab size') > +test:is(strtab_offset, expected_strtab_offset, 'check .strtab > offset') > > As I already said offline, I don’t like that approach. ELF is made > to by > as flexible as possible, so, generally, you have no guarantees about > order and, hence, offsets of any sections. The only reason why we are > getting away with that here, is because this ELF is generated > in `bcsave.lua` in a particular manner. It is ok for now, but no one > knows if this will ever change. I think that the symbol name search > below is sufficient, because it is unlikely to pass with an > incorrect offset. > Sure, I remember your thoughts regarding checking with constant size and offset. I left this for double-checking change proposed in patch. I'll leave this as as without changes and will wait review from Sergey and then we will decide remove these checks or not. > All of the checks are valid for now, though, so feel free to ignore. > > + > +local strtab_str = string.sub(elf_content, strtab_offset, > strtab_offset + strtab_size) > + > +local strtab_p = ffi.cast('char *', strtab_str) > +local sym_name_expected = LJBC_PREFIX .. module_name > +local sym_is_found = false > +for i = 1, sym_cnt do > + local sym_name = ffi.string(strtab_p + i) > + if sym_name_expected == sym_name then > + sym_is_found = true > + break > + end > +end > + > +test:ok(sym_is_found == true, 'symbol is found') > + > +local ret = os.remove(elf_filename) > +assert(ret == true, 'cannot remove an object file') > + > +os.exit(test:check() and 0 or 1) > -- > 2.34.1 > > -- > Best regards, > Maxim Kokryashkin > --------------Ts8B9jJCEnzvKEz3EfJTlp3i Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: 8bit

Hello, Max! Thanks for comments!

Fixed all comments except checks for constant size and offset, fixes force-pushed.


Sergey

On 5/30/23 12:05, Maxim Kokryashkin wrote:
Hi, Sergey!
Thanks for the patch!
LGTM, except for a few comments below.

<snipped>
diff --git a/test/tarantool-tests/lj-366-strtab-correct-size.test.lua b/test/tarantool-tests/lj-366-strtab-correct-size.test.lua
new file mode 100644
index 00000000..5dec6751
--- /dev/null
+++ b/test/tarantool-tests/lj-366-strtab-correct-size.test.lua
@@ -0,0 +1,202 @@
+local tap = require('tap')
+local test = tap.test('lj-366-strtab-correct-size'):skipcond({
+ -- The test is ELF-specific, and because LuaJIT exports object
+ -- files in ELF format for all operating systems except macOS
+ -- and Windows we skip test on these OSes.
Typo: s/we skip test/we skip it/

Fixed!


+ -- See src/jit/bcsave.lua:bcsave_obj.
+ ['Disabled on Windows'] = jit.os == 'Windows',
+ ['Disabled on macOS'] = jit.os == 'OSX',
+})
+
+local ffi = require 'ffi'
+
+-- Command below exports bytecode as an object file in ELF format:
+-- $ luajit -b -n 'lango_team' -e 'print()' xxx.obj
+-- $ file xxx.obj
+-- xxx.obj: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
+--
+-- With read_elf(1) it is possible displaying the entries in symbol table
Typo: s/possible displaying the entries/possible to display entries/


Fixed!


+-- section of the file, if it has one. Object file contains a single symbol
Typo: s/a single symbol/the single symbol/
+-- with name 'luaJIT_BC_lango_team':
+--
+-- $ readelf --symbols xxx.obj
+--
+-- Symbol table '.symtab' contains 2 entries:
+-- Num: Value Size Type Bind Vis Ndx Name
+-- 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
+-- 1: 0000000000000000 66 OBJECT GLOBAL DEFAULT 4 luaJIT_BC_lango_team
+--
+-- and displaying the information contained in the file's section headers, if
Typo: s/and to display/

Fixed!


 
Also, that sentence seems to be a continuation for the previous sentence about
`readelf`’s functionality, however it is completely detached from it both by the
setence inbetween them and grammatically. I suggest moving the demonstration
of `.symtab` contents after the introduction of readelf’s functionality, to improve
readability.
+-- it has any. For our purposes we are interesting in section .symtab,
Typo: s/are interesting in section .symtab/are interested in .symtab section/


Fixed!


+-- so other sections snipped in the output:
Typo: s/sections snipped/sections are snipped/

Fixed!


+--
+-- $ readelf --section-headers xxx.obj
+-- There are 6 section headers, starting at offset 0x40:
+--
+-- Section Headers:
+-- [Nr] Name Type Address Offset
+-- Size EntSize Flags Link Info Align
+-- ...
+--
+-- [ 3] .strtab STRTAB 0000000000000000 00000223
+-- 0000000000000016 0000000000000000 0 0 1
+-- ...
+-- Reference numbers for strtab offset and size could be obtained with
+-- readelf(1). Note that number system of these numbers are hexadecimal.
+
+local expected_strtab_size = 0x16
+local expected_strtab_offset = 0x223
+local module_name = 'lango_team'
Simple value constants should be uppercased.

Fixed.


+
+-- Symbol name prefix for LuaJIT bytecode defined in bcsave.lua.
+local LJBC_PREFIX = 'luaJIT_BC_'
+
+-- Defined in elf.h.
+local SHT_SYMTAB = 2
+
+-- Using the same declarations as defined in <src/jit/bcsave.lua>.
+ffi.cdef[[
+typedef struct {
+ uint8_t emagic[4], eclass, eendian, eversion, eosabi, eabiversion, epad[7];
+ uint16_t type, machine;
+ uint32_t version;
+ uint32_t entry, phofs, shofs;
+ uint32_t flags;
+ uint16_t ehsize, phentsize, phnum, shentsize, shnum, shstridx;
+} ELF32header;
+
+typedef struct {
+ uint8_t emagic[4], eclass, eendian, eversion, eosabi, eabiversion, epad[7];
+ uint16_t type, machine;
+ uint32_t version;
+ uint64_t entry, phofs, shofs;
+ uint32_t flags;
+ uint16_t ehsize, phentsize, phnum, shentsize, shnum, shstridx;
+} ELF64header;
+
+typedef struct {
+ uint32_t name, type, flags, addr, ofs, size, link, info, align, entsize;
+} ELF32sectheader;
+
+typedef struct {
+ uint32_t name, type;
+ uint64_t flags, addr, ofs, size;
+ uint32_t link, info;
+ uint64_t align, entsize;
+} ELF64sectheader;
+
+typedef struct {
+ uint32_t name, value, size;
+ uint8_t info, other;
+ uint16_t sectidx;
+} ELF32symbol;
+
+typedef struct {
+ uint32_t name;
+ uint8_t info, other;
+ uint16_t sectidx;
+ uint64_t value, size;
+} ELF64symbol;
+
+typedef struct {
+ ELF32header hdr;
+ ELF32sectheader sect[6];
+ ELF32symbol sym[2];
+ uint8_t space[4096];
+} ELF32obj;
+
+typedef struct {
+ ELF64header hdr;
+ ELF64sectheader sect[6];
+ ELF64symbol sym[2];
+ uint8_t space[4096];
+} ELF64obj;
+]]
+
+local is64_arch = {
+ ['x64'] = true,
+ ['arm64'] = true,
+ ['arm64be'] = true,
+ ['ppc'] = false,
+ ['mips'] = false,
+}
+
+local is64 = is64_arch[jit.arch] or false
+
+local function create_obj_file(name)
+ local elf_filename = os.tmpname() .. '.obj'
+ local lua_path = os.getenv('LUA_PATH')
+ local lua_bin = require('utils').luacmd(arg):match('%S+')
+ local cmd_fmt = 'LUA_PATH="%s" %s -b -n "%s" -e "print()" %s'
+ local cmd = (cmd_fmt):format(lua_path, lua_bin, name, elf_filename)
+ local ret = os.execute(cmd)
+ assert(ret == 0, 'create an object file')
+ return elf_filename
+end
+
+-- Reads a file located in a specified path and returns its content.
+local function read_file(path)
+ local file = assert(io.open(path), 'cannot open an object file')
+ local content = file:read('*a')
+ file:close()
+ return content
+end
+
+-- Parses a buffer in an ELF format and returns an offset and a size of strtab
+-- and symtab sections.
+local function read_elf(elf_content)
+ local ELFobj_type = ffi.typeof(is64 and 'ELF64obj *' or 'ELF32obj *')
+ local ELFsectheader_type = ffi.typeof(is64 and 'ELF64sectheader *' or 'ELF32sectheader *')
+ local elf = ffi.cast(ELFobj_type, elf_content)
+ local symtab_hdr, strtab_hdr
+ -- Iterate by section headers.
+ for i = 0, elf.hdr.shnum do
+ local sec = ffi.cast(ELFsectheader_type, elf.sect[i])
+ if sec.type == SHT_SYMTAB then
+ symtab_hdr = sec
+ strtab_hdr = ffi.cast(ELFsectheader_type, elf.sect[symtab_hdr.link])
+ break
+ end
+ end
+
+ assert(strtab_hdr ~= nil, 'section .strtab was not found')
+ assert(symtab_hdr ~= nil, 'section .symtab was not found')
+
+ return strtab_hdr, symtab_hdr
+end
+
+test:plan(3)
+
+local elf_filename = create_obj_file(module_name)
+local elf_content = read_file(elf_filename)
+assert(#elf_content ~= 0, 'cannot read an object file')
+
+local strtab, symtab = read_elf(elf_content)
+local strtab_size = tonumber(strtab.size)
+local strtab_offset = tonumber(strtab.ofs)
+local symtab_size = tonumber(symtab.size)
+local sym_cnt = tonumber(symtab_size / symtab.entsize)
+assert(sym_cnt ~= 0, 'number of symbols is zero')
+
+test:is(strtab_size, expected_strtab_size, 'check .strtab size')
+test:is(strtab_offset, expected_strtab_offset, 'check .strtab offset')
As I already said offline, I don’t like that approach. ELF is made to by
as flexible as possible, so, generally, you have no guarantees about
order and, hence, offsets of any sections. The only reason why we are
getting away with that here, is because this ELF is generated
in `bcsave.lua` in a particular manner. It is ok for now, but no one
knows if this will ever change. I think that the symbol name search
below is sufficient, because it is unlikely to pass with an incorrect offset.

Sure, I remember your thoughts regarding checking with constant size and offset.

I left this for double-checking change proposed in patch.

I'll leave this as as without changes and will wait review from Sergey

and then we will decide remove these checks or not.

 
All of the checks are valid for now, though, so feel free to ignore.
+
+local strtab_str = string.sub(elf_content, strtab_offset, strtab_offset + strtab_size)
+
+local strtab_p = ffi.cast('char *', strtab_str)
+local sym_name_expected = LJBC_PREFIX .. module_name
+local sym_is_found = false
+for i = 1, sym_cnt do
+ local sym_name = ffi.string(strtab_p + i)
+ if sym_name_expected == sym_name then
+ sym_is_found = true
+ break
+ end
+end
+
+test:ok(sym_is_found == true, 'symbol is found')
+
+local ret = os.remove(elf_filename)
+assert(ret == true, 'cannot remove an object file')
+
+os.exit(test:check() and 0 or 1)
--
2.34.1
--
Best regards,
Maxim Kokryashkin
--------------Ts8B9jJCEnzvKEz3EfJTlp3i--