Browse Source

[PATCH 004/188] update reading symbol info

From 520a5340b636c24726426126b864f486b243821d Mon Sep 17 00:00:00 2001
From: Dmitry Boyarintsev <[email protected]>
Date: Wed, 25 Sep 2019 10:12:27 -0400

git-svn-id: branches/wasm@46000 -
nickysn 5 years ago
parent
commit
113c995843
3 changed files with 154 additions and 9 deletions
  1. 44 0
      utils/wasmbin/lebutils.pas
  2. 9 3
      utils/wasmbin/wasmbin.pas
  3. 101 6
      utils/wasmbin/wasmlink.pas

+ 44 - 0
utils/wasmbin/lebutils.pas

@@ -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.

+ 9 - 3
utils/wasmbin/wasmbin.pas

@@ -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;

+ 101 - 6
utils/wasmbin/wasmlink.pas

@@ -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;