[PATCH 004/188] update reading symbol info

From 520a5340b636c24726426126b864f486b243821d Mon Sep 17 00:00:00 2001
From: Dmitry Boyarintsev <skalogryz.lists@gmail.com>
Date: Wed, 25 Sep 2019 10:12:27 -0400

git-svn-id: branches/wasm@46000 -
This commit is contained in:
nickysn 2020-08-03 12:58:45 +00:00
parent 64027a4527
commit 113c995843
3 changed files with 154 additions and 9 deletions

View File

@ -8,6 +8,15 @@ uses
function ReadU(src: TStream): UInt64;
function ReadS(src: TStream; bits: Integer): Int64;
procedure WriteU8 (src: TStream; vl: UInt8);
procedure WriteU16(src: TStream; vl: UInt16);
procedure WriteU32(src: TStream; vl: UInt32);
procedure WriteU64(src: TStream; vl: UInt64);
procedure WriteS8 (src: TStream; vl: Int8);
procedure WriteS16(src: TStream; vl: Int16);
procedure WriteS32(src: TStream; vl: Int32);
procedure WriteS64(src: TStream; vl: Int64);
implementation
function ReadU(src: TStream): UInt64;
@ -44,4 +53,39 @@ begin
result := result or ( (not 0) shl sh);
end;
procedure WriteU8(src: TStream; vl: UInt8);
begin
end;
procedure WriteU16(src: TStream; vl: UInt16);
begin
end;
procedure WriteU32(src: TStream; vl: UInt32);
begin
end;
procedure WriteU64(src: TStream; vl: UInt64);
begin
end;
procedure WriteS8 (src: TStream; vl: Int8);
begin
end;
procedure WriteS16(src: TStream; vl: Int16);
begin
end;
procedure WriteS32(src: TStream; vl: Int32);
begin
end;
procedure WriteS64(src: TStream; vl: Int64);
begin
end;
end.

View File

@ -94,6 +94,7 @@ function ValTypeToStr(id: integer): string;
// the name consists of
// size - in butes Leb128
// bytes - in utf8 format
function ReadName(st: TStream): string;
function GetName(sr: TStream): string;
// reads
@ -141,13 +142,18 @@ begin
end;
function GetName(sr: TStream): string;
function ReadName(st: TStream): string;
var
ln : LongWord;
begin
ln := ReadU(sr);
ln := ReadU(st);
SetLength(result, ln);
if ln>0 then sr.Read(result[1], ln);
if ln>0 then st.Read(result[1], ln);
end;
function GetName(sr: TStream): string;
begin
Result := ReadName(sr);
end;
function GetU32(sr: TStream): UInt32;

View File

@ -5,7 +5,7 @@ unit wasmlink;
interface
uses
Classes, SysUtils, lebutils;
Classes, SysUtils, lebutils, wasmbin;
const
SectionName_Linking = 'linking';
@ -67,10 +67,28 @@ const
type
TSymInfo = record
symkind : UInt8;
kind : UInt8;
flags : UInt32;
hasSymIndex : Boolean; // always true for Kind non Data
// for Data it's true for defined symbols (see flags);
symindex : UInt32; // either symbol or data symbol offset
hasSymName : Boolean;
symname : string;
dataofs : integer; // only if Kind is Data and hasSymIndex = true;
datasize : integer;
end;
// The symbol type. One of:
const
SYMTAB_FUNCTION = 0;
SYMTAB_DATA = 1;
SYMTAB_GLOBAL = 2;
SYMTAB_SECTION = 3;
SYMTAB_EVENT = 4;
SYMTAB_TABLE = 5;
// The current set of valid flags for symbols are:
const
// Indicating that this is a weak symbol. When linking multiple modules
@ -96,6 +114,7 @@ const
// this must match whether the symbol is an import or is defined;
// for data symbols, determines whether a segment is specified.
WASM_SYM_UNDEFINED = $10;
WASM_SYM_IMPORTED = WASM_SYM_UNDEFINED;
// The symbol is intended to be exported from the wasm module to the host
// environment. This differs from the visibility flags in that it effects
@ -113,17 +132,21 @@ const
function ReadMetaData(st: TStream; out m:TLinkingMetadata): Boolean;
function ReadLinkSubSect(st: TStream; out m: TLinkinSubSection): Boolean;
function ReadSymInfo(st: TStream; out m: TSymInfo): Boolean;
// dumps linking information. Note: that the name of the "Linking" section
// must have already been read
procedure DumpLinking(st: TStream; secsize: integer);
function SubSecTypeToStr(b: Byte): string;
function SymKindToStr(b: Byte): string;
implementation
function ReadMetaData(st: TStream; out m:TLinkingMetadata): Boolean;
begin
FillChar(m, sizeof(m), 0);
m.version := ReadU(st);
m.version := st.ReadByte;
Result:=true;
end;
@ -132,7 +155,36 @@ begin
FillChar(m, sizeof(m), 0);
m.sectype := ReadU(st);
m.length := ReadU(st);
Result:=true;
Result := true;
end;
function ReadSymInfo(st: TStream; out m: TSymInfo): Boolean;
begin
FillChar(m, sizeof(m), 0);
m.kind := st.ReadByte;
m.flags := ReadU(st);
if m.kind = SYMTAB_DATA then begin
m.hasSymName := true; // always exist
m.symname := ReadName(st);
m.hasSymIndex := (m.flags and WASM_SYM_UNDEFINED)=0;
if m.hasSymIndex then begin
m.symindex := ReadU(st);
m.dataofs := ReadU(st);
m.datasize := ReadU(st);
end;
end else begin
m.hasSymIndex := true; // always exists
m.symindex := ReadU(st);
m.hasSymName := ((m.flags and WASM_SYM_IMPORTED) = 0) or ((m.flags and WASM_SYM_EXPLICIT_NAME) > 0); // imported
if m.hasSymName then
m.symname:=ReadName(st);
end;
Result := true;
end;
procedure DumpLinking(st: TStream; secsize: integer);
@ -140,14 +192,57 @@ var
mt : TLinkingMetadata;
en : Int64;
sub : TLinkinSubSection;
cnt : LongWord;
nx : Int64;
i : integer;
si : TSymInfo;
begin
en := st.Position+secsize;
ReadMetadata(st, mt);
writeln('version: ', mt.version);
while st.Position<en do begin
ReadLinkSubSect(st, sub);
writeln(sub.sectype);
st.Position:=st.Position+sub.length;
nx := st.Position+sub.length;
writeln('subsec=',SubSecTypeToStr(sub.sectype),' ',sub.sectype);
cnt := ReadU(st);
writeln('- symbol table [count=', cnt,']');
for i:=0 to cnt-1 do begin
write(' - ',i,' ');
ReadSymInfo(st, si);
write(SymKindToStr(si.kind),' ',IntToHex(si.flags,8));
if si.hasSymName then write(' ',si.symname);
writeln;
//writeln(si.symname);
end;
st.Position:=nx;
end;
end;
function SubSecTypeToStr(b: Byte): string;
begin
case b of
WASM_SEGMENT_INFO: Result := 'WASM_SEGMENT_INFO';
WASM_INIT_FUNCS: Result := 'WASM_INIT_FUNCS';
WASM_COMDAT_INFO: Result := 'WASM_COMDAT_INFO';
WASM_SYMBOL_TABLE: Result := 'WASM_SYMBOL_TABLE';
else
Result := Format('UNKNOWN %d',[b]);
end;
end;
function SymKindToStr(b: Byte): string;
begin
case b of
SYMTAB_FUNCTION: Result := 'F';
SYMTAB_DATA: Result := 'D';
SYMTAB_GLOBAL: Result := 'G';
SYMTAB_SECTION: Result := 'S';
SYMTAB_EVENT: Result := 'E';
SYMTAB_TABLE: Result := 'T';
else
Result := 'U'+IntToStR(b);
end;
end;